From 60a9a592f5641655d1e0b00731603298bc938ac7 Mon Sep 17 00:00:00 2001 From: Walter van Niftrik Date: Fri, 18 Mar 2016 12:18:22 +0100 Subject: ADL: Clean up script handling --- engines/adl/adl.cpp | 40 +++++++++++++++------------------------- engines/adl/adl.h | 32 ++++++++++++++++++++++---------- 2 files changed, 37 insertions(+), 35 deletions(-) diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp index 7128928664..31c448570c 100644 --- a/engines/adl/adl.cpp +++ b/engines/adl/adl.cpp @@ -724,10 +724,9 @@ bool AdlEngine::canSaveGameStateCurrently() { // "SAVE GAME". This prevents saving via the GMM in situations where // it wouldn't otherwise be possible to do so. for (cmd = _roomCommands.begin(); cmd != _roomCommands.end(); ++cmd) { - ScriptEnv env(*cmd, _saveVerb, _saveNoun); - uint offset; - if (matchCommand(env, &offset)) - return cmd->script[offset] == IDO_ACT_SAVE; + ScriptEnv env(*cmd, _state.room, _saveVerb, _saveNoun); + if (matchCommand(env)) + return env.op() == IDO_ACT_SAVE; } return false; @@ -1009,12 +1008,12 @@ int AdlEngine::o1_goDirection(ScriptEnv &e) { } int AdlEngine::o1_takeItem(ScriptEnv &e) { - takeItem(e.noun); + takeItem(e.getNoun()); return 0; } int AdlEngine::o1_dropItem(ScriptEnv &e) { - dropItem(e.noun); + dropItem(e.getNoun()); return 0; } @@ -1023,18 +1022,12 @@ int AdlEngine::o1_setRoomPic(ScriptEnv &e) { return 2; } -bool AdlEngine::matchCommand(ScriptEnv &env, uint *actions) const { - if (env.cmd.room != IDI_NONE && env.cmd.room != _state.room) - return false; - - if (env.cmd.verb != IDI_NONE && env.cmd.verb != env.verb) +bool AdlEngine::matchCommand(ScriptEnv &env) const { + if (!env.isMatch()) return false; - if (env.cmd.noun != IDI_NONE && env.cmd.noun != env.noun) - return false; - - for (uint i = 0; i < env.cmd.numCond; ++i) { - byte op = env.cmd.script[env.ip]; + for (uint i = 0; i < env.getCondCount(); ++i) { + byte op = env.op(); if (!_condOpcodes[op] || !_condOpcodes[op]->isValid()) error("Unimplemented condition opcode %02x", op); @@ -1044,18 +1037,15 @@ bool AdlEngine::matchCommand(ScriptEnv &env, uint *actions) const { if (numArgs < 0) return false; - env.ip += numArgs + 1; + env.skip(numArgs + 1); } - if (actions) - *actions = env.ip; - return true; } void AdlEngine::doActions(ScriptEnv &env) { - for (uint i = 0; i < env.cmd.numAct; ++i) { - byte op = env.cmd.script[env.ip]; + for (uint i = 0; i < env.getActCount(); ++i) { + byte op = env.op(); if (!_actOpcodes[op] || !_actOpcodes[op]->isValid()) error("Unimplemented action opcode %02x", op); @@ -1065,7 +1055,7 @@ void AdlEngine::doActions(ScriptEnv &env) { if (numArgs < 0) return; - env.ip += numArgs + 1; + env.skip(numArgs + 1); } } @@ -1073,7 +1063,7 @@ bool AdlEngine::doOneCommand(const Commands &commands, byte verb, byte noun) { Commands::const_iterator cmd; for (cmd = commands.begin(); cmd != commands.end(); ++cmd) { - ScriptEnv env(*cmd, verb, noun); + ScriptEnv env(*cmd, _state.room, verb, noun); if (matchCommand(env)) { doActions(env); return true; @@ -1087,7 +1077,7 @@ void AdlEngine::doAllCommands(const Commands &commands, byte verb, byte noun) { Commands::const_iterator cmd; for (cmd = commands.begin(); cmd != commands.end(); ++cmd) { - ScriptEnv env(*cmd, verb, noun); + ScriptEnv env(*cmd, _state.room, verb, noun); if (matchCommand(env)) doActions(env); } diff --git a/engines/adl/adl.h b/engines/adl/adl.h index c12fb555e5..e7c36aefde 100644 --- a/engines/adl/adl.h +++ b/engines/adl/adl.h @@ -54,6 +54,8 @@ struct ScriptEnv; #define IDO_ACT_SAVE 0x0f #define IDO_ACT_LOAD 0x10 +#define IDI_NONE 0xfe + #define IDI_WORD_SIZE 8 enum Direction { @@ -92,16 +94,28 @@ struct Command { class ScriptEnv { public: - ScriptEnv(const Command &cmd_, byte verb_, byte noun_) : - cmd(cmd_), verb(verb_), noun(noun_), ip(0) { } + ScriptEnv(const Command &cmd, byte room, byte verb, byte noun) : + _cmd(cmd), _room(room), _verb(verb), _noun(noun), _ip(0) { } - byte op() const { return cmd.script[ip]; } + byte op() const { return _cmd.script[_ip]; } // We keep this 1-based for easier comparison with the original engine - byte arg(uint i) const { return cmd.script[ip + i]; } + byte arg(uint i) const { return _cmd.script[_ip + i]; } + void skip(uint i) { _ip += i; } - const Command &cmd; - byte verb, noun; - byte ip; + bool isMatch() const { + return (_cmd.room == IDI_NONE || _cmd.room == _room) && + (_cmd.verb == IDI_NONE || _cmd.verb == _verb) && + (_cmd.noun == IDI_NONE || _cmd.noun == _noun); + } + + byte getCondCount() const { return _cmd.numCond; } + byte getActCount() const { return _cmd.numAct; } + byte getNoun() const { return _noun; } + +private: + const Command &_cmd; + const byte _room, _verb, _noun; + byte _ip; }; enum { @@ -110,8 +124,6 @@ enum { IDI_ITEM_DOESNT_MOVE }; -#define IDI_NONE 0xfe - struct Item { byte noun; byte room; @@ -212,7 +224,7 @@ protected: void setVar(uint i, byte value); void takeItem(byte noun); void dropItem(byte noun); - bool matchCommand(ScriptEnv &env, uint *actions = nullptr) const; + bool matchCommand(ScriptEnv &env) const; void doActions(ScriptEnv &env); bool doOneCommand(const Commands &commands, byte verb, byte noun); void doAllCommands(const Commands &commands, byte verb, byte noun); -- cgit v1.2.3