aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWalter van Niftrik2016-12-18 17:26:57 +0100
committerWalter van Niftrik2016-12-18 18:41:02 +0100
commit2c62e5f99c3bf24630eb37d6ddd34eac330b3d91 (patch)
tree8ba9ebad00905308bafffd0b045d9dbedc1cc8f4
parent87609ef75a446b97de8c834a5ca395ac6e2f998f (diff)
downloadscummvm-rg350-2c62e5f99c3bf24630eb37d6ddd34eac330b3d91.tar.gz
scummvm-rg350-2c62e5f99c3bf24630eb37d6ddd34eac330b3d91.tar.bz2
scummvm-rg350-2c62e5f99c3bf24630eb37d6ddd34eac330b3d91.zip
ADL: Add workarounds for hires5
-rw-r--r--engines/adl/adl.cpp28
-rw-r--r--engines/adl/adl.h4
-rw-r--r--engines/adl/adl_v2.cpp2
-rw-r--r--engines/adl/adl_v4.cpp1
-rw-r--r--engines/adl/hires5.cpp32
5 files changed, 65 insertions, 2 deletions
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 834b53a53c..bc5bc74f3a 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -300,6 +300,30 @@ void AdlEngine::readCommands(Common::ReadStream &stream, Commands &commands) {
}
}
+void AdlEngine::removeCommand(Commands &commands, uint idx) {
+ Commands::iterator cmds;
+ uint i = 0;
+ for (cmds = commands.begin(); cmds != commands.end(); ++cmds) {
+ if (i++ == idx) {
+ commands.erase(cmds);
+ return;
+ }
+ }
+
+ error("Command %d not found", idx);
+}
+
+Command &AdlEngine::getCommand(Commands &commands, uint idx) {
+ Commands::iterator cmds;
+ uint i = 0;
+ for (cmds = commands.begin(); cmds != commands.end(); ++cmds) {
+ if (i++ == idx)
+ return *cmds;
+ }
+
+ error("Command %d not found", idx);
+}
+
void AdlEngine::checkInput(byte verb, byte noun) {
// Try room-local command list first
if (doOneCommand(_roomData.commands, verb, noun))
@@ -1343,14 +1367,14 @@ Common::String AdlEngine::verbStr(uint i) const {
if (i == IDI_ANY)
return "*";
else
- return Common::String::format("%d/%s", i, _priVerbs[i - 1].c_str());
+ return Common::String::format("%d/%s", i, (i - 1 < _priVerbs.size() ? _priVerbs[i - 1].c_str() : "<INVALID>"));
}
Common::String AdlEngine::nounStr(uint i) const {
if (i == IDI_ANY)
return "*";
else
- return Common::String::format("%d/%s", i, _priNouns[i - 1].c_str());
+ return Common::String::format("%d/%s", i, (i - 1 < _priNouns.size() ? _priNouns[i - 1].c_str() : "<INVALID>"));
}
Common::String AdlEngine::msgStr(uint i) const {
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index a825200587..87e99a5537 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -252,9 +252,13 @@ protected:
virtual Common::String formatNounError(const Common::String &verb, const Common::String &noun) const;
void loadWords(Common::ReadStream &stream, WordMap &map, Common::StringArray &pri) const;
void readCommands(Common::ReadStream &stream, Commands &commands);
+ void removeCommand(Commands &commands, uint idx);
+ Command &getCommand(Commands &commands, uint idx);
void checkInput(byte verb, byte noun);
virtual bool isInputValid(byte verb, byte noun, bool &is_any);
virtual bool isInputValid(const Commands &commands, byte verb, byte noun, bool &is_any);
+ virtual void applyRoomWorkarounds(byte roomNr) { }
+ virtual void applyRegionWorkarounds() { }
virtual void setupOpcodeTables();
virtual void initState();
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 46bd6aa4d3..8670bd08df 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -245,6 +245,8 @@ void AdlEngine_v2::loadRoom(byte roomNr) {
stream->seek(commandOffset);
readCommands(*stream, _roomData.commands);
}
+
+ applyRoomWorkarounds(roomNr);
}
void AdlEngine_v2::showRoom() {
diff --git a/engines/adl/adl_v4.cpp b/engines/adl/adl_v4.cpp
index 267399fb61..456ee10dca 100644
--- a/engines/adl/adl_v4.cpp
+++ b/engines/adl/adl_v4.cpp
@@ -219,6 +219,7 @@ void AdlEngine_v4::loadRegion(byte region) {
}
}
+ applyRegionWorkarounds();
restoreVars();
}
diff --git a/engines/adl/hires5.cpp b/engines/adl/hires5.cpp
index f298cecf55..a3ed6d890e 100644
--- a/engines/adl/hires5.cpp
+++ b/engines/adl/hires5.cpp
@@ -45,6 +45,8 @@ private:
void runIntro();
void init();
void initGameState();
+ void applyRegionWorkarounds();
+ void applyRoomWorkarounds(byte roomNr);
// AdlEngine_v4
bool isInventoryFull();
@@ -297,6 +299,36 @@ void HiRes5Engine::initGameState() {
_state.room = 5;
}
+void HiRes5Engine::applyRegionWorkarounds() {
+ // WORKAROUND: Remove/fix buggy commands
+ switch (_state.region) {
+ case 3:
+ // "USE PIN" references a missing message, but cannot
+ // be triggered due to shadowing of the "USE" verb.
+ // We remove it anyway to allow script dumping to proceed.
+ // TODO: Investigate if we should fix this command instead
+ // of removing it.
+ removeCommand(_roomCommands, 12);
+ break;
+ case 14:
+ // "WITH SHOVEL" references a missing message. This bug
+ // is game-breaking in the original, but unlikely to occur
+ // in practice due to the "DIG" command not asking for what
+ // to dig with. Probably a remnant of an earlier version
+ // of the script.
+ removeCommand(_roomCommands, 0);
+ }
+}
+
+void HiRes5Engine::applyRoomWorkarounds(byte roomNr) {
+ // WORKAROUND: Remove/fix buggy commands
+ if (_state.region == 17 && roomNr == 49) {
+ // "GET WATER" references a missing message when you already
+ // have water. This message should be 117 instead of 17.
+ getCommand(_roomData.commands, 8).script[4] = 117;
+ }
+}
+
Engine *HiRes5Engine_create(OSystem *syst, const AdlGameDescription *gd) {
return new HiRes5Engine(syst, gd);
}