summaryrefslogtreecommitdiff
path: root/apps/plugins/sdl/src/video/windx5
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/sdl/src/video/windx5')
-rw-r--r--apps/plugins/sdl/src/video/windx5/SDL_dx5events.c1005
-rw-r--r--apps/plugins/sdl/src/video/windx5/SDL_dx5events_c.h37
-rw-r--r--apps/plugins/sdl/src/video/windx5/SDL_dx5video.c2537
-rw-r--r--apps/plugins/sdl/src/video/windx5/SDL_dx5video.h61
-rw-r--r--apps/plugins/sdl/src/video/windx5/SDL_dx5yuv.c296
-rw-r--r--apps/plugins/sdl/src/video/windx5/SDL_dx5yuv_c.h38
-rw-r--r--apps/plugins/sdl/src/video/windx5/directx.h97
7 files changed, 0 insertions, 4071 deletions
diff --git a/apps/plugins/sdl/src/video/windx5/SDL_dx5events.c b/apps/plugins/sdl/src/video/windx5/SDL_dx5events.c
deleted file mode 100644
index e12092fd68..0000000000
--- a/apps/plugins/sdl/src/video/windx5/SDL_dx5events.c
+++ /dev/null
@@ -1,1005 +0,0 @@
1/*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2012 Sam Lantinga
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library 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 GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19 Sam Lantinga
20 slouken@libsdl.org
21*/
22#include "SDL_config.h"
23
24/* CAUTION!!!! If you modify this file, check ../windib/SDL_sysevents.c */
25
26#include "directx.h"
27
28#include "SDL_main.h"
29#include "SDL_events.h"
30#include "SDL_video.h"
31#include "SDL_syswm.h"
32#include "../../events/SDL_sysevents.h"
33#include "../../events/SDL_events_c.h"
34#include "../wincommon/SDL_lowvideo.h"
35#include "SDL_dx5video.h"
36
37#ifndef WM_APP
38#define WM_APP 0x8000
39#endif
40
41#ifdef _WIN32_WCE
42#define NO_GETKEYBOARDSTATE
43#endif
44
45/* The keyboard and mouse device input */
46#define MAX_INPUTS 2
47#define INPUT_QSIZE 512 /* Buffer up to 512 input messages */
48
49static LPDIRECTINPUT dinput = NULL;
50static LPDIRECTINPUTDEVICE2 SDL_DIdev[MAX_INPUTS];
51static HANDLE SDL_DIevt[MAX_INPUTS];
52static void (*SDL_DIfun[MAX_INPUTS])(const int, DIDEVICEOBJECTDATA *);
53static int SDL_DIndev = 0;
54static int mouse_lost;
55static int mouse_pressed;
56static int mouse_buttons_swapped = 0;
57
58/* The translation table from a DirectInput scancode to an SDL keysym */
59static SDLKey DIK_keymap[256];
60static SDL_keysym *TranslateKey(UINT scancode, SDL_keysym *keysym, int pressed);
61
62/* DJM: If the user setup the window for us, we want to save his window proc,
63 and give him a chance to handle some messages. */
64#ifdef STRICT
65#define WNDPROCTYPE WNDPROC
66#else
67#define WNDPROCTYPE FARPROC
68#endif
69static WNDPROCTYPE userWindowProc = NULL;
70
71static HWND GetTopLevelParent(HWND hWnd)
72{
73 HWND hParentWnd;
74 while (1)
75 {
76 hParentWnd = GetParent(hWnd);
77 if (hParentWnd == NULL)
78 break;
79 hWnd = hParentWnd;
80 }
81 return hWnd;
82}
83
84/* Convert a DirectInput return code to a text message */
85static void SetDIerror(char *function, int code)
86{
87 static char *error;
88 static char errbuf[1024];
89
90 errbuf[0] = 0;
91 switch (code) {
92 case DIERR_GENERIC:
93 error = "Undefined error!";
94 break;
95 case DIERR_OLDDIRECTINPUTVERSION:
96 error = "Your version of DirectInput needs upgrading";
97 break;
98 case DIERR_INVALIDPARAM:
99 error = "Invalid parameters";
100 break;
101 case DIERR_OUTOFMEMORY:
102 error = "Out of memory";
103 break;
104 case DIERR_DEVICENOTREG:
105 error = "Device not registered";
106 break;
107 case DIERR_NOINTERFACE:
108 error = "Interface not supported";
109 break;
110 case DIERR_NOTINITIALIZED:
111 error = "Device not initialized";
112 break;
113 default:
114 SDL_snprintf(errbuf, SDL_arraysize(errbuf),
115 "%s: Unknown DirectInput error: 0x%x",
116 function, code);
117 break;
118 }
119 if ( ! errbuf[0] ) {
120 SDL_snprintf(errbuf, SDL_arraysize(errbuf), "%s: %s", function, error);
121 }
122 SDL_SetError("%s", errbuf);
123 return;
124}
125
126/* Initialize DirectInput
127 Note: If NONEXCLUSIVE access is requested for the devices, normal
128 windows input messages will continue to be generated for that
129 input device, in addition to DirectInput messages.
130 */
131static void handle_keyboard(const int numevents, DIDEVICEOBJECTDATA *events);
132static void handle_mouse(const int numevents, DIDEVICEOBJECTDATA *events);
133struct {
134 char *name;
135 REFGUID guid;
136 LPCDIDATAFORMAT format;
137 DWORD win_level;
138 DWORD raw_level;
139 void (*fun)(const int numevents, DIDEVICEOBJECTDATA *events);
140} inputs[] = {
141 { "keyboard",
142 &GUID_SysKeyboard, &c_dfDIKeyboard,
143 (DISCL_FOREGROUND|DISCL_NONEXCLUSIVE),
144 (DISCL_FOREGROUND|DISCL_NONEXCLUSIVE), handle_keyboard },
145 { "mouse",
146 &GUID_SysMouse,
147#if DIRECTINPUT_VERSION >= 0x700
148 &c_dfDIMouse2,
149#else
150 &c_dfDIMouse,
151#endif
152 (DISCL_BACKGROUND|DISCL_NONEXCLUSIVE),
153 (DISCL_BACKGROUND|DISCL_NONEXCLUSIVE), handle_mouse },
154 { NULL, NULL, NULL, 0, 0, NULL }
155};
156
157static int DX5_DInputInit(_THIS)
158{
159 int i;
160 LPDIRECTINPUTDEVICE device;
161 HRESULT result;
162 DIPROPDWORD dipdw;
163 HWND topwnd;
164
165 /* Create the DirectInput object */
166 result = DInputCreate(SDL_Instance, DIRECTINPUT_VERSION,
167 &dinput, NULL);
168 if ( result != DI_OK ) {
169 SetDIerror("DirectInputCreate", result);
170 return(-1);
171 }
172
173 /* Create all of our registered input devices */
174 SDL_DIndev = 0;
175 for ( i=0; inputs[i].name; ++i ) {
176 /* Create the DirectInput device */
177 result = IDirectInput_CreateDevice(dinput, inputs[i].guid,
178 &device, NULL);
179 if ( result != DI_OK ) {
180 SetDIerror("DirectInput::CreateDevice", result);
181 return(-1);
182 }
183 result = IDirectInputDevice_QueryInterface(device,
184 &IID_IDirectInputDevice2, (LPVOID *)&SDL_DIdev[i]);
185 IDirectInputDevice_Release(device);
186 if ( result != DI_OK ) {
187 SetDIerror("DirectInputDevice::QueryInterface", result);
188 return(-1);
189 }
190 topwnd = GetTopLevelParent(SDL_Window);
191 result = IDirectInputDevice2_SetCooperativeLevel(SDL_DIdev[i],
192 topwnd, inputs[i].win_level);
193 if ( result != DI_OK ) {
194 SetDIerror("DirectInputDevice::SetCooperativeLevel",
195 result);
196 return(-1);
197 }
198 result = IDirectInputDevice2_SetDataFormat(SDL_DIdev[i],
199 inputs[i].format);
200 if ( result != DI_OK ) {
201 SetDIerror("DirectInputDevice::SetDataFormat", result);
202 return(-1);
203 }
204
205 /* Set buffered input -- we aren't polling */
206 SDL_memset(&dipdw, 0, sizeof(dipdw));
207 dipdw.diph.dwSize = sizeof(dipdw);
208 dipdw.diph.dwHeaderSize = sizeof(dipdw.diph);
209 dipdw.diph.dwObj = 0;
210 dipdw.diph.dwHow = DIPH_DEVICE;
211 dipdw.dwData = INPUT_QSIZE;
212 result = IDirectInputDevice2_SetProperty(SDL_DIdev[i],
213 DIPROP_BUFFERSIZE, &dipdw.diph);
214 if ( result != DI_OK ) {
215 SetDIerror("DirectInputDevice::SetProperty", result);
216 return(-1);
217 }
218
219 /* Create an event to be signaled when input is ready */
220 SDL_DIevt[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
221 if ( SDL_DIevt[i] == NULL ) {
222 SDL_SetError("Couldn't create DirectInput event");
223 return(-1);
224 }
225 result = IDirectInputDevice2_SetEventNotification(SDL_DIdev[i],
226 SDL_DIevt[i]);
227 if ( result != DI_OK ) {
228 SetDIerror("DirectInputDevice::SetEventNotification",
229 result);
230 return(-1);
231 }
232 SDL_DIfun[i] = inputs[i].fun;
233
234 /* Acquire the device for input */
235 IDirectInputDevice2_Acquire(SDL_DIdev[i]);
236
237 /* Increment the number of devices we have */
238 ++SDL_DIndev;
239 }
240 mouse_pressed = 0;
241 mouse_buttons_swapped = GetSystemMetrics(SM_SWAPBUTTON);
242
243 /* DirectInput is ready! */
244 return(0);
245}
246
247/* Clean up DirectInput */
248static void DX5_DInputQuit(_THIS)
249{
250 int i;
251
252 if ( dinput != NULL ) {
253 /* Close and release all DirectInput devices */
254 for ( i=0; i<MAX_INPUTS; ++i ) {
255 if ( SDL_DIdev[i] != NULL ) {
256 IDirectInputDevice2_Unacquire(SDL_DIdev[i]);
257 IDirectInputDevice2_SetEventNotification(
258 SDL_DIdev[i], NULL);
259 if ( SDL_DIevt[i] != NULL ) {
260 CloseHandle(SDL_DIevt[i]);
261 SDL_DIevt[i] = NULL;
262 }
263 IDirectInputDevice2_Release(SDL_DIdev[i]);
264 SDL_DIdev[i] = NULL;
265 }
266 }
267 SDL_DIndev = 0;
268
269 /* Release DirectInput */
270 IDirectInput_Release(dinput);
271 dinput = NULL;
272 }
273}
274
275/* Flag to tell SDL whether or not we queued an event */
276static int posted = 0;
277
278/* Input event handler functions */
279static void handle_keyboard(const int numevents, DIDEVICEOBJECTDATA *keybuf)
280{
281 int i;
282 SDL_keysym keysym;
283
284 /* Translate keyboard messages */
285 for ( i=0; i<numevents; ++i ) {
286 if ( keybuf[i].dwData & 0x80 ) {
287 posted = SDL_PrivateKeyboard(SDL_PRESSED,
288 TranslateKey(keybuf[i].dwOfs, &keysym, 1));
289 } else {
290 posted = SDL_PrivateKeyboard(SDL_RELEASED,
291 TranslateKey(keybuf[i].dwOfs, &keysym, 0));
292 }
293 }
294}
295
296static void post_mouse_motion(int relative, Sint16 x, Sint16 y)
297{
298 extern int mouse_relative;
299
300 if ( SDL_GetAppState() & SDL_APPMOUSEFOCUS ) {
301 posted = SDL_PrivateMouseMotion(
302 0, relative, x, y);
303
304 if ( !mouse_relative ) {
305 /* As DirectInput reads raw device coordinates, it has no notion of
306 * cursors or absolute position. We must assume responsibility for
307 * keeping track of this. */
308 int current_x, current_y;
309 POINT cursor;
310 RECT trap;
311 RECT window;
312 int at_edge;
313
314 /* Get the current cursor position */
315 SDL_GetMouseState(&current_x, &current_y);
316 cursor.x = current_x;
317 cursor.y = current_y;
318 ClientToScreen(SDL_Window, &cursor);
319
320 /* Construct a 1 pixel square RECT that is used to confine the cursor
321 * pointer to a specific pixel using ClipCursor. This is used in
322 * preference to SetCursorPos as it avoids the cursor jumping around as
323 * both the OS and SDL attempt to move it simultaneously. */
324 trap.left = cursor.x;
325 trap.top = cursor.y;
326 trap.right = cursor.x + 1;
327 trap.bottom = cursor.y + 1;
328
329 GetClientRect(SDL_Window, &window);
330 window.right -= window.left; window.left = 0;
331 window.bottom -= window.top; window.top = 0;
332
333 /* As we're assuming control over the cursor, we need to know when to
334 * relinquish control of it back to the operating system. This is when
335 * the cursor reaches the edge of the window. */
336 at_edge = (current_x == window.left) ||
337 (current_x == (window.right - 1)) ||
338 (current_y == window.top) ||
339 (current_y == (window.bottom - 1));
340
341 if ( at_edge ) {
342 ClipCursor(NULL);
343 } else {
344 ClipCursor(&trap);
345 }
346 } else {
347 /* When in relative mode, warp the OS's idea of where the cursor is to
348 * the center of the screen. This isn't really necessary as DirectInput
349 * reads from the hardware itself, but in case things go wrong, the
350 * cursor will be left in a sensible place. */
351 POINT center;
352 center.x = (SDL_VideoSurface->w/2);
353 center.y = (SDL_VideoSurface->h/2);
354 ClientToScreen(SDL_Window, &center);
355 SetCursorPos(center.x, center.y);
356 }
357 }
358}
359
360static void handle_mouse(const int numevents, DIDEVICEOBJECTDATA *ptrbuf)
361{
362 int i;
363 Sint16 xrel, yrel;
364 Uint8 state;
365 Uint8 button;
366 DWORD timestamp = 0;
367
368 /* Sanity check. Mailing list reports this being NULL unexpectedly. */
369 if (SDL_PublicSurface == NULL) {
370 return;
371 }
372
373 /* If mouse focus has been lost, make sure we release the cursor. */
374 if ( !(SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) {
375 mouse_lost = 1;
376 ClipCursor(NULL);
377 } else {
378 /* If the mouse was lost, regain some sense of mouse state */
379 if ( mouse_lost ) {
380 POINT mouse_pos;
381 Uint8 old_state;
382 Uint8 new_state;
383
384 /* Set ourselves up with the current cursor position */
385 GetCursorPos(&mouse_pos);
386 ScreenToClient(SDL_Window, &mouse_pos);
387 post_mouse_motion( 0, (Sint16)mouse_pos.x, (Sint16)mouse_pos.y);
388
389 /* Check for mouse button changes */
390 old_state = SDL_GetMouseState(NULL, NULL);
391 new_state = 0;
392 { /* Get the new DirectInput button state for the mouse */
393 #if DIRECTINPUT_VERSION >= 0x700
394 DIMOUSESTATE2 distate;
395 #else
396 DIMOUSESTATE distate;
397 #endif
398 HRESULT result;
399
400 result=IDirectInputDevice2_GetDeviceState(SDL_DIdev[1],
401 sizeof(distate), &distate);
402 if ( result != DI_OK ) {
403 /* Try again next time */
404 SetDIerror(
405 "IDirectInputDevice2::GetDeviceState", result);
406 return;
407 }
408 for ( i=3; i>=0; --i ) {
409 if ( (distate.rgbButtons[i]&0x80) == 0x80 ) {
410 new_state |= 0x01;
411 }
412 new_state <<= 1;
413 }
414 }
415 for ( i=0; i<8; ++i ) {
416 if ( (old_state&0x01) != (new_state&0x01) ) {
417 button = (Uint8)(i+1);
418 /* Map DI button numbers to SDL */
419 switch ( button ) {
420 case 2: button = SDL_BUTTON_RIGHT; break;
421 case 3: button = SDL_BUTTON_MIDDLE; break;
422 case 4: button = SDL_BUTTON_X1; break;
423 case 5: button = SDL_BUTTON_X2; break;
424 default: break;
425 }
426 if ( new_state & 0x01 ) {
427 /* Grab mouse so we get mouse-up */
428 if ( ++mouse_pressed > 0 ) {
429 SetCapture(SDL_Window);
430 }
431 state = SDL_PRESSED;
432 } else {
433 /* Release mouse after all mouse-ups */
434 if ( --mouse_pressed <= 0 ) {
435 ReleaseCapture();
436 mouse_pressed = 0;
437 }
438 state = SDL_RELEASED;
439 }
440 if ( mouse_buttons_swapped ) {
441 if ( button == 1 ) button = 3;
442 else
443 if ( button == 3 ) button = 1;
444 }
445 posted = SDL_PrivateMouseButton(state, button,
446 0, 0);
447 }
448 old_state >>= 1;
449 new_state >>= 1;
450 }
451 mouse_lost = 0;
452 return;
453 }
454
455 /* Translate mouse messages */
456 xrel = 0;
457 yrel = 0;
458 for ( i=0; i<(int)numevents; ++i ) {
459 switch (ptrbuf[i].dwOfs) {
460 case DIMOFS_X:
461 if ( timestamp != ptrbuf[i].dwTimeStamp ) {
462 if ( xrel || yrel ) {
463 post_mouse_motion(1, xrel, yrel);
464 xrel = 0;
465 yrel = 0;
466 }
467 timestamp = ptrbuf[i].dwTimeStamp;
468 }
469 xrel += (Sint16)ptrbuf[i].dwData;
470 break;
471 case DIMOFS_Y:
472 if ( timestamp != ptrbuf[i].dwTimeStamp ) {
473 if ( xrel || yrel ) {
474 post_mouse_motion(1, xrel, yrel);
475 xrel = 0;
476 yrel = 0;
477 }
478 timestamp = ptrbuf[i].dwTimeStamp;
479 }
480 yrel += (Sint16)ptrbuf[i].dwData;
481 break;
482 case DIMOFS_Z:
483 if ( xrel || yrel ) {
484 post_mouse_motion(1, xrel, yrel);
485 xrel = 0;
486 yrel = 0;
487 }
488 timestamp = 0;
489 if((int)ptrbuf[i].dwData > 0)
490 button = SDL_BUTTON_WHEELUP;
491 else
492 button = SDL_BUTTON_WHEELDOWN;
493 posted = SDL_PrivateMouseButton(
494 SDL_PRESSED, button, 0, 0);
495 posted |= SDL_PrivateMouseButton(
496 SDL_RELEASED, button, 0, 0);
497 break;
498 case DIMOFS_BUTTON0:
499 case DIMOFS_BUTTON1:
500 case DIMOFS_BUTTON2:
501 case DIMOFS_BUTTON3:
502 #if DIRECTINPUT_VERSION >= 0x700
503 case DIMOFS_BUTTON4:
504 case DIMOFS_BUTTON5:
505 case DIMOFS_BUTTON6:
506 case DIMOFS_BUTTON7:
507 #endif
508 if ( xrel || yrel ) {
509 post_mouse_motion(1, xrel, yrel);
510 xrel = 0;
511 yrel = 0;
512 }
513 timestamp = 0;
514 button = (Uint8)(ptrbuf[i].dwOfs-DIMOFS_BUTTON0)+1;
515 /* Map DI button numbers to SDL */
516 switch ( button ) {
517 case 2: button = SDL_BUTTON_RIGHT; break;
518 case 3: button = SDL_BUTTON_MIDDLE; break;
519 case 4: button = SDL_BUTTON_X1; break;
520 case 5: button = SDL_BUTTON_X2; break;
521 default: break;
522 }
523 if ( ptrbuf[i].dwData & 0x80 ) {
524 /* Grab mouse so we get mouse-up */
525 if ( ++mouse_pressed > 0 ) {
526 SetCapture(SDL_Window);
527 }
528 state = SDL_PRESSED;
529 } else {
530 /* Release mouse after all mouse-ups */
531 if ( --mouse_pressed <= 0 ) {
532 ReleaseCapture();
533 mouse_pressed = 0;
534 }
535 state = SDL_RELEASED;
536 }
537 if ( mouse_buttons_swapped ) {
538 if ( button == 1 ) button = 3;
539 else
540 if ( button == 3 ) button = 1;
541 }
542 posted = SDL_PrivateMouseButton(state, button,
543 0, 0);
544 break;
545 }
546 }
547 if ( xrel || yrel ) {
548 post_mouse_motion(1, xrel, yrel);
549 }
550 }
551}
552
553/* The main Win32 event handler */
554LRESULT DX5_HandleMessage(_THIS, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
555{
556 switch (msg) {
557#ifdef WM_ACTIVATEAPP
558 case WM_ACTIVATEAPP: {
559 int i, active;
560
561 active = (wParam && (GetForegroundWindow() == hwnd));
562 if ( active ) {
563 for ( i=0; i<MAX_INPUTS; ++i ) {
564 if (SDL_DIdev[i] != NULL)
565 IDirectInputDevice2_Acquire(
566 SDL_DIdev[i]);
567 }
568 } else {
569 for ( i=0; i<MAX_INPUTS; ++i ) {
570 if (SDL_DIdev[i] != NULL)
571 IDirectInputDevice2_Unacquire(
572 SDL_DIdev[i]);
573 }
574 mouse_lost = 1;
575 }
576 }
577 break;
578#endif /* WM_ACTIVATEAPP */
579
580#ifdef WM_DISPLAYCHANGE
581 case WM_DISPLAYCHANGE: {
582 WPARAM BitsPerPixel;
583 WORD SizeX, SizeY;
584
585 /* Ack! The display changed size and/or depth! */
586 SizeX = LOWORD(lParam);
587 SizeY = HIWORD(lParam);
588 BitsPerPixel = wParam;
589 /* We cause this message when we go fullscreen */
590 }
591 break;
592#endif /* WM_DISPLAYCHANGE */
593
594 /* The keyboard is handled via DirectInput */
595 case WM_SYSKEYUP:
596 case WM_SYSKEYDOWN:
597 case WM_KEYUP:
598 case WM_KEYDOWN: {
599 /* Ignore windows keyboard messages */;
600 }
601 return(0);
602
603#if defined(SC_SCREENSAVE) || defined(SC_MONITORPOWER)
604 /* Don't allow screen savers or monitor power downs.
605 This is because they quietly clear DirectX surfaces.
606 It would be better to allow the application to
607 decide whether or not to blow these off, but the
608 semantics of SDL_PrivateSysWMEvent() don't allow
609 the application that choice.
610 */
611 case WM_SYSCOMMAND: {
612 if ((wParam&0xFFF0)==SC_SCREENSAVE ||
613 (wParam&0xFFF0)==SC_MONITORPOWER)
614 return(0);
615 }
616 /* Fall through to default processing */
617
618#endif /* SC_SCREENSAVE || SC_MONITORPOWER */
619
620 default: {
621 /* Only post the event if we're watching for it */
622 if ( SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE ) {
623 SDL_SysWMmsg wmmsg;
624
625 SDL_VERSION(&wmmsg.version);
626 wmmsg.hwnd = hwnd;
627 wmmsg.msg = msg;
628 wmmsg.wParam = wParam;
629 wmmsg.lParam = lParam;
630 posted = SDL_PrivateSysWMEvent(&wmmsg);
631
632 /* DJM: If the user isn't watching for private
633 messages in her SDL event loop, then pass it
634 along to any win32 specific window proc.
635 */
636 } else if (userWindowProc) {
637 return CallWindowProc(userWindowProc, hwnd, msg, wParam, lParam);
638 }
639 }
640 break;
641 }
642 return(DefWindowProc(hwnd, msg, wParam, lParam));
643}
644
645/* This function checks the windows message queue and DirectInput and returns
646 1 if there was input, 0 if there was no input, or -1 if the application has
647 posted a quit message.
648*/
649static int DX5_CheckInput(_THIS, int timeout, BOOL processInput)
650{
651 MSG msg;
652 int i;
653 HRESULT result;
654 DWORD event;
655
656 /* Check the normal windows queue (highest preference) */
657 posted = 0;
658 while ( ! posted &&
659 PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) ) {
660 if ( GetMessage(&msg, NULL, 0, 0) > 0 ) {
661 DispatchMessage(&msg);
662 } else {
663 return(-1);
664 }
665 }
666 if ( posted ) {
667 return(1);
668 }
669
670 /* Pump the DirectInput flow */
671 if ( SDL_GetAppState() & SDL_APPMOUSEFOCUS ) {
672 for ( i=0; i<MAX_INPUTS; ++i ) {
673 if ( SDL_DIdev[i] != NULL ) {
674 result = IDirectInputDevice2_Poll(SDL_DIdev[i]);
675 if ( (result == DIERR_INPUTLOST) ||
676 (result == DIERR_NOTACQUIRED) ) {
677 if ( SDL_strcmp(inputs[i].name, "mouse") == 0 ) {
678 mouse_lost = 1;
679 }
680 IDirectInputDevice2_Acquire(SDL_DIdev[i]);
681 IDirectInputDevice2_Poll(SDL_DIdev[i]);
682 }
683 }
684 }
685 }
686
687 /* Wait for messages and input events */
688 event = MsgWaitForMultipleObjects(SDL_DIndev, SDL_DIevt, FALSE,
689 timeout, QS_ALLEVENTS);
690 if ((event >= WAIT_OBJECT_0) && (event < (WAIT_OBJECT_0+SDL_DIndev))) {
691 DWORD numevents;
692 static DIDEVICEOBJECTDATA evtbuf[INPUT_QSIZE];
693
694 event -= WAIT_OBJECT_0;
695 numevents = INPUT_QSIZE;
696 result = IDirectInputDevice2_GetDeviceData(
697 SDL_DIdev[event], sizeof(DIDEVICEOBJECTDATA),
698 evtbuf, &numevents, 0);
699 if ( (result == DIERR_INPUTLOST) ||
700 (result == DIERR_NOTACQUIRED) ) {
701 if ( SDL_strcmp(inputs[event].name, "mouse") == 0 ) {
702 mouse_lost = 1;
703 }
704 IDirectInputDevice2_Acquire(SDL_DIdev[event]);
705 result = IDirectInputDevice2_GetDeviceData(
706 SDL_DIdev[event], sizeof(DIDEVICEOBJECTDATA),
707 evtbuf, &numevents, 0);
708 }
709 /* Handle the events */
710 if ( result == DI_OK && processInput ) {
711 /* Note: This can post multiple events to event queue
712 */
713 (*SDL_DIfun[event])((int)numevents, evtbuf);
714 return(1);
715 }
716 }
717 if ( event != WAIT_TIMEOUT ) {
718 /* Maybe there was a windows message? */
719 if ( PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) ) {
720 if ( GetMessage(&msg, NULL, 0, 0) > 0 ) {
721 DispatchMessage(&msg);
722 } else {
723 return(-1);
724 }
725 return(1);
726 }
727 }
728 return(0);
729}
730
731/* Change cooperative level based on whether or not we are fullscreen */
732void DX5_DInputReset(_THIS, int fullscreen)
733{
734 DWORD level;
735 int i;
736 HRESULT result;
737 HWND topwnd;
738
739 for ( i=0; i<MAX_INPUTS; ++i ) {
740 if ( SDL_DIdev[i] != NULL ) {
741 if ( fullscreen ) {
742 level = inputs[i].raw_level;
743 } else {
744 level = inputs[i].win_level;
745 }
746 IDirectInputDevice2_Unacquire(SDL_DIdev[i]);
747 topwnd = GetTopLevelParent(SDL_Window);
748 result = IDirectInputDevice2_SetCooperativeLevel(
749 SDL_DIdev[i], topwnd, level);
750 IDirectInputDevice2_Acquire(SDL_DIdev[i]);
751 if ( result != DI_OK ) {
752 SetDIerror(
753 "DirectInputDevice::SetCooperativeLevel", result);
754 }
755 }
756 }
757 mouse_lost = 1;
758
759 /* Flush pending input */
760 DX5_CheckInput(this, 0, FALSE);
761}
762
763void DX5_PumpEvents(_THIS)
764{
765 /* Wait for messages and DirectInput */
766 while ( DX5_CheckInput(this, 0, TRUE) > 0 ) {
767 /* Loop and check again */;
768 }
769}
770
771void DX5_InitOSKeymap(_THIS)
772{
773#ifndef DIK_PAUSE
774#define DIK_PAUSE 0xC5
775#endif
776#ifndef DIK_OEM_102
777#define DIK_OEM_102 0x56 /* < > | on UK/Germany keyboards */
778#endif
779 int i;
780
781 /* Map the DIK scancodes to SDL keysyms */
782 for ( i=0; i<SDL_arraysize(DIK_keymap); ++i )
783 DIK_keymap[i] = 0;
784
785 /* Defined DIK_* constants */
786 DIK_keymap[DIK_ESCAPE] = SDLK_ESCAPE;
787 DIK_keymap[DIK_1] = SDLK_1;
788 DIK_keymap[DIK_2] = SDLK_2;
789 DIK_keymap[DIK_3] = SDLK_3;
790 DIK_keymap[DIK_4] = SDLK_4;
791 DIK_keymap[DIK_5] = SDLK_5;
792 DIK_keymap[DIK_6] = SDLK_6;
793 DIK_keymap[DIK_7] = SDLK_7;
794 DIK_keymap[DIK_8] = SDLK_8;
795 DIK_keymap[DIK_9] = SDLK_9;
796 DIK_keymap[DIK_0] = SDLK_0;
797 DIK_keymap[DIK_MINUS] = SDLK_MINUS;
798 DIK_keymap[DIK_EQUALS] = SDLK_EQUALS;
799 DIK_keymap[DIK_BACK] = SDLK_BACKSPACE;
800 DIK_keymap[DIK_TAB] = SDLK_TAB;
801 DIK_keymap[DIK_Q] = SDLK_q;
802 DIK_keymap[DIK_W] = SDLK_w;
803 DIK_keymap[DIK_E] = SDLK_e;
804 DIK_keymap[DIK_R] = SDLK_r;
805 DIK_keymap[DIK_T] = SDLK_t;
806 DIK_keymap[DIK_Y] = SDLK_y;
807 DIK_keymap[DIK_U] = SDLK_u;
808 DIK_keymap[DIK_I] = SDLK_i;
809 DIK_keymap[DIK_O] = SDLK_o;
810 DIK_keymap[DIK_P] = SDLK_p;
811 DIK_keymap[DIK_LBRACKET] = SDLK_LEFTBRACKET;
812 DIK_keymap[DIK_RBRACKET] = SDLK_RIGHTBRACKET;
813 DIK_keymap[DIK_RETURN] = SDLK_RETURN;
814 DIK_keymap[DIK_LCONTROL] = SDLK_LCTRL;
815 DIK_keymap[DIK_A] = SDLK_a;
816 DIK_keymap[DIK_S] = SDLK_s;
817 DIK_keymap[DIK_D] = SDLK_d;
818 DIK_keymap[DIK_F] = SDLK_f;
819 DIK_keymap[DIK_G] = SDLK_g;
820 DIK_keymap[DIK_H] = SDLK_h;
821 DIK_keymap[DIK_J] = SDLK_j;
822 DIK_keymap[DIK_K] = SDLK_k;
823 DIK_keymap[DIK_L] = SDLK_l;
824 DIK_keymap[DIK_SEMICOLON] = SDLK_SEMICOLON;
825 DIK_keymap[DIK_APOSTROPHE] = SDLK_QUOTE;
826 DIK_keymap[DIK_GRAVE] = SDLK_BACKQUOTE;
827 DIK_keymap[DIK_LSHIFT] = SDLK_LSHIFT;
828 DIK_keymap[DIK_BACKSLASH] = SDLK_BACKSLASH;
829 DIK_keymap[DIK_OEM_102] = SDLK_LESS;
830 DIK_keymap[DIK_Z] = SDLK_z;
831 DIK_keymap[DIK_X] = SDLK_x;
832 DIK_keymap[DIK_C] = SDLK_c;
833 DIK_keymap[DIK_V] = SDLK_v;
834 DIK_keymap[DIK_B] = SDLK_b;
835 DIK_keymap[DIK_N] = SDLK_n;
836 DIK_keymap[DIK_M] = SDLK_m;
837 DIK_keymap[DIK_COMMA] = SDLK_COMMA;
838 DIK_keymap[DIK_PERIOD] = SDLK_PERIOD;
839 DIK_keymap[DIK_SLASH] = SDLK_SLASH;
840 DIK_keymap[DIK_RSHIFT] = SDLK_RSHIFT;
841 DIK_keymap[DIK_MULTIPLY] = SDLK_KP_MULTIPLY;
842 DIK_keymap[DIK_LMENU] = SDLK_LALT;
843 DIK_keymap[DIK_SPACE] = SDLK_SPACE;
844 DIK_keymap[DIK_CAPITAL] = SDLK_CAPSLOCK;
845 DIK_keymap[DIK_F1] = SDLK_F1;
846 DIK_keymap[DIK_F2] = SDLK_F2;
847 DIK_keymap[DIK_F3] = SDLK_F3;
848 DIK_keymap[DIK_F4] = SDLK_F4;
849 DIK_keymap[DIK_F5] = SDLK_F5;
850 DIK_keymap[DIK_F6] = SDLK_F6;
851 DIK_keymap[DIK_F7] = SDLK_F7;
852 DIK_keymap[DIK_F8] = SDLK_F8;
853 DIK_keymap[DIK_F9] = SDLK_F9;
854 DIK_keymap[DIK_F10] = SDLK_F10;
855 DIK_keymap[DIK_NUMLOCK] = SDLK_NUMLOCK;
856 DIK_keymap[DIK_SCROLL] = SDLK_SCROLLOCK;
857 DIK_keymap[DIK_NUMPAD7] = SDLK_KP7;
858 DIK_keymap[DIK_NUMPAD8] = SDLK_KP8;
859 DIK_keymap[DIK_NUMPAD9] = SDLK_KP9;
860 DIK_keymap[DIK_SUBTRACT] = SDLK_KP_MINUS;
861 DIK_keymap[DIK_NUMPAD4] = SDLK_KP4;
862 DIK_keymap[DIK_NUMPAD5] = SDLK_KP5;
863 DIK_keymap[DIK_NUMPAD6] = SDLK_KP6;
864 DIK_keymap[DIK_ADD] = SDLK_KP_PLUS;
865 DIK_keymap[DIK_NUMPAD1] = SDLK_KP1;
866 DIK_keymap[DIK_NUMPAD2] = SDLK_KP2;
867 DIK_keymap[DIK_NUMPAD3] = SDLK_KP3;
868 DIK_keymap[DIK_NUMPAD0] = SDLK_KP0;
869 DIK_keymap[DIK_DECIMAL] = SDLK_KP_PERIOD;
870 DIK_keymap[DIK_F11] = SDLK_F11;
871 DIK_keymap[DIK_F12] = SDLK_F12;
872
873 DIK_keymap[DIK_F13] = SDLK_F13;
874 DIK_keymap[DIK_F14] = SDLK_F14;
875 DIK_keymap[DIK_F15] = SDLK_F15;
876
877 DIK_keymap[DIK_NUMPADEQUALS] = SDLK_KP_EQUALS;
878 DIK_keymap[DIK_NUMPADENTER] = SDLK_KP_ENTER;
879 DIK_keymap[DIK_RCONTROL] = SDLK_RCTRL;
880 DIK_keymap[DIK_DIVIDE] = SDLK_KP_DIVIDE;
881 DIK_keymap[DIK_SYSRQ] = SDLK_PRINT;
882 DIK_keymap[DIK_RMENU] = SDLK_RALT;
883 DIK_keymap[DIK_PAUSE] = SDLK_PAUSE;
884 DIK_keymap[DIK_HOME] = SDLK_HOME;
885 DIK_keymap[DIK_UP] = SDLK_UP;
886 DIK_keymap[DIK_PRIOR] = SDLK_PAGEUP;
887 DIK_keymap[DIK_LEFT] = SDLK_LEFT;
888 DIK_keymap[DIK_RIGHT] = SDLK_RIGHT;
889 DIK_keymap[DIK_END] = SDLK_END;
890 DIK_keymap[DIK_DOWN] = SDLK_DOWN;
891 DIK_keymap[DIK_NEXT] = SDLK_PAGEDOWN;
892 DIK_keymap[DIK_INSERT] = SDLK_INSERT;
893 DIK_keymap[DIK_DELETE] = SDLK_DELETE;
894 DIK_keymap[DIK_LWIN] = SDLK_LMETA;
895 DIK_keymap[DIK_RWIN] = SDLK_RMETA;
896 DIK_keymap[DIK_APPS] = SDLK_MENU;
897}
898
899static SDL_keysym *TranslateKey(UINT scancode, SDL_keysym *keysym, int pressed)
900{
901 /* Set the keysym information */
902 keysym->scancode = (unsigned char)scancode;
903 keysym->sym = DIK_keymap[scancode];
904 keysym->mod = KMOD_NONE;
905 keysym->unicode = 0;
906 if ( pressed && SDL_TranslateUNICODE ) {
907 UINT vkey;
908#ifndef NO_GETKEYBOARDSTATE
909 BYTE keystate[256];
910 Uint16 wchars[2];
911#endif
912
913 vkey = MapVirtualKey(scancode, 1);
914#ifdef NO_GETKEYBOARDSTATE
915 /* Uh oh, better hope the vkey is close enough.. */
916 keysym->unicode = vkey;
917#else
918 GetKeyboardState(keystate);
919 /* Numlock isn't taken into account in ToUnicode,
920 * so we handle it as a special case here */
921 if ((keystate[VK_NUMLOCK] & 1) && vkey >= VK_NUMPAD0 && vkey <= VK_NUMPAD9)
922 {
923 keysym->unicode = vkey - VK_NUMPAD0 + '0';
924 }
925 else if (SDL_ToUnicode(vkey, scancode, keystate, wchars, sizeof(wchars)/sizeof(wchars[0]), 0) > 0)
926 {
927 keysym->unicode = wchars[0];
928 }
929#endif /* NO_GETKEYBOARDSTATE */
930 }
931 return(keysym);
932}
933
934int DX5_CreateWindow(_THIS)
935{
936 char *windowid = SDL_getenv("SDL_WINDOWID");
937 int i;
938
939 /* Clear out DirectInput variables in case we fail */
940 for ( i=0; i<MAX_INPUTS; ++i ) {
941 SDL_DIdev[i] = NULL;
942 SDL_DIevt[i] = NULL;
943 SDL_DIfun[i] = NULL;
944 }
945
946 SDL_RegisterApp(NULL, 0, 0);
947
948 SDL_windowid = (windowid != NULL);
949 if ( SDL_windowid ) {
950 SDL_Window = (HWND)((size_t)SDL_strtoull(windowid, NULL, 0));
951 if ( SDL_Window == NULL ) {
952 SDL_SetError("Couldn't get user specified window");
953 return(-1);
954 }
955
956 /* DJM: we want all event's for the user specified
957 window to be handled by SDL.
958 */
959 userWindowProc = (WNDPROCTYPE)GetWindowLongPtr(SDL_Window, GWLP_WNDPROC);
960 SetWindowLongPtr(SDL_Window, GWLP_WNDPROC, (LONG_PTR)WinMessage);
961 } else {
962 SDL_Window = CreateWindow(SDL_Appname, SDL_Appname,
963 (WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX),
964 CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, NULL, NULL, SDL_Instance, NULL);
965 if ( SDL_Window == NULL ) {
966 SDL_SetError("Couldn't create window");
967 return(-1);
968 }
969 ShowWindow(SDL_Window, SW_HIDE);
970 }
971
972 /* Initialize DirectInput */
973 if ( DX5_DInputInit(this) < 0 ) {
974 return(-1);
975 }
976
977 /* JC 14 Mar 2006
978 Flush the message loop or this can cause big problems later
979 Especially if the user decides to use dialog boxes or assert()!
980 */
981 WIN_FlushMessageQueue();
982
983 /* Ready to roll */
984 return(0);
985}
986
987void DX5_DestroyWindow(_THIS)
988{
989 /* Close down DirectInput */
990 DX5_DInputQuit(this);
991
992 /* Destroy our window */
993 if ( SDL_windowid ) {
994 SetWindowLongPtr(SDL_Window, GWLP_WNDPROC, (LONG_PTR)userWindowProc);
995 } else {
996 DestroyWindow(SDL_Window);
997 }
998 SDL_UnregisterApp();
999
1000 /* JC 14 Mar 2006
1001 Flush the message loop or this can cause big problems later
1002 Especially if the user decides to use dialog boxes or assert()!
1003 */
1004 WIN_FlushMessageQueue();
1005}
diff --git a/apps/plugins/sdl/src/video/windx5/SDL_dx5events_c.h b/apps/plugins/sdl/src/video/windx5/SDL_dx5events_c.h
deleted file mode 100644
index 28e1b6c03e..0000000000
--- a/apps/plugins/sdl/src/video/windx5/SDL_dx5events_c.h
+++ /dev/null
@@ -1,37 +0,0 @@
1/*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2012 Sam Lantinga
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library 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 GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19 Sam Lantinga
20 slouken@libsdl.org
21*/
22#include "SDL_config.h"
23
24#include "../wincommon/SDL_lowvideo.h"
25
26/* Variables and functions exported by SDL_dx5events.c to other parts
27 of the native video subsystem (SDL_dx5video.c)
28*/
29extern LONG
30 DX5_HandleMessage(_THIS, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
31extern int DX5_CreateWindow(_THIS);
32extern void DX5_DestroyWindow(_THIS);
33
34extern void DX5_PumpEvents(_THIS);
35extern void DX5_InitOSKeymap(_THIS);
36extern void DX5_DInputReset(_THIS, int fullscreen);
37
diff --git a/apps/plugins/sdl/src/video/windx5/SDL_dx5video.c b/apps/plugins/sdl/src/video/windx5/SDL_dx5video.c
deleted file mode 100644
index f80ca97b07..0000000000
--- a/apps/plugins/sdl/src/video/windx5/SDL_dx5video.c
+++ /dev/null
@@ -1,2537 +0,0 @@
1/*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2012 Sam Lantinga
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library 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 GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19 Sam Lantinga
20 slouken@libsdl.org
21*/
22#include "SDL_config.h"
23
24#include "directx.h"
25
26/* Not yet in the mingw32 cross-compile headers */
27#ifndef CDS_FULLSCREEN
28#define CDS_FULLSCREEN 4
29#endif
30
31#include "SDL_timer.h"
32#include "SDL_events.h"
33#include "SDL_syswm.h"
34#include "../SDL_sysvideo.h"
35#include "../SDL_blit.h"
36#include "../SDL_pixels_c.h"
37#include "SDL_dx5video.h"
38#include "../wincommon/SDL_syswm_c.h"
39#include "../wincommon/SDL_sysmouse_c.h"
40#include "SDL_dx5events_c.h"
41#include "SDL_dx5yuv_c.h"
42#include "../wincommon/SDL_wingl_c.h"
43
44#ifdef _WIN32_WCE
45#define NO_CHANGEDISPLAYSETTINGS
46#endif
47#ifndef WS_MAXIMIZE
48#define WS_MAXIMIZE 0
49#endif
50#ifndef SWP_NOCOPYBITS
51#define SWP_NOCOPYBITS 0
52#endif
53#ifndef PC_NOCOLLAPSE
54#define PC_NOCOLLAPSE 0
55#endif
56
57
58/* DirectX function pointers for video and events */
59HRESULT (WINAPI *DDrawCreate)( GUID FAR *lpGUID, LPDIRECTDRAW FAR *lplpDD, IUnknown FAR *pUnkOuter );
60HRESULT (WINAPI *DInputCreate)(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUT *ppDI, LPUNKNOWN punkOuter);
61
62/* This is the rect EnumModes2 uses */
63struct DX5EnumRect {
64 SDL_Rect r;
65 int refreshRate;
66 struct DX5EnumRect* next;
67};
68static struct DX5EnumRect *enumlists[NUM_MODELISTS];
69
70/*
71 * Experimentally determined values for c_cfDI* constants used in DirectX 5.0
72 */
73
74/* Keyboard */
75
76static DIOBJECTDATAFORMAT KBD_fmt[] = {
77 { &GUID_Key, 0, 0x8000000C, 0x00000000 },
78 { &GUID_Key, 1, 0x8000010C, 0x00000000 },
79 { &GUID_Key, 2, 0x8000020C, 0x00000000 },
80 { &GUID_Key, 3, 0x8000030C, 0x00000000 },
81 { &GUID_Key, 4, 0x8000040C, 0x00000000 },
82 { &GUID_Key, 5, 0x8000050C, 0x00000000 },
83 { &GUID_Key, 6, 0x8000060C, 0x00000000 },
84 { &GUID_Key, 7, 0x8000070C, 0x00000000 },
85 { &GUID_Key, 8, 0x8000080C, 0x00000000 },
86 { &GUID_Key, 9, 0x8000090C, 0x00000000 },
87 { &GUID_Key, 10, 0x80000A0C, 0x00000000 },
88 { &GUID_Key, 11, 0x80000B0C, 0x00000000 },
89 { &GUID_Key, 12, 0x80000C0C, 0x00000000 },
90 { &GUID_Key, 13, 0x80000D0C, 0x00000000 },
91 { &GUID_Key, 14, 0x80000E0C, 0x00000000 },
92 { &GUID_Key, 15, 0x80000F0C, 0x00000000 },
93 { &GUID_Key, 16, 0x8000100C, 0x00000000 },
94 { &GUID_Key, 17, 0x8000110C, 0x00000000 },
95 { &GUID_Key, 18, 0x8000120C, 0x00000000 },
96 { &GUID_Key, 19, 0x8000130C, 0x00000000 },
97 { &GUID_Key, 20, 0x8000140C, 0x00000000 },
98 { &GUID_Key, 21, 0x8000150C, 0x00000000 },
99 { &GUID_Key, 22, 0x8000160C, 0x00000000 },
100 { &GUID_Key, 23, 0x8000170C, 0x00000000 },
101 { &GUID_Key, 24, 0x8000180C, 0x00000000 },
102 { &GUID_Key, 25, 0x8000190C, 0x00000000 },
103 { &GUID_Key, 26, 0x80001A0C, 0x00000000 },
104 { &GUID_Key, 27, 0x80001B0C, 0x00000000 },
105 { &GUID_Key, 28, 0x80001C0C, 0x00000000 },
106 { &GUID_Key, 29, 0x80001D0C, 0x00000000 },
107 { &GUID_Key, 30, 0x80001E0C, 0x00000000 },
108 { &GUID_Key, 31, 0x80001F0C, 0x00000000 },
109 { &GUID_Key, 32, 0x8000200C, 0x00000000 },
110 { &GUID_Key, 33, 0x8000210C, 0x00000000 },
111 { &GUID_Key, 34, 0x8000220C, 0x00000000 },
112 { &GUID_Key, 35, 0x8000230C, 0x00000000 },
113 { &GUID_Key, 36, 0x8000240C, 0x00000000 },
114 { &GUID_Key, 37, 0x8000250C, 0x00000000 },
115 { &GUID_Key, 38, 0x8000260C, 0x00000000 },
116 { &GUID_Key, 39, 0x8000270C, 0x00000000 },
117 { &GUID_Key, 40, 0x8000280C, 0x00000000 },
118 { &GUID_Key, 41, 0x8000290C, 0x00000000 },
119 { &GUID_Key, 42, 0x80002A0C, 0x00000000 },
120 { &GUID_Key, 43, 0x80002B0C, 0x00000000 },
121 { &GUID_Key, 44, 0x80002C0C, 0x00000000 },
122 { &GUID_Key, 45, 0x80002D0C, 0x00000000 },
123 { &GUID_Key, 46, 0x80002E0C, 0x00000000 },
124 { &GUID_Key, 47, 0x80002F0C, 0x00000000 },
125 { &GUID_Key, 48, 0x8000300C, 0x00000000 },
126 { &GUID_Key, 49, 0x8000310C, 0x00000000 },
127 { &GUID_Key, 50, 0x8000320C, 0x00000000 },
128 { &GUID_Key, 51, 0x8000330C, 0x00000000 },
129 { &GUID_Key, 52, 0x8000340C, 0x00000000 },
130 { &GUID_Key, 53, 0x8000350C, 0x00000000 },
131 { &GUID_Key, 54, 0x8000360C, 0x00000000 },
132 { &GUID_Key, 55, 0x8000370C, 0x00000000 },
133 { &GUID_Key, 56, 0x8000380C, 0x00000000 },
134 { &GUID_Key, 57, 0x8000390C, 0x00000000 },
135 { &GUID_Key, 58, 0x80003A0C, 0x00000000 },
136 { &GUID_Key, 59, 0x80003B0C, 0x00000000 },
137 { &GUID_Key, 60, 0x80003C0C, 0x00000000 },
138 { &GUID_Key, 61, 0x80003D0C, 0x00000000 },
139 { &GUID_Key, 62, 0x80003E0C, 0x00000000 },
140 { &GUID_Key, 63, 0x80003F0C, 0x00000000 },
141 { &GUID_Key, 64, 0x8000400C, 0x00000000 },
142 { &GUID_Key, 65, 0x8000410C, 0x00000000 },
143 { &GUID_Key, 66, 0x8000420C, 0x00000000 },
144 { &GUID_Key, 67, 0x8000430C, 0x00000000 },
145 { &GUID_Key, 68, 0x8000440C, 0x00000000 },
146 { &GUID_Key, 69, 0x8000450C, 0x00000000 },
147 { &GUID_Key, 70, 0x8000460C, 0x00000000 },
148 { &GUID_Key, 71, 0x8000470C, 0x00000000 },
149 { &GUID_Key, 72, 0x8000480C, 0x00000000 },
150 { &GUID_Key, 73, 0x8000490C, 0x00000000 },
151 { &GUID_Key, 74, 0x80004A0C, 0x00000000 },
152 { &GUID_Key, 75, 0x80004B0C, 0x00000000 },
153 { &GUID_Key, 76, 0x80004C0C, 0x00000000 },
154 { &GUID_Key, 77, 0x80004D0C, 0x00000000 },
155 { &GUID_Key, 78, 0x80004E0C, 0x00000000 },
156 { &GUID_Key, 79, 0x80004F0C, 0x00000000 },
157 { &GUID_Key, 80, 0x8000500C, 0x00000000 },
158 { &GUID_Key, 81, 0x8000510C, 0x00000000 },
159 { &GUID_Key, 82, 0x8000520C, 0x00000000 },
160 { &GUID_Key, 83, 0x8000530C, 0x00000000 },
161 { &GUID_Key, 84, 0x8000540C, 0x00000000 },
162 { &GUID_Key, 85, 0x8000550C, 0x00000000 },
163 { &GUID_Key, 86, 0x8000560C, 0x00000000 },
164 { &GUID_Key, 87, 0x8000570C, 0x00000000 },
165 { &GUID_Key, 88, 0x8000580C, 0x00000000 },
166 { &GUID_Key, 89, 0x8000590C, 0x00000000 },
167 { &GUID_Key, 90, 0x80005A0C, 0x00000000 },
168 { &GUID_Key, 91, 0x80005B0C, 0x00000000 },
169 { &GUID_Key, 92, 0x80005C0C, 0x00000000 },
170 { &GUID_Key, 93, 0x80005D0C, 0x00000000 },
171 { &GUID_Key, 94, 0x80005E0C, 0x00000000 },
172 { &GUID_Key, 95, 0x80005F0C, 0x00000000 },
173 { &GUID_Key, 96, 0x8000600C, 0x00000000 },
174 { &GUID_Key, 97, 0x8000610C, 0x00000000 },
175 { &GUID_Key, 98, 0x8000620C, 0x00000000 },
176 { &GUID_Key, 99, 0x8000630C, 0x00000000 },
177 { &GUID_Key, 100, 0x8000640C, 0x00000000 },
178 { &GUID_Key, 101, 0x8000650C, 0x00000000 },
179 { &GUID_Key, 102, 0x8000660C, 0x00000000 },
180 { &GUID_Key, 103, 0x8000670C, 0x00000000 },
181 { &GUID_Key, 104, 0x8000680C, 0x00000000 },
182 { &GUID_Key, 105, 0x8000690C, 0x00000000 },
183 { &GUID_Key, 106, 0x80006A0C, 0x00000000 },
184 { &GUID_Key, 107, 0x80006B0C, 0x00000000 },
185 { &GUID_Key, 108, 0x80006C0C, 0x00000000 },
186 { &GUID_Key, 109, 0x80006D0C, 0x00000000 },
187 { &GUID_Key, 110, 0x80006E0C, 0x00000000 },
188 { &GUID_Key, 111, 0x80006F0C, 0x00000000 },
189 { &GUID_Key, 112, 0x8000700C, 0x00000000 },
190 { &GUID_Key, 113, 0x8000710C, 0x00000000 },
191 { &GUID_Key, 114, 0x8000720C, 0x00000000 },
192 { &GUID_Key, 115, 0x8000730C, 0x00000000 },
193 { &GUID_Key, 116, 0x8000740C, 0x00000000 },
194 { &GUID_Key, 117, 0x8000750C, 0x00000000 },
195 { &GUID_Key, 118, 0x8000760C, 0x00000000 },
196 { &GUID_Key, 119, 0x8000770C, 0x00000000 },
197 { &GUID_Key, 120, 0x8000780C, 0x00000000 },
198 { &GUID_Key, 121, 0x8000790C, 0x00000000 },
199 { &GUID_Key, 122, 0x80007A0C, 0x00000000 },
200 { &GUID_Key, 123, 0x80007B0C, 0x00000000 },
201 { &GUID_Key, 124, 0x80007C0C, 0x00000000 },
202 { &GUID_Key, 125, 0x80007D0C, 0x00000000 },
203 { &GUID_Key, 126, 0x80007E0C, 0x00000000 },
204 { &GUID_Key, 127, 0x80007F0C, 0x00000000 },
205 { &GUID_Key, 128, 0x8000800C, 0x00000000 },
206 { &GUID_Key, 129, 0x8000810C, 0x00000000 },
207 { &GUID_Key, 130, 0x8000820C, 0x00000000 },
208 { &GUID_Key, 131, 0x8000830C, 0x00000000 },
209 { &GUID_Key, 132, 0x8000840C, 0x00000000 },
210 { &GUID_Key, 133, 0x8000850C, 0x00000000 },
211 { &GUID_Key, 134, 0x8000860C, 0x00000000 },
212 { &GUID_Key, 135, 0x8000870C, 0x00000000 },
213 { &GUID_Key, 136, 0x8000880C, 0x00000000 },
214 { &GUID_Key, 137, 0x8000890C, 0x00000000 },
215 { &GUID_Key, 138, 0x80008A0C, 0x00000000 },
216 { &GUID_Key, 139, 0x80008B0C, 0x00000000 },
217 { &GUID_Key, 140, 0x80008C0C, 0x00000000 },
218 { &GUID_Key, 141, 0x80008D0C, 0x00000000 },
219 { &GUID_Key, 142, 0x80008E0C, 0x00000000 },
220 { &GUID_Key, 143, 0x80008F0C, 0x00000000 },
221 { &GUID_Key, 144, 0x8000900C, 0x00000000 },
222 { &GUID_Key, 145, 0x8000910C, 0x00000000 },
223 { &GUID_Key, 146, 0x8000920C, 0x00000000 },
224 { &GUID_Key, 147, 0x8000930C, 0x00000000 },
225 { &GUID_Key, 148, 0x8000940C, 0x00000000 },
226 { &GUID_Key, 149, 0x8000950C, 0x00000000 },
227 { &GUID_Key, 150, 0x8000960C, 0x00000000 },
228 { &GUID_Key, 151, 0x8000970C, 0x00000000 },
229 { &GUID_Key, 152, 0x8000980C, 0x00000000 },
230 { &GUID_Key, 153, 0x8000990C, 0x00000000 },
231 { &GUID_Key, 154, 0x80009A0C, 0x00000000 },
232 { &GUID_Key, 155, 0x80009B0C, 0x00000000 },
233 { &GUID_Key, 156, 0x80009C0C, 0x00000000 },
234 { &GUID_Key, 157, 0x80009D0C, 0x00000000 },
235 { &GUID_Key, 158, 0x80009E0C, 0x00000000 },
236 { &GUID_Key, 159, 0x80009F0C, 0x00000000 },
237 { &GUID_Key, 160, 0x8000A00C, 0x00000000 },
238 { &GUID_Key, 161, 0x8000A10C, 0x00000000 },
239 { &GUID_Key, 162, 0x8000A20C, 0x00000000 },
240 { &GUID_Key, 163, 0x8000A30C, 0x00000000 },
241 { &GUID_Key, 164, 0x8000A40C, 0x00000000 },
242 { &GUID_Key, 165, 0x8000A50C, 0x00000000 },
243 { &GUID_Key, 166, 0x8000A60C, 0x00000000 },
244 { &GUID_Key, 167, 0x8000A70C, 0x00000000 },
245 { &GUID_Key, 168, 0x8000A80C, 0x00000000 },
246 { &GUID_Key, 169, 0x8000A90C, 0x00000000 },
247 { &GUID_Key, 170, 0x8000AA0C, 0x00000000 },
248 { &GUID_Key, 171, 0x8000AB0C, 0x00000000 },
249 { &GUID_Key, 172, 0x8000AC0C, 0x00000000 },
250 { &GUID_Key, 173, 0x8000AD0C, 0x00000000 },
251 { &GUID_Key, 174, 0x8000AE0C, 0x00000000 },
252 { &GUID_Key, 175, 0x8000AF0C, 0x00000000 },
253 { &GUID_Key, 176, 0x8000B00C, 0x00000000 },
254 { &GUID_Key, 177, 0x8000B10C, 0x00000000 },
255 { &GUID_Key, 178, 0x8000B20C, 0x00000000 },
256 { &GUID_Key, 179, 0x8000B30C, 0x00000000 },
257 { &GUID_Key, 180, 0x8000B40C, 0x00000000 },
258 { &GUID_Key, 181, 0x8000B50C, 0x00000000 },
259 { &GUID_Key, 182, 0x8000B60C, 0x00000000 },
260 { &GUID_Key, 183, 0x8000B70C, 0x00000000 },
261 { &GUID_Key, 184, 0x8000B80C, 0x00000000 },
262 { &GUID_Key, 185, 0x8000B90C, 0x00000000 },
263 { &GUID_Key, 186, 0x8000BA0C, 0x00000000 },
264 { &GUID_Key, 187, 0x8000BB0C, 0x00000000 },
265 { &GUID_Key, 188, 0x8000BC0C, 0x00000000 },
266 { &GUID_Key, 189, 0x8000BD0C, 0x00000000 },
267 { &GUID_Key, 190, 0x8000BE0C, 0x00000000 },
268 { &GUID_Key, 191, 0x8000BF0C, 0x00000000 },
269 { &GUID_Key, 192, 0x8000C00C, 0x00000000 },
270 { &GUID_Key, 193, 0x8000C10C, 0x00000000 },
271 { &GUID_Key, 194, 0x8000C20C, 0x00000000 },
272 { &GUID_Key, 195, 0x8000C30C, 0x00000000 },
273 { &GUID_Key, 196, 0x8000C40C, 0x00000000 },
274 { &GUID_Key, 197, 0x8000C50C, 0x00000000 },
275 { &GUID_Key, 198, 0x8000C60C, 0x00000000 },
276 { &GUID_Key, 199, 0x8000C70C, 0x00000000 },
277 { &GUID_Key, 200, 0x8000C80C, 0x00000000 },
278 { &GUID_Key, 201, 0x8000C90C, 0x00000000 },
279 { &GUID_Key, 202, 0x8000CA0C, 0x00000000 },
280 { &GUID_Key, 203, 0x8000CB0C, 0x00000000 },
281 { &GUID_Key, 204, 0x8000CC0C, 0x00000000 },
282 { &GUID_Key, 205, 0x8000CD0C, 0x00000000 },
283 { &GUID_Key, 206, 0x8000CE0C, 0x00000000 },
284 { &GUID_Key, 207, 0x8000CF0C, 0x00000000 },
285 { &GUID_Key, 208, 0x8000D00C, 0x00000000 },
286 { &GUID_Key, 209, 0x8000D10C, 0x00000000 },
287 { &GUID_Key, 210, 0x8000D20C, 0x00000000 },
288 { &GUID_Key, 211, 0x8000D30C, 0x00000000 },
289 { &GUID_Key, 212, 0x8000D40C, 0x00000000 },
290 { &GUID_Key, 213, 0x8000D50C, 0x00000000 },
291 { &GUID_Key, 214, 0x8000D60C, 0x00000000 },
292 { &GUID_Key, 215, 0x8000D70C, 0x00000000 },
293 { &GUID_Key, 216, 0x8000D80C, 0x00000000 },
294 { &GUID_Key, 217, 0x8000D90C, 0x00000000 },
295 { &GUID_Key, 218, 0x8000DA0C, 0x00000000 },
296 { &GUID_Key, 219, 0x8000DB0C, 0x00000000 },
297 { &GUID_Key, 220, 0x8000DC0C, 0x00000000 },
298 { &GUID_Key, 221, 0x8000DD0C, 0x00000000 },
299 { &GUID_Key, 222, 0x8000DE0C, 0x00000000 },
300 { &GUID_Key, 223, 0x8000DF0C, 0x00000000 },
301 { &GUID_Key, 224, 0x8000E00C, 0x00000000 },
302 { &GUID_Key, 225, 0x8000E10C, 0x00000000 },
303 { &GUID_Key, 226, 0x8000E20C, 0x00000000 },
304 { &GUID_Key, 227, 0x8000E30C, 0x00000000 },
305 { &GUID_Key, 228, 0x8000E40C, 0x00000000 },
306 { &GUID_Key, 229, 0x8000E50C, 0x00000000 },
307 { &GUID_Key, 230, 0x8000E60C, 0x00000000 },
308 { &GUID_Key, 231, 0x8000E70C, 0x00000000 },
309 { &GUID_Key, 232, 0x8000E80C, 0x00000000 },
310 { &GUID_Key, 233, 0x8000E90C, 0x00000000 },
311 { &GUID_Key, 234, 0x8000EA0C, 0x00000000 },
312 { &GUID_Key, 235, 0x8000EB0C, 0x00000000 },
313 { &GUID_Key, 236, 0x8000EC0C, 0x00000000 },
314 { &GUID_Key, 237, 0x8000ED0C, 0x00000000 },
315 { &GUID_Key, 238, 0x8000EE0C, 0x00000000 },
316 { &GUID_Key, 239, 0x8000EF0C, 0x00000000 },
317 { &GUID_Key, 240, 0x8000F00C, 0x00000000 },
318 { &GUID_Key, 241, 0x8000F10C, 0x00000000 },
319 { &GUID_Key, 242, 0x8000F20C, 0x00000000 },
320 { &GUID_Key, 243, 0x8000F30C, 0x00000000 },
321 { &GUID_Key, 244, 0x8000F40C, 0x00000000 },
322 { &GUID_Key, 245, 0x8000F50C, 0x00000000 },
323 { &GUID_Key, 246, 0x8000F60C, 0x00000000 },
324 { &GUID_Key, 247, 0x8000F70C, 0x00000000 },
325 { &GUID_Key, 248, 0x8000F80C, 0x00000000 },
326 { &GUID_Key, 249, 0x8000F90C, 0x00000000 },
327 { &GUID_Key, 250, 0x8000FA0C, 0x00000000 },
328 { &GUID_Key, 251, 0x8000FB0C, 0x00000000 },
329 { &GUID_Key, 252, 0x8000FC0C, 0x00000000 },
330 { &GUID_Key, 253, 0x8000FD0C, 0x00000000 },
331 { &GUID_Key, 254, 0x8000FE0C, 0x00000000 },
332 { &GUID_Key, 255, 0x8000FF0C, 0x00000000 },
333};
334
335const DIDATAFORMAT c_dfDIKeyboard = { sizeof(DIDATAFORMAT), sizeof(DIOBJECTDATAFORMAT), 0x00000002, 256, 256, KBD_fmt };
336
337
338/* Mouse */
339
340static DIOBJECTDATAFORMAT PTR_fmt[] = {
341 { &GUID_XAxis, 0, 0x00FFFF03, 0x00000000 },
342 { &GUID_YAxis, 4, 0x00FFFF03, 0x00000000 },
343 { &GUID_ZAxis, 8, 0x80FFFF03, 0x00000000 },
344 { NULL, 12, 0x00FFFF0C, 0x00000000 },
345 { NULL, 13, 0x00FFFF0C, 0x00000000 },
346 { NULL, 14, 0x80FFFF0C, 0x00000000 },
347 { NULL, 15, 0x80FFFF0C, 0x00000000 },
348};
349
350const DIDATAFORMAT c_dfDIMouse = { sizeof(DIDATAFORMAT), sizeof(DIOBJECTDATAFORMAT), 0x00000002, 16, 7, PTR_fmt };
351
352static DIOBJECTDATAFORMAT PTR2_fmt[] = {
353 { &GUID_XAxis, 0, 0x00FFFF03, 0x00000000 },
354 { &GUID_YAxis, 4, 0x00FFFF03, 0x00000000 },
355 { &GUID_ZAxis, 8, 0x80FFFF03, 0x00000000 },
356 { NULL, 12, 0x00FFFF0C, 0x00000000 },
357 { NULL, 13, 0x00FFFF0C, 0x00000000 },
358 { NULL, 14, 0x80FFFF0C, 0x00000000 },
359 { NULL, 15, 0x80FFFF0C, 0x00000000 },
360 { NULL, 16, 0x80FFFF0C, 0x00000000 },
361 { NULL, 17, 0x80FFFF0C, 0x00000000 },
362 { NULL, 18, 0x80FFFF0C, 0x00000000 },
363 { NULL, 19, 0x80FFFF0C, 0x00000000 }
364};
365
366const DIDATAFORMAT c_dfDIMouse2 = { sizeof(DIDATAFORMAT), sizeof(DIOBJECTDATAFORMAT), 0x00000002, 20, 11, PTR2_fmt };
367
368
369/* Joystick */
370
371static DIOBJECTDATAFORMAT JOY_fmt[] = {
372 { &GUID_XAxis, 0, 0x80FFFF03, 0x00000100 },
373 { &GUID_YAxis, 4, 0x80FFFF03, 0x00000100 },
374 { &GUID_ZAxis, 8, 0x80FFFF03, 0x00000100 },
375 { &GUID_RxAxis, 12, 0x80FFFF03, 0x00000100 },
376 { &GUID_RyAxis, 16, 0x80FFFF03, 0x00000100 },
377 { &GUID_RzAxis, 20, 0x80FFFF03, 0x00000100 },
378 { &GUID_Slider, 24, 0x80FFFF03, 0x00000100 },
379 { &GUID_Slider, 28, 0x80FFFF03, 0x00000100 },
380 { &GUID_POV, 32, 0x80FFFF10, 0x00000000 },
381 { &GUID_POV, 36, 0x80FFFF10, 0x00000000 },
382 { &GUID_POV, 40, 0x80FFFF10, 0x00000000 },
383 { &GUID_POV, 44, 0x80FFFF10, 0x00000000 },
384 { NULL, 48, 0x80FFFF0C, 0x00000000 },
385 { NULL, 49, 0x80FFFF0C, 0x00000000 },
386 { NULL, 50, 0x80FFFF0C, 0x00000000 },
387 { NULL, 51, 0x80FFFF0C, 0x00000000 },
388 { NULL, 52, 0x80FFFF0C, 0x00000000 },
389 { NULL, 53, 0x80FFFF0C, 0x00000000 },
390 { NULL, 54, 0x80FFFF0C, 0x00000000 },
391 { NULL, 55, 0x80FFFF0C, 0x00000000 },
392 { NULL, 56, 0x80FFFF0C, 0x00000000 },
393 { NULL, 57, 0x80FFFF0C, 0x00000000 },
394 { NULL, 58, 0x80FFFF0C, 0x00000000 },
395 { NULL, 59, 0x80FFFF0C, 0x00000000 },
396 { NULL, 60, 0x80FFFF0C, 0x00000000 },
397 { NULL, 61, 0x80FFFF0C, 0x00000000 },
398 { NULL, 62, 0x80FFFF0C, 0x00000000 },
399 { NULL, 63, 0x80FFFF0C, 0x00000000 },
400 { NULL, 64, 0x80FFFF0C, 0x00000000 },
401 { NULL, 65, 0x80FFFF0C, 0x00000000 },
402 { NULL, 66, 0x80FFFF0C, 0x00000000 },
403 { NULL, 67, 0x80FFFF0C, 0x00000000 },
404 { NULL, 68, 0x80FFFF0C, 0x00000000 },
405 { NULL, 69, 0x80FFFF0C, 0x00000000 },
406 { NULL, 70, 0x80FFFF0C, 0x00000000 },
407 { NULL, 71, 0x80FFFF0C, 0x00000000 },
408 { NULL, 72, 0x80FFFF0C, 0x00000000 },
409 { NULL, 73, 0x80FFFF0C, 0x00000000 },
410 { NULL, 74, 0x80FFFF0C, 0x00000000 },
411 { NULL, 75, 0x80FFFF0C, 0x00000000 },
412 { NULL, 76, 0x80FFFF0C, 0x00000000 },
413 { NULL, 77, 0x80FFFF0C, 0x00000000 },
414 { NULL, 78, 0x80FFFF0C, 0x00000000 },
415 { NULL, 79, 0x80FFFF0C, 0x00000000 },
416};
417
418const DIDATAFORMAT c_dfDIJoystick = { sizeof(DIDATAFORMAT), sizeof(DIOBJECTDATAFORMAT), 0x00000001, 80, 44, JOY_fmt };
419
420
421/* Initialization/Query functions */
422static int DX5_VideoInit(_THIS, SDL_PixelFormat *vformat);
423static SDL_Rect **DX5_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
424static SDL_Surface *DX5_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
425static int DX5_SetColors(_THIS, int firstcolor, int ncolors,
426 SDL_Color *colors);
427static int DX5_SetGammaRamp(_THIS, Uint16 *ramp);
428static int DX5_GetGammaRamp(_THIS, Uint16 *ramp);
429static void DX5_VideoQuit(_THIS);
430
431/* Hardware surface functions */
432static int DX5_AllocHWSurface(_THIS, SDL_Surface *surface);
433static int DX5_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst);
434static int DX5_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color);
435static int DX5_SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key);
436static int DX5_SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 alpha);
437static int DX5_LockHWSurface(_THIS, SDL_Surface *surface);
438static void DX5_UnlockHWSurface(_THIS, SDL_Surface *surface);
439static int DX5_FlipHWSurface(_THIS, SDL_Surface *surface);
440static void DX5_FreeHWSurface(_THIS, SDL_Surface *surface);
441
442static int DX5_AllocDDSurface(_THIS, SDL_Surface *surface,
443 LPDIRECTDRAWSURFACE3 requested, Uint32 flag);
444
445/* Windows message handling functions */
446static void DX5_Activate(_THIS, BOOL active, BOOL minimized);
447static void DX5_RealizePalette(_THIS);
448static void DX5_PaletteChanged(_THIS, HWND window);
449static void DX5_WinPAINT(_THIS, HDC hdc);
450
451/* WinDIB driver functions for manipulating gamma ramps */
452extern int DIB_SetGammaRamp(_THIS, Uint16 *ramp);
453extern int DIB_GetGammaRamp(_THIS, Uint16 *ramp);
454extern void DIB_QuitGamma(_THIS);
455
456/* DX5 driver bootstrap functions */
457
458static int DX5_Available(void)
459{
460 HINSTANCE DInputDLL;
461 HINSTANCE DDrawDLL;
462 int dinput_ok;
463 int ddraw_ok;
464
465 /* Version check DINPUT.DLL and DDRAW.DLL (Is DirectX okay?) */
466 dinput_ok = 0;
467 DInputDLL = LoadLibrary(TEXT("DINPUT.DLL"));
468 if ( DInputDLL != NULL ) {
469 dinput_ok = 1;
470 FreeLibrary(DInputDLL);
471 }
472 ddraw_ok = 0;
473 DDrawDLL = LoadLibrary(TEXT("DDRAW.DLL"));
474 if ( DDrawDLL != NULL ) {
475 HRESULT (WINAPI *DDrawCreate)(GUID *,LPDIRECTDRAW *,IUnknown *);
476 LPDIRECTDRAW DDraw;
477
478 /* Try to create a valid DirectDraw object */
479 DDrawCreate = (void *)GetProcAddress(DDrawDLL, TEXT("DirectDrawCreate"));
480 if ( (DDrawCreate != NULL)
481 && !FAILED(DDrawCreate(NULL, &DDraw, NULL)) ) {
482 if ( !FAILED(IDirectDraw_SetCooperativeLevel(DDraw,
483 NULL, DDSCL_NORMAL)) ) {
484 DDSURFACEDESC desc;
485 LPDIRECTDRAWSURFACE DDrawSurf;
486 LPDIRECTDRAWSURFACE3 DDrawSurf3;
487
488 /* Try to create a DirectDrawSurface3 object */
489 SDL_memset(&desc, 0, sizeof(desc));
490 desc.dwSize = sizeof(desc);
491 desc.dwFlags = DDSD_CAPS;
492 desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE|DDSCAPS_VIDEOMEMORY;
493 if ( !FAILED(IDirectDraw_CreateSurface(DDraw, &desc,
494 &DDrawSurf, NULL)) ) {
495 if ( !FAILED(IDirectDrawSurface_QueryInterface(DDrawSurf,
496 &IID_IDirectDrawSurface3, (LPVOID *)&DDrawSurf3)) ) {
497 /* Yay! */
498 ddraw_ok = 1;
499
500 /* Clean up.. */
501 IDirectDrawSurface3_Release(DDrawSurf3);
502 }
503 IDirectDrawSurface_Release(DDrawSurf);
504 }
505 }
506 IDirectDraw_Release(DDraw);
507 }
508 FreeLibrary(DDrawDLL);
509 }
510 return(dinput_ok && ddraw_ok);
511}
512
513/* Functions for loading the DirectX functions dynamically */
514static HINSTANCE DDrawDLL = NULL;
515static HINSTANCE DInputDLL = NULL;
516
517static void DX5_Unload(void)
518{
519 if ( DDrawDLL != NULL ) {
520 FreeLibrary(DDrawDLL);
521 DDrawCreate = NULL;
522 DDrawDLL = NULL;
523 }
524 if ( DInputDLL != NULL ) {
525 FreeLibrary(DInputDLL);
526 DInputCreate = NULL;
527 DInputDLL = NULL;
528 }
529}
530static int DX5_Load(void)
531{
532 int status;
533
534 DX5_Unload();
535 DDrawDLL = LoadLibrary(TEXT("DDRAW.DLL"));
536 if ( DDrawDLL != NULL ) {
537 DDrawCreate = (void *)GetProcAddress(DDrawDLL,
538 TEXT("DirectDrawCreate"));
539 }
540 DInputDLL = LoadLibrary(TEXT("DINPUT.DLL"));
541 if ( DInputDLL != NULL ) {
542 DInputCreate = (void *)GetProcAddress(DInputDLL,
543 TEXT("DirectInputCreateA"));
544 }
545 if ( DDrawDLL && DDrawCreate && DInputDLL && DInputCreate ) {
546 status = 0;
547 } else {
548 DX5_Unload();
549 status = -1;
550 }
551 return status;
552}
553
554static void DX5_DeleteDevice(SDL_VideoDevice *this)
555{
556 /* Free DirectDraw object */
557 if ( ddraw2 != NULL ) {
558 IDirectDraw2_Release(ddraw2);
559 }
560 DX5_Unload();
561 if ( this ) {
562 if ( this->hidden ) {
563 SDL_free(this->hidden);
564 }
565 if ( this->gl_data ) {
566 SDL_free(this->gl_data);
567 }
568 SDL_free(this);
569 }
570}
571
572static SDL_VideoDevice *DX5_CreateDevice(int devindex)
573{
574 SDL_VideoDevice *device;
575
576 /* Load DirectX */
577 if ( DX5_Load() < 0 ) {
578 return(NULL);
579 }
580
581 /* Initialize all variables that we clean on shutdown */
582 device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
583 if ( device ) {
584 SDL_memset(device, 0, (sizeof *device));
585 device->hidden = (struct SDL_PrivateVideoData *)
586 SDL_malloc((sizeof *device->hidden));
587 device->gl_data = (struct SDL_PrivateGLData *)
588 SDL_malloc((sizeof *device->gl_data));
589 }
590 if ( (device == NULL) || (device->hidden == NULL) ||
591 (device->gl_data == NULL) ) {
592 SDL_OutOfMemory();
593 DX5_DeleteDevice(device);
594 return(NULL);
595 }
596 SDL_memset(device->hidden, 0, (sizeof *device->hidden));
597 SDL_memset(device->gl_data, 0, (sizeof *device->gl_data));
598
599 /* Set the function pointers */
600 device->VideoInit = DX5_VideoInit;
601 device->ListModes = DX5_ListModes;
602 device->SetVideoMode = DX5_SetVideoMode;
603 device->UpdateMouse = WIN_UpdateMouse;
604 device->CreateYUVOverlay = DX5_CreateYUVOverlay;
605 device->SetColors = DX5_SetColors;
606 device->UpdateRects = NULL;
607 device->VideoQuit = DX5_VideoQuit;
608 device->AllocHWSurface = DX5_AllocHWSurface;
609 device->CheckHWBlit = DX5_CheckHWBlit;
610 device->FillHWRect = DX5_FillHWRect;
611 device->SetHWColorKey = DX5_SetHWColorKey;
612 device->SetHWAlpha = DX5_SetHWAlpha;
613 device->LockHWSurface = DX5_LockHWSurface;
614 device->UnlockHWSurface = DX5_UnlockHWSurface;
615 device->FlipHWSurface = DX5_FlipHWSurface;
616 device->FreeHWSurface = DX5_FreeHWSurface;
617 device->SetGammaRamp = DX5_SetGammaRamp;
618 device->GetGammaRamp = DX5_GetGammaRamp;
619#if SDL_VIDEO_OPENGL
620 device->GL_LoadLibrary = WIN_GL_LoadLibrary;
621 device->GL_GetProcAddress = WIN_GL_GetProcAddress;
622 device->GL_GetAttribute = WIN_GL_GetAttribute;
623 device->GL_MakeCurrent = WIN_GL_MakeCurrent;
624 device->GL_SwapBuffers = WIN_GL_SwapBuffers;
625#endif
626 device->SetCaption = WIN_SetWMCaption;
627 device->SetIcon = WIN_SetWMIcon;
628 device->IconifyWindow = WIN_IconifyWindow;
629 device->GrabInput = WIN_GrabInput;
630 device->GetWMInfo = WIN_GetWMInfo;
631 device->FreeWMCursor = WIN_FreeWMCursor;
632 device->CreateWMCursor = WIN_CreateWMCursor;
633 device->ShowWMCursor = WIN_ShowWMCursor;
634 device->WarpWMCursor = WIN_WarpWMCursor;
635 device->CheckMouseMode = WIN_CheckMouseMode;
636 device->InitOSKeymap = DX5_InitOSKeymap;
637 device->PumpEvents = DX5_PumpEvents;
638
639 /* Set up the windows message handling functions */
640 WIN_Activate = DX5_Activate;
641 WIN_RealizePalette = DX5_RealizePalette;
642 WIN_PaletteChanged = DX5_PaletteChanged;
643 WIN_WinPAINT = DX5_WinPAINT;
644 HandleMessage = DX5_HandleMessage;
645
646 device->free = DX5_DeleteDevice;
647
648 /* We're finally ready */
649 return device;
650}
651
652VideoBootStrap DIRECTX_bootstrap = {
653 "directx", "Win95/98/2000 DirectX",
654 DX5_Available, DX5_CreateDevice
655};
656
657static int cmpmodes(const void *va, const void *vb)
658{
659 SDL_Rect *a = *(SDL_Rect **)va;
660 SDL_Rect *b = *(SDL_Rect **)vb;
661 if ( a->w == b->w )
662 return b->h - a->h;
663 else
664 return b->w - a->w;
665}
666
667static HRESULT WINAPI EnumModes2(DDSURFACEDESC *desc, VOID *udata)
668{
669 SDL_VideoDevice *this = (SDL_VideoDevice *)udata;
670 struct DX5EnumRect *enumrect;
671#if defined(NONAMELESSUNION)
672 int bpp = desc->ddpfPixelFormat.u1.dwRGBBitCount;
673 int refreshRate = desc->u2.dwRefreshRate;
674#else
675 int bpp = desc->ddpfPixelFormat.dwRGBBitCount;
676 int refreshRate = desc->dwRefreshRate;
677#endif
678 int maxRefreshRate;
679
680 if ( desc->dwWidth <= SDL_desktop_mode.dmPelsWidth &&
681 desc->dwHeight <= SDL_desktop_mode.dmPelsHeight ) {
682 maxRefreshRate = SDL_desktop_mode.dmDisplayFrequency;
683 } else {
684 maxRefreshRate = 85; /* safe value? */
685 }
686
687 switch (bpp) {
688 case 8:
689 case 16:
690 case 24:
691 case 32:
692 bpp /= 8; --bpp;
693 if ( enumlists[bpp] &&
694 enumlists[bpp]->r.w == (Uint16)desc->dwWidth &&
695 enumlists[bpp]->r.h == (Uint16)desc->dwHeight ) {
696 if ( refreshRate > enumlists[bpp]->refreshRate &&
697 refreshRate <= maxRefreshRate ) {
698 enumlists[bpp]->refreshRate = refreshRate;
699#ifdef DDRAW_DEBUG
700 fprintf(stderr, "New refresh rate for %d bpp: %dx%d at %d Hz\n", (bpp+1)*8, (int)desc->dwWidth, (int)desc->dwHeight, refreshRate);
701#endif
702 }
703 break;
704 }
705 ++SDL_nummodes[bpp];
706 enumrect = (struct DX5EnumRect*)SDL_malloc(sizeof(struct DX5EnumRect));
707 if ( !enumrect ) {
708 SDL_OutOfMemory();
709 return(DDENUMRET_CANCEL);
710 }
711 enumrect->refreshRate = refreshRate;
712 enumrect->r.x = 0;
713 enumrect->r.y = 0;
714 enumrect->r.w = (Uint16)desc->dwWidth;
715 enumrect->r.h = (Uint16)desc->dwHeight;
716 enumrect->next = enumlists[bpp];
717 enumlists[bpp] = enumrect;
718#ifdef DDRAW_DEBUG
719 fprintf(stderr, "New mode for %d bpp: %dx%d at %d Hz\n", (bpp+1)*8, (int)desc->dwWidth, (int)desc->dwHeight, refreshRate);
720#endif
721 break;
722 }
723
724 return(DDENUMRET_OK);
725}
726
727void SetDDerror(const char *function, int code)
728{
729 static char *error;
730 static char errbuf[1024];
731
732 errbuf[0] = 0;
733 switch (code) {
734 case DDERR_GENERIC:
735 error = "Undefined error!";
736 break;
737 case DDERR_EXCEPTION:
738 error = "Exception encountered";
739 break;
740 case DDERR_INVALIDOBJECT:
741 error = "Invalid object";
742 break;
743 case DDERR_INVALIDPARAMS:
744 error = "Invalid parameters";
745 break;
746 case DDERR_NOTFOUND:
747 error = "Object not found";
748 break;
749 case DDERR_INVALIDRECT:
750 error = "Invalid rectangle";
751 break;
752 case DDERR_INVALIDCAPS:
753 error = "Invalid caps member";
754 break;
755 case DDERR_INVALIDPIXELFORMAT:
756 error = "Invalid pixel format";
757 break;
758 case DDERR_OUTOFMEMORY:
759 error = "Out of memory";
760 break;
761 case DDERR_OUTOFVIDEOMEMORY:
762 error = "Out of video memory";
763 break;
764 case DDERR_SURFACEBUSY:
765 error = "Surface busy";
766 break;
767 case DDERR_SURFACELOST:
768 error = "Surface was lost";
769 break;
770 case DDERR_WASSTILLDRAWING:
771 error = "DirectDraw is still drawing";
772 break;
773 case DDERR_INVALIDSURFACETYPE:
774 error = "Invalid surface type";
775 break;
776 case DDERR_NOEXCLUSIVEMODE:
777 error = "Not in exclusive access mode";
778 break;
779 case DDERR_NOPALETTEATTACHED:
780 error = "No palette attached";
781 break;
782 case DDERR_NOPALETTEHW:
783 error = "No palette hardware";
784 break;
785 case DDERR_NOT8BITCOLOR:
786 error = "Not 8-bit color";
787 break;
788 case DDERR_EXCLUSIVEMODEALREADYSET:
789 error = "Exclusive mode was already set";
790 break;
791 case DDERR_HWNDALREADYSET:
792 error = "Window handle already set";
793 break;
794 case DDERR_HWNDSUBCLASSED:
795 error = "Window handle is subclassed";
796 break;
797 case DDERR_NOBLTHW:
798 error = "No blit hardware";
799 break;
800 case DDERR_IMPLICITLYCREATED:
801 error = "Surface was implicitly created";
802 break;
803 case DDERR_INCOMPATIBLEPRIMARY:
804 error = "Incompatible primary surface";
805 break;
806 case DDERR_NOCOOPERATIVELEVELSET:
807 error = "No cooperative level set";
808 break;
809 case DDERR_NODIRECTDRAWHW:
810 error = "No DirectDraw hardware";
811 break;
812 case DDERR_NOEMULATION:
813 error = "No emulation available";
814 break;
815 case DDERR_NOFLIPHW:
816 error = "No flip hardware";
817 break;
818 case DDERR_NOTFLIPPABLE:
819 error = "Surface not flippable";
820 break;
821 case DDERR_PRIMARYSURFACEALREADYEXISTS:
822 error = "Primary surface already exists";
823 break;
824 case DDERR_UNSUPPORTEDMODE:
825 error = "Unsupported mode";
826 break;
827 case DDERR_WRONGMODE:
828 error = "Surface created in different mode";
829 break;
830 case DDERR_UNSUPPORTED:
831 error = "Operation not supported";
832 break;
833 case E_NOINTERFACE:
834 error = "Interface not present";
835 break;
836 default:
837 SDL_snprintf(errbuf, SDL_arraysize(errbuf),
838 "%s: Unknown DirectDraw error: 0x%x",
839 function, code);
840 break;
841 }
842 if ( ! errbuf[0] ) {
843 SDL_snprintf(errbuf, SDL_arraysize(errbuf), "%s: %s", function, error);
844 }
845 SDL_SetError("%s", errbuf);
846 return;
847}
848
849
850static int DX5_UpdateVideoInfo(_THIS)
851{
852 /* This needs to be DDCAPS_DX5 for the DirectDraw2 interface */
853#if DIRECTDRAW_VERSION <= 0x300
854#error Your version of DirectX must be greater than or equal to 5.0
855#endif
856#ifndef IDirectDrawGammaControl_SetGammaRamp
857 /*if gamma is undefined then we really have directx <= 0x500*/
858 DDCAPS DDCaps;
859#else
860 DDCAPS_DX5 DDCaps;
861#endif
862 HRESULT result;
863
864 /* Fill in our hardware acceleration capabilities */
865 SDL_memset(&DDCaps, 0, sizeof(DDCaps));
866 DDCaps.dwSize = sizeof(DDCaps);
867 result = IDirectDraw2_GetCaps(ddraw2, (DDCAPS *)&DDCaps, NULL);
868 if ( result != DD_OK ) {
869 SetDDerror("DirectDraw2::GetCaps", result);
870 return(-1);
871 }
872 this->info.hw_available = 1;
873 if ( (DDCaps.dwCaps & DDCAPS_BLT) == DDCAPS_BLT ) {
874 this->info.blit_hw = 1;
875 }
876 if ( ((DDCaps.dwCaps & DDCAPS_COLORKEY) == DDCAPS_COLORKEY) &&
877 ((DDCaps.dwCKeyCaps & DDCKEYCAPS_SRCBLT) == DDCKEYCAPS_SRCBLT) ) {
878 this->info.blit_hw_CC = 1;
879 }
880 if ( (DDCaps.dwCaps & DDCAPS_ALPHA) == DDCAPS_ALPHA ) {
881 /* This is only for alpha channel, and DirectX 6
882 doesn't support 2D alpha blits yet, so set it 0
883 */
884 this->info.blit_hw_A = 0;
885 }
886 if ( (DDCaps.dwCaps & DDCAPS_CANBLTSYSMEM) == DDCAPS_CANBLTSYSMEM ) {
887 this->info.blit_sw = 1;
888 /* This isn't necessarily true, but the HEL will cover us */
889 this->info.blit_sw_CC = this->info.blit_hw_CC;
890 this->info.blit_sw_A = this->info.blit_hw_A;
891 }
892 if ( (DDCaps.dwCaps & DDCAPS_BLTCOLORFILL) == DDCAPS_BLTCOLORFILL ) {
893 this->info.blit_fill = 1;
894 }
895
896 /* Find out how much video memory is available */
897 { DDSCAPS ddsCaps;
898 DWORD total_mem;
899 ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY;
900 result = IDirectDraw2_GetAvailableVidMem(ddraw2,
901 &ddsCaps, &total_mem, NULL);
902 if ( result != DD_OK ) {
903 total_mem = DDCaps.dwVidMemTotal;
904 }
905 this->info.video_mem = total_mem/1024;
906 }
907 return(0);
908}
909
910int DX5_VideoInit(_THIS, SDL_PixelFormat *vformat)
911{
912 HRESULT result;
913 LPDIRECTDRAW ddraw;
914 int i, j;
915 HDC hdc;
916
917 /* Intialize everything */
918 ddraw2 = NULL;
919 SDL_primary = NULL;
920 SDL_clipper = NULL;
921 SDL_palette = NULL;
922 for ( i=0; i<NUM_MODELISTS; ++i ) {
923 SDL_nummodes[i] = 0;
924 SDL_modelist[i] = NULL;
925 SDL_modeindex[i] = 0;
926 }
927 colorchange_expected = 0;
928
929 /* Create the window */
930 if ( DX5_CreateWindow(this) < 0 ) {
931 return(-1);
932 }
933
934#if !SDL_AUDIO_DISABLED
935 DX5_SoundFocus(SDL_Window);
936#endif
937
938 /* Create the DirectDraw object */
939 result = DDrawCreate(NULL, &ddraw, NULL);
940 if ( result != DD_OK ) {
941 SetDDerror("DirectDrawCreate", result);
942 return(-1);
943 }
944 result = IDirectDraw_QueryInterface(ddraw, &IID_IDirectDraw2,
945 (LPVOID *)&ddraw2);
946 IDirectDraw_Release(ddraw);
947 if ( result != DD_OK ) {
948 SetDDerror("DirectDraw::QueryInterface", result);
949 return(-1);
950 }
951
952 /* Determine the screen depth */
953 hdc = GetDC(SDL_Window);
954 vformat->BitsPerPixel = GetDeviceCaps(hdc,PLANES) *
955 GetDeviceCaps(hdc,BITSPIXEL);
956 ReleaseDC(SDL_Window, hdc);
957
958#ifndef NO_CHANGEDISPLAYSETTINGS
959 /* Query for the desktop resolution */
960 EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &SDL_desktop_mode);
961 this->info.current_w = SDL_desktop_mode.dmPelsWidth;
962 this->info.current_h = SDL_desktop_mode.dmPelsHeight;
963#endif
964
965 /* Enumerate the available fullscreen modes */
966 for ( i=0; i<NUM_MODELISTS; ++i )
967 enumlists[i] = NULL;
968
969 result = IDirectDraw2_EnumDisplayModes(ddraw2,DDEDM_REFRESHRATES,NULL,this,EnumModes2);
970 if ( result != DD_OK ) {
971 SetDDerror("DirectDraw2::EnumDisplayModes", result);
972 return(-1);
973 }
974 for ( i=0; i<NUM_MODELISTS; ++i ) {
975 struct DX5EnumRect *rect;
976 SDL_modelist[i] = (SDL_Rect **)
977 SDL_malloc((SDL_nummodes[i]+1)*sizeof(SDL_Rect *));
978 if ( SDL_modelist[i] == NULL ) {
979 SDL_OutOfMemory();
980 return(-1);
981 }
982 for ( j = 0, rect = enumlists[i]; rect; ++j, rect = rect->next ) {
983 SDL_modelist[i][j] = &rect->r;
984 }
985 SDL_modelist[i][j] = NULL;
986
987 if ( SDL_nummodes[i] > 0 ) {
988 SDL_qsort(SDL_modelist[i], SDL_nummodes[i], sizeof *SDL_modelist[i], cmpmodes);
989 }
990 }
991
992 /* Fill in some window manager capabilities */
993 this->info.wm_available = 1;
994
995 /* Fill in the video hardware capabilities */
996 DX5_UpdateVideoInfo(this);
997
998 return(0);
999}
1000
1001SDL_Rect **DX5_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
1002{
1003 int bpp;
1004
1005 bpp = format->BitsPerPixel;
1006 if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
1007 /* FIXME: No support for 1 bpp or 4 bpp formats */
1008 switch (bpp) { /* Does windows support other BPP? */
1009 case 8:
1010 case 16:
1011 case 24:
1012 case 32:
1013 bpp = (bpp/8)-1;
1014 if ( SDL_nummodes[bpp] > 0 )
1015 return(SDL_modelist[bpp]);
1016 /* Fall through */
1017 default:
1018 return((SDL_Rect **)0);
1019 }
1020 } else {
1021 if ( this->screen->format->BitsPerPixel == bpp ) {
1022 return((SDL_Rect **)-1);
1023 } else {
1024 return((SDL_Rect **)0);
1025 }
1026 }
1027}
1028
1029/* Various screen update functions available */
1030static void DX5_WindowUpdate(_THIS, int numrects, SDL_Rect *rects);
1031static void DX5_DirectUpdate(_THIS, int numrects, SDL_Rect *rects);
1032
1033SDL_Surface *DX5_SetVideoMode(_THIS, SDL_Surface *current,
1034 int width, int height, int bpp, Uint32 flags)
1035{
1036 SDL_Surface *video;
1037 int prev_w = -1;
1038 int prev_h = -1;
1039 HRESULT result;
1040 DWORD sharemode;
1041 DWORD style;
1042 const DWORD directstyle =
1043 (WS_POPUP);
1044 const DWORD windowstyle =
1045 (WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX);
1046 const DWORD resizestyle =
1047 (WS_THICKFRAME|WS_MAXIMIZEBOX);
1048 DDSURFACEDESC ddsd;
1049 LPDIRECTDRAWSURFACE dd_surface1;
1050 LPDIRECTDRAWSURFACE3 dd_surface3;
1051
1052 SDL_resizing = 1;
1053#ifdef DDRAW_DEBUG
1054 fprintf(stderr, "Setting %dx%dx%d video mode\n", width, height, bpp);
1055#endif
1056 /* Clean up any previous DirectDraw surfaces */
1057 if ( current->hwdata ) {
1058 this->FreeHWSurface(this, current);
1059 current->hwdata = NULL;
1060 }
1061 if ( SDL_primary != NULL ) {
1062 IDirectDrawSurface3_Release(SDL_primary);
1063 SDL_primary = NULL;
1064 }
1065
1066#ifndef NO_CHANGEDISPLAYSETTINGS
1067 /* Unset any previous OpenGL fullscreen mode */
1068 if ( (current->flags & (SDL_OPENGL|SDL_FULLSCREEN)) ==
1069 (SDL_OPENGL|SDL_FULLSCREEN) ) {
1070 ChangeDisplaySettings(NULL, 0);
1071 }
1072#endif
1073
1074 /* Clean up any GL context that may be hanging around */
1075 if ( current->flags & SDL_OPENGL ) {
1076 WIN_GL_ShutDown(this);
1077 }
1078
1079 /* If we are setting a GL mode, use GDI, not DirectX (yuck) */
1080 if ( flags & SDL_OPENGL ) {
1081 Uint32 Rmask, Gmask, Bmask;
1082
1083 /* Recalculate the bitmasks if necessary */
1084 if ( bpp == current->format->BitsPerPixel ) {
1085 video = current;
1086 } else {
1087 switch (bpp) {
1088 case 15:
1089 case 16:
1090 if ( 0 /*DIB_SussScreenDepth() == 15*/ ) {
1091 /* 5-5-5 */
1092 Rmask = 0x00007c00;
1093 Gmask = 0x000003e0;
1094 Bmask = 0x0000001f;
1095 } else {
1096 /* 5-6-5 */
1097 Rmask = 0x0000f800;
1098 Gmask = 0x000007e0;
1099 Bmask = 0x0000001f;
1100 }
1101 break;
1102 case 24:
1103 case 32:
1104 /* GDI defined as 8-8-8 */
1105 Rmask = 0x00ff0000;
1106 Gmask = 0x0000ff00;
1107 Bmask = 0x000000ff;
1108 break;
1109 default:
1110 Rmask = 0x00000000;
1111 Gmask = 0x00000000;
1112 Bmask = 0x00000000;
1113 break;
1114 }
1115 video = SDL_CreateRGBSurface(SDL_SWSURFACE, 0, 0, bpp,
1116 Rmask, Gmask, Bmask, 0);
1117 if ( video == NULL ) {
1118 SDL_OutOfMemory();
1119 return(NULL);
1120 }
1121 }
1122
1123 /* Fill in part of the video surface */
1124 prev_w = video->w;
1125 prev_h = video->h;
1126 video->flags = 0; /* Clear flags */
1127 video->w = width;
1128 video->h = height;
1129 video->pitch = SDL_CalculatePitch(video);
1130
1131#ifndef NO_CHANGEDISPLAYSETTINGS
1132 /* Set fullscreen mode if appropriate.
1133 Ugh, since our list of valid video modes comes from
1134 the DirectX driver, we may not actually be able to
1135 change to the desired resolution here.
1136 FIXME: Should we do a closest match?
1137 */
1138 if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
1139 DEVMODE settings;
1140 BOOL changed;
1141
1142 SDL_memset(&settings, 0, sizeof(DEVMODE));
1143 settings.dmSize = sizeof(DEVMODE);
1144 settings.dmBitsPerPel = video->format->BitsPerPixel;
1145 settings.dmPelsWidth = width;
1146 settings.dmPelsHeight = height;
1147 settings.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
1148 if ( width <= (int)SDL_desktop_mode.dmPelsWidth &&
1149 height <= (int)SDL_desktop_mode.dmPelsHeight ) {
1150 settings.dmDisplayFrequency = SDL_desktop_mode.dmDisplayFrequency;
1151 settings.dmFields |= DM_DISPLAYFREQUENCY;
1152 }
1153 changed = (ChangeDisplaySettings(&settings, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL);
1154 if ( ! changed && (settings.dmFields & DM_DISPLAYFREQUENCY) ) {
1155 settings.dmFields &= ~DM_DISPLAYFREQUENCY;
1156 changed = (ChangeDisplaySettings(&settings, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL);
1157 }
1158 if ( changed ) {
1159 video->flags |= SDL_FULLSCREEN;
1160 SDL_fullscreen_mode = settings;
1161 }
1162 }
1163#endif /* !NO_CHANGEDISPLAYSETTINGS */
1164
1165 style = GetWindowLong(SDL_Window, GWL_STYLE);
1166 style &= ~(resizestyle|WS_MAXIMIZE);
1167 if ( video->flags & SDL_FULLSCREEN ) {
1168 style &= ~windowstyle;
1169 style |= directstyle;
1170 } else {
1171 if ( flags & SDL_NOFRAME ) {
1172 style &= ~windowstyle;
1173 style |= directstyle;
1174 video->flags |= SDL_NOFRAME;
1175 } else {
1176 style &= ~directstyle;
1177 style |= windowstyle;
1178 if ( flags & SDL_RESIZABLE ) {
1179 style |= resizestyle;
1180 video->flags |= SDL_RESIZABLE;
1181 }
1182 }
1183#if WS_MAXIMIZE
1184 if (IsZoomed(SDL_Window)) style |= WS_MAXIMIZE;
1185#endif
1186 }
1187
1188 /* DJM: Don't piss of anyone who has setup his own window */
1189 if ( !SDL_windowid )
1190 SetWindowLong(SDL_Window, GWL_STYLE, style);
1191
1192 /* Resize the window (copied from SDL WinDIB driver) */
1193 if ( !SDL_windowid && !IsZoomed(SDL_Window) ) {
1194 RECT bounds;
1195 int x, y;
1196 HWND top;
1197 UINT swp_flags;
1198 const char *window = NULL;
1199 const char *center = NULL;
1200
1201 if ( video->w != prev_w || video->h != prev_h ) {
1202 window = SDL_getenv("SDL_VIDEO_WINDOW_POS");
1203 center = SDL_getenv("SDL_VIDEO_CENTERED");
1204 if ( window ) {
1205 if ( SDL_sscanf(window, "%d,%d", &x, &y) == 2 ) {
1206 SDL_windowX = x;
1207 SDL_windowY = y;
1208 }
1209 if ( SDL_strcmp(window, "center") == 0 ) {
1210 center = window;
1211 }
1212 }
1213 }
1214 swp_flags = (SWP_NOCOPYBITS | SWP_SHOWWINDOW);
1215
1216 bounds.left = SDL_windowX;
1217 bounds.top = SDL_windowY;
1218 bounds.right = SDL_windowX+video->w;
1219 bounds.bottom = SDL_windowY+video->h;
1220 AdjustWindowRectEx(&bounds, GetWindowLong(SDL_Window, GWL_STYLE), (GetMenu(SDL_Window) != NULL), 0);
1221 width = bounds.right-bounds.left;
1222 height = bounds.bottom-bounds.top;
1223 if ( (flags & SDL_FULLSCREEN) ) {
1224 x = (GetSystemMetrics(SM_CXSCREEN)-width)/2;
1225 y = (GetSystemMetrics(SM_CYSCREEN)-height)/2;
1226 } else if ( center ) {
1227 x = (GetSystemMetrics(SM_CXSCREEN)-width)/2;
1228 y = (GetSystemMetrics(SM_CYSCREEN)-height)/2;
1229 } else if ( SDL_windowX || SDL_windowY || window ) {
1230 x = bounds.left;
1231 y = bounds.top;
1232 } else {
1233 x = y = -1;
1234 swp_flags |= SWP_NOMOVE;
1235 }
1236 if ( flags & SDL_FULLSCREEN ) {
1237 top = HWND_TOPMOST;
1238 } else {
1239 top = HWND_NOTOPMOST;
1240 }
1241 SetWindowPos(SDL_Window, top, x, y, width, height, swp_flags);
1242 if ( !(flags & SDL_FULLSCREEN) ) {
1243 SDL_windowX = SDL_bounds.left;
1244 SDL_windowY = SDL_bounds.top;
1245 }
1246 SetForegroundWindow(SDL_Window);
1247 }
1248 SDL_resizing = 0;
1249
1250 /* Set up for OpenGL */
1251 if ( WIN_GL_SetupWindow(this) < 0 ) {
1252 return(NULL);
1253 }
1254 video->flags |= SDL_OPENGL;
1255 return(video);
1256 }
1257
1258 /* Set the appropriate window style */
1259 style = GetWindowLong(SDL_Window, GWL_STYLE);
1260 style &= ~(resizestyle|WS_MAXIMIZE);
1261 if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
1262 style &= ~windowstyle;
1263 style |= directstyle;
1264 } else {
1265 if ( flags & SDL_NOFRAME ) {
1266 style &= ~windowstyle;
1267 style |= directstyle;
1268 } else {
1269 style &= ~directstyle;
1270 style |= windowstyle;
1271 if ( flags & SDL_RESIZABLE ) {
1272 style |= resizestyle;
1273 }
1274 }
1275#if WS_MAXIMIZE
1276 if (IsZoomed(SDL_Window)) style |= WS_MAXIMIZE;
1277#endif
1278 }
1279 /* DJM: Don't piss of anyone who has setup his own window */
1280 if ( !SDL_windowid )
1281 SetWindowLong(SDL_Window, GWL_STYLE, style);
1282
1283 /* Set DirectDraw sharing mode.. exclusive when fullscreen */
1284 if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
1285 sharemode = DDSCL_FULLSCREEN|DDSCL_EXCLUSIVE|DDSCL_ALLOWREBOOT;
1286 } else {
1287 sharemode = DDSCL_NORMAL;
1288 }
1289 result = IDirectDraw2_SetCooperativeLevel(ddraw2,SDL_Window,sharemode);
1290 if ( result != DD_OK ) {
1291 SetDDerror("DirectDraw2::SetCooperativeLevel", result);
1292 return(NULL);
1293 }
1294
1295 /* Set the display mode, if we are in fullscreen mode */
1296 if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
1297 RECT bounds;
1298 struct DX5EnumRect *rect;
1299 int maxRefreshRate;
1300
1301 /* Cover up desktop during mode change */
1302 bounds.left = 0;
1303 bounds.top = 0;
1304 bounds.right = GetSystemMetrics(SM_CXSCREEN);
1305 bounds.bottom = GetSystemMetrics(SM_CYSCREEN);
1306 AdjustWindowRectEx(&bounds, GetWindowLong(SDL_Window, GWL_STYLE), (GetMenu(SDL_Window) != NULL), 0);
1307 SetWindowPos(SDL_Window, HWND_TOPMOST,
1308 bounds.left, bounds.top,
1309 bounds.right - bounds.left,
1310 bounds.bottom - bounds.top, SWP_NOCOPYBITS);
1311 ShowWindow(SDL_Window, SW_SHOW);
1312 while ( GetForegroundWindow() != SDL_Window ) {
1313 SetForegroundWindow(SDL_Window);
1314 SDL_Delay(100);
1315 }
1316
1317 /* find maximum monitor refresh rate for this resolution */
1318 /* Dmitry Yakimov ftech@tula.net */
1319 maxRefreshRate = 0; /* system default */
1320 for ( rect = enumlists[bpp / 8 - 1]; rect; rect = rect->next ) {
1321 if ( (width == rect->r.w) && (height == rect->r.h) ) {
1322 maxRefreshRate = rect->refreshRate;
1323 break;
1324 }
1325 }
1326#ifdef DDRAW_DEBUG
1327 fprintf(stderr, "refresh rate = %d Hz\n", maxRefreshRate);
1328#endif
1329
1330 result = IDirectDraw2_SetDisplayMode(ddraw2, width, height, bpp, maxRefreshRate, 0);
1331 if ( result != DD_OK ) {
1332 result = IDirectDraw2_SetDisplayMode(ddraw2, width, height, bpp, 0, 0);
1333 if ( result != DD_OK ) {
1334 /* We couldn't set fullscreen mode, try window */
1335 return(DX5_SetVideoMode(this, current, width, height, bpp, flags & ~SDL_FULLSCREEN));
1336 }
1337 }
1338 DX5_DInputReset(this, 1);
1339 } else {
1340 DX5_DInputReset(this, 0);
1341 }
1342 DX5_UpdateVideoInfo(this);
1343
1344 /* Create a primary DirectDraw surface */
1345 SDL_memset(&ddsd, 0, sizeof(ddsd));
1346 ddsd.dwSize = sizeof(ddsd);
1347 ddsd.dwFlags = DDSD_CAPS;
1348 ddsd.ddsCaps.dwCaps = (DDSCAPS_PRIMARYSURFACE|DDSCAPS_VIDEOMEMORY);
1349 if ( (flags & SDL_FULLSCREEN) != SDL_FULLSCREEN ) {
1350 /* There's no windowed double-buffering */
1351 flags &= ~SDL_DOUBLEBUF;
1352 }
1353 if ( (flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) {
1354 ddsd.dwFlags |= DDSD_BACKBUFFERCOUNT;
1355 ddsd.ddsCaps.dwCaps |= (DDSCAPS_COMPLEX|DDSCAPS_FLIP);
1356 ddsd.dwBackBufferCount = 1;
1357 }
1358 result = IDirectDraw2_CreateSurface(ddraw2, &ddsd, &dd_surface1, NULL);
1359 if ( (result != DD_OK) && ((flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) ) {
1360 ddsd.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
1361 ddsd.ddsCaps.dwCaps &= ~(DDSCAPS_COMPLEX|DDSCAPS_FLIP);
1362 ddsd.dwBackBufferCount = 0;
1363 result = IDirectDraw2_CreateSurface(ddraw2,
1364 &ddsd, &dd_surface1, NULL);
1365 }
1366 if ( result != DD_OK ) {
1367 SetDDerror("DirectDraw2::CreateSurface(PRIMARY)", result);
1368 return(NULL);
1369 }
1370 result = IDirectDrawSurface_QueryInterface(dd_surface1,
1371 &IID_IDirectDrawSurface3, (LPVOID *)&SDL_primary);
1372 if ( result != DD_OK ) {
1373 SetDDerror("DirectDrawSurface::QueryInterface", result);
1374 return(NULL);
1375 }
1376 IDirectDrawSurface_Release(dd_surface1);
1377
1378 /* Get the format of the primary DirectDraw surface */
1379 SDL_memset(&ddsd, 0, sizeof(ddsd));
1380 ddsd.dwSize = sizeof(ddsd);
1381 ddsd.dwFlags = DDSD_PIXELFORMAT|DDSD_CAPS;
1382 result = IDirectDrawSurface3_GetSurfaceDesc(SDL_primary, &ddsd);
1383 if ( result != DD_OK ) {
1384 SetDDerror("DirectDrawSurface::GetSurfaceDesc", result);
1385 return(NULL);
1386 }
1387 if ( ! (ddsd.ddpfPixelFormat.dwFlags&DDPF_RGB) ) {
1388 SDL_SetError("Primary DDRAW surface is not RGB format");
1389 return(NULL);
1390 }
1391
1392 /* Free old palette and create a new one if we're in 8-bit mode */
1393 if ( SDL_palette != NULL ) {
1394 IDirectDrawPalette_Release(SDL_palette);
1395 SDL_palette = NULL;
1396 }
1397#if defined(NONAMELESSUNION)
1398 if ( ddsd.ddpfPixelFormat.u1.dwRGBBitCount == 8 ) {
1399#else
1400 if ( ddsd.ddpfPixelFormat.dwRGBBitCount == 8 ) {
1401#endif
1402 int i;
1403
1404 if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
1405 /* We have access to the entire palette */
1406 for ( i=0; i<256; ++i ) {
1407 SDL_colors[i].peFlags =
1408 (PC_NOCOLLAPSE|PC_RESERVED);
1409 SDL_colors[i].peRed = 0;
1410 SDL_colors[i].peGreen = 0;
1411 SDL_colors[i].peBlue = 0;
1412 }
1413 } else {
1414 /* First 10 colors are reserved by Windows */
1415 for ( i=0; i<10; ++i ) {
1416 SDL_colors[i].peFlags = PC_EXPLICIT;
1417 SDL_colors[i].peRed = i;
1418 SDL_colors[i].peGreen = 0;
1419 SDL_colors[i].peBlue = 0;
1420 }
1421 for ( i=10; i<(10+236); ++i ) {
1422 SDL_colors[i].peFlags = PC_NOCOLLAPSE;
1423 SDL_colors[i].peRed = 0;
1424 SDL_colors[i].peGreen = 0;
1425 SDL_colors[i].peBlue = 0;
1426 }
1427 /* Last 10 colors are reserved by Windows */
1428 for ( i=246; i<256; ++i ) {
1429 SDL_colors[i].peFlags = PC_EXPLICIT;
1430 SDL_colors[i].peRed = i;
1431 SDL_colors[i].peGreen = 0;
1432 SDL_colors[i].peBlue = 0;
1433 }
1434 }
1435 result = IDirectDraw2_CreatePalette(ddraw2,
1436 (DDPCAPS_8BIT|DDPCAPS_ALLOW256),
1437 SDL_colors, &SDL_palette, NULL);
1438 if ( result != DD_OK ) {
1439 SetDDerror("DirectDraw2::CreatePalette", result);
1440 return(NULL);
1441 }
1442 result = IDirectDrawSurface3_SetPalette(SDL_primary,
1443 SDL_palette);
1444 if ( result != DD_OK ) {
1445 SetDDerror("DirectDrawSurface3::SetPalette", result);
1446 return(NULL);
1447 }
1448 }
1449
1450 /* Create our video surface using the same pixel format */
1451 video = current;
1452 if ( (width != video->w) || (height != video->h)
1453 || (video->format->BitsPerPixel !=
1454#if defined(NONAMELESSUNION)
1455 ddsd.ddpfPixelFormat.u1.dwRGBBitCount) ) {
1456#else
1457 ddsd.ddpfPixelFormat.dwRGBBitCount) ) {
1458#endif
1459 SDL_FreeSurface(video);
1460 video = SDL_CreateRGBSurface(SDL_SWSURFACE, 0, 0,
1461#if defined(NONAMELESSUNION)
1462 ddsd.ddpfPixelFormat.u1.dwRGBBitCount,
1463 ddsd.ddpfPixelFormat.u2.dwRBitMask,
1464 ddsd.ddpfPixelFormat.u3.dwGBitMask,
1465 ddsd.ddpfPixelFormat.u4.dwBBitMask,
1466#else
1467 ddsd.ddpfPixelFormat.dwRGBBitCount,
1468 ddsd.ddpfPixelFormat.dwRBitMask,
1469 ddsd.ddpfPixelFormat.dwGBitMask,
1470 ddsd.ddpfPixelFormat.dwBBitMask,
1471#endif
1472 0);
1473 if ( video == NULL ) {
1474 SDL_OutOfMemory();
1475 return(NULL);
1476 }
1477 prev_w = video->w;
1478 prev_h = video->h;
1479 video->w = width;
1480 video->h = height;
1481 video->pitch = 0;
1482 }
1483 video->flags = 0; /* Clear flags */
1484
1485 /* If not fullscreen, locking is possible, but it doesn't do what
1486 the caller really expects -- if the locked surface is written to,
1487 the appropriate portion of the entire screen is modified, not
1488 the application window, as we would like.
1489 Note that it is still possible to write directly to display
1490 memory, but the application must respect the clip list of
1491 the surface. There might be some odd timing interactions
1492 involving clip list updates and background refreshing as
1493 Windows moves other windows across our window.
1494 We currently don't support this, even though it might be a
1495 good idea since BeOS has an implementation of BDirectWindow
1496 that does the same thing. This would be most useful for
1497 applications that do complete screen updates every frame.
1498 -- Fixme?
1499 */
1500 if ( (flags & SDL_FULLSCREEN) != SDL_FULLSCREEN ) {
1501 /* Necessary if we're going from fullscreen to window */
1502 if ( video->pixels == NULL ) {
1503 video->pitch = (width*video->format->BytesPerPixel);
1504 /* Pitch needs to be QWORD (8-byte) aligned */
1505 video->pitch = (video->pitch + 7) & ~7;
1506 video->pixels = (void *)SDL_malloc(video->h*video->pitch);
1507 if ( video->pixels == NULL ) {
1508 if ( video != current ) {
1509 SDL_FreeSurface(video);
1510 }
1511 SDL_OutOfMemory();
1512 return(NULL);
1513 }
1514 }
1515 dd_surface3 = NULL;
1516#if 0 /* FIXME: enable this when SDL consistently reports lost surfaces */
1517 if ( (flags & SDL_HWSURFACE) == SDL_HWSURFACE ) {
1518 video->flags |= SDL_HWSURFACE;
1519 } else {
1520 video->flags |= SDL_SWSURFACE;
1521 }
1522#else
1523 video->flags |= SDL_SWSURFACE;
1524#endif
1525 if ( (flags & SDL_RESIZABLE) && !(flags & SDL_NOFRAME) ) {
1526 video->flags |= SDL_RESIZABLE;
1527 }
1528 if ( flags & SDL_NOFRAME ) {
1529 video->flags |= SDL_NOFRAME;
1530 }
1531 } else {
1532 /* Necessary if we're going from window to fullscreen */
1533 if ( video->pixels != NULL ) {
1534 SDL_free(video->pixels);
1535 video->pixels = NULL;
1536 }
1537 dd_surface3 = SDL_primary;
1538 video->flags |= SDL_HWSURFACE;
1539 }
1540
1541 /* See if the primary surface has double-buffering enabled */
1542 if ( (ddsd.ddsCaps.dwCaps & DDSCAPS_FLIP) == DDSCAPS_FLIP ) {
1543 video->flags |= SDL_DOUBLEBUF;
1544 }
1545
1546 /* Allocate the SDL surface associated with the primary surface */
1547 if ( DX5_AllocDDSurface(this, video, dd_surface3,
1548 video->flags&SDL_HWSURFACE) < 0 ) {
1549 if ( video != current ) {
1550 SDL_FreeSurface(video);
1551 }
1552 return(NULL);
1553 }
1554
1555 /* Use the appropriate blitting function */
1556 if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
1557 video->flags |= SDL_FULLSCREEN;
1558 if ( video->format->palette != NULL ) {
1559 video->flags |= SDL_HWPALETTE;
1560 }
1561 this->UpdateRects = DX5_DirectUpdate;
1562 } else {
1563 this->UpdateRects = DX5_WindowUpdate;
1564 }
1565
1566 /* Make our window the proper size, set the clipper, then show it */
1567 if ( (flags & SDL_FULLSCREEN) != SDL_FULLSCREEN ) {
1568 /* Create and set a clipper on our primary surface */
1569 if ( SDL_clipper == NULL ) {
1570 result = IDirectDraw2_CreateClipper(ddraw2,
1571 0, &SDL_clipper, NULL);
1572 if ( result != DD_OK ) {
1573 if ( video != current ) {
1574 SDL_FreeSurface(video);
1575 }
1576 SetDDerror("DirectDraw2::CreateClipper",result);
1577 return(NULL);
1578 }
1579 }
1580 result = IDirectDrawClipper_SetHWnd(SDL_clipper, 0, SDL_Window);
1581 if ( result != DD_OK ) {
1582 if ( video != current ) {
1583 SDL_FreeSurface(video);
1584 }
1585 SetDDerror("DirectDrawClipper::SetHWnd", result);
1586 return(NULL);
1587 }
1588 result = IDirectDrawSurface3_SetClipper(SDL_primary,
1589 SDL_clipper);
1590 if ( result != DD_OK ) {
1591 if ( video != current ) {
1592 SDL_FreeSurface(video);
1593 }
1594 SetDDerror("DirectDrawSurface3::SetClipper", result);
1595 return(NULL);
1596 }
1597
1598 /* Resize the window (copied from SDL WinDIB driver) */
1599 if ( !SDL_windowid && !IsZoomed(SDL_Window) ) {
1600 RECT bounds;
1601 int x, y;
1602 UINT swp_flags;
1603 const char *window = NULL;
1604 const char *center = NULL;
1605
1606 if ( video->w != prev_w || video->h != prev_h ) {
1607 window = SDL_getenv("SDL_VIDEO_WINDOW_POS");
1608 center = SDL_getenv("SDL_VIDEO_CENTERED");
1609 if ( window ) {
1610 if ( SDL_sscanf(window, "%d,%d", &x, &y) == 2 ) {
1611 SDL_windowX = x;
1612 SDL_windowY = y;
1613 }
1614 if ( SDL_strcmp(window, "center") == 0 ) {
1615 center = window;
1616 }
1617 }
1618 }
1619 swp_flags = SWP_NOCOPYBITS;
1620
1621 bounds.left = SDL_windowX;
1622 bounds.top = SDL_windowY;
1623 bounds.right = SDL_windowX+video->w;
1624 bounds.bottom = SDL_windowY+video->h;
1625 AdjustWindowRectEx(&bounds, GetWindowLong(SDL_Window, GWL_STYLE), (GetMenu(SDL_Window) != NULL), 0);
1626 width = bounds.right-bounds.left;
1627 height = bounds.bottom-bounds.top;
1628 if ( center ) {
1629 x = (GetSystemMetrics(SM_CXSCREEN)-width)/2;
1630 y = (GetSystemMetrics(SM_CYSCREEN)-height)/2;
1631 } else if ( SDL_windowX || SDL_windowY || window ) {
1632 x = bounds.left;
1633 y = bounds.top;
1634 } else {
1635 x = y = -1;
1636 swp_flags |= SWP_NOMOVE;
1637 }
1638 SetWindowPos(SDL_Window, HWND_NOTOPMOST, x, y, width, height, swp_flags);
1639 SDL_windowX = SDL_bounds.left;
1640 SDL_windowY = SDL_bounds.top;
1641 }
1642
1643 }
1644 ShowWindow(SDL_Window, SW_SHOW);
1645 SetForegroundWindow(SDL_Window);
1646 SDL_resizing = 0;
1647
1648 /* JC 14 Mar 2006
1649 Flush the message loop or this can cause big problems later
1650 Especially if the user decides to use dialog boxes or assert()!
1651 */
1652 WIN_FlushMessageQueue();
1653
1654 /* We're live! */
1655 return(video);
1656}
1657
1658struct private_hwdata {
1659 LPDIRECTDRAWSURFACE3 dd_surface;
1660 LPDIRECTDRAWSURFACE3 dd_writebuf;
1661};
1662
1663static int DX5_AllocDDSurface(_THIS, SDL_Surface *surface,
1664 LPDIRECTDRAWSURFACE3 requested, Uint32 flag)
1665{
1666 LPDIRECTDRAWSURFACE dd_surface1;
1667 LPDIRECTDRAWSURFACE3 dd_surface3;
1668 DDSURFACEDESC ddsd;
1669 HRESULT result;
1670
1671 /* Clear the hardware flag, in case we fail */
1672 surface->flags &= ~flag;
1673
1674 /* Allocate the hardware acceleration data */
1675 surface->hwdata = (struct private_hwdata *)
1676 SDL_malloc(sizeof(*surface->hwdata));
1677 if ( surface->hwdata == NULL ) {
1678 SDL_OutOfMemory();
1679 return(-1);
1680 }
1681 dd_surface3 = NULL;
1682
1683 /* Set up the surface description */
1684 SDL_memset(&ddsd, 0, sizeof(ddsd));
1685 ddsd.dwSize = sizeof(ddsd);
1686 ddsd.dwFlags = (DDSD_WIDTH|DDSD_HEIGHT|DDSD_CAPS|
1687 DDSD_PITCH|DDSD_PIXELFORMAT);
1688 ddsd.dwWidth = surface->w;
1689 ddsd.dwHeight= surface->h;
1690#if defined(NONAMELESSUNION)
1691 ddsd.u1.lPitch = surface->pitch;
1692#else
1693 ddsd.lPitch = surface->pitch;
1694#endif
1695 if ( (flag & SDL_HWSURFACE) == SDL_HWSURFACE ) {
1696 ddsd.ddsCaps.dwCaps =
1697 (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_VIDEOMEMORY);
1698 } else {
1699 ddsd.ddsCaps.dwCaps =
1700 (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY);
1701 }
1702 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
1703 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
1704 if ( surface->format->palette ) {
1705 ddsd.ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED8;
1706 }
1707#if defined(NONAMELESSUNION)
1708 ddsd.ddpfPixelFormat.u1.dwRGBBitCount = surface->format->BitsPerPixel;
1709 ddsd.ddpfPixelFormat.u2.dwRBitMask = surface->format->Rmask;
1710 ddsd.ddpfPixelFormat.u3.dwGBitMask = surface->format->Gmask;
1711 ddsd.ddpfPixelFormat.u4.dwBBitMask = surface->format->Bmask;
1712#else
1713 ddsd.ddpfPixelFormat.dwRGBBitCount = surface->format->BitsPerPixel;
1714 ddsd.ddpfPixelFormat.dwRBitMask = surface->format->Rmask;
1715 ddsd.ddpfPixelFormat.dwGBitMask = surface->format->Gmask;
1716 ddsd.ddpfPixelFormat.dwBBitMask = surface->format->Bmask;
1717#endif
1718
1719 /* Create the DirectDraw video surface */
1720 if ( requested != NULL ) {
1721 dd_surface3 = requested;
1722 } else {
1723 result = IDirectDraw2_CreateSurface(ddraw2,
1724 &ddsd, &dd_surface1, NULL);
1725 if ( result != DD_OK ) {
1726 SetDDerror("DirectDraw2::CreateSurface", result);
1727 goto error_end;
1728 }
1729 result = IDirectDrawSurface_QueryInterface(dd_surface1,
1730 &IID_IDirectDrawSurface3, (LPVOID *)&dd_surface3);
1731 IDirectDrawSurface_Release(dd_surface1);
1732 if ( result != DD_OK ) {
1733 SetDDerror("DirectDrawSurface::QueryInterface", result);
1734 goto error_end;
1735 }
1736 }
1737
1738 if ( (flag & SDL_HWSURFACE) == SDL_HWSURFACE ) {
1739 /* Check to see whether the surface actually ended up
1740 in video memory, and fail if not. We expect the
1741 surfaces we create here to actually be in hardware!
1742 */
1743 result = IDirectDrawSurface3_GetCaps(dd_surface3,&ddsd.ddsCaps);
1744 if ( result != DD_OK ) {
1745 SetDDerror("DirectDrawSurface3::GetCaps", result);
1746 goto error_end;
1747 }
1748 if ( (ddsd.ddsCaps.dwCaps&DDSCAPS_VIDEOMEMORY) !=
1749 DDSCAPS_VIDEOMEMORY ) {
1750 SDL_SetError("No room in video memory");
1751 goto error_end;
1752 }
1753 } else {
1754 /* Try to hook our surface memory */
1755 ddsd.dwFlags = DDSD_LPSURFACE;
1756 ddsd.lpSurface = surface->pixels;
1757 result = IDirectDrawSurface3_SetSurfaceDesc(dd_surface3,
1758 &ddsd, 0);
1759 if ( result != DD_OK ) {
1760 SetDDerror("DirectDraw2::SetSurfaceDesc", result);
1761 goto error_end;
1762 }
1763
1764 }
1765
1766 /* Make sure the surface format was set properly */
1767 SDL_memset(&ddsd, 0, sizeof(ddsd));
1768 ddsd.dwSize = sizeof(ddsd);
1769 result = IDirectDrawSurface3_Lock(dd_surface3, NULL,
1770 &ddsd, (DDLOCK_NOSYSLOCK|DDLOCK_WAIT), NULL);
1771 if ( result != DD_OK ) {
1772 SetDDerror("DirectDrawSurface3::Lock", result);
1773 goto error_end;
1774 }
1775 IDirectDrawSurface3_Unlock(dd_surface3, NULL);
1776
1777 if ( (flag & SDL_HWSURFACE) == SDL_SWSURFACE ) {
1778 if ( ddsd.lpSurface != surface->pixels ) {
1779 SDL_SetError("DDraw didn't use SDL surface memory");
1780 goto error_end;
1781 }
1782 if (
1783#if defined(NONAMELESSUNION)
1784 ddsd.u1.lPitch
1785#else
1786 ddsd.lPitch
1787#endif
1788 != (LONG)surface->pitch ) {
1789 SDL_SetError("DDraw created surface with wrong pitch");
1790 goto error_end;
1791 }
1792 } else {
1793#if defined(NONAMELESSUNION)
1794 surface->pitch = (Uint16)ddsd.u1.lPitch;
1795#else
1796 surface->pitch = (Uint16)ddsd.lPitch;
1797#endif
1798 }
1799#if defined(NONAMELESSUNION)
1800 if ( (ddsd.ddpfPixelFormat.u1.dwRGBBitCount !=
1801 surface->format->BitsPerPixel) ||
1802 (ddsd.ddpfPixelFormat.u2.dwRBitMask != surface->format->Rmask) ||
1803 (ddsd.ddpfPixelFormat.u3.dwGBitMask != surface->format->Gmask) ||
1804 (ddsd.ddpfPixelFormat.u4.dwBBitMask != surface->format->Bmask) ){
1805#else
1806 if ( (ddsd.ddpfPixelFormat.dwRGBBitCount !=
1807 surface->format->BitsPerPixel) ||
1808 (ddsd.ddpfPixelFormat.dwRBitMask != surface->format->Rmask) ||
1809 (ddsd.ddpfPixelFormat.dwGBitMask != surface->format->Gmask) ||
1810 (ddsd.ddpfPixelFormat.dwBBitMask != surface->format->Bmask) ){
1811#endif
1812 SDL_SetError("DDraw didn't use SDL surface description");
1813 goto error_end;
1814 }
1815 if ( (ddsd.dwWidth != (DWORD)surface->w) ||
1816 (ddsd.dwHeight != (DWORD)surface->h) ) {
1817 SDL_SetError("DDraw created surface with wrong size");
1818 goto error_end;
1819 }
1820
1821 /* Set the surface private data */
1822 surface->flags |= flag;
1823 surface->hwdata->dd_surface = dd_surface3;
1824 if ( (surface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) {
1825 LPDIRECTDRAWSURFACE3 dd_writebuf;
1826
1827 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
1828 result = IDirectDrawSurface3_GetAttachedSurface(dd_surface3,
1829 &ddsd.ddsCaps, &dd_writebuf);
1830 if ( result != DD_OK ) {
1831 SetDDerror("DirectDrawSurface3::GetAttachedSurface",
1832 result);
1833 } else {
1834 dd_surface3 = dd_writebuf;
1835 }
1836 }
1837 surface->hwdata->dd_writebuf = dd_surface3;
1838
1839 /* We're ready to go! */
1840 return(0);
1841
1842 /* Okay, so goto's are cheesy, but there are so many possible
1843 errors in this function, and the cleanup is the same in
1844 every single case. Is there a better way, other than deeply
1845 nesting the code?
1846 */
1847error_end:
1848 if ( (dd_surface3 != NULL) && (dd_surface3 != requested) ) {
1849 IDirectDrawSurface_Release(dd_surface3);
1850 }
1851 SDL_free(surface->hwdata);
1852 surface->hwdata = NULL;
1853 return(-1);
1854}
1855
1856static int DX5_AllocHWSurface(_THIS, SDL_Surface *surface)
1857{
1858 /* DDraw limitation -- you need to set cooperative level first */
1859 if ( SDL_primary == NULL ) {
1860 SDL_SetError("You must set a non-GL video mode first");
1861 return(-1);
1862 }
1863 return(DX5_AllocDDSurface(this, surface, NULL, SDL_HWSURFACE));
1864}
1865
1866#ifdef DDRAW_DEBUG
1867void PrintSurface(char *title, LPDIRECTDRAWSURFACE3 surface, Uint32 flags)
1868{
1869 DDSURFACEDESC ddsd;
1870
1871 /* Lock and load! */
1872 SDL_memset(&ddsd, 0, sizeof(ddsd));
1873 ddsd.dwSize = sizeof(ddsd);
1874 if ( IDirectDrawSurface3_Lock(surface, NULL, &ddsd,
1875 (DDLOCK_NOSYSLOCK|DDLOCK_WAIT), NULL) != DD_OK ) {
1876 return;
1877 }
1878 IDirectDrawSurface3_Unlock(surface, NULL);
1879
1880 fprintf(stderr, "%s:\n", title);
1881 fprintf(stderr, "\tSize: %dx%d in %s at %ld bpp (pitch = %ld)\n",
1882 ddsd.dwWidth, ddsd.dwHeight,
1883 (flags & SDL_HWSURFACE) ? "hardware" : "software",
1884#if defined(NONAMELESSUNION)
1885 ddsd.ddpfPixelFormat.u1.dwRGBBitCount, ddsd.u1.lPitch);
1886#else
1887 ddsd.ddpfPixelFormat.dwRGBBitCount, ddsd.lPitch);
1888#endif
1889 fprintf(stderr, "\tR = 0x%X, G = 0x%X, B = 0x%X\n",
1890#if defined(NONAMELESSUNION)
1891 ddsd.ddpfPixelFormat.u2.dwRBitMask,
1892 ddsd.ddpfPixelFormat.u3.dwGBitMask,
1893 ddsd.ddpfPixelFormat.u4.dwBBitMask);
1894#else
1895 ddsd.ddpfPixelFormat.dwRBitMask,
1896 ddsd.ddpfPixelFormat.dwGBitMask,
1897 ddsd.ddpfPixelFormat.dwBBitMask);
1898#endif
1899}
1900#endif /* DDRAW_DEBUG */
1901
1902static int DX5_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
1903 SDL_Surface *dst, SDL_Rect *dstrect)
1904{
1905 LPDIRECTDRAWSURFACE3 src_surface;
1906 LPDIRECTDRAWSURFACE3 dst_surface;
1907 DWORD flags;
1908 RECT rect;
1909 HRESULT result;
1910
1911 /* Set it up.. the desination must have a DDRAW surface */
1912 src_surface = src->hwdata->dd_writebuf;
1913 dst_surface = dst->hwdata->dd_writebuf;
1914 rect.top = (LONG)srcrect->y;
1915 rect.bottom = (LONG)srcrect->y+srcrect->h;
1916 rect.left = (LONG)srcrect->x;
1917 rect.right = (LONG)srcrect->x+srcrect->w;
1918 if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY )
1919 flags = DDBLTFAST_SRCCOLORKEY;
1920 else
1921 flags = DDBLTFAST_NOCOLORKEY;
1922 /* FIXME: We can remove this flag for _really_ fast blit queuing,
1923 but it will affect the return values of locks and flips.
1924 */
1925 flags |= DDBLTFAST_WAIT;
1926
1927 /* Do the blit! */
1928 result = IDirectDrawSurface3_BltFast(dst_surface,
1929 dstrect->x, dstrect->y, src_surface, &rect, flags);
1930 if ( result != DD_OK ) {
1931 if ( result == DDERR_SURFACELOST ) {
1932 result = IDirectDrawSurface3_Restore(src_surface);
1933 result = IDirectDrawSurface3_Restore(dst_surface);
1934 /* The surfaces need to be reloaded with artwork */
1935 SDL_SetError("Blit surfaces were lost, reload them");
1936 return(-2);
1937 }
1938 SetDDerror("IDirectDrawSurface3::BltFast", result);
1939#ifdef DDRAW_DEBUG
1940 fprintf(stderr, "Original dest rect: %dx%d at %d,%d\n", dstrect->w, dstrect->h, dstrect->x, dstrect->y);
1941 fprintf(stderr, "HW accelerated %sblit to from 0x%p to 0x%p at (%d,%d)\n",
1942 (src->flags & SDL_SRCCOLORKEY) ? "colorkey " : "", src, dst,
1943 dstrect->x, dstrect->y);
1944 PrintSurface("SRC", src_surface, src->flags);
1945 PrintSurface("DST", dst_surface, dst->flags);
1946 fprintf(stderr, "Source rectangle: (%d,%d) - (%d,%d)\n",
1947 rect.left, rect.top, rect.right, rect.bottom);
1948#endif
1949 /* Unexpected error, fall back to software blit */
1950 return(src->map->sw_blit(src, srcrect, dst, dstrect));
1951 }
1952 return(0);
1953}
1954
1955static int DX5_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst)
1956{
1957 int accelerated;
1958
1959 /* We need to have a DDraw surface for HW blits */
1960 if ( (src->flags & SDL_HWSURFACE) == SDL_SWSURFACE ) {
1961 /* Allocate a DDraw surface for the blit */
1962 if ( src->hwdata == NULL ) {
1963 DX5_AllocDDSurface(this, src, NULL, SDL_SWSURFACE);
1964 }
1965 }
1966 if ( src->hwdata == NULL ) {
1967 return(0);
1968 }
1969
1970 /* Set initial acceleration on */
1971 src->flags |= SDL_HWACCEL;
1972
1973 /* Set the surface attributes */
1974 if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) {
1975 if ( DX5_SetHWColorKey(this, src, src->format->colorkey) < 0 ) {
1976 src->flags &= ~SDL_HWACCEL;
1977 }
1978 }
1979 if ( (src->flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
1980 if ( DX5_SetHWAlpha(this, src, src->format->alpha) < 0 ) {
1981 src->flags &= ~SDL_HWACCEL;
1982 }
1983 }
1984
1985 /* Check to see if final surface blit is accelerated */
1986 accelerated = !!(src->flags & SDL_HWACCEL);
1987 if ( accelerated ) {
1988#ifdef DDRAW_DEBUG
1989 fprintf(stderr, "Setting accelerated blit on 0x%p\n", src);
1990#endif
1991 src->map->hw_blit = DX5_HWAccelBlit;
1992 }
1993 return(accelerated);
1994}
1995
1996static int DX5_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color)
1997{
1998 LPDIRECTDRAWSURFACE3 dst_surface;
1999 RECT area;
2000 DDBLTFX bltfx;
2001 HRESULT result;
2002
2003#ifdef DDRAW_DEBUG
2004 fprintf(stderr, "HW accelerated fill at (%d,%d)\n", dstrect->x, dstrect->y);
2005#endif
2006 dst_surface = dst->hwdata->dd_writebuf;
2007 area.top = (LONG)dstrect->y;
2008 area.bottom = (LONG)dstrect->y+dstrect->h;
2009 area.left = (LONG)dstrect->x;
2010 area.right = (LONG)dstrect->x+dstrect->w;
2011 bltfx.dwSize = sizeof(bltfx);
2012#if defined(NONAMELESSUNION)
2013 bltfx.u5.dwFillColor = color;
2014#else
2015 bltfx.dwFillColor = color;
2016#endif
2017 result = IDirectDrawSurface3_Blt(dst_surface,
2018 &area, NULL, NULL, DDBLT_COLORFILL|DDBLT_WAIT, &bltfx);
2019 if ( result == DDERR_SURFACELOST ) {
2020 IDirectDrawSurface3_Restore(dst_surface);
2021 result = IDirectDrawSurface3_Blt(dst_surface,
2022 &area, NULL, NULL, DDBLT_COLORFILL|DDBLT_WAIT, &bltfx);
2023 }
2024 if ( result != DD_OK ) {
2025 SetDDerror("IDirectDrawSurface3::Blt", result);
2026 return(-1);
2027 }
2028 return(0);
2029}
2030
2031static int DX5_SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key)
2032{
2033 DDCOLORKEY colorkey;
2034 HRESULT result;
2035
2036 /* Set the surface colorkey */
2037 colorkey.dwColorSpaceLowValue = key;
2038 colorkey.dwColorSpaceHighValue = key;
2039 result = IDirectDrawSurface3_SetColorKey(
2040 surface->hwdata->dd_surface, DDCKEY_SRCBLT, &colorkey);
2041 if ( result != DD_OK ) {
2042 SetDDerror("IDirectDrawSurface3::SetColorKey", result);
2043 return(-1);
2044 }
2045 return(0);
2046}
2047static int DX5_SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 alpha)
2048{
2049 return(-1);
2050}
2051
2052static int DX5_LockHWSurface(_THIS, SDL_Surface *surface)
2053{
2054 HRESULT result;
2055 LPDIRECTDRAWSURFACE3 dd_surface;
2056 DDSURFACEDESC ddsd;
2057
2058 /* Lock and load! */
2059 dd_surface = surface->hwdata->dd_writebuf;
2060 SDL_memset(&ddsd, 0, sizeof(ddsd));
2061 ddsd.dwSize = sizeof(ddsd);
2062 result = IDirectDrawSurface3_Lock(dd_surface, NULL, &ddsd,
2063 (DDLOCK_NOSYSLOCK|DDLOCK_WAIT), NULL);
2064 if ( result == DDERR_SURFACELOST ) {
2065 result = IDirectDrawSurface3_Restore(
2066 surface->hwdata->dd_surface);
2067 result = IDirectDrawSurface3_Lock(dd_surface, NULL, &ddsd,
2068 (DDLOCK_NOSYSLOCK|DDLOCK_WAIT), NULL);
2069 }
2070 if ( result != DD_OK ) {
2071 SetDDerror("DirectDrawSurface3::Lock", result);
2072 return(-1);
2073 }
2074 /* Pitch might have changed -- recalculate pitch and offset */
2075#if defined(NONAMELESSUNION)
2076 if ( surface->pitch != ddsd.u1.lPitch ) {
2077 surface->pitch = ddsd.u1.lPitch;
2078#else
2079 if ( surface->pitch != ddsd.lPitch ) {
2080 surface->pitch = (Uint16)ddsd.lPitch;
2081#endif
2082 surface->offset =
2083 ((ddsd.dwHeight-surface->h)/2)*surface->pitch +
2084 ((ddsd.dwWidth-surface->w)/2)*
2085 surface->format->BytesPerPixel;
2086 }
2087 surface->pixels = ddsd.lpSurface;
2088 return(0);
2089}
2090
2091static void DX5_UnlockHWSurface(_THIS, SDL_Surface *surface)
2092{
2093 IDirectDrawSurface3_Unlock(surface->hwdata->dd_writebuf, NULL);
2094 surface->pixels = NULL;
2095}
2096
2097static int DX5_FlipHWSurface(_THIS, SDL_Surface *surface)
2098{
2099 HRESULT result;
2100 LPDIRECTDRAWSURFACE3 dd_surface;
2101
2102 dd_surface = surface->hwdata->dd_surface;
2103
2104 /* to prevent big slowdown on fast computers, wait here instead of driver ring 0 code */
2105 /* Dmitry Yakimov (ftech@tula.net) */
2106 while(IDirectDrawSurface3_GetFlipStatus(dd_surface, DDGBS_ISBLTDONE) == DDERR_WASSTILLDRAWING);
2107
2108 result = IDirectDrawSurface3_Flip(dd_surface, NULL, DDFLIP_WAIT);
2109 if ( result == DDERR_SURFACELOST ) {
2110 result = IDirectDrawSurface3_Restore(
2111 surface->hwdata->dd_surface);
2112 while(IDirectDrawSurface3_GetFlipStatus(dd_surface, DDGBS_ISBLTDONE) == DDERR_WASSTILLDRAWING);
2113 result = IDirectDrawSurface3_Flip(dd_surface, NULL, DDFLIP_WAIT);
2114 }
2115 if ( result != DD_OK ) {
2116 SetDDerror("DirectDrawSurface3::Flip", result);
2117 return(-1);
2118 }
2119 return(0);
2120}
2121
2122static void DX5_FreeHWSurface(_THIS, SDL_Surface *surface)
2123{
2124 if ( surface->hwdata ) {
2125 if ( surface->hwdata->dd_surface != SDL_primary ) {
2126 IDirectDrawSurface3_Release(surface->hwdata->dd_surface);
2127 }
2128 SDL_free(surface->hwdata);
2129 surface->hwdata = NULL;
2130 }
2131}
2132
2133void DX5_WindowUpdate(_THIS, int numrects, SDL_Rect *rects)
2134{
2135 HRESULT result;
2136 int i;
2137 RECT src, dst;
2138
2139 for ( i=0; i<numrects; ++i ) {
2140 src.top = (LONG)rects[i].y;
2141 src.bottom = (LONG)rects[i].y+rects[i].h;
2142 src.left = (LONG)rects[i].x;
2143 src.right = (LONG)rects[i].x+rects[i].w;
2144 dst.top = SDL_bounds.top+src.top;
2145 dst.left = SDL_bounds.left+src.left;
2146 dst.bottom = SDL_bounds.top+src.bottom;
2147 dst.right = SDL_bounds.left+src.right;
2148 result = IDirectDrawSurface3_Blt(SDL_primary, &dst,
2149 this->screen->hwdata->dd_surface, &src,
2150 DDBLT_WAIT, NULL);
2151 /* Doh! Check for lost surface and restore it */
2152 if ( result == DDERR_SURFACELOST ) {
2153 IDirectDrawSurface3_Restore(SDL_primary);
2154 IDirectDrawSurface3_Blt(SDL_primary, &dst,
2155 this->screen->hwdata->dd_surface, &src,
2156 DDBLT_WAIT, NULL);
2157 }
2158 }
2159}
2160
2161void DX5_DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
2162{
2163}
2164
2165/* Compress a full palette into the limited number of colors given to us
2166 by windows.
2167
2168 The "best" way to do this is to sort the colors by diversity and place
2169 the most diverse colors into the limited palette. Unfortunately this
2170 results in widely varying colors being displayed in the interval during
2171 which the windows palette has been set, and the mapping of the shadow
2172 surface to the new palette. This is especially noticeable during fades.
2173
2174 To deal with this problem, we can copy a predetermined portion of the
2175 full palette, and use that as the limited palette. This allows colors
2176 to fade smoothly as the remapping is very similar on each palette change.
2177 Unfortunately, this breaks applications which partition the palette into
2178 distinct and widely varying areas, expecting all colors to be available.
2179
2180 I'm making them both available, chosen at compile time.
2181 If you want the chunk-o-palette algorithm, define SIMPLE_COMPRESSION,
2182 otherwise the sort-by-diversity algorithm will be used.
2183*/
2184#define SIMPLE_COMPRESSION
2185#define CS_CS_DIST(A, B) ({ \
2186 int r = (A.r - B.r); \
2187 int g = (A.g - B.g); \
2188 int b = (A.b - B.b); \
2189 (r*r + g*g + b*b); \
2190})
2191static void DX5_CompressPalette(_THIS, SDL_Color *colors, int ncolors, int maxcolors)
2192{
2193#ifdef SIMPLE_COMPRESSION
2194 int i, j;
2195#else
2196 static SDL_Color zero = { 0, 0, 0, 0 };
2197 int i, j;
2198 int max, dist;
2199 int prev, next;
2200 int *pool;
2201 int *seen, *order;
2202#endif
2203
2204 /* Does this happen? */
2205 if ( maxcolors > ncolors ) {
2206 maxcolors = ncolors;
2207 }
2208
2209#ifdef SIMPLE_COMPRESSION
2210 /* Just copy the first "maxcolors" colors */
2211 for ( j=10, i=0; i<maxcolors; ++i, ++j ) {
2212 SDL_colors[j].peRed = colors[i].r;
2213 SDL_colors[j].peGreen = colors[i].g;
2214 SDL_colors[j].peBlue = colors[i].b;
2215 }
2216#else
2217 /* Allocate memory for the arrays we use */
2218 pool = SDL_stack_alloc(int, 2*ncolors);
2219 if ( pool == NULL ) {
2220 /* No worries, just return */;
2221 return;
2222 }
2223 seen = pool;
2224 SDL_memset(seen, 0, ncolors*sizeof(int));
2225 order = pool+ncolors;
2226
2227 /* Start with the brightest color */
2228 max = 0;
2229 for ( i=0; i<ncolors; ++i ) {
2230 dist = CS_CS_DIST(zero, colors[i]);
2231 if ( dist >= max ) {
2232 max = dist;
2233 next = i;
2234 }
2235 }
2236 j = 0;
2237 order[j++] = next;
2238 seen[next] = 1;
2239 prev = next;
2240
2241 /* Keep going through all the colors */
2242 while ( j < maxcolors ) {
2243 max = 0;
2244 for ( i=0; i<ncolors; ++i ) {
2245 if ( seen[i] ) {
2246 continue;
2247 }
2248 dist = CS_CS_DIST(colors[i], colors[prev]);
2249 if ( dist >= max ) {
2250 max = dist;
2251 next = i;
2252 }
2253 }
2254 order[j++] = next;
2255 seen[next] = 1;
2256 prev = next;
2257 }
2258
2259 /* Compress the colors to the palette */
2260 for ( j=10, i=0; i<maxcolors; ++i, ++j ) {
2261 SDL_colors[j].peRed = colors[order[i]].r;
2262 SDL_colors[j].peGreen = colors[order[i]].g;
2263 SDL_colors[j].peBlue = colors[order[i]].b;
2264 }
2265 SDL_stack_free(pool);
2266#endif /* SIMPLE_COMPRESSION */
2267}
2268
2269/* Set the system colormap in both fullscreen and windowed modes */
2270int DX5_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
2271{
2272 int i;
2273 int alloct_all;
2274
2275 /* Copy palette colors into display palette */
2276 alloct_all = 0;
2277 if ( SDL_palette != NULL ) {
2278 if ( (this->screen->flags&SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
2279 /* We can set all entries explicitly */
2280 for ( i=0; i< ncolors; ++i ) {
2281 int j = firstcolor + i;
2282 SDL_colors[j].peRed = colors[i].r;
2283 SDL_colors[j].peGreen = colors[i].g;
2284 SDL_colors[j].peBlue = colors[i].b;
2285 }
2286 /* This sends an WM_PALETTECHANGED message to us */
2287 colorchange_expected = 1;
2288 IDirectDrawPalette_SetEntries(SDL_palette, 0,
2289 firstcolor, ncolors, &SDL_colors[firstcolor]);
2290 alloct_all = 1;
2291 } else {
2292 /* Grab the 236 most diverse colors in the palette */
2293 DX5_CompressPalette(this, colors, ncolors, 236);
2294 /* This sends an WM_PALETTECHANGED message to us */
2295 colorchange_expected = 1;
2296 IDirectDrawPalette_SetEntries(SDL_palette, 0,
2297 0, 256, SDL_colors);
2298 }
2299 }
2300 return(alloct_all);
2301}
2302
2303/* Gamma code is only available on DirectX 7 and newer */
2304static int DX5_SetGammaRamp(_THIS, Uint16 *ramp)
2305{
2306#ifdef IDirectDrawGammaControl_SetGammaRamp
2307 LPDIRECTDRAWGAMMACONTROL gamma;
2308 DDGAMMARAMP gamma_ramp;
2309 HRESULT result;
2310#endif
2311
2312 /* In windowed or OpenGL mode, use windib gamma code */
2313 if ( ! DDRAW_FULLSCREEN() ) {
2314 return DIB_SetGammaRamp(this, ramp);
2315 }
2316
2317#ifndef IDirectDrawGammaControl_SetGammaRamp
2318 SDL_SetError("SDL compiled without DirectX gamma ramp support");
2319 return -1;
2320#else
2321 /* Check for a video mode! */
2322 if ( ! SDL_primary ) {
2323 SDL_SetError("A video mode must be set for gamma correction");
2324 return(-1);
2325 }
2326
2327 /* Get the gamma control object */
2328 result = IDirectDrawSurface3_QueryInterface(SDL_primary,
2329 &IID_IDirectDrawGammaControl, (LPVOID *)&gamma);
2330 if ( result != DD_OK ) {
2331 SetDDerror("DirectDrawSurface3::QueryInterface(GAMMA)", result);
2332 return(-1);
2333 }
2334
2335 /* Set up the gamma ramp */
2336 SDL_memcpy(gamma_ramp.red, &ramp[0*256], 256*sizeof(*ramp));
2337 SDL_memcpy(gamma_ramp.green, &ramp[1*256], 256*sizeof(*ramp));
2338 SDL_memcpy(gamma_ramp.blue, &ramp[2*256], 256*sizeof(*ramp));
2339 result = IDirectDrawGammaControl_SetGammaRamp(gamma, 0, &gamma_ramp);
2340 if ( result != DD_OK ) {
2341 SetDDerror("DirectDrawGammaControl::SetGammaRamp()", result);
2342 }
2343
2344 /* Release the interface and return */
2345 IDirectDrawGammaControl_Release(gamma);
2346 return (result == DD_OK) ? 0 : -1;
2347#endif /* !IDirectDrawGammaControl_SetGammaRamp */
2348}
2349
2350static int DX5_GetGammaRamp(_THIS, Uint16 *ramp)
2351{
2352#ifdef IDirectDrawGammaControl_SetGammaRamp
2353 LPDIRECTDRAWGAMMACONTROL gamma;
2354 DDGAMMARAMP gamma_ramp;
2355 HRESULT result;
2356#endif
2357
2358 /* In windowed or OpenGL mode, use windib gamma code */
2359 if ( ! DDRAW_FULLSCREEN() ) {
2360 return DIB_GetGammaRamp(this, ramp);
2361 }
2362
2363#ifndef IDirectDrawGammaControl_SetGammaRamp
2364 SDL_SetError("SDL compiled without DirectX gamma ramp support");
2365 return -1;
2366#else
2367 /* Check for a video mode! */
2368 if ( ! SDL_primary ) {
2369 SDL_SetError("A video mode must be set for gamma correction");
2370 return(-1);
2371 }
2372
2373 /* Get the gamma control object */
2374 result = IDirectDrawSurface3_QueryInterface(SDL_primary,
2375 &IID_IDirectDrawGammaControl, (LPVOID *)&gamma);
2376 if ( result != DD_OK ) {
2377 SetDDerror("DirectDrawSurface3::QueryInterface(GAMMA)", result);
2378 return(-1);
2379 }
2380
2381 /* Set up the gamma ramp */
2382 result = IDirectDrawGammaControl_GetGammaRamp(gamma, 0, &gamma_ramp);
2383 if ( result == DD_OK ) {
2384 SDL_memcpy(&ramp[0*256], gamma_ramp.red, 256*sizeof(*ramp));
2385 SDL_memcpy(&ramp[1*256], gamma_ramp.green, 256*sizeof(*ramp));
2386 SDL_memcpy(&ramp[2*256], gamma_ramp.blue, 256*sizeof(*ramp));
2387 } else {
2388 SetDDerror("DirectDrawGammaControl::GetGammaRamp()", result);
2389 }
2390
2391 /* Release the interface and return */
2392 IDirectDrawGammaControl_Release(gamma);
2393 return (result == DD_OK) ? 0 : -1;
2394#endif /* !IDirectDrawGammaControl_SetGammaRamp */
2395}
2396
2397void DX5_VideoQuit(_THIS)
2398{
2399 int i, j;
2400
2401 /* If we're fullscreen GL, we need to reset the display */
2402 if ( this->screen != NULL ) {
2403#ifndef NO_CHANGEDISPLAYSETTINGS
2404 if ( (this->screen->flags & (SDL_OPENGL|SDL_FULLSCREEN)) ==
2405 (SDL_OPENGL|SDL_FULLSCREEN) ) {
2406 ChangeDisplaySettings(NULL, 0);
2407 ShowWindow(SDL_Window, SW_HIDE);
2408 }
2409#endif
2410 if ( this->screen->flags & SDL_OPENGL ) {
2411 WIN_GL_ShutDown(this);
2412 }
2413 }
2414
2415 /* Free any palettes we used */
2416 if ( SDL_palette != NULL ) {
2417 IDirectDrawPalette_Release(SDL_palette);
2418 SDL_palette = NULL;
2419 }
2420
2421 /* Allow the primary surface to be freed */
2422 if ( SDL_primary != NULL ) {
2423 SDL_primary = NULL;
2424 }
2425
2426 /* Free video mode lists */
2427 for ( i=0; i<NUM_MODELISTS; ++i ) {
2428 if ( SDL_modelist[i] != NULL ) {
2429 for ( j=0; SDL_modelist[i][j]; ++j )
2430 SDL_free(SDL_modelist[i][j]);
2431 SDL_free(SDL_modelist[i]);
2432 SDL_modelist[i] = NULL;
2433 }
2434 }
2435
2436 /* Free the window */
2437 DIB_QuitGamma(this);
2438 if ( SDL_Window ) {
2439 DX5_DestroyWindow(this);
2440 }
2441
2442 /* Free our window icon */
2443 if ( screen_icn ) {
2444 DestroyIcon(screen_icn);
2445 screen_icn = NULL;
2446 }
2447}
2448
2449/* Exported for the windows message loop only */
2450void DX5_Activate(_THIS, BOOL active, BOOL minimized)
2451{
2452}
2453void DX5_RealizePalette(_THIS)
2454{
2455 if ( SDL_palette ) {
2456 IDirectDrawSurface3_SetPalette(SDL_primary, SDL_palette);
2457 }
2458}
2459static void DX5_Recolor8Bit(_THIS, SDL_Surface *surface, Uint8 *mapping)
2460{
2461 int row, col;
2462 Uint8 *pixels;
2463
2464 if ( surface->w && surface->h ) {
2465 if ( (surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) {
2466 if ( this->LockHWSurface(this, surface) < 0 ) {
2467 return;
2468 }
2469 }
2470 for ( row=0; row<surface->h; ++row ) {
2471 pixels = (Uint8 *)surface->pixels+row*surface->pitch;
2472 for ( col=0; col<surface->w; ++col, ++pixels ) {
2473 *pixels = mapping[*pixels];
2474 }
2475 }
2476 if ( (surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) {
2477 this->UnlockHWSurface(this, surface);
2478 }
2479 SDL_UpdateRect(surface, 0, 0, 0, 0);
2480 }
2481}
2482void DX5_PaletteChanged(_THIS, HWND window)
2483{
2484 SDL_Palette *palette;
2485 SDL_Color *saved = NULL;
2486 HDC hdc;
2487 int i;
2488 PALETTEENTRY *entries;
2489
2490 /* This is true when the window is closing */
2491 if ( (SDL_primary == NULL) || (SDL_VideoSurface == NULL) )
2492 return;
2493
2494 /* We need to get the colors as they were set */
2495 palette = this->physpal;
2496 if(!palette)
2497 palette = SDL_VideoSurface->format->palette;
2498 if ( palette == NULL ) { /* Sometimes we don't have a palette */
2499 return;
2500 }
2501 entries = SDL_stack_alloc(PALETTEENTRY, palette->ncolors);
2502 hdc = GetDC(window);
2503 GetSystemPaletteEntries(hdc, 0, palette->ncolors, entries);
2504 ReleaseDC(window, hdc);
2505 if ( ! colorchange_expected ) {
2506 saved = SDL_stack_alloc(SDL_Color, palette->ncolors);
2507 SDL_memcpy(saved, palette->colors,
2508 palette->ncolors*sizeof(SDL_Color));
2509 }
2510 for ( i=0; i<palette->ncolors; ++i ) {
2511 palette->colors[i].r = entries[i].peRed;
2512 palette->colors[i].g = entries[i].peGreen;
2513 palette->colors[i].b = entries[i].peBlue;
2514 }
2515 SDL_stack_free(entries);
2516 if ( ! colorchange_expected ) {
2517 Uint8 mapping[256];
2518
2519 SDL_memset(mapping, 0, sizeof(mapping));
2520 for ( i=0; i<palette->ncolors; ++i ) {
2521 mapping[i] = SDL_FindColor(palette,
2522 saved[i].r, saved[i].g, saved[i].b);
2523 }
2524 DX5_Recolor8Bit(this, SDL_VideoSurface, mapping);
2525 SDL_stack_free(saved);
2526 }
2527 colorchange_expected = 0;
2528
2529 /* Notify all mapped surfaces of the change */
2530 SDL_FormatChanged(SDL_VideoSurface);
2531}
2532
2533/* Exported for the windows message loop only */
2534void DX5_WinPAINT(_THIS, HDC hdc)
2535{
2536 SDL_UpdateRect(SDL_PublicSurface, 0, 0, 0, 0);
2537}
diff --git a/apps/plugins/sdl/src/video/windx5/SDL_dx5video.h b/apps/plugins/sdl/src/video/windx5/SDL_dx5video.h
deleted file mode 100644
index 3d754a0e2e..0000000000
--- a/apps/plugins/sdl/src/video/windx5/SDL_dx5video.h
+++ /dev/null
@@ -1,61 +0,0 @@
1/*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2012 Sam Lantinga
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library 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 GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19 Sam Lantinga
20 slouken@libsdl.org
21*/
22#include "SDL_config.h"
23
24#ifndef _SDL_dx5video_h
25#define _SDL_dx5video_h
26
27#include "directx.h"
28
29/* Private display data */
30struct SDL_PrivateVideoData {
31 LPDIRECTDRAW2 ddraw2;
32 LPDIRECTDRAWSURFACE3 SDL_primary;
33 LPDIRECTDRAWCLIPPER SDL_clipper;
34 LPDIRECTDRAWPALETTE SDL_palette;
35 PALETTEENTRY SDL_colors[256];
36 int colorchange_expected;
37
38#define NUM_MODELISTS 4 /* 8, 16, 24, and 32 bits-per-pixel */
39 int SDL_nummodes[NUM_MODELISTS];
40 SDL_Rect **SDL_modelist[NUM_MODELISTS];
41 int SDL_modeindex[NUM_MODELISTS];
42};
43/* Old variable names */
44#define ddraw2 (this->hidden->ddraw2)
45#define SDL_primary (this->hidden->SDL_primary)
46#define SDL_clipper (this->hidden->SDL_clipper)
47#define SDL_palette (this->hidden->SDL_palette)
48#define SDL_colors (this->hidden->SDL_colors)
49#define colorchange_expected (this->hidden->colorchange_expected)
50#define SDL_nummodes (this->hidden->SDL_nummodes)
51#define SDL_modelist (this->hidden->SDL_modelist)
52#define SDL_modeindex (this->hidden->SDL_modeindex)
53
54/* DirectX function pointers for video and events */
55extern HRESULT (WINAPI *DDrawCreate)( GUID FAR *lpGUID, LPDIRECTDRAW FAR *lplpDD, IUnknown FAR *pUnkOuter );
56extern HRESULT (WINAPI *DInputCreate)(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUT *ppDI, LPUNKNOWN punkOuter);
57
58/* DirectDraw error reporting function */
59extern void SetDDerror(const char *function, int code);
60
61#endif /* _SDL_dx5video_h */
diff --git a/apps/plugins/sdl/src/video/windx5/SDL_dx5yuv.c b/apps/plugins/sdl/src/video/windx5/SDL_dx5yuv.c
deleted file mode 100644
index cb89fdc9bb..0000000000
--- a/apps/plugins/sdl/src/video/windx5/SDL_dx5yuv.c
+++ /dev/null
@@ -1,296 +0,0 @@
1/*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2012 Sam Lantinga
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library 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 GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19 Sam Lantinga
20 slouken@libsdl.org
21*/
22#include "SDL_config.h"
23
24/* This is the DirectDraw implementation of YUV video overlays */
25#include "directx.h"
26#include "SDL_video.h"
27#include "SDL_dx5yuv_c.h"
28#include "../SDL_yuvfuncs.h"
29
30//#define USE_DIRECTX_OVERLAY
31
32/* The functions used to manipulate software video overlays */
33static struct private_yuvhwfuncs dx5_yuvfuncs = {
34 DX5_LockYUVOverlay,
35 DX5_UnlockYUVOverlay,
36 DX5_DisplayYUVOverlay,
37 DX5_FreeYUVOverlay
38};
39
40struct private_yuvhwdata {
41 LPDIRECTDRAWSURFACE3 surface;
42
43 /* These are just so we don't have to allocate them separately */
44 Uint16 pitches[3];
45 Uint8 *planes[3];
46};
47
48
49static LPDIRECTDRAWSURFACE3 CreateYUVSurface(_THIS,
50 int width, int height, Uint32 format)
51{
52 HRESULT result;
53 LPDIRECTDRAWSURFACE dd_surface1;
54 LPDIRECTDRAWSURFACE3 dd_surface3;
55 DDSURFACEDESC ddsd;
56
57 /* Set up the surface description */
58 SDL_memset(&ddsd, 0, sizeof(ddsd));
59 ddsd.dwSize = sizeof(ddsd);
60 ddsd.dwFlags = (DDSD_WIDTH|DDSD_HEIGHT|DDSD_CAPS|DDSD_PIXELFORMAT);
61 ddsd.dwWidth = width;
62 ddsd.dwHeight= height;
63#ifdef USE_DIRECTX_OVERLAY
64 ddsd.ddsCaps.dwCaps = (DDSCAPS_OVERLAY|DDSCAPS_VIDEOMEMORY);
65#else
66 ddsd.ddsCaps.dwCaps = (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_VIDEOMEMORY);
67#endif
68 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
69 ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC;
70 ddsd.ddpfPixelFormat.dwFourCC = format;
71
72 /* Create the DirectDraw video surface */
73 result = IDirectDraw2_CreateSurface(ddraw2, &ddsd, &dd_surface1, NULL);
74 if ( result != DD_OK ) {
75 SetDDerror("DirectDraw2::CreateSurface", result);
76 return(NULL);
77 }
78 result = IDirectDrawSurface_QueryInterface(dd_surface1,
79 &IID_IDirectDrawSurface3, (LPVOID *)&dd_surface3);
80 IDirectDrawSurface_Release(dd_surface1);
81 if ( result != DD_OK ) {
82 SetDDerror("DirectDrawSurface::QueryInterface", result);
83 return(NULL);
84 }
85
86 /* Make sure the surface format was set properly */
87 SDL_memset(&ddsd, 0, sizeof(ddsd));
88 ddsd.dwSize = sizeof(ddsd);
89 result = IDirectDrawSurface3_Lock(dd_surface3, NULL,
90 &ddsd, DDLOCK_NOSYSLOCK, NULL);
91 if ( result != DD_OK ) {
92 SetDDerror("DirectDrawSurface3::Lock", result);
93 IDirectDrawSurface_Release(dd_surface3);
94 return(NULL);
95 }
96 IDirectDrawSurface3_Unlock(dd_surface3, NULL);
97
98 if ( !(ddsd.ddpfPixelFormat.dwFlags & DDPF_FOURCC) ||
99 (ddsd.ddpfPixelFormat.dwFourCC != format) ) {
100 SDL_SetError("DDraw didn't use requested FourCC format");
101 IDirectDrawSurface_Release(dd_surface3);
102 return(NULL);
103 }
104
105 /* We're ready to go! */
106 return(dd_surface3);
107}
108
109#ifdef DEBUG_YUV
110static char *PrintFOURCC(Uint32 code)
111{
112 static char buf[5];
113
114 buf[3] = code >> 24;
115 buf[2] = (code >> 16) & 0xFF;
116 buf[1] = (code >> 8) & 0xFF;
117 buf[0] = (code & 0xFF);
118 return(buf);
119}
120#endif
121
122SDL_Overlay *DX5_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display)
123{
124 SDL_Overlay *overlay;
125 struct private_yuvhwdata *hwdata;
126
127#ifdef DEBUG_YUV
128 DWORD numcodes;
129 DWORD *codes;
130
131 printf("FOURCC format requested: 0x%x\n", PrintFOURCC(format));
132 IDirectDraw2_GetFourCCCodes(ddraw2, &numcodes, NULL);
133 if ( numcodes ) {
134 DWORD i;
135 codes = SDL_malloc(numcodes*sizeof(*codes));
136 if ( codes ) {
137 IDirectDraw2_GetFourCCCodes(ddraw2, &numcodes, codes);
138 for ( i=0; i<numcodes; ++i ) {
139 fprintf(stderr, "Code %d: 0x%x\n", i, PrintFOURCC(codes[i]));
140 }
141 SDL_free(codes);
142 }
143 } else {
144 fprintf(stderr, "No FOURCC codes supported\n");
145 }
146#endif
147
148 /* Create the overlay structure */
149 overlay = (SDL_Overlay *)SDL_malloc(sizeof *overlay);
150 if ( overlay == NULL ) {
151 SDL_OutOfMemory();
152 return(NULL);
153 }
154 SDL_memset(overlay, 0, (sizeof *overlay));
155
156 /* Fill in the basic members */
157 overlay->format = format;
158 overlay->w = width;
159 overlay->h = height;
160
161 /* Set up the YUV surface function structure */
162 overlay->hwfuncs = &dx5_yuvfuncs;
163
164 /* Create the pixel data and lookup tables */
165 hwdata = (struct private_yuvhwdata *)SDL_malloc(sizeof *hwdata);
166 overlay->hwdata = hwdata;
167 if ( hwdata == NULL ) {
168 SDL_OutOfMemory();
169 SDL_FreeYUVOverlay(overlay);
170 return(NULL);
171 }
172 hwdata->surface = CreateYUVSurface(this, width, height, format);
173 if ( hwdata->surface == NULL ) {
174 SDL_FreeYUVOverlay(overlay);
175 return(NULL);
176 }
177 overlay->hw_overlay = 1;
178
179 /* Set up the plane pointers */
180 overlay->pitches = hwdata->pitches;
181 overlay->pixels = hwdata->planes;
182 switch (format) {
183 case SDL_YV12_OVERLAY:
184 case SDL_IYUV_OVERLAY:
185 overlay->planes = 3;
186 break;
187 default:
188 overlay->planes = 1;
189 break;
190 }
191
192 /* We're all done.. */
193 return(overlay);
194}
195
196int DX5_LockYUVOverlay(_THIS, SDL_Overlay *overlay)
197{
198 HRESULT result;
199 LPDIRECTDRAWSURFACE3 surface;
200 DDSURFACEDESC ddsd;
201
202 surface = overlay->hwdata->surface;
203 SDL_memset(&ddsd, 0, sizeof(ddsd));
204 ddsd.dwSize = sizeof(ddsd);
205 result = IDirectDrawSurface3_Lock(surface, NULL,
206 &ddsd, DDLOCK_NOSYSLOCK, NULL);
207 if ( result == DDERR_SURFACELOST ) {
208 result = IDirectDrawSurface3_Restore(surface);
209 result = IDirectDrawSurface3_Lock(surface, NULL, &ddsd,
210 (DDLOCK_NOSYSLOCK|DDLOCK_WAIT), NULL);
211 }
212 if ( result != DD_OK ) {
213 SetDDerror("DirectDrawSurface3::Lock", result);
214 return(-1);
215 }
216
217 /* Find the pitch and offset values for the overlay */
218#if defined(NONAMELESSUNION)
219 overlay->pitches[0] = (Uint16)ddsd.u1.lPitch;
220#else
221 overlay->pitches[0] = (Uint16)ddsd.lPitch;
222#endif
223 overlay->pixels[0] = (Uint8 *)ddsd.lpSurface;
224 switch (overlay->format) {
225 case SDL_YV12_OVERLAY:
226 case SDL_IYUV_OVERLAY:
227 /* Add the two extra planes */
228 overlay->pitches[1] = overlay->pitches[0] / 2;
229 overlay->pitches[2] = overlay->pitches[0] / 2;
230 overlay->pixels[1] = overlay->pixels[0] +
231 overlay->pitches[0] * overlay->h;
232 overlay->pixels[2] = overlay->pixels[1] +
233 overlay->pitches[1] * overlay->h / 2;
234 break;
235 default:
236 /* Only one plane, no worries */
237 break;
238 }
239 return(0);
240}
241
242void DX5_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay)
243{
244 LPDIRECTDRAWSURFACE3 surface;
245
246 surface = overlay->hwdata->surface;
247 IDirectDrawSurface3_Unlock(surface, NULL);
248}
249
250int DX5_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *src, SDL_Rect *dst)
251{
252 HRESULT result;
253 LPDIRECTDRAWSURFACE3 surface;
254 RECT srcrect, dstrect;
255
256 surface = overlay->hwdata->surface;
257 srcrect.top = src->y;
258 srcrect.bottom = srcrect.top+src->h;
259 srcrect.left = src->x;
260 srcrect.right = srcrect.left+src->w;
261 dstrect.top = SDL_bounds.top+dst->y;
262 dstrect.left = SDL_bounds.left+dst->x;
263 dstrect.bottom = dstrect.top+dst->h;
264 dstrect.right = dstrect.left+dst->w;
265#ifdef USE_DIRECTX_OVERLAY
266 result = IDirectDrawSurface3_UpdateOverlay(surface, &srcrect,
267 SDL_primary, &dstrect, DDOVER_SHOW, NULL);
268 if ( result != DD_OK ) {
269 SetDDerror("DirectDrawSurface3::UpdateOverlay", result);
270 return(-1);
271 }
272#else
273 result = IDirectDrawSurface3_Blt(SDL_primary, &dstrect, surface, &srcrect,
274 DDBLT_WAIT, NULL);
275 if ( result != DD_OK ) {
276 SetDDerror("DirectDrawSurface3::Blt", result);
277 return(-1);
278 }
279#endif
280 return(0);
281}
282
283void DX5_FreeYUVOverlay(_THIS, SDL_Overlay *overlay)
284{
285 struct private_yuvhwdata *hwdata;
286
287 hwdata = overlay->hwdata;
288 if ( hwdata ) {
289 if ( hwdata->surface ) {
290 IDirectDrawSurface_Release(hwdata->surface);
291 }
292 SDL_free(hwdata);
293 overlay->hwdata = NULL;
294 }
295}
296
diff --git a/apps/plugins/sdl/src/video/windx5/SDL_dx5yuv_c.h b/apps/plugins/sdl/src/video/windx5/SDL_dx5yuv_c.h
deleted file mode 100644
index dfceaf929a..0000000000
--- a/apps/plugins/sdl/src/video/windx5/SDL_dx5yuv_c.h
+++ /dev/null
@@ -1,38 +0,0 @@
1/*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2012 Sam Lantinga
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library 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 GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19 Sam Lantinga
20 slouken@libsdl.org
21*/
22#include "SDL_config.h"
23
24/* This is the DirectDraw implementation of YUV video overlays */
25
26#include "SDL_video.h"
27#include "../wincommon/SDL_lowvideo.h"
28#include "SDL_dx5video.h"
29
30extern SDL_Overlay *DX5_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display);
31
32extern int DX5_LockYUVOverlay(_THIS, SDL_Overlay *overlay);
33
34extern void DX5_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay);
35
36extern int DX5_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *src, SDL_Rect *dst);
37
38extern void DX5_FreeYUVOverlay(_THIS, SDL_Overlay *overlay);
diff --git a/apps/plugins/sdl/src/video/windx5/directx.h b/apps/plugins/sdl/src/video/windx5/directx.h
deleted file mode 100644
index c7f536530b..0000000000
--- a/apps/plugins/sdl/src/video/windx5/directx.h
+++ /dev/null
@@ -1,97 +0,0 @@
1
2#ifndef _directx_h
3#define _directx_h
4
5/* Include all of the DirectX 5.0 headers and adds any necessary tweaks */
6
7#define WIN32_LEAN_AND_MEAN
8#include <windows.h>
9#include <mmsystem.h>
10#ifndef WIN32
11#define WIN32
12#endif
13#undef WINNT
14
15/* Far pointers don't exist in 32-bit code */
16#ifndef FAR
17#define FAR
18#endif
19
20/* Error codes not yet included in Win32 API header files */
21#ifndef MAKE_HRESULT
22#define MAKE_HRESULT(sev,fac,code) \
23 ((HRESULT)(((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code))))
24#endif
25
26#ifndef S_OK
27#define S_OK (HRESULT)0x00000000L
28#endif
29
30#ifndef SUCCEEDED
31#define SUCCEEDED(x) ((HRESULT)(x) >= 0)
32#endif
33#ifndef FAILED
34#define FAILED(x) ((HRESULT)(x)<0)
35#endif
36
37#ifndef E_FAIL
38#define E_FAIL (HRESULT)0x80000008L
39#endif
40#ifndef E_NOINTERFACE
41#define E_NOINTERFACE (HRESULT)0x80004002L
42#endif
43#ifndef E_OUTOFMEMORY
44#define E_OUTOFMEMORY (HRESULT)0x8007000EL
45#endif
46#ifndef E_INVALIDARG
47#define E_INVALIDARG (HRESULT)0x80070057L
48#endif
49#ifndef E_NOTIMPL
50#define E_NOTIMPL (HRESULT)0x80004001L
51#endif
52#ifndef REGDB_E_CLASSNOTREG
53#define REGDB_E_CLASSNOTREG (HRESULT)0x80040154L
54#endif
55
56/* Severity codes */
57#ifndef SEVERITY_ERROR
58#define SEVERITY_ERROR 1
59#endif
60
61/* Error facility codes */
62#ifndef FACILITY_WIN32
63#define FACILITY_WIN32 7
64#endif
65
66#ifndef FIELD_OFFSET
67#define FIELD_OFFSET(type, field) ((LONG)&(((type *)0)->field))
68#endif
69
70/* DirectX headers (if it isn't included, I haven't tested it yet)
71 */
72/* We need these defines to mark what version of DirectX API we use */
73#define DIRECTDRAW_VERSION 0x0700
74#define DIRECTSOUND_VERSION 0x0500
75#define DIRECTINPUT_VERSION 0x0700
76
77#include <ddraw.h>
78#include <dsound.h>
79#include <dinput.h>
80
81#if DIRECTINPUT_VERSION >= 0x0700 && !defined(DIMOFS_BUTTON4)
82typedef struct _DIMOUSESTATE2 {
83 LONG lX;
84 LONG lY;
85 LONG lZ;
86 BYTE rgbButtons[8];
87} DIMOUSESTATE2, *LPDIMOUSESTATE2;
88
89#define DIMOFS_BUTTON4 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 4)
90#define DIMOFS_BUTTON5 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 5)
91#define DIMOFS_BUTTON6 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 6)
92#define DIMOFS_BUTTON7 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 7)
93
94extern const DIDATAFORMAT c_dfDIMouse2;
95#endif
96
97#endif /* _directx_h */