Subversion Repositories eduke32

Rev

Rev 196 | Rev 214 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
194 terminx 1
#ifndef RENDERTYPEWIN
2
#error Only for Windows
3
#endif
4
 
5
#include "duke3d.h"
6
 
7
#include "build.h"
8
#include "winlayer.h"
9
#include "compat.h"
10
 
11
#define WIN32_LEAN_AND_MEAN
12
#include <windows.h>
13
#include <windowsx.h>
14
#define _WIN32_IE 0x0300
15
#include <commctrl.h>
16
#include <stdio.h>
17
 
18
#include "startwin.game.h"
19
 
20
#define TAB_CONFIG 0
21
#define TAB_MESSAGES 1
22
 
23
static struct {
24
    int fullscreen;
25
    int xdim, ydim, bpp;
26
    int forcesetup;
27
    int usemouse, usejoy;
28
} settings;
29
 
30
static HWND startupdlg = NULL;
31
static HWND pages[2] = { NULL, NULL};
197 terminx 32
static int done = -1, mode = TAB_CONFIG;
194 terminx 33
 
34
static void PopulateForm(void)
35
{
36
    int i,j;
37
    char buf[64];
38
    int mode;
39
    HWND hwnd;
40
 
41
    hwnd = GetDlgItem(pages[TAB_CONFIG], IDCVMODE);
42
 
43
    mode = checkvideomode(&settings.xdim, &settings.ydim, settings.bpp, settings.fullscreen, 1);
44
    if (mode < 0) {
45
        int cd[] = { 32, 24, 16, 15, 8, 0 };
46
        for (i=0; cd[i]; ) { if (cd[i] >= settings.bpp) i++; else break; }
47
        for ( ; cd[i]; i++) {
48
            mode = checkvideomode(&settings.xdim, &settings.ydim, cd[i], settings.fullscreen, 1);
49
            if (mode < 0) continue;
50
            settings.bpp = cd[i];
51
            break;
52
        }
53
    }
54
 
55
    Button_SetCheck(GetDlgItem(pages[TAB_CONFIG], IDCFULLSCREEN), (settings.fullscreen ? BST_CHECKED : BST_UNCHECKED));
56
    Button_SetCheck(GetDlgItem(pages[TAB_CONFIG], IDCALWAYSSHOW), (settings.forcesetup ? BST_CHECKED : BST_UNCHECKED));
57
 
58
    ComboBox_ResetContent(hwnd);
59
    for (i=0; i<validmodecnt; i++) {
60
        if (validmode[i].fs != settings.fullscreen) continue;
61
 
62
        // all modes get added to the 3D mode list
63
        Bsprintf(buf, "%ld x %ld %dbpp", validmode[i].xdim, validmode[i].ydim, validmode[i].bpp);
64
        j = ComboBox_AddString(hwnd, buf);
65
        ComboBox_SetItemData(hwnd, j, i);
66
        if (i == mode) ComboBox_SetCurSel(hwnd, j);
67
    }
68
 
69
    Button_SetCheck(GetDlgItem(pages[TAB_CONFIG], IDCINPUTMOUSE), (settings.usemouse ? BST_CHECKED : BST_UNCHECKED));
70
    Button_SetCheck(GetDlgItem(pages[TAB_CONFIG], IDCINPUTJOY), (settings.usejoy ? BST_CHECKED : BST_UNCHECKED));
71
}
72
 
73
static INT_PTR CALLBACK ConfigPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
74
{
75
    switch (uMsg) {
76
    case WM_COMMAND:
77
        switch (LOWORD(wParam)) {
78
        case IDCFULLSCREEN:
79
            settings.fullscreen = !settings.fullscreen;
80
            PopulateForm();
81
            return TRUE;
82
        case IDCVMODE:
83
            if (HIWORD(wParam) == CBN_SELCHANGE) {
84
                int i;
85
                i = ComboBox_GetCurSel((HWND)lParam);
86
                if (i != CB_ERR) i = ComboBox_GetItemData((HWND)lParam, i);
87
                if (i != CB_ERR) {
88
                    settings.xdim = validmode[i].xdim;
89
                    settings.ydim = validmode[i].ydim;
90
                    settings.bpp  = validmode[i].bpp;
91
                }
92
            }
93
            return TRUE;
94
        case IDCALWAYSSHOW:
95
            settings.forcesetup = IsDlgButtonChecked(hwndDlg, IDCALWAYSSHOW) == BST_CHECKED;
96
            return TRUE;
97
        case IDCINPUTMOUSE:
98
            settings.usemouse = IsDlgButtonChecked(hwndDlg, IDCINPUTMOUSE) == BST_CHECKED;
99
            return TRUE;
100
        case IDCINPUTJOY:
101
            settings.usejoy = IsDlgButtonChecked(hwndDlg, IDCINPUTJOY) == BST_CHECKED;
102
            return TRUE;
103
        default: break;
104
        }
105
        break;
106
    default: break;
107
    }
108
    return FALSE;
109
}
110
 
111
 
112
 
113
static void SetPage(int n)
114
{
115
    HWND tab;
116
    int cur;
117
    tab = GetDlgItem(startupdlg, WIN_STARTWIN_TABCTL);
118
    cur = (int)SendMessage(tab, TCM_GETCURSEL,0,0);
119
    ShowWindow(pages[cur],SW_HIDE);
120
    SendMessage(tab, TCM_SETCURSEL, n, 0);
121
    ShowWindow(pages[n],SW_SHOW);
197 terminx 122
    mode = n;
196 terminx 123
 
124
    SetFocus(GetDlgItem(startupdlg, WIN_STARTWIN_TABCTL));
194 terminx 125
}
126
 
127
static void EnableConfig(int n)
128
{
197 terminx 129
    //EnableWindow(GetDlgItem(startupdlg, WIN_STARTWIN_CANCEL), n);
194 terminx 130
    EnableWindow(GetDlgItem(startupdlg, WIN_STARTWIN_START), n);
131
    EnableWindow(GetDlgItem(pages[TAB_CONFIG], IDCFULLSCREEN), n);
132
    EnableWindow(GetDlgItem(pages[TAB_CONFIG], IDCVMODE), n);
133
    EnableWindow(GetDlgItem(pages[TAB_CONFIG], IDCINPUTMOUSE), n);
134
    EnableWindow(GetDlgItem(pages[TAB_CONFIG], IDCINPUTJOY), n);
135
}
136
 
137
static INT_PTR CALLBACK startup_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
138
{
139
    static HBITMAP hbmp = NULL;
140
    HDC hdc;
141
 
142
    switch (uMsg) {
143
    case WM_INITDIALOG: {
144
            HWND hwnd;
145
            RECT r, rdlg, chrome, rtab, rcancel, rstart;
146
            int xoffset = 0, yoffset = 0;
147
 
148
            // Fetch the positions (in screen coordinates) of all the windows we need to tweak
149
            ZeroMemory(&chrome, sizeof(chrome));
150
            AdjustWindowRect(&chrome, GetWindowLong(hwndDlg, GWL_STYLE), FALSE);
151
            GetWindowRect(hwndDlg, &rdlg);
152
            GetWindowRect(GetDlgItem(hwndDlg, WIN_STARTWIN_TABCTL), &rtab);
153
            GetWindowRect(GetDlgItem(hwndDlg, WIN_STARTWIN_CANCEL), &rcancel);
154
            GetWindowRect(GetDlgItem(hwndDlg, WIN_STARTWIN_START), &rstart);
155
 
156
            // Knock off the non-client area of the main dialogue to give just the client area
157
            rdlg.left -= chrome.left; rdlg.top -= chrome.top;
158
            rdlg.right -= chrome.right; rdlg.bottom -= chrome.bottom;
159
 
160
            // Translate them to client-relative coordinates wrt the main dialogue window
161
            rtab.right -= rtab.left - 1; rtab.bottom -= rtab.top - 1;
162
            rtab.left  -= rdlg.left; rtab.top -= rdlg.top;
163
 
164
            rcancel.right -= rcancel.left - 1; rcancel.bottom -= rcancel.top - 1;
165
            rcancel.left -= rdlg.left; rcancel.top -= rdlg.top;
166
 
167
            rstart.right -= rstart.left - 1; rstart.bottom -= rstart.top - 1;
168
            rstart.left -= rdlg.left; rstart.top -= rdlg.top;
169
 
170
            // And then convert the main dialogue coordinates to just width/length
171
            rdlg.right -= rdlg.left - 1; rdlg.bottom -= rdlg.top - 1;
172
            rdlg.left = 0; rdlg.top = 0;
173
 
174
            // Load the bitmap into the bitmap control and fetch its dimensions
175
            hbmp = LoadBitmap((HINSTANCE)win_gethinstance(), MAKEINTRESOURCE(RSRC_BMP));
176
            hwnd = GetDlgItem(hwndDlg,WIN_STARTWIN_BITMAP);
177
            SendMessage(hwnd, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hbmp);
178
            GetClientRect(hwnd, &r);
179
            xoffset = r.right;
180
            yoffset = r.bottom - rdlg.bottom;
181
 
182
            // Shift and resize the controls that require it
183
            rtab.left += xoffset; rtab.bottom += yoffset;
184
            rcancel.left += xoffset; rcancel.top += yoffset;
185
            rstart.left += xoffset; rstart.top += yoffset;
186
            rdlg.right += xoffset;
187
            rdlg.bottom += yoffset;
188
 
189
            // Move the controls to their new positions
190
            MoveWindow(GetDlgItem(hwndDlg, WIN_STARTWIN_TABCTL), rtab.left, rtab.top, rtab.right, rtab.bottom, FALSE);
191
            MoveWindow(GetDlgItem(hwndDlg, WIN_STARTWIN_CANCEL), rcancel.left, rcancel.top, rcancel.right, rcancel.bottom, FALSE);
192
            MoveWindow(GetDlgItem(hwndDlg, WIN_STARTWIN_START), rstart.left, rstart.top, rstart.right, rstart.bottom, FALSE);
193
 
194
            // Move the main dialogue to the centre of the screen
195
            hdc = GetDC(NULL);
196
            rdlg.left = (GetDeviceCaps(hdc, HORZRES) - rdlg.right) / 2;
197
            rdlg.top = (GetDeviceCaps(hdc, VERTRES) - rdlg.bottom) / 2;
198
            ReleaseDC(NULL, hdc);
199
            MoveWindow(hwndDlg, rdlg.left + chrome.left, rdlg.top + chrome.left,
200
                       rdlg.right + (-chrome.left+chrome.right), rdlg.bottom + (-chrome.top+chrome.bottom), TRUE);
201
 
202
            // Add tabs to the tab control
203
            {
204
                TCITEM tab;
205
 
206
                hwnd = GetDlgItem(hwndDlg, WIN_STARTWIN_TABCTL);
207
 
208
                ZeroMemory(&tab, sizeof(tab));
209
                tab.mask = TCIF_TEXT;
210
                tab.pszText = TEXT("Configuration");
211
                SendMessage(hwnd, TCM_INSERTITEM, (WPARAM)0, (LPARAM)&tab);
212
                tab.mask = TCIF_TEXT;
213
                tab.pszText = TEXT("Messages");
214
                SendMessage(hwnd, TCM_INSERTITEM, (WPARAM)1, (LPARAM)&tab);
215
 
216
                // Work out the position and size of the area inside the tab control for the pages
217
                ZeroMemory(&r, sizeof(r));
218
                GetClientRect(hwnd, &r);
219
                SendMessage(hwnd, TCM_ADJUSTRECT, FALSE, (LPARAM)&r);
220
                r.right -= r.left-1;
221
                r.bottom -= r.top-1;
222
                r.top += rtab.top;
223
                r.left += rtab.left;
224
 
225
                // Create the pages and position them in the tab control, but hide them
226
                pages[TAB_CONFIG] = CreateDialog((HINSTANCE)win_gethinstance(),
227
                                                 MAKEINTRESOURCE(WIN_STARTWINPAGE_CONFIG), hwndDlg, ConfigPageProc);
228
                pages[TAB_MESSAGES] = GetDlgItem(hwndDlg, WIN_STARTWIN_MESSAGES);
229
                SetWindowPos(pages[TAB_CONFIG], hwnd,r.left,r.top,r.right,r.bottom,SWP_HIDEWINDOW);
230
                SetWindowPos(pages[TAB_MESSAGES], hwnd,r.left,r.top,r.right,r.bottom,SWP_HIDEWINDOW);
231
 
232
                // Tell the editfield acting as the console to exclude the width of the scrollbar
233
                GetClientRect(pages[TAB_MESSAGES],&r);
234
                r.right -= GetSystemMetrics(SM_CXVSCROLL)+4;
235
                r.left = r.top = 0;
236
                SendMessage(pages[TAB_MESSAGES], EM_SETRECTNP,0,(LPARAM)&r);
237
 
238
                SetFocus(GetDlgItem(hwndDlg, WIN_STARTWIN_START));
239
            }
240
            return FALSE;
241
        }
242
 
243
    case WM_NOTIFY: {
244
            LPNMHDR nmhdr = (LPNMHDR)lParam;
245
            int cur;
246
            if (nmhdr->idFrom != WIN_STARTWIN_TABCTL) break;
247
            cur = (int)SendMessage(nmhdr->hwndFrom, TCM_GETCURSEL,0,0);
248
            switch (nmhdr->code) {
249
            case TCN_SELCHANGING: {
250
                    if (cur < 0 || !pages[cur]) break;
251
                    ShowWindow(pages[cur],SW_HIDE);
252
                    return TRUE;
253
                }
254
            case TCN_SELCHANGE: {
255
                    if (cur < 0 || !pages[cur]) break;
256
                    ShowWindow(pages[cur],SW_SHOW);
257
                    return TRUE;
258
                }
259
            }
260
            break;
261
        }
262
 
263
    case WM_CLOSE:
197 terminx 264
                if (mode == TAB_CONFIG) done = 0;
265
                else quitevent++;
194 terminx 266
        return TRUE;
267
 
268
    case WM_DESTROY:
269
        if (hbmp) {
270
            DeleteObject(hbmp);
271
            hbmp = NULL;
272
        }
273
 
274
        if (pages[TAB_CONFIG]) {
275
            DestroyWindow(pages[TAB_CONFIG]);
276
            pages[TAB_CONFIG] = NULL;
277
        }
278
 
279
        startupdlg = NULL;
280
        return TRUE;
281
 
282
    case WM_COMMAND:
283
        switch (LOWORD(wParam)) {
197 terminx 284
                case WIN_STARTWIN_CANCEL:
285
                        if (mode == TAB_CONFIG) done = 0;
286
                        else quitevent++;
287
                        return TRUE;
194 terminx 288
        case WIN_STARTWIN_START: done = 1; return TRUE;
289
        }
290
        return FALSE;
291
 
292
    case WM_CTLCOLORSTATIC:
293
        if ((HWND)lParam == pages[TAB_MESSAGES])
294
            return (BOOL)GetSysColorBrush(COLOR_WINDOW);
295
        break;
296
 
297
    default: break;
298
    }
299
 
300
    return FALSE;
301
}
302
 
303
 
304
int startwin_open(void)
305
{
306
    INITCOMMONCONTROLSEX icc;
307
    if (startupdlg) return 1;
308
    icc.dwSize = sizeof(icc);
309
    icc.dwICC = ICC_TAB_CLASSES;
310
    InitCommonControlsEx(&icc);
311
    startupdlg = CreateDialog((HINSTANCE)win_gethinstance(), MAKEINTRESOURCE(WIN_STARTWIN), NULL, startup_dlgproc);
312
    if (startupdlg) {
313
        SetPage(TAB_MESSAGES);
314
        EnableConfig(0);
315
        return 0;
316
    }
317
    return -1;
318
}
319
 
320
int startwin_close(void)
321
{
322
    if (!startupdlg) return 1;
323
    DestroyWindow(startupdlg);
324
    startupdlg = NULL;
325
    return 0;
326
}
327
 
328
int startwin_puts(const char *buf)
329
{
330
    const char *p = NULL, *q = NULL;
331
    char workbuf[1024];
332
    static int newline = 0;
333
    int curlen, linesbefore, linesafter;
334
    HWND edctl;
335
    int vis;
336
 
337
    if (!startupdlg) return 1;
338
 
339
    edctl = pages[TAB_MESSAGES];
340
    if (!edctl) return -1;
341
 
342
    vis = ((int)SendMessage(GetDlgItem(startupdlg, WIN_STARTWIN_TABCTL), TCM_GETCURSEL,0,0) == TAB_MESSAGES);
343
 
344
    if (vis) SendMessage(edctl, WM_SETREDRAW, FALSE,0);
345
    curlen = SendMessage(edctl, WM_GETTEXTLENGTH, 0,0);
346
    SendMessage(edctl, EM_SETSEL, (WPARAM)curlen, (LPARAM)curlen);
347
    linesbefore = SendMessage(edctl, EM_GETLINECOUNT, 0,0);
348
    p = buf;
349
    while (*p) {
350
        if (newline) {
351
            SendMessage(edctl, EM_REPLACESEL, 0, (LPARAM)"\r\n");
352
            newline = 0;
353
        }
354
        q = p;
355
        while (*q && *q != '\n') q++;
356
        memcpy(workbuf, p, q-p);
357
        if (*q == '\n') {
358
            if (!q[1]) {
359
                newline = 1;
360
                workbuf[q-p] = 0;
361
            } else {
362
                workbuf[q-p] = '\r';
363
                workbuf[q-p+1] = '\n';
364
                workbuf[q-p+2] = 0;
365
            }
366
            p = q+1;
367
        } else {
368
            workbuf[q-p] = 0;
369
            p = q;
370
        }
371
        SendMessage(edctl, EM_REPLACESEL, 0, (LPARAM)workbuf);
372
    }
373
    linesafter = SendMessage(edctl, EM_GETLINECOUNT, 0,0);
374
    SendMessage(edctl, EM_LINESCROLL, 0, linesafter-linesbefore);
375
    if (vis) SendMessage(edctl, WM_SETREDRAW, TRUE,0);
376
    return 0;
377
}
378
 
379
int startwin_settitle(const char *str)
380
{
381
    if (!startupdlg) return 1;
382
    SetWindowText(startupdlg, str);
383
    return 0;
384
}
385
 
386
int startwin_idle(void *v)
387
{
388
    if (!startupdlg || !IsWindow(startupdlg)) return 0;
389
    if (IsDialogMessage(startupdlg, (MSG*)v)) return 1;
390
    return 0;
391
}
392
 
393
int startwin_run(void)
394
{
395
    MSG msg;
396
    if (!startupdlg) return 1;
397
 
398
    done = -1;
399
 
400
    SetPage(TAB_CONFIG);
401
    EnableConfig(1);
402
 
403
    settings.fullscreen = ScreenMode;
404
    settings.xdim = ScreenWidth;
405
    settings.ydim = ScreenHeight;
406
    settings.bpp = ScreenBPP;
407
    settings.forcesetup = ForceSetup;
408
    settings.usemouse = UseMouse;
409
    settings.usejoy = UseJoystick;
410
    PopulateForm();
411
 
412
    while (done < 0) {
413
        switch (GetMessage(&msg, NULL, 0,0)) {
414
        case 0: done = 1; break;
415
        case -1: return -1;
416
        default:
417
            if (IsWindow(startupdlg) && IsDialogMessage(startupdlg, &msg)) break;
418
            TranslateMessage(&msg);
419
            DispatchMessage(&msg);
420
            break;
421
        }
422
    }
423
 
424
    SetPage(TAB_MESSAGES);
425
    EnableConfig(0);
426
    if (done) {
427
        ScreenMode = settings.fullscreen;
428
        ScreenWidth = settings.xdim;
429
        ScreenHeight = settings.ydim;
430
        ScreenBPP = settings.bpp;
431
        ForceSetup = settings.forcesetup;
432
        UseMouse = settings.usemouse;
433
        UseJoystick = settings.usejoy;
434
    }
435
 
436
    return done;
437
}
438