]> granicus.if.org Git - nethack/commitdiff
win32tty: dynamic keystroke handler with 3.4.0 behaviour
authornethack.allison <nethack.allison>
Sun, 9 Mar 2003 18:36:24 +0000 (18:36 +0000)
committernethack.allison <nethack.allison>
Sun, 9 Mar 2003 18:36:24 +0000 (18:36 +0000)
Files
sys/winnt/Makefile.msc
sys/winnt/nh340key.c [new file with mode: 0644]

diff --git a/Files b/Files
index 6e014e6601412e7e4f6ebf76e16245811e44b465..4281e9d4ca8267ceebe3c92ee400021d843bef2e 100644 (file)
--- a/Files
+++ b/Files
@@ -190,9 +190,9 @@ winmain.c
 sys/winnt:
 (files for Windows 9x, NT and Windows2000 version)
 Install.nt      Makefile.bcc    Makefile.gcc    Makefile.msc    console.rc
-defaults.nh     mapimail.c      nethack.def     nhdefkey.c      nhico.uu
-nhsetup.bat     ntsound.c       nttty.c         porthelp        win32api.h
-winnt.c
+defaults.nh     mapimail.c      nethack.def     nhdefkey.c      nh340key.c
+nhico.uu        nhsetup.bat     ntsound.c       nttty.c         porthelp
+win32api.h      winnt.c
 
 util:
 (files for all versions)
index c8b92bf81611dd1ec4e0f503f09291346ffcb600..edc17838ca45885cb44196dea595714bbdb19007 100644 (file)
@@ -572,7 +572,7 @@ $(NHRES): $(NTSYS)\console.rc $(NTSYS)\NetHack.ico
 #  DO NOT INDENT THE << below!
 #
 
-$(GAMEFILE) : $(ALLOBJ) $(NHRES) $(GAMEDIR)\nhdefkey.dll
+$(GAMEFILE) : $(ALLOBJ) $(NHRES) $(GAMEDIR)\nhdefkey.dll $(GAMEDIR)\nh340key.dll
        @if not exist $(GAMEDIR)\*.* mkdir $(GAMEDIR)
        @echo Linking....
        $(link) $(LFLAGS) user32.lib winmm.lib -out:$@ @<<$(GAME).lnk
@@ -597,6 +597,21 @@ $(GAMEDIR)\nhdefkey.dll : $(O)$(@B).o $(O)$(@B).def
                /PDB:"$(@B).PDB" /MAP:"$(@B).map" /DEF:$(O)$(@B).def \
                -out:$@ $(O)$(@B).o
 
+$(O)nh340key.def:
+       @echo EXPORTS >$@
+       @echo    ProcessKeystroke >>$@
+       @echo    NHkbhit >>$@
+       @echo    SourceWhere >>$@
+       @echo    SourceAuthor >>$@
+       @echo    KeyHandlerName >>$@
+
+$(GAMEDIR)\nh340key.dll : $(O)$(@B).o $(O)$(@B).def
+       @if not exist $(GAMEDIR)\*.* mkdir $(GAMEDIR)
+       @echo Linking $@
+       $(link) -debug:full -debugtype:cv /RELEASE /NOLOGO /DLL user32.lib \
+               /PDB:"$(@B).PDB" /MAP:"$(@B).map" /DEF:$(O)$(@B).def \
+               -out:$@ $(O)$(@B).o
+
 #
 #  Secondary Targets.
 #
diff --git a/sys/winnt/nh340key.c b/sys/winnt/nh340key.c
new file mode 100644 (file)
index 0000000..fc8c1f2
--- /dev/null
@@ -0,0 +1,241 @@
+/*     SCCS Id: @(#)nh340key.c 3.4     $Date$   */
+/* Copyright (c) NetHack PC Development Team 2003                      */
+/* NetHack may be freely redistributed.  See license for details.      */
+
+/*
+ * This is the NetHack keystroke processing from NetHack 3.4.0.
+ * It can be built as a run-time loadable dll (nh340key.dll),
+ * placed in the same directory as the nethack.exe executable,
+ * and loaded by specifying OPTIONS=altkeyhandler:nh340key
+ * in defaults.nh
+ */
+
+static char where_to_get_source[] = "http://www.nethack.org/";
+static char author[] = "The NetHack Development Team";
+
+#include "hack.h"
+#include "wintty.h"
+#include "win32api.h"
+
+extern HANDLE hConIn;
+extern INPUT_RECORD ir;
+char dllname[512];
+char *shortdllname;
+
+int WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved)
+{
+       char dlltmpname[512];
+       char *tmp = dlltmpname, *tmp2;
+       *(tmp + GetModuleFileName(hInstance, tmp, 511)) = '\0';
+       (void)strcpy(dllname, tmp);
+       tmp2 = strrchr(dllname, '\\');
+       if (tmp2) {
+               tmp2++;
+               shortdllname = tmp2;
+       }
+       return TRUE;
+}
+
+/*
+ *  Keyboard translation tables.
+ *  (Adopted from the MSDOS port)
+ */
+
+#define KEYPADLO       0x47
+#define KEYPADHI       0x53
+
+#define PADKEYS        (KEYPADHI - KEYPADLO + 1)
+#define iskeypad(x)    (KEYPADLO <= (x) && (x) <= KEYPADHI)
+
+/*
+ * Keypad keys are translated to the normal values below.
+ * Shifted keypad keys are translated to the
+ *    shift values below.
+ */
+
+static const struct pad {
+       uchar normal, shift, cntrl;
+} keypad[PADKEYS] = {
+                       {'y', 'Y', C('y')},             /* 7 */
+                       {'k', 'K', C('k')},             /* 8 */
+                       {'u', 'U', C('u')},             /* 9 */
+                       {'m', C('p'), C('p')},          /* - */
+                       {'h', 'H', C('h')},             /* 4 */
+                       {'g', 'G', 'g'},                /* 5 */
+                       {'l', 'L', C('l')},             /* 6 */
+                       {'+', 'P', C('p')},             /* + */
+                       {'b', 'B', C('b')},             /* 1 */
+                       {'j', 'J', C('j')},             /* 2 */
+                       {'n', 'N', C('n')},             /* 3 */
+                       {'i', 'I', C('i')},             /* Ins */
+                       {'.', ':', ':'}                 /* Del */
+}, numpad[PADKEYS] = {
+                       {'7', M('7'), '7'},             /* 7 */
+                       {'8', M('8'), '8'},             /* 8 */
+                       {'9', M('9'), '9'},             /* 9 */
+                       {'m', C('p'), C('p')},          /* - */
+                       {'4', M('4'), '4'},             /* 4 */
+                       {'g', 'G', 'g'},                /* 5 */
+                       {'6', M('6'), '6'},             /* 6 */
+                       {'+', 'P', C('p')},             /* + */
+                       {'1', M('1'), '1'},             /* 1 */
+                       {'2', M('2'), '2'},             /* 2 */
+                       {'3', M('3'), '3'},             /* 3 */
+                       {'i', 'I', C('i')},             /* Ins */
+                       {'.', ':', ':'}                 /* Del */
+};
+
+#define inmap(x,vk)    (((x) > 'A' && (x) < 'Z') || (vk) == 0xBF || (x) == '2')
+
+int __declspec(dllexport) __stdcall
+ProcessKeystroke(ir, valid, numberpad, portdebug)
+INPUT_RECORD *ir;
+boolean *valid;
+boolean numberpad;
+int portdebug;
+{
+       int metaflags = 0, k = 0;
+       int keycode, vk;
+       unsigned char ch, pre_ch, mk = 0;
+       unsigned short int scan;
+       unsigned long shiftstate;
+       int altseq = 0;
+       const struct pad *kpad;
+
+       shiftstate = 0L;
+       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;
+
+       if (shiftstate & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED)) {
+               if (ch || inmap(keycode,vk)) altseq = 1;
+               else altseq = -1;       /* invalid altseq */
+       }
+       if (ch || (iskeypad(scan)) || (altseq > 0))
+               *valid = TRUE;
+       /* if (!valid) return 0; */
+       /*
+        * shiftstate can be checked to see if various special
+         * keys were pressed at the same time as the key.
+         * Currently we are using the ALT & SHIFT & CONTROLS.
+         *
+         *           RIGHT_ALT_PRESSED, LEFT_ALT_PRESSED,
+         *           RIGHT_CTRL_PRESSED, LEFT_CTRL_PRESSED,
+         *           SHIFT_PRESSED,NUMLOCK_ON, SCROLLLOCK_ON,
+         *           CAPSLOCK_ON, ENHANCED_KEY
+         *
+         * are all valid bit masks to use on shiftstate.
+         * eg. (shiftstate & LEFT_CTRL_PRESSED) is true if the
+         *      left control key was pressed with the keystroke.
+         */
+        if (iskeypad(scan)) {
+            kpad = numberpad ? numpad : keypad;
+            if (shiftstate & SHIFT_PRESSED) {
+                ch = kpad[scan - KEYPADLO].shift;
+            }
+            else if (shiftstate & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) {
+                ch = kpad[scan - KEYPADLO].cntrl;
+            }
+            else {
+                ch = kpad[scan - KEYPADLO].normal;
+            }
+        }
+        else if (altseq > 0) { /* ALT sequence */
+               if (vk == 0xBF) ch = M('?');
+               else ch = M(tolower(keycode));
+        }
+       if (ch == '\r') ch = '\n';
+#ifdef PORT_DEBUG
+       if (portdebug) {
+               char buf[BUFSZ];
+               Sprintf(buf,
+       "PORTDEBUG (%s): ch=%u, sc=%u, vk=%d, sh=0x%X (ESC to end)",
+                       shortdllname, ch, scan, vk, shiftstate);
+               fprintf(stdout, "\n%s", buf);
+       }
+#endif
+       return ch;
+}
+
+int __declspec(dllexport) __stdcall
+NHkbhit(hConIn, ir)
+HANDLE hConIn;
+INPUT_RECORD *ir;
+{
+       int done = 0;   /* true =  "stop searching"        */
+       int retval;     /* true =  "we had a match"        */
+       DWORD count;
+       unsigned short int scan;
+       unsigned char ch;
+       unsigned long shiftstate;
+       int altseq = 0, keycode, vk;
+       done = 0;
+       retval = 0;
+       while (!done)
+       {
+           count = 0;
+           PeekConsoleInput(hConIn,ir,1,&count);
+           if (count > 0) {
+               if (ir->EventType == KEY_EVENT && ir->Event.KeyEvent.bKeyDown) {
+                       ch    = ir->Event.KeyEvent.uChar.AsciiChar;
+                       scan  = ir->Event.KeyEvent.wVirtualScanCode;
+                       shiftstate = ir->Event.KeyEvent.dwControlKeyState;
+                       vk = ir->Event.KeyEvent.wVirtualKeyCode;
+                       keycode = MapVirtualKey(vk, 2);
+                       if (shiftstate & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED)) {
+                               if  (ch || inmap(keycode,vk)) altseq = 1;
+                               else altseq = -1;       /* invalid altseq */
+                       }
+                       if (ch || iskeypad(scan) || altseq) {
+                               done = 1;           /* Stop looking         */
+                               retval = 1;         /* Found what we sought */
+                       }
+               }
+               else if ((ir->EventType == MOUSE_EVENT &&
+                 (ir->Event.MouseEvent.dwButtonState & MOUSEMASK))) {
+                       done = 1;
+                       retval = 1;
+               }
+
+               else /* Discard it, it's an insignificant event */
+                       ReadConsoleInput(hConIn,ir,1,&count);
+               } else  /* There are no events in console event queue */ {
+               done = 1;         /* Stop looking               */
+               retval = 0;
+           }
+       }
+       return retval;
+}
+
+
+int __declspec(dllexport) __stdcall
+SourceWhere(buf)
+char **buf;
+{
+       if (!buf) return 0;
+       *buf = where_to_get_source;
+       return 1;
+}
+
+int __declspec(dllexport) __stdcall
+SourceAuthor(buf)
+char **buf;
+{
+       if (!buf) return 0;
+       *buf = author;
+       return 1;
+}
+
+int __declspec(dllexport) __stdcall
+KeyHandlerName(buf, full)
+char **buf;
+int full;
+{
+       if (!buf) return 0;
+       if (full) *buf = dllname;
+       else *buf = shortdllname;
+       return 1;
+}
+