]> granicus.if.org Git - nethack/commitdiff
port-specific debug-mode command
authornethack.allison <nethack.allison>
Thu, 6 Feb 2003 03:07:43 +0000 (03:07 +0000)
committernethack.allison <nethack.allison>
Thu, 6 Feb 2003 03:07:43 +0000 (03:07 +0000)
Provide a way to have a port-specific debug-mode commands
if PORT_DEBUG is defined at build time.

Add a win32 keystroke checking routine to assist debugging
of international keyboards.

Fix a problem with the way NetHack was handling
international keyboards by letting ToAscii() come
up with an input character based on the virtual key,
and the shift and caps lock state.

doc/fixes34.1
include/ntconf.h
src/cmd.c
sys/winnt/nttty.c

index a53dc82d233d6ab15ecbfdbd77275d46da3c7fec..8ba3231aebf68fe8fdf34840cd4d58cb05671af1 100644 (file)
@@ -440,3 +440,4 @@ eating mimics now has an hallucination effect
 prefix pickup command with 'm' to force menu of all objects present
 provide feedback which states the correct command when players try to use 
        'R' or 'P' for armour, or use 'W' or 'T' for accessories
+optional #portdebug wizard mode command to invoke port-specific debug routines
index d4d846d57f5ba8102c1d962ecd6ba40d4b6be664..956bfbde3895426d12d4fb775248e0fda74d3ae5 100644 (file)
 
 #define PORT_HELP      "porthelp"
 
+#ifdef WIN32CON
+#define PORT_DEBUG     /* include ability to debug international keyboard issues */
+#endif
+
 /* The following is needed for prototypes of certain functions */
 #if defined(_MSC_VER)
 #include <process.h>   /* Provides prototypes of exit(), spawn()      */
index c84d92d8da16b3529b15614a83a945742612a645..7a7125dece33eebd6626c91a51aead4810f54af9 100644 (file)
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -132,6 +132,9 @@ STATIC_DCL void FDECL(mon_invent_chain, (winid, const char *, struct monst *, lo
 STATIC_DCL void FDECL(mon_chain, (winid, const char *, struct monst *, long *, long *));
 STATIC_DCL void FDECL(contained, (winid, const char *, long *, long *));
 STATIC_PTR int NDECL(wiz_show_stats);
+#  ifdef PORT_DEBUG
+STATIC_DCL int NDECL(wiz_port_debug);
+#  endif
 # endif
 STATIC_PTR int NDECL(enter_explore_mode);
 STATIC_PTR int NDECL(doattributes);
@@ -1499,6 +1502,9 @@ struct ext_func_tab extcmdlist[] = {
        {(char *)0, (char *)0, donull, TRUE},
        {(char *)0, (char *)0, donull, TRUE},
        {(char *)0, (char *)0, donull, TRUE},
+#ifdef PORT_DEBUG
+       {(char *)0, (char *)0, donull, TRUE},
+#endif
        {(char *)0, (char *)0, donull, TRUE},
         {(char *)0, (char *)0, donull, TRUE},
        {(char *)0, (char *)0, donull, TRUE},
@@ -1518,6 +1524,9 @@ static const struct ext_func_tab debug_extcmdlist[] = {
        {"monpolycontrol", "control monster polymorphs", wiz_mon_polycontrol, TRUE},
        {"panic", "test panic routine (fatal to game)", wiz_panic, TRUE},
        {"polyself", "polymorph self", wiz_polyself, TRUE},
+#ifdef PORT_DEBUG
+       {"portdebug", "wizard port debug command", wiz_port_debug, TRUE},
+#endif
        {"seenv", "show seen vectors", wiz_show_seenv, TRUE},
        {"stats", "show memory statistics", wiz_show_stats, TRUE},
        {"timeout", "look at timeout queue", wiz_timeout_queue, TRUE},
@@ -2388,6 +2397,54 @@ dotravel()
        return 0;
 }
 
+#ifdef PORT_DEBUG
+# ifdef WIN32CON
+extern void NDECL(win32con_debug_keystrokes);
+# endif
+
+int
+wiz_port_debug()
+{
+       int n, k;
+       winid win;
+       anything any;
+       int item = 'a';
+       int num_menu_selections;
+       struct menu_selection_struct {
+               char *menutext;
+               void NDECL((*fn));
+       } menu_selections[] = {
+#ifdef WIN32CON
+               {"test win32 keystrokes", win32con_debug_keystrokes},
+#endif
+               {(char *)0, (void NDECL((*)))0}         /* array terminator */
+       };
+
+       num_menu_selections = SIZE(menu_selections) - 1;
+       if (num_menu_selections > 0) {
+               menu_item *pick_list;
+               win = create_nhwindow(NHW_MENU);
+               start_menu(win);
+               for (k=0; k < num_menu_selections; ++k) {
+                       any.a_int = k+1;
+                       add_menu(win, NO_GLYPH, &any, item++, 0, ATR_NONE,
+                               menu_selections[k].menutext, MENU_UNSELECTED);
+               }
+               end_menu(win, "Which port debugging feature?");
+               n = select_menu(win, PICK_ONE, &pick_list);
+               destroy_nhwindow(win);
+               if (n > 0) {
+                       n = pick_list[0].item.a_int - 1;
+                       free((genericptr_t) pick_list);
+                       /* execute the function */
+                       (*menu_selections[n].fn)();
+               }
+       } else
+               pline("No port-specific debug capability defined.");
+       return 0;
+}
+# endif /*PORT_DEBUG*/
+
 #endif /* OVL0 */
 
 /*cmd.c*/
index e73bb4eb5f9b26e1e7b503c1bc3b820608fcfe8a..f213883071259269c2d0b37689265cee5703dbff 100644 (file)
@@ -321,34 +321,34 @@ static const struct pad {
 };
 
 #define inmap(x,vk)    (((x) > 'A' && (x) < 'Z') || (vk) == 0xBF || (x) == '2')
+
+static BYTE KeyState[256];
  
-int FDECL(process_keystroke, (INPUT_RECORD *ir, boolean *valid));
+int FDECL(process_keystroke, (INPUT_RECORD *ir, boolean *valid, int portdebug));
 
-int process_keystroke(ir, valid)
+int process_keystroke(ir, valid, portdebug)
 INPUT_RECORD *ir;
 boolean *valid;
+int portdebug;
 {
-       int metaflags = 0;
+       int metaflags = 0, k;
        int keycode, vk;
-       unsigned char ch;
+       unsigned char ch, pre_ch;
        unsigned short int scan;
        unsigned long shiftstate;
        int altseq = 0;
        const struct pad *kpad;
 
-#if 0
-       /* sanity check, but caller should have checked already */
-       if (ir->EventType != KEY_EVENT) {
-               if (valid) *valid = 0;
-               return 0;
-       }
-#endif
        shiftstate = 0L;
-       ch    = ir->Event.KeyEvent.uChar.AsciiChar;
+       ch = pre_ch = ir->Event.KeyEvent.uChar.AsciiChar;
        scan  = ir->Event.KeyEvent.wVirtualScanCode;
        vk    = ir->Event.KeyEvent.wVirtualKeyCode;
        keycode = MapVirtualKey(vk, 2);
        shiftstate = ir->Event.KeyEvent.dwControlKeyState;
+       KeyState[VK_SHIFT]   = (shiftstate & SHIFT_PRESSED) ? 0x81 : 0;
+       KeyState[VK_CONTROL] = (shiftstate & (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED)) ?
+                               0x81 : 0;
+       KeyState[VK_CAPITAL] = (shiftstate & CAPSLOCK_ON) ? 0x81 : 0;
 
        if (shiftstate & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED)) {
                if (ch || inmap(keycode,vk)) altseq = 1;
@@ -387,7 +387,36 @@ boolean *valid;
                if (vk == 0xBF) ch = M('?');
                else ch = M(tolower(keycode));
         }
-        return (ch == '\r') ? '\n' : ch;
+       /* Attempt to work better with international keyboards. */
+       else {
+               WORD chr[2];
+               k = ToAscii(vk, scan, KeyState, chr, 0);
+               if (k <= 2)
+                   switch(k) {
+                       case 2:  /* two characters */
+                               ch = (unsigned char)chr[1];
+                               *valid = TRUE;
+                               break;
+                       case 1:  /* one character */
+                               ch = (unsigned char)chr[0];
+                               *valid = TRUE;
+                               break;
+                       case 0:  /* no translation */
+                       default: /* negative */
+                               *valid = FALSE;
+                   }
+       }
+       if (ch == '\r') ch = '\n';
+#ifdef PORT_DEBUG
+       if (portdebug) {
+               char buf[BUFSZ];
+               Sprintf(buf,
+       "PORTDEBUG: ch=%u, scan=%u, vk=%d, pre=%d, shiftstate=0x%X (ESC to end)\n",
+                       ch, scan, vk, pre_ch, shiftstate);
+               xputs(buf);
+       }
+#endif
+       return ch;
 }
 
 int
@@ -397,11 +426,10 @@ tgetch()
        boolean valid = 0;
        int ch;
        valid = 0;
-       while (!valid)
-       {
+       while (!valid) {
           ReadConsoleInput(hConIn,&ir,1,&count);
           if ((ir.EventType == KEY_EVENT) && ir.Event.KeyEvent.bKeyDown)
-               ch = process_keystroke(&ir, &valid);
+               ch = process_keystroke(&ir, &valid, 0);
        }
        return ch;
 }
@@ -420,7 +448,7 @@ int *x, *y, *mod;
            ReadConsoleInput(hConIn,&ir,1,&count);
            if (count > 0) {
                if (ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown) {
-                       keystroke = process_keystroke(&ir, &valid);
+                       keystroke = process_keystroke(&ir, &valid, 0);
                        if (valid) return keystroke;
                } else if (ir.EventType == MOUSE_EVENT) {
                        if ((ir.Event.MouseEvent.dwEventFlags == 0) &&
@@ -891,4 +919,21 @@ const char *pref;
        }
        return;
 }
+
+#ifdef PORT_DEBUG
+void
+win32con_debug_keystrokes()
+{
+       DWORD count;
+       boolean valid = 0;
+       int ch;
+       xputs("\n");
+       while (!valid || ch != 27) {
+          ReadConsoleInput(hConIn,&ir,1,&count);
+          if ((ir.EventType == KEY_EVENT) && ir.Event.KeyEvent.bKeyDown)
+               ch = process_keystroke(&ir, &valid, 1);
+       }
+       (void)doredraw();
+}
+#endif
 #endif /* WIN32CON */