Blood: cleanup of INI loading

* use snprintf instead of sprintf
* keep the IniFile object local
* get rid of the FreeGameData interface function, it only existed to free the global INI object.
This commit is contained in:
Christoph Oelckers 2023-09-30 22:31:52 +02:00
parent bb6d6ae83b
commit 26ba62dc62
7 changed files with 54 additions and 91 deletions

View file

@ -637,10 +637,6 @@ int GameMain()
DeinitMenus(); DeinitMenus();
if (StatusBar) StatusBar->Destroy(); if (StatusBar) StatusBar->Destroy();
StatusBar = nullptr; StatusBar = nullptr;
if (gi)
{
gi->FreeGameData(); // Must be done before taking down any subsystems.
}
S_StopMusic(true); S_StopMusic(true);
if (soundEngine) delete soundEngine; if (soundEngine) delete soundEngine;
soundEngine = nullptr; soundEngine = nullptr;

View file

@ -73,7 +73,6 @@ struct GameInterface
virtual void SetupSpecialTextures(TilesetBuildInfo&) = 0; virtual void SetupSpecialTextures(TilesetBuildInfo&) = 0;
virtual void loadPalette() = 0; virtual void loadPalette() = 0;
virtual void FreeLevelData(); virtual void FreeLevelData();
virtual void FreeGameData() {}
virtual void PlayHudSound() {} virtual void PlayHudSound() {}
virtual GameStats getStats() { return {}; } virtual GameStats getStats() { return {}; }
virtual void MenuOpened() {} virtual void MenuOpened() {}

View file

@ -671,12 +671,6 @@ void sndPlaySpecialMusicOrNothing(int nMusic)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
extern IniFile* BloodINI;
void GameInterface::FreeGameData()
{
if (BloodINI) delete BloodINI;
}
void GameInterface::FreeLevelData() void GameInterface::FreeLevelData()
{ {
EndLevel(); EndLevel();

View file

@ -106,7 +106,6 @@ struct GameInterface : public ::GameInterface
void loadPalette() override; void loadPalette() override;
bool GenerateSavePic() override; bool GenerateSavePic() override;
void FreeLevelData() override; void FreeLevelData() override;
void FreeGameData() override;
FSavegameInfo GetSaveSig() override; FSavegameInfo GetSaveSig() override;
void MenuOpened() override; void MenuOpened() override;
void MenuClosed() override; void MenuClosed() override;

View file

@ -1,7 +1,7 @@
/* /*
* Copyright (C) 2018, 2022 nukeykt * Copyright (C) 2018, 2022 nukeykt
* *
* This file is part of Blood-RE. * This file is part of Raze
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License

View file

@ -1,25 +1,21 @@
//-------------------------------------------------------------------------
/* /*
Copyright (C) 2010-2019 EDuke32 developers and contributors * Copyright (C) 2018, 2022 nukeykt
Copyright (C) 2019 Nuke.YKT * Copyright (C) 2020-2022 Christoph Oelckers
*
* This file is part of Raze
*
* 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.
*
*/
This file is part of NBlood.
NBlood is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#include "ns.h" // Must come before everything else! #include "ns.h" // Must come before everything else!
#include <stdlib.h> #include <stdlib.h>
@ -40,10 +36,12 @@ GAMEOPTIONS gSingleGameOptions = {
int gSkill = 2; int gSkill = 2;
MapRecord* gNextLevel; MapRecord* gNextLevel;
char BloodIniFile[BMAX_PATH] = "BLOOD.INI"; enum
bool bINIOverride = false; {
IniFile* BloodINI; kMaxMessages = 32,
kMaxEpisodes = 7,
kMaxLevels = 16
};
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// //
@ -51,26 +49,11 @@ IniFile* BloodINI;
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void levelInitINI(const char* pzIni) static IniFile* levelInitINI(const char* pzIni)
{ {
if (!fileSystem.FileExists(pzIni)) if (!fileSystem.FileExists(pzIni))
I_Error("Initialization: %s does not exist", pzIni); I_Error("%s: Ini file not found", pzIni);
BloodINI = new IniFile(pzIni); return new IniFile(pzIni);
strncpy(BloodIniFile, pzIni, BMAX_PATH - 1);
}
void CheckSectionAbend(const char* pzSection)
{
if (!pzSection || !BloodINI->SectionExists(pzSection))
I_Error("Section [%s] expected in BLOOD.INI", pzSection);
}
void CheckKeyAbend(const char* pzSection, const char* pzKey)
{
assert(pzSection != NULL);
if (!pzKey || !BloodINI->KeyExists(pzSection, pzKey))
I_Error("Key %s expected in section [%s] of BLOOD.INI", pzKey, pzSection);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -79,12 +62,13 @@ void CheckKeyAbend(const char* pzSection, const char* pzKey)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void levelLoadMapInfo(IniFile* pIni, MapRecord* pLevelInfo, const char* pzSection, int epinum, int mapnum, int* nextmap, int* nextsecret) static void levelLoadMapInfo(IniFile* pIni, MapRecord* pLevelInfo, const char* pzSection, int epinum, int mapnum, int* nextmap, int* nextsecret)
{ {
char buffer[16]; char buffer[16];
pLevelInfo->SetName(pIni->GetKeyString(pzSection, "Title", pLevelInfo->labelName)); pLevelInfo->SetName(pIni->GetKeyString(pzSection, "Title", pLevelInfo->labelName));
pLevelInfo->Author = pIni->GetKeyString(pzSection, "Author", ""); pLevelInfo->Author = pIni->GetKeyString(pzSection, "Author", "");
pLevelInfo->music = pIni->GetKeyString(pzSection, "Song", ""); if (pLevelInfo->music.IsNotEmpty()) DefaultExtension(pLevelInfo->music, ".mid"); pLevelInfo->music = pIni->GetKeyString(pzSection, "Song", "");
if (pLevelInfo->music.IsNotEmpty()) DefaultExtension(pLevelInfo->music, ".mid");
pLevelInfo->cdSongId = pIni->GetKeyInt(pzSection, "Track", -1); pLevelInfo->cdSongId = pIni->GetKeyInt(pzSection, "Track", -1);
*nextmap = pIni->GetKeyInt(pzSection, "EndingA", 0); *nextmap = pIni->GetKeyInt(pzSection, "EndingA", 0);
*nextsecret = pIni->GetKeyInt(pzSection, "EndingB", 0); *nextsecret = pIni->GetKeyInt(pzSection, "EndingB", 0);
@ -92,7 +76,7 @@ void levelLoadMapInfo(IniFile* pIni, MapRecord* pLevelInfo, const char* pzSectio
pLevelInfo->weather = pIni->GetKeyInt(pzSection, "Weather", -0); pLevelInfo->weather = pIni->GetKeyInt(pzSection, "Weather", -0);
for (int i = 0; i < kMaxMessages; i++) for (int i = 0; i < kMaxMessages; i++)
{ {
sprintf(buffer, "Message%d", i + 1); snprintf(buffer, 16, "Message%d", i + 1);
auto msg = pIni->GetKeyString(pzSection, buffer, ""); auto msg = pIni->GetKeyString(pzSection, buffer, "");
pLevelInfo->AddMessage(i, msg); pLevelInfo->AddMessage(i, msg);
} }
@ -184,53 +168,58 @@ void levelLoadDefaults(void)
int cutALevel = 0; int cutALevel = 0;
levelInitINI(DefFile()); auto fn = DefFile();
std::unique_ptr<IniFile> pIni(levelInitINI(fn));
int i; int i;
for (i = 1; i <= kMaxEpisodes; i++) for (i = 1; i <= kMaxEpisodes; i++)
{ {
sprintf(buffer, "Episode%d", i); snprintf(buffer, 64, "Episode%d", i);
if (!BloodINI->SectionExists(buffer)) if (!pIni->SectionExists(buffer))
break; break;
auto cluster = MustFindCluster(i); auto cluster = MustFindCluster(i);
auto volume = MustFindVolume(i); auto volume = MustFindVolume(i);
CutsceneDef& csB = cluster->outro; CutsceneDef& csB = cluster->outro;
FString ep_str = BloodINI->GetKeyString(buffer, "Title", buffer); FString ep_str = pIni->GetKeyString(buffer, "Title", buffer);
ep_str.StripRight(); ep_str.StripRight();
cluster->name = volume->name = FStringTable::MakeMacro(ep_str); cluster->name = volume->name = FStringTable::MakeMacro(ep_str);
if (i > 1) volume->flags |= VF_SHAREWARELOCK; if (i > 1) volume->flags |= VF_SHAREWARELOCK;
if (BloodINI->GetKeyInt(buffer, "BloodBathOnly", 0)) volume->flags |= VF_HIDEFROMSP; if (pIni->GetKeyInt(buffer, "BloodBathOnly", 0)) volume->flags |= VF_HIDEFROMSP;
csB.video = cleanPath(BloodINI->GetKeyString(buffer, "CutSceneB", "")); csB.video = cleanPath(pIni->GetKeyString(buffer, "CutSceneB", ""));
int soundint = BloodINI->GetKeyInt(buffer, "CutWavB", -1); int soundint = pIni->GetKeyInt(buffer, "CutWavB", -1);
if (soundint > 0) csB.soundID = soundint + 0x40000000; if (soundint > 0) csB.soundID = soundint + 0x40000000;
else csB.soundName = cleanPath(BloodINI->GetKeyString(buffer, "CutWavB", "")); else csB.soundName = cleanPath(pIni->GetKeyString(buffer, "CutWavB", ""));
//pEpisodeInfo->bloodbath = BloodINI->GetKeyInt(buffer, "BloodBathOnly", 0); cutALevel = pIni->GetKeyInt(buffer, "CutSceneALevel", 0);
cutALevel = BloodINI->GetKeyInt(buffer, "CutSceneALevel", 0);
if (cutALevel < 1) cutALevel = 1; if (cutALevel < 1) cutALevel = 1;
int nextmaps[kMaxLevels]{}, nextsecrets[kMaxLevels]{}; int nextmaps[kMaxLevels]{}, nextsecrets[kMaxLevels]{};
for (int j = 1; j <= kMaxLevels; j++) for (int j = 1; j <= kMaxLevels; j++)
{ {
sprintf(buffer2, "Map%d", j); snprintf(buffer2, 16, "Map%d", j);
if (!BloodINI->KeyExists(buffer, buffer2)) if (!pIni->KeyExists(buffer, buffer2))
break; break;
auto pLevelInfo = AllocateMap(); auto pLevelInfo = AllocateMap();
const char* pMap = BloodINI->GetKeyString(buffer, buffer2, NULL); const char* pMap = pIni->GetKeyString(buffer, buffer2, NULL);
CheckSectionAbend(pMap);
if (!pMap || !pIni->SectionExists(pMap))
I_Error("Section [%s] expected in %s", buffer2, fn);
SetLevelNum(pLevelInfo, makelevelnum(i, j)); SetLevelNum(pLevelInfo, makelevelnum(i, j));
pLevelInfo->cluster = i; pLevelInfo->cluster = i;
pLevelInfo->labelName = pMap; pLevelInfo->labelName = pMap;
if (j == 1) volume->startmap = pLevelInfo->labelName; if (j == 1) volume->startmap = pLevelInfo->labelName;
pLevelInfo->fileName.Format("%s.map", pMap); pLevelInfo->fileName.Format("%s.map", pMap);
levelLoadMapInfo(BloodINI, pLevelInfo, pMap, i, j, &nextmaps[j - 1], &nextsecrets[j - 1]); levelLoadMapInfo(pIni.get(), pLevelInfo, pMap, i, j, &nextmaps[j - 1], &nextsecrets[j - 1]);
if (j == cutALevel) if (j == cutALevel)
{ {
CutsceneDef& csA = pLevelInfo->intro; CutsceneDef& csA = pLevelInfo->intro;
csA.video = cleanPath(BloodINI->GetKeyString(buffer, "CutSceneA", "")); csA.video = cleanPath(pIni->GetKeyString(buffer, "CutSceneA", ""));
int soundfileint = BloodINI->GetKeyInt(buffer, "CutWavA", -1); int soundfileint = pIni->GetKeyInt(buffer, "CutWavA", -1);
if (soundfileint > 0) csA.soundID = soundfileint + 0x40000000; if (soundfileint > 0) csA.soundID = soundfileint + 0x40000000;
else csA.soundName = cleanPath(BloodINI->GetKeyString(buffer, "CutWavA", "")); else csA.soundName = cleanPath(pIni->GetKeyString(buffer, "CutWavA", ""));
} }
} }
// Now resolve the level links // Now resolve the level links

View file

@ -29,20 +29,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
BEGIN_BLD_NS BEGIN_BLD_NS
enum
{
kMaxMessages = 32,
kMaxEpisodes = 7,
kMaxLevels = 16
};
#pragma pack(push, 1) #pragma pack(push, 1)
enum EGameFlag enum EGameFlag
{ {
GF_AdvanceLevel = 1, GF_AdvanceLevel = 1,
// 4 was for playing intro cutscenes but is no longer used.
GF_PlayCutscene = 8,
}; };
struct GAMEOPTIONS { struct GAMEOPTIONS {
@ -69,14 +60,9 @@ struct GAMEOPTIONS {
extern GAMEOPTIONS gSingleGameOptions; extern GAMEOPTIONS gSingleGameOptions;
extern GAMEOPTIONS gGameOptions; extern GAMEOPTIONS gGameOptions;
extern int gSkill; extern int gSkill;
extern char BloodIniFile[];
extern bool bINIOverride;
extern MapRecord* gNextLevel; extern MapRecord* gNextLevel;
extern bool gGameStarted; extern bool gGameStarted;
void levelInitINI(const char* pzIni);
void CheckSectionAbend(const char* pzSection);
void CheckKeyAbend(const char* pzSection, const char* pzKey);
void levelLoadDefaults(void); void levelLoadDefaults(void);
// arg: 0 is normal exit, 1 is secret level // arg: 0 is normal exit, 1 is secret level
void levelEndLevel(int arg); void levelEndLevel(int arg);