diff options
Diffstat (limited to 'setup/configfile.c')
-rw-r--r-- | setup/configfile.c | 443 |
1 files changed, 443 insertions, 0 deletions
diff --git a/setup/configfile.c b/setup/configfile.c new file mode 100644 index 00000000..3666c7d6 --- /dev/null +++ b/setup/configfile.c @@ -0,0 +1,443 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright(C) 1993-1996 Id Software, Inc. +// Copyright(C) 2005 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. +// +// +// DESCRIPTION: +// Configuration file load/save code. +// +//----------------------------------------------------------------------------- + + +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> + +// for mkdir: + +#ifdef _WIN32 +#include <io.h> +#else +#include <sys/stat.h> +#include <sys/types.h> +#endif + +#include "config.h" +#include "doomkeys.h" + +#include "compatibility.h" +#include "display.h" +#include "keyboard.h" +#include "mouse.h" +#include "multiplayer.h" +#include "sound.h" + +// +// DEFAULTS +// + +// These are options that are not controlled by setup. + +static int showMessages = 1; +static int screenblocks = 9; +static int detaillevel = 0; +static int usegamma = 0; +static int use_joystick = 0; +static int joybfire = 0; +static int joybstrafe = 1; +static int joybuse = 2; + +// 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, + DEFAULT_STRING, + DEFAULT_FLOAT, + DEFAULT_KEY, +} default_type_t; + +typedef struct +{ + char * name; + void * location; + default_type_t type; + int untranslated; +} default_t; + +typedef struct +{ + default_t *defaults; + int numdefaults; + char *filename; +} default_collection_t; + +static default_t doom_defaults_list[] = +{ + {"mouse_sensitivity", &mouseSensitivity, DEFAULT_INT, 0}, + {"sfx_volume",&sfxVolume, DEFAULT_INT, 0}, + {"music_volume",&musicVolume, DEFAULT_INT, 0}, + {"show_messages",&showMessages, DEFAULT_INT, 0}, + + {"key_right",&key_right, DEFAULT_KEY, 0}, + {"key_left",&key_left, DEFAULT_KEY, 0}, + {"key_up",&key_up, DEFAULT_KEY, 0}, + {"key_down",&key_down, DEFAULT_KEY, 0}, + {"key_strafeleft",&key_strafeleft, DEFAULT_KEY, 0}, + {"key_straferight",&key_straferight, DEFAULT_KEY, 0}, + + {"key_fire",&key_fire, DEFAULT_KEY, 0}, + {"key_use",&key_use, DEFAULT_KEY, 0}, + {"key_strafe",&key_strafe, DEFAULT_KEY, 0}, + {"key_speed",&key_speed, DEFAULT_KEY, 0}, + + {"use_mouse",&usemouse, DEFAULT_INT, 0}, + {"mouseb_fire",&mousebfire, DEFAULT_INT, 0}, + {"mouseb_strafe",&mousebstrafe, DEFAULT_INT, 0}, + {"mouseb_forward",&mousebforward, DEFAULT_INT, 0}, + + {"use_joystick",&usejoystick, DEFAULT_INT, 0}, + {"joyb_fire",&joybfire, DEFAULT_INT, 0}, + {"joyb_strafe",&joybstrafe, DEFAULT_INT, 0}, + {"joyb_use",&joybuse, DEFAULT_INT, 0}, + {"joyb_speed",&joybspeed, DEFAULT_INT, 0}, + + {"screenblocks",&screenblocks, DEFAULT_INT, 0}, + {"detaillevel",&detailLevel, DEFAULT_INT, 0}, + + {"snd_channels",&numChannels, DEFAULT_INT, 0}, + + {"snd_musicdevice", &snd_musicdevice, DEFAULT_INT, 0}, + {"snd_sfxdevice", &snd_sfxdevice, DEFAULT_INT, 0}, + {"snd_sbport", &snd_sbport, DEFAULT_INT, 0}, + {"snd_sbirq", &snd_sbirq, DEFAULT_INT, 0}, + {"snd_sbdma", &snd_sbdma, DEFAULT_INT, 0}, + {"snd_mport", &snd_mport, DEFAULT_INT, 0}, + + {"usegamma", &usegamma, DEFAULT_INT, 0}, + + {"chatmacro0", &chat_macros[0], DEFAULT_STRING, 0 }, + {"chatmacro1", &chat_macros[1], DEFAULT_STRING, 0 }, + {"chatmacro2", &chat_macros[2], DEFAULT_STRING, 0 }, + {"chatmacro3", &chat_macros[3], DEFAULT_STRING, 0 }, + {"chatmacro4", &chat_macros[4], DEFAULT_STRING, 0 }, + {"chatmacro5", &chat_macros[5], DEFAULT_STRING, 0 }, + {"chatmacro6", &chat_macros[6], DEFAULT_STRING, 0 }, + {"chatmacro7", &chat_macros[7], DEFAULT_STRING, 0 }, + {"chatmacro8", &chat_macros[8], DEFAULT_STRING, 0 }, + {"chatmacro9", &chat_macros[9], DEFAULT_STRING, 0 }, +}; + +static default_collection_t doom_defaults = +{ + doom_defaults_list, + sizeof(doom_defaults_list) / sizeof(*doom_defaults_list), + NULL, +}; + +static default_t extra_defaults_list[] = +{ + {"autoadjust_video_settings", &autoadjust_video_settings, 0, 0}, + {"fullscreen", &fullscreen, 0, 0}, + {"startup_delay", &startup_delay, 0, 0}, + {"screenmultiply", &screenmultiply, 0, 0}, + {"grabmouse", &grabmouse, 0, 0}, + {"novert", &novert, 0, 0}, + {"mouse_acceleration", &mouse_acceleration, DEFAULT_FLOAT, 0}, + {"mouse_threshold", &mouse_threshold, 0, 0}, + {"show_endoom", &show_endoom, 0, 0}, + {"vanilla_savegame_limit", &vanilla_savegame_limit, 0, 0}, + {"vanilla_demo_limit", &vanilla_demo_limit, 0, 0}, +#ifdef FEATURE_MULTIPLAYER + {"player_name", &net_player_name, DEFAULT_STRING, 0}, +#endif +}; + +static default_collection_t extra_defaults = +{ + extra_defaults_list, + sizeof(extra_defaults_list) / sizeof(*extra_defaults_list), + NULL, +}; + +static int scantokey[128] = +{ + 0 , 27, '1', '2', '3', '4', '5', '6', + '7', '8', '9', '0', '-', '=', KEY_BACKSPACE, 9, + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', + 'o', 'p', '[', ']', 13, KEY_RCTRL, 'a', 's', + 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', + '\'', '`', KEY_RSHIFT,'\\', 'z', 'x', 'c', 'v', + 'b', 'n', 'm', ',', '.', '/', KEY_RSHIFT,KEYP_MULTIPLY, + KEY_RALT, ' ', KEY_CAPSLOCK,KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, + KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_PAUSE,KEY_SCRLCK,KEY_HOME, + KEYP_UPARROW,KEY_PGUP,KEYP_MINUS,KEYP_LEFTARROW,KEYP_5,KEYP_RIGHTARROW,KEYP_PLUS,KEY_END, + KEYP_DOWNARROW,KEY_PGDN,KEY_INS,KEY_DEL,0, 0, 0, KEY_F11, + KEY_F12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; + + +static void SaveDefaultCollection(default_collection_t *collection) +{ + default_t *defaults; + int i, v; + FILE *f; + + f = fopen (collection->filename, "w"); + if (!f) + return; // can't write the file, but don't complain + + defaults = collection->defaults; + + for (i=0 ; i<collection->numdefaults ; i++) + { + int chars_written; + + // Print the name and line up all values at 30 characters + + chars_written = fprintf(f, "%s ", defaults[i].name); + + for (; chars_written < 30; ++chars_written) + fprintf(f, " "); + + // Print the value + + switch (defaults[i].type) + { + case DEFAULT_KEY: + + // use the untranslated version if we can, to reduce + // the possibility of screwing up the user's config + // file + + v = * (int *) defaults[i].location; + + if (defaults[i].untranslated) + { + v = defaults[i].untranslated; + } + else + { + // search for a reverse mapping back to a scancode + // in the scantokey table + + int s; + + for (s=0; s<128; ++s) + { + if (scantokey[s] == v) + { + v = s; + break; + } + } + } + + fprintf(f, "%i", v); + break; + + case DEFAULT_INT: + fprintf(f, "%i", * (int *) defaults[i].location); + break; + + case DEFAULT_FLOAT: + fprintf(f, "%f", * (float *) defaults[i].location); + break; + + case DEFAULT_STRING: + fprintf(f,"\"%s\"", * (char **) (defaults[i].location)); + break; + } + + fprintf(f, "\n"); + } + + fclose (f); +} + +// Parses integer values in the configuration file + +static int ParseIntParameter(char *strparm) +{ + int parm; + + if (strparm[0] == '0' && strparm[1] == 'x') + sscanf(strparm+2, "%x", &parm); + else + sscanf(strparm, "%i", &parm); + + return parm; +} + +static void LoadDefaultCollection(default_collection_t *collection) +{ + default_t *defaults = collection->defaults; + int i; + FILE* f; + char defname[80]; + char strparm[100]; + + // read the file in, overriding any set defaults + f = fopen(collection->filename, "r"); + + if (!f) + { + // File not opened, but don't complain + + return; + } + + while (!feof(f)) + { + if (fscanf (f, "%79s %[^\n]\n", defname, strparm) != 2) + { + // This line doesn't match + + continue; + } + + // Strip off trailing non-printable characters (\r characters + // from DOS text files) + + while (strlen(strparm) > 0 && !isprint(strparm[strlen(strparm)-1])) + { + strparm[strlen(strparm)-1] = '\0'; + } + + // Find the setting in the list + + for (i=0; i<collection->numdefaults; ++i) + { + default_t *def = &collection->defaults[i]; + char *s; + int intparm; + + if (strcmp(defname, def->name) != 0) + { + // not this one + continue; + } + + // parameter found + + 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_KEY: + + // translate scancodes read from config + // file (save the old value in untranslated) + + intparm = ParseIntParameter(strparm); + defaults[i].untranslated = intparm; + intparm = scantokey[intparm]; + + * (int *) def->location = intparm; + break; + + case DEFAULT_FLOAT: + * (float *) def->location = atof(strparm); + break; + } + + // finish + + break; + } + } + + fclose (f); +} + +// +// M_SaveDefaults +// + +void M_SaveDefaults (void) +{ + SaveDefaultCollection(&doom_defaults); + SaveDefaultCollection(&extra_defaults); +} + + +// +// M_LoadDefaults +// + +void M_LoadDefaults (void) +{ + int i; + + // check for a custom default file + i = M_CheckParm ("-config"); + + if (i && i<myargc-1) + { + doom_defaults.filename = myargv[i+1]; + printf (" default file: %s\n",doom_defaults.filename); + } + else + { + doom_defaults.filename = malloc(strlen(configdir) + 20); + sprintf(doom_defaults.filename, "%sdefault.cfg", configdir); + } + + printf("saving config in %s\n", doom_defaults.filename); + + i = M_CheckParm("-extraconfig"); + + if (i && i<myargc-1) + { + extra_defaults.filename = myargv[i+1]; + printf(" extra configuration file: %s\n", + extra_defaults.filename); + } + else + { + extra_defaults.filename + = malloc(strlen(configdir) + strlen(PACKAGE_TARNAME) + 10); + sprintf(extra_defaults.filename, "%s%s.cfg", + configdir, PACKAGE_TARNAME); + } + + LoadDefaultCollection(&doom_defaults); + LoadDefaultCollection(&extra_defaults); +} + |