From 021f2cbccedfd2ed197bb4c54c3d5cf1fc3ca89f Mon Sep 17 00:00:00 2001 From: Robert Göffringmann Date: Tue, 9 Nov 2004 04:06:10 +0000 Subject: free memory on quit. Still leaks some, though svn-id: r15735 --- sword1/control.cpp | 23 +++++++------- sword1/control.h | 1 - sword1/logic.cpp | 10 ++++-- sword1/memman.cpp | 3 ++ sword1/menu.cpp | 12 ++++++++ sword1/menu.h | 1 + sword1/mouse.cpp | 8 +++++ sword1/mouse.h | 1 + sword1/resman.cpp | 19 ++++++++++++ sword1/router.h | 1 - sword1/screen.cpp | 11 +++++++ sword1/screen.h | 2 +- sword1/sound.cpp | 10 ++++++ sword1/sword1.cpp | 90 ++++++++++++++++++++++++++++-------------------------- sword1/sword1.h | 11 +++++-- sword1/text.cpp | 8 ++--- sword1/text.h | 1 + 17 files changed, 146 insertions(+), 66 deletions(-) (limited to 'sword1') diff --git a/sword1/control.cpp b/sword1/control.cpp index 9efeefc495..996c4bff63 100644 --- a/sword1/control.cpp +++ b/sword1/control.cpp @@ -216,7 +216,7 @@ void Control::askForCd(void) { notAccepted = false; } } - } while (notAccepted); + } while (notAccepted && (!SwordEngine::_systemVars.engineQuit)); _resMan->resClose(fontId); free(_screenBuf); @@ -303,7 +303,7 @@ uint8 Control::runPanel(void) { _system->updateScreen(); delay(1000 / 12); newMode = getClicks(mode, &retVal); - } while ((newMode != 1) && (retVal == 0)); + } while ((newMode != 1) && (retVal == 0) && (!SwordEngine::_systemVars.engineQuit)); destroyButtons(); _resMan->resClose(fontId); _resMan->resClose(redFontId); @@ -366,7 +366,7 @@ uint8 Control::handleButtonClick(uint8 id, uint8 mode, uint8 *retVal) { switch(mode) { case BUTTON_MAIN_PANEL: if (id == BUTTON_RESTART) { - if (SwordEngine::_systemVars.deathScreenFlag) // if player is dead or has just started, don't ask for confirmation + if (SwordEngine::_systemVars.controlPanelMode) // if player is dead or has just started, don't ask for confirmation *retVal |= CONTROL_RESTART_GAME; else if (getConfirm(_lStrings[STR_RESTART])) *retVal |= CONTROL_RESTART_GAME; @@ -380,9 +380,8 @@ uint8 Control::handleButtonClick(uint8 id, uint8 mode, uint8 *retVal) { _buttons[5]->setSelected(SwordEngine::_systemVars.showText); } else if (id == BUTTON_QUIT) { if (getConfirm(_lStrings[STR_QUIT])) - _system->quit(); - else - return mode; + SwordEngine::_systemVars.engineQuit = true; + return mode; } break; case BUTTON_SAVE_PANEL: @@ -421,7 +420,7 @@ void Control::deselectSaveslots(void) { void Control::setupMainPanel(void) { uint32 panelId; - if (SwordEngine::_systemVars.deathScreenFlag == 1) + if (SwordEngine::_systemVars.controlPanelMode == CP_DEATHSCREEN) panelId = SR_DEATHPANEL; else { if (SwordEngine::_systemVars.language <= BS1_SPANISH) @@ -434,17 +433,17 @@ void Control::setupMainPanel(void) { panel->draw(); delete panel; - if (SwordEngine::_systemVars.deathScreenFlag) + if (SwordEngine::_systemVars.controlPanelMode != CP_NORMAL) createButtons(_deathButtons, 3); else { createButtons(_panelButtons, 7); _buttons[5]->setSelected(SwordEngine::_systemVars.showText); } - if (SwordEngine::_systemVars.deathScreenFlag == 2) // end of game + if (SwordEngine::_systemVars.controlPanelMode == CP_THEEND) // end of game renderText(_lStrings[STR_THE_END], 480, 188 + 40, TEXT_RIGHT_ALIGN); - if (SwordEngine::_systemVars.deathScreenFlag == 0) { // normal panel + if (SwordEngine::_systemVars.controlPanelMode == CP_NORMAL) { // normal panel renderText(_lStrings[STR_SAVE], 180, 188 + 40, TEXT_LEFT_ALIGN); renderText(_lStrings[STR_DONE], 460, 332 + 40, TEXT_RIGHT_ALIGN); renderText(_lStrings[STR_RESTORE], 180, 224 + 40, TEXT_LEFT_ALIGN); @@ -455,7 +454,7 @@ void Control::setupMainPanel(void) { renderText(_lStrings[STR_TEXT], 460, 224 + 40, TEXT_RIGHT_ALIGN); } else { renderText(_lStrings[STR_RESTORE], 285, 224 + 40, TEXT_LEFT_ALIGN); - if (SwordEngine::_systemVars.deathScreenFlag == 3) // just started game + if (SwordEngine::_systemVars.controlPanelMode == CP_NEWGAME) // just started game renderText(_lStrings[STR_START], 285, 260 + 40, TEXT_LEFT_ALIGN); else renderText(_lStrings[STR_RESTART], 285, 260 + 40, TEXT_LEFT_ALIGN); @@ -1031,7 +1030,7 @@ void Control::delay(uint32 msecs) { _mouseState |= BS1_WHEEL_DOWN; break; case OSystem::EVENT_QUIT: - _system->quit(); + SwordEngine::_systemVars.engineQuit = true; break; default: break; diff --git a/sword1/control.h b/sword1/control.h index 68c4861ec1..d57c32647b 100644 --- a/sword1/control.h +++ b/sword1/control.h @@ -69,7 +69,6 @@ struct ButtonInfo { class Control { public: Control(SaveFileManager *saveFileMan, ResMan *pResMan, ObjectMan *pObjMan, OSystem *system, Mouse *pMouse, Sound *pSound, Music *pMusic, const char *savePath); - ~Control(void); uint8 runPanel(void); void doRestore(void); void askForCd(void); diff --git a/sword1/logic.cpp b/sword1/logic.cpp index d5a314dd34..1d7e85093c 100644 --- a/sword1/logic.cpp +++ b/sword1/logic.cpp @@ -61,6 +61,12 @@ Logic::Logic(ObjectMan *pObjMan, ResMan *resMan, Screen *pScreen, Mouse *pMouse, _mixer = mixer; } +Logic::~Logic(void) { + delete _textMan; + delete _router; + delete _eventMan; +} + void Logic::initialize(void) { memset(_scriptVars, 0, NUM_SCRIPT_VARS * sizeof(uint32)); for (uint8 cnt = 0; cnt < NON_ZERO_SCRIPT_VARS; cnt++) @@ -1616,9 +1622,9 @@ int Logic::fnQuitGame(Object *cpt, int32 id, int32 a, int32 b, int32 c, int32 d, int Logic::fnDeathScreen(Object *cpt, int32 id, int32 a, int32 b, int32 c, int32 d, int32 z, int32 x) { if (_scriptVars[FINALE_OPTION_FLAG] == 4) // successful end of game! - SwordEngine::_systemVars.deathScreenFlag = 2; + SwordEngine::_systemVars.controlPanelMode = CP_THEEND; else - SwordEngine::_systemVars.deathScreenFlag = 1; + SwordEngine::_systemVars.controlPanelMode = CP_DEATHSCREEN; cpt->o_logic = LOGIC_quit; return SCRIPT_STOP; diff --git a/sword1/memman.cpp b/sword1/memman.cpp index f26c61b33c..08cb18e017 100644 --- a/sword1/memman.cpp +++ b/sword1/memman.cpp @@ -31,6 +31,9 @@ MemMan::MemMan(void) { } MemMan::~MemMan(void) { + flush(); + if (_alloced) + warning("deleting MemMan, still %d bytes alloced\n", _alloced); } void MemMan::alloc(MemHandle *bsMem, uint32 pSize, uint16 pCond) { diff --git a/sword1/menu.cpp b/sword1/menu.cpp index 61c8236ffa..89eac4ed2e 100644 --- a/sword1/menu.cpp +++ b/sword1/menu.cpp @@ -103,6 +103,18 @@ Menu::Menu(Screen *pScreen, Mouse *pMouse) { _inMenu = 0; } +Menu::~Menu(void) { + // the menu may be open, so delete the icons + for (int i = 0; i < TOTAL_pockets; i++) { + delete _objects[i]; + _objects[i] = NULL; + } + for (int i = 0; i < TOTAL_subjects; i++) { + delete _subjects[i]; + _subjects[i] = NULL; + } +} + void Menu::refreshMenus() { if (_objectBarStatus == MENU_OPEN) { buildMenu(); diff --git a/sword1/menu.h b/sword1/menu.h index d2b75c7276..3408014708 100644 --- a/sword1/menu.h +++ b/sword1/menu.h @@ -64,6 +64,7 @@ private: class Menu { public: Menu(Screen *pScreen, Mouse *pMouse); + ~Menu(void); void fnChooser(Object *compact); void fnEndChooser(void); void fnAddSubject(int32 sub); diff --git a/sword1/mouse.cpp b/sword1/mouse.cpp index a979bfcf45..c799cdb7eb 100644 --- a/sword1/mouse.cpp +++ b/sword1/mouse.cpp @@ -40,6 +40,14 @@ Mouse::Mouse(OSystem *system, ResMan *pResMan, ObjectMan *pObjMan) { _currentPtr = NULL; } +Mouse::~Mouse(void) { + setLuggage(0, 0); + setPointer(0, 0); + + for (uint8 cnt = 0; cnt < 17; cnt++) // force res manager to keep mouse + _resMan->resClose(MSE_POINTER + cnt); // cursors in memory all the time +} + void Mouse::initialize(void) { _numObjs = 0; Logic::_scriptVars[MOUSE_STATUS] = 0; // mouse off and unlocked diff --git a/sword1/mouse.h b/sword1/mouse.h index a5047674e4..b740347707 100644 --- a/sword1/mouse.h +++ b/sword1/mouse.h @@ -72,6 +72,7 @@ class ObjectMan; class Mouse { public: Mouse(OSystem *system, ResMan *pResMan, ObjectMan *pObjMan); + ~Mouse(void); void initialize(void); void addToList(int id, Object *compact); void useLogicAndMenu(Logic *pLogic, Menu *pMenu); diff --git a/sword1/resman.cpp b/sword1/resman.cpp index 41665cc5df..ecb53ffe0b 100644 --- a/sword1/resman.cpp +++ b/sword1/resman.cpp @@ -52,6 +52,25 @@ ResMan::ResMan(const char *resFile, MemMan *pMemoMan) { } ResMan::~ResMan(void) { +#if 0 + for (uint32 clusCnt = 0; clusCnt < _prj.noClu; clusCnt++) { + Clu *cluster = _prj.clu[clusCnt]; + if (cluster) { + for (uint32 grpCnt = 0; grpCnt < cluster->noGrp; grpCnt++) { + Grp *group = cluster->grp[grpCnt]; + if (group) { + for (uint32 resCnt = 0; resCnt < group->noRes; resCnt++) { + if (group->resHandle[resCnt].cond == MEM_DONT_FREE) { + warning("ResMan::~ResMan: Resource %02X.%04X.%02X is still open", + clusCnt + 1, grpCnt, resCnt); + } + } + } + } + } + } + debug(0, "ResMan closed\n"); +#endif freeCluDescript(); } diff --git a/sword1/router.h b/sword1/router.h index 94b2ebc504..397439c814 100644 --- a/sword1/router.h +++ b/sword1/router.h @@ -96,7 +96,6 @@ extern int whatTarget(int32 startX, int32 startY, int32 destX, int32 destY); class Router { public: Router(ObjectMan *pObjMan, ResMan *pResMan); - ~Router(void); int32 routeFinder(int32 id, Object *mega, int32 x, int32 y, int32 dir); void setPlayerTarget(int32 x, int32 y, int32 dir, int32 stance); void resetExtraData(void); diff --git a/sword1/screen.cpp b/sword1/screen.cpp index d59c6c4f02..3687da9708 100644 --- a/sword1/screen.cpp +++ b/sword1/screen.cpp @@ -47,6 +47,16 @@ Screen::Screen(OSystem *system, ResMan *pResMan, ObjectMan *pObjMan) { _screenBuf = _screenGrid = NULL; _backLength = _foreLength = _sortLength = 0; _fadingStep = 0; + _currentScreen = 0xFFFF; +} + +Screen::~Screen(void) { + if (_screenBuf) + free(_screenBuf); + if (_screenGrid) + free(_screenGrid); + if (_currentScreen != 0xFFFF) + quitScreen(); } void Screen::useTextManager(Text *pTextMan) { @@ -309,6 +319,7 @@ void Screen::quitScreen(void) { _resMan->resClose(_roomDefTable[_currentScreen].parallax[0]); if (_roomDefTable[_currentScreen].parallax[1]) _resMan->resClose(_roomDefTable[_currentScreen].parallax[1]); + _currentScreen = 0xFFFF; } void Screen::draw(void) { diff --git a/sword1/screen.h b/sword1/screen.h index d6f5720b36..dfebf9deab 100644 --- a/sword1/screen.h +++ b/sword1/screen.h @@ -67,8 +67,8 @@ class Text; // Text objects use sprites that are created internally at run-time class Screen { public: Screen(OSystem *system, ResMan *pResMan, ObjectMan *pObjMan); - void useTextManager(Text *pTextMan); ~Screen(void); + void useTextManager(Text *pTextMan); void draw(void); void quitScreen(void); diff --git a/sword1/sound.cpp b/sword1/sound.cpp index f33f1cf36c..550d8dd54b 100644 --- a/sword1/sound.cpp +++ b/sword1/sound.cpp @@ -41,6 +41,16 @@ Sound::Sound(const char *searchPath, SoundMixer *mixer, ResMan *pResMan) { _speechVolL = _speechVolR = _sfxVolL = _sfxVolR = 192; } +Sound::~Sound(void) { + // clean up fx queue + _mixer->stopAll(); + for (uint8 cnt = 0; cnt < _endOfQueue; cnt++) + if (_fxQueue[cnt].delay == 0) + _resMan->resClose(_fxList[_fxQueue[cnt].id].sampleId); + _endOfQueue = 0; + closeCowSystem(); +} + int Sound::addToQueue(int32 fxNo) { bool alreadyInQueue = false; for (uint8 cnt = 0; (cnt < _endOfQueue) && (!alreadyInQueue); cnt++) diff --git a/sword1/sword1.cpp b/sword1/sword1.cpp index 8174ba7a8d..f5225affe8 100644 --- a/sword1/sword1.cpp +++ b/sword1/sword1.cpp @@ -113,6 +113,17 @@ SwordEngine::SwordEngine(GameDetector *detector, OSystem *syst) } SwordEngine::~SwordEngine() { + delete _control; + delete _logic; + delete _menu; + delete _sound; + delete _music; + delete _screen; + delete _mouse; + delete _objectMan; + _resMan->flush(); // free all memory + delete _resMan; + delete _memMan; } void SwordEngine::initialize(void) { @@ -155,10 +166,10 @@ void SwordEngine::initialize(void) { _systemVars.justRestoredGame = 0; _systemVars.currentCD = 0; - _systemVars.gamePaused = 0; - _systemVars.deathScreenFlag = 3; + _systemVars.controlPanelMode = CP_NEWGAME; _systemVars.forceRestart = false; _systemVars.wantFade = true; + _systemVars.engineQuit = false; switch (Common::parseLanguage(ConfMan.get("language"))) { case Common::DE_DEU: @@ -1065,7 +1076,7 @@ void SwordEngine::startPositions(int32 startNumber) { compact = (Object*)_objectMan->fetchObject(PLAYER); _logic->fnEnterSection(compact, PLAYER, startNumber, 0, 0, 0, 0, 0); // (automatically opens the compact resource for that section) - _systemVars.deathScreenFlag = 0; + _systemVars.controlPanelMode = CP_NORMAL; _systemVars.wantFade = true; } @@ -1079,7 +1090,7 @@ void SwordEngine::checkCdFiles(void) { // check if we're running from cd, hdd or #endif "SPEECH%d.CLU" }; - int numFiles = 0; + bool fileFound[2] = { false, false }; File test; _systemVars.playSpeech = true; @@ -1090,13 +1101,13 @@ void SwordEngine::checkCdFiles(void) { // check if we're running from cd, hdd or sprintf(fileName, speechFiles[j], i); if (test.open(fileName)) { test.close(); - numFiles++; + fileFound[i - 1] = true; break; } } } - if (numFiles == 2) { + if (fileFound[0] && fileFound[1]) { // both files exist, assume running from HDD and everything's fine. _systemVars.runningFromCd = false; _systemVars.playSpeech = true; @@ -1128,28 +1139,30 @@ void SwordEngine::go(void) { startPositions(startPos); else { if (_control->savegamesExist()) { - _systemVars.deathScreenFlag = 3; + _systemVars.controlPanelMode = CP_NEWGAME; if (_control->runPanel() == CONTROL_GAME_RESTORED) _control->doRestore(); - else + else if (!_systemVars.engineQuit) startPositions(0); } else // no savegames, start new game. startPositions(0); } - _systemVars.deathScreenFlag = 0; + _systemVars.controlPanelMode = CP_NORMAL; - do { + while (!_systemVars.engineQuit) { uint8 action = mainLoop(); - // the mainloop was left, we have to reinitialize. - reinitialize(); - if (action == CONTROL_GAME_RESTORED) - _control->doRestore(); - else if (action == CONTROL_RESTART_GAME) - startPositions(1); - _systemVars.forceRestart = false; - _systemVars.deathScreenFlag = 0; - } while (true); + if (!_systemVars.engineQuit) { + // the mainloop was left, we have to reinitialize. + reinitialize(); + if (action == CONTROL_GAME_RESTORED) + _control->doRestore(); + else if (action == CONTROL_RESTART_GAME) + startPositions(1); + _systemVars.forceRestart = false; + _systemVars.controlPanelMode = CP_NORMAL; + } + } } void SwordEngine::checkCd(void) { @@ -1178,7 +1191,7 @@ uint8 SwordEngine::mainLoop(void) { uint8 retCode = 0; _keyPressed = 0; - while (retCode == 0) { + while ((retCode == 0) && (!_systemVars.engineQuit)) { // do we need the section45-hack from sword.c here? checkCd(); @@ -1221,28 +1234,29 @@ uint8 SwordEngine::mainLoop(void) { delay(0); _mouse->engine( _mouseX, _mouseY, _mouseState); - _mouseState = 0; if (_systemVars.forceRestart) retCode = CONTROL_RESTART_GAME; // The control panel is triggered by F5 or ESC. // FIXME: This is a very strange way of detecting F5... - else if (((_keyPressed == 63 || _keyPressed == 27) && (Logic::_scriptVars[MOUSE_STATUS] & 1)) || (_systemVars.deathScreenFlag)) { + else if (((_keyPressed == 63 || _keyPressed == 27) && (Logic::_scriptVars[MOUSE_STATUS] & 1)) || (_systemVars.controlPanelMode)) { retCode = _control->runPanel(); if (!retCode) _screen->fullRefresh(); } - _keyPressed = 0; - - // do something smart here to implement pausing the game. If we even want that, that is. - } while ((Logic::_scriptVars[SCREEN] == Logic::_scriptVars[NEW_SCREEN]) && (retCode == 0)); + _mouseState = _keyPressed = 0; + } while ((Logic::_scriptVars[SCREEN] == Logic::_scriptVars[NEW_SCREEN]) && (retCode == 0) && (!_systemVars.engineQuit)); - if ((retCode == 0) && (Logic::_scriptVars[SCREEN] != 53) && _systemVars.wantFade) { + if ((retCode == 0) && (Logic::_scriptVars[SCREEN] != 53) && _systemVars.wantFade && (!_systemVars.engineQuit)) { _screen->fadeDownPalette(); while (_screen->stillFading()) { + int32 relDelay = (int32)_system->getMillis() + (1000 / FRAME_RATE); _screen->updateScreen(); - delay(1000/12); + relDelay -= (int32)_system->getMillis(); + relDelay = (relDelay > 0) ? relDelay : 0; + + delay(relDelay); } } @@ -1258,7 +1272,6 @@ void SwordEngine::delay(uint amount) { //copied and mutilated from sky.cpp OSystem::Event event; uint32 start = _system->getMillis(); - uint32 cur = start; do { while (_system->pollEvent(event)) { @@ -1296,27 +1309,18 @@ void SwordEngine::delay(uint amount) { //copied and mutilated from sky.cpp _mouseState |= BS1R_BUTTON_UP; break; case OSystem::EVENT_QUIT: - _system->quit(); + //_system->quit(); + _systemVars.engineQuit = true; break; default: break; } } - if (amount == 0) - break; + if (amount > 0) + _system->delayMillis(10); - { - uint this_delay = 20; // 1? -#ifdef _WIN32_WCE - this_delay = 10; -#endif - if (this_delay > amount) - this_delay = amount; - _system->delayMillis(this_delay); - } - cur = _system->getMillis(); - } while (cur < start + amount); + } while (_system->getMillis() < start + amount); } } // End of namespace Sword1 diff --git a/sword1/sword1.h b/sword1/sword1.h index a15322bfe2..22a51960d5 100644 --- a/sword1/sword1.h +++ b/sword1/sword1.h @@ -33,6 +33,13 @@ enum { GF_DEMO = 1 << 0 }; +enum ControlPanelMode { + CP_NORMAL = 0, + CP_DEATHSCREEN, + CP_THEEND, + CP_NEWGAME +}; + class Screen; class Sound; class Logic; @@ -48,9 +55,9 @@ struct SystemVars { bool runningFromCd; uint32 currentCD; // starts at zero, then either 1 or 2 depending on section being played uint32 justRestoredGame; // see main() in sword.c & New_screen() in gtm_core.c - uint32 gamePaused; // 1 when paused + bool engineQuit; - uint8 deathScreenFlag; // 1 death screen version of the control panel, 2 = successful end of game, 3 = force restart + uint8 controlPanelMode; // 1 death screen version of the control panel, 2 = successful end of game, 3 = force restart bool forceRestart; bool wantFade; // when true => fade during scene change, else cut. uint8 playSpeech; diff --git a/sword1/text.cpp b/sword1/text.cpp index c832c581ba..b9ad373c0d 100644 --- a/sword1/text.cpp +++ b/sword1/text.cpp @@ -41,10 +41,9 @@ Text::Text(ObjectMan *pObjMan, ResMan *pResMan, bool czechVersion) { _objMan = pObjMan; _resMan = pResMan; _textCount = 0; - if (czechVersion) - _font = (uint8*)_resMan->openFetchRes(CZECH_GAME_FONT); - else - _font = (uint8*)_resMan->openFetchRes(GAME_FONT); + _fontId = (czechVersion) ? CZECH_GAME_FONT : GAME_FONT; + _font = (uint8*)_resMan->openFetchRes(_fontId); + _joinWidth = charWidth( SPACE ) - 2 * OVERLAP; _charHeight = FROM_LE_16(_resMan->fetchFrame(_font, 0)->height); // all chars have the same height _textBlocks[0] = _textBlocks[1] = NULL; @@ -55,6 +54,7 @@ Text::~Text(void) { free(_textBlocks[0]); if (_textBlocks[1]) free(_textBlocks[1]); + //_resMan->resClose(_fontId); => wiped automatically by _resMan->flush(); } uint32 Text::lowTextManager(uint8 *ascii, int32 width, uint8 pen) { diff --git a/sword1/text.h b/sword1/text.h index 6619e7b32d..25e91a8bd0 100644 --- a/sword1/text.h +++ b/sword1/text.h @@ -56,6 +56,7 @@ private: ObjectMan *_objMan; ResMan *_resMan; FrameHeader *_textBlocks[MAX_TEXT_OBS]; + uint32 _fontId; }; } // End of namespace Sword1 -- cgit v1.2.3