Skip to content

Commit 2c62e5f

Browse files
committed
ADL: Add workarounds for hires5
1 parent 87609ef commit 2c62e5f

File tree

5 files changed

+65
-2
lines changed

5 files changed

+65
-2
lines changed

engines/adl/adl.cpp

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,30 @@ void AdlEngine::readCommands(Common::ReadStream &stream, Commands &commands) {
300300
}
301301
}
302302

303+
void AdlEngine::removeCommand(Commands &commands, uint idx) {
304+
Commands::iterator cmds;
305+
uint i = 0;
306+
for (cmds = commands.begin(); cmds != commands.end(); ++cmds) {
307+
if (i++ == idx) {
308+
commands.erase(cmds);
309+
return;
310+
}
311+
}
312+
313+
error("Command %d not found", idx);
314+
}
315+
316+
Command &AdlEngine::getCommand(Commands &commands, uint idx) {
317+
Commands::iterator cmds;
318+
uint i = 0;
319+
for (cmds = commands.begin(); cmds != commands.end(); ++cmds) {
320+
if (i++ == idx)
321+
return *cmds;
322+
}
323+
324+
error("Command %d not found", idx);
325+
}
326+
303327
void AdlEngine::checkInput(byte verb, byte noun) {
304328
// Try room-local command list first
305329
if (doOneCommand(_roomData.commands, verb, noun))
@@ -1343,14 +1367,14 @@ Common::String AdlEngine::verbStr(uint i) const {
13431367
if (i == IDI_ANY)
13441368
return "*";
13451369
else
1346-
return Common::String::format("%d/%s", i, _priVerbs[i - 1].c_str());
1370+
return Common::String::format("%d/%s", i, (i - 1 < _priVerbs.size() ? _priVerbs[i - 1].c_str() : "<INVALID>"));
13471371
}
13481372

13491373
Common::String AdlEngine::nounStr(uint i) const {
13501374
if (i == IDI_ANY)
13511375
return "*";
13521376
else
1353-
return Common::String::format("%d/%s", i, _priNouns[i - 1].c_str());
1377+
return Common::String::format("%d/%s", i, (i - 1 < _priNouns.size() ? _priNouns[i - 1].c_str() : "<INVALID>"));
13541378
}
13551379

13561380
Common::String AdlEngine::msgStr(uint i) const {

engines/adl/adl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,9 +252,13 @@ friend class Console;
252252
virtual Common::String formatNounError(const Common::String &verb, const Common::String &noun) const;
253253
void loadWords(Common::ReadStream &stream, WordMap &map, Common::StringArray &pri) const;
254254
void readCommands(Common::ReadStream &stream, Commands &commands);
255+
void removeCommand(Commands &commands, uint idx);
256+
Command &getCommand(Commands &commands, uint idx);
255257
void checkInput(byte verb, byte noun);
256258
virtual bool isInputValid(byte verb, byte noun, bool &is_any);
257259
virtual bool isInputValid(const Commands &commands, byte verb, byte noun, bool &is_any);
260+
virtual void applyRoomWorkarounds(byte roomNr) { }
261+
virtual void applyRegionWorkarounds() { }
258262

259263
virtual void setupOpcodeTables();
260264
virtual void initState();

engines/adl/adl_v2.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,8 @@ void AdlEngine_v2::loadRoom(byte roomNr) {
245245
stream->seek(commandOffset);
246246
readCommands(*stream, _roomData.commands);
247247
}
248+
249+
applyRoomWorkarounds(roomNr);
248250
}
249251

250252
void AdlEngine_v2::showRoom() {

engines/adl/adl_v4.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ void AdlEngine_v4::loadRegion(byte region) {
219219
}
220220
}
221221

222+
applyRegionWorkarounds();
222223
restoreVars();
223224
}
224225

engines/adl/hires5.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ class HiRes5Engine : public AdlEngine_v4 {
4545
void runIntro();
4646
void init();
4747
void initGameState();
48+
void applyRegionWorkarounds();
49+
void applyRoomWorkarounds(byte roomNr);
4850

4951
// AdlEngine_v4
5052
bool isInventoryFull();
@@ -297,6 +299,36 @@ void HiRes5Engine::initGameState() {
297299
_state.room = 5;
298300
}
299301

302+
void HiRes5Engine::applyRegionWorkarounds() {
303+
// WORKAROUND: Remove/fix buggy commands
304+
switch (_state.region) {
305+
case 3:
306+
// "USE PIN" references a missing message, but cannot
307+
// be triggered due to shadowing of the "USE" verb.
308+
// We remove it anyway to allow script dumping to proceed.
309+
// TODO: Investigate if we should fix this command instead
310+
// of removing it.
311+
removeCommand(_roomCommands, 12);
312+
break;
313+
case 14:
314+
// "WITH SHOVEL" references a missing message. This bug
315+
// is game-breaking in the original, but unlikely to occur
316+
// in practice due to the "DIG" command not asking for what
317+
// to dig with. Probably a remnant of an earlier version
318+
// of the script.
319+
removeCommand(_roomCommands, 0);
320+
}
321+
}
322+
323+
void HiRes5Engine::applyRoomWorkarounds(byte roomNr) {
324+
// WORKAROUND: Remove/fix buggy commands
325+
if (_state.region == 17 && roomNr == 49) {
326+
// "GET WATER" references a missing message when you already
327+
// have water. This message should be 117 instead of 17.
328+
getCommand(_roomData.commands, 8).script[4] = 117;
329+
}
330+
}
331+
300332
Engine *HiRes5Engine_create(OSystem *syst, const AdlGameDescription *gd) {
301333
return new HiRes5Engine(syst, gd);
302334
}

0 commit comments

Comments
 (0)