aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2016-07-22 13:28:32 -0400
committerPaul Gilbert2016-07-22 13:28:32 -0400
commit03b45f44dfdb86a9607aaa09a02e5c57968e275f (patch)
tree189fb7ac253cc3566e9071eec75a8d6f22c38685
parent41a3c83bc6444550c9e4ea1a5918450403e0e5ee (diff)
downloadscummvm-rg350-03b45f44dfdb86a9607aaa09a02e5c57968e275f.tar.gz
scummvm-rg350-03b45f44dfdb86a9607aaa09a02e5c57968e275f.tar.bz2
scummvm-rg350-03b45f44dfdb86a9607aaa09a02e5c57968e275f.zip
TITANIC: Workaround for original using destroyed objects after save load
The original loads savegames by loading a new project hierarchy and then deleting and replacing the existing one. This means that objects in the original project, such as the PET control, are destroyed, leaving the remainder of the PET code that called load operating on destroyed objects. This workaround instead flags for a load to be done, and adds new code in the game manager to take care of it. This way, the remainder of the PET event handling can finish first, and it will be then safe to destroy the original game project (including PET) and load the new savegame.
-rw-r--r--engines/titanic/game_state.h3
-rw-r--r--engines/titanic/main_game_window.cpp12
-rw-r--r--engines/titanic/main_game_window.h6
-rw-r--r--engines/titanic/pet_control/pet_load.cpp13
4 files changed, 24 insertions, 10 deletions
diff --git a/engines/titanic/game_state.h b/engines/titanic/game_state.h
index 125882a9dd..d90c845ed5 100644
--- a/engines/titanic/game_state.h
+++ b/engines/titanic/game_state.h
@@ -33,7 +33,8 @@ namespace Titanic {
class CGameManager;
-enum GameStateMode { GSMODE_UNSELECTED = 0, GSMODE_SELECTED = 1, GSMODE_2 = 2, GSMODE_3 = 3, GSMODE_4 = 4, GSMODE_5 = 5 };
+enum GameStateMode { GSMODE_UNSELECTED = 0, GSMODE_SELECTED = 1, GSMODE_2 = 2, GSMODE_3 = 3, GSMODE_4 = 4, GSMODE_5 = 5,
+ GSMODE_PENDING_LOAD };
PTR_LIST_ITEM(CMovie);
class CGameStateMovieList : public List<CMovieListItem> {
diff --git a/engines/titanic/main_game_window.cpp b/engines/titanic/main_game_window.cpp
index 73ce375881..3c549c4e89 100644
--- a/engines/titanic/main_game_window.cpp
+++ b/engines/titanic/main_game_window.cpp
@@ -36,6 +36,7 @@ CMainGameWindow::CMainGameWindow(TitanicEngine *vm): _vm(vm) {
_inputAllowed = false;
_image = nullptr;
_cursor = nullptr;
+ _pendingLoadSlot = -1;
}
bool CMainGameWindow::Create() {
@@ -137,6 +138,12 @@ void CMainGameWindow::draw() {
g_vm->_filesManager->debug(scrManager);
break;
+ case GSMODE_PENDING_LOAD:
+ // Pending savegame to load
+ _gameManager->_gameState.setMode(GSMODE_SELECTED);
+ _vm->_window->_project->loadGame(_pendingLoadSlot);
+ break;
+
default:
break;
}
@@ -190,4 +197,9 @@ void CMainGameWindow::mouseChanged() {
_gameManager->update();
}
+void CMainGameWindow::loadGame(int slotId) {
+ _pendingLoadSlot = slotId;
+ _gameManager->_gameState.setMode(GSMODE_PENDING_LOAD);
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/main_game_window.h b/engines/titanic/main_game_window.h
index 78f01b9d79..18c03942ce 100644
--- a/engines/titanic/main_game_window.h
+++ b/engines/titanic/main_game_window.h
@@ -37,6 +37,7 @@ class TitanicEngine;
class CMainGameWindow {
private:
TitanicEngine *_vm;
+ int _pendingLoadSlot;
/**
* Checks for the presence of any savegames and, if present,
@@ -98,6 +99,11 @@ public:
* Called by the event handler when a mouse event has been generated
*/
void mouseChanged();
+
+ /**
+ * Schedules a savegame to be loaded
+ */
+ void loadGame(int slotId);
};
} // End of namespace Titanic
diff --git a/engines/titanic/pet_control/pet_load.cpp b/engines/titanic/pet_control/pet_load.cpp
index cb3514ee56..04eec54f25 100644
--- a/engines/titanic/pet_control/pet_load.cpp
+++ b/engines/titanic/pet_control/pet_load.cpp
@@ -24,6 +24,7 @@
#include "titanic/pet_control/pet_control.h"
#include "titanic/core/project_item.h"
#include "titanic/game_manager.h"
+#include "titanic/titanic.h"
namespace Titanic {
@@ -57,16 +58,10 @@ void CPetLoad::execute() {
CPetControl *pet = getPetControl();
if (_savegameSlotNum >= 0 && _slotInUse[_savegameSlotNum]) {
- CProjectItem *project = pet ? pet->getRoot() : nullptr;
- CGameManager *gameManager = project ? project->getGameManager() : nullptr;
+ CMainGameWindow *window = g_vm->_window;
- if (project && gameManager) {
- pet->displayMessage("Loading the selected game, please wait.");
-
- gameManager->destroyTreeItem();
- gameManager->initBounds();
- project->loadGame(_savegameSlotNum);
- }
+ // WORKAROUND: Schedule the savegame to be loaded after frame rendering ends
+ window->loadGame(_savegameSlotNum);
} else if (pet) {
pet->displayMessage("You must select a game to load first.");
}