diff -Naurd ../nethack-3.4.1/sys/winnt/console.rc ./sys/winnt/console.rc --- ../nethack-3.4.1/sys/winnt/console.rc Sun Feb 23 14:43:43 2003 +++ ./sys/winnt/console.rc Mon Sep 1 14:33:32 2003 @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)console.rc 3.4 $Date: 2002/07/24 08:25:20 $ */ +/* SCCS Id: @(#)console.rc 3.4 $Date: 2003/08/28 05:47:22 $ */ /* Copyright (c) Yitzhak Sapir, 2002. */ /* NetHack may be freely redistributed. See license for details. */ @@ -6,6 +6,44 @@ 1 ICON DISCARDABLE "NetHack.ICO" +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 3,4,2,0 + PRODUCTVERSION 3,4,2,0 + FILEFLAGSMASK 0x1fL +#ifdef _DEBUG + FILEFLAGS 0x9L +#else + FILEFLAGS 0x8L +#endif + FILEOS 0x4L + FILETYPE 0x0L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "FileDescription", "NetHack for Windows - TTY Interface\0" + VALUE "FileVersion", "3.4.2\0" + VALUE "InternalName", "NetHack\0" + VALUE "LegalCopyright", "Copyright (C) 1985 - 2003. By Stichting Mathematisch Centrum and M. Stephenson. See license for details.\0" + VALUE "OriginalFilename", "NetHack.exe\0" + VALUE "PrivateBuild", "030825\0" + VALUE "ProductName", "NetHack\0" + VALUE "ProductVersion", "3.4.2\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + /*console.rc*/ diff -Naurd ../nethack-3.4.1/sys/winnt/defaults.nh ./sys/winnt/defaults.nh --- ../nethack-3.4.1/sys/winnt/defaults.nh Sun Feb 23 14:43:43 2003 +++ ./sys/winnt/defaults.nh Mon Sep 1 14:33:32 2003 @@ -13,6 +13,15 @@ # for tty window-port. OPTIONS=IBMGraphics +# Keyboard handling +# Different keyboard handlers can be loaded. +# Default is nhdefkey.dll but you can override that. +# Ray Chason's keyboard handler +# OPTIONS=altkeyhandler:nhraykey.dll +# +# NetHack 3.4.0 keyboard handling +# OPTIONS=altkeyhandler:nh340key.dll + # *** Personal Preferences *** # Some options to set personal preferences. Uncomment and change these to # suit your personal preference. If several people are to use the same @@ -31,7 +40,9 @@ # General options. You might also set "silent" so as not to attract # the boss's attention. # -OPTIONS=time,noshowexp,number_pad,lit_corridor +# number_pad option can have an optional value of 0 (off), 1 (on), +# or 2(on,legacy-mode) which causes 5='g', alt-5='G', alt-0='I' +OPTIONS=time,noshowexp,number_pad:2,lit_corridor # # If you want to get rid of "use #quit to quit..." use: OPTIONS=suppress_alert:3.3.1 @@ -106,6 +117,15 @@ # The location that a record of game aborts and self-diagnosed game problems # is kept (default=HACKDIR, writeable) #TROUBLEDIR=c:\nethack\trouble + +# Finnish keyboards might need these modifications uncommented. +# For \, @, $, [, | +#OPTIONS=subkeyvalue:171/92 +#OPTIONS=subkeyvalue:178/64 +#OPTIONS=subkeyvalue:180/36 +#OPTIONS=subkeyvalue:184/91 +#OPTIONS=subkeyvalue:188/124 + # # *** CHARACTER GRAPHICS *** # @@ -165,4 +185,3 @@ # 047 045 092 058 058 092 045 047 \ # 047 045 092 058 032 058 092 045 047 - diff -Naurd ../nethack-3.4.1/sys/winnt/Install.nt ./sys/winnt/Install.nt --- ../nethack-3.4.1/sys/winnt/Install.nt Sun Feb 23 14:43:43 2003 +++ ./sys/winnt/Install.nt Mon Sep 1 14:33:32 2003 @@ -4,7 +4,7 @@ Instructions for compiling and installing NetHack 3.4 on a Windows 9x, NT, 2000, or XP system ============================================================== - Last revision: $Date: 2003/02/22 01:20:14 $ + Last revision: $Date: 2003/03/15 13:23:39 $ Credit for the porting of NetHack to the Win32 Console Subsystem goes to the NT Porting Team started by Michael Allison. @@ -15,7 +15,7 @@ The PC Windows porting team consisting of Michael Allison, David Cohrs, Alex Kompel, Dion Nicolaas, Yitzhak Sapir, and Janet Walz maintained the -tty and graphical win32 versions of NetHack 3.4.1. +tty and graphical win32 versions of NetHack 3.4.2. You can build either the TTY version of NetHack or the Windows Graphical version. In either case you can use one of the following build @@ -426,10 +426,10 @@ If you will be running it by launching it from a shortcut, just use the following information when setting up the shortcut. - Description : NetHack 3.4.1 Console version + Description : NetHack 3.4.2 Console version Command Line : C:\NETHACK\BINARY\NETHACK.EXE - Description : NetHack 3.4.1 Graphical Interface + Description : NetHack 3.4.2 Graphical Interface Command Line : C:\NETHACK\BINARY\NETHACKW.EXE (changing the directory to the appropriate one of course) diff -Naurd ../nethack-3.4.1/sys/winnt/Makefile.bcc ./sys/winnt/Makefile.bcc --- ../nethack-3.4.1/sys/winnt/Makefile.bcc Sun Feb 23 14:43:43 2003 +++ ./sys/winnt/Makefile.bcc Mon Sep 1 14:33:32 2003 @@ -1,6 +1,10 @@ -# SCCS Id: @(#)Makefile.bcc 3.4 $Date: 2003/02/19 14:20:46 $ +# SCCS Id: @(#)Makefile.bcc 3.4 $Date: 2003/08/24 15:38:47 $ # Copyright (c) NetHack PC Development Team 1993-2003 # +# +# IMPORTANT NOTE: This Makefile has not been tested for 3.4.2. +# +# # NetHack 3.4.x Makefile for Borland C++ V5.5.1 and above and Borland's MAKE # # Win32 Compilers Tested: @@ -132,15 +136,19 @@ # Yacc/Lex ... if you got 'em. # # If you have yacc and lex programs (or work-alike such as bison -# and flex), comment out the upper two macros and uncomment -# the lower two. +# and flex), uncomment the upper two macros. # -DO_YACC = YACC_MSG -DO_LEX = LEX_MSG #DO_YACC = YACC_ACT #DO_LEX = LEX_ACT +!IFNDEF DO_YACC +DO_YACC = YACC_MSG +!ENDIF +!IFNDEF DO_LEX +DO_LEX = LEX_MSG +!ENDIF + # Wilbur Streett's Win32 ports of GNU bison and flex are available at: # http://www.monmouth.com/~wstreett/lex-yacc/lex-yacc.html # @@ -203,23 +211,25 @@ ################################################ !IF "$(GRAPHICAL)" == "Y" -WINPORT = $(O)tile.o $(O)mhaskyn.o $(O)mhdlg.o \ +WINPORT = $(O)tile.o $(O)mhaskyn.o $(O)mhdlg.o \ $(O)mhfont.o $(O)mhinput.o $(O)mhmain.o $(O)mhmap.o \ $(O)mhmenu.o $(O)mhmsgwnd.o $(O)mhrip.o $(O)mhsplash.o \ $(O)mhstatus.o $(O)mhtext.o $(O)mswproc.o $(O)winhack.o -WINPFLAG = -DTILES -DMSWIN_GRAPHICS -NHRES = $(O)winhack.res -WINPINC = -I$(WIN32) -WINPHDR = $(WIN32)\mhaskyn.h $(WIN32)\mhdlg.h $(WIN32)\mhfont.h \ +WINPHDR = $(WIN32)\mhaskyn.h $(WIN32)\mhdlg.h $(WIN32)\mhfont.h \ $(WIN32)\mhinput.h $(WIN32)\mhmain.h $(WIN32)\mhmap.h $(WIN32)\mhmenu.h \ $(WIN32)\mhmsg.h $(WIN32)\mhmsgwnd.h $(WIN32)\mhrip.h $(WIN32)\mhstatus.h \ $(WIN32)\mhtext.h $(WIN32)\resource.h $(WIN32)\winMS.h +WINDLLS = +WINPFLAG= -DTILES -DMSWIN_GRAPHICS +NHRES = $(O)winhack.res +WINPINC = -I$(WIN32) !ELSE -WINPORT = $(O)nttty.o -WINPFLAG = -DWIN32CON -WINPHDR = -NHRES = $(O)console.res -WINPINC = +WINPORT = $(O)nttty.o +WINPHDR = +WINDLLS = $(GAMEDIR)\nhdefkey.dll $(GAMEDIR)\nh340key.dll $(GAMEDIR)\nhraykey.dll +WINPFLAG= -DWIN32CON +NHRES = $(O)console.res +WINPINC = !ENDIF TILEUTIL16 = $(UTIL)\tile2bmp.exe @@ -384,7 +394,7 @@ TILEFILES = $(WSHR)\monsters.txt $(WSHR)\objects.txt $(WSHR)\other.txt # -# These are not invoked during a normal game build in 3.4.1 +# These are not invoked during a normal game build in 3.4 # TEXT_IO = $(O)tiletext.o $(O)tiletxt.o $(O)drawing.o \ $(O)decl.o $(O)monst.o $(O)objects.o @@ -607,12 +617,17 @@ $(SRC)\uuid.lib: $(bcclib)\uuid.lib @copy $(bcclib)\uuid.lib $@ -$(GAMEFILE) : $(ALLOBJ) $(NHRES) $(SRC)\uuid.lib +$(GAMEFILE) : $(ALLOBJ) $(NHRES) $(SRC)\uuid.lib $(O)gamedir.tag $(WINDLLS) @echo Linking.... @$(link) $(lflags) $(startobjg) $(ALLOBJ), $@, $(GAME).map,$(libsmt),,$(NHRES) @if exist $(O)install.tag del $(O)install.tag @if exist $(GAMEDIR)\$(GAME).bak del $(GAMEDIR)\$(GAME).bak +$(O)gamedir.tag: + @if not exist $(GAMEDIR)\*.* echo creating directory $(GAMEDIR) + @if not exist $(GAMEDIR)\*.* mkdir $(GAMEDIR) + @echo directory created > $@ + $(GAME)_.ico : $(NTSYS)\$(GAME).ico @copy $(NTSYS)\$(GAME).ico $@ @@ -638,6 +653,46 @@ ! ENDIF @echo graphicschk > graphicschk + +$(GAMEDIR)\nhdefkey.dll : $(O)nhdefkey.o + @if not exist $(GAMEDIR)\*.* mkdir $(GAMEDIR) + @echo EXPORTS >nhdefkey.def + @echo ProcessKeystroke >>nhdefkey.def + @echo NHkbhit >>nhdefkey.def + @echo CheckInput >>nhdefkey.def + @echo SourceWhere >>nhdefkey.def + @echo SourceAuthor >>nhdefkey.def + @echo KeyHandlerName >>nhdefkey.def + @echo Linking $@ + $(link) $(linkdebug) /Gn /Gz /q -L$(bcclib) /c /aa /Tpd /V$(APPVER) -L$(bcclib) -v \ + c0d32.obj $(O)nhdefkey.o, $@,nhdefkey.map,$(libsmt),nhdefkey.def + +$(GAMEDIR)\nh340key.dll : $(O)nh340key.o + @if not exist $(GAMEDIR)\*.* mkdir $(GAMEDIR) + @echo EXPORTS >nh340key.def + @echo ProcessKeystroke >>nh340key.def + @echo NHkbhit >>nh340key.def + @echo CheckInput >>nh340key.def + @echo SourceWhere >>nh340key.def + @echo SourceAuthor >>nh340key.def + @echo KeyHandlerName >>nh340key.def + @echo Linking $@ + $(link) $(linkdebug) /Gn /Gz /q -L$(bcclib) /c /aa /Tpd /V$(APPVER) -L$(bcclib) -v \ + c0d32.obj $(O)nh340key.o, $@,nh340key.map,$(libsmt),nh340key.def + +$(GAMEDIR)\nhraykey.dll : $(O)nhraykey.o + @if not exist $(GAMEDIR)\*.* mkdir $(GAMEDIR) + @echo EXPORTS >nhraykey.def + @echo ProcessKeystroke >>nhraykey.def + @echo NHkbhit >>nhraykey.def + @echo CheckInput >>nhraykey.def + @echo SourceWhere >>nhraykey.def + @echo SourceAuthor >>nhraykey.def + @echo KeyHandlerName >>nhraykey.def + @echo Linking $@ + $(link) $(linkdebug) /Gn /Gz /q -L$(bcclib) /c /aa /Tpd /V$(APPVER) -L$(bcclib) -v \ + c0d32.obj $(O)nhraykey.o, $@,nhraykey.map,$(libsmt),nhraykey.def + # # Secondary Targets. # diff -Naurd ../nethack-3.4.1/sys/winnt/Makefile.gcc ./sys/winnt/Makefile.gcc --- ../nethack-3.4.1/sys/winnt/Makefile.gcc Sun Feb 23 14:43:43 2003 +++ ./sys/winnt/Makefile.gcc Mon Sep 1 14:33:32 2003 @@ -1,4 +1,4 @@ -# SCCS Id: @(#)Makefile.gcc 3.4 $Date: 2003/02/19 14:20:47 $ +# SCCS Id: @(#)Makefile.gcc 3.4 $Date: 2003/05/18 18:53:57 $ # Copyright (c) NetHack PC Development Team 1993-2003 # # NetHack 3.4.x Makefile for MinGW @@ -47,7 +47,7 @@ rc = windres link = gcc -cflags = +cflags = -mms-bitfields lflags = ifeq "$(DEBUG)" "Y" cdebug = -g @@ -249,24 +249,24 @@ #========================================== $(OBJ)/%.o : /%.c - @$(cc) $(CFLAGS) -o$@ $< + $(cc) $(CFLAGS) -o$@ $< $(OBJ)/%.o : $(SRC)/%.c - @$(cc) $(CFLAGS) -o$@ $< + $(cc) $(CFLAGS) -o$@ $< #========================================== # Rules for files in sys/share #========================================== $(OBJ)/%.o : $(SSYS)/%.c - @$(cc) $(CFLAGS) -o$@ $< + $(cc) $(CFLAGS) -o$@ $< #========================================== # Rules for files in sys/winnt #========================================== $(OBJ)/%.o : $(NTSYS)/%.c - @$(cc) $(CFLAGS) -o$@ $< + $(cc) $(CFLAGS) -o$@ $< $(INCL)/%.h : $(NTSYS)/%.h @copy $< $@ @@ -276,14 +276,14 @@ #========================================== $(OBJ)/%.o : $(UTIL)/%.c - @$(cc) $(CFLAGSU) -o$@ $< + $(cc) $(CFLAGSU) -o$@ $< #========================================== # Rules for files in win/share #========================================== $(OBJ)/%.o : $(WSHR)/%.c - @$(cc) $(CFLAGS) -o$@ $< + $(cc) $(CFLAGS) -o$@ $< $(INCL)/%.h : $(WSHR)/%.h @copy $< $@ @@ -296,14 +296,14 @@ #========================================== $(OBJ)/%.o : $(TTY)/%.c - @$(cc) $(CFLAGS) -o$@ $< + $(cc) $(CFLAGS) -o$@ $< #========================================== # Rules for files in win/win32 #========================================== $(OBJ)/%.o : $(WIN32)/%.c - @$(cc) $(CFLAGS) -o$@ $< + $(cc) $(CFLAGS) -o$@ $< #========================================== #================ MACROS ================== @@ -346,7 +346,7 @@ TILEFILES = $(WSHR)/monsters.txt $(WSHR)/objects.txt $(WSHR)/other.txt # -# These are not invoked during a normal game build in 3.4.1 +# These are not invoked during a normal game build in 3.4 # TEXT_IO = $(O)tiletext.o $(O)tiletxt.o $(O)drawing.o \ $(O)decl.o $(O)monst.o $(O)objects.o @@ -422,25 +422,25 @@ #========================================== CONFIG_H = $(INCL)/config.h $(INCL)/config1.h $(INCL)/tradstdc.h \ - $(INCL)/global.h $(INCL)/coord.h $(INCL)/vmsconf.h \ - $(INCL)/system.h $(INCL)/unixconf.h $(INCL)/os2conf.h \ - $(INCL)/micro.h $(INCL)/pcconf.h $(INCL)/tosconf.h \ - $(INCL)/amiconf.h $(INCL)/macconf.h $(INCL)/beconf.h \ - $(INCL)/ntconf.h $(INCL)/nhlan.h + $(INCL)/global.h $(INCL)/coord.h $(INCL)/vmsconf.h \ + $(INCL)/system.h $(INCL)/unixconf.h $(INCL)/os2conf.h \ + $(INCL)/micro.h $(INCL)/pcconf.h $(INCL)/tosconf.h \ + $(INCL)/amiconf.h $(INCL)/macconf.h $(INCL)/beconf.h \ + $(INCL)/ntconf.h $(INCL)/nhlan.h HACK_H = $(INCL)/hack.h $(CONFIG_H) $(INCL)/align.h \ - $(INCL)/dungeon.h $(INCL)/monsym.h $(INCL)/mkroom.h \ - $(INCL)/objclass.h $(INCL)/youprop.h $(INCL)/prop.h \ - $(INCL)/permonst.h $(INCL)/monattk.h \ - $(INCL)/monflag.h $(INCL)/mondata.h $(INCL)/pm.h \ - $(INCL)/wintype.h $(INCL)/decl.h $(INCL)/quest.h \ - $(INCL)/spell.h $(INCL)/color.h $(INCL)/obj.h \ - $(INCL)/you.h $(INCL)/attrib.h $(INCL)/monst.h \ - $(INCL)/skills.h $(INCL)/onames.h $(INCL)/timeout.h \ - $(INCL)/trap.h $(INCL)/flag.h $(INCL)/rm.h \ - $(INCL)/vision.h $(INCL)/display.h $(INCL)/engrave.h \ - $(INCL)/rect.h $(INCL)/region.h $(INCL)/winprocs.h \ - $(INCL)/wintty.h $(INCL)/trampoli.h + $(INCL)/dungeon.h $(INCL)/monsym.h $(INCL)/mkroom.h \ + $(INCL)/objclass.h $(INCL)/youprop.h $(INCL)/prop.h \ + $(INCL)/permonst.h $(INCL)/monattk.h \ + $(INCL)/monflag.h $(INCL)/mondata.h $(INCL)/pm.h \ + $(INCL)/wintype.h $(INCL)/decl.h $(INCL)/quest.h \ + $(INCL)/spell.h $(INCL)/color.h $(INCL)/obj.h \ + $(INCL)/you.h $(INCL)/attrib.h $(INCL)/monst.h \ + $(INCL)/skills.h $(INCL)/onames.h $(INCL)/timeout.h \ + $(INCL)/trap.h $(INCL)/flag.h $(INCL)/rm.h \ + $(INCL)/vision.h $(INCL)/display.h $(INCL)/engrave.h \ + $(INCL)/rect.h $(INCL)/region.h $(INCL)/winprocs.h \ + $(INCL)/wintty.h $(INCL)/trampoli.h LEV_H = $(INCL)/lev.h DGN_FILE_H = $(INCL)/dgn_file.h @@ -494,7 +494,7 @@ $(O)install.tag: $(DAT)/data $(DAT)/rumors $(DAT)/dungeon \ - $(DAT)/oracles $(DAT)/quest.dat $(O)sp_lev.tag $(DLB) + $(DAT)/oracles $(DAT)/quest.dat $(O)sp_lev.tag $(DLB) ifeq "$(USE_DLB)" "Y" $(subst /,\,copy nhdat $(GAMEDIR)) $(subst /,\,copy $(DAT)/license $(GAMEDIR)) @@ -506,7 +506,7 @@ endif $(subst /,\,if exist $(DOC)/guidebook.txt copy $(DOC)/guidebook.txt $(GAMEDIR)/Guidebook.txt) $(subst /,\,if exist $(DOC)/nethack.txt copy $(DOC)/nethack.txt $(GAMEDIR)/NetHack.txt) - $(subst /,\,-copy $(NTSYS)/defaults.nh $(GAMEDIR)/defaults.nh) + $(subst /,\,copy $(NTSYS)/defaults.nh $(GAMEDIR)/defaults.nh) $(subst /,\,echo install done > $@) # copy $(NTSYS)/winnt.hlp $(GAMEDIR) @@ -516,45 +516,44 @@ $(subst /,\,if exist $(DOC)/recover.txt copy $(DOC)/recover.txt $(GAMEDIR)/recover.txt) $(O)sp_lev.tag: $(O)utility.tag $(DAT)/bigroom.des $(DAT)/castle.des \ - $(DAT)/endgame.des $(DAT)/gehennom.des $(DAT)/knox.des \ - $(DAT)/medusa.des $(DAT)/oracle.des $(DAT)/tower.des \ - $(DAT)/yendor.des $(DAT)/arch.des $(DAT)/barb.des \ - $(DAT)/caveman.des $(DAT)/healer.des $(DAT)/knight.des \ - $(DAT)/monk.des $(DAT)/priest.des $(DAT)/ranger.des \ - $(DAT)/rogue.des $(DAT)/samurai.des $(DAT)/sokoban.des \ - $(DAT)/tourist.des $(DAT)/valkyrie.des $(DAT)/wizard.des - $(subst /,\,cd $(DAT)) & \ - $(subst /,\,$(U)lev_comp bigroom.des) & \ - $(subst /,\,$(U)lev_comp castle.des) & \ - $(subst /,\,$(U)lev_comp endgame.des) & \ - $(subst /,\,$(U)lev_comp gehennom.des) & \ - $(subst /,\,$(U)lev_comp knox.des) & \ - $(subst /,\,$(U)lev_comp mines.des) & \ - $(subst /,\,$(U)lev_comp medusa.des) & \ - $(subst /,\,$(U)lev_comp oracle.des) & \ - $(subst /,\,$(U)lev_comp sokoban.des) & \ - $(subst /,\,$(U)lev_comp tower.des) & \ - $(subst /,\,$(U)lev_comp yendor.des) & \ - $(subst /,\,$(U)lev_comp arch.des) & \ - $(subst /,\,$(U)lev_comp barb.des) & \ - $(subst /,\,$(U)lev_comp caveman.des) & \ - $(subst /,\,$(U)lev_comp healer.des) & \ - $(subst /,\,$(U)lev_comp knight.des) & \ - $(subst /,\,$(U)lev_comp monk.des) & \ - $(subst /,\,$(U)lev_comp priest.des) & \ - $(subst /,\,$(U)lev_comp ranger.des) & \ - $(subst /,\,$(U)lev_comp rogue.des) & \ - $(subst /,\,$(U)lev_comp samurai.des) & \ - $(subst /,\,$(U)lev_comp tourist.des) & \ - $(subst /,\,$(U)lev_comp valkyrie.des) & \ - $(subst /,\,$(U)lev_comp wizard.des) & \ - $(subst /,\,cd $(SRC)) + $(DAT)/endgame.des $(DAT)/gehennom.des $(DAT)/knox.des \ + $(DAT)/medusa.des $(DAT)/oracle.des $(DAT)/tower.des \ + $(DAT)/yendor.des $(DAT)/arch.des $(DAT)/barb.des \ + $(DAT)/caveman.des $(DAT)/healer.des $(DAT)/knight.des \ + $(DAT)/monk.des $(DAT)/priest.des $(DAT)/ranger.des \ + $(DAT)/rogue.des $(DAT)/samurai.des $(DAT)/sokoban.des \ + $(DAT)/tourist.des $(DAT)/valkyrie.des $(DAT)/wizard.des + $(subst /,\,$(U)lev_comp $(DAT)/bigroom.des) + $(subst /,\,$(U)lev_comp $(DAT)/castle.des) + $(subst /,\,$(U)lev_comp $(DAT)/endgame.des) + $(subst /,\,$(U)lev_comp $(DAT)/gehennom.des) + $(subst /,\,$(U)lev_comp $(DAT)/knox.des) + $(subst /,\,$(U)lev_comp $(DAT)/mines.des) + $(subst /,\,$(U)lev_comp $(DAT)/medusa.des) + $(subst /,\,$(U)lev_comp $(DAT)/oracle.des) + $(subst /,\,$(U)lev_comp $(DAT)/sokoban.des) + $(subst /,\,$(U)lev_comp $(DAT)/tower.des) + $(subst /,\,$(U)lev_comp $(DAT)/yendor.des) + $(subst /,\,$(U)lev_comp $(DAT)/arch.des) + $(subst /,\,$(U)lev_comp $(DAT)/barb.des) + $(subst /,\,$(U)lev_comp $(DAT)/caveman.des) + $(subst /,\,$(U)lev_comp $(DAT)/healer.des) + $(subst /,\,$(U)lev_comp $(DAT)/knight.des) + $(subst /,\,$(U)lev_comp $(DAT)/monk.des) + $(subst /,\,$(U)lev_comp $(DAT)/priest.des) + $(subst /,\,$(U)lev_comp $(DAT)/ranger.des) + $(subst /,\,$(U)lev_comp $(DAT)/rogue.des) + $(subst /,\,$(U)lev_comp $(DAT)/samurai.des) + $(subst /,\,$(U)lev_comp $(DAT)/tourist.des) + $(subst /,\,$(U)lev_comp $(DAT)/valkyrie.des) + $(subst /,\,$(U)lev_comp $(DAT)/wizard.des) + $(subst /,\,copy *.lev $(DAT)) + $(subst /,\,del *.lev) $(subst /,\,echo sp_levs done > $(O)sp_lev.tag) $(O)utility.tag: $(INCL)/date.h $(INCL)/onames.h $(INCL)/pm.h \ - $(SRC)/monstr.c $(SRC)/vis_tab.c \ - $(U)lev_comp.exe $(INCL)/vis_tab.h \ - $(U)dgn_comp.exe $(TILEUTIL16) + $(SRC)/monstr.c $(SRC)/vis_tab.c $(U)lev_comp.exe $(INCL)/vis_tab.h \ + $(U)dgn_comp.exe $(TILEUTIL16) $(subst /,\,@echo utilities made >$@) @echo utilities made. @@ -563,9 +562,9 @@ ifeq "$(GRAPHICAL)" "Y" $(NHRES): $(TILEBMP16) $(WIN32)/winhack.rc $(WIN32)/mnsel.bmp \ - $(WIN32)/mnselcnt.bmp $(WIN32)/mnunsel.bmp \ - $(WIN32)/petmark.bmp $(WIN32)/NetHack.ico $(WIN32)/rip.bmp \ - $(WIN32)/splash.bmp + $(WIN32)/mnselcnt.bmp $(WIN32)/mnunsel.bmp \ + $(WIN32)/petmark.bmp $(WIN32)/NetHack.ico $(WIN32)/rip.bmp \ + $(WIN32)/splash.bmp @$(rc) -o$@ --include-dir $(WIN32) -i $(WIN32)/winhack.rc else $(NHRES): $(NTSYS)/console.rc $(NTSYS)/NetHack.ico @@ -575,12 +574,46 @@ #========================================== # The main target. #========================================== +$(O)gamedir.tag: + $(subst /,\,@if not exist $(GAMEDIR)/*.* echo creating directory $(GAMEDIR)) + $(subst /,\,@if not exist $(GAMEDIR)/*.* mkdir $(GAMEDIR)) + $(subst /,\,@echo directory created > $@) -$(GAMEFILE) : $(ALLOBJ) $(NHRES) +ifeq "$(GRAPHICAL)" "Y" +$(GAMEFILE) : $(ALLOBJ) $(NHRES) $(O)gamedir.tag +else +$(GAMEFILE) : $(ALLOBJ) $(NHRES) $(O)gamedir.tag \ + $(GAMEDIR)/nhdefkey.dll $(GAMEDIR)/nh340key.dll $(GAMEDIR)/nhraykey.dll +endif @echo Linking.... @$(link) $(lflags) -o$@ $(ALLOBJ) $(NHRES) $(WINPLIBS) $(subst /,\,@if exist $(O)install.tag del $(O)install.tag) + +$(O)nhdefkey.o: + $(cc) $(CFLAGS) -DBUILD_DLL -o$@ $(NTSYS)/nhdefkey.c + +$(GAMEDIR)/nhdefkey.dll : $(O)nhdefkey.o $(O)gamedir.tag + @echo Linking $@ + $(cc) -shared -Wl,--export-all-symbols \ + -Wl,--add-stdcall-alias -o $@ $< + +$(O)nh340key.o: + $(cc) $(CFLAGS) -DBUILD_DLL -o$@ $(NTSYS)/nh340key.c + +$(GAMEDIR)/nh340key.dll : $(O)nh340key.o $(O)gamedir.tag + @echo Linking $@ + $(cc) -shared -Wl,--export-all-symbols \ + -Wl,--add-stdcall-alias -o $@ $< + +$(O)nhraykey.o: + $(cc) $(CFLAGS) -DBUILD_DLL -o$@ $(NTSYS)/nhraykey.c + +$(GAMEDIR)/nhraykey.dll : $(O)nhraykey.o $(O)gamedir.tag + @echo Linking $@ + $(cc) -shared -Wl,--export-all-symbols \ + -Wl,--add-stdcall-alias -o $@ $< + $(GAME)_.ico : $(NTSYS)/$(GAME).ico $(subst /,\,@copy $(NTSYS)/$(GAME).ico $@) @@ -607,11 +640,10 @@ $(U)makedefs.exe: $(MAKEOBJS) @$(link) $(LFLAGSU) -o$@ $(MAKEOBJS) -$(O)makedefs.o: $(CONFIG_H) $(INCL)/monattk.h $(INCL)/monflag.h $(INCL)/objclass.h \ - $(INCL)/monsym.h $(INCL)/qtext.h $(INCL)/patchlevel.h \ - $(U)makedefs.c - $(subst /,\,@if not exist $(O)*.* mkdir $(OBJ)) - @$(cc) $(CFLAGSU) -o$@ $(U)makedefs.c +$(O)makedefs.o: $(CONFIG_H) $(INCL)/monattk.h $(INCL)/monflag.h \ + $(INCL)/objclass.h $(INCL)/monsym.h $(INCL)/qtext.h \ + $(INCL)/patchlevel.h $(U)makedefs.c $(O)obj.tag + $(cc) $(CFLAGSU) -o$@ $(U)makedefs.c # # date.h should be remade every time any of the source or include @@ -652,44 +684,42 @@ $(O)uudecode.o: $(SSYS)/uudecode.c $(NTSYS)/NetHack.ico : $(U)uudecode.exe $(NTSYS)/nhico.uu - $(subst /,\,chdir $(NTSYS)) & \ - $(subst /,\,..\..\util\uudecode.exe nhico.uu) & \ - $(subst /,\,chdir ..\..\src) + $(subst /,\,$(U)uudecode.exe $(NTSYS)/nhico.uu) + $(subst /,\,copy NetHack.ico $@) + del NetHack.ico -$(WIN32)/NetHack.ico : $(U)uudecode.exe $(NTSYS)/nhico.uu - $(subst /,\,chdir $(WIN32)) & \ - $(subst /,\,..\..\util\uudecode.exe ../../sys/winnt/nhico.uu) & \ - $(subst /,\,chdir ..\..\src) +$(WIN32)/NetHack.ico : $(NTSYS)/NetHack.ico + $(subst /,\,copy $< $@) $(WIN32)/mnsel.bmp: $(U)uudecode.exe $(WIN32)/mnsel.uu - $(subst /,\,chdir $(WIN32)) & \ - $(subst /,\,..\..\util\uudecode.exe mnsel.uu) & \ - $(subst /,\,chdir ..\..\src) + $(subst /,\,$(U)uudecode.exe $(WIN32)/mnsel.uu) + $(subst /,\,copy mnsel.bmp $@) + del mnsel.bmp $(WIN32)/mnselcnt.bmp: $(U)uudecode.exe $(WIN32)/mnselcnt.uu - $(subst /,\,chdir $(WIN32)) & \ - $(subst /,\,..\..\util\uudecode.exe mnselcnt.uu) & \ - $(subst /,\,chdir ..\..\src) + $(subst /,\,$(U)uudecode.exe $(WIN32)/mnselcnt.uu) + $(subst /,\,copy mnselcnt.bmp $@) + del mnselcnt.bmp $(WIN32)/mnunsel.bmp: $(U)uudecode.exe $(WIN32)/mnunsel.uu - $(subst /,\,chdir $(WIN32)) & \ - $(subst /,\,..\..\util\uudecode.exe mnunsel.uu) & \ - $(subst /,\,chdir ..\..\src) + $(subst /,\,$(U)uudecode.exe $(WIN32)/mnunsel.uu) + $(subst /,\,copy mnunsel.bmp $@) + del mnunsel.bmp $(WIN32)/petmark.bmp: $(U)uudecode.exe $(WIN32)/petmark.uu - $(subst /,\,chdir $(WIN32)) & \ - $(subst /,\,..\..\util\uudecode.exe petmark.uu) & \ - $(subst /,\,chdir ..\..\src) + $(subst /,\,$(U)uudecode.exe $(WIN32)/petmark.uu) + $(subst /,\,copy petmark.bmp $@) + del petmark.bmp $(WIN32)/rip.bmp: $(U)uudecode.exe $(WIN32)/rip.uu - $(subst /,\,chdir $(WIN32)) & \ - $(subst /,\,..\..\util\uudecode.exe rip.uu) & \ - $(subst /,\,chdir ..\..\src) + $(subst /,\,$(U)uudecode.exe $(WIN32)/rip.uu) + $(subst /,\,copy rip.bmp $@) + del rip.bmp $(WIN32)/splash.bmp: $(U)uudecode.exe $(WIN32)/splash.uu - $(subst /,\,chdir $(WIN32)) & \ - $(subst /,\,..\..\util\uudecode.exe splash.uu) & \ - $(subst /,\,chdir ..\..\src) + $(subst /,\,$(U)uudecode.exe $(WIN32)/splash.uu) + $(subst /,\,copy splash.bmp $@) + del splash.bmp #========================================== @@ -703,25 +733,24 @@ @$(link) $(LFLAGSU) -o$@ $(SPLEVOBJS) $(O)lev_yacc.o: $(HACK_H) $(SP_LEV_H) $(INCL)/lev_comp.h $(U)lev_yacc.c - @$(cc) $(LEVCFLAGS) -o$@ $(U)lev_yacc.c + $(cc) $(LEVCFLAGS) -o$@ $(U)lev_yacc.c $(O)lev_$(LEX).o: $(HACK_H) $(INCL)/lev_comp.h $(SP_LEV_H) \ $(U)lev_$(LEX).c - @$(cc) $(LEVCFLAGS) -o$@ $(U)lev_$(LEX).c + $(cc) $(LEVCFLAGS) -o$@ $(U)lev_$(LEX).c $(O)lev_main.o: $(U)lev_main.c $(HACK_H) $(SP_LEV_H) - @$(cc) $(LEVCFLAGS) -o$@ $(U)lev_main.c + $(cc) $(LEVCFLAGS) -o$@ $(U)lev_main.c $(U)lev_yacc.c $(INCL)/lev_comp.h : $(U)lev_comp.y ifeq "$(DO_YACC)" "YACC_ACT" - $(subst /,\,chdir $(UTIL)) & \ - $(subst /,\,$(YACC) -d lev_comp.y) & \ - $(subst /,\,copy $(YTABC) lev_yacc.c) & \ - $(subst /,\,copy $(YTABH) $(INCL)/lev_comp.h) & \ - $(subst /,\,@del $(YTABC)) & \ - $(subst /,\,@del $(YTABH)) & \ - $(subst /,\,chdir $(SRC)) + $(subst /,\,$(YACC) -d $(U)lev_comp.y) + $(subst /,\,copy $(YTABC) $(U)lev_yacc.c) + $(subst /,\,copy $(YTABH) $(INCL)/lev_comp.h) + $(subst /,\,@del $(YTABC)) + $(subst /,\,@del $(YTABH)) + else @echo $(U)lev_comp.y has changed. @echo To update $(U)lev_yacc.c and $(INCL)/lev_comp.h run $(YACC). @@ -736,11 +765,9 @@ $(U)lev_$(LEX).c: $(U)lev_comp.l ifeq "$(DO_LEX)" "LEX_ACT" - $(subst /,\,chdir $(UTIL)) & \ - $(subst /,\,$(LEX) $(FLEXSKEL) lev_comp.l) & \ - $(subst /,\,copy $(LEXYYC) $@) & \ - $(subst /,\,@del $(LEXYYC)) & \ - $(subst /,\,chdir $(SRC)) + $(subst /,\,$(LEX) $(FLEXSKEL) $(U)lev_comp.l) + $(subst /,\,copy $(LEXYYC) $@) + $(subst /,\,@del $(LEXYYC)) else @echo $(U)lev_comp.l has changed. To update $@ run $(LEX). @echo --- @@ -760,24 +787,22 @@ $(O)dgn_yacc.o: $(HACK_H) $(DGN_FILE_H) $(INCL)/dgn_comp.h $(U)dgn_yacc.c - @$(cc) $(LEVCFLAGS) -o$@ $(U)dgn_yacc.c + $(cc) $(LEVCFLAGS) -o$@ $(U)dgn_yacc.c $(O)dgn_$(LEX).o: $(HACK_H) $(DGN_FILE_H) $(INCL)/dgn_comp.h \ - $(U)dgn_$(LEX).c - @$(cc) $(LEVCFLAGS) -o$@ $(U)dgn_$(LEX).c + $(U)dgn_$(LEX).c + $(cc) $(LEVCFLAGS) -o$@ $(U)dgn_$(LEX).c $(O)dgn_main.o: $(HACK_H) $(U)dgn_main.c - @$(cc) $(LEVCFLAGS) -o$@ $(U)dgn_main.c + $(cc) $(LEVCFLAGS) -o$@ $(U)dgn_main.c $(U)dgn_yacc.c $(INCL)/dgn_comp.h : $(U)dgn_comp.y ifeq "$(DO_YACC)" "YACC_ACT" - $(subst /,\,chdir $(UTIL)) & \ - $(subst /,\,$(YACC) -d dgn_comp.y) & \ - $(subst /,\,copy $(YTABC) dgn_yacc.c) & \ - $(subst /,\,copy $(YTABH) $(INCL)/dgn_comp.h) & \ - $(subst /,\,@del $(YTABC)) & \ - $(subst /,\,@del $(YTABH)) & \ - $(subst /,\,chdir $(SRC)) + $(subst /,\,$(YACC) -d $(U)dgn_comp.y) + $(subst /,\,copy $(YTABC) $(U)dgn_yacc.c) + $(subst /,\,copy $(YTABH) $(INCL)/dgn_comp.h) + $(subst /,\,@del $(YTABC)) + $(subst /,\,@del $(YTABH)) else @echo $(U)dgn_comp.y has changed. To update dgn_yacc.c and @echo $(INCL)/dgn_comp.h run $(YACC). @@ -786,24 +811,22 @@ @echo dgn_comp.h from $(SSYS) into $(UTIL) and use them. $(subst /,\,@copy $(SSYS)/dgn_yacc.c $(U)dgn_yacc.c >nul) $(subst /,\,@copy $(SSYS)/dgn_comp.h $(INCL)/dgn_comp.h >nul) - @$(subst /,\,echo.>>$(U)dgn_yacc.c) - @$(subst /,\,echo.>>$(INCL)/dgn_comp.h) + $(subst /,\,echo.>>$(U)dgn_yacc.c) + $(subst /,\,echo.>>$(INCL)/dgn_comp.h) endif $(U)dgn_$(LEX).c: $(U)dgn_comp.l ifeq "$(DO_LEX)" "LEX_ACT" - $(subst /,\,chdir $(UTIL)) & \ - $(subst /,\,$(LEX) $(FLEXSKEL) dgn_comp.l) & \ - $(subst /,\,copy $(LEXYYC) $@) & \ - $(subst /,\,@del $(LEXYYC)) & \ - chdir $(SRC) + $(subst /,\,$(LEX) $(FLEXSKEL) $(U)dgn_comp.l) + $(subst /,\,copy $(LEXYYC) $@) + $(subst /,\,@del $(LEXYYC)) else @echo $(U)dgn_comp.l has changed. To update $@ run $(LEX). @echo --- @echo For now, we will copy the prebuilt dgn_lex.c @echo from $(SSYS) into $(UTIL) and use it. $(subst /,\,@copy $(SSYS)/dgn_lex.c $@ >nul) - @$(subst /,\,echo.>>$@) + $(subst /,\,echo.>>$@) endif #========================================== @@ -837,38 +860,36 @@ $(O)dlb.o: $(O)dlb_main.o $(O)alloc.o $(O)panic.o $(INCL)/dlb.h - @$(cc) $(CFLAGS) -o$@ $(SRC)/dlb.c + $(cc) $(CFLAGS) -o$@ $(SRC)/dlb.c $(O)dlb_main.o: $(UTIL)/dlb_main.c $(INCL)/config.h $(INCL)/dlb.h - @$(cc) $(CFLAGS) -o$@ $(UTIL)/dlb_main.c + $(cc) $(CFLAGS) -o$@ $(UTIL)/dlb_main.c $(DAT)/porthelp: $(NTSYS)/porthelp $(subst /,\,@copy $(NTSYS)/porthelp $@ >nul) nhdat: $(U)dlb_main.exe $(DAT)/data $(DAT)/oracles $(OPTIONS_FILE) \ - $(DAT)/quest.dat $(DAT)/rumors $(DAT)/help $(DAT)/hh $(DAT)/cmdhelp \ - $(DAT)/history $(DAT)/opthelp $(DAT)/wizhelp $(DAT)/dungeon $(DAT)/porthelp \ - $(DAT)/license $(O)sp_lev.tag - $(subst /,\,cd $(DAT)) & \ - echo data >dlb.lst & \ - echo oracles >>dlb.lst & \ - (if exist options echo options >>dlb.lst) & \ - (if exist ttyoptions echo ttyoptions >>dlb.lst) & \ - (if exist guioptions echo guioptions >>dlb.lst) & \ - (if exist porthelp echo porthelp >>dlb.lst) & \ - echo quest.dat >>dlb.lst & \ - echo rumors >>dlb.lst & \ - echo help >>dlb.lst & \ - echo hh >>dlb.lst & \ - echo cmdhelp >>dlb.lst & \ - echo history >>dlb.lst & \ - echo opthelp >>dlb.lst & \ - echo wizhelp >>dlb.lst & \ - echo dungeon >>dlb.lst & \ - echo license >>dlb.lst & \ - (for %%N in (*.lev) do echo %%N >>dlb.lst) & \ - $(subst /,\,$(U)dlb_main cIf dlb.lst $(SRC)/nhdat) & \ - $(subst /,\,cd $(SRC)) + $(DAT)/quest.dat $(DAT)/rumors $(DAT)/help $(DAT)/hh $(DAT)/cmdhelp \ + $(DAT)/history $(DAT)/opthelp $(DAT)/wizhelp $(DAT)/dungeon \ + $(DAT)/porthelp $(DAT)/license $(O)sp_lev.tag + $(subst /,\,echo data >$(DAT)/dlb.lst) + $(subst /,\,echo oracles >>$(DAT)/dlb.lst) + $(subst /,\,if exist $(DAT)/options echo options >>$(DAT)/dlb.lst) + $(subst /,\,if exist $(DAT)/ttyoptions echo ttyoptions >>$(DAT)/dlb.lst) + $(subst /,\,if exist $(DAT)/guioptions echo guioptions >>$(DAT)/dlb.lst) + $(subst /,\,if exist $(DAT)/porthelp echo porthelp >>$(DAT)/dlb.lst) + $(subst /,\,echo quest.dat >>$(DAT)/dlb.lst) + $(subst /,\,echo rumors >>$(DAT)/dlb.lst) + $(subst /,\,echo help >>$(DAT)/dlb.lst) + $(subst /,\,echo hh >>$(DAT)/dlb.lst) + $(subst /,\,echo cmdhelp >>$(DAT)/dlb.lst) + $(subst /,\,echo history >>$(DAT)/dlb.lst) + $(subst /,\,echo opthelp >>$(DAT)/dlb.lst) + $(subst /,\,echo wizhelp >>$(DAT)/dlb.lst) + $(subst /,\,echo dungeon >>$(DAT)/dlb.lst) + $(subst /,\,echo license >>$(DAT)/dlb.lst) + dir /l /b /-p $(subst /,\,$(DAT)/*.lev >>$(DAT)/dlb.lst) + $(subst /,\,$(U)dlb_main CcIf $(DAT) dlb.lst $(SRC)/nhdat) #========================================== # Recover Utility @@ -892,28 +913,28 @@ @$(link) $(LFLAGSU) -o$@ $(O)tilemap.o $(O)tilemap.o: $(WSHR)/tilemap.c $(HACK_H) - @$(cc) $(CFLAGSU) -o$@ $(WSHR)/tilemap.c + $(cc) $(CFLAGSU) -o$@ $(WSHR)/tilemap.c $(O)tiletx32.o: $(WSHR)/tilemap.c $(HACK_H) - @$(CC) $(CFLAGS) -DTILETEXT -DTILE_X=32 -DTILE_Y=32 -o$@ $(WSHR)\tilemap.c + $(cc) $(CFLAGS) -DTILETEXT -DTILE_X=32 -DTILE_Y=32 -o$@ $(WSHR)/tilemap.c $(O)tiletxt.o: $(WSHR)/tilemap.c $(HACK_H) - @$(cc) $(CFLAGS) -DTILETEXT -o$@ $(WSHR)/tilemap.c + $(cc) $(CFLAGS) -DTILETEXT -o$@ $(WSHR)/tilemap.c $(O)gifread.o: $(WSHR)/gifread.c $(CONFIG_H) $(TILE_H) - @$(cc) $(CFLAGS) -I$(WSHR) -o$@ $(WSHR)/gifread.c + $(cc) $(CFLAGS) -I$(WSHR) -o$@ $(WSHR)/gifread.c $(O)gifrd32.o: $(WSHR)/gifread.c $(CONFIG_H) $(TILE_H) - @$(CC) $(CFLAGS) -I$(WSHR) -DTILE_X=32 -DTILE_Y=32 -o$@ $(WSHR)/gifread.c + $(cc) $(CFLAGS) -I$(WSHR) -DTILE_X=32 -DTILE_Y=32 -o$@ $(WSHR)/gifread.c $(O)ppmwrite.o: $(WSHR)/ppmwrite.c $(CONFIG_H) $(TILE_H) - @$(cc) $(CFLAGS) -I$(WSHR) -o$@ $(WSHR)/ppmwrite.c + $(cc) $(CFLAGS) -I$(WSHR) -o$@ $(WSHR)/ppmwrite.c $(O)tiletext.o: $(WSHR)/tiletext.c $(CONFIG_H) $(TILE_H) - @$(cc) $(CFLAGS) -I$(WSHR) -o$@ $(WSHR)/tiletext.c + $(cc) $(CFLAGS) -I$(WSHR) -o$@ $(WSHR)/tiletext.c $(O)tilete32.o: $(WSHR)/tiletext.c $(CONFIG_H) $(TILE_H) - @$(CC) $(CFLAGS) -I$(WSHR) -DTILE_X=32 -DTILE_Y=32 -o$@ $(WSHR)/tiletext.c + $(cc) $(CFLAGS) -I$(WSHR) -DTILE_X=32 -DTILE_Y=32 -o$@ $(WSHR)/tiletext.c #========================================== # Optional Tile Utilities @@ -938,8 +959,8 @@ @echo Creating 16x16 binary tile files (this may take some time) $(subst /,\,@$(U)tile2bmp $(TILEBMP16)) #$(TILEBMP32): $(TILEUTIL32) $(TILEFILES32) -# @echo Creating 32x32 binary tile files (this may take some time) -# $(subst /,\,@$(U)til2bm32 $(TILEBMP32)) +# @echo Creating 32x32 binary tile files (this may take some time) +# $(subst /,\,@$(U)til2bm32 $(TILEBMP32)) else $(TILEBMP16): $(TILEBMP32): @@ -954,19 +975,16 @@ @$(link) $(LFLAGSU) -o$@ $(O)til2bm32.o $(TEXT_IO32) $(O)tile2bmp.o: $(WSHR)/tile2bmp.c $(HACK_H) $(TILE_H) $(INCL)/win32api.h - @$(cc) $(CFLAGS) -I$(WSHR) -o$@ $(WSHR)/tile2bmp.c + $(cc) $(CFLAGS) -I$(WSHR) -o$@ $(WSHR)/tile2bmp.c $(O)til2bm32.o: $(WSHR)/til2bm32.c $(HACK_H) $(TILE_H) $(INCL)/win32api.h - @$(cc) $(CFLAGS) -I$(WSHR) -DTILE_X=32 -DTILE_Y=32 -o$@ $(WSHR)/til2bm32.c + $(cc) $(CFLAGS) -I$(WSHR) -DTILE_X=32 -DTILE_Y=32 -o$@ $(WSHR)/til2bm32.c #========================================== # Housekeeping #========================================== spotless: clean -ifneq "$(OBJ)" "" - -rmdir $(OBJ) /s /Q -endif $(subst /,\,if exist graphicschk del graphicschk) $(subst /,\,if exist $(INCL)/date.h del $(INCL)/date.h) $(subst /,\,if exist $(INCL)/onames.h del $(INCL)/onames.h) @@ -1018,6 +1036,12 @@ $(subst /,\,if exist $(U)recover.exe del $(U)recover.exe) $(subst /,\,if exist $(DAT)/dlb.lst del $(DAT)/dlb.lst) $(subst /,\,if exist nhdat. del nhdat.) + $(subst /,\,if exist $(O)install.tag del $(O)install.tag) + $(subst /,\,if exist $(O)obj.tag del $(O)obj.tag) + $(subst /,\,if exist $(O)gamedir.tag del $(O)gamedir.tag) +ifneq "$(OBJ)" "" + $(subst /,\,rmdir $(OBJ)) /s /Q +endif clean: $(subst /,\,if exist $(O)*.o del $(O)*.o) @@ -1052,29 +1076,27 @@ $(DAT)/dungeon: $(O)utility.tag $(DAT)/dungeon.def $(subst /,\,$(U)makedefs -e) - $(subst /,\,cd $(DAT)) & \ - $(subst /,\,$(U)dgn_comp dungeon.pdf) & \ - $(subst /,\,cd $(SRC)) + $(subst /,\,$(U)dgn_comp $(DAT)/dungeon.pdf) # # NT dependencies # $(O)nttty.o: $(HACK_H) $(TILE_H) $(INCL)/win32api.h $(NTSYS)/nttty.c - @$(cc) $(CFLAGS) -I$(WSHR) -o$@ $(NTSYS)/nttty.c + $(cc) $(CFLAGS) -I$(WSHR) -o$@ $(NTSYS)/nttty.c $(O)winnt.o: $(HACK_H) $(INCL)/win32api.h $(NTSYS)/winnt.c - @$(cc) $(CFLAGS) -o$@ $(NTSYS)/winnt.c + $(cc) $(CFLAGS) -o$@ $(NTSYS)/winnt.c $(O)ntsound.o: $(HACK_H) $(NTSYS)/ntsound.c - @$(cc) $(CFLAGS) -o$@ $(NTSYS)/ntsound.c + $(cc) $(CFLAGS) -o$@ $(NTSYS)/ntsound.c $(O)mapimail.o: $(HACK_H) $(INCL)/nhlan.h $(NTSYS)/mapimail.c - @$(cc) $(CFLAGS) -DMAPI_VERBOSE -o$@ $(NTSYS)/mapimail.c + $(cc) $(CFLAGS) -DMAPI_VERBOSE -o$@ $(NTSYS)/mapimail.c # # util dependencies # $(O)panic.o: $(U)panic.c $(CONFIG_H) - @$(cc) $(CFLAGS) -o$@ $(U)panic.c + $(cc) $(CFLAGS) -o$@ $(U)panic.c # # The rest are stolen from sys/unix/Makefile.src, diff -Naurd ../nethack-3.4.1/sys/winnt/Makefile.msc ./sys/winnt/Makefile.msc --- ../nethack-3.4.1/sys/winnt/Makefile.msc Sun Feb 23 14:43:43 2003 +++ ./sys/winnt/Makefile.msc Mon Sep 1 14:33:32 2003 @@ -1,4 +1,4 @@ -# SCCS Id: @(#)Makefile.msc 3.4 $Date: 2003/02/19 14:20:47 $ +# SCCS Id: @(#)Makefile.msc 3.4 $Date: 2003/06/06 02:01:49 $ # Copyright (c) NetHack PC Development Team 1993-2003 # # NetHack 3.4.x Makefile for MS Visual C++ V6.x and above and MS NMAKE @@ -23,8 +23,6 @@ # # If you have any questions read the sys/winnt/Install.nt file included # with the distribution. -# -- -# Michael Allison #============================================================================== # Do not delete the following 3 lines. # @@ -139,23 +137,25 @@ ################################################ !IF "$(GRAPHICAL)" == "Y" -WINPORT = $(O)tile.o $(O)mhaskyn.o $(O)mhdlg.o \ +WINPORT = $(O)tile.o $(O)mhaskyn.o $(O)mhdlg.o \ $(O)mhfont.o $(O)mhinput.o $(O)mhmain.o $(O)mhmap.o \ $(O)mhmenu.o $(O)mhmsgwnd.o $(O)mhrip.o $(O)mhsplash.o \ $(O)mhstatus.o $(O)mhtext.o $(O)mswproc.o $(O)winhack.o -WINPFLAG = -DTILES -DMSWIN_GRAPHICS -NHRES = $(O)winhack.res -WINPINC = -I$(WIN32) -WINPHDR = $(WIN32)\mhaskyn.h $(WIN32)\mhdlg.h $(WIN32)\mhfont.h \ +WINPHDR = $(WIN32)\mhaskyn.h $(WIN32)\mhdlg.h $(WIN32)\mhfont.h \ $(WIN32)\mhinput.h $(WIN32)\mhmain.h $(WIN32)\mhmap.h $(WIN32)\mhmenu.h \ $(WIN32)\mhmsg.h $(WIN32)\mhmsgwnd.h $(WIN32)\mhrip.h $(WIN32)\mhstatus.h \ $(WIN32)\mhtext.h $(WIN32)\resource.h $(WIN32)\winMS.h +WINDLLS = +WINPFLAG= -DTILES -DMSWIN_GRAPHICS +NHRES = $(O)winhack.res +WINPINC = -I$(WIN32) !ELSE -WINPORT = $(O)nttty.o -WINPFLAG = -DWIN32CON -WINPHDR = -NHRES = $(O)console.res -WINPINC = +WINPORT = $(O)nttty.o +WINPHDR = +WINDLLS = $(GAMEDIR)\nhdefkey.dll $(GAMEDIR)\nh340key.dll $(GAMEDIR)\nhraykey.dll +WINPFLAG= -DWIN32CON +NHRES = $(O)console.res +WINPINC = !ENDIF TILEUTIL16 = $(UTIL)\tile2bmp.exe @@ -326,7 +326,7 @@ TILEFILES = $(WSHR)\monsters.txt $(WSHR)\objects.txt $(WSHR)\other.txt # -# These are not invoked during a normal game build in 3.4.1 +# These are not invoked during a normal game build in 3.4 # TEXT_IO = $(O)tiletext.o $(O)tiletxt.o $(O)drawing.o \ $(O)decl.o $(O)monst.o $(O)objects.o @@ -574,7 +574,7 @@ # DO NOT INDENT THE << below! # -$(GAMEFILE) : $(ALLOBJ) $(NHRES) +$(GAMEFILE) : $(ALLOBJ) $(NHRES) $(O)gamedir.tag $(WINDLLS) @if not exist $(GAMEDIR)\*.* mkdir $(GAMEDIR) @echo Linking.... $(link) $(LFLAGS) user32.lib winmm.lib -out:$@ @<<$(GAME).lnk @@ -584,6 +584,56 @@ @if exist $(O)install.tag del $(O)install.tag @if exist $(GAMEDIR)\$(GAME).bak del $(GAMEDIR)\$(GAME).bak +$(O)gamedir.tag: + @if not exist $(GAMEDIR)\*.* echo creating directory $(GAMEDIR) + @if not exist $(GAMEDIR)\*.* mkdir $(GAMEDIR) + @echo directory created > $@ + +$(O)nhdefkey.def: + @echo EXPORTS >$@ + @echo ProcessKeystroke >>$@ + @echo NHkbhit >>$@ + @echo CheckInput >>$@ + @echo SourceWhere >>$@ + @echo SourceAuthor >>$@ + @echo KeyHandlerName >>$@ + +$(GAMEDIR)\nhdefkey.dll : $(O)$(@B).o $(O)gamedir.tag $(O)$(@B).def + @echo Linking $@ + @$(link) -debug:full -debugtype:cv /RELEASE /NOLOGO /DLL user32.lib \ + /PDB:"$(@B).PDB" /MAP:"$(@B).map" /DEF:$(O)$(@B).def \ + /IMPLIB:$(O)$(@B).lib -out:$@ $(O)$(@B).o + +$(O)nh340key.def: + @echo EXPORTS >$@ + @echo ProcessKeystroke >>$@ + @echo NHkbhit >>$@ + @echo CheckInput >>$@ + @echo SourceWhere >>$@ + @echo SourceAuthor >>$@ + @echo KeyHandlerName >>$@ + +$(GAMEDIR)\nh340key.dll : $(O)$(@B).o $(O)gamedir.tag $(O)$(@B).def + @echo Linking $@ + @$(link) -debug:full -debugtype:cv /RELEASE /NOLOGO /DLL user32.lib \ + /PDB:"$(@B).PDB" /MAP:"$(@B).map" /DEF:$(O)$(@B).def \ + /IMPLIB:$(O)$(@B).lib -out:$@ $(O)$(@B).o + +$(O)nhraykey.def: + @echo EXPORTS >$@ + @echo ProcessKeystroke >>$@ + @echo NHkbhit >>$@ + @echo CheckInput >>$@ + @echo SourceWhere >>$@ + @echo SourceAuthor >>$@ + @echo KeyHandlerName >>$@ + +$(GAMEDIR)\nhraykey.dll : $(O)$(@B).o $(O)gamedir.tag $(O)$(@B).def + @echo Linking $@ + @$(link) -debug:full -debugtype:cv /RELEASE /NOLOGO /DLL user32.lib \ + /PDB:"$(@B).PDB" /MAP:"$(@B).map" /DEF:$(O)$(@B).def \ + /IMPLIB:$(O)$(@B).lib -out:$@ $(O)$(@B).o + # # Secondary Targets. # @@ -1049,6 +1099,10 @@ if exist $(SRC)\vis_tab.c del $(SRC)\vis_tab.c if exist $(U)recover.exe del $(U)recover.exe if exist nhdat. del nhdat. + if exist $(O)obj.tag del $(O)obj.tag + if exist $(O)gamedir.tag del $(O)gamedir.tag + if exist $(O)nh*key.lib del $(O)nh*key.lib + if exist $(O)nh*key.exp del $(O)nh*key.exp clean: if exist $(O)*.o del $(O)*.o @@ -1058,6 +1112,7 @@ if exist $(U)dgn_comp.exe del $(U)dgn_comp.exe if exist $(SRC)\*.lnk del $(SRC)\*.lnk if exist $(SRC)\*.map del $(SRC)\*.map + if exist $(O)install.tag del $(O)install.tag ! IF ("$(WINPFLAG)"!="") if exist $(TILEBMP16) del $(TILEBMP16) if exist $(TILEBMP32) del $(TILEBMP32) @@ -1094,20 +1149,22 @@ # $(O)nttty.o: $(HACK_H) $(TILE_H) $(INCL)\win32api.h $(NTSYS)\nttty.c - @@$(CC) $(CFLAGS) -I$(WSHR) -Fo$@ $(NTSYS)\nttty.c + @$(CC) $(CFLAGS) -I$(WSHR) -Fo$@ $(NTSYS)\nttty.c +$(O)nhkeys.o: $(HACK_H) $(TILE_H) $(INCL)\win32api.h $(NTSYS)\nhkeys.c + @$(CC) $(CFLAGS) -I$(WSHR) -Fo$@ $(NTSYS)\nhkeys.c $(O)winnt.o: $(HACK_H) $(INCL)\win32api.h $(NTSYS)\winnt.c - @@$(CC) $(CFLAGS) -Fo$@ $(NTSYS)\winnt.c + @$(CC) $(CFLAGS) -Fo$@ $(NTSYS)\winnt.c $(O)ntsound.o: $(HACK_H) $(NTSYS)\ntsound.c - @@$(CC) $(CFLAGS) -Fo$@ $(NTSYS)\ntsound.c + @$(CC) $(CFLAGS) -Fo$@ $(NTSYS)\ntsound.c $(O)mapimail.o: $(HACK_H) $(INCL)\nhlan.h $(NTSYS)\mapimail.c - @@$(CC) $(CFLAGS) -DMAPI_VERBOSE -Fo$@ $(NTSYS)\mapimail.c + @$(CC) $(CFLAGS) -DMAPI_VERBOSE -Fo$@ $(NTSYS)\mapimail.c # # util dependencies # $(O)panic.o: $(U)panic.c $(CONFIG_H) - @@$(CC) $(CFLAGS) -Fo$@ $(U)panic.c + @$(CC) $(CFLAGS) -Fo$@ $(U)panic.c # # The rest are stolen from sys/unix/Makefile.src, @@ -1179,7 +1236,7 @@ @$(CC) $(CFLAGS) -Fo$@ ..\win\X11\wintext.c $(O)winval.o: ..\win\X11\winval.c $(HACK_H) $(INCL)\winX.h @$(CC) $(CFLAGS) -Fo$@ ..\win\X11\winval.c -$(O)tile.o: tile.c $(HACK_H) +$(O)tile.o: $(SRC)\tile.c $(HACK_H) $(O)gnaskstr.o: ..\win\gnome\gnaskstr.c ..\win\gnome\gnaskstr.h \ ..\win\gnome\gnmain.h @$(CC) $(CFLAGS) $(GNOMEINC) -Fo$@ ..\win\gnome\gnaskstr.c diff -Naurd ../nethack-3.4.1/sys/winnt/nh340key.c ./sys/winnt/nh340key.c --- ../nethack-3.4.1/sys/winnt/nh340key.c Thu Jan 1 01:00:00 1970 +++ ./sys/winnt/nh340key.c Mon Sep 1 14:33:32 2003 @@ -0,0 +1,293 @@ +/* SCCS Id: @(#)nh340key.c 3.4 $Date: 2003/08/24 15:38:48 $ */ +/* 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 FDECL(__declspec(dllexport) __stdcall +ProcessKeystroke, (HANDLE hConIn, INPUT_RECORD *ir, + boolean *valid, BOOLEAN_P numberpad, int portdebug)); + +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(hConIn, ir, valid, numberpad, portdebug) +HANDLE hConIn; +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 +CheckInput(hConIn, ir, count, numpad, mode, mod, cc) +HANDLE hConIn; +INPUT_RECORD *ir; +DWORD *count; +boolean numpad; +int mode; +int *mod; +coord *cc; +{ + int ch; + boolean valid = 0, done = 0; + while (!done) { + ReadConsoleInput(hConIn,ir,1,count); + if (mode == 0) { + if ((ir->EventType == KEY_EVENT) && ir->Event.KeyEvent.bKeyDown) { + ch = ProcessKeystroke(hConIn, ir, &valid, numpad, 0); + done = valid; + } + } else { + if (count > 0) { + if (ir->EventType == KEY_EVENT && ir->Event.KeyEvent.bKeyDown) { + ch = ProcessKeystroke(hConIn, ir, &valid, numpad, 0); + if (valid) return ch; + } else if (ir->EventType == MOUSE_EVENT) { + if ((ir->Event.MouseEvent.dwEventFlags == 0) && + (ir->Event.MouseEvent.dwButtonState & MOUSEMASK)) { + cc->x = ir->Event.MouseEvent.dwMousePosition.X + 1; + cc->y = ir->Event.MouseEvent.dwMousePosition.Y - 1; + + if (ir->Event.MouseEvent.dwButtonState & LEFTBUTTON) + *mod = CLICK_1; + else if (ir->Event.MouseEvent.dwButtonState & RIGHTBUTTON) + *mod = CLICK_2; +#if 0 /* middle button */ + else if (ir->Event.MouseEvent.dwButtonState & MIDBUTTON) + *mod = CLICK_3; +#endif + return 0; + } + } + } else + done = 1; + } + } + return mode ? 0 : ch; +} + +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; +} + diff -Naurd ../nethack-3.4.1/sys/winnt/nhdefkey.c ./sys/winnt/nhdefkey.c --- ../nethack-3.4.1/sys/winnt/nhdefkey.c Thu Jan 1 01:00:00 1970 +++ ./sys/winnt/nhdefkey.c Mon Sep 1 14:33:32 2003 @@ -0,0 +1,325 @@ +/* SCCS Id: @(#)nhdefkey.c 3.4 $Date: 2003/08/24 15:38:48 $ */ +/* Copyright (c) NetHack PC Development Team 2003 */ +/* NetHack may be freely redistributed. See license for details. */ + +/* + * This is the default NetHack keystroke processing. + * It can be built as a run-time loadable dll (nhdefkey.dll). + * Alternative keystroke handlers can be built using the + * entry points in this file as a template. + * + * Use the defaults.nh "altkeyhandler" option to set a + * different dll name (without the ".DLL" extension) to + * get different processing. Ensure that the dll referenced + * in defaults.nh exists in the same directory as NetHack in + * order for it to load successfully. + * + */ + +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 FDECL(__declspec(dllexport) __stdcall +ProcessKeystroke, (HANDLE hConIn, INPUT_RECORD *ir, + boolean *valid, BOOLEAN_P numberpad, int portdebug)); + +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 */ + {'5', M('5'), '5'}, /* 5 */ + {'6', M('6'), '6'}, /* 6 */ + {'+', 'P', C('p')}, /* + */ + {'1', M('1'), '1'}, /* 1 */ + {'2', M('2'), '2'}, /* 2 */ + {'3', M('3'), '3'}, /* 3 */ + {'0', M('0'), '0'}, /* Ins */ + {'.', ':', ':'} /* Del */ +}; + +#define inmap(x,vk) (((x) > 'A' && (x) < 'Z') || (vk) == 0xBF || (x) == '2') + +static BYTE KeyState[256]; + +int __declspec(dllexport) __stdcall +ProcessKeystroke(hConIn,ir, valid, numberpad, portdebug) +HANDLE hConIn; +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; + 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; + 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)); + } + /* 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 (%s): ch=%u, sc=%u, vk=%d, pre=%d, sh=0x%X, ta=%d (ESC to end)", + shortdllname, ch, scan, vk, pre_ch, shiftstate, k); + 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 +CheckInput(hConIn, ir, count, numpad, mode, mod, cc) +HANDLE hConIn; +INPUT_RECORD *ir; +DWORD *count; +boolean numpad; +int mode; +int *mod; +coord *cc; +{ + int ch; + boolean valid = 0, done = 0; + while (!done) { + ReadConsoleInput(hConIn,ir,1,count); + if (mode == 0) { + if ((ir->EventType == KEY_EVENT) && ir->Event.KeyEvent.bKeyDown) { + ch = ProcessKeystroke(hConIn, ir, &valid, numpad, 0); + done = valid; + } + } else { + if (count > 0) { + if (ir->EventType == KEY_EVENT && ir->Event.KeyEvent.bKeyDown) { + ch = ProcessKeystroke(hConIn, ir, &valid, numpad, 0); + if (valid) return ch; + } else if (ir->EventType == MOUSE_EVENT) { + if ((ir->Event.MouseEvent.dwEventFlags == 0) && + (ir->Event.MouseEvent.dwButtonState & MOUSEMASK)) { + cc->x = ir->Event.MouseEvent.dwMousePosition.X + 1; + cc->y = ir->Event.MouseEvent.dwMousePosition.Y - 1; + + if (ir->Event.MouseEvent.dwButtonState & LEFTBUTTON) + *mod = CLICK_1; + else if (ir->Event.MouseEvent.dwButtonState & RIGHTBUTTON) + *mod = CLICK_2; +#if 0 /* middle button */ + else if (ir->Event.MouseEvent.dwButtonState & MIDBUTTON) + *mod = CLICK_3; +#endif + return 0; + } + } + } else + done = 1; + } + } + return mode ? 0 : ch; +} + +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; +} + diff -Naurd ../nethack-3.4.1/sys/winnt/nhraykey.c ./sys/winnt/nhraykey.c --- ../nethack-3.4.1/sys/winnt/nhraykey.c Thu Jan 1 01:00:00 1970 +++ ./sys/winnt/nhraykey.c Mon Sep 1 14:33:32 2003 @@ -0,0 +1,595 @@ +/* SCCS Id: @(#)nhraykey.c 3.4 $Date: 2003/08/24 15:38:48 $ */ +/* Copyright (c) NetHack PC Development Team 2003 */ +/* NetHack may be freely redistributed. See license for details. */ + +/* + * Keystroke handling contributed by Ray Chason. + * The following text was written by Ray Chason. + * + * The problem + * =========== + * + * The console-mode Nethack wants both keyboard and mouse input. The + * problem is that the Windows API provides no easy way to get mouse input + * and also keyboard input properly translated according to the user's + * chosen keyboard layout. + * + * The ReadConsoleInput function returns a stream of keyboard and mouse + * events. Nethack is interested in those events that represent a key + * pressed, or a click on a mouse button. The keyboard events from + * ReadConsoleInput are not translated according to the keyboard layout, + * and do not take into account the shift, control, or alt keys. + * + * The PeekConsoleInput function works similarly to ReadConsoleInput, + * except that it does not remove an event from the queue and it returns + * instead of blocking when the queue is empty. + * + * A program can also use ReadConsole to get a properly translated stream + * of characters. Unfortunately, ReadConsole does not return mouse events, + * does not distinguish the keypad from the main keyboard, does not return + * keys shifted with Alt, and does not even return the ESC key when + * pressed. + * + * We want both the functionality of ReadConsole and the functionality of + * ReadConsoleInput. But Microsoft didn't seem to think of that. + * + * + * The solution, in the original code + * ================================== + * + * The original 3.4.1 distribution tries to get proper keyboard translation + * by passing keyboard events to the ToAscii function. This works, to some + * extent -- it takes the shift key into account, and it processes dead + * keys properly. But it doesn't take non-US keyboards into account. It + * appears that ToAscii is meant for windowed applications, and does not + * have enough information to do its job properly in a console application. + * + * + * The Finnish keyboard patch + * ========================== + * + * This patch adds the "subkeyvalue" option to the defaults.nh file. The + * user can then add OPTIONS=sukeyvalue:171/92, for instance, to replace + * the 171 character with 92, which is \. This works, once properly + * configured, but places too much burden on the user. It also bars the + * use of the substituted characters in naming objects or monsters. + * + * + * The solution presented here + * =========================== + * + * The best way I could find to combine the functionality of ReadConsole + * with that of ReadConsoleInput is simple in concept. First, call + * PeekConsoleInput to get the first event. If it represents a key press, + * call ReadConsole to retrieve the key. Otherwise, pop it off the queue + * with ReadConsoleInput and, if it's a mouse click, return it as such. + * + * But the Devil, as they say, is in the details. The problem is in + * recognizing an event that ReadConsole will return as a key. We don't + * want to call ReadConsole unless we know that it will immediately return: + * if it blocks, the mouse and the Alt sequences will cease to function + * until it returns. + * + * Separating process_keystroke into two functions, one for commands and a + * new one, process_keystroke2, for answering prompts, makes the job a lot + * easier. process_keystroke2 doesn't have to worry about mouse events or + * Alt sequences, and so the consequences are minor if ReadConsole blocks. + * process_keystroke, OTOH, never needs to return a non-ASCII character + * that was read from ReadConsole; it returns bytes with the high bit set + * only in response to an Alt sequence. + * + * So in process_keystroke, before calling ReadConsole, a bogus key event + * is pushed on the queue. This event causes ReadConsole to return, even + * if there was no other character available. Because the bogus key has + * the eighth bit set, it is filtered out. This is not done in + * process_keystroke2, because that would render dead keys unusable. + * + * A separate process_keystroke2 can also process the numeric keypad in a + * way that makes sense for prompts: just return the corresponding symbol, + * and pay no mind to number_pad or the num lock key. + * + * The recognition of Alt sequences is modified, to support the use of + * characters generated with the AltGr key. A keystroke is an Alt sequence + * if an Alt key is seen that can't be an AltGr (since an AltGr sequence + * could be a character, and in some layouts it could even be an ASCII + * character). This recognition is different on NT-based and 95-based + * Windows: + * + * * On NT-based Windows, AltGr signals as right Alt and left Ctrl + * together. So an Alt sequence is recognized if either Alt key is + * pressed and if right Alt and left Ctrl are not both present. This + * is true even if the keyboard in use does not have an AltGr key, and + * uses right Alt for AltGr. + * + * * On 95-based Windows, with a keyboard that lacks the AltGr key, the + * right Alt key is used instead. But it still signals as right Alt, + * without left Ctrl. There is no way for the application to know + * whether right Alt is Alt or AltGr, and so it is always assumed + * to be AltGr. This means that Alt sequences must be formed with + * left Alt. + * + * So the patch processes keystrokes as follows: + * + * * If the scan and virtual key codes are both 0, it's the bogus key, + * and we ignore it. + * + * * Keys on the numeric keypad are processed for commands as in the + * unpatched Nethack, and for prompts by returning the ASCII + * character, even if the num lock is off. + * + * * Alt sequences are processed for commands as in the unpatched + * Nethack, and ignored for prompts. + * + * * Control codes are returned as received, because ReadConsole will + * not return the ESC key. + * + * * Other key-down events are passed to ReadConsole. The use of + * ReadConsole is different for commands than for prompts: + * + * o For commands, the bogus key is pushed onto the queue before + * ReadConsole is called. On return, non-ASCII characters are + * filtered, so they are not mistaken for Alt sequences; this also + * filters the bogus key. + * + * o For prompts, the bogus key is not used, because that would + * interfere with dead keys. Eight bit characters may be returned, + * and are coded in the configured code page. + * + * + * Possible improvements + * ===================== + * + * Some possible improvements remain: + * + * * Integrate the existing Finnish keyboard patch, for use with non- + * QWERTY layouts such as the German QWERTZ keyboard or Dvorak. + * + * * Fix the keyboard glitches in the graphical version. Namely, dead + * keys don't work, and input comes in as ISO-8859-1 but is displayed + * as code page 437 if IBMgraphics is set on startup. + * + * * Transform incoming text to ISO-8859-1, for full compatibility with + * the graphical version. + * + * * After pushing the bogus key and calling ReadConsole, check to see + * if we got the bogus key; if so, and an Alt is pressed, process the + * event as an Alt sequence. + * + */ + +static char where_to_get_source[] = "http://www.nethack.org/"; +static char author[] = "Ray Chason"; + +#include "hack.h" +#include "wintty.h" +#include "win32api.h" + +extern HANDLE hConIn; +extern INPUT_RECORD ir; +char dllname[512]; +char *shortdllname; + +int FDECL(__declspec(dllexport) __stdcall +ProcessKeystroke, (HANDLE hConIn, INPUT_RECORD *ir, + boolean *valid, BOOLEAN_P numberpad, int portdebug)); + +static INPUT_RECORD bogus_key; + +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; + } + /* A bogus key that will be filtered when received, to keep ReadConsole + * from blocking */ + bogus_key.EventType = KEY_EVENT; + bogus_key.Event.KeyEvent.bKeyDown = 1; + bogus_key.Event.KeyEvent.wRepeatCount = 1; + bogus_key.Event.KeyEvent.wVirtualKeyCode = 0; + bogus_key.Event.KeyEvent.wVirtualScanCode = 0; + bogus_key.Event.KeyEvent.uChar.AsciiChar = (uchar)0x80; + bogus_key.Event.KeyEvent.dwControlKeyState = 0; + 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) +#define isnumkeypad(x) (KEYPADLO <= (x) && (x) <= 0x51 && (x) != 0x4A && (x) != 0x4E) + +/* + * 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') + +/* Use process_keystroke for key commands, process_keystroke2 for prompts */ +/* int FDECL(process_keystroke, (INPUT_RECORD *ir, boolean *valid, int portdebug)); */ +int FDECL(process_keystroke2, (HANDLE,INPUT_RECORD *ir, boolean *valid)); +static int FDECL(is_altseq, (unsigned long shiftstate)); + +static int +is_altseq(shiftstate) +unsigned long shiftstate; +{ + /* We need to distinguish the Alt keys from the AltGr key. + * On NT-based Windows, AltGr signals as right Alt and left Ctrl together; + * on 95-based Windows, AltGr signals as right Alt only. + * So on NT, we signal Alt if either Alt is pressed and left Ctrl is not, + * and on 95, we signal Alt for left Alt only. */ + switch (shiftstate & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED | LEFT_CTRL_PRESSED)) { + case LEFT_ALT_PRESSED: + case LEFT_ALT_PRESSED | LEFT_CTRL_PRESSED: + return 1; + + case RIGHT_ALT_PRESSED: + case RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED: + return (GetVersion() & 0x80000000) == 0; + + default: + return 0; + } +} + +int __declspec(dllexport) __stdcall +ProcessKeystroke(hConIn, ir, valid, numberpad, portdebug) +HANDLE hConIn; +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; + DWORD count; + + 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 (scan == 0 && vk == 0) { + /* It's the bogus_key */ + ReadConsoleInput(hConIn,ir,1,&count); + *valid = FALSE; + return 0; + } + + if (is_altseq(shiftstate)) { + 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)) { + ReadConsoleInput(hConIn,ir,1,&count); + 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 */ + ReadConsoleInput(hConIn,ir,1,&count); + if (vk == 0xBF) ch = M('?'); + else ch = M(tolower(keycode)); + } + else if (ch < 32 && !isnumkeypad(scan)) { + /* Control code; ReadConsole seems to filter some of these, + * including ESC */ + ReadConsoleInput(hConIn,ir,1,&count); + } + /* Attempt to work better with international keyboards. */ + else { + CHAR ch2; + DWORD written; + /* The bogus_key guarantees that ReadConsole will return, + * and does not itself do anything */ + WriteConsoleInput(hConIn, &bogus_key, 1, &written); + ReadConsole(hConIn,&ch2,1,&count,NULL); + /* Prevent high characters from being interpreted as alt + * sequences; also filter the bogus_key */ + if (ch2 & 0x80) + *valid = FALSE; + else + ch = ch2; + if (ch == 0) *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); + fprintf(stdout, "\n%s", buf); + } +#endif + return ch; +} + +int process_keystroke2(hConIn, ir, valid) +HANDLE hConIn; +INPUT_RECORD *ir; +boolean *valid; +{ + /* Use these values for the numeric keypad */ + static const char keypad_nums[] = "789-456+1230."; + + unsigned char ch; + int vk; + unsigned short int scan; + unsigned long shiftstate; + int altseq; + DWORD count; + + ch = ir->Event.KeyEvent.uChar.AsciiChar; + vk = ir->Event.KeyEvent.wVirtualKeyCode; + scan = ir->Event.KeyEvent.wVirtualScanCode; + shiftstate = ir->Event.KeyEvent.dwControlKeyState; + + if (scan == 0 && vk == 0) { + /* It's the bogus_key */ + ReadConsoleInput(hConIn,ir,1,&count); + *valid = FALSE; + return 0; + } + + altseq = is_altseq(shiftstate); + if (ch || (iskeypad(scan)) || altseq) + *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) && !altseq) { + ReadConsoleInput(hConIn,ir,1,&count); + ch = keypad_nums[scan - KEYPADLO]; + } + else if (ch < 32 && !isnumkeypad(scan)) { + /* Control code; ReadConsole seems to filter some of these, + * including ESC */ + ReadConsoleInput(hConIn,ir,1,&count); + } + /* Attempt to work better with international keyboards. */ + else { + CHAR ch2; + ReadConsole(hConIn,&ch2,1,&count,NULL); + ch = ch2 & 0xFF; + if (ch == 0) *valid = FALSE; + } + if (ch == '\r') ch = '\n'; + return ch; +} + +int __declspec(dllexport) __stdcall +CheckInput(hConIn, ir, count, numpad, mode, mod, cc) +HANDLE hConIn; +INPUT_RECORD *ir; +DWORD *count; +int *mod; +boolean numpad; +coord *cc; +{ + int ch; + boolean valid = 0, done = 0; + while (!done) { + *count = 0; + WaitForSingleObject(hConIn, INFINITE); + PeekConsoleInput(hConIn,ir,1,count); + if (mode == 0) { + if ((ir->EventType == KEY_EVENT) && ir->Event.KeyEvent.bKeyDown) { + ch = process_keystroke2(hConIn, ir, &valid); + done = valid; + } else + ReadConsoleInput(hConIn,ir,1,count); + } else { + ch = 0; + if (count > 0) { + if (ir->EventType == KEY_EVENT && ir->Event.KeyEvent.bKeyDown) { + ch = ProcessKeystroke(hConIn, ir, &valid, numpad, +#ifdef PORTDEBUG + 1); +#else + 0); +#endif + if (valid) return ch; + } else { + ReadConsoleInput(hConIn,ir,1,count); + if (ir->EventType == MOUSE_EVENT) { + if ((ir->Event.MouseEvent.dwEventFlags == 0) && + (ir->Event.MouseEvent.dwButtonState & MOUSEMASK)) { + cc->x = ir->Event.MouseEvent.dwMousePosition.X + 1; + cc->y = ir->Event.MouseEvent.dwMousePosition.Y - 1; + + if (ir->Event.MouseEvent.dwButtonState & LEFTBUTTON) + *mod = CLICK_1; + else if (ir->Event.MouseEvent.dwButtonState & RIGHTBUTTON) + *mod = CLICK_2; +#if 0 /* middle button */ + else if (ir->Event.MouseEvent.dwButtonState & MIDBUTTON) + *mod = CLICK_3; +#endif + return 0; + } + } +#if 0 + /* We ignore these types of console events */ + else if (ir->EventType == FOCUS_EVENT) { + } + else if (ir->EventType == MENU_EVENT) { + } +#endif + } + } else + done = 1; + } + } + *mod = 0; + 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 (is_altseq(shiftstate)) { + 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; +} + diff -Naurd ../nethack-3.4.1/sys/winnt/nttty.c ./sys/winnt/nttty.c --- ../nethack-3.4.1/sys/winnt/nttty.c Sun Feb 23 14:43:43 2003 +++ ./sys/winnt/nttty.c Mon Sep 1 14:33:32 2003 @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)nttty.c 3.4 $Date: 2003/02/06 03:04:37 $ */ +/* SCCS Id: @(#)nttty.c 3.4 $Date: 2003/08/24 15:38:49 $ */ /* Copyright (c) NetHack PC Development Team 1993 */ /* NetHack may be freely redistributed. See license for details. */ @@ -15,10 +15,11 @@ #include #include #include "win32api.h" -#include void FDECL(cmov, (int, int)); void FDECL(nocmov, (int, int)); +int FDECL(process_keystroke, (INPUT_RECORD *, boolean *, + BOOLEAN_P numberpad, int portdebug)); /* * The following WIN32 Console API routines are used in this file. @@ -53,6 +54,51 @@ int GUILaunched; static BOOL FDECL(CtrlHandler, (DWORD)); +/* dynamic keystroke handling .DLL support */ +typedef int (__stdcall * PROCESS_KEYSTROKE)( + HANDLE, + INPUT_RECORD *, + boolean *, + BOOLEAN_P, + int +); + +typedef int (__stdcall * NHKBHIT)( + HANDLE, + INPUT_RECORD * +); + +typedef int (__stdcall * CHECKINPUT)( + HANDLE, + INPUT_RECORD *, + DWORD *, + BOOLEAN_P, + int, + int *, + coord * +); + +typedef int (__stdcall * SOURCEWHERE)( + char ** +); + +typedef int (__stdcall * SOURCEAUTHOR)( + char ** +); + +typedef int (__stdcall * KEYHANDLERNAME)( + char **, + int +); + +HANDLE hLibrary; +PROCESS_KEYSTROKE pProcessKeystroke; +NHKBHIT pNHkbhit; +CHECKINPUT pCheckInput; +SOURCEWHERE pSourceWhere; +SOURCEAUTHOR pSourceAuthor; +KEYHANDLERNAME pKeyHandlerName; + #ifndef CLR_MAX #define CLR_MAX 16 #endif @@ -61,6 +107,9 @@ static void NDECL(init_ttycolor); # endif +#define MAX_OVERRIDES 256 +unsigned char key_overrides[MAX_OVERRIDES]; + #define DEFTEXTCOLOR ttycolors[7] #ifdef TEXTCOLOR #define DEFGLYPHBGRND (0) @@ -77,11 +126,6 @@ static char currentbackground = 0; static boolean colorchange = TRUE; -#define LEFTBUTTON FROM_LEFT_1ST_BUTTON_PRESSED -#define RIGHTBUTTON RIGHTMOST_BUTTON_PRESSED -#define MIDBUTTON FROM_LEFT_2ND_BUTTON_PRESSED -#define MOUSEMASK (LEFTBUTTON | RIGHTBUTTON | MIDBUTTON) - /* * Called after returning from ! or ^Z */ @@ -111,6 +155,38 @@ if(s) raw_print(s); } +/* + * mode == 0 set processed console output mode. + * mode == 1 set raw console output mode (no control character expansion). + */ +void +set_output_mode(mode) +int mode; +{ + static DWORD save_output_cmode = 0; + static boolean initmode = FALSE; + DWORD cmode, mask = ENABLE_PROCESSED_OUTPUT; + if (!initmode) { + /* fetch original output mode */ + GetConsoleMode(hConOut,&save_output_cmode); + initmode = TRUE; + } + if (mode == 0) { + cmode = save_output_cmode; + /* Turn ON the settings specified in the mask */ + cmode |= mask; + SetConsoleMode(hConOut,cmode); + iflags.rawio = 0; + } else { + cmode = save_output_cmode; + /* Turn OFF the settings specified in the mask */ + cmode &= ~mask; + SetConsoleMode(hConOut,cmode); + iflags.rawio = 1; + } +} + + /* called by init_nhwindows() and resume_nhwindows() */ void setftty() @@ -162,6 +238,7 @@ csbi.dwSize.X * csbi.dwSize.Y, newcoord, &ccnt); } + FlushConsoleInputBuffer(hConIn); } extern boolean getreturn_disable; /* from sys/share/pcsys.c */ @@ -176,6 +253,7 @@ case CTRL_CLOSE_EVENT: case CTRL_LOGOFF_EVENT: case CTRL_SHUTDOWN_EVENT: + set_output_mode(0); /* Allow processed output */ getreturn_disable = TRUE; #ifndef NOSAVEONHANGUP hangup(0); @@ -196,11 +274,11 @@ HANDLE hStdOut; DWORD cmode; long mask; - + + load_keyboard_handler(); /* Initialize the function pointer that points to * the kbhit() equivalent, in this TTY case nttty_kbhit() */ - nt_kbhit = nttty_kbhit; /* The following 6 lines of code were suggested by @@ -242,6 +320,8 @@ cmode |= ENABLE_MOUSE_INPUT; #endif SetConsoleMode(hConIn,cmode); + + set_output_mode(1); /* raw output mode; no tab expansion */ if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE)) { /* Unable to set control handler */ cmode = 0; /* just to have a statement to break on for debugger */ @@ -249,6 +329,26 @@ get_scr_size(); } +int process_keystroke(ir, valid, numberpad, portdebug) +INPUT_RECORD *ir; +boolean *valid; +boolean numberpad; +int portdebug; +{ + int ch = pProcessKeystroke(hConIn, ir, valid, numberpad, portdebug); + /* check for override */ + if (ch && ch < MAX_OVERRIDES && key_overrides[ch]) + ch = key_overrides[ch]; + return ch; +} + +int +nttty_kbhit() +{ + return pNHkbhit(hConIn, &ir); +} + + void get_scr_size() { @@ -270,264 +370,28 @@ } } - -/* - * 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') - -static BYTE KeyState[256]; - -int FDECL(process_keystroke, (INPUT_RECORD *ir, boolean *valid, int portdebug)); - -int process_keystroke(ir, valid, portdebug) -INPUT_RECORD *ir; -boolean *valid; -int portdebug; -{ - int metaflags = 0, k; - int keycode, vk; - unsigned char ch, pre_ch; - 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; - 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; - 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 = iflags.num_pad ? 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)); - } - /* 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 tgetch() { + int mod; + coord cc; DWORD count; - boolean valid = 0; - int ch; - valid = 0; - while (!valid) { - ReadConsoleInput(hConIn,&ir,1,&count); - if ((ir.EventType == KEY_EVENT) && ir.Event.KeyEvent.bKeyDown) - ch = process_keystroke(&ir, &valid, 0); - } - return ch; + return pCheckInput(hConIn, &ir, &count, iflags.num_pad, 0, &mod, &cc); } int ntposkey(x, y, mod) int *x, *y, *mod; { + int ch; + coord cc; DWORD count; - int keystroke = 0; - int done = 0; - boolean valid = 0; - while (!done) - { - count = 0; - ReadConsoleInput(hConIn,&ir,1,&count); - if (count > 0) { - if (ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown) { - keystroke = process_keystroke(&ir, &valid, 0); - if (valid) return keystroke; - } else if (ir.EventType == MOUSE_EVENT) { - if ((ir.Event.MouseEvent.dwEventFlags == 0) && - (ir.Event.MouseEvent.dwButtonState & MOUSEMASK)) { - *x = ir.Event.MouseEvent.dwMousePosition.X + 1; - *y = ir.Event.MouseEvent.dwMousePosition.Y - 1; - - if (ir.Event.MouseEvent.dwButtonState & LEFTBUTTON) - *mod = CLICK_1; - else if (ir.Event.MouseEvent.dwButtonState & RIGHTBUTTON) - *mod = CLICK_2; -#if 0 /* middle button */ - else if (ir.Event.MouseEvent.dwButtonState & MIDBUTTON) - *mod = CLICK_3; -#endif - return 0; - } - } -#if 0 - /* We ignore these types of console events */ - else if (ir.EventType == FOCUS_EVENT) { - } - else if (ir.EventType == MENU_EVENT) { - } -#endif - } else - done = 1; - } - /* NOTREACHED */ - *mod = 0; - return 0; -} - -int -nttty_kbhit() -{ - 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; - } + ch = pCheckInput(hConIn, &ir, &count, iflags.num_pad, 1, mod, &cc); + if (!ch) { + *x = cc.x; + *y = cc.y; } - return retval; + return ch; } void @@ -556,6 +420,12 @@ { DWORD count; + switch(c) { + case '\n': + case '\r': + cmov(ttyDisplay->curx, ttyDisplay->cury); + return; + } if (colorchange) { SetConsoleTextAttribute(hConOut, (currentcolor | currenthilite | currentbackground)); @@ -748,7 +618,7 @@ static void init_ttycolor() { - ttycolors[CLR_BLACK] = FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED; + ttycolors[CLR_BLACK] = FOREGROUND_INTENSITY; /* fix by Quietust */ ttycolors[CLR_RED] = FOREGROUND_RED; ttycolors[CLR_GREEN] = FOREGROUND_GREEN; ttycolors[CLR_BROWN] = FOREGROUND_GREEN|FOREGROUND_RED; @@ -931,9 +801,151 @@ while (!valid || ch != 27) { ReadConsoleInput(hConIn,&ir,1,&count); if ((ir.EventType == KEY_EVENT) && ir.Event.KeyEvent.bKeyDown) - ch = process_keystroke(&ir, &valid, 1); + ch = process_keystroke(&ir, &valid, iflags.num_pad, 1); } (void)doredraw(); } +void +win32con_handler_info() +{ + char *buf; + int ci; + if (!pSourceAuthor && !pSourceWhere) + pline("Keyboard handler source info and author unavailable."); + else { + if (pKeyHandlerName && pKeyHandlerName(&buf, 1)) { + xputs("\n"); + xputs("Keystroke handler loaded: \n "); + xputs(buf); + } + if (pSourceAuthor && pSourceAuthor(&buf)) { + xputs("\n"); + xputs("Keystroke handler Author: \n "); + xputs(buf); + } + if (pSourceWhere && pSourceWhere(&buf)) { + xputs("\n"); + xputs("Keystroke handler source code available at:\n "); + xputs(buf); + } + xputs("\nPress any key to resume."); + ci=nhgetch(); + (void)doredraw(); + } +} #endif + +void +map_subkeyvalue(op) +register char *op; +{ + char digits[] = "0123456789"; + int length, i, idx, val; + char *kp; + + idx = -1; + val = -1; + kp = index(op, '/'); + if (kp) { + *kp = '\0'; + kp++; + length = strlen(kp); + if (length < 1 || length > 3) return; + for (i = 0; i < length; i++) + if (!index(digits, kp[i])) return; + val = atoi(kp); + length = strlen(op); + if (length < 1 || length > 3) return; + for (i = 0; i < length; i++) + if (!index(digits, op[i])) return; + idx = atoi(op); + } + if (idx >= MAX_OVERRIDES || idx < 0 || val >= MAX_OVERRIDES || val < 1) + return; + key_overrides[idx] = val; +} + +void +load_keyboard_handler() +{ + char suffx[] = ".dll"; + char *truncspot; +#define MAX_DLLNAME 25 + char kh[MAX_ALTKEYHANDLER]; + if (iflags.altkeyhandler[0]) { + if (hLibrary) { /* already one loaded apparently */ + FreeLibrary(hLibrary); + hLibrary = (HANDLE)0; + pNHkbhit = (NHKBHIT)0; + pCheckInput = (CHECKINPUT)0; + pSourceWhere = (SOURCEWHERE)0; + pSourceAuthor = (SOURCEAUTHOR)0; + pKeyHandlerName = (KEYHANDLERNAME)0; + pProcessKeystroke = (PROCESS_KEYSTROKE)0; + } + if ((truncspot = strstri(iflags.altkeyhandler, suffx)) != 0) + *truncspot = '\0'; + (void) strncpy(kh, iflags.altkeyhandler, + (MAX_ALTKEYHANDLER - sizeof suffx) - 1); + kh[(MAX_ALTKEYHANDLER - sizeof suffx) - 1] = '\0'; + Strcat(kh, suffx); + Strcpy(iflags.altkeyhandler, kh); + hLibrary = LoadLibrary(kh); + if (hLibrary) { + pProcessKeystroke = + (PROCESS_KEYSTROKE) GetProcAddress (hLibrary, TEXT ("ProcessKeystroke")); + pNHkbhit = + (NHKBHIT) GetProcAddress (hLibrary, TEXT ("NHkbhit")); + pCheckInput = + (CHECKINPUT) GetProcAddress (hLibrary, TEXT ("CheckInput")); + pSourceWhere = + (SOURCEWHERE) GetProcAddress (hLibrary, TEXT ("SourceWhere")); + pSourceAuthor = + (SOURCEAUTHOR) GetProcAddress (hLibrary, TEXT ("SourceAuthor")); + pKeyHandlerName = + (KEYHANDLERNAME) GetProcAddress (hLibrary, TEXT ("KeyHandlerName")); + } + } + if (!pProcessKeystroke || !pNHkbhit || !pCheckInput) { + if (hLibrary) { + FreeLibrary(hLibrary); + hLibrary = (HANDLE)0; + pNHkbhit = (NHKBHIT)0; + pCheckInput = (CHECKINPUT)0; + pSourceWhere = (SOURCEWHERE)0; + pSourceAuthor = (SOURCEAUTHOR)0; + pKeyHandlerName = (KEYHANDLERNAME)0; + pProcessKeystroke = (PROCESS_KEYSTROKE)0; + } + (void)strncpy(kh, "nhdefkey.dll", (MAX_ALTKEYHANDLER - sizeof suffx) - 1); + kh[(MAX_ALTKEYHANDLER - sizeof suffx) - 1] = '\0'; + Strcpy(iflags.altkeyhandler, kh); + hLibrary = LoadLibrary(kh); + if (hLibrary) { + pProcessKeystroke = + (PROCESS_KEYSTROKE) GetProcAddress (hLibrary, TEXT ("ProcessKeystroke")); + pCheckInput = + (CHECKINPUT) GetProcAddress (hLibrary, TEXT ("CheckInput")); + pNHkbhit = + (NHKBHIT) GetProcAddress (hLibrary, TEXT ("NHkbhit")); + pSourceWhere = + (SOURCEWHERE) GetProcAddress (hLibrary, TEXT ("SourceWhere")); + pSourceAuthor = + (SOURCEAUTHOR) GetProcAddress (hLibrary, TEXT ("SourceAuthor")); + pKeyHandlerName = + (KEYHANDLERNAME) GetProcAddress (hLibrary, TEXT ("KeyHandlerName")); + } + } + if (!pProcessKeystroke || !pNHkbhit || !pCheckInput) { + if (!hLibrary) + raw_printf("\nNetHack was unable to load keystroke handler.\n"); + else { + FreeLibrary(hLibrary); + hLibrary = (HANDLE)0; + raw_printf("\nNetHack keystroke handler is invalid.\n"); + } + exit(EXIT_FAILURE); + } +} + #endif /* WIN32CON */ diff -Naurd ../nethack-3.4.1/sys/winnt/porthelp ./sys/winnt/porthelp --- ../nethack-3.4.1/sys/winnt/porthelp Sun Feb 23 14:43:43 2003 +++ ./sys/winnt/porthelp Mon Sep 1 14:33:32 2003 @@ -1,4 +1,4 @@ - Microsoft Windows specific help file for NetHack 3.4.1 + Microsoft Windows specific help file for NetHack 3.4.2 Copyright (c) NetHack PC Development Team 1993-2002. NetHack may be freely distributed. See license for details. (Last Revision: March 16, 2002) @@ -242,7 +242,7 @@ the map_mode option. Window Settings - Changes your logged-on user's settings for NetHack. -In 3.4.1, only one setting is available: NetHack mode, which can be +In 3.4.2, only one setting is available: NetHack mode, which can be checked or unchecked. NetHack mode allows you to use the ALT key for game key commands [see list above]. You can use F10 to access the menu bar while in NetHack mode. You can also clear your logged-on diff -Naurd ../nethack-3.4.1/sys/share/pcmain.c ./sys/share/pcmain.c --- ../nethack-3.4.1/sys/share/pcmain.c Sun Feb 23 14:43:38 2003 +++ ./sys/share/pcmain.c Mon Sep 1 14:33:32 2003 @@ -281,8 +291,19 @@ # endif #endif - if (!*plname) + if (!*plname) { +#ifdef WIN32CON + boolean revert = FALSE; + if (!iflags.rawio) { + set_output_mode(1); + revert = TRUE; + } +#endif askname(); +#ifdef WIN32CON + if (revert && iflags.rawio) set_output_mode(0); +#endif + } plnamesuffix(); /* strip suffix from name; calls askname() */ /* again if suffix was whole name */ /* accepts any suffix */ diff -Naurd ../nethack-3.4.1/sys/share/pcsys.c ./sys/share/pcsys.c --- ../nethack-3.4.1/sys/share/pcsys.c Sun Feb 23 14:43:38 2003 +++ ./sys/share/pcsys.c Mon Sep 1 14:33:32 2003 @@ -416,6 +416,9 @@ if (iflags.grmode) gr_finish(); # endif +#ifdef WIN32CON + if (iflags.rawio) set_output_mode(0); +#endif Vprintf(fmt, VA_ARGS); flushout(); VA_END(); diff -Naurd ../nethack-3.4.1/sys/share/pctty.c ./sys/share/pctty.c --- ../nethack-3.4.1/sys/share/pctty.c Sun Feb 23 14:43:38 2003 +++ ./sys/share/pctty.c Mon Sep 1 14:33:32 2003 @@ -75,6 +75,9 @@ VA_INIT(s, const char *); /* error() may get called before tty is initialized */ if (iflags.window_inited) end_screen(); +#ifdef WIN32CON + if (iflags.rawio) set_output_mode(0); +#endif putchar('\n'); Vprintf(s,VA_ARGS); putchar('\n'); diff -Naurd ../nethack-3.4.1/sys/share/pcunix.c ./sys/share/pcunix.c --- ../nethack-3.4.1/sys/share/pcunix.c Sun Feb 23 14:43:38 2003 +++ ./sys/share/pcunix.c Mon Sep 1 14:33:32 2003 @@ -263,6 +263,9 @@ # if defined(MSDOS) && defined(NO_TERMS) if (grmode) gr_init(); # endif +#ifdef WIN32CON + if (!iflags.rawio) set_output_mode(1); +#endif } #endif /* PC_LOCKING */ diff -Naurd ../nethack-3.4.1/include/flag.h ./include/flag.h --- ../nethack-3.4.1/include/flag.h Sun Feb 23 14:43:20 2003 +++ ./include/flag.h Mon Sep 1 14:33:32 2003 @@ -262,6 +269,10 @@ boolean showrace; /* show hero glyph by race rather than by role */ boolean travelcmd; /* allow travel command */ int runmode; /* update screen display during run moves */ +#ifdef WIN32CON +#define MAX_ALTKEYHANDLER 25 + char altkeyhandler[MAX_ALTKEYHANDLER]; +#endif }; /* diff -Naurd ../nethack-3.4.1/include/ntconf.h ./include/ntconf.h --- ../nethack-3.4.1/include/ntconf.h Sun Feb 23 14:43:21 2003 +++ ./include/ntconf.h Mon Sep 1 14:33:32 2003 @@ -132,6 +132,8 @@ #ifdef WIN32CON extern void FDECL(nttty_preference_update, (const char *)); extern void NDECL(toggle_mouse_support); +extern void FDECL(map_subkeyvalue, (char *)); +extern void NDECL(load_keyboard_handler); #endif #include @@ -183,5 +185,11 @@ #endif extern int FDECL(set_win32_option, (const char *, const char *)); +#ifdef WIN32CON +#define LEFTBUTTON FROM_LEFT_1ST_BUTTON_PRESSED +#define RIGHTBUTTON RIGHTMOST_BUTTON_PRESSED +#define MIDBUTTON FROM_LEFT_2ND_BUTTON_PRESSED +#define MOUSEMASK (LEFTBUTTON | RIGHTBUTTON | MIDBUTTON) +#endif /* WIN32CON */ #endif /* NTCONF_H */ diff -Naurd ../nethack-3.4.1/src/cmd.c ./src/cmd.c --- ../nethack-3.4.1/src/cmd.c Sun Feb 23 14:43:25 2003 +++ ./src/cmd.c Mon Sep 1 14:33:32 2003 @@ -2401,6 +2431,7 @@ #ifdef PORT_DEBUG # ifdef WIN32CON extern void NDECL(win32con_debug_keystrokes); +extern void NDECL(win32con_handler_info); # endif int @@ -2417,6 +2448,7 @@ } menu_selections[] = { #ifdef WIN32CON {"test win32 keystrokes", win32con_debug_keystrokes}, + {"show keystroke handler information", win32con_handler_info}, #endif {(char *)0, (void NDECL((*)))0} /* array terminator */ }; diff -Naurd ../nethack-3.4.1/src/options.c ./src/options.c --- ../nethack-3.4.1/src/options.c Sun Feb 23 14:43:28 2003 +++ ./src/options.c Mon Sep 1 14:33:32 2003 @@ -187,8 +188,13 @@ {"tombstone",&flags.tombstone, TRUE, SET_IN_GAME}, {"toptenwin",&flags.toptenwin, FALSE, SET_IN_GAME}, {"travel", &iflags.travelcmd, TRUE, SET_IN_GAME}, +#ifdef WIN32CON + {"use_inverse", &iflags.wc_inverse, TRUE, SET_IN_GAME}, /*WC*/ +#else {"use_inverse", &iflags.wc_inverse, FALSE, SET_IN_GAME}, /*WC*/ +#endif {"verbose", &flags.verbose, TRUE, SET_IN_GAME}, + {"wraptext", &iflags.wc2_wraptext, FALSE, SET_IN_GAME}, {(char *)0, (boolean *)0, FALSE, 0} }; @@ -317,6 +325,9 @@ { "videoshades", "gray shades to map to black/gray/white", 32, DISP_IN_GAME }, #endif +#ifdef WIN32CON + {"subkeyvalue", "override keystroke value", 7, SET_IN_FILE}, +#endif { "windowcolors", "the foreground/background colors of windows", /*WC*/ 80, DISP_IN_GAME }, { "windowtype", "windowing system to use", WINTYPELEN, DISP_IN_GAME }, @@ -1467,6 +1513,19 @@ return; } + /* altkeyhandler:string */ + fullname = "altkeyhandler"; + if (match_optname(opts, fullname, 4, TRUE)) { + if (negated) bad_negation(fullname, FALSE); + else if ((op = string_for_opt(opts, negated))) { +#ifdef WIN32CON + (void)strncpy(iflags.altkeyhandler, op, MAX_ALTKEYHANDLER - 5); + load_keyboard_handler(); +#endif + } + return; + } + /* WINCAP * align_status:[left|top|right|bottom] */ fullname = "align_status"; @@ -1889,6 +1947,17 @@ } else if (negated) bad_negation(fullname, TRUE); return; } + fullname = "subkeyvalue"; + if (match_optname(opts, fullname, 5, TRUE)) { + if (negated) bad_negation(fullname, FALSE); + else { +#if defined(WIN32CON) + op = string_for_opt(opts, 0); + map_subkeyvalue(op); +#endif + } + return; + } /* WINCAP * tile_width:nn */ fullname = "tile_width"; @@ -2635,6 +2741,11 @@ defopt); else if (!strcmp(optname,"align")) Sprintf(buf, "%s", rolestring(flags.initalign, aligns, adj)); +#ifdef WIN32CON + else if (!strcmp(optname,"altkeyhandler")) + Sprintf(buf, "%s", iflags.altkeyhandler[0] ? + iflags.altkeyhandler : "default"); +#endif else if (!strcmp(optname, "boulder")) Sprintf(buf, "%c", iflags.bouldersym ? iflags.bouldersym : oc_syms[(int)objects[BOULDER].oc_class]);