From 6f7246bdc315c205d1ebd799337c70ca5275a455 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 31 Oct 2019 12:46:33 -0400 Subject: [PATCH 1/7] Guidebook.tex fix --- doc/Guidebook.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 92b4d742a..d1128e967 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -3028,7 +3028,7 @@ See the ``Configuring User Sounds'' section. Define the directory that contains the sound files. See the ``Configuring User Sounds'' section. %.lp -\item[\bb{SYMBOLS} +\item[\bb{SYMBOLS}] Override one or more symbols in the symbol set used for all dungeon levels except for the special rogue level. See the ``Modifying {\it NetHack\/} Symbols'' section. @@ -3036,7 +3036,7 @@ See the ``Modifying {\it NetHack\/} Symbols'' section. Example: %.sd \begin{verbatim} - # replace small punctuation (tick marks) with digits + # replaces small punctuation (tick marks) with digits SYMBOLS=S_boulder:0,S_golem:7 \end{verbatim} %.ed From ac49d7b5e80ab6620e0fa56bd6fcdc77f074ff62 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 31 Oct 2019 12:50:12 -0400 Subject: [PATCH 2/7] unintentional change --- doc/Guidebook.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index d1128e967..b3c175766 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -3036,7 +3036,7 @@ See the ``Modifying {\it NetHack\/} Symbols'' section. Example: %.sd \begin{verbatim} - # replaces small punctuation (tick marks) with digits + # replace small punctuation (tick marks) with digits SYMBOLS=S_boulder:0,S_golem:7 \end{verbatim} %.ed From 696f54a3b83dcd94a1040fe67cf85e279885043e Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 31 Oct 2019 13:27:10 -0400 Subject: [PATCH 3/7] doc updates --- dat/history | 9 ++++++--- doc/Guidebook.mn | 11 +++++++---- doc/Guidebook.tex | 13 +++++++++---- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/dat/history b/dat/history index 70935071a..2922bcd9e 100644 --- a/dat/history +++ b/dat/history @@ -57,7 +57,7 @@ Spackman, Steve VanDevender, and Paul Winner, ported NetHack 3.1 to the PC. Jon W{tte and Hao-yang Wang, with help from Ross Brown, Mike Engber, David Hairston, Michael Hamel, Jonathan Handler, Johnny Lee, Tim Lennan, Rob Menke, and Andy Swanson developed NetHack 3.1 for the Macintosh, porting it for -MPW. Building on their development, Barton House added a Think C port. +MPW. Building on their development, Bart House added a Think C port. Timo Hakulinen ported NetHack 3.1 to OS/2. Eric Smith ported NetHack 3.1 to the Atari. Pat Rankin, with help from Joshua Delahunty, is responsible @@ -195,7 +195,7 @@ Unix flavors as well as maintaining the X11 interface. Ken Lorber, Haoyang Wang, Pat Rankin, and Dean Luick maintained the port of NetHack 3.6.1 for Mac OSX. -Michael Allison, David Cohrs, Barton House, Pasi Kallinen, Alex Kompel, +Michael Allison, David Cohrs, Bart House, Pasi Kallinen, Alex Kompel, Dion Nicolaas, Derek S. Ray and Yitzhak Sapir maintained the port of NetHack 3.6 for Microsoft Windows. @@ -217,6 +217,9 @@ Derek S. Ray, Alex Smith, Mike Stephenson, Janet Walz and Paul Winner. In early May 2019, another 320 bug fixes along with some enhancements and the adopted curses window port, were released as 3.6.2. +Bart House, who had contributed to the game as a porting team participant +for decades, joined the NetHack Development Team in late May 2019. + The official NetHack web site is maintained by Ken Lorber at http://www.nethack.org/. @@ -241,7 +244,7 @@ of these miscreants in this, the list of Dungeoneers: Andy Church Jochen Erwied Pat Rankin Andy Swanson John Kallen Patric Mueller Ari Huttunen John Rupley Paul Winner - Barton House John S. Bien Pierre Martineau + Bart House John S. Bien Pierre Martineau Benson I. Margulies Johnny Lee Ralf Brown Bill Dyer Jon W{tte Ray Chason Boudewijn Waijers Jonathan Handler Richard Addison diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index a9d828728..8e18ec97d 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -24,7 +24,7 @@ .ds vr "NetHack 3.6 .ds f0 "\*(vr .ds f1 -.ds f2 "October 27, 2019 +.ds f2 "October 31, 2019 . .\" A note on some special characters: .\" \(lq = left double quote @@ -4900,7 +4900,7 @@ and \fBPaul Winner\fP, ported NetHack 3.1 to the PC. \fBMike Engber\fP, \fBDavid Hairston\fP, \fBMichael Hamel\fP, \fBJonathan Handler\fP, \fBJohnny Lee\fP, \fBTim Lennan\fP, \fBRob Menke\fP, and \fBAndy Swanson\fP, developed NetHack 3.1 for the Macintosh, -porting it for MPW. Building on their development, \fBBarton House\fP +porting it for MPW. Building on their development, \fBBart House\fP added a Think C port. .pg \fBTimo Hakulinen\fP ported NetHack 3.1 to OS/2. \fBEric Smith\fP @@ -5059,7 +5059,7 @@ flavors and maintained the X11 interface. \fBKen Lorber\fP, \fBHaoyang Wang\fP, \fBPat Rankin\fP, and \fBDean Luick\fP maintained the port of NetHack 3.6 for Mac OSX. .pg -\fBMichael Allison\fP, \fBDavid Cohrs\fP, \fBBarton House\fP, +\fBMichael Allison\fP, \fBDavid Cohrs\fP, \fBBart House\fP, \fBPasi Kallinen\fP, \fBAlex Kompel\fP, \fBDion Nicolaas\fP, \fBDerek S. Ray\fP and \fBYitzhak Sapir\fP maintained the port of NetHack 3.6 for Microsoft Windows. @@ -5084,6 +5084,9 @@ The NetHack Development Team at the time of release of 3.6.1 consisted of In early May 2019, another 320 bug fixes along with some enhancements and the adopted curses window port, were released as 3.6.2. .pg +\fBBart House\fP, who had contributed to the game as a porting team +participant for decades, joined the NetHack Development Team in late May 2019. +.pg The official NetHack web site is maintained by \fBKen Lorber\fP at .UR http://www.nethack.org/ . @@ -5119,7 +5122,7 @@ Andreas Dorn Jeff Bailey Pasi Kallinen Andy Church Jochen Erwied Pat Rankin Andy Swanson John Kallen Patric Mueller Ari Huttunen John Rupley Paul Winner -Barton House John S. Bien Pierre Martineau +Bart House John S. Bien Pierre Martineau Benson I. Margulies Johnny Lee Ralf Brown Bill Dyer Jon W{tte Ray Chason Boudewijn Waijers Jonathan Handler Richard Addison diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index b3c175766..9be2f073d 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -45,7 +45,7 @@ %.au \author{Original version - Eric S. Raymond\\ (Edited and expanded for 3.6 by Mike Stephenson and others)} -\date{October 22, 2019} +\date{October 31, 2019} \maketitle @@ -5457,7 +5457,7 @@ with help from {\it Ross Brown}, {\it Mike Engber}, {\it David Hairston}, {\it Michael Hamel}, {\it Jonathan Handler}, {\it Johnny Lee}, {\it Tim Lennan}, {\it Rob Menke}, and {\it Andy Swanson}, developed {\it NetHack\/} 3.1 for the Macintosh, porting it for MPW. -Building on their development, {\it Barton House} added a Think C port. +Building on their development, {\it Bart House} added a Think C port. %.pg \medskip @@ -5670,7 +5670,7 @@ maintained the port of {\it NetHack\/} 3.6 for Mac OSX. %.pg \medskip -{\it Michael Allison}, {\it David Cohrs}, {\it Barton House}, +{\it Michael Allison}, {\it David Cohrs}, {\it Bart House}, {\it Pasi Kallinen}, {\it Alex Kompel}, {\it Dion Nicolaas}, {\it Derek S. Ray} and {\it Yitzhak Sapir} maintained the port of {\it NetHack\/} 3.6 for Microsoft Windows. @@ -5704,6 +5704,11 @@ time of release of 3.6.1 consisted of In early May 2019, another 320 bug fixes along with some enhancements and the adopted curses window port, were released as 3.6.2. +%.pg +\medskip +{\it Bart House}, who had contributed to the game as a porting team participant +for decades, joined the {\it NetHack Development Team} in late May 2019. + %.pg \medskip \nd The official {\it NetHack\/} web site is maintained by {\it Ken Lorber} at @@ -5745,7 +5750,7 @@ Andreas Dorn & Jeff Bailey & Pasi Kallinen\\ Andy Church & Jochen Erwied & Pat Rankin\\ Andy Swanson & John Kallen & Patric Mueller\\ Ari Huttunen & John Rupley & Paul Winner\\ -Barton House & John S. Bien & Pierre Martineau\\ +Bart House & John S. Bien & Pierre Martineau\\ Benson I. Margulies & Johnny Lee & Ralf Brown\\ Bill Dyer & Jon W\{tte & Ray Chason\\ Boudewijn Waijers & Jonathan Handler & Richard Addison\\ From 5d5a4610ff2f2ae36e8bd40116371703574be27e Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 31 Oct 2019 19:22:05 -0400 Subject: [PATCH 4/7] try to improve some reported TeX Guidebook to pdf results --- doc/Guidebook.tex | 122 +++++++++++++++++++++++----------------------- 1 file changed, 60 insertions(+), 62 deletions(-) diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 9be2f073d..87cf04452 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -1130,7 +1130,7 @@ slot to another so that it has a letter which is more meaningful for you or that it will appear in a particular location when inventory listings are displayed. You can move to a currently empty slot, or if the destination is -occupied--and won't merge--the item there will swap slots with the one +occupied---and won't merge---the item there will swap slots with the one being moved. ``{\tt \#adjust}'' can also be used to split a stack of objects; when choosing the item to adjust, enter a count prior to its letter.\\ @@ -2044,9 +2044,9 @@ will result in it disappearing from your map, similarly if it is the one who moved rather than you. %.pg -However, if you encounter a monster which you can't see or sense-- -perhaps it is invisible and has just tapped you on the noggin-- -a special ``remembered, unseen monster'' marker will be displayed at +However, if you encounter a monster which you can't see or +sense---perhaps it is invisible and has just tapped you on the +noggin---a special ``remembered, unseen monster'' marker will be displayed at the location where you think it is. That will persist until you have proven that there is no monster there, even if the unseen monster @@ -2326,7 +2326,7 @@ But first you need to have a weapon in each hand. (Note that your two weapons are not fully equal; the one in the hand you normally wield with is considered primary and the other one is considered secondary. The most noticeable difference is -after you stop--or before you begin, for that matter--wielding +after you stop---or before you begin, for that matter---wielding two weapons at once. The primary is your wielded weapon and the secondary is just an item in your inventory that's been designated as alternate weapon.) @@ -2558,7 +2558,7 @@ The commands to use rings are `{\tt P}' (put on) and `{\tt R}' (remove). %.pg Spellbooks are tomes of mighty magic. When studied with the `{\tt r}' (read) command, they transfer to the reader the knowledge of a spell (and -therefore eventually become unreadable) --- unless the attempt backfires. +therefore eventually become unreadable)---unless the attempt backfires. Reading a cursed spellbook or one with mystic runes beyond your ken can be harmful to your health! @@ -2701,9 +2701,9 @@ you are carrying (shopkeepers aside). Normally, if you have seen an object at a particular map location and move to another location where you can't directly see that object any more, if will continue to be displayed on your map. -That remains the case even if it is not actually there any more-- -perhaps a monster has picked it up or it has rotted away-- -until you can see or feel that location again. +That remains the case even if it is not actually there any +more---perhaps a monster has picked it up or it has rotted +away---until you can see or feel that location again. One notable exception is that if the object gets covered by the ``remembered, unseen monster'' marker. When that marker is later removed @@ -3033,6 +3033,8 @@ Override one or more symbols in the symbol set used for all dungeon levels except for the special rogue level. See the ``Modifying {\it NetHack\/} Symbols'' section. %.pg + +%.lp "" Example: %.sd \begin{verbatim} @@ -4382,158 +4384,158 @@ Below are the special commands you can rebind. Some of them can be bound to same keys with no problems, others are in the same ``context'', and if bound to same keys, only one of those commands will be available. Special command can only be bound to a single key. +\elist %.pg -\blist{} +\blist{\itemindent 10mm \labelwidth 15mm \rightmargin 20mm} %.lp -\item{\bb{count}} +\item[{\bb{count}}] Prefix key to start a count, to repeat a command this many times. With {\it number\verb+_+pad\/} only. Default is `{\tt n}'. %.lp -\item{\bb{doinv}} +\item[{\bb{doinv}}] Show inventory. With {\it number\verb+_+pad\/} only. Default is `{\tt 0}'. %.lp -\item{\bb{fight}} +\item[{\bb{fight}}] Prefix key to force fight a direction. Default is `{\tt F}'. %.lp -\item{\bb{fight.numpad}} +\item[{\bb{fight.numpad}}] Prefix key to force fight a direction. With {\it number\verb+_+pad\/} only. Default is `{\tt -}'. %.lp -\item{\bb{getdir.help}} +\item[{\bb{getdir.help}}] When asked for a direction, the key to show the help. Default is `{\tt ?}'. %.lp -\item{\bb{getdir.self}} +\item[{\bb{getdir.self}}] When asked for a direction, the key to target yourself. Default is `{\tt .}'. %.lp -\item{\bb{getdir.self2}} +\item[{\bb{getdir.self2}}] When asked for a direction, the key to target yourself. Default is `{\tt s}'. %.lp -\item{\bb{getpos.autodescribe}} +\item[{\bb{getpos.autodescribe}}] When asked for a location, the key to toggle {\it autodescribe\/}. Default is `{\tt \#}'. %.lp -\item{\bb{getpos.all.next}} +\item[{\bb{getpos.all.next}}] When asked for a location, the key to go to next closest interesting thing. Default is `{\tt a}'. %.lp -\item{\bb{getpos.all.prev}} +\item[{\bb{getpos.all.prev}}] When asked for a location, the key to go to previous closest interesting thing. Default is `{\tt A}'. %.lp -\item{\bb{getpos.door.next}} +\item[{\bb{getpos.door.next}}] When asked for a location, the key to go to next closest door or doorway. Default is `{\tt d}'. %.lp -\item{\bb{getpos.door.prev}} +\item[{\bb{getpos.door.prev}}] When asked for a location, the key to go to previous closest door or doorway. Default is `{\tt D}'. %.lp -\item{\bb{getpos.help}} +\item[{\bb{getpos.help}}] When asked for a location, the key to show help. Default is `{\tt ?}'. %.lp -\item{\bb{getpos.mon.next}} +\item[{\bb{getpos.mon.next}}] When asked for a location, the key to go to next closest monster. Default is `{\tt m}'. %.lp -\item{\bb{getpos.mon.prev}} +\item[{\bb{getpos.mon.prev}}] When asked for a location, the key to go to previous closest monster. Default is `{\tt M}'. %.lp -\item{\bb{getpos.obj.next}} +\item[{\bb{getpos.obj.next}}] When asked for a location, the key to go to next closest object. Default is `{\tt o}'. %.lp -\item{\bb{getpos.obj.prev}} +\item[{\bb{getpos.obj.prev}}] When asked for a location, the key to go to previous closest object. Default is `{\tt O}'. %.lp -\item{\bb{getpos.menu}} +\item[{\bb{getpos.menu}}] When asked for a location, and using one of the next or previous keys to cycle through targets, toggle showing a menu instead. Default is `{\tt !}'. %.lp -\item{\bb{getpos.moveskip}} +\item[{\bb{getpos.moveskip}}] When asked for a location, and using the shifted movement keys or meta-digit keys to fast-move around, move by skipping the same glyphs instead of by 8 units. Default is `{\tt *}'. %.lp -\item{\bb{getpos.filter}} +\item[{\bb{getpos.filter}}] When asked for a location, change the filtering mode when using one of the next or previous keys to cycle through targets. Toggles between no filtering, in view only, and in the same area only. Default is `{\tt "}'. %.lp -\item{\bb{getpos.pick}} +\item[{\bb{getpos.pick}}] When asked for a location, the key to choose the location, and possibly ask for more info. Default is `{\tt .}'. %.lp -\item{\bb{getpos.pick.once}} +\item[{\bb{getpos.pick.once}}] When asked for a location, the key to choose the location, and skip asking for more info. Default is `{\tt ,}'. %.lp -\item{\bb{getpos.pick.quick}} +\item[{\bb{getpos.pick.quick}}] When asked for a location, the key to choose the location, skip asking for more info, and exit the location asking loop. Default is `{\tt ;}'. %.lp -\item{\bb{getpos.pick.verbose}} +\item[{\bb{getpos.pick.verbose}}] When asked for a location, the key to choose the location, and show more info without asking. Default is `{\tt :}'. %.lp -\item{\bb{getpos.self}} +\item[{\bb{getpos.self}}] When asked for a location, the key to go to your location. Default is `{\tt @}'. %.lp -\item{\bb{getpos.unexplored.next}} +\item[{\bb{getpos.unexplored.next}}] When asked for a location, the key to go to next closest unexplored location. Default is `{\tt x}'. %.lp -\item{\bb{getpos.unexplored.prev}} +\item[{\bb{getpos.unexplored.prev}}] When asked for a location, the key to go to previous closest unexplored location. Default is `{\tt X}'. %.lp -\item{\bb{getpos.valid}} +\item[{\bb{getpos.valid}}] When asked for a location, the key to go to show valid target locations. Default is `{\tt \$}'. %.lp -\item{\bb{getpos.valid.next}} +\item[{\bb{getpos.valid.next}}] When asked for a location, the key to go to next closest valid location. Default is `{\tt z}'. %.lp -\item{\bb{getpos.valid.prev}} +\item[{\bb{getpos.valid.prev}}] When asked for a location, the key to go to previous closest valid location. Default is `{\tt Z}'. %.lp -\item{\bb{nopickup}} +\item[{\bb{nopickup}}] Prefix key to move without picking up items. Default is `{\tt m}'. %.lp -\item{\bb{redraw}} +\item[{\bb{redraw}}] Key to redraw the screen. Default is `{\tt \^{}R}'. %.lp -\item{\bb{redraw.numpad}} +\item[{\bb{redraw.numpad}}] Key to redraw the screen. With {\it number\verb+_+pad\/} only. Default is `{\tt \^{}L}'. %.lp -\item{\bb{repeat}} +\item[{\bb{repeat}}] Key to repeat previous command. Default is `{\tt \^{}A}'. %.lp -\item{\bb{reqmenu}} +\item[{\bb{reqmenu}}] Prefix key to request menu from some commands. Default is `{\tt m}'. %.lp -\item{\bb{run}} +\item[{\bb{run}}] Prefix key to run towards a direction. Default is `{\tt G}'. %.lp -\item{\bb{run.nopickup}} +\item[{\bb{run.nopickup}}] Prefix key to run towards a direction without picking up items on the way. Default is `{\tt M}'. %.lp -\item{\bb{run.numpad}} +\item[{\bb{run.numpad}}] Prefix key to run towards a direction. With {\it number\verb+_+pad\/} only. Default is `{\tt 5}'. %.lp -\item{\bb{rush}} +\item[{\bb{rush}}] Prefix key to rush towards a direction. Default is `{\tt g}'. \elist -\elist %.hn 2 @@ -4737,6 +4739,8 @@ combination with any of the other attributes. To specify both a color and an attribute, use `\&' to combine them. To specify multiple attributes, use `+' to combine those. + +%.lp "" For example: {\tt magenta\&inverse+dim}. Note that the display may substitute or ignore particular attributes @@ -4789,23 +4793,19 @@ percentage or absolute number threshold, or text to match against. \blist{} %.lp "*" -\item{\bb{}} -``{\tt always}'' will set the default attributes for that field. +\item[{\tt always}] will set the default attributes for that field. %.lp "*" -\item{\bb{}} -``{\tt up}'' and ``{\tt down}'' set the field attributes for when the field +\item[{\tt up} and ``{\tt down}''] set the field attributes for when the field value changes upwards or downwards. This attribute times out after {\tt statushilites} turns. %.lp "*" -\item{\bb{}} -``{\tt changed}'' sets the field attribute for when the field value +\item[{\tt changed}] sets the field attribute for when the field value changes. This attribute times out after {\tt statushilites} turns. (If a field has both a ``changed'' rule and an ``up'' or ``down'' rule which matches a change in the field's value, the ``up'' or ``down'' one takes precedence.) %.lp "*" -\item{\bb{}} -percentage sets the field attribute when the field value +\item[{\tt percentage}] sets the field attribute when the field value matches the percentage. It is specified as a number between 0 and 100, followed by `{\tt \%}' (percent sign). @@ -4833,8 +4833,7 @@ exactly 1 experience point short of the next level. % percentage will remain at 0\% no matter have many additional experience % points you earn.) %.lp "*" -\item{\bb{}} -absolute value sets the attribute when the field value +\item[{\tt absolute}] value sets the attribute when the field value matches that number. The number must be 0 or higher, except for ``{\it armor-class\/} which allows negative values, and may optionally be preceded by `{\tt =}'. @@ -4843,8 +4842,7 @@ it also matches when value is below or above. If the prefix is `{\tt <}' or `{\tt >}', only match when strictly above or below. %.lp "*" -\item{\bb{}} -text match sets the attribute when the field value matches the text. +\item[{\tt text}] match sets the attribute when the field value matches the text. Text matches can only be used for ``{\it alignment\/}'', ``{\it carrying-capacity\/}'', ``{\it hunger\/}'', ``{\it dungeon-level\/}'', and ``{\it title\/}''. From e33dfed4561d8184d17f751dde901294387183f7 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 31 Oct 2019 19:43:59 -0400 Subject: [PATCH 5/7] quiet a mingw warning --- sys/winnt/windmain.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sys/winnt/windmain.c b/sys/winnt/windmain.c index f88fbaa37..2cfab8c91 100644 --- a/sys/winnt/windmain.c +++ b/sys/winnt/windmain.c @@ -21,15 +21,17 @@ extern LONG GetCurrentPackageFullName(UINT32 *packageFullNameLength, PWSTR packageFullName); extern HRESULT SHGetKnownFolderPath(REFKNOWNFOLDERID rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath); +#ifndef DEFINE_KNOWN_FOLDER #ifdef INITGUID #define DEFINE_KNOWN_FOLDER(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) const GUID DECLSPEC_SELECTANY name = { l, w1, w2,{ b1, b2, b3, b4, b5, b6, b7, b8 } } #else #define DEFINE_KNOWN_FOLDER(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) const GUID name -#endif +#endif /* INITGUID */ +#endif /* DEFINE_KNOWN_FOLDER */ DEFINE_KNOWN_FOLDER (FOLDERID_ProgramData, 0x62ab5d82, 0xfdc1, 0x4dc3, 0xa9, 0xdd, 0x07, 0x0d, 0x1d, 0x49, 0x5d, 0x97); DEFINE_KNOWN_FOLDER (FOLDERID_LocalAppData, 0xf1b32785, 0x6fba, 0x4fcf, 0x9d, 0x55, 0x7b, 0x8e, 0x7f, 0x15, 0x70, 0x91); DEFINE_KNOWN_FOLDER (FOLDERID_Profile, 0x5e6c858f, 0x0e22, 0x4760, 0x9a, 0xfe, 0xea, 0x33, 0x17, 0xb6, 0x71, 0x73); -#endif +#endif /* __MINGW32__ */ #if 0 #include "wintty.h" From 215815c0b59c27e65d7b053bbb437ac411c85f5b Mon Sep 17 00:00:00 2001 From: Bart House Date: Thu, 31 Oct 2019 20:18:27 -0700 Subject: [PATCH 6/7] Changes to player selection dialog support to respond to per-monitor DPI. --- win/win32/NetHackW.rc | 10 +- win/win32/mhdlg.c | 541 ++++++++++++++++++++++-------- win/win32/resource.h | 7 +- win/win32/vs2017/NetHackW.vcxproj | 14 +- 4 files changed, 419 insertions(+), 153 deletions(-) diff --git a/win/win32/NetHackW.rc b/win/win32/NetHackW.rc index 1ac42d05d..59381dd90 100644 --- a/win/win32/NetHackW.rc +++ b/win/win32/NetHackW.rc @@ -172,12 +172,12 @@ BEGIN CONTROL "Chaotic",IDC_PLSEL_ALIGN_CHAOTIC,"Button",BS_AUTORADIOBUTTON,168,72,38,10 CONTROL "Male",IDC_PLSEL_GENDER_MALE,"Button",BS_AUTORADIOBUTTON | WS_GROUP,168,108,30,10 CONTROL "Female",IDC_PLSEL_GENDER_FEMALE,"Button",BS_AUTORADIOBUTTON,168,120,38,10 - GROUPBOX "Alignment",IDC_STATIC,162,36,48,54 - GROUPBOX "Gender",IDC_STATIC,162,96,48,42 - GROUPBOX "Role",IDC_STATIC,6,36,72,150 - GROUPBOX "Race",IDC_STATIC,84,36,72,72 + GROUPBOX "Alignment",IDC_PLSEL_ALIGNMENT_GROUP,162,36,48,54 + GROUPBOX "Gender",IDC_PLSEL_GENDER_GROUP,162,96,48,42 + GROUPBOX "Role",IDC_PLSEL_ROLE_GROUP,6,36,72,150 + GROUPBOX "Race",IDC_PLSEL_RACE_GROUP,84,36,72,72 PUSHBUTTON "Random",IDC_PLSEL_RANDOM,90,192,54,14,WS_GROUP - GROUPBOX "Name",IDC_STATIC,6,0,120,30 + GROUPBOX "Name",IDC_PLSEL_NAME_GROUP,6,0,120,30 CONTROL "",IDC_PLSEL_ROLE_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_OWNERDRAWFIXED | LVS_ALIGNLEFT | LVS_NOSCROLL | LVS_NOCOLUMNHEADER | WS_BORDER | WS_GROUP | WS_TABSTOP,12,48,60,130 CONTROL "",IDC_PLSEL_RACE_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_OWNERDRAWFIXED | LVS_ALIGNLEFT | LVS_NOSCROLL | LVS_NOCOLUMNHEADER | WS_BORDER | WS_GROUP | WS_TABSTOP,90,48,60,51 END diff --git a/win/win32/mhdlg.c b/win/win32/mhdlg.c index 51134332c..cb76c9a18 100644 --- a/win/win32/mhdlg.c +++ b/win/win32/mhdlg.c @@ -4,6 +4,7 @@ /* various dialog boxes are defined here */ +#include "win10.h" #include "winMS.h" #include "hack.h" #include "func_tab.h" @@ -12,6 +13,7 @@ #include + /*---------------------------------------------------------------*/ /* data for getlin dialog */ struct getlin_data { @@ -276,22 +278,68 @@ ExtCmdDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) /*---------------------------------------------------------------*/ /* player selector dialog */ + +/* NOTE: this enumeration is in control tab order */ +enum player_selector_control { + psc_name_group, + psc_role_group, + psc_race_group, + psc_alignment_group, + psc_gender_group, + psc_name_box, + psc_role_list, + psc_race_list, + psc_lawful_button, + psc_neutral_button, + psc_chaotic_button, + psc_male_button, + psc_female_button, + psc_play_button, + psc_random_button, + psc_quit_button, + psc_control_count +}; + +static const s_psc_id[psc_control_count] = { + IDC_PLSEL_NAME_GROUP, + IDC_PLSEL_ROLE_GROUP, + IDC_PLSEL_RACE_GROUP, + IDC_PLSEL_ALIGNMENT_GROUP, + IDC_PLSEL_GENDER_GROUP, + IDC_PLSEL_NAME, + IDC_PLSEL_ROLE_LIST, + IDC_PLSEL_RACE_LIST, + IDC_PLSEL_ALIGN_LAWFUL, + IDC_PLSEL_ALIGN_NEUTRAL, + IDC_PLSEL_ALIGN_CHAOTIC, + IDC_PLSEL_GENDER_MALE, + IDC_PLSEL_GENDER_FEMALE, + IDOK, + IDC_PLSEL_RANDOM, + IDCANCEL +}; + +typedef struct { + int id; + POINT pos; + SIZE size; + HWND hWnd; +} control_t; + typedef struct plsel_data { + HWND dialog; + HWND focus; + control_t controls[psc_control_count]; + SIZE client_size; int config_race; int config_role; int config_gender; int config_alignment; - HWND control_role; - HWND control_race; - HWND control_genders[ROLE_GENDERS]; - HWND control_aligns[ROLE_ALIGNS]; int role_count; int race_count; - HWND focus; } plsel_data_t; INT_PTR CALLBACK PlayerSelectorDlgProc(HWND, UINT, WPARAM, LPARAM); -static void plselInitDialog(HWND hWnd); static void plselAdjustSelections(HWND hWnd); static boolean plselRandomize(plsel_data_t * data); static BOOL plselDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam); @@ -322,38 +370,314 @@ mswin_player_selection_window() return ok; } +int +list_view_height(HWND hWnd, int count) +{ + return (ListView_ApproximateViewRect(hWnd, -1, -1, count)) >> 16; +} + +/* calculate the size and position of the controls taking into account + the per-monitor DPI expressed as a scaling factor on sizes at 96 DPI */ +void +calculate_player_selector_layout(plsel_data_t * data) +{ + MonitorInfo monitorInfo; + win10_monitor_info(data->dialog, &monitorInfo); + + double scale = monitorInfo.scale; + + /* Note these hard coded sizes are in 96DPI pixels and must be + scaled by the per-monitor DPI scaling factor */ + int list_width = (int) (120 * scale); + int group_border = (int) (16 * scale); + int client_border = (int) (16 * scale); + int group_spacing = (int) (16 * scale); + int button_width = (int) (80 * scale); + int button_height = (int) (28 * scale); + + /* set control sizes */ + control_t * name_box = &data->controls[psc_name_box]; + name_box->size.cx = (int) (280 * scale); + name_box->size.cy = (int) (24 * scale); + + control_t * role_list = &data->controls[psc_role_list]; + /* NOTE: we dont' scale the list view reported height as it appears these + values are the actual size the control will be drawn at using the + existing DPI value */ + role_list->size.cy = list_view_height(role_list->hWnd, data->role_count); + role_list->size.cx = list_width; + + control_t * race_list = &data->controls[psc_race_list]; + race_list->size.cy = list_view_height(race_list->hWnd, data->race_count); + race_list->size.cx = list_width; + + for(int i = psc_lawful_button; i <= psc_quit_button; i++) { + data->controls[i].size.cx = button_width; + data->controls[i].size.cy = button_height; + } + + for(int i = 0; i < 3; i++) { + control_t * group_control = &data->controls[psc_name_group + i]; + control_t * inner_control = &data->controls[psc_name_box + i]; + group_control->size.cx = inner_control->size.cx + (2 * group_border); + group_control->size.cy = inner_control->size.cy + (2 * group_border); + } + + control_t * alignment_group = &data->controls[psc_alignment_group]; + alignment_group->size.cx = button_width + (2 * group_border); + alignment_group->size.cy = (3 * button_height) + (2 * group_border); + + control_t * gender_group = &data->controls[psc_gender_group]; + gender_group->size.cx = button_width + (2 * group_border); + gender_group->size.cy = (2 * button_height) + (2 * group_border); + + /* set control positions */ + control_t * name_group = &data->controls[psc_name_group]; + name_group->pos.x = client_border; + name_group->pos.y = client_border; + + control_t * role_group = &data->controls[psc_role_group]; + role_group->pos.x = client_border; + role_group->pos.y = name_group->pos.y + name_group->size.cy + group_spacing; + + control_t * race_group = &data->controls[psc_race_group]; + race_group->pos.x = role_group->pos.x + role_group->size.cx + group_spacing; + race_group->pos.y = role_group->pos.y; + + for(int i = 0; i < 3; i++) { + control_t * group_control = &data->controls[psc_name_group + i]; + control_t * inner_control = &data->controls[psc_name_box + i]; + inner_control->pos.x = group_control->pos.x + group_border; + inner_control->pos.y = group_control->pos.y + group_border; + } + + alignment_group->pos.x = race_group->pos.x + race_group->size.cx + group_spacing; + alignment_group->pos.y = race_group->pos.y; + + for(int i = psc_lawful_button; i <= psc_chaotic_button; i++) { + data->controls[i].pos.x = alignment_group->pos.x + group_border; + data->controls[i].pos.y = alignment_group->pos.y + group_border + + ((i -psc_lawful_button) * button_height); + } + + gender_group->pos.x = alignment_group->pos.x; + gender_group->pos.y = alignment_group->pos.y + alignment_group->size.cy + group_spacing; + + for(int i = psc_male_button; i <= psc_female_button; i++) { + data->controls[i].pos.x = gender_group->pos.x + group_border; + data->controls[i].pos.y = gender_group->pos.y + group_border + + ((i - psc_male_button) * button_height); + } + + int group_bottom = role_group->pos.y + role_group->size.cy; + if (group_bottom < race_group->pos.y + race_group->size.cy) + group_bottom = race_group->pos.y + race_group->size.cy; + if (group_bottom < gender_group->pos.y + gender_group->size.cy) + group_bottom = gender_group->pos.y + gender_group->size.cy; + + control_t * play_button = &data->controls[psc_play_button]; + play_button->pos.y = group_bottom + group_spacing; + play_button->pos.x = role_group->pos.x; + + control_t * random_button = &data->controls[psc_random_button]; + random_button->pos.y = play_button->pos.y; + random_button->pos.x = race_list->pos.x; + + control_t * quit_button = &data->controls[psc_quit_button]; + quit_button->pos.y = play_button->pos.y; + quit_button->pos.x = data->controls[psc_female_button].pos.x; + + data->client_size.cx = alignment_group->pos.x + alignment_group->size.cx; + data->client_size.cy = quit_button->pos.y + quit_button->size.cy; + data->client_size.cx += client_border; + data->client_size.cy += client_border; +} + +void +get_rect_size(RECT * rect, SIZE * size) +{ + size->cx = rect->right - rect->left + 1; + size->cy = rect->bottom - rect->top + 1; +} + +/* center given dialog in the main window */ +void +center_dialog(HWND dialog) +{ + RECT main_rect; + SIZE main_size; + RECT dialog_rect; + SIZE dialog_size; + POINT pos; + + GetWindowRect(GetNHApp()->hMainWnd, &main_rect); + get_rect_size(&main_rect, &main_size); + + GetWindowRect(dialog, &dialog_rect); + get_rect_size(&dialog_rect, &dialog_size); + + pos.x = main_rect.left + (main_size.cx - dialog_size.cx) / 2; + pos.y = main_rect.top + (main_size.cy - dialog_size.cy) / 2; + + MoveWindow(dialog, pos.x, pos.y, dialog_size.cx, dialog_size.cy, + TRUE); +} + +/* size the dialog such that it has the given client rect size */ +void +size_dialog(HWND dialog, SIZE new_client_size) +{ + RECT dialog_rect; + SIZE dialog_size; + RECT client_rect; + SIZE client_size; + + GetWindowRect(dialog, &dialog_rect); + get_rect_size(&dialog_rect, &dialog_size); + + GetClientRect(dialog, &client_rect); + get_rect_size(&client_rect, &client_size); + + dialog_size.cx += new_client_size.cx - client_size.cx; + dialog_size.cy += new_client_size.cy - client_size.cy; + + MoveWindow(dialog, dialog_rect.left, dialog_rect.top, + dialog_size.cx, dialog_size.cy, TRUE); +} + +/* helper routine to move all controls according to there position + and size information */ +void +move_controls(control_t * controls, int count) +{ + control_t * control = controls; + while(count-- > 0) { + MoveWindow(control->hWnd, control->pos.x, control->pos.y, + control->size.cx, control->size.cy, TRUE); + control++; + } +} + +/* adjust the size and positions of all controls in the player + selection dialog taking into account the per-monitor DPI. */ +void +do_player_selector_layout(plsel_data_t * data) +{ + calculate_player_selector_layout(data); + move_controls(data->controls, psc_control_count); + size_dialog(data->dialog, data->client_size); +} + +/* initialize player selector dialog */ +void +plselInitDialog(struct plsel_data * data) +{ + TCHAR wbuf[BUFSZ]; + LVCOLUMN lvcol; + + SetWindowLongPtr(data->dialog, GWLP_USERDATA, (LONG_PTR) data); + + for(int i = 0; i < psc_control_count; i++) { + data->controls[i].id = s_psc_id[i]; + data->controls[i].hWnd = GetDlgItem(data->dialog, s_psc_id[i]); + } + + control_t * role_list = &data->controls[psc_role_list]; + + ZeroMemory(&lvcol, sizeof(lvcol)); + lvcol.mask = LVCF_WIDTH; + lvcol.cx = 1024; + + /* build role list */ + ListView_InsertColumn(role_list->hWnd, 0, &lvcol); + data->role_count = 0; + for (int i = 0; roles[i].name.m; i++) { + LVITEM lvitem; + ZeroMemory(&lvitem, sizeof(lvitem)); + + lvitem.mask = LVIF_STATE | LVIF_TEXT; + lvitem.iItem = i; + lvitem.iSubItem = 0; + lvitem.state = 0; + lvitem.stateMask = LVIS_FOCUSED; + if (flags.female && roles[i].name.f) + lvitem.pszText = NH_A2W(roles[i].name.f, wbuf, BUFSZ); + else + lvitem.pszText = NH_A2W(roles[i].name.m, wbuf, BUFSZ); + if (ListView_InsertItem(role_list->hWnd, &lvitem) == -1) { + panic("cannot insert menu item"); + } + data->role_count++; + } + + /* build race list */ + control_t * race_list = &data->controls[psc_race_list]; + ListView_InsertColumn(race_list->hWnd, 0, &lvcol); + data->race_count = 0; + for (int i = 0; races[i].noun; i++) { + LVITEM lvitem; + ZeroMemory(&lvitem, sizeof(lvitem)); + + lvitem.mask = LVIF_STATE | LVIF_TEXT; + lvitem.iItem = i; + lvitem.iSubItem = 0; + lvitem.state = 0; + lvitem.stateMask = LVIS_FOCUSED; + lvitem.pszText = NH_A2W(races[i].noun, wbuf, BUFSZ); + if (ListView_InsertItem(race_list->hWnd, &lvitem) == -1) { + panic("cannot insert menu item"); + } + data->race_count++; + } + + /* set gender radio button state */ + control_t * gender_buttons = &data->controls[psc_male_button]; + for (int i = 0; i < ROLE_GENDERS; i++) + Button_Enable(gender_buttons[i].hWnd, TRUE); + + Button_SetCheck(data->controls[psc_male_button].hWnd, BST_CHECKED); + + /* set alignment radio button state */ + control_t * alignment_buttons = &data->controls[psc_lawful_button]; + for (int i = 0; i < ROLE_ALIGNS; i++) + Button_Enable(alignment_buttons[i].hWnd, TRUE); + + Button_SetCheck(data->controls[psc_lawful_button].hWnd, BST_CHECKED); + + /* set player name */ + control_t * name_box = &data->controls[psc_name_box]; + SetDlgItemText(data->dialog, name_box->id, NH_A2W(plname, wbuf, sizeof(wbuf))); + + plselRandomize(data); + + /* populate select boxes */ + plselAdjustSelections(data->dialog); + + /* set tab order */ + control_t * control = &data->controls[psc_quit_button]; + for(int i = psc_quit_button; i >= psc_name_box; i--, control++) + SetWindowPos(control->hWnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + + do_player_selector_layout(data); + + center_dialog(data->dialog); +} + INT_PTR CALLBACK PlayerSelectorDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { - struct plsel_data *data; - RECT main_rt, dlg_rt; - SIZE dlg_sz; + plsel_data_t *data; switch (message) { case WM_INITDIALOG: - data = (struct plsel_data *) lParam; - SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR) data); - /* center dialog in the main window */ - GetWindowRect(GetNHApp()->hMainWnd, &main_rt); - GetWindowRect(hWnd, &dlg_rt); - dlg_sz.cx = dlg_rt.right - dlg_rt.left; - dlg_sz.cy = dlg_rt.bottom - dlg_rt.top; + data = (plsel_data_t *) lParam; + data->dialog = hWnd; - dlg_rt.left = (main_rt.left + main_rt.right - dlg_sz.cx) / 2; - dlg_rt.right = dlg_rt.left + dlg_sz.cx; - dlg_rt.top = (main_rt.top + main_rt.bottom - dlg_sz.cy) / 2; - dlg_rt.bottom = dlg_rt.top + dlg_sz.cy; - MoveWindow(hWnd, (main_rt.left + main_rt.right - dlg_sz.cx) / 2, - (main_rt.top + main_rt.bottom - dlg_sz.cy) / 2, dlg_sz.cx, - dlg_sz.cy, TRUE); - - /* init dialog */ - plselInitDialog(hWnd); + plselInitDialog(data); /* tell windows to set the focus */ return TRUE; - break; case WM_DRAWITEM: if (wParam == IDC_PLSEL_ROLE_LIST || wParam == IDC_PLSEL_RACE_LIST) @@ -367,20 +691,23 @@ PlayerSelectorDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) data = (struct plsel_data *) GetWindowLongPtr(hWnd, GWLP_USERDATA); + control_t * role_control = &data->controls[psc_role_list]; + control_t * race_control = &data->controls[psc_race_list]; + switch (nmhdr->code) { case LVN_KEYDOWN: { LPNMLVKEYDOWN lpnmkeydown = (LPNMLVKEYDOWN) lParam; if (lpnmkeydown->wVKey == ' ') { - if (control == data->control_role) { - int i = ListView_GetNextItem(data->control_role, -1, LVNI_FOCUSED); - assert(i == -1 || ListView_GetNextItem(data->control_role, i, LVNI_FOCUSED) == -1); + if (control == role_control->hWnd) { + int i = ListView_GetNextItem(control, -1, LVNI_FOCUSED); + assert(i == -1 || ListView_GetNextItem(control, i, LVNI_FOCUSED) == -1); flags.initrole = i; plselAdjustSelections(hWnd); - } else if (control == data->control_race) { - int i = ListView_GetNextItem(data->control_race, -1, LVNI_FOCUSED); - assert(i == -1 || ListView_GetNextItem(data->control_race, i, LVNI_FOCUSED) == -1); + } else if (control == race_control->hWnd) { + int i = ListView_GetNextItem(control, -1, LVNI_FOCUSED); + assert(i == -1 || ListView_GetNextItem(control, i, LVNI_FOCUSED) == -1); if (ok_race(flags.initrole, i, ROLE_RANDOM, ROLE_RANDOM)) { flags.initrace = i; plselAdjustSelections(hWnd); @@ -395,10 +722,10 @@ PlayerSelectorDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) int i = lpnmitem->iItem; if (i == -1) return FALSE; - if (control == data->control_role) { + if (control == role_control->hWnd) { flags.initrole = i; plselAdjustSelections(hWnd); - } else if(control == data->control_race) { + } else if(control == race_control->hWnd) { if (ok_race(flags.initrole, i, ROLE_RANDOM, ROLE_RANDOM)) { flags.initrace = i; plselAdjustSelections(hWnd); @@ -408,12 +735,12 @@ PlayerSelectorDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) break; case NM_KILLFOCUS: { - if (data->focus == data->control_race) { + if (data->focus == race_control->hWnd) { data->focus = NULL; - ListView_RedrawItems(data->control_race, 0, data->race_count - 1); - } else if (data->focus == data->control_role) { + ListView_RedrawItems(race_control->hWnd, 0, data->race_count - 1); + } else if (data->focus == role_control->hWnd) { data->focus = NULL; - ListView_RedrawItems(data->control_role, 0, data->role_count - 1); + ListView_RedrawItems(role_control->hWnd, 0, data->role_count - 1); } } break; @@ -421,11 +748,11 @@ PlayerSelectorDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { data->focus = control; - if (control == data->control_race) { - data->focus = data->control_race; + if (control == race_control->hWnd) { + data->focus = control; plselAdjustSelections(hWnd); - } else if (control == data->control_role) { - data->focus = data->control_role; + } else if (control == role_control->hWnd) { + data->focus = control; plselAdjustSelections(hWnd); } } @@ -478,109 +805,29 @@ PlayerSelectorDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) } break; + + case WM_DPICHANGED: + { + data = (struct plsel_data *) GetWindowLongPtr(hWnd, GWLP_USERDATA); + + do_player_selector_layout(data); + + InvalidateRect(hWnd, NULL, TRUE); + } break; } + return FALSE; } -/* initialize player selector dialog */ -void -plselInitDialog(HWND hWnd) -{ - struct plsel_data * data = (plsel_data_t *) GetWindowLongPtr(hWnd, GWLP_USERDATA); - TCHAR wbuf[BUFSZ]; - LVCOLUMN lvcol; - data->control_role = GetDlgItem(hWnd, IDC_PLSEL_ROLE_LIST); - data->control_race = GetDlgItem(hWnd, IDC_PLSEL_RACE_LIST); - - ZeroMemory(&lvcol, sizeof(lvcol)); - lvcol.mask = LVCF_WIDTH; - lvcol.cx = GetSystemMetrics(SM_CXFULLSCREEN); - - /* build role list */ - ListView_InsertColumn(data->control_role, 0, &lvcol); - data->role_count = 0; - for (int i = 0; roles[i].name.m; i++) { - LVITEM lvitem; - ZeroMemory(&lvitem, sizeof(lvitem)); - - lvitem.mask = LVIF_STATE | LVIF_TEXT; - lvitem.iItem = i; - lvitem.iSubItem = 0; - lvitem.state = 0; - lvitem.stateMask = LVIS_FOCUSED; - if (flags.female && roles[i].name.f) - lvitem.pszText = NH_A2W(roles[i].name.f, wbuf, BUFSZ); - else - lvitem.pszText = NH_A2W(roles[i].name.m, wbuf, BUFSZ); - if (ListView_InsertItem(data->control_role, &lvitem) == -1) { - panic("cannot insert menu item"); - } - data->role_count++; - } - - /* build race list */ - ListView_InsertColumn(data->control_race, 0, &lvcol); - data->race_count = 0; - for (int i = 0; races[i].noun; i++) { - LVITEM lvitem; - ZeroMemory(&lvitem, sizeof(lvitem)); - - lvitem.mask = LVIF_STATE | LVIF_TEXT; - lvitem.iItem = i; - lvitem.iSubItem = 0; - lvitem.state = 0; - lvitem.stateMask = LVIS_FOCUSED; - lvitem.pszText = NH_A2W(races[i].noun, wbuf, BUFSZ); - if (ListView_InsertItem(data->control_race, &lvitem) == -1) { - panic("cannot insert menu item"); - } - data->race_count++; - } - - for(int i = 0; i < ROLE_GENDERS; i++) - data->control_genders[i] = GetDlgItem(hWnd, IDC_PLSEL_GENDER_MALE + i); - - for(int i = 0; i < ROLE_ALIGNS; i++) - data->control_aligns[i] = GetDlgItem(hWnd, IDC_PLSEL_ALIGN_LAWFUL + i); - - /* set gender radio button state */ - for (int i = 0; i < ROLE_GENDERS; i++) - Button_Enable(data->control_genders[i], TRUE); - - Button_SetCheck(data->control_genders[0], BST_CHECKED); - - /* set alignment radio button state */ - for (int i = 0; i < ROLE_ALIGNS; i++) - Button_Enable(data->control_aligns[i], TRUE); - - Button_SetCheck(data->control_aligns[0], BST_CHECKED); - - /* set player name */ - SetDlgItemText(hWnd, IDC_PLSEL_NAME, NH_A2W(plname, wbuf, sizeof(wbuf))); - - plselRandomize(data); - - /* populate select boxes */ - plselAdjustSelections(hWnd); - - /* set tab order */ - SetWindowPos(GetDlgItem(hWnd, IDCANCEL), NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - SetWindowPos(GetDlgItem(hWnd, IDC_PLSEL_RANDOM), NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - SetWindowPos(GetDlgItem(hWnd, IDOK), NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - for(int i = ROLE_GENDERS - 1; i >= 0; i--) - SetWindowPos(data->control_genders[i], NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - for(int i = ROLE_ALIGNS - 1; i >= 0; i--) - SetWindowPos(data->control_aligns[i], NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - SetWindowPos(data->control_race, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - SetWindowPos(data->control_role, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - -} void plselAdjustSelections(HWND hWnd) { struct plsel_data * data = (plsel_data_t *) GetWindowLongPtr(hWnd, GWLP_USERDATA); + control_t * role_control = &data->controls[psc_role_list]; + control_t * race_control = &data->controls[psc_race_list]; + if (!ok_race(flags.initrole, flags.initrace, ROLE_RANDOM, ROLE_RANDOM)) flags.initrace = pick_race(flags.initrole, ROLE_RANDOM, ROLE_RANDOM, ROLE_RANDOM); @@ -590,29 +837,31 @@ plselAdjustSelections(HWND hWnd) if (!ok_align(flags.initrole, flags.initrace, flags.initgend, flags.initalign)) flags.initalign = pick_align(flags.initrole, flags.initrace, flags.initgend , ROLE_RANDOM); - ListView_RedrawItems(data->control_role, 0, data->role_count - 1); - ListView_RedrawItems(data->control_race, 0, data->race_count - 1); + ListView_RedrawItems(role_control->hWnd, 0, data->role_count - 1); + ListView_RedrawItems(race_control->hWnd, 0, data->race_count - 1); /* set gender radio button state */ for (int i = 0; i < ROLE_GENDERS; i++) { + HWND button = data->controls[psc_male_button+i].hWnd; BOOL enable = ok_gend(flags.initrole, flags.initrace, i, flags.initalign); - Button_Enable(data->control_genders[i], enable); - LRESULT state = Button_GetCheck(data->control_genders[i]); + Button_Enable(button, enable); + LRESULT state = Button_GetCheck(button); if (state == BST_CHECKED && flags.initgend != i) - Button_SetCheck(data->control_genders[i], BST_UNCHECKED); + Button_SetCheck(button, BST_UNCHECKED); if (state == BST_UNCHECKED && flags.initgend == i) - Button_SetCheck(data->control_genders[i], BST_CHECKED); + Button_SetCheck(button, BST_CHECKED); } /* set alignment radio button state */ for (int i = 0; i < ROLE_ALIGNS; i++) { + HWND button = data->controls[psc_lawful_button+i].hWnd; BOOL enable = ok_align(flags.initrole, flags.initrace, flags.initgend, i); - Button_Enable(data->control_aligns[i], enable); - LRESULT state = Button_GetCheck(data->control_aligns[i]); + Button_Enable(button, enable); + LRESULT state = Button_GetCheck(button); if (state == BST_CHECKED && flags.initalign != i) - Button_SetCheck(data->control_aligns[i], BST_UNCHECKED); + Button_SetCheck(button, BST_UNCHECKED); if (state == BST_UNCHECKED && flags.initalign == i) - Button_SetCheck(data->control_aligns[i], BST_CHECKED); + Button_SetCheck(button, BST_CHECKED); } } diff --git a/win/win32/resource.h b/win/win32/resource.h index 6be779811..fdd864f12 100644 --- a/win/win32/resource.h +++ b/win/win32/resource.h @@ -1,6 +1,6 @@ //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. -// Used by winhack.rc +// Used by NetHackW.rc // #define IDC_MYICON 2 #define IDD_WINHACK_DIALOG 102 @@ -114,6 +114,11 @@ #define IDC_PLSEL_ALIGN_CHAOTIC 1336 #define IDC_PLSEL_GENDER_MALE 1337 #define IDC_PLSEL_GENDER_FEMALE 1338 +#define IDC_PLSEL_NAME_GROUP 1339 +#define IDC_PLSEL_ROLE_GROUP 1340 +#define IDC_PLSEL_RACE_GROUP 1341 +#define IDC_PLSEL_ALIGNMENT_GROUP 1342 +#define IDC_PLSEL_GENDER_GROUP 1343 #define IDM_SAVE 32771 #define IDM_HELP_LONG 32772 #define IDM_HELP_COMMANDS 32773 diff --git a/win/win32/vs2017/NetHackW.vcxproj b/win/win32/vs2017/NetHackW.vcxproj index 793158e01..4369b4485 100644 --- a/win/win32/vs2017/NetHackW.vcxproj +++ b/win/win32/vs2017/NetHackW.vcxproj @@ -201,6 +201,18 @@ + + + + + + + + + + + + @@ -212,4 +224,4 @@ - + \ No newline at end of file From 34cf17c4d0588a3c01411d9884bc6618dece99dd Mon Sep 17 00:00:00 2001 From: Bart House Date: Thu, 31 Oct 2019 20:37:43 -0700 Subject: [PATCH 7/7] New package submitted to microsoft store. --- win/win32/vs2017/NetHackPackage.appxmanifest | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/win32/vs2017/NetHackPackage.appxmanifest b/win/win32/vs2017/NetHackPackage.appxmanifest index da4928ca9..44c752964 100644 --- a/win/win32/vs2017/NetHackPackage.appxmanifest +++ b/win/win32/vs2017/NetHackPackage.appxmanifest @@ -1,6 +1,6 @@  - + NetHack 3.6 NetHack DevTeam