diff --git a/src/c_cvars.cpp b/src/c_cvars.cpp index 7b5387635..3afdb7c8c 100644 --- a/src/c_cvars.cpp +++ b/src/c_cvars.cpp @@ -600,6 +600,11 @@ void FBaseCVar::EnableCallbacks () } } +void FBaseCVar::DisableCallbacks () +{ + m_UseCallback = false; +} + // // Boolean cvar implementation // diff --git a/src/c_cvars.h b/src/c_cvars.h index 3b685948b..d0ac84fe5 100644 --- a/src/c_cvars.h +++ b/src/c_cvars.h @@ -117,6 +117,7 @@ public: static void EnableNoSet (); // enable the honoring of CVAR_NOSET static void EnableCallbacks (); + static void DisableCallbacks (); static void ResetColors (); // recalc color cvars' indices after screen change static void ListVars (const char *filter, bool plain); diff --git a/src/d_main.cpp b/src/d_main.cpp index 2b3e273a9..64cfd94a9 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -223,6 +223,8 @@ FTexture *Page; FTexture *Advisory; bool nospriterename; FStartupInfo DoomStartupInfo; +FString lastIWAD; +int restart = 0; cycle_t FrameCycles; @@ -890,7 +892,7 @@ void D_Display () // // D_ErrorCleanup () // -// Cleanup after a recoverable error. +// Cleanup after a recoverable error or a restart //========================================================================== void D_ErrorCleanup () @@ -2025,269 +2027,368 @@ void D_DoomMain (void) } FString basewad = wad; - // Load zdoom.pk3 alone so that we can get access to the internal gameinfos before - // the IWAD is known. - GetCmdLineFiles(pwads); - FString iwad = CheckGameInfo(pwads); + // reinit from here - FIWadManager *iwad_man = new FIWadManager; - const FIWADInfo *iwad_info = iwad_man->FindIWAD(allwads, iwad, basewad); - gameinfo.gametype = iwad_info->gametype; - gameinfo.flags = iwad_info->flags; - gameinfo.ConfigName = iwad_info->Configname; - - GameConfig->DoGameSetup (gameinfo.ConfigName); - - AddAutoloadFiles(iwad_info->Autoname); - - // Run automatically executed files - execFiles = new DArgs; - GameConfig->AddAutoexec (execFiles, gameinfo.ConfigName); - D_MultiExec (execFiles, true); - - // Run .cfg files at the start of the command line. - execFiles = Args->GatherFiles ("-exec"); - D_MultiExec (execFiles, true); - - C_ExecCmdLineParams (); // [RH] do all +set commands on the command line - - CopyFiles(allwads, pwads); - - // Since this function will never leave we must delete this array here manually. - pwads.Clear(); - pwads.ShrinkToFit(); - - Printf ("W_Init: Init WADfiles.\n"); - Wads.InitMultipleFiles (allwads); - allwads.Clear(); - allwads.ShrinkToFit(); - SetMapxxFlag(); - - // [RH] Initialize localizable strings. - GStrings.LoadStrings (false); - - V_InitFontColors (); - - // [RH] Moved these up here so that we can do most of our - // startup output in a fullscreen console. - - CT_Init (); - - Printf ("I_Init: Setting up machine state.\n"); - I_Init (); - - Printf ("V_Init: allocate screen.\n"); - V_Init (); - - // Base systems have been inited; enable cvar callbacks - FBaseCVar::EnableCallbacks (); - - Printf ("S_Init: Setting up sound.\n"); - S_Init (); - - Printf ("ST_Init: Init startup screen.\n"); - StartScreen = FStartupScreen::CreateInstance (TexMan.GuesstimateNumTextures() + 5); - - ParseCompatibility(); - - CheckCmdLine(); - - // [RH] Load sound environments - S_ParseReverbDef (); - - // [RH] Parse through all loaded mapinfo lumps - Printf ("G_ParseMapInfo: Load map definitions.\n"); - G_ParseMapInfo (iwad_info->MapInfo); - ReadStatistics(); - - // [RH] Parse any SNDINFO lumps - Printf ("S_InitData: Load sound definitions.\n"); - S_InitData (); - - Printf ("Texman.Init: Init texture manager.\n"); - TexMan.Init(); - C_InitConback(); - - // [CW] Parse any TEAMINFO lumps. - Printf ("ParseTeamInfo: Load team definitions.\n"); - TeamLibrary.ParseTeamInfo (); - - FActorInfo::StaticInit (); - - // [GRB] Initialize player class list - SetupPlayerClasses (); - - - // [RH] Load custom key and weapon settings from WADs - D_LoadWadSettings (); - - // [GRB] Check if someone used clearplayerclasses but not addplayerclass - if (PlayerClasses.Size () == 0) + do { - I_FatalError ("No player classes defined"); - } - - StartScreen->Progress (); - - Printf ("R_Init: Init %s refresh subsystem.\n", gameinfo.ConfigName.GetChars()); - StartScreen->LoadingStatus ("Loading graphics", 0x3f); - R_Init (); - - Printf ("DecalLibrary: Load decals.\n"); - DecalLibrary.ReadAllDecals (); - - // [RH] Add any .deh and .bex files on the command line. - // If there are none, try adding any in the config file. - // Note that the command line overrides defaults from the config. - - if ((ConsiderPatches("-deh") | ConsiderPatches("-bex")) == 0 && - gameinfo.gametype == GAME_Doom && GameConfig->SetSection ("Doom.DefaultDehacked")) - { - const char *key; - const char *value; - - while (GameConfig->NextInSection (key, value)) + if (restart) { - if (stricmp (key, "Path") == 0 && FileExists (value)) - { - Printf ("Applying patch %s\n", value); - D_LoadDehFile(value); - } + C_InitConsole(SCREENWIDTH, SCREENHEIGHT, false); } - } + nospriterename = false; - // Load embedded Dehacked patches - D_LoadDehLumps(); + // Load zdoom.pk3 alone so that we can get access to the internal gameinfos before + // the IWAD is known. - // Create replacements for dehacked pickups - FinishDehPatch(); + GetCmdLineFiles(pwads); + FString iwad = CheckGameInfo(pwads); - FActorInfo::StaticSetActorNums (); + // The IWAD selection dialogue dpes not show in fullscreen so if the + // restart is initiated without a defined IWAD assume for now that it's not going to change. + if (iwad.Len() == 0) iwad = lastIWAD; - //Added by MC: - bglobal.getspawned.Clear(); - argcount = Args->CheckParmList("-bots", &args); - for (p = 0; p < argcount; ++p) - { - bglobal.getspawned.Push(args[p]); - } - bglobal.spawn_tries = 0; - bglobal.wanted_botnum = bglobal.getspawned.Size(); + FIWadManager *iwad_man = new FIWadManager; + const FIWADInfo *iwad_info = iwad_man->FindIWAD(allwads, iwad, basewad); + gameinfo.gametype = iwad_info->gametype; + gameinfo.flags = iwad_info->flags; + gameinfo.ConfigName = iwad_info->Configname; + lastIWAD = iwad; - Printf ("M_Init: Init menus.\n"); - M_Init (); + FBaseCVar::DisableCallbacks(); + GameConfig->DoGameSetup (gameinfo.ConfigName); - Printf ("P_Init: Init Playloop state.\n"); - StartScreen->LoadingStatus ("Init game engine", 0x3f); - AM_StaticInit(); - P_Init (); + AddAutoloadFiles(iwad_info->Autoname); - P_SetupWeapons_ntohton(); + // Run automatically executed files + execFiles = new DArgs; + GameConfig->AddAutoexec (execFiles, gameinfo.ConfigName); + D_MultiExec (execFiles, true); - //SBarInfo support. - SBarInfo::Load(); - HUD_InitHud(); + // Run .cfg files at the start of the command line. + execFiles = Args->GatherFiles ("-exec"); + D_MultiExec (execFiles, true); - // [RH] User-configurable startup strings. Because BOOM does. - static const char *startupString[5] = { - "STARTUP1", "STARTUP2", "STARTUP3", "STARTUP4", "STARTUP5" - }; - for (p = 0; p < 5; ++p) - { - const char *str = GStrings[startupString[p]]; - if (str != NULL && str[0] != '\0') - { - Printf ("%s\n", str); - } - } + C_ExecCmdLineParams (); // [RH] do all +set commands on the command line - Printf ("D_CheckNetGame: Checking network game status.\n"); - StartScreen->LoadingStatus ("Checking network game status.", 0x3f); - D_CheckNetGame (); + CopyFiles(allwads, pwads); - // [RH] Lock any cvars that should be locked now that we're - // about to begin the game. - FBaseCVar::EnableNoSet (); + // Since this function will never leave we must delete this array here manually. + pwads.Clear(); + pwads.ShrinkToFit(); - delete iwad_man; // now we won't need this anymore - - // [RH] Run any saved commands from the command line or autoexec.cfg now. - gamestate = GS_FULLCONSOLE; - Net_NewMakeTic (); - DThinker::RunThinkers (); - gamestate = GS_STARTUP; - - // start the apropriate game based on parms - v = Args->CheckValue ("-record"); - - if (v) - { - G_RecordDemo (v); - autostart = true; - } - - delete StartScreen; - StartScreen = NULL; - - if (Args->CheckParm("-norun")) - { - throw CNoRunExit(); - } - - V_Init2(); - - v = Args->CheckValue("-playdemo"); - if (v != NULL) - { - singledemo = true; // quit after one demo - G_DeferedPlayDemo (v); - D_DoomLoop (); // never returns - } - - v = Args->CheckValue ("-timedemo"); - if (v) - { - G_TimeDemo (v); - D_DoomLoop (); // never returns - } + Printf ("W_Init: Init WADfiles.\n"); + Wads.InitMultipleFiles (allwads); + allwads.Clear(); + allwads.ShrinkToFit(); + SetMapxxFlag(); - v = Args->CheckValue ("-loadgame"); - if (v) - { - FString file(v); - FixPathSeperator (file); - DefaultExtension (file, ".zds"); - G_LoadGame (file); - } + // [RH] Initialize localizable strings. + GStrings.LoadStrings (false); - if (gameaction != ga_loadgame) - { - if (autostart || netgame) + V_InitFontColors (); + + // [RH] Moved these up here so that we can do most of our + // startup output in a fullscreen console. + + CT_Init (); + + if (!restart) { - // Do not do any screenwipes when autostarting a game. - if (!Args->CheckParm("-warpwipe")) + Printf ("I_Init: Setting up machine state.\n"); + I_Init (); + } + + Printf ("V_Init: allocate screen.\n"); + V_Init (!!restart); + + // Base systems have been inited; enable cvar callbacks + FBaseCVar::EnableCallbacks (); + + Printf ("S_Init: Setting up sound.\n"); + S_Init (); + + Printf ("ST_Init: Init startup screen.\n"); + if (!restart) StartScreen = FStartupScreen::CreateInstance (TexMan.GuesstimateNumTextures() + 5); + else StartScreen = new FStartupScreen(0); + + ParseCompatibility(); + + CheckCmdLine(); + + // [RH] Load sound environments + S_ParseReverbDef (); + + // [RH] Parse through all loaded mapinfo lumps + Printf ("G_ParseMapInfo: Load map definitions.\n"); + G_ParseMapInfo (iwad_info->MapInfo); + ReadStatistics(); + + // [RH] Parse any SNDINFO lumps + Printf ("S_InitData: Load sound definitions.\n"); + S_InitData (); + + Printf ("Texman.Init: Init texture manager.\n"); + TexMan.Init(); + C_InitConback(); + + // [CW] Parse any TEAMINFO lumps. + Printf ("ParseTeamInfo: Load team definitions.\n"); + TeamLibrary.ParseTeamInfo (); + + FActorInfo::StaticInit (); + + // [GRB] Initialize player class list + SetupPlayerClasses (); + + + // [RH] Load custom key and weapon settings from WADs + D_LoadWadSettings (); + + // [GRB] Check if someone used clearplayerclasses but not addplayerclass + if (PlayerClasses.Size () == 0) + { + I_FatalError ("No player classes defined"); + } + + StartScreen->Progress (); + + Printf ("R_Init: Init %s refresh subsystem.\n", gameinfo.ConfigName.GetChars()); + StartScreen->LoadingStatus ("Loading graphics", 0x3f); + R_Init (); + + Printf ("DecalLibrary: Load decals.\n"); + DecalLibrary.ReadAllDecals (); + + // [RH] Add any .deh and .bex files on the command line. + // If there are none, try adding any in the config file. + // Note that the command line overrides defaults from the config. + + if ((ConsiderPatches("-deh") | ConsiderPatches("-bex")) == 0 && + gameinfo.gametype == GAME_Doom && GameConfig->SetSection ("Doom.DefaultDehacked")) + { + const char *key; + const char *value; + + while (GameConfig->NextInSection (key, value)) { - NoWipe = TICRATE; + if (stricmp (key, "Path") == 0 && FileExists (value)) + { + Printf ("Applying patch %s\n", value); + D_LoadDehFile(value); + } } - CheckWarpTransMap (startmap, true); - if (demorecording) - G_BeginRecording (startmap); - G_InitNew (startmap, false); + } + + // Load embedded Dehacked patches + D_LoadDehLumps(); + + // Create replacements for dehacked pickups + FinishDehPatch(); + + FActorInfo::StaticSetActorNums (); + + //Added by MC: + bglobal.getspawned.Clear(); + argcount = Args->CheckParmList("-bots", &args); + for (p = 0; p < argcount; ++p) + { + bglobal.getspawned.Push(args[p]); + } + bglobal.spawn_tries = 0; + bglobal.wanted_botnum = bglobal.getspawned.Size(); + + Printf ("M_Init: Init menus.\n"); + M_Init (); + + Printf ("P_Init: Init Playloop state.\n"); + StartScreen->LoadingStatus ("Init game engine", 0x3f); + AM_StaticInit(); + P_Init (); + + P_SetupWeapons_ntohton(); + + //SBarInfo support. + SBarInfo::Load(); + HUD_InitHud(); + + // [RH] User-configurable startup strings. Because BOOM does. + static const char *startupString[5] = { + "STARTUP1", "STARTUP2", "STARTUP3", "STARTUP4", "STARTUP5" + }; + for (p = 0; p < 5; ++p) + { + const char *str = GStrings[startupString[p]]; + if (str != NULL && str[0] != '\0') + { + Printf ("%s\n", str); + } + } + + if (!restart) + { + Printf ("D_CheckNetGame: Checking network game status.\n"); + StartScreen->LoadingStatus ("Checking network game status.", 0x3f); + D_CheckNetGame (); + } + + // [RH] Lock any cvars that should be locked now that we're + // about to begin the game. + FBaseCVar::EnableNoSet (); + + delete iwad_man; // now we won't need this anymore + + // [RH] Run any saved commands from the command line or autoexec.cfg now. + gamestate = GS_FULLCONSOLE; + Net_NewMakeTic (); + DThinker::RunThinkers (); + gamestate = GS_STARTUP; + + if (!restart) + { + // start the apropriate game based on parms + v = Args->CheckValue ("-record"); + + if (v) + { + G_RecordDemo (v); + autostart = true; + } + + delete StartScreen; + StartScreen = NULL; + + if (Args->CheckParm("-norun")) + { + throw CNoRunExit(); + } + + V_Init2(); + + v = Args->CheckValue("-playdemo"); + if (v != NULL) + { + singledemo = true; // quit after one demo + G_DeferedPlayDemo (v); + D_DoomLoop (); // never returns + } + + v = Args->CheckValue ("-timedemo"); + if (v) + { + G_TimeDemo (v); + D_DoomLoop (); // never returns + } + + v = Args->CheckValue ("-loadgame"); + if (v) + { + FString file(v); + FixPathSeperator (file); + DefaultExtension (file, ".zds"); + G_LoadGame (file); + } + + if (gameaction != ga_loadgame) + { + if (autostart || netgame) + { + // Do not do any screenwipes when autostarting a game. + if (!Args->CheckParm("-warpwipe")) + { + NoWipe = TICRATE; + } + CheckWarpTransMap (startmap, true); + if (demorecording) + G_BeginRecording (startmap); + G_InitNew (startmap, false); + } + else + { + D_StartTitle (); // start up intro loop + } + } + else if (demorecording) + { + G_BeginRecording (NULL); + } + + atterm (D_QuitNetGame); // killough } else { + // These calls from inside V_Init2 are still necessary + C_NewModeAdjust(); + M_InitVideoModesMenu(); D_StartTitle (); // start up intro loop + setmodeneeded = false; // This may be set to true here, but isn't needed for a restart + } + + try + { + D_DoomLoop (); // never returns + } + catch (CRestartException &ex) + { + // Music and sound should be stopped first + S_StopMusic(true); + S_StopAllChannels (); + + // clean up game state + ST_Clear(); + D_ErrorCleanup (); + P_FreeLevelData(); + P_FreeExtraLevelData(); + + M_SaveDefaults(NULL); // save config before the restart + + // delete all data that cannot be left until reinitialization + V_ClearFonts(); // must clear global font pointers + R_DeinitTranslationTables(); // some tables are initialized from outside the translation code. + gameinfo.~gameinfo_t(); + new (&gameinfo) gameinfo_t; // Reset gameinfo + S_Shutdown(); // free all channels and delete playlist + C_ClearAliases(); // CCMDs won't be reinitialized so these need to be deleted here + + GC::FullGC(); // perform one final garbage collection before deleting the class data + PClass::ClearRuntimeData(); // clear all runtime generated class data + restart++; } } - else if (demorecording) - { - G_BeginRecording (NULL); - } - - atterm (D_QuitNetGame); // killough + while (1); +} - D_DoomLoop (); // never returns +//========================================================================== +// +// restart the game +// +//========================================================================== + +CCMD(restart) +{ + // remove command line args that would get in the way during restart + Args->RemoveArgs("-iwad"); + Args->RemoveArgs("-deh"); + Args->RemoveArgs("-bex"); + Args->RemoveArgs("-playdemo"); + Args->RemoveArgs("-file"); + Args->RemoveArgs("-altdeath"); + Args->RemoveArgs("-deathmatch"); + Args->RemoveArgs("-skill"); + Args->RemoveArgs("-savedir"); + Args->RemoveArgs("-xlat"); + Args->RemoveArgs("-oldsprites"); + + if (argv.argc() > 1) + { + for(int i=1;iAppendArg(argv[i]); + } + } + + // initiate the restart + throw CRestartException(); } //========================================================================== @@ -2337,6 +2438,14 @@ void FStartupScreen::AppendStatusLine(const char *status) { } + +void FStartupScreen::Progress(void) {} +void FStartupScreen::NetInit(char const *,int) {} +void FStartupScreen::NetProgress(int) {} +void FStartupScreen::NetMessage(char const *,...) {} +void FStartupScreen::NetDone(void) {} +bool FStartupScreen::NetLoop(bool (*)(void *),void *) { return false; } + //========================================================================== // // STAT fps diff --git a/src/d_main.h b/src/d_main.h index 415a6b943..7dd75a107 100644 --- a/src/d_main.h +++ b/src/d_main.h @@ -36,6 +36,12 @@ struct event_t; // calls all startup code, parses command line options. // If not overrided by user input, calls N_AdvanceDemo. // + +struct CRestartException +{ + char dummy; +}; + void D_DoomMain (void); diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index f232d81f2..03a8d2ded 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -80,6 +80,24 @@ void PClass::StaticInit () } } +void PClass::ClearRuntimeData () +{ + StaticShutdown(); + + m_RuntimeActors.Clear(); + m_Types.Clear(); + memset(TypeHash, 0, sizeof(TypeHash)); + bShutdown = false; + + // Immediately reinitialize the internal classes + FAutoSegIterator probe(CRegHead, CRegTail); + + while (*++probe != NULL) + { + ((ClassReg *)*probe)->RegisterClass (); + } +} + void PClass::StaticShutdown () { TArray uniqueFPs(64); @@ -105,6 +123,8 @@ void PClass::StaticShutdown () uniqueFPs.Push(const_cast(type->FlatPointers)); } } + type->FlatPointers = NULL; + // For runtime classes, this call will also delete the PClass. PClass::StaticFreeData (type); } diff --git a/src/dobjtype.h b/src/dobjtype.h index e01929901..256e52ad8 100644 --- a/src/dobjtype.h +++ b/src/dobjtype.h @@ -125,6 +125,7 @@ struct PClass static void StaticInit (); static void StaticShutdown (); static void StaticFreeData (PClass *type); + static void ClearRuntimeData(); // Per-class information ------------------------------------- FName TypeName; // this class's name diff --git a/src/g_game.cpp b/src/g_game.cpp index e10936f93..85bc45fce 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -2573,6 +2573,7 @@ bool G_CheckDemoStatus (void) C_RestoreCVars (); // [RH] Restore cvars demo might have changed M_Free (demobuffer); + demobuffer = NULL; P_SetupWeapons_ntohton(); demoplayback = false; diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp index 09fb9417b..3091d63e3 100644 --- a/src/g_shared/shared_sbar.cpp +++ b/src/g_shared/shared_sbar.cpp @@ -253,6 +253,7 @@ void DBaseStatusBar::Destroy () msg->Destroy(); msg = next; } + Messages = NULL; Super::Destroy(); } diff --git a/src/intermission/intermission_parse.cpp b/src/intermission/intermission_parse.cpp index 183314cd7..fab4dca29 100644 --- a/src/intermission/intermission_parse.cpp +++ b/src/intermission/intermission_parse.cpp @@ -58,6 +58,7 @@ void DeinitIntermissions() delete pair->Value; pair->Value = NULL; } + IntermissionDescriptors.Clear(); } //========================================================================== diff --git a/src/m_argv.cpp b/src/m_argv.cpp index e414ca367..457a1b337 100644 --- a/src/m_argv.cpp +++ b/src/m_argv.cpp @@ -230,6 +230,26 @@ FString DArgs::TakeValue(const char *check) return out; } +//=========================================================================== +// +// DArgs :: RemoveArg +// +//=========================================================================== + +void DArgs::RemoveArgs(const char *check) +{ + int i = CheckParm(check); + + if (i > 0 && i < (int)Argv.Size() - 1) + { + do + { + RemoveArg(i); + } + while (Argv[i][0] != '+' && Argv[i][0] != '-' && i < (int)Argv.Size() - 1); + } +} + //=========================================================================== // // DArgs :: GetArg diff --git a/src/m_argv.h b/src/m_argv.h index 8b4fbf2dc..0fc107a05 100644 --- a/src/m_argv.h +++ b/src/m_argv.h @@ -54,6 +54,7 @@ public: void AppendArg(FString arg); void AppendArgs(int argc, const FString *argv); void RemoveArg(int argindex); + void RemoveArgs(const char *check); void SetArgs(int argc, char **argv); void CollectFiles(const char *param, const char *extension); DArgs *GatherFiles(const char *param) const; diff --git a/src/menu/menudef.cpp b/src/menu/menudef.cpp index 2a8da7d88..f413a9475 100644 --- a/src/menu/menudef.cpp +++ b/src/menu/menudef.cpp @@ -85,6 +85,8 @@ static void DeinitMenus() pair->Value = NULL; } } + MenuDescriptors.Clear(); + OptionValues.Clear(); DMenu::CurrentMenu = NULL; DefaultListMenuSettings.mItems.Clear(); ClearSaveGames(); @@ -1236,10 +1238,11 @@ void M_CreateMenus() // THe skill menu must be refeshed each time it starts up // //============================================================================= +extern int restart; void M_StartupSkillMenu(FGameStartup *gs) { - static bool done = false; + static int done = -1; bool success = false; FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_Skillmenu); if (desc != NULL) @@ -1265,9 +1268,9 @@ void M_StartupSkillMenu(FGameStartup *gs) } } - if (!done) + if (done != restart) { - done = true; + done = restart; int defskill = DefaultSkill; if ((unsigned int)defskill >= AllSkills.Size()) { diff --git a/src/s_sndseq.cpp b/src/s_sndseq.cpp index 19076055e..da02bcab4 100644 --- a/src/s_sndseq.cpp +++ b/src/s_sndseq.cpp @@ -502,6 +502,24 @@ static void AssignHexenTranslations (void) } } +//========================================================================== +// +// S_ClearSndSeq +// +//========================================================================== + +void S_ClearSndSeq() +{ + for (unsigned int i = 0; i < Sequences.Size(); i++) + { + if (Sequences[i]) + { + M_Free(Sequences[i]); + } + } + Sequences.Clear(); +} + //========================================================================== // // S_ParseSndSeq @@ -523,14 +541,7 @@ void S_ParseSndSeq (int levellump) // First free the old SNDSEQ data. This allows us to reload this for each level // and specify a level specific SNDSEQ lump! - for (unsigned int i = 0; i < Sequences.Size(); i++) - { - if (Sequences[i]) - { - M_Free(Sequences[i]); - } - } - Sequences.Clear(); + S_ClearSndSeq(); // be gone, compiler warnings stopsound = 0; diff --git a/src/st_start.h b/src/st_start.h index 3b90aa06f..4ba475e73 100644 --- a/src/st_start.h +++ b/src/st_start.h @@ -42,15 +42,15 @@ public: FStartupScreen(int max_progress); virtual ~FStartupScreen(); - virtual void Progress() = 0; + virtual void Progress(); virtual void LoadingStatus(const char *message, int colors); // Used by Heretic only virtual void AppendStatusLine(const char *status); // Used by Heretic only - virtual void NetInit(const char *message, int num_players) = 0; - virtual void NetProgress(int count) = 0; - virtual void NetMessage(const char *format, ...) = 0; // cover for printf - virtual void NetDone() = 0; - virtual bool NetLoop(bool (*timer_callback)(void *), void *userdata) = 0; + virtual void NetInit(const char *message, int num_players); + virtual void NetProgress(int count); + virtual void NetMessage(const char *format, ...); // cover for printf + virtual void NetDone(); + virtual bool NetLoop(bool (*timer_callback)(void *), void *userdata); protected: int MaxPos, CurPos, NotchPos; }; diff --git a/src/v_palette.cpp b/src/v_palette.cpp index 7761a3dec..4db1ad57c 100644 --- a/src/v_palette.cpp +++ b/src/v_palette.cpp @@ -447,6 +447,7 @@ void InitPalette () int lump; atterm (FreeSpecialLights); + FreeSpecialLights(); if ((lump = Wads.CheckNumForFullName ("palette.dat")) >= 0 && Wads.LumpLength (lump) >= 768) { @@ -780,6 +781,7 @@ static void FreeSpecialLights() delete[] colormap->Maps; delete colormap; } + NormalLight.Next = NULL; } // Builds NUMCOLORMAPS colormaps lit with the specified color diff --git a/src/v_video.cpp b/src/v_video.cpp index ae09f9b78..26632fb62 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -1605,7 +1605,7 @@ CCMD (vid_setmode) // V_Init // -void V_Init (void) +void V_Init (bool restart) { const char *i; int width, height, bits; @@ -1615,40 +1615,43 @@ void V_Init (void) // [RH] Initialize palette management InitPalette (); - width = height = bits = 0; - - if ( (i = Args->CheckValue ("-width")) ) - width = atoi (i); - - if ( (i = Args->CheckValue ("-height")) ) - height = atoi (i); - - if ( (i = Args->CheckValue ("-bits")) ) - bits = atoi (i); - - if (width == 0) + if (!restart) { - if (height == 0) + width = height = bits = 0; + + if ( (i = Args->CheckValue ("-width")) ) + width = atoi (i); + + if ( (i = Args->CheckValue ("-height")) ) + height = atoi (i); + + if ( (i = Args->CheckValue ("-bits")) ) + bits = atoi (i); + + if (width == 0) { - width = vid_defwidth; - height = vid_defheight; + if (height == 0) + { + width = vid_defwidth; + height = vid_defheight; + } + else + { + width = (height * 8) / 6; + } } - else + else if (height == 0) { - width = (height * 8) / 6; + height = (width * 6) / 8; } - } - else if (height == 0) - { - height = (width * 6) / 8; + + if (bits == 0) + { + bits = vid_defbits; + } + screen = new DDummyFrameBuffer (width, height); } - if (bits == 0) - { - bits = vid_defbits; - } - - screen = new DDummyFrameBuffer (width, height); BuildTransTable (GPalette.BaseColors); } diff --git a/src/v_video.h b/src/v_video.h index f4fb6f5bf..ac7f6dea3 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -473,7 +473,7 @@ extern "C" DWORD Col2RGB8_Inverse[65][256]; // --111111111111111111111111111111 = 0x3FFFFFFF // Allocates buffer screens, call before R_Init. -void V_Init (); +void V_Init (bool restart); // Initializes graphics mode for the first time. void V_Init2 ();