From: nethack.allison Date: Sun, 9 Mar 2003 18:36:24 +0000 (+0000) Subject: win32tty: dynamic keystroke handler with 3.4.0 behaviour X-Git-Tag: MOVE2GIT~2100 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=56585d286f4ba8c5cef69d6f5a1688092ecc1f3f;p=nethack win32tty: dynamic keystroke handler with 3.4.0 behaviour --- diff --git a/Files b/Files index 6e014e660..4281e9d4c 100644 --- 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) diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index c8b92bf81..edc17838c 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -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 index 000000000..fc8c1f26b --- /dev/null +++ b/sys/winnt/nh340key.c @@ -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; +} +