Skip to content

Commit

Permalink
ADL: Remove opcode counts from script interface
Browse files Browse the repository at this point in the history
  • Loading branch information
waltervn committed Jul 17, 2019
1 parent 39e4fdb commit f4f4d61
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 22 deletions.
67 changes: 49 additions & 18 deletions engines/adl/adl.cpp
Expand Up @@ -44,6 +44,33 @@

namespace Adl {

class ScriptEnv_6502 : public ScriptEnv {
public:
ScriptEnv_6502(const Command &cmd, byte room, byte verb, byte noun) :
ScriptEnv(cmd, room, verb, noun),
_remCond(cmd.numCond),
_remAct(cmd.numAct) { }

private:
kOpType getOpType() const {
if (_remCond > 0)
return kOpTypeCond;
if (_remAct > 0)
return kOpTypeAct;
return kOpTypeDone;
}

void next(uint numArgs) {
_ip += numArgs + 1;
if (_remCond > 0)
--_remCond;
else if (_remAct > 0)
--_remAct;
}

byte _remCond, _remAct;
};

AdlEngine::~AdlEngine() {
delete _display;
delete _graphics;
Expand Down Expand Up @@ -404,8 +431,8 @@ bool AdlEngine::isInputValid(const Commands &commands, byte verb, byte noun, boo

is_any = false;
for (cmd = commands.begin(); cmd != commands.end(); ++cmd) {
ScriptEnv env(*cmd, _state.room, verb, noun);
if (matchCommand(env)) {
Common::ScopedPtr<ScriptEnv> env(createScriptEnv(*cmd, _state.room, verb, noun));
if (matchCommand(*env)) {
if (cmd->verb == IDI_ANY || cmd->noun == IDI_ANY)
is_any = true;
return true;
Expand Down Expand Up @@ -961,15 +988,15 @@ 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 = _roomData.commands.begin(); cmd != _roomData.commands.end(); ++cmd) {
ScriptEnv env(*cmd, _state.room, _saveVerb, _saveNoun);
if (matchCommand(env))
return env.op() == IDO_ACT_SAVE;
Common::ScopedPtr<ScriptEnv> env(createScriptEnv(*cmd, _state.room, _saveVerb, _saveNoun));
if (matchCommand(*env))
return env->op() == IDO_ACT_SAVE;
}

for (cmd = _roomCommands.begin(); cmd != _roomCommands.end(); ++cmd) {
ScriptEnv env(*cmd, _state.room, _saveVerb, _saveNoun);
if (matchCommand(env))
return env.op() == IDO_ACT_SAVE;
Common::ScopedPtr<ScriptEnv> env(createScriptEnv(*cmd, _state.room, _saveVerb, _saveNoun));
if (matchCommand(*env))
return env->op() == IDO_ACT_SAVE;
}

return false;
Expand Down Expand Up @@ -1346,7 +1373,7 @@ bool AdlEngine::matchCommand(ScriptEnv &env) const {
(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) {
while (env.getOpType() == ScriptEnv::kOpTypeCond) {
byte op = env.op();

if (op >= _condOpcodes.size() || !_condOpcodes[op] || !_condOpcodes[op]->isValid())
Expand All @@ -1360,7 +1387,7 @@ bool AdlEngine::matchCommand(ScriptEnv &env) const {
return false;
}

env.skip(numArgs + 1);
env.next(numArgs);
}

return true;
Expand All @@ -1370,7 +1397,7 @@ void AdlEngine::doActions(ScriptEnv &env) {
if (DebugMan.isDebugChannelEnabled(kDebugChannelScript))
(void)op_debug("THEN");

for (uint i = 0; i < env.getActCount(); ++i) {
while (env.getOpType() == ScriptEnv::kOpTypeAct) {
byte op = env.op();

if (op >= _actOpcodes.size() || !_actOpcodes[op] || !_actOpcodes[op]->isValid())
Expand All @@ -1384,7 +1411,7 @@ void AdlEngine::doActions(ScriptEnv &env) {
return;
}

env.skip(numArgs + 1);
env.next(numArgs);
}

if (DebugMan.isDebugChannelEnabled(kDebugChannelScript))
Expand All @@ -1395,9 +1422,9 @@ 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, _state.room, verb, noun);
if (matchCommand(env)) {
doActions(env);
Common::ScopedPtr<ScriptEnv> env(createScriptEnv(*cmd, _state.room, verb, noun));
if (matchCommand(*env)) {
doActions(*env);
return true;
}

Expand All @@ -1414,9 +1441,9 @@ 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, _state.room, verb, noun);
if (matchCommand(env)) {
doActions(env);
Common::ScopedPtr<ScriptEnv> env(createScriptEnv(*cmd, _state.room, verb, noun));
if (matchCommand(*env)) {
doActions(*env);
// The original long jumps on restart, so we need to abort here
if (_isRestarting)
return;
Expand All @@ -1429,6 +1456,10 @@ void AdlEngine::doAllCommands(const Commands &commands, byte verb, byte noun) {
}
}

ScriptEnv *AdlEngine::createScriptEnv(const Command &cmd, byte room, byte verb, byte noun) {
return new ScriptEnv_6502(cmd, room, verb, noun);
}

Common::String AdlEngine::toAscii(const Common::String &str) {
Common::String ascii = Console::toAscii(str);
if (ascii.lastChar() == '\r')
Expand Down
18 changes: 14 additions & 4 deletions engines/adl/adl.h
Expand Up @@ -117,26 +117,35 @@ class ScriptEnv {
ScriptEnv(const Command &cmd, byte room, byte verb, byte noun) :
_cmd(cmd), _room(room), _verb(verb), _noun(noun), _ip(0) { }

virtual ~ScriptEnv() { }

enum kOpType {
kOpTypeDone,
kOpTypeCond,
kOpTypeAct
};

byte op() const { return _cmd.script[_ip]; }
virtual kOpType getOpType() const = 0;
// We keep this 1-based for easier comparison with the original engine
byte arg(uint i) const { return _cmd.script[_ip + i]; }
void skip(uint i) { _ip += i; }
virtual void next(uint numArgs) = 0;

bool isMatch() const {
return (_cmd.room == IDI_ANY || _cmd.room == _room) &&
(_cmd.verb == IDI_ANY || _cmd.verb == _verb) &&
(_cmd.noun == IDI_ANY || _cmd.noun == _noun);
}

byte getCondCount() const { return _cmd.numCond; }
byte getActCount() const { return _cmd.numAct; }
byte getNoun() const { return _noun; }
const Command &getCommand() const { return _cmd; }

protected:
byte _ip;

private:
const Command &_cmd;
const byte _room, _verb, _noun;
byte _ip;
};

enum {
Expand Down Expand Up @@ -353,6 +362,7 @@ friend class Console;
void doActions(ScriptEnv &env);
bool doOneCommand(const Commands &commands, byte verb, byte noun);
void doAllCommands(const Commands &commands, byte verb, byte noun);
virtual ScriptEnv *createScriptEnv(const Command &cmd, byte room, byte verb, byte noun);

// Debug functions
static Common::String toAscii(const Common::String &str);
Expand Down

0 comments on commit f4f4d61

Please sign in to comment.