Skip to content

Commit

Permalink
ADL: Clean up script handling
Browse files Browse the repository at this point in the history
  • Loading branch information
waltervn committed Jun 6, 2016
1 parent 0cb889b commit 60a9a59
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 35 deletions.
40 changes: 15 additions & 25 deletions engines/adl/adl.cpp
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -1065,15 +1055,15 @@ void AdlEngine::doActions(ScriptEnv &env) {
if (numArgs < 0)
return;

env.ip += numArgs + 1;
env.skip(numArgs + 1);
}
}

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;
Expand All @@ -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);
}
Expand Down
32 changes: 22 additions & 10 deletions engines/adl/adl.h
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand All @@ -110,8 +124,6 @@ enum {
IDI_ITEM_DOESNT_MOVE
};

#define IDI_NONE 0xfe

struct Item {
byte noun;
byte room;
Expand Down Expand Up @@ -212,7 +224,7 @@ class AdlEngine : public Engine {
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);
Expand Down

0 comments on commit 60a9a59

Please sign in to comment.