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