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, const DrawStyle& 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
104 ULONG col=c.rgba();
\r
106 LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();
\r
108 if (screen==this) {
\r
109 //This should not happen!
\r
113 osd->BeginPainting();
\r
114 D3DLOCKED_RECT lockrect;
\r
115 int cx,cy,cwidth,cheight;
\r
116 cx=min(max(x,0),swidth-1);
\r
117 cy=min(max(y,0),sheight-1);
\r
118 cwidth=min(width,swidth-x);
\r
119 cheight=min(height,sheight-y);
\r
120 RECT rect={cx,cy,cwidth,cheight};
\r
122 if (d3dsurface->LockRect(&lockrect,&rect,D3DLOCK_DISCARD)!=D3D_OK) {
\r
126 unsigned int column;
\r
127 for (line=0;line<cheight;line++) {
\r
128 unsigned int*row=((unsigned int*)(((char*)lockrect.pBits)+lockrect.Pitch*line));
\r
129 for (column=0;column<cwidth;column++) {
\r
134 if (d3dsurface->UnlockRect()!=D3D_OK) {
\r
135 osd->EndPainting();
\r
138 osd->EndPainting();
\r
145 void SurfaceWin::startFastDraw(){
\r
146 WaitForSingleObject(event,INFINITE); //since this might be called before surface
\r
147 //allocation we will wait in this case, hopefully without deadlocks
\r
149 return; //why does this happen
\r
151 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
\r
152 LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();
\r
153 if (screen==this) {
\r
154 //This should not happen!
\r
158 osd->BeginPainting();
\r
159 // D3DLOCKED_RECT lockrect;
\r
160 RECT rect={0,0,swidth,sheight};
\r
161 if (d3dsurface->LockRect(&lockrect,&rect,D3DLOCK_DISCARD)!=D3D_OK) {
\r
162 osd->EndPainting();
\r
168 void SurfaceWin::endFastDraw(){
\r
169 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
\r
170 if (d3dsurface->UnlockRect()!=D3D_OK) {
\r
171 osd->EndPainting();
\r
174 osd->EndPainting();
\r
178 void SurfaceWin::drawPixel(int x, int y, Colour & colour, bool fastdraw) {
\r
179 int c = ( (0xFF000000 )
\r
180 | (colour.red << 16)
\r
181 | (colour.green << 8)
\r
182 | (colour.blue ) );
\r
184 drawPixel(x, y, c, fastdraw);
\r
187 void SurfaceWin::drawPixel(int x, int y, unsigned int c, bool fastdraw)
\r
189 //FixMe: locking for every single Pixel will be painfully slow
\r
192 WaitForSingleObject(event,INFINITE); //since this might be called before surface
\r
193 //allocation we will wait in this case, hopefully without deadlocks
\r
195 return; //why does this happen
\r
197 osd=((OsdWin*)(Osd::getInstance()));
\r
199 if (x>=swidth || y>=sheight) return; //do not draw outside the surface
\r
200 if (screen==this) {
\r
201 //This should not happen!
\r
206 osd->BeginPainting();
\r
207 // D3DLOCKED_RECT lockrect;
\r
208 RECT rect={x,y,x+1,y+1};
\r
209 if (d3dsurface->LockRect(&lockrect,&rect,D3DLOCK_DISCARD)!=D3D_OK) {
\r
210 osd->EndPainting();
\r
213 unsigned int*row=(unsigned int*)(((char*)lockrect.pBits));
\r
215 if (d3dsurface->UnlockRect()!=D3D_OK) {
\r
216 osd->EndPainting();
\r
219 osd->EndPainting();
\r
221 unsigned int*row=(unsigned int*)(((char*)lockrect.pBits+lockrect.Pitch*y+4*x));
\r
229 void SurfaceWin::drawHorzLine(int x1, int x2, int y,const DrawStyle& c)
\r
231 fillblt(x1, y, x2-x1, 1, c);
\r
234 void SurfaceWin::drawVertLine(int x, int y1, int y2, const DrawStyle& c)
\r
236 fillblt(x, y1, 1, y2-y1, c);
\r
239 void SurfaceWin::drawBitmap(int x, int y, const Bitmap& bm)
\r
241 // Temporary code? Draw one pixel at a time using drawPixel()
\r
243 for (UINT j = 0; j < bm.getHeight(); ++j)
\r
244 for (UINT i = 0; i < bm.getWidth(); ++i)
\r
245 drawPixel(x+i, y+j, bm.getColour(i,j),true);
\r
249 int SurfaceWin::updateToScreen(int sx, int sy, int w, int h, int dx, int dy) // FIXME new, replace others with this FIXME
\r
251 WaitForSingleObject(event,INFINITE); //since this might be called before surface
\r
252 //allocation we will wait in this case, hopefully without deadlocks
\r
254 return 0; //why does this happen
\r
256 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
\r
257 LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();
\r
258 LPDIRECT3DSURFACE9 screensurface=((SurfaceWin*)screen)->getD3dsurface();
\r
259 if (!screensurface) return 0;
\r
260 RECT sourcerect={sx,sy,sx+w,sy+h};
\r
261 POINT destpoint={dx,dy};
\r
262 osd->BeginPainting();
\r
263 if (d3ddev->UpdateSurface(d3dsurface,&sourcerect,screensurface,&destpoint)!=D3D_OK) {
\r
264 Log::getInstance()->log("Surface", Log::DEBUG, "Could not update to Screen!");
\r
265 osd->EndPainting();
\r
268 osd->EndPainting();
\r
272 int SurfaceWin::blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy)
\r
274 //I don't see code using this function, so I skip it, since it is a MVP specific interface
\r
278 void SurfaceWin::screenShot(const char* fileName)
\r
280 //Isn't this for debugging only, so I won't implement it yet
\r
283 void SurfaceWin::readPixel(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b)
\r
285 //Isn't this for debugging only, so I won't implement it yet
\r
287 void SurfaceWin::ReleaseSurface()
\r
290 LPDIRECT3DSURFACE9 temp_surf=d3dsurface;
\r
291 LPDIRECT3DTEXTURE9 temp_text=d3dtexture;
\r
295 if (temp_surf) temp_surf->Release();
\r
296 if (temp_text) temp_text->Release();
\r
299 void SurfaceWin::drawJpeg(const char *fileName,int x, int y,int *width, int *height){
\r
300 WaitForSingleObject(event,INFINITE); //since this might be called before surface
\r
301 //allocation we will wait in this case, hopefully without deadlocks
\r
303 return ; //why does this happen
\r
305 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
\r
308 D3DXIMAGE_INFO image_inf;
\r
309 osd->BeginPainting();
\r
310 // D3DXGetImageInfoFromFile(fileName,&image_inf);
\r
311 D3DXGetImageInfoFromResource(NULL,fileName,&image_inf);
\r
312 RECT dest_rec={x,y,x+image_inf.Width,
\r
313 y+image_inf.Height};
\r
314 /* if (D3DXLoadSurfaceFromFile(
\r
322 &image_inf)!=D3D_OK) {
\r
323 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
\r
326 if (D3DXLoadSurfaceFromResource(
\r
335 &image_inf)!=D3D_OK) {
\r
336 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
\r
339 osd->EndPainting();
\r
340 *width=image_inf.Width;
\r
341 *height=image_inf.Height;
\r
346 void SurfaceWin::drawJpeg(char *buffer,ULONG buflength,DWORD x, DWORD y,DWORD *width, DWORD *height){
\r
347 WaitForSingleObject(event,INFINITE); //since this might be called before surface
\r
348 //allocation we will wait in this case, hopefully without deadlocks
\r
350 return ; //why does this happen
\r
352 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
\r
355 D3DXIMAGE_INFO image_inf;
\r
356 osd->BeginPainting();
\r
357 // D3DXGetImageInfoFromFile(fileName,&image_inf);
\r
358 D3DXGetImageInfoFromFileInMemory((void*)buffer,buflength,&image_inf);
\r
359 RECT dest_rec={x,y,x+image_inf.Width,
\r
360 y+image_inf.Height};
\r
361 /* if (D3DXLoadSurfaceFromFile(
\r
369 &image_inf)!=D3D_OK) {
\r
370 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
\r
373 /* if (D3DXLoadSurfaceFromResource(
\r
382 &image_inf)!=D3D_OK) {
\r
383 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
\r
386 if (D3DXLoadSurfaceFromFileInMemory(
\r
395 &image_inf)!=D3D_OK) {
\r
396 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
\r
399 osd->EndPainting();
\r
400 *width=image_inf.Width;
\r
401 *height=image_inf.Height;
\r