Set up GPL functions properly (the math evaluator now calls the handler if its implemented).
svn-id: r42188
This commit is contained in:
parent
237707dd6e
commit
edaaca97f9
2 changed files with 61 additions and 33 deletions
|
@ -114,31 +114,32 @@ void Script::setupCommandList() {
|
||||||
{"-", &Script::operSub }
|
{"-", &Script::operSub }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Functions used by the mathematical evaluator */
|
||||||
|
static const GPL2Function gplFunctions[] = {
|
||||||
|
{ "Not", NULL },
|
||||||
|
{ "Random", NULL },
|
||||||
|
{ "IsIcoOn", NULL },
|
||||||
|
{ "IsIcoAct", NULL },
|
||||||
|
{ "IcoStat", NULL },
|
||||||
|
{ "ActIco", NULL },
|
||||||
|
{ "IsObjOn", NULL },
|
||||||
|
{ "IsObjOff", NULL },
|
||||||
|
{ "IsObjAway", NULL },
|
||||||
|
{ "ObjStat", NULL },
|
||||||
|
{ "LastBlock", NULL },
|
||||||
|
{ "AtBegin", NULL },
|
||||||
|
{ "BlockVar", NULL },
|
||||||
|
{ "HasBeen", NULL },
|
||||||
|
{ "MaxLine", NULL },
|
||||||
|
{ "ActPhase", NULL },
|
||||||
|
{ "Cheat", NULL },
|
||||||
|
};
|
||||||
|
|
||||||
_commandList = gplCommands;
|
_commandList = gplCommands;
|
||||||
_operatorList = gplOperators;
|
_operatorList = gplOperators;
|
||||||
|
_functionList = gplFunctions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Functions used by the mathematical evaluator */
|
|
||||||
Common::String functions[] = {
|
|
||||||
"F_Not",
|
|
||||||
"F_Random",
|
|
||||||
"F_IsIcoOn",
|
|
||||||
"F_IsIcoAct",
|
|
||||||
"F_IcoStat",
|
|
||||||
"F_ActIco",
|
|
||||||
"F_IsObjOn",
|
|
||||||
"F_IsObjOff",
|
|
||||||
"F_IsObjAway",
|
|
||||||
"F_ObjStat",
|
|
||||||
"F_LastBlock",
|
|
||||||
"F_AtBegin",
|
|
||||||
"F_BlockVar",
|
|
||||||
"F_HasBeen",
|
|
||||||
"F_MaxLine",
|
|
||||||
"F_ActPhase",
|
|
||||||
"F_Cheat"
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Type of mathematical object */
|
/** Type of mathematical object */
|
||||||
enum mathExpressionObject {
|
enum mathExpressionObject {
|
||||||
kMathEnd,
|
kMathEnd,
|
||||||
|
@ -223,7 +224,11 @@ void Script::start(Common::Queue<int> ¶ms) {
|
||||||
|
|
||||||
GameObject *obj = _vm->_game->getObject(objID);
|
GameObject *obj = _vm->_game->getObject(objID);
|
||||||
|
|
||||||
_vm->_anims->play(animID);
|
int visiblethingy = obj->_visible ? 1 << 7 : 0x00;
|
||||||
|
int thingy = (obj->_location + 1) | visiblethingy;
|
||||||
|
|
||||||
|
if ( ((objID == 0) || (obj->_visible)) && (obj->_location == _vm->_game->_currentRoom._roomNum))
|
||||||
|
_vm->_anims->play(animID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -235,12 +240,13 @@ int Script::handleMathExpression(Common::MemoryReadStream &reader) {
|
||||||
Common::Stack<int> stk;
|
Common::Stack<int> stk;
|
||||||
mathExpressionObject obj;
|
mathExpressionObject obj;
|
||||||
GPL2Operator oper;
|
GPL2Operator oper;
|
||||||
|
GPL2Function func;
|
||||||
|
|
||||||
// Read in initial math object
|
// Read in initial math object
|
||||||
obj = (mathExpressionObject)reader.readUint16LE();
|
obj = (mathExpressionObject)reader.readUint16LE();
|
||||||
|
|
||||||
int value;
|
int value;
|
||||||
int op1, op2, res;
|
int arg1, arg2, res;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (obj == kMathEnd) {
|
if (obj == kMathEnd) {
|
||||||
|
@ -263,20 +269,20 @@ int Script::handleMathExpression(Common::MemoryReadStream &reader) {
|
||||||
|
|
||||||
case kMathOperator:
|
case kMathOperator:
|
||||||
value = reader.readUint16LE();
|
value = reader.readUint16LE();
|
||||||
op1 = stk.pop();
|
arg1 = stk.pop();
|
||||||
op2 = stk.pop();
|
arg2 = stk.pop();
|
||||||
|
|
||||||
// Fetch operator
|
// Fetch operator
|
||||||
oper = _operatorList[value-1];
|
oper = _operatorList[value-1];
|
||||||
|
|
||||||
// Calculate result
|
// Calculate result
|
||||||
res = (this->*(oper._handler))(op1, op2);
|
res = (this->*(oper._handler))(arg1, arg2);
|
||||||
|
|
||||||
// Push result
|
// Push result
|
||||||
stk.push(res);
|
stk.push(res);
|
||||||
|
|
||||||
debugC(3, kDraciBytecodeDebugLevel, "\t\t%d %s %d (res: %d)",
|
debugC(3, kDraciBytecodeDebugLevel, "\t\t%d %s %d (res: %d)",
|
||||||
op1, oper._name.c_str(), op2, res);
|
arg1, oper._name.c_str(), arg2, res);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kMathVariable:
|
case kMathVariable:
|
||||||
|
@ -287,14 +293,29 @@ int Script::handleMathExpression(Common::MemoryReadStream &reader) {
|
||||||
|
|
||||||
case kMathFunctionCall:
|
case kMathFunctionCall:
|
||||||
value = reader.readUint16LE();
|
value = reader.readUint16LE();
|
||||||
|
|
||||||
stk.pop();
|
|
||||||
|
|
||||||
// FIXME: Pushing dummy value for now, but should push return value
|
// Fetch function
|
||||||
stk.push(0);
|
func = _functionList[value-1];
|
||||||
|
|
||||||
|
// If not yet implemented
|
||||||
|
if (func._handler == NULL) {
|
||||||
|
stk.pop();
|
||||||
|
|
||||||
|
// FIXME: Pushing dummy value for now, but should push return value
|
||||||
|
stk.push(0);
|
||||||
|
|
||||||
|
debugC(3, kDraciBytecodeDebugLevel, "\t\tcall: %s (not implemented)",
|
||||||
|
func._name.c_str());
|
||||||
|
} else {
|
||||||
|
arg1 = stk.pop();
|
||||||
|
|
||||||
|
// Calculate result
|
||||||
|
res = (this->*(func._handler))(arg1);
|
||||||
|
|
||||||
|
debugC(3, kDraciBytecodeDebugLevel, "\t\tcall: %s(%d) (res: %d)",
|
||||||
|
func._name.c_str(), arg1, res);
|
||||||
|
}
|
||||||
|
|
||||||
debugC(3, kDraciBytecodeDebugLevel, "\t\tfunction: %s",
|
|
||||||
functions[value-1].c_str());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,7 @@ enum {
|
||||||
|
|
||||||
typedef void (Script::* GPLHandler)(Common::Queue<int> &);
|
typedef void (Script::* GPLHandler)(Common::Queue<int> &);
|
||||||
typedef int (Script::* GPLOperatorHandler)(int, int);
|
typedef int (Script::* GPLOperatorHandler)(int, int);
|
||||||
|
typedef int (Script::* GPLFunctionHandler)(int);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a single command in the GPL scripting language bytecode.
|
* Represents a single command in the GPL scripting language bytecode.
|
||||||
|
@ -65,6 +66,11 @@ struct GPL2Operator {
|
||||||
GPLOperatorHandler _handler;
|
GPLOperatorHandler _handler;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct GPL2Function {
|
||||||
|
Common::String _name;
|
||||||
|
GPLFunctionHandler _handler;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A convenience data type that holds both the actual bytecode and the
|
* A convenience data type that holds both the actual bytecode and the
|
||||||
* length of the bytecode. Passed to Script::run().
|
* length of the bytecode. Passed to Script::run().
|
||||||
|
@ -89,6 +95,7 @@ private:
|
||||||
/** List of all GPL commands. Initialised in the constructor. */
|
/** List of all GPL commands. Initialised in the constructor. */
|
||||||
const GPL2Command *_commandList;
|
const GPL2Command *_commandList;
|
||||||
const GPL2Operator *_operatorList;
|
const GPL2Operator *_operatorList;
|
||||||
|
const GPL2Function *_functionList;
|
||||||
|
|
||||||
void load(Common::Queue<int> ¶ms);
|
void load(Common::Queue<int> ¶ms);
|
||||||
void start(Common::Queue<int> ¶ms);
|
void start(Common::Queue<int> ¶ms);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue