2 Copyright 2006 Marten Richter
4 This file is part of VOMP.
6 VOMP is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 VOMP is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with VOMP; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #include "surfacewin.h"
26 SurfaceWin::SurfaceWin(int id)
33 event = CreateEvent(NULL,/*FALSE*/TRUE,FALSE,NULL);
36 SurfaceWin::~SurfaceWin()
38 if (d3dsurface) d3dsurface->Release();
39 if (d3dtexture) d3dtexture->Release();
43 int SurfaceWin::create(UINT width, UINT height)
45 LPDIRECT3DDEVICE9 d3ddev=((OsdWin*)(Osd::getInstance()))->getD3dDev();
48 if (d3ddev->CreateTexture(1024,1024,0,0,D3DFMT_A8R8G8B8,
49 // Does every adapter with alpha blending support this?
50 D3DPOOL_DEFAULT,&d3dtexture ,NULL)!=D3D_OK) {
51 MILLISLEEP(50);//wait maybe next time it will work
54 if (d3dtexture->GetSurfaceLevel(0,&d3dsurface)!=D3D_OK) {
55 d3dtexture->Release();
62 if (hres=d3ddev->CreateOffscreenPlainSurface(width,height,D3DFMT_A8R8G8B8,
63 D3DPOOL_SYSTEMMEM,&d3dsurface,NULL)!=D3D_OK) {
64 MILLISLEEP(50);//wait maybe next time it will work
71 /* If someone does high performance Animations on the OSD, we have to change the types
72 of surface in order to address these performance issues, if we have only very few updates
73 per second this would be fast enough !*/
80 void SurfaceWin::display()
84 int SurfaceWin::fillblt(int x, int y, int width, int height, unsigned int c)
86 WaitForSingleObject(event,INFINITE); //since this might be called before surface
87 //allocation we will wait in this case, hopefully without deadlocks
88 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
91 return 0; //why does this happen
94 LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();
97 //This should not happen!
101 osd->BeginPainting();
102 D3DLOCKED_RECT lockrect;
103 int cx,cy,cwidth,cheight;
104 cx=min(max(x,0),swidth-1);
105 cy=min(max(y,0),sheight-1);
106 cwidth=min(width,swidth-x);
107 cheight=min(height,sheight-y);
108 RECT rect={cx,cy,cwidth,cheight};
110 if (d3dsurface->LockRect(&lockrect,&rect,D3DLOCK_DISCARD)!=D3D_OK) {
115 for (line=0;line<cheight;line++) {
116 unsigned int*row=((unsigned int*)(((char*)lockrect.pBits)+lockrect.Pitch*line));
117 for (column=0;column<cwidth;column++) {
122 if (d3dsurface->UnlockRect()!=D3D_OK) {
133 void SurfaceWin::startFastDraw(){
134 WaitForSingleObject(event,INFINITE); //since this might be called before surface
135 //allocation we will wait in this case, hopefully without deadlocks
137 return; //why does this happen
139 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
140 LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();
142 //This should not happen!
146 osd->BeginPainting();
147 // D3DLOCKED_RECT lockrect;
148 RECT rect={0,0,swidth,sheight};
149 if (d3dsurface->LockRect(&lockrect,&rect,D3DLOCK_DISCARD)!=D3D_OK) {
156 void SurfaceWin::endFastDraw(){
157 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
158 if (d3dsurface->UnlockRect()!=D3D_OK) {
166 void SurfaceWin::drawPixel(int x, int y, Colour & colour, bool fastdraw) {
167 int c = ( (0xFF000000 )
169 | (colour.green << 8)
172 drawPixel(x, y, c, fastdraw);
175 void SurfaceWin::drawPixel(int x, int y, unsigned int c, bool fastdraw)
177 //FixMe: locking for every single Pixel will be painfully slow
180 WaitForSingleObject(event,INFINITE); //since this might be called before surface
181 //allocation we will wait in this case, hopefully without deadlocks
183 return; //why does this happen
185 osd=((OsdWin*)(Osd::getInstance()));
187 if (x>=swidth || y>=sheight) return; //do not draw outside the surface
189 //This should not happen!
194 osd->BeginPainting();
195 // D3DLOCKED_RECT lockrect;
196 RECT rect={x,y,x+1,y+1};
197 if (d3dsurface->LockRect(&lockrect,&rect,D3DLOCK_DISCARD)!=D3D_OK) {
201 unsigned int*row=(unsigned int*)(((char*)lockrect.pBits));
203 if (d3dsurface->UnlockRect()!=D3D_OK) {
209 unsigned int*row=(unsigned int*)(((char*)lockrect.pBits+lockrect.Pitch*y+4*x));
217 void SurfaceWin::drawHorzLine(int x1, int x2, int y, unsigned int c)
219 fillblt(x1, y, x2-x1, 1, c);
222 void SurfaceWin::drawVertLine(int x, int y1, int y2, unsigned int c)
224 fillblt(x, y1, 1, y2-y1, c);
227 void SurfaceWin::drawBitmap(int x, int y, const Bitmap& bm)
229 // Temporary code? Draw one pixel at a time using drawPixel()
231 for (UINT j = 0; j < bm.getHeight(); ++j)
232 for (UINT i = 0; i < bm.getWidth(); ++i)
233 drawPixel(x+i, y+j, bm.getColour(i,j),true);
237 int SurfaceWin::updateToScreen(int sx, int sy, int w, int h, int dx, int dy) // FIXME new, replace others with this FIXME
239 WaitForSingleObject(event,INFINITE); //since this might be called before surface
240 //allocation we will wait in this case, hopefully without deadlocks
242 return 0; //why does this happen
244 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
245 LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();
246 LPDIRECT3DSURFACE9 screensurface=((SurfaceWin*)screen)->getD3dsurface();
247 if (!screensurface) return 0;
248 RECT sourcerect={sx,sy,sx+w,sy+h};
249 POINT destpoint={dx,dy};
250 osd->BeginPainting();
251 if (d3ddev->UpdateSurface(d3dsurface,&sourcerect,screensurface,&destpoint)!=D3D_OK) {
252 Log::getInstance()->log("Surface", Log::DEBUG, "Could not update to Screen!");
260 int SurfaceWin::blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy)
262 //I don't see code using this function, so I skip it, since it is a MVP specific interface
266 void SurfaceWin::screenShot(char* fileName)
268 //Isn't this for debugging only, so I won't implement it yet
271 void SurfaceWin::readPixel(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b)
273 //Isn't this for debugging only, so I won't implement it yet
275 void SurfaceWin::ReleaseSurface()
278 LPDIRECT3DSURFACE9 temp_surf=d3dsurface;
279 LPDIRECT3DTEXTURE9 temp_text=d3dtexture;
283 if (temp_surf) temp_surf->Release();
284 if (temp_text) temp_text->Release();
287 void SurfaceWin::drawJpeg(char *fileName,DWORD x, DWORD y,DWORD *width, DWORD *height){
288 WaitForSingleObject(event,INFINITE); //since this might be called before surface
289 //allocation we will wait in this case, hopefully without deadlocks
291 return ; //why does this happen
293 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
296 D3DXIMAGE_INFO image_inf;
297 osd->BeginPainting();
298 // D3DXGetImageInfoFromFile(fileName,&image_inf);
299 D3DXGetImageInfoFromResource(NULL,fileName,&image_inf);
300 RECT dest_rec={x,y,x+image_inf.Width,
302 /* if (D3DXLoadSurfaceFromFile(
310 &image_inf)!=D3D_OK) {
311 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
314 if (D3DXLoadSurfaceFromResource(
323 &image_inf)!=D3D_OK) {
324 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
328 *width=image_inf.Width;
329 *height=image_inf.Height;
333 void SurfaceWin::drawJpeg(char *buffer,ULONG buflength,DWORD x, DWORD y,DWORD *width, DWORD *height){
334 WaitForSingleObject(event,INFINITE); //since this might be called before surface
335 //allocation we will wait in this case, hopefully without deadlocks
337 return ; //why does this happen
339 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
342 D3DXIMAGE_INFO image_inf;
343 osd->BeginPainting();
344 // D3DXGetImageInfoFromFile(fileName,&image_inf);
345 D3DXGetImageInfoFromFileInMemory((void*)buffer,buflength,&image_inf);
346 RECT dest_rec={x,y,x+image_inf.Width,
348 /* if (D3DXLoadSurfaceFromFile(
356 &image_inf)!=D3D_OK) {
357 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
360 /* if (D3DXLoadSurfaceFromResource(
369 &image_inf)!=D3D_OK) {
370 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
373 if (D3DXLoadSurfaceFromFileInMemory(
382 &image_inf)!=D3D_OK) {
383 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
387 *width=image_inf.Width;
388 *height=image_inf.Height;