From: Daniel Karbach Date: Sat, 20 Oct 2012 16:15:38 +0000 (+0200) Subject: revised implementation of script text X-Git-Url: http://git.localhorst.tv/?a=commitdiff_plain;h=0bbc2eda56eba3ea195c2043370ff4d3fd29ca79;p=l2e.git revised implementation of script text --- diff --git a/src/common/Script.h b/src/common/Script.h index c203f40..afbea26 100644 --- a/src/common/Script.h +++ b/src/common/Script.h @@ -8,6 +8,8 @@ #ifndef COMMON_SCRIPT_H_ #define COMMON_SCRIPT_H_ +#include + namespace common { class Script { @@ -16,42 +18,40 @@ public: Script(); ~Script(); - enum Code { - CODE_MOVE_A0, - CODE_MOVE_A1, - CODE_MOVE_I0, - CODE_MOVE_I1, - CODE_MOVE_V0, - CODE_MOVE_V1, - - CODE_ADD_I0, - CODE_ADD_I1, - CODE_ADD_V0, - CODE_ADD_V1, - - CODE_MOD_I0, - CODE_MOD_I1, - - CODE_RAND_I0, - CODE_RAND_I1, - - CODE_CMP_I0, - CODE_CMP_I1, - CODE_CMP_I0_I1, - - CODE_JUMP, - CODE_JUMP_EQUAL, - CODE_JUMP_NOT_EQUAL, - CODE_JUMP_LESS, - CODE_JUMP_LESS_EQUAL, - CODE_JUMP_GREATER, - CODE_JUMP_GREATER_EQUAL, - - CODE_SYSCALL, + enum Command { + COMMAND_NOOP, + COMMAND_MOVE, + COMMAND_ADD, + COMMAND_MOD, + COMMAND_RAND, + COMMAND_CMP, + COMMAND_JMP, + COMMAND_JEQ, + COMMAND_JNE, + COMMAND_JL, + COMMAND_JLE, + COMMAND_JG, + COMMAND_JGE, + COMMAND_SYSC, + }; + + enum Type { + TYPE_NONE, + TYPE_ADDRESS, + TYPE_INTEGER, + TYPE_VECTOR, + }; + + struct Code { + Command command : 6; + unsigned int numParams : 2; + Type type : 2; + unsigned int reg1 : 3; + unsigned int reg2 : 3; }; public: - const unsigned char *text; + const char *text; int textlen; }; diff --git a/src/common/ScriptRunner.cpp b/src/common/ScriptRunner.cpp index 98fd4fb..c22a76b 100644 --- a/src/common/ScriptRunner.cpp +++ b/src/common/ScriptRunner.cpp @@ -20,12 +20,6 @@ ScriptRunner::ScriptRunner() : host(0) , script(0) , cursor(0) -, address0(0) -, address1(0) -, integer0(0) -, integer1(0) -, vector0(0, 0) -, vector1(0, 0) , compare(0) { } @@ -44,9 +38,7 @@ void ScriptRunner::Run(ScriptHost &h, const Script &s) { script = &s; Reset(); while (cursor < script->textlen) { - unsigned char code(script->text[cursor]); - ++cursor; - Exec(code); + Exec(PopCode()); } host = 0; script = 0; @@ -54,118 +46,139 @@ void ScriptRunner::Run(ScriptHost &h, const Script &s) { void ScriptRunner::Reset() { cursor = 0; - address0 = 0; - address1 = 0; - integer0 = 0; - integer1 = 0; - vector0 = Vector(0, 0); - vector1 = Vector(0, 0); + for (int i(0); i < numRegisters; ++i) { + address[i] = 0; + integer[i] = 0; + vector[i] = Vector(0, 0); + } } -void ScriptRunner::Exec(unsigned char code) { - switch (code) { - case Script::CODE_MOVE_A0: - address0 = PopAddress(); - break; - case Script::CODE_MOVE_A1: - address1 = PopAddress(); - break; - case Script::CODE_MOVE_I0: - integer0 = PopInt(); - break; - case Script::CODE_MOVE_I1: - integer1 = PopInt(); - break; - case Script::CODE_MOVE_V0: - vector0 = PopVector(); - break; - case Script::CODE_MOVE_V1: - vector1 = PopVector(); - break; - case Script::CODE_ADD_I0: - integer0 += PopInt(); - break; - case Script::CODE_ADD_I1: - integer1 += PopInt(); +void ScriptRunner::Exec(Script::Code code) { + switch (code.command) { + case Script::COMMAND_NOOP: break; - case Script::CODE_ADD_V0: - vector0 += PopVector(); - break; - case Script::CODE_ADD_V1: - vector1 += PopVector(); - break; - case Script::CODE_MOD_I0: - integer0 %= PopInt(); - break; - case Script::CODE_MOD_I1: - integer1 %= PopInt(); - break; - case Script::CODE_RAND_I0: - integer0 = std::rand(); + + case Script::COMMAND_MOVE: + if (code.reg1 >= numRegisters) { + break; + } + switch (code.type) { + case Script::TYPE_ADDRESS: { + void *value(code.reg2 < numRegisters ? address[code.reg2] : PopAddress()); + address[code.reg1] = value; + break; + } + case Script::TYPE_INTEGER: { + int value(code.reg2 < numRegisters ? integer[code.reg2] : PopInt()); + integer[code.reg1] = value; + break; + } + case Script::TYPE_VECTOR: { + Vector value(code.reg2 < numRegisters ? vector[code.reg2] : PopVector()); + vector[code.reg1] = value; + break; + } + } break; - case Script::CODE_RAND_I1: - integer1 = std::rand(); + + case Script::COMMAND_ADD: + if (code.reg1 >= numRegisters) { + break; + } + switch (code.type) { + case Script::TYPE_INTEGER: { + int value(code.reg2 < numRegisters ? integer[code.reg2] : PopInt()); + integer[code.reg1] += value; + break; + } + case Script::TYPE_VECTOR: { + Vector value(code.reg2 < numRegisters ? vector[code.reg2] : PopVector()); + vector[code.reg1] += value; + break; + } + } break; - case Script::CODE_CMP_I0: - Compare(integer0, PopInt()); + + case Script::COMMAND_MOD: { + if (code.reg1 >= numRegisters) { + break; + } + int value(code.reg2 < numRegisters ? integer[code.reg2] : PopInt()); + integer[code.reg1] %= value; break; - case Script::CODE_CMP_I1: - Compare(integer1, PopInt()); + } + + case Script::COMMAND_RAND: + if (code.reg1 >= numRegisters) { + break; + } + integer[code.reg1] = std::rand(); break; - case Script::CODE_CMP_I0_I1: - Compare(integer0, integer1); + + case Script::COMMAND_CMP: { + int lhs(code.reg1 < numRegisters ? integer[code.reg1] : PopInt()); + int rhs(code.reg2 < numRegisters ? integer[code.reg2] : PopInt()); + Compare(lhs, rhs); break; - case Script::CODE_JUMP: + } + + case Script::COMMAND_JMP: cursor = PopInt(); break; - case Script::CODE_JUMP_EQUAL: { + case Script::COMMAND_JEQ: { int addr(PopInt()); if (compare == COMPARE_EQUAL) { cursor = addr; } break; } - case Script::CODE_JUMP_NOT_EQUAL: { + case Script::COMMAND_JNE: { int addr(PopInt()); if (compare != COMPARE_EQUAL) { cursor = addr; } break; } - case Script::CODE_JUMP_LESS: { + case Script::COMMAND_JL: { int addr(PopInt()); if (compare == COMPARE_LESS) { cursor = addr; } break; } - case Script::CODE_JUMP_LESS_EQUAL: { + case Script::COMMAND_JLE: { int addr(PopInt()); if (compare != COMPARE_GREATER) { cursor = addr; } break; } - case Script::CODE_JUMP_GREATER: { + case Script::COMMAND_JG: { int addr(PopInt()); if (compare == COMPARE_GREATER) { cursor = addr; } break; } - case Script::CODE_JUMP_GREATER_EQUAL: { + case Script::COMMAND_JGE: { int addr(PopInt()); if (compare != COMPARE_LESS) { cursor = addr; } break; } - case Script::CODE_SYSCALL: + case Script::COMMAND_SYSC: host->HandleSyscall(*this); break; } } +Script::Code ScriptRunner::PopCode() { + const Script::Code *i(reinterpret_cast(script->text + cursor)); + cursor += sizeof(Script::Code); + return *i; +} + void *ScriptRunner::PopAddress() { void *const *addr(reinterpret_cast(script->text + cursor)); cursor += sizeof(void *); diff --git a/src/common/ScriptRunner.h b/src/common/ScriptRunner.h index 9b0f1ac..879877d 100644 --- a/src/common/ScriptRunner.h +++ b/src/common/ScriptRunner.h @@ -9,6 +9,7 @@ #define COMMON_SCRIPTRUNNER_H_ #include "fwd.h" +#include "Script.h" #include "../geometry/Vector.h" #include @@ -25,18 +26,16 @@ public: void Run(ScriptHost &, const Script &); bool Running() const; - void *Address0() const { return address0; } - void *Address1() const { return address1; } - int Integer0() const { return integer0; } - int Integer1() const { return integer1; } - const geometry::Vector &Vector0() const { return vector0; } - const geometry::Vector &Vector1() const { return vector1; } + void *AddressRegister(int n) const { return address[n]; } + int IntegerRegister(int n) const { return integer[n]; } + const geometry::Vector &VectorRegister(int n) const { return vector[n]; } private: void Reset(); - void Exec(unsigned char code); + void Exec(Script::Code code); void *PopAddress(); + Script::Code PopCode(); int PopInt(); const geometry::Vector &PopVector(); @@ -53,12 +52,10 @@ private: const Script *script; int cursor; - void *address0; - void *address1; - int integer0; - int integer1; - geometry::Vector vector0; - geometry::Vector vector1; + static const int numRegisters = 7; + void *address[numRegisters]; + int integer[numRegisters]; + geometry::Vector vector[numRegisters]; Uint8 compare; diff --git a/src/loader/Interpreter.cpp b/src/loader/Interpreter.cpp index 5adb08e..4b0f5e0 100644 --- a/src/loader/Interpreter.cpp +++ b/src/loader/Interpreter.cpp @@ -355,7 +355,7 @@ void Interpreter::ReadScript(const std::vector &s, Script *script } else if ((*i)->GetType() != ScriptToken::COMMAND) { throw Error("unexpected script token"); } - ++size; + size += sizeof(Script::Code); const string &cmd((*i)->CommandName()); if (cmd == "move") { ++i; @@ -363,59 +363,66 @@ void Interpreter::ReadScript(const std::vector &s, Script *script throw Error("unexpected script end after move"); } const string ®((*i)->RegisterName()); - switch (reg[0]) { - case 'a': - size += sizeof(void *); - break; - case 'i': - size += sizeof(int); - break; - case 'v': - size += sizeof(Vector); - break; - default: - throw Error("unknown register " + reg); + if (reg.size() != 2) { + throw Error("invalid register name " + reg); } ++i; if (i == end) { throw Error("unexpected script end after move"); } + if ((*i)->GetType() != ScriptToken::REGISTER) { + switch (reg[0]) { + case 'a': + size += sizeof(void *); + break; + case 'i': + size += sizeof(int); + break; + case 'v': + size += sizeof(Vector); + break; + default: + throw Error("unknown register " + reg); + } + } } else if (cmd == "add") { ++i; if (i == end) { throw Error("unexpected script end after add"); } const string ®((*i)->RegisterName()); - switch (reg[0]) { - case 'i': - size += sizeof(int); - break; - case 'v': - size += sizeof(Vector); - break; - default: - throw Error("expected register after add " + reg); + if (reg.size() != 2) { + throw Error("invalid register name " + reg); } ++i; if (i == end) { throw Error("unexpected script end after add"); } + if ((*i)->GetType() != ScriptToken::REGISTER) { + switch (reg[0]) { + case 'i': + size += sizeof(int); + break; + case 'v': + size += sizeof(Vector); + break; + default: + throw Error("expected register after add " + reg); + } + } } else if (cmd == "mod") { ++i; if (i == end) { throw Error("unexpected script end after mod"); } - size += sizeof(int); ++i; if (i == end) { throw Error("unexpected script end after mod"); } - } else if (cmd == "rand") { - ++i; - if (i == end) { - throw Error("unexpected script end after rand"); + if ((*i)->GetType() != ScriptToken::REGISTER) { + size += sizeof(int); } - size += sizeof(int); + } else if (cmd == "rand") { ++i; if (i == end) { throw Error("unexpected script end after rand"); @@ -425,11 +432,16 @@ void Interpreter::ReadScript(const std::vector &s, Script *script if (i == end) { throw Error("unexpected script end after cmp"); } - size += sizeof(int); + if ((*i)->GetType() != ScriptToken::REGISTER) { + size += sizeof(int); + } ++i; if (i == end) { throw Error("unexpected script end after cmp"); } + if ((*i)->GetType() != ScriptToken::REGISTER) { + size += sizeof(int); + } } else if (cmd == "jmp") { size += sizeof(int); ++i; @@ -479,7 +491,7 @@ void Interpreter::ReadScript(const std::vector &s, Script *script } } - unsigned char *text(reinterpret_cast(alloc.Alloc(size))); + char *text(alloc.Alloc(size)); int cursor(0); for (vector::const_iterator i(s.begin()), end(s.end()); i != end; ++i) { if ((*i)->GetType() == ScriptToken::LABEL) { @@ -490,123 +502,187 @@ void Interpreter::ReadScript(const std::vector &s, Script *script } const string &cmd((*i)->CommandName()); if (cmd == "move") { + Script::Code &code(CreateScriptCode(Script::COMMAND_MOVE, text + cursor)); + cursor += sizeof(Script::Code); + code.numParams = 2; ++i; const string ®((*i)->RegisterName()); + switch (reg[0]) { + case 'a': + code.type = Script::TYPE_ADDRESS; + break; + case 'i': + code.type = Script::TYPE_INTEGER; + break; + case 'v': + code.type = Script::TYPE_VECTOR; + break; + default: + throw Error("invalid register " + reg); + } + int regnum(reg[1] - '0'); + if (regnum < 0 || regnum > 6) { + throw Error("invalid register " + reg); + } + code.reg1 = regnum; ++i; - if (reg == "a0") { - text[cursor] = Script::CODE_MOVE_A0; - ++cursor; - ReadScriptAddress(**i, text + cursor); - cursor += sizeof(void *); - } else if (reg == "a1") { - text[cursor] = Script::CODE_MOVE_A1; - ++cursor; - ReadScriptAddress(**i, text + cursor); - cursor += sizeof(void *); - } else if (reg == "i0") { - text[cursor] = Script::CODE_MOVE_I0; - ++cursor; - ReadScriptInteger(**i, text + cursor); - cursor += sizeof(int); - } else if (reg == "i1") { - text[cursor] = Script::CODE_MOVE_I1; - ++cursor; - ReadScriptInteger(**i, text + cursor); - cursor += sizeof(int); - } else if (reg == "v0") { - text[cursor] = Script::CODE_MOVE_V0; - ++cursor; - ReadScriptVector(**i, text + cursor); - cursor += sizeof(Vector); - } else if (reg == "v1") { - text[cursor] = Script::CODE_MOVE_V1; - ++cursor; - ReadScriptVector(**i, text + cursor); - cursor += sizeof(Vector); + + if ((*i)->GetType() == ScriptToken::REGISTER) { + string reg2((*i)->RegisterName()); + if (reg[0] != reg2[0]) { + throw Error("mixed-type commands not allowed"); + } + int reg2num(reg[1] - '0'); + if (reg2num < 0 || reg2num > 6) { + throw Error("invalid register " + reg2); + } + code.reg2 = reg2num; } else { - throw Error("unknown register " + reg); + code.reg2 = 7; + switch (code.type) { + case Script::TYPE_ADDRESS: + ReadScriptAddress(**i, text + cursor); + cursor += sizeof(void *); + break; + case Script::TYPE_INTEGER: + ReadScriptInteger(**i, text + cursor); + cursor += sizeof(int); + break; + case Script::TYPE_VECTOR: + ReadScriptVector(**i, text + cursor); + cursor += sizeof(Vector); + break; + } } } else if (cmd == "add") { + Script::Code &code(CreateScriptCode(Script::COMMAND_ADD, text + cursor)); + cursor += sizeof(Script::Code); + code.numParams = 2; ++i; const string ®((*i)->RegisterName()); + switch (reg[0]) { + case 'i': + code.type = Script::TYPE_INTEGER; + break; + case 'v': + code.type = Script::TYPE_VECTOR; + break; + default: + throw Error("invalid register " + reg); + } + int regnum(reg[1] - '0'); + if (regnum < 0 || regnum > 6) { + throw Error("invalid register " + reg); + } + code.reg1 = regnum; ++i; - if (reg == "i0") { - text[cursor] = Script::CODE_ADD_I0; - ++cursor; - ReadScriptInteger(**i, text + cursor); - cursor += sizeof(int); - } else if (reg == "i1") { - text[cursor] = Script::CODE_ADD_I1; - ++cursor; - ReadScriptInteger(**i, text + cursor); - cursor += sizeof(int); - } else if (reg == "v0") { - text[cursor] = Script::CODE_ADD_V0; - ++cursor; - ReadScriptVector(**i, text + cursor); - cursor += sizeof(Vector); - } else if (reg == "v1") { - text[cursor] = Script::CODE_ADD_V1; - ++cursor; - ReadScriptVector(**i, text + cursor); - cursor += sizeof(Vector); + + if ((*i)->GetType() == ScriptToken::REGISTER) { + string reg2((*i)->RegisterName()); + if (reg[0] != reg2[0]) { + throw Error("mixed-type commands not allowed"); + } + int reg2num(reg[1] - '0'); + if (reg2num < 0 || reg2num > 6) { + throw Error("invalid register name " + reg2); + } + code.reg2 = reg2num; } else { - throw Error("unexpected register " + reg); + code.reg2 = 7; + switch (code.type) { + case Script::TYPE_INTEGER: + ReadScriptInteger(**i, text + cursor); + cursor += sizeof(int); + break; + case Script::TYPE_VECTOR: + ReadScriptVector(**i, text + cursor); + cursor += sizeof(Vector); + break; + } } } else if (cmd == "mod") { + Script::Code &code(CreateScriptCode(Script::COMMAND_MOD, text + cursor)); + cursor += sizeof(Script::Code); + code.numParams = 2; ++i; const string ®((*i)->RegisterName()); + if (reg[0] != 'i') { + throw Error("invalid register " + reg); + } + code.type = Script::TYPE_INTEGER; + int regnum(reg[1] - '0'); + if (regnum < 0 || regnum > 6) { + throw Error("invalid register " + reg); + } + code.reg1 = regnum; ++i; - if (reg == "i0") { - text[cursor] = Script::CODE_MOD_I0; - ++cursor; - ReadScriptInteger(**i, text + cursor); - cursor += sizeof(int); - } else if (reg == "i1") { - text[cursor] = Script::CODE_MOD_I1; - ++cursor; + + if ((*i)->GetType() == ScriptToken::REGISTER) { + string reg2((*i)->RegisterName()); + if (reg[0] != reg2[0]) { + throw Error("mixed-type commands not allowed"); + } + int reg2num(reg[1] - '0'); + if (reg2num < 0 || reg2num > 6) { + throw Error("invalid register name " + reg2); + } + code.reg2 = reg2num; + } else { + code.reg2 = 7; ReadScriptInteger(**i, text + cursor); cursor += sizeof(int); - } else { - throw Error("unexpected register " + reg); } } else if (cmd == "rand") { + Script::Code &code(CreateScriptCode(Script::COMMAND_RAND, text + cursor)); + cursor += sizeof(Script::Code); + code.numParams = 1; ++i; const string ®((*i)->RegisterName()); - if (reg == "i0") { - text[cursor] = Script::CODE_RAND_I0; - ++cursor; - } else if (reg == "i1") { - text[cursor] = Script::CODE_RAND_I1; - ++cursor; - } else { - throw Error("unexpected register " + reg); + if (reg[0] != 'i') { + throw Error("invalid register " + reg); } + code.type = Script::TYPE_INTEGER; + int regnum(reg[1] - '0'); + if (regnum < 0 || regnum > 6) { + throw Error("invalid register " + reg); + } + code.reg1 = regnum; } else if (cmd == "cmp") { + Script::Code &code(CreateScriptCode(Script::COMMAND_CMP, text + cursor)); + cursor += sizeof(Script::Code); + code.numParams = 2; ++i; const string ®((*i)->RegisterName()); + if (reg[0] != 'i') { + throw Error("invalid register " + reg); + } + code.type = Script::TYPE_INTEGER; + int regnum(reg[1] - '0'); + if (regnum < 0 || regnum > 6) { + throw Error("invalid register " + reg); + } + code.reg1 = regnum; ++i; - if (reg == "i0") { - if ((*i)->GetType() == ScriptToken::REGISTER && (*i)->RegisterName() == "i1") { - text[cursor] = Script::CODE_CMP_I0_I1; - ++cursor; - } else { - text[cursor] = Script::CODE_CMP_I0; - ++cursor; - ReadScriptInteger(**i, text + cursor); - cursor += sizeof(int); + + if ((*i)->GetType() == ScriptToken::REGISTER) { + string reg2((*i)->RegisterName()); + if (reg[0] != reg2[0]) { + throw Error("mixed-type commands not allowed"); } - } else if (reg == "i1") { - text[cursor] = Script::CODE_CMP_I1; - ++cursor; + int reg2num(reg[1] - '0'); + if (reg2num < 0 || reg2num > 6) { + throw Error("invalid register name " + reg2); + } + code.reg2 = reg2num; + } else { + code.reg2 = 7; ReadScriptInteger(**i, text + cursor); cursor += sizeof(int); - } else { - throw Error("cannot use " + reg + " as lhs for comparison"); } } else if (cmd == "jmp") { - text[cursor] = Script::CODE_JUMP; - ++cursor; + Script::Code &code(CreateScriptCode(Script::COMMAND_JMP, text + cursor)); + cursor += sizeof(Script::Code); + code.numParams = 1; ++i; if (!labels.count((*i)->Identifier())) { throw Error("use of undefined label " + (*i)->Identifier()); @@ -614,8 +690,9 @@ void Interpreter::ReadScript(const std::vector &s, Script *script *reinterpret_cast(text + cursor) = labels[(*i)->Identifier()]; cursor += sizeof(int); } else if (cmd == "jeq") { - text[cursor] = Script::CODE_JUMP_EQUAL; - ++cursor; + Script::Code &code(CreateScriptCode(Script::COMMAND_JEQ, text + cursor)); + cursor += sizeof(Script::Code); + code.numParams = 1; ++i; if (!labels.count((*i)->Identifier())) { throw Error("use of undefined label " + (*i)->Identifier()); @@ -623,8 +700,9 @@ void Interpreter::ReadScript(const std::vector &s, Script *script *reinterpret_cast(text + cursor) = labels[(*i)->Identifier()]; cursor += sizeof(int); } else if (cmd == "jne") { - text[cursor] = Script::CODE_JUMP_NOT_EQUAL; - ++cursor; + Script::Code &code(CreateScriptCode(Script::COMMAND_JNE, text + cursor)); + cursor += sizeof(Script::Code); + code.numParams = 1; ++i; if (!labels.count((*i)->Identifier())) { throw Error("use of undefined label " + (*i)->Identifier()); @@ -632,8 +710,9 @@ void Interpreter::ReadScript(const std::vector &s, Script *script *reinterpret_cast(text + cursor) = labels[(*i)->Identifier()]; cursor += sizeof(int); } else if (cmd == "jl") { - text[cursor] = Script::CODE_JUMP_LESS; - ++cursor; + Script::Code &code(CreateScriptCode(Script::COMMAND_JL, text + cursor)); + cursor += sizeof(Script::Code); + code.numParams = 1; ++i; if (!labels.count((*i)->Identifier())) { throw Error("use of undefined label " + (*i)->Identifier()); @@ -641,8 +720,9 @@ void Interpreter::ReadScript(const std::vector &s, Script *script *reinterpret_cast(text + cursor) = labels[(*i)->Identifier()]; cursor += sizeof(int); } else if (cmd == "jle") { - text[cursor] = Script::CODE_JUMP_LESS_EQUAL; - ++cursor; + Script::Code &code(CreateScriptCode(Script::COMMAND_JLE, text + cursor)); + cursor += sizeof(Script::Code); + code.numParams = 1; ++i; if (!labels.count((*i)->Identifier())) { throw Error("use of undefined label " + (*i)->Identifier()); @@ -650,8 +730,9 @@ void Interpreter::ReadScript(const std::vector &s, Script *script *reinterpret_cast(text + cursor) = labels[(*i)->Identifier()]; cursor += sizeof(int); } else if (cmd == "jg") { - text[cursor] = Script::CODE_JUMP_GREATER; - ++cursor; + Script::Code &code(CreateScriptCode(Script::COMMAND_JG, text + cursor)); + cursor += sizeof(Script::Code); + code.numParams = 1; ++i; if (!labels.count((*i)->Identifier())) { throw Error("use of undefined label " + (*i)->Identifier()); @@ -659,8 +740,9 @@ void Interpreter::ReadScript(const std::vector &s, Script *script *reinterpret_cast(text + cursor) = labels[(*i)->Identifier()]; cursor += sizeof(int); } else if (cmd == "jge") { - text[cursor] = Script::CODE_JUMP_GREATER_EQUAL; - ++cursor; + Script::Code &code(CreateScriptCode(Script::COMMAND_JGE, text + cursor)); + cursor += sizeof(Script::Code); + code.numParams = 1; ++i; if (!labels.count((*i)->Identifier())) { throw Error("use of undefined label " + (*i)->Identifier()); @@ -668,8 +750,9 @@ void Interpreter::ReadScript(const std::vector &s, Script *script *reinterpret_cast(text + cursor) = labels[(*i)->Identifier()]; cursor += sizeof(int); } else if (cmd == "sysc") { - text[cursor] = Script::CODE_SYSCALL; - ++cursor; + Script::Code &code(CreateScriptCode(Script::COMMAND_SYSC, text + cursor)); + cursor += sizeof(Script::Code); + code.numParams = 0; } else { throw Error("unknown command " + cmd); } @@ -687,7 +770,17 @@ char *Interpreter::ReadScript(const vector &s) { return mem; } -void Interpreter::ReadScriptAddress(const ScriptToken &t, unsigned char *dest) { +Script::Code &Interpreter::CreateScriptCode(Script::Command c, char *dest) { + Script::Code &code(*reinterpret_cast(dest)); + code.command = c; + code.numParams = 0; + code.type = Script::TYPE_NONE; + code.reg1 = 7; + code.reg2 = 7; + return code; +} + +void Interpreter::ReadScriptAddress(const ScriptToken &t, char *dest) { if (t.GetType() != ScriptToken::IDENTIFIER) { throw Error("expected identifier for address"); } @@ -700,7 +793,7 @@ void Interpreter::ReadScriptAddress(const ScriptToken &t, unsigned char *dest) { } } -void Interpreter::ReadScriptInteger(const ScriptToken &t, unsigned char *dest) { +void Interpreter::ReadScriptInteger(const ScriptToken &t, char *dest) { if (t.GetType() == ScriptToken::IDENTIFIER) { if (source.IsDefined(t.Identifier())) { void *num(GetObject(TypeDescription::GetTypeId("Number"), t.Identifier())); @@ -715,7 +808,7 @@ void Interpreter::ReadScriptInteger(const ScriptToken &t, unsigned char *dest) { } } -void Interpreter::ReadScriptVector(const ScriptToken &t, unsigned char *dest) { +void Interpreter::ReadScriptVector(const ScriptToken &t, char *dest) { if (t.GetType() == ScriptToken::IDENTIFIER) { if (source.IsDefined(t.Identifier())) { void *vec(GetObject(TypeDescription::GetTypeId("Vector"), t.Identifier())); diff --git a/src/loader/Interpreter.h b/src/loader/Interpreter.h index e78de12..8c14d1e 100644 --- a/src/loader/Interpreter.h +++ b/src/loader/Interpreter.h @@ -14,6 +14,7 @@ #include "TypeDescription.h" #include "../battle/fwd.h" #include "../common/fwd.h" +#include "../common/Script.h" #include "../geometry/Vector.h" #include "../graphics/Color.h" #include "../graphics/ComplexAnimation.h" @@ -91,9 +92,10 @@ private: void ReadObject(int typeId, int id, char *dest, const PropertyList &); void ReadScript(const std::vector &, common::Script *); char *ReadScript(const std::vector &); - void ReadScriptAddress(const ScriptToken &t, unsigned char *dest); - void ReadScriptInteger(const ScriptToken &t, unsigned char *dest); - void ReadScriptVector(const ScriptToken &t, unsigned char *dest); + common::Script::Code &CreateScriptCode(common::Script::Command c, char *dest); + void ReadScriptAddress(const ScriptToken &t, char *dest); + void ReadScriptInteger(const ScriptToken &t, char *dest); + void ReadScriptVector(const ScriptToken &t, char *dest); SDL_Surface *GetImage(const std::string &); diff --git a/src/map/MapState.cpp b/src/map/MapState.cpp index 500acea..5ec9507 100644 --- a/src/map/MapState.cpp +++ b/src/map/MapState.cpp @@ -441,10 +441,10 @@ bool MapState::ZCompare(const Entity *lhs, const Entity *rhs) { void MapState::HandleSyscall(common::ScriptRunner &r) { - switch (r.Integer0()) { + switch (r.IntegerRegister(0)) { case TRANSITION: { Ctrl().PushState(new ColorFade(this, 0, 500, true)); - Ctrl().PushState(new TransitionState(this, reinterpret_cast(r.Address0()), r.Vector0())); + Ctrl().PushState(new TransitionState(this, reinterpret_cast(r.AddressRegister(0)), r.VectorRegister(0))); ColorFade *fadeOut(new ColorFade(this, 0, 500, false)); fadeOut->SetLeadOutTime(500); Ctrl().PushState(fadeOut);