diff --git a/src/cmd.c b/src/cmd.c index e40b4eab6..493a10faa 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -186,6 +186,7 @@ static boolean FDECL(keylist_func_has_key, (const struct ext_func_tab *, static int FDECL(keylist_putcmds, (winid, BOOLEAN_P, int, int, boolean *)); static int FDECL(ch2spkeys, (CHAR_P, int, int)); static boolean FDECL(prefix_cmd, (CHAR_P)); +static const char *FDECL(spkey_name, (int)); static int NDECL((*timed_occ_fn)); static char *FDECL(doc_extcmd_flagstr, (winid, const struct ext_func_tab *)); @@ -2075,13 +2076,13 @@ const char *command; struct ext_func_tab *extcmd; /* special case: "nothing" is reserved for unbinding */ - if (!strcmp(command, "nothing")) { + if (!strcmpi(command, "nothing")) { g.Cmd.commands[key] = (struct ext_func_tab *) 0; return TRUE; } for (extcmd = extcmdlist; extcmd->ef_txt; extcmd++) { - if (strcmp(command, extcmd->ef_txt)) + if (strcmpi(command, extcmd->ef_txt)) continue; g.Cmd.commands[key] = extcmd; #if 0 /* silently accept key binding for unavailable command (!SHELL,&c) */ @@ -2211,12 +2212,6 @@ boolean *keys_used; /* boolean keys_used[256] */ void dokeylist(VOID_ARGS) { - const struct ext_func_tab *extcmd; - char buf[BUFSZ], buf2[BUFSZ]; - uchar key; - boolean keys_used[256]; - winid datawin; - int i; static const char run_desc[] = "Prefix: run until something very interesting is seen", rush_desc[] = "Prefix: rush until something interesting is seen", @@ -2238,17 +2233,26 @@ dokeylist(VOID_ARGS) "Prefix: move without picking up objects or fighting", FALSE }, { NHKF_RUN_NOPICKUP, "Prefix: run without picking up objects or fighting", FALSE }, - { NHKF_DOINV, "view full inventory", TRUE }, - /* NHKF_DOINV2 for num_pad+pcHack_compat isn't implemented */ - /* { NHKF_DOINV2, "view inventory of one class of objects", TRUE }, */ - { NHKF_REQMENU, "Prefix: request a menu", FALSE }, + { NHKF_REQMENU, + "Prefix: request a menu (for some non-movement commands)", FALSE }, { NHKF_COUNT, - "Prefix: for digits when prefixing a command with a count", TRUE }, - { NHKF_DOAGAIN , "re-do: perform the previous command again", FALSE }, + "Prefix: for digits when preceding a command with a count", TRUE }, + { NHKF_DOINV, "numpad: view full inventory", TRUE }, + /* NHKF_DOINV2 for num_pad+pcHack_compat isn't implemented */ + /* { NHKF_DOINV2, "numpad: view inventory of one class of objects", + TRUE }, */ + { NHKF_DOAGAIN , "repeat: perform the previous command again", FALSE }, { 0, (const char *) 0, FALSE } }; + const struct ext_func_tab *extcmd; + winid datawin; + char buf[BUFSZ], buf2[BUFSZ]; + uchar key; + boolean spkey_gap, keys_used[256], mov_seen[256]; + int i, j, pfx_seen[256]; (void) memset((genericptr_t) keys_used, 0, sizeof keys_used); + (void) memset((genericptr_t) pfx_seen, 0, sizeof pfx_seen); keys_used[(uchar) g.Cmd.move_NW] = keys_used[(uchar) g.Cmd.move_N] = keys_used[(uchar) g.Cmd.move_NE] = keys_used[(uchar) g.Cmd.move_W] @@ -2279,25 +2283,38 @@ dokeylist(VOID_ARGS) = keys_used[(uchar) M('6')] = keys_used[(uchar) M('7')] = keys_used[(uchar) M('8')] = keys_used[(uchar) M('9')] = TRUE; } - for (i = 0; misc_keys[i].desc; ++i) { - key = (uchar) g.Cmd.spkeys[misc_keys[i].nhkf]; - if (key && ((misc_keys[i].numpad && iflags.num_pad) - || !misc_keys[i].numpad)) { - keys_used[key] = TRUE; - } - } #ifndef NO_SIGNAL - /* this is actually ambiguous; tty raw mode will override SIGINT */ + /* this is actually ambiguous; tty raw mode will override SIGINT; + when enabled, treat it like a movement command since assigning + other commands to this keystroke would be unwise... */ key = (uchar) C('c'); keys_used[key] = TRUE; #endif + /* movement keys have been flagged in keys_used[]; clone them */ + (void) memcpy((genericptr_t) mov_seen, (genericptr_t) keys_used, + sizeof mov_seen); + + spkey_gap = FALSE; + for (i = 0; misc_keys[i].desc; ++i) { + if (misc_keys[i].numpad && !iflags.num_pad) + continue; + j = misc_keys[i].nhkf; + key = (uchar) g.Cmd.spkeys[j]; + if (key && !mov_seen[key] && (!pfx_seen[key] || j == NHKF_REQMENU)) { + keys_used[key] = TRUE; + if (j != NHKF_REQMENU) + pfx_seen[key] = j; + } else + spkey_gap = TRUE; + } + datawin = create_nhwindow(NHW_TEXT); putstr(datawin, 0, ""); Sprintf(buf, "%7s %s", "", " Full Current Key Bindings List"); putstr(datawin, 0, buf); for (extcmd = extcmdlist; extcmd->ef_txt; ++extcmd) - if (!keylist_func_has_key(extcmd, keys_used)) { + if (spkey_gap || !keylist_func_has_key(extcmd, keys_used)) { Sprintf(buf, "%7s %s", "", "(also commands with no key assignment)"); putstr(datawin, 0, buf); @@ -2330,20 +2347,44 @@ dokeylist(VOID_ARGS) putstr(datawin, 0, ""); putstr(datawin, 0, "Miscellaneous keys:"); for (i = 0; misc_keys[i].desc; ++i) { - key = (uchar) g.Cmd.spkeys[misc_keys[i].nhkf]; - if (key && ((misc_keys[i].numpad && iflags.num_pad) - || !misc_keys[i].numpad)) { + if (misc_keys[i].numpad && !iflags.num_pad) + continue; + j = misc_keys[i].nhkf; + key = (uchar) g.Cmd.spkeys[j]; + if (key && !mov_seen[key] + && (pfx_seen[key] == j || j == NHKF_REQMENU)) { Sprintf(buf, "%-7s %s", key2txt(key, buf2), misc_keys[i].desc); putstr(datawin, 0, buf); } } -#ifndef NO_SIGNAL /* (see above) */ key = (uchar) C('c'); - Sprintf(buf, "%-7s %s", key2txt(key, buf2), - "break out of NetHack (SIGINT)"); - putstr(datawin, 0, buf); +#ifndef NO_SIGNAL + /* last of the special keys */ + Sprintf(buf, "%-7s", key2txt(key, buf2)); +#else + /* first of the keyless commands */ + Sprintf(buf2, "[%s]", key2txt(key, buf)); + Sprintf(buf, "%-21s", buf2); #endif + Strcat(buf, " interrupt: break out of NetHack (SIGINT)"); + putstr(datawin, 0, buf); + /* keyless special key commands, if any */ + if (spkey_gap) { + for (i = 0; misc_keys[i].desc; ++i) { + if (misc_keys[i].numpad && !iflags.num_pad) + continue; + j = misc_keys[i].nhkf; + key = (uchar) g.Cmd.spkeys[j]; + if (!key || (pfx_seen[key] != j && j != NHKF_REQMENU)) { + Sprintf(buf2, "[%s]", spkey_name(j)); + /* lines up with the other unassigned commands which use + "#%-20s ", but not with the other special keys */ + Sprintf(buf, "%-21s %s", buf2, misc_keys[i].desc); + putstr(datawin, 0, buf); + } + } + } putstr(datawin, 0, ""); show_menu_controls(datawin, TRUE); @@ -2935,6 +2976,7 @@ uchar key; const char *command; { int i; + for (i = 0; i < SIZE(spkeys_binds); i++) { if (!spkeys_binds[i].name || strcmp(command, spkeys_binds[i].name)) continue; @@ -2944,6 +2986,22 @@ const char *command; return FALSE; } +static const char * +spkey_name(nhkf) +int nhkf; +{ + const char *name = 0; + int i; + + for (i = 0; i < SIZE(spkeys_binds); i++) { + if (spkeys_binds[i].nhkf == nhkf) { + name = (nhkf == NHKF_ESC) ? "escape" : spkeys_binds[i].name; + break; + } + } + return name; +} + /* returns a one-byte character from the text; may change txt[] */ uchar txt2key(txt)