diff --git a/src/c_cvars.cpp b/src/c_cvars.cpp index 7edf126ab..3f7d900cd 100644 --- a/src/c_cvars.cpp +++ b/src/c_cvars.cpp @@ -60,6 +60,7 @@ struct FLatchedValue FBaseCVar *Variable; UCVarValue Value; ECVarType Type; + bool UnsafeContext; }; static TArray LatchedValues; @@ -71,11 +72,6 @@ FBaseCVar *CVars = NULL; int cvar_defflags; -FBaseCVar::FBaseCVar (const FBaseCVar &var) -{ - I_FatalError ("Use of cvar copy constructor"); -} - FBaseCVar::FBaseCVar (const char *var_name, uint32_t flags, void (*callback)(FBaseCVar &)) { FBaseCVar *var; @@ -148,7 +144,12 @@ void FBaseCVar::ForceSet (UCVarValue value, ECVarType type, bool nouserinfosend) if (m_UseCallback) Callback (); - Flags &= ~CVAR_ISDEFAULT; + if ((Flags & CVAR_ARCHIVE) && !(Flags & CVAR_UNSAFECONTEXT)) + { + SafeValue = GetGenericRep(CVAR_String).String; + } + + Flags &= ~(CVAR_ISDEFAULT | CVAR_UNSAFECONTEXT); } void FBaseCVar::SetGenericRep (UCVarValue value, ECVarType type) @@ -167,13 +168,17 @@ void FBaseCVar::SetGenericRep (UCVarValue value, ECVarType type) latch.Value = value; else latch.Value.String = copystring(value.String); + latch.UnsafeContext = !!(Flags & CVAR_UNSAFECONTEXT); LatchedValues.Push (latch); + + Flags &= ~CVAR_UNSAFECONTEXT; } else if ((Flags & CVAR_SERVERINFO) && gamestate != GS_STARTUP && !demoplayback) { if (netgame && !players[consoleplayer].settings_controller) { Printf ("Only setting controllers can change %s\n", Name); + Flags &= ~CVAR_UNSAFECONTEXT; return; } D_SendServerInfoChange (this, value, type); @@ -1134,6 +1139,14 @@ DEFINE_ACTION_FUNCTION(_CVar, ResetToDefault) return 0; } +void FBaseCVar::MarkUnsafe() +{ + if (!(Flags & CVAR_MOD) && UnsafeExecutionContext) + { + Flags |= CVAR_UNSAFECONTEXT; + } +} + // // Flag cvar implementation // @@ -1644,6 +1657,8 @@ void UnlatchCVars (void) { uint32_t oldflags = var.Variable->Flags; var.Variable->Flags &= ~(CVAR_LATCH | CVAR_SERVERINFO); + if (var.UnsafeContext) + var.Variable->Flags |= CVAR_UNSAFECONTEXT; var.Variable->SetGenericRep (var.Value, var.Type); if (var.Type == CVAR_String) delete[] var.Value.String; @@ -1697,9 +1712,7 @@ void C_ArchiveCVars (FConfigFile *f, uint32_t filter) (CVAR_GLOBALCONFIG|CVAR_ARCHIVE|CVAR_MOD|CVAR_AUTO|CVAR_USERINFO|CVAR_SERVERINFO|CVAR_NOSAVE)) == filter) { - UCVarValue val; - val = cvar->GetGenericRep (CVAR_String); - f->SetValueForKey (cvar->GetName (), val.String); + f->SetValueForKey(cvar->GetName(), cvar->SafeValue); } cvar = cvar->m_Next; } @@ -1707,16 +1720,6 @@ void C_ArchiveCVars (FConfigFile *f, uint32_t filter) EXTERN_CVAR(Bool, sv_cheats); -static bool IsUnsafe(const FBaseCVar *const var) -{ - const bool unsafe = UnsafeExecutionContext && !(var->GetFlags() & CVAR_MOD); - if (unsafe) - { - Printf(TEXTCOLOR_RED "Cannot set console variable" TEXTCOLOR_GOLD " %s " TEXTCOLOR_RED "from unsafe command\n", var->GetName()); - } - return unsafe; -} - void FBaseCVar::CmdSet (const char *newval) { if ((GetFlags() & CVAR_CHEAT) && !sv_cheats) @@ -1724,10 +1727,8 @@ void FBaseCVar::CmdSet (const char *newval) Printf("sv_cheats must be true to set this console variable.\n"); return; } - else if (IsUnsafe(this)) - { - return; - } + + MarkUnsafe(); UCVarValue val; @@ -1814,10 +1815,7 @@ CCMD (toggle) { if ( (var = FindCVar (argv[1], &prev)) ) { - if (IsUnsafe(var)) - { - return; - } + var->MarkUnsafe(); val = var->GetGenericRep (CVAR_Bool); val.Bool = !val.Bool; diff --git a/src/c_cvars.h b/src/c_cvars.h index 02e9d67a2..11166098b 100644 --- a/src/c_cvars.h +++ b/src/c_cvars.h @@ -64,6 +64,7 @@ enum CVAR_MOD = 8192, // cvar was defined by a mod CVAR_IGNORE = 16384,// do not send cvar across the network/inaccesible from ACS (dummy mod cvar) CVAR_CHEAT = 32768,// can be set only when sv_cheats is enabled + CVAR_UNSAFECONTEXT = 65536,// cvar value came from unsafe context }; union UCVarValue @@ -110,6 +111,7 @@ public: void SetGenericRep (UCVarValue value, ECVarType type); void ResetToDefault (); void SetArchiveBit () { Flags |= CVAR_ARCHIVE; } + void MarkUnsafe(); virtual ECVarType GetRealType () const = 0; @@ -132,7 +134,6 @@ public: static void ListVars (const char *filter, bool plain); protected: - FBaseCVar () {} virtual void DoSet (UCVarValue value, ECVarType type) = 0; static bool ToBool (UCVarValue value, ECVarType type); @@ -147,10 +148,11 @@ protected: static UCVarValue FromGUID (const GUID &value, ECVarType type); char *Name; + FString SafeValue; uint32_t Flags; private: - FBaseCVar (const FBaseCVar &var); + FBaseCVar (const FBaseCVar &var) = delete; FBaseCVar (const char *name, uint32_t flags); void (*m_Callback)(FBaseCVar &); diff --git a/src/g_game.cpp b/src/g_game.cpp index d0cf74be7..2ca349631 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -2388,7 +2388,9 @@ void G_DoSaveGame (bool okForQuicksave, FString filename, const char *descriptio level.info->Snapshot.Clean(); insave = false; - I_FreezeTime(false); + + if (cl_waitforsave) + I_FreezeTime(false); } diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index 951b6a346..325f6c2d2 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -1431,7 +1431,7 @@ MapFlagHandlers[] = { "activateowndeathspecials", MITYPE_SETFLAG, LEVEL_ACTOWNSPECIAL, 0 }, { "killeractivatesdeathspecials", MITYPE_CLRFLAG, LEVEL_ACTOWNSPECIAL, 0 }, { "missilesactivateimpactlines", MITYPE_SETFLAG2, LEVEL2_MISSILESACTIVATEIMPACT, 0 }, - { "missileshootersactivetimpactlines",MITYPE_CLRFLAG2, LEVEL2_MISSILESACTIVATEIMPACT, 0 }, + { "missileshootersactivateimpactlines",MITYPE_CLRFLAG2, LEVEL2_MISSILESACTIVATEIMPACT, 0 }, { "noinventorybar", MITYPE_SETFLAG, LEVEL_NOINVENTORYBAR, 0 }, { "deathslideshow", MITYPE_IGNORE, 0, 0 }, { "strictmonsteractivation", MITYPE_CLRFLAG2, LEVEL2_LAXMONSTERACTIVATION, LEVEL2_LAXACTIVATIONMAPINFO }, diff --git a/src/gameconfigfile.cpp b/src/gameconfigfile.cpp index 80e08b3e7..c2655c359 100644 --- a/src/gameconfigfile.cpp +++ b/src/gameconfigfile.cpp @@ -73,6 +73,38 @@ FGameConfigFile::FGameConfigFile () { #ifdef __APPLE__ FString user_docs, user_app_support, local_app_support; + { + char cpath[PATH_MAX]; + FSRef folder; + + if (noErr == FSFindFolder(kUserDomain, kDocumentsFolderType, kCreateFolder, &folder) && + noErr == FSRefMakePath(&folder, (UInt8*)cpath, PATH_MAX)) + { + user_docs << cpath << "/" GAME_DIR; + } + else + { + user_docs = "~/" GAME_DIR; + } + if (noErr == FSFindFolder(kUserDomain, kApplicationSupportFolderType, kCreateFolder, &folder) && + noErr == FSRefMakePath(&folder, (UInt8*)cpath, PATH_MAX)) + { + user_app_support << cpath << "/" GAME_DIR; + } + else + { + user_app_support = "~/Library/Application Support/" GAME_DIR; + } + if (noErr == FSFindFolder(kLocalDomain, kApplicationSupportFolderType, kCreateFolder, &folder) && + noErr == FSRefMakePath(&folder, (UInt8*)cpath, PATH_MAX)) + { + local_app_support << cpath << "/" GAME_DIR; + } + else + { + local_app_support = "Library/Application Support/" GAME_DIR; + } + } #endif FString pathname; @@ -95,32 +127,10 @@ FGameConfigFile::FGameConfigFile () SetValueForKey ("Path", ".", true); SetValueForKey ("Path", "$DOOMWADDIR", true); #ifdef __APPLE__ - char cpath[PATH_MAX]; - FSRef folder; - - if (noErr == FSFindFolder(kUserDomain, kDocumentsFolderType, kCreateFolder, &folder) && - noErr == FSRefMakePath(&folder, (UInt8*)cpath, PATH_MAX)) - { - user_docs << cpath << "/" GAME_DIR; - SetValueForKey("Path", user_docs, true); - } - else - { - SetValueForKey("Path", "~/" GAME_DIR, true); - } - if (noErr == FSFindFolder(kUserDomain, kApplicationSupportFolderType, kCreateFolder, &folder) && - noErr == FSRefMakePath(&folder, (UInt8*)cpath, PATH_MAX)) - { - user_app_support << cpath << "/" GAME_DIR; - SetValueForKey("Path", user_app_support, true); - } + SetValueForKey ("Path", user_docs, true); + SetValueForKey ("Path", user_app_support, true); SetValueForKey ("Path", "$PROGDIR", true); - if (noErr == FSFindFolder(kLocalDomain, kApplicationSupportFolderType, kCreateFolder, &folder) && - noErr == FSRefMakePath(&folder, (UInt8*)cpath, PATH_MAX)) - { - local_app_support << cpath << "/" GAME_DIR; - SetValueForKey("Path", local_app_support, true); - } + SetValueForKey ("Path", local_app_support, true); #elif !defined(__unix__) SetValueForKey ("Path", "$HOME", true); SetValueForKey ("Path", "$PROGDIR", true); diff --git a/src/i_time.cpp b/src/i_time.cpp index 29119ddb4..8fd058723 100644 --- a/src/i_time.cpp +++ b/src/i_time.cpp @@ -187,10 +187,12 @@ void I_FreezeTime(bool frozen) { if (frozen) { + assert(FreezeTime == 0); FreezeTime = GetClockTimeNS(); } else { + assert(FreezeTime != 0); FirstFrameStartTime += GetClockTimeNS() - FreezeTime; FreezeTime = 0; I_SetFrameTime(); diff --git a/src/menu/menu.cpp b/src/menu/menu.cpp index f03c37eb7..bf8999ded 100644 --- a/src/menu/menu.cpp +++ b/src/menu/menu.cpp @@ -714,7 +714,7 @@ bool M_Responder (event_t *ev) return false; } else if (ev->type == EV_GUI_Event && ev->subtype == EV_GUI_LButtonDown && - ConsoleState != c_down && m_use_mouse) + ConsoleState != c_down && gamestate != GS_LEVEL && m_use_mouse) { M_StartControlPanel(true); M_SetMenu(NAME_Mainmenu, -1); diff --git a/src/menu/menudef.cpp b/src/menu/menudef.cpp index 21e82f841..beb1562f2 100644 --- a/src/menu/menudef.cpp +++ b/src/menu/menudef.cpp @@ -1404,7 +1404,7 @@ static void InitMusicMenus() { FString display = entry.mName; display.ReplaceChars("_", ' '); - auto it = CreateOptionMenuItemCommand(display, FStringf("%s %s", std::get<2>(p), entry.mName.GetChars()), true); + auto it = CreateOptionMenuItemCommand(display, FStringf("%s \"%s\"", std::get<2>(p), entry.mName.GetChars()), true); static_cast(*menu)->mItems.Push(it); } } diff --git a/src/sound/i_musicinterns.h b/src/sound/i_musicinterns.h index 2f04a39c1..b4269aaba 100644 --- a/src/sound/i_musicinterns.h +++ b/src/sound/i_musicinterns.h @@ -297,7 +297,6 @@ protected: static TReqProc fluid_settings_setnum; static TReqProc fluid_settings_setstr; static TReqProc fluid_settings_setint; - static TReqProc fluid_settings_getstr; static TReqProc fluid_settings_getint; static TReqProc fluid_synth_set_reverb_on; static TReqProc fluid_synth_set_chorus_on; diff --git a/src/sound/i_soundfont.cpp b/src/sound/i_soundfont.cpp index 4bb6eeeef..4a073bc5e 100644 --- a/src/sound/i_soundfont.cpp +++ b/src/sound/i_soundfont.cpp @@ -107,7 +107,7 @@ int FSoundFontReader::pathcmp(const char *p1, const char *p2) FSF2Reader::FSF2Reader(const char *fn) { - mMainConfigForSF2.Format("soundfont %s\n", fn); + mMainConfigForSF2.Format("soundfont \"%s\"\n", fn); mFilename = fn; } diff --git a/src/sound/mididevices/music_fluidsynth_mididevice.cpp b/src/sound/mididevices/music_fluidsynth_mididevice.cpp index a00fb01e6..05ed27532 100644 --- a/src/sound/mididevices/music_fluidsynth_mididevice.cpp +++ b/src/sound/mididevices/music_fluidsynth_mididevice.cpp @@ -656,10 +656,9 @@ FString FluidSynthMIDIDevice::GetStats() int polyphony = fluid_synth_get_polyphony(FluidSynth); int voices = fluid_synth_get_active_voice_count(FluidSynth); double load = fluid_synth_get_cpu_load(FluidSynth); - char *chorus, *reverb; - int maxpoly; - fluid_settings_getstr(FluidSettings, "synth.chorus.active", &chorus); - fluid_settings_getstr(FluidSettings, "synth.reverb.active", &reverb); + int chorus, reverb, maxpoly; + fluid_settings_getint(FluidSettings, "synth.chorus.active", &chorus); + fluid_settings_getint(FluidSettings, "synth.reverb.active", &reverb); fluid_settings_getint(FluidSettings, "synth.polyphony", &maxpoly); CritSec.Leave(); @@ -667,7 +666,7 @@ FString FluidSynthMIDIDevice::GetStats() TEXTCOLOR_YELLOW "%6.2f" TEXTCOLOR_NORMAL "%% CPU " "Reverb: " TEXTCOLOR_YELLOW "%3s" TEXTCOLOR_NORMAL " Chorus: " TEXTCOLOR_YELLOW "%3s", - voices, polyphony, maxpoly, load, reverb, chorus); + voices, polyphony, maxpoly, load, reverb ? "yes" : "no", chorus ? "yes" : "no"); return out; } @@ -691,7 +690,6 @@ DYN_FLUID_SYM(delete_fluid_settings); DYN_FLUID_SYM(fluid_settings_setnum); DYN_FLUID_SYM(fluid_settings_setstr); DYN_FLUID_SYM(fluid_settings_setint); -DYN_FLUID_SYM(fluid_settings_getstr); DYN_FLUID_SYM(fluid_settings_getint); DYN_FLUID_SYM(fluid_synth_set_reverb_on); DYN_FLUID_SYM(fluid_synth_set_chorus_on);