]> git.vomp.tv Git - vompclient.git/blob - surfacewin.cc
End of line normalization
[vompclient.git] / surfacewin.cc
1 /*
2     Copyright 2006 Marten Richter
3
4     This file is part of VOMP.
5
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.
10
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.
15
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.
19 */
20
21 #include "surfacewin.h"
22 #include "osdwin.h"
23 #include "bitmap.h"
24 #include "log.h"
25
26 SurfaceWin::SurfaceWin(int id)
27 : Surface(id)
28 {
29   d3dtexture=NULL;
30   d3dsurface=NULL;
31   sheight=swidth=0;
32 //  fastdraw=false;
33   event = CreateEvent(NULL,/*FALSE*/TRUE,FALSE,NULL);
34 }
35
36 SurfaceWin::~SurfaceWin()
37 {
38         if (d3dsurface) d3dsurface->Release();
39         if (d3dtexture) d3dtexture->Release();
40         CloseHandle(event);
41 }
42
43 int SurfaceWin::create(UINT width, UINT height)
44 {
45         OsdWin* osd=((OsdWin*)(Osd::getInstance()));
46
47
48         LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();
49
50         while (true) {
51                 if (screen==this) {
52                         osd->BeginPainting();
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) {
56                                         osd->EndPainting();
57                                         MILLISLEEP(50);//wait maybe next time it will work
58                                         continue;
59                         }
60                         if (d3dtexture->GetSurfaceLevel(0,&d3dsurface)!=D3D_OK) {
61                                 d3dtexture->Release();
62                                 d3dtexture=NULL;
63                                 MILLISLEEP(50);
64                                 osd->EndPainting();
65                                 continue;
66                         }
67                 } else {
68                         HRESULT hres;
69                         if (hres=d3ddev->CreateOffscreenPlainSurface(width,height,D3DFMT_A8R8G8B8,
70                                 D3DPOOL_SYSTEMMEM,&d3dsurface,NULL)!=D3D_OK) {
71                                         osd->EndPainting();
72                                         MILLISLEEP(50);//wait maybe next time it will work
73
74                                         continue;
75                         }
76
77                 }
78                 osd->EndPainting();
79
80                 sheight=height;
81                 swidth=width;
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 !*/
85                 break;
86         }
87         SetEvent(event);
88         return 1;
89 }
90
91 void SurfaceWin::display()
92 {
93 }
94
95 int SurfaceWin::fillblt(int x, int y, int width, int height, const DrawStyle& c)
96 {
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()));
100
101   if (!d3dsurface) {
102     return 0; //why does this happen
103   }
104   ULONG col=c.rgba();
105
106   LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();
107
108   if (screen==this) {
109     //This should not happen!
110     return 0;
111
112   } else {
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};
121
122     if (d3dsurface->LockRect(&lockrect,&rect,D3DLOCK_DISCARD)!=D3D_OK) {
123       return 0;
124     }
125     unsigned int line;
126     unsigned int column;
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++) {
130         row[column]=col;
131       }
132     }
133
134     if (d3dsurface->UnlockRect()!=D3D_OK) {
135       osd->EndPainting();
136       return 0;
137     }
138     osd->EndPainting();
139   }
140
141   return 0;
142 }
143
144
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
148   if (!d3dsurface) {
149     return; //why does this happen
150   }
151   OsdWin* osd=((OsdWin*)(Osd::getInstance()));
152   LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();
153   if (screen==this) {
154     //This should not happen!
155     return ;
156
157   } else {
158     osd->BeginPainting();
159 //    D3DLOCKED_RECT lockrect;
160     RECT rect={0,0,swidth,sheight};
161     if (d3dsurface->LockRect(&lockrect,&rect,D3DLOCK_DISCARD)!=D3D_OK) {
162       osd->EndPainting();
163       return ;
164     }
165   }
166 //  fastdraw=true;
167 }
168 void SurfaceWin::endFastDraw(){
169     OsdWin* osd=((OsdWin*)(Osd::getInstance()));
170     if (d3dsurface->UnlockRect()!=D3D_OK) {
171       osd->EndPainting();
172       return ;
173     }
174     osd->EndPainting();
175 //    fastdraw=false;
176  }
177
178 void SurfaceWin::drawPixel(int x, int y, Colour & colour, bool fastdraw) {
179   int c = (  (0xFF000000         )
180              | (colour.red    << 16)
181              | (colour.green  <<  8)
182              | (colour.blue        ) );
183
184     drawPixel(x, y, c, fastdraw);
185   }
186
187 void SurfaceWin::drawPixel(int x, int y, unsigned int c, bool fastdraw)
188 {
189   //FixMe: locking for every single Pixel will be painfully slow
190     OsdWin* osd;
191     if (!fastdraw) {
192   WaitForSingleObject(event,INFINITE); //since this might be called before surface
193   //allocation we will wait in this case, hopefully without deadlocks
194   if (!d3dsurface) {
195     return; //why does this happen
196   }
197          osd=((OsdWin*)(Osd::getInstance()));
198     }
199   if (x>=swidth || y>=sheight) return; //do not draw outside the surface
200   if (screen==this) {
201     //This should not happen!
202     return ;
203
204   } else {
205       if (!fastdraw) {
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) {
210       osd->EndPainting();
211       return ;
212     }
213     unsigned int*row=(unsigned int*)(((char*)lockrect.pBits));
214     row[0]=c;
215     if (d3dsurface->UnlockRect()!=D3D_OK) {
216       osd->EndPainting();
217       return ;
218     }
219     osd->EndPainting();
220       } else {
221           unsigned int*row=(unsigned int*)(((char*)lockrect.pBits+lockrect.Pitch*y+4*x));
222           row[0]=c;
223       }
224
225   }
226
227 }
228
229 void SurfaceWin::drawHorzLine(int x1, int x2, int y,const DrawStyle& c)
230 {
231    fillblt(x1, y, x2-x1, 1, c);
232 }
233
234 void SurfaceWin::drawVertLine(int x, int y1, int y2, const DrawStyle& c)
235 {
236   fillblt(x, y1, 1, y2-y1, c);
237 }
238
239 void SurfaceWin::drawBitmap(int x, int y, const Bitmap& bm)
240 {
241   // Temporary code? Draw one pixel at a time using drawPixel()
242   startFastDraw();
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);
246   endFastDraw();
247 }
248
249 int SurfaceWin::updateToScreen(int sx, int sy, int w, int h, int dx, int dy) // FIXME new, replace others with this FIXME
250 {
251   WaitForSingleObject(event,INFINITE); //since this might be called before surface
252   //allocation we will wait in this case, hopefully without deadlocks
253   if (!d3dsurface) {
254     return 0; //why does this happen
255   }
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!");
265     osd->EndPainting();
266     return 0;
267   }
268   osd->EndPainting();
269   return 0;
270 }
271
272 int SurfaceWin::blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy)
273 {
274   //I don't see code using this function, so I skip it, since it is a MVP specific interface
275   return 0;
276 }
277
278 void SurfaceWin::screenShot(const char* fileName)
279 {
280   //Isn't this for debugging only, so I won't implement it yet
281 }
282
283 void SurfaceWin::readPixel(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b)
284 {
285   //Isn't this for debugging only, so I won't implement it yet
286 }
287 void SurfaceWin::ReleaseSurface()
288 {
289   ResetEvent(event);
290   LPDIRECT3DSURFACE9 temp_surf=d3dsurface;
291   LPDIRECT3DTEXTURE9 temp_text=d3dtexture;
292   d3dsurface=NULL;
293   d3dtexture=NULL;
294   sheight=swidth=0;
295   if (temp_surf) temp_surf->Release();
296   if (temp_text) temp_text->Release();
297 }
298
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
302   if (!d3dsurface) {
303     return ; //why does this happen
304   }
305   OsdWin* osd=((OsdWin*)(Osd::getInstance()));
306
307
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,
313     y+image_inf.Height};
314 /*  if (D3DXLoadSurfaceFromFile(
315     d3dsurface,
316     NULL,
317     &dest_rec,
318     fileName,
319     NULL,
320     D3DX_FILTER_NONE,
321     0,
322     &image_inf)!=D3D_OK) {
323       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
324
325   }*/
326   if (D3DXLoadSurfaceFromResource(
327     d3dsurface,
328     NULL,
329     &dest_rec,
330     NULL,
331     fileName,
332     NULL,
333     D3DX_FILTER_NONE,
334     0,
335     &image_inf)!=D3D_OK) {
336       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
337
338   }
339   osd->EndPainting();
340   *width=image_inf.Width;
341   *height=image_inf.Height;
342
343 }
344
345 /*
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
349   if (!d3dsurface) {
350     return ; //why does this happen
351   }
352   OsdWin* osd=((OsdWin*)(Osd::getInstance()));
353
354
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,
360     y+image_inf.Height};
361 /*  if (D3DXLoadSurfaceFromFile(
362     d3dsurface,
363     NULL,
364     &dest_rec,
365     fileName,
366     NULL,
367     D3DX_FILTER_NONE,
368     0,
369     &image_inf)!=D3D_OK) {
370       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
371
372   }*/
373 /*  if (D3DXLoadSurfaceFromResource(
374     d3dsurface,
375     NULL,
376     &dest_rec,
377     NULL,
378     fileName,
379     NULL,
380     D3DX_FILTER_NONE,
381     0,
382     &image_inf)!=D3D_OK) {
383       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
384
385   }*
386   if (D3DXLoadSurfaceFromFileInMemory(
387     d3dsurface,
388     NULL,
389     &dest_rec,
390     (void*)buffer,
391     buflength,
392     NULL,
393     D3DX_FILTER_NONE,
394     0,
395     &image_inf)!=D3D_OK) {
396       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
397
398   }
399   osd->EndPainting();
400   *width=image_inf.Width;
401   *height=image_inf.Height;
402
403 }*/
404