]> git.vomp.tv Git - vompclient.git/blob - surfacewin.cc
Windows port, JPEGs
[vompclient.git] / surfacewin.cc
1 /*\r
2     Copyright 2004-2005 Chris Tallon\r
3     Portions copyright 2004 Jon Gettler\r
4 \r
5     This file is part of VOMP.\r
6 \r
7     VOMP is free software; you can redistribute it and/or modify\r
8     it under the terms of the GNU General Public License as published by\r
9     the Free Software Foundation; either version 2 of the License, or\r
10     (at your option) any later version.\r
11 \r
12     VOMP is distributed in the hope that it will be useful,\r
13     but WITHOUT ANY WARRANTY; without even the implied warranty of\r
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
15     GNU General Public License for more details.\r
16 \r
17     You should have received a copy of the GNU General Public License\r
18     along with VOMP; if not, write to the Free Software\r
19     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
20 */\r
21 \r
22 #include "surfacewin.h"\r
23 #include "osdwin.h"\r
24 #include <d3dx9tex.h>\r
25 \r
26 SurfaceWin::SurfaceWin(int id)\r
27 : Surface(id)\r
28 {\r
29         d3dtexture=NULL;\r
30         d3dsurface=NULL;\r
31         sheight=swidth=0;\r
32         event = CreateEvent(NULL,/*FALSE*/TRUE,FALSE,NULL);\r
33 }\r
34 \r
35 SurfaceWin::~SurfaceWin()\r
36 {\r
37         if (d3dsurface) d3dsurface->Release();\r
38         if (d3dtexture) d3dtexture->Release();\r
39         CloseHandle(event);\r
40 }\r
41 \r
42 int SurfaceWin::create(UINT width, UINT height)\r
43 {\r
44         LPDIRECT3DDEVICE9 d3ddev=((OsdWin*)(Osd::getInstance()))->getD3dDev();\r
45         while (true) {\r
46                 if (screen==this) {\r
47                         if (d3ddev->CreateTexture(1024,1024,0,0,D3DFMT_A8R8G8B8,\r
48                                 // Does every adapter with alpha blending support this?\r
49                                 D3DPOOL_DEFAULT,&d3dtexture ,NULL)!=D3D_OK) {\r
50                                         MILLISLEEP(50);//wait maybe next time it will work\r
51                                         continue;\r
52                         }\r
53                         if (d3dtexture->GetSurfaceLevel(0,&d3dsurface)!=D3D_OK) {\r
54                                 d3dtexture->Release();\r
55                                 d3dtexture=NULL;\r
56                                 MILLISLEEP(50);\r
57                                 continue;\r
58                         }\r
59                 } else {\r
60                         HRESULT hres;\r
61                         if (hres=d3ddev->CreateOffscreenPlainSurface(width,height,D3DFMT_A8R8G8B8,\r
62                                 D3DPOOL_SYSTEMMEM,&d3dsurface,NULL)!=D3D_OK) {\r
63                                         MILLISLEEP(50);//wait maybe next time it will work\r
64                                         continue;\r
65                         }\r
66 \r
67                 }\r
68                 sheight=height;\r
69                 swidth=width;\r
70                 /* If someone does high performance Animations on the OSD, we have to change the types\r
71            of surface in order to address these performance issues, if we have only very few updates \r
72            per second this would be fast enough !*/\r
73                 break;\r
74         }\r
75         SetEvent(event);\r
76         return 1;\r
77 }\r
78 \r
79 void SurfaceWin::display()\r
80 {\r
81 }\r
82 \r
83 int SurfaceWin::fillblt(int x, int y, int width, int height, unsigned int c)\r
84 {\r
85   WaitForSingleObject(event,INFINITE); //since this might be called before surface\r
86   //allocation we will wait in this case, hopefully without deadlocks\r
87   OsdWin* osd=((OsdWin*)(Osd::getInstance()));\r
88  \r
89   if (!d3dsurface) {\r
90                 return 0; //why does this happen\r
91   }\r
92 \r
93   LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();\r
94   \r
95   if (screen==this) {\r
96           //This should not happen!\r
97           return 0;\r
98 \r
99   } else {\r
100           osd->BeginPainting();\r
101           D3DLOCKED_RECT lockrect;\r
102           int cx,cy,cwidth,cheight;\r
103           cx=min(max(x,0),swidth);\r
104           cy=min(max(y,0),sheight);\r
105           cwidth=min(width,swidth-x);\r
106           cheight=min(height,sheight-y);\r
107           RECT rect={cx,cy,cwidth,cheight};\r
108           \r
109           if (d3dsurface->LockRect(&lockrect,&rect,D3DLOCK_DISCARD)!=D3D_OK) {\r
110                   return 0;\r
111           }\r
112           unsigned int line;\r
113           unsigned int column;\r
114           for (line=0;line<cheight;line++) {\r
115                   unsigned int*row=((unsigned int*)(((char*)lockrect.pBits)+lockrect.Pitch*line));\r
116                   for (column=0;column<cwidth;column++) {\r
117                           row[column]=c;\r
118                   }\r
119           }\r
120 \r
121           if (d3dsurface->UnlockRect()!=D3D_OK) {\r
122                   osd->EndPainting();\r
123                   return 0;\r
124           }\r
125           osd->EndPainting();\r
126   }\r
127 \r
128   return 0;\r
129 }\r
130 \r
131 void SurfaceWin::drawPixel(int x, int y, unsigned int c)\r
132 {\r
133   //FixMe: locking for every single Pixel will be painfully slow\r
134   WaitForSingleObject(event,INFINITE); //since this might be called before surface\r
135   //allocation we will wait in this case, hopefully without deadlocks\r
136   if (!d3dsurface) {\r
137                 return; //why does this happen\r
138   }\r
139   OsdWin* osd=((OsdWin*)(Osd::getInstance()));\r
140   LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();\r
141   if (x>swidth || y>sheight) return; //do not draw outside the surface\r
142   if (screen==this) {\r
143           //This should not happen!\r
144           return ;\r
145 \r
146   } else {\r
147           osd->BeginPainting();\r
148           D3DLOCKED_RECT lockrect;\r
149           RECT rect={x,y,x+1,y+1};\r
150           if (d3dsurface->LockRect(&lockrect,&rect,D3DLOCK_DISCARD)!=D3D_OK) {\r
151                   osd->EndPainting();\r
152                   return ;\r
153           }\r
154           unsigned int*row=(unsigned int*)(((char*)lockrect.pBits));\r
155           row[0]=c;\r
156           if (d3dsurface->UnlockRect()!=D3D_OK) {\r
157                   osd->EndPainting();\r
158                   return ;\r
159           }\r
160           osd->EndPainting();\r
161   }\r
162 \r
163 }\r
164 \r
165 void SurfaceWin::drawHorzLine(int x1, int x2, int y, unsigned int c)\r
166 {\r
167          fillblt(x1, y, x2-x1, 1, c);\r
168 }\r
169 \r
170 void SurfaceWin::drawVertLine(int x, int y1, int y2, unsigned int c)\r
171 {\r
172         fillblt(x, y1, 1, y2-y1, c);\r
173 }\r
174 \r
175 int SurfaceWin::updateToScreen(int sx, int sy, int w, int h, int dx, int dy) // FIXME new, replace others with this FIXME\r
176 {\r
177         WaitForSingleObject(event,INFINITE); //since this might be called before surface\r
178   //allocation we will wait in this case, hopefully without deadlocks\r
179         if (!d3dsurface) {\r
180                 return 0; //why does this happen\r
181         }\r
182         OsdWin* osd=((OsdWin*)(Osd::getInstance()));\r
183         LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();\r
184     LPDIRECT3DSURFACE9 screensurface=((SurfaceWin*)screen)->getD3dsurface();\r
185         if (!screensurface) return 0;\r
186         RECT sourcerect={sx,sy,sx+w,sy+h};\r
187         POINT destpoint={dx,dy};\r
188         osd->BeginPainting();\r
189         if (d3ddev->UpdateSurface(d3dsurface,&sourcerect,screensurface,&destpoint)!=D3D_OK) {\r
190                 Log::getInstance()->log("Surface", Log::DEBUG, "Could not update to Screen!");\r
191                 osd->EndPainting();\r
192                 return 0;\r
193         }\r
194         osd->EndPainting();\r
195         return 0;\r
196 }\r
197 \r
198 int SurfaceWin::blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy)\r
199 {\r
200   //I don't see code using this function, so I skip it, since it is a MVP specific interface\r
201   return 0;\r
202 }\r
203 \r
204 void SurfaceWin::screenShot(char* fileName)\r
205 {\r
206         //Isn't this for debugging only, so I won't implement it yet\r
207 }\r
208 \r
209 void SurfaceWin::readPixel(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b)\r
210 {\r
211         //Isn't this for debugging only, so I won't implement it yet\r
212 }\r
213 void SurfaceWin::ReleaseSurface()\r
214 {\r
215         ResetEvent(event);\r
216         LPDIRECT3DSURFACE9 temp_surf=d3dsurface;\r
217         LPDIRECT3DTEXTURE9 temp_text=d3dtexture;\r
218         d3dsurface=NULL;\r
219         d3dtexture=NULL;\r
220         sheight=swidth=0;\r
221         if (temp_surf) temp_surf->Release();\r
222         if (temp_text) temp_text->Release();\r
223 }\r
224 \r
225 void SurfaceWin::drawJpeg(char *fileName,DWORD x, DWORD y,DWORD *width, DWORD *height){\r
226         WaitForSingleObject(event,INFINITE); //since this might be called before surface\r
227   //allocation we will wait in this case, hopefully without deadlocks\r
228         if (!d3dsurface) {\r
229                 return ; //why does this happen\r
230         }\r
231         OsdWin* osd=((OsdWin*)(Osd::getInstance()));\r
232 \r
233         \r
234         D3DXIMAGE_INFO image_inf;\r
235         osd->BeginPainting();\r
236 //      D3DXGetImageInfoFromFile(fileName,&image_inf);\r
237         D3DXGetImageInfoFromResource(NULL,fileName,&image_inf);\r
238         RECT dest_rec={x,y,x+image_inf.Width,\r
239                 y+image_inf.Height};\r
240 /*      if (D3DXLoadSurfaceFromFile(\r
241                 d3dsurface,\r
242                 NULL,\r
243                 &dest_rec,\r
244                 fileName,\r
245                 NULL,\r
246                 D3DX_FILTER_NONE,\r
247                 0,\r
248                 &image_inf)!=D3D_OK) {\r
249                         Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");\r
250                         \r
251         }*/\r
252         if (D3DXLoadSurfaceFromResource(\r
253                 d3dsurface,\r
254                 NULL,\r
255                 &dest_rec,\r
256                 NULL,\r
257                 fileName,\r
258                 NULL,\r
259                 D3DX_FILTER_NONE,\r
260                 0,\r
261                 &image_inf)!=D3D_OK) {\r
262                         Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");\r
263                         \r
264         }\r
265         osd->EndPainting();\r
266         *width=image_inf.Width;\r
267         *height=image_inf.Height;\r
268          \r
269 }\r
270 \r