From ea61a13adde216bb2e55235b7a7415ebc5749506 Mon Sep 17 00:00:00 2001 From: "nethack.rankin" Date: Sat, 26 Nov 2005 02:34:23 +0000 Subject: [PATCH] number_pad:3,4,-1 (trunk only) [See the cvs log from flag.h for comments pertaining to iflags.num_pad and Cmd.num_pad, Cmd.commands[], Cmd.serialno.] --- dat/help | 12 ++- dat/hh | 10 ++- dat/opthelp | 8 +- doc/fixes35.0 | 2 + src/cmd.c | 198 +++++++++++++++++++++++++++++++------------ src/decl.c | 6 +- src/dig.c | 6 +- src/do_name.c | 25 +++--- src/options.c | 97 ++++++++++++--------- sys/mac/macwin.c | 13 +-- sys/vms/vmstty.c | 18 ++-- win/Qt/qt_win.cpp | 6 +- win/gnome/gnsignal.c | 18 ++-- win/tty/termcap.c | 4 +- 14 files changed, 279 insertions(+), 144 deletions(-) diff --git a/dat/help b/dat/help index 4c377828c..5959add2d 100644 --- a/dat/help +++ b/dat/help @@ -67,6 +67,12 @@ b j n 1 2 3 g: run in direction until something Meta number, or Alt number will invoke the YUHJKLBN commands. Control may or may not work when number_pad is enabled, depending on the platform's capabilities. + Digit '5' acts as 'G' prefix, unless number_pad is set to 2 + in which case it acts as 'g' instead. + If number_pad is set to 3, the roles of 1,2,3 and 7,8,9 are + reversed; when set to 4, behaves same as 3 combined with 2. + If number_pad is set to -1, alphabetic movement commands are + used but 'y' and 'z' are swapped. Commands: NetHack knows the following commands: @@ -143,9 +149,9 @@ Commands: x Swap wielded and secondary weapons. X Switch the game to explore (discovery) mode. ^X Show your attributes. - z Zap a wand. - Z Cast a spell. - ^Z Suspend the game. + z Zap a wand. (Use y instead of z if number_pad is -1.) + Z Cast a spell. (Use Y instead of Z if number_pad is -1.) + ^Z Suspend the game. (^Y instead of ^Z if number_pad is -1.) : Look at what is here. ; Look at what is somewhere else. , Pick up some things. diff --git a/dat/hh b/dat/hh index 5fe6bfaec..bc56d319c 100644 --- a/dat/hh +++ b/dat/hh @@ -14,6 +14,12 @@ b j n 1 2 3 g: run in direction until something Meta number, or Alt number will invoke the YUHJKLBN commands. Control may or may not work when number_pad is enabled, depending on the platform's capabilities. + Digit '5' acts as 'G' prefix, unless number_pad is set to 2 + in which case it acts as 'g' instead. + If number_pad is set to 3, the roles of 1,2,3 and 7,8,9 are + reversed; when set to 4, behaves same as 3 combined with 2. + If number_pad is set to -1, alphabetic movement commands are + used but 'y' and 'z' are swapped. General commands: ? help display one of several informative texts @@ -64,8 +70,8 @@ T takeoff take off some armor w wield wield a weapon (w- wield nothing) W wear put on some armor x xchange swap wielded and secondary weapons -z zap zap a wand -Z Zap cast a spell +z zap zap a wand (use y instead of z if number_pad is -1) +Z Zap cast a spell (use Y instead of Z if number_pad is -1) < up go up the stairs > down go down the stairs ^ trap_id identify a previously found trap diff --git a/dat/opthelp b/dat/opthelp index 57cb6a7c6..ff1f18663 100644 --- a/dat/opthelp +++ b/dat/opthelp @@ -23,7 +23,6 @@ mail enable the mail daemon [TRUE] null allow nulls to be sent to your terminal [TRUE] try turning this option off (forcing NetHack to use its own delay code) if moving objects seem to teleport across rooms -number_pad use the number keys to move instead of yuhjklbn [FALSE] perm_invent keep inventory in a permanent window [FALSE] prayconfirm use confirmation prompt when #pray command issued [TRUE] pushweapon when wielding a new weapon, put your previously @@ -102,6 +101,13 @@ menustyle user interface for selection of multiple objects: Full -- menu for classes of interest, then object menu; only the first letter ('T','C','P','F') matters; 'N' (None) is a synonym for 'T', as is boolean style negation [Full] +number_pad alphabetic versus numeric control over movement: + 0 -- traditional hjkl + yubn movement (default); + 1 -- digits control movement, for use with numeric keypad; + 2 -- same as 1, but '5' works as 'g' prefix rather than 'G'; + 3 -- numeric for phone keypad (1,2,3 above, 7,8,9 below); + 4 -- phone keypad (3) combined with MSDOS compatibility (2); + -1 -- alphabetic movement but 'z' swapped with 'y'. [0] packorder a list of default symbols for kinds of objects that gives the order in which your pack will be displayed [")[%?+!=/(*`0_] (If you specify only some kinds of items, the others from the diff --git a/doc/fixes35.0 b/doc/fixes35.0 index ff389d213..8d73d9fa5 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -152,6 +152,8 @@ introduce support for negation of role, race, align, gender values to eliminate them from random selection and the pick list of startup choices some intelligent pets will avoid cannibalism keep track of which monsters were cloned from other monsters +number_pad:3 run-time option to use inverted phone keypad layout for movement +number_pad:-1 to swap function of y and z keys; z to move NW, y to zap wands Platform- and/or Interface-Specific New Features diff --git a/src/cmd.c b/src/cmd.c index abdd0a5d7..c59090a9f 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)cmd.c 3.5 2005/05/06 */ +/* SCCS Id: @(#)cmd.c 3.5 2005/11/19 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -6,6 +6,8 @@ #include "func_tab.h" /* #define DEBUG */ /* uncomment for debugging */ +struct cmd Cmd = { 0 }; /* flag.h */ + /* * Some systems may have getchar() return EOF for various reasons, and * we should not quit before seeing at least NR_OF_EOFS consecutive EOFs. @@ -17,6 +19,8 @@ #define CMD_TRAVEL (char)0x90 #define CMD_CLICKLOOK (char)0x8F +#define NODIAG(monnum) ((monnum) == PM_GRID_BUG) + #ifdef DEBUG /* * only one "wiz_debug_cmd" routine should be available (in whatever @@ -1655,12 +1659,101 @@ add_debug_extended_commands() } } +/* called at startup and after number_pad is twiddled */ +void +reset_commands(initial) +boolean initial; +{ + static const char + sdir[] = "hykulnjb><", sdir_swap_yz[] = "hzkulnjb><", + ndir[] = "47896321><", ndir_phone_layout[] = "41236987><"; + static const int ylist[] = { 'y', 'Y', C('y'), M('y'), M('Y'), M(C('y')) }; + const struct func_tab *cmdtmp; + boolean flagtemp; + int c, i, updated = 0; + + if (initial) { + updated = 1; + for (i = 0; i < SIZE(cmdlist); i++) { + c = cmdlist[i].f_char & 0xff; + Cmd.commands[c] = &cmdlist[i]; + } + Cmd.num_pad = FALSE; + Cmd.pcHack_compat = Cmd.phone_layout = Cmd.swap_yz = FALSE; + } else { + /* basic num_pad */ + flagtemp = iflags.num_pad; + if (flagtemp != Cmd.num_pad) { + Cmd.num_pad = flagtemp; + ++updated; + } + /* swap_yz mode (only applicable for !num_pad) */ + flagtemp = (iflags.num_pad_mode & 1) ? !Cmd.num_pad : FALSE; + if (flagtemp != Cmd.swap_yz) { + Cmd.swap_yz = flagtemp; + ++updated; + /* Cmd.swap_yz has been toggled; + perform the swap (or reverse previous one) */ + for (i = 0; i < SIZE(ylist); i++) { + c = ylist[i] & 0xff; + cmdtmp = Cmd.commands[c]; /* tmp = [y] */ + Cmd.commands[c] = Cmd.commands[c + 1]; /* [y] = [z] */ + Cmd.commands[c + 1] = cmdtmp; /* [z] = tmp */ + } + } + /* MSDOS compatibility mode (only applicable for num_pad) */ + flagtemp = (iflags.num_pad_mode & 1) ? Cmd.num_pad : FALSE; + if (flagtemp != Cmd.pcHack_compat) { + Cmd.pcHack_compat = flagtemp; + ++updated; + /* pcHack_compat has been toggled */ + c = M('5') & 0xff; + cmdtmp = Cmd.commands['5']; + Cmd.commands['5'] = Cmd.commands[c]; + Cmd.commands[c] = cmdtmp; + c = M('0') & 0xff; + Cmd.commands[c] = Cmd.pcHack_compat ? Cmd.commands['I'] : 0; + } + /* phone keypad layout (only applicable for num_pad) */ + flagtemp = (iflags.num_pad_mode & 2) ? Cmd.num_pad : FALSE; + if (flagtemp != Cmd.phone_layout) { + Cmd.phone_layout = flagtemp; + ++updated; + /* phone_layout has been toggled */ + for (i = 0; i < 3; i++) { + c = '1' + i; /* 1,2,3 <-> 7,8,9 */ + cmdtmp = Cmd.commands[c]; /* tmp = [1] */ + Cmd.commands[c] = Cmd.commands[c + 6]; /* [1] = [7] */ + Cmd.commands[c + 6] = cmdtmp; /* [7] = tmp */ + c = (M('1') & 0xff) + i; /* M-1,M-2,M-3 <-> M-7,M-8,M-9 */ + cmdtmp = Cmd.commands[c]; /* tmp = [M-1] */ + Cmd.commands[c] = Cmd.commands[c + 6]; /* [M-1] = [M-7] */ + Cmd.commands[c + 6] = cmdtmp; /* [M-7] = tmp */ + } + } + } /*?initial*/ + + if (updated) Cmd.serialno++; + Cmd.dirchars = !Cmd.num_pad ? (!Cmd.swap_yz ? sdir : sdir_swap_yz) : + (!Cmd.phone_layout ? ndir : ndir_phone_layout); + Cmd.alphadirchars = !Cmd.num_pad ? Cmd.dirchars : sdir; + + Cmd.move_W = Cmd.dirchars[0]; + Cmd.move_NW = Cmd.dirchars[1]; + Cmd.move_N = Cmd.dirchars[2]; + Cmd.move_NE = Cmd.dirchars[3]; + Cmd.move_E = Cmd.dirchars[4]; + Cmd.move_SE = Cmd.dirchars[5]; + Cmd.move_S = Cmd.dirchars[6]; + Cmd.move_SW = Cmd.dirchars[7]; +} + /* decide whether a character (user input keystroke) requests screen repaint */ boolean redraw_cmd(c) char c; { - return (c == C('r') || (iflags.num_pad && c == C('l'))); + return (c == C('r') || (Cmd.num_pad && c == C('l'))); } static const char template[] = "%-18s %4ld %6ld"; @@ -1917,7 +2010,7 @@ register char *cmd; context.move = FALSE; return; /* probably we just had an interrupt */ } - if (iflags.num_pad && iflags.num_pad_mode == 1) { + if (Cmd.pcHack_compat) { /* This handles very old inconsistent DOS/Windows behaviour * in a new way: earlier, the keyboard handler mapped these, * which caused counts to be strange when entered from the @@ -1927,8 +2020,9 @@ register char *cmd; case '5': *cmd = 'g'; break; case M('5'): *cmd = 'G'; break; case M('0'): *cmd = 'I'; break; - } - } + } + } + /* handle most movement commands */ do_walk = do_rush = prefix_seen = FALSE; context.travel = context.travel1 = 0; @@ -1939,14 +2033,14 @@ register char *cmd; } else prefix_seen = TRUE; break; - case '5': if (!iflags.num_pad) break; /* else FALLTHRU */ + case '5': if (!Cmd.num_pad) break; /* else FALLTHRU */ case 'G': if (movecmd(lowc(cmd[1]))) { context.run = 3; do_rush = TRUE; } else prefix_seen = TRUE; break; - case '-': if (!iflags.num_pad) break; /* else FALLTHRU */ + case '-': if (!Cmd.num_pad) break; /* else FALLTHRU */ /* Effects of movement commands and invisible monsters: * m: always move onto space (even if 'I' remembered) * F: always attack space (even if 'I' not remembered) @@ -1973,7 +2067,7 @@ register char *cmd; } else prefix_seen = TRUE; break; - case '0': if (!iflags.num_pad) break; + case '0': if (!Cmd.num_pad) break; (void)ddoinv(); /* a convenience borrowed from the PC */ context.move = FALSE; multi = 0; @@ -1997,7 +2091,7 @@ register char *cmd; default: if (movecmd(*cmd)) { /* ordinary movement */ context.run = 0; /* only matters here if it was 8 */ do_walk = TRUE; - } else if (movecmd(iflags.num_pad ? + } else if (movecmd(Cmd.num_pad ? unmeta(*cmd) : lowc(*cmd))) { context.run = 1; do_rush = TRUE; @@ -2039,8 +2133,12 @@ register char *cmd; register const struct func_tab *tlist; int res, NDECL((*func)); +#if 0 for (tlist = cmdlist; tlist->f_char; tlist++) { if ((*cmd & 0xff) != (tlist->f_char & 0xff)) continue; +#else + if ((tlist = Cmd.commands[*cmd & 0xff]) != 0) { +#endif if (u.uburied && !tlist->can_if_buried) { You_cant("do that while you are buried!"); @@ -2065,18 +2163,19 @@ register char *cmd; if (bad_command) { char expcmd[10]; - register char *cp = expcmd; + register char c, *cp = expcmd; - while (*cmd && (int)(cp - expcmd) < (int)(sizeof expcmd - 3)) { - if (*cmd >= 040 && *cmd < 0177) { - *cp++ = *cmd++; - } else if (*cmd & 0200) { + while ((c = *cmd++) != '\0' && + (int)(cp - expcmd) < (int)(sizeof expcmd - 3)) { + if (c >= 040 && c < 0177) { + *cp++ = c; + } else if (c & 0200) { *cp++ = 'M'; *cp++ = '-'; - *cp++ = *cmd++ &= ~0200; + *cp++ = c & ~0200; } else { *cp++ = '^'; - *cp++ = *cmd++ ^ 0100; + *cp++ = c ^ 0100; } } *cp = '\0'; @@ -2116,16 +2215,14 @@ int movecmd(sym) /* also sets u.dz, but returns false for <> */ char sym; { - register const char *dp; - register const char *sdp; - if(iflags.num_pad) sdp = ndir; else sdp = sdir; /* DICE workaround */ + register const char *dp = index(Cmd.dirchars, sym); u.dz = 0; - if(!(dp = index(sdp, sym))) return 0; - u.dx = xdir[dp-sdp]; - u.dy = ydir[dp-sdp]; - u.dz = zdir[dp-sdp]; - if (u.dx && u.dy && u.umonnum == PM_GRID_BUG) { + if (!dp) return 0; + u.dx = xdir[dp - Cmd.dirchars]; + u.dy = ydir[dp - Cmd.dirchars]; + u.dz = zdir[dp - Cmd.dirchars]; + if (u.dx && u.dy && NODIAG(u.umonnum)) { u.dx = u.dy = 0; return 0; } @@ -2250,34 +2347,28 @@ const char *msg; putstr(win, 0, ""); } } - if (iflags.num_pad && u.umonnum == PM_GRID_BUG) { - putstr(win, 0, "Valid direction keys in your current form (with number_pad on) are:"); - putstr(win, 0, " 8 "); - putstr(win, 0, " | "); - putstr(win, 0, " 4- . -6"); - putstr(win, 0, " | "); - putstr(win, 0, " 2 "); - } else if (u.umonnum == PM_GRID_BUG) { + if (NODIAG(u.umonnum)) { putstr(win, 0, "Valid direction keys in your current form are:"); - putstr(win, 0, " k "); + Sprintf(buf, " %c ", Cmd.move_N); + putstr(win, 0, buf); putstr(win, 0, " | "); - putstr(win, 0, " h- . -l"); + Sprintf(buf, " %c- . -%c", Cmd.move_W, Cmd.move_E); + putstr(win, 0, buf); putstr(win, 0, " | "); - putstr(win, 0, " j "); - } else if (iflags.num_pad) { - putstr(win, 0, "Valid direction keys (with number_pad on) are:"); - putstr(win, 0, " 7 8 9"); - putstr(win, 0, " \\ | / "); - putstr(win, 0, " 4- . -6"); - putstr(win, 0, " / | \\ "); - putstr(win, 0, " 1 2 3"); + Sprintf(buf, " %c ", Cmd.move_S); + putstr(win, 0, buf); } else { putstr(win, 0, "Valid direction keys are:"); - putstr(win, 0, " y k u"); + Sprintf(buf, " %c %c %c", + Cmd.move_NW, Cmd.move_N, Cmd.move_NE); + putstr(win, 0, buf); putstr(win, 0, " \\ | / "); - putstr(win, 0, " h- . -l"); + Sprintf(buf, " %c- . -%c", Cmd.move_W, Cmd.move_E); + putstr(win, 0, buf); putstr(win, 0, " / | \\ "); - putstr(win, 0, " b j n"); + Sprintf(buf, " %c %c %c", + Cmd.move_SW, Cmd.move_S, Cmd.move_SE); + putstr(win, 0, buf); }; putstr(win, 0, ""); putstr(win, 0, " < up"); @@ -2297,7 +2388,8 @@ const char *msg; void confdir() { - register int x = (u.umonnum == PM_GRID_BUG) ? 2*rn2(4) : rn2(8); + register int x = NODIAG(u.umonnum) ? 2*rn2(4) : rn2(8); + u.dx = xdir[x]; u.dy = ydir[x]; return; @@ -2373,8 +2465,8 @@ click_to_cmd(x, y, mod) dir = xytod(x, y); if (!m_at(u.ux+x, u.uy+y) && !test_move(u.ux, u.uy, x, y, TEST_MOVE)) { - cmd[1] = (iflags.num_pad ? ndir[dir] : sdir[dir]); - cmd[2] = 0; + cmd[1] = Cmd.dirchars[dir]; + cmd[2] = '\0'; if (IS_DOOR(levl[u.ux+x][u.uy+y].typ)) { /* slight assistance to the player: choose kick/open for them */ if (levl[u.ux+x][u.uy+y].doormask & D_LOCKED) { @@ -2414,10 +2506,10 @@ click_to_cmd(x, y, mod) /* move, attack, etc. */ cmd[1] = 0; if(mod == CLICK_1) { - cmd[0] = (iflags.num_pad ? ndir[dir] : sdir[dir]); + cmd[0] = Cmd.dirchars[dir]; } else { - cmd[0] = (iflags.num_pad ? M(ndir[dir]) : - (sdir[dir] - 'a' + 'A')); /* run command */ + cmd[0] = (Cmd.num_pad ? M(Cmd.dirchars[dir]) : + (Cmd.dirchars[dir] - 'a' + 'A')); /* run command */ } return cmd; @@ -2438,7 +2530,7 @@ parse() context.move = 1; flush_screen(1); /* Flush screen buffer. Put the cursor on the hero. */ - if (!iflags.num_pad || (foo = readchar()) == 'n') + if (!Cmd.num_pad || (foo = readchar()) == 'n') for (;;) { foo = readchar(); if (foo >= '0' && foo <= '9') { @@ -2477,7 +2569,7 @@ parse() in_line[0] = foo; in_line[1] = '\0'; if (foo == 'g' || foo == 'G' || foo == 'm' || foo == 'M' || - foo == 'F' || (iflags.num_pad && (foo == '5' || foo == '-'))) { + foo == 'F' || (Cmd.num_pad && (foo == '5' || foo == '-'))) { foo = readchar(); #ifdef REDO savech((char)foo); diff --git a/src/decl.c b/src/decl.c index cdde3333c..5b1dad3fc 100644 --- a/src/decl.c +++ b/src/decl.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)decl.c 3.5 2001/12/10 */ +/* SCCS Id: @(#)decl.c 3.5 2005/11/19 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -95,9 +95,7 @@ struct linfo level_info[MAXLINFO]; NEARDATA struct sinfo program_state; -/* 'rogue'-like direction commands (cmd.c) */ -const char sdir[] = "hykulnjb><"; -const char ndir[] = "47896321><"; /* number pad mode */ +/* x/y/z deltas for the 10 movement directions (8 compass pts, 2 up/down) */ const schar xdir[10] = { -1,-1, 0, 1, 1, 1, 0,-1, 0, 0 }; const schar ydir[10] = { 0,-1,-1,-1, 0, 1, 1, 1, 0, 0 }; const schar zdir[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 1,-1 }; diff --git a/src/dig.c b/src/dig.c index fa1fdb26e..08a2a5001 100644 --- a/src/dig.c +++ b/src/dig.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)dig.c 3.5 2005/06/02 */ +/* SCCS Id: @(#)dig.c 3.5 2005/11/19 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -831,9 +831,7 @@ struct obj *obj; register char *dsp = dirsyms; register int rx, ry; int res = 0; - register const char *sdp, *verb; - - if(iflags.num_pad) sdp = ndir; else sdp = sdir; /* DICE workaround */ + const char *sdp = Cmd.dirchars, *verb; /* Check tool */ if (obj != uwep) { diff --git a/src/do_name.c b/src/do_name.c index a3a389bf0..af325879f 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)do_name.c 3.5 2005/07/15 */ +/* SCCS Id: @(#)do_name.c 3.5 2005/11/19 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -33,8 +33,8 @@ const char *goal; boolean doing_what_is; winid tmpwin = create_nhwindow(NHW_MENU); - Sprintf(sbuf, "Use [%s] to move the cursor to %s.", - iflags.num_pad ? "2468" : "hjkl", goal); + Sprintf(sbuf, "Use [%c%c%c%c] to move the cursor to %s.", /* hjkl */ + Cmd.move_W, Cmd.move_S, Cmd.move_N, Cmd.move_E, goal); putstr(tmpwin, 0, sbuf); putstr(tmpwin, 0, "Use [HJKL] to move the cursor 8 units at a time."); putstr(tmpwin, 0, "Or enter a background symbol (ex. <)."); @@ -63,8 +63,6 @@ const char *goal; boolean msg_given = TRUE; /* clear message window by default */ static const char pick_chars[] = ".,;:"; const char *cp; - const char *sdp; - if(iflags.num_pad) sdp = ndir; else sdp = sdir; /* DICE workaround */ if (!goal) goal = "desired location"; if (flags.verbose) { @@ -104,12 +102,13 @@ const char *goal; for (i = 0; i < 8; i++) { int dx, dy; - if (sdp[i] == c) { + if (Cmd.dirchars[i] == c) { /* a normal movement letter or digit */ dx = xdir[i]; dy = ydir[i]; - } else if (sdir[i] == lowc((char)c)) { - /* a shifted movement letter */ + } else if (Cmd.alphadirchars[i] == lowc((char)c) || + (Cmd.num_pad && Cmd.dirchars[i] == (c & 0177))) { + /* a shifted movement letter or Meta-digit */ dx = 8 * xdir[i]; dy = 8 * ydir[i]; } else @@ -178,10 +177,14 @@ const char *goal; msg_given = TRUE; goto nxtc; } else { + char note[QBUFSZ]; + + if (!force) Strcpy(note, "aborted"); + else Sprintf(note, "use %c%c%c%c or .", /* hjkl */ + Cmd.move_W, Cmd.move_S, + Cmd.move_N, Cmd.move_E); pline("Unknown direction: '%s' (%s).", - visctrl((char)c), - !force ? "aborted" : - iflags.num_pad ? "use 2468 or ." : "use hjkl or ."); + visctrl((char)c), note); msg_given = TRUE; } /* k => matching */ } /* !quitchars */ diff --git a/src/options.c b/src/options.c index 862c50d04..965385662 100644 --- a/src/options.c +++ b/src/options.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)options.c 3.5 2005/09/23 */ +/* SCCS Id: @(#)options.c 3.5 2005/11/19 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -304,7 +304,7 @@ static struct Comp_Opt # endif { "name", "your character's name (e.g., name:Merlin-W)", PL_NSIZ, DISP_IN_GAME }, - { "number_pad", "use the number pad", 1, SET_IN_GAME}, + { "number_pad", "use the number pad for movement", 1, SET_IN_GAME}, { "objects", "the symbols to use for objects", MAXOCLASSES, SET_IN_FILE }, { "packorder", "the inventory order of the items in your pack", @@ -523,6 +523,9 @@ initoptions() #endif int i; + /* set up the command parsing */ + reset_commands(TRUE); /* init */ + /* initialize the random number generator */ setrandom(); @@ -1258,30 +1261,40 @@ boolean tinitial, tfrom_file; fullname = "number_pad"; if (match_optname(opts, fullname, 10, TRUE)) { boolean compat = (strlen(opts) <= 10); + if (duplicate) complain_about_duplicate(opts,1); - number_pad(iflags.num_pad ? 1 : 0); op = string_for_opt(opts, (compat || !initial)); if (!op) { if (compat || negated || initial) { /* for backwards compatibility, "number_pad" without a value is a synonym for number_pad:1 */ iflags.num_pad = !negated; - if (iflags.num_pad) iflags.num_pad_mode = 0; + iflags.num_pad_mode = 0; } - return; - } - if (negated) { + } else if (negated) { bad_negation("number_pad", TRUE); return; - } - if (*op == '1' || *op == '2') { - iflags.num_pad = 1; - if (*op == '2') iflags.num_pad_mode = 1; - else iflags.num_pad_mode = 0; - } else if (*op == '0') { - iflags.num_pad = 0; + } else { + int mode = atoi(op); + + if (mode < -1 || mode > 4 || (mode == 0 && *op != '0')) { + badoption(opts); + return; + } else if (mode <= 0) { + iflags.num_pad = FALSE; + /* German keyboard; y and z keys swapped */ + iflags.num_pad_mode = (mode < 0); /* 0 or 1 */ + } else { /* mode > 0 */ + iflags.num_pad = TRUE; iflags.num_pad_mode = 0; - } else badoption(opts); + /* PC Hack / MSDOS compatibility */ + if (mode == 2 || mode == 4) iflags.num_pad_mode |= 1; + /* phone keypad layout */ + if (mode == 3 || mode == 4) iflags.num_pad_mode |= 2; + } + } + reset_commands(FALSE); + number_pad(iflags.num_pad ? 1 : 0); return; } @@ -2955,35 +2968,34 @@ boolean setinitial,setfromfile; } destroy_nhwindow(tmpwin); } else if (!strcmp("number_pad", optname)) { - static const char *npchoices[3] = - {"0 (off)", "1 (on)", "2 (on, DOS compatible)"}; - const char *npletters = "abc"; + static const char *npchoices[] = { + " 0 (off)", " 1 (on)", " 2 (on, MSDOS compatible)", + " 3 (on, phone-style digit layout)", + " 4 (on, phone-style layout, MSDOS compatible)", + "-1 (off, 'z' to move upper-left, 'y' to zap wands)" + }; menu_item *mode_pick = (menu_item *)0; tmpwin = create_nhwindow(NHW_MENU); start_menu(tmpwin); for (i = 0; i < SIZE(npchoices); i++) { any.a_int = i + 1; - add_menu(tmpwin, NO_GLYPH, &any, npletters[i], 0, + add_menu(tmpwin, NO_GLYPH, &any, 'a' + i, 0, ATR_NONE, npchoices[i], MENU_UNSELECTED); } end_menu(tmpwin, "Select number_pad mode:"); if (select_menu(tmpwin, PICK_ONE, &mode_pick) > 0) { - int mode = mode_pick->item.a_int - 1; - switch(mode) { - case 2: - iflags.num_pad = 1; - iflags.num_pad_mode = 1; - break; - case 1: - iflags.num_pad = 1; - iflags.num_pad_mode = 0; - break; - case 0: - default: - iflags.num_pad = 0; - iflags.num_pad_mode = 0; + switch (mode_pick->item.a_int - 1) { + case 0: iflags.num_pad = FALSE; iflags.num_pad_mode = 0; break; + case 1: iflags.num_pad = TRUE; iflags.num_pad_mode = 0; break; + case 2: iflags.num_pad = TRUE; iflags.num_pad_mode = 1; break; + case 3: iflags.num_pad = TRUE; iflags.num_pad_mode = 2; break; + case 4: iflags.num_pad = TRUE; iflags.num_pad_mode = 3; break; + /* last menu choice: number_pad == -1 */ + case 5: iflags.num_pad = FALSE; iflags.num_pad_mode = 1; break; } + reset_commands(FALSE); + number_pad(iflags.num_pad ? 1 : 0); free((genericptr_t)mode_pick); } destroy_nhwindow(tmpwin); @@ -3274,11 +3286,20 @@ char *buf; #endif else if (!strcmp(optname, "name")) Sprintf(buf, "%s", plname); - else if (!strcmp(optname, "number_pad")) - Sprintf(buf, "%s", - (!iflags.num_pad) ? "0=off" : - (iflags.num_pad_mode) ? "2=on, DOS compatible" : "1=on"); - else if (!strcmp(optname, "objects")) + else if (!strcmp(optname, "number_pad")) { + static const char *numpadmodes[] = { + "0=off", "1=on", + "2=on, MSDOS compatible", "3=on, phone-style layout", + "4=on, phone layout, MSDOS compatible", + "-1=off, y & z swapped", /*[5]*/ + }; + int indx = Cmd.num_pad ? + (Cmd.phone_layout ? (Cmd.pcHack_compat ? 4 : 3) : + (Cmd.pcHack_compat ? 2 : 1)) : + Cmd.swap_yz ? 5 : 0; + + Strcpy(buf, numpadmodes[indx]); + } else if (!strcmp(optname, "objects")) Sprintf(buf, "%s", to_be_done); else if (!strcmp(optname, "packorder")) { oc_to_str(flags.inv_order, ocl); diff --git a/sys/mac/macwin.c b/sys/mac/macwin.c index 55a2213a5..67a6f169c 100644 --- a/sys/mac/macwin.c +++ b/sys/mac/macwin.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)macwin.c 3.5 1996/01/15 */ +/* SCCS Id: @(#)macwin.c 3.5 2005/11/19 */ /* Copyright (c) Jon W{tte, Hao-Yang Wang, Jonathan Handler 1992. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1366,8 +1366,11 @@ mac_destroy_nhwindow (winid win) { void -mac_number_pad (int pad) { - iflags.num_pad = pad; +mac_number_pad (int pad) { /* no effect */ +#if defined(__SC__) || defined(__MRC__) +# pragma unused(pad) +#endif + return; } @@ -1382,7 +1385,7 @@ trans_num_keys(EventRecord *theEvent) { * The number_pad option controls how digits are interpreted. */ #if 0 - if (iflags.num_pad) { + if (Cmd.num_pad) { Handle h = GetResource('Nump', theEvent->modifiers & shiftKey ? 129 : 128); if (h) { short inkey = (theEvent->message & keyCodeMask), *ab = (short *)*h; @@ -2146,7 +2149,7 @@ BaseCursor(NhWindow *wind, Point pt) if (cursor_locked) dir = (char *)0; else { - dir_bas = iflags.num_pad ? (char *) ndir : (char *) sdir; + dir_bas = (char *)Cmd.dirchars; dir = strchr(dir_bas, *click_to_cmd(pt.h / wind->char_width + 1 , pt.v / wind->row_height, CLICK_1)); } diff --git a/sys/vms/vmstty.c b/sys/vms/vmstty.c index 1b6f39631..d95419de8 100644 --- a/sys/vms/vmstty.c +++ b/sys/vms/vmstty.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)vmstty.c 3.5 2003/09/18 */ +/* SCCS Id: @(#)vmstty.c 3.5 2005/11/19 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ /* tty.c - (VMS) version */ @@ -137,10 +137,10 @@ vms_getchar() key = (short)'\n'; } else if (kb_buf == ESC || kb_buf == CSI || kb_buf == SS3) { switch(parse_function_key((int)kb_buf)) { - case SMG$K_TRM_UP: key = iflags.num_pad ? '8' : 'k'; break; - case SMG$K_TRM_DOWN: key = iflags.num_pad ? '2' : 'j'; break; - case SMG$K_TRM_LEFT: key = iflags.num_pad ? '4' : 'h'; break; - case SMG$K_TRM_RIGHT: key = iflags.num_pad ? '6' : 'l'; break; + case SMG$K_TRM_UP: key = Cmd.move_N; break; + case SMG$K_TRM_DOWN: key = Cmd.move_S; break; + case SMG$K_TRM_LEFT: key = Cmd.move_W; break; + case SMG$K_TRM_RIGHT: key = Cmd.move_E; break; default: key = ESC; break; } } else { @@ -157,10 +157,10 @@ vms_getchar() if (recurse++ == 0 && kb != 0) { smg$read_keystroke(&kb, &key); switch (key) { - case SMG$K_TRM_UP: iflags.num_pad ? '8' : key = 'k'; break; - case SMG$K_TRM_DOWN: iflags.num_pad ? '2' : key = 'j'; break; - case SMG$K_TRM_LEFT: iflags.num_pad ? '4' : key = 'h'; break; - case SMG$K_TRM_RIGHT: iflags.num_pad ? '6' : key = 'l'; break; + case SMG$K_TRM_UP: key = Cmd.move_N; break; + case SMG$K_TRM_DOWN: key = Cmd.move_S; break; + case SMG$K_TRM_LEFT: key = Cmd.move_W; break; + case SMG$K_TRM_RIGHT: key = Cmd.move_E; break; case '\r': key = '\n'; break; default: if (key > 255) key = ESC; break; diff --git a/win/Qt/qt_win.cpp b/win/Qt/qt_win.cpp index 74348653c..51cc6f84a 100644 --- a/win/Qt/qt_win.cpp +++ b/win/Qt/qt_win.cpp @@ -1,4 +1,4 @@ -// SCCS Id: @(#)qt_win.cpp 3.5 1999/11/19 +// SCCS Id: @(#)qt_win.cpp 3.5 2005/11/19 // Copyright (c) Warwick Allison, 1999. // NetHack may be freely redistributed. See license for details. @@ -3995,7 +3995,7 @@ void NetHackQtMainWindow::keyPressEvent(QKeyEvent* event) event->key() >= Key_Left && event->key() <= Key_Down ) return; - const char* d = iflags.num_pad ? ndir : sdir; + const char* d = Cmd.dirchars; switch (event->key()) { case Key_Up: if ( dirkey == d[0] ) @@ -4141,7 +4141,7 @@ char NetHackQtYnDialog::Exec() } if ( strstr(question, "what direction") ) { // We replace this regardless, since sometimes you get choices. - const char* d = iflags.num_pad ? ndir : sdir; + const char* d = Cmd.dirchars; enable=ch; ch=""; ch.append(d[1]); diff --git a/win/gnome/gnsignal.c b/win/gnome/gnsignal.c index c428dcff4..61ae673c1 100644 --- a/win/gnome/gnsignal.c +++ b/win/gnome/gnsignal.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)gnsignal.c 3.5 2000/07/16 */ +/* SCCS Id: @(#)gnsignal.c 3.5 2005/11/19 */ /* Copyright (C) 1998 by Anthony Taylor */ /* NetHack may be freely redistributed. See license for details. */ @@ -268,24 +268,24 @@ ghack_handle_key_press(GtkWidget *widget, GdkEventKey *event, gpointer data) /* First handle the arrow keys -- these always mean move */ case GDK_Right: case GDK_rightarrow: - if (iflags.num_pad) key='6'; else key='l'; break; + key = Cmd.move_E; break; case GDK_Left: case GDK_leftarrow: - if (iflags.num_pad) key='4'; else key='h'; break; + key = Cmd.move_W; break; case GDK_Up: case GDK_uparrow: - if (iflags.num_pad) key='8'; else key='k'; break; + key = Cmd.move_N; break; case GDK_Down: case GDK_downarrow: - if (iflags.num_pad) key='2'; else key='j'; break; + key = Cmd.move_S; break; case GDK_Home: - if (iflags.num_pad) key='7'; else key='y'; break; + key = Cmd.move_NW; break; case GDK_End: - if (iflags.num_pad) key='1'; else key='b'; break; + key = Cmd.move_SW; break; case GDK_Page_Down: - if (iflags.num_pad) key='3'; else key='n'; break; + key = Cmd.move_SE; break; case GDK_Page_Up: - if (iflags.num_pad) key='9'; else key='u'; break; + key = Cmd.move_NE; break; case ' ': key='.'; break; /* Now, handle the numberpad (move or numbers) */ diff --git a/win/tty/termcap.c b/win/tty/termcap.c index 9454d2657..b9a8bcf1a 100644 --- a/win/tty/termcap.c +++ b/win/tty/termcap.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)termcap.c 3.5 2000/07/10 */ +/* SCCS Id: @(#)termcap.c 3.5 2005/11/19 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -465,7 +465,7 @@ tty_start_screen() /* set up callback in case option is not set yet but toggled later */ decgraphics_mode_callback = tty_decgraphics_termcap_fixup; #endif - if (iflags.num_pad) tty_number_pad(1); /* make keypad send digits */ + if (Cmd.num_pad) tty_number_pad(1); /* make keypad send digits */ } void -- 2.40.0