foxygit / doom Log in
commit 122dcc372f579c54ba2e6f793493cfa4d0a7d609
Merge: 46ad00de b6491fa4
Author:     Simon Howard <fraggle@gmail.com>
AuthorDate: Tue Jun 9 18:28:51 2009 +0000
Commit:     Simon Howard <fraggle@gmail.com>
CommitDate: Tue Jun 9 18:28:51 2009 +0000

    Merge from trunk.

    Subversion-branch: /branches/raven-branch
    Subversion-revision: 1579

 .lvimrc                 |  25 +++++
 Makefile.am             |   2 +-
 configure.in            |  15 +++
 pcsound/pcsound.c       |   1 +
 pcsound/pcsound_win32.c |   1 +
 src/Makefile.am         |   1 +
 src/d_iwad.c            |  11 +-
 src/doom/am_map.c       | 210 ++++++++++++++++++++------------------
 src/doom/d_main.c       |   3 +-
 src/doom/deh_ammo.c     |   1 +
 src/doom/g_game.c       |  33 +++++-
 src/doom/m_menu.c       | 234 +++++++++++++++++++++++++++---------------
 src/doomtype.h          |   7 ++
 src/i_main.c            |  19 +++-
 src/i_system.c          |  12 ++-
 src/i_video.c           | 198 ++++++++++++++++++++---------------
 src/m_config.c          | 266 +++++++++++++++++++++++++++++++++++++++++++++++-
 src/setup/display.c     |  15 ++-
 src/setup/execute.c     |  27 ++++-
 src/setup/keyboard.c    | 223 +++++++++++++++++++++++++++++++++++++---
 src/setup/keyboard.h    |  53 ++++++++++
 src/setup/mainmenu.c    |   5 +
 src/w_file_win32.c      |  18 +++-
 textscreen/Makefile.am  |   2 +
 textscreen/txt_sdl.c    |   8 +-
 wince/Makefile.am       |  16 +++
 wince/README            |   8 ++
 wince/env.c             |  65 ++++++++++++
 wince/env.h             |  17 ++++
 wince/errno.c           |  20 ++++
 wince/errno.h           |  17 ++++
 wince/fileops.c         |  49 +++++++++
 wince/fileops.h         |  14 +++
 wince/libc_wince.h      |   4 +
 34 files changed, 1293 insertions(+), 307 deletions(-)

diff --cc Makefile.am
index 92939fbf,e4b7c825..cb3c4a89
--- a/Makefile.am
+++ b/Makefile.am
@@@ -52,7 -44,7 +52,7 @@@ EXTRA_DIST
  MAINTAINERCLEANFILES =  $(AUX_DIST_GEN)

  docdir=$(prefix)/share/doc/@PACKAGE@
- SUBDIRS=textscreen pcsound src man
 -SUBDIRS=wince textscreen pcsound src man setup
++SUBDIRS=wince textscreen pcsound src man

  if HAVE_PYTHON

diff --cc configure.in
index 0de7622a,5a1dfab2..42400e09
--- a/configure.in
+++ b/configure.in
@@@ -89,18 -100,15 +103,19 @@@ AC_DEFUN([AC_DATAROOTDIR_CHECKED]

  AC_OUTPUT([
  Makefile
+ wince/Makefile
  textscreen/Makefile
  textscreen/examples/Makefile
 -setup/Makefile
  man/Makefile
  src/Makefile
 +src/doom/Makefile
 +src/heretic/Makefile
 +src/hexen/Makefile
 +src/setup/Makefile
  pcsound/Makefile
  src/resource.rc
 +src/setup-res.rc
 +src/setup/setup-manifest.xml
  src/doom-screensaver.desktop
 -setup/setup-res.rc
  ])

diff --cc src/Makefile.am
index 10f9c2c5,64e23b79..e51f6727
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@@ -114,14 -162,7 +114,15 @@@ SOURCE_FILES = $(COMMON_SOURCE_FILES
                 $(FEATURE_WAD_MERGE_SOURCE_FILES)   \
                 $(FEATURE_SOUND_SOURCE_FILES)

 +EXTRA_LIBS =                                       \
++               ../wince/libc_wince.a               \
 +	       ../textscreen/libtextscreen.a       \
 +	       ../pcsound/libpcsound.a             \
 +	       @LDFLAGS@                           \
 +	       @SDL_LIBS@                          \
 +	       @SDLMIXER_LIBS@                     \
 +	       @SDLNET_LIBS@
 +
  if HAVE_WINDRES
  chocolate_doom_SOURCES=$(SOURCE_FILES) resource.rc
  else
diff --cc src/doom/am_map.c
index 115a1878,9a81d62c..37ccf5b3
--- a/src/doom/am_map.c
+++ b/src/doom/am_map.c
@@@ -89,20 -88,20 +89,19 @@@
  #define XHAIRCOLORS	GRAYS

  // drawing stuff
 -#define	FB		0

- #define AM_PANDOWNKEY	KEY_DOWNARROW
- #define AM_PANUPKEY	KEY_UPARROW
- #define AM_PANRIGHTKEY	KEY_RIGHTARROW
- #define AM_PANLEFTKEY	KEY_LEFTARROW
- #define AM_ZOOMINKEY	'='
- #define AM_ZOOMOUTKEY	'-'
- #define AM_STARTKEY	KEY_TAB
- #define AM_ENDKEY	KEY_TAB
- #define AM_GOBIGKEY	'0'
- #define AM_FOLLOWKEY	'f'
- #define AM_GRIDKEY	'g'
- #define AM_MARKKEY	'm'
- #define AM_CLEARMARKKEY	'c'
+ int key_map_north     = KEY_UPARROW;
+ int key_map_south     = KEY_DOWNARROW;
+ int key_map_east      = KEY_RIGHTARROW;
+ int key_map_west      = KEY_LEFTARROW;
+ int key_map_zoomin    = '=';
+ int key_map_zoomout   = '-';
+ int key_map_toggle    = KEY_TAB;
+ int key_map_maxzoom   = '0';
+ int key_map_follow    = 'f';
+ int key_map_grid      = 'g';
+ int key_map_mark      = 'm';
+ int key_map_clearmark = 'c';

  #define AM_NUMMARKPOINTS 10

diff --cc src/doom/g_game.c
index c430a870,cd070884..a2b08739
--- a/src/doom/g_game.c
+++ b/src/doom/g_game.c
@@@ -157,6 -158,60 +157,15 @@@ wbstartstruct_t wminfo;

  byte		consistancy[MAXPLAYERS][BACKUPTICS];

 -
 -//
 -// Controls
 -//
 -int             key_right = KEY_RIGHTARROW;
 -int		key_left = KEY_LEFTARROW;
 -
 -int		key_up = KEY_UPARROW;
 -int		key_down = KEY_DOWNARROW;
 -int             key_strafeleft = ',';
 -int		key_straferight = '.';
 -int             key_fire = KEY_RCTRL;
 -int		key_use = ' ';
 -int		key_strafe = KEY_RALT;
 -int		key_speed = KEY_RSHIFT;
 -
+ int             key_weapon1 = '1';
+ int             key_weapon2 = '2';
+ int             key_weapon3 = '3';
+ int             key_weapon4 = '4';
+ int             key_weapon5 = '5';
+ int             key_weapon6 = '6';
+ int             key_weapon7 = '7';
+ int             key_weapon8 = '8';
+
 -int             mousebfire = 0;
 -int             mousebstrafe = 1;
 -int             mousebforward = 2;
 -
 -int             mousebstrafeleft = -1;
 -int             mousebstraferight = -1;
 -int             mousebbackward = -1;
 -int             mousebuse = -1;
 -
 -// Control whether if a mouse button is double clicked, it acts like
 -// "use" has been pressed
 -
 -int             dclick_use = 1;
 -
 -int             joybfire = 0;
 -int             joybstrafe = 1;
 -int             joybuse = 3;
 -int             joybspeed = 2;
 -int             joybstrafeleft = -1;
 -int             joybstraferight = -1;
 -
 -// fraggle: Disallow mouse and joystick movement to cause forward/backward
 -// motion.  Specified with the '-novert' command line parameter.
 -// This is an int to allow saving to config file
 -
 -int             novert = 0;
 -
 -
 -
  #define MAXPLMOVE		(forwardmove[1])

  #define TURBOTHRESHOLD	0x32
diff --cc src/doom/m_menu.c
index 4ca30926,1ced1d16..af3d1ae2
--- a/src/doom/m_menu.c
+++ b/src/doom/m_menu.c
@@@ -932,12 -950,12 +961,12 @@@ int     epi

  void M_DrawEpisode(void)
  {
 -    V_DrawPatchDirect (54,38,0,W_CacheLumpName(DEH_String("M_EPISOD"),PU_CACHE));
 +    V_DrawPatchDirect(54, 38, W_CacheLumpName(DEH_String("M_EPISOD"), PU_CACHE));
  }

- void M_VerifyNightmare(int ch)
+ void M_VerifyNightmare(int key)
  {
-     if (ch != 'y')
+     if (key != key_menu_confirm)
  	return;

      G_DeferedInitNew(nightmare,epi+1,1);
diff --cc src/doomtype.h
index 0adc5fab,0a5b5e38..b79bd687
--- a/src/doomtype.h
+++ b/src/doomtype.h
@@@ -29,39 -29,13 +29,46 @@@
  #ifndef __DOOMTYPE__
  #define __DOOMTYPE__

 +// #define macros to provide functions missing in Windows.
 +// Outside Windows, we use strings.h for str[n]casecmp.
 +
 +
 +#ifdef _WIN32
 +
 +#define snprintf _snprintf
 +#define vsnprintf _vsnprintf
 +#define strcasecmp stricmp
 +#define strncasecmp strnicmp
 +
 +#else
 +
 +#include <strings.h>
 +
 +#endif
 +
 +
 +//
 +// The packed attribute forces structures to be packed into the minimum
 +// space necessary.  If this is not done, the compiler may align structure
 +// fields differently to optimise memory access, inflating the overall
 +// structure size.  It is important to use the packed attribute on certain
 +// structures where alignment is important, particularly data read/written
 +// to disk.
 +//
 +
 +#ifdef __GNUC__
 +#define PACKEDATTR __attribute__((packed))
 +#else
 +#define PACKEDATTR
 +#endif
 +
+ // Windows CE is missing some vital ANSI C functions.  We have to
+ // use our own replacements.
+
+ #ifdef _WIN32_WCE
+ #include "libc_wince.h"
+ #endif
+
  // C99 integer types; with gcc we just use this.  Other compilers
  // should add conditional statements that define the C99 types.

diff --cc src/i_main.c
index c1a9cb98,03f8a5ac..a17d56b9
--- a/src/i_main.c
+++ b/src/i_main.c
@@@ -28,19 -29,20 +28,27 @@@

  #include "SDL.h"

 -#include "doomdef.h"
 +#include "doomtype.h"
  #include "i_system.h"
  #include "m_argv.h"
 -#include "d_main.h"
 +
 +//
 +// D_DoomMain()
 +// Not a globally visible function, just included for source reference,
 +// calls all startup code, parses command line options.
 +//
 +
 +void D_DoomMain (void);

- #if defined(_WIN32)
+ #if defined(_WIN32_WCE)
+
+ // Windows CE?  I doubt it even supports SMP..
+
+ static void LockCPUAffinity(void)
+ {
+ }
+
+ #elif defined(_WIN32)

  #define WIN32_LEAN_AND_MEAN
  #include <windows.h>
diff --cc src/m_config.c
index a746e151,5bc46ca3..25e59917
--- a/src/m_config.c
+++ b/src/m_config.c
@@@ -710,8 -745,10 +710,10 @@@ static default_t extra_defaults_list[]
      // the "use" key to use an object in-game, eg. a door or switch.
      //

 -    CONFIG_VARIABLE_INT(dclick_use,                dclick_use),
 +    CONFIG_VARIABLE_INT(dclick_use),

+ #ifdef FEATURE_SOUND
+
      //!
      // Controls whether libsamplerate support is used for performing
      // sample rate conversions of sound effects.  Support for this
@@@ -725,7 -762,261 +727,261 @@@
      // Sinc filter = 4; High quality Sinc filter = 5.
      //

 -    CONFIG_VARIABLE_INT(use_libsamplerate,         use_libsamplerate),
 +    CONFIG_VARIABLE_INT(use_libsamplerate),
+
+ #endif
+
+     //!
+     // Key that activates the menu when pressed.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_menu_activate,         key_menu_activate),
++    CONFIG_VARIABLE_KEY(key_menu_activate),
+
+     //!
+     // Key that moves the cursor up on the menu.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_menu_up,               key_menu_up),
++    CONFIG_VARIABLE_KEY(key_menu_up),
+
+     //!
+     // Key that moves the cursor down on the menu.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_menu_down,             key_menu_down),
++    CONFIG_VARIABLE_KEY(key_menu_down),
+
+     //!
+     // Key that moves the currently selected slider on the menu left.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_menu_left,             key_menu_left),
++    CONFIG_VARIABLE_KEY(key_menu_left),
+
+     //!
+     // Key that moves the currently selected slider on the menu right.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_menu_right,            key_menu_right),
++    CONFIG_VARIABLE_KEY(key_menu_right),
+
+     //!
+     // Key to go back to the previous menu.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_menu_back,             key_menu_back),
++    CONFIG_VARIABLE_KEY(key_menu_back),
+
+     //!
+     // Key to activate the currently selected menu item.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_menu_forward,          key_menu_forward),
++    CONFIG_VARIABLE_KEY(key_menu_forward),
+
+     //!
+     // Key to answer 'yes' to a question in the menu.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_menu_confirm,          key_menu_confirm),
++    CONFIG_VARIABLE_KEY(key_menu_confirm),
+
+     //!
+     // Key to answer 'no' to a question in the menu.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_menu_abort,            key_menu_abort),
++    CONFIG_VARIABLE_KEY(key_menu_abort),
+
+     //!
+     // Keyboard shortcut to bring up the help screen.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_menu_help,             key_menu_help),
++    CONFIG_VARIABLE_KEY(key_menu_help),
+
+     //!
+     // Keyboard shortcut to bring up the save game menu.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_menu_save,             key_menu_save),
++    CONFIG_VARIABLE_KEY(key_menu_save),
+
+     //!
+     // Keyboard shortcut to bring up the load game menu.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_menu_load,             key_menu_load),
++    CONFIG_VARIABLE_KEY(key_menu_load),
+
+     //!
+     // Keyboard shortcut to bring up the sound volume menu.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_menu_volume,           key_menu_volume),
++    CONFIG_VARIABLE_KEY(key_menu_volume),
+
+     //!
+     // Keyboard shortcut to toggle the detail level.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_menu_detail,           key_menu_detail),
++    CONFIG_VARIABLE_KEY(key_menu_detail),
+
+     //!
+     // Keyboard shortcut to quicksave the current game.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_menu_qsave,            key_menu_qsave),
++    CONFIG_VARIABLE_KEY(key_menu_qsave),
+
+     //!
+     // Keyboard shortcut to end the game.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_menu_endgame,          key_menu_endgame),
++    CONFIG_VARIABLE_KEY(key_menu_endgame),
+
+     //!
+     // Keyboard shortcut to toggle heads-up messages.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_menu_messages,         key_menu_messages),
++    CONFIG_VARIABLE_KEY(key_menu_messages),
+
+     //!
+     // Keyboard shortcut to load the last quicksave.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_menu_qload,            key_menu_qload),
++    CONFIG_VARIABLE_KEY(key_menu_qload),
+
+     //!
+     // Keyboard shortcut to quit the game.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_menu_quit,             key_menu_quit),
++    CONFIG_VARIABLE_KEY(key_menu_quit),
+
+     //!
+     // Keyboard shortcut to toggle the gamma correction level.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_menu_gamma,            key_menu_gamma),
++    CONFIG_VARIABLE_KEY(key_menu_gamma),
+
+     //!
+     // Keyboard shortcut to increase the screen size.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_menu_incscreen,        key_menu_incscreen),
++    CONFIG_VARIABLE_KEY(key_menu_incscreen),
+
+     //!
+     // Keyboard shortcut to decrease the screen size.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_menu_decscreen,        key_menu_decscreen),
++    CONFIG_VARIABLE_KEY(key_menu_decscreen),
+
+     //!
+     // Key to toggle the map view.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_map_toggle,            key_map_toggle),
++    CONFIG_VARIABLE_KEY(key_map_toggle),
+
+     //!
+     // Key to pan north when in the map view.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_map_north,             key_map_north),
++    CONFIG_VARIABLE_KEY(key_map_north),
+
+     //!
+     // Key to pan south when in the map view.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_map_south,             key_map_south),
++    CONFIG_VARIABLE_KEY(key_map_south),
+
+     //!
+     // Key to pan east when in the map view.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_map_east,              key_map_east),
++    CONFIG_VARIABLE_KEY(key_map_east),
+
+     //!
+     // Key to pan west when in the map view.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_map_west,              key_map_west),
++    CONFIG_VARIABLE_KEY(key_map_west),
+
+     //!
+     // Key to zoom in when in the map view.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_map_zoomin,            key_map_zoomin),
++    CONFIG_VARIABLE_KEY(key_map_zoomin),
+
+     //!
+     // Key to zoom out when in the map view.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_map_zoomout,           key_map_zoomout),
++    CONFIG_VARIABLE_KEY(key_map_zoomout),
+
+     //!
+     // Key to zoom out the maximum amount when in the map view.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_map_maxzoom,           key_map_maxzoom),
++    CONFIG_VARIABLE_KEY(key_map_maxzoom),
+
+     //!
+     // Key to toggle follow mode when in the map view.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_map_follow,            key_map_follow),
++    CONFIG_VARIABLE_KEY(key_map_follow),
+
+     //!
+     // Key to toggle the grid display when in the map view.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_map_grid,              key_map_grid),
++    CONFIG_VARIABLE_KEY(key_map_grid),
+
+     //!
+     // Key to set a mark when in the map view.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_map_mark,              key_map_mark),
++    CONFIG_VARIABLE_KEY(key_map_mark),
+
+     //!
+     // Key to clear all marks when in the map view.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_map_clearmark,         key_map_clearmark),
++    CONFIG_VARIABLE_KEY(key_map_clearmark),
+
+     //!
+     // Key to select weapon 1.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_weapon1,               key_weapon1),
++    CONFIG_VARIABLE_KEY(key_weapon1),
+
+     //!
+     // Key to select weapon 2.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_weapon2,               key_weapon2),
++    CONFIG_VARIABLE_KEY(key_weapon2),
+
+     //!
+     // Key to select weapon 3.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_weapon3,               key_weapon3),
++    CONFIG_VARIABLE_KEY(key_weapon3),
+
+     //!
+     // Key to select weapon 4.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_weapon4,               key_weapon4),
++    CONFIG_VARIABLE_KEY(key_weapon4),
+
+     //!
+     // Key to select weapon 5.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_weapon5,               key_weapon5),
++    CONFIG_VARIABLE_KEY(key_weapon5),
+
+     //!
+     // Key to select weapon 6.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_weapon6,               key_weapon6),
++    CONFIG_VARIABLE_KEY(key_weapon6),
+
+     //!
+     // Key to select weapon 7.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_weapon7,               key_weapon7),
++    CONFIG_VARIABLE_KEY(key_weapon7),
+
+     //!
+     // Key to select weapon 8.
+     //
+
 -    CONFIG_VARIABLE_KEY(key_weapon8,               key_weapon8),
++    CONFIG_VARIABLE_KEY(key_weapon8),
  };

  static default_collection_t extra_defaults =
@@@ -1065,56 -1304,22 +1321,58 @@@ void M_LoadDefaults (void
      LoadDefaultCollection(&extra_defaults);
  }

 -//
 -// SetConfigDir:
 +// Get a configuration file variable by its name
 +
 +static default_t *GetDefaultForName(char *name)
 +{
 +    default_t *result;
 +
 +    // Try the main list and the extras
 +
 +    result = SearchCollection(&doom_defaults, name);
 +
 +    if (result == NULL)
 +    {
 +        result = SearchCollection(&extra_defaults, name);
 +    }
 +
 +    // Not found? Internal error.
 +
 +    if (result == NULL)
 +    {
 +        I_Error("Unknown configuration variable: '%s'", name);
 +    }
 +
 +    return result;
 +}
 +
  //
 -// Sets the location of the configuration directory, where configuration
 -// files are stored - default.cfg, chocolate-doom.cfg, savegames, etc.
 +// Bind a variable to a given configuration file variable, by name.
  //

 -void M_SetConfigDir(void)
 +void M_BindVariable(char *name, void *location)
 +{
 +    default_t *variable;
 +
 +    variable = GetDefaultForName(name);
 +
 +    variable->location = location;
 +    variable->bound = true;
 +}
 +
 +// Get the path to the default configuration dir to use, if NULL
 +// is passed to M_SetConfigDir.
 +
 +static char *GetDefaultConfigDir(void)
  {
- #ifndef _WIN32
-     // On Unix systems we put configuration into ~/.chocolate-doom, but
-     // on Windows we just use the current directory, like Vanilla.
+ #if !defined(_WIN32) || defined(_WIN32_WCE)
+
+     // Configuration settings are stored in ~/.chocolate-doom/,
+     // except on Windows, where we behave like Vanilla Doom and
+     // save in the current directory.

      char *homedir;
 +    char *result;

      homedir = getenv("HOME");

@@@ -1133,36 -1340,27 +1391,34 @@@
      else
  #endif /* #ifndef _WIN32 */
      {
-         // On Windows, we just use the current directory.
 -#if defined(_WIN32) && !defined(_WIN32_WCE)
 -        //!
 -        // @platform windows
 -        // @vanilla
 -        //
 -        // Save configuration data and savegames in c:\doomdata,
 -        // allowing play from CD.
 -        //
--
 -        if (M_CheckParm("-cdrom") > 0)
 -        {
 -            printf(D_CDROM);
 -            configdir = strdup("c:\\doomdata\\");
 +        return strdup("");
 +    }
 +}

 -            M_MakeDirectory(configdir);
 -        }
 -        else
 -#endif
 -        {
 -            configdir = strdup("");
 -        }
 +//
 +// SetConfigDir:
 +//
 +// Sets the location of the configuration directory, where configuration
 +// files are stored - default.cfg, chocolate-doom.cfg, savegames, etc.
 +//
 +
 +void M_SetConfigDir(char *dir)
 +{
 +    // Use the directory that was passed, or find the default.
 +
 +    if (dir != NULL)
 +    {
 +        configdir = dir;
      }
 +    else
 +    {
 +        configdir = GetDefaultConfigDir();
 +    }
 +
 +    printf("Using %s for configuration and saves\n", configdir);
 +
 +    // Make the directory if it doesn't already exist:
 +
 +    M_MakeDirectory(configdir);
  }

diff --cc src/setup/keyboard.c
index 22fc8a02,27ade663..e6d0143d
--- a/src/setup/keyboard.c
+++ b/src/setup/keyboard.c
@@@ -18,10 -18,9 +18,11 @@@
  // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  // 02111-1307, USA.
  //
+
  #include "textscreen.h"
  #include "doomtype.h"
 +#include "m_config.h"
 +#include "m_controls.h"

  #include "execute.h"
  #include "txt_keyinput.h"
@@@ -30,18 -28,94 +31,87 @@@
  #include "joystick.h"
  #include "keyboard.h"

 -int key_left = KEY_LEFTARROW;
 -int key_right = KEY_RIGHTARROW;
 -int key_up = KEY_UPARROW;
 -int key_down = KEY_DOWNARROW;
 -int key_strafeleft = ',';
 -int key_straferight = '.';
 -int key_fire = KEY_RCTRL;
 -int key_use = ' ';
 -int key_strafe = KEY_RALT;
 -int key_speed = KEY_RSHIFT;
 +static int vanilla_keyboard_mapping = 1;

+ // Menu keys:
+
+ int key_menu_activate  = KEY_ESCAPE;
+ int key_menu_up        = KEY_UPARROW;
+ int key_menu_down      = KEY_DOWNARROW;
+ int key_menu_left      = KEY_LEFTARROW;
+ int key_menu_right     = KEY_RIGHTARROW;
+ int key_menu_back      = KEY_BACKSPACE;
+ int key_menu_forward   = KEY_ENTER;
+ int key_menu_confirm   = 'y';
+ int key_menu_abort     = 'n';
+
+ int key_menu_help      = KEY_F1;
+ int key_menu_save      = KEY_F2;
+ int key_menu_load      = KEY_F3;
+ int key_menu_volume    = KEY_F4;
+ int key_menu_detail    = KEY_F5;
+ int key_menu_qsave     = KEY_F6;
+ int key_menu_endgame   = KEY_F7;
+ int key_menu_messages  = KEY_F8;
+ int key_menu_qload     = KEY_F9;
+ int key_menu_quit      = KEY_F10;
+ int key_menu_gamma     = KEY_F11;
+
+ int key_menu_incscreen = KEY_EQUALS;
+ int key_menu_decscreen = KEY_MINUS;
+
+ int key_map_north      = KEY_UPARROW;
+ int key_map_south      = KEY_DOWNARROW;
+ int key_map_east       = KEY_RIGHTARROW;
+ int key_map_west       = KEY_LEFTARROW;
+ int key_map_zoomin     = '=';
+ int key_map_zoomout    = '-';
+ int key_map_toggle     = KEY_TAB;
+ int key_map_maxzoom    = '0';
+ int key_map_follow     = 'f';
+ int key_map_grid       = 'g';
+ int key_map_mark       = 'm';
+ int key_map_clearmark  = 'c';
+
+ int key_weapon1        = '1';
+ int key_weapon2        = '2';
+ int key_weapon3        = '3';
+ int key_weapon4        = '4';
+ int key_weapon5        = '5';
+ int key_weapon6        = '6';
+ int key_weapon7        = '7';
+ int key_weapon8        = '8';
+
 -int vanilla_keyboard_mapping = 1;
 -
  static int always_run = 0;

- static int *allkeys[] = {
-     &key_left, &key_right, &key_up, &key_down,
-     &key_strafeleft, &key_straferight, &key_strafe,
-     &key_jump, &key_fire, &key_use, &key_speed,
-     &key_flyup, &key_flydown, &key_flycenter,
-     &key_lookup, &key_lookdown, &key_lookcenter,
-     &key_invleft, &key_invright, &key_useartifact
- };
+ // Keys within these groups cannot have the same value.
+
+ static int *controls[] = { &key_left, &key_right, &key_up, &key_down,
+                            &key_strafeleft, &key_straferight, &key_fire,
 -                           &key_use, &key_strafe, &key_speed,
++                           &key_use, &key_strafe, &key_speed, &key_jump,
++                           &key_flyup, &key_flydown, &key_flycenter,
++                           &key_lookup, &key_lookdown, &key_lookcenter,
++                           &key_invleft, &key_invright, &key_useartifact,
+                            &key_weapon1, &key_weapon2, &key_weapon3,
+                            &key_weapon4, &key_weapon5, &key_weapon6,
 -                           &key_weapon7, &key_weapon8, NULL };
++                           &key_weapon7, &key_weapon8,
++                           NULL };
+
+ static int *menu_nav[] = { &key_menu_activate, &key_menu_up, &key_menu_down,
+                            &key_menu_left, &key_menu_right, &key_menu_back,
+                            &key_menu_forward, NULL };
+
+ static int *shortcuts[] = { &key_menu_help, &key_menu_save, &key_menu_load,
+                             &key_menu_volume, &key_menu_detail, &key_menu_qsave,
+                             &key_menu_endgame, &key_menu_messages,
+                             &key_menu_qload, &key_menu_quit, &key_menu_gamma,
+                             &key_menu_incscreen, &key_menu_decscreen, NULL };
+
+ static int *map_keys[] = { &key_map_north, &key_map_south, &key_map_east,
+                            &key_map_west, &key_map_zoomin, &key_map_zoomout,
+                            &key_map_toggle, &key_map_maxzoom, &key_map_follow,
+                            &key_map_grid, &key_map_mark, &key_map_clearmark,
+                            NULL };

  static void UpdateJoybSpeed(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(var))
  {
@@@ -93,43 -203,92 +199,129 @@@ static void AddKeyControl(txt_table_t *
      TXT_SignalConnect(key_input, "set", KeySetCallback, var);
  }

 +static void ConfigExtraKeys(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(unused))
 +{
 +    txt_window_t *window;
 +    txt_table_t *view_table;
 +    txt_table_t *fly_table;
 +    txt_table_t *inv_table;
 +
 +    window = TXT_NewWindow("Extra keyboard controls");
 +
 +    TXT_AddWidgets(window,
 +                   TXT_NewSeparator("View"),
 +                   view_table = TXT_NewTable(2),
 +                   TXT_NewSeparator("Flying"),
 +                   fly_table = TXT_NewTable(2),
 +                   TXT_NewSeparator("Inventory"),
 +                   inv_table = TXT_NewTable(2),
 +                   NULL);
 +
 +    TXT_SetColumnWidths(view_table, 25, 12);
 +
 +    AddKeyControl(view_table, "Look up", &key_lookup);
 +    AddKeyControl(view_table, "Look down", &key_lookdown);
 +    AddKeyControl(view_table, "Center view", &key_lookcenter);
 +
 +    TXT_SetColumnWidths(fly_table, 25, 12);
 +
 +    AddKeyControl(fly_table, "Fly up", &key_flyup);
 +    AddKeyControl(fly_table, "Fly down", &key_flydown);
 +    AddKeyControl(fly_table, "Fly center", &key_flycenter);
 +
 +    TXT_SetColumnWidths(inv_table, 25, 12);
 +
 +    AddKeyControl(inv_table, "Inventory left", &key_invleft);
 +    AddKeyControl(inv_table, "Inventory right", &key_invright);
 +    AddKeyControl(inv_table, "Use artifact", &key_useartifact);
 +}
 +
+ static void OtherKeysDialog(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(unused))
+ {
+     txt_window_t *window;
+     txt_table_t *table;
+     txt_scrollpane_t *scrollpane;
+
+     window = TXT_NewWindow("Other keys");
+
+     table = TXT_NewTable(2);
+
+     TXT_SetColumnWidths(table, 25, 10);
+
+     TXT_AddWidgets(table, TXT_NewLabel(" - Weapons - "),
+                           TXT_NewStrut(0, 0),
+                           NULL);
+
+     AddKeyControl(table, "Weapon 1",              &key_weapon1);
+     AddKeyControl(table, "Weapon 2",              &key_weapon2);
+     AddKeyControl(table, "Weapon 3",              &key_weapon3);
+     AddKeyControl(table, "Weapon 4",              &key_weapon4);
+     AddKeyControl(table, "Weapon 5",              &key_weapon5);
+     AddKeyControl(table, "Weapon 6",              &key_weapon6);
+     AddKeyControl(table, "Weapon 7",              &key_weapon7);
+     AddKeyControl(table, "Weapon 8",              &key_weapon8);
+
+     TXT_AddWidgets(table, TXT_NewStrut(0, 1),
+                           TXT_NewStrut(0, 1),
+                           TXT_NewLabel(" - Menu navigation - "),
+                           TXT_NewStrut(0, 0),
+                           NULL);
+
+     AddKeyControl(table, "Activate menu",         &key_menu_activate);
+     AddKeyControl(table, "Move cursor up",        &key_menu_up);
+     AddKeyControl(table, "Move cursor down",      &key_menu_down);
+     AddKeyControl(table, "Move slider left",      &key_menu_left);
+     AddKeyControl(table, "Move slider right",     &key_menu_right);
+     AddKeyControl(table, "Go to previous menu",   &key_menu_back);
+     AddKeyControl(table, "Activate menu item",    &key_menu_forward);
+     AddKeyControl(table, "Confirm action",        &key_menu_confirm);
+     AddKeyControl(table, "Cancel action",         &key_menu_abort);
+
+     TXT_AddWidgets(table, TXT_NewStrut(0, 1),
+                           TXT_NewStrut(0, 1),
+                           TXT_NewLabel(" - Shortcut keys - "),
+                           TXT_NewStrut(0, 0),
+                           NULL);
+
+     AddKeyControl(table, "Help screen",           &key_menu_help);
+     AddKeyControl(table, "Save game",             &key_menu_save);
+     AddKeyControl(table, "Load game",             &key_menu_load);
+     AddKeyControl(table, "Sound volume",          &key_menu_volume);
+     AddKeyControl(table, "Toggle detail",         &key_menu_detail);
+     AddKeyControl(table, "Quick save",            &key_menu_qsave);
+     AddKeyControl(table, "End game",              &key_menu_endgame);
+     AddKeyControl(table, "Toggle messages",       &key_menu_messages);
+     AddKeyControl(table, "Quick load",            &key_menu_qload);
+     AddKeyControl(table, "Quit game",             &key_menu_quit);
+     AddKeyControl(table, "Toggle gamma",          &key_menu_gamma);
+
+     AddKeyControl(table, "Increase screen size",  &key_menu_incscreen);
+     AddKeyControl(table, "Decrease screen size",  &key_menu_decscreen);
+
+     TXT_AddWidgets(table, TXT_NewStrut(0, 1),
+                           TXT_NewStrut(0, 1),
+                           TXT_NewLabel(" - Map - "),
+                           TXT_NewStrut(0, 0),
+                           NULL);
+
+     AddKeyControl(table, "Toggle map",            &key_map_toggle);
+     AddKeyControl(table, "Zoom in",               &key_map_zoomin);
+     AddKeyControl(table, "Zoom out",              &key_map_zoomout);
+     AddKeyControl(table, "Maximum zoom out",      &key_map_maxzoom);
+     AddKeyControl(table, "Follow mode",           &key_map_follow);
+     AddKeyControl(table, "Pan north",             &key_map_north);
+     AddKeyControl(table, "Pan south",             &key_map_south);
+     AddKeyControl(table, "Pan east",              &key_map_east);
+     AddKeyControl(table, "Pan west",              &key_map_west);
+     AddKeyControl(table, "Toggle grid",           &key_map_grid);
+     AddKeyControl(table, "Mark location",         &key_map_mark);
+     AddKeyControl(table, "Clear all marks",       &key_map_clearmark);
+
+     scrollpane = TXT_NewScrollPane(0, 12, table);
+
+     TXT_AddWidget(window, scrollpane);
+ }
+
  void ConfigKeyboard(void)
  {
      txt_window_t *window;
@@@ -147,18 -306,9 +339,19 @@@

                     TXT_NewSeparator("Action"),
                     action_table = TXT_NewTable(4),
+                    TXT_NewButton2("Other keys...", OtherKeysDialog, NULL),
                     NULL);

 +    // Look up/down, inventory and flying controls are only in Heretic/Hexen
 +    // and are kept in a separate window to conserve space.
 +
 +    if (gamemission == heretic || gamemission == hexen)
 +    {
 +        TXT_AddWidget(window, TXT_NewButton2("More controls...",
 +                                             ConfigExtraKeys,
 +                                             NULL));
 +    }
 +
      TXT_AddWidgets(window,
                     TXT_NewSeparator("Misc."),
                     run_control = TXT_NewCheckBox("Always run", &always_run),
diff --cc src/setup/keyboard.h
index 12059bf8,29ff2a1a..2797ba8f
--- a/src/setup/keyboard.h
+++ b/src/setup/keyboard.h
@@@ -22,8 -22,73 +22,61 @@@
  #ifndef SETUP_KEYBOARD_H
  #define SETUP_KEYBOARD_H

 -extern int key_left;
 -extern int key_right;
 -extern int key_up;
 -extern int key_down;
 -extern int key_strafeleft;
 -extern int key_straferight;
 -extern int key_fire;
 -extern int key_use;
 -extern int key_strafe;
 -extern int key_speed;
 -extern int joybspeed;
 -extern int vanilla_keyboard_mapping;
 -
+ // Menu keys:
+
+ extern int key_menu_activate;
+ extern int key_menu_up;
+ extern int key_menu_down;
+ extern int key_menu_left;
+ extern int key_menu_right;
+ extern int key_menu_back;
+ extern int key_menu_forward;
+ extern int key_menu_confirm;
+ extern int key_menu_abort;
+
+ extern int key_menu_help;
+ extern int key_menu_save;
+ extern int key_menu_load;
+ extern int key_menu_volume;
+ extern int key_menu_detail;
+ extern int key_menu_qsave;
+ extern int key_menu_endgame;
+ extern int key_menu_messages;
+ extern int key_menu_qload;
+ extern int key_menu_quit;
+ extern int key_menu_gamma;
+
+ extern int key_menu_incscreen;
+ extern int key_menu_decscreen;
+
+ // Automap keys:
+
+ extern int key_map_north;
+ extern int key_map_south;
+ extern int key_map_east;
+ extern int key_map_west;
+ extern int key_map_zoomin;
+ extern int key_map_zoomout;
+ extern int key_map_toggle;
+ extern int key_map_maxzoom;
+ extern int key_map_follow;
+ extern int key_map_grid;
+ extern int key_map_mark;
+ extern int key_map_clearmark;
+
+ // Weapon keys:
+
+ extern int key_weapon1;
+ extern int key_weapon2;
+ extern int key_weapon3;
+ extern int key_weapon4;
+ extern int key_weapon5;
+ extern int key_weapon6;
+ extern int key_weapon7;
+ extern int key_weapon8;
+
  void ConfigKeyboard(void);
 +void BindKeyboardVariables(void);

  #endif /* #ifndef SETUP_KEYBOARD_H */

diff --cc src/setup/mainmenu.c
index d7b8e676,6a1f01c2..3b79bc94
--- a/src/setup/mainmenu.c
+++ b/src/setup/mainmenu.c
@@@ -243,15 -213,23 +247,16 @@@ static void RunGUI(void
      TXT_GUIMainLoop();
  }

 -int main(int argc, char *argv[])
 +static void MissionSet(void)
  {
 -    myargc = argc;
 -    myargv = argv;
 -
 -#ifdef _WIN32_WCE
 -
 -    // Windows CE has no environment, but SDL provides an implementation.
 -    // Populate the environment with the values we normally find.
 -
 -    PopulateEnvironment();
 +    InitConfig();
 +    MainMenu();
 +}

 -#endif
 +void D_DoomMain(void)
 +{
 +    SetupMission(MissionSet);
+
 -    InitConfig();
      RunGUI();
 -
 -    return 0;
  }

diff --cc textscreen/txt_sdl.c
index ea2280d0,6cfee614..ef00cfb4
--- a/textscreen/txt_sdl.c
+++ b/textscreen/txt_sdl.c
@@@ -166,12 -169,11 +169,15 @@@ static void ChooseFont(void

  int TXT_Init(void)
  {
 +    int flags;
 +
-     SDL_InitSubSystem(SDL_INIT_VIDEO);
+     if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
+     {
+         return 0;
+     }

 +    flags = SDL_SWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF;
 +
      ChooseFont();

      screen = SDL_SetVideoMode(TXT_SCREEN_W * font->w,