2 Copyright 2006 Marten Richter
\r
4 This file is part of VOMP.
\r
6 VOMP is free software; you can redistribute it and/or modify
\r
7 it under the terms of the GNU General Public License as published by
\r
8 the Free Software Foundation; either version 2 of the License, or
\r
9 (at your option) any later version.
\r
11 VOMP is distributed in the hope that it will be useful,
\r
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
14 GNU General Public License for more details.
\r
16 You should have received a copy of the GNU General Public License
\r
17 along with VOMP; if not, write to the Free Software
\r
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
\r
21 #include "surfacewin.h"
\r
26 SurfaceWin::SurfaceWin(int id)
\r
33 event = CreateEvent(NULL,/*FALSE*/TRUE,FALSE,NULL);
\r
36 SurfaceWin::~SurfaceWin()
\r
38 if (d3dsurface) d3dsurface->Release();
\r
39 if (d3dtexture) d3dtexture->Release();
\r
43 int SurfaceWin::create(UINT width, UINT height)
\r
45 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
\r
48 LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();
\r
52 osd->BeginPainting();
\r
53 if (d3ddev->CreateTexture(1024,1024,0,0,D3DFMT_A8R8G8B8,
\r
54 // Does every adapter with alpha blending support this?
\r
55 D3DPOOL_DEFAULT,&d3dtexture ,NULL)!=D3D_OK) {
\r
57 MILLISLEEP(50);//wait maybe next time it will work
\r
60 if (d3dtexture->GetSurfaceLevel(0,&d3dsurface)!=D3D_OK) {
\r
61 d3dtexture->Release();
\r
69 if (hres=d3ddev->CreateOffscreenPlainSurface(width,height,D3DFMT_A8R8G8B8,
\r
70 D3DPOOL_SYSTEMMEM,&d3dsurface,NULL)!=D3D_OK) {
\r
72 MILLISLEEP(50);//wait maybe next time it will work
\r
82 /* If someone does high performance Animations on the OSD, we have to change the types
\r
83 of surface in order to address these performance issues, if we have only very few updates
\r
84 per second this would be fast enough !*/
\r
91 void SurfaceWin::display()
\r
95 int SurfaceWin::fillblt(int x, int y, int width, int height, unsigned int c)
\r
97 WaitForSingleObject(event,INFINITE); //since this might be called before surface
\r
98 //allocation we will wait in this case, hopefully without deadlocks
\r
99 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
\r
102 return 0; //why does this happen
\r
105 LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();
\r
107 if (screen==this) {
\r
108 //This should not happen!
\r
112 osd->BeginPainting();
\r
113 D3DLOCKED_RECT lockrect;
\r
114 int cx,cy,cwidth,cheight;
\r
115 cx=min(max(x,0),swidth-1);
\r
116 cy=min(max(y,0),sheight-1);
\r
117 cwidth=min(width,swidth-x);
\r
118 cheight=min(height,sheight-y);
\r
119 RECT rect={cx,cy,cwidth,cheight};
\r
121 if (d3dsurface->LockRect(&lockrect,&rect,D3DLOCK_DISCARD)!=D3D_OK) {
\r
125 unsigned int column;
\r
126 for (line=0;line<cheight;line++) {
\r
127 unsigned int*row=((unsigned int*)(((char*)lockrect.pBits)+lockrect.Pitch*line));
\r
128 for (column=0;column<cwidth;column++) {
\r
133 if (d3dsurface->UnlockRect()!=D3D_OK) {
\r
134 osd->EndPainting();
\r
137 osd->EndPainting();
\r
144 void SurfaceWin::startFastDraw(){
\r
145 WaitForSingleObject(event,INFINITE); //since this might be called before surface
\r
146 //allocation we will wait in this case, hopefully without deadlocks
\r
148 return; //why does this happen
\r
150 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
\r
151 LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();
\r
152 if (screen==this) {
\r
153 //This should not happen!
\r
157 osd->BeginPainting();
\r
158 // D3DLOCKED_RECT lockrect;
\r
159 RECT rect={0,0,swidth,sheight};
\r
160 if (d3dsurface->LockRect(&lockrect,&rect,D3DLOCK_DISCARD)!=D3D_OK) {
\r
161 osd->EndPainting();
\r
167 void SurfaceWin::endFastDraw(){
\r
168 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
\r
169 if (d3dsurface->UnlockRect()!=D3D_OK) {
\r
170 osd->EndPainting();
\r
173 osd->EndPainting();
\r
177 void SurfaceWin::drawPixel(int x, int y, Colour & colour, bool fastdraw) {
\r
178 int c = ( (0xFF000000 )
\r
179 | (colour.red << 16)
\r
180 | (colour.green << 8)
\r
181 | (colour.blue ) );
\r
183 drawPixel(x, y, c, fastdraw);
\r
186 void SurfaceWin::drawPixel(int x, int y, unsigned int c, bool fastdraw)
\r
188 //FixMe: locking for every single Pixel will be painfully slow
\r
191 WaitForSingleObject(event,INFINITE); //since this might be called before surface
\r
192 //allocation we will wait in this case, hopefully without deadlocks
\r
194 return; //why does this happen
\r
196 osd=((OsdWin*)(Osd::getInstance()));
\r
198 if (x>=swidth || y>=sheight) return; //do not draw outside the surface
\r
199 if (screen==this) {
\r
200 //This should not happen!
\r
205 osd->BeginPainting();
\r
206 // D3DLOCKED_RECT lockrect;
\r
207 RECT rect={x,y,x+1,y+1};
\r
208 if (d3dsurface->LockRect(&lockrect,&rect,D3DLOCK_DISCARD)!=D3D_OK) {
\r
209 osd->EndPainting();
\r
212 unsigned int*row=(unsigned int*)(((char*)lockrect.pBits));
\r
214 if (d3dsurface->UnlockRect()!=D3D_OK) {
\r
215 osd->EndPainting();
\r
218 osd->EndPainting();
\r
220 unsigned int*row=(unsigned int*)(((char*)lockrect.pBits+lockrect.Pitch*y+4*x));
\r
228 void SurfaceWin::drawHorzLine(int x1, int x2, int y, unsigned int c)
\r
230 fillblt(x1, y, x2-x1, 1, c);
\r
233 void SurfaceWin::drawVertLine(int x, int y1, int y2, unsigned int c)
\r
235 fillblt(x, y1, 1, y2-y1, c);
\r
238 void SurfaceWin::drawBitmap(int x, int y, const Bitmap& bm)
\r
240 // Temporary code? Draw one pixel at a time using drawPixel()
\r
242 for (UINT j = 0; j < bm.getHeight(); ++j)
\r
243 for (UINT i = 0; i < bm.getWidth(); ++i)
\r
244 drawPixel(x+i, y+j, bm.getColour(i,j),true);
\r
248 int SurfaceWin::updateToScreen(int sx, int sy, int w, int h, int dx, int dy) // FIXME new, replace others with this FIXME
\r
250 WaitForSingleObject(event,INFINITE); //since this might be called before surface
\r
251 //allocation we will wait in this case, hopefully without deadlocks
\r
253 return 0; //why does this happen
\r
255 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
\r
256 LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();
\r
257 LPDIRECT3DSURFACE9 screensurface=((SurfaceWin*)screen)->getD3dsurface();
\r
258 if (!screensurface) return 0;
\r
259 RECT sourcerect={sx,sy,sx+w,sy+h};
\r
260 POINT destpoint={dx,dy};
\r
261 osd->BeginPainting();
\r
262 if (d3ddev->UpdateSurface(d3dsurface,&sourcerect,screensurface,&destpoint)!=D3D_OK) {
\r
263 Log::getInstance()->log("Surface", Log::DEBUG, "Could not update to Screen!");
\r
264 osd->EndPainting();
\r
267 osd->EndPainting();
\r
271 int SurfaceWin::blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy)
\r
273 //I don't see code using this function, so I skip it, since it is a MVP specific interface
\r
277 void SurfaceWin::screenShot(const char* fileName)
\r
279 //Isn't this for debugging only, so I won't implement it yet
\r
282 void SurfaceWin::readPixel(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b)
\r
284 //Isn't this for debugging only, so I won't implement it yet
\r
286 void SurfaceWin::ReleaseSurface()
\r
289 LPDIRECT3DSURFACE9 temp_surf=d3dsurface;
\r
290 LPDIRECT3DTEXTURE9 temp_text=d3dtexture;
\r
294 if (temp_surf) temp_surf->Release();
\r
295 if (temp_text) temp_text->Release();
\r
298 void SurfaceWin::drawJpeg(const char *fileName,int x, int y,int *width, int *height){
\r
299 WaitForSingleObject(event,INFINITE); //since this might be called before surface
\r
300 //allocation we will wait in this case, hopefully without deadlocks
\r
302 return ; //why does this happen
\r
304 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
\r
307 D3DXIMAGE_INFO image_inf;
\r
308 osd->BeginPainting();
\r
309 // D3DXGetImageInfoFromFile(fileName,&image_inf);
\r
310 D3DXGetImageInfoFromResource(NULL,fileName,&image_inf);
\r
311 RECT dest_rec={x,y,x+image_inf.Width,
\r
312 y+image_inf.Height};
\r
313 /* if (D3DXLoadSurfaceFromFile(
\r
321 &image_inf)!=D3D_OK) {
\r
322 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
\r
325 if (D3DXLoadSurfaceFromResource(
\r
334 &image_inf)!=D3D_OK) {
\r
335 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
\r
338 osd->EndPainting();
\r
339 *width=image_inf.Width;
\r
340 *height=image_inf.Height;
\r
345 void SurfaceWin::drawJpeg(char *buffer,ULONG buflength,DWORD x, DWORD y,DWORD *width, DWORD *height){
\r
346 WaitForSingleObject(event,INFINITE); //since this might be called before surface
\r
347 //allocation we will wait in this case, hopefully without deadlocks
\r
349 return ; //why does this happen
\r
351 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
\r
354 D3DXIMAGE_INFO image_inf;
\r
355 osd->BeginPainting();
\r
356 // D3DXGetImageInfoFromFile(fileName,&image_inf);
\r
357 D3DXGetImageInfoFromFileInMemory((void*)buffer,buflength,&image_inf);
\r
358 RECT dest_rec={x,y,x+image_inf.Width,
\r
359 y+image_inf.Height};
\r
360 /* if (D3DXLoadSurfaceFromFile(
\r
368 &image_inf)!=D3D_OK) {
\r
369 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
\r
372 /* if (D3DXLoadSurfaceFromResource(
\r
381 &image_inf)!=D3D_OK) {
\r
382 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
\r
385 if (D3DXLoadSurfaceFromFileInMemory(
\r
394 &image_inf)!=D3D_OK) {
\r
395 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
\r
398 osd->EndPainting();
\r
399 *width=image_inf.Width;
\r
400 *height=image_inf.Height;
\r