Set up GPL functions properly (the math evaluator now calls the handler if its implemented).

svn-id: r42188
This commit is contained in:
Denis Kasak 2009-07-06 18:49:51 +00:00
parent 237707dd6e
commit edaaca97f9
2 changed files with 61 additions and 33 deletions

View file

@ -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> &params) {
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;
} }

View file

@ -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> &params); void load(Common::Queue<int> &params);
void start(Common::Queue<int> &params); void start(Common::Queue<int> &params);