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 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
48 LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();
53 if (d3ddev->CreateTexture(1024,1024,0,0,D3DFMT_A8R8G8B8,
54 // Does every adapter with alpha blending support this?
55 D3DPOOL_DEFAULT,&d3dtexture ,NULL)!=D3D_OK) {
57 MILLISLEEP(50);//wait maybe next time it will work
60 if (d3dtexture->GetSurfaceLevel(0,&d3dsurface)!=D3D_OK) {
61 d3dtexture->Release();
69 if (hres=d3ddev->CreateOffscreenPlainSurface(width,height,D3DFMT_A8R8G8B8,
70 D3DPOOL_SYSTEMMEM,&d3dsurface,NULL)!=D3D_OK) {
72 MILLISLEEP(50);//wait maybe next time it will work
82 /* If someone does high performance Animations on the OSD, we have to change the types
83 of surface in order to address these performance issues, if we have only very few updates
84 per second this would be fast enough !*/
91 void SurfaceWin::display()
95 int SurfaceWin::fillblt(int x, int y, int width, int height, unsigned int c)
97 WaitForSingleObject(event,INFINITE); //since this might be called before surface
98 //allocation we will wait in this case, hopefully without deadlocks
99 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
102 return 0; //why does this happen
105 LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();
108 //This should not happen!
112 osd->BeginPainting();
113 D3DLOCKED_RECT lockrect;
114 int cx,cy,cwidth,cheight;
115 cx=min(max(x,0),swidth-1);
116 cy=min(max(y,0),sheight-1);
117 cwidth=min(width,swidth-x);
118 cheight=min(height,sheight-y);
119 RECT rect={cx,cy,cwidth,cheight};
121 if (d3dsurface->LockRect(&lockrect,&rect,D3DLOCK_DISCARD)!=D3D_OK) {
126 for (line=0;line<cheight;line++) {
127 unsigned int*row=((unsigned int*)(((char*)lockrect.pBits)+lockrect.Pitch*line));
128 for (column=0;column<cwidth;column++) {
133 if (d3dsurface->UnlockRect()!=D3D_OK) {
144 void SurfaceWin::startFastDraw(){
145 WaitForSingleObject(event,INFINITE); //since this might be called before surface
146 //allocation we will wait in this case, hopefully without deadlocks
148 return; //why does this happen
150 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
151 LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();
153 //This should not happen!
157 osd->BeginPainting();
158 // D3DLOCKED_RECT lockrect;
159 RECT rect={0,0,swidth,sheight};
160 if (d3dsurface->LockRect(&lockrect,&rect,D3DLOCK_DISCARD)!=D3D_OK) {
167 void SurfaceWin::endFastDraw(){
168 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
169 if (d3dsurface->UnlockRect()!=D3D_OK) {
177 void SurfaceWin::drawPixel(int x, int y, Colour & colour, bool fastdraw) {
178 int c = ( (0xFF000000 )
180 | (colour.green << 8)
183 drawPixel(x, y, c, fastdraw);
186 void SurfaceWin::drawPixel(int x, int y, unsigned int c, bool fastdraw)
188 //FixMe: locking for every single Pixel will be painfully slow
191 WaitForSingleObject(event,INFINITE); //since this might be called before surface
192 //allocation we will wait in this case, hopefully without deadlocks
194 return; //why does this happen
196 osd=((OsdWin*)(Osd::getInstance()));
198 if (x>=swidth || y>=sheight) return; //do not draw outside the surface
200 //This should not happen!
205 osd->BeginPainting();
206 // D3DLOCKED_RECT lockrect;
207 RECT rect={x,y,x+1,y+1};
208 if (d3dsurface->LockRect(&lockrect,&rect,D3DLOCK_DISCARD)!=D3D_OK) {
212 unsigned int*row=(unsigned int*)(((char*)lockrect.pBits));
214 if (d3dsurface->UnlockRect()!=D3D_OK) {
220 unsigned int*row=(unsigned int*)(((char*)lockrect.pBits+lockrect.Pitch*y+4*x));
228 void SurfaceWin::drawHorzLine(int x1, int x2, int y, unsigned int c)
230 fillblt(x1, y, x2-x1, 1, c);
233 void SurfaceWin::drawVertLine(int x, int y1, int y2, unsigned int c)
235 fillblt(x, y1, 1, y2-y1, c);
238 void SurfaceWin::drawBitmap(int x, int y, const Bitmap& bm)
240 // Temporary code? Draw one pixel at a time using drawPixel()
242 for (UINT j = 0; j < bm.getHeight(); ++j)
243 for (UINT i = 0; i < bm.getWidth(); ++i)
244 drawPixel(x+i, y+j, bm.getColour(i,j),true);
248 int SurfaceWin::updateToScreen(int sx, int sy, int w, int h, int dx, int dy) // FIXME new, replace others with this FIXME
250 WaitForSingleObject(event,INFINITE); //since this might be called before surface
251 //allocation we will wait in this case, hopefully without deadlocks
253 return 0; //why does this happen
255 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
256 LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();
257 LPDIRECT3DSURFACE9 screensurface=((SurfaceWin*)screen)->getD3dsurface();
258 if (!screensurface) return 0;
259 RECT sourcerect={sx,sy,sx+w,sy+h};
260 POINT destpoint={dx,dy};
261 osd->BeginPainting();
262 if (d3ddev->UpdateSurface(d3dsurface,&sourcerect,screensurface,&destpoint)!=D3D_OK) {
263 Log::getInstance()->log("Surface", Log::DEBUG, "Could not update to Screen!");
271 int SurfaceWin::blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy)
273 //I don't see code using this function, so I skip it, since it is a MVP specific interface
277 void SurfaceWin::screenShot(char* fileName)
279 //Isn't this for debugging only, so I won't implement it yet
282 void SurfaceWin::readPixel(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b)
284 //Isn't this for debugging only, so I won't implement it yet
286 void SurfaceWin::ReleaseSurface()
289 LPDIRECT3DSURFACE9 temp_surf=d3dsurface;
290 LPDIRECT3DTEXTURE9 temp_text=d3dtexture;
294 if (temp_surf) temp_surf->Release();
295 if (temp_text) temp_text->Release();
298 void SurfaceWin::drawJpeg(char *fileName,DWORD x, DWORD y,DWORD *width, DWORD *height){
299 WaitForSingleObject(event,INFINITE); //since this might be called before surface
300 //allocation we will wait in this case, hopefully without deadlocks
302 return ; //why does this happen
304 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
307 D3DXIMAGE_INFO image_inf;
308 osd->BeginPainting();
309 // D3DXGetImageInfoFromFile(fileName,&image_inf);
310 D3DXGetImageInfoFromResource(NULL,fileName,&image_inf);
311 RECT dest_rec={x,y,x+image_inf.Width,
313 /* if (D3DXLoadSurfaceFromFile(
321 &image_inf)!=D3D_OK) {
322 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
325 if (D3DXLoadSurfaceFromResource(
334 &image_inf)!=D3D_OK) {
335 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
339 *width=image_inf.Width;
340 *height=image_inf.Height;
344 void SurfaceWin::drawJpeg(char *buffer,ULONG buflength,DWORD x, DWORD y,DWORD *width, DWORD *height){
345 WaitForSingleObject(event,INFINITE); //since this might be called before surface
346 //allocation we will wait in this case, hopefully without deadlocks
348 return ; //why does this happen
350 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
353 D3DXIMAGE_INFO image_inf;
354 osd->BeginPainting();
355 // D3DXGetImageInfoFromFile(fileName,&image_inf);
356 D3DXGetImageInfoFromFileInMemory((void*)buffer,buflength,&image_inf);
357 RECT dest_rec={x,y,x+image_inf.Width,
359 /* if (D3DXLoadSurfaceFromFile(
367 &image_inf)!=D3D_OK) {
368 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
371 /* if (D3DXLoadSurfaceFromResource(
380 &image_inf)!=D3D_OK) {
381 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
384 if (D3DXLoadSurfaceFromFileInMemory(
393 &image_inf)!=D3D_OK) {
394 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
398 *width=image_inf.Width;
399 *height=image_inf.Height;