~ubuntu-branches/ubuntu/dapper/vice/dapper

« back to all changes in this revision

Viewing changes to src/arch/win32/fullscreen.c

  • Committer: Bazaar Package Importer
  • Author(s): Zed Pobre
  • Date: 2004-08-26 13:35:51 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20040826133551-gcje8j31q5cqgdq2
Tags: 1.14-3
Apply patch from Spiro Trikaliotis <vice@trikaliotis.net> to fix a
problem that some users were experiencing with a floating point
exception on startup related to the fullscreen option being enabled
during compile.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * fullscreen.c - Fullscreen related support functions for Win32
3
 
 *
4
 
 * Written by
5
 
 *  Tibor Biczo <crown@matavnet.hu>
6
 
 *
7
 
 * This file is part of VICE, the Versatile Commodore Emulator.
8
 
 * See README for copyright notice.
9
 
 *
10
 
 *  This program is free software; you can redistribute it and/or modify
11
 
 *  it under the terms of the GNU General Public License as published by
12
 
 *  the Free Software Foundation; either version 2 of the License, or
13
 
 *  (at your option) any later version.
14
 
 *
15
 
 *  This program is distributed in the hope that it will be useful,
16
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 
 *  GNU General Public License for more details.
19
 
 *
20
 
 *  You should have received a copy of the GNU General Public License
21
 
 *  along with this program; if not, write to the Free Software
22
 
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
23
 
 *  02111-1307  USA.
24
 
 *
25
 
 */
26
 
 
27
 
#include "vice.h"
28
 
 
29
 
#include <stdlib.h>
30
 
 
31
 
#include <windows.h>
32
 
#include <ddraw.h>
33
 
#include <mmsystem.h>
34
 
#include <prsht.h>
35
 
#include "res.h"
36
 
#include "ui.h"
37
 
#include "winmain.h"
38
 
#include "palette.h"
39
 
#include "resources.h"
40
 
#include "raster.h"
41
 
#include "utils.h"
42
 
#include "log.h"
43
 
#include "videoarch.h"
44
 
#include "statusbar.h"
45
 
 
46
 
raster_t *video_find_raster_for_canvas(video_canvas_t *canvas);
47
 
 
48
 
 
49
 
// ----------------------------------------------
50
 
 
51
 
#ifndef HAVE_GUIDLIB
52
 
const GUID IID_IDirectDraw2={0xB3A6F3E0,0x2B43,0x11CF,
53
 
{0xA2,0xDE,0x00,0xAA,0x00,0xB9,0x33,0x56}};
54
 
#endif
55
 
 
56
 
typedef struct _DDL {
57
 
    struct _DDL *next;
58
 
    int         isNullGUID;
59
 
    GUID        guid;
60
 
    LPSTR       desc;
61
 
} DirectDrawDeviceList;
62
 
 
63
 
typedef struct _ML {
64
 
    struct _ML  *next;
65
 
    int         devicenumber;
66
 
    int         width;
67
 
    int         height;
68
 
    int         bitdepth;
69
 
    int         refreshrate;
70
 
} DirectDrawModeList;
71
 
 
72
 
static  DirectDrawDeviceList    *devices=NULL;
73
 
static  DirectDrawModeList      *modes=NULL;
74
 
static  LPDIRECTDRAW            DirectDrawObject;
75
 
static  LPDIRECTDRAW2           DirectDrawObject2;
76
 
 
77
 
#define CHECK_DDRESULT(ddresult)    {\
78
 
if (ddresult!=DD_OK) {\
79
 
ui_error("DirectDraw error: Code:%8x Error:%s",ddresult,dd_error(ddresult));\
80
 
}}\
81
 
 
82
 
BOOL WINAPI DDEnumCallbackFunction(
83
 
  GUID FAR *lpGUID,           
84
 
  LPSTR  lpDriverDescription, 
85
 
  LPSTR  lpDriverName,        
86
 
  LPVOID lpContext            
87
 
)
88
 
{
89
 
DirectDrawDeviceList    *new_device;
90
 
DirectDrawDeviceList    *search_device;
91
 
 
92
 
    new_device=malloc(sizeof(DirectDrawDeviceList));
93
 
    new_device->next=NULL;
94
 
    if (lpGUID!=NULL) {
95
 
        memcpy(&new_device->guid,lpGUID,sizeof(GUID));
96
 
        new_device->isNullGUID=0;
97
 
    } else {
98
 
        new_device->isNullGUID=1;
99
 
    }
100
 
    new_device->desc=stralloc(lpDriverDescription);
101
 
    if (devices==NULL) {
102
 
        devices=new_device;
103
 
    } else {
104
 
        search_device=devices;
105
 
        while (search_device->next!=NULL) {
106
 
            search_device=search_device->next;
107
 
        }
108
 
        search_device->next=new_device;
109
 
    }
110
 
 
111
 
/*
112
 
    log_debug("--------- DirectDraw Device ---");
113
 
    log_debug("GUID: %16x",lpGUID);
114
 
    log_debug("Desc: %s",lpDriverDescription);
115
 
    log_debug("Name: %s",lpDriverName);
116
 
*/
117
 
    return DDENUMRET_OK;
118
 
}
119
 
 
120
 
HRESULT WINAPI ModeCallBack(LPDDSURFACEDESC desc, LPVOID context)
121
 
{
122
 
DirectDrawModeList  *new_mode;
123
 
DirectDrawModeList  *search_mode;
124
 
 
125
 
    new_mode=malloc(sizeof(DirectDrawModeList));
126
 
    new_mode->next=NULL;
127
 
    new_mode->devicenumber=*(int*)context;
128
 
    new_mode->width=new_mode->height=new_mode->bitdepth=new_mode->refreshrate=0;
129
 
    if (desc->dwFlags&(DDSD_WIDTH)) {
130
 
//        log_debug("Width:       %d",desc->dwWidth);
131
 
        new_mode->width=desc->dwWidth;
132
 
    }
133
 
    if (desc->dwFlags&(DDSD_HEIGHT)) {
134
 
//        log_debug("Height:      %d",desc->dwHeight);
135
 
        new_mode->height=desc->dwHeight;
136
 
    }
137
 
    if (desc->dwFlags&(DDSD_PIXELFORMAT)) {
138
 
//        log_debug("Bitdepth:    %d",desc->ddpfPixelFormat.dwRGBBitCount);
139
 
//        log_debug("Red mask:    %04x",desc->ddpfPixelFormat.dwRBitMask);
140
 
//        log_debug("Blue mask:   %04x",desc->ddpfPixelFormat.dwBBitMask);
141
 
//        log_debug("Green mask:  %04x",desc->ddpfPixelFormat.dwGBitMask);
142
 
#ifdef HAVE_UNNAMED_UNIONS
143
 
        new_mode->bitdepth=desc->ddpfPixelFormat.dwRGBBitCount;
144
 
#else
145
 
        new_mode->bitdepth=desc->ddpfPixelFormat.u1.dwRGBBitCount;
146
 
#endif
147
 
    }
148
 
    if (desc->dwFlags&(DDSD_REFRESHRATE)) {
149
 
//        log_debug("Refreshrate: %d",desc->dwRefreshRate);
150
 
#ifdef HAVE_UNNAMED_UNIONS
151
 
        new_mode->refreshrate=desc->dwRefreshRate;
152
 
#else
153
 
        new_mode->refreshrate=desc->u2.dwRefreshRate;
154
 
#endif
155
 
    }
156
 
    if (modes==NULL) {
157
 
        modes=new_mode;
158
 
    } else {
159
 
        search_mode=modes;
160
 
        while (search_mode->next!=NULL) {
161
 
            search_mode=search_mode->next;
162
 
        }
163
 
        search_mode->next=new_mode;
164
 
    }
165
 
    return DDENUMRET_OK;
166
 
}
167
 
 
168
 
void fullscreen_getmodes(void)
169
 
{
170
 
HRESULT                 ddresult;
171
 
DirectDrawDeviceList    *search_device;
172
 
int                     i;
173
 
 
174
 
    /*  Enumerate DirectDraw Devices */
175
 
    ddresult = DirectDrawEnumerate(DDEnumCallbackFunction, NULL);
176
 
 
177
 
    /*  List all available modes for all available devices */
178
 
    search_device=devices;
179
 
    i=0;
180
 
    while (search_device!=NULL) {
181
 
//        log_debug("--- Video modes for device %s",search_device->desc);
182
 
//        log_debug("MODEPROBE_Create");
183
 
        if (search_device->isNullGUID) {
184
 
            ddresult = DirectDrawCreate(NULL, &DirectDrawObject, NULL);
185
 
        } else {
186
 
            ddresult = DirectDrawCreate(&search_device->guid, &DirectDrawObject, NULL);
187
 
        }
188
 
        CHECK_DDRESULT(ddresult);
189
 
//        log_debug("MODEPROBE_SetCooperativeLevel");
190
 
        ddresult = IDirectDraw_SetCooperativeLevel(DirectDrawObject, ui_get_main_hwnd(), DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN);
191
 
        CHECK_DDRESULT(ddresult);
192
 
//        log_debug("MODEPROBE_ObtainDirectDraw2");
193
 
        ddresult=IDirectDraw_QueryInterface(DirectDrawObject,(GUID *)&IID_IDirectDraw2,(LPVOID *)&DirectDrawObject2);
194
 
        CHECK_DDRESULT(ddresult);
195
 
//        log_debug("MODEPROBE_EnumDisplayModes");
196
 
        ddresult=IDirectDraw2_EnumDisplayModes(DirectDrawObject2,DDEDM_REFRESHRATES,NULL,&i,ModeCallBack);
197
 
        CHECK_DDRESULT(ddresult);
198
 
        IDirectDraw2_Release(DirectDrawObject2);
199
 
        DirectDrawObject2=NULL;
200
 
        IDirectDraw_Release(DirectDrawObject);
201
 
        DirectDrawObject=NULL;
202
 
        search_device=search_device->next;
203
 
        i++;
204
 
    }
205
 
 
206
 
    /*  This is here because some Matrox G200 drivers don't leave the window in its previous state */
207
 
    ShowWindow(ui_get_main_hwnd(),SW_HIDE);
208
 
}
209
 
 
210
 
GUID *GetGUIDForActualDevice()
211
 
{
212
 
int                     device;
213
 
DirectDrawDeviceList    *search_device;
214
 
 
215
 
    resources_get_value("FullscreenDevice",(resource_value_t *)&device);
216
 
    search_device=devices;
217
 
    while (search_device!=NULL) {
218
 
        if (device==0) {
219
 
            if (search_device->isNullGUID) {
220
 
                return NULL;
221
 
            } else {
222
 
                return (&search_device->guid);
223
 
            }
224
 
        }
225
 
        device--;
226
 
        search_device=search_device->next;
227
 
    }
228
 
    return NULL;
229
 
}
230
 
 
231
 
void validate_mode(int *device, int *width, int *height, int *bitdepth, int *rate)
232
 
{
233
 
DirectDrawModeList  *mode;
234
 
 
235
 
//  Validate devicenumber
236
 
    mode=modes;
237
 
    while (mode!=NULL) {
238
 
        if (mode->devicenumber==*device) break;
239
 
        mode=mode->next;
240
 
    }
241
 
    if (mode==NULL) {
242
 
        *device=modes->devicenumber;
243
 
    }
244
 
 
245
 
//  Validate bitdepth
246
 
    mode=modes;
247
 
    while (mode!=NULL) {
248
 
        if ((mode->devicenumber==*device) && (mode->bitdepth==*bitdepth)) break;
249
 
        mode=mode->next;
250
 
    }
251
 
    if (mode==NULL) {
252
 
        mode=modes;
253
 
        while (mode!=NULL) {
254
 
            if (mode->devicenumber==*device) {
255
 
                *bitdepth=mode->bitdepth;
256
 
                break;
257
 
            }
258
 
            mode=mode->next;
259
 
        }
260
 
    }
261
 
 
262
 
//  Validate resolution
263
 
    mode=modes;
264
 
    while (mode!=NULL) {
265
 
        if ((mode->devicenumber==*device) && (mode->bitdepth==*bitdepth) && (mode->width==*width) && (mode->height==*height)) break;
266
 
        mode=mode->next;
267
 
    }
268
 
    if (mode==NULL) {
269
 
        mode=modes;
270
 
        while (mode!=NULL) {
271
 
            if ((mode->devicenumber==*device) && (mode->bitdepth==*bitdepth)) {
272
 
                *width=mode->width;
273
 
                *height=mode->height;
274
 
                break;
275
 
            }
276
 
            mode=mode->next;
277
 
        }
278
 
    }
279
 
 
280
 
//  Validate refreshrate
281
 
    mode=modes;
282
 
    while (mode!=NULL) {
283
 
        if ((mode->devicenumber==*device) && (mode->bitdepth==*bitdepth) && (mode->width==*width) && (mode->height==*height) && (mode->refreshrate==*rate)) break;
284
 
        mode=mode->next;
285
 
    }
286
 
    if (mode==NULL) {
287
 
        *rate=0;
288
 
    }
289
 
}
290
 
 
291
 
typedef struct _VL {
292
 
    struct _VL  *next;
293
 
    struct _VL  *prev;
294
 
    char        *text;
295
 
    int         value;
296
 
} ValueList;
297
 
 
298
 
ValueList   *bitdepthlist=NULL;
299
 
ValueList   *resolutionlist=NULL;
300
 
ValueList   *refresh_rates=NULL;
301
 
 
302
 
int         fullscreen_device=0;
303
 
int         fullscreen_bitdepth=0;
304
 
int         fullscreen_width=0;
305
 
int         fullscreen_height=0;
306
 
int         fullscreen_refreshrate=0;
307
 
 
308
 
int GetIndexFromList (ValueList *list, int value)
309
 
{
310
 
ValueList   *search;
311
 
int         pos;
312
 
 
313
 
    pos=0;
314
 
    search=list;
315
 
    while (search!=NULL) {
316
 
        if (search->value==value) return pos;
317
 
        search=search->next;
318
 
        pos++;
319
 
    }
320
 
    return -1;
321
 
}
322
 
 
323
 
int GetValueFromList (ValueList * list, int index)
324
 
{
325
 
ValueList   *search;
326
 
int         pos;
327
 
 
328
 
    search=list;
329
 
    pos=0;
330
 
    while (search!=NULL) {
331
 
        if (pos==index) return search->value;
332
 
        pos++;
333
 
        search=search->next;
334
 
    }
335
 
    return 0;
336
 
}
337
 
 
338
 
void InsertInto (ValueList **list, ValueList *value)
339
 
{
340
 
ValueList   *after;
341
 
ValueList   *before;
342
 
 
343
 
    after=*list;
344
 
    before=NULL;
345
 
    while (after!=NULL) {
346
 
        if (value->value<after->value) {
347
 
            break;
348
 
        }
349
 
        before=after;
350
 
        after=after->next;
351
 
    }
352
 
    value->prev=before;
353
 
    value->next=after;
354
 
    if (*list==NULL) {
355
 
        *list=value;
356
 
    } else if (after==NULL) {
357
 
        before->next=value;
358
 
    } else if (before==NULL) {
359
 
        after->prev=value;
360
 
        *list=value;
361
 
    } else {
362
 
        before->next=value;
363
 
        after->prev=value;
364
 
    }
365
 
}
366
 
 
367
 
void DestroyList (ValueList **list)
368
 
{
369
 
ValueList   *value;
370
 
ValueList   *value2;
371
 
 
372
 
    value=*list;
373
 
    while (value!=NULL) {
374
 
        free(value->text);
375
 
        value2=value->next;
376
 
        free(value);
377
 
        value=value2;
378
 
    }
379
 
    *list=NULL;
380
 
}
381
 
 
382
 
void get_refreshratelist(int device, int bitdepth, int width, int height)
383
 
{
384
 
DirectDrawModeList  *mode;
385
 
ValueList           *value;
386
 
char                buff[256];
387
 
 
388
 
    DestroyList(&refresh_rates);
389
 
 
390
 
    //  We always need 'Default' as when support for different
391
 
    //  Refreshrates exists, then it is not reported back
392
 
    value=malloc(sizeof(ValueList));
393
 
    value->value=0;
394
 
    value->text=stralloc("Default");
395
 
    InsertInto(&refresh_rates, value);
396
 
 
397
 
    mode=modes;
398
 
    while (mode!=NULL) {
399
 
        if ((mode->devicenumber==device) && (mode->bitdepth==bitdepth) && (mode->width==width) && (mode->height==height)) {
400
 
            if (GetIndexFromList(refresh_rates,mode->refreshrate)==-1) {
401
 
                value=malloc(sizeof(ValueList));
402
 
                value->value=mode->refreshrate;
403
 
                itoa(mode->refreshrate,buff,10);
404
 
                value->text=stralloc(buff);
405
 
                InsertInto(&refresh_rates, value);
406
 
            }
407
 
        }
408
 
        mode=mode->next;
409
 
    }
410
 
}
411
 
 
412
 
void get_bitdepthlist(int device)
413
 
{
414
 
DirectDrawModeList  *mode;
415
 
ValueList           *value;
416
 
char                buff[256];
417
 
 
418
 
    DestroyList(&bitdepthlist);
419
 
    mode=modes;
420
 
    while (mode!=NULL) {
421
 
        if ((mode->devicenumber==device)) {
422
 
            if (GetIndexFromList(bitdepthlist,mode->bitdepth)==-1) {
423
 
                value=malloc(sizeof(ValueList));
424
 
                value->value=mode->bitdepth;
425
 
                itoa(mode->bitdepth,buff,10);
426
 
                value->text=stralloc(buff);
427
 
                InsertInto(&bitdepthlist,value);
428
 
            }
429
 
        }
430
 
        mode=mode->next;
431
 
    }
432
 
}
433
 
 
434
 
void get_resolutionlist(int device, int bitdepth)
435
 
{
436
 
DirectDrawModeList  *mode;
437
 
ValueList           *value;
438
 
char                buff[256];
439
 
 
440
 
    DestroyList(&resolutionlist);
441
 
    mode=modes;
442
 
    while (mode!=NULL) {
443
 
        if ((mode->devicenumber==device) && (mode->bitdepth==bitdepth)) {
444
 
            if (GetIndexFromList(resolutionlist,((mode->width<<16)+mode->height))==-1) {
445
 
                value=malloc(sizeof(ValueList));
446
 
                value->value=(mode->width<<16)+mode->height;
447
 
                sprintf(buff,"%dx%d",mode->width,mode->height);
448
 
                value->text=stralloc(buff);
449
 
                InsertInto(&resolutionlist,value);
450
 
            }
451
 
        }
452
 
        mode=mode->next;
453
 
    }
454
 
}
455
 
 
456
 
static void init_fullscreen_dialog(HWND hwnd)
457
 
{
458
 
HWND                    setting_hwnd;
459
 
DirectDrawDeviceList    *dev;
460
 
ValueList               *value;
461
 
 
462
 
    validate_mode(&fullscreen_device,&fullscreen_width,&fullscreen_height,&fullscreen_bitdepth,&fullscreen_refreshrate);
463
 
    setting_hwnd=GetDlgItem(hwnd, IDC_FULLSCREEN_DEVICE);
464
 
    SendMessage(setting_hwnd,CB_RESETCONTENT,0,0);
465
 
    dev=devices;
466
 
    while (dev!=NULL) {
467
 
        SendMessage(setting_hwnd,CB_ADDSTRING,0,(LPARAM)dev->desc);
468
 
        dev=dev->next;
469
 
    }
470
 
    SendMessage(setting_hwnd,CB_SETCURSEL,(WPARAM)fullscreen_device,0);
471
 
 
472
 
    get_bitdepthlist(fullscreen_device);
473
 
    setting_hwnd=GetDlgItem(hwnd, IDC_FULLSCREEN_BITDEPTH);
474
 
    SendMessage(setting_hwnd,CB_RESETCONTENT,0,0);
475
 
    value=bitdepthlist;
476
 
    while (value!=NULL) {
477
 
        SendMessage(setting_hwnd,CB_ADDSTRING,0,(LPARAM)value->text);
478
 
        value=value->next;
479
 
    }
480
 
    SendMessage(setting_hwnd,CB_SETCURSEL,(WPARAM)GetIndexFromList(bitdepthlist,fullscreen_bitdepth),0);
481
 
 
482
 
    get_resolutionlist(fullscreen_device,fullscreen_bitdepth);
483
 
    setting_hwnd=GetDlgItem(hwnd, IDC_FULLSCREEN_RESOLUTION);
484
 
    SendMessage(setting_hwnd,CB_RESETCONTENT,0,0);
485
 
    value=resolutionlist;
486
 
    while (value!=NULL) {
487
 
        SendMessage(setting_hwnd,CB_ADDSTRING,0,(LPARAM)value->text);
488
 
        value=value->next;
489
 
    }
490
 
    SendMessage(setting_hwnd,CB_SETCURSEL,(WPARAM)GetIndexFromList(resolutionlist,(fullscreen_width<<16)+fullscreen_height),0);
491
 
 
492
 
    get_refreshratelist(fullscreen_device,fullscreen_bitdepth,fullscreen_width,fullscreen_height);
493
 
    setting_hwnd=GetDlgItem(hwnd, IDC_FULLSCREEN_REFRESHRATE);
494
 
    SendMessage(setting_hwnd,CB_RESETCONTENT,0,0);
495
 
    value=refresh_rates;
496
 
    while (value!=NULL) {
497
 
        SendMessage(setting_hwnd,CB_ADDSTRING,0,(LPARAM)value->text);
498
 
        value=value->next;
499
 
    }
500
 
    SendMessage(setting_hwnd,CB_SETCURSEL,(WPARAM)GetIndexFromList(refresh_rates,fullscreen_refreshrate),0);
501
 
}
502
 
 
503
 
 
504
 
BOOL CALLBACK dialog_fullscreen_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
505
 
{
506
 
int notifycode;
507
 
int item;
508
 
int index;
509
 
int value;
510
 
int command;
511
 
 
512
 
    switch (msg) {
513
 
        case WM_NOTIFY:
514
 
            if (((NMHDR FAR *)lparam)->code==PSN_APPLY) {
515
 
                resources_set_value("FullScreenDevice",(resource_value_t)fullscreen_device);
516
 
                resources_set_value("FullScreenBitdepth",(resource_value_t)fullscreen_bitdepth);
517
 
                resources_set_value("FullScreenWidth",(resource_value_t)fullscreen_width);
518
 
                resources_set_value("FullScreenHeight",(resource_value_t)fullscreen_height);
519
 
                resources_set_value("FullScreenRefreshRate",(resource_value_t)fullscreen_refreshrate);
520
 
 
521
 
                                SetWindowLong (hwnd, DWL_MSGRESULT, FALSE);
522
 
                return TRUE;
523
 
            }
524
 
            return FALSE;
525
 
        case WM_COMMAND:
526
 
            notifycode=HIWORD(wparam);
527
 
            item=LOWORD(wparam);
528
 
            if (notifycode==CBN_SELENDOK) {
529
 
                if (item==IDC_FULLSCREEN_DEVICE) { 
530
 
                    fullscreen_device=SendMessage(GetDlgItem(hwnd,IDC_FULLSCREEN_DEVICE),CB_GETCURSEL,0,0);
531
 
                } else if (item==IDC_FULLSCREEN_BITDEPTH) {
532
 
                    index=SendMessage(GetDlgItem(hwnd,IDC_FULLSCREEN_BITDEPTH),CB_GETCURSEL,0,0);
533
 
                    fullscreen_bitdepth=GetValueFromList(bitdepthlist,index);
534
 
                } else if (item==IDC_FULLSCREEN_RESOLUTION) {
535
 
                    index=SendMessage(GetDlgItem(hwnd,IDC_FULLSCREEN_RESOLUTION),CB_GETCURSEL,0,0);
536
 
                    value=GetValueFromList(resolutionlist,index);
537
 
                    fullscreen_width=value>>16;
538
 
                    fullscreen_height=value&0xffff;
539
 
                } else if (item==IDC_FULLSCREEN_REFRESHRATE) {
540
 
                    index=SendMessage(GetDlgItem(hwnd,IDC_FULLSCREEN_REFRESHRATE),CB_GETCURSEL,0,0);
541
 
                    fullscreen_refreshrate=GetValueFromList(refresh_rates,index);
542
 
                }
543
 
                init_fullscreen_dialog(hwnd);
544
 
            } else {
545
 
                command=LOWORD(wparam);
546
 
                switch (command) {
547
 
                    case IDOK:
548
 
                        resources_set_value("FullScreenDevice",(resource_value_t)fullscreen_device);
549
 
                        resources_set_value("FullScreenBitdepth",(resource_value_t)fullscreen_bitdepth);
550
 
                        resources_set_value("FullScreenWidth",(resource_value_t)fullscreen_width);
551
 
                        resources_set_value("FullScreenHeight",(resource_value_t)fullscreen_height);
552
 
                        resources_set_value("FullScreenRefreshRate",(resource_value_t)fullscreen_refreshrate);
553
 
                    case IDCANCEL:
554
 
                        EndDialog(hwnd,0);
555
 
                        return TRUE;
556
 
                }
557
 
            }
558
 
            return FALSE;
559
 
        case WM_CLOSE:
560
 
            EndDialog(hwnd,0);
561
 
            return TRUE;
562
 
        case WM_INITDIALOG:
563
 
            resources_get_value("FullscreenDevice",(resource_value_t *)&fullscreen_device);
564
 
            resources_get_value("FullscreenBitdepth",(resource_value_t *)&fullscreen_bitdepth);
565
 
            resources_get_value("FullscreenWidth",(resource_value_t *)&fullscreen_width);
566
 
            resources_get_value("FullscreenHeight",(resource_value_t *)&fullscreen_height);
567
 
            resources_get_value("FullscreenRefreshRate",(resource_value_t *)&fullscreen_refreshrate);
568
 
            init_fullscreen_dialog(hwnd);
569
 
            return TRUE;
570
 
    }
571
 
    return FALSE;
572
 
}
573
 
 
574
 
void ui_fullscreen_init(void)
575
 
{
576
 
    fullscreen_getmodes();
577
 
}
578
 
 
579
 
int IsFullscreenEnabled(void)
580
 
{
581
 
int b;
582
 
 
583
 
    resources_get_value("FullscreenEnabled",(resource_value_t *)&b);
584
 
    return b;
585
 
}
586
 
 
587
 
void GetCurrentModeParameters(int *width, int *height, int *bitdepth, int *refreshrate)
588
 
{
589
 
    resources_get_value("FullscreenBitdepth",(resource_value_t *)bitdepth);
590
 
    resources_get_value("FullscreenWidth",(resource_value_t *)width);
591
 
    resources_get_value("FullscreenHeight",(resource_value_t *)height);
592
 
    resources_get_value("FullscreenRefreshRate",(resource_value_t *)refreshrate);
593
 
}
594
 
 
595
 
 
596
 
HMENU   old_menu;
597
 
RECT    old_rect;
598
 
DWORD   old_style;
599
 
int     old_width;
600
 
int     old_height;
601
 
int     old_bitdepth;
602
 
int     old_client_width;
603
 
int     old_client_height;
604
 
int     fullscreen_active;
605
 
 
606
 
int     fullscreen_transition=0;
607
 
 
608
 
void SwitchToFullscreenMode(HWND hwnd)
609
 
{
610
 
int             w,h,wnow,hnow;
611
 
int             fullscreen_width;
612
 
int             fullscreen_height;
613
 
int             bitdepth;
614
 
int             refreshrate;
615
 
video_canvas_t  *c;
616
 
HRESULT         ddresult;
617
 
DDSURFACEDESC   desc;
618
 
DDSURFACEDESC   desc2;
619
 
GUID            *device_guid;
620
 
int             i;
621
 
HDC             hdc;
622
 
raster_t        *r;
623
 
 
624
 
    fullscreen_transition=1;
625
 
    //  Get fullscreen parameters
626
 
    GetCurrentModeParameters(&fullscreen_width,&fullscreen_height,&bitdepth,&refreshrate);
627
 
    //  Get the Canvas for this window
628
 
    c=canvas_find_canvas_for_hwnd(hwnd);
629
 
 
630
 
 
631
 
    memset(&desc2,0,sizeof(desc2));
632
 
    desc2.dwSize=sizeof(desc2);
633
 
    ddresult=IDirectDraw2_GetDisplayMode(c->dd_object2,&desc2);
634
 
    old_width=desc2.dwWidth;
635
 
    old_height=desc2.dwHeight;
636
 
#ifdef HAVE_UNNAMED_UNIONS
637
 
    old_bitdepth=desc2.ddpfPixelFormat.dwRGBBitCount;;
638
 
#else
639
 
    old_bitdepth=desc2.ddpfPixelFormat.u1.dwRGBBitCount;;
640
 
#endif
641
 
 
642
 
    IDirectDrawSurface_Release(c->temporary_surface);
643
 
    IDirectDrawSurface_Release(c->primary_surface);
644
 
    IDirectDraw_Release(c->dd_object2);
645
 
    IDirectDraw_Release(c->dd_object);
646
 
 
647
 
    statusbar_destroy();
648
 
 
649
 
    //  Remove Window Styles
650
 
    old_style=GetWindowLong(hwnd,GWL_STYLE);
651
 
    GetWindowRect(hwnd,&old_rect);
652
 
    SetWindowLong(hwnd,GWL_STYLE,old_style&~WS_SYSMENU&~WS_CAPTION);
653
 
    //  Remove Menu
654
 
    old_menu=GetMenu(hwnd);
655
 
    SetMenu(hwnd,NULL);
656
 
    //  Cover screen with window
657
 
    wnow=GetSystemMetrics(SM_CXSCREEN);
658
 
    hnow=GetSystemMetrics(SM_CYSCREEN);
659
 
    w=(fullscreen_width>wnow) ? fullscreen_width : wnow;
660
 
    h=(fullscreen_height>hnow) ? fullscreen_height : hnow;
661
 
    SetWindowPos(hwnd,HWND_TOPMOST,0,0,w,h,SWP_NOCOPYBITS);
662
 
    ShowCursor(FALSE);
663
 
 
664
 
    device_guid=GetGUIDForActualDevice();
665
 
    ddresult=DirectDrawCreate(device_guid, &c->dd_object, NULL);
666
 
    ddresult=IDirectDraw_SetCooperativeLevel(c->dd_object, c->hwnd, DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN);
667
 
    ddresult=IDirectDraw_QueryInterface(c->dd_object,(GUID *)&IID_IDirectDraw2,(LPVOID *)&c->dd_object2);
668
 
 
669
 
    //  Set cooperative level
670
 
    ddresult=IDirectDraw_SetCooperativeLevel(c->dd_object, c->hwnd, DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN);
671
 
    //  Set Mode
672
 
    ddresult=IDirectDraw2_SetDisplayMode(c->dd_object2,fullscreen_width,fullscreen_height,bitdepth,refreshrate,0);
673
 
    //  Adjust window size
674
 
    old_client_width=c->client_width;
675
 
    old_client_height=c->client_height;
676
 
    c->client_width=fullscreen_width;
677
 
    c->client_height=fullscreen_height;
678
 
 
679
 
    /*  Create Primary surface */
680
 
    memset(&desc, 0, sizeof(desc));
681
 
    desc.dwSize = sizeof(desc);
682
 
    desc.dwFlags = DDSD_CAPS;
683
 
    desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
684
 
 
685
 
    ddresult = IDirectDraw2_CreateSurface(c->dd_object2, &desc, &c->primary_surface, NULL);
686
 
    if (ddresult != DD_OK) {
687
 
    }
688
 
    ddresult = IDirectDraw2_CreateClipper(c->dd_object2, 0, &c->clipper, NULL);
689
 
    if (ddresult != DD_OK) {
690
 
        ui_error("Cannot create clipper for primary surface:\n%s",
691
 
                 dd_error(ddresult));
692
 
    }
693
 
    ddresult = IDirectDrawSurface_SetClipper(c->primary_surface, c->clipper);
694
 
    if (ddresult != DD_OK) {
695
 
        ui_error("Cannot set clipper for primary surface:\n%s",
696
 
                 dd_error(ddresult));
697
 
    }
698
 
 
699
 
    /* Create the temporary surface.  */
700
 
    memset(&desc, 0, sizeof(desc));
701
 
    desc.dwSize = sizeof(desc);
702
 
    desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
703
 
    /* FIXME: SYSTEMMEMORY?  */
704
 
    desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
705
 
    desc.dwWidth = fullscreen_width;
706
 
    desc.dwHeight = fullscreen_height;
707
 
    ddresult = IDirectDraw2_CreateSurface(c->dd_object2, &desc, &c->temporary_surface, NULL);
708
 
    if (ddresult != DD_OK) {
709
 
        ui_error("Cannot create temporary DirectDraw surface:\n%s",
710
 
                 dd_error(ddresult));
711
 
    }
712
 
 
713
 
    c->depth=bitdepth;
714
 
    /* Create palette.  */
715
 
    if (c->depth == 8) {
716
 
        PALETTEENTRY ape[256];
717
 
        HRESULT result;
718
 
 
719
 
        /* Default to a 332 palette.  */
720
 
        for (i = 0; i < 256; i++) {
721
 
            ape[i].peRed   = (BYTE)(((i >> 5) & 0x07) * 255 / 7);
722
 
            ape[i].peGreen = (BYTE)(((i >> 2) & 0x07) * 255 / 7);
723
 
            ape[i].peBlue  = (BYTE)(((i >> 0) & 0x03) * 255 / 3);
724
 
            ape[i].peFlags = (BYTE)0;
725
 
        }
726
 
 
727
 
        /* Overwrite first colors with the palette ones.  */
728
 
        for (i = 0; i < c->palette->num_entries; i++) {
729
 
            ape[i].peRed = c->palette->entries[i].red;
730
 
            ape[i].peGreen = c->palette->entries[i].green;
731
 
            ape[i].peBlue = c->palette->entries[i].blue;
732
 
            ape[i].peFlags = 0;
733
 
        }
734
 
 
735
 
        result = IDirectDraw2_CreatePalette(c->dd_object2, DDPCAPS_8BIT,
736
 
                                           ape, &c->dd_palette, NULL);
737
 
        if (result != DD_OK) {
738
 
        }
739
 
    }
740
 
 
741
 
    set_palette(c);
742
 
    set_physical_colors(c);
743
 
 
744
 
    r=video_find_raster_for_canvas(c);
745
 
    if (r) {
746
 
        video_frame_buffer_translate(c);
747
 
        raster_rebuild_tables(r);
748
 
    }
749
 
    IDirectDrawSurface_GetDC(c->primary_surface,&hdc);
750
 
    canvas_update(c->hwnd,hdc,0,0,fullscreen_width,fullscreen_height);
751
 
    IDirectDrawSurface_ReleaseDC(c->primary_surface, hdc);
752
 
    fullscreen_active=1;
753
 
 
754
 
    fullscreen_transition=0;
755
 
}
756
 
 
757
 
void SwitchToWindowedMode(HWND hwnd)
758
 
{
759
 
video_canvas_t  *c;
760
 
HRESULT         ddresult;
761
 
DDSURFACEDESC   desc;
762
 
DDSURFACEDESC   desc2;
763
 
int             i;
764
 
HDC             hdc;
765
 
raster_t        *r;
766
 
 
767
 
    fullscreen_transition=1;
768
 
 
769
 
    //  Get the Canvas for this window
770
 
    c=canvas_find_canvas_for_hwnd(hwnd);
771
 
 
772
 
    IDirectDrawSurface_Release(c->temporary_surface);
773
 
    IDirectDrawSurface_Release(c->primary_surface);
774
 
    ddresult = IDirectDraw_SetCooperativeLevel(c->dd_object, NULL, DDSCL_NORMAL);
775
 
    IDirectDraw_RestoreDisplayMode(c->dd_object);
776
 
    IDirectDraw_Release(c->dd_object2);
777
 
    IDirectDraw_Release(c->dd_object);
778
 
 
779
 
 
780
 
    LockWindowUpdate(hwnd);
781
 
    SetWindowLong(hwnd,GWL_STYLE,old_style);
782
 
    //  Remove Menu
783
 
    SetMenu(hwnd,old_menu);
784
 
    SetWindowPos(hwnd,HWND_TOP,old_rect.left,old_rect.top,old_rect.right-old_rect.left,old_rect.bottom-old_rect.top,SWP_NOCOPYBITS);
785
 
    ShowCursor(TRUE);
786
 
    c->client_width=old_client_width;
787
 
    c->client_height=old_client_height;
788
 
    LockWindowUpdate(NULL);
789
 
 
790
 
    statusbar_create(hwnd);
791
 
 
792
 
    ddresult=DirectDrawCreate(NULL, &c->dd_object, NULL);
793
 
    ddresult=IDirectDraw_SetCooperativeLevel(c->dd_object, NULL, DDSCL_NORMAL);
794
 
    ddresult=IDirectDraw_QueryInterface(c->dd_object,(GUID *)&IID_IDirectDraw2,(LPVOID *)&c->dd_object2);
795
 
 
796
 
    /*  Create Primary surface */
797
 
    memset(&desc, 0, sizeof(desc));
798
 
    desc.dwSize = sizeof(desc);
799
 
    desc.dwFlags = DDSD_CAPS;
800
 
    desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
801
 
 
802
 
    ddresult = IDirectDraw2_CreateSurface(c->dd_object2, &desc, &c->primary_surface, NULL);
803
 
    if (ddresult != DD_OK) {
804
 
    }
805
 
    ddresult = IDirectDraw2_CreateClipper(c->dd_object2, 0, &c->clipper, NULL);
806
 
    if (ddresult != DD_OK) {
807
 
        ui_error("Cannot create clipper for primary surface:\n%s",
808
 
                 dd_error(ddresult));
809
 
    }
810
 
    ddresult = IDirectDrawSurface_SetClipper(c->primary_surface, c->clipper);
811
 
    if (ddresult != DD_OK) {
812
 
        ui_error("Cannot set clipper for primary surface:\n%s",
813
 
                 dd_error(ddresult));
814
 
    }
815
 
 
816
 
    memset(&desc2,0,sizeof(desc2));
817
 
    desc2.dwSize=sizeof(desc2);
818
 
    ddresult=IDirectDraw2_GetDisplayMode(c->dd_object2,&desc2);
819
 
 
820
 
    /* Create the temporary surface.  */
821
 
    memset(&desc, 0, sizeof(desc));
822
 
    desc.dwSize = sizeof(desc);
823
 
    desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
824
 
    /* FIXME: SYSTEMMEMORY?  */
825
 
    desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
826
 
    desc.dwWidth = desc2.dwWidth;
827
 
    desc.dwHeight = desc2.dwHeight;
828
 
    ddresult = IDirectDraw2_CreateSurface(c->dd_object2, &desc, &c->temporary_surface, NULL);
829
 
    if (ddresult != DD_OK) {
830
 
        ui_error("Cannot create temporary DirectDraw surface:\n%s",
831
 
                 dd_error(ddresult));
832
 
    }
833
 
 
834
 
    c->depth=old_bitdepth;
835
 
 
836
 
 
837
 
    /* Create palette.  */
838
 
    if (c->depth == 8) {
839
 
        PALETTEENTRY ape[256];
840
 
        HRESULT result;
841
 
 
842
 
        /* Default to a 332 palette.  */
843
 
        for (i = 0; i < 256; i++) {
844
 
            ape[i].peRed   = (BYTE)(((i >> 5) & 0x07) * 255 / 7);
845
 
            ape[i].peGreen = (BYTE)(((i >> 2) & 0x07) * 255 / 7);
846
 
            ape[i].peBlue  = (BYTE)(((i >> 0) & 0x03) * 255 / 3);
847
 
            ape[i].peFlags = (BYTE)0;
848
 
        }
849
 
 
850
 
        /* Overwrite first colors with the palette ones.  */
851
 
        for (i = 0; i < c->palette->num_entries; i++) {
852
 
            ape[i].peRed = c->palette->entries[i].red;
853
 
            ape[i].peGreen = c->palette->entries[i].green;
854
 
            ape[i].peBlue = c->palette->entries[i].blue;
855
 
            ape[i].peFlags = 0;
856
 
        }
857
 
 
858
 
        result = IDirectDraw2_CreatePalette(c->dd_object2, DDPCAPS_8BIT,
859
 
                                           ape, &c->dd_palette, NULL);
860
 
        if (result != DD_OK) {
861
 
        }
862
 
    }
863
 
 
864
 
    set_palette(c);
865
 
    set_physical_colors(c);
866
 
 
867
 
 
868
 
    r=video_find_raster_for_canvas(c);
869
 
    video_frame_buffer_translate(c);
870
 
    raster_rebuild_tables(r);
871
 
    IDirectDrawSurface_GetDC(c->primary_surface,&hdc);
872
 
    canvas_update(c->hwnd,hdc,0,0,c->client_width,c->client_height);
873
 
    IDirectDrawSurface_ReleaseDC(c->primary_surface, hdc);
874
 
    fullscreen_active=0;
875
 
 
876
 
    fullscreen_transition=0;
877
 
}
878
 
 
879
 
 
880
 
void StartFullscreenMode(HWND hwnd)
881
 
{
882
 
    SwitchToFullscreenMode(hwnd);
883
 
    resources_set_value("FullScreenEnabled",(resource_value_t)1);
884
 
}
885
 
 
886
 
 
887
 
void EndFullscreenMode(HWND hwnd)
888
 
{
889
 
    SwitchToWindowedMode(hwnd);
890
 
    resources_set_value("FullScreenEnabled",(resource_value_t)0);
891
 
}
892
 
 
893
 
void SwitchFullscreenMode(HWND hwnd)
894
 
{
895
 
    if (IsFullscreenEnabled()) {
896
 
        EndFullscreenMode(hwnd);
897
 
    } else {
898
 
        StartFullscreenMode(hwnd);
899
 
    }
900
 
}
901
 
 
902
 
 
903
 
int     fullscreen_nesting_level=0;
904
 
 
905
 
void SuspendFullscreenMode(HWND hwnd)
906
 
{
907
 
    if (IsFullscreenEnabled()) {
908
 
        if (fullscreen_nesting_level==0) {
909
 
            SwitchToWindowedMode(hwnd);
910
 
        }
911
 
        fullscreen_nesting_level++;
912
 
    }
913
 
}
914
 
 
915
 
void ResumeFullscreenMode(HWND hwnd)
916
 
{
917
 
    if (IsFullscreenEnabled()) {
918
 
        fullscreen_nesting_level--;
919
 
        if (fullscreen_nesting_level==0) {
920
 
            SwitchToFullscreenMode(hwnd);
921
 
        }
922
 
    }
923
 
}