shithub: choc

Download patch

ref: b868352951acee0e556d702e5e90aa67d9a2b39e
parent: d863f019a2d19f1146d92c4db71883ab2ead87ec
author: Simon Howard <fraggle@gmail.com>
date: Thu Sep 11 17:03:48 EDT 2008

Refactor configuration file system to allow configuration file variables
to be bound in a distributed fashion around the program. Remove
dependency of m_config.c on doom/.

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

--- a/src/doom/d_main.c
+++ b/src/doom/d_main.c
@@ -55,6 +55,7 @@
 
 #include "m_argv.h"
 #include "m_config.h"
+#include "m_controls.h"
 #include "m_misc.h"
 #include "m_menu.h"
 #include "p_saveg.h"
@@ -336,6 +337,39 @@
 }
 
 //
+// Add configuration file variable bindings.
+//
+
+void D_BindVariables(void)
+{
+    int i;
+
+    I_BindVariables();
+    M_BindBaseControls();
+    NET_BindVariables();
+
+    M_BindVariable("mouse_sensitivity",      &mouseSensitivity);
+    M_BindVariable("sfx_volume",             &sfxVolume);
+    M_BindVariable("music_volume",           &musicVolume);
+    M_BindVariable("show_messages",          &showMessages);
+    M_BindVariable("screenblocks",           &screenblocks);
+    M_BindVariable("detaillevel",            &detailLevel);
+    M_BindVariable("snd_channels",           &snd_channels);
+    M_BindVariable("vanilla_savegame_limit", &vanilla_savegame_limit);
+    M_BindVariable("vanilla_demo_limit",     &vanilla_demo_limit);
+
+    // Multiplayer chat macros
+
+    for (i=0; i<10; ++i)
+    {
+        char buf[12];
+
+        sprintf(buf, "chatmacro%i", i);
+        M_BindVariable(buf, &chat_macros[i]);
+    }
+}
+
+//
 // D_GrabMouseCallback
 //
 // Called to determine whether to grab the mouse pointer
@@ -944,11 +978,13 @@
     }
     
     // init subsystems
-    printf (DEH_String("V_Init: allocate screens.\n"));
-    V_Init ();
+    printf(DEH_String("V_Init: allocate screens.\n"));
+    V_Init();
 
-    printf (DEH_String("M_LoadDefaults: Load system defaults.\n"));
-    M_LoadDefaults ();              // load before initing other systems
+    // Load configuration files before initialising other subsystems.
+    printf(DEH_String("M_LoadDefaults: Load system defaults.\n"));
+    D_BindVariables();
+    M_LoadDefaults();
 
     // Save configuration at exit.
     I_AtExit(M_SaveDefaults, false);
--- a/src/doom/g_game.h
+++ b/src/doom/g_game.h
@@ -81,4 +81,7 @@
 
 void G_DrawMouseSpeedBox(void);
 
+extern int vanilla_savegame_limit;
+extern int vanilla_demo_limit;
 #endif
+
--- a/src/doom/hu_stuff.c
+++ b/src/doom/hu_stuff.c
@@ -67,7 +67,7 @@
 
 
 
-char*	chat_macros[] =
+char *chat_macros[10] =
 {
     HUSTR_CHATMACRO0,
     HUSTR_CHATMACRO1,
--- a/src/doom/hu_stuff.h
+++ b/src/doom/hu_stuff.h
@@ -62,5 +62,7 @@
 char HU_dequeueChatChar(void);
 void HU_Erase(void);
 
+extern char *chat_macros[10];
 
 #endif
+
--- a/src/doom/s_sound.c
+++ b/src/doom/s_sound.c
@@ -110,7 +110,7 @@
 
 // Number of channels to use
 
-int numChannels = 8;
+int snd_channels = 8;
 
 //
 // Initializes sound stuff, including volume
@@ -131,10 +131,10 @@
     // Allocating the internal channels for mixing
     // (the maximum numer of sounds rendered
     // simultaneously) within zone memory.
-    channels = Z_Malloc(numChannels*sizeof(channel_t), PU_STATIC, 0);
+    channels = Z_Malloc(snd_channels*sizeof(channel_t), PU_STATIC, 0);
 
     // Free all channels for use
-    for (i=0 ; i<numChannels ; i++)
+    for (i=0 ; i<snd_channels ; i++)
     {
         channels[i].sfxinfo = 0;
     }
@@ -175,7 +175,7 @@
 
         // check to see if other channels are playing the sound
 
-        for (i=0; i<numChannels; i++)
+        for (i=0; i<snd_channels; i++)
         {
             if (cnum != i && c->sfxinfo == channels[i].sfxinfo)
             {
@@ -203,7 +203,7 @@
 
     // kill all playing sounds at start of level
     //  (trust me - a good idea)
-    for (cnum=0 ; cnum<numChannels ; cnum++)
+    for (cnum=0 ; cnum<snd_channels ; cnum++)
     {
         if (channels[cnum].sfxinfo)
         {
@@ -252,7 +252,7 @@
 {
     int cnum;
 
-    for (cnum=0 ; cnum<numChannels ; cnum++)
+    for (cnum=0 ; cnum<snd_channels ; cnum++)
     {
         if (channels[cnum].sfxinfo && channels[cnum].origin == origin)
         {
@@ -275,7 +275,7 @@
     channel_t*        c;
 
     // Find an open channel
-    for (cnum=0 ; cnum<numChannels ; cnum++)
+    for (cnum=0 ; cnum<snd_channels ; cnum++)
     {
         if (!channels[cnum].sfxinfo)
         {
@@ -289,10 +289,10 @@
     }
 
     // None available
-    if (cnum == numChannels)
+    if (cnum == snd_channels)
     {
         // Look for lower priority
-        for (cnum=0 ; cnum<numChannels ; cnum++)
+        for (cnum=0 ; cnum<snd_channels ; cnum++)
         {
             if (channels[cnum].sfxinfo->priority >= sfxinfo->priority)
             {
@@ -300,7 +300,7 @@
             }
         }
 
-        if (cnum == numChannels)
+        if (cnum == snd_channels)
         {
             // FUCK!  No lower priority.  Sorry, Charlie.    
             return -1;
@@ -524,7 +524,7 @@
     sfxinfo_t*        sfx;
     channel_t*        c;
 
-    for (cnum=0; cnum<numChannels; cnum++)
+    for (cnum=0; cnum<snd_channels; cnum++)
     {
         c = &channels[cnum];
         sfx = c->sfxinfo;
--- a/src/doom/s_sound.h
+++ b/src/doom/s_sound.h
@@ -91,6 +91,7 @@
 void S_SetMusicVolume(int volume);
 void S_SetSfxVolume(int volume);
 
+extern int snd_channels;
 
 #endif
 
--- a/src/i_joystick.c
+++ b/src/i_joystick.c
@@ -35,6 +35,8 @@
 #include "d_event.h"
 #include "i_joystick.h"
 
+#include "m_config.h"
+
 // When an axis is within the dead zone, it is set to zero.
 // This is 5% of the full range:
 
@@ -46,23 +48,23 @@
 
 // Standard default.cfg Joystick enable/disable
 
-extern int usejoystick;
+static int usejoystick = 0;
 
 // Joystick to use, as an SDL joystick index:
 
-int joystick_index = -1;
+static int joystick_index = -1;
 
 // Which joystick axis to use for horizontal movement, and whether to
 // invert the direction:
 
-int joystick_x_axis = 0;
-int joystick_x_invert = 0;
+static int joystick_x_axis = 0;
+static int joystick_x_invert = 0;
 
 // Which joystick axis to use for vertical movement, and whether to
 // invert the direction:
 
-int joystick_y_axis = 1;
-int joystick_y_invert = 0;
+static int joystick_y_axis = 1;
+static int joystick_y_invert = 0;
 
 void I_InitJoystick(void)
 {
@@ -182,5 +184,15 @@
 
         D_PostEvent(&ev);
     }
+}
+
+void I_BindJoystickVariables(void)
+{
+    M_BindVariable("use_joystick",          &usejoystick);
+    M_BindVariable("joystick_index",        &joystick_index);
+    M_BindVariable("joystick_x_axis",       &joystick_x_axis);
+    M_BindVariable("joystick_y_axis",       &joystick_y_axis);
+    M_BindVariable("joystick_x_invert",     &joystick_x_invert);
+    M_BindVariable("joystick_y_invert",     &joystick_y_invert);
 }
 
--- a/src/i_joystick.h
+++ b/src/i_joystick.h
@@ -27,15 +27,11 @@
 #ifndef __I_JOYSTICK__
 #define __I_JOYSTICK__
 
-extern int joystick_index;
-extern int joystick_x_axis;
-extern int joystick_x_invert;
-extern int joystick_y_axis;
-extern int joystick_y_invert;
-
 void I_InitJoystick(void);
 void I_ShutdownJoystick(void);
 void I_UpdateJoystick(void);
+
+void I_BindJoystickVariables(void);
 
 #endif /* #ifndef __I_JOYSTICK__ */
 
--- a/src/i_sound.c
+++ b/src/i_sound.c
@@ -33,6 +33,7 @@
 #include "i_sound.h"
 #include "i_video.h"
 #include "m_argv.h"
+#include "m_config.h"
 
 // Disable music on OSX by default; there are problems with SDL_mixer.
 
@@ -60,6 +61,15 @@
 extern sound_module_t sound_pcsound_module;
 extern music_module_t music_sdl_module;
 
+// DOS-specific options: These are unused but should be maintained
+// so that the config file can be shared between chocolate
+// doom and doom.exe
+
+static int snd_sbport = 0;
+static int snd_sbirq = 0;
+static int snd_sbdma = 0;
+static int snd_mport = 0;
+
 // Compiled-in sound modules:
 
 static sound_module_t *sound_modules[] = 
@@ -358,5 +368,19 @@
     {
         return false;
     }
+}
+
+void I_BindSoundVariables(void)
+{
+    extern int use_libsamplerate;
+
+    M_BindVariable("snd_musicdevice",   &snd_musicdevice);
+    M_BindVariable("snd_sfxdevice",     &snd_sfxdevice);
+    M_BindVariable("snd_sbport",        &snd_sbport);
+    M_BindVariable("snd_sbirq",         &snd_sbirq);
+    M_BindVariable("snd_sbdma",         &snd_sbdma);
+    M_BindVariable("snd_mport",         &snd_mport);
+    M_BindVariable("snd_samplerate",    &snd_samplerate);
+    M_BindVariable("use_libsamplerate", &use_libsamplerate);
 }
 
--- a/src/i_sound.h
+++ b/src/i_sound.h
@@ -221,5 +221,7 @@
 extern int snd_musicdevice;
 extern int snd_samplerate;
 
+void I_BindSoundVariables(void);
+
 #endif
 
--- a/src/i_system.c
+++ b/src/i_system.c
@@ -44,6 +44,7 @@
 #include "m_config.h"
 #include "m_misc.h"
 #include "i_joystick.h"
+#include "i_sound.h"
 #include "i_timer.h"
 #include "i_video.h"
 
@@ -305,5 +306,14 @@
     // abort();
 
     exit(-1);
+}
+
+void I_BindVariables(void)
+{
+    I_BindVideoVariables();
+    I_BindJoystickVariables();
+    I_BindSoundVariables();
+
+    M_BindVariable("show_endoom", &show_endoom);
 }
 
--- a/src/i_system.h
+++ b/src/i_system.h
@@ -93,5 +93,9 @@
 
 void I_AtExit(atexit_func_t func, boolean run_if_error);
 
+// Add all system-specific config file variable bindings.
+
+void I_BindVariables(void);
+
 #endif
 
--- a/src/i_video.c
+++ b/src/i_video.c
@@ -43,6 +43,7 @@
 #include "i_video.h"
 #include "i_scale.h"
 #include "m_argv.h"
+#include "m_config.h"
 #include "v_video.h"
 #include "w_wad.h"
 #include "z_zone.h"
@@ -78,8 +79,6 @@
     &mode_squash_5x,
 };
 
-extern void M_QuitDOOM();
-
 // SDL video driver name
 
 char *video_driver = "";
@@ -100,7 +99,7 @@
 // disable mouse?
 
 static boolean nomouse = false;
-extern int usemouse;
+int usemouse = 1;
 
 // if true, screens[0] is screen->pixel
 
@@ -108,30 +107,30 @@
 
 // Screen width and height, from configuration file.
 
-int screen_width = SCREENWIDTH;
-int screen_height = SCREENHEIGHT;
+static int screen_width = SCREENWIDTH;
+static int screen_height = SCREENHEIGHT;
 
 // Automatically adjust video settings if the selected mode is 
 // not a valid video mode.
 
-int autoadjust_video_settings = 1;
+static int autoadjust_video_settings = 1;
 
 // Run in full screen mode?  (int type for config code)
 
-int fullscreen = true;
+static int fullscreen = true;
 
 // Aspect ratio correction mode
 
-int aspect_ratio_correct = true;
+static int aspect_ratio_correct = true;
 
 // Time to wait for the screen to settle on startup before starting the
 // game (ms)
 
-int startup_delay = 1000;
+static int startup_delay = 1000;
 
 // Grab the mouse? (int type for config code)
 
-int grabmouse = true;
+static int grabmouse = true;
 
 // If true, game is running as a screensaver
 
@@ -191,6 +190,10 @@
 float mouse_acceleration = 2.0;
 int mouse_threshold = 10;
 
+// Gamma correction level to use
+
+int usegamma = 0;
+
 static boolean MouseShouldBeGrabbed()
 {
     // never grab the mouse when in screensaver mode
@@ -1642,5 +1645,25 @@
     // Call I_ShutdownGraphics on quit
 
     I_AtExit(I_ShutdownGraphics, true);
+}
+
+// Bind all variables controlling video options into the configuration
+// file system.
+
+void I_BindVideoVariables(void)
+{
+    M_BindVariable("use_mouse",                 &usemouse);
+    M_BindVariable("autoadjust_video_settings", &autoadjust_video_settings);
+    M_BindVariable("fullscreen",                &fullscreen);
+    M_BindVariable("aspect_ratio_correct",      &aspect_ratio_correct);
+    M_BindVariable("startup_delay",             &startup_delay);
+    M_BindVariable("screen_width",              &screen_width);
+    M_BindVariable("screen_height",             &screen_height);
+    M_BindVariable("grabmouse",                 &grabmouse);
+    M_BindVariable("mouse_acceleration",        &mouse_acceleration);
+    M_BindVariable("mouse_threshold",           &mouse_threshold);
+    M_BindVariable("video_driver",              &video_driver);
+    M_BindVariable("usegamma",                  &usegamma);
+    M_BindVariable("vanilla_keyboard_mapping",  &vanilla_keyboard_mapping);
 }
 
--- a/src/i_video.h
+++ b/src/i_video.h
@@ -100,20 +100,15 @@
 void I_SetGrabMouseCallback(grabmouse_callback_t func);
 
 void I_DisplayFPSDots(boolean dots_on);
+void I_BindVideoVariables(void);
 
 extern char *video_driver;
-extern int autoadjust_video_settings;
 extern boolean screenvisible;
-extern int screen_width, screen_height;
-extern int fullscreen;
-extern int aspect_ratio_correct;
-extern int grabmouse;
 extern float mouse_acceleration;
 extern int mouse_threshold;
-extern int startup_delay;
 extern int vanilla_keyboard_mapping;
 extern boolean screensaver_mode;
-
+extern int usegamma;
 
 #endif
 
--- a/src/m_config.c
+++ b/src/m_config.c
@@ -19,7 +19,6 @@
 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 // 02111-1307, USA.
 //
-//
 // DESCRIPTION:
 //    Configuration file interface.
 //
@@ -28,33 +27,20 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <ctype.h>
 #include <errno.h>
 
 #include "config.h"
-#include "deh_str.h"
+
 #include "doomtype.h"
 #include "doomkeys.h"
 #include "doomfeatures.h"
-
-#include "z_zone.h"
-
-#include "m_controls.h"
-#include "m_argv.h"
-#include "net_client.h"
-
-#include "w_wad.h"
-
-#include "i_joystick.h"
-#include "i_swap.h"
 #include "i_system.h"
-#include "i_video.h"
-#include "v_video.h"
-
+#include "m_argv.h"
 #include "m_misc.h"
 
-#include "m_menu.h"
-#include "doomstat.h"
+#include "z_zone.h"
 
 //
 // DEFAULTS
@@ -63,40 +49,8 @@
 // Location where all configuration data is stored - 
 // default.cfg, savegames, etc.
 
-char *          configdir;
+char *configdir;
 
-int		usemouse = 1;
-int		usejoystick = 0;
-
-extern int	mouseSensitivity;
-extern int	showMessages;
-
-// machine-independent sound params
-extern	int	numChannels;
-
-extern char*	chat_macros[];
-
-extern int      show_endoom;
-extern int      vanilla_savegame_limit;
-extern int      vanilla_demo_limit;
-
-extern int snd_musicdevice;
-extern int snd_sfxdevice;
-extern int snd_samplerate;
-
-// controls whether to use libsamplerate for sample rate conversions
-
-extern int use_libsamplerate;
-
-// dos specific options: these are unused but should be maintained
-// so that the config file can be shared between chocolate
-// doom and doom.exe
-
-static int snd_sbport = 0;
-static int snd_sbirq = 0;
-static int snd_sbdma = 0;
-static int snd_mport = 0;
-
 typedef enum 
 {
     DEFAULT_INT,
@@ -108,10 +62,10 @@
 typedef struct
 {
     // Name of the variable
-    char *         name;
+    char *name;
 
     // Pointer to the location in memory of the variable
-    void *         location;
+    void *location;
 
     // Type of the variable
     default_type_t type;
@@ -119,30 +73,34 @@
     // If this is a key value, the original integer scancode we read from
     // the config file before translating it to the internal key value.
     // If zero, we didn't read this value from a config file.
-    int            untranslated;
+    int untranslated;
 
     // The value we translated the scancode into when we read the 
     // config file on startup.  If the variable value is different from
     // this, it has been changed and needs to be converted; otherwise,
     // use the 'untranslated' value.
-    int            original_translated;
+    int original_translated;
+
+    // If true, this config variable has been bound to a variable
+    // and is being used.
+    boolean bound;
 } default_t;
 
 typedef struct
 {
     default_t *defaults;
-    int        numdefaults;
-    char      *filename;
+    int numdefaults;
+    char *filename;
 } default_collection_t;
 
-#define CONFIG_VARIABLE_KEY(name, variable) \
-    { #name, &variable, DEFAULT_KEY, 0, 0 }
-#define CONFIG_VARIABLE_INT(name, variable) \
-    { #name, &variable, DEFAULT_INT, 0, 0 }
-#define CONFIG_VARIABLE_FLOAT(name, variable) \
-    { #name, &variable, DEFAULT_FLOAT, 0, 0 }
-#define CONFIG_VARIABLE_STRING(name, variable) \
-    { #name, &variable, DEFAULT_STRING, 0, 0 }
+#define CONFIG_VARIABLE_KEY(name) \
+    { #name, NULL, DEFAULT_KEY, 0, 0, false }
+#define CONFIG_VARIABLE_INT(name) \
+    { #name, NULL, DEFAULT_INT, 0, 0, false }
+#define CONFIG_VARIABLE_FLOAT(name) \
+    { #name, NULL, DEFAULT_FLOAT, 0, 0, false }
+#define CONFIG_VARIABLE_STRING(name) \
+    { #name, NULL, DEFAULT_STRING, 0, 0, false }
 
 //! @begin_config_file default.cfg
 
@@ -157,19 +115,19 @@
     // the game to crash when entering the options menu.
     //
 
-    CONFIG_VARIABLE_INT(mouse_sensitivity, mouseSensitivity),
+    CONFIG_VARIABLE_INT(mouse_sensitivity),
 
     //!
     // Volume of sound effects, range 0-15.
     //
 
-    CONFIG_VARIABLE_INT(sfx_volume,        sfxVolume),
+    CONFIG_VARIABLE_INT(sfx_volume),
 
     //!
     // Volume of in-game music, range 0-15.
     //
 
-    CONFIG_VARIABLE_INT(music_volume,      musicVolume),
+    CONFIG_VARIABLE_INT(music_volume),
 
     //!
     // If non-zero, messages are displayed on the heads-up display
@@ -177,55 +135,55 @@
     // are not displayed.
     //
 
-    CONFIG_VARIABLE_INT(show_messages,     showMessages),
+    CONFIG_VARIABLE_INT(show_messages),
 
     //! 
     // Keyboard key to turn right.
     //
 
-    CONFIG_VARIABLE_KEY(key_right,         key_right),
+    CONFIG_VARIABLE_KEY(key_right),
 
     //!
     // Keyboard key to turn left.
     //
 
-    CONFIG_VARIABLE_KEY(key_left,          key_left),
+    CONFIG_VARIABLE_KEY(key_left),
 
     //!
     // Keyboard key to move forward.
     //
 
-    CONFIG_VARIABLE_KEY(key_up,            key_up),
+    CONFIG_VARIABLE_KEY(key_up),
 
     //!
     // Keyboard key to move backward.
     //
 
-    CONFIG_VARIABLE_KEY(key_down,          key_down),
+    CONFIG_VARIABLE_KEY(key_down),
 
     //!
     // Keyboard key to strafe left.
     //
 
-    CONFIG_VARIABLE_KEY(key_strafeleft,    key_strafeleft),
+    CONFIG_VARIABLE_KEY(key_strafeleft),
 
     //!
     // Keyboard key to strafe right.
     //
 
-    CONFIG_VARIABLE_KEY(key_straferight,   key_straferight),
+    CONFIG_VARIABLE_KEY(key_straferight),
 
     //!
     // Keyboard key to fire the currently selected weapon.
     //
 
-    CONFIG_VARIABLE_KEY(key_fire,          key_fire),
+    CONFIG_VARIABLE_KEY(key_fire),
 
     //!
     // Keyboard key to "use" an object, eg. a door or switch.
     //
 
-    CONFIG_VARIABLE_KEY(key_use,           key_use),
+    CONFIG_VARIABLE_KEY(key_use),
 
     //!
     // Keyboard key to turn on strafing.  When held down, pressing the
@@ -233,13 +191,13 @@
     // right instead.
     //
 
-    CONFIG_VARIABLE_KEY(key_strafe,        key_strafe),
+    CONFIG_VARIABLE_KEY(key_strafe),
 
     //!
     // Keyboard key to make the player run.
     //
 
-    CONFIG_VARIABLE_KEY(key_speed,         key_speed),
+    CONFIG_VARIABLE_KEY(key_speed),
 
     //!
     // If non-zero, mouse input is enabled.  If zero, mouse input is
@@ -246,13 +204,13 @@
     // disabled.
     //
 
-    CONFIG_VARIABLE_INT(use_mouse,         usemouse),
+    CONFIG_VARIABLE_INT(use_mouse), 
 
     //!
     // Mouse button to fire the currently selected weapon.
     //
 
-    CONFIG_VARIABLE_INT(mouseb_fire,       mousebfire),
+    CONFIG_VARIABLE_INT(mouseb_fire),
 
     //!
     // Mouse button to turn on strafing.  When held down, the player
@@ -259,37 +217,37 @@
     // will strafe left and right instead of turning left and right.
     //
 
-    CONFIG_VARIABLE_INT(mouseb_strafe,     mousebstrafe),
+    CONFIG_VARIABLE_INT(mouseb_strafe),
 
     //!
     // Mouse button to move forward.
     //
 
-    CONFIG_VARIABLE_INT(mouseb_forward,    mousebforward),
+    CONFIG_VARIABLE_INT(mouseb_forward),
 
     //!
     // If non-zero, joystick input is enabled.
     //
 
-    CONFIG_VARIABLE_INT(use_joystick,      usejoystick),
+    CONFIG_VARIABLE_INT(use_joystick),
 
     //!
     // Joystick button to fire the current weapon.
     //
 
-    CONFIG_VARIABLE_INT(joyb_fire,         joybfire),
+    CONFIG_VARIABLE_INT(joyb_fire),
 
     //!
     // Joystick button to fire the current weapon.
     //
 
-    CONFIG_VARIABLE_INT(joyb_strafe,       joybstrafe),
+    CONFIG_VARIABLE_INT(joyb_strafe),
 
     //!
     // Joystick button to "use" an object, eg. a door or switch.
     //
 
-    CONFIG_VARIABLE_INT(joyb_use,          joybuse),
+    CONFIG_VARIABLE_INT(joyb_use),
 
     //!
     // Joystick button to make the player run.
@@ -297,7 +255,7 @@
     // If this has a value of 20 or greater, the player will always run.
     //
 
-    CONFIG_VARIABLE_INT(joyb_speed,        joybspeed),
+    CONFIG_VARIABLE_INT(joyb_speed),
 
     //!
     // Screen size, range 3-11.
@@ -307,7 +265,7 @@
     // status bar displayed.
     //
 
-    CONFIG_VARIABLE_INT(screenblocks,      screenblocks),
+    CONFIG_VARIABLE_INT(screenblocks),
 
     //!
     // Screen detail.  Zero gives normal "high detail" mode, while
@@ -314,13 +272,13 @@
     // a non-zero value gives "low detail" mode.
     //
 
-    CONFIG_VARIABLE_INT(detaillevel,       detailLevel),
+    CONFIG_VARIABLE_INT(detaillevel),
 
     //!
     // Number of sounds that will be played simultaneously.
     //
 
-    CONFIG_VARIABLE_INT(snd_channels,      numChannels),
+    CONFIG_VARIABLE_INT(snd_channels),
 
     //!
     // Music output device.  A non-zero value gives MIDI sound output,
@@ -327,7 +285,7 @@
     // while a value of zero disables music.
     //
 
-    CONFIG_VARIABLE_INT(snd_musicdevice,   snd_musicdevice),
+    CONFIG_VARIABLE_INT(snd_musicdevice),
 
     //!
     // Sound effects device.  A value of zero disables in-game sound 
@@ -336,31 +294,31 @@
     // effects.
     //
 
-    CONFIG_VARIABLE_INT(snd_sfxdevice,     snd_sfxdevice),
+    CONFIG_VARIABLE_INT(snd_sfxdevice),
 
     //!
     // SoundBlaster I/O port. Unused.
     //
 
-    CONFIG_VARIABLE_INT(snd_sbport,        snd_sbport),
+    CONFIG_VARIABLE_INT(snd_sbport),
 
     //!
     // SoundBlaster IRQ.  Unused.
     //
 
-    CONFIG_VARIABLE_INT(snd_sbirq,         snd_sbirq),
+    CONFIG_VARIABLE_INT(snd_sbirq),
 
     //!
     // SoundBlaster DMA channel.  Unused.
     //
 
-    CONFIG_VARIABLE_INT(snd_sbdma,         snd_sbdma),
+    CONFIG_VARIABLE_INT(snd_sbdma), 
 
     //!
     // Output port to use for OPL MIDI playback.  Unused.
     //
 
-    CONFIG_VARIABLE_INT(snd_mport,         snd_mport),
+    CONFIG_VARIABLE_INT(snd_mport),
 
     //!
     // Gamma correction level.  A value of zero disables gamma 
@@ -368,67 +326,67 @@
     // levels of gamma correction.
     //
 
-    CONFIG_VARIABLE_INT(usegamma,          usegamma),
+    CONFIG_VARIABLE_INT(usegamma),
 
     //!
     // Multiplayer chat macro: message to send when alt+0 is pressed.
     //
 
-    CONFIG_VARIABLE_STRING(chatmacro0,     chat_macros[0]),
+    CONFIG_VARIABLE_STRING(chatmacro0),
 
     //!
     // Multiplayer chat macro: message to send when alt+1 is pressed.
     //
 
-    CONFIG_VARIABLE_STRING(chatmacro1,     chat_macros[1]),
+    CONFIG_VARIABLE_STRING(chatmacro1),
 
     //!
     // Multiplayer chat macro: message to send when alt+2 is pressed.
     //
 
-    CONFIG_VARIABLE_STRING(chatmacro2,     chat_macros[2]),
+    CONFIG_VARIABLE_STRING(chatmacro2),
 
     //!
     // Multiplayer chat macro: message to send when alt+3 is pressed.
     //
 
-    CONFIG_VARIABLE_STRING(chatmacro3,     chat_macros[3]),
+    CONFIG_VARIABLE_STRING(chatmacro3),
 
     //!
     // Multiplayer chat macro: message to send when alt+4 is pressed.
     //
 
-    CONFIG_VARIABLE_STRING(chatmacro4,     chat_macros[4]),
+    CONFIG_VARIABLE_STRING(chatmacro4), 
 
     //!
     // Multiplayer chat macro: message to send when alt+5 is pressed.
     //
 
-    CONFIG_VARIABLE_STRING(chatmacro5,     chat_macros[5]),
+    CONFIG_VARIABLE_STRING(chatmacro5), 
 
     //!
     // Multiplayer chat macro: message to send when alt+6 is pressed.
     //
 
-    CONFIG_VARIABLE_STRING(chatmacro6,     chat_macros[6]),
+    CONFIG_VARIABLE_STRING(chatmacro6),
 
     //!
     // Multiplayer chat macro: message to send when alt+7 is pressed.
     //
 
-    CONFIG_VARIABLE_STRING(chatmacro7,     chat_macros[7]),
+    CONFIG_VARIABLE_STRING(chatmacro7),
 
     //!
     // Multiplayer chat macro: message to send when alt+8 is pressed.
     //
 
-    CONFIG_VARIABLE_STRING(chatmacro8,     chat_macros[8]),
+    CONFIG_VARIABLE_STRING(chatmacro8),
 
     //!
     // Multiplayer chat macro: message to send when alt+9 is pressed.
     //
 
-    CONFIG_VARIABLE_STRING(chatmacro9,     chat_macros[9]),
+    CONFIG_VARIABLE_STRING(chatmacro9),
 };
 
 static default_collection_t doom_defaults = 
@@ -448,7 +406,7 @@
     // do not match any valid configuration.
     //
 
-    CONFIG_VARIABLE_INT(autoadjust_video_settings, autoadjust_video_settings),
+    CONFIG_VARIABLE_INT(autoadjust_video_settings), 
 
     //!
     // If non-zero, the game will run in full screen mode.  If zero,
@@ -455,7 +413,7 @@
     // the game will run in a window.
     //
 
-    CONFIG_VARIABLE_INT(fullscreen,                fullscreen),
+    CONFIG_VARIABLE_INT(fullscreen), 
 
     //!
     // If non-zero, the screen will be stretched vertically to display
@@ -462,7 +420,7 @@
     // correctly on a square pixel video mode.
     //
 
-    CONFIG_VARIABLE_INT(aspect_ratio_correct,      aspect_ratio_correct),
+    CONFIG_VARIABLE_INT(aspect_ratio_correct),
 
     //!
     // Number of milliseconds to wait on startup after the video mode
@@ -471,7 +429,7 @@
     // for a brief interval after changing video modes.
     //
 
-    CONFIG_VARIABLE_INT(startup_delay,             startup_delay),
+    CONFIG_VARIABLE_INT(startup_delay), 
 
     //!
     // Screen width in pixels.  If running in full screen mode, this is
@@ -480,7 +438,7 @@
     // will run.
     //
 
-    CONFIG_VARIABLE_INT(screen_width,              screen_width),
+    CONFIG_VARIABLE_INT(screen_width),
 
     //!
     // Screen height in pixels.  If running in full screen mode, this is
@@ -489,7 +447,7 @@
     // will run.
     //
 
-    CONFIG_VARIABLE_INT(screen_height,             screen_height),
+    CONFIG_VARIABLE_INT(screen_height), 
 
     //!
     // If this is non-zero, the mouse will be "grabbed" when running
@@ -497,7 +455,7 @@
     // When running full screen, this has no effect.
     //
 
-    CONFIG_VARIABLE_INT(grabmouse,                 grabmouse),
+    CONFIG_VARIABLE_INT(grabmouse),
 
     //!
     // If non-zero, all vertical mouse movement is ignored.  This 
@@ -505,7 +463,7 @@
     // that performs the same function.
     //
 
-    CONFIG_VARIABLE_INT(novert,                    novert),
+    CONFIG_VARIABLE_INT(novert),
 
     //!
     // Mouse acceleration factor.  When the speed of mouse movement
@@ -513,7 +471,7 @@
     // multiplied by this value.
     //
 
-    CONFIG_VARIABLE_FLOAT(mouse_acceleration,      mouse_acceleration),
+    CONFIG_VARIABLE_FLOAT(mouse_acceleration), 
 
     //!
     // Mouse acceleration threshold.  When the speed of mouse movement
@@ -521,7 +479,7 @@
     // acceleration factor (mouse_acceleration).
     //
 
-    CONFIG_VARIABLE_INT(mouse_threshold,           mouse_threshold),
+    CONFIG_VARIABLE_INT(mouse_threshold),
 
     //!
     // Sound output sample rate, in Hz.  Typical values to use are 
@@ -528,7 +486,7 @@
     // 11025, 22050, 44100 and 48000.
     //
 
-    CONFIG_VARIABLE_INT(snd_samplerate,            snd_samplerate),
+    CONFIG_VARIABLE_INT(snd_samplerate),
 
     //!
     // If non-zero, the ENDOOM screen is displayed when exiting the
@@ -535,7 +493,7 @@
     // game.  If zero, the ENDOOM screen is not displayed.
     //
 
-    CONFIG_VARIABLE_INT(show_endoom,               show_endoom),
+    CONFIG_VARIABLE_INT(show_endoom),
 
     //!
     // If non-zero, the Vanilla savegame limit is enforced; if the 
@@ -544,7 +502,7 @@
     // the size of savegames.
     //
 
-    CONFIG_VARIABLE_INT(vanilla_savegame_limit,    vanilla_savegame_limit),
+    CONFIG_VARIABLE_INT(vanilla_savegame_limit),
 
     //!
     // If non-zero, the Vanilla demo size limit is enforced; the game 
@@ -553,7 +511,7 @@
     // limit to the size of demos.
     //
 
-    CONFIG_VARIABLE_INT(vanilla_demo_limit,        vanilla_demo_limit),
+    CONFIG_VARIABLE_INT(vanilla_demo_limit),
 
     //!
     // If non-zero, the game behaves like Vanilla Doom, always assuming
@@ -561,7 +519,7 @@
     // native keyboard mapping of the keyboard is used.
     //
 
-    CONFIG_VARIABLE_INT(vanilla_keyboard_mapping,  vanilla_keyboard_mapping),
+    CONFIG_VARIABLE_INT(vanilla_keyboard_mapping),
 
     //!
     // Name of the SDL video driver to use.  If this is an empty string,
@@ -568,7 +526,7 @@
     // the default video driver is used.
     //
 
-    CONFIG_VARIABLE_STRING(video_driver,           video_driver),
+    CONFIG_VARIABLE_STRING(video_driver), 
 
 #ifdef FEATURE_MULTIPLAYER
 
@@ -577,7 +535,7 @@
     // used on the "waiting" screen while waiting for the game to start.
     //
 
-    CONFIG_VARIABLE_STRING(player_name,            net_player_name),
+    CONFIG_VARIABLE_STRING(player_name),
 
 #endif
 
@@ -586,67 +544,67 @@
     // value ('-1') indicates that no joystick is configured.
     //
 
-    CONFIG_VARIABLE_INT(joystick_index,            joystick_index),
+    CONFIG_VARIABLE_INT(joystick_index),
 
     //!
     // Joystick axis to use to for horizontal (X) movement.
     //
 
-    CONFIG_VARIABLE_INT(joystick_x_axis,           joystick_x_axis),
+    CONFIG_VARIABLE_INT(joystick_x_axis),
 
     //!
     // If non-zero, movement on the horizontal joystick axis is inverted.
     //
 
-    CONFIG_VARIABLE_INT(joystick_x_invert,         joystick_x_invert),
+    CONFIG_VARIABLE_INT(joystick_x_invert),
 
     //!
     // Joystick axis to use to for vertical (Y) movement.
     //
 
-    CONFIG_VARIABLE_INT(joystick_y_axis,           joystick_y_axis),
+    CONFIG_VARIABLE_INT(joystick_y_axis),
 
     //!
     // If non-zero, movement on the vertical joystick axis is inverted.
     //
 
-    CONFIG_VARIABLE_INT(joystick_y_invert,         joystick_y_invert),
+    CONFIG_VARIABLE_INT(joystick_y_invert), 
 
     //!
     // Joystick button to strafe left.
     //
 
-    CONFIG_VARIABLE_INT(joyb_strafeleft,           joybstrafeleft),
+    CONFIG_VARIABLE_INT(joyb_strafeleft),
 
     //!
     // Joystick button to strafe right.
     //
 
-    CONFIG_VARIABLE_INT(joyb_straferight,          joybstraferight),
+    CONFIG_VARIABLE_INT(joyb_straferight),
 
     //!
     // Mouse button to strafe left.
     //
 
-    CONFIG_VARIABLE_INT(mouseb_strafeleft,         mousebstrafeleft),
+    CONFIG_VARIABLE_INT(mouseb_strafeleft),
 
     //!
     // Mouse button to strafe right.
     //
 
-    CONFIG_VARIABLE_INT(mouseb_straferight,        mousebstraferight),
+    CONFIG_VARIABLE_INT(mouseb_straferight),
 
     //!
     // Mouse button to "use" an object, eg. a door or switch.
     //
 
-    CONFIG_VARIABLE_INT(mouseb_use,                mousebuse),
+    CONFIG_VARIABLE_INT(mouseb_use),
 
     //!
     // Mouse button to move backwards.
     //
 
-    CONFIG_VARIABLE_INT(mouseb_backward,           mousebbackward),
+    CONFIG_VARIABLE_INT(mouseb_backward),
 
     //!
     // If non-zero, double-clicking a mouse button acts like pressing
@@ -653,7 +611,7 @@
     // 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),
 
     //!
     // Controls whether libsamplerate support is used for performing
@@ -668,7 +626,7 @@
     // Sinc filter = 4; High quality Sinc filter = 5.
     //
 
-    CONFIG_VARIABLE_INT(use_libsamplerate,         use_libsamplerate),
+    CONFIG_VARIABLE_INT(use_libsamplerate),
 };
 
 static default_collection_t extra_defaults =
@@ -678,6 +636,23 @@
     NULL,
 };
 
+// Search a collection for a variable
+
+static default_t *SearchCollection(default_collection_t *collection, char *name)
+{
+    int i;
+
+    for (i=0; i<collection->numdefaults; ++i) 
+    {
+        if (!strcmp(name, collection->defaults[i].name))
+        {
+            return &collection->defaults[i];
+        }
+    }
+
+    return NULL;
+}
+
 static const int scantokey[128] =
 {
     0  ,    27,     '1',    '2',    '3',    '4',    '5',    '6',
@@ -715,6 +690,13 @@
     {
         int chars_written;
 
+        // Ignore unbound variables
+
+        if (!defaults[i].bound)
+        {
+            continue;
+        }
+
         // Print the name and line up all values at 30 characters
 
         chars_written = fprintf(f, "%s ", defaults[i].name);
@@ -797,18 +779,20 @@
 
 static void LoadDefaultCollection(default_collection_t *collection)
 {
-    default_t  *defaults = collection->defaults;
-    int		i;
-    FILE*	f;
-    char	defname[80];
-    char	strparm[100];
+    default_t *def;
+    FILE *f;
+    char defname[80];
+    char strparm[100];
+    char *s;
+    int intparm;
 
     // read the file in, overriding any set defaults
     f = fopen(collection->filename, "r");
 
-    if (!f)
+    if (f == NULL)
     {
-        // File not opened, but don't complain
+        // File not opened, but don't complain. 
+        // It's probably just the first time they ran the game.
 
         return;
     }
@@ -832,53 +816,46 @@
         
         // Find the setting in the list
        
-        for (i=0; i<collection->numdefaults; ++i)
+        def = SearchCollection(collection, defname);
+
+        if (def == NULL || !def->bound)
         {
-            default_t *def = &collection->defaults[i];
-            char *s;
-            int intparm;
+            // Unknown variable?  Unbound variables are also treated
+            // as unknown.
 
-            if (strcmp(defname, def->name) != 0)
-            {
-                // not this one
-                continue;
-            }
+            continue;
+        }
 
-            // parameter found
+        // parameter found
 
-            switch (def->type)
-            {
-                case DEFAULT_STRING:
-                    s = strdup(strparm + 1);
-                    s[strlen(s) - 1] = '\0';
-                    * (char **) def->location = s;
-                    break;
+        switch (def->type)
+        {
+            case DEFAULT_STRING:
+                s = strdup(strparm + 1);
+                s[strlen(s) - 1] = '\0';
+                * (char **) def->location = s;
+                break;
 
-                case DEFAULT_INT:
-                    * (int *) def->location = ParseIntParameter(strparm);
-                    break;
+            case DEFAULT_INT:
+                * (int *) def->location = ParseIntParameter(strparm);
+                break;
 
-                case DEFAULT_KEY:
+            case DEFAULT_KEY:
 
-                    // translate scancodes read from config
-                    // file (save the old value in untranslated)
+                // translate scancodes read from config
+                // file (save the old value in untranslated)
 
-                    intparm = ParseIntParameter(strparm);
-                    defaults[i].untranslated = intparm;
-                    intparm = scantokey[intparm];
+                intparm = ParseIntParameter(strparm);
+                def->untranslated = intparm;
+                intparm = scantokey[intparm];
 
-                    defaults[i].original_translated = intparm;
-                    * (int *) def->location = intparm;
-                    break;
+                def->original_translated = intparm;
+                * (int *) def->location = intparm;
+                break;
 
-                case DEFAULT_FLOAT:
-                    * (float *) def->location = (float) atof(strparm);
-                    break;
-            }
-
-            // finish
-
-            break; 
+            case DEFAULT_FLOAT:
+                * (float *) def->location = (float) atof(strparm);
+                break;
         }
     }
             
@@ -895,7 +872,6 @@
     SaveDefaultCollection(&extra_defaults);
 }
 
-
 //
 // M_LoadDefaults
 //
@@ -954,6 +930,45 @@
 
     LoadDefaultCollection(&doom_defaults);
     LoadDefaultCollection(&extra_defaults);
+}
+
+// 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;
+}
+
+//
+// Bind a variable to a given configuration file variable, by name.
+//
+
+void M_BindVariable(char *name, void *location)
+{
+    default_t *variable;
+
+    variable = GetDefaultForName(name);
+
+    variable->location = location;
+    variable->bound = true;
 }
 
 // 
--- a/src/m_config.h
+++ b/src/m_config.h
@@ -31,6 +31,7 @@
 void M_LoadDefaults(void);
 void M_SaveDefaults(void);
 void M_SetConfigDir(void);
+void M_BindVariable(char *name, void *variable);
 
 extern char *configdir;
 
--- a/src/m_controls.c
+++ b/src/m_controls.c
@@ -23,6 +23,8 @@
 
 #include "doomtype.h"
 #include "doomkeys.h"
+
+#include "m_config.h"
  
 // 
 // Keyboard controls 
@@ -76,3 +78,41 @@
 
 int novert = 0;
  
+// 
+// Bind all of the common controls used by Doom and all other games.
+//
+
+void M_BindBaseControls(void)
+{
+    M_BindVariable("key_right",          &key_right),
+    M_BindVariable("key_left",           &key_left),
+    M_BindVariable("key_up",             &key_up),
+    M_BindVariable("key_down",           &key_down),
+    M_BindVariable("key_strafeleft",     &key_strafeleft),
+    M_BindVariable("key_straferight",    &key_straferight),
+    M_BindVariable("key_fire",           &key_fire),
+    M_BindVariable("key_use",            &key_use),
+    M_BindVariable("key_strafe",         &key_strafe),
+    M_BindVariable("key_speed",          &key_speed),
+
+    M_BindVariable("mouseb_fire",        &mousebfire),
+    M_BindVariable("mouseb_strafe",      &mousebstrafe),
+    M_BindVariable("mouseb_forward",     &mousebforward),
+
+    M_BindVariable("joyb_fire",          &joybfire),
+    M_BindVariable("joyb_strafe",        &joybstrafe),
+    M_BindVariable("joyb_use",           &joybuse),
+    M_BindVariable("joyb_speed",         &joybspeed),
+
+    // Extra controls that are not in the Vanilla versions:
+  
+    M_BindVariable("joyb_strafeleft",    &joybstrafeleft);
+    M_BindVariable("joyb_straferight",   &joybstraferight);
+    M_BindVariable("mouseb_strafeleft",  &mousebstrafeleft);
+    M_BindVariable("mouseb_straferight", &mousebstraferight);
+    M_BindVariable("mouseb_use",         &mousebuse);
+    M_BindVariable("mouseb_backward",    &mousebbackward);
+    M_BindVariable("dclick_use",         &dclick_use);
+    M_BindVariable("novert",             &novert);
+}
+
--- a/src/m_controls.h
+++ b/src/m_controls.h
@@ -55,5 +55,7 @@
 extern int dclick_use;
 extern int novert;
  
+void M_BindBaseControls(void);
+
 #endif /* #ifndef __M_CONTROLS_H__ */
 
--- a/src/net_client.c
+++ b/src/net_client.c
@@ -34,6 +34,7 @@
 #include "i_system.h"
 #include "i_timer.h"
 #include "m_argv.h"
+#include "m_config.h"
 #include "net_client.h"
 #include "net_common.h"
 #include "net_defs.h"
@@ -1280,5 +1281,10 @@
 void NET_Init(void)
 {
     NET_CL_Init();
+}
+
+void NET_BindVariables(void)
+{
+    M_BindVariable("player_name", &net_player_name);
 }
 
--- a/src/net_client.h
+++ b/src/net_client.h
@@ -39,6 +39,8 @@
 void NET_CL_SendTiccmd(ticcmd_t *ticcmd, int maketic);
 void NET_Init(void);
 
+void NET_BindVariables(void);
+
 extern boolean net_client_connected;
 extern boolean net_client_received_wait_data;
 extern boolean net_client_controller;
--- a/src/v_video.c
+++ b/src/v_video.c
@@ -135,10 +135,6 @@
 };
 
 
-// Gamma correction level to use
-
-int	usegamma = 0;
-			 
 //
 // V_MarkRect 
 // 
--- a/src/v_video.h
+++ b/src/v_video.h
@@ -45,16 +45,11 @@
 // Screen 0 is the screen updated by I_Update screen.
 // Screen 1 is an extra buffer.
 
-
-
 extern byte *screens[5];
 
 extern int dirtybox[4];
 
 extern const byte gammatable[5][256];
-extern int usegamma;
-
-
 
 // Allocates buffer screens, call before R_Init.
 void V_Init (void);