src/video/windx5/SDL_dx5video.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 28 May 2006 13:04:16 +0000
branchSDL-1.3
changeset 1662 782fd950bd46
parent 1661 281d3f4870e5
child 1668 4da1ee79c9af
permissions -rw-r--r--
Revamp of the video system in progress - adding support for multiple displays, multiple windows, and a full video mode selection API.

WARNING: None of the video drivers have been updated for the new API yet! The API is still under design and very fluid.

The code is now run through a consistent indent format:
indent -i4 -nut -nsc -br -ce

The headers are being converted to automatically generate doxygen documentation.
slouken@0
     1
/*
slouken@0
     2
    SDL - Simple DirectMedia Layer
slouken@1312
     3
    Copyright (C) 1997-2006 Sam Lantinga
slouken@0
     4
slouken@0
     5
    This library is free software; you can redistribute it and/or
slouken@1312
     6
    modify it under the terms of the GNU Lesser General Public
slouken@0
     7
    License as published by the Free Software Foundation; either
slouken@1312
     8
    version 2.1 of the License, or (at your option) any later version.
slouken@0
     9
slouken@0
    10
    This library is distributed in the hope that it will be useful,
slouken@0
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@0
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@1312
    13
    Lesser General Public License for more details.
slouken@0
    14
slouken@1312
    15
    You should have received a copy of the GNU Lesser General Public
slouken@1312
    16
    License along with this library; if not, write to the Free Software
slouken@1312
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
slouken@0
    18
slouken@0
    19
    Sam Lantinga
slouken@252
    20
    slouken@libsdl.org
slouken@0
    21
*/
slouken@1402
    22
#include "SDL_config.h"
slouken@0
    23
slouken@0
    24
#include "directx.h"
slouken@0
    25
slouken@0
    26
/* Not yet in the mingw32 cross-compile headers */
slouken@0
    27
#ifndef CDS_FULLSCREEN
slouken@0
    28
#define CDS_FULLSCREEN	4
slouken@0
    29
#endif
slouken@0
    30
slouken@0
    31
#include "SDL_timer.h"
slouken@0
    32
#include "SDL_events.h"
slouken@0
    33
#include "SDL_syswm.h"
slouken@1361
    34
#include "../SDL_sysvideo.h"
slouken@1361
    35
#include "../SDL_blit.h"
slouken@1361
    36
#include "../SDL_pixels_c.h"
slouken@0
    37
#include "SDL_dx5video.h"
slouken@1361
    38
#include "../wincommon/SDL_syswm_c.h"
slouken@1361
    39
#include "../wincommon/SDL_sysmouse_c.h"
slouken@0
    40
#include "SDL_dx5events_c.h"
slouken@0
    41
#include "SDL_dx5yuv_c.h"
slouken@1361
    42
#include "../wincommon/SDL_wingl_c.h"
slouken@0
    43
slouken@453
    44
#ifdef _WIN32_WCE
slouken@453
    45
#define NO_CHANGEDISPLAYSETTINGS
slouken@453
    46
#endif
slouken@453
    47
#ifndef WS_MAXIMIZE
slouken@453
    48
#define WS_MAXIMIZE		0
slouken@453
    49
#endif
slouken@453
    50
#ifndef SWP_NOCOPYBITS
slouken@453
    51
#define SWP_NOCOPYBITS	0
slouken@453
    52
#endif
slouken@453
    53
#ifndef PC_NOCOLLAPSE
slouken@453
    54
#define PC_NOCOLLAPSE	0
slouken@453
    55
#endif
slouken@453
    56
slouken@0
    57
slouken@0
    58
/* DirectX function pointers for video and events */
slouken@1662
    59
HRESULT (WINAPI * DDrawCreate) (GUID FAR * lpGUID, LPDIRECTDRAW FAR * lplpDD,
slouken@1662
    60
                                IUnknown FAR * pUnkOuter);
slouken@1662
    61
HRESULT (WINAPI * DInputCreate) (HINSTANCE hinst, DWORD dwVersion,
slouken@1662
    62
                                 LPDIRECTINPUT * ppDI, LPUNKNOWN punkOuter);
slouken@0
    63
slouken@0
    64
/* This is the rect EnumModes2 uses */
slouken@1662
    65
struct DX5EnumRect
slouken@1662
    66
{
slouken@1662
    67
    SDL_Rect r;
slouken@1662
    68
    int refreshRate;
slouken@1662
    69
    struct DX5EnumRect *next;
slouken@0
    70
};
slouken@0
    71
static struct DX5EnumRect *enumlists[NUM_MODELISTS];
slouken@0
    72
slouken@0
    73
/*
slouken@0
    74
 * Experimentally determined values for c_cfDI* constants used in DirectX 5.0
slouken@0
    75
 */
slouken@0
    76
slouken@0
    77
/* Keyboard */
slouken@0
    78
slouken@0
    79
static DIOBJECTDATAFORMAT KBD_fmt[] = {
slouken@1662
    80
    {&GUID_Key, 0, 0x8000000C, 0x00000000},
slouken@1662
    81
    {&GUID_Key, 1, 0x8000010C, 0x00000000},
slouken@1662
    82
    {&GUID_Key, 2, 0x8000020C, 0x00000000},
slouken@1662
    83
    {&GUID_Key, 3, 0x8000030C, 0x00000000},
slouken@1662
    84
    {&GUID_Key, 4, 0x8000040C, 0x00000000},
slouken@1662
    85
    {&GUID_Key, 5, 0x8000050C, 0x00000000},
slouken@1662
    86
    {&GUID_Key, 6, 0x8000060C, 0x00000000},
slouken@1662
    87
    {&GUID_Key, 7, 0x8000070C, 0x00000000},
slouken@1662
    88
    {&GUID_Key, 8, 0x8000080C, 0x00000000},
slouken@1662
    89
    {&GUID_Key, 9, 0x8000090C, 0x00000000},
slouken@1662
    90
    {&GUID_Key, 10, 0x80000A0C, 0x00000000},
slouken@1662
    91
    {&GUID_Key, 11, 0x80000B0C, 0x00000000},
slouken@1662
    92
    {&GUID_Key, 12, 0x80000C0C, 0x00000000},
slouken@1662
    93
    {&GUID_Key, 13, 0x80000D0C, 0x00000000},
slouken@1662
    94
    {&GUID_Key, 14, 0x80000E0C, 0x00000000},
slouken@1662
    95
    {&GUID_Key, 15, 0x80000F0C, 0x00000000},
slouken@1662
    96
    {&GUID_Key, 16, 0x8000100C, 0x00000000},
slouken@1662
    97
    {&GUID_Key, 17, 0x8000110C, 0x00000000},
slouken@1662
    98
    {&GUID_Key, 18, 0x8000120C, 0x00000000},
slouken@1662
    99
    {&GUID_Key, 19, 0x8000130C, 0x00000000},
slouken@1662
   100
    {&GUID_Key, 20, 0x8000140C, 0x00000000},
slouken@1662
   101
    {&GUID_Key, 21, 0x8000150C, 0x00000000},
slouken@1662
   102
    {&GUID_Key, 22, 0x8000160C, 0x00000000},
slouken@1662
   103
    {&GUID_Key, 23, 0x8000170C, 0x00000000},
slouken@1662
   104
    {&GUID_Key, 24, 0x8000180C, 0x00000000},
slouken@1662
   105
    {&GUID_Key, 25, 0x8000190C, 0x00000000},
slouken@1662
   106
    {&GUID_Key, 26, 0x80001A0C, 0x00000000},
slouken@1662
   107
    {&GUID_Key, 27, 0x80001B0C, 0x00000000},
slouken@1662
   108
    {&GUID_Key, 28, 0x80001C0C, 0x00000000},
slouken@1662
   109
    {&GUID_Key, 29, 0x80001D0C, 0x00000000},
slouken@1662
   110
    {&GUID_Key, 30, 0x80001E0C, 0x00000000},
slouken@1662
   111
    {&GUID_Key, 31, 0x80001F0C, 0x00000000},
slouken@1662
   112
    {&GUID_Key, 32, 0x8000200C, 0x00000000},
slouken@1662
   113
    {&GUID_Key, 33, 0x8000210C, 0x00000000},
slouken@1662
   114
    {&GUID_Key, 34, 0x8000220C, 0x00000000},
slouken@1662
   115
    {&GUID_Key, 35, 0x8000230C, 0x00000000},
slouken@1662
   116
    {&GUID_Key, 36, 0x8000240C, 0x00000000},
slouken@1662
   117
    {&GUID_Key, 37, 0x8000250C, 0x00000000},
slouken@1662
   118
    {&GUID_Key, 38, 0x8000260C, 0x00000000},
slouken@1662
   119
    {&GUID_Key, 39, 0x8000270C, 0x00000000},
slouken@1662
   120
    {&GUID_Key, 40, 0x8000280C, 0x00000000},
slouken@1662
   121
    {&GUID_Key, 41, 0x8000290C, 0x00000000},
slouken@1662
   122
    {&GUID_Key, 42, 0x80002A0C, 0x00000000},
slouken@1662
   123
    {&GUID_Key, 43, 0x80002B0C, 0x00000000},
slouken@1662
   124
    {&GUID_Key, 44, 0x80002C0C, 0x00000000},
slouken@1662
   125
    {&GUID_Key, 45, 0x80002D0C, 0x00000000},
slouken@1662
   126
    {&GUID_Key, 46, 0x80002E0C, 0x00000000},
slouken@1662
   127
    {&GUID_Key, 47, 0x80002F0C, 0x00000000},
slouken@1662
   128
    {&GUID_Key, 48, 0x8000300C, 0x00000000},
slouken@1662
   129
    {&GUID_Key, 49, 0x8000310C, 0x00000000},
slouken@1662
   130
    {&GUID_Key, 50, 0x8000320C, 0x00000000},
slouken@1662
   131
    {&GUID_Key, 51, 0x8000330C, 0x00000000},
slouken@1662
   132
    {&GUID_Key, 52, 0x8000340C, 0x00000000},
slouken@1662
   133
    {&GUID_Key, 53, 0x8000350C, 0x00000000},
slouken@1662
   134
    {&GUID_Key, 54, 0x8000360C, 0x00000000},
slouken@1662
   135
    {&GUID_Key, 55, 0x8000370C, 0x00000000},
slouken@1662
   136
    {&GUID_Key, 56, 0x8000380C, 0x00000000},
slouken@1662
   137
    {&GUID_Key, 57, 0x8000390C, 0x00000000},
slouken@1662
   138
    {&GUID_Key, 58, 0x80003A0C, 0x00000000},
slouken@1662
   139
    {&GUID_Key, 59, 0x80003B0C, 0x00000000},
slouken@1662
   140
    {&GUID_Key, 60, 0x80003C0C, 0x00000000},
slouken@1662
   141
    {&GUID_Key, 61, 0x80003D0C, 0x00000000},
slouken@1662
   142
    {&GUID_Key, 62, 0x80003E0C, 0x00000000},
slouken@1662
   143
    {&GUID_Key, 63, 0x80003F0C, 0x00000000},
slouken@1662
   144
    {&GUID_Key, 64, 0x8000400C, 0x00000000},
slouken@1662
   145
    {&GUID_Key, 65, 0x8000410C, 0x00000000},
slouken@1662
   146
    {&GUID_Key, 66, 0x8000420C, 0x00000000},
slouken@1662
   147
    {&GUID_Key, 67, 0x8000430C, 0x00000000},
slouken@1662
   148
    {&GUID_Key, 68, 0x8000440C, 0x00000000},
slouken@1662
   149
    {&GUID_Key, 69, 0x8000450C, 0x00000000},
slouken@1662
   150
    {&GUID_Key, 70, 0x8000460C, 0x00000000},
slouken@1662
   151
    {&GUID_Key, 71, 0x8000470C, 0x00000000},
slouken@1662
   152
    {&GUID_Key, 72, 0x8000480C, 0x00000000},
slouken@1662
   153
    {&GUID_Key, 73, 0x8000490C, 0x00000000},
slouken@1662
   154
    {&GUID_Key, 74, 0x80004A0C, 0x00000000},
slouken@1662
   155
    {&GUID_Key, 75, 0x80004B0C, 0x00000000},
slouken@1662
   156
    {&GUID_Key, 76, 0x80004C0C, 0x00000000},
slouken@1662
   157
    {&GUID_Key, 77, 0x80004D0C, 0x00000000},
slouken@1662
   158
    {&GUID_Key, 78, 0x80004E0C, 0x00000000},
slouken@1662
   159
    {&GUID_Key, 79, 0x80004F0C, 0x00000000},
slouken@1662
   160
    {&GUID_Key, 80, 0x8000500C, 0x00000000},
slouken@1662
   161
    {&GUID_Key, 81, 0x8000510C, 0x00000000},
slouken@1662
   162
    {&GUID_Key, 82, 0x8000520C, 0x00000000},
slouken@1662
   163
    {&GUID_Key, 83, 0x8000530C, 0x00000000},
slouken@1662
   164
    {&GUID_Key, 84, 0x8000540C, 0x00000000},
slouken@1662
   165
    {&GUID_Key, 85, 0x8000550C, 0x00000000},
slouken@1662
   166
    {&GUID_Key, 86, 0x8000560C, 0x00000000},
slouken@1662
   167
    {&GUID_Key, 87, 0x8000570C, 0x00000000},
slouken@1662
   168
    {&GUID_Key, 88, 0x8000580C, 0x00000000},
slouken@1662
   169
    {&GUID_Key, 89, 0x8000590C, 0x00000000},
slouken@1662
   170
    {&GUID_Key, 90, 0x80005A0C, 0x00000000},
slouken@1662
   171
    {&GUID_Key, 91, 0x80005B0C, 0x00000000},
slouken@1662
   172
    {&GUID_Key, 92, 0x80005C0C, 0x00000000},
slouken@1662
   173
    {&GUID_Key, 93, 0x80005D0C, 0x00000000},
slouken@1662
   174
    {&GUID_Key, 94, 0x80005E0C, 0x00000000},
slouken@1662
   175
    {&GUID_Key, 95, 0x80005F0C, 0x00000000},
slouken@1662
   176
    {&GUID_Key, 96, 0x8000600C, 0x00000000},
slouken@1662
   177
    {&GUID_Key, 97, 0x8000610C, 0x00000000},
slouken@1662
   178
    {&GUID_Key, 98, 0x8000620C, 0x00000000},
slouken@1662
   179
    {&GUID_Key, 99, 0x8000630C, 0x00000000},
slouken@1662
   180
    {&GUID_Key, 100, 0x8000640C, 0x00000000},
slouken@1662
   181
    {&GUID_Key, 101, 0x8000650C, 0x00000000},
slouken@1662
   182
    {&GUID_Key, 102, 0x8000660C, 0x00000000},
slouken@1662
   183
    {&GUID_Key, 103, 0x8000670C, 0x00000000},
slouken@1662
   184
    {&GUID_Key, 104, 0x8000680C, 0x00000000},
slouken@1662
   185
    {&GUID_Key, 105, 0x8000690C, 0x00000000},
slouken@1662
   186
    {&GUID_Key, 106, 0x80006A0C, 0x00000000},
slouken@1662
   187
    {&GUID_Key, 107, 0x80006B0C, 0x00000000},
slouken@1662
   188
    {&GUID_Key, 108, 0x80006C0C, 0x00000000},
slouken@1662
   189
    {&GUID_Key, 109, 0x80006D0C, 0x00000000},
slouken@1662
   190
    {&GUID_Key, 110, 0x80006E0C, 0x00000000},
slouken@1662
   191
    {&GUID_Key, 111, 0x80006F0C, 0x00000000},
slouken@1662
   192
    {&GUID_Key, 112, 0x8000700C, 0x00000000},
slouken@1662
   193
    {&GUID_Key, 113, 0x8000710C, 0x00000000},
slouken@1662
   194
    {&GUID_Key, 114, 0x8000720C, 0x00000000},
slouken@1662
   195
    {&GUID_Key, 115, 0x8000730C, 0x00000000},
slouken@1662
   196
    {&GUID_Key, 116, 0x8000740C, 0x00000000},
slouken@1662
   197
    {&GUID_Key, 117, 0x8000750C, 0x00000000},
slouken@1662
   198
    {&GUID_Key, 118, 0x8000760C, 0x00000000},
slouken@1662
   199
    {&GUID_Key, 119, 0x8000770C, 0x00000000},
slouken@1662
   200
    {&GUID_Key, 120, 0x8000780C, 0x00000000},
slouken@1662
   201
    {&GUID_Key, 121, 0x8000790C, 0x00000000},
slouken@1662
   202
    {&GUID_Key, 122, 0x80007A0C, 0x00000000},
slouken@1662
   203
    {&GUID_Key, 123, 0x80007B0C, 0x00000000},
slouken@1662
   204
    {&GUID_Key, 124, 0x80007C0C, 0x00000000},
slouken@1662
   205
    {&GUID_Key, 125, 0x80007D0C, 0x00000000},
slouken@1662
   206
    {&GUID_Key, 126, 0x80007E0C, 0x00000000},
slouken@1662
   207
    {&GUID_Key, 127, 0x80007F0C, 0x00000000},
slouken@1662
   208
    {&GUID_Key, 128, 0x8000800C, 0x00000000},
slouken@1662
   209
    {&GUID_Key, 129, 0x8000810C, 0x00000000},
slouken@1662
   210
    {&GUID_Key, 130, 0x8000820C, 0x00000000},
slouken@1662
   211
    {&GUID_Key, 131, 0x8000830C, 0x00000000},
slouken@1662
   212
    {&GUID_Key, 132, 0x8000840C, 0x00000000},
slouken@1662
   213
    {&GUID_Key, 133, 0x8000850C, 0x00000000},
slouken@1662
   214
    {&GUID_Key, 134, 0x8000860C, 0x00000000},
slouken@1662
   215
    {&GUID_Key, 135, 0x8000870C, 0x00000000},
slouken@1662
   216
    {&GUID_Key, 136, 0x8000880C, 0x00000000},
slouken@1662
   217
    {&GUID_Key, 137, 0x8000890C, 0x00000000},
slouken@1662
   218
    {&GUID_Key, 138, 0x80008A0C, 0x00000000},
slouken@1662
   219
    {&GUID_Key, 139, 0x80008B0C, 0x00000000},
slouken@1662
   220
    {&GUID_Key, 140, 0x80008C0C, 0x00000000},
slouken@1662
   221
    {&GUID_Key, 141, 0x80008D0C, 0x00000000},
slouken@1662
   222
    {&GUID_Key, 142, 0x80008E0C, 0x00000000},
slouken@1662
   223
    {&GUID_Key, 143, 0x80008F0C, 0x00000000},
slouken@1662
   224
    {&GUID_Key, 144, 0x8000900C, 0x00000000},
slouken@1662
   225
    {&GUID_Key, 145, 0x8000910C, 0x00000000},
slouken@1662
   226
    {&GUID_Key, 146, 0x8000920C, 0x00000000},
slouken@1662
   227
    {&GUID_Key, 147, 0x8000930C, 0x00000000},
slouken@1662
   228
    {&GUID_Key, 148, 0x8000940C, 0x00000000},
slouken@1662
   229
    {&GUID_Key, 149, 0x8000950C, 0x00000000},
slouken@1662
   230
    {&GUID_Key, 150, 0x8000960C, 0x00000000},
slouken@1662
   231
    {&GUID_Key, 151, 0x8000970C, 0x00000000},
slouken@1662
   232
    {&GUID_Key, 152, 0x8000980C, 0x00000000},
slouken@1662
   233
    {&GUID_Key, 153, 0x8000990C, 0x00000000},
slouken@1662
   234
    {&GUID_Key, 154, 0x80009A0C, 0x00000000},
slouken@1662
   235
    {&GUID_Key, 155, 0x80009B0C, 0x00000000},
slouken@1662
   236
    {&GUID_Key, 156, 0x80009C0C, 0x00000000},
slouken@1662
   237
    {&GUID_Key, 157, 0x80009D0C, 0x00000000},
slouken@1662
   238
    {&GUID_Key, 158, 0x80009E0C, 0x00000000},
slouken@1662
   239
    {&GUID_Key, 159, 0x80009F0C, 0x00000000},
slouken@1662
   240
    {&GUID_Key, 160, 0x8000A00C, 0x00000000},
slouken@1662
   241
    {&GUID_Key, 161, 0x8000A10C, 0x00000000},
slouken@1662
   242
    {&GUID_Key, 162, 0x8000A20C, 0x00000000},
slouken@1662
   243
    {&GUID_Key, 163, 0x8000A30C, 0x00000000},
slouken@1662
   244
    {&GUID_Key, 164, 0x8000A40C, 0x00000000},
slouken@1662
   245
    {&GUID_Key, 165, 0x8000A50C, 0x00000000},
slouken@1662
   246
    {&GUID_Key, 166, 0x8000A60C, 0x00000000},
slouken@1662
   247
    {&GUID_Key, 167, 0x8000A70C, 0x00000000},
slouken@1662
   248
    {&GUID_Key, 168, 0x8000A80C, 0x00000000},
slouken@1662
   249
    {&GUID_Key, 169, 0x8000A90C, 0x00000000},
slouken@1662
   250
    {&GUID_Key, 170, 0x8000AA0C, 0x00000000},
slouken@1662
   251
    {&GUID_Key, 171, 0x8000AB0C, 0x00000000},
slouken@1662
   252
    {&GUID_Key, 172, 0x8000AC0C, 0x00000000},
slouken@1662
   253
    {&GUID_Key, 173, 0x8000AD0C, 0x00000000},
slouken@1662
   254
    {&GUID_Key, 174, 0x8000AE0C, 0x00000000},
slouken@1662
   255
    {&GUID_Key, 175, 0x8000AF0C, 0x00000000},
slouken@1662
   256
    {&GUID_Key, 176, 0x8000B00C, 0x00000000},
slouken@1662
   257
    {&GUID_Key, 177, 0x8000B10C, 0x00000000},
slouken@1662
   258
    {&GUID_Key, 178, 0x8000B20C, 0x00000000},
slouken@1662
   259
    {&GUID_Key, 179, 0x8000B30C, 0x00000000},
slouken@1662
   260
    {&GUID_Key, 180, 0x8000B40C, 0x00000000},
slouken@1662
   261
    {&GUID_Key, 181, 0x8000B50C, 0x00000000},
slouken@1662
   262
    {&GUID_Key, 182, 0x8000B60C, 0x00000000},
slouken@1662
   263
    {&GUID_Key, 183, 0x8000B70C, 0x00000000},
slouken@1662
   264
    {&GUID_Key, 184, 0x8000B80C, 0x00000000},
slouken@1662
   265
    {&GUID_Key, 185, 0x8000B90C, 0x00000000},
slouken@1662
   266
    {&GUID_Key, 186, 0x8000BA0C, 0x00000000},
slouken@1662
   267
    {&GUID_Key, 187, 0x8000BB0C, 0x00000000},
slouken@1662
   268
    {&GUID_Key, 188, 0x8000BC0C, 0x00000000},
slouken@1662
   269
    {&GUID_Key, 189, 0x8000BD0C, 0x00000000},
slouken@1662
   270
    {&GUID_Key, 190, 0x8000BE0C, 0x00000000},
slouken@1662
   271
    {&GUID_Key, 191, 0x8000BF0C, 0x00000000},
slouken@1662
   272
    {&GUID_Key, 192, 0x8000C00C, 0x00000000},
slouken@1662
   273
    {&GUID_Key, 193, 0x8000C10C, 0x00000000},
slouken@1662
   274
    {&GUID_Key, 194, 0x8000C20C, 0x00000000},
slouken@1662
   275
    {&GUID_Key, 195, 0x8000C30C, 0x00000000},
slouken@1662
   276
    {&GUID_Key, 196, 0x8000C40C, 0x00000000},
slouken@1662
   277
    {&GUID_Key, 197, 0x8000C50C, 0x00000000},
slouken@1662
   278
    {&GUID_Key, 198, 0x8000C60C, 0x00000000},
slouken@1662
   279
    {&GUID_Key, 199, 0x8000C70C, 0x00000000},
slouken@1662
   280
    {&GUID_Key, 200, 0x8000C80C, 0x00000000},
slouken@1662
   281
    {&GUID_Key, 201, 0x8000C90C, 0x00000000},
slouken@1662
   282
    {&GUID_Key, 202, 0x8000CA0C, 0x00000000},
slouken@1662
   283
    {&GUID_Key, 203, 0x8000CB0C, 0x00000000},
slouken@1662
   284
    {&GUID_Key, 204, 0x8000CC0C, 0x00000000},
slouken@1662
   285
    {&GUID_Key, 205, 0x8000CD0C, 0x00000000},
slouken@1662
   286
    {&GUID_Key, 206, 0x8000CE0C, 0x00000000},
slouken@1662
   287
    {&GUID_Key, 207, 0x8000CF0C, 0x00000000},
slouken@1662
   288
    {&GUID_Key, 208, 0x8000D00C, 0x00000000},
slouken@1662
   289
    {&GUID_Key, 209, 0x8000D10C, 0x00000000},
slouken@1662
   290
    {&GUID_Key, 210, 0x8000D20C, 0x00000000},
slouken@1662
   291
    {&GUID_Key, 211, 0x8000D30C, 0x00000000},
slouken@1662
   292
    {&GUID_Key, 212, 0x8000D40C, 0x00000000},
slouken@1662
   293
    {&GUID_Key, 213, 0x8000D50C, 0x00000000},
slouken@1662
   294
    {&GUID_Key, 214, 0x8000D60C, 0x00000000},
slouken@1662
   295
    {&GUID_Key, 215, 0x8000D70C, 0x00000000},
slouken@1662
   296
    {&GUID_Key, 216, 0x8000D80C, 0x00000000},
slouken@1662
   297
    {&GUID_Key, 217, 0x8000D90C, 0x00000000},
slouken@1662
   298
    {&GUID_Key, 218, 0x8000DA0C, 0x00000000},
slouken@1662
   299
    {&GUID_Key, 219, 0x8000DB0C, 0x00000000},
slouken@1662
   300
    {&GUID_Key, 220, 0x8000DC0C, 0x00000000},
slouken@1662
   301
    {&GUID_Key, 221, 0x8000DD0C, 0x00000000},
slouken@1662
   302
    {&GUID_Key, 222, 0x8000DE0C, 0x00000000},
slouken@1662
   303
    {&GUID_Key, 223, 0x8000DF0C, 0x00000000},
slouken@1662
   304
    {&GUID_Key, 224, 0x8000E00C, 0x00000000},
slouken@1662
   305
    {&GUID_Key, 225, 0x8000E10C, 0x00000000},
slouken@1662
   306
    {&GUID_Key, 226, 0x8000E20C, 0x00000000},
slouken@1662
   307
    {&GUID_Key, 227, 0x8000E30C, 0x00000000},
slouken@1662
   308
    {&GUID_Key, 228, 0x8000E40C, 0x00000000},
slouken@1662
   309
    {&GUID_Key, 229, 0x8000E50C, 0x00000000},
slouken@1662
   310
    {&GUID_Key, 230, 0x8000E60C, 0x00000000},
slouken@1662
   311
    {&GUID_Key, 231, 0x8000E70C, 0x00000000},
slouken@1662
   312
    {&GUID_Key, 232, 0x8000E80C, 0x00000000},
slouken@1662
   313
    {&GUID_Key, 233, 0x8000E90C, 0x00000000},
slouken@1662
   314
    {&GUID_Key, 234, 0x8000EA0C, 0x00000000},
slouken@1662
   315
    {&GUID_Key, 235, 0x8000EB0C, 0x00000000},
slouken@1662
   316
    {&GUID_Key, 236, 0x8000EC0C, 0x00000000},
slouken@1662
   317
    {&GUID_Key, 237, 0x8000ED0C, 0x00000000},
slouken@1662
   318
    {&GUID_Key, 238, 0x8000EE0C, 0x00000000},
slouken@1662
   319
    {&GUID_Key, 239, 0x8000EF0C, 0x00000000},
slouken@1662
   320
    {&GUID_Key, 240, 0x8000F00C, 0x00000000},
slouken@1662
   321
    {&GUID_Key, 241, 0x8000F10C, 0x00000000},
slouken@1662
   322
    {&GUID_Key, 242, 0x8000F20C, 0x00000000},
slouken@1662
   323
    {&GUID_Key, 243, 0x8000F30C, 0x00000000},
slouken@1662
   324
    {&GUID_Key, 244, 0x8000F40C, 0x00000000},
slouken@1662
   325
    {&GUID_Key, 245, 0x8000F50C, 0x00000000},
slouken@1662
   326
    {&GUID_Key, 246, 0x8000F60C, 0x00000000},
slouken@1662
   327
    {&GUID_Key, 247, 0x8000F70C, 0x00000000},
slouken@1662
   328
    {&GUID_Key, 248, 0x8000F80C, 0x00000000},
slouken@1662
   329
    {&GUID_Key, 249, 0x8000F90C, 0x00000000},
slouken@1662
   330
    {&GUID_Key, 250, 0x8000FA0C, 0x00000000},
slouken@1662
   331
    {&GUID_Key, 251, 0x8000FB0C, 0x00000000},
slouken@1662
   332
    {&GUID_Key, 252, 0x8000FC0C, 0x00000000},
slouken@1662
   333
    {&GUID_Key, 253, 0x8000FD0C, 0x00000000},
slouken@1662
   334
    {&GUID_Key, 254, 0x8000FE0C, 0x00000000},
slouken@1662
   335
    {&GUID_Key, 255, 0x8000FF0C, 0x00000000},
slouken@0
   336
};
slouken@0
   337
slouken@0
   338
const DIDATAFORMAT c_dfDIKeyboard = { 24, 16, 0x00000002, 256, 256, KBD_fmt };
slouken@0
   339
slouken@0
   340
slouken@0
   341
/* Mouse */
slouken@0
   342
slouken@0
   343
static DIOBJECTDATAFORMAT PTR_fmt[] = {
slouken@1662
   344
    {&GUID_XAxis, 0, 0x00FFFF03, 0x00000000},
slouken@1662
   345
    {&GUID_YAxis, 4, 0x00FFFF03, 0x00000000},
slouken@1662
   346
    {&GUID_ZAxis, 8, 0x80FFFF03, 0x00000000},
slouken@1662
   347
    {NULL, 12, 0x00FFFF0C, 0x00000000},
slouken@1662
   348
    {NULL, 13, 0x00FFFF0C, 0x00000000},
slouken@1662
   349
    {NULL, 14, 0x80FFFF0C, 0x00000000},
slouken@1662
   350
    {NULL, 15, 0x80FFFF0C, 0x00000000},
slouken@0
   351
};
slouken@0
   352
slouken@0
   353
const DIDATAFORMAT c_dfDIMouse = { 24, 16, 0x00000002, 16, 7, PTR_fmt };
slouken@0
   354
slouken@0
   355
slouken@0
   356
/* Joystick */
slouken@0
   357
slouken@0
   358
static DIOBJECTDATAFORMAT JOY_fmt[] = {
slouken@1662
   359
    {&GUID_XAxis, 0, 0x80FFFF03, 0x00000100},
slouken@1662
   360
    {&GUID_YAxis, 4, 0x80FFFF03, 0x00000100},
slouken@1662
   361
    {&GUID_ZAxis, 8, 0x80FFFF03, 0x00000100},
slouken@1662
   362
    {&GUID_RxAxis, 12, 0x80FFFF03, 0x00000100},
slouken@1662
   363
    {&GUID_RyAxis, 16, 0x80FFFF03, 0x00000100},
slouken@1662
   364
    {&GUID_RzAxis, 20, 0x80FFFF03, 0x00000100},
slouken@1662
   365
    {&GUID_Slider, 24, 0x80FFFF03, 0x00000100},
slouken@1662
   366
    {&GUID_Slider, 28, 0x80FFFF03, 0x00000100},
slouken@1662
   367
    {&GUID_POV, 32, 0x80FFFF10, 0x00000000},
slouken@1662
   368
    {&GUID_POV, 36, 0x80FFFF10, 0x00000000},
slouken@1662
   369
    {&GUID_POV, 40, 0x80FFFF10, 0x00000000},
slouken@1662
   370
    {&GUID_POV, 44, 0x80FFFF10, 0x00000000},
slouken@1662
   371
    {NULL, 48, 0x80FFFF0C, 0x00000000},
slouken@1662
   372
    {NULL, 49, 0x80FFFF0C, 0x00000000},
slouken@1662
   373
    {NULL, 50, 0x80FFFF0C, 0x00000000},
slouken@1662
   374
    {NULL, 51, 0x80FFFF0C, 0x00000000},
slouken@1662
   375
    {NULL, 52, 0x80FFFF0C, 0x00000000},
slouken@1662
   376
    {NULL, 53, 0x80FFFF0C, 0x00000000},
slouken@1662
   377
    {NULL, 54, 0x80FFFF0C, 0x00000000},
slouken@1662
   378
    {NULL, 55, 0x80FFFF0C, 0x00000000},
slouken@1662
   379
    {NULL, 56, 0x80FFFF0C, 0x00000000},
slouken@1662
   380
    {NULL, 57, 0x80FFFF0C, 0x00000000},
slouken@1662
   381
    {NULL, 58, 0x80FFFF0C, 0x00000000},
slouken@1662
   382
    {NULL, 59, 0x80FFFF0C, 0x00000000},
slouken@1662
   383
    {NULL, 60, 0x80FFFF0C, 0x00000000},
slouken@1662
   384
    {NULL, 61, 0x80FFFF0C, 0x00000000},
slouken@1662
   385
    {NULL, 62, 0x80FFFF0C, 0x00000000},
slouken@1662
   386
    {NULL, 63, 0x80FFFF0C, 0x00000000},
slouken@1662
   387
    {NULL, 64, 0x80FFFF0C, 0x00000000},
slouken@1662
   388
    {NULL, 65, 0x80FFFF0C, 0x00000000},
slouken@1662
   389
    {NULL, 66, 0x80FFFF0C, 0x00000000},
slouken@1662
   390
    {NULL, 67, 0x80FFFF0C, 0x00000000},
slouken@1662
   391
    {NULL, 68, 0x80FFFF0C, 0x00000000},
slouken@1662
   392
    {NULL, 69, 0x80FFFF0C, 0x00000000},
slouken@1662
   393
    {NULL, 70, 0x80FFFF0C, 0x00000000},
slouken@1662
   394
    {NULL, 71, 0x80FFFF0C, 0x00000000},
slouken@1662
   395
    {NULL, 72, 0x80FFFF0C, 0x00000000},
slouken@1662
   396
    {NULL, 73, 0x80FFFF0C, 0x00000000},
slouken@1662
   397
    {NULL, 74, 0x80FFFF0C, 0x00000000},
slouken@1662
   398
    {NULL, 75, 0x80FFFF0C, 0x00000000},
slouken@1662
   399
    {NULL, 76, 0x80FFFF0C, 0x00000000},
slouken@1662
   400
    {NULL, 77, 0x80FFFF0C, 0x00000000},
slouken@1662
   401
    {NULL, 78, 0x80FFFF0C, 0x00000000},
slouken@1662
   402
    {NULL, 79, 0x80FFFF0C, 0x00000000},
slouken@0
   403
};
slouken@0
   404
slouken@0
   405
const DIDATAFORMAT c_dfDIJoystick = { 24, 16, 0x00000001, 80, 44, JOY_fmt };
slouken@0
   406
slouken@0
   407
slouken@0
   408
/* Initialization/Query functions */
slouken@1662
   409
static int DX5_VideoInit (_THIS, SDL_PixelFormat * vformat);
slouken@1662
   410
static SDL_Rect **DX5_ListModes (_THIS, SDL_PixelFormat * format,
slouken@1662
   411
                                 Uint32 flags);
slouken@1662
   412
static SDL_Surface *DX5_SetVideoMode (_THIS, SDL_Surface * current, int width,
slouken@1662
   413
                                      int height, int bpp, Uint32 flags);
slouken@1662
   414
static int DX5_SetColors (_THIS, int firstcolor, int ncolors,
slouken@1662
   415
                          SDL_Color * colors);
slouken@1662
   416
static int DX5_SetGammaRamp (_THIS, Uint16 * ramp);
slouken@1662
   417
static int DX5_GetGammaRamp (_THIS, Uint16 * ramp);
slouken@1662
   418
static void DX5_VideoQuit (_THIS);
slouken@0
   419
slouken@0
   420
/* Hardware surface functions */
slouken@1662
   421
static int DX5_AllocHWSurface (_THIS, SDL_Surface * surface);
slouken@1662
   422
static int DX5_CheckHWBlit (_THIS, SDL_Surface * src, SDL_Surface * dst);
slouken@1662
   423
static int DX5_FillHWRect (_THIS, SDL_Surface * dst, SDL_Rect * dstrect,
slouken@1662
   424
                           Uint32 color);
slouken@1662
   425
static int DX5_SetHWColorKey (_THIS, SDL_Surface * surface, Uint32 key);
slouken@1662
   426
static int DX5_SetHWAlpha (_THIS, SDL_Surface * surface, Uint8 alpha);
slouken@1662
   427
static int DX5_LockHWSurface (_THIS, SDL_Surface * surface);
slouken@1662
   428
static void DX5_UnlockHWSurface (_THIS, SDL_Surface * surface);
slouken@1662
   429
static int DX5_FlipHWSurface (_THIS, SDL_Surface * surface);
slouken@1662
   430
static void DX5_FreeHWSurface (_THIS, SDL_Surface * surface);
slouken@0
   431
slouken@1662
   432
static int DX5_AllocDDSurface (_THIS, SDL_Surface * surface,
slouken@1662
   433
                               LPDIRECTDRAWSURFACE3 requested, Uint32 flag);
slouken@0
   434
slouken@0
   435
/* Windows message handling functions */
slouken@1662
   436
static void DX5_RealizePalette (_THIS);
slouken@1662
   437
static void DX5_PaletteChanged (_THIS, HWND window);
slouken@1662
   438
static void DX5_WinPAINT (_THIS, HDC hdc);
slouken@0
   439
slouken@338
   440
/* WinDIB driver functions for manipulating gamma ramps */
slouken@1662
   441
extern int DIB_SetGammaRamp (_THIS, Uint16 * ramp);
slouken@1662
   442
extern int DIB_GetGammaRamp (_THIS, Uint16 * ramp);
slouken@1662
   443
extern void DIB_QuitGamma (_THIS);
slouken@338
   444
slouken@1661
   445
/* Functions for loading the DirectX functions dynamically */
slouken@1661
   446
static int DX5_loaded = 0;
slouken@1661
   447
static HINSTANCE DDrawDLL = NULL;
slouken@1661
   448
static HINSTANCE DInputDLL = NULL;
slouken@1661
   449
slouken@1662
   450
void
slouken@1662
   451
DX5_Unload (void)
slouken@1661
   452
{
slouken@1662
   453
    if (--DX5_loaded == 0) {
slouken@1662
   454
        if (DDrawDLL != NULL) {
slouken@1662
   455
            FreeLibrary (DDrawDLL);
slouken@1662
   456
            DDrawCreate = NULL;
slouken@1662
   457
            DDrawDLL = NULL;
slouken@1662
   458
        }
slouken@1662
   459
        if (DInputDLL != NULL) {
slouken@1662
   460
            FreeLibrary (DInputDLL);
slouken@1662
   461
            DInputCreate = NULL;
slouken@1662
   462
            DInputDLL = NULL;
slouken@1662
   463
        }
slouken@1662
   464
    }
slouken@1661
   465
}
slouken@1662
   466
int
slouken@1662
   467
DX5_Load (void)
slouken@1661
   468
{
slouken@1662
   469
    int status = 0;
slouken@1661
   470
slouken@1662
   471
    if (++DX5_loaded == 1) {
slouken@1662
   472
        DDrawDLL = LoadLibrary (TEXT ("DDRAW.DLL"));
slouken@1662
   473
        if (DDrawDLL != NULL) {
slouken@1662
   474
            DDrawCreate = (void *) GetProcAddress (DDrawDLL,
slouken@1662
   475
                                                   TEXT ("DirectDrawCreate"));
slouken@1662
   476
        }
slouken@1662
   477
        DInputDLL = LoadLibrary (TEXT ("DINPUT.DLL"));
slouken@1662
   478
        if (DInputDLL != NULL) {
slouken@1662
   479
            DInputCreate = (void *) GetProcAddress (DInputDLL,
slouken@1662
   480
                                                    TEXT
slouken@1662
   481
                                                    ("DirectInputCreateA"));
slouken@1662
   482
        }
slouken@1662
   483
        if (DDrawDLL && DDrawCreate && DInputDLL && DInputCreate) {
slouken@1662
   484
            status = 0;
slouken@1662
   485
        } else {
slouken@1662
   486
            DX5_Unload ();
slouken@1662
   487
            status = -1;
slouken@1662
   488
        }
slouken@1662
   489
    }
slouken@1662
   490
    return status;
slouken@1661
   491
}
slouken@1661
   492
slouken@0
   493
/* DX5 driver bootstrap functions */
slouken@0
   494
slouken@1662
   495
static int
slouken@1662
   496
DX5_Available (void)
slouken@0
   497
{
slouken@1662
   498
    int ddraw_ok = 0;
slouken@1662
   499
    HRESULT (WINAPI * DDrawCreate) (GUID *, LPDIRECTDRAW *, IUnknown *);
slouken@1662
   500
    LPDIRECTDRAW DDraw;
slouken@0
   501
slouken@1662
   502
    /* Version check DINPUT.DLL and DDRAW.DLL (Is DirectX okay?) */
slouken@1662
   503
    if (DX5_Load () < 0) {
slouken@1662
   504
        return -1;
slouken@1662
   505
    }
slouken@0
   506
slouken@1662
   507
    /* Try to create a valid DirectDraw object */
slouken@1662
   508
    DDrawCreate =
slouken@1662
   509
        (void *) GetProcAddress (DDrawDLL, TEXT ("DirectDrawCreate"));
slouken@1662
   510
    if ((DDrawCreate != NULL) && !FAILED (DDrawCreate (NULL, &DDraw, NULL))) {
slouken@1662
   511
        if (!FAILED (IDirectDraw_SetCooperativeLevel (DDraw,
slouken@1662
   512
                                                      NULL, DDSCL_NORMAL))) {
slouken@1662
   513
            DDSURFACEDESC desc;
slouken@1662
   514
            LPDIRECTDRAWSURFACE DDrawSurf;
slouken@1662
   515
            LPDIRECTDRAWSURFACE3 DDrawSurf3;
slouken@0
   516
slouken@1662
   517
            /* Try to create a DirectDrawSurface3 object */
slouken@1662
   518
            SDL_memset (&desc, 0, sizeof (desc));
slouken@1662
   519
            desc.dwSize = sizeof (desc);
slouken@1662
   520
            desc.dwFlags = DDSD_CAPS;
slouken@1662
   521
            desc.ddsCaps.dwCaps =
slouken@1662
   522
                DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY;
slouken@1662
   523
            if (!FAILED
slouken@1662
   524
                (IDirectDraw_CreateSurface
slouken@1662
   525
                 (DDraw, &desc, &DDrawSurf, NULL))) {
slouken@1662
   526
                if (!FAILED
slouken@1662
   527
                    (IDirectDrawSurface_QueryInterface
slouken@1662
   528
                     (DDrawSurf, &IID_IDirectDrawSurface3,
slouken@1662
   529
                      (LPVOID *) & DDrawSurf3))) {
slouken@1662
   530
                    /* Yay! */
slouken@1662
   531
                    ddraw_ok = 1;
slouken@0
   532
slouken@1662
   533
                    /* Clean up.. */
slouken@1662
   534
                    IDirectDrawSurface3_Release (DDrawSurf3);
slouken@1662
   535
                }
slouken@1662
   536
                IDirectDrawSurface_Release (DDrawSurf);
slouken@1662
   537
            }
slouken@1662
   538
        }
slouken@1662
   539
        IDirectDraw_Release (DDraw);
slouken@1662
   540
    }
slouken@0
   541
slouken@1662
   542
    DX5_Unload ();
slouken@1661
   543
slouken@1662
   544
    return ddraw_ok;
slouken@0
   545
}
slouken@0
   546
slouken@1662
   547
static void
slouken@1662
   548
DX5_DeleteDevice (SDL_VideoDevice * this)
slouken@0
   549
{
slouken@1662
   550
    /* Free DirectDraw object */
slouken@1662
   551
    if (ddraw2 != NULL) {
slouken@1662
   552
        IDirectDraw2_Release (ddraw2);
slouken@1662
   553
    }
slouken@1662
   554
    DX5_Unload ();
slouken@1661
   555
slouken@1662
   556
    if (this) {
slouken@1662
   557
        if (this->hidden) {
slouken@1662
   558
            SDL_free (this->hidden);
slouken@1662
   559
        }
slouken@1662
   560
        if (this->gl_data) {
slouken@1662
   561
            SDL_free (this->gl_data);
slouken@1662
   562
        }
slouken@1662
   563
        SDL_free (this);
slouken@1662
   564
    }
slouken@0
   565
}
slouken@0
   566
slouken@1662
   567
static SDL_VideoDevice *
slouken@1662
   568
DX5_CreateDevice (int devindex)
slouken@0
   569
{
slouken@1662
   570
    SDL_VideoDevice *device;
slouken@0
   571
slouken@1662
   572
    /* Load DirectX */
slouken@1662
   573
    if (DX5_Load () < 0) {
slouken@1662
   574
        return (NULL);
slouken@1662
   575
    }
slouken@0
   576
slouken@1662
   577
    /* Initialize all variables that we clean on shutdown */
slouken@1662
   578
    device = (SDL_VideoDevice *) SDL_malloc (sizeof (SDL_VideoDevice));
slouken@1662
   579
    if (device) {
slouken@1662
   580
        SDL_memset (device, 0, (sizeof *device));
slouken@1662
   581
        device->hidden = (struct SDL_PrivateVideoData *)
slouken@1662
   582
            SDL_malloc ((sizeof *device->hidden));
slouken@1662
   583
        device->gl_data = (struct SDL_PrivateGLData *)
slouken@1662
   584
            SDL_malloc ((sizeof *device->gl_data));
slouken@1662
   585
    }
slouken@1662
   586
    if ((device == NULL) || (device->hidden == NULL) ||
slouken@1662
   587
        (device->gl_data == NULL)) {
slouken@1662
   588
        SDL_OutOfMemory ();
slouken@1662
   589
        DX5_DeleteDevice (device);
slouken@1662
   590
        return (NULL);
slouken@1662
   591
    }
slouken@1662
   592
    SDL_memset (device->hidden, 0, (sizeof *device->hidden));
slouken@1662
   593
    SDL_memset (device->gl_data, 0, (sizeof *device->gl_data));
slouken@0
   594
slouken@1662
   595
    /* Set the function pointers */
slouken@1662
   596
    device->VideoInit = DX5_VideoInit;
slouken@1662
   597
    device->ListModes = DX5_ListModes;
slouken@1662
   598
    device->SetVideoMode = DX5_SetVideoMode;
slouken@1662
   599
    device->UpdateMouse = WIN_UpdateMouse;
slouken@1662
   600
    device->CreateYUVOverlay = DX5_CreateYUVOverlay;
slouken@1662
   601
    device->SetColors = DX5_SetColors;
slouken@1662
   602
    device->UpdateRects = NULL;
slouken@1662
   603
    device->VideoQuit = DX5_VideoQuit;
slouken@1662
   604
    device->AllocHWSurface = DX5_AllocHWSurface;
slouken@1662
   605
    device->CheckHWBlit = DX5_CheckHWBlit;
slouken@1662
   606
    device->FillHWRect = DX5_FillHWRect;
slouken@1662
   607
    device->SetHWColorKey = DX5_SetHWColorKey;
slouken@1662
   608
    device->SetHWAlpha = DX5_SetHWAlpha;
slouken@1662
   609
    device->LockHWSurface = DX5_LockHWSurface;
slouken@1662
   610
    device->UnlockHWSurface = DX5_UnlockHWSurface;
slouken@1662
   611
    device->FlipHWSurface = DX5_FlipHWSurface;
slouken@1662
   612
    device->FreeHWSurface = DX5_FreeHWSurface;
slouken@1662
   613
    device->SetGammaRamp = DX5_SetGammaRamp;
slouken@1662
   614
    device->GetGammaRamp = DX5_GetGammaRamp;
slouken@1361
   615
#if SDL_VIDEO_OPENGL
slouken@1662
   616
    device->GL_LoadLibrary = WIN_GL_LoadLibrary;
slouken@1662
   617
    device->GL_GetProcAddress = WIN_GL_GetProcAddress;
slouken@1662
   618
    device->GL_GetAttribute = WIN_GL_GetAttribute;
slouken@1662
   619
    device->GL_MakeCurrent = WIN_GL_MakeCurrent;
slouken@1662
   620
    device->GL_SwapBuffers = WIN_GL_SwapBuffers;
slouken@0
   621
#endif
slouken@1662
   622
    device->SetCaption = WIN_SetWMCaption;
slouken@1662
   623
    device->SetIcon = WIN_SetWMIcon;
slouken@1662
   624
    device->IconifyWindow = WIN_IconifyWindow;
slouken@1662
   625
    device->GrabInput = WIN_GrabInput;
slouken@1662
   626
    device->GetWMInfo = WIN_GetWMInfo;
slouken@1662
   627
    device->FreeWMCursor = WIN_FreeWMCursor;
slouken@1662
   628
    device->CreateWMCursor = WIN_CreateWMCursor;
slouken@1662
   629
    device->ShowWMCursor = WIN_ShowWMCursor;
slouken@1662
   630
    device->WarpWMCursor = WIN_WarpWMCursor;
slouken@1662
   631
    device->CheckMouseMode = WIN_CheckMouseMode;
slouken@1662
   632
    device->InitOSKeymap = DX5_InitOSKeymap;
slouken@1662
   633
    device->PumpEvents = DX5_PumpEvents;
slouken@0
   634
slouken@1662
   635
    /* Set up the windows message handling functions */
slouken@1662
   636
    WIN_RealizePalette = DX5_RealizePalette;
slouken@1662
   637
    WIN_PaletteChanged = DX5_PaletteChanged;
slouken@1662
   638
    WIN_WinPAINT = DX5_WinPAINT;
slouken@1662
   639
    HandleMessage = DX5_HandleMessage;
slouken@0
   640
slouken@1662
   641
    device->free = DX5_DeleteDevice;
slouken@0
   642
slouken@1662
   643
    /* We're finally ready */
slouken@1662
   644
    return device;
slouken@0
   645
}
slouken@0
   646
slouken@0
   647
VideoBootStrap DIRECTX_bootstrap = {
slouken@1662
   648
    "directx", "Win95/98/2000 DirectX",
slouken@1662
   649
    DX5_Available, DX5_CreateDevice
slouken@0
   650
};
slouken@0
   651
slouken@1662
   652
static int
slouken@1662
   653
cmpmodes (const void *va, const void *vb)
slouken@1659
   654
{
slouken@1662
   655
    SDL_Rect *a = *(SDL_Rect **) va;
slouken@1662
   656
    SDL_Rect *b = *(SDL_Rect **) vb;
slouken@1662
   657
    if (a->w == b->w)
slouken@1659
   658
        return b->h - a->h;
slouken@1659
   659
    else
slouken@1659
   660
        return b->w - a->w;
slouken@1659
   661
}
slouken@1659
   662
slouken@1662
   663
static HRESULT WINAPI
slouken@1662
   664
EnumModes2 (DDSURFACEDESC * desc, VOID * udata)
slouken@0
   665
{
slouken@1662
   666
    SDL_VideoDevice *this = (SDL_VideoDevice *) udata;
slouken@1662
   667
    struct DX5EnumRect *enumrect;
slouken@0
   668
#if defined(NONAMELESSUNION)
slouken@1662
   669
    int bpp = desc->ddpfPixelFormat.u1.dwRGBBitCount;
slouken@1662
   670
    int refreshRate = desc->u2.dwRefreshRate;
slouken@0
   671
#else
slouken@1662
   672
    int bpp = desc->ddpfPixelFormat.dwRGBBitCount;
slouken@1662
   673
    int refreshRate = desc->dwRefreshRate;
slouken@0
   674
#endif
slouken@1662
   675
    int maxRefreshRate;
slouken@1295
   676
slouken@1662
   677
    if (desc->dwWidth <= SDL_desktop_mode.dmPelsWidth &&
slouken@1662
   678
        desc->dwHeight <= SDL_desktop_mode.dmPelsHeight) {
slouken@1662
   679
        maxRefreshRate = SDL_desktop_mode.dmDisplayFrequency;
slouken@1662
   680
    } else {
slouken@1662
   681
        maxRefreshRate = 85;    /* safe value? */
slouken@1662
   682
    }
slouken@0
   683
slouken@1662
   684
    switch (bpp) {
slouken@1662
   685
    case 8:
slouken@1662
   686
    case 16:
slouken@1662
   687
    case 24:
slouken@1662
   688
    case 32:
slouken@1662
   689
        bpp /= 8;
slouken@1662
   690
        --bpp;
slouken@1662
   691
        if (enumlists[bpp] &&
slouken@1662
   692
            enumlists[bpp]->r.w == (Uint16) desc->dwWidth &&
slouken@1662
   693
            enumlists[bpp]->r.h == (Uint16) desc->dwHeight) {
slouken@1662
   694
            if (refreshRate > enumlists[bpp]->refreshRate &&
slouken@1662
   695
                refreshRate <= maxRefreshRate) {
slouken@1662
   696
                enumlists[bpp]->refreshRate = refreshRate;
slouken@815
   697
#ifdef DDRAW_DEBUG
slouken@1662
   698
                fprintf (stderr,
slouken@1662
   699
                         "New refresh rate for %d bpp: %dx%d at %d Hz\n",
slouken@1662
   700
                         (bpp + 1) * 8, (int) desc->dwWidth,
slouken@1662
   701
                         (int) desc->dwHeight, refreshRate);
slouken@815
   702
#endif
slouken@1662
   703
            }
slouken@1662
   704
            break;
slouken@1662
   705
        }
slouken@1662
   706
        ++SDL_nummodes[bpp];
slouken@1662
   707
        enumrect =
slouken@1662
   708
            (struct DX5EnumRect *) SDL_malloc (sizeof (struct DX5EnumRect));
slouken@1662
   709
        if (!enumrect) {
slouken@1662
   710
            SDL_OutOfMemory ();
slouken@1662
   711
            return (DDENUMRET_CANCEL);
slouken@1662
   712
        }
slouken@1662
   713
        enumrect->refreshRate = refreshRate;
slouken@1662
   714
        enumrect->r.x = 0;
slouken@1662
   715
        enumrect->r.y = 0;
slouken@1662
   716
        enumrect->r.w = (Uint16) desc->dwWidth;
slouken@1662
   717
        enumrect->r.h = (Uint16) desc->dwHeight;
slouken@1662
   718
        enumrect->next = enumlists[bpp];
slouken@1662
   719
        enumlists[bpp] = enumrect;
slouken@815
   720
#ifdef DDRAW_DEBUG
slouken@1662
   721
        fprintf (stderr, "New mode for %d bpp: %dx%d at %d Hz\n",
slouken@1662
   722
                 (bpp + 1) * 8, (int) desc->dwWidth, (int) desc->dwHeight,
slouken@1662
   723
                 refreshRate);
slouken@815
   724
#endif
slouken@1662
   725
        break;
slouken@1662
   726
    }
slouken@0
   727
slouken@1662
   728
    return (DDENUMRET_OK);
slouken@0
   729
}
slouken@0
   730
slouken@1662
   731
void
slouken@1662
   732
SetDDerror (const char *function, int code)
slouken@0
   733
{
slouken@1662
   734
    static char *error;
slouken@1662
   735
    static char errbuf[1024];
slouken@0
   736
slouken@1662
   737
    errbuf[0] = 0;
slouken@1662
   738
    switch (code) {
slouken@1662
   739
    case DDERR_GENERIC:
slouken@1662
   740
        error = "Undefined error!";
slouken@1662
   741
        break;
slouken@1662
   742
    case DDERR_EXCEPTION:
slouken@1662
   743
        error = "Exception encountered";
slouken@1662
   744
        break;
slouken@1662
   745
    case DDERR_INVALIDOBJECT:
slouken@1662
   746
        error = "Invalid object";
slouken@1662
   747
        break;
slouken@1662
   748
    case DDERR_INVALIDPARAMS:
slouken@1662
   749
        error = "Invalid parameters";
slouken@1662
   750
        break;
slouken@1662
   751
    case DDERR_NOTFOUND:
slouken@1662
   752
        error = "Object not found";
slouken@1662
   753
        break;
slouken@1662
   754
    case DDERR_INVALIDRECT:
slouken@1662
   755
        error = "Invalid rectangle";
slouken@1662
   756
        break;
slouken@1662
   757
    case DDERR_INVALIDCAPS:
slouken@1662
   758
        error = "Invalid caps member";
slouken@1662
   759
        break;
slouken@1662
   760
    case DDERR_INVALIDPIXELFORMAT:
slouken@1662
   761
        error = "Invalid pixel format";
slouken@1662
   762
        break;
slouken@1662
   763
    case DDERR_OUTOFMEMORY:
slouken@1662
   764
        error = "Out of memory";
slouken@1662
   765
        break;
slouken@1662
   766
    case DDERR_OUTOFVIDEOMEMORY:
slouken@1662
   767
        error = "Out of video memory";
slouken@1662
   768
        break;
slouken@1662
   769
    case DDERR_SURFACEBUSY:
slouken@1662
   770
        error = "Surface busy";
slouken@1662
   771
        break;
slouken@1662
   772
    case DDERR_SURFACELOST:
slouken@1662
   773
        error = "Surface was lost";
slouken@1662
   774
        break;
slouken@1662
   775
    case DDERR_WASSTILLDRAWING:
slouken@1662
   776
        error = "DirectDraw is still drawing";
slouken@1662
   777
        break;
slouken@1662
   778
    case DDERR_INVALIDSURFACETYPE:
slouken@1662
   779
        error = "Invalid surface type";
slouken@1662
   780
        break;
slouken@1662
   781
    case DDERR_NOEXCLUSIVEMODE:
slouken@1662
   782
        error = "Not in exclusive access mode";
slouken@1662
   783
        break;
slouken@1662
   784
    case DDERR_NOPALETTEATTACHED:
slouken@1662
   785
        error = "No palette attached";
slouken@1662
   786
        break;
slouken@1662
   787
    case DDERR_NOPALETTEHW:
slouken@1662
   788
        error = "No palette hardware";
slouken@1662
   789
        break;
slouken@1662
   790
    case DDERR_NOT8BITCOLOR:
slouken@1662
   791
        error = "Not 8-bit color";
slouken@1662
   792
        break;
slouken@1662
   793
    case DDERR_EXCLUSIVEMODEALREADYSET:
slouken@1662
   794
        error = "Exclusive mode was already set";
slouken@1662
   795
        break;
slouken@1662
   796
    case DDERR_HWNDALREADYSET:
slouken@1662
   797
        error = "Window handle already set";
slouken@1662
   798
        break;
slouken@1662
   799
    case DDERR_HWNDSUBCLASSED:
slouken@1662
   800
        error = "Window handle is subclassed";
slouken@1662
   801
        break;
slouken@1662
   802
    case DDERR_NOBLTHW:
slouken@1662
   803
        error = "No blit hardware";
slouken@1662
   804
        break;
slouken@1662
   805
    case DDERR_IMPLICITLYCREATED:
slouken@1662
   806
        error = "Surface was implicitly created";
slouken@1662
   807
        break;
slouken@1662
   808
    case DDERR_INCOMPATIBLEPRIMARY:
slouken@1662
   809
        error = "Incompatible primary surface";
slouken@1662
   810
        break;
slouken@1662
   811
    case DDERR_NOCOOPERATIVELEVELSET:
slouken@1662
   812
        error = "No cooperative level set";
slouken@1662
   813
        break;
slouken@1662
   814
    case DDERR_NODIRECTDRAWHW:
slouken@1662
   815
        error = "No DirectDraw hardware";
slouken@1662
   816
        break;
slouken@1662
   817
    case DDERR_NOEMULATION:
slouken@1662
   818
        error = "No emulation available";
slouken@1662
   819
        break;
slouken@1662
   820
    case DDERR_NOFLIPHW:
slouken@1662
   821
        error = "No flip hardware";
slouken@1662
   822
        break;
slouken@1662
   823
    case DDERR_NOTFLIPPABLE:
slouken@1662
   824
        error = "Surface not flippable";
slouken@1662
   825
        break;
slouken@1662
   826
    case DDERR_PRIMARYSURFACEALREADYEXISTS:
slouken@1662
   827
        error = "Primary surface already exists";
slouken@1662
   828
        break;
slouken@1662
   829
    case DDERR_UNSUPPORTEDMODE:
slouken@1662
   830
        error = "Unsupported mode";
slouken@1662
   831
        break;
slouken@1662
   832
    case DDERR_WRONGMODE:
slouken@1662
   833
        error = "Surface created in different mode";
slouken@1662
   834
        break;
slouken@1662
   835
    case DDERR_UNSUPPORTED:
slouken@1662
   836
        error = "Operation not supported";
slouken@1662
   837
        break;
slouken@1662
   838
    case E_NOINTERFACE:
slouken@1662
   839
        error = "Interface not present";
slouken@1662
   840
        break;
slouken@1662
   841
    default:
slouken@1662
   842
        SDL_snprintf (errbuf, SDL_arraysize (errbuf),
slouken@1662
   843
                      "%s: Unknown DirectDraw error: 0x%x", function, code);
slouken@1662
   844
        break;
slouken@1662
   845
    }
slouken@1662
   846
    if (!errbuf[0]) {
slouken@1662
   847
        SDL_snprintf (errbuf, SDL_arraysize (errbuf), "%s: %s", function,
slouken@1662
   848
                      error);
slouken@1662
   849
    }
slouken@1662
   850
    SDL_SetError ("%s", errbuf);
slouken@1662
   851
    return;
slouken@0
   852
}
slouken@0
   853
slouken@0
   854
slouken@1662
   855
static int
slouken@1662
   856
DX5_UpdateVideoInfo (_THIS)
slouken@0
   857
{
slouken@1662
   858
    /* This needs to be DDCAPS_DX5 for the DirectDraw2 interface */
slouken@0
   859
#if DIRECTDRAW_VERSION <= 0x300
slouken@0
   860
#error Your version of DirectX must be greater than or equal to 5.0
slouken@0
   861
#endif
slouken@334
   862
#ifndef IDirectDrawGammaControl_SetGammaRamp
slouken@1662
   863
    /*if gamma is undefined then we really have directx <= 0x500 */
slouken@1662
   864
    DDCAPS DDCaps;
slouken@0
   865
#else
slouken@1662
   866
    DDCAPS_DX5 DDCaps;
slouken@0
   867
#endif
slouken@1662
   868
    HRESULT result;
slouken@0
   869
slouken@1662
   870
    /* Fill in our hardware acceleration capabilities */
slouken@1662
   871
    SDL_memset (&DDCaps, 0, sizeof (DDCaps));
slouken@1662
   872
    DDCaps.dwSize = sizeof (DDCaps);
slouken@1662
   873
    result = IDirectDraw2_GetCaps (ddraw2, (DDCAPS *) & DDCaps, NULL);
slouken@1662
   874
    if (result != DD_OK) {
slouken@1662
   875
        SetDDerror ("DirectDraw2::GetCaps", result);
slouken@1662
   876
        return (-1);
slouken@1662
   877
    }
slouken@1662
   878
    this->info.hw_available = 1;
slouken@1662
   879
    if ((DDCaps.dwCaps & DDCAPS_BLT) == DDCAPS_BLT) {
slouken@1662
   880
        this->info.blit_hw = 1;
slouken@1662
   881
    }
slouken@1662
   882
    if (((DDCaps.dwCaps & DDCAPS_COLORKEY) == DDCAPS_COLORKEY) &&
slouken@1662
   883
        ((DDCaps.dwCKeyCaps & DDCKEYCAPS_SRCBLT) == DDCKEYCAPS_SRCBLT)) {
slouken@1662
   884
        this->info.blit_hw_CC = 1;
slouken@1662
   885
    }
slouken@1662
   886
    if ((DDCaps.dwCaps & DDCAPS_ALPHA) == DDCAPS_ALPHA) {
slouken@1662
   887
        /* This is only for alpha channel, and DirectX 6
slouken@1662
   888
           doesn't support 2D alpha blits yet, so set it 0
slouken@1662
   889
         */
slouken@1662
   890
        this->info.blit_hw_A = 0;
slouken@1662
   891
    }
slouken@1662
   892
    if ((DDCaps.dwCaps & DDCAPS_CANBLTSYSMEM) == DDCAPS_CANBLTSYSMEM) {
slouken@1662
   893
        this->info.blit_sw = 1;
slouken@1662
   894
        /* This isn't necessarily true, but the HEL will cover us */
slouken@1662
   895
        this->info.blit_sw_CC = this->info.blit_hw_CC;
slouken@1662
   896
        this->info.blit_sw_A = this->info.blit_hw_A;
slouken@1662
   897
    }
slouken@1662
   898
    if ((DDCaps.dwCaps & DDCAPS_BLTCOLORFILL) == DDCAPS_BLTCOLORFILL) {
slouken@1662
   899
        this->info.blit_fill = 1;
slouken@1662
   900
    }
slouken@0
   901
slouken@1662
   902
    /* Find out how much video memory is available */
slouken@1662
   903
    {
slouken@1662
   904
        DDSCAPS ddsCaps;
slouken@1662
   905
        DWORD total_mem;
slouken@1662
   906
        ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY;
slouken@1662
   907
        result = IDirectDraw2_GetAvailableVidMem (ddraw2,
slouken@1662
   908
                                                  &ddsCaps, &total_mem, NULL);
slouken@1662
   909
        if (result != DD_OK) {
slouken@1662
   910
            total_mem = DDCaps.dwVidMemTotal;
slouken@1662
   911
        }
slouken@1662
   912
        this->info.video_mem = total_mem / 1024;
slouken@1662
   913
    }
slouken@1662
   914
    return (0);
slouken@0
   915
}
slouken@0
   916
slouken@1662
   917
int
slouken@1662
   918
DX5_VideoInit (_THIS, SDL_PixelFormat * vformat)
slouken@0
   919
{
slouken@1662
   920
    HRESULT result;
slouken@1662
   921
    LPDIRECTDRAW ddraw;
slouken@1662
   922
    int i, j;
slouken@1662
   923
    HDC hdc;
slouken@0
   924
slouken@1662
   925
    /* Intialize everything */
slouken@1662
   926
    ddraw2 = NULL;
slouken@1662
   927
    SDL_primary = NULL;
slouken@1662
   928
    SDL_clipper = NULL;
slouken@1662
   929
    SDL_palette = NULL;
slouken@1662
   930
    for (i = 0; i < NUM_MODELISTS; ++i) {
slouken@1662
   931
        SDL_nummodes[i] = 0;
slouken@1662
   932
        SDL_modelist[i] = NULL;
slouken@1662
   933
        SDL_modeindex[i] = 0;
slouken@1662
   934
    }
slouken@1662
   935
    colorchange_expected = 0;
slouken@0
   936
slouken@1662
   937
    /* Create the window */
slouken@1662
   938
    if (DX5_CreateWindow (this) < 0) {
slouken@1662
   939
        return (-1);
slouken@1662
   940
    }
slouken@1361
   941
#if !SDL_AUDIO_DISABLED
slouken@1662
   942
    DX5_SoundFocus (SDL_Window);
slouken@169
   943
#endif
slouken@0
   944
slouken@1662
   945
    /* Create the DirectDraw object */
slouken@1662
   946
    result = DDrawCreate (NULL, &ddraw, NULL);
slouken@1662
   947
    if (result != DD_OK) {
slouken@1662
   948
        SetDDerror ("DirectDrawCreate", result);
slouken@1662
   949
        return (-1);
slouken@1662
   950
    }
slouken@1662
   951
    result = IDirectDraw_QueryInterface (ddraw, &IID_IDirectDraw2,
slouken@1662
   952
                                         (LPVOID *) & ddraw2);
slouken@1662
   953
    IDirectDraw_Release (ddraw);
slouken@1662
   954
    if (result != DD_OK) {
slouken@1662
   955
        SetDDerror ("DirectDraw::QueryInterface", result);
slouken@1662
   956
        return (-1);
slouken@1662
   957
    }
slouken@0
   958
slouken@1662
   959
    /* Determine the screen depth */
slouken@1662
   960
    hdc = GetDC (SDL_Window);
slouken@1662
   961
    vformat->BitsPerPixel = GetDeviceCaps (hdc, PLANES) *
slouken@1662
   962
        GetDeviceCaps (hdc, BITSPIXEL);
slouken@1662
   963
    ReleaseDC (SDL_Window, hdc);
slouken@0
   964
slouken@1295
   965
#ifndef NO_CHANGEDISPLAYSETTINGS
slouken@1662
   966
    /* Query for the desktop resolution */
slouken@1662
   967
    EnumDisplaySettings (NULL, ENUM_CURRENT_SETTINGS, &SDL_desktop_mode);
slouken@1662
   968
    this->info.current_w = SDL_desktop_mode.dmPelsWidth;
slouken@1662
   969
    this->info.current_h = SDL_desktop_mode.dmPelsHeight;
slouken@1295
   970
#endif
slouken@1295
   971
slouken@1662
   972
    /* Enumerate the available fullscreen modes */
slouken@1662
   973
    for (i = 0; i < NUM_MODELISTS; ++i)
slouken@1662
   974
        enumlists[i] = NULL;
slouken@0
   975
slouken@1662
   976
    result =
slouken@1662
   977
        IDirectDraw2_EnumDisplayModes (ddraw2, DDEDM_REFRESHRATES, NULL, this,
slouken@1662
   978
                                       EnumModes2);
slouken@1662
   979
    if (result != DD_OK) {
slouken@1662
   980
        SetDDerror ("DirectDraw2::EnumDisplayModes", result);
slouken@1662
   981
        return (-1);
slouken@1662
   982
    }
slouken@1662
   983
    for (i = 0; i < NUM_MODELISTS; ++i) {
slouken@1662
   984
        struct DX5EnumRect *rect;
slouken@1662
   985
        SDL_modelist[i] = (SDL_Rect **)
slouken@1662
   986
            SDL_malloc ((SDL_nummodes[i] + 1) * sizeof (SDL_Rect *));
slouken@1662
   987
        if (SDL_modelist[i] == NULL) {
slouken@1662
   988
            SDL_OutOfMemory ();
slouken@1662
   989
            return (-1);
slouken@1662
   990
        }
slouken@1662
   991
        for (j = 0, rect = enumlists[i]; rect; ++j, rect = rect->next) {
slouken@1662
   992
            SDL_modelist[i][j] = &rect->r;
slouken@1662
   993
        }
slouken@1662
   994
        SDL_modelist[i][j] = NULL;
slouken@1659
   995
slouken@1662
   996
        if (SDL_nummodes[i] > 0) {
slouken@1662
   997
            SDL_qsort (SDL_modelist[i], SDL_nummodes[i],
slouken@1662
   998
                       sizeof *SDL_modelist[i], cmpmodes);
slouken@1662
   999
        }
slouken@1662
  1000
    }
slouken@0
  1001
slouken@1662
  1002
    /* Fill in some window manager capabilities */
slouken@1662
  1003
    this->info.wm_available = 1;
slouken@0
  1004
slouken@1662
  1005
    /* Fill in the video hardware capabilities */
slouken@1662
  1006
    DX5_UpdateVideoInfo (this);
slouken@1662
  1007
slouken@1662
  1008
    return (0);
slouken@0
  1009
}
slouken@0
  1010
slouken@1662
  1011
SDL_Rect **
slouken@1662
  1012
DX5_ListModes (_THIS, SDL_PixelFormat * format, Uint32 flags)
slouken@0
  1013
{
slouken@1662
  1014
    int bpp;
slouken@0
  1015
slouken@1662
  1016
    bpp = format->BitsPerPixel;
slouken@1662
  1017
    if ((flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) {
slouken@1662
  1018
        /* FIXME:  No support for 1 bpp or 4 bpp formats */
slouken@1662
  1019
        switch (bpp) {          /* Does windows support other BPP? */
slouken@1662
  1020
        case 8:
slouken@1662
  1021
        case 16:
slouken@1662
  1022
        case 24:
slouken@1662
  1023
        case 32:
slouken@1662
  1024
            bpp = (bpp / 8) - 1;
slouken@1662
  1025
            if (SDL_nummodes[bpp] > 0)
slouken@1662
  1026
                return (SDL_modelist[bpp]);
slouken@1662
  1027
            /* Fall through */
slouken@1662
  1028
        default:
slouken@1662
  1029
            return ((SDL_Rect **) 0);
slouken@1662
  1030
        }
slouken@1662
  1031
    } else {
slouken@1662
  1032
        if (this->screen->format->BitsPerPixel == bpp) {
slouken@1662
  1033
            return ((SDL_Rect **) - 1);
slouken@1662
  1034
        } else {
slouken@1662
  1035
            return ((SDL_Rect **) 0);
slouken@1662
  1036
        }
slouken@1662
  1037
    }
slouken@0
  1038
}
slouken@0
  1039
slouken@0
  1040
/* Various screen update functions available */
slouken@1662
  1041
static void DX5_WindowUpdate (_THIS, int numrects, SDL_Rect * rects);
slouken@1662
  1042
static void DX5_DirectUpdate (_THIS, int numrects, SDL_Rect * rects);
slouken@0
  1043
slouken@1662
  1044
SDL_Surface *
slouken@1662
  1045
DX5_SetVideoMode (_THIS, SDL_Surface * current,
slouken@1662
  1046
                  int width, int height, int bpp, Uint32 flags)
slouken@0
  1047
{
slouken@1662
  1048
    SDL_Surface *video;
slouken@1662
  1049
    HRESULT result;
slouken@1662
  1050
    DWORD sharemode;
slouken@1662
  1051
    DWORD style;
slouken@1662
  1052
    const DWORD directstyle = (WS_POPUP);
slouken@1662
  1053
    const DWORD windowstyle =
slouken@1662
  1054
        (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX);
slouken@1662
  1055
    const DWORD resizestyle = (WS_THICKFRAME | WS_MAXIMIZEBOX);
slouken@1662
  1056
    DDSURFACEDESC ddsd;
slouken@1662
  1057
    LPDIRECTDRAWSURFACE dd_surface1;
slouken@1662
  1058
    LPDIRECTDRAWSURFACE3 dd_surface3;
slouken@0
  1059
slouken@1662
  1060
    SDL_resizing = 1;
slouken@0
  1061
#ifdef DDRAW_DEBUG
slouken@1662
  1062
    fprintf (stderr, "Setting %dx%dx%d video mode\n", width, height, bpp);
slouken@0
  1063
#endif
slouken@1662
  1064
    /* Clean up any previous DirectDraw surfaces */
slouken@1662
  1065
    if (current->hwdata) {
slouken@1662
  1066
        this->FreeHWSurface (this, current);
slouken@1662
  1067
        current->hwdata = NULL;
slouken@1662
  1068
    }
slouken@1662
  1069
    if (SDL_primary != NULL) {
slouken@1662
  1070
        IDirectDrawSurface3_Release (SDL_primary);
slouken@1662
  1071
        SDL_primary = NULL;
slouken@1662
  1072
    }
slouken@453
  1073
#ifndef NO_CHANGEDISPLAYSETTINGS
slouken@1662
  1074
    /* Unset any previous OpenGL fullscreen mode */
slouken@1662
  1075
    if ((current->flags & (SDL_INTERNALOPENGL | SDL_FULLSCREEN)) ==
slouken@1662
  1076
        (SDL_INTERNALOPENGL | SDL_FULLSCREEN)) {
slouken@1662
  1077
        ChangeDisplaySettings (NULL, 0);
slouken@1662
  1078
    }
slouken@453
  1079
#endif
slouken@0
  1080
slouken@1662
  1081
    /* Clean up any GL context that may be hanging around */
slouken@1662
  1082
    if (current->flags & SDL_INTERNALOPENGL) {
slouken@1662
  1083
        WIN_GL_ShutDown (this);
slouken@1662
  1084
    }
slouken@0
  1085
slouken@1662
  1086
    /* If we are setting a GL mode, use GDI, not DirectX (yuck) */
slouken@1662
  1087
    if (flags & SDL_INTERNALOPENGL) {
slouken@1662
  1088
        Uint32 Rmask, Gmask, Bmask;
slouken@0
  1089
slouken@1662
  1090
        /* Recalculate the bitmasks if necessary */
slouken@1662
  1091
        if (bpp == current->format->BitsPerPixel) {
slouken@1662
  1092
            video = current;
slouken@1662
  1093
        } else {
slouken@1662
  1094
            switch (bpp) {
slouken@1662
  1095
            case 15:
slouken@1662
  1096
            case 16:
slouken@1662
  1097
                if (0 /*DIB_SussScreenDepth() == 15 */ ) {
slouken@1662
  1098
                    /* 5-5-5 */
slouken@1662
  1099
                    Rmask = 0x00007c00;
slouken@1662
  1100
                    Gmask = 0x000003e0;
slouken@1662
  1101
                    Bmask = 0x0000001f;
slouken@1662
  1102
                } else {
slouken@1662
  1103
                    /* 5-6-5 */
slouken@1662
  1104
                    Rmask = 0x0000f800;
slouken@1662
  1105
                    Gmask = 0x000007e0;
slouken@1662
  1106
                    Bmask = 0x0000001f;
slouken@1662
  1107
                }
slouken@1662
  1108
                break;
slouken@1662
  1109
            case 24:
slouken@1662
  1110
            case 32:
slouken@1662
  1111
                /* GDI defined as 8-8-8 */
slouken@1662
  1112
                Rmask = 0x00ff0000;
slouken@1662
  1113
                Gmask = 0x0000ff00;
slouken@1662
  1114
                Bmask = 0x000000ff;
slouken@1662
  1115
                break;
slouken@1662
  1116
            default:
slouken@1662
  1117
                Rmask = 0x00000000;
slouken@1662
  1118
                Gmask = 0x00000000;
slouken@1662
  1119
                Bmask = 0x00000000;
slouken@1662
  1120
                break;
slouken@1662
  1121
            }
slouken@1662
  1122
            video = SDL_CreateRGBSurface (SDL_SWSURFACE, 0, 0, bpp,
slouken@1662
  1123
                                          Rmask, Gmask, Bmask, 0);
slouken@1662
  1124
            if (video == NULL) {
slouken@1662
  1125
                SDL_OutOfMemory ();
slouken@1662
  1126
                return (NULL);
slouken@1662
  1127
            }
slouken@1662
  1128
        }
slouken@0
  1129
slouken@1662
  1130
        /* Fill in part of the video surface */
slouken@1662
  1131
        video->flags = 0;       /* Clear flags */
slouken@1662
  1132
        video->w = width;
slouken@1662
  1133
        video->h = height;
slouken@1662
  1134
        video->pitch = SDL_CalculatePitch (video);
slouken@0
  1135
slouken@453
  1136
#ifndef NO_CHANGEDISPLAYSETTINGS
slouken@1662
  1137
        /* Set fullscreen mode if appropriate.
slouken@1662
  1138
           Ugh, since our list of valid video modes comes from
slouken@1662
  1139
           the DirectX driver, we may not actually be able to
slouken@1662
  1140
           change to the desired resolution here.
slouken@1662
  1141
           FIXME: Should we do a closest match?
slouken@1662
  1142
         */
slouken@1662
  1143
        if ((flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) {
slouken@1662
  1144
            DEVMODE settings;
slouken@1662
  1145
            BOOL changed;
slouken@0
  1146
slouken@1662
  1147
            SDL_memset (&settings, 0, sizeof (DEVMODE));
slouken@1662
  1148
            settings.dmSize = sizeof (DEVMODE);
slouken@1662
  1149
            settings.dmBitsPerPel = video->format->BitsPerPixel;
slouken@1662
  1150
            settings.dmPelsWidth = width;
slouken@1662
  1151
            settings.dmPelsHeight = height;
slouken@1662
  1152
            settings.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
slouken@1662
  1153
            if (width <= (int) SDL_desktop_mode.dmPelsWidth
slouken@1662
  1154
                && height <= (int) SDL_desktop_mode.dmPelsHeight) {
slouken@1662
  1155
                settings.dmDisplayFrequency =
slouken@1662
  1156
                    SDL_desktop_mode.dmDisplayFrequency;
slouken@1662
  1157
                settings.dmFields |= DM_DISPLAYFREQUENCY;
slouken@1662
  1158
            }
slouken@1662
  1159
            changed =
slouken@1662
  1160
                (ChangeDisplaySettings (&settings, CDS_FULLSCREEN) ==
slouken@1662
  1161
                 DISP_CHANGE_SUCCESSFUL);
slouken@1662
  1162
            if (!changed && (settings.dmFields & DM_DISPLAYFREQUENCY)) {
slouken@1662
  1163
                settings.dmFields &= ~DM_DISPLAYFREQUENCY;
slouken@1662
  1164
                changed = (ChangeDisplaySettings (&settings, CDS_FULLSCREEN)
slouken@1662
  1165
                           == DISP_CHANGE_SUCCESSFUL);
slouken@1662
  1166
            }
slouken@1662
  1167
            if (changed) {
slouken@1662
  1168
                video->flags |= SDL_FULLSCREEN;
slouken@1662
  1169
                SDL_fullscreen_mode = settings;
slouken@1662
  1170
            }
slouken@1662
  1171
        }
slouken@453
  1172
#endif /* !NO_CHANGEDISPLAYSETTINGS */
slouken@0
  1173
slouken@1662
  1174
        style = GetWindowLong (SDL_Window, GWL_STYLE);
slouken@1662
  1175
        style &= ~(resizestyle | WS_MAXIMIZE);
slouken@1662
  1176
        if (video->flags & SDL_FULLSCREEN) {
slouken@1662
  1177
            style &= ~windowstyle;
slouken@1662
  1178
            style |= directstyle;
slouken@1662
  1179
        } else {
slouken@1662
  1180
            if (flags & SDL_NOFRAME) {
slouken@1662
  1181
                style &= ~windowstyle;
slouken@1662
  1182
                style |= directstyle;
slouken@1662
  1183
                video->flags |= SDL_NOFRAME;
slouken@1662
  1184
            } else {
slouken@1662
  1185
                style &= ~directstyle;
slouken@1662
  1186
                style |= windowstyle;
slouken@1662
  1187
                if (flags & SDL_RESIZABLE) {
slouken@1662
  1188
                    style |= resizestyle;
slouken@1662
  1189
                    video->flags |= SDL_RESIZABLE;
slouken@1662
  1190
                }
slouken@1662
  1191
            }
slouken@453
  1192
#if WS_MAXIMIZE
slouken@1662
  1193
            if (IsZoomed (SDL_Window))
slouken@1662
  1194
                style |= WS_MAXIMIZE;
slouken@453
  1195
#endif
slouken@1662
  1196
        }
slouken@833
  1197
slouken@1662
  1198
        /* DJM: Don't piss of anyone who has setup his own window */
slouken@1662
  1199
        if (!SDL_windowid)
slouken@1662
  1200
            SetWindowLong (SDL_Window, GWL_STYLE, style);
slouken@0
  1201
slouken@1662
  1202
        /* Resize the window (copied from SDL WinDIB driver) */
slouken@1662
  1203
        if (!SDL_windowid && !IsZoomed (SDL_Window)) {
slouken@1662
  1204
            RECT bounds;
slouken@1662
  1205
            int x, y;
slouken@1662
  1206
            HWND top;
slouken@1662
  1207
            UINT swp_flags;
slouken@1662
  1208
            const char *window = NULL;
slouken@1662
  1209
            const char *center = NULL;
slouken@833
  1210
slouken@1662
  1211
            if (!SDL_windowX && !SDL_windowY) {
slouken@1662
  1212
                window = SDL_getenv ("SDL_VIDEO_WINDOW_POS");
slouken@1662
  1213
                center = SDL_getenv ("SDL_VIDEO_CENTERED");
slouken@1662
  1214
                if (window) {
slouken@1662
  1215
                    if (SDL_sscanf (window, "%d,%d", &x, &y) == 2) {
slouken@1662
  1216
                        SDL_windowX = x;
slouken@1662
  1217
                        SDL_windowY = y;
slouken@1662
  1218
                    }
slouken@1662
  1219
                    if (SDL_strcmp (window, "center") == 0) {
slouken@1662
  1220
                        center = window;
slouken@1662
  1221
                    }
slouken@1662
  1222
                }
slouken@1662
  1223
            }
slouken@1662
  1224
            swp_flags = (SWP_NOCOPYBITS | SWP_SHOWWINDOW);
slouken@0
  1225
slouken@1662
  1226
            bounds.left = SDL_windowX;
slouken@1662
  1227
            bounds.top = SDL_windowY;
slouken@1662
  1228
            bounds.right = SDL_windowX + video->w;
slouken@1662
  1229
            bounds.bottom = SDL_windowY + video->h;
slouken@1662
  1230
            AdjustWindowRectEx (&bounds,
slouken@1662
  1231
                                GetWindowLong (SDL_Window, GWL_STYLE),
slouken@1662
  1232
                                FALSE, 0);
slouken@1662
  1233
            width = bounds.right - bounds.left;
slouken@1662
  1234
            height = bounds.bottom - bounds.top;
slouken@1662
  1235
            if ((flags & SDL_FULLSCREEN)) {
slouken@1662
  1236
                x = (GetSystemMetrics (SM_CXSCREEN) - width) / 2;
slouken@1662
  1237
                y = (GetSystemMetrics (SM_CYSCREEN) - height) / 2;
slouken@1662
  1238
            } else if (center) {
slouken@1662
  1239
                x = (GetSystemMetrics (SM_CXSCREEN) - width) / 2;
slouken@1662
  1240
                y = (GetSystemMetrics (SM_CYSCREEN) - height) / 2;
slouken@1662
  1241
            } else if (SDL_windowX || SDL_windowY || window) {
slouken@1662
  1242
                x = bounds.left;
slouken@1662
  1243
                y = bounds.top;
slouken@1662
  1244
            } else {
slouken@1662
  1245
                x = y = -1;
slouken@1662
  1246
                swp_flags |= SWP_NOMOVE;
slouken@1662
  1247
            }
slouken@1662
  1248
            if (flags & SDL_FULLSCREEN) {
slouken@1662
  1249
                top = HWND_TOPMOST;
slouken@1662
  1250
            } else {
slouken@1662
  1251
                top = HWND_NOTOPMOST;
slouken@1662
  1252
            }
slouken@1662
  1253
            SetWindowPos (SDL_Window, top, x, y, width, height, swp_flags);
slouken@1662
  1254
            if (!(flags & SDL_FULLSCREEN)) {
slouken@1662
  1255
                SDL_windowX = SDL_bounds.left;
slouken@1662
  1256
                SDL_windowY = SDL_bounds.top;
slouken@1662
  1257
            }
slouken@1662
  1258
            SetForegroundWindow (SDL_Window);
slouken@1662
  1259
        }
slouken@1662
  1260
        SDL_resizing = 0;
slouken@0
  1261
slouken@1662
  1262
        /* Set up for OpenGL */
slouken@1662
  1263
        if (WIN_GL_SetupWindow (this) < 0) {
slouken@1662
  1264
            return (NULL);
slouken@1662
  1265
        }
slouken@1662
  1266
        video->flags |= SDL_INTERNALOPENGL;
slouken@1662
  1267
        return (video);
slouken@1662
  1268
    }
slouken@0
  1269
slouken@1662
  1270
    /* Set the appropriate window style */
slouken@1662
  1271
    style = GetWindowLong (SDL_Window, GWL_STYLE);
slouken@1662
  1272
    style &= ~(resizestyle | WS_MAXIMIZE);
slouken@1662
  1273
    if ((flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) {
slouken@1662
  1274
        style &= ~windowstyle;
slouken@1662
  1275
        style |= directstyle;
slouken@1662
  1276
    } else {
slouken@1662
  1277
        if (flags & SDL_NOFRAME) {
slouken@1662
  1278
            style &= ~windowstyle;
slouken@1662
  1279
            style |= directstyle;
slouken@1662
  1280
        } else {
slouken@1662
  1281
            style &= ~directstyle;
slouken@1662
  1282
            style |= windowstyle;
slouken@1662
  1283
            if (flags & SDL_RESIZABLE) {
slouken@1662
  1284
                style |= resizestyle;
slouken@1662
  1285
            }
slouken@1662
  1286
        }
slouken@453
  1287
#if WS_MAXIMIZE
slouken@1662
  1288
        if (IsZoomed (SDL_Window))
slouken@1662
  1289
            style |= WS_MAXIMIZE;
slouken@453
  1290
#endif
slouken@1662
  1291
    }
slouken@1662
  1292
    /* DJM: Don't piss of anyone who has setup his own window */
slouken@1662
  1293
    if (!SDL_windowid)
slouken@1662
  1294
        SetWindowLong (SDL_Window, GWL_STYLE, style);
slouken@0
  1295
slouken@1662
  1296
    /* Set DirectDraw sharing mode.. exclusive when fullscreen */
slouken@1662
  1297
    if ((flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) {
slouken@1662
  1298
        sharemode = DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT;
slouken@1662
  1299
    } else {
slouken@1662
  1300
        sharemode = DDSCL_NORMAL;
slouken@1662
  1301
    }
slouken@1662
  1302
    result = IDirectDraw2_SetCooperativeLevel (ddraw2, SDL_Window, sharemode);
slouken@1662
  1303
    if (result != DD_OK) {
slouken@1662
  1304
        SetDDerror ("DirectDraw2::SetCooperativeLevel", result);
slouken@1662
  1305
        return (NULL);
slouken@1662
  1306
    }
slouken@0
  1307
slouken@1662
  1308
    /* Set the display mode, if we are in fullscreen mode */
slouken@1662
  1309
    if ((flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) {
slouken@1662
  1310
        RECT bounds;
slouken@1662
  1311
        struct DX5EnumRect *rect;
slouken@1662
  1312
        int maxRefreshRate;
slouken@809
  1313
slouken@1662
  1314
        /* Cover up desktop during mode change */
slouken@1662
  1315
        bounds.left = 0;
slouken@1662
  1316
        bounds.top = 0;
slouken@1662
  1317
        bounds.right = GetSystemMetrics (SM_CXSCREEN);
slouken@1662
  1318
        bounds.bottom = GetSystemMetrics (SM_CYSCREEN);
slouken@1662
  1319
        AdjustWindowRectEx (&bounds, GetWindowLong (SDL_Window, GWL_STYLE),
slouken@1662
  1320
                            FALSE, 0);
slouken@1662
  1321
        SetWindowPos (SDL_Window, HWND_TOPMOST, bounds.left, bounds.top,
slouken@1662
  1322
                      bounds.right - bounds.left,
slouken@1662
  1323
                      bounds.bottom - bounds.top, SWP_NOCOPYBITS);
slouken@1662
  1324
        ShowWindow (SDL_Window, SW_SHOW);
slouken@1662
  1325
        while (GetForegroundWindow () != SDL_Window) {
slouken@1662
  1326
            SetForegroundWindow (SDL_Window);
slouken@1662
  1327
            SDL_Delay (100);
slouken@1662
  1328
        }
slouken@809
  1329
slouken@1662
  1330
        /* find maximum monitor refresh rate for this resolution */
slouken@1662
  1331
        /* Dmitry Yakimov ftech@tula.net */
slouken@1662
  1332
        maxRefreshRate = 0;     /* system default */
slouken@1662
  1333
        for (rect = enumlists[bpp / 8 - 1]; rect; rect = rect->next) {
slouken@1662
  1334
            if ((width == rect->r.w) && (height == rect->r.h)) {
slouken@1662
  1335
                maxRefreshRate = rect->refreshRate;
slouken@1662
  1336
                break;
slouken@1662
  1337
            }
slouken@1662
  1338
        }
slouken@830
  1339
#ifdef DDRAW_DEBUG
slouken@1662
  1340
        fprintf (stderr, "refresh rate = %d Hz\n", maxRefreshRate);
slouken@830
  1341
#endif
slouken@809
  1342
slouken@1662
  1343
        result =
slouken@1662
  1344
            IDirectDraw2_SetDisplayMode (ddraw2, width, height, bpp,
slouken@1662
  1345
                                         maxRefreshRate, 0);
slouken@1662
  1346
        if (result != DD_OK) {
slouken@1662
  1347
            result =
slouken@1662
  1348
                IDirectDraw2_SetDisplayMode (ddraw2, width, height, bpp,
slouken@1662
  1349
                                             0, 0);
slouken@1662
  1350
            if (result != DD_OK) {
slouken@1662
  1351
                /* We couldn't set fullscreen mode, try window */
slouken@1662
  1352
                return (DX5_SetVideoMode
slouken@1662
  1353
                        (this, current, width, height, bpp,
slouken@1662
  1354
                         flags & ~SDL_FULLSCREEN));
slouken@1662
  1355
            }
slouken@1662
  1356
        }
slouken@1662
  1357
        DX5_DInputReset (this, 1);
slouken@1662
  1358
    } else {
slouken@1662
  1359
        DX5_DInputReset (this, 0);
slouken@1662
  1360
    }
slouken@1662
  1361
    DX5_UpdateVideoInfo (this);
slouken@0
  1362
slouken@1662
  1363
    /* Create a primary DirectDraw surface */
slouken@1662
  1364
    SDL_memset (&ddsd, 0, sizeof (ddsd));
slouken@1662
  1365
    ddsd.dwSize = sizeof (ddsd);
slouken@1662
  1366
    ddsd.dwFlags = DDSD_CAPS;
slouken@1662
  1367
    ddsd.ddsCaps.dwCaps = (DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY);
slouken@1662
  1368
    if ((flags & SDL_FULLSCREEN) != SDL_FULLSCREEN) {
slouken@1662
  1369
        /* There's no windowed double-buffering */
slouken@1662
  1370
        flags &= ~SDL_DOUBLEBUF;
slouken@1662
  1371
    }
slouken@1662
  1372
    if ((flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) {
slouken@1662
  1373
        ddsd.dwFlags |= DDSD_BACKBUFFERCOUNT;
slouken@1662
  1374
        ddsd.ddsCaps.dwCaps |= (DDSCAPS_COMPLEX | DDSCAPS_FLIP);
slouken@1662
  1375
        ddsd.dwBackBufferCount = 1;
slouken@1662
  1376
    }
slouken@1662
  1377
    result = IDirectDraw2_CreateSurface (ddraw2, &ddsd, &dd_surface1, NULL);
slouken@1662
  1378
    if ((result != DD_OK) && ((flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF)) {
slouken@1662
  1379
        ddsd.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
slouken@1662
  1380
        ddsd.ddsCaps.dwCaps &= ~(DDSCAPS_COMPLEX | DDSCAPS_FLIP);
slouken@1662
  1381
        ddsd.dwBackBufferCount = 0;
slouken@1662
  1382
        result = IDirectDraw2_CreateSurface (ddraw2,
slouken@1662
  1383
                                             &ddsd, &dd_surface1, NULL);
slouken@1662
  1384
    }
slouken@1662
  1385
    if (result != DD_OK) {
slouken@1662
  1386
        SetDDerror ("DirectDraw2::CreateSurface(PRIMARY)", result);
slouken@1662
  1387
        return (NULL);
slouken@1662
  1388
    }
slouken@1662
  1389
    result = IDirectDrawSurface_QueryInterface (dd_surface1,
slouken@1662
  1390
                                                &IID_IDirectDrawSurface3,
slouken@1662
  1391
                                                (LPVOID *) & SDL_primary);
slouken@1662
  1392
    if (result != DD_OK) {
slouken@1662
  1393
        SetDDerror ("DirectDrawSurface::QueryInterface", result);
slouken@1662
  1394
        return (NULL);
slouken@1662
  1395
    }
slouken@1662
  1396
    IDirectDrawSurface_Release (dd_surface1);
slouken@0
  1397
slouken@1662
  1398
    /* Get the format of the primary DirectDraw surface */
slouken@1662
  1399
    SDL_memset (&ddsd, 0, sizeof (ddsd));
slouken@1662
  1400
    ddsd.dwSize = sizeof (ddsd);
slouken@1662
  1401
    ddsd.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
slouken@1662
  1402
    result = IDirectDrawSurface3_GetSurfaceDesc (SDL_primary, &ddsd);
slouken@1662
  1403
    if (result != DD_OK) {
slouken@1662
  1404
        SetDDerror ("DirectDrawSurface::GetSurfaceDesc", result);
slouken@1662
  1405
        return (NULL);
slouken@1662
  1406
    }
slouken@1662
  1407
    if (!(ddsd.ddpfPixelFormat.dwFlags & DDPF_RGB)) {
slouken@1662
  1408
        SDL_SetError ("Primary DDRAW surface is not RGB format");
slouken@1662
  1409
        return (NULL);
slouken@1662
  1410
    }
slouken@0
  1411
slouken@1662
  1412
    /* Free old palette and create a new one if we're in 8-bit mode */
slouken@1662
  1413
    if (SDL_palette != NULL) {
slouken@1662
  1414
        IDirectDrawPalette_Release (SDL_palette);
slouken@1662
  1415
        SDL_palette = NULL;
slouken@1662
  1416
    }
slouken@1662
  1417
#if defined(NONAMELESSUNION)
slouken@1662
  1418
    if (ddsd.ddpfPixelFormat.u1.dwRGBBitCount == 8) {
slouken@1662
  1419
#else
slouken@1662
  1420
    if (ddsd.ddpfPixelFormat.dwRGBBitCount == 8) {
slouken@1662
  1421
#endif
slouken@1662
  1422
        int i;
slouken@0
  1423
slouken@1662
  1424
        if ((flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) {
slouken@1662
  1425
            /* We have access to the entire palette */
slouken@1662
  1426
            for (i = 0; i < 256; ++i) {
slouken@1662
  1427
                SDL_colors[i].peFlags = (PC_NOCOLLAPSE | PC_RESERVED);
slouken@1662
  1428
                SDL_colors[i].peRed = 0;
slouken@1662
  1429
                SDL_colors[i].peGreen = 0;
slouken@1662
  1430
                SDL_colors[i].peBlue = 0;
slouken@1662
  1431
            }
slouken@1662
  1432
        } else {
slouken@1662
  1433
            /* First 10 colors are reserved by Windows */
slouken@1662
  1434
            for (i = 0; i < 10; ++i) {
slouken@1662
  1435
                SDL_colors[i].peFlags = PC_EXPLICIT;
slouken@1662
  1436
                SDL_colors[i].peRed = i;
slouken@1662
  1437
                SDL_colors[i].peGreen = 0;
slouken@1662
  1438
                SDL_colors[i].peBlue = 0;
slouken@1662
  1439
            }
slouken@1662
  1440
            for (i = 10; i < (10 + 236); ++i) {
slouken@1662
  1441
                SDL_colors[i].peFlags = PC_NOCOLLAPSE;
slouken@1662
  1442
                SDL_colors[i].peRed = 0;
slouken@1662
  1443
                SDL_colors[i].peGreen = 0;
slouken@1662
  1444
                SDL_colors[i].peBlue = 0;
slouken@1662
  1445
            }
slouken@1662
  1446
            /* Last 10 colors are reserved by Windows */
slouken@1662
  1447
            for (i = 246; i < 256; ++i) {
slouken@1662
  1448
                SDL_colors[i].peFlags = PC_EXPLICIT;
slouken@1662
  1449
                SDL_colors[i].peRed = i;
slouken@1662
  1450
                SDL_colors[i].peGreen = 0;
slouken@1662
  1451
                SDL_colors[i].peBlue = 0;
slouken@1662
  1452
            }
slouken@1662
  1453
        }
slouken@1662
  1454
        result = IDirectDraw2_CreatePalette (ddraw2,
slouken@1662
  1455
                                             (DDPCAPS_8BIT |
slouken@1662
  1456
                                              DDPCAPS_ALLOW256), SDL_colors,
slouken@1662
  1457
                                             &SDL_palette, NULL);
slouken@1662
  1458
        if (result != DD_OK) {
slouken@1662
  1459
            SetDDerror ("DirectDraw2::CreatePalette", result);
slouken@1662
  1460
            return (NULL);
slouken@1662
  1461
        }
slouken@1662
  1462
        result = IDirectDrawSurface3_SetPalette (SDL_primary, SDL_palette);
slouken@1662
  1463
        if (result != DD_OK) {
slouken@1662
  1464
            SetDDerror ("DirectDrawSurface3::SetPalette", result);
slouken@1662
  1465
            return (NULL);
slouken@1662
  1466
        }
slouken@1662
  1467
    }
slouken@1662
  1468
slouken@1662
  1469
    /* Create our video surface using the same pixel format */
slouken@1662
  1470
    video = current;
slouken@1662
  1471
    if ((width != video->w) || (height != video->h)
slouken@1662
  1472
        || (video->format->BitsPerPixel !=
slouken@0
  1473
#if defined(NONAMELESSUNION)
slouken@1662
  1474
            ddsd.ddpfPixelFormat.u1.dwRGBBitCount)) {
slouken@0
  1475
#else
slouken@1662
  1476
            ddsd.ddpfPixelFormat.dwRGBBitCount)) {
slouken@0
  1477
#endif
slouken@1662
  1478
        SDL_FreeSurface (video);
slouken@1662
  1479
        video = SDL_CreateRGBSurface (SDL_SWSURFACE, 0, 0,
slouken@1662
  1480
#if defined(NONAMELESSUNION)
slouken@1662
  1481
                                      ddsd.ddpfPixelFormat.u1.dwRGBBitCount,
slouken@1662
  1482
                                      ddsd.ddpfPixelFormat.u2.dwRBitMask,
slouken@1662
  1483
                                      ddsd.ddpfPixelFormat.u3.dwGBitMask,
slouken@1662
  1484
                                      ddsd.ddpfPixelFormat.u4.dwBBitMask,
slouken@1662
  1485
#else
slouken@1662
  1486
                                      ddsd.ddpfPixelFormat.dwRGBBitCount,
slouken@1662
  1487
                                      ddsd.ddpfPixelFormat.dwRBitMask,
slouken@1662
  1488
                                      ddsd.ddpfPixelFormat.dwGBitMask,
slouken@1662
  1489
                                      ddsd.ddpfPixelFormat.dwBBitMask,
slouken@1662
  1490
#endif
slouken@1662
  1491
                                      0);
slouken@1662
  1492
        if (video == NULL) {
slouken@1662
  1493
            SDL_OutOfMemory ();
slouken@1662
  1494
            return (NULL);
slouken@1662
  1495
        }
slouken@1662
  1496
        video->w = width;
slouken@1662
  1497
        video->h = height;
slouken@1662
  1498
        video->pitch = 0;
slouken@1662
  1499
    }
slouken@1662
  1500
    video->flags = 0;           /* Clear flags */
slouken@0
  1501
slouken@1662
  1502
    /* If not fullscreen, locking is possible, but it doesn't do what 
slouken@1662
  1503
       the caller really expects -- if the locked surface is written to,
slouken@1662
  1504
       the appropriate portion of the entire screen is modified, not 
slouken@1662
  1505
       the application window, as we would like.
slouken@1662
  1506
       Note that it is still possible to write directly to display
slouken@1662
  1507
       memory, but the application must respect the clip list of
slouken@1662
  1508
       the surface.  There might be some odd timing interactions
slouken@1662
  1509
       involving clip list updates and background refreshing as
slouken@1662
  1510
       Windows moves other windows across our window.
slouken@1662
  1511
       We currently don't support this, even though it might be a
slouken@1662
  1512
       good idea since BeOS has an implementation of BDirectWindow
slouken@1662
  1513
       that does the same thing.  This would be most useful for
slouken@1662
  1514
       applications that do complete screen updates every frame.
slouken@1662
  1515
       -- Fixme?
slouken@1662
  1516
     */
slouken@1662
  1517
    if ((flags & SDL_FULLSCREEN) != SDL_FULLSCREEN) {
slouken@1662
  1518
        /* Necessary if we're going from fullscreen to window */
slouken@1662
  1519
        if (video->pixels == NULL) {
slouken@1662
  1520
            video->pitch = (width * video->format->BytesPerPixel);
slouken@1662
  1521
            /* Pitch needs to be QWORD (8-byte) aligned */
slouken@1662
  1522
            video->pitch = (video->pitch + 7) & ~7;
slouken@1662
  1523
            video->pixels = (void *) SDL_malloc (video->h * video->pitch);
slouken@1662
  1524
            if (video->pixels == NULL) {
slouken@1662
  1525
                if (video != current) {
slouken@1662
  1526
                    SDL_FreeSurface (video);
slouken@1662
  1527
                }
slouken@1662
  1528
                SDL_OutOfMemory ();
slouken@1662
  1529
                return (NULL);
slouken@1662
  1530
            }
slouken@1662
  1531
        }
slouken@1662
  1532
        dd_surface3 = NULL;
slouken@1662
  1533
#if 0                           /* FIXME: enable this when SDL consistently reports lost surfaces */
slouken@1662
  1534
        if ((flags & SDL_HWSURFACE) == SDL_HWSURFACE) {
slouken@1662
  1535
            video->flags |= SDL_HWSURFACE;
slouken@1662
  1536
        } else {
slouken@1662
  1537
            video->flags |= SDL_SWSURFACE;
slouken@1662
  1538
        }
slouken@443
  1539
#else
slouken@1662
  1540
        video->flags |= SDL_SWSURFACE;
slouken@443
  1541
#endif
slouken@1662
  1542
        if ((flags & SDL_RESIZABLE) && !(flags & SDL_NOFRAME)) {
slouken@1662
  1543
            video->flags |= SDL_RESIZABLE;
slouken@1662
  1544
        }
slouken@1662
  1545
        if (flags & SDL_NOFRAME) {
slouken@1662
  1546
            video->flags |= SDL_NOFRAME;
slouken@1662
  1547
        }
slouken@1662
  1548
    } else {
slouken@1662
  1549
        /* Necessary if we're going from window to fullscreen */
slouken@1662
  1550
        if (video->pixels != NULL) {
slouken@1662
  1551
            SDL_free (video->pixels);
slouken@1662
  1552
            video->pixels = NULL;
slouken@1662
  1553
        }
slouken@1662
  1554
        dd_surface3 = SDL_primary;
slouken@1662
  1555
        video->flags |= SDL_HWSURFACE;
slouken@1662
  1556
    }
slouken@0
  1557
slouken@1662
  1558
    /* See if the primary surface has double-buffering enabled */
slouken@1662
  1559
    if ((ddsd.ddsCaps.dwCaps & DDSCAPS_FLIP) == DDSCAPS_FLIP) {
slouken@1662
  1560
        video->flags |= SDL_DOUBLEBUF;
slouken@1662
  1561
    }
slouken@0
  1562
slouken@1662
  1563
    /* Allocate the SDL surface associated with the primary surface */
slouken@1662
  1564
    if (DX5_AllocDDSurface (this, video, dd_surface3,
slouken@1662
  1565
                            video->flags & SDL_HWSURFACE) < 0) {
slouken@1662
  1566
        if (video != current) {
slouken@1662
  1567
            SDL_FreeSurface (video);
slouken@1662
  1568
        }
slouken@1662
  1569
        return (NULL);
slouken@1662
  1570
    }
slouken@0
  1571
slouken@1662
  1572
    /* Use the appropriate blitting function */
slouken@1662
  1573
    if ((flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) {
slouken@1662
  1574
        video->flags |= SDL_FULLSCREEN;
slouken@1662
  1575
        if (video->format->palette != NULL) {
slouken@1662
  1576
            video->flags |= SDL_HWPALETTE;
slouken@1662
  1577
        }
slouken@1662
  1578
        this->UpdateRects = DX5_DirectUpdate;
slouken@1662
  1579
    } else {
slouken@1662
  1580
        this->UpdateRects = DX5_WindowUpdate;
slouken@1662
  1581
    }
slouken@0
  1582
slouken@1662
  1583
    /* Make our window the proper size, set the clipper, then show it */
slouken@1662
  1584
    if ((flags & SDL_FULLSCREEN) != SDL_FULLSCREEN) {
slouken@1662
  1585
        /* Create and set a clipper on our primary surface */
slouken@1662
  1586
        if (SDL_clipper == NULL) {
slouken@1662
  1587
            result = IDirectDraw2_CreateClipper (ddraw2,
slouken@1662
  1588
                                                 0, &SDL_clipper, NULL);
slouken@1662
  1589
            if (result != DD_OK) {
slouken@1662
  1590
                if (video != current) {
slouken@1662
  1591
                    SDL_FreeSurface (video);
slouken@1662
  1592
                }
slouken@1662
  1593
                SetDDerror ("DirectDraw2::CreateClipper", result);
slouken@1662
  1594
                return (NULL);
slouken@1662
  1595
            }
slouken@1662
  1596
        }
slouken@1662
  1597
        result = IDirectDrawClipper_SetHWnd (SDL_clipper, 0, SDL_Window);
slouken@1662
  1598
        if (result != DD_OK) {
slouken@1662
  1599
            if (video != current) {
slouken@1662
  1600
                SDL_FreeSurface (video);
slouken@1662
  1601
            }
slouken@1662
  1602
            SetDDerror ("DirectDrawClipper::SetHWnd", result);
slouken@1662
  1603
            return (NULL);
slouken@1662
  1604
        }
slouken@1662
  1605
        result = IDirectDrawSurface3_SetClipper (SDL_primary, SDL_clipper);
slouken@1662
  1606
        if (result != DD_OK) {
slouken@1662
  1607
            if (video != current) {
slouken@1662
  1608
                SDL_FreeSurface (video);
slouken@1662
  1609
            }
slouken@1662
  1610
            SetDDerror ("DirectDrawSurface3::SetClipper", result);
slouken@1662
  1611
            return (NULL);
slouken@1662
  1612
        }
slouken@0
  1613
slouken@1662
  1614
        /* Resize the window (copied from SDL WinDIB driver) */
slouken@1662
  1615
        if (!SDL_windowid && !IsZoomed (SDL_Window)) {
slouken@1662
  1616
            RECT bounds;
slouken@1662
  1617
            int x, y;
slouken@1662
  1618
            UINT swp_flags;
slouken@1662
  1619
            const char *window = NULL;
slouken@1662
  1620
            const char *center = NULL;
slouken@1290
  1621
slouken@1662
  1622
            if (!SDL_windowX && !SDL_windowY) {
slouken@1662
  1623
                window = SDL_getenv ("SDL_VIDEO_WINDOW_POS");
slouken@1662
  1624
                center = SDL_getenv ("SDL_VIDEO_CENTERED");
slouken@1662
  1625
                if (window) {
slouken@1662
  1626
                    if (SDL_sscanf (window, "%d,%d", &x, &y) == 2) {
slouken@1662
  1627
                        SDL_windowX = x;
slouken@1662
  1628
                        SDL_windowY = y;
slouken@1662
  1629
                    }
slouken@1662
  1630
                    if (SDL_strcmp (window, "center") == 0) {
slouken@1662
  1631
                        center = window;
slouken@1662
  1632
                    }
slouken@1662
  1633
                }
slouken@1662
  1634
            }
slouken@1662
  1635
            swp_flags = SWP_NOCOPYBITS;
slouken@833
  1636
slouken@1662
  1637
            bounds.left = SDL_windowX;
slouken@1662
  1638
            bounds.top = SDL_windowY;
slouken@1662
  1639
            bounds.right = SDL_windowX + video->w;
slouken@1662
  1640
            bounds.bottom = SDL_windowY + video->h;
slouken@1662
  1641
            AdjustWindowRectEx (&bounds,
slouken@1662
  1642
                                GetWindowLong (SDL_Window, GWL_STYLE),
slouken@1662
  1643
                                FALSE, 0);
slouken@1662
  1644
            width = bounds.right - bounds.left;
slouken@1662
  1645
            height = bounds.bottom - bounds.top;
slouken@1662
  1646
            if (center) {
slouken@1662
  1647
                x = (GetSystemMetrics (SM_CXSCREEN) - width) / 2;
slouken@1662
  1648
                y = (GetSystemMetrics (SM_CYSCREEN) - height) / 2;
slouken@1662
  1649
            } else if (SDL_windowX || SDL_windowY || window) {
slouken@1662
  1650
                x = bounds.left;
slouken@1662
  1651
                y = bounds.top;
slouken@1662
  1652
            } else {
slouken@1662
  1653
                x = y = -1;
slouken@1662
  1654
                swp_flags |= SWP_NOMOVE;
slouken@1662
  1655
            }
slouken@1662
  1656
            SetWindowPos (SDL_Window, HWND_NOTOPMOST, x, y, width, height,
slouken@1662
  1657
                          swp_flags);
slouken@1662
  1658
            SDL_windowX = SDL_bounds.left;
slouken@1662
  1659
            SDL_windowY = SDL_bounds.top;
slouken@1662
  1660
        }
slouken@833
  1661
slouken@1662
  1662
    }
slouken@1662
  1663
    ShowWindow (SDL_Window, SW_SHOW);
slouken@1662
  1664
    SetForegroundWindow (SDL_Window);
slouken@1662
  1665
    SDL_resizing = 0;
slouken@0
  1666
slouken@1662
  1667
    /* JC 14 Mar 2006
slouken@1662
  1668
       Flush the message loop or this can cause big problems later
slouken@1662
  1669
       Especially if the user decides to use dialog boxes or assert()!
slouken@1662
  1670
     */
slouken@1662
  1671
    WIN_FlushMessageQueue ();
slouken@1523
  1672
slouken@1662
  1673
    /* We're live! */
slouken@1662
  1674
    return (video);
slouken@0
  1675
}
slouken@0
  1676
slouken@1662
  1677
struct private_hwdata
slouken@1662
  1678
{
slouken@1662
  1679
    LPDIRECTDRAWSURFACE3 dd_surface;
slouken@1662
  1680
    LPDIRECTDRAWSURFACE3 dd_writebuf;
slouken@0
  1681
};
slouken@0
  1682
slouken@1662
  1683
static int
slouken@1662
  1684
DX5_AllocDDSurface (_THIS, SDL_Surface * surface,
slouken@1662
  1685
                    LPDIRECTDRAWSURFACE3 requested, Uint32 flag)
slouken@0
  1686
{
slouken@1662
  1687
    LPDIRECTDRAWSURFACE dd_surface1;
slouken@1662
  1688
    LPDIRECTDRAWSURFACE3 dd_surface3;
slouken@1662
  1689
    DDSURFACEDESC ddsd;
slouken@1662
  1690
    HRESULT result;
slouken@0
  1691
slouken@1662
  1692
    /* Clear the hardware flag, in case we fail */
slouken@1662
  1693
    surface->flags &= ~flag;
slouken@0
  1694
slouken@1662
  1695
    /* Allocate the hardware acceleration data */
slouken@1662
  1696
    surface->hwdata = (struct private_hwdata *)
slouken@1662
  1697
        SDL_malloc (sizeof (*surface->hwdata));
slouken@1662
  1698
    if (surface->hwdata == NULL) {
slouken@1662
  1699
        SDL_OutOfMemory ();
slouken@1662
  1700
        return (-1);
slouken@1662
  1701
    }
slouken@1662
  1702
    dd_surface3 = NULL;
slouken@0
  1703
slouken@1662
  1704
    /* Set up the surface description */
slouken@1662
  1705
    SDL_memset (&ddsd, 0, sizeof (ddsd));
slouken@1662
  1706
    ddsd.dwSize = sizeof (ddsd);
slouken@1662
  1707
    ddsd.dwFlags = (DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS |
slouken@1662
  1708
                    DDSD_PITCH | DDSD_PIXELFORMAT);
slouken@1662
  1709
    ddsd.dwWidth = surface->w;
slouken@1662
  1710
    ddsd.dwHeight = surface->h;
slouken@0
  1711
#if defined(NONAMELESSUNION)
slouken@1662
  1712
    ddsd.u1.lPitch = surface->pitch;
slouken@0
  1713
#else
slouken@1662
  1714
    ddsd.lPitch = surface->pitch;
slouken@0
  1715
#endif
slouken@1662
  1716
    if ((flag & SDL_HWSURFACE) == SDL_HWSURFACE) {
slouken@1662
  1717
        ddsd.ddsCaps.dwCaps = (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY);
slouken@1662
  1718
    } else {
slouken@1662
  1719
        ddsd.ddsCaps.dwCaps = (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY);
slouken@1662
  1720
    }
slouken@1662
  1721
    ddsd.ddpfPixelFormat.dwSize = sizeof (ddsd.ddpfPixelFormat);
slouken@1662
  1722
    ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
slouken@1662
  1723
    if (surface->format->palette) {
slouken@1662
  1724
        ddsd.ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED8;
slouken@1662
  1725
    }
slouken@0
  1726
#if defined(NONAMELESSUNION)
slouken@1662
  1727
    ddsd.ddpfPixelFormat.u1.dwRGBBitCount = surface->format->BitsPerPixel;
slouken@1662
  1728
    ddsd.ddpfPixelFormat.u2.dwRBitMask = surface->format->Rmask;
slouken@1662
  1729
    ddsd.ddpfPixelFormat.u3.dwGBitMask = surface->format->Gmask;
slouken@1662
  1730
    ddsd.ddpfPixelFormat.u4.dwBBitMask = surface->format->Bmask;
slouken@0
  1731
#else
slouken@1662
  1732
    ddsd.ddpfPixelFormat.dwRGBBitCount = surface->format->BitsPerPixel;
slouken@1662
  1733
    ddsd.ddpfPixelFormat.dwRBitMask = surface->format->Rmask;
slouken@1662
  1734
    ddsd.ddpfPixelFormat.dwGBitMask = surface->format->Gmask;
slouken@1662
  1735
    ddsd.ddpfPixelFormat.dwBBitMask = surface->format->Bmask;
slouken@0
  1736
#endif
slouken@0
  1737
slouken@1662
  1738
    /* Create the DirectDraw video surface */
slouken@1662
  1739
    if (requested != NULL) {
slouken@1662
  1740
        dd_surface3 = requested;
slouken@1662
  1741
    } else {
slouken@1662
  1742
        result = IDirectDraw2_CreateSurface (ddraw2,
slouken@1662
  1743
                                             &ddsd, &dd_surface1, NULL);
slouken@1662
  1744
        if (result != DD_OK) {
slouken@1662
  1745
            SetDDerror ("DirectDraw2::CreateSurface", result);
slouken@1662
  1746
            goto error_end;
slouken@1662
  1747
        }
slouken@1662
  1748
        result = IDirectDrawSurface_QueryInterface (dd_surface1,
slouken@1662
  1749
                                                    &IID_IDirectDrawSurface3,
slouken@1662
  1750
                                                    (LPVOID *) & dd_surface3);
slouken@1662
  1751
        IDirectDrawSurface_Release (dd_surface1);
slouken@1662
  1752
        if (result != DD_OK) {
slouken@1662
  1753
            SetDDerror ("DirectDrawSurface::QueryInterface", result);
slouken@1662
  1754
            goto error_end;
slouken@1662
  1755
        }
slouken@1662
  1756
    }
slouken@0
  1757
slouken@1662
  1758
    if ((flag & SDL_HWSURFACE) == SDL_HWSURFACE) {
slouken@1662
  1759
        /* Check to see whether the surface actually ended up
slouken@1662
  1760
           in video memory, and fail if not.  We expect the
slouken@1662
  1761
           surfaces we create here to actually be in hardware!
slouken@1662
  1762
         */
slouken@1662
  1763
        result = IDirectDrawSurface3_GetCaps (dd_surface3, &ddsd.ddsCaps);
slouken@1662
  1764
        if (result != DD_OK) {
slouken@1662
  1765
            SetDDerror ("DirectDrawSurface3::GetCaps", result);
slouken@1662
  1766
            goto error_end;
slouken@1662
  1767
        }
slouken@1662
  1768
        if ((ddsd.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY) !=
slouken@1662
  1769
            DDSCAPS_VIDEOMEMORY) {
slouken@1662
  1770
            SDL_SetError ("No room in video memory");
slouken@1662
  1771
            goto error_end;
slouken@1662
  1772
        }
slouken@1662
  1773
    } else {
slouken@1662
  1774
        /* Try to hook our surface memory */
slouken@1662
  1775
        ddsd.dwFlags = DDSD_LPSURFACE;
slouken@1662
  1776
        ddsd.lpSurface = surface->pixels;
slouken@1662
  1777
        result = IDirectDrawSurface3_SetSurfaceDesc (dd_surface3, &ddsd, 0);
slouken@1662
  1778
        if (result != DD_OK) {
slouken@1662
  1779
            SetDDerror ("DirectDraw2::SetSurfaceDesc", result);
slouken@1662
  1780
            goto error_end;
slouken@1662
  1781
        }
slouken@0
  1782
slouken@1662
  1783
    }
slouken@0
  1784
slouken@1662
  1785
    /* Make sure the surface format was set properly */
slouken@1662
  1786
    SDL_memset (&ddsd, 0, sizeof (ddsd));
slouken@1662
  1787
    ddsd.dwSize = sizeof (ddsd);
slouken@1662
  1788
    result = IDirectDrawSurface3_Lock (dd_surface3, NULL,
slouken@1662
  1789
                                       &ddsd,
slouken@1662
  1790
                                       (DDLOCK_NOSYSLOCK | DDLOCK_WAIT),
slouken@1662
  1791
                                       NULL);
slouken@1662
  1792
    if (result != DD_OK) {
slouken@1662
  1793
        SetDDerror ("DirectDrawSurface3::Lock", result);
slouken@1662
  1794
        goto error_end;
slouken@1662
  1795
    }
slouken@1662
  1796
    IDirectDrawSurface3_Unlock (dd_surface3, NULL);
slouken@1662
  1797
slouken@1662
  1798
    if ((flag & SDL_HWSURFACE) == SDL_SWSURFACE) {
slouken@1662
  1799
        if (ddsd.lpSurface != surface->pixels) {
slouken@1662
  1800
            SDL_SetError ("DDraw didn't use SDL surface memory");
slouken@1662
  1801
            goto error_end;
slouken@1662
  1802
        }
slouken@1662
  1803
        if (
slouken@0
  1804
#if defined(NONAMELESSUNION)
slouken@1662
  1805
               ddsd.u1.lPitch
slouken@0
  1806
#else
slouken@1662
  1807
               ddsd.lPitch
slouken@0
  1808
#endif
slouken@1662
  1809
               != (LONG) surface->pitch) {
slouken@1662
  1810
            SDL_SetError ("DDraw created surface with wrong pitch");
slouken@1662
  1811
            goto error_end;
slouken@1662
  1812
        }
slouken@1662
  1813
    } else {
slouken@0
  1814
#if defined(NONAMELESSUNION)
slouken@1662
  1815
        surface->pitch = (Uint16) ddsd.u1.lPitch;
slouken@0
  1816
#else
slouken@1662
  1817
        surface->pitch = (Uint16) ddsd.lPitch;
slouken@0
  1818
#endif
slouken@1662
  1819
    }
slouken@0
  1820
#if defined(NONAMELESSUNION)
slouken@1662
  1821
    if ((ddsd.ddpfPixelFormat.u1.dwRGBBitCount !=
slouken@1662
  1822
         surface->format->BitsPerPixel) ||
slouken@1662
  1823
        (ddsd.ddpfPixelFormat.u2.dwRBitMask != surface->format->Rmask) ||
slouken@1662
  1824
        (ddsd.ddpfPixelFormat.u3.dwGBitMask != surface->format->Gmask) ||
slouken@1662
  1825
        (ddsd.ddpfPixelFormat.u4.dwBBitMask != surface->format->Bmask)) {
slouken@0
  1826
#else
slouken@1662
  1827
    if ((ddsd.ddpfPixelFormat.dwRGBBitCount !=
slouken@1662
  1828
         surface->format->BitsPerPixel) ||
slouken@1662
  1829
        (ddsd.ddpfPixelFormat.dwRBitMask != surface->format->Rmask) ||
slouken@1662
  1830
        (ddsd.ddpfPixelFormat.dwGBitMask != surface->format->Gmask) ||
slouken@1662
  1831
        (ddsd.ddpfPixelFormat.dwBBitMask != surface->format->Bmask)) {
slouken@0
  1832
#endif
slouken@1662
  1833
        SDL_SetError ("DDraw didn't use SDL surface description");
slouken@1662
  1834
        goto error_end;
slouken@1662
  1835
    }
slouken@1662
  1836
    if ((ddsd.dwWidth != (DWORD) surface->w) ||
slouken@1662
  1837
        (ddsd.dwHeight != (DWORD) surface->h)) {
slouken@1662
  1838
        SDL_SetError ("DDraw created surface with wrong size");
slouken@1662
  1839
        goto error_end;
slouken@1662
  1840
    }
slouken@0
  1841
slouken@1662
  1842
    /* Set the surface private data */
slouken@1662
  1843
    surface->flags |= flag;
slouken@1662
  1844
    surface->hwdata->dd_surface = dd_surface3;
slouken@1662
  1845
    if ((surface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) {
slouken@1662
  1846
        LPDIRECTDRAWSURFACE3 dd_writebuf;
slouken@0
  1847
slouken@1662
  1848
        ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
slouken@1662
  1849
        result = IDirectDrawSurface3_GetAttachedSurface (dd_surface3,
slouken@1662
  1850
                                                         &ddsd.ddsCaps,
slouken@1662
  1851
                                                         &dd_writebuf);
slouken@1662
  1852
        if (result != DD_OK) {
slouken@1662
  1853
            SetDDerror ("DirectDrawSurface3::GetAttachedSurface", result);
slouken@1662
  1854
        } else {
slouken@1662
  1855
            dd_surface3 = dd_writebuf;
slouken@1662
  1856
        }
slouken@1662
  1857
    }
slouken@1662
  1858
    surface->hwdata->dd_writebuf = dd_surface3;
slouken@0
  1859
slouken@1662
  1860
    /* We're ready to go! */
slouken@1662
  1861
    return (0);
slouken@0
  1862
slouken@1662
  1863
    /* Okay, so goto's are cheesy, but there are so many possible
slouken@1662
  1864
       errors in this function, and the cleanup is the same in 
slouken@1662
  1865
       every single case.  Is there a better way, other than deeply
slouken@1662
  1866
       nesting the code?
slouken@1662
  1867
     */
slouken@1662
  1868
  error_end:
slouken@1662
  1869
    if ((dd_surface3 != NULL) && (dd_surface3 != requested)) {
slouken@1662
  1870
        IDirectDrawSurface_Release (dd_surface3);
slouken@1662
  1871
    }
slouken@1662
  1872
    SDL_free (surface->hwdata);
slouken@1662
  1873
    surface->hwdata = NULL;
slouken@1662
  1874
    return (-1);
slouken@0
  1875
}
slouken@0
  1876
slouken@1662
  1877
static int
slouken@1662
  1878
DX5_AllocHWSurface (_THIS, SDL_Surface * surface)
slouken@0
  1879
{
slouken@1662
  1880
    /* DDraw limitation -- you need to set cooperative level first */
slouken@1662
  1881
    if (SDL_primary == NULL) {
slouken@1662
  1882
        SDL_SetError ("You must set a non-GL video mode first");
slouken@1662
  1883
        return (-1);
slouken@1662
  1884
    }
slouken@1662
  1885
    return (DX5_AllocDDSurface (this, surface, NULL, SDL_HWSURFACE));
slouken@0
  1886
}
slouken@0
  1887
slouken@1
  1888
#ifdef DDRAW_DEBUG
slouken@1662
  1889
void
slouken@1662
  1890
PrintSurface (char *title, LPDIRECTDRAWSURFACE3 surface, Uint32 flags)
slouken@0
  1891
{
slouken@1662
  1892
    DDSURFACEDESC ddsd;
slouken@1662
  1893
slouken@1662
  1894
    /* Lock and load! */
slouken@1662
  1895
    SDL_memset (&ddsd, 0, sizeof (ddsd));
slouken@1662
  1896
    ddsd.dwSize = sizeof (ddsd);
slouken@1662
  1897
    if (IDirectDrawSurface3_Lock (surface, NULL, &ddsd,
slouken@1662
  1898
                                  (DDLOCK_NOSYSLOCK | DDLOCK_WAIT),
slouken@1662
  1899
                                  NULL) != DD_OK) {
slouken@1662
  1900
        return;
slouken@1662
  1901
    }
slouken@1662
  1902
    IDirectDrawSurface3_Unlock (surface, NULL);
slouken@0
  1903
slouken@1662
  1904
    fprintf (stderr, "%s:\n", title);
slouken@1662
  1905
    fprintf (stderr, "\tSize: %dx%d in %s at %ld bpp (pitch = %ld)\n",
slouken@1662
  1906
             ddsd.dwWidth, ddsd.dwHeight,
slouken@1662
  1907
             (flags & SDL_HWSURFACE) ? "hardware" : "software",
slouken@0
  1908
#if defined(NONAMELESSUNION)
slouken@1662
  1909
             ddsd.ddpfPixelFormat.u1.dwRGBBitCount, ddsd.u1.lPitch);
slouken@0
  1910
#else
slouken@1662
  1911
             ddsd.ddpfPixelFormat.dwRGBBitCount, ddsd.lPitch);
slouken@0
  1912
#endif
slouken@1662
  1913
    fprintf (stderr, "\tR = 0x%X, G = 0x%X, B = 0x%X\n",
slouken@0
  1914
#if defined(NONAMELESSUNION)
slouken@1662
  1915
             ddsd.ddpfPixelFormat.u2.dwRBitMask,
slouken@1662
  1916
             ddsd.ddpfPixelFormat.u3.dwGBitMask,
slouken@1662
  1917
             ddsd.ddpfPixelFormat.u4.dwBBitMask);
slouken@0
  1918
#else
slouken@1662
  1919
             ddsd.ddpfPixelFormat.dwRBitMask,
slouken@1662
  1920
             ddsd.ddpfPixelFormat.dwGBitMask,
slouken@1662
  1921
             ddsd.ddpfPixelFormat.dwBBitMask);
slouken@0
  1922
#endif
slouken@0
  1923
}
slouken@1
  1924
#endif /* DDRAW_DEBUG */
slouken@0
  1925
slouken@1662
  1926
static int
slouken@1662
  1927
DX5_HWAccelBlit (SDL_Surface * src, SDL_Rect * srcrect,
slouken@1662
  1928
                 SDL_Surface * dst, SDL_Rect * dstrect)
slouken@0
  1929
{
slouken@1662
  1930
    LPDIRECTDRAWSURFACE3 src_surface;
slouken@1662
  1931
    LPDIRECTDRAWSURFACE3 dst_surface;
slouken@1662
  1932
    DWORD flags;
slouken@1662
  1933
    RECT rect;
slouken@1662
  1934
    HRESULT result;
slouken@0
  1935
slouken@1662
  1936
    /* Set it up.. the desination must have a DDRAW surface */
slouken@1662
  1937
    src_surface = src->hwdata->dd_writebuf;
slouken@1662
  1938
    dst_surface = dst->hwdata->dd_writebuf;
slouken@1662
  1939
    rect.top = (LONG) srcrect->y;
slouken@1662
  1940
    rect.bottom = (LONG) srcrect->y + srcrect->h;
slouken@1662
  1941
    rect.left = (LONG) srcrect->x;
slouken@1662
  1942
    rect.right = (LONG) srcrect->x + srcrect->w;
slouken@1662
  1943
    if ((src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY)
slouken@1662
  1944
        flags = DDBLTFAST_SRCCOLORKEY;
slouken@1662
  1945
    else
slouken@1662
  1946
        flags = DDBLTFAST_NOCOLORKEY;
slouken@1662
  1947
    /* FIXME:  We can remove this flag for _really_ fast blit queuing,
slouken@1662
  1948
       but it will affect the return values of locks and flips.
slouken@1662
  1949
     */
slouken@1662
  1950
    flags |= DDBLTFAST_WAIT;
slouken@0
  1951
slouken@1662
  1952
    /* Do the blit! */
slouken@1662
  1953
    result = IDirectDrawSurface3_BltFast (dst_surface,
slouken@1662
  1954
                                          dstrect->x, dstrect->y, src_surface,
slouken@1662
  1955
                                          &rect, flags);
slouken@1662
  1956
    if (result != DD_OK) {
slouken@1662
  1957
        if (result == DDERR_SURFACELOST) {
slouken@1662
  1958
            result = IDirectDrawSurface3_Restore (src_surface);
slouken@1662
  1959
            result = IDirectDrawSurface3_Restore (dst_surface);
slouken@1662
  1960
            /* The surfaces need to be reloaded with artwork */
slouken@1662
  1961
            SDL_SetError ("Blit surfaces were lost, reload them");
slouken@1662
  1962
            return (-2);
slouken@1662
  1963
        }
slouken@1662
  1964
        SetDDerror ("IDirectDrawSurface3::BltFast", result);
slouken@0
  1965
#ifdef DDRAW_DEBUG
slouken@1662
  1966
        fprintf (stderr, "Original dest rect: %dx%d at %d,%d\n", dstrect->w,
slouken@1662
  1967
                 dstrect->h, dstrect->x, dstrect->y);
slouken@1662
  1968
        fprintf (stderr,
slouken@1662
  1969
                 "HW accelerated %sblit to from 0x%p to 0x%p at (%d,%d)\n",
slouken@1662
  1970
                 (src->flags & SDL_SRCCOLORKEY) ? "colorkey " : "", src,
slouken@1662
  1971
                 dst, dstrect->x, dstrect->y);
slouken@1662
  1972
        PrintSurface ("SRC", src_surface, src->flags);
slouken@1662
  1973
        PrintSurface ("DST", dst_surface, dst->flags);
slouken@1662
  1974
        fprintf (stderr, "Source rectangle: (%d,%d) - (%d,%d)\n",
slouken@1662
  1975
                 rect.left, rect.top, rect.right, rect.bottom);
slouken@0
  1976
#endif
slouken@1662
  1977
        /* Unexpected error, fall back to software blit */
slouken@1662
  1978
        return (src->map->sw_blit (src, srcrect, dst, dstrect));
slouken@1662
  1979
    }
slouken@1662
  1980
    return (0);
slouken@0
  1981
}
slouken@0
  1982
slouken@1662
  1983
static int
slouken@1662
  1984
DX5_CheckHWBlit (_THIS, SDL_Surface * src, SDL_Surface * dst)
slouken@0
  1985
{
slouken@1662
  1986
    int accelerated;
slouken@0
  1987
slouken@1662
  1988
    /* We need to have a DDraw surface for HW blits */
slouken@1662
  1989
    if ((src->flags & SDL_HWSURFACE) == SDL_SWSURFACE) {
slouken@1662
  1990
        /* Allocate a DDraw surface for the blit */
slouken@1662
  1991
        if (src->hwdata == NULL) {
slouken@1662
  1992
            DX5_AllocDDSurface (this, src, NULL, SDL_SWSURFACE);
slouken@1662
  1993
        }
slouken@1662
  1994
    }
slouken@1662
  1995
    if (src->hwdata == NULL) {
slouken@1662
  1996
        return (0);
slouken@1662
  1997
    }
slouken@0
  1998
slouken@1662
  1999
    /* Set initial acceleration on */
slouken@1662
  2000
    src->flags |= SDL_HWACCEL;
slouken@0
  2001
slouken@1662
  2002
    /* Set the surface attributes */
slouken@1662
  2003
    if ((src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) {
slouken@1662
  2004
        if (DX5_SetHWColorKey (this, src, src->format->colorkey) < 0) {
slouken@1662
  2005
            src->flags &= ~SDL_HWACCEL;
slouken@1662
  2006
        }
slouken@1662
  2007
    }
slouken@1662
  2008
    if ((src->flags & SDL_SRCALPHA) == SDL_SRCALPHA) {
slouken@1662
  2009
        if (DX5_SetHWAlpha (this, src, src->format->alpha) < 0) {
slouken@1662
  2010
            src->flags &= ~SDL_HWACCEL;
slouken@1662
  2011
        }
slouken@1662
  2012
    }
slouken@0
  2013
slouken@1662
  2014
    /* Check to see if final surface blit is accelerated */
slouken@1662
  2015
    accelerated = !!(src->flags & SDL_HWACCEL);
slouken@1662
  2016
    if (accelerated) {
slouken@0
  2017
#ifdef DDRAW_DEBUG
slouken@1662
  2018
        fprintf (stderr, "Setting accelerated blit on 0x%p\n", src);
slouken@0
  2019
#endif
slouken@1662
  2020
        src->map->hw_blit = DX5_HWAccelBlit;
slouken@1662
  2021
    }
slouken@1662
  2022
    return (accelerated);
slouken@0
  2023
}
slouken@0
  2024
slouken@1662
  2025
static int
slouken@1662
  2026
DX5_FillHWRect (_THIS, SDL_Surface * dst, SDL_Rect * dstrect, Uint32 color)
slouken@0
  2027
{
slouken@1662
  2028
    LPDIRECTDRAWSURFACE3 dst_surface;
slouken@1662
  2029
    RECT area;
slouken@1662
  2030
    DDBLTFX bltfx;
slouken@1662
  2031
    HRESULT result;
slouken@0
  2032
slouken@0
  2033
#ifdef DDRAW_DEBUG
slouken@1662
  2034
    fprintf (stderr, "HW accelerated fill at (%d,%d)\n", dstrect->x,
slouken@1662
  2035
             dstrect->y);
slouken@0
  2036
#endif
slouken@1662
  2037
    dst_surface = dst->hwdata->dd_writebuf;
slouken@1662
  2038
    area.top = (LONG) dstrect->y;
slouken@1662
  2039
    area.bottom = (LONG) dstrect->y + dstrect->h;
slouken@1662
  2040
    area.left = (LONG) dstrect->x;
slouken@1662
  2041
    area.right = (LONG) dstrect->x + dstrect->w;
slouken@1662
  2042
    bltfx.dwSize = sizeof (bltfx);
slouken@0
  2043
#if defined(NONAMELESSUNION)
slouken@1662
  2044
    bltfx.u5.dwFillColor = color;
slouken@0
  2045
#else
slouken@1662
  2046
    bltfx.dwFillColor = color;
slouken@0
  2047
#endif
slouken@1662
  2048
    result = IDirectDrawSurface3_Blt (dst_surface,
slouken@1662
  2049
                                      &area, NULL, NULL,
slouken@1662
  2050
                                      DDBLT_COLORFILL | DDBLT_WAIT, &bltfx);
slouken@1662
  2051
    if (result == DDERR_SURFACELOST) {
slouken@1662
  2052
        IDirectDrawSurface3_Restore (dst_surface);
slouken@1662
  2053
        result = IDirectDrawSurface3_Blt (dst_surface,
slouken@1662
  2054
                                          &area, NULL, NULL,
slouken@1662
  2055
                                          DDBLT_COLORFILL | DDBLT_WAIT,
slouken@1662
  2056
                                          &bltfx);
slouken@1662
  2057
    }
slouken@1662
  2058
    if (result != DD_OK) {
slouken@1662
  2059
        SetDDerror ("IDirectDrawSurface3::Blt", result);
slouken@1662
  2060
        return (-1);
slouken@1662
  2061
    }
slouken@1662
  2062
    return (0);
slouken@0
  2063
}
slouken@0
  2064
slouken@1662
  2065
static int
slouken@1662
  2066
DX5_SetHWColorKey (_THIS, SDL_Surface * surface, Uint32 key)
slouken@0
  2067
{
slouken@1662
  2068
    DDCOLORKEY colorkey;
slouken@1662
  2069
    HRESULT result;
slouken@0
  2070
slouken@1662
  2071
    /* Set the surface colorkey */
slouken@1662
  2072
    colorkey.dwColorSpaceLowValue = key;
slouken@1662
  2073
    colorkey.dwColorSpaceHighValue = key;
slouken@1662
  2074
    result =
slouken@1662
  2075
        IDirectDrawSurface3_SetColorKey (surface->hwdata->dd_surface,
slouken@1662
  2076
                                         DDCKEY_SRCBLT, &colorkey);
slouken@1662
  2077
    if (result != DD_OK) {
slouken@1662
  2078
        SetDDerror ("IDirectDrawSurface3::SetColorKey", result);
slouken@1662
  2079
        return (-1);
slouken@1662
  2080
    }
slouken@1662
  2081
    return (0);
slouken@0
  2082
}
slouken@1662
  2083
static int
slouken@1662
  2084
DX5_SetHWAlpha (_THIS, SDL_Surface * surface, Uint8 alpha)
slouken@0
  2085
{
slouken@1662
  2086
    return (-1);
slouken@0
  2087
}
slouken@0
  2088
slouken@1662
  2089
static int
slouken@1662
  2090
DX5_LockHWSurface (_THIS, SDL_Surface * surface)
slouken@0
  2091
{
slouken@1662
  2092
    HRESULT result;
slouken@1662
  2093
    LPDIRECTDRAWSURFACE3 dd_surface;
slouken@1662
  2094
    DDSURFACEDESC ddsd;
slouken@0
  2095
slouken@1662
  2096
    /* Lock and load! */
slouken@1662
  2097
    dd_surface = surface->hwdata->dd_writebuf;
slouken@1662
  2098
    SDL_memset (&ddsd, 0, sizeof (ddsd));
slouken@1662
  2099
    ddsd.dwSize = sizeof (ddsd);
slouken@1662
  2100
    result = IDirectDrawSurface3_Lock (dd_surface, NULL, &ddsd,
slouken@1662
  2101
                                       (DDLOCK_NOSYSLOCK | DDLOCK_WAIT),
slouken@1662
  2102
                                       NULL);
slouken@1662
  2103
    if (result == DDERR_SURFACELOST) {
slouken@1662
  2104
        result = IDirectDrawSurface3_Restore (surface->hwdata->dd_surface);
slouken@1662
  2105
        result = IDirectDrawSurface3_Lock (dd_surface, NULL, &ddsd,
slouken@1662
  2106
                                           (DDLOCK_NOSYSLOCK | DDLOCK_WAIT),
slouken@1662
  2107
                                           NULL);
slouken@1662
  2108
    }
slouken@1662
  2109
    if (result != DD_OK) {
slouken@1662
  2110
        SetDDerror ("DirectDrawSurface3::Lock", result);
slouken@1662
  2111
        return (-1);
slouken@1662
  2112
    }
slouken@1662
  2113
    /* Pitch might have changed -- recalculate pitch and offset */
slouken@0
  2114
#if defined(NONAMELESSUNION)
slouken@1662
  2115
    if (surface->pitch != ddsd.u1.lPitch) {
slouken@1662
  2116
        surface->pitch = ddsd.u1.lPitch;
slouken@0
  2117
#else
slouken@1662
  2118
    if (surface->pitch != ddsd.lPitch) {
slouken@1662
  2119
        surface->pitch = (Uint16) ddsd.lPitch;
slouken@0
  2120
#endif
slouken@1662
  2121
        surface->offset =
slouken@1662
  2122
            ((ddsd.dwHeight - surface->h) / 2) * surface->pitch +
slouken@1662
  2123
            ((ddsd.dwWidth - surface->w) / 2) *
slouken@1662
  2124
            surface->format->BytesPerPixel;
slouken@1662
  2125
    }
slouken@1662
  2126
    surface->pixels = ddsd.lpSurface;
slouken@1662
  2127
    return (0);
slouken@0
  2128
}
slouken@0
  2129
slouken@1662
  2130
static void
slouken@1662
  2131
DX5_UnlockHWSurface (_THIS, SDL_Surface * surface)
slouken@0
  2132
{
slouken@1662
  2133
    IDirectDrawSurface3_Unlock (surface->hwdata->dd_writebuf, NULL);
slouken@1662
  2134
    surface->pixels = NULL;
slouken@1662
  2135
}
slouken@0
  2136
slouken@1662
  2137
static int
slouken@1662
  2138
DX5_FlipHWSurface (_THIS, SDL_Surface * surface)
slouken@1662
  2139
{
slouken@1662
  2140
    HRESULT result;
slouken@1662
  2141
    LPDIRECTDRAWSURFACE3 dd_surface;
slouken@809
  2142
slouken@1662
  2143
    dd_surface = surface->hwdata->dd_surface;
slouken@809
  2144
slouken@1662
  2145
    /* to prevent big slowdown on fast computers, wait here instead of driver ring 0 code */
slouken@1662
  2146
    /* Dmitry Yakimov (ftech@tula.net) */
slouken@1662
  2147
    while (IDirectDrawSurface3_GetFlipStatus (dd_surface, DDGBS_ISBLTDONE) ==
slouken@1662
  2148
           DDERR_WASSTILLDRAWING);
slouken@1662
  2149
slouken@1662
  2150
    result = IDirectDrawSurface3_Flip (dd_surface, NULL, DDFLIP_WAIT);
slouken@1662
  2151
    if (result == DDERR_SURFACELOST) {
slouken@1662
  2152
        result = IDirectDrawSurface3_Restore (surface->hwdata->dd_surface);
slouken@1662
  2153
        while (IDirectDrawSurface3_GetFlipStatus
slouken@1662
  2154
               (dd_surface, DDGBS_ISBLTDONE) == DDERR_WASSTILLDRAWING);
slouken@1662
  2155
        result = IDirectDrawSurface3_Flip (dd_surface, NULL, DDFLIP_WAIT);
slouken@1662
  2156
    }
slouken@1662
  2157
    if (result != DD_OK) {
slouken@1662
  2158
        SetDDerror ("DirectDrawSurface3::Flip", result);
slouken@1662
  2159
        return (-1);
slouken@1662
  2160
    }
slouken@1662
  2161
    return (0);
slouken@0
  2162
}
slouken@0
  2163
slouken@1662
  2164
static void
slouken@1662
  2165
DX5_FreeHWSurface (_THIS, SDL_Surface * surface)
slouken@0
  2166
{
slouken@1662
  2167
    if (surface->hwdata) {
slouken@1662
  2168
        if (surface->hwdata->dd_surface != SDL_primary) {
slouken@1662
  2169
            IDirectDrawSurface3_Release (surface->hwdata->dd_surface);
slouken@1662
  2170
        }
slouken@1662
  2171
        SDL_free (surface->hwdata);
slouken@1662
  2172
        surface->hwdata = NULL;
slouken@1662
  2173
    }
slouken@0
  2174
}
slouken@0
  2175
slouken@1662
  2176
void
slouken@1662
  2177
DX5_WindowUpdate (_THIS, int numrects, SDL_Rect * rects)
slouken@0
  2178
{
slouken@1662
  2179
    HRESULT result;
slouken@1662
  2180
    int i;
slouken@1662
  2181
    RECT src, dst;
slouken@0
  2182
slouken@1662
  2183
    for (i = 0; i < numrects; ++i) {
slouken@1662
  2184
        src.top = (LONG) rects[i].y;
slouken@1662
  2185
        src.bottom = (LONG) rects[i].y + rects[i].h;
slouken@1662
  2186
        src.left = (LONG) rects[i].x;
slouken@1662
  2187
        src.right = (LONG) rects[i].x + rects[i].w;
slouken@1662
  2188
        dst.top = SDL_bounds.top + src.top;
slouken@1662
  2189
        dst.left = SDL_bounds.left + src.left;
slouken@1662
  2190
        dst.bottom = SDL_bounds.top + src.bottom;
slouken@1662
  2191
        dst.right = SDL_bounds.left + src.right;
slouken@1662
  2192
        result = IDirectDrawSurface3_Blt (SDL_primary, &dst,
slouken@1662
  2193
                                          this->screen->hwdata->dd_surface,
slouken@1662
  2194
                                          &src, DDBLT_WAIT, NULL);
slouken@1662
  2195
        /* Doh!  Check for lost surface and restore it */
slouken@1662
  2196
        if (result == DDERR_SURFACELOST) {
slouken@1662
  2197
            IDirectDrawSurface3_Restore (SDL_primary);
slouken@1662
  2198
            IDirectDrawSurface3_Blt (SDL_primary, &dst,
slouken@1662
  2199
                                     this->screen->hwdata->dd_surface,
slouken@1662
  2200
                                     &src, DDBLT_WAIT, NULL);
slouken@1662
  2201
        }
slouken@1662
  2202
    }
slouken@0
  2203
}
slouken@0
  2204
slouken@1662
  2205
void
slouken@1662
  2206
DX5_DirectUpdate (_THIS, int numrects, SDL_Rect * rects)
slouken@0
  2207
{
slouken@0
  2208
}
slouken@0
  2209
slouken@0
  2210
/* Compress a full palette into the limited number of colors given to us
slouken@0
  2211
   by windows.
slouken@0
  2212
slouken@0
  2213
   The "best" way to do this is to sort the colors by diversity and place
slouken@0
  2214
   the most diverse colors into the limited palette.  Unfortunately this
slouken@0
  2215
   results in widely varying colors being displayed in the interval during
slouken@0
  2216
   which the windows palette has been set, and the mapping of the shadow
slouken@0
  2217
   surface to the new palette.  This is especially noticeable during fades.
slouken@0
  2218
slouken@0
  2219
   To deal with this problem, we can copy a predetermined portion of the
slouken@0
  2220
   full palette, and use that as the limited palette.  This allows colors
slouken@0
  2221
   to fade smoothly as the remapping is very similar on each palette change.
slouken@0
  2222
   Unfortunately, this breaks applications which partition the palette into