src/video/windx5/SDL_dx5video.c
author Sam Lantinga <slouken@libsdl.org>
Mon, 29 May 2006 04:04:35 +0000
branchSDL-1.3
changeset 1668 4da1ee79c9af
parent 1662 782fd950bd46
child 1705 fc731a7d83ed
permissions -rw-r--r--
more tweaking indent options
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@1668
    59
HRESULT(WINAPI * DDrawCreate) (GUID FAR * lpGUID, LPDIRECTDRAW FAR * lplpDD,
slouken@1668
    60
                               IUnknown FAR * pUnkOuter);
slouken@1668
    61
HRESULT(WINAPI * DInputCreate) (HINSTANCE hinst, DWORD dwVersion,
slouken@1668
    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@1668
   409
static int DX5_VideoInit(_THIS, SDL_PixelFormat * vformat);
slouken@1668
   410
static SDL_Rect **DX5_ListModes(_THIS, SDL_PixelFormat * format,
slouken@1668
   411
                                Uint32 flags);
slouken@1668
   412
static SDL_Surface *DX5_SetVideoMode(_THIS, SDL_Surface * current, int width,
slouken@1668
   413
                                     int height, int bpp, Uint32 flags);
slouken@1668
   414
static int DX5_SetColors(_THIS, int firstcolor, int ncolors,
slouken@1668
   415
                         SDL_Color * colors);
slouken@1668
   416
static int DX5_SetGammaRamp(_THIS, Uint16 * ramp);
slouken@1668
   417
static int DX5_GetGammaRamp(_THIS, Uint16 * ramp);
slouken@1668
   418
static void DX5_VideoQuit(_THIS);
slouken@0
   419
slouken@0
   420
/* Hardware surface functions */
slouken@1668
   421
static int DX5_AllocHWSurface(_THIS, SDL_Surface * surface);
slouken@1668
   422
static int DX5_CheckHWBlit(_THIS, SDL_Surface * src, SDL_Surface * dst);
slouken@1668
   423
static int DX5_FillHWRect(_THIS, SDL_Surface * dst, SDL_Rect * dstrect,
slouken@1668
   424
                          Uint32 color);
slouken@1668
   425
static int DX5_SetHWColorKey(_THIS, SDL_Surface * surface, Uint32 key);
slouken@1668
   426
static int DX5_SetHWAlpha(_THIS, SDL_Surface * surface, Uint8 alpha);
slouken@1668
   427
static int DX5_LockHWSurface(_THIS, SDL_Surface * surface);
slouken@1668
   428
static void DX5_UnlockHWSurface(_THIS, SDL_Surface * surface);
slouken@1668
   429
static int DX5_FlipHWSurface(_THIS, SDL_Surface * surface);
slouken@1668
   430
static void DX5_FreeHWSurface(_THIS, SDL_Surface * surface);
slouken@0
   431
slouken@1668
   432
static int DX5_AllocDDSurface(_THIS, SDL_Surface * surface,
slouken@1668
   433
                              LPDIRECTDRAWSURFACE3 requested, Uint32 flag);
slouken@0
   434
slouken@0
   435
/* Windows message handling functions */
slouken@1668
   436
static void DX5_RealizePalette(_THIS);
slouken@1668
   437
static void DX5_PaletteChanged(_THIS, HWND window);
slouken@1668
   438
static void DX5_WinPAINT(_THIS, HDC hdc);
slouken@0
   439
slouken@338
   440
/* WinDIB driver functions for manipulating gamma ramps */
slouken@1668
   441
extern int DIB_SetGammaRamp(_THIS, Uint16 * ramp);
slouken@1668
   442
extern int DIB_GetGammaRamp(_THIS, Uint16 * ramp);
slouken@1668
   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@1668
   451
DX5_Unload(void)
slouken@1661
   452
{
slouken@1662
   453
    if (--DX5_loaded == 0) {
slouken@1662
   454
        if (DDrawDLL != NULL) {
slouken@1668
   455
            FreeLibrary(DDrawDLL);
slouken@1662
   456
            DDrawCreate = NULL;
slouken@1662
   457
            DDrawDLL = NULL;
slouken@1662
   458
        }
slouken@1662
   459
        if (DInputDLL != NULL) {
slouken@1668
   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@1668
   467
DX5_Load(void)
slouken@1661
   468
{
slouken@1662
   469
    int status = 0;
slouken@1661
   470
slouken@1662
   471
    if (++DX5_loaded == 1) {
slouken@1668
   472
        DDrawDLL = LoadLibrary(TEXT("DDRAW.DLL"));
slouken@1662
   473
        if (DDrawDLL != NULL) {
slouken@1668
   474
            DDrawCreate = (void *) GetProcAddress(DDrawDLL,
slouken@1668
   475
                                                  TEXT("DirectDrawCreate"));
slouken@1662
   476
        }
slouken@1668
   477
        DInputDLL = LoadLibrary(TEXT("DINPUT.DLL"));
slouken@1662
   478
        if (DInputDLL != NULL) {
slouken@1668
   479
            DInputCreate = (void *) GetProcAddress(DInputDLL,
slouken@1668
   480
                                                   TEXT
slouken@1668
   481
                                                   ("DirectInputCreateA"));
slouken@1662
   482
        }
slouken@1662
   483
        if (DDrawDLL && DDrawCreate && DInputDLL && DInputCreate) {
slouken@1662
   484
            status = 0;
slouken@1662
   485
        } else {
slouken@1668
   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@1668
   496
DX5_Available(void)
slouken@0
   497
{
slouken@1662
   498
    int ddraw_ok = 0;
slouken@1668
   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@1668
   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@1668
   508
    DDrawCreate = (void *) GetProcAddress(DDrawDLL, TEXT("DirectDrawCreate"));
slouken@1668
   509
    if ((DDrawCreate != NULL) && !FAILED(DDrawCreate(NULL, &DDraw, NULL))) {
slouken@1668
   510
        if (!FAILED(IDirectDraw_SetCooperativeLevel(DDraw,
slouken@1668
   511
                                                    NULL, DDSCL_NORMAL))) {
slouken@1662
   512
            DDSURFACEDESC desc;
slouken@1662
   513
            LPDIRECTDRAWSURFACE DDrawSurf;
slouken@1662
   514
            LPDIRECTDRAWSURFACE3 DDrawSurf3;
slouken@0
   515
slouken@1662
   516
            /* Try to create a DirectDrawSurface3 object */
slouken@1668
   517
            SDL_memset(&desc, 0, sizeof(desc));
slouken@1668
   518
            desc.dwSize = sizeof(desc);
slouken@1662
   519
            desc.dwFlags = DDSD_CAPS;
slouken@1662
   520
            desc.ddsCaps.dwCaps =
slouken@1662
   521
                DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY;
slouken@1662
   522
            if (!FAILED
slouken@1668
   523
                (IDirectDraw_CreateSurface(DDraw, &desc, &DDrawSurf, NULL))) {
slouken@1662
   524
                if (!FAILED
slouken@1662
   525
                    (IDirectDrawSurface_QueryInterface
slouken@1662
   526
                     (DDrawSurf, &IID_IDirectDrawSurface3,
slouken@1662
   527
                      (LPVOID *) & DDrawSurf3))) {
slouken@1662
   528
                    /* Yay! */
slouken@1662
   529
                    ddraw_ok = 1;
slouken@0
   530
slouken@1662
   531
                    /* Clean up.. */
slouken@1668
   532
                    IDirectDrawSurface3_Release(DDrawSurf3);
slouken@1662
   533
                }
slouken@1668
   534
                IDirectDrawSurface_Release(DDrawSurf);
slouken@1662
   535
            }
slouken@1662
   536
        }
slouken@1668
   537
        IDirectDraw_Release(DDraw);
slouken@1662
   538
    }
slouken@0
   539
slouken@1668
   540
    DX5_Unload();
slouken@1661
   541
slouken@1662
   542
    return ddraw_ok;
slouken@0
   543
}
slouken@0
   544
slouken@1662
   545
static void
slouken@1668
   546
DX5_DeleteDevice(SDL_VideoDevice * this)
slouken@0
   547
{
slouken@1662
   548
    /* Free DirectDraw object */
slouken@1662
   549
    if (ddraw2 != NULL) {
slouken@1668
   550
        IDirectDraw2_Release(ddraw2);
slouken@1662
   551
    }
slouken@1668
   552
    DX5_Unload();
slouken@1661
   553
slouken@1662
   554
    if (this) {
slouken@1662
   555
        if (this->hidden) {
slouken@1668
   556
            SDL_free(this->hidden);
slouken@1662
   557
        }
slouken@1662
   558
        if (this->gl_data) {
slouken@1668
   559
            SDL_free(this->gl_data);
slouken@1662
   560
        }
slouken@1668
   561
        SDL_free(this);
slouken@1662
   562
    }
slouken@0
   563
}
slouken@0
   564
slouken@1662
   565
static SDL_VideoDevice *
slouken@1668
   566
DX5_CreateDevice(int devindex)
slouken@0
   567
{
slouken@1662
   568
    SDL_VideoDevice *device;
slouken@0
   569
slouken@1662
   570
    /* Load DirectX */
slouken@1668
   571
    if (DX5_Load() < 0) {
slouken@1662
   572
        return (NULL);
slouken@1662
   573
    }
slouken@0
   574
slouken@1662
   575
    /* Initialize all variables that we clean on shutdown */
slouken@1668
   576
    device = (SDL_VideoDevice *) SDL_malloc(sizeof(SDL_VideoDevice));
slouken@1662
   577
    if (device) {
slouken@1668
   578
        SDL_memset(device, 0, (sizeof *device));
slouken@1662
   579
        device->hidden = (struct SDL_PrivateVideoData *)
slouken@1668
   580
            SDL_malloc((sizeof *device->hidden));
slouken@1662
   581
        device->gl_data = (struct SDL_PrivateGLData *)
slouken@1668
   582
            SDL_malloc((sizeof *device->gl_data));
slouken@1662
   583
    }
slouken@1662
   584
    if ((device == NULL) || (device->hidden == NULL) ||
slouken@1662
   585
        (device->gl_data == NULL)) {
slouken@1668
   586
        SDL_OutOfMemory();
slouken@1668
   587
        DX5_DeleteDevice(device);
slouken@1662
   588
        return (NULL);
slouken@1662
   589
    }
slouken@1668
   590
    SDL_memset(device->hidden, 0, (sizeof *device->hidden));
slouken@1668
   591
    SDL_memset(device->gl_data, 0, (sizeof *device->gl_data));
slouken@0
   592
slouken@1662
   593
    /* Set the function pointers */
slouken@1662
   594
    device->VideoInit = DX5_VideoInit;
slouken@1662
   595
    device->ListModes = DX5_ListModes;
slouken@1662
   596
    device->SetVideoMode = DX5_SetVideoMode;
slouken@1662
   597
    device->UpdateMouse = WIN_UpdateMouse;
slouken@1662
   598
    device->CreateYUVOverlay = DX5_CreateYUVOverlay;
slouken@1662
   599
    device->SetColors = DX5_SetColors;
slouken@1662
   600
    device->UpdateRects = NULL;
slouken@1662
   601
    device->VideoQuit = DX5_VideoQuit;
slouken@1662
   602
    device->AllocHWSurface = DX5_AllocHWSurface;
slouken@1662
   603
    device->CheckHWBlit = DX5_CheckHWBlit;
slouken@1662
   604
    device->FillHWRect = DX5_FillHWRect;
slouken@1662
   605
    device->SetHWColorKey = DX5_SetHWColorKey;
slouken@1662
   606
    device->SetHWAlpha = DX5_SetHWAlpha;
slouken@1662
   607
    device->LockHWSurface = DX5_LockHWSurface;
slouken@1662
   608
    device->UnlockHWSurface = DX5_UnlockHWSurface;
slouken@1662
   609
    device->FlipHWSurface = DX5_FlipHWSurface;
slouken@1662
   610
    device->FreeHWSurface = DX5_FreeHWSurface;
slouken@1662
   611
    device->SetGammaRamp = DX5_SetGammaRamp;
slouken@1662
   612
    device->GetGammaRamp = DX5_GetGammaRamp;
slouken@1361
   613
#if SDL_VIDEO_OPENGL
slouken@1662
   614
    device->GL_LoadLibrary = WIN_GL_LoadLibrary;
slouken@1662
   615
    device->GL_GetProcAddress = WIN_GL_GetProcAddress;
slouken@1662
   616
    device->GL_GetAttribute = WIN_GL_GetAttribute;
slouken@1662
   617
    device->GL_MakeCurrent = WIN_GL_MakeCurrent;
slouken@1662
   618
    device->GL_SwapBuffers = WIN_GL_SwapBuffers;
slouken@0
   619
#endif
slouken@1662
   620
    device->SetCaption = WIN_SetWMCaption;
slouken@1662
   621
    device->SetIcon = WIN_SetWMIcon;
slouken@1662
   622
    device->IconifyWindow = WIN_IconifyWindow;
slouken@1662
   623
    device->GrabInput = WIN_GrabInput;
slouken@1662
   624
    device->GetWMInfo = WIN_GetWMInfo;
slouken@1662
   625
    device->FreeWMCursor = WIN_FreeWMCursor;
slouken@1662
   626
    device->CreateWMCursor = WIN_CreateWMCursor;
slouken@1662
   627
    device->ShowWMCursor = WIN_ShowWMCursor;
slouken@1662
   628
    device->WarpWMCursor = WIN_WarpWMCursor;
slouken@1662
   629
    device->CheckMouseMode = WIN_CheckMouseMode;
slouken@1662
   630
    device->InitOSKeymap = DX5_InitOSKeymap;
slouken@1662
   631
    device->PumpEvents = DX5_PumpEvents;
slouken@0
   632
slouken@1662
   633
    /* Set up the windows message handling functions */
slouken@1662
   634
    WIN_RealizePalette = DX5_RealizePalette;
slouken@1662
   635
    WIN_PaletteChanged = DX5_PaletteChanged;
slouken@1662
   636
    WIN_WinPAINT = DX5_WinPAINT;
slouken@1662
   637
    HandleMessage = DX5_HandleMessage;
slouken@0
   638
slouken@1662
   639
    device->free = DX5_DeleteDevice;
slouken@0
   640
slouken@1662
   641
    /* We're finally ready */
slouken@1662
   642
    return device;
slouken@0
   643
}
slouken@0
   644
slouken@0
   645
VideoBootStrap DIRECTX_bootstrap = {
slouken@1662
   646
    "directx", "Win95/98/2000 DirectX",
slouken@1662
   647
    DX5_Available, DX5_CreateDevice
slouken@0
   648
};
slouken@0
   649
slouken@1662
   650
static int
slouken@1668
   651
cmpmodes(const void *va, const void *vb)
slouken@1659
   652
{
slouken@1662
   653
    SDL_Rect *a = *(SDL_Rect **) va;
slouken@1662
   654
    SDL_Rect *b = *(SDL_Rect **) vb;
slouken@1662
   655
    if (a->w == b->w)
slouken@1659
   656
        return b->h - a->h;
slouken@1659
   657
    else
slouken@1659
   658
        return b->w - a->w;
slouken@1659
   659
}
slouken@1659
   660
slouken@1662
   661
static HRESULT WINAPI
slouken@1668
   662
EnumModes2(DDSURFACEDESC * desc, VOID * udata)
slouken@0
   663
{
slouken@1662
   664
    SDL_VideoDevice *this = (SDL_VideoDevice *) udata;
slouken@1662
   665
    struct DX5EnumRect *enumrect;
slouken@0
   666
#if defined(NONAMELESSUNION)
slouken@1662
   667
    int bpp = desc->ddpfPixelFormat.u1.dwRGBBitCount;
slouken@1662
   668
    int refreshRate = desc->u2.dwRefreshRate;
slouken@0
   669
#else
slouken@1662
   670
    int bpp = desc->ddpfPixelFormat.dwRGBBitCount;
slouken@1662
   671
    int refreshRate = desc->dwRefreshRate;
slouken@0
   672
#endif
slouken@1662
   673
    int maxRefreshRate;
slouken@1295
   674
slouken@1662
   675
    if (desc->dwWidth <= SDL_desktop_mode.dmPelsWidth &&
slouken@1662
   676
        desc->dwHeight <= SDL_desktop_mode.dmPelsHeight) {
slouken@1662
   677
        maxRefreshRate = SDL_desktop_mode.dmDisplayFrequency;
slouken@1662
   678
    } else {
slouken@1662
   679
        maxRefreshRate = 85;    /* safe value? */
slouken@1662
   680
    }
slouken@0
   681
slouken@1662
   682
    switch (bpp) {
slouken@1662
   683
    case 8:
slouken@1662
   684
    case 16:
slouken@1662
   685
    case 24:
slouken@1662
   686
    case 32:
slouken@1662
   687
        bpp /= 8;
slouken@1662
   688
        --bpp;
slouken@1662
   689
        if (enumlists[bpp] &&
slouken@1662
   690
            enumlists[bpp]->r.w == (Uint16) desc->dwWidth &&
slouken@1662
   691
            enumlists[bpp]->r.h == (Uint16) desc->dwHeight) {
slouken@1662
   692
            if (refreshRate > enumlists[bpp]->refreshRate &&
slouken@1662
   693
                refreshRate <= maxRefreshRate) {
slouken@1662
   694
                enumlists[bpp]->refreshRate = refreshRate;
slouken@815
   695
#ifdef DDRAW_DEBUG
slouken@1668
   696
                fprintf(stderr,
slouken@1668
   697
                        "New refresh rate for %d bpp: %dx%d at %d Hz\n",
slouken@1668
   698
                        (bpp + 1) * 8, (int) desc->dwWidth,
slouken@1668
   699
                        (int) desc->dwHeight, refreshRate);
slouken@815
   700
#endif
slouken@1662
   701
            }
slouken@1662
   702
            break;
slouken@1662
   703
        }
slouken@1662
   704
        ++SDL_nummodes[bpp];
slouken@1662
   705
        enumrect =
slouken@1668
   706
            (struct DX5EnumRect *) SDL_malloc(sizeof(struct DX5EnumRect));
slouken@1662
   707
        if (!enumrect) {
slouken@1668
   708
            SDL_OutOfMemory();
slouken@1662
   709
            return (DDENUMRET_CANCEL);
slouken@1662
   710
        }
slouken@1662
   711
        enumrect->refreshRate = refreshRate;
slouken@1662
   712
        enumrect->r.x = 0;
slouken@1662
   713
        enumrect->r.y = 0;
slouken@1662
   714
        enumrect->r.w = (Uint16) desc->dwWidth;
slouken@1662
   715
        enumrect->r.h = (Uint16) desc->dwHeight;
slouken@1662
   716
        enumrect->next = enumlists[bpp];
slouken@1662
   717
        enumlists[bpp] = enumrect;
slouken@815
   718
#ifdef DDRAW_DEBUG
slouken@1668
   719
        fprintf(stderr, "New mode for %d bpp: %dx%d at %d Hz\n",
slouken@1668
   720
                (bpp + 1) * 8, (int) desc->dwWidth, (int) desc->dwHeight,
slouken@1668
   721
                refreshRate);
slouken@815
   722
#endif
slouken@1662
   723
        break;
slouken@1662
   724
    }
slouken@0
   725
slouken@1662
   726
    return (DDENUMRET_OK);
slouken@0
   727
}
slouken@0
   728
slouken@1662
   729
void
slouken@1668
   730
SetDDerror(const char *function, int code)
slouken@0
   731
{
slouken@1662
   732
    static char *error;
slouken@1662
   733
    static char errbuf[1024];
slouken@0
   734
slouken@1662
   735
    errbuf[0] = 0;
slouken@1662
   736
    switch (code) {
slouken@1662
   737
    case DDERR_GENERIC:
slouken@1662
   738
        error = "Undefined error!";
slouken@1662
   739
        break;
slouken@1662
   740
    case DDERR_EXCEPTION:
slouken@1662
   741
        error = "Exception encountered";
slouken@1662
   742
        break;
slouken@1662
   743
    case DDERR_INVALIDOBJECT:
slouken@1662
   744
        error = "Invalid object";
slouken@1662
   745
        break;
slouken@1662
   746
    case DDERR_INVALIDPARAMS:
slouken@1662
   747
        error = "Invalid parameters";
slouken@1662
   748
        break;
slouken@1662
   749
    case DDERR_NOTFOUND:
slouken@1662
   750
        error = "Object not found";
slouken@1662
   751
        break;
slouken@1662
   752
    case DDERR_INVALIDRECT:
slouken@1662
   753
        error = "Invalid rectangle";
slouken@1662
   754
        break;
slouken@1662
   755
    case DDERR_INVALIDCAPS:
slouken@1662
   756
        error = "Invalid caps member";
slouken@1662
   757
        break;
slouken@1662
   758
    case DDERR_INVALIDPIXELFORMAT:
slouken@1662
   759
        error = "Invalid pixel format";
slouken@1662
   760
        break;
slouken@1662
   761
    case DDERR_OUTOFMEMORY:
slouken@1662
   762
        error = "Out of memory";
slouken@1662
   763
        break;
slouken@1662
   764
    case DDERR_OUTOFVIDEOMEMORY:
slouken@1662
   765
        error = "Out of video memory";
slouken@1662
   766
        break;
slouken@1662
   767
    case DDERR_SURFACEBUSY:
slouken@1662
   768
        error = "Surface busy";
slouken@1662
   769
        break;
slouken@1662
   770
    case DDERR_SURFACELOST:
slouken@1662
   771
        error = "Surface was lost";
slouken@1662
   772
        break;
slouken@1662
   773
    case DDERR_WASSTILLDRAWING:
slouken@1662
   774
        error = "DirectDraw is still drawing";
slouken@1662
   775
        break;
slouken@1662
   776
    case DDERR_INVALIDSURFACETYPE:
slouken@1662
   777
        error = "Invalid surface type";
slouken@1662
   778
        break;
slouken@1662
   779
    case DDERR_NOEXCLUSIVEMODE:
slouken@1662
   780
        error = "Not in exclusive access mode";
slouken@1662
   781
        break;
slouken@1662
   782
    case DDERR_NOPALETTEATTACHED:
slouken@1662
   783
        error = "No palette attached";
slouken@1662
   784
        break;
slouken@1662
   785
    case DDERR_NOPALETTEHW:
slouken@1662
   786
        error = "No palette hardware";
slouken@1662
   787
        break;
slouken@1662
   788
    case DDERR_NOT8BITCOLOR:
slouken@1662
   789
        error = "Not 8-bit color";
slouken@1662
   790
        break;
slouken@1662
   791
    case DDERR_EXCLUSIVEMODEALREADYSET:
slouken@1662
   792
        error = "Exclusive mode was already set";
slouken@1662
   793
        break;
slouken@1662
   794
    case DDERR_HWNDALREADYSET:
slouken@1662
   795
        error = "Window handle already set";
slouken@1662
   796
        break;
slouken@1662
   797
    case DDERR_HWNDSUBCLASSED:
slouken@1662
   798
        error = "Window handle is subclassed";
slouken@1662
   799
        break;
slouken@1662
   800
    case DDERR_NOBLTHW:
slouken@1662
   801
        error = "No blit hardware";
slouken@1662
   802
        break;
slouken@1662
   803
    case DDERR_IMPLICITLYCREATED:
slouken@1662
   804
        error = "Surface was implicitly created";
slouken@1662
   805
        break;
slouken@1662
   806
    case DDERR_INCOMPATIBLEPRIMARY:
slouken@1662
   807
        error = "Incompatible primary surface";
slouken@1662
   808
        break;
slouken@1662
   809
    case DDERR_NOCOOPERATIVELEVELSET:
slouken@1662
   810
        error = "No cooperative level set";
slouken@1662
   811
        break;
slouken@1662
   812
    case DDERR_NODIRECTDRAWHW:
slouken@1662
   813
        error = "No DirectDraw hardware";
slouken@1662
   814
        break;
slouken@1662
   815
    case DDERR_NOEMULATION:
slouken@1662
   816
        error = "No emulation available";
slouken@1662
   817
        break;
slouken@1662
   818
    case DDERR_NOFLIPHW:
slouken@1662
   819
        error = "No flip hardware";
slouken@1662
   820
        break;
slouken@1662
   821
    case DDERR_NOTFLIPPABLE:
slouken@1662
   822
        error = "Surface not flippable";
slouken@1662
   823
        break;
slouken@1662
   824
    case DDERR_PRIMARYSURFACEALREADYEXISTS:
slouken@1662
   825
        error = "Primary surface already exists";
slouken@1662
   826
        break;
slouken@1662
   827
    case DDERR_UNSUPPORTEDMODE:
slouken@1662
   828
        error = "Unsupported mode";
slouken@1662
   829
        break;
slouken@1662
   830
    case DDERR_WRONGMODE:
slouken@1662
   831
        error = "Surface created in different mode";
slouken@1662
   832
        break;
slouken@1662
   833
    case DDERR_UNSUPPORTED:
slouken@1662
   834
        error = "Operation not supported";
slouken@1662
   835
        break;
slouken@1662
   836
    case E_NOINTERFACE:
slouken@1662
   837
        error = "Interface not present";
slouken@1662
   838
        break;
slouken@1662
   839
    default:
slouken@1668
   840
        SDL_snprintf(errbuf, SDL_arraysize(errbuf),
slouken@1668
   841
                     "%s: Unknown DirectDraw error: 0x%x", function, code);
slouken@1662
   842
        break;
slouken@1662
   843
    }
slouken@1662
   844
    if (!errbuf[0]) {
slouken@1668
   845
        SDL_snprintf(errbuf, SDL_arraysize(errbuf), "%s: %s", function,
slouken@1668
   846
                     error);
slouken@1662
   847
    }
slouken@1668
   848
    SDL_SetError("%s", errbuf);
slouken@1662
   849
    return;
slouken@0
   850
}
slouken@0
   851
slouken@0
   852
slouken@1662
   853
static int
slouken@1668
   854
DX5_UpdateVideoInfo(_THIS)
slouken@0
   855
{
slouken@1662
   856
    /* This needs to be DDCAPS_DX5 for the DirectDraw2 interface */
slouken@0
   857
#if DIRECTDRAW_VERSION <= 0x300
slouken@0
   858
#error Your version of DirectX must be greater than or equal to 5.0
slouken@0
   859
#endif
slouken@334
   860
#ifndef IDirectDrawGammaControl_SetGammaRamp
slouken@1662
   861
    /*if gamma is undefined then we really have directx <= 0x500 */
slouken@1662
   862
    DDCAPS DDCaps;
slouken@0
   863
#else
slouken@1662
   864
    DDCAPS_DX5 DDCaps;
slouken@0
   865
#endif
slouken@1662
   866
    HRESULT result;
slouken@0
   867
slouken@1662
   868
    /* Fill in our hardware acceleration capabilities */
slouken@1668
   869
    SDL_memset(&DDCaps, 0, sizeof(DDCaps));
slouken@1668
   870
    DDCaps.dwSize = sizeof(DDCaps);
slouken@1668
   871
    result = IDirectDraw2_GetCaps(ddraw2, (DDCAPS *) & DDCaps, NULL);
slouken@1662
   872
    if (result != DD_OK) {
slouken@1668
   873
        SetDDerror("DirectDraw2::GetCaps", result);
slouken@1662
   874
        return (-1);
slouken@1662
   875
    }
slouken@1662
   876
    this->info.hw_available = 1;
slouken@1662
   877
    if ((DDCaps.dwCaps & DDCAPS_BLT) == DDCAPS_BLT) {
slouken@1662
   878
        this->info.blit_hw = 1;
slouken@1662
   879
    }
slouken@1662
   880
    if (((DDCaps.dwCaps & DDCAPS_COLORKEY) == DDCAPS_COLORKEY) &&
slouken@1662
   881
        ((DDCaps.dwCKeyCaps & DDCKEYCAPS_SRCBLT) == DDCKEYCAPS_SRCBLT)) {
slouken@1662
   882
        this->info.blit_hw_CC = 1;
slouken@1662
   883
    }
slouken@1662
   884
    if ((DDCaps.dwCaps & DDCAPS_ALPHA) == DDCAPS_ALPHA) {
slouken@1662
   885
        /* This is only for alpha channel, and DirectX 6
slouken@1662
   886
           doesn't support 2D alpha blits yet, so set it 0
slouken@1662
   887
         */
slouken@1662
   888
        this->info.blit_hw_A = 0;
slouken@1662
   889
    }
slouken@1662
   890
    if ((DDCaps.dwCaps & DDCAPS_CANBLTSYSMEM) == DDCAPS_CANBLTSYSMEM) {
slouken@1662
   891
        this->info.blit_sw = 1;
slouken@1662
   892
        /* This isn't necessarily true, but the HEL will cover us */
slouken@1662
   893
        this->info.blit_sw_CC = this->info.blit_hw_CC;
slouken@1662
   894
        this->info.blit_sw_A = this->info.blit_hw_A;
slouken@1662
   895
    }
slouken@1662
   896
    if ((DDCaps.dwCaps & DDCAPS_BLTCOLORFILL) == DDCAPS_BLTCOLORFILL) {
slouken@1662
   897
        this->info.blit_fill = 1;
slouken@1662
   898
    }
slouken@0
   899
slouken@1662
   900
    /* Find out how much video memory is available */
slouken@1662
   901
    {
slouken@1662
   902
        DDSCAPS ddsCaps;
slouken@1662
   903
        DWORD total_mem;
slouken@1662
   904
        ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY;
slouken@1668
   905
        result = IDirectDraw2_GetAvailableVidMem(ddraw2,
slouken@1668
   906
                                                 &ddsCaps, &total_mem, NULL);
slouken@1662
   907
        if (result != DD_OK) {
slouken@1662
   908
            total_mem = DDCaps.dwVidMemTotal;
slouken@1662
   909
        }
slouken@1662
   910
        this->info.video_mem = total_mem / 1024;
slouken@1662
   911
    }
slouken@1662
   912
    return (0);
slouken@0
   913
}
slouken@0
   914
slouken@1662
   915
int
slouken@1668
   916
DX5_VideoInit(_THIS, SDL_PixelFormat * vformat)
slouken@0
   917
{
slouken@1662
   918
    HRESULT result;
slouken@1662
   919
    LPDIRECTDRAW ddraw;
slouken@1662
   920
    int i, j;
slouken@1662
   921
    HDC hdc;
slouken@0
   922
slouken@1662
   923
    /* Intialize everything */
slouken@1662
   924
    ddraw2 = NULL;
slouken@1662
   925
    SDL_primary = NULL;
slouken@1662
   926
    SDL_clipper = NULL;
slouken@1662
   927
    SDL_palette = NULL;
slouken@1662
   928
    for (i = 0; i < NUM_MODELISTS; ++i) {
slouken@1662
   929
        SDL_nummodes[i] = 0;
slouken@1662
   930
        SDL_modelist[i] = NULL;
slouken@1662
   931
        SDL_modeindex[i] = 0;
slouken@1662
   932
    }
slouken@1662
   933
    colorchange_expected = 0;
slouken@0
   934
slouken@1662
   935
    /* Create the window */
slouken@1668
   936
    if (DX5_CreateWindow(this) < 0) {
slouken@1662
   937
        return (-1);
slouken@1662
   938
    }
slouken@1361
   939
#if !SDL_AUDIO_DISABLED
slouken@1668
   940
    DX5_SoundFocus(SDL_Window);
slouken@169
   941
#endif
slouken@0
   942
slouken@1662
   943
    /* Create the DirectDraw object */
slouken@1668
   944
    result = DDrawCreate(NULL, &ddraw, NULL);
slouken@1662
   945
    if (result != DD_OK) {
slouken@1668
   946
        SetDDerror("DirectDrawCreate", result);
slouken@1662
   947
        return (-1);
slouken@1662
   948
    }
slouken@1668
   949
    result = IDirectDraw_QueryInterface(ddraw, &IID_IDirectDraw2,
slouken@1668
   950
                                        (LPVOID *) & ddraw2);
slouken@1668
   951
    IDirectDraw_Release(ddraw);
slouken@1662
   952
    if (result != DD_OK) {
slouken@1668
   953
        SetDDerror("DirectDraw::QueryInterface", result);
slouken@1662
   954
        return (-1);
slouken@1662
   955
    }
slouken@0
   956
slouken@1662
   957
    /* Determine the screen depth */
slouken@1668
   958
    hdc = GetDC(SDL_Window);
slouken@1668
   959
    vformat->BitsPerPixel = GetDeviceCaps(hdc, PLANES) *
slouken@1668
   960
        GetDeviceCaps(hdc, BITSPIXEL);
slouken@1668
   961
    ReleaseDC(SDL_Window, hdc);
slouken@0
   962
slouken@1295
   963
#ifndef NO_CHANGEDISPLAYSETTINGS
slouken@1662
   964
    /* Query for the desktop resolution */
slouken@1668
   965
    EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &SDL_desktop_mode);
slouken@1662
   966
    this->info.current_w = SDL_desktop_mode.dmPelsWidth;
slouken@1662
   967
    this->info.current_h = SDL_desktop_mode.dmPelsHeight;
slouken@1295
   968
#endif
slouken@1295
   969
slouken@1662
   970
    /* Enumerate the available fullscreen modes */
slouken@1662
   971
    for (i = 0; i < NUM_MODELISTS; ++i)
slouken@1662
   972
        enumlists[i] = NULL;
slouken@0
   973
slouken@1662
   974
    result =
slouken@1668
   975
        IDirectDraw2_EnumDisplayModes(ddraw2, DDEDM_REFRESHRATES, NULL, this,
slouken@1668
   976
                                      EnumModes2);
slouken@1662
   977
    if (result != DD_OK) {
slouken@1668
   978
        SetDDerror("DirectDraw2::EnumDisplayModes", result);
slouken@1662
   979
        return (-1);
slouken@1662
   980
    }
slouken@1662
   981
    for (i = 0; i < NUM_MODELISTS; ++i) {
slouken@1662
   982
        struct DX5EnumRect *rect;
slouken@1662
   983
        SDL_modelist[i] = (SDL_Rect **)
slouken@1668
   984
            SDL_malloc((SDL_nummodes[i] + 1) * sizeof(SDL_Rect *));
slouken@1662
   985
        if (SDL_modelist[i] == NULL) {
slouken@1668
   986
            SDL_OutOfMemory();
slouken@1662
   987
            return (-1);
slouken@1662
   988
        }
slouken@1662
   989
        for (j = 0, rect = enumlists[i]; rect; ++j, rect = rect->next) {
slouken@1662
   990
            SDL_modelist[i][j] = &rect->r;
slouken@1662
   991
        }
slouken@1662
   992
        SDL_modelist[i][j] = NULL;
slouken@1659
   993
slouken@1662
   994
        if (SDL_nummodes[i] > 0) {
slouken@1668
   995
            SDL_qsort(SDL_modelist[i], SDL_nummodes[i],
slouken@1668
   996
                      sizeof *SDL_modelist[i], cmpmodes);
slouken@1662
   997
        }
slouken@1662
   998
    }
slouken@0
   999
slouken@1662
  1000
    /* Fill in some window manager capabilities */
slouken@1662
  1001
    this->info.wm_available = 1;
slouken@0
  1002
slouken@1662
  1003
    /* Fill in the video hardware capabilities */
slouken@1668
  1004
    DX5_UpdateVideoInfo(this);
slouken@1662
  1005
slouken@1662
  1006
    return (0);
slouken@0
  1007
}
slouken@0
  1008
slouken@1662
  1009
SDL_Rect **
slouken@1668
  1010
DX5_ListModes(_THIS, SDL_PixelFormat * format, Uint32 flags)
slouken@0
  1011
{
slouken@1662
  1012
    int bpp;
slouken@0
  1013
slouken@1662
  1014
    bpp = format->BitsPerPixel;
slouken@1662
  1015
    if ((flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) {
slouken@1662
  1016
        /* FIXME:  No support for 1 bpp or 4 bpp formats */
slouken@1662
  1017
        switch (bpp) {          /* Does windows support other BPP? */
slouken@1662
  1018
        case 8:
slouken@1662
  1019
        case 16:
slouken@1662
  1020
        case 24:
slouken@1662
  1021
        case 32:
slouken@1662
  1022
            bpp = (bpp / 8) - 1;
slouken@1662
  1023
            if (SDL_nummodes[bpp] > 0)
slouken@1662
  1024
                return (SDL_modelist[bpp]);
slouken@1662
  1025
            /* Fall through */
slouken@1662
  1026
        default:
slouken@1662
  1027
            return ((SDL_Rect **) 0);
slouken@1662
  1028
        }
slouken@1662
  1029
    } else {
slouken@1662
  1030
        if (this->screen->format->BitsPerPixel == bpp) {
slouken@1662
  1031
            return ((SDL_Rect **) - 1);
slouken@1662
  1032
        } else {
slouken@1662
  1033
            return ((SDL_Rect **) 0);
slouken@1662
  1034
        }
slouken@1662
  1035
    }
slouken@0
  1036
}
slouken@0
  1037
slouken@0
  1038
/* Various screen update functions available */
slouken@1668
  1039
static void DX5_WindowUpdate(_THIS, int numrects, SDL_Rect * rects);
slouken@1668
  1040
static void DX5_DirectUpdate(_THIS, int numrects, SDL_Rect * rects);
slouken@0
  1041
slouken@1662
  1042
SDL_Surface *
slouken@1668
  1043
DX5_SetVideoMode(_THIS, SDL_Surface * current,
slouken@1668
  1044
                 int width, int height, int bpp, Uint32 flags)
slouken@0
  1045
{
slouken@1662
  1046
    SDL_Surface *video;
slouken@1662
  1047
    HRESULT result;
slouken@1662
  1048
    DWORD sharemode;
slouken@1662
  1049
    DWORD style;
slouken@1662
  1050
    const DWORD directstyle = (WS_POPUP);
slouken@1662
  1051
    const DWORD windowstyle =
slouken@1662
  1052
        (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX);
slouken@1662
  1053
    const DWORD resizestyle = (WS_THICKFRAME | WS_MAXIMIZEBOX);
slouken@1662
  1054
    DDSURFACEDESC ddsd;
slouken@1662
  1055
    LPDIRECTDRAWSURFACE dd_surface1;
slouken@1662
  1056
    LPDIRECTDRAWSURFACE3 dd_surface3;
slouken@0
  1057
slouken@1662
  1058
    SDL_resizing = 1;
slouken@0
  1059
#ifdef DDRAW_DEBUG
slouken@1668
  1060
    fprintf(stderr, "Setting %dx%dx%d video mode\n", width, height, bpp);
slouken@0
  1061
#endif
slouken@1662
  1062
    /* Clean up any previous DirectDraw surfaces */
slouken@1662
  1063
    if (current->hwdata) {
slouken@1668
  1064
        this->FreeHWSurface(this, current);
slouken@1662
  1065
        current->hwdata = NULL;
slouken@1662
  1066
    }
slouken@1662
  1067
    if (SDL_primary != NULL) {
slouken@1668
  1068
        IDirectDrawSurface3_Release(SDL_primary);
slouken@1662
  1069
        SDL_primary = NULL;
slouken@1662
  1070
    }
slouken@453
  1071
#ifndef NO_CHANGEDISPLAYSETTINGS
slouken@1662
  1072
    /* Unset any previous OpenGL fullscreen mode */
slouken@1662
  1073
    if ((current->flags & (SDL_INTERNALOPENGL | SDL_FULLSCREEN)) ==
slouken@1662
  1074
        (SDL_INTERNALOPENGL | SDL_FULLSCREEN)) {
slouken@1668
  1075
        ChangeDisplaySettings(NULL, 0);
slouken@1662
  1076
    }
slouken@453
  1077
#endif
slouken@0
  1078
slouken@1662
  1079
    /* Clean up any GL context that may be hanging around */
slouken@1662
  1080
    if (current->flags & SDL_INTERNALOPENGL) {
slouken@1668
  1081
        WIN_GL_ShutDown(this);
slouken@1662
  1082
    }
slouken@0
  1083
slouken@1662
  1084
    /* If we are setting a GL mode, use GDI, not DirectX (yuck) */
slouken@1662
  1085
    if (flags & SDL_INTERNALOPENGL) {
slouken@1662
  1086
        Uint32 Rmask, Gmask, Bmask;
slouken@0
  1087
slouken@1662
  1088
        /* Recalculate the bitmasks if necessary */
slouken@1662
  1089
        if (bpp == current->format->BitsPerPixel) {
slouken@1662
  1090
            video = current;
slouken@1662
  1091
        } else {
slouken@1662
  1092
            switch (bpp) {
slouken@1662
  1093
            case 15:
slouken@1662
  1094
            case 16:
slouken@1662
  1095
                if (0 /*DIB_SussScreenDepth() == 15 */ ) {
slouken@1662
  1096
                    /* 5-5-5 */
slouken@1662
  1097
                    Rmask = 0x00007c00;
slouken@1662
  1098
                    Gmask = 0x000003e0;
slouken@1662
  1099
                    Bmask = 0x0000001f;
slouken@1662
  1100
                } else {
slouken@1662
  1101
                    /* 5-6-5 */
slouken@1662
  1102
                    Rmask = 0x0000f800;
slouken@1662
  1103
                    Gmask = 0x000007e0;
slouken@1662
  1104
                    Bmask = 0x0000001f;
slouken@1662
  1105
                }
slouken@1662
  1106
                break;
slouken@1662
  1107
            case 24:
slouken@1662
  1108
            case 32:
slouken@1662
  1109
                /* GDI defined as 8-8-8 */
slouken@1662
  1110
                Rmask = 0x00ff0000;
slouken@1662
  1111
                Gmask = 0x0000ff00;
slouken@1662
  1112
                Bmask = 0x000000ff;
slouken@1662
  1113
                break;
slouken@1662
  1114
            default:
slouken@1662
  1115
                Rmask = 0x00000000;
slouken@1662
  1116
                Gmask = 0x00000000;
slouken@1662
  1117
                Bmask = 0x00000000;
slouken@1662
  1118
                break;
slouken@1662
  1119
            }
slouken@1668
  1120
            video = SDL_CreateRGBSurface(SDL_SWSURFACE, 0, 0, bpp,
slouken@1668
  1121
                                         Rmask, Gmask, Bmask, 0);
slouken@1662
  1122
            if (video == NULL) {
slouken@1668
  1123
                SDL_OutOfMemory();
slouken@1662
  1124
                return (NULL);
slouken@1662
  1125
            }
slouken@1662
  1126
        }
slouken@0
  1127
slouken@1662
  1128
        /* Fill in part of the video surface */
slouken@1662
  1129
        video->flags = 0;       /* Clear flags */
slouken@1662
  1130
        video->w = width;
slouken@1662
  1131
        video->h = height;
slouken@1668
  1132
        video->pitch = SDL_CalculatePitch(video);
slouken@0
  1133
slouken@453
  1134
#ifndef NO_CHANGEDISPLAYSETTINGS
slouken@1662
  1135
        /* Set fullscreen mode if appropriate.
slouken@1662
  1136
           Ugh, since our list of valid video modes comes from
slouken@1662
  1137
           the DirectX driver, we may not actually be able to
slouken@1662
  1138
           change to the desired resolution here.
slouken@1662
  1139
           FIXME: Should we do a closest match?
slouken@1662
  1140
         */
slouken@1662
  1141
        if ((flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) {
slouken@1662
  1142
            DEVMODE settings;
slouken@1662
  1143
            BOOL changed;
slouken@0
  1144
slouken@1668
  1145
            SDL_memset(&settings, 0, sizeof(DEVMODE));
slouken@1668
  1146
            settings.dmSize = sizeof(DEVMODE);
slouken@1662
  1147
            settings.dmBitsPerPel = video->format->BitsPerPixel;
slouken@1662
  1148
            settings.dmPelsWidth = width;
slouken@1662
  1149
            settings.dmPelsHeight = height;
slouken@1662
  1150
            settings.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
slouken@1662
  1151
            if (width <= (int) SDL_desktop_mode.dmPelsWidth
slouken@1662
  1152
                && height <= (int) SDL_desktop_mode.dmPelsHeight) {
slouken@1662
  1153
                settings.dmDisplayFrequency =
slouken@1662
  1154
                    SDL_desktop_mode.dmDisplayFrequency;
slouken@1662
  1155
                settings.dmFields |= DM_DISPLAYFREQUENCY;
slouken@1662
  1156
            }
slouken@1662
  1157
            changed =
slouken@1668
  1158
                (ChangeDisplaySettings(&settings, CDS_FULLSCREEN) ==
slouken@1662
  1159
                 DISP_CHANGE_SUCCESSFUL);
slouken@1662
  1160
            if (!changed && (settings.dmFields & DM_DISPLAYFREQUENCY)) {
slouken@1662
  1161
                settings.dmFields &= ~DM_DISPLAYFREQUENCY;
slouken@1668
  1162
                changed = (ChangeDisplaySettings(&settings, CDS_FULLSCREEN)
slouken@1662
  1163
                           == DISP_CHANGE_SUCCESSFUL);
slouken@1662
  1164
            }
slouken@1662
  1165
            if (changed) {
slouken@1662
  1166
                video->flags |= SDL_FULLSCREEN;
slouken@1662
  1167
                SDL_fullscreen_mode = settings;
slouken@1662
  1168
            }
slouken@1662
  1169
        }
slouken@453
  1170
#endif /* !NO_CHANGEDISPLAYSETTINGS */
slouken@0
  1171
slouken@1668
  1172
        style = GetWindowLong(SDL_Window, GWL_STYLE);
slouken@1662
  1173
        style &= ~(resizestyle | WS_MAXIMIZE);
slouken@1662
  1174
        if (video->flags & SDL_FULLSCREEN) {
slouken@1662
  1175
            style &= ~windowstyle;
slouken@1662
  1176
            style |= directstyle;
slouken@1662
  1177
        } else {
slouken@1662
  1178
            if (flags & SDL_NOFRAME) {
slouken@1662
  1179
                style &= ~windowstyle;
slouken@1662
  1180
                style |= directstyle;
slouken@1662
  1181
                video->flags |= SDL_NOFRAME;
slouken@1662
  1182
            } else {
slouken@1662
  1183
                style &= ~directstyle;
slouken@1662
  1184
                style |= windowstyle;
slouken@1662
  1185
                if (flags & SDL_RESIZABLE) {
slouken@1662
  1186
                    style |= resizestyle;
slouken@1662
  1187
                    video->flags |= SDL_RESIZABLE;
slouken@1662
  1188
                }
slouken@1662
  1189
            }
slouken@453
  1190
#if WS_MAXIMIZE
slouken@1668
  1191
            if (IsZoomed(SDL_Window))
slouken@1662
  1192
                style |= WS_MAXIMIZE;
slouken@453
  1193
#endif
slouken@1662
  1194
        }
slouken@833
  1195
slouken@1662
  1196
        /* DJM: Don't piss of anyone who has setup his own window */
slouken@1662
  1197
        if (!SDL_windowid)
slouken@1668
  1198
            SetWindowLong(SDL_Window, GWL_STYLE, style);
slouken@0
  1199
slouken@1662
  1200
        /* Resize the window (copied from SDL WinDIB driver) */
slouken@1668
  1201
        if (!SDL_windowid && !IsZoomed(SDL_Window)) {
slouken@1662
  1202
            RECT bounds;
slouken@1662
  1203
            int x, y;
slouken@1662
  1204
            HWND top;
slouken@1662
  1205
            UINT swp_flags;
slouken@1662
  1206
            const char *window = NULL;
slouken@1662
  1207
            const char *center = NULL;
slouken@833
  1208
slouken@1662
  1209
            if (!SDL_windowX && !SDL_windowY) {
slouken@1668
  1210
                window = SDL_getenv("SDL_VIDEO_WINDOW_POS");
slouken@1668
  1211
                center = SDL_getenv("SDL_VIDEO_CENTERED");
slouken@1662
  1212
                if (window) {
slouken@1668
  1213
                    if (SDL_sscanf(window, "%d,%d", &x, &y) == 2) {
slouken@1662
  1214
                        SDL_windowX = x;
slouken@1662
  1215
                        SDL_windowY = y;
slouken@1662
  1216
                    }
slouken@1668
  1217
                    if (SDL_strcmp(window, "center") == 0) {
slouken@1662
  1218
                        center = window;
slouken@1662
  1219
                    }
slouken@1662
  1220
                }
slouken@1662
  1221
            }
slouken@1662
  1222
            swp_flags = (SWP_NOCOPYBITS | SWP_SHOWWINDOW);
slouken@0
  1223
slouken@1662
  1224
            bounds.left = SDL_windowX;
slouken@1662
  1225
            bounds.top = SDL_windowY;
slouken@1662
  1226
            bounds.right = SDL_windowX + video->w;
slouken@1662
  1227
            bounds.bottom = SDL_windowY + video->h;
slouken@1668
  1228
            AdjustWindowRectEx(&bounds,
slouken@1668
  1229
                               GetWindowLong(SDL_Window, GWL_STYLE),
slouken@1668
  1230
                               FALSE, 0);
slouken@1662
  1231
            width = bounds.right - bounds.left;
slouken@1662
  1232
            height = bounds.bottom - bounds.top;
slouken@1662
  1233
            if ((flags & SDL_FULLSCREEN)) {
slouken@1668
  1234
                x = (GetSystemMetrics(SM_CXSCREEN) - width) / 2;
slouken@1668
  1235
                y = (GetSystemMetrics(SM_CYSCREEN) - height) / 2;
slouken@1662
  1236
            } else if (center) {
slouken@1668
  1237
                x = (GetSystemMetrics(SM_CXSCREEN) - width) / 2;
slouken@1668
  1238
                y = (GetSystemMetrics(SM_CYSCREEN) - height) / 2;
slouken@1662
  1239
            } else if (SDL_windowX || SDL_windowY || window) {
slouken@1662
  1240
                x = bounds.left;
slouken@1662
  1241
                y = bounds.top;
slouken@1662
  1242
            } else {
slouken@1662
  1243
                x = y = -1;
slouken@1662
  1244
                swp_flags |= SWP_NOMOVE;
slouken@1662
  1245
            }
slouken@1662
  1246
            if (flags & SDL_FULLSCREEN) {
slouken@1662
  1247
                top = HWND_TOPMOST;
slouken@1662
  1248
            } else {
slouken@1662
  1249
                top = HWND_NOTOPMOST;
slouken@1662
  1250
            }
slouken@1668
  1251
            SetWindowPos(SDL_Window, top, x, y, width, height, swp_flags);
slouken@1662
  1252
            if (!(flags & SDL_FULLSCREEN)) {
slouken@1662
  1253
                SDL_windowX = SDL_bounds.left;
slouken@1662
  1254
                SDL_windowY = SDL_bounds.top;
slouken@1662
  1255
            }
slouken@1668
  1256
            SetForegroundWindow(SDL_Window);
slouken@1662
  1257
        }
slouken@1662
  1258
        SDL_resizing = 0;
slouken@0
  1259
slouken@1662
  1260
        /* Set up for OpenGL */
slouken@1668
  1261
        if (WIN_GL_SetupWindow(this) < 0) {
slouken@1662
  1262
            return (NULL);
slouken@1662
  1263
        }
slouken@1662
  1264
        video->flags |= SDL_INTERNALOPENGL;
slouken@1662
  1265
        return (video);
slouken@1662
  1266
    }
slouken@0
  1267
slouken@1662
  1268
    /* Set the appropriate window style */
slouken@1668
  1269
    style = GetWindowLong(SDL_Window, GWL_STYLE);
slouken@1662
  1270
    style &= ~(resizestyle | WS_MAXIMIZE);
slouken@1662
  1271
    if ((flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) {
slouken@1662
  1272
        style &= ~windowstyle;
slouken@1662
  1273
        style |= directstyle;
slouken@1662
  1274
    } else {
slouken@1662
  1275
        if (flags & SDL_NOFRAME) {
slouken@1662
  1276
            style &= ~windowstyle;
slouken@1662
  1277
            style |= directstyle;
slouken@1662
  1278
        } else {
slouken@1662
  1279
            style &= ~directstyle;
slouken@1662
  1280
            style |= windowstyle;
slouken@1662
  1281
            if (flags & SDL_RESIZABLE) {
slouken@1662
  1282
                style |= resizestyle;
slouken@1662
  1283
            }
slouken@1662
  1284
        }
slouken@453
  1285
#if WS_MAXIMIZE
slouken@1668
  1286
        if (IsZoomed(SDL_Window))
slouken@1662
  1287
            style |= WS_MAXIMIZE;
slouken@453
  1288
#endif
slouken@1662
  1289
    }
slouken@1662
  1290
    /* DJM: Don't piss of anyone who has setup his own window */
slouken@1662
  1291
    if (!SDL_windowid)
slouken@1668
  1292
        SetWindowLong(SDL_Window, GWL_STYLE, style);
slouken@0
  1293
slouken@1662
  1294
    /* Set DirectDraw sharing mode.. exclusive when fullscreen */
slouken@1662
  1295
    if ((flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) {
slouken@1662
  1296
        sharemode = DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT;
slouken@1662
  1297
    } else {
slouken@1662
  1298
        sharemode = DDSCL_NORMAL;
slouken@1662
  1299
    }
slouken@1668
  1300
    result = IDirectDraw2_SetCooperativeLevel(ddraw2, SDL_Window, sharemode);
slouken@1662
  1301
    if (result != DD_OK) {
slouken@1668
  1302
        SetDDerror("DirectDraw2::SetCooperativeLevel", result);
slouken@1662
  1303
        return (NULL);
slouken@1662
  1304
    }
slouken@0
  1305
slouken@1662
  1306
    /* Set the display mode, if we are in fullscreen mode */
slouken@1662
  1307
    if ((flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) {
slouken@1662
  1308
        RECT bounds;
slouken@1662
  1309
        struct DX5EnumRect *rect;
slouken@1662
  1310
        int maxRefreshRate;
slouken@809
  1311
slouken@1662
  1312
        /* Cover up desktop during mode change */
slouken@1662
  1313
        bounds.left = 0;
slouken@1662
  1314
        bounds.top = 0;
slouken@1668
  1315
        bounds.right = GetSystemMetrics(SM_CXSCREEN);
slouken@1668
  1316
        bounds.bottom = GetSystemMetrics(SM_CYSCREEN);
slouken@1668
  1317
        AdjustWindowRectEx(&bounds, GetWindowLong(SDL_Window, GWL_STYLE),
slouken@1668
  1318
                           FALSE, 0);
slouken@1668
  1319
        SetWindowPos(SDL_Window, HWND_TOPMOST, bounds.left, bounds.top,
slouken@1668
  1320
                     bounds.right - bounds.left,
slouken@1668
  1321
                     bounds.bottom - bounds.top, SWP_NOCOPYBITS);
slouken@1668
  1322
        ShowWindow(SDL_Window, SW_SHOW);
slouken@1668
  1323
        while (GetForegroundWindow() != SDL_Window) {
slouken@1668
  1324
            SetForegroundWindow(SDL_Window);
slouken@1668
  1325
            SDL_Delay(100);
slouken@1662
  1326
        }
slouken@809
  1327
slouken@1662
  1328
        /* find maximum monitor refresh rate for this resolution */
slouken@1662
  1329
        /* Dmitry Yakimov ftech@tula.net */
slouken@1662
  1330
        maxRefreshRate = 0;     /* system default */
slouken@1662
  1331
        for (rect = enumlists[bpp / 8 - 1]; rect; rect = rect->next) {
slouken@1662
  1332
            if ((width == rect->r.w) && (height == rect->r.h)) {
slouken@1662
  1333
                maxRefreshRate = rect->refreshRate;
slouken@1662
  1334
                break;
slouken@1662
  1335
            }
slouken@1662
  1336
        }
slouken@830
  1337
#ifdef DDRAW_DEBUG
slouken@1668
  1338
        fprintf(stderr, "refresh rate = %d Hz\n", maxRefreshRate);
slouken@830
  1339
#endif
slouken@809
  1340
slouken@1662
  1341
        result =
slouken@1668
  1342
            IDirectDraw2_SetDisplayMode(ddraw2, width, height, bpp,
slouken@1668
  1343
                                        maxRefreshRate, 0);
slouken@1662
  1344
        if (result != DD_OK) {
slouken@1662
  1345
            result =
slouken@1668
  1346
                IDirectDraw2_SetDisplayMode(ddraw2, width, height, bpp, 0, 0);
slouken@1662
  1347
            if (result != DD_OK) {
slouken@1662
  1348
                /* We couldn't set fullscreen mode, try window */
slouken@1662
  1349
                return (DX5_SetVideoMode
slouken@1662
  1350
                        (this, current, width, height, bpp,
slouken@1662
  1351
                         flags & ~SDL_FULLSCREEN));
slouken@1662
  1352
            }
slouken@1662
  1353
        }
slouken@1668
  1354
        DX5_DInputReset(this, 1);
slouken@1662
  1355
    } else {
slouken@1668
  1356
        DX5_DInputReset(this, 0);
slouken@1662
  1357
    }
slouken@1668
  1358
    DX5_UpdateVideoInfo(this);
slouken@0
  1359
slouken@1662
  1360
    /* Create a primary DirectDraw surface */
slouken@1668
  1361
    SDL_memset(&ddsd, 0, sizeof(ddsd));
slouken@1668
  1362
    ddsd.dwSize = sizeof(ddsd);
slouken@1662
  1363
    ddsd.dwFlags = DDSD_CAPS;
slouken@1662
  1364
    ddsd.ddsCaps.dwCaps = (DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY);
slouken@1662
  1365
    if ((flags & SDL_FULLSCREEN) != SDL_FULLSCREEN) {
slouken@1662
  1366
        /* There's no windowed double-buffering */
slouken@1662
  1367
        flags &= ~SDL_DOUBLEBUF;
slouken@1662
  1368
    }
slouken@1662
  1369
    if ((flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) {
slouken@1662
  1370
        ddsd.dwFlags |= DDSD_BACKBUFFERCOUNT;
slouken@1662
  1371
        ddsd.ddsCaps.dwCaps |= (DDSCAPS_COMPLEX | DDSCAPS_FLIP);
slouken@1662
  1372
        ddsd.dwBackBufferCount = 1;
slouken@1662
  1373
    }
slouken@1668
  1374
    result = IDirectDraw2_CreateSurface(ddraw2, &ddsd, &dd_surface1, NULL);
slouken@1662
  1375
    if ((result != DD_OK) && ((flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF)) {
slouken@1662
  1376
        ddsd.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
slouken@1662
  1377
        ddsd.ddsCaps.dwCaps &= ~(DDSCAPS_COMPLEX | DDSCAPS_FLIP);
slouken@1662
  1378
        ddsd.dwBackBufferCount = 0;
slouken@1668
  1379
        result = IDirectDraw2_CreateSurface(ddraw2,
slouken@1668
  1380
                                            &ddsd, &dd_surface1, NULL);
slouken@1662
  1381
    }
slouken@1662
  1382
    if (result != DD_OK) {
slouken@1668
  1383
        SetDDerror("DirectDraw2::CreateSurface(PRIMARY)", result);
slouken@1662
  1384
        return (NULL);
slouken@1662
  1385
    }
slouken@1668
  1386
    result = IDirectDrawSurface_QueryInterface(dd_surface1,
slouken@1668
  1387
                                               &IID_IDirectDrawSurface3,
slouken@1668
  1388
                                               (LPVOID *) & SDL_primary);
slouken@1662
  1389
    if (result != DD_OK) {
slouken@1668
  1390
        SetDDerror("DirectDrawSurface::QueryInterface", result);
slouken@1662
  1391
        return (NULL);
slouken@1662
  1392
    }
slouken@1668
  1393
    IDirectDrawSurface_Release(dd_surface1);
slouken@0
  1394
slouken@1662
  1395
    /* Get the format of the primary DirectDraw surface */
slouken@1668
  1396
    SDL_memset(&ddsd, 0, sizeof(ddsd));
slouken@1668
  1397
    ddsd.dwSize = sizeof(ddsd);
slouken@1662
  1398
    ddsd.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
slouken@1668
  1399
    result = IDirectDrawSurface3_GetSurfaceDesc(SDL_primary, &ddsd);
slouken@1662
  1400
    if (result != DD_OK) {
slouken@1668
  1401
        SetDDerror("DirectDrawSurface::GetSurfaceDesc", result);
slouken@1662
  1402
        return (NULL);
slouken@1662
  1403
    }
slouken@1662
  1404
    if (!(ddsd.ddpfPixelFormat.dwFlags & DDPF_RGB)) {
slouken@1668
  1405
        SDL_SetError("Primary DDRAW surface is not RGB format");
slouken@1662
  1406
        return (NULL);
slouken@1662
  1407
    }
slouken@0
  1408
slouken@1662
  1409
    /* Free old palette and create a new one if we're in 8-bit mode */
slouken@1662
  1410
    if (SDL_palette != NULL) {
slouken@1668
  1411
        IDirectDrawPalette_Release(SDL_palette);
slouken@1662
  1412
        SDL_palette = NULL;
slouken@1662
  1413
    }
slouken@1662
  1414
#if defined(NONAMELESSUNION)
slouken@1662
  1415
    if (ddsd.ddpfPixelFormat.u1.dwRGBBitCount == 8) {
slouken@1662
  1416
#else
slouken@1662
  1417
    if (ddsd.ddpfPixelFormat.dwRGBBitCount == 8) {
slouken@1662
  1418
#endif
slouken@1662
  1419
        int i;
slouken@0
  1420
slouken@1662
  1421
        if ((flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) {
slouken@1662
  1422
            /* We have access to the entire palette */
slouken@1662
  1423
            for (i = 0; i < 256; ++i) {
slouken@1662
  1424
                SDL_colors[i].peFlags = (PC_NOCOLLAPSE | PC_RESERVED);
slouken@1662
  1425
                SDL_colors[i].peRed = 0;
slouken@1662
  1426
                SDL_colors[i].peGreen = 0;
slouken@1662
  1427
                SDL_colors[i].peBlue = 0;
slouken@1662
  1428
            }
slouken@1662
  1429
        } else {
slouken@1662
  1430
            /* First 10 colors are reserved by Windows */
slouken@1662
  1431
            for (i = 0; i < 10; ++i) {
slouken@1662
  1432
                SDL_colors[i].peFlags = PC_EXPLICIT;
slouken@1662
  1433
                SDL_colors[i].peRed = i;
slouken@1662
  1434
                SDL_colors[i].peGreen = 0;
slouken@1662
  1435
                SDL_colors[i].peBlue = 0;
slouken@1662
  1436
            }
slouken@1662
  1437
            for (i = 10; i < (10 + 236); ++i) {
slouken@1662
  1438
                SDL_colors[i].peFlags = PC_NOCOLLAPSE;
slouken@1662
  1439
                SDL_colors[i].peRed = 0;
slouken@1662
  1440
                SDL_colors[i].peGreen = 0;
slouken@1662
  1441
                SDL_colors[i].peBlue = 0;
slouken@1662
  1442
            }
slouken@1662
  1443
            /* Last 10 colors are reserved by Windows */
slouken@1662
  1444
            for (i = 246; i < 256; ++i) {
slouken@1662
  1445
                SDL_colors[i].peFlags = PC_EXPLICIT;
slouken@1662
  1446
                SDL_colors[i].peRed = i;
slouken@1662
  1447
                SDL_colors[i].peGreen = 0;
slouken@1662
  1448
                SDL_colors[i].peBlue = 0;
slouken@1662
  1449
            }
slouken@1662
  1450
        }
slouken@1668
  1451
        result = IDirectDraw2_CreatePalette(ddraw2,
slouken@1668
  1452
                                            (DDPCAPS_8BIT |
slouken@1668
  1453
                                             DDPCAPS_ALLOW256), SDL_colors,
slouken@1668
  1454
                                            &SDL_palette, NULL);
slouken@1662
  1455
        if (result != DD_OK) {
slouken@1668
  1456
            SetDDerror("DirectDraw2::CreatePalette", result);
slouken@1662
  1457
            return (NULL);
slouken@1662
  1458
        }
slouken@1668
  1459
        result = IDirectDrawSurface3_SetPalette(SDL_primary, SDL_palette);
slouken@1662
  1460
        if (result != DD_OK) {
slouken@1668
  1461
            SetDDerror("DirectDrawSurface3::SetPalette", result);
slouken@1662
  1462
            return (NULL);
slouken@1662
  1463
        }
slouken@1662
  1464
    }
slouken@1662
  1465
slouken@1662
  1466
    /* Create our video surface using the same pixel format */
slouken@1662
  1467
    video = current;
slouken@1662
  1468
    if ((width != video->w) || (height != video->h)
slouken@1662
  1469
        || (video->format->BitsPerPixel !=
slouken@0
  1470
#if defined(NONAMELESSUNION)
slouken@1662
  1471
            ddsd.ddpfPixelFormat.u1.dwRGBBitCount)) {
slouken@0
  1472
#else
slouken@1662
  1473
            ddsd.ddpfPixelFormat.dwRGBBitCount)) {
slouken@0
  1474
#endif
slouken@1668
  1475
        SDL_FreeSurface(video);
slouken@1668
  1476
        video = SDL_CreateRGBSurface(SDL_SWSURFACE, 0, 0,
slouken@1662
  1477
#if defined(NONAMELESSUNION)
slouken@1668
  1478
                                     ddsd.ddpfPixelFormat.u1.dwRGBBitCount,
slouken@1668
  1479
                                     ddsd.ddpfPixelFormat.u2.dwRBitMask,
slouken@1668
  1480
                                     ddsd.ddpfPixelFormat.u3.dwGBitMask,
slouken@1668
  1481
                                     ddsd.ddpfPixelFormat.u4.dwBBitMask,
slouken@1662
  1482
#else
slouken@1668
  1483
                                     ddsd.ddpfPixelFormat.dwRGBBitCount,
slouken@1668
  1484
                                     ddsd.ddpfPixelFormat.dwRBitMask,
slouken@1668
  1485
                                     ddsd.ddpfPixelFormat.dwGBitMask,
slouken@1668
  1486
                                     ddsd.ddpfPixelFormat.dwBBitMask,
slouken@1662
  1487
#endif
slouken@1668
  1488
                                     0);
slouken@1662
  1489
        if (video == NULL) {
slouken@1668
  1490
            SDL_OutOfMemory();
slouken@1662
  1491
            return (NULL);
slouken@1662
  1492
        }
slouken@1662
  1493
        video->w = width;
slouken@1662
  1494
        video->h = height;
slouken@1662
  1495
        video->pitch = 0;
slouken@1662
  1496
    }
slouken@1662
  1497
    video->flags = 0;           /* Clear flags */
slouken@0
  1498
slouken@1662
  1499
    /* If not fullscreen, locking is possible, but it doesn't do what 
slouken@1662
  1500
       the caller really expects -- if the locked surface is written to,
slouken@1662
  1501
       the appropriate portion of the entire screen is modified, not 
slouken@1662
  1502
       the application window, as we would like.
slouken@1662
  1503
       Note that it is still possible to write directly to display
slouken@1662
  1504
       memory, but the application must respect the clip list of
slouken@1662
  1505
       the surface.  There might be some odd timing interactions
slouken@1662
  1506
       involving clip list updates and background refreshing as
slouken@1662
  1507
       Windows moves other windows across our window.
slouken@1662
  1508
       We currently don't support this, even though it might be a
slouken@1662
  1509
       good idea since BeOS has an implementation of BDirectWindow
slouken@1662
  1510
       that does the same thing.  This would be most useful for
slouken@1662
  1511
       applications that do complete screen updates every frame.
slouken@1662
  1512
       -- Fixme?
slouken@1662
  1513
     */
slouken@1662
  1514
    if ((flags & SDL_FULLSCREEN) != SDL_FULLSCREEN) {
slouken@1662
  1515
        /* Necessary if we're going from fullscreen to window */
slouken@1662
  1516
        if (video->pixels == NULL) {
slouken@1662
  1517
            video->pitch = (width * video->format->BytesPerPixel);
slouken@1662
  1518
            /* Pitch needs to be QWORD (8-byte) aligned */
slouken@1662
  1519
            video->pitch = (video->pitch + 7) & ~7;
slouken@1668
  1520
            video->pixels = (void *) SDL_malloc(video->h * video->pitch);
slouken@1662
  1521
            if (video->pixels == NULL) {
slouken@1662
  1522
                if (video != current) {
slouken@1668
  1523
                    SDL_FreeSurface(video);
slouken@1662
  1524
                }
slouken@1668
  1525
                SDL_OutOfMemory();
slouken@1662
  1526
                return (NULL);
slouken@1662
  1527
            }
slouken@1662
  1528
        }
slouken@1662
  1529
        dd_surface3 = NULL;
slouken@1662
  1530
#if 0                           /* FIXME: enable this when SDL consistently reports lost surfaces */
slouken@1662
  1531
        if ((flags & SDL_HWSURFACE) == SDL_HWSURFACE) {
slouken@1662
  1532
            video->flags |= SDL_HWSURFACE;
slouken@1662
  1533
        } else {
slouken@1662
  1534
            video->flags |= SDL_SWSURFACE;
slouken@1662
  1535
        }
slouken@443
  1536
#else
slouken@1662
  1537
        video->flags |= SDL_SWSURFACE;
slouken@443
  1538
#endif
slouken@1662
  1539
        if ((flags & SDL_RESIZABLE) && !(flags & SDL_NOFRAME)) {
slouken@1662
  1540
            video->flags |= SDL_RESIZABLE;
slouken@1662
  1541
        }
slouken@1662
  1542
        if (flags & SDL_NOFRAME) {
slouken@1662
  1543
            video->flags |= SDL_NOFRAME;
slouken@1662
  1544
        }
slouken@1662
  1545
    } else {
slouken@1662
  1546
        /* Necessary if we're going from window to fullscreen */
slouken@1662
  1547
        if (video->pixels != NULL) {
slouken@1668
  1548
            SDL_free(video->pixels);
slouken@1662
  1549
            video->pixels = NULL;
slouken@1662
  1550
        }
slouken@1662
  1551
        dd_surface3 = SDL_primary;
slouken@1662
  1552
        video->flags |= SDL_HWSURFACE;
slouken@1662
  1553
    }
slouken@0
  1554
slouken@1662
  1555
    /* See if the primary surface has double-buffering enabled */
slouken@1662
  1556
    if ((ddsd.ddsCaps.dwCaps & DDSCAPS_FLIP) == DDSCAPS_FLIP) {
slouken@1662
  1557
        video->flags |= SDL_DOUBLEBUF;
slouken@1662
  1558
    }
slouken@0
  1559
slouken@1662
  1560
    /* Allocate the SDL surface associated with the primary surface */
slouken@1668
  1561
    if (DX5_AllocDDSurface(this, video, dd_surface3,
slouken@1668
  1562
                           video->flags & SDL_HWSURFACE) < 0) {
slouken@1662
  1563
        if (video != current) {
slouken@1668
  1564
            SDL_FreeSurface(video);
slouken@1662
  1565
        }
slouken@1662
  1566
        return (NULL);
slouken@1662
  1567
    }
slouken@0
  1568
slouken@1662
  1569
    /* Use the appropriate blitting function */
slouken@1662
  1570
    if ((flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) {
slouken@1662
  1571
        video->flags |= SDL_FULLSCREEN;
slouken@1662
  1572
        if (video->format->palette != NULL) {
slouken@1662
  1573
            video->flags |= SDL_HWPALETTE;
slouken@1662
  1574
        }
slouken@1662
  1575
        this->UpdateRects = DX5_DirectUpdate;
slouken@1662
  1576
    } else {
slouken@1662
  1577
        this->UpdateRects = DX5_WindowUpdate;
slouken@1662
  1578
    }
slouken@0
  1579
slouken@1662
  1580
    /* Make our window the proper size, set the clipper, then show it */
slouken@1662
  1581
    if ((flags & SDL_FULLSCREEN) != SDL_FULLSCREEN) {
slouken@1662
  1582
        /* Create and set a clipper on our primary surface */
slouken@1662
  1583
        if (SDL_clipper == NULL) {
slouken@1668
  1584
            result = IDirectDraw2_CreateClipper(ddraw2,
slouken@1668
  1585
                                                0, &SDL_clipper, NULL);
slouken@1662
  1586
            if (result != DD_OK) {
slouken@1662
  1587
                if (video != current) {
slouken@1668
  1588
                    SDL_FreeSurface(video);
slouken@1662
  1589
                }
slouken@1668
  1590
                SetDDerror("DirectDraw2::CreateClipper", result);
slouken@1662
  1591
                return (NULL);
slouken@1662
  1592
            }
slouken@1662
  1593
        }
slouken@1668
  1594
        result = IDirectDrawClipper_SetHWnd(SDL_clipper, 0, SDL_Window);
slouken@1662
  1595
        if (result != DD_OK) {
slouken@1662
  1596
            if (video != current) {
slouken@1668
  1597
                SDL_FreeSurface(video);
slouken@1662
  1598
            }
slouken@1668
  1599
            SetDDerror("DirectDrawClipper::SetHWnd", result);
slouken@1662
  1600
            return (NULL);
slouken@1662
  1601
        }
slouken@1668
  1602
        result = IDirectDrawSurface3_SetClipper(SDL_primary, SDL_clipper);
slouken@1662
  1603
        if (result != DD_OK) {
slouken@1662
  1604
            if (video != current) {
slouken@1668
  1605
                SDL_FreeSurface(video);
slouken@1662
  1606
            }
slouken@1668
  1607
            SetDDerror("DirectDrawSurface3::SetClipper", result);
slouken@1662
  1608
            return (NULL);
slouken@1662
  1609
        }
slouken@0
  1610
slouken@1662
  1611
        /* Resize the window (copied from SDL WinDIB driver) */
slouken@1668
  1612
        if (!SDL_windowid && !IsZoomed(SDL_Window)) {
slouken@1662
  1613
            RECT bounds;
slouken@1662
  1614
            int x, y;
slouken@1662
  1615
            UINT swp_flags;
slouken@1662
  1616
            const char *window = NULL;
slouken@1662
  1617
            const char *center = NULL;
slouken@1290
  1618
slouken@1662
  1619
            if (!SDL_windowX && !SDL_windowY) {
slouken@1668
  1620
                window = SDL_getenv("SDL_VIDEO_WINDOW_POS");
slouken@1668
  1621
                center = SDL_getenv("SDL_VIDEO_CENTERED");
slouken@1662
  1622
                if (window) {
slouken@1668
  1623
                    if (SDL_sscanf(window, "%d,%d", &x, &y) == 2) {
slouken@1662
  1624
                        SDL_windowX = x;
slouken@1662
  1625
                        SDL_windowY = y;
slouken@1662
  1626
                    }
slouken@1668
  1627
                    if (SDL_strcmp(window, "center") == 0) {
slouken@1662
  1628
                        center = window;
slouken@1662
  1629
                    }
slouken@1662
  1630
                }
slouken@1662
  1631
            }
slouken@1662
  1632
            swp_flags = SWP_NOCOPYBITS;
slouken@833
  1633
slouken@1662
  1634
            bounds.left = SDL_windowX;
slouken@1662
  1635
            bounds.top = SDL_windowY;
slouken@1662
  1636
            bounds.right = SDL_windowX + video->w;
slouken@1662
  1637
            bounds.bottom = SDL_windowY + video->h;
slouken@1668
  1638
            AdjustWindowRectEx(&bounds,
slouken@1668
  1639
                               GetWindowLong(SDL_Window, GWL_STYLE),
slouken@1668
  1640
                               FALSE, 0);
slouken@1662
  1641
            width = bounds.right - bounds.left;
slouken@1662
  1642
            height = bounds.bottom - bounds.top;
slouken@1662
  1643
            if (center) {
slouken@1668
  1644
                x = (GetSystemMetrics(SM_CXSCREEN) - width) / 2;
slouken@1668
  1645
                y = (GetSystemMetrics(SM_CYSCREEN) - height) / 2;
slouken@1662
  1646
            } else if (SDL_windowX || SDL_windowY || window) {
slouken@1662
  1647
                x = bounds.left;
slouken@1662
  1648
                y = bounds.top;
slouken@1662
  1649
            } else {
slouken@1662
  1650
                x = y = -1;
slouken@1662
  1651
                swp_flags |= SWP_NOMOVE;
slouken@1662
  1652
            }
slouken@1668
  1653
            SetWindowPos(SDL_Window, HWND_NOTOPMOST, x, y, width, height,
slouken@1668
  1654
                         swp_flags);
slouken@1662
  1655
            SDL_windowX = SDL_bounds.left;
slouken@1662
  1656
            SDL_windowY = SDL_bounds.top;
slouken@1662
  1657
        }
slouken@833
  1658
slouken@1662
  1659
    }
slouken@1668
  1660
    ShowWindow(SDL_Window, SW_SHOW);
slouken@1668
  1661
    SetForegroundWindow(SDL_Window);
slouken@1662
  1662
    SDL_resizing = 0;
slouken@0
  1663
slouken@1662
  1664
    /* JC 14 Mar 2006
slouken@1662
  1665
       Flush the message loop or this can cause big problems later
slouken@1662
  1666
       Especially if the user decides to use dialog boxes or assert()!
slouken@1662
  1667
     */
slouken@1668
  1668
    WIN_FlushMessageQueue();
slouken@1523
  1669
slouken@1662
  1670
    /* We're live! */
slouken@1662
  1671
    return (video);
slouken@0
  1672
}
slouken@0
  1673
slouken@1662
  1674
struct private_hwdata
slouken@1662
  1675
{
slouken@1662
  1676
    LPDIRECTDRAWSURFACE3 dd_surface;
slouken@1662
  1677
    LPDIRECTDRAWSURFACE3 dd_writebuf;
slouken@0
  1678
};
slouken@0
  1679
slouken@1662
  1680
static int
slouken@1668
  1681
DX5_AllocDDSurface(_THIS, SDL_Surface * surface,
slouken@1668
  1682
                   LPDIRECTDRAWSURFACE3 requested, Uint32 flag)
slouken@0
  1683
{
slouken@1662
  1684
    LPDIRECTDRAWSURFACE dd_surface1;
slouken@1662
  1685
    LPDIRECTDRAWSURFACE3 dd_surface3;
slouken@1662
  1686
    DDSURFACEDESC ddsd;
slouken@1662
  1687
    HRESULT result;
slouken@0
  1688
slouken@1662
  1689
    /* Clear the hardware flag, in case we fail */
slouken@1662
  1690
    surface->flags &= ~flag;
slouken@0
  1691
slouken@1662
  1692
    /* Allocate the hardware acceleration data */
slouken@1662
  1693
    surface->hwdata = (struct private_hwdata *)
slouken@1668
  1694
        SDL_malloc(sizeof(*surface->hwdata));
slouken@1662
  1695
    if (surface->hwdata == NULL) {
slouken@1668
  1696
        SDL_OutOfMemory();
slouken@1662
  1697
        return (-1);
slouken@1662
  1698
    }
slouken@1662
  1699
    dd_surface3 = NULL;
slouken@0
  1700
slouken@1662
  1701
    /* Set up the surface description */
slouken@1668
  1702
    SDL_memset(&ddsd, 0, sizeof(ddsd));
slouken@1668
  1703
    ddsd.dwSize = sizeof(ddsd);
slouken@1662
  1704
    ddsd.dwFlags = (DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS |
slouken@1662
  1705
                    DDSD_PITCH | DDSD_PIXELFORMAT);
slouken@1662
  1706
    ddsd.dwWidth = surface->w;
slouken@1662
  1707
    ddsd.dwHeight = surface->h;
slouken@0
  1708
#if defined(NONAMELESSUNION)
slouken@1662
  1709
    ddsd.u1.lPitch = surface->pitch;
slouken@0
  1710
#else
slouken@1662
  1711
    ddsd.lPitch = surface->pitch;
slouken@0
  1712
#endif
slouken@1662
  1713
    if ((flag & SDL_HWSURFACE) == SDL_HWSURFACE) {
slouken@1662
  1714
        ddsd.ddsCaps.dwCaps = (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY);
slouken@1662
  1715
    } else {
slouken@1662
  1716
        ddsd.ddsCaps.dwCaps = (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY);
slouken@1662
  1717
    }
slouken@1668
  1718
    ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
slouken@1662
  1719
    ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
slouken@1662
  1720
    if (surface->format->palette) {
slouken@1662
  1721
        ddsd.ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED8;
slouken@1662
  1722
    }
slouken@0
  1723
#if defined(NONAMELESSUNION)
slouken@1662
  1724
    ddsd.ddpfPixelFormat.u1.dwRGBBitCount = surface->format->BitsPerPixel;
slouken@1662
  1725
    ddsd.ddpfPixelFormat.u2.dwRBitMask = surface->format->Rmask;
slouken@1662
  1726
    ddsd.ddpfPixelFormat.u3.dwGBitMask = surface->format->Gmask;
slouken@1662
  1727
    ddsd.ddpfPixelFormat.u4.dwBBitMask = surface->format->Bmask;
slouken@0
  1728
#else
slouken@1662
  1729
    ddsd.ddpfPixelFormat.dwRGBBitCount = surface->format->BitsPerPixel;
slouken@1662
  1730
    ddsd.ddpfPixelFormat.dwRBitMask = surface->format->Rmask;
slouken@1662
  1731
    ddsd.ddpfPixelFormat.dwGBitMask = surface->format->Gmask;
slouken@1662
  1732
    ddsd.ddpfPixelFormat.dwBBitMask = surface->format->Bmask;
slouken@0
  1733
#endif
slouken@0
  1734
slouken@1662
  1735
    /* Create the DirectDraw video surface */
slouken@1662
  1736
    if (requested != NULL) {
slouken@1662
  1737
        dd_surface3 = requested;
slouken@1662
  1738
    } else {
slouken@1668
  1739
        result = IDirectDraw2_CreateSurface(ddraw2,
slouken@1668
  1740
                                            &ddsd, &dd_surface1, NULL);
slouken@1662
  1741
        if (result != DD_OK) {
slouken@1668
  1742
            SetDDerror("DirectDraw2::CreateSurface", result);
slouken@1662
  1743
            goto error_end;
slouken@1662
  1744
        }
slouken@1668
  1745
        result = IDirectDrawSurface_QueryInterface(dd_surface1,
slouken@1668
  1746
                                                   &IID_IDirectDrawSurface3,
slouken@1668
  1747
                                                   (LPVOID *) & dd_surface3);
slouken@1668
  1748
        IDirectDrawSurface_Release(dd_surface1);
slouken@1662
  1749
        if (result != DD_OK) {
slouken@1668
  1750
            SetDDerror("DirectDrawSurface::QueryInterface", result);
slouken@1662
  1751
            goto error_end;
slouken@1662
  1752
        }
slouken@1662
  1753
    }
slouken@0
  1754
slouken@1662
  1755
    if ((flag & SDL_HWSURFACE) == SDL_HWSURFACE) {
slouken@1662
  1756
        /* Check to see whether the surface actually ended up
slouken@1662
  1757
           in video memory, and fail if not.  We expect the
slouken@1662
  1758
           surfaces we create here to actually be in hardware!
slouken@1662
  1759
         */
slouken@1668
  1760
        result = IDirectDrawSurface3_GetCaps(dd_surface3, &ddsd.ddsCaps);
slouken@1662
  1761
        if (result != DD_OK) {
slouken@1668
  1762
            SetDDerror("DirectDrawSurface3::GetCaps", result);
slouken@1662
  1763
            goto error_end;
slouken@1662
  1764
        }
slouken@1662
  1765
        if ((ddsd.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY) !=
slouken@1662
  1766
            DDSCAPS_VIDEOMEMORY) {
slouken@1668
  1767
            SDL_SetError("No room in video memory");
slouken@1662
  1768
            goto error_end;
slouken@1662
  1769
        }
slouken@1662
  1770
    } else {
slouken@1662
  1771
        /* Try to hook our surface memory */
slouken@1662
  1772
        ddsd.dwFlags = DDSD_LPSURFACE;
slouken@1662
  1773
        ddsd.lpSurface = surface->pixels;
slouken@1668
  1774
        result = IDirectDrawSurface3_SetSurfaceDesc(dd_surface3, &ddsd, 0);
slouken@1662
  1775
        if (result != DD_OK) {
slouken@1668
  1776
            SetDDerror("DirectDraw2::SetSurfaceDesc", result);
slouken@1662
  1777
            goto error_end;
slouken@1662
  1778
        }
slouken@0
  1779
slouken@1662
  1780
    }
slouken@0
  1781
slouken@1662
  1782
    /* Make sure the surface format was set properly */
slouken@1668
  1783
    SDL_memset(&ddsd, 0, sizeof(ddsd));
slouken@1668
  1784
    ddsd.dwSize = sizeof(ddsd);
slouken@1668
  1785
    result = IDirectDrawSurface3_Lock(dd_surface3, NULL,
slouken@1668
  1786
                                      &ddsd,
slouken@1668
  1787
                                      (DDLOCK_NOSYSLOCK | DDLOCK_WAIT), NULL);
slouken@1662
  1788
    if (result != DD_OK) {
slouken@1668
  1789
        SetDDerror("DirectDrawSurface3::Lock", result);
slouken@1662
  1790
        goto error_end;
slouken@1662
  1791
    }
slouken@1668
  1792
    IDirectDrawSurface3_Unlock(dd_surface3, NULL);
slouken@1662
  1793
slouken@1662
  1794
    if ((flag & SDL_HWSURFACE) == SDL_SWSURFACE) {
slouken@1662
  1795
        if (ddsd.lpSurface != surface->pixels) {
slouken@1668
  1796
            SDL_SetError("DDraw didn't use SDL surface memory");
slouken@1662
  1797
            goto error_end;
slouken@1662
  1798
        }
slouken@1662
  1799
        if (
slouken@0
  1800
#if defined(NONAMELESSUNION)
slouken@1662
  1801
               ddsd.u1.lPitch
slouken@0
  1802
#else
slouken@1662
  1803
               ddsd.lPitch
slouken@0
  1804
#endif
slouken@1662
  1805
               != (LONG) surface->pitch) {
slouken@1668
  1806
            SDL_SetError("DDraw created surface with wrong pitch");
slouken@1662
  1807
            goto error_end;
slouken@1662
  1808
        }
slouken@1662
  1809
    } else {
slouken@0
  1810
#if defined(NONAMELESSUNION)
slouken@1662
  1811
        surface->pitch = (Uint16) ddsd.u1.lPitch;
slouken@0
  1812
#else
slouken@1662
  1813
        surface->pitch = (Uint16) ddsd.lPitch;
slouken@0
  1814
#endif
slouken@1662
  1815
    }
slouken@0
  1816
#if defined(NONAMELESSUNION)
slouken@1662
  1817
    if ((ddsd.ddpfPixelFormat.u1.dwRGBBitCount !=
slouken@1662
  1818
         surface->format->BitsPerPixel) ||
slouken@1662
  1819
        (ddsd.ddpfPixelFormat.u2.dwRBitMask != surface->format->Rmask) ||
slouken@1662
  1820
        (ddsd.ddpfPixelFormat.u3.dwGBitMask != surface->format->Gmask) ||
slouken@1662
  1821
        (ddsd.ddpfPixelFormat.u4.dwBBitMask != surface->format->Bmask)) {
slouken@0
  1822
#else
slouken@1662
  1823
    if ((ddsd.ddpfPixelFormat.dwRGBBitCount !=
slouken@1662
  1824
         surface->format->BitsPerPixel) ||
slouken@1662
  1825
        (ddsd.ddpfPixelFormat.dwRBitMask != surface->format->Rmask) ||
slouken@1662
  1826
        (ddsd.ddpfPixelFormat.dwGBitMask != surface->format->Gmask) ||
slouken@1662
  1827
        (ddsd.ddpfPixelFormat.dwBBitMask != surface->format->Bmask)) {
slouken@0
  1828
#endif
slouken@1668
  1829
        SDL_SetError("DDraw didn't use SDL surface description");
slouken@1662
  1830
        goto error_end;
slouken@1662
  1831
    }
slouken@1662
  1832
    if ((ddsd.dwWidth != (DWORD) surface->w) ||
slouken@1662
  1833
        (ddsd.dwHeight != (DWORD) surface->h)) {
slouken@1668
  1834
        SDL_SetError("DDraw created surface with wrong size");
slouken@1662
  1835
        goto error_end;
slouken@1662
  1836
    }
slouken@0
  1837
slouken@1662
  1838
    /* Set the surface private data */
slouken@1662
  1839
    surface->flags |= flag;
slouken@1662
  1840
    surface->hwdata->dd_surface = dd_surface3;
slouken@1662
  1841
    if ((surface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) {
slouken@1662
  1842
        LPDIRECTDRAWSURFACE3 dd_writebuf;
slouken@0
  1843
slouken@1662
  1844
        ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
slouken@1668
  1845
        result = IDirectDrawSurface3_GetAttachedSurface(dd_surface3,
slouken@1668
  1846
                                                        &ddsd.ddsCaps,
slouken@1668
  1847
                                                        &dd_writebuf);
slouken@1662
  1848
        if (result != DD_OK) {
slouken@1668
  1849
            SetDDerror("DirectDrawSurface3::GetAttachedSurface", result);
slouken@1662
  1850
        } else {
slouken@1662
  1851
            dd_surface3 = dd_writebuf;
slouken@1662
  1852
        }
slouken@1662
  1853
    }
slouken@1662
  1854
    surface->hwdata->dd_writebuf = dd_surface3;
slouken@0
  1855
slouken@1662
  1856
    /* We're ready to go! */
slouken@1662
  1857
    return (0);
slouken@0
  1858
slouken@1662
  1859
    /* Okay, so goto's are cheesy, but there are so many possible
slouken@1662
  1860
       errors in this function, and the cleanup is the same in 
slouken@1662
  1861
       every single case.  Is there a better way, other than deeply
slouken@1662
  1862
       nesting the code?
slouken@1662
  1863
     */
slouken@1662
  1864
  error_end:
slouken@1662
  1865
    if ((dd_surface3 != NULL) && (dd_surface3 != requested)) {
slouken@1668
  1866
        IDirectDrawSurface_Release(dd_surface3);
slouken@1662
  1867
    }
slouken@1668
  1868
    SDL_free(surface->hwdata);
slouken@1662
  1869
    surface->hwdata = NULL;
slouken@1662
  1870
    return (-1);
slouken@0
  1871
}
slouken@0
  1872
slouken@1662
  1873
static int
slouken@1668
  1874
DX5_AllocHWSurface(_THIS, SDL_Surface * surface)
slouken@0
  1875
{
slouken@1662
  1876
    /* DDraw limitation -- you need to set cooperative level first */
slouken@1662
  1877
    if (SDL_primary == NULL) {
slouken@1668
  1878
        SDL_SetError("You must set a non-GL video mode first");
slouken@1662
  1879
        return (-1);
slouken@1662
  1880
    }
slouken@1668
  1881
    return (DX5_AllocDDSurface(this, surface, NULL, SDL_HWSURFACE));
slouken@0
  1882
}
slouken@0
  1883
slouken@1
  1884
#ifdef DDRAW_DEBUG
slouken@1662
  1885
void
slouken@1668
  1886
PrintSurface(char *title, LPDIRECTDRAWSURFACE3 surface, Uint32 flags)
slouken@0
  1887
{
slouken@1662
  1888
    DDSURFACEDESC ddsd;
slouken@1662
  1889
slouken@1662
  1890
    /* Lock and load! */
slouken@1668
  1891
    SDL_memset(&ddsd, 0, sizeof(ddsd));
slouken@1668
  1892
    ddsd.dwSize = sizeof(ddsd);
slouken@1668
  1893
    if (IDirectDrawSurface3_Lock(surface, NULL, &ddsd,
slouken@1668
  1894
                                 (DDLOCK_NOSYSLOCK | DDLOCK_WAIT),
slouken@1668
  1895
                                 NULL) != DD_OK) {
slouken@1662
  1896
        return;
slouken@1662
  1897
    }
slouken@1668
  1898
    IDirectDrawSurface3_Unlock(surface, NULL);
slouken@0
  1899
slouken@1668
  1900
    fprintf(stderr, "%s:\n", title);
slouken@1668
  1901
    fprintf(stderr, "\tSize: %dx%d in %s at %ld bpp (pitch = %ld)\n",
slouken@1668
  1902
            ddsd.dwWidth, ddsd.dwHeight,
slouken@1668
  1903
            (flags & SDL_HWSURFACE) ? "hardware" : "software",
slouken@0
  1904
#if defined(NONAMELESSUNION)
slouken@1668
  1905
            ddsd.ddpfPixelFormat.u1.dwRGBBitCount, ddsd.u1.lPitch);
slouken@0
  1906
#else
slouken@1668
  1907
            ddsd.ddpfPixelFormat.dwRGBBitCount, ddsd.lPitch);
slouken@0
  1908
#endif
slouken@1668
  1909
    fprintf(stderr, "\tR = 0x%X, G = 0x%X, B = 0x%X\n",
slouken@0
  1910
#if defined(NONAMELESSUNION)
slouken@1668
  1911
            ddsd.ddpfPixelFormat.u2.dwRBitMask,
slouken@1668
  1912
            ddsd.ddpfPixelFormat.u3.dwGBitMask,
slouken@1668
  1913
            ddsd.ddpfPixelFormat.u4.dwBBitMask);
slouken@0
  1914
#else
slouken@1668
  1915
            ddsd.ddpfPixelFormat.dwRBitMask,
slouken@1668
  1916
            ddsd.ddpfPixelFormat.dwGBitMask, ddsd.ddpfPixelFormat.dwBBitMask);
slouken@0
  1917
#endif
slouken@0
  1918
}
slouken@1
  1919
#endif /* DDRAW_DEBUG */
slouken@0
  1920
slouken@1662
  1921
static int
slouken@1668
  1922
DX5_HWAccelBlit(SDL_Surface * src, SDL_Rect * srcrect,
slouken@1668
  1923
                SDL_Surface * dst, SDL_Rect * dstrect)
slouken@0
  1924
{
slouken@1662
  1925
    LPDIRECTDRAWSURFACE3 src_surface;
slouken@1662
  1926
    LPDIRECTDRAWSURFACE3 dst_surface;
slouken@1662
  1927
    DWORD flags;
slouken@1662
  1928
    RECT rect;
slouken@1662
  1929
    HRESULT result;
slouken@0
  1930
slouken@1662
  1931
    /* Set it up.. the desination must have a DDRAW surface */
slouken@1662
  1932
    src_surface = src->hwdata->dd_writebuf;
slouken@1662
  1933
    dst_surface = dst->hwdata->dd_writebuf;
slouken@1662
  1934
    rect.top = (LONG) srcrect->y;
slouken@1662
  1935
    rect.bottom = (LONG) srcrect->y + srcrect->h;
slouken@1662
  1936
    rect.left = (LONG) srcrect->x;
slouken@1662
  1937
    rect.right = (LONG) srcrect->x + srcrect->w;
slouken@1662
  1938
    if ((src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY)
slouken@1662
  1939
        flags = DDBLTFAST_SRCCOLORKEY;
slouken@1662
  1940
    else
slouken@1662
  1941
        flags = DDBLTFAST_NOCOLORKEY;
slouken@1662
  1942
    /* FIXME:  We can remove this flag for _really_ fast blit queuing,
slouken@1662
  1943
       but it will affect the return values of locks and flips.
slouken@1662
  1944
     */
slouken@1662
  1945
    flags |= DDBLTFAST_WAIT;
slouken@0
  1946
slouken@1662
  1947
    /* Do the blit! */
slouken@1668
  1948
    result = IDirectDrawSurface3_BltFast(dst_surface,
slouken@1668
  1949
                                         dstrect->x, dstrect->y, src_surface,
slouken@1668
  1950
                                         &rect, flags);
slouken@1662
  1951
    if (result != DD_OK) {
slouken@1662
  1952
        if (result == DDERR_SURFACELOST) {
slouken@1668
  1953
            result = IDirectDrawSurface3_Restore(src_surface);
slouken@1668
  1954
            result = IDirectDrawSurface3_Restore(dst_surface);
slouken@1662
  1955
            /* The surfaces need to be reloaded with artwork */
slouken@1668
  1956
            SDL_SetError("Blit surfaces were lost, reload them");
slouken@1662
  1957
            return (-2);
slouken@1662
  1958
        }
slouken@1668
  1959
        SetDDerror("IDirectDrawSurface3::BltFast", result);
slouken@0
  1960
#ifdef DDRAW_DEBUG
slouken@1668
  1961
        fprintf(stderr, "Original dest rect: %dx%d at %d,%d\n", dstrect->w,
slouken@1668
  1962
                dstrect->h, dstrect->x, dstrect->y);
slouken@1668
  1963
        fprintf(stderr,
slouken@1668
  1964
                "HW accelerated %sblit to from 0x%p to 0x%p at (%d,%d)\n",
slouken@1668
  1965
                (src->flags & SDL_SRCCOLORKEY) ? "colorkey " : "", src,
slouken@1668
  1966
                dst, dstrect->x, dstrect->y);
slouken@1668
  1967
        PrintSurface("SRC", src_surface, src->flags);
slouken@1668
  1968
        PrintSurface("DST", dst_surface, dst->flags);
slouken@1668
  1969
        fprintf(stderr, "Source rectangle: (%d,%d) - (%d,%d)\n",
slouken@1668
  1970
                rect.left, rect.top, rect.right, rect.bottom);
slouken@0
  1971
#endif
slouken@1662
  1972
        /* Unexpected error, fall back to software blit */
slouken@1668
  1973
        return (src->map->sw_blit(src, srcrect, dst, dstrect));
slouken@1662
  1974
    }
slouken@1662
  1975
    return (0);
slouken@0
  1976
}
slouken@0
  1977
slouken@1662
  1978
static int
slouken@1668
  1979
DX5_CheckHWBlit(_THIS, SDL_Surface * src, SDL_Surface * dst)
slouken@0
  1980
{
slouken@1662
  1981
    int accelerated;
slouken@0
  1982
slouken@1662
  1983
    /* We need to have a DDraw surface for HW blits */
slouken@1662
  1984
    if ((src->flags & SDL_HWSURFACE) == SDL_SWSURFACE) {
slouken@1662
  1985
        /* Allocate a DDraw surface for the blit */
slouken@1662
  1986
        if (src->hwdata == NULL) {
slouken@1668
  1987
            DX5_AllocDDSurface(this, src, NULL, SDL_SWSURFACE);
slouken@1662
  1988
        }
slouken@1662
  1989
    }
slouken@1662
  1990
    if (src->hwdata == NULL) {
slouken@1662
  1991
        return (0);
slouken@1662
  1992
    }
slouken@0
  1993
slouken@1662
  1994
    /* Set initial acceleration on */
slouken@1662
  1995
    src->flags |= SDL_HWACCEL;
slouken@0
  1996
slouken@1662
  1997
    /* Set the surface attributes */
slouken@1662
  1998
    if ((src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) {
slouken@1668
  1999
        if (DX5_SetHWColorKey(this, src, src->format->colorkey) < 0) {
slouken@1662
  2000
            src->flags &= ~SDL_HWACCEL;
slouken@1662
  2001
        }
slouken@1662
  2002
    }
slouken@1662
  2003
    if ((src->flags & SDL_SRCALPHA) == SDL_SRCALPHA) {
slouken@1668
  2004
        if (DX5_SetHWAlpha(this, src, src->format->alpha) < 0) {
slouken@1662
  2005
            src->flags &= ~SDL_HWACCEL;
slouken@1662
  2006
        }
slouken@1662
  2007
    }
slouken@0
  2008
slouken@1662
  2009
    /* Check to see if final surface blit is accelerated */
slouken@1662
  2010
    accelerated = !!(src->flags & SDL_HWACCEL);
slouken@1662
  2011
    if (accelerated) {
slouken@0
  2012
#ifdef DDRAW_DEBUG
slouken@1668
  2013
        fprintf(stderr, "Setting accelerated blit on 0x%p\n", src);
slouken@0
  2014
#endif
slouken@1662
  2015
        src->map->hw_blit = DX5_HWAccelBlit;
slouken@1662
  2016
    }
slouken@1662
  2017
    return (accelerated);
slouken@0
  2018
}
slouken@0
  2019
slouken@1662
  2020
static int
slouken@1668
  2021
DX5_FillHWRect(_THIS, SDL_Surface * dst, SDL_Rect * dstrect, Uint32 color)
slouken@0
  2022
{
slouken@1662
  2023
    LPDIRECTDRAWSURFACE3 dst_surface;
slouken@1662
  2024
    RECT area;
slouken@1662
  2025
    DDBLTFX bltfx;
slouken@1662
  2026
    HRESULT result;
slouken@0
  2027
slouken@0
  2028
#ifdef DDRAW_DEBUG
slouken@1668
  2029
    fprintf(stderr, "HW accelerated fill at (%d,%d)\n", dstrect->x,
slouken@1668
  2030
            dstrect->y);
slouken@0
  2031
#endif
slouken@1662
  2032
    dst_surface = dst->hwdata->dd_writebuf;
slouken@1662
  2033
    area.top = (LONG) dstrect->y;
slouken@1662
  2034
    area.bottom = (LONG) dstrect->y + dstrect->h;
slouken@1662
  2035
    area.left = (LONG) dstrect->x;
slouken@1662
  2036
    area.right = (LONG) dstrect->x + dstrect->w;
slouken@1668
  2037
    bltfx.dwSize = sizeof(bltfx);
slouken@0
  2038
#if defined(NONAMELESSUNION)
slouken@1662
  2039
    bltfx.u5.dwFillColor = color;
slouken@0
  2040
#else
slouken@1662
  2041
    bltfx.dwFillColor = color;
slouken@0
  2042
#endif
slouken@1668
  2043
    result = IDirectDrawSurface3_Blt(dst_surface,
slouken@1668
  2044
                                     &area, NULL, NULL,
slouken@1668
  2045
                                     DDBLT_COLORFILL | DDBLT_WAIT, &bltfx);
slouken@1662
  2046
    if (result == DDERR_SURFACELOST) {
slouken@1668
  2047
        IDirectDrawSurface3_Restore(dst_surface);
slouken@1668
  2048
        result = IDirectDrawSurface3_Blt(dst_surface,
slouken@1668
  2049
                                         &area, NULL, NULL,
slouken@1668
  2050
                                         DDBLT_COLORFILL | DDBLT_WAIT,
slouken@1668
  2051
                                         &bltfx);
slouken@1662
  2052
    }
slouken@1662
  2053
    if (result != DD_OK) {
slouken@1668
  2054
        SetDDerror("IDirectDrawSurface3::Blt", result);
slouken@1662
  2055
        return (-1);
slouken@1662
  2056
    }
slouken@1662
  2057
    return (0);
slouken@0
  2058
}
slouken@0
  2059
slouken@1662
  2060
static int
slouken@1668
  2061
DX5_SetHWColorKey(_THIS, SDL_Surface * surface, Uint32 key)
slouken@0
  2062
{
slouken@1662
  2063
    DDCOLORKEY colorkey;
slouken@1662
  2064
    HRESULT result;
slouken@0
  2065
slouken@1662
  2066
    /* Set the surface colorkey */
slouken@1662
  2067
    colorkey.dwColorSpaceLowValue = key;
slouken@1662
  2068
    colorkey.dwColorSpaceHighValue = key;
slouken@1662
  2069
    result =
slouken@1668
  2070
        IDirectDrawSurface3_SetColorKey(surface->hwdata->dd_surface,
slouken@1668
  2071
                                        DDCKEY_SRCBLT, &colorkey);
slouken@1662
  2072
    if (result != DD_OK) {
slouken@1668
  2073
        SetDDerror("IDirectDrawSurface3::SetColorKey", result);
slouken@1662
  2074
        return (-1);
slouken@1662
  2075
    }
slouken@1662
  2076
    return (0);
slouken@0
  2077
}
slouken@1662
  2078
static int
slouken@1668
  2079
DX5_SetHWAlpha(_THIS, SDL_Surface * surface, Uint8 alpha)
slouken@0
  2080
{
slouken@1662
  2081
    return (-1);
slouken@0
  2082
}
slouken@0
  2083
slouken@1662
  2084
static int
slouken@1668
  2085
DX5_LockHWSurface(_THIS, SDL_Surface * surface)
slouken@0
  2086
{
slouken@1662
  2087
    HRESULT result;
slouken@1662
  2088
    LPDIRECTDRAWSURFACE3 dd_surface;
slouken@1662
  2089
    DDSURFACEDESC ddsd;
slouken@0
  2090
slouken@1662
  2091
    /* Lock and load! */
slouken@1662
  2092
    dd_surface = surface->hwdata->dd_writebuf;
slouken@1668
  2093
    SDL_memset(&ddsd, 0, sizeof(ddsd));
slouken@1668
  2094
    ddsd.dwSize = sizeof(ddsd);
slouken@1668
  2095
    result = IDirectDrawSurface3_Lock(dd_surface, NULL, &ddsd,
slouken@1668
  2096
                                      (DDLOCK_NOSYSLOCK | DDLOCK_WAIT), NULL);
slouken@1662
  2097
    if (result == DDERR_SURFACELOST) {
slouken@1668
  2098
        result = IDirectDrawSurface3_Restore(surface->hwdata->dd_surface);
slouken@1668
  2099
        result = IDirectDrawSurface3_Lock(dd_surface, NULL, &ddsd,
slouken@1668
  2100
                                          (DDLOCK_NOSYSLOCK | DDLOCK_WAIT),
slouken@1668
  2101
                                          NULL);
slouken@1662
  2102
    }
slouken@1662
  2103
    if (result != DD_OK) {
slouken@1668
  2104
        SetDDerror("DirectDrawSurface3::Lock", result);
slouken@1662
  2105
        return (-1);
slouken@1662
  2106
    }
slouken@1662
  2107
    /* Pitch might have changed -- recalculate pitch and offset */
slouken@0
  2108
#if defined(NONAMELESSUNION)
slouken@1662
  2109
    if (surface->pitch != ddsd.u1.lPitch) {
slouken@1662
  2110
        surface->pitch = ddsd.u1.lPitch;
slouken@0
  2111
#else
slouken@1662
  2112
    if (surface->pitch != ddsd.lPitch) {
slouken@1662
  2113
        surface->pitch = (Uint16) ddsd.lPitch;
slouken@0
  2114
#endif
slouken@1662
  2115
        surface->offset =
slouken@1662
  2116
            ((ddsd.dwHeight - surface->h) / 2) * surface->pitch +
slouken@1662
  2117
            ((ddsd.dwWidth - surface->w) / 2) *
slouken@1662
  2118
            surface->format->BytesPerPixel;
slouken@1662
  2119
    }
slouken@1662
  2120
    surface->pixels = ddsd.lpSurface;
slouken@1662
  2121
    return (0);
slouken@0
  2122
}
slouken@0
  2123
slouken@1662
  2124
static void
slouken@1668
  2125
DX5_UnlockHWSurface(_THIS, SDL_Surface * surface)
slouken@0
  2126
{
slouken@1668
  2127
    IDirectDrawSurface3_Unlock(surface->hwdata->dd_writebuf, NULL);
slouken@1662
  2128
    surface->pixels = NULL;
slouken@1662
  2129
}
slouken@0
  2130
slouken@1662
  2131
static int
slouken@1668
  2132
DX5_FlipHWSurface(_THIS, SDL_Surface * surface)
slouken@1662
  2133
{
slouken@1662
  2134
    HRESULT result;
slouken@1662
  2135
    LPDIRECTDRAWSURFACE3 dd_surface;
slouken@809
  2136
slouken@1662
  2137
    dd_surface = surface->hwdata->dd_surface;
slouken@809
  2138
slouken@1662
  2139
    /* to prevent big slowdown on fast computers, wait here instead of driver ring 0 code */
slouken@1662
  2140
    /* Dmitry Yakimov (ftech@tula.net) */
slouken@1668
  2141
    while (IDirectDrawSurface3_GetFlipStatus(dd_surface, DDGBS_ISBLTDONE) ==
slouken@1662
  2142
           DDERR_WASSTILLDRAWING);
slouken@1662
  2143
slouken@1668
  2144
    result = IDirectDrawSurface3_Flip(dd_surface, NULL, DDFLIP_WAIT);
slouken@1662
  2145
    if (result == DDERR_SURFACELOST) {
slouken@1668
  2146
        result = IDirectDrawSurface3_Restore(surface->hwdata->dd_surface);
slouken@1662
  2147
        while (IDirectDrawSurface3_GetFlipStatus
slouken@1662
  2148
               (dd_surface, DDGBS_ISBLTDONE) == DDERR_WASSTILLDRAWING);
slouken@1668
  2149
        result = IDirectDrawSurface3_Flip(dd_surface, NULL, DDFLIP_WAIT);
slouken@1662
  2150
    }
slouken@1662
  2151
    if (result != DD_OK) {
slouken@1668
  2152
        SetDDerror("DirectDrawSurface3::Flip", result);
slouken@1662
  2153
        return (-1);
slouken@1662
  2154
    }
slouken@1662
  2155
    return (0);
slouken@0
  2156
}
slouken@0
  2157
slouken@1662
  2158
static void
slouken@1668
  2159
DX5_FreeHWSurface(_THIS, SDL_Surface * surface)
slouken@0
  2160
{
slouken@1662
  2161
    if (surface->hwdata) {
slouken@1662
  2162
        if (surface->hwdata->dd_surface != SDL_primary) {
slouken@1668
  2163
            IDirectDrawSurface3_Release(surface->hwdata->dd_surface);
slouken@1662
  2164
        }
slouken@1668
  2165
        SDL_free(surface->hwdata);
slouken@1662
  2166
        surface->hwdata = NULL;
slouken@1662
  2167
    }
slouken@0
  2168
}
slouken@0
  2169
slouken@1662
  2170
void
slouken@1668
  2171
DX5_WindowUpdate(_THIS, int numrects, SDL_Rect * rects)
slouken@0
  2172
{
slouken@1662
  2173
    HRESULT result;
slouken@1662
  2174
    int i;
slouken@1662
  2175
    RECT src, dst;
slouken@0
  2176
slouken@1662
  2177
    for (i = 0; i < numrects; ++i) {
slouken@1662
  2178
        src.top = (LONG) rects[i].y;
slouken@1662
  2179
        src.bottom = (LONG) rects[i].y + rects[i].h;
slouken@1662
  2180
        src.left = (LONG) rects[i].x;
slouken@1662
  2181
        src.right = (LONG) rects[i].x + rects[i].w;
slouken@1662
  2182
        dst.top = SDL_bounds.top + src.top;
slouken@1662
  2183
        dst.left = SDL_bounds.left + src.left;
slouken@1662
  2184
        dst.bottom = SDL_bounds.top + src.bottom;
slouken@1662
  2185
        dst.right = SDL_bounds.left + src.right;
slouken@1668
  2186
        result = IDirectDrawSurface3_Blt(SDL_primary, &dst,
slouken@1668
  2187
                                         this->screen->hwdata->dd_surface,
slouken@1668
  2188
                                         &src, DDBLT_WAIT, NULL);
slouken@1662
  2189
        /* Doh!  Check for lost surface and restore it */
slouken@1662
  2190
        if (result == DDERR_SURFACELOST) {
slouken@1668
  2191
            IDirectDrawSurface3_Restore(SDL_primary);
slouken@1668
  2192
            IDirectDrawSurface3_Blt(SDL_primary, &dst,
slouken@1668
  2193
                                    this->screen->hwdata->dd_surface,
slouken@1668
  2194
                                    &src, DDBLT_WAIT, NULL);
slouken@1662
  2195
        }
slouken@1662
  2196
    }
slouken@0
  2197
}
slouken@0
  2198
slouken@1662
  2199
void
slouken@1668
  2200
DX5_DirectUpdate(_THIS, int numrects, SDL_Rect * rects)
slouken@0
  2201
{
slouken@0
  2202
}
slouken@0
  2203
slouken@0
  2204
/* Compress a full palette into the limited number of colors given to us
slouken@0
  2205
   by windows.
slouken@0
  2206
slouken@0
  2207
   The "best" way to do this is to sort the colors by diversity and place
slouken@0
  2208
   the most diverse colors into the limited palette.  Unfortunately this
slouken@0
  2209
   results in widely varying colors being displayed in the interval during
slouken@0
  2210
   which the windows palette has been set, and the mapping of the shadow
slouken@0
  2211
   surface to the new palette.  This is especially noticeable during fades.
slouken@0
  2212
slouken@0
  2213
   To deal with this problem, we can copy a predetermined portion of the
slouken@0
  2214
   full palette, and use that as the limited palette.  This allows colors
slouken@0
  2215
   to fade smoothly as the remapping is very similar on each palette change.
slouken@0
  2216
   Unfortunately, this breaks applications which partition the palette into
slouken@0
  2217
   distinct and widely varying areas, expecting all colors to be available.
slouken@0
  2218
slouken@0
  2219
   I'm making them both available, chosen at compile time.
slouken@0
  2220
   If you want the chunk-o-palette algorithm, define SIMPLE_COMPRESSION,
slouken@0
  2221
   otherwise the sort-by-diversity algorithm will be used.
slouken@0
  2222
*/
slouken@0
  2223
#define SIMPLE_COMPRESSION
slouken@0
  2224
#define CS_CS_DIST(A, B) ({						\
slouken@0
  2225
	int r = (A.r - B.r);						\
slouken@0
  2226
	int g = (A.g - B.g);						\
slouken@0
  2227
	int b = (A.b - B.b);						\
slouken@0
  2228
	(r*r + g*g + b*b);						\
slouken@0
  2229
})
slouken@1662
  2230
static void
slouken@1668
  2231
DX5_CompressPalette(_THIS, SDL_Color * colors, int ncolors, int maxcolors)
slouken@0
  2232
{
slouken@0
  2233
#ifdef SIMPLE_COMPRESSION
slouken@1662
  2234
    int i, j;
slouken@0
  2235
#else
slouken@1662
  2236
    static SDL_Color zero = { 0, 0, 0, 0 };
slouken@1662
  2237
    int i, j;
slouken@1662
  2238
    int max, dist;
slouken@1662
  2239
    int prev, next;
slouken@1662
  2240
    int *pool;
slouken@1662
  2241
    int *seen, *order;
slouken@0
  2242
#endif
slouken@0
  2243
slouken@1662
  2244
    /* Does this happen? */
slouken@1662
  2245
    if (maxcolors > ncolors) {
slouken@1662
  2246
        maxcolors = ncolors;
slouken@1662
  2247
    }
slouken@0
  2248
#ifdef SIMPLE_COMPRESSION
slouken@1662
  2249
    /* Just copy the first "maxcolors" colors */
slouken@1662
  2250
    for (j = 10, i = 0; i < maxcolors; ++i, ++j) {
slouken@1662
  2251
        SDL_colors[j].peRed = colors[i].r;
slouken@1662
  2252
        SDL_colors[j].peGreen = colors[i].g;
slouken@1662
  2253
        SDL_colors[j].peBlue = colors[i].b;
slouken@1662
  2254
    }
slouken@0
  2255
#else
slouken@1662
  2256
    /* Allocate memory for the arrays we use */
slouken@1668
  2257
    pool = SDL_stack_alloc(int, 2 * ncolors);
slouken@1662
  2258
    if (pool == NULL) {
slouken@1662
  2259
        /* No worries, just return */ ;
slouken@1662
  2260
        return;
slouken@1662
  2261
    }
slouken@1662
  2262
    seen = pool;
slouken@1668
  2263
    SDL_memset(seen, 0, ncolors * sizeof(int));
slouken@1662
  2264
    order = pool + ncolors;
slouken@0
  2265
slouken@1662
  2266
    /* Start with the brightest color */
slouken@1662
  2267
    max = 0;
slouken@1662
  2268
    for (i = 0; i < ncolors; ++i) {
slouken@1668
  2269
        dist = CS_CS_DIST(zero, colors[i]);
slouken@1662
  2270
        if (dist >= max) {
slouken@1662
  2271
            max = dist;
slouken@1662
  2272
            next = i;
slouken@1662
  2273
        }
slouken@1662
  2274
    }
slouken@1662
  2275
    j = 0;
slouken@1662
  2276
    order[j++] = next;
slouken@1662
  2277
    seen[next] = 1;
slouken@1662
  2278
    prev = next;
slouken@0
  2279
slouken@1662
  2280
    /* Keep going through all the colors */
slouken@1662
  2281
    while (j < maxcolors) {
slouken@1662
  2282
        max = 0;
slouken@1662
  2283
        for (i = 0; i < ncolors; ++i) {
slouken@1662
  2284
            if (seen[i]) {
slouken@1662
  2285
                continue;
slouken@1662
  2286
            }
slouken@1668
  2287
            dist = CS_CS_DIST(colors[i], colors[prev]);
slouken@1662
  2288
            if (dist >= max) {
slouken@1662
  2289
                max = dist;
slouken@1662
  2290
                next = i;
slouken@1662
  2291
            }
slouken@1662
  2292
        }
slouken@1662
  2293
        order[j++] = next;
slouken@1662
  2294
        seen[next] = 1;
slouken@1662
  2295
        prev = next;
slouken@1662
  2296
    }
slouken@0
  2297
slouken@1662
  2298
    /* Compress the colors to the palette */
slouken@1662
  2299
    for (j = 10, i = 0; i < maxcolors; ++i, ++j) {
slouken@1662
  2300
        SDL_colors[j].peRed = colors[order[i]].r;
slouken@1662
  2301
        SDL_colors[j].peGreen = colors[order[i]].g;
slouken@1662
  2302
        SDL_colors[j].peBlue = colors[order[i]].b;
slouken@1662
  2303
    }
slouken@1668
  2304
    SDL_stack_free(pool);
slouken@0
  2305
#endif /* SIMPLE_COMPRESSION */
slouken@0
  2306
}
slouken@0
  2307
slouken@0
  2308
/* Set the system colormap in both fullscreen and windowed modes */
slouken@1662
  2309
int
slouken@1668
  2310
DX5_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color * colors)
slouken@0
  2311
{
slouken@1662
  2312
    int i;
slouken@1662
  2313
    int alloct_all;
slouken@0
  2314
slouken@1662
  2315
    /* Copy palette colors into display palette */