aboutsummaryrefslogtreecommitdiff
path: root/engines/illusions
diff options
context:
space:
mode:
Diffstat (limited to 'engines/illusions')
-rw-r--r--engines/illusions/bbdou/bbdou_specialcode.cpp13
-rw-r--r--engines/illusions/bbdou/bbdou_specialcode.h1
-rw-r--r--engines/illusions/bbdou/gamestate_bbdou.cpp53
-rw-r--r--engines/illusions/bbdou/gamestate_bbdou.h44
-rw-r--r--engines/illusions/bbdou/illusions_bbdou.cpp61
-rw-r--r--engines/illusions/bbdou/illusions_bbdou.h9
-rw-r--r--engines/illusions/bbdou/scriptopcodes_bbdou.cpp40
-rw-r--r--engines/illusions/bbdou/scriptopcodes_bbdou.h5
-rw-r--r--engines/illusions/illusions.h1
-rw-r--r--engines/illusions/module.mk1
-rw-r--r--engines/illusions/specialcode.h1
11 files changed, 215 insertions, 14 deletions
diff --git a/engines/illusions/bbdou/bbdou_specialcode.cpp b/engines/illusions/bbdou/bbdou_specialcode.cpp
index 0f3a264b85..8614fb68a9 100644
--- a/engines/illusions/bbdou/bbdou_specialcode.cpp
+++ b/engines/illusions/bbdou/bbdou_specialcode.cpp
@@ -214,6 +214,19 @@ void BbdouSpecialCode::run(uint32 specialCodeId, OpCall &opCall) {
}
}
+void BbdouSpecialCode::resetBeforeResumeSavegame() {
+ if (_vm->getCurrentScene() == 0x00010032)
+ _inventory->close();
+ _vm->_threads->terminateThreads(0);
+ _vm->reset();
+ _vm->_input->activateButton(0xFFFF);
+ // TODO _vm->stopMusic();
+ // TODO _vm->_gameStates->clear();
+ _cursor->reset(0x0004001A);
+ setCursorControlRoutine(0x0004001A, 0);
+ _cursor->enable(0x0004001A);
+}
+
// Special codes
void BbdouSpecialCode::spcInitCursor(OpCall &opCall) {
diff --git a/engines/illusions/bbdou/bbdou_specialcode.h b/engines/illusions/bbdou/bbdou_specialcode.h
index df9b3f76c1..c281824077 100644
--- a/engines/illusions/bbdou/bbdou_specialcode.h
+++ b/engines/illusions/bbdou/bbdou_specialcode.h
@@ -110,6 +110,7 @@ public:
virtual ~BbdouSpecialCode();
virtual void init();
virtual void run(uint32 specialCodeId, OpCall &opCall);
+ virtual void resetBeforeResumeSavegame();
public:
typedef Common::HashMap<uint32, SpecialCodeFunction*> Map;
typedef Map::iterator MapIterator;
diff --git a/engines/illusions/bbdou/gamestate_bbdou.cpp b/engines/illusions/bbdou/gamestate_bbdou.cpp
new file mode 100644
index 0000000000..a20e2c4080
--- /dev/null
+++ b/engines/illusions/bbdou/gamestate_bbdou.cpp
@@ -0,0 +1,53 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "illusions/bbdou/gamestate_bbdou.h"
+#include "illusions/bbdou/illusions_bbdou.h"
+#include "illusions/resources/scriptresource.h"
+
+namespace Illusions {
+
+BBDOU_GameState::BBDOU_GameState(IllusionsEngine_BBDOU *vm)
+ : _vm(vm) {
+}
+
+uint32 BBDOU_GameState::calcWriteBufferSizeInternal() {
+ return
+ 4 + // uint32 prevSceneId
+ _vm->_scriptResource->_properties.getSize() +
+ _vm->_scriptResource->_blockCounters.getSize();
+}
+
+bool BBDOU_GameState::readStateInternal(Common::ReadStream *in) {
+ _vm->_prevSceneId = in->readUint32LE();
+ return
+ _vm->_scriptResource->_properties.readFromStream(in) &&
+ _vm->_scriptResource->_blockCounters.readFromStream(in);
+}
+
+void BBDOU_GameState::writeStateInternal(Common::WriteStream *out) {
+ out->writeUint32LE(_vm->_prevSceneId);
+ _vm->_scriptResource->_properties.writeToStream(out);
+ _vm->_scriptResource->_blockCounters.writeToStream(out);
+}
+
+} // End of namespace Illusions
diff --git a/engines/illusions/bbdou/gamestate_bbdou.h b/engines/illusions/bbdou/gamestate_bbdou.h
new file mode 100644
index 0000000000..2ef68b5b5e
--- /dev/null
+++ b/engines/illusions/bbdou/gamestate_bbdou.h
@@ -0,0 +1,44 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ILLUSIONS_BBDOU_GAMESTATE_BBDOU_H
+#define ILLUSIONS_BBDOU_GAMESTATE_BBDOU_H
+
+#include "illusions/gamestate.h"
+
+namespace Illusions {
+
+class IllusionsEngine_BBDOU;
+
+class BBDOU_GameState : public GameState {
+public:
+ BBDOU_GameState(IllusionsEngine_BBDOU *vm);
+protected:
+ IllusionsEngine_BBDOU *_vm;
+ uint32 calcWriteBufferSizeInternal();
+ bool readStateInternal(Common::ReadStream *in);
+ void writeStateInternal(Common::WriteStream *out);
+};
+
+} // End of namespace Illusions
+
+#endif // ILLUSIONS_BBDOU_GAMESTATE_BBDOU_H
diff --git a/engines/illusions/bbdou/illusions_bbdou.cpp b/engines/illusions/bbdou/illusions_bbdou.cpp
index 7c129f12b6..78315c404c 100644
--- a/engines/illusions/bbdou/illusions_bbdou.cpp
+++ b/engines/illusions/bbdou/illusions_bbdou.cpp
@@ -23,6 +23,7 @@
#include "illusions/bbdou/illusions_bbdou.h"
#include "illusions/bbdou/bbdou_menukeys.h"
#include "illusions/bbdou/bbdou_videoplayer.h"
+#include "illusions/bbdou/gamestate_bbdou.h"
#include "illusions/bbdou/menusystem_bbdou.h"
#include "illusions/actor.h"
#include "illusions/camera.h"
@@ -171,6 +172,7 @@ Common::Error IllusionsEngine_BBDOU::run() {
_soundMan = new SoundMan(this);
_menuSystem = new BBDOUMenuSystem(this);
_videoPlayer = new BBDOUVideoPlayer(this);
+ _gameState = new BBDOU_GameState(this);
_menuKeys = new BBDOUMenuKeys(this);
_screen->setColorKey1(0xF81F);
@@ -205,7 +207,12 @@ Common::Error IllusionsEngine_BBDOU::run() {
startScriptThread(0x00020004, 0, 0, 0, 0);
_doScriptThreadInit = true;
+ if (ConfMan.hasKey("save_slot")) {
+ loadGameState(ConfMan.getInt("save_slot"));
+ }
+
_walkthroughStarted = false;
+ _canResumeFromSavegame = false;
while (!shouldQuit()) {
if (_walkthroughStarted) {
@@ -213,6 +220,10 @@ Common::Error IllusionsEngine_BBDOU::run() {
startScriptThread(0x00020404, 0, 0, 0, 0);
_walkthroughStarted = false;
}
+ if (_resumeFromSavegameRequested && _canResumeFromSavegame) {
+ resumeFromSavegame();
+ _resumeFromSavegameRequested = false;
+ }
runUpdateFunctions();
_system->updateScreen();
updateEvents();
@@ -222,6 +233,7 @@ Common::Error IllusionsEngine_BBDOU::run() {
delete _scriptOpcodes;
delete _menuKeys;
+ delete _gameState;
delete _videoPlayer;
delete _menuSystem;
delete _soundMan;
@@ -248,12 +260,9 @@ Common::Error IllusionsEngine_BBDOU::run() {
bool IllusionsEngine_BBDOU::hasFeature(EngineFeature f) const {
return
- false;
- /*
(f == kSupportsRTL) ||
(f == kSupportsLoadingDuringRuntime) ||
(f == kSupportsSavingDuringRuntime);
- */
}
void IllusionsEngine_BBDOU::initInput() {
@@ -460,6 +469,11 @@ void IllusionsEngine_BBDOU::startScriptThreadSimple(uint32 threadId, uint32 call
void IllusionsEngine_BBDOU::startScriptThread(uint32 threadId, uint32 callingThreadId,
uint32 value8, uint32 valueC, uint32 value10) {
+ if (threadId == 0x0002041E && ConfMan.hasKey("save_slot")) {
+ // Skip intro videos when loading a savegame from the launcher (kludge)
+ notifyThreadId(callingThreadId);
+ return;
+ }
debug(2, "Starting script thread %08X", threadId);
byte *scriptCodeIp = _scriptResource->getThreadCode(threadId);
newScriptThread(threadId, callingThreadId, 0, scriptCodeIp, value8, valueC, value10);
@@ -503,10 +517,6 @@ uint32 IllusionsEngine_BBDOU::startTalkThread(int16 duration, uint32 objectId, u
return tempThreadId;
}
-void IllusionsEngine_BBDOU::resumeFromSavegame(uint32 callingThreadId) {
- // TODO
-}
-
uint32 IllusionsEngine_BBDOU::startTempScriptThread(byte *scriptCodeIp, uint32 callingThreadId,
uint32 value8, uint32 valueC, uint32 value10) {
uint32 tempThreadId = newTempThreadId();
@@ -555,6 +565,13 @@ bool IllusionsEngine_BBDOU::enterScene(uint32 sceneId, uint32 threadId) {
sceneId = _theSceneId;
}
_activeScenes.push(sceneId);
+ if (sceneId == 0x0001007D) {
+ // Savegame loading from the ScummVM GUI or command line is only
+ // possible after resources have been initialized by the startup script.
+ // Once that script is done, it switches to the start menu scene.
+ // After that the game is ready and a savegame can finally be loaded.
+ _canResumeFromSavegame = true;
+ }
return sceneInfo != 0;
}
@@ -647,4 +664,34 @@ void IllusionsEngine_BBDOU::reset() {
// TODO script_sub_417FF0(1, 0);
}
+void IllusionsEngine_BBDOU::loadSavegameFromScript(int16 slotNum, uint32 callingThreadId) {
+ // NOTE Just loads the savegame, doesn't activate it yet
+ const char *fileName = getSavegameFilename(_savegameSlotNum);
+ _loadGameResult = loadgame(fileName);
+}
+
+void IllusionsEngine_BBDOU::saveSavegameFromScript(int16 slotNum, uint32 callingThreadId) {
+ // TODO
+ // const char *fileName = getSavegameFilename(slotNum);
+ _saveGameResult = false;//savegame(fileName, _savegameDescription.c_str());
+}
+
+void IllusionsEngine_BBDOU::activateSavegame(uint32 callingThreadId) {
+ uint32 sceneId, threadId;
+ _prevSceneId = 0x10000;
+ _gameState->readState(sceneId, threadId);
+ enterScene(sceneId, callingThreadId);
+ // TODO Check if value8, valueC, value10 are needed at all
+ startAnonScriptThread(threadId, 0, 0, 0, 0);
+ _gameState->deleteReadStream();
+}
+
+void IllusionsEngine_BBDOU::resumeFromSavegame() {
+ // Resetting the game is usually done by the script, when loading from the ScummVM menu or
+ // command line this has to be done manually.
+ _specialCode->resetBeforeResumeSavegame();
+ dumpActiveScenes(0x00010003, 0);
+ activateSavegame(0);
+}
+
} // End of namespace Illusions
diff --git a/engines/illusions/bbdou/illusions_bbdou.h b/engines/illusions/bbdou/illusions_bbdou.h
index 2bad993041..f9311e1723 100644
--- a/engines/illusions/bbdou/illusions_bbdou.h
+++ b/engines/illusions/bbdou/illusions_bbdou.h
@@ -75,11 +75,14 @@ public:
uint32 _theThreadId;
uint32 _globalSceneId;
+ bool _loadGameResult, _saveGameResult;
+
BBDOUMenuSystem *_menuSystem;
BBDOUVideoPlayer *_videoPlayer;
BBDOUMenuKeys *_menuKeys;
bool _walkthroughStarted;
+ bool _canResumeFromSavegame;
void initInput();
@@ -128,7 +131,6 @@ public:
uint32 sequenceId2, uint32 namedPointId, uint32 callingThreadId);
uint32 startTempScriptThread(byte *scriptCodeIp, uint32 callingThreadId,
uint32 value8, uint32 valueC, uint32 value10);
- void resumeFromSavegame(uint32 callingThreadId);
void newScriptThread(uint32 threadId, uint32 callingThreadId, uint notifyFlags,
byte *scriptCodeIp, uint32 value8, uint32 valueC, uint32 value10);
@@ -151,6 +153,11 @@ public:
bool findTriggerCause(uint32 sceneId, uint32 verbId, uint32 objectId2, uint32 objectId, uint32 &codeOffs);
void reset();
+ void loadSavegameFromScript(int16 slotNum, uint32 callingThreadId);
+ void saveSavegameFromScript(int16 slotNum, uint32 callingThreadId);
+ void activateSavegame(uint32 callingThreadId);
+ void resumeFromSavegame();
+
};
} // End of namespace Illusions
diff --git a/engines/illusions/bbdou/scriptopcodes_bbdou.cpp b/engines/illusions/bbdou/scriptopcodes_bbdou.cpp
index e70be8fdb9..9dd9c9aac4 100644
--- a/engines/illusions/bbdou/scriptopcodes_bbdou.cpp
+++ b/engines/illusions/bbdou/scriptopcodes_bbdou.cpp
@@ -23,6 +23,7 @@
#include "illusions/bbdou/illusions_bbdou.h"
#include "illusions/bbdou/scriptopcodes_bbdou.h"
#include "illusions/bbdou/bbdou_menukeys.h"
+#include "illusions/bbdou/gamestate_bbdou.h"
#include "illusions/bbdou/menusystem_bbdou.h"
#include "illusions/actor.h"
#include "illusions/camera.h"
@@ -140,8 +141,8 @@ void ScriptOpcodes_BBDOU::initOpcodes() {
OPCODE(82, opSwitchMenuChoice);
OPCODE(83, opQuitGame);
OPCODE(84, opResetGame);
- // TODO OPCODE(85, opSaveGame);
- // TODO OPCODE(86, opRestoreGame);
+ OPCODE(85, opSaveGame);
+ OPCODE(86, opRestoreGameState);
OPCODE(87, opDeactivateButton);
OPCODE(88, opActivateButton);
OPCODE(89, opNop);
@@ -170,6 +171,10 @@ void ScriptOpcodes_BBDOU::initOpcodes() {
OPCODE(161, opSetActorUsePan);
OPCODE(168, opStartAbortableThread);
OPCODE(169, opKillThread);
+ OPCODE(170, opLoadGame);
+ OPCODE(171, opPushLoadgameResult);
+ OPCODE(172, opPushSavegameResult);
+ // 173, 174 unused
OPCODE(175, opSetSceneIdThreadId);
OPCODE(176, opStackPush0);
OPCODE(177, opSetFontId);
@@ -342,7 +347,7 @@ void ScriptOpcodes_BBDOU::opChangeScene(ScriptThread *scriptThread, OpCall &opCa
_vm->_prevSceneId = _vm->getCurrentScene();
_vm->exitScene(opCall._callerThreadId);
_vm->enterScene(sceneId, opCall._callerThreadId);
- // TODO _vm->_gameStates->writeStates(_vm->_prevSceneId, sceneId, threadId);
+ _vm->_gameState->writeState(sceneId, threadId);
_vm->startAnonScriptThread(threadId, 0,
scriptThread->_value8, scriptThread->_valueC, scriptThread->_value10);
}
@@ -740,6 +745,17 @@ void ScriptOpcodes_BBDOU::opResetGame(ScriptThread *scriptThread, OpCall &opCall
// TODO _vm->_gameStates->clear();
}
+void ScriptOpcodes_BBDOU::opSaveGame(ScriptThread *scriptThread, OpCall &opCall) {
+ ARG_SKIP(2);
+ ARG_INT16(bankNum)
+ ARG_INT16(slotNum)
+ _vm->saveSavegameFromScript(slotNum, opCall._callerThreadId);
+}
+
+void ScriptOpcodes_BBDOU::opRestoreGameState(ScriptThread *scriptThread, OpCall &opCall) {
+ _vm->activateSavegame(opCall._callerThreadId);
+}
+
void ScriptOpcodes_BBDOU::opDeactivateButton(ScriptThread *scriptThread, OpCall &opCall) {
ARG_INT16(button)
_vm->_input->deactivateButton(button);
@@ -920,6 +936,21 @@ void ScriptOpcodes_BBDOU::opKillThread(ScriptThread *scriptThread, OpCall &opCal
_vm->_threads->killThread(threadId);
}
+void ScriptOpcodes_BBDOU::opLoadGame(ScriptThread *scriptThread, OpCall &opCall) {
+ ARG_SKIP(2);
+ ARG_INT16(bankNum)
+ ARG_INT16(slotNum)
+ _vm->loadSavegameFromScript(slotNum, opCall._callerThreadId);
+}
+
+void ScriptOpcodes_BBDOU::opPushLoadgameResult(ScriptThread *scriptThread, OpCall &opCall) {
+ _vm->_stack->push(_vm->_loadGameResult ? 1 : 0);
+}
+
+void ScriptOpcodes_BBDOU::opPushSavegameResult(ScriptThread *scriptThread, OpCall &opCall) {
+ _vm->_stack->push(_vm->_saveGameResult ? 1 : 0);
+}
+
void ScriptOpcodes_BBDOU::opSetSceneIdThreadId(ScriptThread *scriptThread, OpCall &opCall) {
ARG_SKIP(2);
ARG_UINT32(sceneId);
@@ -941,7 +972,6 @@ void ScriptOpcodes_BBDOU::opAddMenuKey(ScriptThread *scriptThread, OpCall &opCal
ARG_SKIP(2);
ARG_UINT32(key);
ARG_UINT32(threadId);
- debug("addMenuKey(%08X; %08X)", key, threadId);
_vm->_menuKeys->addMenuKey(key, threadId);
}
@@ -954,7 +984,7 @@ void ScriptOpcodes_BBDOU::opChangeSceneAll(ScriptThread *scriptThread, OpCall &o
_vm->_prevSceneId = _vm->getCurrentScene();
_vm->dumpActiveScenes(_vm->_globalSceneId, opCall._callerThreadId);
_vm->enterScene(sceneId, opCall._callerThreadId);
- // TODO _vm->_gameStates->writeStates(_vm->_prevSceneId, sceneId, threadId);
+ _vm->_gameState->writeState(sceneId, threadId);
_vm->startAnonScriptThread(threadId, 0,
scriptThread->_value8, scriptThread->_valueC, scriptThread->_value10);
}
diff --git a/engines/illusions/bbdou/scriptopcodes_bbdou.h b/engines/illusions/bbdou/scriptopcodes_bbdou.h
index a1118836e2..63731cf412 100644
--- a/engines/illusions/bbdou/scriptopcodes_bbdou.h
+++ b/engines/illusions/bbdou/scriptopcodes_bbdou.h
@@ -110,6 +110,8 @@ protected:
void opSwitchMenuChoice(ScriptThread *scriptThread, OpCall &opCall);
void opQuitGame(ScriptThread *scriptThread, OpCall &opCall);
void opResetGame(ScriptThread *scriptThread, OpCall &opCall);
+ void opSaveGame(ScriptThread *scriptThread, OpCall &opCall);
+ void opRestoreGameState(ScriptThread *scriptThread, OpCall &opCall);
void opDeactivateButton(ScriptThread *scriptThread, OpCall &opCall);
void opActivateButton(ScriptThread *scriptThread, OpCall &opCall);
void opNop(ScriptThread *scriptThread, OpCall &opCall);
@@ -135,6 +137,9 @@ protected:
void opSetActorUsePan(ScriptThread *scriptThread, OpCall &opCall);
void opStartAbortableThread(ScriptThread *scriptThread, OpCall &opCall);
void opKillThread(ScriptThread *scriptThread, OpCall &opCall);
+ void opLoadGame(ScriptThread *scriptThread, OpCall &opCall);
+ void opPushLoadgameResult(ScriptThread *scriptThread, OpCall &opCall);
+ void opPushSavegameResult(ScriptThread *scriptThread, OpCall &opCall);
void opSetSceneIdThreadId(ScriptThread *scriptThread, OpCall &opCall);
void opStackPush0(ScriptThread *scriptThread, OpCall &opCall);
void opSetFontId(ScriptThread *scriptThread, OpCall &opCall);
diff --git a/engines/illusions/illusions.h b/engines/illusions/illusions.h
index 9c73c478a7..4140c9c4fb 100644
--- a/engines/illusions/illusions.h
+++ b/engines/illusions/illusions.h
@@ -211,7 +211,6 @@ public:
virtual void startScriptThreadSimple(uint32 threadId, uint32 callingThreadId) = 0;
virtual uint32 startTempScriptThread(byte *scriptCodeIp, uint32 callingThreadId,
uint32 value8, uint32 valueC, uint32 value10) = 0;
- virtual void resumeFromSavegame(uint32 callingThreadId) = 0;
// Savegame API
diff --git a/engines/illusions/module.mk b/engines/illusions/module.mk
index cb68485218..6d2a5aa163 100644
--- a/engines/illusions/module.mk
+++ b/engines/illusions/module.mk
@@ -11,6 +11,7 @@ MODULE_OBJS := \
bbdou/bbdou_menukeys.o \
bbdou/bbdou_specialcode.o \
bbdou/bbdou_videoplayer.o \
+ bbdou/gamestate_bbdou.o \
bbdou/bbdou_triggerfunctions.o \
bbdou/illusions_bbdou.o \
bbdou/menusystem_bbdou.o \
diff --git a/engines/illusions/specialcode.h b/engines/illusions/specialcode.h
index 9a69b389b3..25d7032519 100644
--- a/engines/illusions/specialcode.h
+++ b/engines/illusions/specialcode.h
@@ -47,6 +47,7 @@ public:
virtual ~SpecialCode() {}
virtual void init() = 0;
virtual void run(uint32 specialCodeId, OpCall &opCall) = 0;
+ virtual void resetBeforeResumeSavegame() {};
};
} // End of namespace Illusions