]> granicus.if.org Git - nethack/commitdiff
number_pad:3,4,-1 (trunk only)
authornethack.rankin <nethack.rankin>
Sat, 26 Nov 2005 02:34:23 +0000 (02:34 +0000)
committernethack.rankin <nethack.rankin>
Sat, 26 Nov 2005 02:34:23 +0000 (02:34 +0000)
[See the cvs log from flag.h for comments pertaining to iflags.num_pad
and Cmd.num_pad, Cmd.commands[], Cmd.serialno.]

14 files changed:
dat/help
dat/hh
dat/opthelp
doc/fixes35.0
src/cmd.c
src/decl.c
src/dig.c
src/do_name.c
src/options.c
sys/mac/macwin.c
sys/vms/vmstty.c
win/Qt/qt_win.cpp
win/gnome/gnsignal.c
win/tty/termcap.c

index 4c377828c09dea4e58d1d2fe9333ccf54a149007..5959add2d3816b02ce6c1accf222ad856e8e8be7 100644 (file)
--- a/dat/help
+++ b/dat/help
@@ -67,6 +67,12 @@ b j n   1 2 3           g<dir>:   run in direction <dir> until something
                 Meta number, or Alt number will invoke the YUHJKLBN commands.
                 Control <dir> 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 5fe6bfaec175173d02ab7ffefd4a3bbd6baa1f6e..bc56d319cdc808d91dea3eda9e99e5be2bbcb400 100644 (file)
--- a/dat/hh
+++ b/dat/hh
@@ -14,6 +14,12 @@ b j n   1 2 3           g<dir>:   run in direction <dir> until something
                 Meta number, or Alt number will invoke the YUHJKLBN commands.
                 Control <dir> 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
index 57cb6a7c618089ddb9f1d323978589881f20bd09..ff1f18663daab842ac8092f8fd34892a9fc2400d 100644 (file)
@@ -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
index ff389d2139e21384d905159120c1dfa194c8119c..8d73d9fa5e63172715f35bb1bd4cc9bb98696557 100644 (file)
@@ -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
index abdd0a5d70908748219f7a5240cbc7f2bdc45591..c59090a9f8fa62ce74e6883f6c764303b1815fff 100644 (file)
--- 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);
index cdde3333c3efddaa9fce54a76901587d197228d5..5b1dad3fcfb2e3442cd4d400c238024c1ad4ae6b 100644 (file)
@@ -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 };
index fa1fdb26e493be3159cbb8743716c9d9ade59175..08a2a5001d4f6ade48637f07dbd18c58fc7fce95 100644 (file)
--- 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) {
index a3a389bf0554d00b70ec6c4b4eb803357eade7a8..af325879fa011d55746c2c06f5a77e217ef1244c 100644 (file)
@@ -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 */
index 862c50d04e16bf9d4542daa58e485e49472157c7..965385662861f6f686f3e3c51872ff27c072e710 100644 (file)
@@ -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);
index 55a2213a587b4192d541e4ab63741e094e92b2a0..67a6f169c0f8d183d14eb03b4ef2bd8d6f6f80a0 100644 (file)
@@ -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));
        }
index 1b6f39631b2c30c44d56434bbb5bb829eec9c38f..d95419de829aaf7208eb7469760097c46905d54a 100644 (file)
@@ -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;
index 74348653ccd5158066700fc202201bfbef90fa63..51cc6f84a802564f07557433c7d85009cc620825 100644 (file)
@@ -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]);
index c428dcff4fa521ffeaeceb5abedbfadc164817ce..61ae673c10d471bdd30a39667a0cb3e0af833b48 100644 (file)
@@ -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 <tonyt@ptialaska.net> */
 /* 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) */
index 9454d2657b1bca8f84eb14a603e1513424b9578a..b9a8bcf1aadbe04f7f082286a4652cba51c9942c 100644 (file)
@@ -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