diff --git a/engines/ultima/ultima4/game/intro.cpp b/engines/ultima/ultima4/game/intro.cpp index c986f40729b..41643fead15 100644 --- a/engines/ultima/ultima4/game/intro.cpp +++ b/engines/ultima/ultima4/game/intro.cpp @@ -922,37 +922,26 @@ Common::String IntroController::getQuestion(int v1, int v2) { * Starts the game. */ void IntroController::journeyOnward() { - Common::InSaveFile *saveGameFile; bool validSave = false; + int lastSave = ConfMan.hasKey("last_save") ? ConfMan.getInt("last_save") : -1; - /* - * ensure a party.sav file exists, otherwise require user to - * initiate game - */ - saveGameFile = g_system->getSavefileManager()->openForLoading(PARTY_SAV_BASE_FILENAME); - if (saveGameFile) { - SaveGame *saveGame = new SaveGame; - - // Make sure there are players in party.sav -- - // In the Ultima Collection CD, party.sav exists, but does - // not contain valid info to journey onward - Common::Serializer ser(saveGameFile, nullptr); - saveGame->synchronize(ser); - - if (saveGame->_members > 0) - validSave = true; - delete saveGame; - delete saveGameFile; + if (lastSave != -1) { + // At this point the game context hasn't been created yet, so we only + // want to validate that the given savegame file exists without loading it + Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading( + g_ultima->getSaveStateName(lastSave)); + validSave = saveFile != nullptr; + delete saveFile; } - if (!validSave) { + if (validSave) { + EventHandler::setControllerDone(); + g_ultima->setToJourneyOnwards(); + } else { _errorMessage = "Initiate a new game first!"; updateScreen(); g_screen->update(); - return; } - - EventHandler::setControllerDone(); } /** diff --git a/engines/ultima/ultima4/ultima4.cpp b/engines/ultima/ultima4/ultima4.cpp index 9083172001b..b9299b9163d 100644 --- a/engines/ultima/ultima4/ultima4.cpp +++ b/engines/ultima/ultima4/ultima4.cpp @@ -47,8 +47,8 @@ bool quit = false, verbose = false; Ultima4Engine *g_ultima; Ultima4Engine::Ultima4Engine(OSystem *syst, const Ultima::UltimaGameDescription *gameDesc) : - Shared::UltimaEngine(syst, gameDesc), _config(nullptr), _game(nullptr), - _imageLoaders(nullptr), _screen(nullptr) { + Shared::UltimaEngine(syst, gameDesc), _saveSlotToLoad(-1), _config(nullptr), _game(nullptr), + _imageLoaders(nullptr), _screen(nullptr) { g_ultima = this; g_context = nullptr; g_game = nullptr; @@ -79,12 +79,13 @@ bool Ultima4Engine::initialize() { _imageLoaders = new ImageLoaders(); _screen->init(); + _saveSlotToLoad = ConfMan.hasKey("save_slot") ? ConfMan.getInt("save_slot") : -1; + return true; } void Ultima4Engine::startup() { - int saveSlot = ConfMan.hasKey("save_slot") ? ConfMan.getInt("save_slot") : -1; - bool skipInfo = saveSlot != -1; + bool skipInfo = _saveSlotToLoad != -1; ProgressBar pb((320 / 2) - (200 / 2), (200 / 2), 200, 10, 0, (skipInfo ? 4 : 7)); pb.setBorderColor(240, 240, 240); @@ -129,9 +130,8 @@ Common::Error Ultima4Engine::run() { if (!shouldQuit()) { g_game->init(); - int saveSlot = ConfMan.hasKey("save_slot") ? ConfMan.getInt("save_slot") : -1; - if (saveSlot != -1) { - if (loadGameState(saveSlot).getCode() != Common::kNoError) + if (_saveSlotToLoad != -1) { + if (loadGameState(_saveSlotToLoad).getCode() != Common::kNoError) error("Error loading save"); } @@ -152,10 +152,26 @@ bool Ultima4Engine::isDataRequired(Common::String &folder, int &majorVersion, in return true; } +void Ultima4Engine::setToJourneyOnwards() { + _saveSlotToLoad = ConfMan.hasKey("last_save") ? ConfMan.getInt("last_save") : -1; + assert(_saveSlotToLoad); +} + bool Ultima4Engine::canSaveGameStateCurrently(bool isAutosave) { return g_game != nullptr && g_context != nullptr && eventHandler->getController() == g_game; } +Common::Error Ultima4Engine::saveGameState(int slot, const Common::String &desc, bool isAutosave) { + Common::Error result = Shared::UltimaEngine::saveGameState(slot, desc, isAutosave); + if (!isAutosave && result.getCode() == Common::kNoError) { + ConfMan.setInt("last_save", slot); + ConfMan.flushToDisk(); + } + + return result; +} + + Common::Error Ultima4Engine::loadGameStream(Common::SeekableReadStream *stream) { Common::Serializer ser(stream, nullptr); g_context->_saveGame->synchronize(ser); diff --git a/engines/ultima/ultima4/ultima4.h b/engines/ultima/ultima4/ultima4.h index 707407d3e8c..9db8b59af8f 100644 --- a/engines/ultima/ultima4/ultima4.h +++ b/engines/ultima/ultima4/ultima4.h @@ -34,6 +34,8 @@ class GameController; class Screen; class Ultima4Engine : public Shared::UltimaEngine { +private: + int _saveSlotToLoad; private: void startup(); protected: @@ -67,6 +69,15 @@ public: */ bool canSaveGameStateCurrently(bool isAutosave = false) override; + /** + * Save a game state. + * @param slot the slot into which the savestate should be stored + * @param desc a description for the savestate, entered by the user + * @param isAutosave Expected to be true if an autosave is being created + * @return returns kNoError on success, else an error code. + */ + Common::Error saveGameState(int slot, const Common::String &desc, bool isAutosave = false) override; + /** * Load a game state. * @param stream the stream to load the savestate from @@ -81,6 +92,12 @@ public: * @return returns kNoError on success, else an error code. */ Common::Error saveGameStream(Common::WriteStream *stream, bool isAutosave = false) override; + + /** + * Specifies to load the previous save as the actual game starts. Used by + * the main menu when the Journey Onwards option is selected + */ + void setToJourneyOnwards(); }; extern Ultima4Engine *g_ultima;