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"
27 SurfaceWin::SurfaceWin(int id)
34 event = CreateEvent(NULL,/*FALSE*/TRUE,FALSE,NULL);
37 SurfaceWin::~SurfaceWin()
39 if (d3dsurface) d3dsurface->Release();
40 if (d3dtexture) d3dtexture->Release();
44 int SurfaceWin::create(UINT width, UINT height)
46 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
49 LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();
54 if (d3ddev->CreateTexture(1024,1024,0,0,D3DFMT_A8R8G8B8,
55 // Does every adapter with alpha blending support this?
56 D3DPOOL_DEFAULT,&d3dtexture ,NULL)!=D3D_OK) {
58 MILLISLEEP(50);//wait maybe next time it will work
61 if (d3dtexture->GetSurfaceLevel(0,&d3dsurface)!=D3D_OK) {
62 d3dtexture->Release();
70 if (hres=d3ddev->CreateOffscreenPlainSurface(width,height,D3DFMT_A8R8G8B8,
71 D3DPOOL_SYSTEMMEM,&d3dsurface,NULL)!=D3D_OK) {
73 MILLISLEEP(50);//wait maybe next time it will work
83 /* If someone does high performance Animations on the OSD, we have to change the types
84 of surface in order to address these performance issues, if we have only very few updates
85 per second this would be fast enough !*/
92 void SurfaceWin::display()
96 int SurfaceWin::fillblt(int x, int y, int width, int height, const DrawStyle& c)
98 WaitForSingleObject(event,INFINITE); //since this might be called before surface
99 //allocation we will wait in this case, hopefully without deadlocks
100 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
103 return 0; //why does this happen
107 LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();
110 //This should not happen!
114 osd->BeginPainting();
115 D3DLOCKED_RECT lockrect;
116 int cx,cy,cwidth,cheight;
117 cx=min(max(x,0),swidth-1);
118 cy=min(max(y,0),sheight-1);
119 cwidth=min(width,swidth-x);
120 cheight=min(height,sheight-y);
121 RECT rect={cx,cy,cwidth,cheight};
123 if (d3dsurface->LockRect(&lockrect,&rect,D3DLOCK_DISCARD)!=D3D_OK) {
128 for (line=0;line<cheight;line++) {
129 unsigned int*row=((unsigned int*)(((char*)lockrect.pBits)+lockrect.Pitch*line));
130 for (column=0;column<cwidth;column++) {
135 if (d3dsurface->UnlockRect()!=D3D_OK) {
146 void SurfaceWin::startFastDraw(){
147 WaitForSingleObject(event,INFINITE); //since this might be called before surface
148 //allocation we will wait in this case, hopefully without deadlocks
150 return; //why does this happen
152 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
153 LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();
155 //This should not happen!
159 osd->BeginPainting();
160 // D3DLOCKED_RECT lockrect;
161 RECT rect={0,0,swidth,sheight};
162 if (d3dsurface->LockRect(&lockrect,&rect,D3DLOCK_DISCARD)!=D3D_OK) {
169 void SurfaceWin::endFastDraw(){
170 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
171 if (d3dsurface->UnlockRect()!=D3D_OK) {
179 void SurfaceWin::drawPixel(int x, int y, Colour & colour, bool fastdraw) {
180 int c = ( (0xFF000000 )
182 | (colour.green << 8)
185 drawPixel(x, y, c, fastdraw);
188 void SurfaceWin::drawPixel(int x, int y, unsigned int c, bool fastdraw)
190 //FixMe: locking for every single Pixel will be painfully slow
193 WaitForSingleObject(event,INFINITE); //since this might be called before surface
194 //allocation we will wait in this case, hopefully without deadlocks
196 return; //why does this happen
198 osd=((OsdWin*)(Osd::getInstance()));
200 if (x>=swidth || y>=sheight) return; //do not draw outside the surface
202 //This should not happen!
207 osd->BeginPainting();
208 // D3DLOCKED_RECT lockrect;
209 RECT rect={x,y,x+1,y+1};
210 if (d3dsurface->LockRect(&lockrect,&rect,D3DLOCK_DISCARD)!=D3D_OK) {
214 unsigned int*row=(unsigned int*)(((char*)lockrect.pBits));
216 if (d3dsurface->UnlockRect()!=D3D_OK) {
222 unsigned int*row=(unsigned int*)(((char*)lockrect.pBits+lockrect.Pitch*y+4*x));
230 void SurfaceWin::drawHorzLine(int x1, int x2, int y,const DrawStyle& c)
232 fillblt(x1, y, x2-x1, 1, c);
235 void SurfaceWin::drawVertLine(int x, int y1, int y2, const DrawStyle& c)
237 fillblt(x, y1, 1, y2-y1, c);
240 void SurfaceWin::drawBitmap(int x, int y, const Bitmap& bm,const DisplayRegion & region)
242 // Temporary code? Draw one pixel at a time using drawPixel()
244 for (UINT j = 0; j < bm.getHeight(); ++j)
245 for (UINT i = 0; i < bm.getWidth(); ++i)
246 drawPixel(x+i, y+j, bm.getColour(i,j),true);
250 int SurfaceWin::updateToScreen(int sx, int sy, int w, int h, int dx, int dy) // FIXME new, replace others with this FIXME
252 WaitForSingleObject(event,INFINITE); //since this might be called before surface
253 //allocation we will wait in this case, hopefully without deadlocks
255 return 0; //why does this happen
257 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
258 LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();
259 LPDIRECT3DSURFACE9 screensurface=((SurfaceWin*)screen)->getD3dsurface();
260 if (!screensurface) return 0;
261 RECT sourcerect={sx,sy,sx+w,sy+h};
262 POINT destpoint={dx,dy};
263 osd->BeginPainting();
264 if (d3ddev->UpdateSurface(d3dsurface,&sourcerect,screensurface,&destpoint)!=D3D_OK) {
265 Log::getInstance()->log("Surface", Log::DEBUG, "Could not update to Screen!");
273 int SurfaceWin::blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy)
275 //I don't see code using this function, so I skip it, since it is a MVP specific interface
279 void SurfaceWin::screenShot(const char* fileName)
281 //Isn't this for debugging only, so I won't implement it yet
284 void SurfaceWin::readPixel(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b)
286 //Isn't this for debugging only, so I won't implement it yet
288 void SurfaceWin::ReleaseSurface()
291 LPDIRECT3DSURFACE9 temp_surf=d3dsurface;
292 LPDIRECT3DTEXTURE9 temp_text=d3dtexture;
296 if (temp_surf) temp_surf->Release();
297 if (temp_text) temp_text->Release();
300 void SurfaceWin::drawJpeg(const char *fileName,int x, int y,int *width, int *height){
301 WaitForSingleObject(event,INFINITE); //since this might be called before surface
302 //allocation we will wait in this case, hopefully without deadlocks
304 return ; //why does this happen
306 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
309 D3DXIMAGE_INFO image_inf;
310 osd->BeginPainting();
311 // D3DXGetImageInfoFromFile(fileName,&image_inf);
312 D3DXGetImageInfoFromResource(NULL,fileName,&image_inf);
313 RECT dest_rec={x,y,x+image_inf.Width,
315 /* if (D3DXLoadSurfaceFromFile(
323 &image_inf)!=D3D_OK) {
324 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
327 if (D3DXLoadSurfaceFromResource(
336 &image_inf)!=D3D_OK) {
337 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
341 *width=image_inf.Width;
342 *height=image_inf.Height;
347 void SurfaceWin::drawJpeg(char *buffer,ULONG buflength,DWORD x, DWORD y,DWORD *width, DWORD *height){
348 WaitForSingleObject(event,INFINITE); //since this might be called before surface
349 //allocation we will wait in this case, hopefully without deadlocks
351 return ; //why does this happen
353 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
356 D3DXIMAGE_INFO image_inf;
357 osd->BeginPainting();
358 // D3DXGetImageInfoFromFile(fileName,&image_inf);
359 D3DXGetImageInfoFromFileInMemory((void*)buffer,buflength,&image_inf);
360 RECT dest_rec={x,y,x+image_inf.Width,
362 /* if (D3DXLoadSurfaceFromFile(
370 &image_inf)!=D3D_OK) {
371 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
374 /* if (D3DXLoadSurfaceFromResource(
383 &image_inf)!=D3D_OK) {
384 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
387 if (D3DXLoadSurfaceFromFileInMemory(
396 &image_inf)!=D3D_OK) {
397 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
401 *width=image_inf.Width;
402 *height=image_inf.Height;