Files
nethack/win/win32/mhdlg.c
2018-12-15 19:31:42 -05:00

788 lines
26 KiB
C

/* NetHack 3.6 mhdlg.c $NHDT-Date: 1544695946 2018/12/13 10:12:26 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.30 $ */
/* Copyright (C) 2001 by Alex Kompel */
/* NetHack may be freely redistributed. See license for details. */
/* various dialog boxes are defined here */
#include "winMS.h"
#include "hack.h"
#include "func_tab.h"
#include "resource.h"
#include "mhdlg.h"
#include <assert.h>
/*---------------------------------------------------------------*/
/* data for getlin dialog */
struct getlin_data {
const char *question;
char *result;
size_t result_size;
};
INT_PTR CALLBACK GetlinDlgProc(HWND, UINT, WPARAM, LPARAM);
int
mswin_getlin_window(const char *question, char *result, size_t result_size)
{
if (iflags.debug_fuzzer) {
random_response(result, (int) result_size);
if (result[0] != '\0')
return IDOK;
else
return IDCANCEL;
}
INT_PTR ret;
struct getlin_data data;
/* initilize dialog data */
ZeroMemory(&data, sizeof(data));
data.question = question;
data.result = result;
data.result_size = result_size;
/* create modal dialog window */
ret = DialogBoxParam(GetNHApp()->hApp, MAKEINTRESOURCE(IDD_GETLIN),
GetNHApp()->hMainWnd, GetlinDlgProc, (LPARAM) &data);
if (ret == -1)
panic("Cannot create getlin window");
return (int) ret;
}
INT_PTR CALLBACK
GetlinDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
struct getlin_data *data;
RECT main_rt, dlg_rt;
SIZE dlg_sz;
TCHAR wbuf[BUFSZ];
HDC WindowDC;
HWND ControlHWND;
SIZE WindowExtents;
SIZE ViewPortExtents;
RECT ControlRect;
RECT ClientRect;
LONG Division;
LONG ButtonOffset;
switch (message) {
case WM_INITDIALOG:
data = (struct getlin_data *) lParam;
SetWindowText(hWnd, NH_A2W(data->question, wbuf, sizeof(wbuf)));
SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR) data);
/* center dialog in the main window */
GetWindowRect(hWnd, &dlg_rt);
GetWindowRect(GetNHApp()->hMainWnd, &main_rt);
WindowDC = GetWindowDC(hWnd);
if (!GetWindowExtEx(WindowDC, &WindowExtents)
|| !GetViewportExtEx(WindowDC, &ViewPortExtents)
|| !GetTextExtentPoint32(GetWindowDC(hWnd), wbuf, _tcslen(wbuf),
&dlg_sz)) {
dlg_sz.cx = 0;
} else {
/* I think we need to do the following scaling */
dlg_sz.cx *= ViewPortExtents.cx;
dlg_sz.cx /= WindowExtents.cx;
/* Add the size of the various items in the caption bar */
dlg_sz.cx += GetSystemMetrics(SM_CXSIZE)
+ 2 * (GetSystemMetrics(SM_CXBORDER)
+ GetSystemMetrics(SM_CXFRAME));
}
if (dlg_sz.cx < dlg_rt.right - dlg_rt.left)
dlg_sz.cx = dlg_rt.right - dlg_rt.left;
dlg_sz.cy = dlg_rt.bottom - dlg_rt.top;
dlg_rt.left = (main_rt.left + main_rt.right - dlg_sz.cx) / 2;
dlg_rt.right = dlg_rt.left + dlg_sz.cx;
dlg_rt.top = (main_rt.top + main_rt.bottom - dlg_sz.cy) / 2;
dlg_rt.bottom = dlg_rt.top + dlg_sz.cy;
MoveWindow(hWnd, (main_rt.left + main_rt.right - dlg_sz.cx) / 2,
(main_rt.top + main_rt.bottom - dlg_sz.cy) / 2, dlg_sz.cx,
dlg_sz.cy, TRUE);
/* set focus and size of the edit control */
ControlHWND = GetDlgItem(hWnd, IDC_GETLIN_EDIT);
SetFocus(ControlHWND);
GetClientRect(hWnd, &ClientRect);
GetWindowRect(ControlHWND, &ControlRect);
MoveWindow(ControlHWND, 0, 0, ClientRect.right - ClientRect.left,
ControlRect.bottom - ControlRect.top, TRUE);
ButtonOffset = ControlRect.bottom - ControlRect.top;
/* Now get the OK and CANCEL buttons */
ControlHWND = GetDlgItem(hWnd, IDOK);
GetWindowRect(ControlHWND, &ControlRect);
Division = ((ClientRect.right - ClientRect.left)
- 2 * (ControlRect.right - ControlRect.left)) / 3;
MoveWindow(ControlHWND, Division, ButtonOffset,
ControlRect.right - ControlRect.left,
ControlRect.bottom - ControlRect.top, TRUE);
ControlHWND = GetDlgItem(hWnd, IDCANCEL);
MoveWindow(ControlHWND,
Division * 2 + ControlRect.right - ControlRect.left,
ButtonOffset, ControlRect.right - ControlRect.left,
ControlRect.bottom - ControlRect.top, TRUE);
/* tell windows that we've set the focus */
return FALSE;
break;
case WM_COMMAND: {
TCHAR wbuf[BUFSZ];
switch (LOWORD(wParam)) {
/* OK button was pressed */
case IDOK:
data =
(struct getlin_data *) GetWindowLongPtr(hWnd, GWLP_USERDATA);
SendDlgItemMessage(hWnd, IDC_GETLIN_EDIT, WM_GETTEXT,
(WPARAM) sizeof(wbuf), (LPARAM) wbuf);
NH_W2A(wbuf, data->result, data->result_size);
/* Fall through. */
/* cancel button was pressed */
case IDCANCEL:
EndDialog(hWnd, wParam);
return TRUE;
}
} break;
} /* end switch (message) */
return FALSE;
}
/*---------------------------------------------------------------*/
/* dialog data for the list of extended commands */
struct extcmd_data {
int *selection;
};
INT_PTR CALLBACK ExtCmdDlgProc(HWND, UINT, WPARAM, LPARAM);
int
mswin_ext_cmd_window(int *selection)
{
if (iflags.debug_fuzzer) {
*selection = rnd_extcmd_idx();
if (*selection != -1)
return IDOK;
else
return IDCANCEL;
}
INT_PTR ret;
struct extcmd_data data;
/* init dialog data */
ZeroMemory(&data, sizeof(data));
*selection = -1;
data.selection = selection;
/* create modal dialog window */
ret = DialogBoxParam(GetNHApp()->hApp, MAKEINTRESOURCE(IDD_EXTCMD),
GetNHApp()->hMainWnd, ExtCmdDlgProc, (LPARAM) &data);
if (ret == -1)
panic("Cannot create extcmd window");
return (int) ret;
}
INT_PTR CALLBACK
ExtCmdDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
struct extcmd_data *data;
RECT main_rt, dlg_rt;
SIZE dlg_sz;
int i;
TCHAR wbuf[255];
switch (message) {
case WM_INITDIALOG:
data = (struct extcmd_data *) lParam;
SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR) data);
/* center dialog in the main window */
GetWindowRect(GetNHApp()->hMainWnd, &main_rt);
GetWindowRect(hWnd, &dlg_rt);
dlg_sz.cx = dlg_rt.right - dlg_rt.left;
dlg_sz.cy = dlg_rt.bottom - dlg_rt.top;
dlg_rt.left = (main_rt.left + main_rt.right - dlg_sz.cx) / 2;
dlg_rt.right = dlg_rt.left + dlg_sz.cx;
dlg_rt.top = (main_rt.top + main_rt.bottom - dlg_sz.cy) / 2;
dlg_rt.bottom = dlg_rt.top + dlg_sz.cy;
MoveWindow(hWnd, (main_rt.left + main_rt.right - dlg_sz.cx) / 2,
(main_rt.top + main_rt.bottom - dlg_sz.cy) / 2, dlg_sz.cx,
dlg_sz.cy, TRUE);
/* fill combobox with extended commands */
for (i = 0; extcmdlist[i].ef_txt; i++) {
SendDlgItemMessage(
hWnd, IDC_EXTCMD_LIST, LB_ADDSTRING, (WPARAM) 0,
(LPARAM) NH_A2W(extcmdlist[i].ef_txt, wbuf, sizeof(wbuf)));
}
/* set focus to the list control */
SetFocus(GetDlgItem(hWnd, IDC_EXTCMD_LIST));
/* tell windows we set the focus */
return FALSE;
break;
case WM_COMMAND:
data = (struct extcmd_data *) GetWindowLongPtr(hWnd, GWLP_USERDATA);
switch (LOWORD(wParam)) {
/* OK button ws clicked */
case IDOK:
*data->selection = (int) SendDlgItemMessage(
hWnd, IDC_EXTCMD_LIST, LB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
if (*data->selection == LB_ERR)
*data->selection = -1;
/* Fall through. */
/* CANCEL button ws clicked */
case IDCANCEL:
EndDialog(hWnd, wParam);
return TRUE;
/* list control events */
case IDC_EXTCMD_LIST:
switch (HIWORD(wParam)) {
case LBN_DBLCLK:
/* double click within the list
wParam
The low-order word is the list box identifier.
The high-order word is the notification message.
lParam
Handle to the list box
*/
*data->selection = (int) SendMessage(
(HWND) lParam, LB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
if (*data->selection == LB_ERR)
*data->selection = -1;
EndDialog(hWnd, IDOK);
return TRUE;
}
break;
}
}
return FALSE;
}
/*---------------------------------------------------------------*/
/* player selector dialog */
typedef struct plsel_data {
int config_race;
int config_role;
int config_gender;
int config_alignment;
HWND control_role;
HWND control_race;
HWND control_genders[ROLE_GENDERS];
HWND control_aligns[ROLE_ALIGNS];
int role_count;
int race_count;
HWND focus;
} plsel_data_t;
INT_PTR CALLBACK PlayerSelectorDlgProc(HWND, UINT, WPARAM, LPARAM);
static void plselInitDialog(HWND hWnd);
static void plselAdjustSelections(HWND hWnd);
static boolean plselRandomize(plsel_data_t * data);
static BOOL plselDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam);
boolean
mswin_player_selection_window()
{
INT_PTR ret;
plsel_data_t data;
boolean ok = TRUE;
/* save away configuration settings */
data.config_role = flags.initrole;
data.config_race = flags.initrace;
data.config_gender = flags.initgend;
data.config_alignment = flags.initalign;
if (!plselRandomize(&data)) {
/* create modal dialog */
ret = DialogBoxParam(
GetNHApp()->hApp, MAKEINTRESOURCE(IDD_PLAYER_SELECTOR),
GetNHApp()->hMainWnd, PlayerSelectorDlgProc, (LPARAM) &data);
if (ret == -1)
panic("Cannot create getlin window");
ok = (ret == IDOK);
}
return ok;
}
INT_PTR CALLBACK
PlayerSelectorDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
struct plsel_data *data;
RECT main_rt, dlg_rt;
SIZE dlg_sz;
switch (message) {
case WM_INITDIALOG:
data = (struct plsel_data *) lParam;
SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR) data);
/* center dialog in the main window */
GetWindowRect(GetNHApp()->hMainWnd, &main_rt);
GetWindowRect(hWnd, &dlg_rt);
dlg_sz.cx = dlg_rt.right - dlg_rt.left;
dlg_sz.cy = dlg_rt.bottom - dlg_rt.top;
dlg_rt.left = (main_rt.left + main_rt.right - dlg_sz.cx) / 2;
dlg_rt.right = dlg_rt.left + dlg_sz.cx;
dlg_rt.top = (main_rt.top + main_rt.bottom - dlg_sz.cy) / 2;
dlg_rt.bottom = dlg_rt.top + dlg_sz.cy;
MoveWindow(hWnd, (main_rt.left + main_rt.right - dlg_sz.cx) / 2,
(main_rt.top + main_rt.bottom - dlg_sz.cy) / 2, dlg_sz.cx,
dlg_sz.cy, TRUE);
/* init dialog */
plselInitDialog(hWnd);
/* tell windows to set the focus */
return TRUE;
break;
case WM_DRAWITEM:
if (wParam == IDC_PLSEL_ROLE_LIST || wParam == IDC_PLSEL_RACE_LIST)
return plselDrawItem(hWnd, wParam, lParam);
break;
case WM_NOTIFY:
{
LPNMHDR nmhdr = (LPNMHDR)lParam;
HWND control = nmhdr->hwndFrom;
data = (struct plsel_data *) GetWindowLongPtr(hWnd, GWLP_USERDATA);
switch (nmhdr->code) {
case LVN_KEYDOWN:
{
LPNMLVKEYDOWN lpnmkeydown = (LPNMLVKEYDOWN) lParam;
if (lpnmkeydown->wVKey == ' ') {
if (control == data->control_role) {
int i = ListView_GetNextItem(data->control_role, -1, LVNI_FOCUSED);
assert(i == -1 || ListView_GetNextItem(data->control_role, i, LVNI_FOCUSED) == -1);
flags.initrole = i;
plselAdjustSelections(hWnd);
} else if (control == data->control_race) {
int i = ListView_GetNextItem(data->control_race, -1, LVNI_FOCUSED);
assert(i == -1 || ListView_GetNextItem(data->control_race, i, LVNI_FOCUSED) == -1);
if (ok_race(flags.initrole, i, ROLE_RANDOM, ROLE_RANDOM)) {
flags.initrace = i;
plselAdjustSelections(hWnd);
}
}
}
}
break;
case NM_CLICK:
{
LPNMLISTVIEW lpnmitem = (LPNMLISTVIEW)lParam;
int i = lpnmitem->iItem;
if (i == -1)
return FALSE;
if (control == data->control_role) {
flags.initrole = i;
plselAdjustSelections(hWnd);
} else if(control == data->control_race) {
if (ok_race(flags.initrole, i, ROLE_RANDOM, ROLE_RANDOM)) {
flags.initrace = i;
plselAdjustSelections(hWnd);
}
}
}
break;
case NM_KILLFOCUS:
{
if (data->focus == data->control_race) {
data->focus = NULL;
ListView_RedrawItems(data->control_race, 0, data->race_count - 1);
} else if (data->focus == data->control_role) {
data->focus = NULL;
ListView_RedrawItems(data->control_role, 0, data->role_count - 1);
}
}
break;
case NM_SETFOCUS:
{
data->focus = control;
if (control == data->control_race) {
data->focus = data->control_race;
plselAdjustSelections(hWnd);
} else if (control == data->control_role) {
data->focus = data->control_role;
plselAdjustSelections(hWnd);
}
}
break;
}
}
break;
case WM_COMMAND:
data = (struct plsel_data *) GetWindowLongPtr(hWnd, GWLP_USERDATA);
switch (LOWORD(wParam)) {
/* OK button was clicked */
case IDOK:
EndDialog(hWnd, wParam);
return TRUE;
/* CANCEL button was clicked */
case IDCANCEL:
EndDialog(hWnd, wParam);
return TRUE;
case IDC_PLSEL_RANDOM:
plselRandomize(data);
plselAdjustSelections(hWnd);
return TRUE;
case IDC_PLSEL_GENDER_MALE:
case IDC_PLSEL_GENDER_FEMALE:
if (HIWORD(wParam) == BN_CLICKED) {
int i = LOWORD(wParam) - IDC_PLSEL_GENDER_MALE;
if (ok_gend(flags.initrole, flags.initrace, i, ROLE_RANDOM)) {
flags.initgend = i;
plselAdjustSelections(hWnd);
}
}
break;
case IDC_PLSEL_ALIGN_LAWFUL:
case IDC_PLSEL_ALIGN_NEUTRAL:
case IDC_PLSEL_ALIGN_CHAOTIC:
if (HIWORD(wParam) == BN_CLICKED) {
int i = LOWORD(wParam) - IDC_PLSEL_ALIGN_LAWFUL;
if (ok_align(flags.initrole, flags.initrace, flags.initgend, i)) {
flags.initalign = i;
plselAdjustSelections(hWnd);
}
}
break;
}
break;
}
return FALSE;
}
/* initialize player selector dialog */
void
plselInitDialog(HWND hWnd)
{
struct plsel_data * data = (plsel_data_t *) GetWindowLongPtr(hWnd, GWLP_USERDATA);
TCHAR wbuf[BUFSZ];
LVCOLUMN lvcol;
data->control_role = GetDlgItem(hWnd, IDC_PLSEL_ROLE_LIST);
data->control_race = GetDlgItem(hWnd, IDC_PLSEL_RACE_LIST);
ZeroMemory(&lvcol, sizeof(lvcol));
lvcol.mask = LVCF_WIDTH;
lvcol.cx = GetSystemMetrics(SM_CXFULLSCREEN);
/* build role list */
ListView_InsertColumn(data->control_role, 0, &lvcol);
data->role_count = 0;
for (int i = 0; roles[i].name.m; i++) {
LVITEM lvitem;
ZeroMemory(&lvitem, sizeof(lvitem));
lvitem.mask = LVIF_STATE | LVIF_TEXT;
lvitem.iItem = i;
lvitem.iSubItem = 0;
lvitem.state = 0;
lvitem.stateMask = LVIS_FOCUSED;
if (flags.female && roles[i].name.f)
lvitem.pszText = NH_A2W(roles[i].name.f, wbuf, BUFSZ);
else
lvitem.pszText = NH_A2W(roles[i].name.m, wbuf, BUFSZ);
if (ListView_InsertItem(data->control_role, &lvitem) == -1) {
panic("cannot insert menu item");
}
data->role_count++;
}
/* build race list */
ListView_InsertColumn(data->control_race, 0, &lvcol);
data->race_count = 0;
for (int i = 0; races[i].noun; i++) {
LVITEM lvitem;
ZeroMemory(&lvitem, sizeof(lvitem));
lvitem.mask = LVIF_STATE | LVIF_TEXT;
lvitem.iItem = i;
lvitem.iSubItem = 0;
lvitem.state = 0;
lvitem.stateMask = LVIS_FOCUSED;
lvitem.pszText = NH_A2W(races[i].noun, wbuf, BUFSZ);
if (ListView_InsertItem(data->control_race, &lvitem) == -1) {
panic("cannot insert menu item");
}
data->race_count++;
}
for(int i = 0; i < ROLE_GENDERS; i++)
data->control_genders[i] = GetDlgItem(hWnd, IDC_PLSEL_GENDER_MALE + i);
for(int i = 0; i < ROLE_ALIGNS; i++)
data->control_aligns[i] = GetDlgItem(hWnd, IDC_PLSEL_ALIGN_LAWFUL + i);
/* set gender radio button state */
for (int i = 0; i < ROLE_GENDERS; i++)
Button_Enable(data->control_genders[i], TRUE);
Button_SetCheck(data->control_genders[0], BST_CHECKED);
/* set alignment radio button state */
for (int i = 0; i < ROLE_ALIGNS; i++)
Button_Enable(data->control_aligns[i], TRUE);
Button_SetCheck(data->control_aligns[0], BST_CHECKED);
/* set player name */
SetDlgItemText(hWnd, IDC_PLSEL_NAME, NH_A2W(plname, wbuf, sizeof(wbuf)));
plselRandomize(data);
/* populate select boxes */
plselAdjustSelections(hWnd);
/* set tab order */
SetWindowPos(GetDlgItem(hWnd, IDCANCEL), NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
SetWindowPos(GetDlgItem(hWnd, IDC_PLSEL_RANDOM), NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
SetWindowPos(GetDlgItem(hWnd, IDOK), NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
for(int i = ROLE_GENDERS - 1; i >= 0; i--)
SetWindowPos(data->control_genders[i], NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
for(int i = ROLE_ALIGNS - 1; i >= 0; i--)
SetWindowPos(data->control_aligns[i], NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
SetWindowPos(data->control_race, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
SetWindowPos(data->control_role, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
}
void
plselAdjustSelections(HWND hWnd)
{
struct plsel_data * data = (plsel_data_t *) GetWindowLongPtr(hWnd, GWLP_USERDATA);
if (!ok_race(flags.initrole, flags.initrace, ROLE_RANDOM, ROLE_RANDOM))
flags.initrace = pick_race(flags.initrole, ROLE_RANDOM, ROLE_RANDOM, ROLE_RANDOM);
if (!ok_gend(flags.initrole, flags.initrace, flags.initgend, ROLE_RANDOM))
flags.initgend = pick_gend(flags.initrole, flags.initrace, ROLE_RANDOM , ROLE_RANDOM);
if (!ok_align(flags.initrole, flags.initrace, flags.initgend, flags.initalign))
flags.initalign = pick_align(flags.initrole, flags.initrace, flags.initgend , ROLE_RANDOM);
ListView_RedrawItems(data->control_role, 0, data->role_count - 1);
ListView_RedrawItems(data->control_race, 0, data->race_count - 1);
/* set gender radio button state */
for (int i = 0; i < ROLE_GENDERS; i++) {
BOOL enable = ok_gend(flags.initrole, flags.initrace, i, flags.initalign);
Button_Enable(data->control_genders[i], enable);
LRESULT state = Button_GetCheck(data->control_genders[i]);
if (state == BST_CHECKED && flags.initgend != i)
Button_SetCheck(data->control_genders[i], BST_UNCHECKED);
if (state == BST_UNCHECKED && flags.initgend == i)
Button_SetCheck(data->control_genders[i], BST_CHECKED);
}
/* set alignment radio button state */
for (int i = 0; i < ROLE_ALIGNS; i++) {
BOOL enable = ok_align(flags.initrole, flags.initrace, flags.initgend, i);
Button_Enable(data->control_aligns[i], enable);
LRESULT state = Button_GetCheck(data->control_aligns[i]);
if (state == BST_CHECKED && flags.initalign != i)
Button_SetCheck(data->control_aligns[i], BST_UNCHECKED);
if (state == BST_UNCHECKED && flags.initalign == i)
Button_SetCheck(data->control_aligns[i], BST_CHECKED);
}
}
/* player made up his mind - get final selection here */
int
plselFinalSelection(HWND hWnd)
{
int role = flags.initrole;
int race = flags.initrace;
int gender = flags.initgend;
int alignment = flags.initalign;
assert(role != ROLE_RANDOM && role != ROLE_NONE);
assert(race != ROLE_RANDOM && race != ROLE_NONE);
assert(gender != ROLE_RANDOM && gender != ROLE_NONE);
assert(alignment != ROLE_RANDOM && alignment != ROLE_NONE);
assert(ok_role(role, race, gender, alignment));
assert(ok_race(role, race, gender, alignment));
assert(ok_gend(role, race, gender, alignment));
assert(ok_align(role, race, gender, alignment));
return TRUE;
}
static boolean plselRandomize(plsel_data_t * data)
{
boolean fully_specified = TRUE;
// restore back to configuration settings
flags.initrole = data->config_role;
flags.initrace = data->config_race;
flags.initgend = data->config_gender;
flags.initalign = data->config_alignment;
if (!flags.randomall) {
if(flags.initrole == ROLE_NONE || flags.initrace == ROLE_NONE
|| flags.initgend == ROLE_NONE || flags.initalign == ROLE_NONE)
fully_specified = FALSE;
}
if (flags.initrole == ROLE_NONE)
flags.initrole = ROLE_RANDOM;
if (flags.initrace == ROLE_NONE)
flags.initrace = ROLE_RANDOM;
if (flags.initgend == ROLE_NONE)
flags.initgend = ROLE_RANDOM;
if (flags.initalign == ROLE_NONE)
flags.initalign = ROLE_RANDOM;
rigid_role_checks();
int role = flags.initrole;
int race = flags.initrace;
int gender = flags.initgend;
int alignment = flags.initalign;
assert(role != ROLE_RANDOM && role != ROLE_NONE);
assert(race != ROLE_RANDOM && race != ROLE_NONE);
assert(gender != ROLE_RANDOM && gender != ROLE_NONE);
assert(alignment != ROLE_RANDOM && alignment != ROLE_NONE);
if (!ok_role(role, race, gender, alignment)) {
fully_specified = FALSE;
flags.initrole = ROLE_RANDOM;
}
if (!ok_race(role, race, gender, alignment)) {
fully_specified = FALSE;
flags.initrace = ROLE_RANDOM;
}
if (!ok_gend(role, race, gender, alignment)) {
fully_specified = FALSE;
flags.initgend = ROLE_RANDOM;
}
if(!ok_align(role, race, gender, alignment))
{
fully_specified = FALSE;
flags.initalign = ROLE_RANDOM;
}
rigid_role_checks();
role = flags.initrole;
race = flags.initrace;
gender = flags.initgend;
alignment = flags.initalign;
assert(role != ROLE_RANDOM && role != ROLE_NONE);
assert(race != ROLE_RANDOM && race != ROLE_NONE);
assert(gender != ROLE_RANDOM && gender != ROLE_NONE);
assert(alignment != ROLE_RANDOM && alignment != ROLE_NONE);
assert(ok_role(role, race, gender, alignment));
assert(ok_race(role, race, gender, alignment));
assert(ok_gend(role, race, gender, alignment));
assert(ok_align(role, race, gender, alignment));
return fully_specified;
}
/*-----------------------------------------------------------------------------*/
BOOL
plselDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT) lParam;
struct plsel_data * data = (plsel_data_t *) GetWindowLongPtr(hWnd, GWLP_USERDATA);
/* If there are no list box items, skip this message. */
if (lpdis->itemID < 0)
return FALSE;
HWND control = GetDlgItem(hWnd, (int) wParam);
int i = lpdis->itemID;
const char * string;
boolean ok = TRUE;
boolean selected;
if (wParam == IDC_PLSEL_ROLE_LIST) {
if (flags.female && roles[i].name.f)
string = roles[i].name.f;
else
string = roles[i].name.m;
selected = (flags.initrole == i);
} else {
assert(wParam == IDC_PLSEL_RACE_LIST);
ok = ok_race(flags.initrole, i, ROLE_RANDOM, ROLE_RANDOM);
string = races[i].noun;
selected = (flags.initrace == i);
}
SetBkMode(lpdis->hDC, OPAQUE);
HBRUSH brush;
if (selected) {
brush = CreateSolidBrush(RGB(0, 0, 0));
SetTextColor(lpdis->hDC, RGB(255, 255, 255));
SetBkColor(lpdis->hDC, RGB(0, 0, 0));
} else {
brush = CreateSolidBrush(RGB(255, 255, 255));
if (!ok)
SetTextColor(lpdis->hDC, RGB(220, 0, 0));
else
SetTextColor(lpdis->hDC, RGB(0, 0, 0));
SetBkColor(lpdis->hDC, RGB(255, 255, 255));
}
FillRect(lpdis->hDC, &lpdis->rcItem, brush);
RECT rect = lpdis->rcItem;
rect.left += 5;
DrawTextA(lpdis->hDC, string, strlen(string), &rect,
DT_LEFT | DT_SINGLELINE | DT_VCENTER);
if (data->focus == control) {
if (lpdis->itemState & LVIS_FOCUSED) {
/* draw focus rect */
RECT client_rt;
GetClientRect(lpdis->hwndItem, &client_rt);
SetRect(&rect, client_rt.left, lpdis->rcItem.top,
client_rt.left + ListView_GetColumnWidth(lpdis->hwndItem, 0),
lpdis->rcItem.bottom);
DrawFocusRect(lpdis->hDC, &rect);
}
}
DeleteObject(brush);
return TRUE;
}