Subversion Repositories eduke32

Rev

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