Subversion Repositories eduke32

Rev

Rev 196 | Go to most recent revision | Details | 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};
32
static int done = -1;
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);
122
}
123
 
124
static void EnableConfig(int n)
125
{
126
    EnableWindow(GetDlgItem(startupdlg, WIN_STARTWIN_CANCEL), n);
127
    EnableWindow(GetDlgItem(startupdlg, WIN_STARTWIN_START), n);
128
    EnableWindow(GetDlgItem(pages[TAB_CONFIG], IDCFULLSCREEN), n);
129
    EnableWindow(GetDlgItem(pages[TAB_CONFIG], IDCVMODE), n);
130
    EnableWindow(GetDlgItem(pages[TAB_CONFIG], IDCINPUTMOUSE), n);
131
    EnableWindow(GetDlgItem(pages[TAB_CONFIG], IDCINPUTJOY), n);
132
}
133
 
134
static INT_PTR CALLBACK startup_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
135
{
136
    static HBITMAP hbmp = NULL;
137
    HDC hdc;
138
 
139
    switch (uMsg) {
140
    case WM_INITDIALOG: {
141
            HWND hwnd;
142
            RECT r, rdlg, chrome, rtab, rcancel, rstart;
143
            int xoffset = 0, yoffset = 0;
144
 
145
            // Fetch the positions (in screen coordinates) of all the windows we need to tweak
146
            ZeroMemory(&chrome, sizeof(chrome));
147
            AdjustWindowRect(&chrome, GetWindowLong(hwndDlg, GWL_STYLE), FALSE);
148
            GetWindowRect(hwndDlg, &rdlg);
149
            GetWindowRect(GetDlgItem(hwndDlg, WIN_STARTWIN_TABCTL), &rtab);
150
            GetWindowRect(GetDlgItem(hwndDlg, WIN_STARTWIN_CANCEL), &rcancel);
151
            GetWindowRect(GetDlgItem(hwndDlg, WIN_STARTWIN_START), &rstart);
152
 
153
            // Knock off the non-client area of the main dialogue to give just the client area
154
            rdlg.left -= chrome.left; rdlg.top -= chrome.top;
155
            rdlg.right -= chrome.right; rdlg.bottom -= chrome.bottom;
156
 
157
            // Translate them to client-relative coordinates wrt the main dialogue window
158
            rtab.right -= rtab.left - 1; rtab.bottom -= rtab.top - 1;
159
            rtab.left  -= rdlg.left; rtab.top -= rdlg.top;
160
 
161
            rcancel.right -= rcancel.left - 1; rcancel.bottom -= rcancel.top - 1;
162
            rcancel.left -= rdlg.left; rcancel.top -= rdlg.top;
163
 
164
            rstart.right -= rstart.left - 1; rstart.bottom -= rstart.top - 1;
165
            rstart.left -= rdlg.left; rstart.top -= rdlg.top;
166
 
167
            // And then convert the main dialogue coordinates to just width/length
168
            rdlg.right -= rdlg.left - 1; rdlg.bottom -= rdlg.top - 1;
169
            rdlg.left = 0; rdlg.top = 0;
170
 
171
            // Load the bitmap into the bitmap control and fetch its dimensions
172
            hbmp = LoadBitmap((HINSTANCE)win_gethinstance(), MAKEINTRESOURCE(RSRC_BMP));
173
            hwnd = GetDlgItem(hwndDlg,WIN_STARTWIN_BITMAP);
174
            SendMessage(hwnd, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hbmp);
175
            GetClientRect(hwnd, &r);
176
            xoffset = r.right;
177
            yoffset = r.bottom - rdlg.bottom;
178
 
179
            // Shift and resize the controls that require it
180
            rtab.left += xoffset; rtab.bottom += yoffset;
181
            rcancel.left += xoffset; rcancel.top += yoffset;
182
            rstart.left += xoffset; rstart.top += yoffset;
183
            rdlg.right += xoffset;
184
            rdlg.bottom += yoffset;
185
 
186
            // Move the controls to their new positions
187
            MoveWindow(GetDlgItem(hwndDlg, WIN_STARTWIN_TABCTL), rtab.left, rtab.top, rtab.right, rtab.bottom, FALSE);
188
            MoveWindow(GetDlgItem(hwndDlg, WIN_STARTWIN_CANCEL), rcancel.left, rcancel.top, rcancel.right, rcancel.bottom, FALSE);
189
            MoveWindow(GetDlgItem(hwndDlg, WIN_STARTWIN_START), rstart.left, rstart.top, rstart.right, rstart.bottom, FALSE);
190
 
191
            // Move the main dialogue to the centre of the screen
192
            hdc = GetDC(NULL);
193
            rdlg.left = (GetDeviceCaps(hdc, HORZRES) - rdlg.right) / 2;
194
            rdlg.top = (GetDeviceCaps(hdc, VERTRES) - rdlg.bottom) / 2;
195
            ReleaseDC(NULL, hdc);
196
            MoveWindow(hwndDlg, rdlg.left + chrome.left, rdlg.top + chrome.left,
197
                       rdlg.right + (-chrome.left+chrome.right), rdlg.bottom + (-chrome.top+chrome.bottom), TRUE);
198
 
199
            // Add tabs to the tab control
200
            {
201
                TCITEM tab;
202
 
203
                hwnd = GetDlgItem(hwndDlg, WIN_STARTWIN_TABCTL);
204
 
205
                ZeroMemory(&tab, sizeof(tab));
206
                tab.mask = TCIF_TEXT;
207
                tab.pszText = TEXT("Configuration");
208
                SendMessage(hwnd, TCM_INSERTITEM, (WPARAM)0, (LPARAM)&tab);
209
                tab.mask = TCIF_TEXT;
210
                tab.pszText = TEXT("Messages");
211
                SendMessage(hwnd, TCM_INSERTITEM, (WPARAM)1, (LPARAM)&tab);
212
 
213
                // Work out the position and size of the area inside the tab control for the pages
214
                ZeroMemory(&r, sizeof(r));
215
                GetClientRect(hwnd, &r);
216
                SendMessage(hwnd, TCM_ADJUSTRECT, FALSE, (LPARAM)&r);
217
                r.right -= r.left-1;
218
                r.bottom -= r.top-1;
219
                r.top += rtab.top;
220
                r.left += rtab.left;
221
 
222
                // Create the pages and position them in the tab control, but hide them
223
                pages[TAB_CONFIG] = CreateDialog((HINSTANCE)win_gethinstance(),
224
                                                 MAKEINTRESOURCE(WIN_STARTWINPAGE_CONFIG), hwndDlg, ConfigPageProc);
225
                pages[TAB_MESSAGES] = GetDlgItem(hwndDlg, WIN_STARTWIN_MESSAGES);
226
                SetWindowPos(pages[TAB_CONFIG], hwnd,r.left,r.top,r.right,r.bottom,SWP_HIDEWINDOW);
227
                SetWindowPos(pages[TAB_MESSAGES], hwnd,r.left,r.top,r.right,r.bottom,SWP_HIDEWINDOW);
228
 
229
                // Tell the editfield acting as the console to exclude the width of the scrollbar
230
                GetClientRect(pages[TAB_MESSAGES],&r);
231
                r.right -= GetSystemMetrics(SM_CXVSCROLL)+4;
232
                r.left = r.top = 0;
233
                SendMessage(pages[TAB_MESSAGES], EM_SETRECTNP,0,(LPARAM)&r);
234
 
235
                SetFocus(GetDlgItem(hwndDlg, WIN_STARTWIN_START));
236
            }
237
            return FALSE;
238
        }
239
 
240
    case WM_NOTIFY: {
241
            LPNMHDR nmhdr = (LPNMHDR)lParam;
242
            int cur;
243
            if (nmhdr->idFrom != WIN_STARTWIN_TABCTL) break;
244
            cur = (int)SendMessage(nmhdr->hwndFrom, TCM_GETCURSEL,0,0);
245
            switch (nmhdr->code) {
246
            case TCN_SELCHANGING: {
247
                    if (cur < 0 || !pages[cur]) break;
248
                    ShowWindow(pages[cur],SW_HIDE);
249
                    return TRUE;
250
                }
251
            case TCN_SELCHANGE: {
252
                    if (cur < 0 || !pages[cur]) break;
253
                    ShowWindow(pages[cur],SW_SHOW);
254
                    return TRUE;
255
                }
256
            }
257
            break;
258
        }
259
 
260
    case WM_CLOSE:
261
        done = 0;
262
        return TRUE;
263
 
264
    case WM_DESTROY:
265
        if (hbmp) {
266
            DeleteObject(hbmp);
267
            hbmp = NULL;
268
        }
269
 
270
        if (pages[TAB_CONFIG]) {
271
            DestroyWindow(pages[TAB_CONFIG]);
272
            pages[TAB_CONFIG] = NULL;
273
        }
274
 
275
        startupdlg = NULL;
276
        return TRUE;
277
 
278
    case WM_COMMAND:
279
        switch (LOWORD(wParam)) {
280
        case WIN_STARTWIN_CANCEL: done = 0; return TRUE;
281
        case WIN_STARTWIN_START: done = 1; return TRUE;
282
        }
283
        return FALSE;
284
 
285
    case WM_CTLCOLORSTATIC:
286
        if ((HWND)lParam == pages[TAB_MESSAGES])
287
            return (BOOL)GetSysColorBrush(COLOR_WINDOW);
288
        break;
289
 
290
    default: break;
291
    }
292
 
293
    return FALSE;
294
}
295
 
296
 
297
int startwin_open(void)
298
{
299
    INITCOMMONCONTROLSEX icc;
300
    if (startupdlg) return 1;
301
    icc.dwSize = sizeof(icc);
302
    icc.dwICC = ICC_TAB_CLASSES;
303
    InitCommonControlsEx(&icc);
304
    startupdlg = CreateDialog((HINSTANCE)win_gethinstance(), MAKEINTRESOURCE(WIN_STARTWIN), NULL, startup_dlgproc);
305
    if (startupdlg) {
306
        SetPage(TAB_MESSAGES);
307
        EnableConfig(0);
308
        return 0;
309
    }
310
    return -1;
311
}
312
 
313
int startwin_close(void)
314
{
315
    if (!startupdlg) return 1;
316
    DestroyWindow(startupdlg);
317
    startupdlg = NULL;
318
    return 0;
319
}
320
 
321
int startwin_puts(const char *buf)
322
{
323
    const char *p = NULL, *q = NULL;
324
    char workbuf[1024];
325
    static int newline = 0;
326
    int curlen, linesbefore, linesafter;
327
    HWND edctl;
328
    int vis;
329
 
330
    if (!startupdlg) return 1;
331
 
332
    edctl = pages[TAB_MESSAGES];
333
    if (!edctl) return -1;
334
 
335
    vis = ((int)SendMessage(GetDlgItem(startupdlg, WIN_STARTWIN_TABCTL), TCM_GETCURSEL,0,0) == TAB_MESSAGES);
336
 
337
    if (vis) SendMessage(edctl, WM_SETREDRAW, FALSE,0);
338
    curlen = SendMessage(edctl, WM_GETTEXTLENGTH, 0,0);
339
    SendMessage(edctl, EM_SETSEL, (WPARAM)curlen, (LPARAM)curlen);
340
    linesbefore = SendMessage(edctl, EM_GETLINECOUNT, 0,0);
341
    p = buf;
342
    while (*p) {
343
        if (newline) {
344
            SendMessage(edctl, EM_REPLACESEL, 0, (LPARAM)"\r\n");
345
            newline = 0;
346
        }
347
        q = p;
348
        while (*q && *q != '\n') q++;
349
        memcpy(workbuf, p, q-p);
350
        if (*q == '\n') {
351
            if (!q[1]) {
352
                newline = 1;
353
                workbuf[q-p] = 0;
354
            } else {
355
                workbuf[q-p] = '\r';
356
                workbuf[q-p+1] = '\n';
357
                workbuf[q-p+2] = 0;
358
            }
359
            p = q+1;
360
        } else {
361
            workbuf[q-p] = 0;
362
            p = q;
363
        }
364
        SendMessage(edctl, EM_REPLACESEL, 0, (LPARAM)workbuf);
365
    }
366
    linesafter = SendMessage(edctl, EM_GETLINECOUNT, 0,0);
367
    SendMessage(edctl, EM_LINESCROLL, 0, linesafter-linesbefore);
368
    if (vis) SendMessage(edctl, WM_SETREDRAW, TRUE,0);
369
    return 0;
370
}
371
 
372
int startwin_settitle(const char *str)
373
{
374
    if (!startupdlg) return 1;
375
    SetWindowText(startupdlg, str);
376
    return 0;
377
}
378
 
379
int startwin_idle(void *v)
380
{
381
    if (!startupdlg || !IsWindow(startupdlg)) return 0;
382
    if (IsDialogMessage(startupdlg, (MSG*)v)) return 1;
383
    return 0;
384
}
385
 
386
int startwin_run(void)
387
{
388
    MSG msg;
389
    if (!startupdlg) return 1;
390
 
391
    done = -1;
392
 
393
    SetPage(TAB_CONFIG);
394
    EnableConfig(1);
395
 
396
    settings.fullscreen = ScreenMode;
397
    settings.xdim = ScreenWidth;
398
    settings.ydim = ScreenHeight;
399
    settings.bpp = ScreenBPP;
400
    settings.forcesetup = ForceSetup;
401
    settings.usemouse = UseMouse;
402
    settings.usejoy = UseJoystick;
403
    PopulateForm();
404
 
405
    while (done < 0) {
406
        switch (GetMessage(&msg, NULL, 0,0)) {
407
        case 0: done = 1; break;
408
        case -1: return -1;
409
        default:
410
            if (IsWindow(startupdlg) && IsDialogMessage(startupdlg, &msg)) break;
411
            TranslateMessage(&msg);
412
            DispatchMessage(&msg);
413
            break;
414
        }
415
    }
416
 
417
    SetPage(TAB_MESSAGES);
418
    EnableConfig(0);
419
    if (done) {
420
        ScreenMode = settings.fullscreen;
421
        ScreenWidth = settings.xdim;
422
        ScreenHeight = settings.ydim;
423
        ScreenBPP = settings.bpp;
424
        ForceSetup = settings.forcesetup;
425
        UseMouse = settings.usemouse;
426
        UseJoystick = settings.usejoy;
427
    }
428
 
429
    return done;
430
}
431