From efac7b5eb0dd90bc45761a666d8b68ddad703d19 Mon Sep 17 00:00:00 2001 From: Bendegúz Nagy Date: Fri, 19 Aug 2016 11:49:29 +0200 Subject: DM: Add loading from game --- engines/dm/TODOs/todo.txt | 4 +++- engines/dm/dialog.cpp | 4 ++-- engines/dm/dm.cpp | 43 ++++++++++++++++++++++++++++++++++++++++--- engines/dm/dm.h | 6 ++++++ engines/dm/dungeonman.cpp | 2 -- engines/dm/loadsave.cpp | 38 ++++++++++++++++++++++---------------- 6 files changed, 73 insertions(+), 24 deletions(-) (limited to 'engines/dm') diff --git a/engines/dm/TODOs/todo.txt b/engines/dm/TODOs/todo.txt index 94c510592f..f3030084c5 100644 --- a/engines/dm/TODOs/todo.txt +++ b/engines/dm/TODOs/todo.txt @@ -18,4 +18,6 @@ Code stuff todo: Save file f433_processCommand140_saveGame fails silently, add error checking Add loading from dungeon - Fix incorrect thumbnail \ No newline at end of file + Fix incorrect thumbnail + Add translations to f433_processCommand140_saveGame 'LOAD' + \ No newline at end of file diff --git a/engines/dm/dialog.cpp b/engines/dm/dialog.cpp index 943f8c58c6..900ff76df6 100644 --- a/engines/dm/dialog.cpp +++ b/engines/dm/dialog.cpp @@ -223,7 +223,7 @@ int16 DialogMan::f424_dialogGetChoice(uint16 choiceCount, uint16 dialogSetIndex, L1303_s_BoxB = L1304_s_BoxA; L1303_s_BoxB._x1 = L1303_s_BoxB._x2; _vm->_displayMan->D24_fillScreenBox(L1303_s_BoxB, k0_ColorBlack); - _vm->f22_delay(5); + _vm->f22_delay(2); L1303_s_BoxB = L1304_s_BoxA; L1303_s_BoxB._y1++; L1303_s_BoxB._y2 = L1303_s_BoxB._y1; @@ -251,7 +251,7 @@ int16 DialogMan::f424_dialogGetChoice(uint16 choiceCount, uint16 dialogSetIndex, L1303_s_BoxB._x1 = L1303_s_BoxB._x2 = L1303_s_BoxB._x2 + 3; L1303_s_BoxB._y2 += 2; _vm->_displayMan->D24_fillScreenBox(L1303_s_BoxB, k13_ColorLightestGray); - _vm->f22_delay(5); + _vm->f22_delay(2); L1304_s_BoxA._x2 += 3; L1304_s_BoxA._y2 += 3; _vm->_displayMan->f132_blitToBitmap(_vm->_displayMan->_g296_bitmapViewport, _vm->_displayMan->_g348_bitmapScreen, diff --git a/engines/dm/dm.cpp b/engines/dm/dm.cpp index 634ddb51c3..2003ace00f 100644 --- a/engines/dm/dm.cpp +++ b/engines/dm/dm.cpp @@ -207,6 +207,8 @@ DMEngine::DMEngine(OSystem *syst, const ADGameDescription *desc) : Engine(syst), debug("DMEngine::DMEngine"); _saveThumbnail = nullptr; + _canLoadFromGMM = false; + _loadSaveSlotAtRuntime = -1; } DMEngine::~DMEngine() { @@ -243,6 +245,26 @@ bool DMEngine::hasFeature(EngineFeature f) const { (f == kSupportsLoadingDuringRuntime); } +Common::Error DMEngine::loadGameState(int slot) { + if (f435_loadgame(slot) != kM1_LoadgameFailure) { + _displayMan->fillScreen(k0_ColorBlack); + _displayMan->f436_STARTEND_FadeToPalette(_displayMan->_palDungeonView[0]); + _g298_newGame = k0_modeLoadSavedGame; + + f462_startGame(); + _g523_restartGameRequest = false; + _eventMan->f77_hideMouse(); + _eventMan->f357_discardAllInput(); + return Common::kNoError; + } + + return Common::kNoGameDataFoundError; +} + +bool DMEngine::canLoadGameStateCurrently() { + return _canLoadFromGMM; +} + void DMEngine::f22_delay(uint16 verticalBlank) { for (uint16 i = 0; i < verticalBlank * 2; ++i) { _eventMan->processInput(); @@ -386,9 +408,18 @@ Common::Error DMEngine::run() { f463_initializeGame(); while (true) { f2_gameloop(); + if (_engineShouldQuit) return Common::kNoError; - f444_endGame(_championMan->_g303_partyDead); + + if (_loadSaveSlotAtRuntime == -1) + f444_endGame(_championMan->_g303_partyDead); + else { + loadGameState(_loadSaveSlotAtRuntime); + _menuMan->f457_drawEnabledMenus(); + _displayMan->updateScreen(); + _loadSaveSlotAtRuntime = -1; + } } return Common::kNoError; @@ -403,10 +434,13 @@ void DMEngine::f2_gameloop() { _dungeonMan->_g308_partyDir = kDirWest; } + _canLoadFromGMM = true; _g318_waitForInputMaxVerticalBlankCount = 10; while (true) { - if (_engineShouldQuit) + if (_engineShouldQuit) { + _canLoadFromGMM = false; return; + } // DEBUG CODE for (int16 i = 0; i < _championMan->_g305_partyChampionCount; ++i) { @@ -495,8 +529,10 @@ void DMEngine::f2_gameloop() { } _eventMan->f380_processCommandQueue(); - if (_engineShouldQuit) + if (_engineShouldQuit || _loadSaveSlotAtRuntime != -1) { + _canLoadFromGMM = false; return; + } _displayMan->updateScreen(); if (!_g321_stopWaitingForPlayerInput) { _eventMan->f363_highlightBoxDisable(); @@ -508,6 +544,7 @@ void DMEngine::f2_gameloop() { } while (!_g321_stopWaitingForPlayerInput || !_g301_gameTimeTicking); } + _canLoadFromGMM = false; } int16 DMEngine::M1_ordinalToIndex(int16 val) { diff --git a/engines/dm/dm.h b/engines/dm/dm.h index 2e3144bbaf..9bf2c1521c 100644 --- a/engines/dm/dm.h +++ b/engines/dm/dm.h @@ -219,6 +219,10 @@ public: explicit DMEngine(OSystem *syst, const ADGameDescription *gameDesc); ~DMEngine(); virtual bool hasFeature(EngineFeature f) const; + + virtual Common::Error loadGameState(int slot); + virtual bool canLoadGameStateCurrently(); + GUI::Debugger *getDebugger() { return _console; } void f22_delay(uint16 verticalBlank); // @ F0022_MAIN_Delay @@ -250,6 +254,7 @@ private: byte *_savedScreenForOpenEntranceDoors; // ad-hoc HACK const ADGameDescription *_gameVersion; + bool _canLoadFromGMM; public: Console *_console; DisplayMan *_displayMan; @@ -270,6 +275,7 @@ public: Common::MemoryWriteStreamDynamic *_saveThumbnail; bool _engineShouldQuit; + int _loadSaveSlotAtRuntime; int16 _g298_newGame; // @ G0298_B_NewGame bool _g523_restartGameRequest; // @ G0523_B_RestartGameRequested diff --git a/engines/dm/dungeonman.cpp b/engines/dm/dungeonman.cpp index 8cb702ab37..7b8d69decb 100644 --- a/engines/dm/dungeonman.cpp +++ b/engines/dm/dungeonman.cpp @@ -740,8 +740,6 @@ void DungeonMan::f173_setCurrentMap(uint16 mapIndex) { DoorInfo(5, 255) /* Door type 3 Ra door */ }; - if (_g272_currMapIndex == mapIndex) - return; _g272_currMapIndex = mapIndex; _g271_currMapData = _g279_dungeonMapData[mapIndex]; diff --git a/engines/dm/loadsave.cpp b/engines/dm/loadsave.cpp index 90ac9d9ea5..6a21c4283e 100644 --- a/engines/dm/loadsave.cpp +++ b/engines/dm/loadsave.cpp @@ -56,19 +56,13 @@ LoadgameResponse DMEngine::f435_loadgame(int16 slot) { Common::InSaveFile *file = nullptr; struct { - int16 _saveFormat; - int16 _saveAndPlayChoice; - int32 _gameId; - int16 _platform; - uint16 _dungeonId; + int16 _saveFormat = 0; + int16 _saveAndPlayChoice = 0; + int32 _gameId = 0; + int16 _platform = 0; + uint16 _dungeonId = 0; } dmSaveHeader; - dmSaveHeader._saveFormat = 0; - dmSaveHeader._saveAndPlayChoice = 0; - dmSaveHeader._gameId = 0; - dmSaveHeader._platform = 0; - dmSaveHeader._dungeonId = 0; - if (!_g298_newGame) { fileName = getSavefileName(slot); saveFileManager = _system->getSavefileManager(); @@ -188,23 +182,35 @@ void DMEngine::f433_processCommand140_saveGame() { switch (getGameLanguage()) { // localized default: case Common::EN_ANY: - _dialog->f427_dialogDraw(nullptr, nullptr, "SAVE AND PLAY", "SAVE AND QUIT", "CANCEL", nullptr, false, false, false); + _dialog->f427_dialogDraw(nullptr, nullptr, "SAVE AND PLAY", "SAVE AND QUIT", "CANCEL", "LOAD", false, false, false); break; case Common::DE_DEU: - _dialog->f427_dialogDraw(nullptr, nullptr, "SICHERN/SPIEL", "SICHERN/ENDEN", "WIDERRUFEN", nullptr, false, false, false); + _dialog->f427_dialogDraw(nullptr, nullptr, "SICHERN/SPIEL", "SICHERN/ENDEN", "WIDERRUFEN", "LOAD", false, false, false); break; case Common::FR_FRA: - _dialog->f427_dialogDraw(nullptr, nullptr, "GARDER/JOUER", "GARDER/SORTIR", "ANNULLER", nullptr, false, false, false); + _dialog->f427_dialogDraw(nullptr, nullptr, "GARDER/JOUER", "GARDER/SORTIR", "ANNULLER", "LOAD", false, false, false); break; } enum SaveAndPlayChoice { kSaveAndPlay = 1, kSaveAndQuit = 2, - kCancel = 3 + kCancel = 3, + kLoad = 4 }; - SaveAndPlayChoice saveAndPlayChoice = (SaveAndPlayChoice)_dialog->f424_dialogGetChoice(3, k0_DIALOG_SET_VIEWPORT, 0, k0_DIALOG_CHOICE_NONE); + SaveAndPlayChoice saveAndPlayChoice = (SaveAndPlayChoice)_dialog->f424_dialogGetChoice(4, k0_DIALOG_SET_VIEWPORT, 0, k0_DIALOG_CHOICE_NONE); + + if (saveAndPlayChoice == kLoad) { + GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"), false); + int loadSlot = dialog->runModalWithCurrentTarget(); + if (loadSlot >= 0) { + _loadSaveSlotAtRuntime = loadSlot; + return; + } + + saveAndPlayChoice = kCancel; + } if (saveAndPlayChoice == kSaveAndQuit || saveAndPlayChoice == kSaveAndPlay) { GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true); -- cgit v1.2.3