aboutsummaryrefslogtreecommitdiff
path: root/engines/adl/adl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/adl/adl.cpp')
-rw-r--r--engines/adl/adl.cpp275
1 files changed, 145 insertions, 130 deletions
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index bc5bc74f3a..c1c3820b10 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -56,11 +56,14 @@ AdlEngine::AdlEngine(OSystem *syst, const AdlGameDescription *gd) :
_dumpFile(nullptr),
_display(nullptr),
_graphics(nullptr),
+ _speaker(nullptr),
_isRestarting(false),
_isRestoring(false),
_isQuitting(false),
_skipOneCommand(false),
_gameDescription(gd),
+ _console(nullptr),
+ _messageIds(),
_saveVerb(0),
_saveNoun(0),
_restoreVerb(0),
@@ -427,6 +430,11 @@ void AdlEngine::initState() {
initGameState();
}
+void AdlEngine::switchRoom(byte roomNr) {
+ getCurRoom().curPicture = getCurRoom().picture;
+ _state.room = roomNr;
+}
+
byte AdlEngine::roomArg(byte room) const {
return room;
}
@@ -578,6 +586,60 @@ void AdlEngine::dropItem(byte noun) {
printMessage(_messageIds.dontUnderstand);
}
+void AdlEngine::gameLoop() {
+ uint verb = 0, noun = 0;
+ _isRestarting = false;
+
+ // When restoring from the launcher, we don't read
+ // input on the first iteration. This is needed to
+ // ensure that restoring from the launcher and
+ // restoring in-game brings us to the same game state.
+ // (Also see comment below.)
+ if (!_isRestoring) {
+ showRoom();
+
+ if (_isRestarting)
+ return;
+
+ _canSaveNow = _canRestoreNow = true;
+ getInput(verb, noun);
+ _canSaveNow = _canRestoreNow = false;
+
+ if (shouldQuit())
+ return;
+
+ // If we just restored from the GMM, we skip this command
+ // set, as no command has been input by the user
+ if (!_isRestoring)
+ checkInput(verb, noun);
+ }
+
+ if (_isRestoring) {
+ // We restored from the GMM or launcher. As restoring
+ // with "RESTORE GAME" does not end command processing,
+ // we don't break it off here either. This essentially
+ // means that restoring a game will always run through
+ // the global commands and increase the move counter
+ // before the first user input.
+ _display->printAsciiString("\r");
+ _isRestoring = false;
+ verb = _restoreVerb;
+ noun = _restoreNoun;
+ }
+
+ // Restarting does end command processing
+ if (_isRestarting)
+ return;
+
+ doAllCommands(_globalCommands, verb, noun);
+
+ if (_isRestarting)
+ return;
+
+ advanceClock();
+ _state.moves++;
+}
+
Common::Error AdlEngine::run() {
initGraphics(DISPLAY_WIDTH * 2, DISPLAY_HEIGHT * 2, true);
@@ -603,59 +665,8 @@ Common::Error AdlEngine::run() {
_display->setMode(DISPLAY_MODE_MIXED);
- while (!_isQuitting) {
- uint verb = 0, noun = 0;
- _isRestarting = false;
-
- // When restoring from the launcher, we don't read
- // input on the first iteration. This is needed to
- // ensure that restoring from the launcher and
- // restoring in-game brings us to the same game state.
- // (Also see comment below.)
- if (!_isRestoring) {
- showRoom();
-
- if (_isRestarting)
- continue;
-
- _canSaveNow = _canRestoreNow = true;
- getInput(verb, noun);
- _canSaveNow = _canRestoreNow = false;
-
- if (shouldQuit())
- break;
-
- // If we just restored from the GMM, we skip this command
- // set, as no command has been input by the user
- if (!_isRestoring)
- checkInput(verb, noun);
- }
-
- if (_isRestoring) {
- // We restored from the GMM or launcher. As restoring
- // with "RESTORE GAME" does not end command processing,
- // we don't break it off here either. This essentially
- // means that restoring a game will always run through
- // the global commands and increase the move counter
- // before the first user input.
- _display->printAsciiString("\r");
- _isRestoring = false;
- verb = _restoreVerb;
- noun = _restoreNoun;
- }
-
- // Restarting does end command processing
- if (_isRestarting)
- continue;
-
- doAllCommands(_globalCommands, verb, noun);
-
- if (_isRestarting)
- continue;
-
- advanceClock();
- _state.moves++;
- }
+ while (!(_isQuitting || shouldQuit()))
+ gameLoop();
return Common::kNoError;
}
@@ -671,6 +682,49 @@ bool AdlEngine::hasFeature(EngineFeature f) const {
}
}
+void AdlEngine::loadState(Common::ReadStream &stream) {
+ _state.room = stream.readByte();
+ _state.moves = stream.readByte();
+ _state.isDark = stream.readByte();
+ _state.time.hours = stream.readByte();
+ _state.time.minutes = stream.readByte();
+
+ uint32 size = stream.readUint32BE();
+ if (size != _state.rooms.size())
+ error("Room count mismatch (expected %i; found %i)", _state.rooms.size(), size);
+
+ for (uint i = 0; i < size; ++i) {
+ _state.rooms[i].picture = stream.readByte();
+ _state.rooms[i].curPicture = stream.readByte();
+ _state.rooms[i].isFirstTime = stream.readByte();
+ }
+
+ // NOTE: _state.curPicture is part of the save state in the original engine. We
+ // reconstruct it instead. This is believed to be safe for at least hires 0-2, but
+ // this may need to be re-evaluated for later games.
+ _state.curPicture = getCurRoom().curPicture;
+
+ size = stream.readUint32BE();
+ if (size != _state.items.size())
+ error("Item count mismatch (expected %i; found %i)", _state.items.size(), size);
+
+ Common::List<Item>::iterator item;
+ for (item = _state.items.begin(); item != _state.items.end(); ++item) {
+ item->room = stream.readByte();
+ item->picture = stream.readByte();
+ item->position.x = stream.readByte();
+ item->position.y = stream.readByte();
+ item->state = stream.readByte();
+ }
+
+ size = stream.readUint32BE();
+ if (size != _state.vars.size())
+ error("Variable count mismatch (expected %i; found %i)", _state.vars.size(), size);
+
+ for (uint i = 0; i < size; ++i)
+ _state.vars[i] = stream.readByte();
+}
+
Common::Error AdlEngine::loadGameState(int slot) {
Common::String fileName = Common::String::format("%s.s%02d", _targetName.c_str(), slot);
Common::InSaveFile *inFile = getSaveFileManager()->openForLoading(fileName);
@@ -703,47 +757,7 @@ Common::Error AdlEngine::loadGameState(int slot) {
Graphics::skipThumbnail(*inFile);
initState();
-
- _state.room = inFile->readByte();
- _state.moves = inFile->readByte();
- _state.isDark = inFile->readByte();
- _state.time.hours = inFile->readByte();
- _state.time.minutes = inFile->readByte();
-
- uint32 size = inFile->readUint32BE();
- if (size != _state.rooms.size())
- error("Room count mismatch (expected %i; found %i)", _state.rooms.size(), size);
-
- for (uint i = 0; i < size; ++i) {
- _state.rooms[i].picture = inFile->readByte();
- _state.rooms[i].curPicture = inFile->readByte();
- _state.rooms[i].isFirstTime = inFile->readByte();
- }
-
- // NOTE: _state.curPicture is part of the save state in the original engine. We
- // reconstruct it instead. This is believed to be safe for at least hires 0-2, but
- // this may need to be re-evaluated for later games.
- _state.curPicture = getCurRoom().curPicture;
-
- size = inFile->readUint32BE();
- if (size != _state.items.size())
- error("Item count mismatch (expected %i; found %i)", _state.items.size(), size);
-
- Common::List<Item>::iterator item;
- for (item = _state.items.begin(); item != _state.items.end(); ++item) {
- item->room = inFile->readByte();
- item->picture = inFile->readByte();
- item->position.x = inFile->readByte();
- item->position.y = inFile->readByte();
- item->state = inFile->readByte();
- }
-
- size = inFile->readUint32BE();
- if (size != _state.vars.size())
- error("Variable count mismatch (expected %i; found %i)", _state.vars.size(), size);
-
- for (uint i = 0; i < size; ++i)
- _state.vars[i] = inFile->readByte();
+ loadState(*inFile);
if (inFile->err() || inFile->eos())
error("Failed to load game '%s'", fileName.c_str());
@@ -760,6 +774,35 @@ bool AdlEngine::canLoadGameStateCurrently() {
return _canRestoreNow;
}
+void AdlEngine::saveState(Common::WriteStream &stream) {
+ stream.writeByte(_state.room);
+ stream.writeByte(_state.moves);
+ stream.writeByte(_state.isDark);
+ stream.writeByte(_state.time.hours);
+ stream.writeByte(_state.time.minutes);
+
+ stream.writeUint32BE(_state.rooms.size());
+ for (uint i = 0; i < _state.rooms.size(); ++i) {
+ stream.writeByte(_state.rooms[i].picture);
+ stream.writeByte(_state.rooms[i].curPicture);
+ stream.writeByte(_state.rooms[i].isFirstTime);
+ }
+
+ stream.writeUint32BE(_state.items.size());
+ Common::List<Item>::const_iterator item;
+ for (item = _state.items.begin(); item != _state.items.end(); ++item) {
+ stream.writeByte(item->room);
+ stream.writeByte(item->picture);
+ stream.writeByte(item->position.x);
+ stream.writeByte(item->position.y);
+ stream.writeByte(item->state);
+ }
+
+ stream.writeUint32BE(_state.vars.size());
+ for (uint i = 0; i < _state.vars.size(); ++i)
+ stream.writeByte(_state.vars[i]);
+}
+
Common::Error AdlEngine::saveGameState(int slot, const Common::String &desc) {
Common::String fileName = Common::String::format("%s.s%02d", _targetName.c_str(), slot);
Common::OutSaveFile *outFile = getSaveFileManager()->openForSaving(fileName);
@@ -797,34 +840,7 @@ Common::Error AdlEngine::saveGameState(int slot, const Common::String &desc) {
outFile->writeUint32BE(playTime);
_display->saveThumbnail(*outFile);
-
- outFile->writeByte(_state.room);
- outFile->writeByte(_state.moves);
- outFile->writeByte(_state.isDark);
- outFile->writeByte(_state.time.hours);
- outFile->writeByte(_state.time.minutes);
-
- outFile->writeUint32BE(_state.rooms.size());
- for (uint i = 0; i < _state.rooms.size(); ++i) {
- outFile->writeByte(_state.rooms[i].picture);
- outFile->writeByte(_state.rooms[i].curPicture);
- outFile->writeByte(_state.rooms[i].isFirstTime);
- }
-
- outFile->writeUint32BE(_state.items.size());
- Common::List<Item>::const_iterator item;
- for (item = _state.items.begin(); item != _state.items.end(); ++item) {
- outFile->writeByte(item->room);
- outFile->writeByte(item->picture);
- outFile->writeByte(item->position.x);
- outFile->writeByte(item->position.y);
- outFile->writeByte(item->state);
- }
-
- outFile->writeUint32BE(_state.vars.size());
- for (uint i = 0; i < _state.vars.size(); ++i)
- outFile->writeByte(_state.vars[i]);
-
+ saveState(*outFile);
outFile->finalize();
if (outFile->err()) {
@@ -1073,8 +1089,7 @@ int AdlEngine::o1_moveItem(ScriptEnv &e) {
int AdlEngine::o1_setRoom(ScriptEnv &e) {
OP_DEBUG_1("\tROOM = %d", e.arg(1));
- getCurRoom().curPicture = getCurRoom().picture;
- _state.room = e.arg(1);
+ switchRoom(e.arg(1));
return 1;
}
@@ -1228,8 +1243,8 @@ bool AdlEngine::matchCommand(ScriptEnv &env) const {
return false;
if (DebugMan.isDebugChannelEnabled(kDebugChannelScript)) {
- op_debug("IF\n\tROOM == %s", roomStr(env.getCommand().room).c_str());
- op_debug("\t&& SAID(%s, %s)", verbStr(env.getCommand().verb).c_str(), nounStr(env.getCommand().noun).c_str());
+ (void)op_debug("IF\n\tROOM == %s", roomStr(env.getCommand().room).c_str());
+ (void)op_debug("\t&& SAID(%s, %s)", verbStr(env.getCommand().verb).c_str(), nounStr(env.getCommand().noun).c_str());
}
for (uint i = 0; i < env.getCondCount(); ++i) {
@@ -1242,7 +1257,7 @@ bool AdlEngine::matchCommand(ScriptEnv &env) const {
if (numArgs < 0) {
if (DebugMan.isDebugChannelEnabled(kDebugChannelScript))
- op_debug("FAIL\n");
+ (void)op_debug("FAIL\n");
return false;
}
@@ -1254,7 +1269,7 @@ bool AdlEngine::matchCommand(ScriptEnv &env) const {
void AdlEngine::doActions(ScriptEnv &env) {
if (DebugMan.isDebugChannelEnabled(kDebugChannelScript))
- op_debug("THEN");
+ (void)op_debug("THEN");
for (uint i = 0; i < env.getActCount(); ++i) {
byte op = env.op();
@@ -1266,7 +1281,7 @@ void AdlEngine::doActions(ScriptEnv &env) {
if (numArgs < 0) {
if (DebugMan.isDebugChannelEnabled(kDebugChannelScript))
- op_debug("ABORT\n");
+ (void)op_debug("ABORT\n");
return;
}
@@ -1274,7 +1289,7 @@ void AdlEngine::doActions(ScriptEnv &env) {
}
if (DebugMan.isDebugChannelEnabled(kDebugChannelScript))
- op_debug("END\n");
+ (void)op_debug("END\n");
}
bool AdlEngine::doOneCommand(const Commands &commands, byte verb, byte noun) {