forked from speed-dreams/speed-dreams-code
Implemented restart of Memory Manager while restart()
DisplayMenu allocates data but had no destructor to free it GButtons did not free userDataOnFocus git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@5839 30fe4595-0a0c-4342-8851-515496e4dcbd Former-commit-id: ca943f98b94e089d277b533d709d601fb0ff39fd Former-commit-id: 50b1f006e658b859c9f30d1200fd4610612bf330
This commit is contained in:
parent
f8f4ea55a3
commit
27a2db6688
12 changed files with 146 additions and 45 deletions
|
@ -38,6 +38,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <portability.h>
|
#include <portability.h>
|
||||||
|
#include "..\tgfdata\tgfdata.h"
|
||||||
|
|
||||||
#include "tgf.hpp"
|
#include "tgf.hpp"
|
||||||
|
|
||||||
|
@ -213,6 +214,12 @@ void GfApplication::restart()
|
||||||
|
|
||||||
// Delete the event loop if any.
|
// Delete the event loop if any.
|
||||||
delete _pEventLoop;
|
delete _pEventLoop;
|
||||||
|
_pEventLoop = 0;
|
||||||
|
|
||||||
|
// Reset the Memory Manager
|
||||||
|
#ifdef __DEBUG_MEMORYMANAGER__
|
||||||
|
(*ReleaseData)();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Restart the process, using same command line args.
|
// Restart the process, using same command line args.
|
||||||
// 1) The process executable path-name is the 1st arg left untouched.
|
// 1) The process executable path-name is the 1st arg left untouched.
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <crtdbg.h>
|
#include <crtdbg.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#define GetRetAddrs __builtin_return_address(0)
|
#define GetRetAddrs GCCRetAddrs
|
||||||
// ... MinGW
|
// ... MinGW
|
||||||
#else
|
#else
|
||||||
// VC++ ...
|
// VC++ ...
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
#include <intrin.h>
|
#include <intrin.h>
|
||||||
#pragma intrinsic(_ReturnAddress)
|
#pragma intrinsic(_ReturnAddress)
|
||||||
#undef ANSI_ISO // Old VC++ versions returning NULL instead of exception
|
#undef ANSI_ISO // Old VC++ versions returning NULL instead of exception
|
||||||
#define GetRetAddrs _ReturnAddress()
|
#define GetRetAddrs _ReturnAddress
|
||||||
// ... VC++
|
// ... VC++
|
||||||
#endif
|
#endif
|
||||||
// ... Windows
|
// ... Windows
|
||||||
|
@ -62,6 +62,18 @@
|
||||||
//----------------------------------------------------------------------------*
|
//----------------------------------------------------------------------------*
|
||||||
static tMemoryManager* GfMM = NULL; // The one and only memory manager!
|
static tMemoryManager* GfMM = NULL; // The one and only memory manager!
|
||||||
static unsigned int GfMM_Counter = 0; // Counter of memory blocks
|
static unsigned int GfMM_Counter = 0; // Counter of memory blocks
|
||||||
|
//============================================================================*
|
||||||
|
#if defined(__MINGW32__)
|
||||||
|
//============================================================================*
|
||||||
|
// GCC allows to set the level parameter, we use 0 to get the same as for VC++
|
||||||
|
//----------------------------------------------------------------------------*
|
||||||
|
void* GCCRetAddrs(void)
|
||||||
|
{
|
||||||
|
return __builtin_return_address(0);
|
||||||
|
}
|
||||||
|
//============================================================================*
|
||||||
|
#endif
|
||||||
|
|
||||||
//----------------------------------------------------------------------------*
|
//----------------------------------------------------------------------------*
|
||||||
// ... Implementation
|
// ... Implementation
|
||||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*
|
||||||
|
@ -76,7 +88,7 @@ static unsigned int GfMM_Counter = 0; // Counter of memory blocks
|
||||||
//ExternC void* operator new (size_t size)
|
//ExternC void* operator new (size_t size)
|
||||||
void* operator new (size_t size)
|
void* operator new (size_t size)
|
||||||
{
|
{
|
||||||
void* retAddr = GetRetAddrs;
|
void* retAddr = GetRetAddrs();
|
||||||
return GfMemoryManagerAlloc(size, GF_MM_ALLOCTYPE_NEW,retAddr);
|
return GfMemoryManagerAlloc(size, GF_MM_ALLOCTYPE_NEW,retAddr);
|
||||||
}
|
}
|
||||||
//============================================================================*
|
//============================================================================*
|
||||||
|
@ -96,7 +108,7 @@ void operator delete (void* b)
|
||||||
//----------------------------------------------------------------------------*
|
//----------------------------------------------------------------------------*
|
||||||
ExternC void* _tgf_win_malloc(size_t size)
|
ExternC void* _tgf_win_malloc(size_t size)
|
||||||
{
|
{
|
||||||
void* retAddr = GetRetAddrs;
|
void* retAddr = GetRetAddrs();
|
||||||
return GfMemoryManagerAlloc(size,GF_MM_ALLOCTYPE_MALLOC,retAddr);
|
return GfMemoryManagerAlloc(size,GF_MM_ALLOCTYPE_MALLOC,retAddr);
|
||||||
}
|
}
|
||||||
//============================================================================*
|
//============================================================================*
|
||||||
|
@ -115,7 +127,7 @@ ExternC void _tgf_win_free(void* b)
|
||||||
//----------------------------------------------------------------------------*
|
//----------------------------------------------------------------------------*
|
||||||
ExternC void* _tgf_win_calloc(size_t num, size_t size)
|
ExternC void* _tgf_win_calloc(size_t num, size_t size)
|
||||||
{
|
{
|
||||||
void* retAddr = GetRetAddrs;
|
void* retAddr = GetRetAddrs();
|
||||||
void* p = GfMemoryManagerAlloc(num * size,GF_MM_ALLOCTYPE_MALLOC,retAddr);
|
void* p = GfMemoryManagerAlloc(num * size,GF_MM_ALLOCTYPE_MALLOC,retAddr);
|
||||||
memset(p, 0, num * size);
|
memset(p, 0, num * size);
|
||||||
return p;
|
return p;
|
||||||
|
@ -127,7 +139,7 @@ ExternC void* _tgf_win_calloc(size_t num, size_t size)
|
||||||
//----------------------------------------------------------------------------*
|
//----------------------------------------------------------------------------*
|
||||||
ExternC void* _tgf_win_realloc(void* memblock, size_t size)
|
ExternC void* _tgf_win_realloc(void* memblock, size_t size)
|
||||||
{
|
{
|
||||||
void* retAddr = GetRetAddrs;
|
void* retAddr = GetRetAddrs();
|
||||||
|
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
{
|
{
|
||||||
|
@ -175,7 +187,7 @@ ExternC void* _tgf_win_realloc(void* memblock, size_t size)
|
||||||
//----------------------------------------------------------------------------*
|
//----------------------------------------------------------------------------*
|
||||||
ExternC char * _tgf_win_strdup(const char * str)
|
ExternC char * _tgf_win_strdup(const char * str)
|
||||||
{
|
{
|
||||||
void* retAddr = GetRetAddrs;
|
void* retAddr = GetRetAddrs();
|
||||||
|
|
||||||
char * s = (char*) GfMemoryManagerAlloc(
|
char * s = (char*) GfMemoryManagerAlloc(
|
||||||
strlen(str)+1,GF_MM_ALLOCTYPE_MALLOC,retAddr);
|
strlen(str)+1,GF_MM_ALLOCTYPE_MALLOC,retAddr);
|
||||||
|
@ -295,7 +307,7 @@ void* GfMemoryManagerAlloc (size_t size, unsigned int type, void* retAddr)
|
||||||
// b: (void*) official pointer to the new data block
|
// b: (void*) official pointer to the new data block
|
||||||
|
|
||||||
// Hunting memory leaks ...
|
// Hunting memory leaks ...
|
||||||
#define IDTOSTOP 371835 // ID of block you are looking for
|
#define IDTOSTOP 280452 // ID of block you are looking for
|
||||||
|
|
||||||
if (ID == IDTOSTOP)
|
if (ID == IDTOSTOP)
|
||||||
{
|
{
|
||||||
|
@ -453,7 +465,7 @@ bool GfMemoryManagerAllocate(void)
|
||||||
//============================================================================*
|
//============================================================================*
|
||||||
// Destroy the one and only global memory manager and it's allocated data
|
// Destroy the one and only global memory manager and it's allocated data
|
||||||
//----------------------------------------------------------------------------*
|
//----------------------------------------------------------------------------*
|
||||||
void GfMemoryManagerRelease(void)
|
void GfMemoryManagerRelease(bool Dump)
|
||||||
{
|
{
|
||||||
int LeakSizeTotal = 0;
|
int LeakSizeTotal = 0;
|
||||||
int LeakSizeNewTotal = 0;
|
int LeakSizeNewTotal = 0;
|
||||||
|
@ -510,6 +522,9 @@ void GfMemoryManagerRelease(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Dump)
|
||||||
|
|
||||||
|
{
|
||||||
fprintf(stderr,"\nMemory manager leak statistics:\n\n");
|
fprintf(stderr,"\nMemory manager leak statistics:\n\n");
|
||||||
|
|
||||||
fprintf(stderr,"Number of allocated blocks : %d\n",GfMM_Counter);
|
fprintf(stderr,"Number of allocated blocks : %d\n",GfMM_Counter);
|
||||||
|
@ -523,6 +538,10 @@ void GfMemoryManagerRelease(void)
|
||||||
fprintf(stderr,"Max leak block size malloc/free: %d [Byte]\n",MaxLeakSizeMallocTotal);
|
fprintf(stderr,"Max leak block size malloc/free: %d [Byte]\n",MaxLeakSizeMallocTotal);
|
||||||
fprintf(stderr,"Max leak block size total : %d [Byte]\n",MaxLeakSizeTotal);
|
fprintf(stderr,"Max leak block size total : %d [Byte]\n",MaxLeakSizeTotal);
|
||||||
|
|
||||||
|
fprintf(stderr,"\nPress [Enter] to show next part of info\n");
|
||||||
|
|
||||||
|
getchar(); // Stop to show leaks first
|
||||||
|
|
||||||
unsigned int total = MM->Hist[0];
|
unsigned int total = MM->Hist[0];
|
||||||
for (int I = 1; I < MAXBLOCKSIZE; I++)
|
for (int I = 1; I < MAXBLOCKSIZE; I++)
|
||||||
total += I * MM->Hist[I];
|
total += I * MM->Hist[I];
|
||||||
|
@ -543,13 +562,17 @@ void GfMemoryManagerRelease(void)
|
||||||
if (MM->Hist[I] > 0)
|
if (MM->Hist[I] > 0)
|
||||||
fprintf(stderr,"%04.4d : %d\n",I,MM->Hist[I]);
|
fprintf(stderr,"%04.4d : %d\n",I,MM->Hist[I]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delete(Block); // Delete the memory manager itself
|
delete(Block); // Delete the memory manager itself
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Dump)
|
||||||
|
{
|
||||||
fprintf(stderr,"\nPress [Enter] to close the program\n");
|
fprintf(stderr,"\nPress [Enter] to close the program\n");
|
||||||
getchar();
|
getchar();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
//============================================================================*
|
//============================================================================*
|
||||||
|
|
||||||
//============================================================================*
|
//============================================================================*
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
// Interface
|
// Interface
|
||||||
//
|
//
|
||||||
TGF_API bool GfMemoryManagerAllocate(void); // Initialize memory manager
|
TGF_API bool GfMemoryManagerAllocate(void); // Initialize memory manager
|
||||||
TGF_API void GfMemoryManagerRelease(void); // Release memory manager at Shutdown
|
TGF_API void GfMemoryManagerRelease(bool Dump = true); // Release memory manager at Shutdown
|
||||||
TGF_API bool GfMemoryManagerRunning(void); // Is the memory manager running?
|
TGF_API bool GfMemoryManagerRunning(void); // Is the memory manager running?
|
||||||
TGF_API void GfMemoryManagerSetup(int AddedSpace);
|
TGF_API void GfMemoryManagerSetup(int AddedSpace);
|
||||||
TGF_API void GfMemoryManagerDoAccept(void);
|
TGF_API void GfMemoryManagerDoAccept(void);
|
||||||
|
|
|
@ -238,6 +238,9 @@ class TGF_API GfApplication
|
||||||
//! Restart the app.
|
//! Restart the app.
|
||||||
virtual void restart();
|
virtual void restart();
|
||||||
|
|
||||||
|
// Allow clean restart
|
||||||
|
void (*ReleaseData)();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
//! Print a short help about using the command line.
|
//! Print a short help about using the command line.
|
||||||
|
|
|
@ -776,6 +776,8 @@ GfuiHookCreate(void *userDataOnActivate, tfuiCallback onActivate)
|
||||||
screen->userActData = userDataOnActivate;
|
screen->userActData = userDataOnActivate;
|
||||||
screen->onlyCallback = 1;
|
screen->onlyCallback = 1;
|
||||||
|
|
||||||
|
RegisterScreens(screen);
|
||||||
|
|
||||||
return (void*)screen;
|
return (void*)screen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -298,6 +298,7 @@ typedef struct GfuiKey
|
||||||
/* screen definition */
|
/* screen definition */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
int ScreenID; /* Identify screen in registration */
|
||||||
float width, height; /* in menu/screen objects coordinate system */
|
float width, height; /* in menu/screen objects coordinate system */
|
||||||
GfuiColor bgColor; /* RGBA */
|
GfuiColor bgColor; /* RGBA */
|
||||||
GLuint bgImage; /* Should always be 2^N x 2^P (for low-end graphic hardwares) */
|
GLuint bgImage; /* Should always be 2^N x 2^P (for low-end graphic hardwares) */
|
||||||
|
|
|
@ -775,5 +775,6 @@ gfuiReleaseGrButton(tGfuiObject *obj)
|
||||||
GfTexFreeTexture(button->focused);
|
GfTexFreeTexture(button->focused);
|
||||||
GfTexFreeTexture(button->pushed);
|
GfTexFreeTexture(button->pushed);
|
||||||
|
|
||||||
|
freez(button->userDataOnFocus);
|
||||||
free(obj);
|
free(obj);
|
||||||
}//gfuiReleaseGrButton
|
}//gfuiReleaseGrButton
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#ifdef __DEBUG_MEMORYMANAGER__
|
#ifdef __DEBUG_MEMORYMANAGER__
|
||||||
|
|
||||||
// Avoid memory leaks ...
|
// Avoid memory leaks ...
|
||||||
|
int NextScreenID = 0;
|
||||||
int NumberOfScreens = 0;
|
int NumberOfScreens = 0;
|
||||||
tGfuiScreen* OwnerOfScreens[MAXSCREENS];
|
tGfuiScreen* OwnerOfScreens[MAXSCREENS];
|
||||||
|
|
||||||
|
@ -29,6 +30,7 @@ tGfuiScreen* OwnerOfScreens[MAXSCREENS];
|
||||||
void RegisterScreens(void* screen)
|
void RegisterScreens(void* screen)
|
||||||
{
|
{
|
||||||
tGfuiScreen* _screen = (tGfuiScreen*) screen;
|
tGfuiScreen* _screen = (tGfuiScreen*) screen;
|
||||||
|
_screen->ScreenID = ++NextScreenID;
|
||||||
|
|
||||||
// Find a deleted entry
|
// Find a deleted entry
|
||||||
for (int I = 0; I < NumberOfScreens; I++)
|
for (int I = 0; I < NumberOfScreens; I++)
|
||||||
|
@ -66,7 +68,7 @@ void FreeScreens()
|
||||||
// For debugging purposes:
|
// For debugging purposes:
|
||||||
//doaccept(); // Do not free the blocks, just take it out of the list
|
//doaccept(); // Do not free the blocks, just take it out of the list
|
||||||
|
|
||||||
for (int I = 0; I <= NumberOfScreens; I++)
|
for (int I = 0; I < NumberOfScreens; I++)
|
||||||
{
|
{
|
||||||
// Get the screen from the owner
|
// Get the screen from the owner
|
||||||
tGfuiScreen* screen = OwnerOfScreens[I];
|
tGfuiScreen* screen = OwnerOfScreens[I];
|
||||||
|
|
|
@ -41,9 +41,31 @@
|
||||||
#include <iuserinterface.h>
|
#include <iuserinterface.h>
|
||||||
|
|
||||||
// WDB test ...
|
// WDB test ...
|
||||||
// Use the define to enable the memorymanager for hunting memory leaks
|
|
||||||
#ifdef __DEBUG_MEMORYMANAGER__
|
#ifdef __DEBUG_MEMORYMANAGER__
|
||||||
#include "memmanager.h"
|
#include "memmanager.h"
|
||||||
|
|
||||||
|
IUserInterface* piUserItf = 0;
|
||||||
|
GfModule* pmodUserItf = NULL;
|
||||||
|
IRaceEngine* piRaceEngine = 0;
|
||||||
|
GfModule* pmodRaceEngine = NULL;
|
||||||
|
|
||||||
|
void ReleaseData(void)
|
||||||
|
{
|
||||||
|
if (piUserItf && piRaceEngine)
|
||||||
|
{
|
||||||
|
// Shutdown and unload the user interface and race engine modules.
|
||||||
|
piUserItf->shutdown();
|
||||||
|
piRaceEngine->shutdown();
|
||||||
|
|
||||||
|
GfModule::unload(pmodUserItf);
|
||||||
|
GfModule::unload(pmodRaceEngine);
|
||||||
|
|
||||||
|
// Shutdown the data layer.
|
||||||
|
//GfData::shutdown(); << causes crashes if called from here
|
||||||
|
|
||||||
|
GfMemoryManagerRelease(false); // Release the memeory manager without dump
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
// ... WDB test
|
// ... WDB test
|
||||||
|
|
||||||
|
@ -156,11 +178,19 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the user interface module (graphical or text-only UI).
|
// Load the user interface module (graphical or text-only UI).
|
||||||
|
// WDB test ...
|
||||||
|
#ifdef __DEBUG_MEMORYMANAGER__
|
||||||
|
pmodUserItf =
|
||||||
|
#else
|
||||||
GfModule* pmodUserItf =
|
GfModule* pmodUserItf =
|
||||||
|
#endif
|
||||||
GfModule::load("modules/userinterface", (bTextOnly ? "textonly" : "legacymenu"));
|
GfModule::load("modules/userinterface", (bTextOnly ? "textonly" : "legacymenu"));
|
||||||
|
|
||||||
// Check that it implements IUserInterface.
|
// Check that it implements IUserInterface.
|
||||||
|
#ifdef __DEBUG_MEMORYMANAGER__
|
||||||
|
#else
|
||||||
IUserInterface* piUserItf = 0;
|
IUserInterface* piUserItf = 0;
|
||||||
|
#endif
|
||||||
if (pmodUserItf)
|
if (pmodUserItf)
|
||||||
{
|
{
|
||||||
piUserItf = pmodUserItf->getInterface<IUserInterface>();
|
piUserItf = pmodUserItf->getInterface<IUserInterface>();
|
||||||
|
@ -175,10 +205,18 @@ main(int argc, char *argv[])
|
||||||
void* hREParams =
|
void* hREParams =
|
||||||
GfParmReadFile(ossParm.str().c_str(), GFPARM_RMODE_REREAD | GFPARM_RMODE_CREAT);
|
GfParmReadFile(ossParm.str().c_str(), GFPARM_RMODE_REREAD | GFPARM_RMODE_CREAT);
|
||||||
const char* pszModName = GfParmGetStr(hREParams, "Modules", "racing", "standardgame");
|
const char* pszModName = GfParmGetStr(hREParams, "Modules", "racing", "standardgame");
|
||||||
|
|
||||||
|
#ifdef __DEBUG_MEMORYMANAGER__
|
||||||
|
pmodRaceEngine = GfModule::load("modules/racing", pszModName);
|
||||||
|
#else
|
||||||
GfModule* pmodRaceEngine = GfModule::load("modules/racing", pszModName);
|
GfModule* pmodRaceEngine = GfModule::load("modules/racing", pszModName);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Check that it implements IRaceEngine.
|
// Check that it implements IRaceEngine.
|
||||||
|
#ifdef __DEBUG_MEMORYMANAGER__
|
||||||
|
#else
|
||||||
IRaceEngine* piRaceEngine = 0;
|
IRaceEngine* piRaceEngine = 0;
|
||||||
|
#endif
|
||||||
if (pmodRaceEngine)
|
if (pmodRaceEngine)
|
||||||
{
|
{
|
||||||
piRaceEngine = pmodRaceEngine->getInterface<IRaceEngine>();
|
piRaceEngine = pmodRaceEngine->getInterface<IRaceEngine>();
|
||||||
|
@ -193,6 +231,11 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
if (piUserItf && piRaceEngine)
|
if (piUserItf && piRaceEngine)
|
||||||
{
|
{
|
||||||
|
#ifdef __DEBUG_MEMORYMANAGER__
|
||||||
|
// Allow to avoid memory leaks at restart
|
||||||
|
pApp->ReleaseData = &ReleaseData;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Enter the user interface.
|
// Enter the user interface.
|
||||||
if (piUserItf->activate())
|
if (piUserItf->activate())
|
||||||
{
|
{
|
||||||
|
|
|
@ -424,6 +424,11 @@ DisplayMenu::DisplayMenu()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DisplayMenu::~DisplayMenu()
|
||||||
|
{
|
||||||
|
free(_aColorDepths);
|
||||||
|
}
|
||||||
|
|
||||||
bool DisplayMenu::initialize(void *pPreviousMenu)
|
bool DisplayMenu::initialize(void *pPreviousMenu)
|
||||||
{
|
{
|
||||||
// Save the menu to return to.
|
// Save the menu to return to.
|
||||||
|
@ -517,5 +522,13 @@ void* DisplayMenuInit(void *pPreviousMenu)
|
||||||
return PDisplayMenu->getMenuHandle();
|
return PDisplayMenu->getMenuHandle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Relase the display options menu screen.
|
||||||
|
@ingroup screen
|
||||||
|
*/
|
||||||
|
void DisplayMenuRelease(void)
|
||||||
|
{
|
||||||
|
delete PDisplayMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,8 @@ class DisplayMenu : public GfuiMenuScreen
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DisplayMenu();
|
DisplayMenu();
|
||||||
|
~DisplayMenu();
|
||||||
|
|
||||||
bool initialize(void* pPreviousMenu);
|
bool initialize(void* pPreviousMenu);
|
||||||
|
|
||||||
enum EDisplayMode { eFullScreen = 0, eWindowed = 1, nDisplayModes };
|
enum EDisplayMode { eFullScreen = 0, eWindowed = 1, nDisplayModes };
|
||||||
|
@ -105,5 +107,6 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void* DisplayMenuInit(void* pPreviousMenu);
|
extern void* DisplayMenuInit(void* pPreviousMenu);
|
||||||
|
extern void DisplayMenuRelease(void);
|
||||||
|
|
||||||
#endif //_DISPLAYCONFIG_H_
|
#endif //_DISPLAYCONFIG_H_
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "racescreens.h"
|
#include "racescreens.h"
|
||||||
|
|
||||||
#include "legacymenu.h"
|
#include "legacymenu.h"
|
||||||
|
#include "displayconfig.h"
|
||||||
|
|
||||||
|
|
||||||
// The LegacyMenu singleton.
|
// The LegacyMenu singleton.
|
||||||
|
@ -62,6 +63,8 @@ int closeGfModule()
|
||||||
if (LegacyMenu::_pSelf)
|
if (LegacyMenu::_pSelf)
|
||||||
GfModule::unregister(LegacyMenu::_pSelf);
|
GfModule::unregister(LegacyMenu::_pSelf);
|
||||||
|
|
||||||
|
DisplayMenuRelease();
|
||||||
|
|
||||||
// Delete the (only) module instance.
|
// Delete the (only) module instance.
|
||||||
delete LegacyMenu::_pSelf;
|
delete LegacyMenu::_pSelf;
|
||||||
LegacyMenu::_pSelf = 0;
|
LegacyMenu::_pSelf = 0;
|
||||||
|
|
Loading…
Reference in a new issue