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