1 /* Copyright (C) 2001 by Alex Kompel <shurikk@pacbell.net> */
2 /* NetHack may be freely redistributed. See license for details. */
3
4 /* various dialog boxes are defined here */
5
6 #include "winMS.h"
7 #include "hack.h"
8 #include "func_tab.h"
9 #include "mhdlg.h"
10 #include "mhmain.h"
11
12 #define CheckDlgButton(dlg, btn_id, st) SendDlgItemMessage((dlg), (btn_id), BM_SETCHECK, (WPARAM)(st), 0)
13
14
15 /*---------------------------------------------------------------*/
16 /* data for getlin dialog */
17 struct getlin_data {
18 const char* question;
19 char* result;
20 size_t result_size;
21 };
22
23 LRESULT CALLBACK GetlinDlgProc(HWND, UINT, WPARAM, LPARAM);
24
mswin_getlin_window(const char * question,char * result,size_t result_size)25 int mswin_getlin_window (
26 const char *question,
27 char *result,
28 size_t result_size
29 )
30 {
31 int ret;
32 struct getlin_data data;
33
34 /* initilize dialog data */
35 ZeroMemory(&data, sizeof(data));
36 data.question = question;
37 data.result = result;
38 data.result_size = result_size;
39
40 /* create modal dialog window */
41 ret = DialogBoxParam(
42 GetNHApp()->hApp,
43 MAKEINTRESOURCE(IDD_GETLIN),
44 GetNHApp()->hMainWnd,
45 GetlinDlgProc,
46 (LPARAM)&data
47 );
48 if( ret==-1 ) panic("Cannot create getlin window");
49
50 return ret;
51 }
52
GetlinDlgProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)53 LRESULT CALLBACK GetlinDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
54 {
55 struct getlin_data* data;
56 RECT main_rt, text_rt, dlg_rt, edit_rt;
57 SIZE dlg_sz;
58 TCHAR wbuf[BUFSZ];
59 HDC hdc;
60 HWND control;
61 HWND hwndMap;
62
63 #if defined(WIN_CE_POCKETPC)
64 SHInputDialog(hWnd, message, wParam);
65 #endif
66
67 switch (message)
68 {
69 case WM_INITDIALOG:
70 data = (struct getlin_data*)lParam;
71 SetWindowText(hWnd, NH_A2W(data->question, wbuf, sizeof(wbuf)));
72 SetWindowLong(hWnd, GWL_USERDATA, lParam);
73
74 /* get title text width */
75 SetRect(&text_rt, 0, 0, 100, 50);
76 hdc = GetWindowDC(hWnd);
77 DrawText(hdc, wbuf, _tcslen(wbuf), &text_rt,
78 DT_CALCRECT | DT_SINGLELINE | DT_NOPREFIX | DT_LEFT | DT_VCENTER );
79 ReleaseDC(hWnd, hdc);
80
81 /* center dialog in the main window */
82 GetWindowRect(hWnd, &dlg_rt);
83 hwndMap = mswin_hwnd_from_winid(WIN_MAP);
84 GetWindowRect( IsWindow(hwndMap)? hwndMap : GetNHApp()->hMainWnd, &main_rt);
85 dlg_sz.cx = max(dlg_rt.right-dlg_rt.left,
86 min( text_rt.right-text_rt.left+GetSystemMetrics(SM_CXICON),
87 main_rt.right-main_rt.left ) );
88 dlg_sz.cy = min(dlg_rt.bottom - dlg_rt.top, main_rt.bottom - main_rt.top);
89 dlg_rt.left = (main_rt.left+main_rt.right-dlg_sz.cx)/2;
90 dlg_rt.right = dlg_rt.left + dlg_sz.cx;
91 dlg_rt.top = (main_rt.top+main_rt.bottom-dlg_sz.cy)/2;
92 dlg_rt.bottom = dlg_rt.top + dlg_sz.cy;
93 MoveWindow( hWnd,
94 (main_rt.left+main_rt.right-dlg_sz.cx)/2,
95 (main_rt.top+main_rt.bottom-dlg_sz.cy)/2,
96 dlg_sz.cx,
97 dlg_sz.cy,
98 TRUE );
99
100 /* change layout of controls */
101 GetClientRect(hWnd, &dlg_rt);
102
103 control = GetDlgItem(hWnd, IDC_GETLIN_EDIT);
104 GetWindowRect(control, &edit_rt);
105 MoveWindow( control,
106 0,
107 0,
108 dlg_rt.right - dlg_rt.left,
109 edit_rt.bottom - edit_rt.top,
110 TRUE );
111
112 control = GetDlgItem(hWnd, IDOK);
113 GetWindowRect(control, &text_rt);
114 MoveWindow( control,
115 0,
116 edit_rt.bottom - edit_rt.top,
117 (dlg_rt.right-dlg_rt.left)/2,
118 text_rt.bottom - text_rt.top,
119 TRUE );
120
121 control = GetDlgItem(hWnd, IDCANCEL);
122 GetWindowRect(control, &text_rt);
123 MoveWindow( control,
124 (dlg_rt.right-dlg_rt.left)/2,
125 edit_rt.bottom - edit_rt.top,
126 (dlg_rt.right-dlg_rt.left)/2,
127 text_rt.bottom - text_rt.top,
128 TRUE );
129
130 #if defined(WIN_CE_SMARTPHONE)
131 NHSPhoneDialogSetup(hWnd, TRUE, FALSE);
132 #endif
133
134 /* set focus to the edit control */
135 SetFocus(GetDlgItem(hWnd, IDC_GETLIN_EDIT));
136
137 /* tell windows that we've set the focus */
138 return FALSE;
139 break;
140
141 case WM_COMMAND:
142 {
143 TCHAR wbuf[BUFSZ];
144
145 switch (LOWORD(wParam))
146 {
147 /* OK button was pressed */
148 case IDOK:
149 data = (struct getlin_data*)GetWindowLong(hWnd, GWL_USERDATA);
150 SendDlgItemMessage(hWnd, IDC_GETLIN_EDIT, WM_GETTEXT, (WPARAM)sizeof(wbuf), (LPARAM)wbuf );
151 NH_W2A(wbuf, data->result, data->result_size);
152
153 /* Fall through. */
154
155 /* cancel button was pressed */
156 case IDCANCEL:
157 EndDialog(hWnd, wParam);
158 return TRUE;
159 }
160 } break;
161
162 #if defined(WIN_CE_SMARTPHONE)
163 case WM_HOTKEY:
164 if(VK_TBACK == HIWORD(lParam)) {
165 SHSendBackToFocusWindow(message, wParam, lParam);
166 }
167 break;
168 #endif
169
170 } /* end switch (message) */
171 return FALSE;
172 }
173
174
175 /*---------------------------------------------------------------*/
176 /* dialog data for the list of extended commands */
177 struct extcmd_data {
178 int* selection;
179 };
180
181 LRESULT CALLBACK ExtCmdDlgProc(HWND, UINT, WPARAM, LPARAM);
182
mswin_ext_cmd_window(int * selection)183 int mswin_ext_cmd_window (int* selection)
184 {
185 int ret;
186 struct extcmd_data data;
187
188 /* init dialog data */
189 ZeroMemory(&data, sizeof(data));
190 *selection = -1;
191 data.selection = selection;
192
193 /* create modal dialog window */
194 ret = DialogBoxParam(
195 GetNHApp()->hApp,
196 MAKEINTRESOURCE(IDD_EXTCMD),
197 GetNHApp()->hMainWnd,
198 ExtCmdDlgProc,
199 (LPARAM)&data
200 );
201 if( ret==-1 ) panic("Cannot create extcmd window");
202 return ret;
203 }
204
ExtCmdDlgProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)205 LRESULT CALLBACK ExtCmdDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
206 {
207 struct extcmd_data* data;
208 RECT main_rt, dlg_rt;
209 SIZE dlg_sz;
210 int i;
211 const char *ptr;
212 TCHAR wbuf[255];
213
214 switch (message)
215 {
216 case WM_INITDIALOG:
217 data = (struct extcmd_data*)lParam;
218 SetWindowLong(hWnd, GWL_USERDATA, lParam);
219
220 /* center dialog in the main window */
221 GetWindowRect(GetNHApp()->hMainWnd, &main_rt);
222 GetWindowRect(hWnd, &dlg_rt);
223 dlg_sz.cx = dlg_rt.right - dlg_rt.left;
224 dlg_sz.cy = dlg_rt.bottom - dlg_rt.top;
225
226 dlg_rt.left = (main_rt.left+main_rt.right-dlg_sz.cx)/2;
227 dlg_rt.right = dlg_rt.left + dlg_sz.cx;
228 dlg_rt.top = (main_rt.top+main_rt.bottom-dlg_sz.cy)/2;
229 dlg_rt.bottom = dlg_rt.top + dlg_sz.cy;
230 MoveWindow( hWnd,
231 (main_rt.left+main_rt.right-dlg_sz.cx)/2,
232 (main_rt.top+main_rt.bottom-dlg_sz.cy)/2,
233 dlg_sz.cx,
234 dlg_sz.cy,
235 TRUE );
236
237 /* fill combobox with extended commands */
238 for(i=0; (ptr=extcmdlist[i].ef_txt); i++) {
239 SendDlgItemMessage(hWnd, IDC_EXTCMD_LIST, LB_ADDSTRING, (WPARAM)0, (LPARAM)NH_A2W(ptr, wbuf, sizeof(wbuf)) );
240 }
241
242 #if defined(WIN_CE_SMARTPHONE)
243 NHSPhoneDialogSetup(hWnd, FALSE, FALSE);
244
245 GetClientRect(hWnd, &dlg_rt);
246 MoveWindow(GetDlgItem(hWnd, IDC_EXTCMD_LIST),
247 dlg_rt.left, dlg_rt.top,
248 dlg_rt.right-dlg_rt.left, dlg_rt.bottom-dlg_rt.top,
249 TRUE);
250 #endif
251
252 /* set focus to the list control */
253 SetFocus(GetDlgItem(hWnd, IDC_EXTCMD_LIST));
254
255 /* tell windows we set the focus */
256 return FALSE;
257 break;
258
259 case WM_COMMAND:
260 data = (struct extcmd_data*)GetWindowLong(hWnd, GWL_USERDATA);
261 switch (LOWORD(wParam))
262 {
263 /* OK button ws clicked */
264 case IDOK:
265 *data->selection = SendDlgItemMessage(hWnd, IDC_EXTCMD_LIST, LB_GETCURSEL, (WPARAM)0, (LPARAM)0 );
266 if( *data->selection==LB_ERR )
267 *data->selection = -1;
268 /* Fall through. */
269
270 /* CANCEL button ws clicked */
271 case IDCANCEL:
272 EndDialog(hWnd, wParam);
273 return TRUE;
274
275 /* list control events */
276 case IDC_EXTCMD_LIST:
277 switch(HIWORD(wParam)) {
278
279 case LBN_DBLCLK:
280 /* double click within the list
281 wParam
282 The low-order word is the list box identifier.
283 The high-order word is the notification message.
284 lParam
285 Handle to the list box
286 */
287 *data->selection = SendMessage((HWND)lParam, LB_GETCURSEL, (WPARAM)0, (LPARAM)0);
288 if( *data->selection==LB_ERR )
289 *data->selection = -1;
290 EndDialog(hWnd, IDOK);
291 return TRUE;
292 }
293 break;
294 }
295 }
296 return FALSE;
297 }
298
299 /*---------------------------------------------------------------*/
300 /* player selector dialog data */
301 struct plsel_data {
302 int* selection;
303 };
304
305 BOOL CALLBACK PlayerSelectorDlgProc(HWND, UINT, WPARAM, LPARAM);
306 static void plselInitDialog(HWND hWnd);
307 static void plselAdjustLists(HWND hWnd, int changed_opt);
308 static int plselFinalSelection(HWND hWnd, int* selection);
309
mswin_player_selection_window(int * selection)310 int mswin_player_selection_window ( int* selection )
311 {
312 int ret;
313 struct plsel_data data;
314
315 /* init dialog data */
316 ZeroMemory(&data, sizeof(data));
317 data.selection = selection;
318
319 /* create modal dialog */
320 ret = DialogBoxParam(
321 GetNHApp()->hApp,
322 MAKEINTRESOURCE(IDD_PLAYER_SELECTOR),
323 GetNHApp()->hMainWnd,
324 PlayerSelectorDlgProc,
325 (LPARAM)&data
326 );
327 if( ret==-1 ) panic("Cannot create getlin window");
328
329 return ret;
330 }
331
PlayerSelectorDlgProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)332 BOOL CALLBACK PlayerSelectorDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
333 {
334 struct plsel_data* data;
335 RECT main_rt, dlg_rt;
336 SIZE dlg_sz;
337
338 switch (message)
339 {
340 case WM_INITDIALOG:
341 data = (struct plsel_data*)lParam;
342 SetWindowLong(hWnd, GWL_USERDATA, lParam);
343
344 /* center dialog in the main window */
345 GetWindowRect(GetNHApp()->hMainWnd, &main_rt);
346 GetWindowRect(hWnd, &dlg_rt);
347 dlg_sz.cx = dlg_rt.right - dlg_rt.left;
348 dlg_sz.cy = dlg_rt.bottom - dlg_rt.top;
349
350 dlg_rt.left = (main_rt.left+main_rt.right-dlg_sz.cx)/2;
351 dlg_rt.right = dlg_rt.left + dlg_sz.cx;
352 dlg_rt.top = (main_rt.top+main_rt.bottom-dlg_sz.cy)/2;
353 dlg_rt.bottom = dlg_rt.top + dlg_sz.cy;
354 MoveWindow( hWnd,
355 (main_rt.left+main_rt.right-dlg_sz.cx)/2,
356 (main_rt.top+main_rt.bottom-dlg_sz.cy)/2,
357 dlg_sz.cx,
358 dlg_sz.cy,
359 TRUE );
360
361 /* init dialog */
362 plselInitDialog(hWnd);
363
364 #if defined(WIN_CE_SMARTPHONE)
365 NHSPhoneDialogSetup(hWnd, FALSE, FALSE);
366 #endif
367 /* set focus on the role checkbox (random) field */
368 SetFocus(GetDlgItem(hWnd, IDC_PLSEL_ROLE_RANDOM));
369
370 /* tell windows we set the focus */
371 return FALSE;
372 break;
373
374 case WM_COMMAND:
375 data = (struct plsel_data*)GetWindowLong(hWnd, GWL_USERDATA);
376 switch (LOWORD(wParam)) {
377
378 /* OK button was clicked */
379 case IDOK:
380 if( plselFinalSelection(hWnd, data->selection) ) {
381 EndDialog(hWnd, wParam);
382 } else {
383 MessageBox(hWnd, TEXT("Cannot match this role. Try something else."), TEXT("STOP"), MB_OK );
384 }
385 return TRUE;
386
387 /* CANCEL button was clicked */
388 case IDCANCEL:
389 *data->selection = -1;
390 EndDialog(hWnd, wParam);
391 return TRUE;
392
393 /* following are events from dialog controls:
394 "random" checkboxes send BN_CLICKED messages;
395 role/race/... combo-boxes send CBN_SELENDOK
396 if something was selected;
397 */
398 case IDC_PLSEL_ROLE_RANDOM:
399 if( HIWORD(wParam)==BN_CLICKED ) {
400 /* enable corresponding list window if "random"
401 checkbox was "unchecked" */
402 EnableWindow(
403 GetDlgItem(hWnd, IDC_PLSEL_ROLE_LIST),
404 SendMessage((HWND)lParam, BM_GETCHECK, 0, 0)==BST_UNCHECKED
405 );
406 }
407 break;
408
409 case IDC_PLSEL_RACE_RANDOM:
410 if( HIWORD(wParam)==BN_CLICKED ) {
411 EnableWindow(
412 GetDlgItem(hWnd, IDC_PLSEL_RACE_LIST),
413 SendMessage((HWND)lParam, BM_GETCHECK, 0, 0)==BST_UNCHECKED
414 );
415 }
416 break;
417
418 case IDC_PLSEL_GENDER_RANDOM:
419 if( HIWORD(wParam)==BN_CLICKED ) {
420 EnableWindow(
421 GetDlgItem(hWnd, IDC_PLSEL_GENDER_LIST),
422 SendMessage((HWND)lParam, BM_GETCHECK, 0, 0)==BST_UNCHECKED
423 );
424 }
425 break;
426
427 case IDC_PLSEL_ALIGN_RANDOM:
428 if( HIWORD(wParam)==BN_CLICKED ) {
429 EnableWindow(
430 GetDlgItem(hWnd, IDC_PLSEL_ALIGN_LIST),
431 SendMessage((HWND)lParam, BM_GETCHECK, 0, 0)==BST_UNCHECKED
432 );
433 }
434 break;
435
436 case IDC_PLSEL_ROLE_LIST:
437 if( HIWORD(wParam)==CBN_SELENDOK ) {
438 /* filter out invalid options if
439 the selection was made */
440 plselAdjustLists( hWnd, LOWORD(wParam) );
441 }
442 break;
443
444 case IDC_PLSEL_RACE_LIST:
445 if( HIWORD(wParam)==CBN_SELENDOK ) {
446 plselAdjustLists( hWnd, LOWORD(wParam) );
447 }
448 break;
449
450 case IDC_PLSEL_GENDER_LIST:
451 if( HIWORD(wParam)==CBN_SELENDOK ) {
452 plselAdjustLists( hWnd, LOWORD(wParam) );
453 }
454 break;
455
456 case IDC_PLSEL_ALIGN_LIST:
457 if( HIWORD(wParam)==CBN_SELENDOK ) {
458 plselAdjustLists( hWnd, LOWORD(wParam) );
459 }
460 break;
461 }
462 break;
463 }
464 return FALSE;
465 }
466
setComboBoxValue(HWND hWnd,int combo_box,int value)467 void setComboBoxValue(HWND hWnd, int combo_box, int value)
468 {
469 int index_max = SendDlgItemMessage(hWnd, combo_box, CB_GETCOUNT, 0, 0);
470 int index;
471 int value_to_set = LB_ERR;
472 for (index = 0; index < index_max; index++) {
473 if (SendDlgItemMessage(hWnd, combo_box, CB_GETITEMDATA, (WPARAM)index, 0) == value) {
474 value_to_set = index;
475 break;
476 }
477 }
478 SendDlgItemMessage(hWnd, combo_box, CB_SETCURSEL, (WPARAM)value_to_set, 0);
479 }
480
481 /* initialize player selector dialog */
plselInitDialog(HWND hWnd)482 void plselInitDialog(HWND hWnd)
483 {
484 TCHAR wbuf[BUFSZ];
485
486 /* set player name */
487 SetDlgItemText(hWnd, IDC_PLSEL_NAME, NH_A2W(plname, wbuf, sizeof(wbuf)));
488
489 /* check flags for consistency */
490 if( flags.initrole>=0 ) {
491 if (flags.initrace>=0 && !validrace(flags.initrole, flags.initrace)) {
492 flags.initrace = ROLE_NONE;
493 }
494
495 if (flags.initgend>=0 && !validgend(flags.initrole, flags.initrace, flags.initgend)) {
496 flags.initgend = ROLE_NONE;
497 }
498
499 if (flags.initalign>=0 && !validalign(flags.initrole, flags.initrace, flags.initalign)) {
500 flags.initalign = ROLE_NONE;
501 }
502 }
503
504 /* populate select boxes */
505 plselAdjustLists(hWnd, -1);
506
507 /* intialize roles list */
508 if( flags.initrole<0 || !ok_role(flags.initrole, ROLE_NONE, ROLE_NONE, ROLE_NONE)) {
509 CheckDlgButton(hWnd, IDC_PLSEL_ROLE_RANDOM, BST_CHECKED);
510 EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_ROLE_LIST), FALSE);
511 } else {
512 CheckDlgButton(hWnd, IDC_PLSEL_ROLE_RANDOM, BST_UNCHECKED);
513 EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_ROLE_LIST), TRUE);
514 setComboBoxValue(hWnd, IDC_PLSEL_ROLE_LIST, flags.initrole);
515 }
516
517 /* intialize races list */
518 if( flags.initrace<0 || !ok_race(flags.initrole, flags.initrace, ROLE_NONE, ROLE_NONE) ) {
519 CheckDlgButton(hWnd, IDC_PLSEL_RACE_RANDOM, BST_CHECKED);
520 EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_RACE_LIST), FALSE);
521 } else {
522 CheckDlgButton(hWnd, IDC_PLSEL_RACE_RANDOM, BST_UNCHECKED);
523 EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_RACE_LIST), TRUE);
524 setComboBoxValue(hWnd, IDC_PLSEL_RACE_LIST, flags.initrace);
525 }
526
527 /* intialize genders list */
528 if( flags.initgend<0 || !ok_gend(flags.initrole, flags.initrace, flags.initgend, ROLE_NONE)) {
529 CheckDlgButton(hWnd, IDC_PLSEL_GENDER_RANDOM, BST_CHECKED);
530 EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_GENDER_LIST), FALSE);
531 } else {
532 CheckDlgButton(hWnd, IDC_PLSEL_GENDER_RANDOM, BST_UNCHECKED);
533 EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_GENDER_LIST), TRUE);
534 setComboBoxValue(hWnd, IDC_PLSEL_GENDER_LIST, flags.initgend);
535 }
536
537 /* intialize alignments list */
538 if( flags.initalign<0 || !ok_align(flags.initrole, flags.initrace, flags.initgend, flags.initalign) ) {
539 CheckDlgButton(hWnd, IDC_PLSEL_ALIGN_RANDOM, BST_CHECKED);
540 EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_ALIGN_LIST), FALSE);
541 } else {
542 CheckDlgButton(hWnd, IDC_PLSEL_ALIGN_RANDOM, BST_UNCHECKED);
543 EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_ALIGN_LIST), TRUE);
544 setComboBoxValue(hWnd, IDC_PLSEL_ALIGN_LIST, flags.initalign);
545 }
546 }
547
548 /* adjust role/race/alignment/gender list - filter out
549 invalid combinations
550 changed_sel points to the list where selection occured
551 (-1 if unknown)
552 */
plselAdjustLists(HWND hWnd,int changed_sel)553 void plselAdjustLists(HWND hWnd, int changed_sel)
554 {
555 HWND control_role, control_race, control_gender, control_align;
556 int initrole, initrace, initgend, initalign;
557 int i;
558 int ind;
559 int valid_opt;
560 TCHAR wbuf[255];
561
562 /* get control handles */
563 control_role = GetDlgItem(hWnd, IDC_PLSEL_ROLE_LIST);
564 control_race = GetDlgItem(hWnd, IDC_PLSEL_RACE_LIST);
565 control_gender = GetDlgItem(hWnd, IDC_PLSEL_GENDER_LIST);
566 control_align = GetDlgItem(hWnd, IDC_PLSEL_ALIGN_LIST);
567
568 /* get current selections */
569 ind = SendMessage(control_role, CB_GETCURSEL, 0, 0);
570 initrole = (ind==LB_ERR)? flags.initrole : SendMessage(control_role, CB_GETITEMDATA, ind, 0);
571
572 ind = SendMessage(control_race, CB_GETCURSEL, 0, 0);
573 initrace = (ind==LB_ERR)? flags.initrace : SendMessage(control_race, CB_GETITEMDATA, ind, 0);
574
575 ind = SendMessage(control_gender, CB_GETCURSEL, 0, 0);
576 initgend = (ind==LB_ERR)? flags.initgend : SendMessage(control_gender, CB_GETITEMDATA, ind, 0);
577
578 ind = SendMessage(control_align, CB_GETCURSEL, 0, 0);
579 initalign = (ind==LB_ERR)? flags.initalign : SendMessage(control_align, CB_GETITEMDATA, ind, 0);
580
581 /* intialize roles list */
582 if( changed_sel==-1 ) {
583 valid_opt = 0;
584
585 /* reset content and populate the list */
586 SendMessage(control_role, CB_RESETCONTENT, 0, 0);
587 for (i = 0; roles[i].name.m; i++) {
588 if (ok_role(i, initrace, initgend, initalign)) {
589 if (initgend>=0 && flags.female && roles[i].name.f)
590 ind = SendMessage(control_role, CB_ADDSTRING, (WPARAM)0, (LPARAM)NH_A2W(roles[i].name.f, wbuf, sizeof(wbuf)) );
591 else
592 ind = SendMessage(control_role, CB_ADDSTRING, (WPARAM)0, (LPARAM)NH_A2W(roles[i].name.m, wbuf, sizeof(wbuf)) );
593
594 SendMessage(control_role, CB_SETITEMDATA, (WPARAM)ind, (LPARAM)i );
595 if( i==initrole ) {
596 SendMessage(control_role, CB_SETCURSEL, (WPARAM)ind, (LPARAM)0 );
597 valid_opt = 1;
598 }
599 }
600 }
601
602 /* set selection to the previously selected role
603 if it is still valid */
604 if( !valid_opt ) {
605 initrole = ROLE_NONE;
606 initrace = ROLE_NONE;
607 initgend = ROLE_NONE;
608 initalign = ROLE_NONE;
609 SendMessage(control_role, CB_SETCURSEL, (WPARAM)-1, (LPARAM)0 );
610 }
611
612 /* trigger change of the races list */
613 changed_sel=IDC_PLSEL_ROLE_LIST;
614 }
615
616 /* intialize races list */
617 if( changed_sel==IDC_PLSEL_ROLE_LIST ) {
618 valid_opt = 0;
619
620 /* reset content and populate the list */
621 SendMessage(control_race, CB_RESETCONTENT, 0, 0);
622 for (i = 0; races[i].noun; i++)
623 if (ok_race(initrole, i, ROLE_NONE, ROLE_NONE)) {
624 ind = SendMessage(control_race, CB_ADDSTRING, (WPARAM)0, (LPARAM)NH_A2W(races[i].noun, wbuf, sizeof(wbuf)) );
625 SendMessage(control_race, CB_SETITEMDATA, (WPARAM)ind, (LPARAM)i );
626 if( i==initrace ) {
627 SendMessage(control_race, CB_SETCURSEL, (WPARAM)ind, (LPARAM)0 );
628 valid_opt = 1;
629 }
630 }
631
632 /* set selection to the previously selected race
633 if it is still valid */
634 if( !valid_opt ) {
635 initrace = ROLE_NONE;
636 initgend = ROLE_NONE;
637 initalign = ROLE_NONE;
638 SendMessage(control_race, CB_SETCURSEL, (WPARAM)-1, (LPARAM)0 );
639 }
640
641 /* trigger change of the genders list */
642 changed_sel=IDC_PLSEL_RACE_LIST;
643 }
644
645 /* intialize genders list */
646 if( changed_sel==IDC_PLSEL_RACE_LIST ) {
647 valid_opt = 0;
648
649 /* reset content and populate the list */
650 SendMessage(control_gender, CB_RESETCONTENT, 0, 0);
651 for (i = 0; i < ROLE_GENDERS; i++)
652 if (ok_gend(initrole, initrace, i, ROLE_NONE)) {
653 ind = SendMessage(control_gender, CB_ADDSTRING, (WPARAM)0, (LPARAM)NH_A2W(genders[i].adj, wbuf, sizeof(wbuf)) );
654 SendMessage(control_gender, CB_SETITEMDATA, (WPARAM)ind, (LPARAM)i );
655 if( i==initgend ) {
656 SendMessage(control_gender, CB_SETCURSEL, (WPARAM)ind, (LPARAM)0 );
657 valid_opt = 1;
658 }
659 }
660
661 /* set selection to the previously selected gender
662 if it is still valid */
663 if( !valid_opt ) {
664 initgend = ROLE_NONE;
665 initalign = ROLE_NONE;
666 SendMessage(control_gender, CB_SETCURSEL, (WPARAM)-1, (LPARAM)0 );
667 }
668
669 /* trigger change of the alignments list */
670 changed_sel=IDC_PLSEL_GENDER_LIST;
671 }
672
673 /* intialize alignments list */
674 if( changed_sel==IDC_PLSEL_GENDER_LIST ) {
675 valid_opt = 0;
676
677 /* reset content and populate the list */
678 SendMessage(control_align, CB_RESETCONTENT, 0, 0);
679 for (i = 0; i < ROLE_ALIGNS; i++)
680 if (ok_align(initrole, initrace, initgend, i)) {
681 ind = SendMessage(control_align, CB_ADDSTRING, (WPARAM)0, (LPARAM)NH_A2W(aligns[i].adj, wbuf, sizeof(wbuf)) );
682 SendMessage(control_align, CB_SETITEMDATA, (WPARAM)ind, (LPARAM)i );
683 if( i==initalign ) {
684 SendMessage(control_align, CB_SETCURSEL, (WPARAM)ind, (LPARAM)0 );
685 valid_opt = 1;
686 }
687 }
688
689 /* set selection to the previously selected alignment
690 if it is still valid */
691 if( !valid_opt ) {
692 initalign = ROLE_NONE;
693 SendMessage(control_align, CB_SETCURSEL, (WPARAM)-1, (LPARAM)0 );
694 }
695 }
696 }
697
698 /* player made up his mind - get final selection here */
plselFinalSelection(HWND hWnd,int * selection)699 int plselFinalSelection(HWND hWnd, int* selection)
700 {
701 int ind;
702
703 /* get current selections */
704 if( SendDlgItemMessage(hWnd, IDC_PLSEL_ROLE_RANDOM, BM_GETCHECK, 0, 0)==BST_CHECKED ) {
705 flags.initrole = ROLE_RANDOM;
706 } else {
707 ind = SendDlgItemMessage(hWnd, IDC_PLSEL_ROLE_LIST, CB_GETCURSEL, 0, 0);
708 flags.initrole = (ind==LB_ERR)? ROLE_RANDOM : SendDlgItemMessage(hWnd, IDC_PLSEL_ROLE_LIST, CB_GETITEMDATA, ind, 0);
709 }
710
711 if( SendDlgItemMessage(hWnd, IDC_PLSEL_RACE_RANDOM, BM_GETCHECK, 0, 0)==BST_CHECKED ) {
712 flags.initrace = ROLE_RANDOM;
713 } else {
714 ind = SendDlgItemMessage(hWnd, IDC_PLSEL_RACE_LIST, CB_GETCURSEL, 0, 0);
715 flags.initrace = (ind==LB_ERR)? ROLE_RANDOM : SendDlgItemMessage(hWnd, IDC_PLSEL_RACE_LIST, CB_GETITEMDATA, ind, 0);
716 }
717
718 if( SendDlgItemMessage(hWnd, IDC_PLSEL_GENDER_RANDOM, BM_GETCHECK, 0, 0)==BST_CHECKED ) {
719 flags.initgend = ROLE_RANDOM;
720 } else {
721 ind = SendDlgItemMessage(hWnd, IDC_PLSEL_GENDER_LIST, CB_GETCURSEL, 0, 0);
722 flags.initgend = (ind==LB_ERR)? ROLE_RANDOM : SendDlgItemMessage(hWnd, IDC_PLSEL_GENDER_LIST, CB_GETITEMDATA, ind, 0);
723 }
724
725 if( SendDlgItemMessage(hWnd, IDC_PLSEL_ALIGN_RANDOM, BM_GETCHECK, 0, 0)==BST_CHECKED ) {
726 flags.initalign = ROLE_RANDOM;
727 } else {
728 ind = SendDlgItemMessage(hWnd, IDC_PLSEL_ALIGN_LIST, CB_GETCURSEL, 0, 0);
729 flags.initalign = (ind==LB_ERR)? ROLE_RANDOM : SendDlgItemMessage(hWnd, IDC_PLSEL_ALIGN_LIST, CB_GETITEMDATA, ind, 0);
730 }
731
732
733 /* check the role */
734 if( flags.initrole==ROLE_RANDOM ) {
735 flags.initrole = pick_role(flags.initrace, flags.initgend, flags.initalign, PICK_RANDOM);
736 if (flags.initrole < 0) {
737 MessageBox(hWnd, TEXT("Incompatible role!"), TEXT("STOP"), MB_OK);
738 return FALSE;
739 }
740 }
741
742 /* Select a race, if necessary */
743 /* force compatibility with role */
744 if (flags.initrace==ROLE_RANDOM || !validrace(flags.initrole, flags.initrace)) {
745 /* pre-selected race not valid */
746 if (flags.initrace == ROLE_RANDOM) {
747 flags.initrace = pick_race(flags.initrole, flags.initgend, flags.initalign, PICK_RANDOM);
748 }
749
750 if (flags.initrace < 0) {
751 MessageBox(hWnd, TEXT("Incompatible race!"), TEXT("STOP"), MB_OK);
752 return FALSE;
753 }
754 }
755
756 /* Select a gender, if necessary */
757 /* force compatibility with role/race, try for compatibility with
758 * pre-selected alignment */
759 if (flags.initgend < 0 ||
760 !validgend(flags.initrole, flags.initrace, flags.initgend)) {
761 /* pre-selected gender not valid */
762 if (flags.initgend == ROLE_RANDOM) {
763 flags.initgend = pick_gend(flags.initrole, flags.initrace, flags.initalign, PICK_RANDOM);
764 }
765
766 if (flags.initgend < 0) {
767 MessageBox(hWnd, TEXT("Incompatible gender!"), TEXT("STOP"), MB_OK);
768 return FALSE;
769 }
770 }
771
772 /* Select an alignment, if necessary */
773 /* force compatibility with role/race/gender */
774 if (flags.initalign < 0 ||
775 !validalign(flags.initrole, flags.initrace, flags.initalign)) {
776 /* pre-selected alignment not valid */
777 if (flags.initalign == ROLE_RANDOM) {
778 flags.initalign = pick_align(flags.initrole, flags.initrace, flags.initgend, PICK_RANDOM);
779 } else {
780 MessageBox(hWnd, TEXT("Incompatible alignment!"), TEXT("STOP"), MB_OK);
781 return FALSE;
782 }
783 }
784
785 return TRUE;
786 }
787
788