shithub: choc

Download patch

ref: efd15d965dee947a04727bb62f4e2092cf28732f
parent: 4d17ab361e90a75dc6deefd37e6eb2ba0610b386
parent: 11024d8214580d63ca7a9e70a121f5ff542a2fce
author: Simon Howard <[email protected]>
date: Sun Sep 11 19:40:44 EDT 2011

Merge from raven-branch.

Subversion-branch: /branches/strife-branch
Subversion-revision: 2367

--- a/BUGS
+++ /dev/null
@@ -1,13 +1,0 @@
-
-* Sound may not set volumes correctly.
-
-  It is possible that volume of sound effects does not scale properly 
-  with distance from the sound source.  It is also possible that sound 
-  effects are cut off at the wrong distance. This needs further 
-  investigation.
-
-* A small number of Doom bugs are almost impossible to emulate.
-
-  An example of this can be seen in Ledmeister's "Blackbug" demo which 
-  shows a bug that relies on the memory layout of the Doom executable.  
-
--- a/COPYING
+++ b/COPYING
@@ -1,12 +1,12 @@
-		    GNU GENERAL PUBLIC LICENSE
-		       Version 2, June 1991
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
 
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  Everyone is permitted to copy and distribute verbatim copies
  of this license document, but changing it is not allowed.
 
-			    Preamble
+                            Preamble
 
   The licenses for most software are designed to take away your
 freedom to share and change it.  By contrast, the GNU General Public
@@ -15,7 +15,7 @@
 General Public License applies to most of the Free Software
 Foundation's software and to any other program whose authors commit to
 using it.  (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.)  You can apply it to
+the GNU Lesser General Public License instead.)  You can apply it to
 your programs, too.
 
   When we speak of free software, we are referring to freedom, not
@@ -55,8 +55,8 @@
 
   The precise terms and conditions for copying, distribution and
 modification follow.
-
-		    GNU GENERAL PUBLIC LICENSE
+
+                    GNU GENERAL PUBLIC LICENSE
    TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 
   0. This License applies to any program or other work which contains
@@ -110,7 +110,7 @@
     License.  (Exception: if the Program itself is interactive but
     does not normally print such an announcement, your work based on
     the Program is not required to print an announcement.)
-
+
 These requirements apply to the modified work as a whole.  If
 identifiable sections of that work are not derived from the Program,
 and can be reasonably considered independent and separate works in
@@ -168,7 +168,7 @@
 access to copy the source code from the same place counts as
 distribution of the source code, even though third parties are not
 compelled to copy the source along with the object code.
-
+
   4. You may not copy, modify, sublicense, or distribute the Program
 except as expressly provided under this License.  Any attempt
 otherwise to copy, modify, sublicense or distribute the Program is
@@ -225,7 +225,7 @@
 
 This section is intended to make thoroughly clear what is believed to
 be a consequence of the rest of this License.
-
+
   8. If the distribution and/or use of the Program is restricted in
 certain countries either by patents or by copyrighted interfaces, the
 original copyright holder who places the Program under this License
@@ -255,7 +255,7 @@
 of preserving the free status of all derivatives of our free software and
 of promoting the sharing and reuse of software generally.
 
-			    NO WARRANTY
+                            NO WARRANTY
 
   11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
 FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
@@ -277,10 +277,10 @@
 PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGES.
 
-		     END OF TERMS AND CONDITIONS
-
-	    How to Apply These Terms to Your New Programs
+                     END OF TERMS AND CONDITIONS
 
+            How to Apply These Terms to Your New Programs
+
   If you develop a new program, and you want it to be of the greatest
 possible use to the public, the best way to achieve this is to make it
 free software which everyone can redistribute and change under these terms.
@@ -303,17 +303,16 @@
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
 
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
-
 Also add information on how to contact you by electronic and paper mail.
 
 If the program is interactive, make it output a short notice like this
 when it starts in an interactive mode:
 
-    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision version 69, Copyright (C) year name of author
     Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
     This is free software, and you are welcome to redistribute it
     under certain conditions; type `show c' for details.
@@ -336,5 +335,5 @@
 This General Public License does not permit incorporating your program into
 proprietary programs.  If your program is a subroutine library, you may
 consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Library General
+library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,258 @@
+2011-05-17 23:51:37 fraggle
+	
+	Add dependency for INSTALL generation.
+
+2011-05-17 23:06:22 fraggle
+	
+	Detect chex.deh if it is in the same directory as the IWAD file.
+
+2011-05-14 22:50:46 fraggle
+	
+	Fix display of ENDOOM screen.
+
+2011-05-14 22:47:12 fraggle
+	
+	Fix install of screensaver desktop file.
+
+2011-05-14 22:07:55 fraggle
+	
+	Add freedesktop.org desktop files for chocolate-doom, chocolate-setup
+	(thanks Adrián Chaves Fernández).
+
+2011-05-14 21:11:26 fraggle
+	
+	Convert build system to using the PROGRAM_PREFIX system used on
+	raven-branch.
+
+2011-05-08 19:32:02 fraggle
+	
+	Update NEWS.
+
+2011-05-08 19:29:46 fraggle
+	
+	Allow IWAD files to be double-clicked in the finder to set the IWAD
+	configuration.
+
+2011-05-08 01:31:01 fraggle
+	
+	Shut up compiler warnings.
+
+2011-05-08 00:52:26 fraggle
+	
+	Rework OS X launcher package.  Include documentation files within the
+	application bundle and add a help menu with links.  Rework .dmg
+	generation to generate a file with a "fancy" background image and
+	overall nicer appearance.
+
+2011-04-26 06:49:53 quasar_te
+	
+	Support for Win32 native OPL output when compiled with Microsoft
+	Visual C++.  Confirmed to work with Aureal Vortex AU8830 in Win98SE by
+	GhostlyDeath.
+
+2011-04-24 23:22:11 fraggle
+	
+	Infer -server when -privateserver is specified (thanks Porsche Monty).
+
+2011-04-24 22:39:31 fraggle
+	
+	Add test button to joystick menu in setup tool (thanks Alexandre
+	Xavier).
+
+2011-04-18 23:10:16 fraggle
+	
+	Add test hack for simulating Porsche Monty's scanline emulation (see
+	comment in file).
+
+2011-04-17 18:33:04 fraggle
+	
+	Fix libtextscreen window hotkeys to work when shift is held down /
+	capslock turned on.  Fix a similar problem in-game when typing cheat
+	codes or using menu hotkeys (thanks Alexandre Xavier).
+
+2011-04-17 17:53:47 fraggle
+	
+	Make Final Doom IWAD labels shorter, so they don't make the launch
+	windows grow.
+
+2011-04-11 20:49:45 fraggle
+	
+	Allow the shift key to be held down when changing key/mouse/joystick
+	bindings to prevent bindings to the same key from being cleared
+	(thanks myk).
+
+2011-04-09 01:27:13 fraggle
+	
+	Fix action area minimum width calculation.
+
+2011-04-04 21:30:17 fraggle
+	
+	Close dropdown list popup windows when clicking outside the window.
+
+2011-04-04 21:12:59 fraggle
+	
+	Fix crash.
+
+2011-04-04 21:09:42 fraggle
+	
+	Fix crash.
+
+2011-04-04 21:07:07 fraggle
+	
+	Change the background color when hovering over widgets.
+
+2011-04-04 19:40:28 fraggle
+	
+	Change setup tool default sampling rate to 44100Hz to match the game
+	(thanks Alexandre Xavier).
+
+2011-03-30 20:16:40 fraggle
+	
+	Add a symlink hack to work around the fact that OS X doesn't like
+	paths in MANPATH to contain spaces.
+
+2011-03-30 20:00:51 fraggle
+	
+	On OS X, display a dialog box when exiting with I_Error, like on
+	Windows.
+
+2011-03-29 00:48:31 fraggle
+	
+	Remove the BUGS file as it doesn't really contain any useful
+	information.
+
+2011-03-29 00:39:48 fraggle
+	
+	Add vim modeline for text wrapping to documentation text files.
+
+2011-03-29 00:33:09 fraggle
+	
+	Emulate bug with IDMUS cheat when emulating v1.9 (thanks Alexandre
+	Xavier).
+
+2011-03-28 22:36:00 fraggle
+	
+	Fix OPL MIDI playback when using an empty .mus / .mid file (thanks
+	Alexandre Xavier).
+
+2011-03-28 22:32:14 fraggle
+	
+	Allow .lmp files to be loaded (and demo files to be played back) that
+	have long filenames (thanks blzut3).
+
+2011-03-28 01:24:47 fraggle
+	
+	Fix weapon cycling from the shotgun to the chaingun in Doom 1 (thanks
+	Alexandre Xavier).
+
+2011-03-28 00:45:53 fraggle
+	
+	Scroll faster in reaction to the scroll wheel.
+
+2011-03-28 00:42:00 fraggle
+	
+	Change default sfx/music volume in setup tool to 8, to match the game
+	(thanks Alexandre Xavier).
+
+2011-03-22 21:33:17 fraggle
+	
+	Switch separator to show "screen mode" or "window size" depending on
+	whether fullscreen is turned on or not.
+
+2011-03-22 21:08:04 fraggle
+	
+	Fix scrollbars so that clicks scroll the pane to a location that
+	matches the clicked location.  Interpret mousewheel events so that
+	scroll panes can be scrolled.
+
+2011-03-22 19:49:31 fraggle
+	
+	Reorganise the display settings window.
+
+2011-03-17 22:54:33 fraggle
+	
+	Add back -a option to automake, and remove INSTALL if automake
+	installs it.
+
+2011-03-17 22:43:56 fraggle
+	
+	Fix up placement of display settings window.
+
+2011-03-15 22:41:22 fraggle
+	
+	Fix NEWS entry to list the full name for Alexandre Xavier.
+
+2011-03-10 19:47:14 fraggle
+	
+	Include Unix manpages in MacOS package, and set MANPATH to point to
+	them when opening a terminal window.
+
+2011-03-10 19:45:29 fraggle
+	
+	Minor tweaks to MacOS instructions.
+
+2011-03-10 19:20:10 fraggle
+	
+	Minor tweak to INSTALL instructions.
+
+2011-03-10 19:03:23 fraggle
+	
+	Replace the INSTALL file with a template version that is customized to
+	different platforms.
+
+2011-03-09 19:02:15 fraggle
+	
+	Add null sector dereference emulation code from Prboom+, to fix desync
+	with CLNJ-506.LMP (thanks entryway).
+
+2011-03-09 01:06:07 fraggle
+	
+	Add support for the alternate version of the Final Doom executable
+	that fixes the demo loop crash (thanks Porsche Monty, Enjay).
+
+2011-03-06 20:59:51 fraggle
+	
+	Discard very short sound effects and strip lead-in / lead-out samples
+	that apparently aren't played by Vanilla Doom (thanks Quasar).
+
+2011-03-03 21:41:51 fraggle
+	
+	Fix Visual Studio build (thanks GhostlyDeath).
+
+2011-02-28 20:48:27 fraggle
+	
+	Fix autoadjust of pixel depth in setup tool.
+
+2011-02-05 16:50:28 fraggle
+	
+	Fix bug with libtextscreen where it was not possible to type a '+'
+	(thanks Alexandre Xavier).
+
+2011-01-31 01:25:47 fraggle
+	
+	When large numbers of screen resolutions are detected, increase the
+	number of columns in the mode list to fit them all on-screen.  Remove
+	superfluous left-side spacing from the checkbox and radio button
+	widgets so that the modes can be packed closer together.
+
+2011-01-23 21:42:09 fraggle
+	
+	Fix default joystick buttons in setup tool to match Vanilla (thanks
+	twipley).
+
+2011-01-13 20:34:55 fraggle
+	
+	In configuration files, use the scan code for right shift, not left
+	shift, to match Vanilla (thanks AlexXav).
+
+2011-01-12 23:22:20 fraggle
+	
+	Fix menu navigation when using joystick / joypad (thanks AlexXav).
+
+2011-01-02 18:14:59 fraggle
+	
+	Update NEWS and ChangeLog, bump version number.
+
 2011-01-02 17:45:24 fraggle
 	
 	Remove redundant package version label from top of OS X launcher
--- a/HACKING
+++ b/HACKING
@@ -172,3 +172,5 @@
 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 // 02111-1307, USA.
 
+# vim: tw=70
+
--- a/INSTALL
+++ /dev/null
@@ -1,173 +1,0 @@
-
-Chocolate Doom installation
-===========================
-
-These are instructions for how to install and set up Chocolate Doom
-for play.
-
-Building Chocolate Doom
------------------------
-
-Before you can play Chocolate Doom, you need to compile a binary that
-you can run.  If you are using Windows or Mac OS X, precompiled
-binaries are available on the website for download, and you can skip
-this section.
-
-For compilation, Chocolate Doom requires the following to be installed:
-
- * A C compiler (gcc is recommended)
- * make (GNU make is recommended)
- * LibSDL (see http://www.libsdl.org/)
- * SDL_mixer (see http://www.libsdl.org/projects/SDL_mixer/)
- * SDL_net (see http://www.libsdl.org/projects/SDL_net/)
- * Python (optional)
-
-Follow the standard instructions for installing an autotools-based
-package:
-
- 1. Run './configure' to initialize the package.
- 2. Run 'make' to compile the package.
- 3. Run 'make install' to install the package.
-
-Advanced topics such as cross-compilation are beyond the scope of this
-document.  Please see the GNU autoconf / automake documentation for more
-information.
-
-Obtaining an IWAD file
-----------------------
-
-To play Doom, you need an IWAD file.  This file contains the game data
-that is used in gameplay (graphics, sounds, etc).  The full versions of
-the Doom games are proprietary and need to be bought.  The IWAD file
-has one of the following names:
-
-   doom1.wad                   (Shareware Doom)
-   doom.wad                    (Registered / Ultimate Doom)
-   doom2.wad                   (Doom 2)
-   tnt.wad                     (Final Doom: TNT: Evilution)
-   plutonia.wad                (Final Doom: Plutonia Experiment)
-   chex.wad                    (Chex Quest)
-
-If you don't have a copy of the commercial version, you can download
-the shareware version (extract the file named doom1.wad):
-
- * http://www.doomworld.com/idgames/index.php?id=7053
-   (idstuff/doom/win95/doom95.zip in your nearest /idgames mirror)
-
-If you have a commercial version, obtaining the IWAD file may slightly
-complicated.  The method depends on how you obtained your copy of the
-game:
-
- * There have been several CD-based versions of Doom.  Generally, the
-   IWAD files can be found on the CD and copied off directly.
-
- * The IWAD files might not be directly available on the CD.  Look for
-   a program named "deice.exe".  In the same directory, there should
-   be a single large file with a numbered extension (eg.
-   "resource.1"); to extract this, follow the same instructions as for
-   the floppy disk version (see below).
-
- * If you have the floppy disk version of Doom, first copy the
-   contents of all the floppy disks into a directory together.  You
-   will have several large files with numbered extensions.
-   Concatenate these into a single file, eg.
-
-     (Unix instructions)
-     cat doom_se.1 doom_se.2 doom_se.3 doom_se.4 doom_se.5 > doom_se.exe
-
-     (Windows/DOS instructions)
-     copy doom_se.1+doom_se.2+doom_se.3+doom_se.4+doom_se+5 doom_se.exe
-
-   The resulting file is self-extracting LHA file.  If you have a DOS
-   emulator (such as DOSbox), you can run it to extract the files;
-   alternatively, you can use the Unix LHA tool to extract the
-   archive.
-
- * The Doom games are also available for download on Steam
-   (http://www.steampowered.com/).  To find the IWAD files, look in
-   your Steam directory, under the "steamapps/common" path.
-
-Running the game
-----------------
-
-When you have an IWAD file, install it through one of the following
-methods:
-
- * Under Mac OS X, you can specify the locations of the IWAD files
-   through the graphical launcher program.  Click the "Configure..."
-   button, and then click "Set..." for each IWAD location to choose
-   its location.
-
- * Under Unix, put the file into the /usr/share/games/doom or
-   /usr/local/share/games/doom directories.
-
- * Place it in a directory and set the environment variable DOOMWADDIR
-   to be the path to that directory.
-
- * Install multiple IWADs into separate directories and set the
-   environment variable DOOMWADPATH to be a colon-separated list of
-   directories to search (similar to the Unix PATH environment
-   variable).
-
- * Run Chocolate Doom with the '-iwad' command line parameter to
-   specify the IWAD file to use, eg.
-
-       chocolate-doom -iwad /root/doom2.wad
-
-Playing with Chex Quest
------------------------
-
-Chex Quest is a game based on Doom with some minor modifications that
-was distributed with boxes of Chex cereal in 1997.  It is possible to
-play Chex Quest using Chocolate Doom.  To do this, the following files
-are needed:
-
- * The IWAD file 'chex.wad', from the Chex Quest CD.
-
- * The dehacked patch 'chex.deh', which can be found in the /idgames
-   repository in utils/exe_edit/patches/chexdeh.zip.
-
-Copy these files into a directory together and use the '-iwad' command
-line parameter to specify the Chex Quest IWAD file:
-
-   chocolate-doom -iwad chex.wad
-
-Installing upgrades
--------------------
-
-Chocolate Doom requires a Doom 1.9 IWAD file.  Generally, if you
-install a recent version of Doom you should automatically have a 1.9
-IWAD.  However, if you are installing from a very old CD version or
-from floppy disks, you might find you have an older version.
-
-The most obvious symptom of an out of date IWAD file is that the game
-will exit at the title screen before the demo starts, with the message
-"Demo is from a different game version!".  If this happens, your IWAD
-file is out of date and you need to upgrade.
-
-Id Software released upgrade patches that will update your game to
-1.9.  The following sites have the patches:
-
-  http://www.doomworld.com/files/patches.shtml
-  http://www.doom2.net/doom2/utils.html
-  ftp://ftp.idsoftware.com/idstuff/doom2
-
-As the patches are binary patches that run as DOS executables, you
-will need a DOS emulator (such as DOSBox) to install them.
-
-Music support
--------------
-
-Support for Doom's MIDI music is available through Timidity:
-
-  http://timidity.sourceforge.net/
-
-A good set of patches for Timidity is the eawpats collection, which can
-be found here:
-
-  http://www.doomworld.com/idgames/index.php?id=13928
-  (Doom idgames archive, /sounds/eawpats.zip)
-
-If compiling from source, be sure to compile and install timidity
-before installing SDL_mixer.
-
--- a/Makefile.am
+++ b/Makefile.am
@@ -31,36 +31,32 @@
         codeblocks/setup.cbp                   \
         codeblocks/setup-res.rc
 
-DATA_FILES=                   \
-        data/README           \
-        data/doom.ico         \
-        data/doom8.ico        \
-        data/doom.png         \
-        data/setup.ico        \
-        data/setup8.ico       \
-        data/setup.png        \
-        data/convert-icon
+DOC_FILES=                              \
+        CMDLINE                         \
+        README                          \
+        README.OPL                      \
+        NEWS                            \
+        ChangeLog                       \
+        NOT-BUGS
 
 EXTRA_DIST=                             \
         $(AUX_DIST_GEN)                 \
         $(MSVC_FILES)                   \
         $(CODEBLOCKS_FILES)             \
-        $(DATA_FILES)                   \
+        $(DOC_FILES)                    \
         .lvimrc                         \
-        config.h                        \
-        CMDLINE                         \
         HACKING                         \
-        README.OPL                      \
         TODO                            \
-        BUGS                            \
-        NOT-BUGS                        \
         rpm.spec
 
+docdir=$(prefix)/share/doc/@PACKAGE@
+doc_DATA=$(DOC_FILES)
+
 MAINTAINERCLEANFILES =  $(AUX_DIST_GEN)
 
 docdir=$(prefix)/share/doc/@PACKAGE@
 
-SUBDIRS=wince textscreen opl pcsound src man
+SUBDIRS=wince textscreen opl pcsound data src man
 
 DIST_SUBDIRS=pkg $(SUBDIRS)
 
@@ -70,6 +66,9 @@
 
 CMDLINE : src/
 	./man/docgen -p man/CMDLINE.template src/ > $@
+
+INSTALL : man/INSTALL.template man/simplecpp
+	./man/simplecpp < man/INSTALL.template > $@
 
 endif
 
--- a/NEWS
+++ b/NEWS
@@ -1,22 +1,92 @@
-1.6.0 (2011-??-??):
 
+     * Fixed gnome-screensaver desktop file (thanks Rahul Sundaram).
+     * Updated COPYING to current version of GPL2 (thanks Rahul
+       Sundaram).
+     * Fix bug with detection of IWAD type by filename (thanks mether).
+
+1.6.0 (2011-05-17):
+
+     * The instructions in the INSTALL file are now customized for
+       different platforms, and each binary package contains a version
+       with instructions specific to the platform that it is
+       targetting.  This should help to avoid confusion that some
+       users have reported experiencing.
+     * The display settings window in the setup tool has been
+       reorganised to a better arrangement.
+     * It is now possible to load .lmp files (and play back demos)
+       with long filenames (thanks blzut3).
+     * In the setup tool, it is now possible to hold down shift when
+       changing key/mouse/joystick bindings to prevent other bindings
+       to the same key from being cleared (thanks myk).
+     * The joystick menu in the setup tool now has a test button
+       (thanks Alexandre Xavier).
+     * Specifying the -privateserver option implies -server (thanks
+       Porsche Monty).
+     * The Mac OS X .dmg package now has a background and looks generally
+       more polished.
+     * In Mac OS X, it is now possible to simply double click an IWAD
+       file in the Finder to configure its location within the launcher.
+     * Freedesktop.org desktop files are now installed for Doom and
+       the setup tool, which will appear in the main menu on desktop
+       environments such as Gnome and KDE (thanks Adrián Chaves
+       Fernández).
+     * The Chex Quest dehacked patch (chex.deh) will now be detected
+       if it is in the same directory as the IWAD file.
+
     Compatibility:
+     * Added support for the alternate version of the Final Doom
+       executable included in some later versions of the Id Anthology.
+       This version fixed the demo loop crash that occurred with the
+       "original" Final Doom executable.
+
+       This executable can be selected on the command line with
+       -gameversion final2. It has been made the default when playing
+       with the Final Doom IWADs (the original behavior can be
+       selected with -gameversion final).  (thanks Porsche Monty,
+       Enjay).
      * Very short sound effects are not played, to better emulate the
        behavior of DMX in Vanilla Doom (thanks to Quasar for help in
        investigating this).
+     * The null sector dereference emulation code has been imported
+       from Prboom+ - this fixes a desync with CLNJ-506.LMP (thanks
+       entryway).
+     * The IDMUS cheat doesn't work when emulating the v1.9 executable
+       (thanks Alexandre Xavier).
 
     Bugs fixed:
      * Menu navigation when using joystick/joypad (thanks Alexandre
        Xavier).
      * For configuration file value for shift keys, use scan code for
-       right shift, not left shift (thanks AlexXav).
+       right shift, not left shift (thanks Alexandre Xavier).
      * Default joystick buttons for the setup tool now match Vanilla
        (thanks twipley).
      * Visual Studio project files work again (thanks GhostlyDeath).
+     * The default sfx/music volume set by the setup tool is now 8
+       instead of 15, matching the game itself. (thanks Alexandre
+       Xavier).
+     * Weapon cycling from the shotgun to the chaingun in Doom 1 now
+       works properly (thanks Alexandre Xavier).
+     * MIDI playback that locked up when using an empty MUS / MIDI
+       file (thanks Alexandre Xavier).
+     * Default sampling rate used by setup tool changed to 44100Hz, to
+       match the game default (thanks Alexandre Xavier).
+     * Cheat codes and menu hot keys now work when shift is held down
+       or capslock turned on (thanks Alexandre Xavier).
 
     libtextscreen:
+     * The background on GUI controls now lights up when hovering over
+       them, so that it is more obvious what you are selecting.
      * It is now possible to type a '+' in input boxes (thanks
        Alexandre Xavier).
+     * It is possible to use the mouse wheel to scroll through scroll
+       panes.
+     * Clicking on scroll bars now moves the scroll handle to a
+       matching location.
+     * Clicking outside a dropdown list popup window now dismisses the
+       window.
+     * Window hotkeys that are an alphabetical letter now work when
+       shift is held down or capslock turned on (thanks Alexandre
+       Xavier).
 
 1.5.0 (2011-01-02):
 
@@ -622,4 +692,6 @@
 
 0.0.1 (2005-09-07):
     First beta release
+
+# vim: tw=70
 
--- a/NOT-BUGS
+++ b/NOT-BUGS
@@ -31,29 +31,6 @@
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-== Game exits in demo loop when playing Final Doom ==
-
-When playing with the Final Doom IWAD files (tnt.wad, plutonia.wad),
-if you leave the game at the title screen to play through the demo
-loop, it will eventually exit with the following error message:
-
-    W_GetNumForName: demo4 not found!
-
-This is the same behavior as the Vanilla executables that were
-bundled with Final Doom.  When Ultimate Doom was developed, a fourth
-demo was added to the demo loop, and this change was retained in the
-Final Doom version of the executable.  However, the Final Doom IWADs
-do not include a fourth demo, so the game crashes.
-
-One way to work around this problem is to make the game emulate the
-original (pre-Ultimate Doom) v1.9 executable.  To do this, add the
-command line argument "-gameversion 1.9" when running the game.
-However, be aware this version does have some subtle differences that
-will affect the playback of Final Doom demos (lost soul bouncing,
-teleport behavior).
-
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
 == Game exits when accessing the options menu ==
 
 The game may exit with the message "Bad V_DrawPatch" when accessing
@@ -132,4 +109,21 @@
 More information can be found here:
 
     http://rome.ro/lee_killough/editing/visplane.shtml
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+== IDMUS## cheat doesn't work with shareware/registered Doom IWADs ==
+
+The IDMUS cheat allows the in-game music to be changed.  However, in
+the original v1.9 this cheat didn't work properly when playing with
+the Doom 1 (shareware and registered) IWADs.  This bug was fixed in
+the Ultimate Doom and Final Doom executables.
+
+Chocolate Doom emulates this bug.  When playing with the shareware or
+registered Doom IWADs, the IDMUS cheat therefore does not work
+properly.  If you are playing with the Ultimate Doom IWAD, the
+Ultimate Doom executable is emulated by default, so the cheat works
+properly.
+
+# vim: tw=70
 
--- a/README
+++ b/README
@@ -65,10 +65,11 @@
    You are encouraged to sign up and contribute any useful information
    you may have regarding the port!
 
- * Chocolate Doom is not perfect. See the BUGS file for a list of
-   known issues. Because of the nature of the project, you may also
-   encounter Vanilla Doom bugs; these are intentionally present; see
-   the NOT-BUGS file for more information.
+ * Chocolate Doom is not perfect.  Although it aims to accurately
+   emulate Vanilla Doom, some of the behavior of Vanilla Doom can be
+   very difficult to reproduce. Because of the nature of the project,
+   you may also encounter Vanilla Doom bugs; these are intentionally
+   present; see the NOT-BUGS file for more information.
 
    New bug reports can be submitted to the Chocolate Doom bug tracker
    on Sourceforge.  See:
@@ -84,4 +85,6 @@
 
  * Please send any feedback, questions or suggestions to
    [email protected].  Thanks!
+
+# vim: tw=70
 
--- a/README.OPL
+++ b/README.OPL
@@ -105,3 +105,5 @@
 
 There is no native OPL backend for FreeBSD yet.  Sorry!
 
+# vim: tw=70
+
--- a/TODO
+++ b/TODO
@@ -54,3 +54,5 @@
  * Get a better software OPL emulator
  * DMXOPTIONS opl3/phase option support.
 
+# vim: tw=70
+
--- a/autogen.sh
+++ b/autogen.sh
@@ -1,12 +1,26 @@
 #!/bin/sh
 
+if [ -e INSTALL ]; then
+    have_INSTALL=true
+else
+    have_INSTALL=false
+fi
+
 mkdir autotools
 
 aclocal
 autoheader
-automake -a -c
+automake -ac
 autoconf
 automake
+
+# The INSTALL file is autogenerated, so it isn't stored in version control.
+# As the file isn't present, automake's -a option will install generic
+# install instructions.  So remove INSTALL if automake installed one.
+
+if ! $have_INSTALL; then
+    rm -f INSTALL
+fi
 
 ./configure "$@"
 
--- a/codeblocks/config.h
+++ b/codeblocks/config.h
@@ -9,19 +9,22 @@
 #define PACKAGE_NAME "Chocolate Doom"
 
 /* Define to the full name and version of this package. */
-#define PACKAGE_STRING "Chocolate Doom 1.5.0"
+#define PACKAGE_STRING "Chocolate Doom 1.6.0"
 
 /* Define to the one symbol short name of this package. */
 #define PACKAGE_TARNAME "chocolate-doom"
 
 /* Define to the version of this package. */
-#define PACKAGE_VERSION "1.5.0"
+#define PACKAGE_VERSION "1.6.0"
 
+/* Change this when you create your awesome forked version */
+#define PROGRAM_PREFIX "chocolate-"
+
 /* Define to 1 if you have the ANSI C header files. */
 #define STDC_HEADERS 1
 
 /* Version number of package */
-#define VERSION "1.5.0"
+#define VERSION "1.6.0"
 
 /* Define to 1 if your processor stores words with the most significant byte
    first (like Motorola and SPARC, unlike Intel and VAX). */
--- a/codeblocks/game-res.rc
+++ b/codeblocks/game-res.rc
@@ -1,8 +1,8 @@
 1 ICON "../data/doom.ico"
 
 1 VERSIONINFO
-PRODUCTVERSION 1,5,0,0
-FILEVERSION 1,5,0,0
+PRODUCTVERSION 1,6,0,0
+FILEVERSION 1,6,0,0
 FILETYPE 1
 {
  BLOCK "StringFileInfo"
@@ -9,13 +9,13 @@
  {
   BLOCK "040904E4"
   {
-   VALUE "FileVersion", "1.5.0"
-   VALUE "FileDescription", "1.5.0"
+   VALUE "FileVersion", "1.6.0"
+   VALUE "FileDescription", "1.6.0"
    VALUE "InternalName", "Chocolate-Doom"
    VALUE "CompanyName", "Chocolate-Doom"
    VALUE "LegalCopyright", "GNU General Public License"
    VALUE "ProductName", "Chocolate-Doom"
-   VALUE "ProductVersion", "1.5.0"
+   VALUE "ProductVersion", "1.6.0"
   }
  }
 }
--- a/codeblocks/setup-res.rc
+++ b/codeblocks/setup-res.rc
@@ -3,8 +3,8 @@
 CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "setup-manifest.xml"
 
 1 VERSIONINFO
-PRODUCTVERSION 1,5,0,0
-FILEVERSION 1,5,0,0
+PRODUCTVERSION 1,6,0,0
+FILEVERSION 1,6,0,0
 FILETYPE 1
 {
  BLOCK "StringFileInfo"
@@ -11,13 +11,13 @@
  {
   BLOCK "040904E4"
   {
-   VALUE "FileVersion", "1.5.0"
+   VALUE "FileVersion", "1.6.0"
    VALUE "FileDescription", "Chocolate-Doom Setup"
    VALUE "InternalName", "chocolate-setup"
    VALUE "CompanyName", "[email protected]"
    VALUE "LegalCopyright", "GNU General Public License"
    VALUE "ProductName", "Chocolate-Doom Setup"
-   VALUE "ProductVersion", "1.5.0"
+   VALUE "ProductVersion", "1.6.0"
   }
  }
 }
--- a/configure.in
+++ b/configure.in
@@ -1,7 +1,7 @@
-AC_INIT(Chocolate Doom, 1.5.0, [email protected], chocolate-doom)
+AC_INIT(Chocolate Doom, 1.6.0, [email protected], chocolate-doom)
 
 PACKAGE_SHORTDESC="Conservative Doom source port"
-PACKAGE_COPYRIGHT="Copyright (C) 1993-2010"
+PACKAGE_COPYRIGHT="Copyright (C) 1993-2011"
 PACKAGE_LICENSE="GNU General Public License, version 2"
 PACKAGE_MAINTAINER="Simon Howard"
 PACKAGE_URL="http://www.chocolate-doom.org/"
@@ -110,6 +110,7 @@
 dnl Automake v1.8.0 is required, please upgrade!
 
 AM_INIT_AUTOMAKE([1.8.0])
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 
 WINDOWS_RC_VERSION=`echo $PACKAGE_VERSION.0 | sed 's/\./, /g' `
 
@@ -154,7 +155,9 @@
 pkg/osx/Info-gnustep.plist
 pkg/osx/Info.plist
 rpm.spec
+data/Makefile
 src/Makefile
+src/doom.desktop
 src/doom-screensaver.desktop
 src/doom/Makefile
 src/heretic/Makefile
@@ -162,6 +165,7 @@
 src/resource.rc
 src/setup-res.rc
 src/setup/Makefile
+src/setup/setup.desktop
 src/setup/setup-manifest.xml
 src/strife/Makefile
 textscreen/Makefile
--- /dev/null
+++ b/data/.gitignore
@@ -1,0 +1,4 @@
+Makefile.in
+Makefile
+*-doom.png
+*-setup.png
--- /dev/null
+++ b/data/Makefile.am
@@ -1,0 +1,21 @@
+
+EXTRA_DIST=              \
+        README           \
+        doom.ico         \
+        doom8.ico        \
+        doom.png         \
+        setup.ico        \
+        setup8.ico       \
+        setup.png        \
+        convert-icon
+
+iconsdir = $(prefix)/share/icons
+icons_DATA = @[email protected]   \
+             @[email protected]
+
+@[email protected] : doom.png
+	cp $< $@
+
+@[email protected] : setup.png
+	cp $< $@
+
--- a/data/README
+++ b/data/README
@@ -3,6 +3,10 @@
 
     http://www.flickr.com/photos/laffy4k/448920776/
 
+Chris has kindly agreed that the Chocolate Doom icon may be used under
+the GNU GPL, so the copyright status of the icon is the same as that of
+the rest of the project.
+
 The "foo8.ico" files are 8-bit depth only, while the "foo.ico" files
 contain full 32-bit versions, scaled to different sizes and with proper
 alpha masks (as well as the 8-bit versions).  The 8-bit versions are
--- /dev/null
+++ b/man/INSTALL.template
@@ -1,0 +1,253 @@
+
+Chocolate Doom installation
+===========================
+
+These are instructions for how to install and set up Chocolate Doom
+for play.
+
+#ifn PRECOMPILED
+Building Chocolate Doom
+-----------------------
+
+Before you can play Chocolate Doom, you need to compile a binary that
+you can run.  For compilation, Chocolate Doom requires the following
+to be installed:
+
+ * A C compiler (gcc is recommended)
+ * make (GNU make is recommended)
+ * LibSDL (see http://www.libsdl.org/)
+ * SDL_mixer (see http://www.libsdl.org/projects/SDL_mixer/)
+ * SDL_net (see http://www.libsdl.org/projects/SDL_net/)
+ * Python (optional)
+
+Follow the standard instructions for installing an autotools-based
+package:
+
+ 1. Run './configure' to initialize the package.
+ 2. Run 'make' to compile the package.
+ 3. Run 'make install' to install the package.
+
+An automated build script is available that installs the necessary
+dependencies and builds the source code automatically.  See the build
+instructions on the website.
+
+Advanced topics such as cross-compilation are beyond the scope of this
+document.  Please see the GNU autoconf / automake documentation for more
+information.
+
+#endif
+Obtaining an IWAD file
+----------------------
+
+To play Doom, you need an IWAD file.  This file contains the game data
+(graphics, sounds, etc).  The full versions of the Doom games are
+proprietary and need to be bought.  The IWAD file has one of the
+following names:
+
+   doom1.wad                   (Shareware Doom)
+   doom.wad                    (Registered / Ultimate Doom)
+   doom2.wad                   (Doom 2)
+   tnt.wad                     (Final Doom: TNT: Evilution)
+   plutonia.wad                (Final Doom: Plutonia Experiment)
+   chex.wad                    (Chex Quest)
+
+If you don't have a copy of a commercial version, you can download
+the shareware version (extract the file named doom1.wad):
+
+ * http://www.doomworld.com/idgames/index.php?id=7053
+   (idstuff/doom/win95/doom95.zip in your nearest /idgames mirror)
+
+If you have a commercial version, obtaining the IWAD file is usually
+straightforward.  The method depends on how you obtained your copy of
+the game:
+
+#if _WIN32
+ * The Doom games are available to buy for download on Steam
+   (http://www.steampowered.com/).  Chocolate Doom will autodetect
+   IWADs installed by Steam and you do not need to do anything.
+#else
+ * The Doom games are available to buy for download on Steam
+   (http://www.steampowered.com/).  To find the IWAD files on a
+   Windows system, look in the Steam directory (usually within
+   "Program Files"), under the "steamapps/common" path.
+#endif
+
+ * There have been several CD-based versions of Doom.  Generally, the
+   IWAD files can be found on the CD and copied off directly.
+
+#if _WIN32
+ * If the IWAD files are not directly available on the CD, or you have
+   a floppy disk version, you will need to run the install program to
+   install the game to your hard disk.  As the installer is DOS-based,
+   you may not be able to do this on 64-bit versions of Windows.  In
+   this case, the best suggestion is to use a DOS emulator (such as
+   DOSbox) to run the installer.
+#else
+ * If the IWAD files are not directly available on the CD, or you have
+   a floppy disk version, installation is more difficult.  The best
+   suggestion is to use a DOS emulator (such as DOSbox) to run the
+   installer.
+#endif
+
+ * As an alternative to using an emulator, it is possible to extract
+   the files manually.  On the install disk(s), you will find several
+   files with numbered extensions (with CD versions there may be a
+   single large file with the extension .1, eg. "resource.1").
+
+   From the command line it is possible to combine these files into a
+   single large file, using a command similar to the following:
+
+#if _WIN32
+     copy doom_se.1+doom_se.2+doom_se.3+doom_se.4+doom_se.5 doom_se.lha
+#else
+     cat doom_se.1 doom_se.2 doom_se.3 doom_se.4 doom_se.5 > doom_se.lha
+#endif
+
+   The resulting file is an LHA archive file, and it can be extracted
+   using an LHA archive tool (there is one available for almost every
+   operating system).
+
+Running the game
+----------------
+
+#if __MACOSX__
+Once you have an IWAD file, you can specify its location within the
+graphical launcher program.  Click the "Configure..." button, and then
+click "Set..." for each IWAD to choose its location.  From the main
+launcher dialog you can then choose which game you want to play and
+click the "Launch" button to start the game.
+
+If you are an advanced user and like to run Doom from the command
+line, you can use the "Command Prompt..." menu item to open a Terminal
+window.  The DOOMWADPATH environment variable is preconfigured
+to point to the locations of the IWAD files set within the launcher.
+You can launch the game with a specific IWAD file by typing, for
+example:
+
+    chocolate-doom -iwad tnt.wad
+#else
+Chocolate Doom needs to know where to find your IWAD file. To do this,
+do one of the following:
+
+#if _WIN32
+ * Within Explorer, simply place the IWAD file in the same folder as
+   the Chocolate Doom files, and double-click chocolate-doom.exe.
+
+ * Run Chocolate Doom from the command prompt with the '-iwad' command
+   line parameter to specify the IWAD file to use, eg.
+
+       chocolate-doom -iwad c:\games\doom2.wad
+
+ * Set the environment variable DOOMWADDIR to the location of a
+   directory containing your IWAD files.
+
+ * If you have multiple IWADs in different directories, set the
+   environment variable DOOMWADPATH to be a semicolon-separated list
+   of directories to search (similar to the PATH environment
+   variable).
+#else
+ * Run Chocolate Doom from the Unix console with the '-iwad' command
+   line parameter to specify the IWAD file to use, eg.
+
+       chocolate-doom -iwad /root/doom2.wad
+
+ * Put the file into one of the following directories:
+
+     /usr/share/games/doom
+     /usr/local/share/games/doom
+
+ * Set the environment variable DOOMWADDIR to specify the path to a
+   directory containing your IWAD files.
+
+ * If you have multiple IWADs in different directories, set the
+   environment variable DOOMWADPATH to be a colon-separated list of
+   directories to search (similar to the Unix PATH environment
+   variable).
+#endif
+#endif
+
+Playing with Chex Quest
+-----------------------
+
+Chex Quest is a game based on Doom with some minor modifications that
+was distributed with boxes of Chex cereal in 1997.  It is possible to
+play Chex Quest using Chocolate Doom.  To do this, the following files
+are needed:
+
+ * The IWAD file 'chex.wad', from the Chex Quest CD.
+
+ * The dehacked patch 'chex.deh', which can be found here:
+   http://www.doomworld.com/idgames/?id=15420
+   (utils/exe_edit/patches/chexdeh.zip in your nearest /idgames mirror)
+
+Copy these files into a directory together and use the '-iwad' command
+line parameter to specify the Chex Quest IWAD file:
+
+   chocolate-doom -iwad chex.wad
+
+Installing upgrades
+-------------------
+
+Chocolate Doom requires a version 1.9 IWAD file.  Generally, if you
+install a recent version of Doom you should have a version 1.9 IWAD.
+However, if you are installing from a very old CD version or from
+floppy disks, you might find you have an older version.
+
+The most obvious symptom of an out of date IWAD file is that the game
+will exit at the title screen before the demo starts, with the message
+"Demo is from a different game version!".  If this happens, your IWAD
+file is out of date and you need to upgrade.
+
+Id Software released upgrade patches that will update your game to
+version 1.9.  The following sites have the patches:
+
+  http://www.doomworld.com/files/patches.shtml
+  http://www.doom2.net/doom2/utils.html
+  ftp://ftp.idsoftware.com/idstuff/doom2
+
+#if _WIN32
+As the patches are binary patches that run as DOS executables, on
+recent 64-bit versions of Windows you will need to use a DOS emulator
+(such as DOSBox) to run them.
+#else
+As the patches are binary patches that run as DOS executables, you
+will need to use a DOS emulator (such as DOSBox) to run them.
+#endif
+
+Music support
+-------------
+
+Chocolate Doom includes OPL emulation code that accurately reproduces
+the way that the in-game music sounded under DOS when using an
+Adlib/Soundblaster card.  This is, however, not to everyone's taste.
+
+#if _WIN32
+Better quality MIDI playback is possible by using Windows' native
+MIDI synthesizer that is part of the operating system.  Select "Native
+MIDI" within the sound dialog in the setup tool.
+
+#endif
+#if __MACOSX__
+High quality MIDI playback is possible by using Mac OS X's native MIDI
+synthesizer that is part of the operating system. Select "Native MIDI"
+within the sound dialog in the setup tool.
+
+#endif
+As an alternative it is possible to use Timidity for high quality MIDI
+playback:
+
+  http://timidity.sourceforge.net/
+
+A good set of patches for Timidity is the eawpats collection, which can
+be found here:
+
+  http://www.doomworld.com/idgames/index.php?id=13928
+  (Doom idgames archive, /sounds/eawpats.zip)
+
+#ifn PRECOMPILED
+When compiling from source, be sure to compile and install timidity
+before installing SDL_mixer.
+#endif
+
+# vim: tw=70
+
--- a/man/Makefile.am
+++ b/man/Makefile.am
@@ -1,6 +1,8 @@
 
 MANPAGE_GEN_FILES=manpage.template docgen default.cfg.template extra.cfg.template
 
+docdir=$(prefix)/share/doc/@PACKAGE@
+
 if HAVE_PYTHON
 
 man_MANS=chocolate-doom.6      \
@@ -9,6 +11,8 @@
          default.cfg.5         \
          $(PACKAGE).cfg.5
 
+nodist_doc_DATA=INSTALL
+
 chocolate-doom.6: ../src $(MANPAGE_GEN_FILES)
 	./docgen -m manpage.template ../src > $@
 
@@ -18,9 +22,14 @@
 $(PACKAGE).cfg.5: ../src extra.cfg.template
 	./docgen -m extra.cfg.template -c $(PACKAGE).cfg ../src > $@
 
+INSTALL: INSTALL.template
+	./simplecpp -DPRECOMPILED < INSTALL.template > $@
+
 endif
 
 EXTRA_DIST = $(man_MANS) $(MANPAGE_GEN_FILES)        \
              wikipages                               \
-             CMDLINE.template
+             CMDLINE.template                        \
+             INSTALL.template                        \
+             simplecpp
 
--- /dev/null
+++ b/man/simplecpp
@@ -1,0 +1,211 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+# Contributors to the Freedoom project.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#  * Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#  * Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#  * Neither the name of the freedoom project nor the names of its
+#    contributors may be used to endorse or promote products derived from
+#    this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+#
+# simple cpp-style preprocessor
+#
+# Understands:
+#
+# #define NAME
+#
+# Set an option
+# You can use -D on the command line too
+#
+# #undef NAME
+#
+# Unset an option if it is set
+#
+# #if .. #endif / #ifdef .. #endif
+#
+# Specify a list of options set, eg #ifdef DOOM2 || ULTDOOM || SHAREWARE
+# The block is only displayed if one of the options is set
+#
+# #ifn .. #endif / #ifndef .. #endif
+#
+# Similarly specify a list of options
+# The block is displayed if none of the options are set
+#
+# #include "filename"
+#
+# include the contents of a file
+
+import sys
+import re
+
+debug = False
+defines = {}
+
+command_re = re.compile("\#(\w+)(\s+(.*))?")
+include_re = re.compile("\s*\"(.*)\"\s*")
+
+def debug_msg(message):
+	if debug:
+		sys.stderr.write(message)
+
+# Parse command line options
+
+def parse_cmdline():
+	for arg in sys.argv[1:]:
+		if arg.startswith("-D"):
+			name = arg[2:]
+			defines[name] = True
+
+def parse_stream(stream):
+	result = read_block(stream, False)
+
+	if result is not None:
+		raise Exception("Mismatched #if in '%s'" % stream.name)
+
+def parse_file(filename):
+	f = open(filename)
+
+	try:
+		parse_stream(f)
+	finally:
+		f.close()
+
+# #include
+
+def cmd_include(arg):
+	# Extract the filename
+
+	match = include_re.match(arg)
+
+	if not match:
+		raise Exception("Invalid 'include' command")
+
+	filename = match.group(1)
+
+	# Open the file and process it
+
+	parse_file(filename)
+
+# #define
+
+def cmd_define(arg):
+	defines[arg] = True
+
+# #undef
+
+def cmd_undef(arg):
+	if arg in defines:
+		del defines[arg]
+
+# #ifdef/#ifndef
+
+def cmd_ifdef(arg, command, stream, ignore):
+
+	# Get the define name
+	name = arg.strip()
+
+	debug_msg("%s %s >\n" % (command, arg))
+
+	# Should we ignore the contents of this block?
+
+	sub_ignore = (name not in defines)
+
+	if "n" in command:
+		sub_ignore = not sub_ignore
+
+	# Parse the block
+
+	result = read_block(stream, ignore or sub_ignore)
+
+	debug_msg("%s %s < (%s)\n" % (command, arg, result))
+
+	# There may be a second "else" block to parse:
+
+	if result == "else":
+		debug_msg("%s %s else >\n" % (command, arg))
+		result = read_block(stream, ignore or (not sub_ignore))
+		debug_msg("%s %s else < (%s)\n" % (command, arg, result))
+
+	# Should end in an endif:
+
+	if result != "endif":
+		raise Exception("'if' block did not end in an 'endif'")
+
+commands = {
+	"include" : cmd_include,
+	"define"  : cmd_define,
+	"undef"   : cmd_undef,
+	"if"      : cmd_ifdef,
+	"ifdef"   : cmd_ifdef,
+	"ifn"     : cmd_ifdef,
+	"ifndef"  : cmd_ifdef,
+}
+
+# Recursive block reading function
+# if 'ignore' argument is 1, contents are ignored
+
+def read_block(stream, ignore):
+
+	for line in stream:
+
+		# Remove newline
+
+		line = line[0:-1]
+
+		# Check if this line has a command
+
+		match = command_re.match(line)
+
+		if match:
+			command = match.group(1)
+			arg = match.group(3)
+
+			if command == "else" or command == "endif":
+				return command
+			elif command not in commands:
+				raise Exception("Unknown command: '%s'" % \
+						command)
+
+			# Get the callback function.
+
+			func = commands[command]
+
+			# Invoke the callback function. #ifdef commands
+			# are a special case and need extra arguments.
+			# Other commands are only executed if we are not
+			# ignoring this block.
+
+			if func == cmd_ifdef:
+				cmd_ifdef(arg, command=command,
+					       stream=stream,
+					       ignore=ignore)
+			elif not ignore:
+				func(arg)
+		else:
+			if not ignore:
+				print(line)
+
+parse_cmdline()
+parse_stream(sys.stdin)
+
--- a/msvc/config.h
+++ b/msvc/config.h
@@ -11,16 +11,19 @@
 #define PACKAGE_NAME "Chocolate Doom"
 
 /* Define to the full name and version of this package. */
-#define PACKAGE_STRING "Chocolate Doom 1.5.0"
+#define PACKAGE_STRING "Chocolate Doom 1.6.0"
 
 /* Define to the one symbol short name of this package. */
 #define PACKAGE_TARNAME "chocolate-doom"
 
 /* Define to the version of this package. */
-#define PACKAGE_VERSION "1.5.0"
+#define PACKAGE_VERSION "1.6.0"
 
+/* Change this when you create your awesome forked version */
+#define PROGRAM_PREFIX "chocolate-"
+
 /* Version number of package */
-#define VERSION "1.5.0"
+#define VERSION "1.6.0"
 
 /* Define to 1 if your processor stores words with the most significant byte
    first (like Motorola and SPARC, unlike Intel and VAX). */
--- a/msvc/win32.rc
+++ b/msvc/win32.rc
@@ -32,8 +32,8 @@
 #endif
 
 1 VERSIONINFO
-PRODUCTVERSION 1,5,0,0
-FILEVERSION 1,5,0,0
+PRODUCTVERSION 1,6,0,0
+FILEVERSION 1,6,0,0
 FILETYPE 1
 BEGIN
 	BLOCK "StringFileInfo"
@@ -40,13 +40,13 @@
 	BEGIN
 		BLOCK "040904E4"
 		BEGIN
-			VALUE "FileVersion", "1.5.0"
-			VALUE "FileDescription", "Chocolate Doom 1.5.0"
+			VALUE "FileVersion", "1.6.0"
+			VALUE "FileDescription", "Chocolate Doom 1.6.0"
 			VALUE "InternalName", "chocolate-doom"
 			VALUE "CompanyName", "[email protected]"
 			VALUE "LegalCopyright", "GNU General Public License"
 			VALUE "ProductName", "Chocolate Doom"
-			VALUE "ProductVersion", "1.5.0"
+			VALUE "ProductVersion", "1.6.0"
 		END
 	END
 END
--- a/opl/opl_win32.c
+++ b/opl/opl_win32.c
@@ -72,8 +72,35 @@
     );
 }
 
-// TODO: MSVC version
-// #elif defined(_MSC_VER) && defined(_M_IX6) ...
+// haleyjd 20110417: MSVC version
+#elif defined(_MSC_VER) && defined(_M_IX86)
+
+static unsigned int OPL_Win32_PortRead(opl_port_t port)
+{
+    unsigned char result;
+    opl_port_t dst_port = opl_port_base + port;
+    
+    __asm    
+    {
+        mov edx, dword ptr [dst_port]
+        in al, dx
+        mov byte ptr [result], al
+    }
+    
+    return result;
+}
+
+static void OPL_Win32_PortWrite(opl_port_t port, unsigned int value)
+{
+    opl_port_t dst_port = opl_port_base + port;
+    
+    __asm    
+    {
+        mov edx, dword ptr [dst_port]
+        mov al, byte ptr [value]
+        out dx, al
+    }
+}
 
 #else
 
--- a/pkg/Makefile.am
+++ b/pkg/Makefile.am
@@ -7,10 +7,13 @@
 osx/Resources/wadfile.png                                               \
 osx/Resources/launcher.nib/designable.nib                               \
 osx/Resources/launcher.nib/keyedobjects.nib                             \
+osx/disk/dir.DS_Store                                                   \
+osx/disk/background.png                                                 \
 osx/GNUmakefile                                                         \
 osx/Info.plist.in       osx/Info-gnustep.plist.in                       \
 osx/PkgInfo                                                             \
 osx/cp-with-libs                                                        \
+osx/dmgfix                                                              \
 osx/main.m                                                              \
 osx/AppController.m     osx/AppController.h                             \
 osx/Execute.m           osx/Execute.h                                   \
--- a/pkg/config.make.in
+++ b/pkg/config.make.in
@@ -22,9 +22,7 @@
 DOC_FILES = README       \
             COPYING      \
             ChangeLog    \
-            INSTALL      \
             NEWS         \
-            BUGS         \
             NOT-BUGS     \
             CMDLINE      \
             TODO
--- a/pkg/osx/AppController.m
+++ b/pkg/osx/AppController.m
@@ -83,6 +83,14 @@
 {
     NSString *extension;
 
+    // This may be an IWAD.  If so, add it to the IWAD configuration;
+    // don't add it like a PWAD.
+
+    if ([self->launcherManager addIWADPath: fileName])
+    {
+        return YES;
+    }
+
     // If this is the first file added, clear out the existing
     // command line.  This allows us to select multiple files
     // in the finder and open them all together (for TCs, etc).
--- a/pkg/osx/Execute.h
+++ b/pkg/osx/Execute.h
@@ -26,6 +26,7 @@
 void SetProgramLocation(const char *path);
 void ExecuteProgram(const char *executable, const char *iwad, const char *args);
 void OpenTerminalWindow(const char *doomwadpath);
+void OpenDocumentation(const char *filename);
 
 #endif /* #ifndef LAUNCHER_EXECUTE_H */
 
--- a/pkg/osx/Execute.m
+++ b/pkg/osx/Execute.m
@@ -175,6 +175,19 @@
     fprintf(stream, "#!/bin/sh\n");
     //fprintf(stream, "set -x\n");
     fprintf(stream, "PATH=\"%s:$PATH\"\n", executable_path);
+
+    // MANPATH is set to point to the directory within the bundle that
+    // contains the Unix manpages.  However, the bundle name or path to
+    // it can contain a space, and OS X doesn't like this!  As a
+    // workaround, create a symlink in /tmp to point to the real directory,
+    // and put *this* in MANPATH.
+
+    fprintf(stream, "rm -f \"/tmp/%s.man\"\n", PACKAGE_TARNAME);
+    fprintf(stream, "ln -s \"%s/man\" \"/tmp/%s.man\"\n",
+                    executable_path, PACKAGE_TARNAME);
+    fprintf(stream, "MANPATH=\"/tmp/%s.man:$(manpath)\"\n", PACKAGE_TARNAME);
+    fprintf(stream, "export MANPATH\n");
+
     fprintf(stream, "DOOMWADPATH=\"%s\"\n", doomwadpath);
     fprintf(stream, "export DOOMWADPATH\n");
     fprintf(stream, "rm -f \"%s\"\n", TEMP_SCRIPT);
@@ -204,5 +217,15 @@
 
     [[NSWorkspace sharedWorkspace] openFile: @TEMP_SCRIPT
                                    withApplication: @"Terminal"];
+}
+
+void OpenDocumentation(const char *filename)
+{
+    NSString *path;
+
+    path = [NSString stringWithFormat: @"%s/Documentation/%s",
+                     executable_path, filename];
+
+    [[NSWorkspace sharedWorkspace] openFile: path];
 }
 
--- a/pkg/osx/GNUmakefile
+++ b/pkg/osx/GNUmakefile
@@ -20,10 +20,18 @@
 
 # DMG file containing package:
 
-$(DMG) : $(STAGING_DIR)
+$(DMG) : tmp.dmg
 	rm -f $@
-	hdiutil create -volname "$(PACKAGE_STRING)" -srcdir $(STAGING_DIR) $@
+	./dmgfix "$(realpath tmp.dmg)" "$(PACKAGE_STRING)" "$(PACKAGE_NAME).app"
+	hdiutil convert -format UDZO -o $@ tmp.dmg
+	rm -f tmp.dmg
 
+tmp.dmg : $(STAGING_DIR)
+	rm -f $@
+	hdiutil makehybrid -hfs -hfs-volume-name "$(PACKAGE_STRING)"     \
+	                   -hfs-openfolder $(STAGING_DIR) $(STAGING_DIR) \
+			   -o tmp.dmg
+
 endif
 
 # Staging dir build for package:
@@ -46,12 +54,13 @@
 SRC_INFO_PLIST=Info.plist
 endif
 
+APP_DOC_DIR=$(APP_BIN_DIR)/Documentation
+APP_DOC_RELDIR=$(patsubst $(STAGING_DIR)/%,%,$(APP_DOC_DIR))
+
 $(STAGING_DIR): launcher $(TOPLEVEL_DOCS)
 	rm -rf $(STAGING_DIR)
 	mkdir $(STAGING_DIR)
 
-	cp $(TOPLEVEL_DOCS) "$(STAGING_DIR)"
-
 	mkdir -p "$(APP_TOP_DIR)"
 	cp -R Resources "$(APP_TOP_DIR)"
 	cp PkgInfo "$(APP_TOP_DIR)"
@@ -59,6 +68,13 @@
 
 	mkdir -p "$(APP_BIN_DIR)"
 
+	mkdir -p "$(APP_DOC_DIR)"
+	cp $(TOPLEVEL_DOCS) "$(APP_DOC_DIR)"
+
+	ln -s "$(APP_DOC_RELDIR)/COPYING" "$(STAGING_DIR)/Software License"
+	ln -s "$(APP_DOC_RELDIR)/README" "$(STAGING_DIR)/README"
+	ln -s /Applications "$(STAGING_DIR)"
+
 	cp launcher "$(APP_BIN_DIR)"
 	$(STRIP) "$(APP_BIN_DIR)/launcher"
 
@@ -73,7 +89,17 @@
 	./cp-with-libs $(TOPLEVEL)/src/$(PROGRAM_PREFIX)setup "$(APP_BIN_DIR)"
 	$(STRIP) "$(APP_BIN_DIR)/$(PROGRAM_PREFIX)setup"
 
+	$(TOPLEVEL)/man/simplecpp -DPRECOMPILED -D__MACOSX__  \
+	             < $(TOPLEVEL)/man/INSTALL.template       \
+	             > "$(APP_DOC_DIR)/INSTALL"
+
 	find $(STAGING_DIR) -name .svn -delete -exec rm -rf {} \; || true
+
+	mkdir -p "$(APP_BIN_DIR)/man/man5" "$(APP_BIN_DIR)/man/man6"
+	cp $(TOPLEVEL)/man/*.5 "$(APP_BIN_DIR)/man/man5"
+	cp $(TOPLEVEL)/man/*.6 "$(APP_BIN_DIR)/man/man6"
+	cp disk/dir.DS_Store $(STAGING_DIR)/.DS_Store
+	cp disk/background.png $(STAGING_DIR)/background.png
 
 clean : launcher_clean
 	rm -f $(DMG)
--- a/pkg/osx/IWADController.h
+++ b/pkg/osx/IWADController.h
@@ -52,6 +52,7 @@
 - (char *) doomWadPath;
 - (void) setEnvironment;
 - (const char *) getGameName;
+- (BOOL) addIWADPath: (NSString *) path;
 
 @end
 
--- a/pkg/osx/IWADController.m
+++ b/pkg/osx/IWADController.m
@@ -384,5 +384,44 @@
     //free(env);
 }
 
+// Examine a path to a WAD and determine whether it is an IWAD file.
+// If so, it is added to the IWAD configuration, and true is returned.
+
+- (BOOL) addIWADPath: (NSString *) path
+{
+    IWADLocation *iwadList[NUM_IWAD_TYPES];
+    NSArray *pathComponents;
+    NSString *filename;
+    unsigned int i;
+
+    [self getIWADList: iwadList];
+
+    // Find an IWAD file that matches the filename in the path that we
+    // have been given.
+
+    pathComponents = [path pathComponents];
+    filename = [pathComponents objectAtIndex: [pathComponents count] - 1];
+
+    for (i = 0; i < NUM_IWAD_TYPES; ++i)
+    {
+        if ([filename caseInsensitiveCompare: IWADFilenames[i]] == 0)
+        {
+            // Configure this IWAD.
+
+            [iwadList[i] setLocation: path];
+
+            // Rebuild dropdown list and select the new IWAD.
+
+            [self setDropdownList];
+            [self->iwadSelector selectItemWithTitle:IWADLabels[i]];
+            return YES;
+        }
+    }
+
+    // No IWAD found with this name.
+
+    return NO;
+}
+
 @end
 
--- a/pkg/osx/LauncherManager.h
+++ b/pkg/osx/LauncherManager.h
@@ -41,9 +41,16 @@
 - (void) runSetup: (id)sender;
 - (void) awakeFromNib;
 - (void) clearCommandLine;
+- (BOOL) addIWADPath: (NSString *) path;
 - (void) addFileToCommandLine: (NSString *) fileName
          forArgument: (NSString *) args;
 - (void) openTerminal: (id) sender;
+
+- (void) openREADME: (id) sender;
+- (void) openINSTALL: (id) sender;
+- (void) openCMDLINE: (id) sender;
+- (void) openCOPYING: (id) sender;
+- (void) openDocumentation: (id) sender;
 
 @end
 
--- a/pkg/osx/LauncherManager.m
+++ b/pkg/osx/LauncherManager.m
@@ -343,6 +343,31 @@
     free(doomwadpath);
 }
 
+- (void) openREADME: (id) sender
+{
+    OpenDocumentation("README");
+}
+
+- (void) openINSTALL: (id) sender
+{
+    OpenDocumentation("INSTALL");
+}
+
+- (void) openCMDLINE: (id) sender
+{
+    OpenDocumentation("CMDLINE");
+}
+
+- (void) openCOPYING: (id) sender
+{
+    OpenDocumentation("COPYING");
+}
+
+- (void) openDocumentation: (id) sender
+{
+    OpenDocumentation("");
+}
+
 - (void) awakeFromNib
 {
     [self->launcherWindow setTitle: @PACKAGE_NAME " Launcher"];
@@ -349,6 +374,11 @@
     [self->launcherWindow center];
     [self->launcherWindow setDefaultButtonCell: [self->launchButton cell]];
     [self setConfig];
+}
+
+- (BOOL) addIWADPath: (NSString *) path
+{
+    return [self->iwadController addIWADPath: path];
 }
 
 @end
--- a/pkg/osx/Resources/launcher.nib/designable.nib
+++ b/pkg/osx/Resources/launcher.nib/designable.nib
@@ -2,19 +2,19 @@
 <archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10">
 	<data>
 		<int key="IBDocument.SystemTarget">1060</int>
-		<string key="IBDocument.SystemVersion">10F569</string>
-		<string key="IBDocument.InterfaceBuilderVersion">823</string>
-		<string key="IBDocument.AppKitVersion">1038.29</string>
+		<string key="IBDocument.SystemVersion">10J869</string>
+		<string key="IBDocument.InterfaceBuilderVersion">851</string>
+		<string key="IBDocument.AppKitVersion">1038.35</string>
 		<string key="IBDocument.HIToolboxVersion">461.00</string>
 		<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
 			<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
-			<string key="NS.object.0">823</string>
+			<string key="NS.object.0">851</string>
 		</object>
 		<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
 			<bool key="EncodedWithXMLCoder">YES</bool>
-			<integer value="29"/>
+			<integer value="228"/>
+			<integer value="370"/>
 			<integer value="2"/>
-			<integer value="227"/>
 		</object>
 		<object class="NSArray" key="IBDocument.PluginDependencies">
 			<bool key="EncodedWithXMLCoder">YES</bool>
@@ -600,6 +600,73 @@
 							<string key="NSName">_NSWindowsMenu</string>
 						</object>
 					</object>
+					<object class="NSMenuItem" id="391919375">
+						<reference key="NSMenu" ref="624798014"/>
+						<string key="NSTitle">Help</string>
+						<string key="NSKeyEquiv"/>
+						<int key="NSMnemonicLoc">2147483647</int>
+						<reference key="NSOnImage" ref="819247708"/>
+						<reference key="NSMixedImage" ref="94574589"/>
+						<string key="NSAction">submenuAction:</string>
+						<object class="NSMenu" key="NSSubmenu" id="733442466">
+							<string key="NSTitle">Help</string>
+							<object class="NSMutableArray" key="NSMenuItems">
+								<bool key="EncodedWithXMLCoder">YES</bool>
+								<object class="NSMenuItem" id="860531190">
+									<reference key="NSMenu" ref="733442466"/>
+									<string key="NSTitle">Introduction</string>
+									<string key="NSKeyEquiv">?</string>
+									<int key="NSKeyEquivModMask">1048576</int>
+									<int key="NSMnemonicLoc">2147483647</int>
+									<reference key="NSOnImage" ref="819247708"/>
+									<reference key="NSMixedImage" ref="94574589"/>
+								</object>
+								<object class="NSMenuItem" id="378926680">
+									<reference key="NSMenu" ref="733442466"/>
+									<string key="NSTitle">Set up guide</string>
+									<string key="NSKeyEquiv"/>
+									<int key="NSMnemonicLoc">2147483647</int>
+									<reference key="NSOnImage" ref="819247708"/>
+									<reference key="NSMixedImage" ref="94574589"/>
+								</object>
+								<object class="NSMenuItem" id="784926086">
+									<reference key="NSMenu" ref="733442466"/>
+									<string key="NSTitle">Command line reference</string>
+									<string key="NSKeyEquiv"/>
+									<int key="NSMnemonicLoc">2147483647</int>
+									<reference key="NSOnImage" ref="819247708"/>
+									<reference key="NSMixedImage" ref="94574589"/>
+								</object>
+								<object class="NSMenuItem" id="913959081">
+									<reference key="NSMenu" ref="733442466"/>
+									<string key="NSTitle">More documentation...</string>
+									<string key="NSKeyEquiv"/>
+									<int key="NSMnemonicLoc">2147483647</int>
+									<reference key="NSOnImage" ref="819247708"/>
+									<reference key="NSMixedImage" ref="94574589"/>
+								</object>
+								<object class="NSMenuItem" id="258703436">
+									<reference key="NSMenu" ref="733442466"/>
+									<bool key="NSIsDisabled">YES</bool>
+									<bool key="NSIsSeparator">YES</bool>
+									<string key="NSTitle"/>
+									<string key="NSKeyEquiv"/>
+									<int key="NSMnemonicLoc">2147483647</int>
+									<reference key="NSOnImage" ref="819247708"/>
+									<reference key="NSMixedImage" ref="94574589"/>
+								</object>
+								<object class="NSMenuItem" id="590365178">
+									<reference key="NSMenu" ref="733442466"/>
+									<string key="NSTitle">Software license</string>
+									<string key="NSKeyEquiv"/>
+									<int key="NSMnemonicLoc">2147483647</int>
+									<reference key="NSOnImage" ref="819247708"/>
+									<reference key="NSMixedImage" ref="94574589"/>
+								</object>
+							</object>
+							<string key="NSName">_NSHelpMenu</string>
+						</object>
+					</object>
 				</object>
 				<string key="NSName">_NSMainMenu</string>
 			</object>
@@ -612,7 +679,7 @@
 			<object class="NSWindowTemplate" id="193084417">
 				<int key="NSWindowStyleMask">7</int>
 				<int key="NSWindowBacking">2</int>
-				<string key="NSWindowRect">{{377, 409}, {480, 316}}</string>
+				<string key="NSWindowRect">{{377, 417}, {518, 308}}</string>
 				<int key="NSWTFlags">1886912512</int>
 				<string key="NSWindowTitle">IWAD configuration</string>
 				<object class="NSMutableString" key="NSWindowClass">
@@ -628,301 +695,476 @@
 					<int key="NSvFlags">256</int>
 					<object class="NSMutableArray" key="NSSubviews">
 						<bool key="EncodedWithXMLCoder">YES</bool>
-						<object class="NSTextField" id="348674481">
+						<object class="NSButton" id="658359713">
 							<reference key="NSNextResponder" ref="145141922"/>
 							<int key="NSvFlags">256</int>
-							<string key="NSFrame">{{17, 285}, {446, 11}}</string>
+							<string key="NSFrame">{{422, 12}, {82, 32}}</string>
 							<reference key="NSSuperview" ref="145141922"/>
 							<bool key="NSEnabled">YES</bool>
-							<object class="NSTextFieldCell" key="NSCell" id="522582983">
+							<object class="NSButtonCell" key="NSCell" id="235375789">
 								<int key="NSCellFlags">67239424</int>
-								<int key="NSCellFlags2">272629760</int>
-								<string key="NSContents">Doom IWAD location (doom.wad):</string>
-								<reference key="NSSupport" ref="22"/>
-								<reference key="NSControlView" ref="348674481"/>
-								<reference key="NSBackgroundColor" ref="77619338"/>
-								<reference key="NSTextColor" ref="206071849"/>
-							</object>
-						</object>
-						<object class="NSTextField" id="215057262">
-							<reference key="NSNextResponder" ref="145141922"/>
-							<int key="NSvFlags">256</int>
-							<string key="NSFrame">{{20, 255}, {369, 22}}</string>
-							<reference key="NSSuperview" ref="145141922"/>
-							<bool key="NSEnabled">YES</bool>
-							<object class="NSTextFieldCell" key="NSCell" id="596525351">
-								<int key="NSCellFlags">-1804468671</int>
-								<int key="NSCellFlags2">272630784</int>
-								<string key="NSContents"/>
-								<reference key="NSSupport" ref="407649812"/>
-								<reference key="NSControlView" ref="215057262"/>
-								<bool key="NSDrawsBackground">YES</bool>
-								<reference key="NSBackgroundColor" ref="612330193"/>
-								<reference key="NSTextColor" ref="943265597"/>
-							</object>
-						</object>
-						<object class="NSButton" id="410786529">
-							<reference key="NSNextResponder" ref="145141922"/>
-							<int key="NSvFlags">256</int>
-							<string key="NSFrame">{{397, 255}, {63, 23}}</string>
-							<reference key="NSSuperview" ref="145141922"/>
-							<bool key="NSEnabled">YES</bool>
-							<object class="NSButtonCell" key="NSCell" id="673476660">
-								<int key="NSCellFlags">67239424</int>
 								<int key="NSCellFlags2">134217728</int>
-								<string key="NSContents">Set...</string>
+								<string key="NSContents">Close</string>
 								<reference key="NSSupport" ref="407649812"/>
-								<reference key="NSControlView" ref="410786529"/>
-								<int key="NSButtonFlags">-2038021889</int>
-								<int key="NSButtonFlags2">32</int>
-								<reference key="NSAlternateImage" ref="813720862"/>
+								<reference key="NSControlView" ref="658359713"/>
+								<int key="NSButtonFlags">-2038284033</int>
+								<int key="NSButtonFlags2">1</int>
+								<reference key="NSAlternateImage" ref="407649812"/>
 								<string key="NSAlternateContents"/>
-								<string key="NSKeyEquivalent"/>
-								<int key="NSPeriodicDelay">400</int>
-								<int key="NSPeriodicInterval">75</int>
+								<object class="NSMutableString" key="NSKeyEquivalent">
+									<characters key="NS.bytes"/>
+								</object>
+								<int key="NSPeriodicDelay">200</int>
+								<int key="NSPeriodicInterval">25</int>
 							</object>
 						</object>
-						<object class="NSTextField" id="316721564">
+						<object class="NSButton" id="811205099">
 							<reference key="NSNextResponder" ref="145141922"/>
-							<int key="NSvFlags">256</int>
-							<string key="NSFrame">{{17, 236}, {446, 11}}</string>
+							<int key="NSvFlags">268</int>
+							<string key="NSFrame">{{17, 16}, {25, 25}}</string>
 							<reference key="NSSuperview" ref="145141922"/>
 							<bool key="NSEnabled">YES</bool>
-							<object class="NSTextFieldCell" key="NSCell" id="663066257">
+							<object class="NSButtonCell" key="NSCell" id="33467307">
 								<int key="NSCellFlags">67239424</int>
-								<int key="NSCellFlags2">272629760</int>
-								<string key="NSContents">Doom II IWAD location (doom2.wad):</string>
-								<reference key="NSSupport" ref="22"/>
-								<reference key="NSControlView" ref="316721564"/>
-								<reference key="NSBackgroundColor" ref="77619338"/>
-								<reference key="NSTextColor" ref="206071849"/>
-							</object>
-						</object>
-						<object class="NSTextField" id="458378991">
-							<reference key="NSNextResponder" ref="145141922"/>
-							<int key="NSvFlags">256</int>
-							<string key="NSFrame">{{20, 206}, {369, 22}}</string>
-							<reference key="NSSuperview" ref="145141922"/>
-							<bool key="NSEnabled">YES</bool>
-							<object class="NSTextFieldCell" key="NSCell" id="848829815">
-								<int key="NSCellFlags">-1804468671</int>
-								<int key="NSCellFlags2">272630784</int>
-								<string key="NSContents"/>
-								<reference key="NSSupport" ref="407649812"/>
-								<reference key="NSControlView" ref="458378991"/>
-								<bool key="NSDrawsBackground">YES</bool>
-								<reference key="NSBackgroundColor" ref="612330193"/>
-								<reference key="NSTextColor" ref="943265597"/>
-							</object>
-						</object>
-						<object class="NSButton" id="644218899">
-							<reference key="NSNextResponder" ref="145141922"/>
-							<int key="NSvFlags">256</int>
-							<string key="NSFrame">{{397, 206}, {63, 23}}</string>
-							<reference key="NSSuperview" ref="145141922"/>
-							<bool key="NSEnabled">YES</bool>
-							<object class="NSButtonCell" key="NSCell" id="63361904">
-								<int key="NSCellFlags">67239424</int>
 								<int key="NSCellFlags2">134217728</int>
-								<string key="NSContents">Set...</string>
-								<reference key="NSSupport" ref="407649812"/>
-								<reference key="NSControlView" ref="644218899"/>
-								<int key="NSButtonFlags">-2038021889</int>
-								<int key="NSButtonFlags2">32</int>
-								<reference key="NSAlternateImage" ref="813720862"/>
-								<string key="NSAlternateContents"/>
-								<string key="NSKeyEquivalent"/>
-								<int key="NSPeriodicDelay">400</int>
-								<int key="NSPeriodicInterval">75</int>
-							</object>
-						</object>
-						<object class="NSTextField" id="179636494">
-							<reference key="NSNextResponder" ref="145141922"/>
-							<int key="NSvFlags">256</int>
-							<string key="NSFrame">{{17, 187}, {446, 11}}</string>
-							<reference key="NSSuperview" ref="145141922"/>
-							<bool key="NSEnabled">YES</bool>
-							<object class="NSTextFieldCell" key="NSCell" id="84857374">
-								<int key="NSCellFlags">67239424</int>
-								<int key="NSCellFlags2">272629760</int>
-								<string type="base64-UTF8" key="NSContents">RmluYWwgRG9vbTogVE5UOiBFdmlsdXRpb24gbG9jYXRpb24gKHRudC53YWQpOgo</string>
-								<reference key="NSSupport" ref="22"/>
-								<reference key="NSControlView" ref="179636494"/>
-								<reference key="NSBackgroundColor" ref="77619338"/>
-								<reference key="NSTextColor" ref="206071849"/>
-							</object>
-						</object>
-						<object class="NSTextField" id="1021143679">
-							<reference key="NSNextResponder" ref="145141922"/>
-							<int key="NSvFlags">256</int>
-							<string key="NSFrame">{{20, 157}, {369, 22}}</string>
-							<reference key="NSSuperview" ref="145141922"/>
-							<bool key="NSEnabled">YES</bool>
-							<object class="NSTextFieldCell" key="NSCell" id="629867670">
-								<int key="NSCellFlags">-1804468671</int>
-								<int key="NSCellFlags2">272630784</int>
 								<string key="NSContents"/>
 								<reference key="NSSupport" ref="407649812"/>
-								<reference key="NSControlView" ref="1021143679"/>
-								<bool key="NSDrawsBackground">YES</bool>
-								<reference key="NSBackgroundColor" ref="612330193"/>
-								<reference key="NSTextColor" ref="943265597"/>
-							</object>
-						</object>
-						<object class="NSButton" id="539465960">
-							<reference key="NSNextResponder" ref="145141922"/>
-							<int key="NSvFlags">256</int>
-							<string key="NSFrame">{{397, 157}, {63, 23}}</string>
-							<reference key="NSSuperview" ref="145141922"/>
-							<bool key="NSEnabled">YES</bool>
-							<object class="NSButtonCell" key="NSCell" id="979277836">
-								<int key="NSCellFlags">67239424</int>
-								<int key="NSCellFlags2">134217728</int>
-								<string key="NSContents">Set...</string>
-								<reference key="NSSupport" ref="407649812"/>
-								<reference key="NSControlView" ref="539465960"/>
-								<int key="NSButtonFlags">-2038021889</int>
-								<int key="NSButtonFlags2">32</int>
-								<reference key="NSAlternateImage" ref="813720862"/>
+								<reference key="NSControlView" ref="811205099"/>
+								<int key="NSButtonFlags">-2038415105</int>
+								<int key="NSButtonFlags2">161</int>
 								<string key="NSAlternateContents"/>
 								<string key="NSKeyEquivalent"/>
-								<int key="NSPeriodicDelay">400</int>
-								<int key="NSPeriodicInterval">75</int>
+								<int key="NSPeriodicDelay">200</int>
+								<int key="NSPeriodicInterval">25</int>
 							</object>
 						</object>
-						<object class="NSTextField" id="712311825">
+						<object class="NSTabView" id="793342693">
 							<reference key="NSNextResponder" ref="145141922"/>
-							<int key="NSvFlags">256</int>
-							<string key="NSFrame">{{17, 138}, {446, 11}}</string>
+							<int key="NSvFlags">12</int>
+							<string key="NSFrame">{{13, 42}, {492, 260}}</string>
 							<reference key="NSSuperview" ref="145141922"/>
-							<bool key="NSEnabled">YES</bool>
-							<object class="NSTextFieldCell" key="NSCell" id="131918744">
-								<int key="NSCellFlags">67239424</int>
-								<int key="NSCellFlags2">272629760</int>
-								<string type="base64-UTF8" key="NSContents">RmluYWwgRG9vbTogUGx1dG9uaWEgRXhwZXJpbWVudCBsb2NhdGlvbiAocGx1dG9uaWEud2FkKToKA</string>
-								<reference key="NSSupport" ref="22"/>
-								<reference key="NSControlView" ref="712311825"/>
-								<reference key="NSBackgroundColor" ref="77619338"/>
-								<reference key="NSTextColor" ref="206071849"/>
+							<object class="NSMutableArray" key="NSTabViewItems">
+								<bool key="EncodedWithXMLCoder">YES</bool>
+								<object class="NSTabViewItem" id="939760325">
+									<string key="NSIdentifier">1</string>
+									<object class="NSView" key="NSView" id="948790550">
+										<reference key="NSNextResponder" ref="793342693"/>
+										<int key="NSvFlags">256</int>
+										<object class="NSMutableArray" key="NSSubviews">
+											<bool key="EncodedWithXMLCoder">YES</bool>
+											<object class="NSTextField" id="348674481">
+												<reference key="NSNextResponder" ref="948790550"/>
+												<int key="NSvFlags">256</int>
+												<string key="NSFrame">{{14, 200}, {446, 11}}</string>
+												<reference key="NSSuperview" ref="948790550"/>
+												<bool key="NSEnabled">YES</bool>
+												<object class="NSTextFieldCell" key="NSCell" id="522582983">
+													<int key="NSCellFlags">67239424</int>
+													<int key="NSCellFlags2">272629760</int>
+													<string key="NSContents">Doom IWAD location (doom.wad):</string>
+													<reference key="NSSupport" ref="22"/>
+													<reference key="NSControlView" ref="348674481"/>
+													<reference key="NSBackgroundColor" ref="77619338"/>
+													<reference key="NSTextColor" ref="206071849"/>
+												</object>
+											</object>
+											<object class="NSTextField" id="215057262">
+												<reference key="NSNextResponder" ref="948790550"/>
+												<int key="NSvFlags">256</int>
+												<string key="NSFrame">{{17, 171}, {369, 22}}</string>
+												<reference key="NSSuperview" ref="948790550"/>
+												<bool key="NSEnabled">YES</bool>
+												<object class="NSTextFieldCell" key="NSCell" id="596525351">
+													<int key="NSCellFlags">-1804468671</int>
+													<int key="NSCellFlags2">272630784</int>
+													<string key="NSContents"/>
+													<reference key="NSSupport" ref="407649812"/>
+													<reference key="NSControlView" ref="215057262"/>
+													<bool key="NSDrawsBackground">YES</bool>
+													<reference key="NSBackgroundColor" ref="612330193"/>
+													<reference key="NSTextColor" ref="943265597"/>
+												</object>
+											</object>
+											<object class="NSButton" id="410786529">
+												<reference key="NSNextResponder" ref="948790550"/>
+												<int key="NSvFlags">256</int>
+												<string key="NSFrame">{{393, 169}, {63, 23}}</string>
+												<reference key="NSSuperview" ref="948790550"/>
+												<bool key="NSEnabled">YES</bool>
+												<object class="NSButtonCell" key="NSCell" id="673476660">
+													<int key="NSCellFlags">67239424</int>
+													<int key="NSCellFlags2">134217728</int>
+													<string key="NSContents">Set...</string>
+													<reference key="NSSupport" ref="407649812"/>
+													<reference key="NSControlView" ref="410786529"/>
+													<int key="NSButtonFlags">-2038021889</int>
+													<int key="NSButtonFlags2">32</int>
+													<reference key="NSAlternateImage" ref="813720862"/>
+													<string key="NSAlternateContents"/>
+													<string key="NSKeyEquivalent"/>
+													<int key="NSPeriodicDelay">400</int>
+													<int key="NSPeriodicInterval">75</int>
+												</object>
+											</object>
+											<object class="NSTextField" id="316721564">
+												<reference key="NSNextResponder" ref="948790550"/>
+												<int key="NSvFlags">256</int>
+												<string key="NSFrame">{{14, 151}, {446, 11}}</string>
+												<reference key="NSSuperview" ref="948790550"/>
+												<bool key="NSEnabled">YES</bool>
+												<object class="NSTextFieldCell" key="NSCell" id="663066257">
+													<int key="NSCellFlags">67239424</int>
+													<int key="NSCellFlags2">272629760</int>
+													<string key="NSContents">Doom II IWAD location (doom2.wad):</string>
+													<reference key="NSSupport" ref="22"/>
+													<reference key="NSControlView" ref="316721564"/>
+													<reference key="NSBackgroundColor" ref="77619338"/>
+													<reference key="NSTextColor" ref="206071849"/>
+												</object>
+											</object>
+											<object class="NSTextField" id="458378991">
+												<reference key="NSNextResponder" ref="948790550"/>
+												<int key="NSvFlags">256</int>
+												<string key="NSFrame">{{17, 121}, {369, 22}}</string>
+												<reference key="NSSuperview" ref="948790550"/>
+												<bool key="NSEnabled">YES</bool>
+												<object class="NSTextFieldCell" key="NSCell" id="848829815">
+													<int key="NSCellFlags">-1804468671</int>
+													<int key="NSCellFlags2">272630784</int>
+													<string key="NSContents"/>
+													<reference key="NSSupport" ref="407649812"/>
+													<reference key="NSControlView" ref="458378991"/>
+													<bool key="NSDrawsBackground">YES</bool>
+													<reference key="NSBackgroundColor" ref="612330193"/>
+													<reference key="NSTextColor" ref="943265597"/>
+												</object>
+											</object>
+											<object class="NSButton" id="644218899">
+												<reference key="NSNextResponder" ref="948790550"/>
+												<int key="NSvFlags">256</int>
+												<string key="NSFrame">{{393, 121}, {63, 23}}</string>
+												<reference key="NSSuperview" ref="948790550"/>
+												<bool key="NSEnabled">YES</bool>
+												<object class="NSButtonCell" key="NSCell" id="63361904">
+													<int key="NSCellFlags">67239424</int>
+													<int key="NSCellFlags2">134217728</int>
+													<string key="NSContents">Set...</string>
+													<reference key="NSSupport" ref="407649812"/>
+													<reference key="NSControlView" ref="644218899"/>
+													<int key="NSButtonFlags">-2038021889</int>
+													<int key="NSButtonFlags2">32</int>
+													<reference key="NSAlternateImage" ref="813720862"/>
+													<string key="NSAlternateContents"/>
+													<string key="NSKeyEquivalent"/>
+													<int key="NSPeriodicDelay">400</int>
+													<int key="NSPeriodicInterval">75</int>
+												</object>
+											</object>
+											<object class="NSTextField" id="179636494">
+												<reference key="NSNextResponder" ref="948790550"/>
+												<int key="NSvFlags">256</int>
+												<string key="NSFrame">{{14, 103}, {446, 11}}</string>
+												<reference key="NSSuperview" ref="948790550"/>
+												<bool key="NSEnabled">YES</bool>
+												<object class="NSTextFieldCell" key="NSCell" id="84857374">
+													<int key="NSCellFlags">67239424</int>
+													<int key="NSCellFlags2">272629760</int>
+													<string type="base64-UTF8" key="NSContents">RmluYWwgRG9vbTogVE5UOiBFdmlsdXRpb24gbG9jYXRpb24gKHRudC53YWQpOgo</string>
+													<reference key="NSSupport" ref="22"/>
+													<reference key="NSControlView" ref="179636494"/>
+													<reference key="NSBackgroundColor" ref="77619338"/>
+													<reference key="NSTextColor" ref="206071849"/>
+												</object>
+											</object>
+											<object class="NSTextField" id="1021143679">
+												<reference key="NSNextResponder" ref="948790550"/>
+												<int key="NSvFlags">256</int>
+												<string key="NSFrame">{{17, 73}, {369, 22}}</string>
+												<reference key="NSSuperview" ref="948790550"/>
+												<bool key="NSEnabled">YES</bool>
+												<object class="NSTextFieldCell" key="NSCell" id="629867670">
+													<int key="NSCellFlags">-1804468671</int>
+													<int key="NSCellFlags2">272630784</int>
+													<string key="NSContents"/>
+													<reference key="NSSupport" ref="407649812"/>
+													<reference key="NSControlView" ref="1021143679"/>
+													<bool key="NSDrawsBackground">YES</bool>
+													<reference key="NSBackgroundColor" ref="612330193"/>
+													<reference key="NSTextColor" ref="943265597"/>
+												</object>
+											</object>
+											<object class="NSButton" id="539465960">
+												<reference key="NSNextResponder" ref="948790550"/>
+												<int key="NSvFlags">256</int>
+												<string key="NSFrame">{{395, 73}, {63, 23}}</string>
+												<reference key="NSSuperview" ref="948790550"/>
+												<bool key="NSEnabled">YES</bool>
+												<object class="NSButtonCell" key="NSCell" id="979277836">
+													<int key="NSCellFlags">67239424</int>
+													<int key="NSCellFlags2">134217728</int>
+													<string key="NSContents">Set...</string>
+													<reference key="NSSupport" ref="407649812"/>
+													<reference key="NSControlView" ref="539465960"/>
+													<int key="NSButtonFlags">-2038021889</int>
+													<int key="NSButtonFlags2">32</int>
+													<reference key="NSAlternateImage" ref="813720862"/>
+													<string key="NSAlternateContents"/>
+													<string key="NSKeyEquivalent"/>
+													<int key="NSPeriodicDelay">400</int>
+													<int key="NSPeriodicInterval">75</int>
+												</object>
+											</object>
+											<object class="NSTextField" id="712311825">
+												<reference key="NSNextResponder" ref="948790550"/>
+												<int key="NSvFlags">256</int>
+												<string key="NSFrame">{{14, 54}, {446, 11}}</string>
+												<reference key="NSSuperview" ref="948790550"/>
+												<bool key="NSEnabled">YES</bool>
+												<object class="NSTextFieldCell" key="NSCell" id="131918744">
+													<int key="NSCellFlags">67239424</int>
+													<int key="NSCellFlags2">272629760</int>
+													<string type="base64-UTF8" key="NSContents">RmluYWwgRG9vbTogUGx1dG9uaWEgRXhwZXJpbWVudCBsb2NhdGlvbiAocGx1dG9uaWEud2FkKToKA</string>
+													<reference key="NSSupport" ref="22"/>
+													<reference key="NSControlView" ref="712311825"/>
+													<reference key="NSBackgroundColor" ref="77619338"/>
+													<reference key="NSTextColor" ref="206071849"/>
+												</object>
+											</object>
+											<object class="NSTextField" id="355049668">
+												<reference key="NSNextResponder" ref="948790550"/>
+												<int key="NSvFlags">256</int>
+												<string key="NSFrame">{{17, 24}, {369, 22}}</string>
+												<reference key="NSSuperview" ref="948790550"/>
+												<bool key="NSEnabled">YES</bool>
+												<object class="NSTextFieldCell" key="NSCell" id="17259252">
+													<int key="NSCellFlags">-1804468671</int>
+													<int key="NSCellFlags2">272630784</int>
+													<string key="NSContents"/>
+													<reference key="NSSupport" ref="407649812"/>
+													<reference key="NSControlView" ref="355049668"/>
+													<bool key="NSDrawsBackground">YES</bool>
+													<reference key="NSBackgroundColor" ref="612330193"/>
+													<reference key="NSTextColor" ref="943265597"/>
+												</object>
+											</object>
+											<object class="NSButton" id="602477213">
+												<reference key="NSNextResponder" ref="948790550"/>
+												<int key="NSvFlags">256</int>
+												<string key="NSFrame">{{395, 24}, {63, 23}}</string>
+												<reference key="NSSuperview" ref="948790550"/>
+												<bool key="NSEnabled">YES</bool>
+												<object class="NSButtonCell" key="NSCell" id="406066834">
+													<int key="NSCellFlags">67239424</int>
+													<int key="NSCellFlags2">134217728</int>
+													<string key="NSContents">Set...</string>
+													<reference key="NSSupport" ref="407649812"/>
+													<reference key="NSControlView" ref="602477213"/>
+													<int key="NSButtonFlags">-2038021889</int>
+													<int key="NSButtonFlags2">32</int>
+													<reference key="NSAlternateImage" ref="813720862"/>
+													<string key="NSAlternateContents"/>
+													<string key="NSKeyEquivalent"/>
+													<int key="NSPeriodicDelay">400</int>
+													<int key="NSPeriodicInterval">75</int>
+												</object>
+											</object>
+										</object>
+										<string key="NSFrame">{{10, 33}, {472, 214}}</string>
+										<reference key="NSSuperview" ref="793342693"/>
+									</object>
+									<string key="NSLabel">Doom</string>
+									<reference key="NSColor" ref="77619338"/>
+									<reference key="NSTabView" ref="793342693"/>
+								</object>
+								<object class="NSTabViewItem" id="989716837">
+									<string key="NSIdentifier">2</string>
+									<object class="NSView" key="NSView" id="1000383860">
+										<nil key="NSNextResponder"/>
+										<int key="NSvFlags">256</int>
+										<object class="NSMutableArray" key="NSSubviews">
+											<bool key="EncodedWithXMLCoder">YES</bool>
+											<object class="NSTextField" id="452288864">
+												<reference key="NSNextResponder" ref="1000383860"/>
+												<int key="NSvFlags">256</int>
+												<string key="NSFrame">{{14, 103}, {446, 11}}</string>
+												<reference key="NSSuperview" ref="1000383860"/>
+												<bool key="NSEnabled">YES</bool>
+												<object class="NSTextFieldCell" key="NSCell" id="969661180">
+													<int key="NSCellFlags">67239424</int>
+													<int key="NSCellFlags2">272629760</int>
+													<string key="NSContents">Chex Quest IWAD location (chex.wad):</string>
+													<reference key="NSSupport" ref="22"/>
+													<reference key="NSControlView" ref="452288864"/>
+													<reference key="NSBackgroundColor" ref="77619338"/>
+													<reference key="NSTextColor" ref="206071849"/>
+												</object>
+											</object>
+											<object class="NSTextField" id="625273251">
+												<reference key="NSNextResponder" ref="1000383860"/>
+												<int key="NSvFlags">256</int>
+												<string key="NSFrame">{{17, 73}, {369, 22}}</string>
+												<reference key="NSSuperview" ref="1000383860"/>
+												<bool key="NSEnabled">YES</bool>
+												<object class="NSTextFieldCell" key="NSCell" id="857754300">
+													<int key="NSCellFlags">-1804468671</int>
+													<int key="NSCellFlags2">272630784</int>
+													<string key="NSContents"/>
+													<reference key="NSSupport" ref="407649812"/>
+													<reference key="NSControlView" ref="625273251"/>
+													<bool key="NSDrawsBackground">YES</bool>
+													<reference key="NSBackgroundColor" ref="612330193"/>
+													<reference key="NSTextColor" ref="943265597"/>
+												</object>
+											</object>
+											<object class="NSButton" id="680095551">
+												<reference key="NSNextResponder" ref="1000383860"/>
+												<int key="NSvFlags">256</int>
+												<string key="NSFrame">{{395, 73}, {63, 23}}</string>
+												<reference key="NSSuperview" ref="1000383860"/>
+												<bool key="NSEnabled">YES</bool>
+												<object class="NSButtonCell" key="NSCell" id="1012408786">
+													<int key="NSCellFlags">67239424</int>
+													<int key="NSCellFlags2">134217728</int>
+													<string key="NSContents">Set...</string>
+													<reference key="NSSupport" ref="407649812"/>
+													<reference key="NSControlView" ref="680095551"/>
+													<int key="NSButtonFlags">-2038021889</int>
+													<int key="NSButtonFlags2">32</int>
+													<reference key="NSAlternateImage" ref="813720862"/>
+													<string key="NSAlternateContents"/>
+													<string key="NSKeyEquivalent"/>
+													<int key="NSPeriodicDelay">400</int>
+													<int key="NSPeriodicInterval">75</int>
+												</object>
+											</object>
+											<object class="NSButton" id="318836161">
+												<reference key="NSNextResponder" ref="1000383860"/>
+												<int key="NSvFlags">256</int>
+												<string key="NSFrame">{{393, 122}, {63, 23}}</string>
+												<reference key="NSSuperview" ref="1000383860"/>
+												<bool key="NSEnabled">YES</bool>
+												<object class="NSButtonCell" key="NSCell" id="118467388">
+													<int key="NSCellFlags">67239424</int>
+													<int key="NSCellFlags2">134217728</int>
+													<string key="NSContents">Set...</string>
+													<reference key="NSSupport" ref="407649812"/>
+													<reference key="NSControlView" ref="318836161"/>
+													<int key="NSButtonFlags">-2038021889</int>
+													<int key="NSButtonFlags2">32</int>
+													<reference key="NSAlternateImage" ref="813720862"/>
+													<string key="NSAlternateContents"/>
+													<string key="NSKeyEquivalent"/>
+													<int key="NSPeriodicDelay">400</int>
+													<int key="NSPeriodicInterval">75</int>
+												</object>
+											</object>
+											<object class="NSTextField" id="634339523">
+												<reference key="NSNextResponder" ref="1000383860"/>
+												<int key="NSvFlags">268</int>
+												<string key="NSFrame">{{17, 122}, {369, 22}}</string>
+												<reference key="NSSuperview" ref="1000383860"/>
+												<bool key="NSEnabled">YES</bool>
+												<object class="NSTextFieldCell" key="NSCell" id="247064311">
+													<int key="NSCellFlags">-1804468671</int>
+													<int key="NSCellFlags2">272630784</int>
+													<string key="NSContents"/>
+													<reference key="NSSupport" ref="407649812"/>
+													<reference key="NSControlView" ref="634339523"/>
+													<bool key="NSDrawsBackground">YES</bool>
+													<reference key="NSBackgroundColor" ref="612330193"/>
+													<reference key="NSTextColor" ref="943265597"/>
+												</object>
+											</object>
+											<object class="NSTextField" id="568653906">
+												<reference key="NSNextResponder" ref="1000383860"/>
+												<int key="NSvFlags">268</int>
+												<string key="NSFrame">{{17, 171}, {369, 22}}</string>
+												<reference key="NSSuperview" ref="1000383860"/>
+												<bool key="NSEnabled">YES</bool>
+												<object class="NSTextFieldCell" key="NSCell" id="332680482">
+													<int key="NSCellFlags">-1804468671</int>
+													<int key="NSCellFlags2">272630784</int>
+													<string key="NSContents"/>
+													<reference key="NSSupport" ref="407649812"/>
+													<reference key="NSControlView" ref="568653906"/>
+													<bool key="NSDrawsBackground">YES</bool>
+													<reference key="NSBackgroundColor" ref="612330193"/>
+													<reference key="NSTextColor" ref="943265597"/>
+												</object>
+											</object>
+											<object class="NSTextField" id="840089166">
+												<reference key="NSNextResponder" ref="1000383860"/>
+												<int key="NSvFlags">256</int>
+												<string key="NSFrame">{{14, 146}, {446, 17}}</string>
+												<reference key="NSSuperview" ref="1000383860"/>
+												<bool key="NSEnabled">YES</bool>
+												<object class="NSTextFieldCell" key="NSCell" id="1045009541">
+													<int key="NSCellFlags">67239424</int>
+													<int key="NSCellFlags2">272629760</int>
+													<string key="NSContents">Hexen IWAD location (hexen.wad):</string>
+													<reference key="NSSupport" ref="22"/>
+													<reference key="NSControlView" ref="840089166"/>
+													<reference key="NSBackgroundColor" ref="77619338"/>
+													<reference key="NSTextColor" ref="206071849"/>
+												</object>
+											</object>
+											<object class="NSTextField" id="10172086">
+												<reference key="NSNextResponder" ref="1000383860"/>
+												<int key="NSvFlags">256</int>
+												<string key="NSFrame">{{14, 194}, {446, 17}}</string>
+												<reference key="NSSuperview" ref="1000383860"/>
+												<bool key="NSEnabled">YES</bool>
+												<object class="NSTextFieldCell" key="NSCell" id="738481735">
+													<int key="NSCellFlags">67239424</int>
+													<int key="NSCellFlags2">272629760</int>
+													<string key="NSContents">Heretic IWAD location (heretic.wad):</string>
+													<reference key="NSSupport" ref="22"/>
+													<reference key="NSControlView" ref="10172086"/>
+													<reference key="NSBackgroundColor" ref="77619338"/>
+													<reference key="NSTextColor" ref="206071849"/>
+												</object>
+											</object>
+											<object class="NSButton" id="198489100">
+												<reference key="NSNextResponder" ref="1000383860"/>
+												<int key="NSvFlags">256</int>
+												<string key="NSFrame">{{393, 169}, {63, 23}}</string>
+												<reference key="NSSuperview" ref="1000383860"/>
+												<bool key="NSEnabled">YES</bool>
+												<object class="NSButtonCell" key="NSCell" id="670956484">
+													<int key="NSCellFlags">67239424</int>
+													<int key="NSCellFlags2">134217728</int>
+													<string key="NSContents">Set...</string>
+													<reference key="NSSupport" ref="407649812"/>
+													<reference key="NSControlView" ref="198489100"/>
+													<int key="NSButtonFlags">-2038021889</int>
+													<int key="NSButtonFlags2">32</int>
+													<reference key="NSAlternateImage" ref="813720862"/>
+													<string key="NSAlternateContents"/>
+													<string key="NSKeyEquivalent"/>
+													<int key="NSPeriodicDelay">400</int>
+													<int key="NSPeriodicInterval">75</int>
+												</object>
+											</object>
+										</object>
+										<string key="NSFrame">{{10, 33}, {472, 214}}</string>
+									</object>
+									<string key="NSLabel">Other games</string>
+									<reference key="NSColor" ref="77619338"/>
+									<reference key="NSTabView" ref="793342693"/>
+								</object>
 							</object>
-						</object>
-						<object class="NSTextField" id="355049668">
-							<reference key="NSNextResponder" ref="145141922"/>
-							<int key="NSvFlags">256</int>
-							<string key="NSFrame">{{20, 108}, {369, 22}}</string>
-							<reference key="NSSuperview" ref="145141922"/>
-							<bool key="NSEnabled">YES</bool>
-							<object class="NSTextFieldCell" key="NSCell" id="17259252">
-								<int key="NSCellFlags">-1804468671</int>
-								<int key="NSCellFlags2">272630784</int>
-								<string key="NSContents"/>
-								<reference key="NSSupport" ref="407649812"/>
-								<reference key="NSControlView" ref="355049668"/>
-								<bool key="NSDrawsBackground">YES</bool>
-								<reference key="NSBackgroundColor" ref="612330193"/>
-								<reference key="NSTextColor" ref="943265597"/>
+							<reference key="NSSelectedTabViewItem" ref="939760325"/>
+							<reference key="NSFont" ref="407649812"/>
+							<int key="NSTvFlags">0</int>
+							<bool key="NSAllowTruncatedLabels">YES</bool>
+							<bool key="NSDrawsBackground">YES</bool>
+							<object class="NSMutableArray" key="NSSubviews">
+								<bool key="EncodedWithXMLCoder">YES</bool>
+								<reference ref="948790550"/>
 							</object>
 						</object>
-						<object class="NSButton" id="602477213">
-							<reference key="NSNextResponder" ref="145141922"/>
-							<int key="NSvFlags">256</int>
-							<string key="NSFrame">{{397, 108}, {63, 23}}</string>
-							<reference key="NSSuperview" ref="145141922"/>
-							<bool key="NSEnabled">YES</bool>
-							<object class="NSButtonCell" key="NSCell" id="406066834">
-								<int key="NSCellFlags">67239424</int>
-								<int key="NSCellFlags2">134217728</int>
-								<string key="NSContents">Set...</string>
-								<reference key="NSSupport" ref="407649812"/>
-								<reference key="NSControlView" ref="602477213"/>
-								<int key="NSButtonFlags">-2038021889</int>
-								<int key="NSButtonFlags2">32</int>
-								<reference key="NSAlternateImage" ref="813720862"/>
-								<string key="NSAlternateContents"/>
-								<string key="NSKeyEquivalent"/>
-								<int key="NSPeriodicDelay">400</int>
-								<int key="NSPeriodicInterval">75</int>
-							</object>
-						</object>
-						<object class="NSTextField" id="452288864">
-							<reference key="NSNextResponder" ref="145141922"/>
-							<int key="NSvFlags">256</int>
-							<string key="NSFrame">{{17, 89}, {446, 11}}</string>
-							<reference key="NSSuperview" ref="145141922"/>
-							<bool key="NSEnabled">YES</bool>
-							<object class="NSTextFieldCell" key="NSCell" id="969661180">
-								<int key="NSCellFlags">67239424</int>
-								<int key="NSCellFlags2">272629760</int>
-								<string key="NSContents">Chex Quest IWAD location (chex.wad):</string>
-								<reference key="NSSupport" ref="22"/>
-								<reference key="NSControlView" ref="452288864"/>
-								<reference key="NSBackgroundColor" ref="77619338"/>
-								<reference key="NSTextColor" ref="206071849"/>
-							</object>
-						</object>
-						<object class="NSTextField" id="625273251">
-							<reference key="NSNextResponder" ref="145141922"/>
-							<int key="NSvFlags">256</int>
-							<string key="NSFrame">{{20, 59}, {369, 22}}</string>
-							<reference key="NSSuperview" ref="145141922"/>
-							<bool key="NSEnabled">YES</bool>
-							<object class="NSTextFieldCell" key="NSCell" id="857754300">
-								<int key="NSCellFlags">-1804468671</int>
-								<int key="NSCellFlags2">272630784</int>
-								<string key="NSContents"/>
-								<reference key="NSSupport" ref="407649812"/>
-								<reference key="NSControlView" ref="625273251"/>
-								<bool key="NSDrawsBackground">YES</bool>
-								<reference key="NSBackgroundColor" ref="612330193"/>
-								<reference key="NSTextColor" ref="943265597"/>
-							</object>
-						</object>
-						<object class="NSButton" id="680095551">
-							<reference key="NSNextResponder" ref="145141922"/>
-							<int key="NSvFlags">256</int>
-							<string key="NSFrame">{{397, 59}, {63, 23}}</string>
-							<reference key="NSSuperview" ref="145141922"/>
-							<bool key="NSEnabled">YES</bool>
-							<object class="NSButtonCell" key="NSCell" id="1012408786">
-								<int key="NSCellFlags">67239424</int>
-								<int key="NSCellFlags2">134217728</int>
-								<string key="NSContents">Set...</string>
-								<reference key="NSSupport" ref="407649812"/>
-								<reference key="NSControlView" ref="680095551"/>
-								<int key="NSButtonFlags">-2038021889</int>
-								<int key="NSButtonFlags2">32</int>
-								<reference key="NSAlternateImage" ref="813720862"/>
-								<string key="NSAlternateContents"/>
-								<string key="NSKeyEquivalent"/>
-								<int key="NSPeriodicDelay">400</int>
-								<int key="NSPeriodicInterval">75</int>
-							</object>
-						</object>
-						<object class="NSButton" id="658359713">
-							<reference key="NSNextResponder" ref="145141922"/>
-							<int key="NSvFlags">256</int>
-							<string key="NSFrame">{{384, 12}, {82, 32}}</string>
-							<reference key="NSSuperview" ref="145141922"/>
-							<bool key="NSEnabled">YES</bool>
-							<object class="NSButtonCell" key="NSCell" id="235375789">
-								<int key="NSCellFlags">67239424</int>
-								<int key="NSCellFlags2">134217728</int>
-								<string key="NSContents">Close</string>
-								<reference key="NSSupport" ref="407649812"/>
-								<reference key="NSControlView" ref="658359713"/>
-								<int key="NSButtonFlags">-2038284033</int>
-								<int key="NSButtonFlags2">1</int>
-								<reference key="NSAlternateImage" ref="407649812"/>
-								<string key="NSAlternateContents"/>
-								<object class="NSMutableString" key="NSKeyEquivalent">
-									<characters key="NS.bytes"/>
-								</object>
-								<int key="NSPeriodicDelay">200</int>
-								<int key="NSPeriodicInterval">25</int>
-							</object>
-						</object>
 					</object>
-					<string key="NSFrameSize">{480, 316}</string>
+					<string key="NSFrameSize">{518, 308}</string>
 					<reference key="NSSuperview"/>
 				</object>
 				<string key="NSScreenRect">{{0, 0}, {1440, 878}}</string>
@@ -947,15 +1189,12 @@
 			<object class="NSCustomObject" id="825061065">
 				<string key="NSClassName">AppController</string>
 			</object>
-			<object class="NSCustomObject" id="201870239">
-				<string key="NSClassName">LauncherManager</string>
+			<object class="NSCustomObject" id="5964108">
+				<string key="NSClassName">IWADLocation</string>
 			</object>
-			<object class="NSCustomObject" id="895790931">
-				<string key="NSClassName">LauncherManager</string>
+			<object class="NSCustomObject" id="354490064">
+				<string key="NSClassName">IWADLocation</string>
 			</object>
-			<object class="NSCustomObject" id="366010945">
-				<string key="NSClassName">LauncherManager</string>
-			</object>
 		</object>
 		<object class="IBObjectContainer" key="IBDocument.Objects">
 			<object class="NSMutableArray" key="connectionRecords">
@@ -1312,6 +1551,102 @@
 					</object>
 					<int key="connectionID">322</int>
 				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBActionConnection" key="connection">
+						<string key="label">openINSTALL:</string>
+						<reference key="source" ref="590266459"/>
+						<reference key="destination" ref="378926680"/>
+					</object>
+					<int key="connectionID">374</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBActionConnection" key="connection">
+						<string key="label">openCMDLINE:</string>
+						<reference key="source" ref="590266459"/>
+						<reference key="destination" ref="784926086"/>
+					</object>
+					<int key="connectionID">376</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBActionConnection" key="connection">
+						<string key="label">openDocumentation:</string>
+						<reference key="source" ref="590266459"/>
+						<reference key="destination" ref="913959081"/>
+					</object>
+					<int key="connectionID">378</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBActionConnection" key="connection">
+						<string key="label">openCOPYING:</string>
+						<reference key="source" ref="590266459"/>
+						<reference key="destination" ref="590365178"/>
+					</object>
+					<int key="connectionID">381</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBActionConnection" key="connection">
+						<string key="label">openREADME:</string>
+						<reference key="source" ref="590266459"/>
+						<reference key="destination" ref="860531190"/>
+					</object>
+					<int key="connectionID">382</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBActionConnection" key="connection">
+						<string key="label">openINSTALL:</string>
+						<reference key="source" ref="590266459"/>
+						<reference key="destination" ref="811205099"/>
+					</object>
+					<int key="connectionID">385</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBOutletConnection" key="connection">
+						<string key="label">locationConfigBox</string>
+						<reference key="source" ref="5964108"/>
+						<reference key="destination" ref="568653906"/>
+					</object>
+					<int key="connectionID">403</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBOutletConnection" key="connection">
+						<string key="label">locationConfigBox</string>
+						<reference key="source" ref="354490064"/>
+						<reference key="destination" ref="634339523"/>
+					</object>
+					<int key="connectionID">404</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBActionConnection" key="connection">
+						<string key="label">setButtonClicked:</string>
+						<reference key="source" ref="5964108"/>
+						<reference key="destination" ref="198489100"/>
+					</object>
+					<int key="connectionID">411</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBActionConnection" key="connection">
+						<string key="label">setButtonClicked:</string>
+						<reference key="source" ref="354490064"/>
+						<reference key="destination" ref="318836161"/>
+					</object>
+					<int key="connectionID">412</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBOutletConnection" key="connection">
+						<string key="label">heretic</string>
+						<reference key="source" ref="938927474"/>
+						<reference key="destination" ref="5964108"/>
+					</object>
+					<int key="connectionID">413</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBOutletConnection" key="connection">
+						<string key="label">hexen</string>
+						<reference key="source" ref="938927474"/>
+						<reference key="destination" ref="354490064"/>
+					</object>
+					<int key="connectionID">414</int>
+				</object>
 			</object>
 			<object class="IBMutableOrderedSet" key="objectRecords">
 				<object class="NSArray" key="orderedObjects">
@@ -1442,7 +1777,8 @@
 							<reference ref="419477060"/>
 							<reference ref="231654028"/>
 							<reference ref="729612487"/>
-						</object>
+							<reference ref="391919375"/>
+						</object>
 						<reference key="parent" ref="0"/>
 						<string key="objectName">MainMenu</string>
 					</object>
@@ -1677,161 +2013,13 @@
 						<reference key="object" ref="145141922"/>
 						<object class="NSMutableArray" key="children">
 							<bool key="EncodedWithXMLCoder">YES</bool>
-							<reference ref="348674481"/>
-							<reference ref="215057262"/>
-							<reference ref="410786529"/>
-							<reference ref="316721564"/>
-							<reference ref="458378991"/>
-							<reference ref="644218899"/>
-							<reference ref="179636494"/>
-							<reference ref="1021143679"/>
-							<reference ref="539465960"/>
-							<reference ref="712311825"/>
-							<reference ref="355049668"/>
-							<reference ref="602477213"/>
-							<reference ref="452288864"/>
-							<reference ref="625273251"/>
-							<reference ref="680095551"/>
+							<reference ref="793342693"/>
 							<reference ref="658359713"/>
+							<reference ref="811205099"/>
 						</object>
 						<reference key="parent" ref="193084417"/>
 					</object>
 					<object class="IBObjectRecord">
-						<int key="objectID">234</int>
-						<reference key="object" ref="348674481"/>
-						<object class="NSMutableArray" key="children">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<reference ref="522582983"/>
-						</object>
-						<reference key="parent" ref="145141922"/>
-					</object>
-					<object class="IBObjectRecord">
-						<int key="objectID">235</int>
-						<reference key="object" ref="215057262"/>
-						<object class="NSMutableArray" key="children">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<reference ref="596525351"/>
-						</object>
-						<reference key="parent" ref="145141922"/>
-					</object>
-					<object class="IBObjectRecord">
-						<int key="objectID">236</int>
-						<reference key="object" ref="410786529"/>
-						<object class="NSMutableArray" key="children">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<reference ref="673476660"/>
-						</object>
-						<reference key="parent" ref="145141922"/>
-					</object>
-					<object class="IBObjectRecord">
-						<int key="objectID">238</int>
-						<reference key="object" ref="316721564"/>
-						<object class="NSMutableArray" key="children">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<reference ref="663066257"/>
-						</object>
-						<reference key="parent" ref="145141922"/>
-					</object>
-					<object class="IBObjectRecord">
-						<int key="objectID">239</int>
-						<reference key="object" ref="458378991"/>
-						<object class="NSMutableArray" key="children">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<reference ref="848829815"/>
-						</object>
-						<reference key="parent" ref="145141922"/>
-					</object>
-					<object class="IBObjectRecord">
-						<int key="objectID">240</int>
-						<reference key="object" ref="644218899"/>
-						<object class="NSMutableArray" key="children">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<reference ref="63361904"/>
-						</object>
-						<reference key="parent" ref="145141922"/>
-					</object>
-					<object class="IBObjectRecord">
-						<int key="objectID">241</int>
-						<reference key="object" ref="179636494"/>
-						<object class="NSMutableArray" key="children">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<reference ref="84857374"/>
-						</object>
-						<reference key="parent" ref="145141922"/>
-					</object>
-					<object class="IBObjectRecord">
-						<int key="objectID">242</int>
-						<reference key="object" ref="1021143679"/>
-						<object class="NSMutableArray" key="children">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<reference ref="629867670"/>
-						</object>
-						<reference key="parent" ref="145141922"/>
-					</object>
-					<object class="IBObjectRecord">
-						<int key="objectID">243</int>
-						<reference key="object" ref="539465960"/>
-						<object class="NSMutableArray" key="children">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<reference ref="979277836"/>
-						</object>
-						<reference key="parent" ref="145141922"/>
-					</object>
-					<object class="IBObjectRecord">
-						<int key="objectID">244</int>
-						<reference key="object" ref="712311825"/>
-						<object class="NSMutableArray" key="children">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<reference ref="131918744"/>
-						</object>
-						<reference key="parent" ref="145141922"/>
-					</object>
-					<object class="IBObjectRecord">
-						<int key="objectID">245</int>
-						<reference key="object" ref="355049668"/>
-						<object class="NSMutableArray" key="children">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<reference ref="17259252"/>
-						</object>
-						<reference key="parent" ref="145141922"/>
-					</object>
-					<object class="IBObjectRecord">
-						<int key="objectID">246</int>
-						<reference key="object" ref="602477213"/>
-						<object class="NSMutableArray" key="children">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<reference ref="406066834"/>
-						</object>
-						<reference key="parent" ref="145141922"/>
-					</object>
-					<object class="IBObjectRecord">
-						<int key="objectID">247</int>
-						<reference key="object" ref="452288864"/>
-						<object class="NSMutableArray" key="children">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<reference ref="969661180"/>
-						</object>
-						<reference key="parent" ref="145141922"/>
-					</object>
-					<object class="IBObjectRecord">
-						<int key="objectID">248</int>
-						<reference key="object" ref="625273251"/>
-						<object class="NSMutableArray" key="children">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<reference ref="857754300"/>
-						</object>
-						<reference key="parent" ref="145141922"/>
-					</object>
-					<object class="IBObjectRecord">
-						<int key="objectID">249</int>
-						<reference key="object" ref="680095551"/>
-						<object class="NSMutableArray" key="children">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<reference ref="1012408786"/>
-						</object>
-						<reference key="parent" ref="145141922"/>
-					</object>
-					<object class="IBObjectRecord">
 						<int key="objectID">250</int>
 						<reference key="object" ref="658359713"/>
 						<object class="NSMutableArray" key="children">
@@ -1921,120 +2109,468 @@
 						<reference key="parent" ref="858516582"/>
 					</object>
 					<object class="IBObjectRecord">
+						<int key="objectID">348</int>
+						<reference key="object" ref="235375789"/>
+						<reference key="parent" ref="658359713"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">212</int>
+						<reference key="object" ref="562767686"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="532676330"/>
+						</object>
+						<reference key="parent" ref="968990884"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">213</int>
+						<reference key="object" ref="532676330"/>
+						<reference key="parent" ref="562767686"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">-3</int>
+						<reference key="object" ref="226652452"/>
+						<reference key="parent" ref="0"/>
+						<string key="objectName">Application</string>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">369</int>
+						<reference key="object" ref="391919375"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="733442466"/>
+						</object>
+						<reference key="parent" ref="624798014"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">370</int>
+						<reference key="object" ref="733442466"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="860531190"/>
+							<reference ref="378926680"/>
+							<reference ref="784926086"/>
+							<reference ref="913959081"/>
+							<reference ref="258703436"/>
+							<reference ref="590365178"/>
+						</object>
+						<reference key="parent" ref="391919375"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">371</int>
+						<reference key="object" ref="860531190"/>
+						<reference key="parent" ref="733442466"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">373</int>
+						<reference key="object" ref="378926680"/>
+						<reference key="parent" ref="733442466"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">375</int>
+						<reference key="object" ref="784926086"/>
+						<reference key="parent" ref="733442466"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">377</int>
+						<reference key="object" ref="913959081"/>
+						<reference key="parent" ref="733442466"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">379</int>
+						<reference key="object" ref="258703436"/>
+						<reference key="parent" ref="733442466"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">380</int>
+						<reference key="object" ref="590365178"/>
+						<reference key="parent" ref="733442466"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">383</int>
+						<reference key="object" ref="811205099"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="33467307"/>
+						</object>
+						<reference key="parent" ref="145141922"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">384</int>
+						<reference key="object" ref="33467307"/>
+						<reference key="parent" ref="811205099"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">386</int>
+						<reference key="object" ref="793342693"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="939760325"/>
+							<reference ref="989716837"/>
+						</object>
+						<reference key="parent" ref="145141922"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">387</int>
+						<reference key="object" ref="939760325"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="948790550"/>
+						</object>
+						<reference key="parent" ref="793342693"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">388</int>
+						<reference key="object" ref="989716837"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="1000383860"/>
+						</object>
+						<reference key="parent" ref="793342693"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">389</int>
+						<reference key="object" ref="1000383860"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="568653906"/>
+							<reference ref="840089166"/>
+							<reference ref="10172086"/>
+							<reference ref="634339523"/>
+							<reference ref="452288864"/>
+							<reference ref="625273251"/>
+							<reference ref="198489100"/>
+							<reference ref="318836161"/>
+							<reference ref="680095551"/>
+						</object>
+						<reference key="parent" ref="989716837"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">390</int>
+						<reference key="object" ref="948790550"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="348674481"/>
+							<reference ref="410786529"/>
+							<reference ref="316721564"/>
+							<reference ref="458378991"/>
+							<reference ref="644218899"/>
+							<reference ref="1021143679"/>
+							<reference ref="179636494"/>
+							<reference ref="712311825"/>
+							<reference ref="355049668"/>
+							<reference ref="602477213"/>
+							<reference ref="215057262"/>
+							<reference ref="539465960"/>
+						</object>
+						<reference key="parent" ref="939760325"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">234</int>
+						<reference key="object" ref="348674481"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="522582983"/>
+						</object>
+						<reference key="parent" ref="948790550"/>
+					</object>
+					<object class="IBObjectRecord">
 						<int key="objectID">333</int>
 						<reference key="object" ref="522582983"/>
 						<reference key="parent" ref="348674481"/>
 					</object>
 					<object class="IBObjectRecord">
+						<int key="objectID">235</int>
+						<reference key="object" ref="215057262"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="596525351"/>
+						</object>
+						<reference key="parent" ref="948790550"/>
+					</object>
+					<object class="IBObjectRecord">
 						<int key="objectID">334</int>
 						<reference key="object" ref="596525351"/>
 						<reference key="parent" ref="215057262"/>
 					</object>
 					<object class="IBObjectRecord">
+						<int key="objectID">236</int>
+						<reference key="object" ref="410786529"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="673476660"/>
+						</object>
+						<reference key="parent" ref="948790550"/>
+					</object>
+					<object class="IBObjectRecord">
 						<int key="objectID">335</int>
 						<reference key="object" ref="673476660"/>
 						<reference key="parent" ref="410786529"/>
 					</object>
 					<object class="IBObjectRecord">
+						<int key="objectID">238</int>
+						<reference key="object" ref="316721564"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="663066257"/>
+						</object>
+						<reference key="parent" ref="948790550"/>
+					</object>
+					<object class="IBObjectRecord">
 						<int key="objectID">336</int>
 						<reference key="object" ref="663066257"/>
 						<reference key="parent" ref="316721564"/>
 					</object>
 					<object class="IBObjectRecord">
+						<int key="objectID">239</int>
+						<reference key="object" ref="458378991"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="848829815"/>
+						</object>
+						<reference key="parent" ref="948790550"/>
+					</object>
+					<object class="IBObjectRecord">
 						<int key="objectID">337</int>
 						<reference key="object" ref="848829815"/>
 						<reference key="parent" ref="458378991"/>
 					</object>
 					<object class="IBObjectRecord">
+						<int key="objectID">240</int>
+						<reference key="object" ref="644218899"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="63361904"/>
+						</object>
+						<reference key="parent" ref="948790550"/>
+					</object>
+					<object class="IBObjectRecord">
 						<int key="objectID">338</int>
 						<reference key="object" ref="63361904"/>
 						<reference key="parent" ref="644218899"/>
 					</object>
 					<object class="IBObjectRecord">
+						<int key="objectID">241</int>
+						<reference key="object" ref="179636494"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="84857374"/>
+						</object>
+						<reference key="parent" ref="948790550"/>
+					</object>
+					<object class="IBObjectRecord">
 						<int key="objectID">339</int>
 						<reference key="object" ref="84857374"/>
 						<reference key="parent" ref="179636494"/>
 					</object>
 					<object class="IBObjectRecord">
+						<int key="objectID">242</int>
+						<reference key="object" ref="1021143679"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="629867670"/>
+						</object>
+						<reference key="parent" ref="948790550"/>
+					</object>
+					<object class="IBObjectRecord">
 						<int key="objectID">340</int>
 						<reference key="object" ref="629867670"/>
 						<reference key="parent" ref="1021143679"/>
 					</object>
 					<object class="IBObjectRecord">
+						<int key="objectID">243</int>
+						<reference key="object" ref="539465960"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="979277836"/>
+						</object>
+						<reference key="parent" ref="948790550"/>
+					</object>
+					<object class="IBObjectRecord">
 						<int key="objectID">341</int>
 						<reference key="object" ref="979277836"/>
 						<reference key="parent" ref="539465960"/>
 					</object>
 					<object class="IBObjectRecord">
+						<int key="objectID">244</int>
+						<reference key="object" ref="712311825"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="131918744"/>
+						</object>
+						<reference key="parent" ref="948790550"/>
+					</object>
+					<object class="IBObjectRecord">
 						<int key="objectID">342</int>
 						<reference key="object" ref="131918744"/>
 						<reference key="parent" ref="712311825"/>
 					</object>
 					<object class="IBObjectRecord">
+						<int key="objectID">245</int>
+						<reference key="object" ref="355049668"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="17259252"/>
+						</object>
+						<reference key="parent" ref="948790550"/>
+					</object>
+					<object class="IBObjectRecord">
 						<int key="objectID">343</int>
 						<reference key="object" ref="17259252"/>
 						<reference key="parent" ref="355049668"/>
 					</object>
 					<object class="IBObjectRecord">
+						<int key="objectID">246</int>
+						<reference key="object" ref="602477213"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="406066834"/>
+						</object>
+						<reference key="parent" ref="948790550"/>
+					</object>
+					<object class="IBObjectRecord">
 						<int key="objectID">344</int>
 						<reference key="object" ref="406066834"/>
 						<reference key="parent" ref="602477213"/>
 					</object>
 					<object class="IBObjectRecord">
+						<int key="objectID">247</int>
+						<reference key="object" ref="452288864"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="969661180"/>
+						</object>
+						<reference key="parent" ref="1000383860"/>
+					</object>
+					<object class="IBObjectRecord">
 						<int key="objectID">345</int>
 						<reference key="object" ref="969661180"/>
 						<reference key="parent" ref="452288864"/>
 					</object>
 					<object class="IBObjectRecord">
+						<int key="objectID">248</int>
+						<reference key="object" ref="625273251"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="857754300"/>
+						</object>
+						<reference key="parent" ref="1000383860"/>
+					</object>
+					<object class="IBObjectRecord">
 						<int key="objectID">346</int>
 						<reference key="object" ref="857754300"/>
 						<reference key="parent" ref="625273251"/>
 					</object>
 					<object class="IBObjectRecord">
+						<int key="objectID">249</int>
+						<reference key="object" ref="680095551"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="1012408786"/>
+						</object>
+						<reference key="parent" ref="1000383860"/>
+					</object>
+					<object class="IBObjectRecord">
 						<int key="objectID">347</int>
 						<reference key="object" ref="1012408786"/>
 						<reference key="parent" ref="680095551"/>
 					</object>
 					<object class="IBObjectRecord">
-						<int key="objectID">348</int>
-						<reference key="object" ref="235375789"/>
-						<reference key="parent" ref="658359713"/>
+						<int key="objectID">391</int>
+						<reference key="object" ref="634339523"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="247064311"/>
+						</object>
+						<reference key="parent" ref="1000383860"/>
 					</object>
 					<object class="IBObjectRecord">
-						<int key="objectID">212</int>
-						<reference key="object" ref="562767686"/>
+						<int key="objectID">392</int>
+						<reference key="object" ref="247064311"/>
+						<reference key="parent" ref="634339523"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">393</int>
+						<reference key="object" ref="568653906"/>
 						<object class="NSMutableArray" key="children">
 							<bool key="EncodedWithXMLCoder">YES</bool>
-							<reference ref="532676330"/>
+							<reference ref="332680482"/>
 						</object>
-						<reference key="parent" ref="968990884"/>
+						<reference key="parent" ref="1000383860"/>
 					</object>
 					<object class="IBObjectRecord">
-						<int key="objectID">213</int>
-						<reference key="object" ref="532676330"/>
-						<reference key="parent" ref="562767686"/>
+						<int key="objectID">394</int>
+						<reference key="object" ref="332680482"/>
+						<reference key="parent" ref="568653906"/>
 					</object>
 					<object class="IBObjectRecord">
-						<int key="objectID">-3</int>
-						<reference key="object" ref="226652452"/>
-						<reference key="parent" ref="0"/>
-						<string key="objectName">Application</string>
+						<int key="objectID">397</int>
+						<reference key="object" ref="840089166"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="1045009541"/>
+						</object>
+						<reference key="parent" ref="1000383860"/>
 					</object>
 					<object class="IBObjectRecord">
-						<int key="objectID">349</int>
-						<reference key="object" ref="201870239"/>
-						<reference key="parent" ref="0"/>
+						<int key="objectID">398</int>
+						<reference key="object" ref="1045009541"/>
+						<reference key="parent" ref="840089166"/>
 					</object>
 					<object class="IBObjectRecord">
-						<int key="objectID">350</int>
-						<reference key="object" ref="895790931"/>
+						<int key="objectID">399</int>
+						<reference key="object" ref="10172086"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="738481735"/>
+						</object>
+						<reference key="parent" ref="1000383860"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">400</int>
+						<reference key="object" ref="738481735"/>
+						<reference key="parent" ref="10172086"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">401</int>
+						<reference key="object" ref="5964108"/>
 						<reference key="parent" ref="0"/>
+						<string key="objectName">HereticIWAD</string>
 					</object>
 					<object class="IBObjectRecord">
-						<int key="objectID">351</int>
-						<reference key="object" ref="366010945"/>
+						<int key="objectID">402</int>
+						<reference key="object" ref="354490064"/>
 						<reference key="parent" ref="0"/>
+						<string key="objectName">HexenIWAD</string>
 					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">405</int>
+						<reference key="object" ref="318836161"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="118467388"/>
+						</object>
+						<reference key="parent" ref="1000383860"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">406</int>
+						<reference key="object" ref="118467388"/>
+						<reference key="parent" ref="318836161"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">408</int>
+						<reference key="object" ref="198489100"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="670956484"/>
+						</object>
+						<reference key="parent" ref="1000383860"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">409</int>
+						<reference key="object" ref="670956484"/>
+						<reference key="parent" ref="198489100"/>
+					</object>
 				</object>
 			</object>
 			<object class="NSMutableDictionary" key="flattenedProperties">
@@ -2043,6 +2579,7 @@
 					<bool key="EncodedWithXMLCoder">YES</bool>
 					<string>129.IBPluginDependency</string>
 					<string>129.ImportedFromIB2</string>
+					<string>130.IBEditorWindowLastContentRect</string>
 					<string>130.IBPluginDependency</string>
 					<string>130.ImportedFromIB2</string>
 					<string>131.IBPluginDependency</string>
@@ -2122,42 +2659,60 @@
 					<string>232.ImportedFromIB2</string>
 					<string>233.ImportedFromIB2</string>
 					<string>234.IBPluginDependency</string>
+					<string>234.IBViewBoundsToFrameTransform</string>
 					<string>234.ImportedFromIB2</string>
 					<string>235.IBPluginDependency</string>
+					<string>235.IBViewBoundsToFrameTransform</string>
 					<string>235.ImportedFromIB2</string>
 					<string>236.IBPluginDependency</string>
+					<string>236.IBViewBoundsToFrameTransform</string>
 					<string>236.ImportedFromIB2</string>
 					<string>238.IBPluginDependency</string>
+					<string>238.IBViewBoundsToFrameTransform</string>
 					<string>238.ImportedFromIB2</string>
 					<string>239.IBPluginDependency</string>
+					<string>239.IBViewBoundsToFrameTransform</string>
 					<string>239.ImportedFromIB2</string>
+					<string>24.IBEditorWindowLastContentRect</string>
 					<string>24.IBPluginDependency</string>
 					<string>24.ImportedFromIB2</string>
 					<string>240.IBPluginDependency</string>
+					<string>240.IBViewBoundsToFrameTransform</string>
 					<string>240.ImportedFromIB2</string>
 					<string>241.IBPluginDependency</string>
+					<string>241.IBViewBoundsToFrameTransform</string>
 					<string>241.ImportedFromIB2</string>
 					<string>242.IBPluginDependency</string>
+					<string>242.IBViewBoundsToFrameTransform</string>
 					<string>242.ImportedFromIB2</string>
 					<string>243.IBPluginDependency</string>
+					<string>243.IBViewBoundsToFrameTransform</string>
 					<string>243.ImportedFromIB2</string>
 					<string>244.IBPluginDependency</string>
+					<string>244.IBViewBoundsToFrameTransform</string>
 					<string>244.ImportedFromIB2</string>
 					<string>245.IBPluginDependency</string>
+					<string>245.IBViewBoundsToFrameTransform</string>
 					<string>245.ImportedFromIB2</string>
 					<string>246.IBPluginDependency</string>
+					<string>246.IBViewBoundsToFrameTransform</string>
 					<string>246.ImportedFromIB2</string>
 					<string>247.IBPluginDependency</string>
+					<string>247.IBViewBoundsToFrameTransform</string>
 					<string>247.ImportedFromIB2</string>
 					<string>248.IBPluginDependency</string>
+					<string>248.IBViewBoundsToFrameTransform</string>
 					<string>248.ImportedFromIB2</string>
 					<string>249.IBPluginDependency</string>
+					<string>249.IBViewBoundsToFrameTransform</string>
 					<string>249.ImportedFromIB2</string>
 					<string>250.IBPluginDependency</string>
+					<string>250.IBViewBoundsToFrameTransform</string>
 					<string>250.ImportedFromIB2</string>
 					<string>270.ImportedFromIB2</string>
 					<string>274.IBPluginDependency</string>
 					<string>274.ImportedFromIB2</string>
+					<string>275.IBEditorWindowLastContentRect</string>
 					<string>275.IBPluginDependency</string>
 					<string>275.ImportedFromIB2</string>
 					<string>281.IBPluginDependency</string>
@@ -2181,13 +2736,49 @@
 					<string>301.ImportedFromIB2</string>
 					<string>320.IBPluginDependency</string>
 					<string>320.ImportedFromIB2</string>
-					<string>349.IBPluginDependency</string>
-					<string>350.IBPluginDependency</string>
-					<string>351.IBPluginDependency</string>
+					<string>369.IBPluginDependency</string>
+					<string>370.IBEditorWindowLastContentRect</string>
+					<string>370.IBPluginDependency</string>
+					<string>371.IBPluginDependency</string>
+					<string>373.IBPluginDependency</string>
+					<string>375.IBPluginDependency</string>
+					<string>377.IBPluginDependency</string>
+					<string>379.IBPluginDependency</string>
+					<string>380.IBPluginDependency</string>
+					<string>383.IBPluginDependency</string>
+					<string>383.IBViewBoundsToFrameTransform</string>
+					<string>384.IBPluginDependency</string>
+					<string>386.IBPluginDependency</string>
+					<string>386.IBViewBoundsToFrameTransform</string>
+					<string>387.IBPluginDependency</string>
+					<string>388.IBPluginDependency</string>
+					<string>389.IBPluginDependency</string>
+					<string>390.IBPluginDependency</string>
+					<string>391.IBPluginDependency</string>
+					<string>391.IBViewBoundsToFrameTransform</string>
+					<string>392.IBPluginDependency</string>
+					<string>393.IBPluginDependency</string>
+					<string>393.IBViewBoundsToFrameTransform</string>
+					<string>394.IBPluginDependency</string>
+					<string>397.IBPluginDependency</string>
+					<string>397.IBViewBoundsToFrameTransform</string>
+					<string>397.ImportedFromIB2</string>
+					<string>399.IBPluginDependency</string>
+					<string>399.IBViewBoundsToFrameTransform</string>
+					<string>399.ImportedFromIB2</string>
+					<string>401.IBPluginDependency</string>
+					<string>402.IBPluginDependency</string>
+					<string>405.IBPluginDependency</string>
+					<string>405.IBViewBoundsToFrameTransform</string>
+					<string>405.ImportedFromIB2</string>
+					<string>408.IBPluginDependency</string>
+					<string>408.IBViewBoundsToFrameTransform</string>
+					<string>408.ImportedFromIB2</string>
 					<string>5.IBPluginDependency</string>
 					<string>5.ImportedFromIB2</string>
 					<string>56.IBPluginDependency</string>
 					<string>56.ImportedFromIB2</string>
+					<string>57.IBEditorWindowLastContentRect</string>
 					<string>57.IBPluginDependency</string>
 					<string>57.ImportedFromIB2</string>
 					<string>58.IBPluginDependency</string>
@@ -2199,6 +2790,7 @@
 					<bool key="EncodedWithXMLCoder">YES</bool>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 					<boolean value="YES"/>
+					<string>{{576, 728}, {64, 6}}</string>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 					<boolean value="YES"/>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -2231,9 +2823,9 @@
 						<bytes key="NSTransformStruct">P4AAAL+AAABBiAAAwyEAAA</bytes>
 					</object>
 					<boolean value="YES"/>
-					<string>{{337, 406}, {530, 190}}</string>
+					<string>{{368, 418}, {530, 190}}</string>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
-					<string>{{337, 406}, {530, 190}}</string>
+					<string>{{368, 418}, {530, 190}}</string>
 					<boolean value="YES"/>
 					<boolean value="YES"/>
 					<boolean value="YES"/>
@@ -2274,13 +2866,13 @@
 					<boolean value="YES"/>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 					<object class="NSAffineTransform">
-						<bytes key="NSTransformStruct">P4AAAL+AAABBYAAAwgQAAA</bytes>
+						<bytes key="NSTransformStruct">P4AAAL+AAABBYAAAwigAAA</bytes>
 					</object>
 					<boolean value="YES"/>
 					<boolean value="YES"/>
-					<string>{{329, 484}, {480, 316}}</string>
+					<string>{{358, 421}, {518, 308}}</string>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
-					<string>{{329, 484}, {480, 316}}</string>
+					<string>{{358, 421}, {518, 308}}</string>
 					<boolean value="YES"/>
 					<boolean value="YES"/>
 					<string>{213, 107}</string>
@@ -2294,42 +2886,92 @@
 					<boolean value="YES"/>
 					<boolean value="YES"/>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<object class="NSAffineTransform">
+						<bytes key="NSTransformStruct">P4AAAL+AAABD24AAw5+AAA</bytes>
+					</object>
 					<boolean value="YES"/>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<object class="NSAffineTransform">
+						<bytes key="NSTransformStruct">P4AAAL+AAABBiAAAwz8AAA</bytes>
+					</object>
 					<boolean value="YES"/>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<object class="NSAffineTransform">
+						<bytes key="NSTransformStruct">P4AAAL+AAABDxoAAxBJAAA</bytes>
+					</object>
 					<boolean value="YES"/>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<object class="NSAffineTransform">
+						<bytes key="NSTransformStruct">P4AAAL+AAABBiAAAxAqAAA</bytes>
+					</object>
 					<boolean value="YES"/>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<object class="NSAffineTransform">
+						<bytes key="NSTransformStruct">P4AAAL+AAABBoAAAxAXAAA</bytes>
+					</object>
 					<boolean value="YES"/>
+					<string>{{469, 741}, {194, 73}}</string>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 					<boolean value="YES"/>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<object class="NSAffineTransform">
+						<bytes key="NSTransformStruct">P4AAAL+AAABDxIAAwzQAAA</bytes>
+					</object>
 					<boolean value="YES"/>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<object class="NSAffineTransform">
+						<bytes key="NSTransformStruct">P4AAAL+AAABBYAAAwxcAAA</bytes>
+					</object>
 					<boolean value="YES"/>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<object class="NSAffineTransform">
+						<bytes key="NSTransformStruct">P4AAAL+AAABBcAAAwwQAAA</bytes>
+					</object>
 					<boolean value="YES"/>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<object class="NSAffineTransform">
+						<bytes key="NSTransformStruct">P4AAAL+AAABDxIAAwrwAAA</bytes>
+					</object>
 					<boolean value="YES"/>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<object class="NSAffineTransform">
+						<bytes key="NSTransformStruct">P4AAAL+AAABBQAAAwswAAA</bytes>
+					</object>
 					<boolean value="YES"/>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<object class="NSAffineTransform">
+						<bytes key="NSTransformStruct">P4AAAL+AAABBoAAAw9qAAA</bytes>
+					</object>
 					<boolean value="YES"/>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<object class="NSAffineTransform">
+						<bytes key="NSTransformStruct">P4AAAL+AAABDxoAAw9sAAA</bytes>
+					</object>
 					<boolean value="YES"/>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<object class="NSAffineTransform">
+						<bytes key="NSTransformStruct">P4AAAL+AAABCRAAAwoQAAA</bytes>
+					</object>
 					<boolean value="YES"/>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<object class="NSAffineTransform">
+						<bytes key="NSTransformStruct">P4AAAL+AAABCUAAAwjwAAA</bytes>
+					</object>
 					<boolean value="YES"/>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<object class="NSAffineTransform">
+						<bytes key="NSTransformStruct">P4AAAL+AAABDxYAAwrgAAA</bytes>
+					</object>
 					<boolean value="YES"/>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<object class="NSAffineTransform">
+						<bytes key="NSTransformStruct">P4AAAL+AAABD2gAAwqIAAA</bytes>
+					</object>
 					<boolean value="YES"/>
 					<boolean value="YES"/>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 					<boolean value="YES"/>
+					<string>{{425, 661}, {151, 153}}</string>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 					<boolean value="YES"/>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -2340,7 +2982,7 @@
 					<boolean value="YES"/>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 					<boolean value="YES"/>
-					<string>{{329, 814}, {223, 20}}</string>
+					<string>{{329, 814}, {272, 20}}</string>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 					<boolean value="YES"/>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -2354,18 +2996,70 @@
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 					<boolean value="YES"/>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<string>{{540, 701}, {238, 113}}</string>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<object class="NSAffineTransform">
+						<bytes key="NSTransformStruct">P4AAAL+AAABBiAAAwhwAAA</bytes>
+					</object>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<object class="NSAffineTransform">
+						<bytes key="NSTransformStruct">P4AAAL+AAABBUAAAw5YAAA</bytes>
+					</object>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<object class="NSAffineTransform">
+						<bytes key="NSTransformStruct">P4AAAL+AAABBiAAAwwgAAA</bytes>
+					</object>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<object class="NSAffineTransform">
+						<bytes key="NSTransformStruct">P4AAAL+AAABBgAAAw0EAAA</bytes>
+					</object>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<object class="NSAffineTransform">
+						<bytes key="NSTransformStruct">P4AAAL+AAABClAAAwwIAAA</bytes>
+					</object>
 					<boolean value="YES"/>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<object class="NSAffineTransform">
+						<bytes key="NSTransformStruct">P4AAAL+AAABBUAAAw1EAAA</bytes>
+					</object>
 					<boolean value="YES"/>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<object class="NSAffineTransform">
+						<bytes key="NSTransformStruct">P4AAAL+AAABDxIAAww0AAA</bytes>
+					</object>
 					<boolean value="YES"/>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<object class="NSAffineTransform">
+						<bytes key="NSTransformStruct">P4AAAL+AAABDxIAAw0AAAA</bytes>
+					</object>
 					<boolean value="YES"/>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 					<boolean value="YES"/>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<boolean value="YES"/>
+					<string>{{341, 611}, {235, 203}}</string>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<boolean value="YES"/>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<boolean value="YES"/>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<boolean value="YES"/>
 				</object>
 			</object>
 			<object class="NSMutableDictionary" key="unlocalizedProperties">
@@ -2384,7 +3078,7 @@
 				</object>
 			</object>
 			<nil key="sourceID"/>
-			<int key="maxID">351</int>
+			<int key="maxID">414</int>
 		</object>
 		<object class="IBClassDescriber" key="IBDocument.Classes">
 			<object class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -2410,6 +3104,7 @@
 				</object>
 				<object class="IBPartialClassDescription">
 					<string key="className">FirstResponder</string>
+					<string key="superclassName">NSObject</string>
 					<object class="IBClassDescriptionSource" key="sourceIdentifier">
 						<string key="majorKey">IBUserSource</string>
 						<string key="minorKey"/>
@@ -2458,6 +3153,8 @@
 							<string>configWindow</string>
 							<string>doom1</string>
 							<string>doom2</string>
+							<string>heretic</string>
+							<string>hexen</string>
 							<string>iwadSelector</string>
 							<string>plutonia</string>
 							<string>tnt</string>
@@ -2471,6 +3168,8 @@
 							<string>id</string>
 							<string>id</string>
 							<string>id</string>
+							<string>id</string>
+							<string>id</string>
 						</object>
 					</object>
 					<object class="NSMutableDictionary" key="toOneOutletInfosByName">
@@ -2481,6 +3180,8 @@
 							<string>configWindow</string>
 							<string>doom1</string>
 							<string>doom2</string>
+							<string>heretic</string>
+							<string>hexen</string>
 							<string>iwadSelector</string>
 							<string>plutonia</string>
 							<string>tnt</string>
@@ -2504,6 +3205,14 @@
 								<string key="candidateClassName">id</string>
 							</object>
 							<object class="IBToOneOutletInfo">
+								<string key="name">heretic</string>
+								<string key="candidateClassName">id</string>
+							</object>
+							<object class="IBToOneOutletInfo">
+								<string key="name">hexen</string>
+								<string key="candidateClassName">id</string>
+							</object>
+							<object class="IBToOneOutletInfo">
 								<string key="name">iwadSelector</string>
 								<string key="candidateClassName">id</string>
 							</object>
@@ -2560,6 +3269,11 @@
 						<object class="NSArray" key="dict.sortedKeys">
 							<bool key="EncodedWithXMLCoder">YES</bool>
 							<string>launch:</string>
+							<string>openCMDLINE:</string>
+							<string>openCOPYING:</string>
+							<string>openDocumentation:</string>
+							<string>openINSTALL:</string>
+							<string>openREADME:</string>
 							<string>openTerminal:</string>
 							<string>runSetup:</string>
 						</object>
@@ -2568,6 +3282,11 @@
 							<string>id</string>
 							<string>id</string>
 							<string>id</string>
+							<string>id</string>
+							<string>id</string>
+							<string>id</string>
+							<string>id</string>
+							<string>id</string>
 						</object>
 					</object>
 					<object class="NSMutableDictionary" key="actionInfosByName">
@@ -2575,6 +3294,11 @@
 						<object class="NSArray" key="dict.sortedKeys">
 							<bool key="EncodedWithXMLCoder">YES</bool>
 							<string>launch:</string>
+							<string>openCMDLINE:</string>
+							<string>openCOPYING:</string>
+							<string>openDocumentation:</string>
+							<string>openINSTALL:</string>
+							<string>openREADME:</string>
 							<string>openTerminal:</string>
 							<string>runSetup:</string>
 						</object>
@@ -2582,6 +3306,26 @@
 							<bool key="EncodedWithXMLCoder">YES</bool>
 							<object class="IBActionInfo">
 								<string key="name">launch:</string>
+								<string key="candidateClassName">id</string>
+							</object>
+							<object class="IBActionInfo">
+								<string key="name">openCMDLINE:</string>
+								<string key="candidateClassName">id</string>
+							</object>
+							<object class="IBActionInfo">
+								<string key="name">openCOPYING:</string>
+								<string key="candidateClassName">id</string>
+							</object>
+							<object class="IBActionInfo">
+								<string key="name">openDocumentation:</string>
+								<string key="candidateClassName">id</string>
+							</object>
+							<object class="IBActionInfo">
+								<string key="name">openINSTALL:</string>
+								<string key="candidateClassName">id</string>
+							</object>
+							<object class="IBActionInfo">
+								<string key="name">openREADME:</string>
 								<string key="candidateClassName">id</string>
 							</object>
 							<object class="IBActionInfo">
binary files a/pkg/osx/Resources/launcher.nib/keyedobjects.nib b/pkg/osx/Resources/launcher.nib/keyedobjects.nib differ
binary files /dev/null b/pkg/osx/disk/background.png differ
binary files /dev/null b/pkg/osx/disk/dir.DS_Store differ
--- /dev/null
+++ b/pkg/osx/dmgfix
@@ -1,0 +1,64 @@
+#!/usr/bin/osascript
+--
+-- Copyright(C) 2009 Simon Howard
+--
+-- This program is free software; you can redistribute it and/or
+-- modify it under the terms of the GNU General Public License
+-- as published by the Free Software Foundation; either version 2
+-- of the License, or (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program; if not, write to the Free Software
+-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+-- 02111-1307, USA.
+--
+--
+-- AppleScript script to automatically set the view properties in a
+-- .dmg file - ie. the background image, other Finder view options
+-- and icon positions.
+--
+-- Usage: dmgfix <absolute path to dmg> <disk name> <name of app>
+--
+
+on run argv
+    set dmgFile to POSIX file (item 1 of argv)
+    set diskName to item 2 of argv
+    set appName to item 3 of argv
+
+    tell application "Finder"
+        --activate
+        open dmgFile
+        delay 1
+        set win to the front Finder window
+        set theDisk to disk diskName
+        set the target of win to theDisk
+
+        -- window options:
+
+        set bgfile to file "background.png" of theDisk
+        set the bounds of win to {200, 200, 717, 536}
+        set icon size of icon view options of win to 96
+        set background picture of icon view options of win to bgfile
+        set toolbar visible of win to false
+
+        -- hide background file:
+
+        set bgloc to quoted form of POSIX path of (bgfile as text)
+        do shell script "SetFile -a V " & bgloc
+
+        -- icon positions:
+
+        set position of file "README" of theDisk to {120, 250}
+        set position of file "Software License" of theDisk to {380, 250}
+        set position of file appName of theDisk to {70, 110}
+        set position of file "Applications" of theDisk to {450, 110}
+
+        eject theDisk
+    end tell
+end run
+
--- a/pkg/win32/GNUmakefile
+++ b/pkg/win32/GNUmakefile
@@ -29,6 +29,10 @@
 		cp $(TOPLEVEL)/$$f staging/$$f.txt;  \
 		unix2dos staging/$$f.txt;            \
 	done
+	$(TOPLEVEL)/man/simplecpp -D_WIN32 -DPRECOMPILED  \
+	         < $(TOPLEVEL)/man/INSTALL.template       \
+	         > staging/INSTALL.txt
+	unix2dos staging/INSTALL.txt
 
 clean:
 	rm -f $(ZIP)
--- a/rpm.spec.in
+++ b/rpm.spec.in
@@ -18,6 +18,16 @@
 
 See @PACKAGE_URL@ for more information.
 
+%package -n @PROGRAM_PREFIX@heretic
+Summary: @PACKAGE_SHORTDESC@ (Heretic binaries)
+Group: Amusements/Games
+Requires: libSDL-1.2.so.0, libSDL_mixer-1.2.so.0, libSDL_net-1.2.so.0
+
+%package -n @PROGRAM_PREFIX@hexen
+Summary: @PACKAGE_SHORTDESC@ (Hexen binaries)
+Group: Amusements/Games
+Requires: libSDL-1.2.so.0, libSDL_mixer-1.2.so.0, libSDL_net-1.2.so.0
+
 %prep
 rm -rf $RPM_BUILD_ROOT
 
@@ -47,16 +57,33 @@
 rm -rf $RPM_BUILD_ROOT
 
 %files
-%doc %{_mandir}/man5/*
-%doc %{_mandir}/man6/*
-%doc README
-%doc README.OPL
-%doc INSTALL
-%doc NEWS
-%doc AUTHORS
-%doc COPYING
-%doc CMDLINE
-%doc BUGS
-%doc NOT-BUGS
-/usr/games/*
+%{_mandir}/man5/@[email protected]
+%{_mandir}/man5/default.cfg.5
+%{_mandir}/man6/@[email protected]
+%{_mandir}/man6/@[email protected]
+%{_mandir}/man6/@[email protected]
+/usr/share/doc/@PACKAGE@/*
+/usr/games/@PROGRAM_PREFIX@doom
+/usr/games/@PROGRAM_PREFIX@server
+/usr/games/@PROGRAM_PREFIX@doom-setup
+/usr/share/icons/*
+/usr/share/applications/*
+
+%files @PROGRAM_PREFIX@heretic
+%{_mandir}/man5/@[email protected]
+%{_mandir}/man5/heretic.cfg.5
+%{_mandir}/man6/@[email protected]
+%{_mandir}/man6/@[email protected]
+/usr/share/doc/@PROGRAM_PREFIX@heretic/*
+/usr/games/@PROGRAM_PREFIX@heretic
+/usr/games/@PROGRAM_PREFIX@heretic-setup
+
+%files @PROGRAM_PREFIX@hexen
+%{_mandir}/man5/@[email protected]
+%{_mandir}/man5/hexen.cfg.5
+%{_mandir}/man6/@[email protected]
+%{_mandir}/man6/@[email protected]
+/usr/share/doc/@PROGRAM_PREFIX@hexen/*
+/usr/games/@PROGRAM_PREFIX@hexen
+/usr/games/@PROGRAM_PREFIX@hexen-setup
 
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -194,24 +194,36 @@
 @PROGRAM_PREFIX@setup_LDADD = setup/libsetup.a                             \
                         $(top_builddir)/wince/libc_wince.a           \
                         $(top_builddir)/textscreen/libtextscreen.a   \
-                        @LDFLAGS@ @SDL_LIBS@ @SDLNET_LIBS@ 
+                        @LDFLAGS@ @SDL_LIBS@ @SDLMIXER_LIBS@ @SDLNET_LIBS@
 
 EXTRA_DIST =                        \
         icon.c                      \
         doom-screensaver.desktop.in
 
+appdir = $(prefix)/share/applications
+app_DATA = @[email protected]
+
+@[email protected] : doom.desktop
+	cp $< $@
+
+screensaverdir = $(prefix)/share/applications/screensavers
+screensaver_DATA = @[email protected]
+
+@[email protected]: doom-screensaver.desktop
+	cp $< $@
+
 .rc.o:
-	$(WINDRES) $^ -o $@
+	$(WINDRES) $< -o $@
 %.o : %.rc
-	$(WINDRES) $^ -o $@
+	$(WINDRES) $< -o $@
 
 if HAVE_PYTHON
 
 icon.c : $(top_builddir)/data/doom8.ico
-	$(top_builddir)/data/convert-icon $^ $@
+	$(top_builddir)/data/convert-icon $< $@
 
 endif
 
 midiread : midifile.c
-	$(CC) -DTEST $(CFLAGS) @LDFLAGS@ $^ -o $@
+	$(CC) -DTEST $(CFLAGS) @LDFLAGS@ $< -o $@
 
--- a/src/d_iwad.c
+++ b/src/d_iwad.c
@@ -424,12 +424,20 @@
 {
     size_t i;
     GameMission_t mission;
+    char *p;
 
+    p = strrchr(name, DIR_SEPARATOR);
+
+    if (p != NULL)
+    {
+        name = p + 1;
+    }
+
     mission = none;
 
     for (i=0; i<arrlen(iwads); ++i)
     {
-        char *iwadname;
+        // Check if the filename is this IWAD name.
 
         // Only use supported missions:
 
@@ -436,15 +444,9 @@
         if (((1 << iwads[i].mission) & mask) == 0)
             continue;
 
-        iwadname = DEH_String(iwads[i].name);
-
-        if (strlen(name) < strlen(iwadname))
-            continue;
-
         // Check if it ends in this IWAD name.
 
-        if (!strcasecmp(name + strlen(name) - strlen(iwadname), 
-                        iwadname))
+        if (!strcasecmp(name, iwads[i].name))
         {
             mission = iwads[i].mission;
             break;
@@ -727,5 +729,33 @@
     result[result_len] = NULL;
 
     return result;
+}
+
+//
+// Get the IWAD name used for savegames.
+//
+
+char *D_SaveGameIWADName(GameMission_t gamemission)
+{
+    size_t i;
+
+    // Determine the IWAD name to use for savegames.
+    // This determines the directory the savegame files get put into.
+    //
+    // Note that we match on gamemission rather than on IWAD name.
+    // This ensures that doom1.wad and doom.wad saves are stored
+    // in the same place.
+
+    for (i=0; i<arrlen(iwads); ++i)
+    {
+        if (gamemission == iwads[i].mission)
+        {
+            return iwads[i].name;
+        }
+    }
+
+    // Default fallback:
+
+    return "unknown.wad";
 }
 
--- a/src/d_iwad.h
+++ b/src/d_iwad.h
@@ -49,6 +49,7 @@
 char *D_TryFindWADByName(char *filename);
 char *D_FindIWAD(int mask, GameMission_t *mission);
 iwad_t **D_FindAllIWADs(int mask);
+char *D_SaveGameIWADName(GameMission_t gamemission);
 
 #endif
 
--- a/src/d_mode.h
+++ b/src/d_mode.h
@@ -66,6 +66,7 @@
     exe_hacx,        // Hacx
     exe_ultimate,    // Ultimate Doom (retail)
     exe_final,       // Final Doom
+    exe_final2,      // Final Doom (alternate exe)
     exe_chex,        // Chex Quest executable (based on Final Doom)
 
     exe_heretic_1_3, // Heretic 1.3
--- a/src/deh_io.c
+++ b/src/deh_io.c
@@ -181,7 +181,7 @@
 
 int DEH_GetChar(deh_context_t *context)
 {
-    int result;
+    int result = 0;
 
     // Read characters, but ignore carriage returns
     // Essentially this is a DOS->Unix conversion
--- a/src/doom-screensaver.desktop.in
+++ b/src/doom-screensaver.desktop.in
@@ -1,12 +1,12 @@
 
 [Desktop Entry]
-Encoding=UTF-8
-Name=Doom
-Comment=DOOM by Id Software.
-TryExec=@PACKAGE_TARNAME@
-Exec=@PACKAGE_TARNAME@
+Name=@PACKAGE_NAME@
+Comment=@PACKAGE_SHORTDESC@
+TryExec=@PROGRAM_PREFIX@doom
+Exec=@PROGRAM_PREFIX@doom
 StartupNotify=false
 Terminal=false
 Type=Application
-Categories=Screensaver
+OnlyShowIn=GNOME;
+Categories=Screensaver;
 
--- /dev/null
+++ b/src/doom.desktop.in
@@ -1,0 +1,7 @@
+[Desktop Entry]
+Name=@PACKAGE_NAME@
+Exec=@PROGRAM_PREFIX@doom
+Icon=@PROGRAM_PREFIX@doom
+Type=Application
+Comment=@PACKAGE_SHORTDESC@
+Categories=Game;ActionGame;
--- a/src/doom/d_main.c
+++ b/src/doom/d_main.c
@@ -532,6 +532,9 @@
     // include a DEMO4 lump, so the game bombs out with an error
     // when it reaches this point in the demo sequence.
 
+    // However! There is an alternate version of Final Doom that
+    // includes a fixed executable.
+
     if (gameversion == exe_ultimate || gameversion == exe_final)
       demosequence = (demosequence+1)%7;
     else
@@ -783,40 +786,6 @@
     }
 }
 
-static void SetSaveGameDir(char *iwad_filename)
-{
-    char *sep;
-    char *basefile;
-
-    // Extract the base filename
- 
-    sep = strrchr(iwad_filename, DIR_SEPARATOR);
-
-    if (sep == NULL)
-    {
-        basefile = iwad_filename;
-    }
-    else
-    {
-        basefile = sep + 1;
-    }
-
-    // ~/.chocolate-doom/savegames/
-
-    savegamedir = Z_Malloc(strlen(configdir) + 30, PU_STATIC, 0);
-    sprintf(savegamedir, "%ssavegames%c", configdir,
-                         DIR_SEPARATOR);
-
-    M_MakeDirectory(savegamedir);
-
-    // eg. ~/.chocolate-doom/savegames/doom2.wad/
-
-    sprintf(savegamedir + strlen(savegamedir), "%s%c",
-            basefile, DIR_SEPARATOR);
-
-    M_MakeDirectory(savegamedir);
-}
-
 // Check if the IWAD file is the Chex Quest IWAD.  
 // Returns true if this is chex.wad.
 
@@ -914,6 +883,7 @@
     {"Hacx",                 "hacx",       exe_hacx},
     {"Ultimate Doom",        "ultimate",   exe_ultimate},
     {"Final Doom",           "final",      exe_final},
+    {"Final Doom (alt)",     "final2",     exe_final2},
     {"Chex Quest",           "chex",       exe_chex},
     { NULL,                  NULL,         0},
 };
@@ -930,7 +900,7 @@
     // @category compat
     //
     // Emulate a specific version of Doom.  Valid values are "1.9",
-    // "ultimate" and "final".
+    // "ultimate", "final", "final2", "hacx" and "chex".
     //
 
     p = M_CheckParmWithArgs("-gameversion", 1);
@@ -994,8 +964,10 @@
             else
             {
                 // Final Doom: tnt or plutonia
+                // Default to the "alt" version of the executable that
+                // fixes the demo loop behavior.
 
-                gameversion = exe_final;
+                gameversion = exe_final2;
             }
         }
     }
@@ -1034,12 +1006,38 @@
 
 static void LoadChexDeh(void)
 {
-    char *chex_deh;
+    char *chex_deh = NULL;
+    char *sep;
 
     if (gameversion == exe_chex)
     {
-        chex_deh = D_FindWADByName("chex.deh");
+        // Look for chex.deh in the same directory as the IWAD file.
 
+        sep = strrchr(iwadfile, DIR_SEPARATOR);
+
+        if (sep != NULL)
+        {
+            chex_deh = malloc(strlen(iwadfile) + 9);
+            strcpy(chex_deh, iwadfile);
+            chex_deh[sep - iwadfile + 1] = '\0';
+            strcat(chex_deh, "chex.deh");
+        }
+        else
+        {
+            chex_deh = strdup("chex.deh");
+        }
+
+        // If the dehacked patch isn't found, try searching the WAD
+        // search path instead.  We might find it...
+
+        if (!M_FileExists(chex_deh))
+        {
+            free(chex_deh);
+            chex_deh = D_FindWADByName("chex.deh");
+        }
+
+        // Still not found?
+
         if (chex_deh == NULL)
         {
             I_Error("Unable to find Chex Quest dehacked file (chex.deh).\n"
@@ -1089,6 +1087,27 @@
     }
 }
 
+// Figure out what IWAD name to use for savegames.
+
+static char *SaveGameIWADName(void)
+{
+    // Chex quest hack
+
+    if (gameversion == exe_chex)
+    {
+        return "chex.wad";
+    }
+
+    // Hacx hack
+
+    if (gameversion == exe_hacx)
+    {
+        return "hacx.wad";
+    }
+
+    return D_SaveGameIWADName(gamemission);
+}
+
 //
 // D_DoomMain
 //
@@ -1407,7 +1426,7 @@
     LoadChexDeh();
     LoadHacxDeh();
     D_SetGameDescription();
-    SetSaveGameDir(iwadfile);
+    savegamedir = M_GetSaveGameDir(SaveGameIWADName());
 
     // Check for -file in shareware
     if (modifiedgame)
--- a/src/doom/d_net.c
+++ b/src/doom/d_net.c
@@ -474,7 +474,8 @@
     // Start a multiplayer server, listening for connections.
     //
 
-    if (M_CheckParm("-server") > 0)
+    if (M_CheckParm("-server") > 0
+     || M_CheckParm("-privateserver") > 0)
     {
         NET_SV_Init();
         NET_SV_AddModule(&net_loop_server_module);
--- /dev/null
+++ b/src/doom/doom.desktop.in
@@ -1,0 +1,7 @@
+[Desktop Entry]
+Name=@PACKAGE_NAME@
+Exec=@PROGRAM_PREFIX@doom
+Icon=@PROGRAM_PREFIX@doom
+Type=Application
+Comment=@PACKAGE_SHORTDESC@
+Categories=Game;ActionGame;
--- a/src/doom/doomstat.c
+++ b/src/doom/doomstat.c
@@ -32,7 +32,7 @@
 // Game Mode - identify IWAD as shareware, retail etc.
 GameMode_t gamemode = indetermined;
 GameMission_t	gamemission = doom;
-GameVersion_t   gameversion = exe_final;
+GameVersion_t   gameversion = exe_final2;
 char *gamedescription;
 
 // Set if homebrew PWAD stuff has been added.
--- a/src/doom/g_game.c
+++ b/src/doom/g_game.c
@@ -361,6 +361,13 @@
 
 static boolean WeaponSelectable(weapontype_t weapon)
 {
+    // Can't select the super shotgun in Doom 1.
+
+    if (weapon == wp_supershotgun && gamemission == doom)
+    {
+        return false;
+    }
+
     // Can't select a weapon if we don't own it.
 
     if (!players[consoleplayer].weaponowned[weapon])
--- a/src/doom/m_menu.c
+++ b/src/doom/m_menu.c
@@ -798,6 +798,7 @@
             break;
 
         case exe_final:
+        case exe_final2:
 
             // Final Doom always displays "HELP".
 
--- a/src/doom/p_map.c
+++ b/src/doom/p_map.c
@@ -885,17 +885,8 @@
 	
 	dist = FixedMul (attackrange, in->frac);
 
-        // Return false if there is no back sector.  This should never
-        // be the case if the line is two-sided; however, some WADs
-        // (eg. ottawau.wad) use this as an "impassible glass" trick
-        // and rely on Vanilla Doom's (unintentional) support for this.
-
-        if (li->backsector == NULL)
-        {
-            return false;
-        }
-
-        if (li->frontsector->floorheight != li->backsector->floorheight)
+        if (li->backsector == NULL
+         || li->frontsector->floorheight != li->backsector->floorheight)
 	{
 	    slope = FixedDiv (openbottom - shootz , dist);
 	    if (slope > bottomslope)
@@ -902,7 +893,8 @@
 		bottomslope = slope;
 	}
 		
-	if (li->frontsector->ceilingheight != li->backsector->ceilingheight)
+	if (li->backsector == NULL
+         || li->frontsector->ceilingheight != li->backsector->ceilingheight)
 	{
 	    slope = FixedDiv (opentop - shootz , dist);
 	    if (slope < topslope)
@@ -983,26 +975,35 @@
 		
 	dist = FixedMul (attackrange, in->frac);
 
-        // Check if backsector is NULL.  See comment in PTR_AimTraverse.
+        // e6y: emulation of missed back side on two-sided lines.
+        // backsector can be NULL when emulating missing back side.
 
-	if (li->backsector == NULL)
+        if (li->backsector == NULL)
         {
-            goto hitline;
+            slope = FixedDiv (openbottom - shootz , dist);
+            if (slope > aimslope)
+                goto hitline;
+
+            slope = FixedDiv (opentop - shootz , dist);
+            if (slope < aimslope)
+                goto hitline;
         }
+        else
+        {
+            if (li->frontsector->floorheight != li->backsector->floorheight)
+            {
+                slope = FixedDiv (openbottom - shootz , dist);
+                if (slope > aimslope)
+                    goto hitline;
+            }
 
-        if (li->frontsector->floorheight != li->backsector->floorheight)
-	{
-	    slope = FixedDiv (openbottom - shootz , dist);
-	    if (slope > aimslope)
-		goto hitline;
-	}
-		
-	if (li->frontsector->ceilingheight != li->backsector->ceilingheight)
-	{
-	    slope = FixedDiv (opentop - shootz , dist);
-	    if (slope < aimslope)
-		goto hitline;
-	}
+            if (li->frontsector->ceilingheight != li->backsector->ceilingheight)
+            {
+                slope = FixedDiv (opentop - shootz , dist);
+                if (slope < aimslope)
+                    goto hitline;
+            }
+        }
 
 	// shot continues
 	return true;
--- a/src/doom/p_setup.c
+++ b/src/doom/p_setup.c
@@ -155,8 +155,25 @@
     W_ReleaseLumpNum(lump);
 }
 
+//
+// GetSectorAtNullAddress
+//
+sector_t* GetSectorAtNullAddress(void)
+{
+    static boolean null_sector_is_initialized = false;
+    static sector_t null_sector;
 
+    if (!null_sector_is_initialized)
+    {
+        memset(&null_sector, 0, sizeof(null_sector));
+        I_GetMemoryValue(0, &null_sector.floorheight, 4);
+        I_GetMemoryValue(4, &null_sector.ceilingheight, 4);
+        null_sector_is_initialized = true;
+    }
 
+    return &null_sector;
+}
+
 //
 // P_LoadSegs
 //
@@ -204,10 +221,12 @@
 
             if (sidenum < 0 || sidenum >= numsides)
             {
-                sidenum = 0;
+                li->backsector = GetSectorAtNullAddress();
             }
-
-            li->backsector = sides[sidenum].sector;
+            else
+            {
+                li->backsector = sides[sidenum].sector;
+            }
         }
         else
         {
@@ -681,7 +700,7 @@
     if (len > sizeof(rejectpad))
     {
         fprintf(stderr, "PadRejectArray: REJECT lump too short to pad! (%i > %i)\n",
-                        len, sizeof(rejectpad));
+                        len, (int) sizeof(rejectpad));
 
         // Pad remaining space with 0 (or 0xff, if specified on command line).
 
--- a/src/doom/st_stuff.c
+++ b/src/doom/st_stuff.c
@@ -525,8 +525,13 @@
 	
 	plyr->message = DEH_String(STSTR_MUS);
 	cht_GetParam(&cheat_mus, buf);
-	
-	if (gamemode == commercial)
+
+        // Note: The original v1.9 had a bug that tried to play back
+        // the Doom II music regardless of gamemode.  This was fixed
+        // in the Ultimate Doom executable so that it would work for
+        // the Doom 1 music as well.
+
+	if (gamemode == commercial || gameversion < exe_ultimate)
 	{
 	  musnum = mus_runnin + (buf[0]-'0')*10 + buf[1]-'0' - 1;
 	  
--- a/src/heretic/d_main.c
+++ b/src/heretic/d_main.c
@@ -421,25 +421,19 @@
 void D_CheckRecordFrom(void)
 {
     int p;
-    char file[256];
+    char *filename;
 
     p = M_CheckParm("-recordfrom");
     if (!p || p > myargc - 2)
         return;
 
-    if (cdrom)
-    {
-        sprintf(file, SAVEGAMENAMECD "%c.hsg", myargv[p + 1][0]);
-    }
-    else
-    {
-        sprintf(file, SAVEGAMENAME "%c.hsg", myargv[p + 1][0]);
-    }
-    G_LoadGame(file);
+    filename = SV_Filename(myargv[p + 1][0] - '0');
+    G_LoadGame(filename);
     G_DoLoadGame();             // load the gameskill etc info from savegame
 
     G_RecordDemo(gameskill, 1, gameepisode, gamemap, myargv[p + 2]);
     D_DoomLoop();               // never returns
+    free(filename);
 }
 
 /*
@@ -940,6 +934,8 @@
         gamedescription = "Heretic (registered)";
     }
 
+    savegamedir = M_GetSaveGameDir("heretic.wad");
+
     I_PrintStartupBanner(gamedescription);
 
     // haleyjd: removed WATCOMC
@@ -1033,15 +1029,11 @@
     p = M_CheckParm("-loadgame");
     if (p && p < myargc - 1)
     {
-        if (cdrom)
-        {
-            sprintf(file, SAVEGAMENAMECD "%c.hsg", myargv[p + 1][0]);
-        }
-        else
-        {
-            sprintf(file, SAVEGAMENAME "%c.hsg", myargv[p + 1][0]);
-        }
-        G_LoadGame(file);
+        char *filename;
+
+	filename = SV_Filename(myargv[p + 1][0] - '0');
+        G_LoadGame(filename);
+	free(filename);
     }
 
     // Check valid episode and map
--- a/src/heretic/doomdef.h
+++ b/src/heretic/doomdef.h
@@ -66,7 +66,6 @@
 #include "d_ticcmd.h"
 
 #define	SAVEGAMENAME "hticsav"
-#define SAVEGAMENAMECD "c:\\heretic.cd\\hticsav"
 
 /*
 ===============================================================================
@@ -740,6 +739,7 @@
 // called by M_Responder
 
 // Support routines for saving games
+char *SV_Filename(int slot);
 void SV_Open(char *fileName);
 void SV_Close(char *fileName);
 void SV_Write(void *buffer, int size);
@@ -746,6 +746,8 @@
 void SV_WriteByte(byte val);
 void SV_WriteWord(unsigned short val);
 void SV_WriteLong(unsigned int val);
+
+extern char *savegamedir;
 
 void G_RecordDemo(skill_t skill, int numplayers, int episode, int map,
                   char *name);
--- a/src/heretic/g_game.c
+++ b/src/heretic/g_game.c
@@ -25,6 +25,7 @@
 // G_game.c
 
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include "doomdef.h"
 #include "doomkeys.h"
@@ -133,6 +134,7 @@
 
 short consistancy[MAXPLAYERS][BACKUPTICS];
 
+char *savegamedir;
 byte *savebuffer, *save_p;
 
 
@@ -1294,11 +1296,11 @@
 //
 //---------------------------------------------------------------------------
 
-char savename[256];
+static char *savename = NULL;
 
 void G_LoadGame(char *name)
 {
-    strcpy(savename, name);
+    savename = strdup(name);
     gameaction = ga_loadgame;
 }
 
@@ -1322,6 +1324,9 @@
     gameaction = ga_nothing;
 
     length = M_ReadFile(savename, &savebuffer);
+    free(savename);
+    savename = NULL;
+
     save_p = savebuffer + SAVESTRINGSIZE;
     // Skip the description field
     memset(vcheck, 0, sizeof(vcheck));
@@ -1684,21 +1689,15 @@
 void G_DoSaveGame(void)
 {
     int i;
-    char name[100];
+    char *filename;
     char verString[VERSIONSIZE];
     char *description;
 
-    if (cdrom)
-    {
-        sprintf(name, SAVEGAMENAMECD "%d.hsg", savegameslot);
-    }
-    else
-    {
-        sprintf(name, SAVEGAMENAME "%d.hsg", savegameslot);
-    }
+    filename = SV_Filename(savegameslot);
+
     description = savedescription;
 
-    SV_Open(name);
+    SV_Open(filename);
     SV_Write(description, SAVESTRINGSIZE);
     memset(verString, 0, sizeof(verString));
     DEH_snprintf(verString, VERSIONSIZE, "version %i", HERETIC_VERSION);
@@ -1717,11 +1716,32 @@
     P_ArchiveWorld();
     P_ArchiveThinkers();
     P_ArchiveSpecials();
-    SV_Close(name);
+    SV_Close(filename);
 
     gameaction = ga_nothing;
     savedescription[0] = 0;
     P_SetMessage(&players[consoleplayer], DEH_String(TXT_GAMESAVED), true);
+
+    free(filename);
+}
+
+//==========================================================================
+//
+// SV_Filename
+//
+// Generate the filename to use for a particular savegame slot.
+// Returns a malloc()'d buffer that must be freed by the caller.
+//
+//==========================================================================
+
+char *SV_Filename(int slot)
+{
+    char *filename;
+
+    filename = malloc(strlen(savegamedir) + strlen(SAVEGAMENAME) + 8);
+    sprintf(filename, "%s" SAVEGAMENAME "%d.hsg", savegamedir, slot);
+
+    return filename;
 }
 
 //==========================================================================
--- a/src/heretic/mn_menu.c
+++ b/src/heretic/mn_menu.c
@@ -645,19 +645,14 @@
     FILE *fp;
     int count;
     int i;
-    char name[256];
+    char *filename;
 
     for (i = 0; i < 6; i++)
     {
-        if (cdrom)
-        {
-            sprintf(name, SAVEGAMENAMECD "%d.hsg", i);
-        }
-        else
-        {
-            sprintf(name, SAVEGAMENAME "%d.hsg", i);
-        }
-        fp = fopen(name, "rb+");
+        filename = SV_Filename(i);
+        fp = fopen(filename, "rb+");
+	free(filename);
+
         if (!fp)
         {
             SlotText[i][0] = 0; // empty the string
@@ -826,21 +821,17 @@
 
 static boolean SCLoadGame(int option)
 {
-    char name[256];
+    char *filename;
 
     if (!SlotStatus[option])
     {                           // slot's empty...don't try and load
         return false;
     }
-    if (cdrom)
-    {
-        sprintf(name, SAVEGAMENAMECD "%d.hsg", option);
-    }
-    else
-    {
-        sprintf(name, SAVEGAMENAME "%d.hsg", option);
-    }
-    G_LoadGame(name);
+
+    filename = SV_Filename(option);
+    G_LoadGame(filename);
+    free(filename);
+
     MN_DeactivateMenu();
     BorderNeedRefresh = true;
     if (quickload == -1)
--- a/src/hexen/h2_main.c
+++ b/src/hexen/h2_main.c
@@ -184,8 +184,17 @@
 
 static void D_SetDefaultSavePath(void)
 {
-    SavePath = malloc(strlen(configdir) + 10);
-    sprintf(SavePath, "%shexndata%c", configdir, DIR_SEPARATOR);
+    SavePath = M_GetSaveGameDir("hexen.wad");
+
+    // If we are not using a savegame path (probably because we are on
+    // Windows and not using a config dir), behave like Vanilla Hexen
+    // and use hexndata/:
+
+    if (!strcmp(SavePath, ""))
+    {
+        SavePath = malloc(10);
+	sprintf(SavePath, "hexndata%c", DIR_SEPARATOR);
+    }
 }
 
 //
--- a/src/i_endoom.c
+++ b/src/i_endoom.c
@@ -67,7 +67,7 @@
     {
         TXT_UpdateScreen();
 
-        if (TXT_GetChar() >= 0)
+        if (TXT_GetChar() > 0)
         {
             break;
         }
--- a/src/i_oplmusic.c
+++ b/src/i_oplmusic.c
@@ -1079,7 +1079,7 @@
 
 // Restart a song from the beginning.
 
-static void RestartSong(void)
+static void RestartSong(void *unused)
 {
     unsigned int i;
 
@@ -1117,10 +1117,15 @@
         --running_tracks;
 
         // When all tracks have finished, restart the song.
+        // Don't restart the song immediately, but wait for 5ms
+        // before triggering a restart.  Otherwise it is possible
+        // to construct an empty MIDI file that causes the game
+        // to lock up in an infinite loop. (5ms should be short
+        // enough not to be noticeable by the listener).
 
         if (running_tracks <= 0 && song_looping)
         {
-            RestartSong();
+            OPL_SetCallback(5, RestartSong, NULL);
         }
 
         return;
--- a/src/i_scale.c
+++ b/src/i_scale.c
@@ -33,6 +33,7 @@
 #include "doomtype.h"
 
 #include "i_video.h"
+#include "m_argv.h"
 #include "z_zone.h"
 
 #if defined(_MSC_VER) && !defined(__cplusplus)
@@ -965,6 +966,21 @@
         // 100% line 0
         WriteLine5x(screenp, bufp);
         screenp += dest_pitch; bufp += SCREENWIDTH;
+    }
+
+    // test hack for Porsche Monty... scan line simulation:
+    // See here: http://www.doomworld.com/vb/post/962612
+
+    if (M_CheckParm("-scanline") > 0)
+    {
+        screenp = (byte *) dest_buffer + 2 * dest_pitch;
+
+        for (y=0; y<1198; y += 3)
+        {
+            memset(screenp, 0, 1600);
+
+            screenp += dest_pitch * 3;
+        }
     }
 
     return true;
--- a/src/i_system.c
+++ b/src/i_system.c
@@ -38,6 +38,8 @@
 #include <unistd.h>
 #endif
 
+#include "SDL.h"
+
 #include "config.h"
 
 #include "deh_str.h"
@@ -55,6 +57,10 @@
 #include "w_wad.h"
 #include "z_zone.h"
 
+#ifdef __MACOSX__
+#include <CoreFoundation/CFUserNotification.h>
+#endif
+
 #define DEFAULT_RAM 16 /* MiB */
 #define MIN_RAM     4  /* MiB */
 
@@ -282,7 +288,6 @@
 }
 */
 
-
 //
 // I_Quit
 //
@@ -366,8 +371,152 @@
     }
 #endif
 
+#ifdef __MACOSX__
+    if (!I_ConsoleStdout())
+    {
+        CFStringRef message;
+        char msgbuf[512];
+	int i;
+
+        va_start(argptr, error);
+        memset(msgbuf, 0, sizeof(msgbuf));
+        vsnprintf(msgbuf, sizeof(msgbuf) - 1, error, argptr);
+        va_end(argptr);
+
+	// The CoreFoundation message box wraps text lines, so replace
+	// newline characters with spaces so that multiline messages
+	// are continuous.
+
+	for (i = 0; msgbuf[i] != '\0'; ++i)
+        {
+            if (msgbuf[i] == '\n')
+            {
+                msgbuf[i] = ' ';
+            }
+        }
+
+        message = CFStringCreateWithCString(NULL, msgbuf,
+                                            kCFStringEncodingUTF8);
+
+        CFUserNotificationDisplayNotice(0,
+                                        kCFUserNotificationCautionAlertLevel,
+                                        NULL,
+                                        NULL,
+                                        NULL,
+                                        CFSTR(PACKAGE_STRING),
+                                        message,
+                                        NULL);
+    }
+#endif
+
     // abort();
 
     exit(-1);
+}
+
+//
+// Read Access Violation emulation.
+//
+// From PrBoom+, by entryway.
+//
+
+// C:\>debug
+// -d 0:0
+//
+// DOS 6.22:
+// 0000:0000  (57 92 19 00) F4 06 70 00-(16 00)
+// DOS 7.1:
+// 0000:0000  (9E 0F C9 00) 65 04 70 00-(16 00)
+// Win98:
+// 0000:0000  (9E 0F C9 00) 65 04 70 00-(16 00)
+// DOSBox under XP:
+// 0000:0000  (00 00 00 F1) ?? ?? ?? 00-(07 00)
+
+#define DOS_MEM_DUMP_SIZE 10
+
+static const unsigned char mem_dump_dos622[DOS_MEM_DUMP_SIZE] = {
+  0x57, 0x92, 0x19, 0x00, 0xF4, 0x06, 0x70, 0x00, 0x16, 0x00};
+static const unsigned char mem_dump_win98[DOS_MEM_DUMP_SIZE] = {
+  0x9E, 0x0F, 0xC9, 0x00, 0x65, 0x04, 0x70, 0x00, 0x16, 0x00};
+static const unsigned char mem_dump_dosbox[DOS_MEM_DUMP_SIZE] = {
+  0x00, 0x00, 0x00, 0xF1, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00};
+static unsigned char mem_dump_custom[DOS_MEM_DUMP_SIZE];
+
+static const unsigned char *dos_mem_dump = mem_dump_dos622;
+
+boolean I_GetMemoryValue(unsigned int offset, void *value, int size)
+{
+    static boolean firsttime = true;
+
+    if (firsttime)
+    {
+        int p, i, val;
+
+        firsttime = false;
+        i = 0;
+
+        //!
+        // @category compat
+        // @arg <version>
+        //
+        // Specify DOS version to emulate for NULL pointer dereference
+        // emulation.  Supported versions are: dos622, dos71, dosbox.
+        // The default is to emulate DOS 7.1 (Windows 98).
+        //
+
+        p = M_CheckParmWithArgs("-setmem", 1);
+
+        if (p > 0)
+        {
+            if (!strcasecmp(myargv[p + 1], "dos622"))
+            {
+                dos_mem_dump = mem_dump_dos622;
+            }
+            if (!strcasecmp(myargv[p + 1], "dos71"))
+            {
+                dos_mem_dump = mem_dump_win98;
+            }
+            else if (!strcasecmp(myargv[p + 1], "dosbox"))
+            {
+                dos_mem_dump = mem_dump_dosbox;
+            }
+            else
+            {
+                for (i = 0; i < DOS_MEM_DUMP_SIZE; ++i)
+                {
+                    ++p;
+
+                    if (p >= myargc || myargv[p][0] == '-')
+                    {
+                        break;
+                    }
+
+                    M_StrToInt(myargv[p], &val);
+                    mem_dump_custom[i++] = (unsigned char) val;
+                }
+
+                dos_mem_dump = mem_dump_custom;
+            }
+        }
+    }
+
+    switch (size)
+    {
+    case 1:
+        *((unsigned char *) value) = dos_mem_dump[offset];
+        return true;
+    case 2:
+        *((unsigned short *) value) = dos_mem_dump[offset]
+                                    | (dos_mem_dump[offset + 1] << 8);
+        return true;
+    case 4:
+        *((unsigned int *) value) = dos_mem_dump[offset]
+                                  | (dos_mem_dump[offset + 1] << 8)
+                                  | (dos_mem_dump[offset + 2] << 16)
+                                  | (dos_mem_dump[offset + 3] << 24);
+        return true;
+    }
+
+    return false;
 }
 
--- a/src/i_system.h
+++ b/src/i_system.h
@@ -71,6 +71,8 @@
 
 void I_Error (char *error, ...);
 
+boolean I_GetMemoryValue(unsigned int offset, void *value, int size);
+
 // Schedule a function to be called when the program exits.
 // If run_if_error is true, the function is called if the exit
 // is due to an error (I_Error)
--- a/src/i_video.c
+++ b/src/i_video.c
@@ -656,7 +656,7 @@
     {
         // Unicode value, from key layout.
 
-        return event->key.keysym.unicode;
+        return tolower(event->key.keysym.unicode);
     }
 }
 
--- a/src/m_config.c
+++ b/src/m_config.c
@@ -1703,3 +1703,40 @@
     M_MakeDirectory(configdir);
 }
 
+//
+// Calculate the path to the directory to use to store save games.
+// Creates the directory as necessary.
+//
+
+char *M_GetSaveGameDir(char *iwadname)
+{
+    char *savegamedir;
+
+    // If not "doing" a configuration directory (Windows), don't "do"
+    // a savegame directory, either.
+
+    if (!strcmp(configdir, ""))
+    {
+	savegamedir = strdup("");
+    }
+    else
+    {
+        // ~/.chocolate-doom/savegames/
+
+        savegamedir = malloc(strlen(configdir) + 30);
+        sprintf(savegamedir, "%ssavegames%c", configdir,
+                             DIR_SEPARATOR);
+
+        M_MakeDirectory(savegamedir);
+
+        // eg. ~/.chocolate-doom/savegames/doom2.wad/
+
+        sprintf(savegamedir + strlen(savegamedir), "%s%c",
+                iwadname, DIR_SEPARATOR);
+
+        M_MakeDirectory(savegamedir);
+    }
+
+    return savegamedir;
+}
+
--- a/src/m_config.h
+++ b/src/m_config.h
@@ -34,6 +34,7 @@
 void M_SetConfigDir(char *dir);
 void M_BindVariable(char *name, void *variable);
 void M_SetConfigFilenames(char *main_config, char *extra_config);
+char *M_GetSaveGameDir(char *iwadname);
 
 extern char *configdir;
 
--- a/src/m_misc.c
+++ b/src/m_misc.c
@@ -209,8 +209,9 @@
 
 void M_ExtractFileBase(char *path, char *dest)
 {
-    char*	src;
-    int		length;
+    char *src;
+    char *filename;
+    int length;
 
     src = path + strlen(path) - 1;
 
@@ -220,20 +221,26 @@
 	src--;
     }
 
-    // copy up to eight characters
-    memset(dest, 0, 8);
+    filename = src;
+
+    // Copy up to eight characters
+    // Note: Vanilla Doom exits with an error if a filename is specified
+    // with a base of more than eight characters.  To remove the 8.3
+    // filename limit, instead we simply truncate the name.
+
     length = 0;
+    memset(dest, 0, 8);
 
     while (*src != '\0' && *src != '.')
     {
-        ++length;
-
-	if (length > 8)
+        if (length >= 8)
         {
-	    I_Error ("Filename base of %s >8 chars", path);
+            printf("Warning: Truncated '%s' lump name to '%.8s'.\n",
+                   filename, dest);
+            break;
         }
 
-	*dest++ = toupper((int)*src++);
+	dest[length++] = toupper((int)*src++);
     }
 }
 
--- a/src/net_server.c
+++ b/src/net_server.c
@@ -1563,6 +1563,7 @@
 {
     //!
     // When running a server, don't register with the global master server.
+    // Implies -server.
     //
     // @category net
     //
--- a/src/setup/Makefile.am
+++ b/src/setup/Makefile.am
@@ -27,6 +27,12 @@
 EXTRA_DIST=                                     \
     setup_icon.c
 
+appdir = $(prefix)/share/applications
+app_DATA = @[email protected]
+
+@[email protected] : setup.desktop
+	cp $^ $@
+
 if HAVE_PYTHON
 
 setup_icon.c : $(top_builddir)/data/setup8.ico
--- a/src/setup/display.c
+++ b/src/setup/display.c
@@ -527,25 +527,34 @@
     GenerateModesTable(NULL, modes_table);
 }
 
-#if defined(_WIN32) && !defined(_WIN32_WCE)
+static void UpdateModeSeparator(TXT_UNCAST_ARG(widget),
+                                TXT_UNCAST_ARG(separator))
+{
+    TXT_CAST_ARG(txt_separator_t, separator);
 
-static int win32_video_driver = 0;
+    if (fullscreen)
+    {
+        TXT_SetSeparatorLabel(separator, "Screen mode");
+    }
+    else
+    {
+        TXT_SetSeparatorLabel(separator, "Window size");
+    }
+}
 
-static char *win32_video_drivers[] = 
-{
-    "DirectX",
-    "Windows GDI",
-};
+#if defined(_WIN32) && !defined(_WIN32_WCE)
 
+static int use_directx = 1;
+
 static void SetWin32VideoDriver(void)
 {
     if (!strcmp(video_driver, "windib"))
     {
-        win32_video_driver = 1;
+        use_directx = 0;
     }
     else
     {
-        win32_video_driver = 0;
+        use_directx = 1;
     }
 }
 
@@ -553,14 +562,16 @@
                               TXT_UNCAST_ARG(modes_table))
 {
     TXT_CAST_ARG(txt_table_t, modes_table);
-    char *drivers[] = 
+
+    if (use_directx)
     {
-        "",
-        "windib",
-    };
+        video_driver = "";
+    }
+    else
+    {
+        video_driver = "windib";
+    }
 
-    video_driver = drivers[win32_video_driver != 0];
-
     // When the video driver is changed, we need to restart the textscreen 
     // library.
 
@@ -579,16 +590,72 @@
 
 #endif
 
+static void AdvancedDisplayConfig(TXT_UNCAST_ARG(widget),
+                                  TXT_UNCAST_ARG(modes_table))
+{
+    TXT_CAST_ARG(txt_table_t, modes_table);
+    txt_window_t *window;
+    txt_checkbox_t *ar_checkbox;
 
+    window = TXT_NewWindow("Advanced display options");
+
+    TXT_SetColumnWidths(window, 35);
+
+    TXT_AddWidgets(window,
+                   ar_checkbox = TXT_NewCheckBox("Fix aspect ratio",
+                                                 &aspect_ratio_correct),
+                   NULL);
+
+    if (gamemission == heretic || gamemission == hexen)
+    {
+        TXT_AddWidget(window,
+                      TXT_NewCheckBox("Graphical startup", &graphical_startup));
+    }
+
+    if (gamemission == doom || gamemission == heretic || gamemission == strife)
+    {
+        TXT_AddWidget(window,
+                      TXT_NewCheckBox("Show ENDOOM screen on exit",
+                                      &show_endoom));
+    }
+
+    TXT_SignalConnect(ar_checkbox, "changed", GenerateModesTable, modes_table);
+
+    // On Windows, there is an extra control to change between 
+    // the Windows GDI and DirectX video drivers.
+
+#if defined(_WIN32) && !defined(_WIN32_WCE)
+    {
+        txt_radiobutton_t *dx_button, *gdi_button;
+
+        TXT_AddWidgets(window,
+                       TXT_NewSeparator("Windows video driver"),
+                       dx_button = TXT_NewRadioButton("DirectX",
+                                                      &use_directx, 1),
+                       gdi_button = TXT_NewRadioButton("Windows GDI",
+                                                       &use_directx, 0),
+                       NULL);
+
+        TXT_SignalConnect(dx_button, "selected",
+                          UpdateVideoDriver, modes_table);
+        TXT_SignalConnect(gdi_button, "selected",
+                          UpdateVideoDriver, modes_table);
+        SetWin32VideoDriver();
+    }
+#endif
+}
+
 void ConfigDisplay(void)
 {
     txt_window_t *window;
     txt_table_t *modes_table;
+    txt_separator_t *modes_separator;
     txt_table_t *bpp_table;
+    txt_window_action_t *advanced_button;
     txt_checkbox_t *fs_checkbox;
-    txt_checkbox_t *ar_checkbox;
-    txt_dropdown_list_t *bpp_selector;
+    int i;
     int num_columns;
+    int num_rows;
     int window_y;
 
     // What color depths are supported?  Generate supported_bpps array
@@ -606,15 +673,9 @@
     }
 
     // Open the window
-    
+
     window = TXT_NewWindow("Display Configuration");
 
-    TXT_AddWidgets(window, 
-                   fs_checkbox = TXT_NewCheckBox("Fullscreen", &fullscreen),
-                   ar_checkbox = TXT_NewCheckBox("Correct aspect ratio",
-                                                 &aspect_ratio_correct),
-                   NULL);
-
     // Some machines can have lots of video modes.  This tries to
     // keep a limit of six lines by increasing the number of
     // columns.  In extreme cases, the window is moved up slightly.
@@ -621,13 +682,11 @@
 
     BuildFullscreenModesList();
 
-    window_y = 5;
-
-    if (num_screen_modes_fullscreen <= 18)
+    if (num_screen_modes_fullscreen <= 24)
     {
         num_columns = 3;
     }
-    else if (num_screen_modes_fullscreen <= 24)
+    else if (num_screen_modes_fullscreen <= 40)
     {
         num_columns = 4;
     }
@@ -634,81 +693,90 @@
     else
     {
         num_columns = 5;
-        window_y -= 3;
     }
 
     modes_table = TXT_NewTable(num_columns);
 
-    // The window is set at a fixed vertical position.  This keeps
-    // the top of the window stationary when switching between
-    // fullscreen and windowed mode (which causes the window's
-    // height to change).
+    // Build window:
 
-    TXT_SetWindowPosition(window, TXT_HORIZ_CENTER, TXT_VERT_TOP, 
-                                  TXT_SCREEN_W / 2, window_y);
+    TXT_AddWidget(window, 
+                  fs_checkbox = TXT_NewCheckBox("Full screen", &fullscreen));
 
-    // On Windows, there is an extra control to change between 
-    // the Windows GDI and DirectX video drivers.
-
-#if defined(_WIN32) && !defined(_WIN32_WCE)
+    if (num_supported_bpps > 1)
     {
-        txt_table_t *driver_table;
-        txt_dropdown_list_t *driver_list;
-
-        driver_table = TXT_NewTable(2);
-
-        TXT_SetColumnWidths(driver_table, 20, 0);
-
-        TXT_AddWidgets(driver_table,
-                       TXT_NewLabel("Video driver"),
-                       driver_list = TXT_NewDropdownList(&win32_video_driver,
-                                                         win32_video_drivers,
-                                                         2),
+        TXT_AddWidgets(window,
+                       TXT_NewSeparator("Color depth"),
+                       bpp_table = TXT_NewTable(4),
                        NULL);
 
-        TXT_SignalConnect(driver_list, "changed",
-                          UpdateVideoDriver, modes_table);
-        SetWin32VideoDriver();
+        for (i = 0; i < num_supported_bpps; ++i)
+        {
+            txt_radiobutton_t *button;
 
-        TXT_AddWidget(window, driver_table);
+            button = TXT_NewRadioButton(supported_bpps[i],
+                                        &selected_bpp, i);
+
+            TXT_AddWidget(bpp_table, button);
+            TXT_SignalConnect(button, "selected", UpdateBPP, modes_table);
+        }
     }
-#endif
 
-    // Screen modes list
-
     TXT_AddWidgets(window,
-                   TXT_NewSeparator("Screen mode"),
-                   bpp_table = TXT_NewTable(2),
+                   modes_separator = TXT_NewSeparator(""),
                    modes_table,
-                   TXT_NewSeparator("Misc."),
                    NULL);
 
-    if (gamemission == heretic || gamemission == hexen)
+    TXT_SignalConnect(fs_checkbox, "changed",
+                      GenerateModesTable, modes_table);
+    TXT_SignalConnect(fs_checkbox, "changed",
+                      UpdateModeSeparator, modes_separator);
+
+    // How many rows high will the configuration window be?
+    // Need to take into account number of fullscreen modes, and also
+    // number of supported pixel depths.
+    // The windowed modes list is four rows, so take the maximum of
+    // windowed and fullscreen.
+
+    num_rows = (num_screen_modes_fullscreen + num_columns - 1) / num_columns;
+
+    if (num_rows < 4)
     {
-        TXT_AddWidget(window,
-                      TXT_NewCheckBox("Graphical startup", &graphical_startup));
+        num_rows = 4;
     }
 
-    if (gamemission == doom || gamemission == heretic
-     || gamemission == strife)
+    if (num_supported_bpps > 1)
     {
-        TXT_AddWidget(window,
-                      TXT_NewCheckBox("Show ENDOOM screen", &show_endoom));
+        num_rows += 2;
     }
 
-    TXT_AddWidgets(bpp_table,
-                   TXT_NewLabel("Color depth: "),
-                   bpp_selector = TXT_NewDropdownList(&selected_bpp,
-                                                      supported_bpps,
-                                                      num_supported_bpps),
-                   NULL);
+    if (num_rows < 14)
+    {
+        window_y = 8 - ((num_rows + 1) / 2);
+    }
+    else
+    {
+        window_y = 1;
+    }
 
+    // The window is set at a fixed vertical position.  This keeps
+    // the top of the window stationary when switching between
+    // fullscreen and windowed mode (which causes the window's
+    // height to change).
 
-    TXT_SignalConnect(bpp_selector, "changed", UpdateBPP, modes_table);
-    TXT_SignalConnect(fs_checkbox, "changed", GenerateModesTable, modes_table);
-    TXT_SignalConnect(ar_checkbox, "changed", GenerateModesTable, modes_table);
+    TXT_SetWindowPosition(window, TXT_HORIZ_CENTER, TXT_VERT_TOP, 
+                                  TXT_SCREEN_W / 2, window_y);
 
     GenerateModesTable(NULL, modes_table);
+    UpdateModeSeparator(NULL, modes_separator);
+
+    // Button to open "advanced" window.
+    // Need to pass a pointer to the modes table, as some of the options
+    // in there trigger a rebuild of it.
+
+    advanced_button = TXT_NewWindowAction('a', "Advanced");
+    TXT_SetWindowAction(window, TXT_HORIZ_CENTER, advanced_button);
+    TXT_SignalConnect(advanced_button, "pressed",
+                      AdvancedDisplayConfig, modes_table);
 }
 
 void BindDisplayVariables(void)
--- a/src/setup/joystick.c
+++ b/src/setup/joystick.c
@@ -27,6 +27,7 @@
 #include "m_controls.h"
 #include "textscreen.h"
 
+#include "execute.h"
 #include "joystick.h"
 #include "mode.h"
 #include "txt_joybinput.h"
@@ -435,6 +436,8 @@
 
     TXT_SignalConnect(joystick_button, "pressed", CalibrateJoystick, NULL);
     TXT_SignalConnect(window, "closed", JoystickWindowClosed, NULL);
+
+    TXT_SetWindowAction(window, TXT_HORIZ_CENTER, TestConfigAction());
 
     SetJoystickButtonLabel();
 }
--- a/src/setup/setup-manifest.xml.in
+++ b/src/setup/setup-manifest.xml.in
@@ -1,16 +1,33 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+
+<!-- Magic manifest file that should make Windows Vista/7 not
+     attempt to gain elevated privileges for chocolate-setup.
+     
+     Based on:
+     
+     http://www.cygwin.com/ml/cygwin/2006-12/msg00580.html
+  -->
+
 <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
   <!-- The "name" field in this tag should be the same as the executable's
        name -->
-  <assemblyIdentity version="@[email protected]" processorArchitecture="*"
-                    name="@PROGRAM_PREFIX@setup" type="win32"/>
+  <assemblyIdentity version="0.0.0.0" processorArchitecture="X86"
+                    name="@[email protected]" type="win32"/>
   <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
     <security>
       <requestedPrivileges>
-        <!-- Hi Vista! We don't require elevated privileges. Thanks! -->
-        <requestedExecutionLevel level="asInvoker"/>
+        <requestedExecutionLevel level="asInvoker" uiAccess="false" />
       </requestedPrivileges>
     </security>
   </trustInfo>
+
+  <!-- Stop the Program Compatibility Assistant appearing: -->
+
+  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
+    <application>
+      <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> <!-- 7 -->
+      <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> <!-- Vista -->
+    </application>
+  </compatibility>
 </assembly>
 
--- /dev/null
+++ b/src/setup/setup.desktop.in
@@ -1,0 +1,7 @@
+[Desktop Entry]
+Name=@PACKAGE_NAME@ Setup
+Exec=@PROGRAM_PREFIX@setup
+Icon=@PROGRAM_PREFIX@setup
+Type=Application
+Comment=Setup tool for @PACKAGE_NAME@
+Categories=Settings;ConsoleOnly;
--- a/src/setup/sound.c
+++ b/src/setup/sound.c
@@ -68,7 +68,7 @@
 
 int snd_sfxdevice = SNDDEVICE_SB;
 int snd_musicdevice = SNDDEVICE_GENMIDI;
-int snd_samplerate = 22050;
+int snd_samplerate = 44100;
 int opl_io_port = 0x388;
 
 static int numChannels = 8;
--- a/src/setup/txt_joybinput.c
+++ b/src/setup/txt_joybinput.c
@@ -48,7 +48,12 @@
     if (event->type == SDL_JOYBUTTONDOWN)
     {
         *joystick_input->variable = event->jbutton.button;
-        TXT_EmitSignal(joystick_input, "set");
+
+        if (joystick_input->check_conflicts)
+        {
+            TXT_EmitSignal(joystick_input, "set");
+        }
+
         TXT_CloseWindow(joystick_input->prompt_window);
         return 1;
     }
@@ -89,6 +94,10 @@
     txt_label_t *label;
     SDL_Joystick *joystick;
 
+    // Silently update when the shift button is held down.
+
+    joystick_input->check_conflicts = !TXT_GetModifierState(TXT_MOD_SHIFT);
+
     if (SDL_Init(SDL_INIT_JOYSTICK) < 0)
     {
         return;
@@ -153,15 +162,7 @@
         GetJoystickButtonDescription(*joystick_input->variable, buf);
     }
 
-    if (selected)
-    {
-        TXT_BGColor(TXT_COLOR_GREY, 0);
-    }
-    else
-    {
-        TXT_BGColor(TXT_COLOR_BLUE, 0);
-    }
-
+    TXT_SetWidgetBG(joystick_input, selected);
     TXT_FGColor(TXT_COLOR_BRIGHT_WHITE);
     
     TXT_DrawString(buf);
--- a/src/setup/txt_joybinput.h
+++ b/src/setup/txt_joybinput.h
@@ -37,6 +37,7 @@
     txt_widget_t widget;
     int *variable;
     txt_window_t *prompt_window;
+    int check_conflicts;
 };
 
 txt_joystick_input_t *TXT_NewJoystickInput(int *variable);
--- a/src/setup/txt_keyinput.c
+++ b/src/setup/txt_keyinput.c
@@ -42,7 +42,12 @@
         // Got the key press.  Save to the variable and close the window.
 
         *key_input->variable = key;
-        TXT_EmitSignal(key_input, "set");
+
+        if (key_input->check_conflicts)
+        {
+            TXT_EmitSignal(key_input, "set");
+        }
+
         TXT_CloseWindow(window);
 
         // Re-enable key mappings now that we have the key
@@ -67,6 +72,10 @@
     txt_window_t *window;
     txt_label_t *label;
 
+    // Silently update when the shift button is held down.
+
+    key_input->check_conflicts = !TXT_GetModifierState(TXT_MOD_SHIFT);
+
     window = TXT_NewWindow(NULL);
     TXT_SetWindowAction(window, TXT_HORIZ_LEFT, NULL);
     TXT_SetWindowAction(window, TXT_HORIZ_CENTER, 
@@ -118,15 +127,7 @@
         TXT_GetKeyDescription(*key_input->variable, buf);
     }
 
-    if (selected)
-    {
-        TXT_BGColor(TXT_COLOR_GREY, 0);
-    }
-    else
-    {
-        TXT_BGColor(TXT_COLOR_BLUE, 0);
-    }
-
+    TXT_SetWidgetBG(key_input, selected);
     TXT_FGColor(TXT_COLOR_BRIGHT_WHITE);
     
     TXT_DrawString(buf);
--- a/src/setup/txt_keyinput.h
+++ b/src/setup/txt_keyinput.h
@@ -35,6 +35,7 @@
 {
     txt_widget_t widget;
     int *variable;
+    int check_conflicts;
 };
 
 txt_key_input_t *TXT_NewKeyInput(int *variable);
--- a/src/setup/txt_mouseinput.c
+++ b/src/setup/txt_mouseinput.c
@@ -42,7 +42,12 @@
     // Got the mouse press.  Save to the variable and close the window.
 
     *mouse_input->variable = b - TXT_MOUSE_BASE;
-    TXT_EmitSignal(mouse_input, "set");
+
+    if (mouse_input->check_conflicts)
+    {
+        TXT_EmitSignal(mouse_input, "set");
+    }
+
     TXT_CloseWindow(window);
 
     return 1;
@@ -53,6 +58,9 @@
     txt_window_t *window;
     txt_label_t *label;
 
+    // Silently update when the shift key is held down.
+    mouse_input->check_conflicts = !TXT_GetModifierState(TXT_MOD_SHIFT);
+
     window = TXT_NewWindow(NULL);
     TXT_SetWindowAction(window, TXT_HORIZ_LEFT, NULL);
     TXT_SetWindowAction(window, TXT_HORIZ_CENTER, 
@@ -111,15 +119,7 @@
         GetMouseButtonDescription(*mouse_input->variable, buf);
     }
 
-    if (selected)
-    {
-        TXT_BGColor(TXT_COLOR_GREY, 0);
-    }
-    else
-    {
-        TXT_BGColor(TXT_COLOR_BLUE, 0);
-    }
-
+    TXT_SetWidgetBG(mouse_input, selected);
     TXT_FGColor(TXT_COLOR_BRIGHT_WHITE);
     
     TXT_DrawString(buf);
--- a/src/setup/txt_mouseinput.h
+++ b/src/setup/txt_mouseinput.h
@@ -35,6 +35,7 @@
 {
     txt_widget_t widget;
     int *variable;
+    int check_conflicts;
 };
 
 txt_mouse_input_t *TXT_NewMouseInput(int *variable);
--- a/textscreen/txt_button.c
+++ b/textscreen/txt_button.c
@@ -46,16 +46,12 @@
 
     w = button->widget.w;
 
-    TXT_BGColor(TXT_COLOR_BLUE, 0);
     TXT_FGColor(TXT_COLOR_BRIGHT_WHITE);
 
-    if (selected)
-    {
-        TXT_BGColor(TXT_COLOR_GREY, 0);
-    }
+    TXT_SetWidgetBG(button, selected);
 
     TXT_DrawString(button->label);
-    
+
     for (i=strlen(button->label); i < w; ++i)
     {
         TXT_DrawString(" ");
--- a/textscreen/txt_checkbox.c
+++ b/textscreen/txt_checkbox.c
@@ -48,7 +48,7 @@
 
     w = checkbox->widget.w;
 
-    TXT_BGColor(TXT_COLOR_BLUE, 0);
+    TXT_BGColor(TXT_WINDOW_BACKGROUND, 0);
     TXT_FGColor(TXT_COLOR_BRIGHT_CYAN);
     TXT_DrawString("(");
 
@@ -67,11 +67,7 @@
 
     TXT_DrawString(") ");
 
-    if (selected)
-    {
-        TXT_BGColor(TXT_COLOR_GREY, 0);
-    }
-
+    TXT_SetWidgetBG(checkbox, selected);
     TXT_FGColor(TXT_COLOR_BRIGHT_WHITE);
 
     TXT_DrawString(checkbox->label);
--- a/textscreen/txt_desktop.c
+++ b/textscreen/txt_desktop.c
@@ -61,6 +61,16 @@
     num_windows = to;
 }
 
+txt_window_t *TXT_GetActiveWindow(void)
+{
+    if (num_windows == 0)
+    {
+        return NULL;
+    }
+
+    return all_windows[num_windows - 1];
+}
+
 static void DrawDesktopBackground(const char *title)
 {
     int i;
--- a/textscreen/txt_desktop.h
+++ b/textscreen/txt_desktop.h
@@ -63,6 +63,15 @@
 
 void TXT_GUIMainLoop(void);
 
+/**
+ * Get the top window on the desktop that is currently receiving
+ * inputs.
+ *
+ * @return    The active window, or NULL if no windows are present.
+ */
+
+txt_window_t *TXT_GetActiveWindow(void);
+
 #endif /* #ifndef TXT_DESKTOP_H */
 
 
--- a/textscreen/txt_dropdown.c
+++ b/textscreen/txt_dropdown.c
@@ -99,6 +99,22 @@
     return 0;
 }
 
+static int SelectorMouseListener(txt_window_t *window, int x, int y, int b,
+                                 void *unused)
+{
+    txt_widget_t *win;
+
+    win = (txt_widget_t *) window;
+
+    if (x < win->x || x > win->x + win->w || y < win->y || y > win->y + win->h)
+    {
+        TXT_CloseWindow(window);
+        return 1;
+    }
+
+    return 0;
+}
+
 // Open the dropdown list window to select an item
 
 static void OpenSelectorWindow(txt_dropdown_list_t *list)
@@ -158,6 +174,7 @@
     // Catch presses of escape in this window and close it.
 
     TXT_SetKeyListener(window, SelectorWindowListener, NULL);
+    TXT_SetMouseListener(window, SelectorMouseListener, NULL);
 }
 
 static int DropdownListWidth(txt_dropdown_list_t *list)
@@ -197,15 +214,7 @@
 
     // Set bg/fg text colors.
 
-    if (selected) 
-    {
-        TXT_BGColor(TXT_COLOR_GREY, 0);
-    }
-    else
-    {
-        TXT_BGColor(TXT_COLOR_BLUE, 0);
-    }
-
+    TXT_SetWidgetBG(list, selected);
     TXT_FGColor(TXT_COLOR_BRIGHT_WHITE);
 
     // Select a string to draw from the list, if the current value is
--- a/textscreen/txt_gui.c
+++ b/textscreen/txt_gui.c
@@ -131,7 +131,7 @@
     int bx, by;
 
     TXT_FGColor(TXT_COLOR_BRIGHT_CYAN);
-    TXT_BGColor(TXT_COLOR_BLUE, 0);
+    TXT_BGColor(TXT_WINDOW_BACKGROUND, 0);
 
     for (y1=y; y1<y+h; ++y1)
     {
@@ -191,7 +191,7 @@
     data = TXT_GetScreenData();
 
     TXT_FGColor(TXT_COLOR_BRIGHT_CYAN);
-    TXT_BGColor(TXT_COLOR_BLUE, 0);
+    TXT_BGColor(TXT_WINDOW_BACKGROUND, 0);
 
     if (!VALID_Y(y))
     {
--- a/textscreen/txt_gui.h
+++ b/textscreen/txt_gui.h
@@ -27,6 +27,9 @@
 #ifndef TXT_GUI_H
 #define TXT_GUI_H
 
+#define TXT_WINDOW_BACKGROUND TXT_COLOR_BLUE
+#define TXT_HOVER_BACKGROUND  TXT_COLOR_CYAN
+
 void TXT_DrawDesktopBackground(const char *title);
 void TXT_DrawWindowFrame(const char *title, int x, int y, int w, int h);
 void TXT_DrawSeparator(int x, int y, int w);
@@ -34,6 +37,7 @@
 
 void TXT_DrawHorizScrollbar(int x, int y, int w, int cursor, int range);
 void TXT_DrawVertScrollbar(int x, int y, int h, int cursor, int range);
+
 
 void TXT_InitClipArea(void);
 void TXT_PushClipArea(int x1, int x2, int y1, int y2);
--- a/textscreen/txt_inputbox.c
+++ b/textscreen/txt_inputbox.c
@@ -60,15 +60,9 @@
     {
         TXT_BGColor(TXT_COLOR_BLACK, 0);
     }
-    else if (selected)
-    {
-        TXT_BGColor(TXT_COLOR_GREY, 0);
-    }
     else
     {
-        // Not even selected
-
-        TXT_BGColor(TXT_COLOR_BLUE, 0);
+        TXT_SetWidgetBG(inputbox, selected);
     }
 
     TXT_FGColor(TXT_COLOR_BRIGHT_WHITE);
--- a/textscreen/txt_label.c
+++ b/textscreen/txt_label.c
@@ -176,7 +176,7 @@
 
     // Default colors
 
-    label->bgcolor = TXT_COLOR_BLUE;
+    label->bgcolor = TXT_WINDOW_BACKGROUND;
     label->fgcolor = TXT_COLOR_BRIGHT_WHITE;
 
     TXT_SetLabel(label, text);
--- a/textscreen/txt_main.h
+++ b/textscreen/txt_main.h
@@ -34,10 +34,12 @@
 
 // Special keypress values that correspond to mouse button clicks
 
-#define TXT_MOUSE_BASE   0x10000
-#define TXT_MOUSE_LEFT   (TXT_MOUSE_BASE + 0)
-#define TXT_MOUSE_RIGHT  (TXT_MOUSE_BASE + 1)
-#define TXT_MOUSE_MIDDLE (TXT_MOUSE_BASE + 2)
+#define TXT_MOUSE_BASE         0x10000
+#define TXT_MOUSE_LEFT         (TXT_MOUSE_BASE + 0)
+#define TXT_MOUSE_RIGHT        (TXT_MOUSE_BASE + 1)
+#define TXT_MOUSE_MIDDLE       (TXT_MOUSE_BASE + 2)
+#define TXT_MOUSE_SCROLLUP     (TXT_MOUSE_BASE + 3)
+#define TXT_MOUSE_SCROLLDOWN   (TXT_MOUSE_BASE + 4)
 #define TXT_MAX_MOUSE_BUTTONS  16
 
 // Screen size
@@ -67,6 +69,16 @@
     TXT_COLOR_BRIGHT_WHITE,
 } txt_color_t;
 
+// Modifier keys.
+
+typedef enum
+{
+    TXT_MOD_SHIFT,
+    TXT_MOD_CTRL,
+    TXT_MOD_ALT,
+    TXT_NUM_MODIFIERS
+} txt_modifier_t;
+
 // Initialize the screen
 // Returns 1 if successful, 0 if failed.
 
@@ -91,6 +103,10 @@
 // Read a character from the keyboard
 
 int TXT_GetChar(void);
+
+// Read the current state of modifier keys that are held down.
+
+int TXT_GetModifierState(txt_modifier_t mod);
 
 // Provides a short description of a key code, placing into the 
 // provided buffer.
--- a/textscreen/txt_radiobutton.c
+++ b/textscreen/txt_radiobutton.c
@@ -48,7 +48,7 @@
 
     w = radiobutton->widget.w;
 
-    TXT_BGColor(TXT_COLOR_BLUE, 0);
+    TXT_BGColor(TXT_WINDOW_BACKGROUND, 0);
     TXT_FGColor(TXT_COLOR_BRIGHT_CYAN);
     TXT_DrawString("(");
 
@@ -67,11 +67,7 @@
 
     TXT_DrawString(") ");
 
-    if (selected)
-    {
-        TXT_BGColor(TXT_COLOR_GREY, 0);
-    }
-
+    TXT_SetWidgetBG(radiobutton, selected);
     TXT_FGColor(TXT_COLOR_BRIGHT_WHITE);
 
     TXT_DrawString(radiobutton->label);
--- a/textscreen/txt_scrollpane.c
+++ b/textscreen/txt_scrollpane.c
@@ -416,6 +416,33 @@
 
     scrollbars = NeedsScrollbars(scrollpane);
 
+    if (b == TXT_MOUSE_SCROLLUP)
+    {
+        if (scrollbars & SCROLLBAR_VERTICAL)
+        {
+            scrollpane->y -= 3;
+        }
+        else if (scrollbars & SCROLLBAR_HORIZONTAL)
+        {
+            scrollpane->x -= 3;
+        }
+
+        return;
+    }
+    else if (b == TXT_MOUSE_SCROLLDOWN)
+    {
+        if (scrollbars & SCROLLBAR_VERTICAL)
+        {
+            scrollpane->y += 3;
+        }
+        else if (scrollbars & SCROLLBAR_HORIZONTAL)
+        {
+            scrollpane->x += 3;
+        }
+
+        return;
+    }
+
     rel_x = x - scrollpane->widget.x;
     rel_y = y - scrollpane->widget.y;
 
@@ -433,14 +460,15 @@
         else
         {
             int range = FullWidth(scrollpane) - scrollpane->w;
+            int bar_max = scrollpane->w - 3;
 
-            scrollpane->x = ((rel_x - 1) * range) / (scrollpane->w - 3);
+            scrollpane->x = ((rel_x - 1) * range + (bar_max / 2)) / bar_max;
         }
 
         return;
     }
 
-    // Click on the horizontal scrollbar?
+    // Click on the vertical scrollbar?
     if ((scrollbars & SCROLLBAR_VERTICAL) && rel_x == scrollpane->w)
     {
         if (rel_y == 0)
@@ -454,8 +482,9 @@
         else
         {
             int range = FullHeight(scrollpane) - scrollpane->h;
+            int bar_max = scrollpane->h - 3;
 
-            scrollpane->y = ((rel_y - 1) * range) / (scrollpane->h - 3);
+            scrollpane->y = ((rel_y - 1) * range + (bar_max / 2)) / bar_max;
         }
 
         return;
@@ -465,7 +494,6 @@
     {
         TXT_WidgetMousePress(scrollpane->child, x, y, b);
     }
-
 }
 
 static void TXT_ScrollPaneLayout(TXT_UNCAST_ARG(scrollpane))
@@ -528,6 +556,10 @@
     scrollpane->child = target;
     scrollpane->expand_w = w <= 0;
     scrollpane->expand_h = h <= 0;
+
+    // Set parent pointer for inner widget.
+
+    target->parent = &scrollpane->widget;
 
     return scrollpane;
 }
--- a/textscreen/txt_sdl.c
+++ b/textscreen/txt_sdl.c
@@ -63,6 +63,8 @@
 static TxtSDLEventCallbackFunc event_callback;
 static void *event_callback_data;
 
+static int modifier_state[TXT_NUM_MODIFIERS];
+
 // Font we are using:
 
 static txt_font_t *font;
@@ -225,7 +227,7 @@
 
     // Ignore all mouse motion events
 
-    SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
+//    SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
 
     // Repeat key presses so we can hold down arrows to scroll down the
     // menu, for example. This is what setup.exe does.
@@ -479,6 +481,66 @@
     }
 }
 
+static int MouseHasMoved(void)
+{
+    static int last_x = 0, last_y = 0;
+    int x, y;
+
+    TXT_GetMousePosition(&x, &y);
+
+    if (x != last_x || y != last_y)
+    {
+        last_x = x; last_y = y;
+        return 1;
+    }
+    else
+    {
+        return 0;
+    }
+}
+
+// Examine a key press/release and update the modifier key state
+// if necessary.
+
+static void UpdateModifierState(SDL_keysym *sym, int pressed)
+{
+    txt_modifier_t mod;
+
+    switch (sym->sym)
+    {
+        case SDLK_LSHIFT:
+        case SDLK_RSHIFT:
+            mod = TXT_MOD_SHIFT;
+            break;
+
+        case SDLK_LCTRL:
+        case SDLK_RCTRL:
+            mod = TXT_MOD_CTRL;
+            break;
+
+        case SDLK_LALT:
+        case SDLK_RALT:
+#if !SDL_VERSION_ATLEAST(1, 3, 0)
+        case SDLK_LMETA:
+        case SDLK_RMETA:
+#endif
+            mod = TXT_MOD_ALT;
+            break;
+
+        default:
+            return;
+    }
+
+    if (pressed)
+    {
+        ++modifier_state[mod];
+    }
+    else
+    {
+        --modifier_state[mod];
+    }
+}
+
 signed int TXT_GetChar(void)
 {
     SDL_Event ev;
@@ -508,12 +570,24 @@
                 break;
 
             case SDL_KEYDOWN:
+                UpdateModifierState(&ev.key.keysym, 1);
+
                 return TranslateKey(&ev.key.keysym);
 
+            case SDL_KEYUP:
+                UpdateModifierState(&ev.key.keysym, 0);
+                break;
+
             case SDL_QUIT:
                 // Quit = escape
                 return 27;
 
+            case SDL_MOUSEMOTION:
+                if (MouseHasMoved())
+                {
+                    return 0;
+                }
+
             default:
                 break;
         }
@@ -520,6 +594,16 @@
     }
 
     return -1;
+}
+
+int TXT_GetModifierState(txt_modifier_t mod)
+{
+    if (mod < TXT_NUM_MODIFIERS)
+    {
+        return modifier_state[mod] > 0;
+    }
+
+    return 0;
 }
 
 static const char *SpecialKeyName(int key)
--- a/textscreen/txt_separator.c
+++ b/textscreen/txt_separator.c
@@ -65,7 +65,7 @@
     {
         TXT_GotoXY(x, y);
 
-        TXT_BGColor(TXT_COLOR_BLUE, 0);
+        TXT_BGColor(TXT_WINDOW_BACKGROUND, 0);
         TXT_FGColor(TXT_COLOR_BRIGHT_GREEN);
         TXT_DrawString(" ");
         TXT_DrawString(separator->label);
@@ -80,6 +80,20 @@
     free(separator->label);
 }
 
+void TXT_SetSeparatorLabel(txt_separator_t *separator, char *label)
+{
+    free(separator->label);
+
+    if (label != NULL)
+    {
+        separator->label = strdup(label);
+    }
+    else
+    {
+        separator->label = NULL;
+    }
+}
+
 txt_widget_class_t txt_separator_class =
 {
     TXT_NeverSelectable,
@@ -99,14 +113,8 @@
 
     TXT_InitWidget(separator, &txt_separator_class);
 
-    if (label != NULL)
-    {
-        separator->label = strdup(label);
-    }
-    else
-    {
-        separator->label = NULL;
-    }
+    separator->label = NULL;
+    TXT_SetSeparatorLabel(separator, label);
 
     return separator;
 }
--- a/textscreen/txt_separator.h
+++ b/textscreen/txt_separator.h
@@ -59,6 +59,14 @@
 
 txt_separator_t *TXT_NewSeparator(char *label);
 
-#endif /* #ifndef TXT_SEPARATOR_H */
+/**
+ * Change the label on a separator.
+ *
+ * @param separator     The separator.
+ * @param label         The new label.
+ */
 
+void TXT_SetSeparatorLabel(txt_separator_t *separator, char *label);
+
+#endif /* #ifndef TXT_SEPARATOR_H */
 
--- a/textscreen/txt_spinctrl.c
+++ b/textscreen/txt_spinctrl.c
@@ -149,7 +149,7 @@
     unsigned int padding;
 
     TXT_FGColor(TXT_COLOR_BRIGHT_CYAN);
-    TXT_BGColor(TXT_COLOR_BLUE, 0);
+    TXT_BGColor(TXT_WINDOW_BACKGROUND, 0);
 
     TXT_DrawString("\x1b ");
     
@@ -161,13 +161,9 @@
     {
         TXT_BGColor(TXT_COLOR_BLACK, 0);
     }
-    else if (selected)
-    {
-        TXT_BGColor(TXT_COLOR_GREY, 0);
-    }
     else
     {
-        TXT_BGColor(TXT_COLOR_BLUE, 0);
+        TXT_SetWidgetBG(spincontrol, selected);
     }
 
     if (!spincontrol->editing)
@@ -195,7 +191,7 @@
     }
 
     TXT_FGColor(TXT_COLOR_BRIGHT_CYAN);
-    TXT_BGColor(TXT_COLOR_BLUE, 0);
+    TXT_BGColor(TXT_WINDOW_BACKGROUND, 0);
     TXT_DrawString(" \x1a");
 }
 
--- a/textscreen/txt_table.c
+++ b/textscreen/txt_table.c
@@ -173,6 +173,13 @@
                              sizeof(txt_widget_t *) * (table->num_widgets + 1));
     table->widgets[table->num_widgets] = widget;
     ++table->num_widgets;
+
+    // Maintain parent pointer.
+
+    if (widget != NULL)
+    {
+        widget->parent = &table->widget;
+    }
 }
 
 // Add multiple widgets to a table.
--- a/textscreen/txt_widget.c
+++ b/textscreen/txt_widget.c
@@ -24,6 +24,8 @@
 
 #include "txt_io.h"
 #include "txt_widget.h"
+#include "txt_gui.h"
+#include "txt_desktop.h"
 
 typedef struct
 {
@@ -82,6 +84,7 @@
 
     widget->widget_class = widget_class;
     widget->callback_table = TXT_NewCallbackTable();
+    widget->parent = NULL;
 
     // Visible by default.
 
@@ -234,6 +237,65 @@
     else
     {
         return 0;
+    }
+}
+
+int TXT_ContainsWidget(TXT_UNCAST_ARG(haystack), TXT_UNCAST_ARG(needle))
+{
+    TXT_CAST_ARG(txt_widget_t, haystack);
+    TXT_CAST_ARG(txt_widget_t, needle);
+
+    while (needle != NULL)
+    {
+        if (needle == haystack)
+        {
+            return 1;
+        }
+
+        needle = needle->parent;
+    }
+
+    return 0;
+}
+
+int TXT_HoveringOverWidget(TXT_UNCAST_ARG(widget))
+{
+    TXT_CAST_ARG(txt_widget_t, widget);
+    txt_window_t *active_window;
+    int x, y;
+
+    // We can only be hovering over widgets in the active window.
+
+    active_window = TXT_GetActiveWindow();
+
+    if (active_window == NULL || !TXT_ContainsWidget(active_window, widget))
+    {
+        return 0;
+    }
+
+    // Is the mouse cursor within the bounds of the widget?
+
+    TXT_GetMousePosition(&x, &y);
+
+    return (x >= widget->x && x < widget->x + widget->w
+         && y >= widget->y && y < widget->y + widget->h);
+}
+
+void TXT_SetWidgetBG(TXT_UNCAST_ARG(widget), int selected)
+{
+    TXT_CAST_ARG(txt_widget_t, widget);
+
+    if (selected)
+    {
+        TXT_BGColor(TXT_COLOR_GREY, 0);
+    }
+    else if (TXT_HoveringOverWidget(widget))
+    {
+        TXT_BGColor(TXT_HOVER_BACKGROUND, 0);
+    }
+    else
+    {
+        TXT_BGColor(TXT_WINDOW_BACKGROUND, 0);
     }
 }
 
--- a/textscreen/txt_widget.h
+++ b/textscreen/txt_widget.h
@@ -102,6 +102,10 @@
 
     int x, y;
     unsigned int w, h;
+
+    // Pointer up to parent widget that contains this widget.
+
+    txt_widget_t *parent;
 };
 
 void TXT_InitWidget(TXT_UNCAST_ARG(widget), txt_widget_class_t *widget_class);
@@ -146,6 +150,34 @@
 
 int TXT_SelectableWidget(TXT_UNCAST_ARG(widget));
 
-#endif /* #ifndef TXT_WIDGET_H */
+/**
+ * Query whether the mouse is hovering over the specified widget.
+ *
+ * @param widget       The widget.
+ * @return             Non-zero if the mouse cursor is over the widget.
+ */
 
+int TXT_HoveringOverWidget(TXT_UNCAST_ARG(widget));
+
+/**
+ * Set the background to draw the specified widget, depending on
+ * whether it is selected and the mouse is hovering over it.
+ *
+ * @param widget       The widget.
+ * @param selected     Whether the widget is selected.
+ */
+
+void TXT_SetWidgetBG(TXT_UNCAST_ARG(widget), int selected);
+
+/**
+ * Query whether the specified widget is contained within another
+ * widget.
+ *
+ * @param haystack     The widget that might contain needle.
+ * @param needle       The widget being queried.
+ */
+
+int TXT_ContainsWidget(TXT_UNCAST_ARG(haystack), TXT_UNCAST_ARG(needle));
+
+#endif /* #ifndef TXT_WIDGET_H */
 
--- a/textscreen/txt_window.c
+++ b/textscreen/txt_window.c
@@ -40,6 +40,13 @@
     }
 
     window->actions[position] = action;
+
+    // Maintain parent pointer.
+
+    if (action != NULL)
+    {
+        action->widget.parent = &window->table.widget;
+    }
 }
 
 txt_window_t *TXT_NewWindow(char *title)
@@ -158,7 +165,7 @@
 
         TXT_CalcWidgetSize(widget);
 
-        widget->x = window->window_x + 2;
+        widget->x = window->window_x + 1;
         widget->y = window->window_y + window->window_h - widget->h - 1;
 
         // Adjust available space:
@@ -175,7 +182,7 @@
 
         TXT_CalcWidgetSize(widget);
 
-        widget->x = window->window_x + window->window_w - 2 - widget->w;
+        widget->x = window->window_x + window->window_w - 1 - widget->w;
         widget->y = window->window_y + window->window_h - widget->h - 1;
 
         // Adjust available space:
@@ -220,7 +227,7 @@
     txt_widget_t *widget;
     int i;
 
-    *w = 1;
+    *w = 0;
     *h = 0;
 
     // Calculate the width of all the action widgets and use this
@@ -233,7 +240,7 @@
         if (widget != NULL)
         {
             TXT_CalcWidgetSize(widget);
-            *w += widget->w + 1;
+            *w += widget->w;
 
             if (widget->h > *h)
             {
--- a/textscreen/txt_window_action.c
+++ b/textscreen/txt_window_action.c
@@ -37,9 +37,10 @@
 
     TXT_GetKeyDescription(action->key, buf);
 
-    // Minimum width is the string length + two spaces for padding
+    // Width is label length, plus key description length, plus '='
+    // and two surrounding spaces.
 
-    action->widget.w = strlen(action->label) + strlen(buf) + 1;
+    action->widget.w = strlen(action->label) + strlen(buf) + 3;
     action->widget.h = 1;
 }
 
@@ -50,12 +51,24 @@
 
     TXT_GetKeyDescription(action->key, buf);
 
+    if (TXT_HoveringOverWidget(action))
+    {
+        TXT_BGColor(TXT_COLOR_BLACK, 0);
+    }
+    else
+    {
+        TXT_BGColor(TXT_WINDOW_BACKGROUND, 0);
+    }
+
+    TXT_DrawString(" ");
     TXT_FGColor(TXT_COLOR_BRIGHT_GREEN);
     TXT_DrawString(buf);
     TXT_FGColor(TXT_COLOR_BRIGHT_CYAN);
     TXT_DrawString("=");
+
     TXT_FGColor(TXT_COLOR_BRIGHT_WHITE);
     TXT_DrawString(action->label);
+    TXT_DrawString(" ");
 }
 
 static void TXT_WindowActionDestructor(TXT_UNCAST_ARG(action))
@@ -69,7 +82,7 @@
 {
     TXT_CAST_ARG(txt_window_action_t, action);
 
-    if (key == action->key)
+    if (tolower(key) == tolower(action->key))
     {
         TXT_EmitSignal(action, "pressed");
         return 1;