From b1325755332238b3b90c82712868ee0fa191a09a Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 20 Sep 2006 02:00:19 +0000 Subject: [PATCH] - Added a dialog that gives the user the chance to fix things if the config could not be saved for some reason. - Added the writeini console command to write the config file, optionally specifying a specific file name for it. - Fixed: "Multiplayer" demos that only had one player were not played back properly because the demo playback code only checked the number of players to determine if it should be played as a netdemo. SVN r333 (trunk) --- docs/rh-log.txt | 7 +++++++ src/configfile.cpp | 5 +++-- src/configfile.h | 2 +- src/d_protocol.h | 1 + src/g_game.cpp | 13 +++++++++++++ src/gameconfigfile.cpp | 2 +- src/m_misc.cpp | 39 ++++++++++++++++++++++++++++++++++++--- src/m_misc.h | 2 +- src/sdl/i_system.cpp | 8 ++++++++ src/sdl/i_system.h | 3 +++ src/win32/i_system.cpp | 21 +++++++++++++++++++++ src/win32/i_system.h | 3 +++ 12 files changed, 98 insertions(+), 8 deletions(-) diff --git a/docs/rh-log.txt b/docs/rh-log.txt index a53d9ef17..3a08c5390 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,11 @@ September 19, 2006 +- Added a dialog that gives the user the chance to fix things if the config + could not be saved for some reason. +- Added the writeini console command to write the config file, optionally + specifying a specific file name for it. +- Fixed: "Multiplayer" demos that only had one player were not played back + properly because the demo playback code only checked the number of players + to determine if it should be played as a netdemo. - Assembly code is disabled when building with __APPLE__ defined, for now. - If you aren't targeting x86, m_fixed.h only includes basicinlines.h now. - Moved x64inlines.h into basicinlines.h. diff --git a/src/configfile.cpp b/src/configfile.cpp index 08aca2911..850ef6cc9 100644 --- a/src/configfile.cpp +++ b/src/configfile.cpp @@ -398,14 +398,14 @@ char *FConfigFile::ReadLine (char *string, int n, void *file) const return fgets (string, n, (FILE *)file); } -void FConfigFile::WriteConfigFile () const +bool FConfigFile::WriteConfigFile () const { FILE *file = fopen (PathName, "w"); FConfigSection *section; FConfigEntry *entry; if (file == NULL) - return; + return false; WriteCommentHeader (file); @@ -423,6 +423,7 @@ void FConfigFile::WriteConfigFile () const fprintf (file, "\n"); } fclose (file); + return true; } void FConfigFile::WriteCommentHeader (FILE *file) const diff --git a/src/configfile.h b/src/configfile.h index 1eec7b3f5..05dfd406e 100644 --- a/src/configfile.h +++ b/src/configfile.h @@ -61,7 +61,7 @@ public: void ChangePathName (const char *path); void LoadConfigFile (void (*nosechandler)(const char *pathname, FConfigFile *config, void *userdata), void *userdata); - void WriteConfigFile () const; + bool WriteConfigFile () const; protected: virtual void WriteCommentHeader (FILE *file) const; diff --git a/src/d_protocol.h b/src/d_protocol.h index f35c154c5..448a2afa3 100644 --- a/src/d_protocol.h +++ b/src/d_protocol.h @@ -51,6 +51,7 @@ #define UINF_ID BIGE_ID('U','I','N','F') #define COMP_ID BIGE_ID('C','O','M','P') #define BODY_ID BIGE_ID('B','O','D','Y') +#define NETD_ID BIGE_ID('N','E','T','D') #define ANGLE2SHORT(x) ((((x)/360) & 65535) #define SHORT2ANGLE(x) ((x)*360) diff --git a/src/g_game.cpp b/src/g_game.cpp index 3046686b2..54a85aeb5 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -2231,6 +2231,15 @@ void G_BeginRecording (const char *startmap) } } + // It is possible to start a "multiplayer" game with only one player, + // so checking the number of players when playing back the demo is not + // enough. + if (multiplayer) + { + StartChunk (NETD_ID, &demo_p); + FinishChunk (&demo_p); + } + // Write cvars chunk StartChunk (VARS_ID, &demo_p); C_WriteCVars (&demo_p, CVAR_SERVERINFO|CVAR_DEMOSAVE); @@ -2358,6 +2367,10 @@ bool G_ProcessIFFDemo (char *mapname) D_ReadUserInfoStrings (i, &demo_p, false); break; + case NETD_ID: + multiplayer = netgame = netdemo = true; + break; + case BODY_ID: bodyHit = true; zdembodyend = demo_p + len; diff --git a/src/gameconfigfile.cpp b/src/gameconfigfile.cpp index 889eedf73..17d82f17a 100644 --- a/src/gameconfigfile.cpp +++ b/src/gameconfigfile.cpp @@ -519,7 +519,7 @@ FString FGameConfigFile::GetConfigPath (bool tryProg) HRESULT hr; TCHAR uname[UNLEN+1]; - DWORD unamelen = sizeof(uname); + DWORD unamelen = countof(uname); // 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. diff --git a/src/m_misc.cpp b/src/m_misc.cpp index 6708a8a08..80cb5c1a0 100644 --- a/src/m_misc.cpp +++ b/src/m_misc.cpp @@ -339,18 +339,51 @@ FString GetUserFile (const char *file, bool nodir) // M_SaveDefaults // -void M_SaveDefaults () +bool M_SaveDefaults (const char *filename) { + FString oldpath; + bool success; + + if (filename != NULL) + { + oldpath = GameConfig->GetPathName(); + GameConfig->ChangePathName (filename); + } GameConfig->ArchiveGlobalData (); if (GameNames[gameinfo.gametype] != NULL) { GameConfig->ArchiveGameData (GameNames[gameinfo.gametype]); } - GameConfig->WriteConfigFile (); + success = GameConfig->WriteConfigFile (); + if (filename != NULL) + { + GameConfig->ChangePathName (filename); + } + return success; +} + +void M_SaveDefaultsFinal () +{ + while (!M_SaveDefaults (NULL) && I_WriteIniFailed ()) + { + /* Loop until the config saves or I_WriteIniFailed() returns false */ + } delete GameConfig; GameConfig = NULL; } +CCMD (writeini) +{ + const char *filename = (argv.argc() == 1) ? NULL : argv[1]; + if (!M_SaveDefaults (filename)) + { + Printf ("Writing config failed: %s\n", strerror(errno)); + } + else + { + Printf ("Config saved.\n"); + } +} // // M_LoadDefaults @@ -361,7 +394,7 @@ void M_LoadDefaults () GameConfig = new FGameConfigFile; GameConfig->DoGlobalSetup (); atterm (FreeKeySections); - atterm (M_SaveDefaults); + atterm (M_SaveDefaultsFinal); } diff --git a/src/m_misc.h b/src/m_misc.h index 49333fc53..9802ead71 100644 --- a/src/m_misc.h +++ b/src/m_misc.h @@ -40,7 +40,7 @@ void M_ScreenShot (const char *filename); void M_LoadDefaults (); -void M_SaveDefaults (); +bool M_SaveDefaults (const char *filename); void M_SaveCustomKeys (FConfigFile *config, char *section, char *subsection); FString GetUserFile (const char *path, bool nodir=false); diff --git a/src/sdl/i_system.cpp b/src/sdl/i_system.cpp index 0b8fe6a1f..314e1c465 100644 --- a/src/sdl/i_system.cpp +++ b/src/sdl/i_system.cpp @@ -55,6 +55,7 @@ #include "stats.h" #include "hardware.h" #include "zstring.h" +#include "gameconfigfile.h" EXTERN_CVAR (String, language) @@ -364,6 +365,13 @@ int I_PickIWad (WadStuff *wads, int numwads, bool queryiwad, int defaultiwad) return i-1; } +bool I_WriteIniFailed () +{ + printf ("The config file %s could not be saved:\n%s\n", GameConfig->GetPathName(), strerror(errno)); + return false; + // return true to retry +} + static const char *pattern; #ifdef OSF1 diff --git a/src/sdl/i_system.h b/src/sdl/i_system.h index 2a4a085dd..e27027d71 100644 --- a/src/sdl/i_system.h +++ b/src/sdl/i_system.h @@ -187,6 +187,9 @@ void I_SetTitleString (const char *title); // Pick from multiple IWADs to use int I_PickIWad (WadStuff *wads, int numwads, bool queryiwad, int defaultiwad); +// The ini could not be saved at exit +bool I_WriteIniFailed (); + // [RH] Returns millisecond-accurate time unsigned int I_MSTime (void); diff --git a/src/win32/i_system.cpp b/src/win32/i_system.cpp index 2154da292..1900c968f 100644 --- a/src/win32/i_system.cpp +++ b/src/win32/i_system.cpp @@ -59,6 +59,7 @@ #include "i_system.h" #include "c_dispatch.h" #include "templates.h" +#include "gameconfigfile.h" #include "stats.h" @@ -724,6 +725,26 @@ int I_PickIWad (WadStuff *wads, int numwads, bool showwin, int defaultiwad) return defaultiwad; } +bool I_WriteIniFailed () +{ + char *lpMsgBuf; + FString errortext; + + FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPSTR)&lpMsgBuf, + 0, + NULL + ); + errortext.Format ("The config file %s could not be written:\n%s", GameConfig->GetPathName(), lpMsgBuf); + LocalFree (lpMsgBuf); + return MessageBox (Window, errortext.GetChars(), GAMENAME " configuration not saved", MB_ICONEXCLAMATION | MB_RETRYCANCEL) == IDRETRY; +} + void *I_FindFirst (const char *filespec, findstate_t *fileinfo) { return FindFirstFileA (filespec, (LPWIN32_FIND_DATAA)fileinfo); diff --git a/src/win32/i_system.h b/src/win32/i_system.h index 333282792..219b3ecce 100644 --- a/src/win32/i_system.h +++ b/src/win32/i_system.h @@ -195,6 +195,9 @@ void I_SetTitleString (const char *title); // Pick from multiple IWADs to use int I_PickIWad (WadStuff *wads, int numwads, bool queryiwad, int defaultiwad); +// The ini could not be saved at exit +bool I_WriteIniFailed (); + // [RH] Returns millisecond-accurate time unsigned int I_MSTime (void);