Mercurial > mplayer.hg
annotate libvo/vo_directx.c @ 11510:3638adcfdcbd
send quit command instead of key 'q'.
catch backspace key instead of ctrl key.
keycodes.h says CTRL and BS are the same.
this is not true for windows keycodes.
author | joey |
---|---|
date | Sun, 23 Nov 2003 16:59:57 +0000 |
parents | 3cf2c7f8d9a9 |
children | 85e503ddf65f |
rev | line source |
---|---|
7537 | 1 /****************************************************************************** |
2 * vo_directx.c: Directx v2 or later DirectDraw interface for MPlayer | |
3 * Copyright (c) 2002 Sascha Sommer <saschasommer@freenet.de>. | |
4 * | |
5 * This program is free software; you can redistribute it and/or modify | |
6 * it under the terms of the GNU General Public License as published by | |
7 * the Free Software Foundation; either version 2 of the License, or | |
8 * (at your option) any later version. | |
9 * | |
10 * This program is distributed in the hope that it will be useful, | |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 * GNU General Public License for more details. | |
14 * | |
15 * You should have received a copy of the GNU General Public License | |
16 * along with this program; if not, write to the Free Software | |
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. | |
18 * | |
19 *****************************************************************************/ | |
20 | |
21 #include <windows.h> | |
22 #include <windowsx.h> | |
23 #include <ddraw.h> | |
24 #include <stdlib.h> | |
25 #include <errno.h> | |
26 #include "config.h" | |
27 #include "video_out.h" | |
28 #include "video_out_internal.h" | |
29 #include "fastmemcpy.h" | |
30 #include "../input/input.h" | |
9380 | 31 #include "../osdep/keycodes.h" |
7537 | 32 #include "../mp_msg.h" |
8519 | 33 #include "aspect.h" |
10900 | 34 #include "geometry.h" |
7537 | 35 |
36 static LPDIRECTDRAW2 g_lpdd = NULL; //DirectDraw Object | |
37 static LPDIRECTDRAWSURFACE g_lpddsPrimary = NULL; //Primary Surface: viewport through the Desktop | |
38 static LPDIRECTDRAWSURFACE g_lpddsOverlay = NULL; //Overlay Surface | |
39 static LPDIRECTDRAWSURFACE g_lpddsBack = NULL; //Back surface | |
7624
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
40 static LPDIRECTDRAWCLIPPER g_lpddclipper; //clipper object, can only be used without overlay |
7537 | 41 static DDSURFACEDESC ddsdsf; //surface descripiton needed for locking |
7778
f804db78f704
10l - noticed by Soeren Mueller <soeren.mueller at webwasher.com>
faust3
parents:
7713
diff
changeset
|
42 static HINSTANCE hddraw_dll; //handle to ddraw.dll |
7537 | 43 static RECT rd; //rect of our stretched image |
44 static RECT rs; //rect of our source image | |
45 static HWND hWnd=NULL; //handle to the window | |
46 static uint32_t ontop=0; //always in foreground | |
47 static uint32_t image_width, image_height; //image width and height | |
48 static uint32_t d_image_width, d_image_height; //image width and height zoomed | |
49 static uint8_t *image=NULL; //image data | |
10640
01e0d93182f8
fix playback of rgb files when overlay is not disabled
faust3
parents:
9943
diff
changeset
|
50 static uint32_t image_format=0; //image format |
01e0d93182f8
fix playback of rgb files when overlay is not disabled
faust3
parents:
9943
diff
changeset
|
51 static uint32_t primary_image_format; |
7537 | 52 static uint32_t vm = 0; //exclusive mode, allows resolution switching (not implemented yet) |
53 static uint32_t dstride; //surface stride | |
7682 | 54 static uint32_t nooverlay = 0; //NonOverlay mode |
7624
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
55 static DWORD destcolorkey; //colorkey for our surface |
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
56 static COLORREF windowcolor = RGB(0,0,16); //windowcolor == colorkey |
7537 | 57 |
58 extern void mplayer_put_key(int code); //let mplayer handel the keyevents | |
8667 | 59 extern void vo_draw_text(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)); |
7537 | 60 extern int vo_doublebuffering; //tribblebuffering |
10900 | 61 extern int vo_fs; |
11061 | 62 extern int vo_directrendering; |
7537 | 63 |
64 /***************************************************************************** | |
65 * DirectDraw GUIDs. | |
66 * Defining them here allows us to get rid of the dxguid library during | |
67 * the linking stage. | |
68 *****************************************************************************/ | |
8667 | 69 static const GUID IID_IDirectDraw2 = |
70 { | |
71 0xB3A6F3E0,0x2B43,0x11CF,{0xA2,0xDE,0x00,0xAA,0x00,0xB9,0x33,0x56} | |
72 }; | |
7537 | 73 |
74 typedef struct directx_fourcc_caps | |
75 { | |
76 char* img_format_name; //human readable name | |
77 uint32_t img_format; //as MPlayer image format | |
78 uint32_t drv_caps; //what hw supports with this format | |
79 DDPIXELFORMAT g_ddpfOverlay; //as Directx Sourface description | |
80 } directx_fourcc_caps; | |
81 | |
82 | |
83 static directx_fourcc_caps g_ddpf[] = | |
84 { | |
85 {"YV12 ",IMGFMT_YV12 ,0,{sizeof(DDPIXELFORMAT), DDPF_FOURCC,MAKEFOURCC('Y','V','1','2'),0,0,0,0,0}}, | |
86 {"I420 ",IMGFMT_I420 ,0,{sizeof(DDPIXELFORMAT), DDPF_FOURCC,MAKEFOURCC('I','4','2','0'),0,0,0,0,0}}, //yv12 with swapped uv | |
87 {"IYUV ",IMGFMT_IYUV ,0,{sizeof(DDPIXELFORMAT), DDPF_FOURCC,MAKEFOURCC('I','Y','U','V'),0,0,0,0,0}}, //same as i420 | |
88 {"YVU9 ",IMGFMT_YVU9 ,0,{sizeof(DDPIXELFORMAT), DDPF_FOURCC,MAKEFOURCC('Y','V','U','9'),0,0,0,0,0}}, | |
89 {"YUY2 ",IMGFMT_YUY2 ,0,{sizeof(DDPIXELFORMAT), DDPF_FOURCC,MAKEFOURCC('Y','U','Y','2'),0,0,0,0,0}}, | |
90 // {"UYVY ",IMGFMT_UYVY ,0,{sizeof(DDPIXELFORMAT), DDPF_FOURCC,MAKEFOURCC('U','Y','V','Y'),0,0,0,0,0}}, | |
91 {"RGB15",IMGFMT_RGB15,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16, 0x0000001F, 0x000003E0, 0x00007C00, 0}}, //RGB 5:5:5 | |
92 {"BGR15",IMGFMT_BGR15,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16, 0x00007C00, 0x000003E0, 0x0000001F, 0}}, | |
10647 | 93 {"RGB16",IMGFMT_RGB16,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16, 0x0000001F, 0x000007E0, 0x0000F800, 0}}, //RGB 5:6:5 |
94 {"BGR16",IMGFMT_BGR16,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16, 0x0000F800, 0x000007E0, 0x0000001F, 0}}, | |
7537 | 95 {"RGB24",IMGFMT_RGB24,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 24, 0x000000FF, 0x0000FF00, 0x00FF0000, 0}}, |
96 {"BGR24",IMGFMT_BGR24,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 24, 0x00FF0000, 0x0000FF00, 0x000000FF, 0}}, | |
97 {"RGB32",IMGFMT_RGB32,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0}}, | |
98 {"BGR32",IMGFMT_BGR32,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0}} | |
99 }; | |
100 #define NUM_FORMATS (sizeof(g_ddpf) / sizeof(g_ddpf[0])) | |
101 | |
8148
5b39e79af5fe
removed get_info, using the same sheme as in libmpcodecs instead
alex
parents:
7778
diff
changeset
|
102 static vo_info_t info = |
7537 | 103 { |
104 "Directx DDraw YUV/RGB/BGR renderer", | |
105 "directx", | |
106 "Sascha Sommer <saschasommer@freenet.de>", | |
107 "" | |
108 }; | |
109 | |
8148
5b39e79af5fe
removed get_info, using the same sheme as in libmpcodecs instead
alex
parents:
7778
diff
changeset
|
110 LIBVO_EXTERN(directx) |
7537 | 111 |
112 static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src, | |
113 unsigned char *srca, int stride) | |
114 { | |
115 switch(image_format) { | |
116 case IMGFMT_YV12 : | |
117 case IMGFMT_I420 : | |
118 case IMGFMT_IYUV : | |
119 case IMGFMT_YVU9 : | |
8495 | 120 vo_draw_alpha_yv12(w,h,src,srca,stride,((uint8_t *) image) + dstride*y0 + x0,dstride); |
7537 | 121 break; |
122 case IMGFMT_YUY2 : | |
8495 | 123 vo_draw_alpha_yuy2(w,h,src,srca,stride,((uint8_t *) image)+ dstride*y0 + 2*x0 ,dstride); |
7537 | 124 break; |
125 case IMGFMT_UYVY : | |
8495 | 126 vo_draw_alpha_yuy2(w,h,src,srca,stride,((uint8_t *) image) + dstride*y0 + 2*x0 + 1,dstride); |
7537 | 127 break; |
128 case IMGFMT_RGB15: | |
129 case IMGFMT_BGR15: | |
130 vo_draw_alpha_rgb15(w,h,src,srca,stride,((uint8_t *) image)+dstride*y0+2*x0,dstride); | |
131 break; | |
132 case IMGFMT_RGB16: | |
133 case IMGFMT_BGR16: | |
134 vo_draw_alpha_rgb16(w,h,src,srca,stride,((uint8_t *) image)+dstride*y0+2*x0,dstride); | |
135 break; | |
136 case IMGFMT_RGB24: | |
137 case IMGFMT_BGR24: | |
138 vo_draw_alpha_rgb24(w,h,src,srca,stride,((uint8_t *) image)+dstride*y0+4*x0,dstride); | |
139 break; | |
140 case IMGFMT_RGB32: | |
141 case IMGFMT_BGR32: | |
142 vo_draw_alpha_rgb32(w,h,src,srca,stride,((uint8_t *) image)+dstride*y0+4*x0,dstride); | |
143 break; | |
144 } | |
145 } | |
146 | |
147 static void draw_osd(void) | |
148 { | |
149 vo_draw_text(image_width,image_height,draw_alpha); | |
150 } | |
151 | |
152 static uint32_t | |
153 query_format(uint32_t format) | |
154 { | |
155 uint32_t i=0; | |
156 while ( i < NUM_FORMATS ) | |
157 { | |
158 if (g_ddpf[i].img_format == format) | |
159 return g_ddpf[i].drv_caps; | |
160 i++; | |
161 } | |
162 return 0; | |
163 } | |
164 | |
165 static uint32_t Directx_CreatePrimarySurface() | |
166 { | |
167 DDSURFACEDESC ddsd; | |
168 //cleanup | |
169 if(g_lpddsPrimary)g_lpddsPrimary->lpVtbl->Release(g_lpddsPrimary); | |
170 g_lpddsPrimary=NULL; | |
171 ZeroMemory(&ddsd, sizeof(ddsd)); | |
172 ddsd.dwSize = sizeof(ddsd); | |
173 //set flags and create a primary surface. | |
174 ddsd.dwFlags = DDSD_CAPS; | |
175 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; | |
176 if(g_lpdd->lpVtbl->CreateSurface(g_lpdd,&ddsd, &g_lpddsPrimary, NULL )== DD_OK) | |
177 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>primary surface created\n"); | |
178 else | |
179 { | |
180 mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>could not create primary surface\n"); | |
181 return 1; | |
182 } | |
183 return 0; | |
184 } | |
185 | |
186 static uint32_t Directx_CreateOverlay(uint32_t imgfmt) | |
187 { | |
188 HRESULT ddrval; | |
189 DDSURFACEDESC ddsdOverlay; | |
190 uint32_t i=0; | |
191 while ( i < NUM_FORMATS +1 && imgfmt != g_ddpf[i].img_format) | |
192 { | |
193 i++; | |
194 } | |
195 if (!g_lpdd || !g_lpddsPrimary) | |
196 return 1; | |
197 //cleanup | |
198 if (g_lpddsOverlay)g_lpddsOverlay->lpVtbl->Release(g_lpddsOverlay); | |
199 if (g_lpddsBack)g_lpddsBack->lpVtbl->Release(g_lpddsBack); | |
200 g_lpddsOverlay= NULL; | |
201 g_lpddsBack = NULL; | |
202 //create our overlay | |
203 ZeroMemory(&ddsdOverlay, sizeof(ddsdOverlay)); | |
204 ddsdOverlay.dwSize = sizeof(ddsdOverlay); | |
205 ddsdOverlay.ddsCaps.dwCaps=DDSCAPS_OVERLAY | DDSCAPS_FLIP | DDSCAPS_COMPLEX | DDSCAPS_VIDEOMEMORY; | |
206 ddsdOverlay.dwFlags= DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT| DDSD_PIXELFORMAT; | |
207 ddsdOverlay.dwWidth=image_width; | |
208 ddsdOverlay.dwHeight=image_height; | |
209 ddsdOverlay.dwBackBufferCount=2; | |
210 ddsdOverlay.ddpfPixelFormat=g_ddpf[i].g_ddpfOverlay; | |
211 if(vo_doublebuffering) //tribblebuffering | |
212 { | |
213 if (g_lpdd->lpVtbl->CreateSurface(g_lpdd,&ddsdOverlay, &g_lpddsOverlay, NULL)== DD_OK) | |
214 { | |
215 mp_msg(MSGT_VO, MSGL_V,"<vo_directx><INFO>overlay with format %s created\n",g_ddpf[i].img_format_name); | |
216 //get the surface directly attached to the primary (the back buffer) | |
217 ddsdOverlay.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER; | |
218 if(g_lpddsOverlay->lpVtbl->GetAttachedSurface(g_lpddsOverlay,&ddsdOverlay.ddsCaps, &g_lpddsBack) != DD_OK) | |
219 { | |
220 mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't get attached surface\n"); | |
221 return 1; | |
222 } | |
223 return 0; | |
224 } | |
225 vo_doublebuffering=0; //disable tribblebuffering | |
226 mp_msg(MSGT_VO, MSGL_V,"<vo_directx><WARN>cannot create tribblebuffer overlay with format %s\n",g_ddpf[i].img_format_name); | |
227 } | |
228 //single buffer | |
229 mp_msg(MSGT_VO, MSGL_V,"<vo_directx><INFO>using singlebuffer overlay\n"); | |
230 ddsdOverlay.dwBackBufferCount=0; | |
231 ddsdOverlay.ddsCaps.dwCaps=DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY; | |
232 ddsdOverlay.dwFlags= DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT; | |
233 ddsdOverlay.ddpfPixelFormat=g_ddpf[i].g_ddpfOverlay; | |
234 // try to create the overlay surface | |
235 ddrval = g_lpdd->lpVtbl->CreateSurface(g_lpdd,&ddsdOverlay, &g_lpddsOverlay, NULL); | |
236 if(ddrval != DD_OK) | |
237 { | |
10640
01e0d93182f8
fix playback of rgb files when overlay is not disabled
faust3
parents:
9943
diff
changeset
|
238 if(ddrval == DDERR_INVALIDPIXELFORMAT)mp_msg(MSGT_VO,MSGL_V,"<vo_directx><ERROR> invalid pixelformat: %s\n",g_ddpf[i].img_format_name); |
01e0d93182f8
fix playback of rgb files when overlay is not disabled
faust3
parents:
9943
diff
changeset
|
239 else mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>"); |
01e0d93182f8
fix playback of rgb files when overlay is not disabled
faust3
parents:
9943
diff
changeset
|
240 switch(ddrval) |
7537 | 241 { |
242 case DDERR_INCOMPATIBLEPRIMARY: | |
243 {mp_msg(MSGT_VO, MSGL_ERR,"incompatible primary surface\n");break;} | |
244 case DDERR_INVALIDCAPS: | |
245 {mp_msg(MSGT_VO, MSGL_ERR,"invalid caps\n");break;} | |
246 case DDERR_INVALIDOBJECT: | |
247 {mp_msg(MSGT_VO, MSGL_ERR,"invalid object\n");break;} | |
248 case DDERR_INVALIDPARAMS: | |
249 {mp_msg(MSGT_VO, MSGL_ERR,"invalid parameters\n");break;} | |
250 case DDERR_NODIRECTDRAWHW: | |
251 {mp_msg(MSGT_VO, MSGL_ERR,"no directdraw hardware\n");break;} | |
252 case DDERR_NOEMULATION: | |
11000 | 253 {mp_msg(MSGT_VO, MSGL_ERR,"can't emulate\n");break;} |
7537 | 254 case DDERR_NOFLIPHW: |
255 {mp_msg(MSGT_VO, MSGL_ERR,"hardware can't do flip\n");break;} | |
256 case DDERR_NOOVERLAYHW: | |
257 {mp_msg(MSGT_VO, MSGL_ERR,"hardware can't do overlay\n");break;} | |
258 case DDERR_OUTOFMEMORY: | |
259 {mp_msg(MSGT_VO, MSGL_ERR,"not enough system memory\n");break;} | |
260 case DDERR_UNSUPPORTEDMODE: | |
261 {mp_msg(MSGT_VO, MSGL_ERR,"unsupported mode\n");break;} | |
262 case DDERR_OUTOFVIDEOMEMORY: | |
263 {mp_msg(MSGT_VO, MSGL_ERR,"not enough video memory\n");break;} | |
264 } | |
265 return 1; | |
266 } | |
267 g_lpddsBack = g_lpddsOverlay; | |
268 return 0; | |
269 } | |
270 | |
271 static uint32_t Directx_CreateBackpuffer() | |
272 { | |
273 DDSURFACEDESC ddsd; | |
274 //cleanup | |
275 if (g_lpddsBack)g_lpddsBack->lpVtbl->Release(g_lpddsBack); | |
276 g_lpddsBack=NULL; | |
277 ZeroMemory(&ddsd, sizeof(ddsd)); | |
278 ddsd.dwSize = sizeof(ddsd); | |
279 ddsd.ddsCaps.dwCaps= DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; | |
280 ddsd.dwFlags= DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; | |
281 ddsd.dwWidth=image_width; | |
282 ddsd.dwHeight=image_height; | |
283 if(g_lpdd->lpVtbl->CreateSurface( g_lpdd, &ddsd, &g_lpddsBack, 0 ) != DD_OK ) | |
284 { | |
285 mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't create backpuffer\n"); | |
286 return 1; | |
287 } | |
288 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>backbuffer created\n"); | |
289 return 0; | |
290 } | |
291 | |
292 static void uninit(void) | |
293 { | |
294 if (g_lpddclipper != NULL) g_lpddclipper->lpVtbl->Release(g_lpddclipper); | |
9619 | 295 g_lpddclipper = NULL; |
7537 | 296 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>clipper released\n"); |
297 if (g_lpddsBack != NULL) g_lpddsBack->lpVtbl->Release(g_lpddsBack); | |
298 g_lpddsBack = NULL; | |
299 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>back surface released\n"); | |
10640
01e0d93182f8
fix playback of rgb files when overlay is not disabled
faust3
parents:
9943
diff
changeset
|
300 if(vo_doublebuffering && !nooverlay) |
7537 | 301 { |
302 if (g_lpddsOverlay != NULL)g_lpddsOverlay->lpVtbl->Release(g_lpddsOverlay); | |
303 g_lpddsOverlay = NULL; | |
304 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>overlay surface released\n"); | |
305 } | |
306 if (g_lpddsPrimary != NULL) g_lpddsPrimary->lpVtbl->Release(g_lpddsPrimary); | |
7682 | 307 g_lpddsPrimary = NULL; |
308 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>primary released\n"); | |
7624
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
309 if(hWnd != NULL)DestroyWindow(hWnd); |
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
310 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>window destroyed\n"); |
7537 | 311 if (g_lpdd != NULL) g_lpdd->lpVtbl->Release(g_lpdd); |
312 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>directdrawobject released\n"); | |
7778
f804db78f704
10l - noticed by Soeren Mueller <soeren.mueller at webwasher.com>
faust3
parents:
7713
diff
changeset
|
313 FreeLibrary( hddraw_dll); |
f804db78f704
10l - noticed by Soeren Mueller <soeren.mueller at webwasher.com>
faust3
parents:
7713
diff
changeset
|
314 hddraw_dll= NULL; |
f804db78f704
10l - noticed by Soeren Mueller <soeren.mueller at webwasher.com>
faust3
parents:
7713
diff
changeset
|
315 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>ddraw.dll freed\n"); |
7537 | 316 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>uninited\n"); |
317 } | |
318 | |
319 static uint32_t Directx_InitDirectDraw() | |
320 { | |
321 HRESULT (WINAPI *OurDirectDrawCreate)(GUID *,LPDIRECTDRAW *,IUnknown *); | |
322 LPDIRECTDRAW lpDDraw; | |
323 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>Initing DirectDraw\n" ); | |
324 | |
325 //load direct draw DLL: based on videolans code | |
326 hddraw_dll = LoadLibrary("DDRAW.DLL"); | |
327 if( hddraw_dll == NULL ) | |
328 { | |
329 mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>failed loading ddraw.dll\n" ); | |
330 return 1; | |
331 } | |
332 OurDirectDrawCreate = (void *)GetProcAddress(hddraw_dll, "DirectDrawCreate"); | |
333 if ( OurDirectDrawCreate == NULL ) | |
334 { | |
335 FreeLibrary( hddraw_dll ); | |
336 hddraw_dll = NULL; | |
337 mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>failed geting proc address\n"); | |
338 return 1; | |
339 } | |
340 // initialize DirectDraw and create directx v1 object | |
341 if (OurDirectDrawCreate( NULL, &lpDDraw, NULL ) != DD_OK ) | |
342 { | |
343 lpDDraw = NULL; | |
344 FreeLibrary( hddraw_dll ); | |
345 hddraw_dll = NULL; | |
346 mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't initialize ddraw\n"); | |
347 return 1; | |
348 } | |
349 // ask IDirectDraw for IDirectDraw2 | |
350 if (lpDDraw->lpVtbl->QueryInterface(lpDDraw, &IID_IDirectDraw2, (void **)&g_lpdd) != DD_OK) | |
351 { | |
352 mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>no directx 2 installed\n"); | |
353 return 1; | |
354 } | |
355 //release our old interface and free ddraw.dll | |
356 lpDDraw->lpVtbl->Release(lpDDraw); | |
7778
f804db78f704
10l - noticed by Soeren Mueller <soeren.mueller at webwasher.com>
faust3
parents:
7713
diff
changeset
|
357 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>lpDDraw released\n" ); |
7537 | 358 //set cooperativelevel: for our tests, no handle to a window is needed |
359 if (g_lpdd->lpVtbl->SetCooperativeLevel(g_lpdd, NULL, DDSCL_NORMAL) != DD_OK) | |
360 { | |
361 mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>could not set cooperativelevel for hardwarecheck\n"); | |
362 return 1; | |
363 } | |
364 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>DirectDraw Inited\n"); | |
365 return 0; | |
366 } | |
367 | |
368 static void check_events(void) | |
369 { | |
370 MSG msg; | |
371 while (PeekMessage(&msg, NULL, 0, 0,PM_REMOVE)) | |
372 { | |
373 TranslateMessage(&msg); | |
374 DispatchMessage(&msg); | |
375 } | |
376 } | |
377 | |
8667 | 378 static uint32_t Directx_ManageDisplay(uint32_t width,uint32_t height) |
7537 | 379 { |
8667 | 380 RECT rd_window; |
7537 | 381 HRESULT ddrval; |
382 DDCAPS capsDrv; | |
383 DDOVERLAYFX ovfx; | |
8667 | 384 DWORD dwUpdateFlags=0; |
7537 | 385 HWND hWndafter; |
386 uint32_t xscreen = GetSystemMetrics(SM_CXSCREEN); | |
387 uint32_t yscreen = GetSystemMetrics(SM_CYSCREEN); | |
8667 | 388 POINT point_window; |
10900 | 389 if(vo_fs) |
8667 | 390 { |
391 /*center and zoom image*/ | |
392 rd_window.top = 0; | |
393 rd_window.left = 0; | |
394 rd_window.right = xscreen; | |
395 rd_window.bottom = yscreen; | |
396 aspect(&width,&height,A_ZOOM); | |
397 rd.left = (xscreen-width)/2; | |
398 rd.right = rd.left+width; | |
399 rd.top = (yscreen-height)/2; | |
400 rd.bottom = rd.top + height; | |
401 } | |
402 else /*windowed*/ | |
7537 | 403 { |
404 GetClientRect (hWnd, &rd_window); | |
8667 | 405 if((rd_window.top == rd_window.bottom)&&!nooverlay) |
7537 | 406 { |
8667 | 407 /*window is minimized let's hide our overlay*/ |
7537 | 408 ddrval = g_lpddsOverlay->lpVtbl->UpdateOverlay(g_lpddsOverlay,NULL, g_lpddsPrimary, NULL, DDOVER_HIDE, NULL); //hide the overlay |
409 return 0; | |
410 } | |
8667 | 411 /*width and height are zero therefore we have to get them from the window size*/ |
412 if(!width)width = rd_window.right - rd_window.left; | |
413 if(!height)height = rd_window.bottom - rd_window.top; | |
414 point_window.x = 0; //overlayposition relative to the window | |
7537 | 415 point_window.y = 0; |
416 ClientToScreen(hWnd,&point_window); | |
8667 | 417 rd.left = point_window.x; |
7537 | 418 rd.top = point_window.y; |
8667 | 419 rd.bottom = rd.top + height; |
420 rd.right = rd.left + width; | |
421 rd_window = rd; | |
422 } | |
423 | |
424 /*ok, let's workaround some overlay limitations*/ | |
425 if(!nooverlay) | |
426 { | |
427 uint32_t uStretchFactor1000; //minimum stretch | |
428 uint32_t xstretch1000,ystretch1000; | |
429 /*get driver capabilities*/ | |
430 ZeroMemory(&capsDrv, sizeof(capsDrv)); | |
431 capsDrv.dwSize = sizeof(capsDrv); | |
432 if(g_lpdd->lpVtbl->GetCaps(g_lpdd,&capsDrv, NULL) != DD_OK)return 1; | |
433 /*do not allow to zoom or shrink if hardware isn't able to do so*/ | |
434 if((width < image_width)&& !(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSHRINKX)) | |
435 { | |
436 if(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSHRINKXN)mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can only shrinkN\n"); | |
437 else mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can't shrink x\n"); | |
438 width=image_width; | |
439 } | |
440 else if((width > image_width)&& !(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSTRETCHX)) | |
441 { | |
442 if(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSTRETCHXN)mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can only stretchN\n"); | |
443 else mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can't stretch x\n"); | |
444 width = image_width; | |
445 } | |
446 if((height < image_height) && !(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSHRINKY)) | |
447 { | |
448 if(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSHRINKYN)mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can only shrinkN\n"); | |
449 else mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can't shrink y\n"); | |
450 height = image_height; | |
451 } | |
452 else if((height > image_height ) && !(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSTRETCHY)) | |
453 { | |
454 if(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSTRETCHYN)mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can only stretchN\n"); | |
455 else mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can't stretch y\n"); | |
456 height = image_height; | |
457 } | |
458 /*get minimum stretch, depends on display adaptor and mode (refresh rate!) */ | |
459 uStretchFactor1000 = capsDrv.dwMinOverlayStretch>1000 ? capsDrv.dwMinOverlayStretch : 1000; | |
460 rd.right = ((width+rd.left)*uStretchFactor1000+999)/1000; | |
461 rd.bottom = (height+rd.top)*uStretchFactor1000/1000; | |
462 /*calculate xstretch1000 and ystretch1000*/ | |
7537 | 463 xstretch1000 = ((rd.right - rd.left)* 1000)/image_width ; |
464 ystretch1000 = ((rd.bottom - rd.top)* 1000)/image_height; | |
8667 | 465 /*handle move outside of window with cropping |
466 not really needed with colorkey, but shouldn't hurt*/ | |
467 rs.left=0; | |
468 rs.right=image_width; | |
469 rs.top=0; | |
470 rs.bottom=image_height; | |
10900 | 471 if(!vo_fs)rd_window = rd; /*don't crop the window !!!*/ |
7537 | 472 if(rd.left < 0) //move out left |
473 { | |
474 rs.left=(-rd.left*1000)/xstretch1000; | |
475 rd.left = 0; | |
476 } | |
477 else rs.left=0; | |
478 if(rd.top < 0) //move out up | |
479 { | |
480 rs.top=(-rd.top*1000)/ystretch1000; | |
481 rd.top = 0; | |
482 } | |
483 else rs.top = 0; | |
484 if(rd.right > xscreen) //move out right | |
485 { | |
486 rs.right=((xscreen-rd.left)*1000)/xstretch1000; | |
487 rd.right= xscreen; | |
488 } | |
489 else rs.right = image_width; | |
490 if(rd.bottom > yscreen) //move out down | |
491 { | |
492 rs.bottom=((yscreen-rd.top)*1000)/ystretch1000; | |
493 rd.bottom= yscreen; | |
494 } | |
495 else rs.bottom= image_height; | |
8667 | 496 /*the last thing to check are alignment restrictions |
497 these expressions (x & -y) just do alignment by dropping low order bits... | |
498 so to round up, we add first, then truncate*/ | |
499 if ((capsDrv.dwCaps & DDCAPS_ALIGNBOUNDARYSRC) && capsDrv.dwAlignBoundarySrc) | |
500 rs.left = (rs.left + capsDrv.dwAlignBoundarySrc / 2) & -(signed)(capsDrv.dwAlignBoundarySrc); | |
501 if ((capsDrv.dwCaps & DDCAPS_ALIGNSIZESRC) && capsDrv.dwAlignSizeSrc) | |
502 rs.right = rs.left + ((rs.right - rs.left + capsDrv.dwAlignSizeSrc / 2) & -(signed) (capsDrv.dwAlignSizeSrc)); | |
503 if ((capsDrv.dwCaps & DDCAPS_ALIGNBOUNDARYDEST) && capsDrv.dwAlignBoundaryDest) | |
504 { | |
505 rd.left = (rd.left + capsDrv.dwAlignBoundaryDest / 2) & -(signed)(capsDrv.dwAlignBoundaryDest); | |
10900 | 506 if(!vo_fs)rd_window.left = (rd_window.left + capsDrv.dwAlignBoundaryDest / 2) & -(signed)(capsDrv.dwAlignBoundaryDest); //don't forget the window |
8667 | 507 } |
508 if ((capsDrv.dwCaps & DDCAPS_ALIGNSIZEDEST) && capsDrv.dwAlignSizeDest) | |
509 { | |
510 rd.right = rd.left + ((rd.right - rd.left) & -(signed) (capsDrv.dwAlignSizeDest)); | |
10900 | 511 if(!vo_fs)rd_window.right = rd_window.left + ((rd_window.right - rd_window.left) & -(signed) (capsDrv.dwAlignSizeDest)); //don't forget the window |
8667 | 512 } |
513 /*create an overlay FX structure to specify a destination color key*/ | |
514 ZeroMemory(&ovfx, sizeof(ovfx)); | |
515 ovfx.dwSize = sizeof(ovfx); | |
10900 | 516 if(vo_fs) |
8667 | 517 { |
518 ovfx.dckDestColorkey.dwColorSpaceLowValue = 0; | |
519 ovfx.dckDestColorkey.dwColorSpaceHighValue = 0; | |
520 } | |
521 else | |
522 { | |
523 ovfx.dckDestColorkey.dwColorSpaceLowValue = destcolorkey; | |
524 ovfx.dckDestColorkey.dwColorSpaceHighValue = destcolorkey; | |
525 } | |
526 // set the flags we'll send to UpdateOverlay //DDOVER_AUTOFLIP|DDOVERFX_MIRRORLEFTRIGHT|DDOVERFX_MIRRORUPDOWN could be usefull?; | |
527 dwUpdateFlags = DDOVER_SHOW | DDOVER_DDFX; | |
528 /*if hardware can't do colorkeying set the window on top*/ | |
529 if(capsDrv.dwCKeyCaps & DDCKEYCAPS_DESTOVERLAY) dwUpdateFlags |= DDOVER_KEYDESTOVERRIDE; | |
530 else ontop = 1; | |
7537 | 531 } |
8667 | 532 /*calculate window rect with borders*/ |
10900 | 533 if(!vo_fs)AdjustWindowRect(&rd_window,WS_OVERLAPPEDWINDOW|WS_SIZEBOX,0); |
8667 | 534 |
10900 | 535 if((vo_fs) || (!vo_fs && ontop))hWndafter=HWND_TOPMOST; |
8667 | 536 else hWndafter=HWND_NOTOPMOST; |
7624
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
537 |
8667 | 538 /*display the window*/ |
539 SetWindowPos(hWnd, | |
540 hWndafter, | |
541 rd_window.left, | |
542 rd_window.top, | |
543 rd_window.right - rd_window.left, | |
544 rd_window.bottom - rd_window.top, | |
545 SWP_SHOWWINDOW|SWP_NOOWNERZORDER); | |
7624
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
546 //printf("Window:x:%i,y:%i,w:%i,h:%i\n",rd_window.left,rd_window.top,rd_window.right - rd_window.left,rd_window.bottom - rd_window.top); |
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
547 //printf("Overlay:x1:%i,y1:%i,x2:%i,y2:%i,w:%i,h:%i\n",rd.left,rd.top,rd.right,rd.bottom,rd.right - rd.left,rd.bottom - rd.top); |
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
548 //printf("Source:x1:%i,x2:%i,y1:%i,y2:%i\n",rs.left,rs.right,rs.top,rs.bottom); |
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
549 //printf("Image:x:%i->%i,y:%i->%i\n",image_width,d_image_width,image_height,d_image_height); |
8667 | 550 |
551 | |
552 /*for nonoverlay mode we are finished, for overlay mode we have to display the overlay first*/ | |
553 if(nooverlay)return 0; | |
554 | |
7624
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
555 ddrval = g_lpddsOverlay->lpVtbl->UpdateOverlay(g_lpddsOverlay,&rs, g_lpddsPrimary, &rd, dwUpdateFlags, &ovfx); |
7537 | 556 if(FAILED(ddrval)) |
557 { | |
8667 | 558 // one cause might be the driver lied about minimum stretch |
7537 | 559 // we should try upping the destination size a bit, or |
560 // perhaps shrinking the source size | |
561 mp_msg(MSGT_VO, MSGL_ERR ,"<vo_directx><ERROR>UpdateOverlay failed\n" ); | |
562 mp_msg(MSGT_VO, MSGL_ERR ,"<vo_directx><ERROR>Overlay:x1:%i,y1:%i,x2:%i,y2:%i,w:%i,h:%i\n",rd.left,rd.top,rd.right,rd.bottom,rd.right - rd.left,rd.bottom - rd.top ); | |
563 mp_msg(MSGT_VO, MSGL_ERR ,"<vo_directx><ERROR>"); | |
564 switch (ddrval) | |
565 { | |
566 case DDERR_NOSTRETCHHW: | |
567 {mp_msg(MSGT_VO, MSGL_ERR ,"hardware can't stretch: try to size the window back\n");break;} | |
568 case DDERR_INVALIDRECT: | |
569 {mp_msg(MSGT_VO, MSGL_ERR ,"invalid rectangle\n");break;} | |
570 case DDERR_INVALIDPARAMS: | |
571 {mp_msg(MSGT_VO, MSGL_ERR ,"invalid parameters\n");break;} | |
572 case DDERR_HEIGHTALIGN: | |
573 {mp_msg(MSGT_VO, MSGL_ERR ,"height align\n");break;} | |
574 case DDERR_XALIGN: | |
575 {mp_msg(MSGT_VO, MSGL_ERR ,"x align\n");break;} | |
576 case DDERR_UNSUPPORTED: | |
577 {mp_msg(MSGT_VO, MSGL_ERR ,"unsupported\n");break;} | |
578 case DDERR_INVALIDSURFACETYPE: | |
579 {mp_msg(MSGT_VO, MSGL_ERR ,"invalid surfacetype\n");break;} | |
580 case DDERR_INVALIDOBJECT: | |
581 {mp_msg(MSGT_VO, MSGL_ERR ,"invalid object\n");break;} | |
582 case DDERR_SURFACELOST: | |
583 { | |
584 mp_msg(MSGT_VO, MSGL_ERR ,"surfaces lost\n"); | |
585 g_lpddsOverlay->lpVtbl->Restore( g_lpddsOverlay ); //restore and try again | |
586 g_lpddsPrimary->lpVtbl->Restore( g_lpddsPrimary ); | |
587 ddrval = g_lpddsOverlay->lpVtbl->UpdateOverlay(g_lpddsOverlay,&rs, g_lpddsPrimary, &rd, dwUpdateFlags, &ovfx); | |
588 if(ddrval !=DD_OK)mp_msg(MSGT_VO, MSGL_FATAL ,"<vo_directx><FATAL ERROR>UpdateOverlay failed again\n" ); | |
589 break; | |
590 } | |
591 } | |
8667 | 592 /*ok we can't do anything about it -> hide overlay*/ |
7537 | 593 if(ddrval != DD_OK) |
594 { | |
595 ddrval = g_lpddsOverlay->lpVtbl->UpdateOverlay(g_lpddsOverlay,NULL, g_lpddsPrimary, NULL, DDOVER_HIDE, NULL); | |
596 return 1; | |
597 } | |
598 } | |
599 return 0; | |
600 } | |
601 | |
602 //find out supported overlay pixelformats | |
603 static uint32_t Directx_CheckOverlayPixelformats() | |
604 { | |
605 DDCAPS capsDrv; | |
606 HRESULT ddrval; | |
607 DDSURFACEDESC ddsdOverlay; | |
608 uint32_t i; | |
609 uint32_t formatcount = 0; | |
610 //get driver caps to determine overlay support | |
611 ZeroMemory(&capsDrv, sizeof(capsDrv)); | |
612 capsDrv.dwSize = sizeof(capsDrv); | |
613 ddrval = g_lpdd->lpVtbl->GetCaps(g_lpdd,&capsDrv, NULL); | |
614 if (FAILED(ddrval)) | |
615 { | |
616 mp_msg(MSGT_VO, MSGL_ERR ,"<vo_directx><ERROR>failed getting ddrawcaps\n"); | |
617 return 1; | |
618 } | |
619 if (!(capsDrv.dwCaps & DDCAPS_OVERLAY)) | |
620 { | |
621 mp_msg(MSGT_VO, MSGL_ERR ,"<vo_directx><ERROR>Your card doesn't support overlay\n"); | |
622 return 1; | |
623 } | |
624 mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>testing supported overlay pixelformats\n"); | |
625 //it is not possible to query for pixel formats supported by the | |
626 //overlay hardware: try out various formats till one works | |
627 ZeroMemory(&ddsdOverlay, sizeof(ddsdOverlay)); | |
628 ddsdOverlay.dwSize = sizeof(ddsdOverlay); | |
629 ddsdOverlay.ddsCaps.dwCaps=DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY; | |
630 ddsdOverlay.dwFlags= DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH| DDSD_PIXELFORMAT; | |
631 ddsdOverlay.dwWidth=300; | |
632 ddsdOverlay.dwHeight=280; | |
633 ddsdOverlay.dwBackBufferCount=0; | |
634 //try to create an overlay surface using one of the pixel formats in our global list | |
635 i=0; | |
636 do | |
637 { | |
638 ddsdOverlay.ddpfPixelFormat=g_ddpf[i].g_ddpfOverlay; | |
639 ddrval = g_lpdd->lpVtbl->CreateSurface(g_lpdd,&ddsdOverlay, &g_lpddsOverlay, NULL); | |
640 if (ddrval == DD_OK) | |
641 { | |
642 mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><FORMAT OVERLAY>%i %s supported\n",i,g_ddpf[i].img_format_name); | |
643 g_ddpf[i].drv_caps = VFCAP_CSP_SUPPORTED |VFCAP_OSD |VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_HWSCALE_UP; | |
644 formatcount++;} | |
645 else mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><FORMAT OVERLAY>%i %s not supported\n",i,g_ddpf[i].img_format_name); | |
646 if (g_lpddsOverlay != NULL) {g_lpddsOverlay->lpVtbl->Release(g_lpddsOverlay);g_lpddsOverlay = NULL;} | |
647 } while( ++i < NUM_FORMATS ); | |
648 mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>Your card supports %i of %i overlayformats\n",formatcount, NUM_FORMATS); | |
649 if (formatcount == 0) | |
650 { | |
651 mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><WARN>Your card supports overlay, but we couldn't create one\n"); | |
652 mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>This can have the following reasons:\n"); | |
653 mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>- you are already using an overlay with another app\n"); | |
654 mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>- you don't have enough videomemory\n"); | |
655 mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>- vo_directx doesn't support the cards overlay pixelformat\n"); | |
656 return 1; | |
657 } | |
658 if(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYMIRRORLEFTRIGHT)mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>can mirror left right\n"); //I don't have hardware which | |
659 if(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYMIRRORUPDOWN )mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>can mirror up down\n"); //supports those send me one and I'll implement ;) | |
660 return 0; | |
661 } | |
662 | |
663 //find out the Pixelformat of the Primary Surface | |
664 static uint32_t Directx_CheckPrimaryPixelformat() | |
665 { | |
666 uint32_t i=0; | |
667 uint32_t formatcount = 0; | |
668 DDPIXELFORMAT ddpf; | |
7624
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
669 DDSURFACEDESC ddsd; |
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
670 HDC hdc; |
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
671 HRESULT hres; |
8667 | 672 COLORREF rgbT=RGB(0,0,0); |
7537 | 673 mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>checking primary surface\n"); |
674 memset( &ddpf, 0, sizeof( DDPIXELFORMAT )); | |
675 ddpf.dwSize = sizeof( DDPIXELFORMAT ); | |
676 //we have to create a primary surface first | |
677 if(Directx_CreatePrimarySurface()!=0)return 1; | |
678 if(g_lpddsPrimary->lpVtbl->GetPixelFormat( g_lpddsPrimary, &ddpf ) != DD_OK ) | |
679 { | |
680 mp_msg(MSGT_VO, MSGL_FATAL ,"<vo_directx><FATAL ERROR>can't get pixelformat\n"); | |
681 return 1; | |
682 } | |
683 while ( i < NUM_FORMATS ) | |
684 { | |
685 if (g_ddpf[i].g_ddpfOverlay.dwRGBBitCount == ddpf.dwRGBBitCount) | |
686 { | |
687 if (g_ddpf[i].g_ddpfOverlay.dwRBitMask == ddpf.dwRBitMask) | |
688 { | |
689 mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><FORMAT PRIMARY>%i %s supported\n",i,g_ddpf[i].img_format_name); | |
7713 | 690 g_ddpf[i].drv_caps = VFCAP_CSP_SUPPORTED |VFCAP_OSD; |
7537 | 691 formatcount++; |
10640
01e0d93182f8
fix playback of rgb files when overlay is not disabled
faust3
parents:
9943
diff
changeset
|
692 primary_image_format=g_ddpf[i].img_format; |
7537 | 693 } |
694 } | |
695 i++; | |
696 } | |
7624
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
697 //get the colorkey for overlay mode |
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
698 destcolorkey = CLR_INVALID; |
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
699 if (windowcolor != CLR_INVALID && g_lpddsPrimary->lpVtbl->GetDC(g_lpddsPrimary,&hdc) == DD_OK) |
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
700 { |
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
701 rgbT = GetPixel(hdc, 0, 0); |
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
702 SetPixel(hdc, 0, 0, windowcolor); |
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
703 g_lpddsPrimary->lpVtbl->ReleaseDC(g_lpddsPrimary,hdc); |
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
704 } |
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
705 // read back the converted color |
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
706 ddsd.dwSize = sizeof(ddsd); |
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
707 while ((hres = g_lpddsPrimary->lpVtbl->Lock(g_lpddsPrimary,NULL, &ddsd, 0, NULL)) == DDERR_WASSTILLDRAWING) |
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
708 ; |
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
709 if (hres == DD_OK) |
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
710 { |
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
711 destcolorkey = *(DWORD *) ddsd.lpSurface; |
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
712 if (ddsd.ddpfPixelFormat.dwRGBBitCount < 32) |
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
713 destcolorkey &= (1 << ddsd.ddpfPixelFormat.dwRGBBitCount) - 1; |
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
714 g_lpddsPrimary->lpVtbl->Unlock(g_lpddsPrimary,NULL); |
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
715 } |
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
716 if (windowcolor != CLR_INVALID && g_lpddsPrimary->lpVtbl->GetDC(g_lpddsPrimary,&hdc) == DD_OK) |
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
717 { |
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
718 SetPixel(hdc, 0, 0, rgbT); |
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
719 g_lpddsPrimary->lpVtbl->ReleaseDC(g_lpddsPrimary,hdc); |
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
720 } |
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
721 //release primary |
7537 | 722 g_lpddsPrimary->lpVtbl->Release(g_lpddsPrimary); |
723 g_lpddsPrimary = NULL; | |
724 if(formatcount==0) | |
725 { | |
726 mp_msg(MSGT_VO, MSGL_FATAL ,"<vo_directx><FATAL ERROR>Unknown Pixelformat\n"); | |
727 return 1; | |
728 } | |
729 return 0; | |
730 } | |
731 | |
732 //function handles input | |
733 static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) | |
734 { | |
735 switch (message) | |
736 { | |
737 case WM_DESTROY: | |
738 { | |
7624
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
739 PostQuitMessage(0); |
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
740 return 0; |
7537 | 741 } |
742 case WM_CLOSE: | |
743 { | |
11510 | 744 mp_input_queue_cmd(mp_input_parse_cmd("quit")); |
7537 | 745 return 0; |
746 } | |
747 case WM_WINDOWPOSCHANGED: | |
748 { | |
749 //printf("Windowposchange\n"); | |
7624
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
750 if(g_lpddsBack != NULL) //or it will crash with -vm |
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
751 { |
8667 | 752 Directx_ManageDisplay(0,0); |
7624
b1a3b979c630
This patch hopefully fixes colorkeying and a segfault in exclusive mode
arpi
parents:
7537
diff
changeset
|
753 } |
7537 | 754 break; |
755 } | |
756 case WM_SYSCOMMAND: | |
757 { | |
758 switch (wParam) | |
759 { //kill screensaver etc. | |
760 //note: works only when the window is active | |
761 //you can workaround this by disabling the allow screensaver option in | |
762 //the link to the app | |
763 case SC_SCREENSAVE: | |
764 case SC_MONITORPOWER: | |
765 mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>killing screensaver\n" ); | |
766 return 0; | |
767 } | |
768 } | |
769 case WM_KEYDOWN: | |
770 { | |
771 switch (wParam) | |
772 { | |
773 case VK_LEFT: | |
774 {mplayer_put_key(KEY_LEFT);break;} | |
775 case VK_UP: | |
776 {mplayer_put_key(KEY_UP);break;} | |
777 case VK_RIGHT: | |
778 {mplayer_put_key(KEY_RIGHT);break;} | |
779 case VK_DOWN: | |
780 {mplayer_put_key(KEY_DOWN);break;} | |
781 case VK_TAB: | |
782 {mplayer_put_key(KEY_TAB);break;} | |
11510 | 783 case VK_BACK: |
784 {mplayer_put_key(KEY_BS);break;} | |
7537 | 785 case VK_DELETE: |
786 {mplayer_put_key(KEY_DELETE);break;} | |
787 case VK_INSERT: | |
788 {mplayer_put_key(KEY_INSERT);break;} | |
789 case VK_HOME: | |
790 {mplayer_put_key(KEY_HOME);break;} | |
791 case VK_END: | |
9894
3933e0ef000c
10l noticed by Joey Parrish <joey at nicewarrior.org>
faust3
parents:
9728
diff
changeset
|
792 {mplayer_put_key(KEY_END);break;} |
7537 | 793 case VK_PRIOR: |
794 {mplayer_put_key(KEY_PAGE_UP);break;} | |
795 case VK_NEXT: | |
796 {mplayer_put_key(KEY_PAGE_DOWN);break;} | |
797 case VK_ESCAPE: | |
798 {mplayer_put_key(KEY_ESC);break;} | |
799 } | |
800 break; | |
801 } | |
802 case WM_CHAR: | |
803 { | |
804 mplayer_put_key(wParam); | |
805 break; | |
806 } | |
807 | |
808 } | |
809 return DefWindowProc(hWnd, message, wParam, lParam); | |
810 } | |
811 | |
8667 | 812 static uint32_t preinit(const char *arg) |
7537 | 813 { |
814 HINSTANCE hInstance = GetModuleHandle(NULL); | |
9943 | 815 HICON mplayericon=NULL; |
816 char exedir[MAX_PATH]; | |
7537 | 817 WNDCLASS wc; |
7682 | 818 if(arg) |
819 { | |
9488
abe81caa8cc1
fix fullscreenswitching patch by Joey Parrish <joey at nicewarrior.org>
faust3
parents:
9380
diff
changeset
|
820 if(strstr(arg,"noaccel")) |
7682 | 821 { |
822 mp_msg(MSGT_VO,MSGL_V,"<vo_directx><INFO>disabled overlay\n"); | |
823 nooverlay = 1; | |
824 } | |
9488
abe81caa8cc1
fix fullscreenswitching patch by Joey Parrish <joey at nicewarrior.org>
faust3
parents:
9380
diff
changeset
|
825 if(strstr(arg,"ontop")) |
7682 | 826 { |
9488
abe81caa8cc1
fix fullscreenswitching patch by Joey Parrish <joey at nicewarrior.org>
faust3
parents:
9380
diff
changeset
|
827 mp_msg(MSGT_VO,MSGL_V,"<vo_directx><INFO>window ontop\n"); |
abe81caa8cc1
fix fullscreenswitching patch by Joey Parrish <joey at nicewarrior.org>
faust3
parents:
9380
diff
changeset
|
828 ontop = 1; |
7682 | 829 } |
830 } | |
7537 | 831 if (Directx_InitDirectDraw()!= 0)return 1; //init DirectDraw |
832 if (Directx_CheckPrimaryPixelformat()!=0)return 1; | |
7682 | 833 if (!nooverlay && Directx_CheckOverlayPixelformats() == 0) //check for supported hardware |
7537 | 834 { |
835 mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>hardware supports overlay\n"); | |
836 nooverlay = 0; | |
837 } | |
838 else //if we can't have overlay we create a backpuffer with the same imageformat as the primary surface | |
839 { | |
840 mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>using backpuffer\n"); | |
841 nooverlay = 1; | |
842 } | |
9943 | 843 /*load icon from the main app*/ |
844 if(GetModuleFileName(NULL,exedir,MAX_PATH)) | |
845 { | |
846 mplayericon = ExtractIcon( hInstance, exedir, 0 ); | |
847 } | |
848 if(!mplayericon)mplayericon=LoadIcon(NULL,IDI_APPLICATION); | |
8667 | 849 wc.style = CS_HREDRAW | CS_VREDRAW; |
850 wc.lpfnWndProc = WndProc; | |
851 wc.cbClsExtra = 0; | |
852 wc.cbWndExtra = 0; | |
853 wc.hInstance = hInstance; | |
854 wc.hCursor = LoadCursor(NULL,IDC_ARROW); | |
9943 | 855 wc.hIcon = mplayericon; |
8667 | 856 wc.hbrBackground = CreateSolidBrush(windowcolor); |
857 wc.lpszClassName = "Mplayer - Movieplayer for Linux"; | |
858 wc.lpszMenuName = NULL; | |
859 RegisterClass(&wc); | |
860 hWnd = CreateWindow("MPlayer - Movieplayer for Linux", | |
861 "", | |
862 WS_OVERLAPPEDWINDOW| WS_SIZEBOX, | |
863 CW_USEDEFAULT, //position x | |
864 CW_USEDEFAULT, //position y | |
865 100, //width | |
866 100, //height | |
867 NULL, | |
868 NULL, | |
869 hInstance, | |
870 NULL); | |
871 mp_msg(MSGT_VO, MSGL_DBG3 ,"<vo_directx><INFO>initial mplayer window created\n"); | |
7537 | 872 mp_msg(MSGT_VO, MSGL_DBG3 ,"<vo_directx><INFO>preinit succesfully finished\n"); |
873 return 0; | |
874 } | |
875 | |
876 static uint32_t draw_slice(uint8_t *src[], int stride[], int w,int h,int x,int y ) | |
877 { | |
878 uint8_t *s; | |
879 uint8_t *d; | |
8490
ac40496c7d9e
1000l! I have no idea how this code worked at all before. I guess no
rfelker
parents:
8148
diff
changeset
|
880 uint32_t i=0, uvstride=dstride/2; |
7537 | 881 // copy Y |
882 d=image+dstride*y+x; | |
883 s=src[0]; | |
884 for(i=0;i<h;i++){ | |
885 memcpy(d,s,w); | |
886 s+=stride[0]; | |
8490
ac40496c7d9e
1000l! I have no idea how this code worked at all before. I guess no
rfelker
parents:
8148
diff
changeset
|
887 d+=dstride; |
7537 | 888 } |
889 | |
890 w/=2;h/=2;x/=2;y/=2; | |
891 | |
892 // copy U | |
8490
ac40496c7d9e
1000l! I have no idea how this code worked at all before. I guess no
rfelker
parents:
8148
diff
changeset
|
893 d=image+dstride*image_height + uvstride*y+x; |
8667 | 894 if(image_format == IMGFMT_YV12)s=src[2]; |
7537 | 895 else s=src[1]; |
896 for(i=0;i<h;i++){ | |
897 memcpy(d,s,w); | |
898 s+=stride[1]; | |
8490
ac40496c7d9e
1000l! I have no idea how this code worked at all before. I guess no
rfelker
parents:
8148
diff
changeset
|
899 d+=uvstride; |
7537 | 900 } |
901 | |
902 // copy V | |
8490
ac40496c7d9e
1000l! I have no idea how this code worked at all before. I guess no
rfelker
parents:
8148
diff
changeset
|
903 d=image+dstride*image_height +uvstride*(image_height/2) + uvstride*y+x; |
8667 | 904 if(image_format == IMGFMT_YV12)s=src[1]; |
7537 | 905 else s=src[2]; |
906 for(i=0;i<h;i++){ | |
907 memcpy(d,s,w); | |
908 s+=stride[2]; | |
8490
ac40496c7d9e
1000l! I have no idea how this code worked at all before. I guess no
rfelker
parents:
8148
diff
changeset
|
909 d+=uvstride; |
7537 | 910 } |
911 return 0; | |
912 } | |
913 | |
914 static void flip_page(void) | |
915 { | |
916 HRESULT dxresult; | |
8519 | 917 g_lpddsBack->lpVtbl->Unlock (g_lpddsBack,NULL); |
7537 | 918 if (vo_doublebuffering) |
919 { | |
920 // flip to the next image in the sequence | |
921 dxresult = g_lpddsOverlay->lpVtbl->Flip( g_lpddsOverlay,NULL, DDFLIP_WAIT); | |
922 if(dxresult == DDERR_SURFACELOST) | |
923 { | |
924 mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR><vo_directx><INFO>Restoring Surface\n"); | |
925 g_lpddsBack->lpVtbl->Restore( g_lpddsBack ); | |
926 dxresult = g_lpddsOverlay->lpVtbl->Flip( g_lpddsOverlay,NULL, DDFLIP_WAIT); | |
927 } | |
928 if(dxresult != DD_OK)mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can't flip page\n"); | |
929 } | |
8495 | 930 if(nooverlay) |
7537 | 931 { |
932 DDBLTFX ddbltfx; | |
933 // ask for the "NOTEARING" option | |
934 memset( &ddbltfx, 0, sizeof(DDBLTFX) ); | |
935 ddbltfx.dwSize = sizeof(DDBLTFX); | |
936 ddbltfx.dwDDFX = DDBLTFX_NOTEARING; | |
937 g_lpddsPrimary->lpVtbl->Blt(g_lpddsPrimary, &rd, g_lpddsBack, NULL, DDBLT_WAIT, &ddbltfx); | |
938 } | |
8495 | 939 g_lpddsBack->lpVtbl->Lock(g_lpddsBack,NULL,&ddsdsf, DDLOCK_NOSYSLOCK | DDLOCK_WAIT , NULL); |
11061 | 940 if(vo_directrendering && (dstride != ddsdsf.lPitch)){ |
941 mp_msg(MSGT_VO,MSGL_WARN,"<vo_directx><WARN>stride changed !!!! disabling direct rendering\n"); | |
942 vo_directrendering=0; | |
943 } | |
8495 | 944 dstride = ddsdsf.lPitch; |
945 image = ddsdsf.lpSurface; | |
7537 | 946 } |
947 | |
948 static uint32_t draw_frame(uint8_t *src[]) | |
949 { | |
950 memcpy( image, *src, dstride * image_height ); | |
951 return 0; | |
952 } | |
953 | |
954 static uint32_t get_image(mp_image_t *mpi) | |
955 { | |
956 if(mpi->flags&MP_IMGFLAG_READABLE) {mp_msg(MSGT_VO, MSGL_V,"<vo_directx><ERROR>slow video ram\n");return VO_FALSE;} | |
957 if(mpi->type==MP_IMGTYPE_STATIC) {mp_msg(MSGT_VO, MSGL_V,"<vo_directx><ERROR>not static\n");return VO_FALSE;} | |
958 if((mpi->width==dstride) || (mpi->flags&(MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_ACCEPT_WIDTH))) | |
959 { | |
8667 | 960 if(mpi->flags&MP_IMGFLAG_PLANAR) |
7537 | 961 { |
8667 | 962 if(image_format == IMGFMT_YV12) |
7537 | 963 { |
964 mpi->planes[2]= image + dstride*image_height; | |
965 mpi->planes[1]= image + dstride*image_height+ dstride*image_height/4; | |
8667 | 966 mpi->stride[1]=mpi->stride[2]=dstride/2; |
7537 | 967 } |
8667 | 968 else if(image_format == IMGFMT_IYUV || image_format == IMGFMT_I420) |
7537 | 969 { |
970 mpi->planes[1]= image + dstride*image_height; | |
971 mpi->planes[2]= image + dstride*image_height+ dstride*image_height/4; | |
8667 | 972 mpi->stride[1]=mpi->stride[2]=dstride/2; |
7537 | 973 } |
8667 | 974 else if(image_format == IMGFMT_YVU9) |
975 { | |
976 mpi->planes[2] = image + dstride*image_height; | |
977 mpi->planes[1] = image + dstride*image_height+ dstride*image_height/16; | |
978 mpi->stride[1]=mpi->stride[2]=dstride/4; | |
979 } | |
7537 | 980 } |
8667 | 981 mpi->planes[0]=image; |
982 mpi->stride[0]=dstride; | |
983 mpi->width=image_width; | |
984 mpi->height=image_height; | |
7537 | 985 mpi->flags|=MP_IMGFLAG_DIRECT; |
986 mp_msg(MSGT_VO, MSGL_DBG3, "<vo_directx><INFO>Direct Rendering ENABLED\n"); | |
987 return VO_TRUE; | |
988 } | |
989 return VO_FALSE; | |
990 } | |
991 | |
992 static uint32_t put_image(mp_image_t *mpi){ | |
993 | |
994 uint32_t i = 0; | |
995 uint8_t *d; | |
996 uint8_t *s; | |
997 uint32_t x = mpi->x; | |
998 uint32_t y = mpi->y; | |
999 uint32_t w = mpi->w; | |
1000 uint32_t h = mpi->h; | |
1001 | |
8667 | 1002 if((mpi->flags&MP_IMGFLAG_DIRECT)||(mpi->flags&MP_IMGFLAG_DRAW_CALLBACK)) |
7537 | 1003 { |
1004 mp_msg(MSGT_VO, MSGL_DBG3 ,"<vo_directx><INFO>put_image: nothing to do: drawslices\n"); | |
1005 return VO_TRUE; | |
1006 } | |
1007 | |
1008 if (mpi->flags&MP_IMGFLAG_PLANAR) | |
1009 { | |
8667 | 1010 |
1011 if(image_format!=IMGFMT_YVU9)draw_slice(mpi->planes,mpi->stride,mpi->w,mpi->h,0,0); | |
1012 else | |
7537 | 1013 { |
1014 // copy Y | |
1015 d=image+dstride*y+x; | |
1016 s=mpi->planes[0]; | |
1017 for(i=0;i<h;i++){ | |
1018 memcpy(d,s,w); | |
1019 s+=mpi->stride[0]; | |
1020 d+=dstride; | |
1021 } | |
8519 | 1022 w/=4;h/=4;x/=4;y/=4; |
7537 | 1023 // copy V |
8519 | 1024 d=image+dstride*image_height + dstride*y/4+x; |
8667 | 1025 s=mpi->planes[2]; |
7537 | 1026 for(i=0;i<h;i++){ |
1027 memcpy(d,s,w); | |
1028 s+=mpi->stride[1]; | |
8519 | 1029 d+=dstride/4; |
7537 | 1030 } |
1031 // copy U | |
8519 | 1032 d=image+dstride*image_height + dstride*image_height/16 + dstride/4*y+x; |
8667 | 1033 s=mpi->planes[1]; |
7537 | 1034 for(i=0;i<h;i++){ |
1035 memcpy(d,s,w); | |
1036 s+=mpi->stride[2]; | |
8519 | 1037 d+=dstride/4; |
7537 | 1038 } |
1039 } | |
1040 } | |
1041 else //packed | |
1042 { | |
1043 memcpy( image, mpi->planes[0], image_height * dstride); | |
1044 } | |
1045 return VO_TRUE; | |
1046 } | |
1047 | |
1048 static uint32_t | |
1049 config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t options, char *title, uint32_t format) | |
1050 { | |
10900 | 1051 int wx=-1; |
1052 int wy=-1; | |
1053 vo_fs = options & 0x01; | |
7537 | 1054 vm = options & 0x02; |
1055 image_format = format; | |
1056 image_width = width; | |
1057 image_height = height; | |
8519 | 1058 d_image_width = d_width; |
1059 d_image_height = d_height; | |
10640
01e0d93182f8
fix playback of rgb files when overlay is not disabled
faust3
parents:
9943
diff
changeset
|
1060 nooverlay = 0; |
8519 | 1061 aspect_save_orig(image_width,image_height); |
1062 aspect_save_prescale(d_image_width,d_image_height); | |
1063 aspect_save_screenres(GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN)); | |
10900 | 1064 geometry(&wx, &wy, &d_image_width, &d_image_height,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN)); |
1065 aspect(&d_image_width,&d_image_height,A_NOZOOM); | |
1066 if(wx !=-1)SetWindowPos(hWnd,NULL, wx, wy,d_image_width,d_image_height,SWP_SHOWWINDOW|SWP_NOOWNERZORDER); | |
1067 SetWindowText(hWnd,title); | |
1068 | |
8667 | 1069 /*release all surfaces*/ |
7682 | 1070 if (g_lpddsBack != NULL) g_lpddsBack->lpVtbl->Release(g_lpddsBack); |
1071 g_lpddsBack = NULL; | |
1072 if(vo_doublebuffering) | |
1073 { | |
1074 if (g_lpddsOverlay != NULL)g_lpddsOverlay->lpVtbl->Release(g_lpddsOverlay); | |
1075 } | |
1076 g_lpddsOverlay = NULL; | |
1077 if (g_lpddsPrimary != NULL) g_lpddsPrimary->lpVtbl->Release(g_lpddsPrimary); | |
1078 g_lpddsPrimary = NULL; | |
1079 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>overlay surfaces released\n"); | |
8667 | 1080 /*set cooperativelevel*/ |
1081 if(vm) /*exclusive mode*/ | |
1082 { | |
10900 | 1083 vo_fs=1; |
8667 | 1084 if (g_lpdd->lpVtbl->SetCooperativeLevel(g_lpdd, hWnd, DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN) != DD_OK) |
1085 { | |
1086 mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't set cooperativelevel for exclusive mode"); | |
1087 return 1; | |
1088 } | |
1089 SetWindowLong( hWnd, GWL_STYLE, 0 ); | |
1090 /*SetDisplayMode(ddobject,width,height,bpp,refreshrate,aditionalflags)*/ | |
1091 if(g_lpdd->lpVtbl->SetDisplayMode(g_lpdd,640, 480, 16,0,0) != DD_OK) | |
1092 { | |
1093 mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't set displaymode\n"); | |
1094 return 1; | |
1095 } | |
1096 aspect_save_screenres(GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN)); | |
1097 mp_msg(MSGT_VO, MSGL_V,"<vo_directx><INFO>using exclusive mode\n"); | |
7537 | 1098 } |
1099 else | |
1100 { | |
8667 | 1101 if (g_lpdd->lpVtbl->SetCooperativeLevel(g_lpdd, hWnd, DDSCL_NORMAL) != DD_OK) |
7537 | 1102 { |
8667 | 1103 mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't set cooperativelevel for windowed mode"); |
1104 return 1; | |
7537 | 1105 } |
8667 | 1106 mp_msg(MSGT_VO, MSGL_V,"<vo_directx><INFO>using normal cooperativelevel\n"); |
7537 | 1107 } |
10900 | 1108 if(vo_fs) |
8667 | 1109 { |
1110 /*remove the borders*/ | |
1111 SetWindowLong( hWnd, GWL_STYLE, 0 ); | |
1112 /*change backgroundcolor*/ | |
1113 SetClassLongA(hWnd,GCL_HBRBACKGROUND,(int)CreateSolidBrush(RGB(0,0,0))); | |
1114 /*repaint*/ | |
1115 RedrawWindow(hWnd,NULL,NULL,RDW_INVALIDATE|RDW_ERASE|RDW_INTERNALPAINT); | |
1116 /*hide mouse*/ | |
1117 ShowCursor(FALSE); | |
1118 } | |
1119 /*create the surfaces*/ | |
1120 if(Directx_CreatePrimarySurface())return 1; | |
1121 if (!nooverlay && Directx_CreateOverlay(image_format)) | |
7537 | 1122 { |
10640
01e0d93182f8
fix playback of rgb files when overlay is not disabled
faust3
parents:
9943
diff
changeset
|
1123 if(format == primary_image_format)nooverlay=1; /*overlay creation failed*/ |
01e0d93182f8
fix playback of rgb files when overlay is not disabled
faust3
parents:
9943
diff
changeset
|
1124 else { |
01e0d93182f8
fix playback of rgb files when overlay is not disabled
faust3
parents:
9943
diff
changeset
|
1125 mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't use overlay mode: please use -vo directx:noaccel\n"); |
01e0d93182f8
fix playback of rgb files when overlay is not disabled
faust3
parents:
9943
diff
changeset
|
1126 return 1; |
01e0d93182f8
fix playback of rgb files when overlay is not disabled
faust3
parents:
9943
diff
changeset
|
1127 } |
7537 | 1128 } |
8667 | 1129 if(nooverlay) |
1130 { | |
1131 if(Directx_CreateBackpuffer()) | |
1132 { | |
1133 mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't get the driver to work on your system :(\n"); | |
1134 return 1; | |
1135 } | |
1136 mp_msg(MSGT_VO, MSGL_V,"<vo_directx><INFO>back surface created\n"); | |
1137 vo_doublebuffering = 0; | |
1138 /*create clipper for nonoverlay mode*/ | |
1139 if(g_lpddclipper)g_lpddclipper->lpVtbl->Release(g_lpddclipper); | |
1140 g_lpddclipper=NULL; | |
1141 if(g_lpdd->lpVtbl->CreateClipper(g_lpdd, 0, &g_lpddclipper,NULL)!= DD_OK){mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't create clipper\n");return 1;} | |
1142 if(g_lpddclipper->lpVtbl->SetHWnd (g_lpddclipper, 0, hWnd)!= DD_OK){mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't associate clipper with window\n");return 1;} | |
1143 if(g_lpddsPrimary->lpVtbl->SetClipper (g_lpddsPrimary,g_lpddclipper)!=DD_OK){mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't associate primary surface with clipper\n");return 1;} | |
1144 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>clipper succesfully created\n"); | |
1145 } | |
1146 Directx_ManageDisplay(d_image_width,d_image_height); | |
7537 | 1147 memset(&ddsdsf, 0,sizeof(DDSURFACEDESC)); |
1148 ddsdsf.dwSize = sizeof (DDSURFACEDESC); | |
1149 g_lpddsBack->lpVtbl->Lock(g_lpddsBack,NULL,&ddsdsf, DDLOCK_NOSYSLOCK | DDLOCK_WAIT, NULL); | |
1150 dstride = ddsdsf.lPitch; | |
1151 image = ddsdsf.lpSurface; | |
1152 return 0; | |
1153 } | |
1154 | |
1155 static uint32_t control(uint32_t request, void *data, ...) | |
1156 { | |
1157 switch (request) { | |
1158 | |
1159 case VOCTRL_GET_IMAGE: | |
1160 return get_image(data); | |
1161 case VOCTRL_QUERY_FORMAT: | |
1162 return query_format(*((uint32_t*)data)); | |
1163 case VOCTRL_DRAW_IMAGE: | |
1164 return put_image(data); | |
1165 case VOCTRL_FULLSCREEN: | |
1166 { | |
1167 if(vm) | |
1168 { | |
1169 mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>currently we do not allow to switch from exclusive to windowed mode\n"); | |
1170 } | |
1171 else | |
1172 { | |
8667 | 1173 WINDOWPLACEMENT window_placement; |
1174 uint32_t width = 0; /*default: restore to the size it had before maximizing*/ | |
1175 uint32_t height = 0; | |
1176 window_placement.length = sizeof(WINDOWPLACEMENT); | |
1177 GetWindowPlacement(hWnd, &window_placement); | |
10900 | 1178 if(vo_fs) /*go to windowed*/ |
8667 | 1179 { |
10900 | 1180 vo_fs = 0; |
8667 | 1181 /*prevent the screen being filled with garbage*/ |
1182 window_placement.showCmd = SW_SHOWMINIMIZED; | |
1183 SetWindowPlacement(hWnd,&window_placement); | |
1184 /*change style and restore the window*/ | |
1185 SetWindowLong(hWnd,GWL_STYLE,WS_OVERLAPPEDWINDOW|WS_SIZEBOX); | |
9488
abe81caa8cc1
fix fullscreenswitching patch by Joey Parrish <joey at nicewarrior.org>
faust3
parents:
9380
diff
changeset
|
1186 window_placement.showCmd = SW_RESTORE; |
8667 | 1187 SetWindowPlacement(hWnd,&window_placement ); |
1188 /*restore backgroundcolor*/ | |
1189 SetClassLongA(hWnd,GCL_HBRBACKGROUND,(int)CreateSolidBrush(windowcolor)); | |
1190 /*never ever make a big window*/ | |
1191 if(((window_placement.rcNormalPosition.bottom - window_placement.rcNormalPosition.top)==GetSystemMetrics(SM_CYSCREEN)) | |
1192 &&((window_placement.rcNormalPosition.right - window_placement.rcNormalPosition.left)==GetSystemMetrics(SM_CXSCREEN))) | |
1193 { | |
1194 width = d_image_width; | |
1195 height = d_image_height; | |
1196 } | |
1197 /*show cursor again*/ | |
1198 ShowCursor(TRUE); | |
1199 } | |
1200 else /*go to fullscreen*/ | |
1201 { | |
10900 | 1202 vo_fs = 1; |
8667 | 1203 /*remove decoration and maximize*/ |
1204 SetWindowLong(hWnd,GWL_STYLE,0); | |
1205 window_placement.showCmd = SW_SHOWMAXIMIZED; | |
1206 SetWindowPlacement(hWnd,&window_placement); | |
1207 /*make the window really black*/ | |
1208 SetClassLongA(hWnd,GCL_HBRBACKGROUND,(int)CreateSolidBrush(RGB(0,0,0))); | |
1209 /*hide mouse cursor in fullscreen mode*/ | |
1210 if(ShowCursor(FALSE)<0); | |
1211 else while(ShowCursor(FALSE)>=0)mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx>ShowCursor(FALSE)>=0\n"); | |
1212 } | |
1213 RedrawWindow(hWnd,NULL,NULL,RDW_INVALIDATE|RDW_ERASE|RDW_INTERNALPAINT); | |
1214 Directx_ManageDisplay(width,height); | |
7537 | 1215 } |
1216 return VO_TRUE; | |
1217 } | |
1218 }; | |
1219 return VO_NOTIMPL; | |
1220 } |