2006-02-24 04:48:15 +00:00
|
|
|
/*
|
|
|
|
** gameconfigfile.cpp
|
|
|
|
** An .ini parser specifically for zdoom.ini
|
|
|
|
**
|
|
|
|
**---------------------------------------------------------------------------
|
2006-06-11 01:37:00 +00:00
|
|
|
** Copyright 1998-2006 Randy Heit
|
2006-02-24 04:48:15 +00:00
|
|
|
** All rights reserved.
|
|
|
|
**
|
|
|
|
** Redistribution and use in source and binary forms, with or without
|
|
|
|
** modification, are permitted provided that the following conditions
|
|
|
|
** are met:
|
|
|
|
**
|
|
|
|
** 1. Redistributions of source code must retain the above copyright
|
|
|
|
** notice, this list of conditions and the following disclaimer.
|
|
|
|
** 2. 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.
|
|
|
|
** 3. The name of the author may not be used to endorse or promote products
|
|
|
|
** derived from this software without specific prior written permission.
|
|
|
|
**
|
|
|
|
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
|
|
|
**---------------------------------------------------------------------------
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
#define WIN32_LEAN_AND_MEAN
|
|
|
|
#include <windows.h>
|
|
|
|
#include <lmcons.h>
|
|
|
|
#include <shlobj.h>
|
|
|
|
extern HWND Window;
|
2006-09-14 00:02:31 +00:00
|
|
|
#define USE_WINDOWS_DWORD
|
2006-02-24 04:48:15 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "doomdef.h"
|
|
|
|
#include "gameconfigfile.h"
|
|
|
|
#include "c_cvars.h"
|
|
|
|
#include "c_dispatch.h"
|
|
|
|
#include "c_bind.h"
|
|
|
|
#include "gstrings.h"
|
|
|
|
#include "m_argv.h"
|
|
|
|
#include "cmdlib.h"
|
|
|
|
#include "version.h"
|
|
|
|
#include "m_misc.h"
|
|
|
|
#include "v_font.h"
|
|
|
|
#include "a_pickups.h"
|
|
|
|
#include "doomstat.h"
|
|
|
|
#include "i_system.h"
|
|
|
|
|
|
|
|
EXTERN_CVAR (Bool, con_centernotify)
|
|
|
|
EXTERN_CVAR (Int, msg0color)
|
|
|
|
EXTERN_CVAR (Color, dimcolor)
|
|
|
|
EXTERN_CVAR (Color, color)
|
|
|
|
EXTERN_CVAR (Float, dimamount)
|
|
|
|
EXTERN_CVAR (Int, msgmidcolor)
|
|
|
|
EXTERN_CVAR (Int, msgmidcolor2)
|
|
|
|
EXTERN_CVAR (Bool, snd_pitched)
|
|
|
|
EXTERN_CVAR (Color, am_wallcolor)
|
|
|
|
EXTERN_CVAR (Color, am_fdwallcolor)
|
|
|
|
EXTERN_CVAR (Color, am_cdwallcolor)
|
2008-04-09 03:55:04 +00:00
|
|
|
EXTERN_CVAR (Float, spc_amp)
|
2006-02-24 04:48:15 +00:00
|
|
|
|
2006-10-31 14:53:21 +00:00
|
|
|
FString WeaponSection;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
FGameConfigFile::FGameConfigFile ()
|
|
|
|
{
|
2006-05-03 22:45:01 +00:00
|
|
|
FString pathname;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
bMigrating = false;
|
|
|
|
pathname = GetConfigPath (true);
|
|
|
|
ChangePathName (pathname);
|
|
|
|
LoadConfigFile (MigrateStub, NULL);
|
|
|
|
|
|
|
|
if (!HaveSections ())
|
|
|
|
{ // Config file not found; try the old one
|
|
|
|
MigrateOldConfig ();
|
|
|
|
}
|
|
|
|
|
|
|
|
// If zdoom.ini was read from the program directory, switch
|
|
|
|
// to the user directory now. If it was read from the user
|
|
|
|
// directory, this effectively does nothing.
|
|
|
|
pathname = GetConfigPath (false);
|
|
|
|
ChangePathName (pathname);
|
|
|
|
|
|
|
|
// Set default IWAD search paths if none present
|
|
|
|
if (!SetSection ("IWADSearch.Directories"))
|
|
|
|
{
|
|
|
|
SetSection ("IWADSearch.Directories", true);
|
|
|
|
SetValueForKey ("Path", ".", true);
|
|
|
|
SetValueForKey ("Path", "$DOOMWADDIR", true);
|
|
|
|
#ifndef unix
|
|
|
|
SetValueForKey ("Path", "$HOME", true);
|
|
|
|
SetValueForKey ("Path", "$PROGDIR", true);
|
|
|
|
#else
|
2006-05-14 14:30:13 +00:00
|
|
|
SetValueForKey ("Path", HOME_DIR, true);
|
2006-02-24 04:48:15 +00:00
|
|
|
SetValueForKey ("Path", SHARE_DIR, true);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set default search paths if none present
|
|
|
|
if (!SetSection ("FileSearch.Directories"))
|
|
|
|
{
|
|
|
|
SetSection ("FileSearch.Directories", true);
|
|
|
|
#ifndef unix
|
|
|
|
SetValueForKey ("Path", "$PROGDIR", true);
|
|
|
|
#else
|
|
|
|
SetValueForKey ("Path", SHARE_DIR, true);
|
|
|
|
#endif
|
|
|
|
SetValueForKey ("Path", "$DOOMWADDIR", true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
FGameConfigFile::~FGameConfigFile ()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void FGameConfigFile::WriteCommentHeader (FILE *file) const
|
|
|
|
{
|
2007-12-23 22:22:21 +00:00
|
|
|
fprintf (file, "# This file was generated by " GAMENAME " " DOTVERSIONSTR " on %s"
|
2006-02-24 04:48:15 +00:00
|
|
|
"# It is not really meant to be modified outside of ZDoom, nyo.\n\n", myasctime ());
|
|
|
|
}
|
|
|
|
|
|
|
|
void FGameConfigFile::MigrateStub (const char *pathname, FConfigFile *config, void *userdata)
|
|
|
|
{
|
|
|
|
static_cast<FGameConfigFile *>(config)->bMigrating = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FGameConfigFile::MigrateOldConfig ()
|
|
|
|
{
|
|
|
|
// Set default key bindings. These will be overridden
|
|
|
|
// by the bindings in the config file if it exists.
|
|
|
|
C_SetDefaultBindings ();
|
|
|
|
|
|
|
|
#if 0 // Disabled for now, maybe forever.
|
|
|
|
int i;
|
|
|
|
char *execcommand;
|
|
|
|
|
|
|
|
i = strlen (GetPathName ()) + 8;
|
|
|
|
execcommand = new char[i];
|
|
|
|
sprintf (execcommand, "exec \"%s\"", GetPathName ());
|
|
|
|
execcommand[i-5] = 'c';
|
|
|
|
execcommand[i-4] = 'f';
|
|
|
|
execcommand[i-3] = 'g';
|
|
|
|
cvar_defflags = CVAR_ARCHIVE;
|
|
|
|
C_DoCommand (execcommand);
|
|
|
|
cvar_defflags = 0;
|
|
|
|
delete[] execcommand;
|
|
|
|
|
|
|
|
FBaseCVar *configver = FindCVar ("configver", NULL);
|
|
|
|
if (configver != NULL)
|
|
|
|
{
|
|
|
|
UCVarValue oldver = configver->GetGenericRep (CVAR_Float);
|
|
|
|
|
|
|
|
if (oldver.Float < 118.f)
|
|
|
|
{
|
|
|
|
C_DoCommand ("alias idclip noclip");
|
|
|
|
C_DoCommand ("alias idspispopd noclip");
|
|
|
|
|
|
|
|
if (oldver.Float < 117.2f)
|
|
|
|
{
|
|
|
|
dimamount = *dimamount * 0.25f;
|
|
|
|
if (oldver.Float <= 113.f)
|
|
|
|
{
|
|
|
|
C_DoCommand ("bind t messagemode; bind \\ +showscores;"
|
|
|
|
"bind f12 spynext; bind sysrq screenshot");
|
|
|
|
if (C_GetBinding (KEY_F5) && !stricmp (C_GetBinding (KEY_F5), "menu_video"))
|
|
|
|
{
|
|
|
|
C_ChangeBinding ("menu_display", KEY_F5);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
delete configver;
|
|
|
|
}
|
|
|
|
// Change all impulses to slot commands
|
|
|
|
for (i = 0; i < NUM_KEYS; i++)
|
|
|
|
{
|
|
|
|
char slotcmd[8] = "slot ";
|
|
|
|
char *bind, *numpart;
|
|
|
|
|
|
|
|
bind = C_GetBinding (i);
|
|
|
|
if (bind != NULL && strnicmp (bind, "impulse ", 8) == 0)
|
|
|
|
{
|
|
|
|
numpart = strchr (bind, ' ');
|
|
|
|
if (numpart != NULL && strlen (numpart) < 4)
|
|
|
|
{
|
|
|
|
strcpy (slotcmd + 5, numpart);
|
|
|
|
C_ChangeBinding (slotcmd, i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Migrate and delete some obsolete cvars
|
|
|
|
FBaseCVar *oldvar;
|
|
|
|
UCVarValue oldval;
|
|
|
|
|
|
|
|
oldvar = FindCVar ("autoexec", NULL);
|
|
|
|
if (oldvar != NULL)
|
|
|
|
{
|
|
|
|
oldval = oldvar->GetGenericRep (CVAR_String);
|
|
|
|
if (oldval.String[0])
|
|
|
|
{
|
|
|
|
SetSection ("Doom.AutoExec", true);
|
|
|
|
SetValueForKey ("Path", oldval.String, true);
|
|
|
|
}
|
|
|
|
delete oldvar;
|
|
|
|
}
|
|
|
|
|
|
|
|
oldvar = FindCVar ("def_patch", NULL);
|
|
|
|
if (oldvar != NULL)
|
|
|
|
{
|
|
|
|
oldval = oldvar->GetGenericRep (CVAR_String);
|
|
|
|
if (oldval.String[0])
|
|
|
|
{
|
|
|
|
SetSection ("Doom.DefaultDehacked", true);
|
|
|
|
SetValueForKey ("Path", oldval.String, true);
|
|
|
|
}
|
|
|
|
delete oldvar;
|
|
|
|
}
|
|
|
|
|
|
|
|
oldvar = FindCVar ("vid_noptc", NULL);
|
|
|
|
if (oldvar != NULL)
|
|
|
|
{
|
|
|
|
delete oldvar;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void FGameConfigFile::DoGlobalSetup ()
|
|
|
|
{
|
|
|
|
if (SetSection ("GlobalSettings.Unknown"))
|
|
|
|
{
|
|
|
|
ReadCVars (CVAR_GLOBALCONFIG);
|
|
|
|
}
|
|
|
|
if (SetSection ("GlobalSettings"))
|
|
|
|
{
|
|
|
|
ReadCVars (CVAR_GLOBALCONFIG);
|
|
|
|
}
|
|
|
|
if (SetSection ("LastRun"))
|
|
|
|
{
|
|
|
|
const char *lastver = GetValueForKey ("Version");
|
|
|
|
if (lastver != NULL)
|
|
|
|
{
|
|
|
|
double last = atof (lastver);
|
|
|
|
if (last < 123.1)
|
|
|
|
{
|
|
|
|
FBaseCVar *noblitter = FindCVar ("vid_noblitter", NULL);
|
|
|
|
if (noblitter != NULL)
|
|
|
|
{
|
|
|
|
noblitter->ResetToDefault ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (last < 201)
|
|
|
|
{
|
|
|
|
// Be sure the Hexen fourth weapons are assigned to slot 4
|
|
|
|
// If this section does not already exist, then they will be
|
|
|
|
// assigned by SetupWeaponList().
|
|
|
|
if (SetSection ("Hexen.WeaponSlots"))
|
|
|
|
{
|
|
|
|
SetValueForKey ("Slot[4]", "FWeapQuietus CWeapWraithverge MWeapBloodscourge");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (last < 202)
|
|
|
|
{
|
|
|
|
// Make sure the Hexen hotkeys are accessible by default.
|
|
|
|
if (SetSection ("Hexen.Bindings"))
|
|
|
|
{
|
|
|
|
SetValueForKey ("\\", "use ArtiHealth");
|
|
|
|
SetValueForKey ("scroll", "+showscores");
|
|
|
|
SetValueForKey ("0", "useflechette");
|
|
|
|
SetValueForKey ("9", "use ArtiBlastRadius");
|
|
|
|
SetValueForKey ("8", "use ArtiTeleport");
|
|
|
|
SetValueForKey ("7", "use ArtiTeleportOther");
|
|
|
|
SetValueForKey ("6", "use ArtiEgg");
|
|
|
|
SetValueForKey ("5", "use ArtiInvulnerability");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (last < 204)
|
|
|
|
{ // The old default for vsync was true, but with an unlimited framerate
|
|
|
|
// now, false is a better default.
|
|
|
|
FBaseCVar *vsync = FindCVar ("vid_vsync", NULL);
|
|
|
|
if (vsync != NULL)
|
|
|
|
{
|
|
|
|
vsync->ResetToDefault ();
|
|
|
|
}
|
|
|
|
}
|
2008-03-11 22:17:57 +00:00
|
|
|
if (last < 206)
|
|
|
|
{ // spc_amp is now a float, not an int.
|
2008-04-09 03:55:04 +00:00
|
|
|
if (spc_amp > 16)
|
2008-03-11 22:17:57 +00:00
|
|
|
{
|
2008-04-09 03:55:04 +00:00
|
|
|
spc_amp = spc_amp / 16.f;
|
2008-03-11 22:17:57 +00:00
|
|
|
}
|
|
|
|
}
|
2008-04-09 03:55:04 +00:00
|
|
|
if (last < 207)
|
|
|
|
{ // Now that snd_midiprecache works again, you probably don't want it on.
|
2008-04-12 05:04:37 +00:00
|
|
|
FBaseCVar *precache = FindCVar ("snd_midiprecache", NULL);
|
|
|
|
if (precache != NULL)
|
|
|
|
{
|
|
|
|
precache->ResetToDefault();
|
|
|
|
}
|
2008-04-09 03:55:04 +00:00
|
|
|
}
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void FGameConfigFile::DoGameSetup (const char *gamename)
|
|
|
|
{
|
|
|
|
const char *key;
|
|
|
|
const char *value;
|
|
|
|
enum { Doom, Heretic, Hexen, Strife } game;
|
|
|
|
|
|
|
|
if (strcmp (gamename, "Heretic") == 0)
|
|
|
|
game = Heretic;
|
|
|
|
else if (strcmp (gamename, "Hexen") == 0)
|
|
|
|
game = Hexen;
|
|
|
|
else if (strcmp (gamename, "Strife") == 0)
|
|
|
|
game = Strife;
|
|
|
|
else
|
|
|
|
game = Doom;
|
|
|
|
|
|
|
|
if (bMigrating)
|
|
|
|
{
|
|
|
|
MigrateOldConfig ();
|
|
|
|
}
|
|
|
|
subsection = section + sprintf (section, "%s.", gamename);
|
|
|
|
|
|
|
|
strcpy (subsection, "UnknownConsoleVariables");
|
|
|
|
if (SetSection (section))
|
|
|
|
{
|
|
|
|
ReadCVars (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
strcpy (subsection, "ConsoleVariables");
|
|
|
|
if (SetSection (section))
|
|
|
|
{
|
|
|
|
ReadCVars (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (game != Doom && game != Strife)
|
|
|
|
{
|
|
|
|
SetRavenDefaults (game == Hexen);
|
|
|
|
}
|
|
|
|
|
|
|
|
// The NetServerInfo section will be read when it's determined that
|
|
|
|
// a netgame is being played.
|
|
|
|
strcpy (subsection, "LocalServerInfo");
|
|
|
|
if (SetSection (section))
|
|
|
|
{
|
|
|
|
ReadCVars (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
strcpy (subsection, "Player");
|
|
|
|
if (SetSection (section))
|
|
|
|
{
|
|
|
|
ReadCVars (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
strcpy (subsection, "Bindings");
|
|
|
|
if (!SetSection (section))
|
|
|
|
{ // Config has no bindings for the given game
|
|
|
|
if (!bMigrating)
|
|
|
|
{
|
|
|
|
C_SetDefaultBindings ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
C_UnbindAll ();
|
|
|
|
while (NextInSection (key, value))
|
|
|
|
{
|
|
|
|
C_DoBind (key, value, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
strcpy (subsection, "DoubleBindings");
|
|
|
|
if (SetSection (section))
|
|
|
|
{
|
|
|
|
while (NextInSection (key, value))
|
|
|
|
{
|
|
|
|
C_DoBind (key, value, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
strcpy (subsection, "ConsoleAliases");
|
|
|
|
if (SetSection (section))
|
|
|
|
{
|
|
|
|
const char *name = NULL;
|
|
|
|
while (NextInSection (key, value))
|
|
|
|
{
|
|
|
|
if (stricmp (key, "Name") == 0)
|
|
|
|
{
|
|
|
|
name = value;
|
|
|
|
}
|
|
|
|
else if (stricmp (key, "Command") == 0 && name != NULL)
|
|
|
|
{
|
|
|
|
C_SetAlias (name, value);
|
|
|
|
name = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-04-28 09:06:32 +00:00
|
|
|
}
|
2006-02-24 04:48:15 +00:00
|
|
|
|
2007-04-28 09:06:32 +00:00
|
|
|
// Separated from DoGameSetup because it needs all the weapons properly defined
|
|
|
|
void FGameConfigFile::DoWeaponSetup (const char *gamename)
|
|
|
|
{
|
2006-02-24 04:48:15 +00:00
|
|
|
strcpy (subsection, "WeaponSlots");
|
2007-04-28 09:06:32 +00:00
|
|
|
|
2006-04-11 16:27:41 +00:00
|
|
|
if (!SetSection (section) || !LocalWeapons.RestoreSlots (*this))
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
SetupWeaponList (gamename);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void FGameConfigFile::ReadNetVars ()
|
|
|
|
{
|
|
|
|
strcpy (subsection, "NetServerInfo");
|
|
|
|
if (SetSection (section))
|
|
|
|
{
|
|
|
|
ReadCVars (0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void FGameConfigFile::ReadCVars (DWORD flags)
|
|
|
|
{
|
|
|
|
const char *key, *value;
|
|
|
|
FBaseCVar *cvar;
|
|
|
|
UCVarValue val;
|
|
|
|
|
|
|
|
while (NextInSection (key, value))
|
|
|
|
{
|
|
|
|
cvar = FindCVar (key, NULL);
|
|
|
|
if (cvar == NULL)
|
|
|
|
{
|
|
|
|
cvar = new FStringCVar (key, NULL,
|
|
|
|
CVAR_AUTO|CVAR_UNSETTABLE|CVAR_ARCHIVE|flags);
|
|
|
|
}
|
|
|
|
val.String = const_cast<char *>(value);
|
|
|
|
cvar->SetGenericRep (val, CVAR_String);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void FGameConfigFile::ArchiveGameData (const char *gamename)
|
|
|
|
{
|
|
|
|
char section[32*3], *subsection;
|
|
|
|
|
|
|
|
subsection = section + sprintf (section, "%s.", gamename);
|
|
|
|
|
|
|
|
strcpy (subsection, "Player");
|
|
|
|
SetSection (section, true);
|
|
|
|
ClearCurrentSection ();
|
|
|
|
C_ArchiveCVars (this, 4);
|
|
|
|
|
|
|
|
strcpy (subsection, "ConsoleVariables");
|
|
|
|
SetSection (section, true);
|
|
|
|
ClearCurrentSection ();
|
|
|
|
C_ArchiveCVars (this, 0);
|
|
|
|
|
|
|
|
strcpy (subsection, netgame ? "NetServerInfo" : "LocalServerInfo");
|
|
|
|
if (!netgame || consoleplayer == 0)
|
|
|
|
{ // Do not overwrite this section if playing a netgame, and
|
|
|
|
// this machine was not the initial host.
|
|
|
|
SetSection (section, true);
|
|
|
|
ClearCurrentSection ();
|
|
|
|
C_ArchiveCVars (this, 5);
|
|
|
|
}
|
|
|
|
|
|
|
|
strcpy (subsection, "UnknownConsoleVariables");
|
|
|
|
SetSection (section, true);
|
|
|
|
ClearCurrentSection ();
|
|
|
|
C_ArchiveCVars (this, 2);
|
|
|
|
|
|
|
|
strcpy (subsection, "ConsoleAliases");
|
|
|
|
SetSection (section, true);
|
|
|
|
ClearCurrentSection ();
|
|
|
|
C_ArchiveAliases (this);
|
|
|
|
|
|
|
|
M_SaveCustomKeys (this, section, subsection);
|
|
|
|
|
|
|
|
strcpy (subsection, "Bindings");
|
|
|
|
SetSection (section, true);
|
|
|
|
ClearCurrentSection ();
|
|
|
|
C_ArchiveBindings (this, false);
|
|
|
|
|
|
|
|
strcpy (subsection, "DoubleBindings");
|
|
|
|
SetSection (section, true);
|
|
|
|
ClearCurrentSection ();
|
|
|
|
C_ArchiveBindings (this, true);
|
|
|
|
|
2006-10-31 14:53:21 +00:00
|
|
|
if (WeaponSection.IsEmpty())
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
strcpy (subsection, "WeaponSlots");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-10-31 14:53:21 +00:00
|
|
|
sprintf (subsection, "%s.WeaponSlots", WeaponSection.GetChars());
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
SetSection (section, true);
|
|
|
|
ClearCurrentSection ();
|
|
|
|
LocalWeapons.SaveSlots (*this);
|
|
|
|
}
|
|
|
|
|
|
|
|
void FGameConfigFile::ArchiveGlobalData ()
|
|
|
|
{
|
|
|
|
SetSection ("LastRun", true);
|
|
|
|
ClearCurrentSection ();
|
2006-04-21 05:44:21 +00:00
|
|
|
SetValueForKey ("Version", LASTRUNVERSION);
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
SetSection ("GlobalSettings", true);
|
|
|
|
ClearCurrentSection ();
|
|
|
|
C_ArchiveCVars (this, 1);
|
|
|
|
|
|
|
|
SetSection ("GlobalSettings.Unknown", true);
|
|
|
|
ClearCurrentSection ();
|
|
|
|
C_ArchiveCVars (this, 3);
|
|
|
|
}
|
|
|
|
|
2006-05-03 22:45:01 +00:00
|
|
|
FString FGameConfigFile::GetConfigPath (bool tryProg)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
char *pathval;
|
2006-05-03 22:45:01 +00:00
|
|
|
FString path;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
2008-03-12 02:56:11 +00:00
|
|
|
pathval = Args->CheckValue ("-config");
|
2006-02-24 04:48:15 +00:00
|
|
|
if (pathval != NULL)
|
2006-05-03 22:45:01 +00:00
|
|
|
return FString(pathval);
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
#ifndef unix
|
|
|
|
path = NULL;
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
|
|
TCHAR uname[UNLEN+1];
|
2006-09-20 02:00:19 +00:00
|
|
|
DWORD unamelen = countof(uname);
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
// Because people complained, try for a user-specific .ini in the program directory first.
|
|
|
|
// If that is not writeable, use the one in the home directory instead.
|
|
|
|
hr = GetUserName (uname, &unamelen);
|
|
|
|
if (SUCCEEDED(hr) && uname[0] != 0)
|
|
|
|
{
|
|
|
|
// Is it valid for a user name to have slashes?
|
|
|
|
// Check for them and substitute just in case.
|
|
|
|
char *probe = uname;
|
|
|
|
while (*probe != 0)
|
|
|
|
{
|
|
|
|
if (*probe == '\\' || *probe == '/')
|
|
|
|
*probe = '_';
|
|
|
|
++probe;
|
|
|
|
}
|
|
|
|
|
|
|
|
path = progdir;
|
|
|
|
path += "zdoom-";
|
|
|
|
path += uname;
|
|
|
|
path += ".ini";
|
|
|
|
if (tryProg)
|
|
|
|
{
|
|
|
|
if (!FileExists (path.GetChars()))
|
|
|
|
{
|
|
|
|
path = "";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // check if writeable
|
|
|
|
FILE *checker = fopen (path.GetChars(), "a");
|
|
|
|
if (checker == NULL)
|
|
|
|
{
|
|
|
|
path = "";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
fclose (checker);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (path.IsEmpty())
|
|
|
|
{
|
2008-03-12 02:56:11 +00:00
|
|
|
if (Args->CheckParm ("-cdrom"))
|
2007-12-26 09:56:09 +00:00
|
|
|
return CDROM_DIR "\\zdoom.ini";
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
path = progdir;
|
|
|
|
path += "zdoom.ini";
|
|
|
|
}
|
|
|
|
return path;
|
|
|
|
#else
|
|
|
|
return GetUserFile ("zdoom.ini");
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void FGameConfigFile::AddAutoexec (DArgs *list, const char *game)
|
|
|
|
{
|
|
|
|
char section[64];
|
|
|
|
const char *key;
|
|
|
|
const char *value;
|
|
|
|
|
|
|
|
sprintf (section, "%s.AutoExec", game);
|
|
|
|
|
|
|
|
if (bMigrating)
|
|
|
|
{
|
|
|
|
FBaseCVar *autoexec = FindCVar ("autoexec", NULL);
|
|
|
|
|
|
|
|
if (autoexec != NULL)
|
|
|
|
{
|
|
|
|
UCVarValue val;
|
|
|
|
char *path;
|
|
|
|
|
|
|
|
val = autoexec->GetGenericRep (CVAR_String);
|
|
|
|
path = copystring (val.String);
|
|
|
|
delete autoexec;
|
|
|
|
SetSection (section, true);
|
|
|
|
SetValueForKey ("Path", path);
|
|
|
|
list->AppendArg (path);
|
|
|
|
delete[] path;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// If <game>.AutoExec section does not exist, create it
|
|
|
|
// with a default autoexec.cfg file present.
|
|
|
|
if (!SetSection (section))
|
|
|
|
{
|
2006-05-03 22:45:01 +00:00
|
|
|
FString path;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
#ifndef unix
|
2008-03-12 02:56:11 +00:00
|
|
|
if (Args->CheckParm ("-cdrom"))
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
2007-12-26 09:56:09 +00:00
|
|
|
path = CDROM_DIR "\\autoexec.cfg";
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
path = progdir;
|
|
|
|
path += "autoexec.cfg";
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
path = GetUserFile ("autoexec.cfg");
|
|
|
|
#endif
|
|
|
|
SetSection (section, true);
|
|
|
|
SetValueForKey ("Path", path.GetChars());
|
|
|
|
}
|
|
|
|
// Run any files listed in the <game>.AutoExec section
|
|
|
|
if (SetSection (section))
|
|
|
|
{
|
|
|
|
while (NextInSection (key, value))
|
|
|
|
{
|
|
|
|
if (stricmp (key, "Path") == 0 && FileExists (value))
|
|
|
|
{
|
|
|
|
list->AppendArg (value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void FGameConfigFile::SetRavenDefaults (bool isHexen)
|
|
|
|
{
|
|
|
|
UCVarValue val;
|
|
|
|
|
|
|
|
if (bMigrating)
|
|
|
|
{
|
|
|
|
con_centernotify.ResetToDefault ();
|
|
|
|
msg0color.ResetToDefault ();
|
|
|
|
dimcolor.ResetToDefault ();
|
|
|
|
color.ResetToDefault ();
|
|
|
|
}
|
|
|
|
|
|
|
|
val.Bool = true;
|
|
|
|
con_centernotify.SetGenericRepDefault (val, CVAR_Bool);
|
|
|
|
snd_pitched.SetGenericRepDefault (val, CVAR_Bool);
|
|
|
|
val.Int = 9;
|
|
|
|
msg0color.SetGenericRepDefault (val, CVAR_Int);
|
|
|
|
val.Int = 0x0000ff;
|
|
|
|
dimcolor.SetGenericRepDefault (val, CVAR_Int);
|
|
|
|
val.Int = CR_WHITE;
|
|
|
|
msgmidcolor.SetGenericRepDefault (val, CVAR_Int);
|
|
|
|
val.Int = CR_YELLOW;
|
|
|
|
msgmidcolor2.SetGenericRepDefault (val, CVAR_Int);
|
|
|
|
|
|
|
|
val.Int = 0x543b17;
|
|
|
|
am_wallcolor.SetGenericRepDefault (val, CVAR_Int);
|
|
|
|
val.Int = 0xd0b085;
|
|
|
|
am_fdwallcolor.SetGenericRepDefault (val, CVAR_Int);
|
|
|
|
val.Int = 0x734323;
|
|
|
|
am_cdwallcolor.SetGenericRepDefault (val, CVAR_Int);
|
|
|
|
|
|
|
|
// Fix the Heretic/Hexen automap colors so they are correct.
|
|
|
|
// (They were wrong on older versions.)
|
|
|
|
if (*am_wallcolor == 0x2c1808 && *am_fdwallcolor == 0x887058 && *am_cdwallcolor == 0x4c3820)
|
|
|
|
{
|
|
|
|
am_wallcolor.ResetToDefault ();
|
|
|
|
am_fdwallcolor.ResetToDefault ();
|
|
|
|
am_cdwallcolor.ResetToDefault ();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!isHexen)
|
|
|
|
{
|
|
|
|
val.Int = 0x3f6040;
|
|
|
|
color.SetGenericRepDefault (val, CVAR_Int);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void FGameConfigFile::SetupWeaponList (const char *gamename)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < NUM_WEAPON_SLOTS; ++i)
|
|
|
|
{
|
|
|
|
LocalWeapons.Slots[i].Clear ();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strcmp (gamename, "Heretic") == 0)
|
|
|
|
{
|
|
|
|
LocalWeapons.Slots[1].AddWeapon ("Staff");
|
|
|
|
LocalWeapons.Slots[1].AddWeapon ("Gauntlets");
|
|
|
|
LocalWeapons.Slots[2].AddWeapon ("GoldWand");
|
|
|
|
LocalWeapons.Slots[3].AddWeapon ("Crossbow");
|
|
|
|
LocalWeapons.Slots[4].AddWeapon ("Blaster");
|
|
|
|
LocalWeapons.Slots[5].AddWeapon ("SkullRod");
|
|
|
|
LocalWeapons.Slots[6].AddWeapon ("PhoenixRod");
|
|
|
|
LocalWeapons.Slots[7].AddWeapon ("Mace");
|
|
|
|
}
|
|
|
|
else if (strcmp (gamename, "Hexen") == 0)
|
|
|
|
{
|
|
|
|
LocalWeapons.Slots[1].AddWeapon ("FWeapFist");
|
|
|
|
LocalWeapons.Slots[2].AddWeapon ("FWeapAxe");
|
|
|
|
LocalWeapons.Slots[3].AddWeapon ("FWeapHammer");
|
|
|
|
LocalWeapons.Slots[4].AddWeapon ("FWeapQuietus");
|
|
|
|
LocalWeapons.Slots[1].AddWeapon ("CWeapMace");
|
|
|
|
LocalWeapons.Slots[2].AddWeapon ("CWeapStaff");
|
|
|
|
LocalWeapons.Slots[3].AddWeapon ("CWeapFlame");
|
|
|
|
LocalWeapons.Slots[4].AddWeapon ("CWeapWraithverge");
|
|
|
|
LocalWeapons.Slots[1].AddWeapon ("MWeapWand");
|
|
|
|
LocalWeapons.Slots[2].AddWeapon ("MWeapFrost");
|
|
|
|
LocalWeapons.Slots[3].AddWeapon ("MWeapLightning");
|
|
|
|
LocalWeapons.Slots[4].AddWeapon ("MWeapBloodscourge");
|
|
|
|
}
|
|
|
|
else if (strcmp (gamename, "Strife") == 0)
|
|
|
|
{
|
|
|
|
LocalWeapons.Slots[1].AddWeapon ("PunchDagger");
|
|
|
|
LocalWeapons.Slots[2].AddWeapon ("StrifeCrossbow2");
|
|
|
|
LocalWeapons.Slots[2].AddWeapon ("StrifeCrossbow");
|
|
|
|
LocalWeapons.Slots[3].AddWeapon ("AssaultGun");
|
|
|
|
LocalWeapons.Slots[4].AddWeapon ("MiniMissileLauncher");
|
|
|
|
LocalWeapons.Slots[5].AddWeapon ("StrifeGrenadeLauncher2");
|
|
|
|
LocalWeapons.Slots[5].AddWeapon ("StrifeGrenadeLauncher");
|
|
|
|
LocalWeapons.Slots[6].AddWeapon ("FlameThrower");
|
|
|
|
LocalWeapons.Slots[7].AddWeapon ("Mauler2");
|
|
|
|
LocalWeapons.Slots[7].AddWeapon ("Mauler");
|
|
|
|
LocalWeapons.Slots[8].AddWeapon ("Sigil");
|
|
|
|
}
|
|
|
|
else // Doom
|
|
|
|
{
|
|
|
|
LocalWeapons.Slots[1].AddWeapon ("Fist");
|
|
|
|
LocalWeapons.Slots[1].AddWeapon ("Chainsaw");
|
|
|
|
LocalWeapons.Slots[2].AddWeapon ("Pistol");
|
|
|
|
LocalWeapons.Slots[3].AddWeapon ("Shotgun");
|
|
|
|
LocalWeapons.Slots[3].AddWeapon ("SuperShotgun");
|
|
|
|
LocalWeapons.Slots[4].AddWeapon ("Chaingun");
|
|
|
|
LocalWeapons.Slots[5].AddWeapon ("RocketLauncher");
|
|
|
|
LocalWeapons.Slots[6].AddWeapon ("PlasmaRifle");
|
|
|
|
LocalWeapons.Slots[7].AddWeapon ("BFG9000");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CCMD (whereisini)
|
|
|
|
{
|
2006-05-03 22:45:01 +00:00
|
|
|
FString path = GameConfig->GetConfigPath (false);
|
2006-02-24 04:48:15 +00:00
|
|
|
Printf ("%s\n", path.GetChars());
|
|
|
|
}
|