aboutsummaryrefslogtreecommitdiff
path: root/engines/illusions/duckman
diff options
context:
space:
mode:
authorjohndoe1232015-12-04 23:20:22 +0100
committerEugene Sandulenko2018-07-20 06:43:33 +0000
commitaed38527010e7b155af469d0521aa07e7fd7d12e (patch)
tree95a5ce5eb4ce90fe1500a6265090a5292c5faf17 /engines/illusions/duckman
parent6b36b750c2567c32d20f8f7868a8b664baac5cde (diff)
downloadscummvm-rg350-aed38527010e7b155af469d0521aa07e7fd7d12e.tar.gz
scummvm-rg350-aed38527010e7b155af469d0521aa07e7fd7d12e.tar.bz2
scummvm-rg350-aed38527010e7b155af469d0521aa07e7fd7d12e.zip
ILLUSIONS: Implement save/load functionality
- Only works in Duckman at the moment - Only via the ScummVM main menu for now, save/load via the game's menu to be implemented
Diffstat (limited to 'engines/illusions/duckman')
-rw-r--r--engines/illusions/duckman/gamestate_duckman.cpp50
-rw-r--r--engines/illusions/duckman/gamestate_duckman.h44
-rw-r--r--engines/illusions/duckman/illusions_duckman.cpp86
-rw-r--r--engines/illusions/duckman/illusions_duckman.h5
-rw-r--r--engines/illusions/duckman/scriptopcodes_duckman.cpp12
5 files changed, 152 insertions, 45 deletions
diff --git a/engines/illusions/duckman/gamestate_duckman.cpp b/engines/illusions/duckman/gamestate_duckman.cpp
new file mode 100644
index 0000000000..8f4939f9dc
--- /dev/null
+++ b/engines/illusions/duckman/gamestate_duckman.cpp
@@ -0,0 +1,50 @@
+/* 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/duckman/gamestate_duckman.h"
+#include "illusions/duckman/illusions_duckman.h"
+#include "illusions/resources/scriptresource.h"
+
+namespace Illusions {
+
+Duckman_GameState::Duckman_GameState(IllusionsEngine_Duckman *vm)
+ : _vm(vm) {
+}
+
+uint32 Duckman_GameState::calcWriteBufferSizeInternal() {
+ return
+ _vm->_scriptResource->_properties.getSize() +
+ _vm->_scriptResource->_blockCounters.getSize();
+}
+
+bool Duckman_GameState::readStateInternal(Common::ReadStream *in) {
+ return
+ _vm->_scriptResource->_properties.readFromStream(in) &&
+ _vm->_scriptResource->_blockCounters.readFromStream(in);
+}
+
+void Duckman_GameState::writeStateInternal(Common::WriteStream *out) {
+ _vm->_scriptResource->_properties.writeToStream(out);
+ _vm->_scriptResource->_blockCounters.writeToStream(out);
+}
+
+} // End of namespace Illusions
diff --git a/engines/illusions/duckman/gamestate_duckman.h b/engines/illusions/duckman/gamestate_duckman.h
new file mode 100644
index 0000000000..36024c8d8e
--- /dev/null
+++ b/engines/illusions/duckman/gamestate_duckman.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_DUCKMAN_GAMESTATE_DUCKMAN_H
+#define ILLUSIONS_DUCKMAN_GAMESTATE_DUCKMAN_H
+
+#include "illusions/gamestate.h"
+
+namespace Illusions {
+
+class IllusionsEngine_Duckman;
+
+class Duckman_GameState : public GameState {
+public:
+ Duckman_GameState(IllusionsEngine_Duckman *vm);
+protected:
+ IllusionsEngine_Duckman *_vm;
+ uint32 calcWriteBufferSizeInternal();
+ bool readStateInternal(Common::ReadStream *in);
+ void writeStateInternal(Common::WriteStream *out);
+};
+
+} // End of namespace Illusions
+
+#endif // ILLUSIONS_DUCKMAN_GAMESTATE_DUCKMAN_H
diff --git a/engines/illusions/duckman/illusions_duckman.cpp b/engines/illusions/duckman/illusions_duckman.cpp
index ebfcdca4bd..c9233ae6d1 100644
--- a/engines/illusions/duckman/illusions_duckman.cpp
+++ b/engines/illusions/duckman/illusions_duckman.cpp
@@ -23,6 +23,7 @@
#include "illusions/duckman/illusions_duckman.h"
#include "illusions/duckman/duckman_dialog.h"
#include "illusions/duckman/duckman_specialcode.h"
+#include "illusions/duckman/gamestate_duckman.h"
#include "illusions/duckman/menusystem_duckman.h"
#include "illusions/duckman/scriptopcodes_duckman.h"
#include "illusions/actor.h"
@@ -114,6 +115,7 @@ Common::Error IllusionsEngine_Duckman::run() {
_updateFunctions = new UpdateFunctions();
_soundMan = new SoundMan(this);
_menuSystem = new DuckmanMenuSystem(this);
+ _gameState = new Duckman_GameState(this);
_fader = new Fader();
@@ -153,10 +155,7 @@ Common::Error IllusionsEngine_Duckman::run() {
_resSys->loadResource(0x120001, 0x00010001, 0);
_resSys->loadResource(0x120002, 0x00010001, 0);
_resSys->loadResource(0x120003, 0x00010001, 0);
-
_resSys->loadResource(0x000D0001, 0x00010001, 0);
- startScriptThread(0x00020004, 0);
- _doScriptThreadInit = true;
#if 0
//DEBUG
@@ -174,13 +173,28 @@ Common::Error IllusionsEngine_Duckman::run() {
_scriptResource->_blockCounters.set(238, 1);
#endif
-#if 1
+#if 0
// DEBUG Map / special code 0016001A
_scriptResource->_properties.set(0x000E0017, true);
_scriptResource->_properties.set(0x000E0022, false);
#endif
+ if (ConfMan.hasKey("save_slot")) {
+ _doScriptThreadInit = true;
+ // Load global resources manually, usually done by the game script
+ enterScene(0x00010003, 0);
+ loadGameState(ConfMan.getInt("save_slot"));
+ } else {
+ startScriptThread(0x00020004, 0);
+ _doScriptThreadInit = true;
+ }
+
while (!shouldQuit()) {
+ if (_resumeFromSavegameRequested) {
+ activateSavegame(0);
+ resumeFromSavegame(0);
+ _resumeFromSavegameRequested = false;
+ }
runUpdateFunctions();
_system->updateScreen();
updateEvents();
@@ -195,6 +209,7 @@ Common::Error IllusionsEngine_Duckman::run() {
delete _fader;
+ delete _gameState;
delete _menuSystem;
delete _soundMan;
delete _updateFunctions;
@@ -218,12 +233,9 @@ Common::Error IllusionsEngine_Duckman::run() {
bool IllusionsEngine_Duckman::hasFeature(EngineFeature f) const {
return
- false;
- /*
(f == kSupportsRTL) ||
(f == kSupportsLoadingDuringRuntime) ||
(f == kSupportsSavingDuringRuntime);
- */
}
void IllusionsEngine_Duckman::initInput() {
@@ -793,7 +805,7 @@ bool IllusionsEngine_Duckman::changeScene(uint32 sceneId, uint32 threadId, uint3
_controls->destroyControls();
_resSys->unloadSceneResources(0x10003, 0x10001);
if (enterScene(sceneId, threadId)) {
- // TODO GameStates_writeStates(sceneId, threadId);
+ _gameState->writeState(sceneId, threadId);
return true;
}
return false;
@@ -1075,23 +1087,24 @@ uint32 IllusionsEngine_Duckman::runTriggerCause(uint32 verbId, uint32 objectId2,
if (!getTriggerCause(verbId, objectId2, objectId, triggerThreadId))
return 0;
- bool flag = false;
+ // TODO Extract sound effect playing to method
+ bool soundWasPlayed = false;
if (_scriptResource->_properties.get(0x000E003C)) {
if (verbId == 7 && objectId == 0x40003) {
playSoundEffect(7);
- flag = true;
+ soundWasPlayed = true;
} else if (objectId == 0x40003) {
playSoundEffect(14);
- flag = true;
+ soundWasPlayed = true;
} else if (verbId == 3) {
playSoundEffect(16);
- flag = true;
+ soundWasPlayed = true;
} else if (verbId == 2) {
- flag = true;
+ soundWasPlayed = true;
}
}
- if (!flag) {
+ if (!soundWasPlayed) {
if (objectId == 0x40003) {
playSoundEffect(14);
} else if ((verbId == 1 || verbId == 2) && _scriptResource->getMainActorObjectId() == objectId) {
@@ -1120,34 +1133,33 @@ uint32 IllusionsEngine_Duckman::runTriggerCause(uint32 verbId, uint32 objectId2,
return tempThreadId;
}
-bool IllusionsEngine_Duckman::loadSavegame(int16 slotNum, uint32 callingThreadId) {
-#if 0
- // TODO
- bool success = _gameStates->load(slotNum);
- if (success) {
- _vm->_screen->setDisplayOn(false);
- uint32 currSceneId = getCurrentScene();
- if (currSceneId != 0x10003)
- dumpCurrSceneFiles(currSceneId, callerThreadId);
- reset();
- stopMidi();
- clearMidiPlayList();
- _gameStates->readStates();
- pushActiveScene(0x10000);
- }
- _gameStates->freeGameStateReadBuffer();
+bool IllusionsEngine_Duckman::loadSavegameFromScript(int16 slotNum, uint32 callingThreadId) {
+ const char *fileName = getSavegameFilename(slotNum);
+ bool success = loadgame(fileName);
+ if (success)
+ activateSavegame(callingThreadId);
+ _gameState->deleteReadStream();
return success;
-#endif
- return true;
}
-bool IllusionsEngine_Duckman::saveSavegame(int16 slotNum, uint32 callingThreadId) {
-#if 0
+bool IllusionsEngine_Duckman::saveSavegameFromScript(int16 slotNum, uint32 callingThreadId) {
// TODO
- bool success = _gameStates->save(slotNum);
+ const char *fileName = getSavegameFilename(slotNum);
+ bool success = false;//savegame(fileName, _savegameDescription.c_str());
return success;
-#endif
- return true;
+}
+
+void IllusionsEngine_Duckman::activateSavegame(uint32 callingThreadId) {
+ // TODO _screen->setDisplayOn(false);
+ uint32 currSceneId = getCurrentScene();
+ if (currSceneId != 0x10003)
+ dumpCurrSceneFiles(currSceneId, callingThreadId);
+ reset();
+ // TODO stopMidi();
+ // TODO clearMidiPlayList();
+ _gameState->readState(_savegameSceneId, _savegameThreadId);
+ pushActiveScene(0x10000);
+ _gameState->deleteReadStream();
}
} // End of namespace Illusions
diff --git a/engines/illusions/duckman/illusions_duckman.h b/engines/illusions/duckman/illusions_duckman.h
index 87520d3a6a..1825123e5c 100644
--- a/engines/illusions/duckman/illusions_duckman.h
+++ b/engines/illusions/duckman/illusions_duckman.h
@@ -187,8 +187,9 @@ public:
bool getTriggerCause(uint32 verbId, uint32 objectId2, uint32 objectId, uint32 &outThreadId);
uint32 runTriggerCause(uint32 verbId, uint32 objectId2, uint32 objectId);
- bool loadSavegame(int16 slotNum, uint32 callingThreadId);
- bool saveSavegame(int16 slotNum, uint32 callingThreadId);
+ bool loadSavegameFromScript(int16 slotNum, uint32 callingThreadId);
+ bool saveSavegameFromScript(int16 slotNum, uint32 callingThreadId);
+ void activateSavegame(uint32 callingThreadId);
};
diff --git a/engines/illusions/duckman/scriptopcodes_duckman.cpp b/engines/illusions/duckman/scriptopcodes_duckman.cpp
index a62a78b46b..1456cfc0ee 100644
--- a/engines/illusions/duckman/scriptopcodes_duckman.cpp
+++ b/engines/illusions/duckman/scriptopcodes_duckman.cpp
@@ -259,7 +259,7 @@ void ScriptOpcodes_Duckman::opUnloadResourcesBySceneId(ScriptThread *scriptThrea
//static uint dsceneId = 0, dthreadId = 0;
//static uint dsceneId = 0x00010008, dthreadId = 0x00020029;//Beginning in Jac
-//static uint dsceneId = 0x0001000A, dthreadId = 0x00020043;//Home front
+static uint dsceneId = 0x0001000A, dthreadId = 0x00020043;//Home front
//static uint dsceneId = 0x0001000E, dthreadId = 0x0002007C;
//static uint dsceneId = 0x00010012, dthreadId = 0x0002009D;//Paramount
//static uint dsceneId = 0x00010020, dthreadId = 0x00020112;//Xmas
@@ -276,7 +276,7 @@ void ScriptOpcodes_Duckman::opUnloadResourcesBySceneId(ScriptThread *scriptThrea
//static uint dsceneId = 0x10002, dthreadId = 0x20001;//Debug menu, not supported
//static uint dsceneId = 0x10044, dthreadId = 0x000202B8; // Starship Enterprise
//static uint dsceneId = 0x00010039, dthreadId = 0x00020089; // Map
-static uint dsceneId = 0x00010052, dthreadId = 0x00020347; // Credits
+//static uint dsceneId = 0x00010052, dthreadId = 0x00020347; // Credits
void ScriptOpcodes_Duckman::opChangeScene(ScriptThread *scriptThread, OpCall &opCall) {
ARG_SKIP(2);
@@ -348,12 +348,12 @@ void ScriptOpcodes_Duckman::opLeaveScene24(ScriptThread *scriptThread, OpCall &o
void ScriptOpcodes_Duckman::opEnterDebugger(ScriptThread *scriptThread, OpCall &opCall) {
// Used for debugging purposes in the original engine
// This is not supported and only reachable by code not implemented here!
- error("ScriptOpcodes_Duckman::opEnterDebugger() Debugger function called");
+ //error("ScriptOpcodes_Duckman::opEnterDebugger() Debugger function called");
}
void ScriptOpcodes_Duckman::opLeaveDebugger(ScriptThread *scriptThread, OpCall &opCall) {
// See opEnterDebugger
- error("ScriptOpcodes_Duckman::opLeaveDebugger() Debugger function called");
+ //error("ScriptOpcodes_Duckman::opLeaveDebugger() Debugger function called");
}
void ScriptOpcodes_Duckman::opDumpCurrentSceneFiles(ScriptThread *scriptThread, OpCall &opCall) {
@@ -690,7 +690,7 @@ void ScriptOpcodes_Duckman::opLoadGame(ScriptThread *scriptThread, OpCall &opCal
ARG_SKIP(2);
ARG_INT16(bankNum)
ARG_INT16(slotNum)
- bool success = _vm->loadSavegame(slotNum, opCall._callerThreadId);
+ bool success = _vm->loadSavegameFromScript(slotNum, opCall._callerThreadId);
_vm->_stack->push(success ? 1 : 0);
}
@@ -698,7 +698,7 @@ void ScriptOpcodes_Duckman::opSaveGame(ScriptThread *scriptThread, OpCall &opCal
ARG_SKIP(2);
ARG_INT16(bankNum)
ARG_INT16(slotNum)
- bool success = _vm->saveSavegame(slotNum, opCall._callerThreadId);
+ bool success = _vm->saveSavegameFromScript(slotNum, opCall._callerThreadId);
_vm->_stack->push(success ? 1 : 0);
}