- Blood now also starts the first level without leaks.

I had to refactor the LoadSave data to allow automatic takedown, the linked list was not the most convenient thing - an array is better.
This commit is contained in:
Christoph Oelckers 2019-12-24 19:47:34 +01:00
parent 2820dc85a8
commit 43033e830a
12 changed files with 38 additions and 28 deletions

View file

@ -104,8 +104,6 @@ short BloodVersion = 0x115;
int gNetPlayers; int gNetPlayers;
char *pUserTiles = NULL; char *pUserTiles = NULL;
char *pUserSoundRFF = NULL;
char *pUserRFF = NULL;
int gChokeCounter = 0; int gChokeCounter = 0;
@ -177,8 +175,6 @@ void ShutDown(void)
if (syncstate) if (syncstate)
printf("A packet was lost! (syncstate)\n"); printf("A packet was lost! (syncstate)\n");
DO_FREE_AND_NULL(pUserTiles); DO_FREE_AND_NULL(pUserTiles);
DO_FREE_AND_NULL(pUserSoundRFF);
DO_FREE_AND_NULL(pUserRFF);
} }
void QuitGame(void) void QuitGame(void)
@ -1965,6 +1961,13 @@ void sndPlaySpecialMusicOrNothing(int nMusic)
} }
} }
extern IniFile* BloodINI;
void GameInterface::FreeGameData()
{
if (BloodINI) delete BloodINI;
ShutDown();
}
::GameInterface* CreateInterface() ::GameInterface* CreateInterface()
{ {

View file

@ -84,6 +84,7 @@ struct GameInterface : ::GameInterface
{ {
void faketimerhandler() override; void faketimerhandler() override;
int app_main() override; int app_main() override;
void FreeGameData() override;
bool validate_hud(int) override; bool validate_hud(int) override;
void set_hud_layout(int size) override; void set_hud_layout(int size) override;
void set_hud_scale(int size) override; void set_hud_scale(int size) override;

View file

@ -49,6 +49,10 @@ public:
{ {
PQueue = NULL; PQueue = NULL;
} }
~EventQueue()
{
if (PQueue) delete PQueue;
}
bool IsNotEmpty(unsigned int nTime) bool IsNotEmpty(unsigned int nTime)
{ {
return PQueue->Size() > 0 && nTime >= PQueue->LowestPriority(); return PQueue->Size() > 0 && nTime >= PQueue->LowestPriority();

View file

@ -60,9 +60,9 @@ unsigned int dword_27AA3C = 0;
unsigned int dword_27AA40 = 0; unsigned int dword_27AA40 = 0;
void *dword_27AA44 = NULL; void *dword_27AA44 = NULL;
LoadSave LoadSave::head(123);
FileWriter *LoadSave::hSFile = NULL; FileWriter *LoadSave::hSFile = NULL;
FileReader LoadSave::hLFile; FileReader LoadSave::hLFile;
TDeletingArray<LoadSave*> LoadSave::loadSaves;
short word_27AA54 = 0; short word_27AA54 = 0;
@ -121,11 +121,10 @@ bool GameInterface::LoadGame(FSaveGameNode* node)
LoadSave::hLFile = ReadSavegameChunk("snapshot.bld"); LoadSave::hLFile = ReadSavegameChunk("snapshot.bld");
if (!LoadSave::hLFile.isOpen()) if (!LoadSave::hLFile.isOpen())
return false; return false;
LoadSave *rover = LoadSave::head.next;
while (rover != &LoadSave::head) for (auto rover : LoadSave::loadSaves)
{ {
rover->Load(); rover->Load();
rover = rover->next;
} }
LoadSave::hLFile.Close(); LoadSave::hLFile.Close();
@ -193,14 +192,12 @@ bool GameInterface::SaveGame(FSaveGameNode* node)
{ {
dword_27AA38 = 0; dword_27AA38 = 0;
dword_27AA40 = 0; dword_27AA40 = 0;
LoadSave* rover = LoadSave::head.next; for (auto rover : LoadSave::loadSaves)
while (rover != &LoadSave::head)
{ {
rover->Save(); rover->Save();
if (dword_27AA38 > dword_27AA40) if (dword_27AA38 > dword_27AA40)
dword_27AA40 = dword_27AA38; dword_27AA40 = dword_27AA38;
dword_27AA38 = 0; dword_27AA38 = 0;
rover = rover->next;
} }
} }
catch (std::runtime_error & err) catch (std::runtime_error & err)

View file

@ -32,18 +32,9 @@ public:
static LoadSave head; static LoadSave head;
static FileWriter *hSFile; static FileWriter *hSFile;
static FileReader hLFile; static FileReader hLFile;
LoadSave *prev; static TDeletingArray<LoadSave*> loadSaves;
LoadSave *next;
LoadSave() { LoadSave() {
prev = head.prev; loadSaves.Push(this);
prev->next = this;
next = &head;
next->prev = this;
}
LoadSave(int dummy)
{
UNREFERENCED_PARAMETER(dummy);
next = prev = this;
} }
//~LoadSave() { } //~LoadSave() { }
virtual void Save(void); virtual void Save(void);

View file

@ -55,6 +55,7 @@ extern void videoFadeToBlack(int32_t moreopaquep);
void paletteMakeLookupTable(int32_t palnum, const char *remapbuf, uint8_t r, uint8_t g, uint8_t b, char noFloorPal); void paletteMakeLookupTable(int32_t palnum, const char *remapbuf, uint8_t r, uint8_t g, uint8_t b, char noFloorPal);
void paletteSetColorTable(int32_t id, uint8_t const *table, bool transient = false); void paletteSetColorTable(int32_t id, uint8_t const *table, bool transient = false);
void paletteFreeColorTable(int32_t id); void paletteFreeColorTable(int32_t id);
void paletteFreeColorTables();
void paletteSetBlendTable(int32_t blend, const char *tab); void paletteSetBlendTable(int32_t blend, const char *tab);
void paletteFreeBlendTable(int32_t blend); void paletteFreeBlendTable(int32_t blend);
int32_t paletteSetLookupTable(int32_t palnum, const uint8_t *shtab); int32_t paletteSetLookupTable(int32_t palnum, const uint8_t *shtab);

View file

@ -729,6 +729,13 @@ void paletteFreeColorTable(int32_t const id)
DO_FREE_AND_NULL(basepaltable[id]); DO_FREE_AND_NULL(basepaltable[id]);
} }
void paletteFreeColorTables()
{
for (int i = 0; i < countof(basepaltable); i++)
{
paletteFreeColorTable(i);
}
}
// //
// setbrightness // setbrightness
// //

View file

@ -320,6 +320,7 @@ int GameMain()
TileFiles.CloseAll(); // do this before shutting down graphics. TileFiles.CloseAll(); // do this before shutting down graphics.
GLInterface.Deinit(); GLInterface.Deinit();
I_ShutdownGraphics(); I_ShutdownGraphics();
paletteFreeColorTables();
gi->FreeGameData(); gi->FreeGameData();
if (gi) delete gi; if (gi) delete gi;
#ifndef NETCODE_DISABLE #ifndef NETCODE_DISABLE

View file

@ -422,6 +422,12 @@ void M_ActivateMenu(DMenu *menu)
bool M_SetMenu(FName menu, int param, FName caller) bool M_SetMenu(FName menu, int param, FName caller)
{ {
#if 0
// skip the menu and go right into the first level.
// For tracking memory leaks that normally require operating the menu to start the game so that they always get the same allocation number.
GameStartupInfo.Episode = GameStartupInfo.Skill = 0;
menu = NAME_StartGame;
#endif
if (DrawBackground == -1) if (DrawBackground == -1)
{ {
if (menu == NAME_MainMenu) DrawBackground = 1; if (menu == NAME_MainMenu) DrawBackground = 1;

View file

@ -123,12 +123,11 @@ class FImageTexture : public FTexture
FImageSource *mImage; FImageSource *mImage;
public: public:
FImageTexture (FImageSource *image, const char *name = nullptr); FImageTexture (FImageSource *image, const char *name = nullptr);
void Create8BitPixels(uint8_t* buffer) override; ~FImageTexture()
void SetImage(FImageSource *img) // This is only for the multipatch texture builder!
{ {
mImage = img; if (mImage) delete mImage;
} }
void Create8BitPixels(uint8_t* buffer) override;
FImageSource *GetImage() const override { return mImage; } FImageSource *GetImage() const override { return mImage; }
FBitmap GetBgraBitmap(const PalEntry *p, int *trans) override; FBitmap GetBgraBitmap(const PalEntry *p, int *trans) override;

View file

@ -1173,7 +1173,7 @@ int WINAPI wWinMain (HINSTANCE hInstance, HINSTANCE nothing, LPWSTR cmdline, int
// Use this to break at a specific allocation number. // Use this to break at a specific allocation number.
// _crtBreakAlloc = 257481; _crtBreakAlloc = 253018;
#endif #endif
int ret = DoMain (hInstance); int ret = DoMain (hInstance);

View file

@ -123,7 +123,7 @@ FStartupScreen *FStartupScreen::CreateInstance(int max_progress)
FBasicStartupScreen::FBasicStartupScreen(int max_progress, bool show_bar) FBasicStartupScreen::FBasicStartupScreen(int max_progress, bool show_bar)
: FStartupScreen(max_progress) : FStartupScreen(max_progress)
{ {
if (show_bar) if (false)//show_bar)
{ {
ProgressBar = CreateWindowEx(0, PROGRESS_CLASS, ProgressBar = CreateWindowEx(0, PROGRESS_CLASS,
NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS,