예제 #1
0
//////////////////////////////////////////////////////////////////////////
// high level scripting interface
//////////////////////////////////////////////////////////////////////////
bool BaseKeyboardState::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
	//////////////////////////////////////////////////////////////////////////
	// IsKeyDown
	//////////////////////////////////////////////////////////////////////////
	if (strcmp(name, "IsKeyDown") == 0) {
		stack->correctParams(1);
		ScValue *val = stack->pop();
		int vKey;

		if (val->_type == VAL_STRING && strlen(val->getString()) > 0) {
			const char *str = val->getString();
			char temp = str[0];
			if (temp >= 'A' && temp <= 'Z') {
				temp += ('a' - 'A');
			}
			vKey = (int)temp;
		} else {
			vKey = val->getInt();
		}

		bool isDown = _keyStates[vKeyToKeyCode(vKey)];

		stack->pushBool(isDown);
		return STATUS_OK;
	} else {
		return BaseScriptable::scCallMethod(script, stack, thisStack, name);
	}
}
예제 #2
0
void ScStack::correctParams(uint32 expectedParams) {
	uint32 nuParams = (uint32)pop()->getInt();

	if (expectedParams < nuParams) { // too many params
		while (expectedParams < nuParams) {
			//Pop();
			delete _values[_sP - expectedParams];
			_values.remove_at(_sP - expectedParams);
			nuParams--;
			_sP--;
		}
	} else if (expectedParams > nuParams) { // need more params
		while (expectedParams > nuParams) {
			//Push(null_val);
			ScValue *nullVal = new ScValue(_gameRef);
			nullVal->setNULL();
			_values.insert_at(_sP - nuParams + 1, nullVal);
			nuParams++;
			_sP++;

			if ((int32)_values.size() > _sP + 1) {
				delete _values[_values.size() - 1];
				_values.remove_at(_values.size() - 1);
			}
		}
	}
}
예제 #3
0
void ScStack::push(ScValue *val) {
	_sP++;

	if (_sP < (int32)_values.size()) {
		_values[_sP]->cleanup();
		_values[_sP]->copy(val);
	} else {
		ScValue *copyVal = new ScValue(_gameRef);
		copyVal->copy(val);
		_values.add(copyVal);
	}
}
예제 #4
0
파일: debugger.cpp 프로젝트: 86400/scummvm
bool Console::Cmd_Set(int argc, const char **argv) {
	if (argc == 4 && !strncmp("=", argv[2], 1)) {
		ScValue *val = nullptr;
		Error error = CONTROLLER->setValue(argv[1], argv[3], val);
		if (error.getErrorLevel() == SUCCESS) {
			assert(val);
			debugPrintf("%s = %s\n", argv[1], val->getString());
		} else {
			printError(argv[0], error);
		}
	} else {
		printUsage(argv[0]);
	}
	return true;
}
예제 #5
0
SXFile::SXFile(BaseGame *inGame, ScStack *stack) : BaseScriptable(inGame) {
	stack->correctParams(1);
	ScValue *val = stack->pop();

	_filename = nullptr;
	if (!val->isNULL()) {
		BaseUtils::setString(&_filename, val->getString());
	}

	_readFile = nullptr;
	_writeFile = nullptr;

	_mode = 0;
	_textMode = false;
}
예제 #6
0
bool ScValue::setProp(const char *name, ScValue *val, bool copyWhole, bool setAsConst) {
	if (_type == VAL_VARIABLE_REF) {
		return _valRef->setProp(name, val);
	}

	bool ret = STATUS_FAILED;
	if (_type == VAL_NATIVE && _valNative) {
		ret = _valNative->scSetProperty(name, val);
	}

	if (DID_FAIL(ret)) {
		ScValue *newVal = nullptr;

		_valIter = _valObject.find(name);
		if (_valIter != _valObject.end()) {
			newVal = _valIter->_value;
		}
		if (!newVal) {
			newVal = new ScValue(_gameRef);
		} else {
			newVal->cleanup();
		}

		newVal->copy(val, copyWhole);
		newVal->_isConstVar = setAsConst;
		_valObject[name] = newVal;

		if (_type != VAL_NATIVE) {
			_type = VAL_OBJECT;
		}

		/*
		_valIter = _valObject.find(Name);
		if (_valIter != _valObject.end()) {
		    delete _valIter->_value;
		    _valIter->_value = nullptr;
		}
		ScValue* val = new ScValue(_gameRef);
		val->Copy(Val, CopyWhole);
		val->_isConstVar = SetAsConst;
		_valObject[Name] = val;

		if (_type!=VAL_NATIVE) _type = VAL_OBJECT;
		*/
	}

	return STATUS_OK;
}
예제 #7
0
SXDate::SXDate(BaseGame *inGame, ScStack *stack) : BaseScriptable(inGame) {
	stack->correctParams(6);

	memset(&_tm, 0, sizeof(_tm));

	ScValue *valYear = stack->pop();
	_tm.tm_year = valYear->getInt() - 1900;
	_tm.tm_mon = stack->pop()->getInt() - 1;
	_tm.tm_mday = stack->pop()->getInt();
	_tm.tm_hour = stack->pop()->getInt();
	_tm.tm_min = stack->pop()->getInt();
	_tm.tm_sec = stack->pop()->getInt();

	if (valYear->isNULL()) {
		g_system->getTimeAndDate(_tm);
	}
}
예제 #8
0
ScValue *ScScript::getVar(char *name) {
	ScValue *ret = nullptr;

	// scope locals
	if (_scopeStack->_sP >= 0) {
		if (_scopeStack->getTop()->propExists(name)) {
			ret = _scopeStack->getTop()->getProp(name);
		}
	}

	// script globals
	if (ret == nullptr) {
		if (_globals->propExists(name)) {
			ret = _globals->getProp(name);
		}
	}

	// engine globals
	if (ret == nullptr) {
		if (_engine->_globals->propExists(name)) {
			ret = _engine->_globals->getProp(name);
		}
	}

	if (ret == nullptr) {
		//RuntimeError("Variable '%s' is inaccessible in the current block. Consider changing the script.", name);
		_gameRef->LOG(0, "Warning: variable '%s' is inaccessible in the current block. Consider changing the script (script:%s, line:%d)", name, _filename, _currentLine);
		ScValue *val = new ScValue(_gameRef);
		ScValue *scope = _scopeStack->getTop();
		if (scope) {
			scope->setProp(name, val);
			ret = _scopeStack->getTop()->getProp(name);
		} else {
			_globals->setProp(name, val);
			ret = _globals->getProp(name);
		}
		delete val;
	}

	return ret;
}
예제 #9
0
SXString::SXString(BaseGame *inGame, ScStack *stack) : BaseScriptable(inGame) {
	_string = nullptr;
	_capacity = 0;

	stack->correctParams(1);
	ScValue *val = stack->pop();

	if (val->isInt()) {
		_capacity = MAX(0, val->getInt());
		if (_capacity > 0) {
			_string = new char[_capacity];
			memset(_string, 0, _capacity);
		}
	} else {
		setStringVal(val->getString());
	}

	if (_capacity == 0) {
		setStringVal("");
	}
}
예제 #10
0
bool ScScript::executeInstruction() {
	bool ret = STATUS_OK;

	uint32 dw;
	const char *str = nullptr;

	//ScValue* op = new ScValue(_gameRef);
	_operand->cleanup();

	ScValue *op1;
	ScValue *op2;

	uint32 inst = getDWORD();
	switch (inst) {

	case II_DEF_VAR:
		_operand->setNULL();
		dw = getDWORD();
		if (_scopeStack->_sP < 0) {
			_globals->setProp(_symbols[dw], _operand);
		} else {
			_scopeStack->getTop()->setProp(_symbols[dw], _operand);
		}

		break;

	case II_DEF_GLOB_VAR:
	case II_DEF_CONST_VAR: {
		dw = getDWORD();
		/*      char *temp = _symbols[dw]; // TODO delete */
		// only create global var if it doesn't exist
		if (!_engine->_globals->propExists(_symbols[dw])) {
			_operand->setNULL();
			_engine->_globals->setProp(_symbols[dw], _operand, false, inst == II_DEF_CONST_VAR);
		}
		break;
	}

	case II_RET:
		if (_scopeStack->_sP >= 0 && _callStack->_sP >= 0) {
			_scopeStack->pop();
			_iP = (uint32)_callStack->pop()->getInt();
		} else {
			if (_thread) {
				_state = SCRIPT_THREAD_FINISHED;
			} else {
				if (_numEvents == 0 && _numMethods == 0) {
					_state = SCRIPT_FINISHED;
				} else {
					_state = SCRIPT_PERSISTENT;
				}
			}
		}

		break;

	case II_RET_EVENT:
		_state = SCRIPT_FINISHED;
		break;


	case II_CALL:
		dw = getDWORD();

		_operand->setInt(_iP);
		_callStack->push(_operand);

		_iP = dw;

		break;

	case II_CALL_BY_EXP: {
		// push var
		// push string
		str = _stack->pop()->getString();
		char *methodName = new char[strlen(str) + 1];
		strcpy(methodName, str);

		ScValue *var = _stack->pop();
		if (var->_type == VAL_VARIABLE_REF) {
			var = var->_valRef;
		}

		bool res = STATUS_FAILED;
		bool triedNative = false;

		// we are already calling this method, try native
		if (_thread && _methodThread && strcmp(methodName, _threadEvent) == 0 && var->_type == VAL_NATIVE && _owner == var->getNative()) {
			triedNative = true;
			res = var->_valNative->scCallMethod(this, _stack, _thisStack, methodName);
		}

		if (DID_FAIL(res)) {
			if (var->isNative() && var->getNative()->canHandleMethod(methodName)) {
				if (!_unbreakable) {
					_waitScript = var->getNative()->invokeMethodThread(methodName);
					if (!_waitScript) {
						_stack->correctParams(0);
						runtimeError("Error invoking method '%s'.", methodName);
						_stack->pushNULL();
					} else {
						_state = SCRIPT_WAITING_SCRIPT;
						_waitScript->copyParameters(_stack);
					}
				} else {
					// can call methods in unbreakable mode
					_stack->correctParams(0);
					runtimeError("Cannot call method '%s'. Ignored.", methodName);
					_stack->pushNULL();
				}
				delete[] methodName;
				break;
			}
			/*
			ScValue* val = var->getProp(MethodName);
			if (val) {
			    dw = GetFuncPos(val->getString());
			    if (dw==0) {
			        TExternalFunction* f = GetExternal(val->getString());
			        if (f) {
			            ExternalCall(_stack, _thisStack, f);
			        }
			        else{
			            // not an internal nor external, try for native function
			            _gameRef->ExternalCall(this, _stack, _thisStack, val->getString());
			        }
			    }
			    else{
			        _operand->setInt(_iP);
			        _callStack->Push(_operand);
			        _iP = dw;
			    }
			}
			*/
			else {
				res = STATUS_FAILED;
				if (var->_type == VAL_NATIVE && !triedNative) {
					res = var->_valNative->scCallMethod(this, _stack, _thisStack, methodName);
				}

				if (DID_FAIL(res)) {
					_stack->correctParams(0);
					runtimeError("Call to undefined method '%s'. Ignored.", methodName);
					_stack->pushNULL();
				}
			}
		}
		delete[] methodName;
	}
	break;

	case II_EXTERNAL_CALL: {
		uint32 symbolIndex = getDWORD();

		TExternalFunction *f = getExternal(_symbols[symbolIndex]);
		if (f) {
			externalCall(_stack, _thisStack, f);
		} else {
			_gameRef->externalCall(this, _stack, _thisStack, _symbols[symbolIndex]);
		}

		break;
	}
	case II_SCOPE:
		_operand->setNULL();
		_scopeStack->push(_operand);
		break;

	case II_CORRECT_STACK:
		dw = getDWORD(); // params expected
		_stack->correctParams(dw);
		break;

	case II_CREATE_OBJECT:
		_operand->setObject();
		_stack->push(_operand);
		break;

	case II_POP_EMPTY:
		_stack->pop();
		break;

	case II_PUSH_VAR: {
		ScValue *var = getVar(_symbols[getDWORD()]);
		if (false && /*var->_type==VAL_OBJECT ||*/ var->_type == VAL_NATIVE) {
			_operand->setReference(var);
			_stack->push(_operand);
		} else {
			_stack->push(var);
		}
		break;
	}

	case II_PUSH_VAR_REF: {
		ScValue *var = getVar(_symbols[getDWORD()]);
		_operand->setReference(var);
		_stack->push(_operand);
		break;
	}

	case II_POP_VAR: {
		char *varName = _symbols[getDWORD()];
		ScValue *var = getVar(varName);
		if (var) {
			ScValue *val = _stack->pop();
			if (!val) {
				runtimeError("Script stack corruption detected. Please report this script at WME bug reports forum.");
				var->setNULL();
			} else {
				if (val->getType() == VAL_VARIABLE_REF) {
					val = val->_valRef;
				}
				if (val->_type == VAL_NATIVE) {
					var->setValue(val);
				} else {
					var->copy(val);
				}
			}
		}

		break;
	}

	case II_PUSH_VAR_THIS:
		_stack->push(_thisStack->getTop());
		break;

	case II_PUSH_INT:
		_stack->pushInt((int)getDWORD());
		break;

	case II_PUSH_FLOAT:
		_stack->pushFloat(getFloat());
		break;


	case II_PUSH_BOOL:
		_stack->pushBool(getDWORD() != 0);

		break;

	case II_PUSH_STRING:
		_stack->pushString(getString());
		break;

	case II_PUSH_NULL:
		_stack->pushNULL();
		break;

	case II_PUSH_THIS_FROM_STACK:
		_operand->setReference(_stack->getTop());
		_thisStack->push(_operand);
		break;

	case II_PUSH_THIS:
		_operand->setReference(getVar(_symbols[getDWORD()]));
		_thisStack->push(_operand);
		break;

	case II_POP_THIS:
		_thisStack->pop();
		break;

	case II_PUSH_BY_EXP: {
		str = _stack->pop()->getString();
		ScValue *val = _stack->pop()->getProp(str);
		if (val) {
			_stack->push(val);
		} else {
			_stack->pushNULL();
		}

		break;
	}

	case II_POP_BY_EXP: {
		str = _stack->pop()->getString();
		ScValue *var = _stack->pop();
		ScValue *val = _stack->pop();

		if (val == nullptr) {
			runtimeError("Script stack corruption detected. Please report this script at WME bug reports forum.");
			var->setNULL();
		} else {
			var->setProp(str, val);
		}

		break;
	}

	case II_PUSH_REG1:
		_stack->push(_reg1);
		break;

	case II_POP_REG1:
		_reg1->copy(_stack->pop());
		break;

	case II_JMP:
		_iP = getDWORD();
		break;

	case II_JMP_FALSE: {
		dw = getDWORD();
		//if (!_stack->pop()->getBool()) _iP = dw;
		ScValue *val = _stack->pop();
		if (!val) {
			runtimeError("Script corruption detected. Did you use '=' instead of '==' for comparison?");
		} else {
			if (!val->getBool()) {
				_iP = dw;
			}
		}
		break;
	}

	case II_ADD:
		op2 = _stack->pop();
		op1 = _stack->pop();

		if (op1->isNULL() || op2->isNULL()) {
			_operand->setNULL();
		} else if (op1->getType() == VAL_STRING || op2->getType() == VAL_STRING) {
			char *tempStr = new char [strlen(op1->getString()) + strlen(op2->getString()) + 1];
			strcpy(tempStr, op1->getString());
			strcat(tempStr, op2->getString());
			_operand->setString(tempStr);
			delete[] tempStr;
		} else if (op1->getType() == VAL_INT && op2->getType() == VAL_INT) {
			_operand->setInt(op1->getInt() + op2->getInt());
		} else {
			_operand->setFloat(op1->getFloat() + op2->getFloat());
		}

		_stack->push(_operand);

		break;

	case II_SUB:
		op2 = _stack->pop();
		op1 = _stack->pop();

		if (op1->isNULL() || op2->isNULL()) {
			_operand->setNULL();
		} else if (op1->getType() == VAL_INT && op2->getType() == VAL_INT) {
			_operand->setInt(op1->getInt() - op2->getInt());
		} else {
			_operand->setFloat(op1->getFloat() - op2->getFloat());
		}

		_stack->push(_operand);

		break;

	case II_MUL:
		op2 = _stack->pop();
		op1 = _stack->pop();

		if (op1->isNULL() || op2->isNULL()) {
			_operand->setNULL();
		} else if (op1->getType() == VAL_INT && op2->getType() == VAL_INT) {
			_operand->setInt(op1->getInt() * op2->getInt());
		} else {
			_operand->setFloat(op1->getFloat() * op2->getFloat());
		}

		_stack->push(_operand);

		break;

	case II_DIV:
		op2 = _stack->pop();
		op1 = _stack->pop();

		if (op2->getFloat() == 0.0f) {
			runtimeError("Division by zero.");
		}

		if (op1->isNULL() || op2->isNULL() || op2->getFloat() == 0.0f) {
			_operand->setNULL();
		} else {
			_operand->setFloat(op1->getFloat() / op2->getFloat());
		}

		_stack->push(_operand);

		break;

	case II_MODULO:
		op2 = _stack->pop();
		op1 = _stack->pop();

		if (op2->getInt() == 0) {
			runtimeError("Division by zero.");
		}

		if (op1->isNULL() || op2->isNULL() || op2->getInt() == 0) {
			_operand->setNULL();
		} else {
			_operand->setInt(op1->getInt() % op2->getInt());
		}

		_stack->push(_operand);

		break;

	case II_NOT:
		op1 = _stack->pop();
		//if (op1->isNULL()) _operand->setNULL();
		if (op1->isNULL()) {
			_operand->setBool(true);
		} else {
			_operand->setBool(!op1->getBool());
		}
		_stack->push(_operand);

		break;

	case II_AND:
		op2 = _stack->pop();
		op1 = _stack->pop();
		if (op1 == nullptr || op2 == nullptr) {
			runtimeError("Script corruption detected. Did you use '=' instead of '==' for comparison?");
			_operand->setBool(false);
		} else {
			_operand->setBool(op1->getBool() && op2->getBool());
		}
		_stack->push(_operand);
		break;

	case II_OR:
		op2 = _stack->pop();
		op1 = _stack->pop();
		if (op1 == nullptr || op2 == nullptr) {
			runtimeError("Script corruption detected. Did you use '=' instead of '==' for comparison?");
			_operand->setBool(false);
		} else {
			_operand->setBool(op1->getBool() || op2->getBool());
		}
		_stack->push(_operand);
		break;

	case II_CMP_EQ:
		op2 = _stack->pop();
		op1 = _stack->pop();

		/*
		if ((op1->isNULL() && !op2->isNULL()) || (!op1->isNULL() && op2->isNULL())) _operand->setBool(false);
		else if (op1->isNative() && op2->isNative()) {
		    _operand->setBool(op1->getNative() == op2->getNative());
		}
		else if (op1->getType()==VAL_STRING || op2->getType()==VAL_STRING) {
		    _operand->setBool(scumm_stricmp(op1->getString(), op2->getString())==0);
		}
		else if (op1->getType()==VAL_FLOAT && op2->getType()==VAL_FLOAT) {
		    _operand->setBool(op1->getFloat() == op2->getFloat());
		}
		else{
		    _operand->setBool(op1->getInt() == op2->getInt());
		}
		*/

		_operand->setBool(ScValue::compare(op1, op2) == 0);
		_stack->push(_operand);
		break;

	case II_CMP_NE:
		op2 = _stack->pop();
		op1 = _stack->pop();

		/*
		if ((op1->isNULL() && !op2->isNULL()) || (!op1->isNULL() && op2->isNULL())) _operand->setBool(true);
		else if (op1->isNative() && op2->isNative()) {
		    _operand->setBool(op1->getNative() != op2->getNative());
		}
		else if (op1->getType()==VAL_STRING || op2->getType()==VAL_STRING) {
		    _operand->setBool(scumm_stricmp(op1->getString(), op2->getString())!=0);
		}
		else if (op1->getType()==VAL_FLOAT && op2->getType()==VAL_FLOAT) {
		    _operand->setBool(op1->getFloat() != op2->getFloat());
		}
		else{
		    _operand->setBool(op1->getInt() != op2->getInt());
		}
		*/

		_operand->setBool(ScValue::compare(op1, op2) != 0);
		_stack->push(_operand);
		break;

	case II_CMP_L:
		op2 = _stack->pop();
		op1 = _stack->pop();

		/*
		if (op1->getType()==VAL_FLOAT && op2->getType()==VAL_FLOAT) {
		    _operand->setBool(op1->getFloat() < op2->getFloat());
		}
		else _operand->setBool(op1->getInt() < op2->getInt());
		*/

		_operand->setBool(ScValue::compare(op1, op2) < 0);
		_stack->push(_operand);
		break;

	case II_CMP_G:
		op2 = _stack->pop();
		op1 = _stack->pop();

		/*
		if (op1->getType()==VAL_FLOAT && op2->getType()==VAL_FLOAT) {
		    _operand->setBool(op1->getFloat() > op2->getFloat());
		}
		else _operand->setBool(op1->getInt() > op2->getInt());
		*/

		_operand->setBool(ScValue::compare(op1, op2) > 0);
		_stack->push(_operand);
		break;

	case II_CMP_LE:
		op2 = _stack->pop();
		op1 = _stack->pop();

		/*
		if (op1->getType()==VAL_FLOAT && op2->getType()==VAL_FLOAT) {
		    _operand->setBool(op1->getFloat() <= op2->getFloat());
		}
		else _operand->setBool(op1->getInt() <= op2->getInt());
		*/

		_operand->setBool(ScValue::compare(op1, op2) <= 0);
		_stack->push(_operand);
		break;

	case II_CMP_GE:
		op2 = _stack->pop();
		op1 = _stack->pop();

		/*
		if (op1->getType()==VAL_FLOAT && op2->getType()==VAL_FLOAT) {
		    _operand->setBool(op1->getFloat() >= op2->getFloat());
		}
		else _operand->setBool(op1->getInt() >= op2->getInt());
		*/

		_operand->setBool(ScValue::compare(op1, op2) >= 0);
		_stack->push(_operand);
		break;

	case II_CMP_STRICT_EQ:
		op2 = _stack->pop();
		op1 = _stack->pop();

		//_operand->setBool(op1->getType()==op2->getType() && op1->getFloat()==op2->getFloat());
		_operand->setBool(ScValue::compareStrict(op1, op2) == 0);
		_stack->push(_operand);

		break;

	case II_CMP_STRICT_NE:
		op2 = _stack->pop();
		op1 = _stack->pop();

		//_operand->setBool(op1->getType()!=op2->getType() || op1->getFloat()!=op2->getFloat());
		_operand->setBool(ScValue::compareStrict(op1, op2) != 0);
		_stack->push(_operand);
		break;

	case II_DBG_LINE: {
		int newLine = getDWORD();
		if (newLine != _currentLine) {
			_currentLine = newLine;
		}
		break;

	}
	default:
		_gameRef->LOG(0, "Fatal: Invalid instruction %d ('%s', line %d, IP:0x%x)\n", inst, _filename, _currentLine, _iP - sizeof(uint32));
		_state = SCRIPT_FINISHED;
		ret = STATUS_FAILED;
	} // switch(instruction)

	//delete op;

	return ret;
}
예제 #11
0
파일: ad_actor.cpp 프로젝트: Fyre91/scummvm
//////////////////////////////////////////////////////////////////////////
// high level scripting interface
//////////////////////////////////////////////////////////////////////////
bool AdActor::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
	//////////////////////////////////////////////////////////////////////////
	// GoTo / GoToAsync
	//////////////////////////////////////////////////////////////////////////
	if (strcmp(name, "GoTo") == 0 || strcmp(name, "GoToAsync") == 0) {
		stack->correctParams(2);
		int x = stack->pop()->getInt();
		int y = stack->pop()->getInt();
		goTo(x, y);
		if (strcmp(name, "GoToAsync") != 0) {
			script->waitForExclusive(this);
		}
		stack->pushNULL();
		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GoToObject / GoToObjectAsync
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "GoToObject") == 0 || strcmp(name, "GoToObjectAsync") == 0) {
		stack->correctParams(1);
		ScValue *val = stack->pop();
		if (!val->isNative()) {
			script->runtimeError("actor.%s method accepts an entity refrence only", name);
			stack->pushNULL();
			return STATUS_OK;
		}
		AdObject *obj = (AdObject *)val->getNative();
		if (!obj || obj->getType() != OBJECT_ENTITY) {
			script->runtimeError("actor.%s method accepts an entity refrence only", name);
			stack->pushNULL();
			return STATUS_OK;
		}
		AdEntity *ent = (AdEntity *)obj;
		if (ent->getWalkToX() == 0 && ent->getWalkToY() == 0) {
			goTo(ent->_posX, ent->_posY);
		} else {
			goTo(ent->getWalkToX(), ent->getWalkToY(), ent->getWalkToDir());
		}
		if (strcmp(name, "GoToObjectAsync") != 0) {
			script->waitForExclusive(this);
		}
		stack->pushNULL();
		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// TurnTo / TurnToAsync
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "TurnTo") == 0 || strcmp(name, "TurnToAsync") == 0) {
		stack->correctParams(1);
		int dir;
		ScValue *val = stack->pop();

		// turn to object?
		if (val->isNative() && _gameRef->validObject((BaseObject *)val->getNative())) {
			BaseObject *obj = (BaseObject *)val->getNative();
			int angle = (int)(atan2((double)(obj->_posY - _posY), (double)(obj->_posX - _posX)) * (180 / 3.14));
			dir = (int)angleToDirection(angle);
		}
		// otherwise turn to direction
		else {
			dir = val->getInt();
		}

		if (dir >= 0 && dir < NUM_DIRECTIONS) {
			turnTo((TDirection)dir);
			if (strcmp(name, "TurnToAsync") != 0) {
				script->waitForExclusive(this);
			}
		}
		stack->pushNULL();
		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// IsWalking
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "IsWalking") == 0) {
		stack->correctParams(0);
		stack->pushBool(_state == STATE_FOLLOWING_PATH);
		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// MergeAnims
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "MergeAnims") == 0) {
		stack->correctParams(1);
		stack->pushBool(DID_SUCCEED(mergeAnims(stack->pop()->getString())));
		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// UnloadAnim
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "UnloadAnim") == 0) {
		stack->correctParams(1);
		const char *animName = stack->pop()->getString();

		bool found = false;
		for (uint32 i = 0; i < _anims.size(); i++) {
			if (scumm_stricmp(_anims[i]->getName(), animName) == 0) {
				// invalidate sprites in use
				if (_anims[i]->containsSprite(_tempSprite2)) {
					_tempSprite2 = nullptr;
				}
				if (_anims[i]->containsSprite(_currentSprite)) {
					_currentSprite = nullptr;
				}
				if (_anims[i]->containsSprite(_animSprite2)) {
					_animSprite2 = nullptr;
				}

				delete _anims[i];
				_anims[i] = nullptr;
				_anims.remove_at(i);
				i--;
				found = true;
			}
		}
		stack->pushBool(found);
		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// HasAnim
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "HasAnim") == 0) {
		stack->correctParams(1);
		const char *animName = stack->pop()->getString();
		stack->pushBool(getAnimByName(animName) != nullptr);
		return STATUS_OK;
	} else {
		return AdTalkHolder::scCallMethod(script, stack, thisStack, name);
	}
}
예제 #12
0
//////////////////////////////////////////////////////////////////////////
// high level scripting interface
//////////////////////////////////////////////////////////////////////////
bool AdObject::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {

	//////////////////////////////////////////////////////////////////////////
	// PlayAnim / PlayAnimAsync
	//////////////////////////////////////////////////////////////////////////
	if (strcmp(name, "PlayAnim") == 0 || strcmp(name, "PlayAnimAsync") == 0) {
		stack->correctParams(1);
		if (DID_FAIL(playAnim(stack->pop()->getString()))) {
			stack->pushBool(false);
		} else {
			if (strcmp(name, "PlayAnimAsync") != 0) {
				script->waitFor(this);
			}
			stack->pushBool(true);
		}
		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// Reset
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "Reset") == 0) {
		stack->correctParams(0);
		reset();
		stack->pushNULL();
		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// IsTalking
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "IsTalking") == 0) {
		stack->correctParams(0);
		stack->pushBool(_state == STATE_TALKING);
		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// StopTalk / StopTalking
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "StopTalk") == 0 || strcmp(name, "StopTalking") == 0) {
		stack->correctParams(0);
		if (_sentence) {
			_sentence->finish();
		}
		if (_state == STATE_TALKING) {
			_state = _nextState;
			_nextState = STATE_READY;
			stack->pushBool(true);
		} else {
			stack->pushBool(false);
		}
		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// ForceTalkAnim
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "ForceTalkAnim") == 0) {
		stack->correctParams(1);
		const char *animName = stack->pop()->getString();
		delete[] _forcedTalkAnimName;
		_forcedTalkAnimName = new char[strlen(animName) + 1];
		strcpy(_forcedTalkAnimName, animName);
		_forcedTalkAnimUsed = false;
		stack->pushBool(true);
		return STATUS_OK;
	}


	//////////////////////////////////////////////////////////////////////////
	// Talk / TalkAsync
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "Talk") == 0 || strcmp(name, "TalkAsync") == 0) {
		stack->correctParams(5);

		const char *text    = stack->pop()->getString();
		ScValue *soundVal = stack->pop();
		int duration  = stack->pop()->getInt();
		ScValue *valStances = stack->pop();

		const char *stances = valStances->isNULL() ? nullptr : valStances->getString();

		int align = 0;
		ScValue *val = stack->pop();
		if (val->isNULL()) {
			align = TAL_CENTER;
		} else {
			align = val->getInt();
		}

		align = MIN(MAX(0, align), NUM_TEXT_ALIGN - 1);

		const char *sound = soundVal->isNULL() ? nullptr : soundVal->getString();

		talk(text, sound, duration, stances, (TTextAlign)align);
		if (strcmp(name, "TalkAsync") != 0) {
			script->waitForExclusive(this);
		}

		stack->pushNULL();
		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// StickToRegion
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "StickToRegion") == 0) {
		stack->correctParams(1);

		AdLayer *main = ((AdGame *)_gameRef)->_scene->_mainLayer;
		bool regFound = false;

		uint32 i;
		ScValue *val = stack->pop();
		if (val->isNULL() || !main) {
			_stickRegion = nullptr;
			regFound = true;
		} else if (val->isString()) {
			const char *regionName = val->getString();
			for (i = 0; i < main->_nodes.size(); i++) {
				if (main->_nodes[i]->_type == OBJECT_REGION && main->_nodes[i]->_region->getName() && scumm_stricmp(main->_nodes[i]->_region->getName(), regionName) == 0) {
					_stickRegion = main->_nodes[i]->_region;
					regFound = true;
					break;
				}
			}
		} else if (val->isNative()) {
			BaseScriptable *obj = val->getNative();

			for (i = 0; i < main->_nodes.size(); i++) {
				if (main->_nodes[i]->_type == OBJECT_REGION && main->_nodes[i]->_region == obj) {
					_stickRegion = main->_nodes[i]->_region;
					regFound = true;
					break;
				}
			}

		}

		if (!regFound) {
			_stickRegion = nullptr;
		}
		stack->pushBool(regFound);
		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SetFont
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "SetFont") == 0) {
		stack->correctParams(1);
		ScValue *val = stack->pop();

		if (val->isNULL()) {
			setFont(nullptr);
		} else {
			setFont(val->getString());
		}

		stack->pushNULL();
		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetFont
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "GetFont") == 0) {
		stack->correctParams(0);
		if (_font && _font->getFilename()) {
			stack->pushString(_font->getFilename());
		} else {
			stack->pushNULL();
		}
		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// TakeItem
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "TakeItem") == 0) {
		stack->correctParams(2);

		if (!_inventory) {
			_inventory = new AdInventory(_gameRef);
			((AdGame *)_gameRef)->registerInventory(_inventory);
		}

		ScValue *val = stack->pop();
		if (!val->isNULL()) {
			const char *itemName = val->getString();
			val = stack->pop();
			const char *insertAfter = val->isNULL() ? nullptr : val->getString();
			if (DID_FAIL(_inventory->insertItem(itemName, insertAfter))) {
				script->runtimeError("Cannot add item '%s' to inventory", itemName);
			} else {
				// hide associated entities
				((AdGame *)_gameRef)->_scene->handleItemAssociations(itemName, false);
			}

		} else {
			script->runtimeError("TakeItem: item name expected");
		}

		stack->pushNULL();
		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// DropItem
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "DropItem") == 0) {
		stack->correctParams(1);

		if (!_inventory) {
			_inventory = new AdInventory(_gameRef);
			((AdGame *)_gameRef)->registerInventory(_inventory);
		}

		ScValue *val = stack->pop();
		if (!val->isNULL()) {
			if (DID_FAIL(_inventory->removeItem(val->getString()))) {
				script->runtimeError("Cannot remove item '%s' from inventory", val->getString());
			} else {
				// show associated entities
				((AdGame *)_gameRef)->_scene->handleItemAssociations(val->getString(), true);
			}
		} else {
			script->runtimeError("DropItem: item name expected");
		}

		stack->pushNULL();
		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetItem
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "GetItem") == 0) {
		stack->correctParams(1);

		if (!_inventory) {
			_inventory = new AdInventory(_gameRef);
			((AdGame *)_gameRef)->registerInventory(_inventory);
		}

		ScValue *val = stack->pop();
		if (val->_type == VAL_STRING) {
			AdItem *item = ((AdGame *)_gameRef)->getItemByName(val->getString());
			if (item) {
				stack->pushNative(item, true);
			} else {
				stack->pushNULL();
			}
		} else if (val->isNULL() || val->getInt() < 0 || val->getInt() >= (int32)_inventory->_takenItems.size()) {
			stack->pushNULL();
		} else {
			stack->pushNative(_inventory->_takenItems[val->getInt()], true);
		}

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// HasItem
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "HasItem") == 0) {
		stack->correctParams(1);

		if (!_inventory) {
			_inventory = new AdInventory(_gameRef);
			((AdGame *)_gameRef)->registerInventory(_inventory);
		}

		ScValue *val = stack->pop();
		if (!val->isNULL()) {
			for (uint32 i = 0; i < _inventory->_takenItems.size(); i++) {
				if (val->getNative() == _inventory->_takenItems[i]) {
					stack->pushBool(true);
					return STATUS_OK;
				} else if (scumm_stricmp(val->getString(), _inventory->_takenItems[i]->getName()) == 0) {
					stack->pushBool(true);
					return STATUS_OK;
				}
			}
		} else {
			script->runtimeError("HasItem: item name expected");
		}

		stack->pushBool(false);
		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// CreateParticleEmitter
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "CreateParticleEmitter") == 0) {
		stack->correctParams(3);
		bool followParent = stack->pop()->getBool();
		int offsetX = stack->pop()->getInt();
		int offsetY = stack->pop()->getInt();

		PartEmitter *emitter = createParticleEmitter(followParent, offsetX, offsetY);
		if (emitter) {
			stack->pushNative(_partEmitter, true);
		} else {
			stack->pushNULL();
		}

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// DeleteParticleEmitter
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "DeleteParticleEmitter") == 0) {
		stack->correctParams(0);
		if (_partEmitter) {
			_gameRef->unregisterObject(_partEmitter);
			_partEmitter = nullptr;
		}
		stack->pushNULL();

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// AddAttachment
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "AddAttachment") == 0) {
		stack->correctParams(4);
		const char *filename = stack->pop()->getString();
		bool preDisplay = stack->pop()->getBool(true);
		int offsetX = stack->pop()->getInt();
		int offsetY = stack->pop()->getInt();

		bool res;
		AdEntity *ent = new AdEntity(_gameRef);
		if (DID_FAIL(res = ent->loadFile(filename))) {
			delete ent;
			ent = nullptr;
			script->runtimeError("AddAttachment() failed loading entity '%s'", filename);
			stack->pushBool(false);
		} else {
			_gameRef->registerObject(ent);

			ent->_posX = offsetX;
			ent->_posY = offsetY;
			ent->_active = true;

			if (preDisplay) {
				_attachmentsPre.add(ent);
			} else {
				_attachmentsPost.add(ent);
			}

			stack->pushBool(true);
		}

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// RemoveAttachment
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "RemoveAttachment") == 0) {
		stack->correctParams(1);
		ScValue *val = stack->pop();
		bool found = false;
		if (val->isNative()) {
			BaseScriptable *obj = val->getNative();
			for (uint32 i = 0; i < _attachmentsPre.size(); i++) {
				if (_attachmentsPre[i] == obj) {
					found = true;
					_gameRef->unregisterObject(_attachmentsPre[i]);
					_attachmentsPre.remove_at(i);
					i--;
				}
			}
			for (uint32 i = 0; i < _attachmentsPost.size(); i++) {
				if (_attachmentsPost[i] == obj) {
					found = true;
					_gameRef->unregisterObject(_attachmentsPost[i]);
					_attachmentsPost.remove_at(i);
					i--;
				}
			}
		} else {
			const char *attachmentName = val->getString();
			for (uint32 i = 0; i < _attachmentsPre.size(); i++) {
				if (_attachmentsPre[i]->getName() && scumm_stricmp(_attachmentsPre[i]->getName(), attachmentName) == 0) {
					found = true;
					_gameRef->unregisterObject(_attachmentsPre[i]);
					_attachmentsPre.remove_at(i);
					i--;
				}
			}
			for (uint32 i = 0; i < _attachmentsPost.size(); i++) {
				if (_attachmentsPost[i]->getName() && scumm_stricmp(_attachmentsPost[i]->getName(), attachmentName) == 0) {
					found = true;
					_gameRef->unregisterObject(_attachmentsPost[i]);
					_attachmentsPost.remove_at(i);
					i--;
				}
			}
		}
		stack->pushBool(found);

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetAttachment
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "GetAttachment") == 0) {
		stack->correctParams(1);
		ScValue *val = stack->pop();

		AdObject *ret = nullptr;
		if (val->isInt()) {
			int index = val->getInt();
			int currIndex = 0;
			for (uint32 i = 0; i < _attachmentsPre.size(); i++) {
				if (currIndex == index) {
					ret = _attachmentsPre[i];
				}
				currIndex++;
			}
			for (uint32 i = 0; i < _attachmentsPost.size(); i++) {
				if (currIndex == index) {
					ret = _attachmentsPost[i];
				}
				currIndex++;
			}
		} else {
			const char *attachmentName = val->getString();
			for (uint32 i = 0; i < _attachmentsPre.size(); i++) {
				if (_attachmentsPre[i]->getName() && scumm_stricmp(_attachmentsPre[i]->getName(), attachmentName) == 0) {
					ret = _attachmentsPre[i];
					break;
				}
			}
			if (!ret) {
				for (uint32 i = 0; i < _attachmentsPost.size(); i++) {
					if (_attachmentsPost[i]->getName() && scumm_stricmp(_attachmentsPost[i]->getName(), attachmentName) == 0) {
						ret = _attachmentsPre[i];
						break;
					}
				}
			}
		}

		if (ret != nullptr) {
			stack->pushNative(ret, true);
		} else {
			stack->pushNULL();
		}

		return STATUS_OK;
	} else {
		return BaseObject::scCallMethod(script, stack, thisStack, name);
	}
}
예제 #13
0
bool SXString::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
	//////////////////////////////////////////////////////////////////////////
	// Substring
	//////////////////////////////////////////////////////////////////////////
	if (strcmp(name, "Substring") == 0) {
		stack->correctParams(2);
		int start = stack->pop()->getInt();
		int end   = stack->pop()->getInt();

		if (end < start) {
			BaseUtils::swap(&start, &end);
		}

		//try {
		WideString str;
		if (_gameRef->_textEncoding == TEXT_UTF8) {
			str = StringUtil::utf8ToWide(_string);
		} else {
			str = StringUtil::ansiToWide(_string);
		}

		//WideString subStr = str.substr(start, end - start + 1);
		WideString subStr(str.c_str() + start, end - start + 1);

		if (_gameRef->_textEncoding == TEXT_UTF8) {
			stack->pushString(StringUtil::wideToUtf8(subStr).c_str());
		} else {
			stack->pushString(StringUtil::wideToAnsi(subStr).c_str());
		}
		//  } catch (std::exception &) {
		//      stack->pushNULL();
		//  }

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// Substr
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "Substr") == 0) {
		stack->correctParams(2);
		int start = stack->pop()->getInt();

		ScValue *val = stack->pop();
		int len = val->getInt();

		if (!val->isNULL() && len <= 0) {
			stack->pushString("");
			return STATUS_OK;
		}

		if (val->isNULL()) {
			len = strlen(_string) - start;
		}

//		try {
		WideString str;
		if (_gameRef->_textEncoding == TEXT_UTF8) {
			str = StringUtil::utf8ToWide(_string);
		} else {
			str = StringUtil::ansiToWide(_string);
		}

//			WideString subStr = str.substr(start, len);
		WideString subStr(str.c_str() + start, len);

		if (_gameRef->_textEncoding == TEXT_UTF8) {
			stack->pushString(StringUtil::wideToUtf8(subStr).c_str());
		} else {
			stack->pushString(StringUtil::wideToAnsi(subStr).c_str());
		}
//		} catch (std::exception &) {
//			stack->pushNULL();
//		}

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// ToUpperCase
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "ToUpperCase") == 0) {
		stack->correctParams(0);

		WideString str;
		if (_gameRef->_textEncoding == TEXT_UTF8) {
			str = StringUtil::utf8ToWide(_string);
		} else {
			str = StringUtil::ansiToWide(_string);
		}

		str.toUppercase();

		if (_gameRef->_textEncoding == TEXT_UTF8) {
			stack->pushString(StringUtil::wideToUtf8(str).c_str());
		} else {
			stack->pushString(StringUtil::wideToAnsi(str).c_str());
		}

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// ToLowerCase
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "ToLowerCase") == 0) {
		stack->correctParams(0);

		WideString str;
		if (_gameRef->_textEncoding == TEXT_UTF8) {
			str = StringUtil::utf8ToWide(_string);
		} else {
			str = StringUtil::ansiToWide(_string);
		}

		str.toLowercase();

		if (_gameRef->_textEncoding == TEXT_UTF8) {
			stack->pushString(StringUtil::wideToUtf8(str).c_str());
		} else {
			stack->pushString(StringUtil::wideToAnsi(str).c_str());
		}

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// IndexOf
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "IndexOf") == 0) {
		stack->correctParams(2);

		const char *strToFind = stack->pop()->getString();
		int index = stack->pop()->getInt();

		WideString str;
		if (_gameRef->_textEncoding == TEXT_UTF8) {
			str = StringUtil::utf8ToWide(_string);
		} else {
			str = StringUtil::ansiToWide(_string);
		}

		WideString toFind;
		if (_gameRef->_textEncoding == TEXT_UTF8) {
			toFind = StringUtil::utf8ToWide(strToFind);
		} else {
			toFind = StringUtil::ansiToWide(strToFind);
		}

		int indexOf = StringUtil::indexOf(str, toFind, index);
		stack->pushInt(indexOf);

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// Split
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "Split") == 0) {
		stack->correctParams(1);
		ScValue *val = stack->pop();
		char separators[MAX_PATH_LENGTH] = ",";
		if (!val->isNULL()) {
			strcpy(separators, val->getString());
		}

		SXArray *array = new SXArray(_gameRef);
		if (!array) {
			stack->pushNULL();
			return STATUS_OK;
		}


		WideString str;
		if (_gameRef->_textEncoding == TEXT_UTF8) {
			str = StringUtil::utf8ToWide(_string);
		} else {
			str = StringUtil::ansiToWide(_string);
		}

		WideString delims;
		if (_gameRef->_textEncoding == TEXT_UTF8) {
			delims = StringUtil::utf8ToWide(separators);
		} else {
			delims = StringUtil::ansiToWide(separators);
		}

		Common::Array<WideString> parts;

		uint32 start = 0;
		for(uint32 i = 0; i < str.size() + 1; i++) {
			char ch = str.c_str()[i];
			if(ch=='\0' || delims.contains(ch))
			{
				char *part = new char[i - start + 1];
				if(i != start) {
					Common::strlcpy(part, str.c_str() + start, i - start + 1);
					part[i - start] = '\0';
				} else {
					part[0] = '\0';
				}
				val = new ScValue(_gameRef, part);
				array->push(val);
				delete[] part;
				delete val;
				val = nullptr;
				start = i + 1;
			}
		}

		for (Common::Array<WideString>::iterator it = parts.begin(); it != parts.end(); ++it) {
			WideString &part = (*it);

			if (_gameRef->_textEncoding == TEXT_UTF8) {
				val = new ScValue(_gameRef,  StringUtil::wideToUtf8(part).c_str());
			} else {
				val = new ScValue(_gameRef,  StringUtil::wideToAnsi(part).c_str());
			}

			array->push(val);
			delete val;
			val = nullptr;
		}

		stack->pushNative(array, false);
		return STATUS_OK;
	} else {
		return STATUS_FAILED;
	}
}
예제 #14
0
//////////////////////////////////////////////////////////////////////////
// high level scripting interface
//////////////////////////////////////////////////////////////////////////
bool UIObject::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
	//////////////////////////////////////////////////////////////////////////
	// SetFont
	//////////////////////////////////////////////////////////////////////////
	if (strcmp(name, "SetFont") == 0) {
		stack->correctParams(1);
		ScValue *val = stack->pop();

		if (_font) {
			_gameRef->_fontStorage->removeFont(_font);
		}
		if (val->isNULL()) {
			_font = nullptr;
			stack->pushBool(true);
		} else {
			_font = _gameRef->_fontStorage->addFont(val->getString());
			stack->pushBool(_font != nullptr);
		}
		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SetImage
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "SetImage") == 0) {
		stack->correctParams(1);
		ScValue *val = stack->pop();

		/* const char *filename = */ val->getString();

		delete _image;
		_image = nullptr;
		if (val->isNULL()) {
			stack->pushBool(true);
			return STATUS_OK;
		}

		_image = new BaseSprite(_gameRef);
		if (!_image || DID_FAIL(_image->loadFile(val->getString()))) {
			delete _image;
			_image = nullptr;
			stack->pushBool(false);
		} else {
			stack->pushBool(true);
		}

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetImage
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "GetImage") == 0) {
		stack->correctParams(0);
		if (!_image || !_image->getFilename()) {
			stack->pushNULL();
		} else {
			stack->pushString(_image->getFilename());
		}

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetImageObject
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "GetImageObject") == 0) {
		stack->correctParams(0);
		if (!_image) {
			stack->pushNULL();
		} else {
			stack->pushNative(_image, true);
		}

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// Focus
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "Focus") == 0) {
		stack->correctParams(0);
		focus();
		stack->pushNULL();
		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// MoveAfter / MoveBefore
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "MoveAfter") == 0 || strcmp(name, "MoveBefore") == 0) {
		stack->correctParams(1);

		if (_parent && _parent->_type == UI_WINDOW) {
			UIWindow *win = (UIWindow *)_parent;

			uint32 i;
			bool found = false;
			ScValue *val = stack->pop();
			// find directly
			if (val->isNative()) {
				UIObject *widget = (UIObject *)val->getNative();
				for (i = 0; i < win->_widgets.size(); i++) {
					if (win->_widgets[i] == widget) {
						found = true;
						break;
					}
				}
			}
			// find by name
			else {
				const char *findName = val->getString();
				for (i = 0; i < win->_widgets.size(); i++) {
					if (scumm_stricmp(win->_widgets[i]->getName(), findName) == 0) {
						found = true;
						break;
					}
				}
			}

			if (found) {
				bool done = false;
				for (uint32 j = 0; j < win->_widgets.size(); j++) {
					if (win->_widgets[j] == this) {
						if (strcmp(name, "MoveAfter") == 0) {
							i++;
						}
						if (j >= i) {
							j++;
						}

						win->_widgets.insert_at(i, this);
						win->_widgets.remove_at(j);

						done = true;
						stack->pushBool(true);
						break;
					}
				}
				if (!done) {
					stack->pushBool(false);
				}
			} else {
				stack->pushBool(false);
			}

		} else {
			stack->pushBool(false);
		}

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// MoveToBottom
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "MoveToBottom") == 0) {
		stack->correctParams(0);

		if (_parent && _parent->_type == UI_WINDOW) {
			UIWindow *win = (UIWindow *)_parent;
			for (uint32 i = 0; i < win->_widgets.size(); i++) {
				if (win->_widgets[i] == this) {
					win->_widgets.remove_at(i);
					win->_widgets.insert_at(0, this);
					break;
				}
			}
			stack->pushBool(true);
		} else {
			stack->pushBool(false);
		}

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// MoveToTop
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "MoveToTop") == 0) {
		stack->correctParams(0);

		if (_parent && _parent->_type == UI_WINDOW) {
			UIWindow *win = (UIWindow *)_parent;
			for (uint32 i = 0; i < win->_widgets.size(); i++) {
				if (win->_widgets[i] == this) {
					win->_widgets.remove_at(i);
					win->_widgets.add(this);
					break;
				}
			}
			stack->pushBool(true);
		} else {
			stack->pushBool(false);
		}

		return STATUS_OK;
	} else {
		return BaseObject::scCallMethod(script, stack, thisStack, name);
	}
}
예제 #15
0
//////////////////////////////////////////////////////////////////////////
// high level scripting interface
//////////////////////////////////////////////////////////////////////////
bool AdTalkHolder::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
	//////////////////////////////////////////////////////////////////////////
	// SetSprite
	//////////////////////////////////////////////////////////////////////////
	if (strcmp(name, "SetSprite") == 0) {
		stack->correctParams(1);

		ScValue *val = stack->pop();

		bool setCurrent = false;
		if (_currentSprite && _currentSprite == _sprite) {
			setCurrent = true;
		}

		delete _sprite;
		_sprite = nullptr;

		if (val->isNULL()) {
			_sprite = nullptr;
			if (setCurrent) {
				_currentSprite = nullptr;
			}
			stack->pushBool(true);
		} else {
			const char *filename = val->getString();
			BaseSprite *spr = new BaseSprite(_gameRef, this);
			if (!spr || DID_FAIL(spr->loadFile(filename))) {
				script->runtimeError("SetSprite method failed for file '%s'", filename);
				stack->pushBool(false);
			} else {
				_sprite = spr;
				if (setCurrent) {
					_currentSprite = _sprite;
				}
				stack->pushBool(true);
			}
		}
		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetSprite
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "GetSprite") == 0) {
		stack->correctParams(0);

		if (!_sprite || !_sprite->getFilename()) {
			stack->pushNULL();
		} else {
			stack->pushString(_sprite->getFilename());
		}
		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetSpriteObject
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "GetSpriteObject") == 0) {
		stack->correctParams(0);

		if (!_sprite) {
			stack->pushNULL();
		} else {
			stack->pushNative(_sprite, true);
		}
		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// AddTalkSprite
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "AddTalkSprite") == 0) {
		stack->correctParams(2);

		const char *filename = stack->pop()->getString();
		bool ex = stack->pop()->getBool();

		BaseSprite *spr = new BaseSprite(_gameRef, this);
		if (!spr || DID_FAIL(spr->loadFile(filename))) {
			stack->pushBool(false);
			script->runtimeError("AddTalkSprite method failed for file '%s'", filename);
		} else {
			if (ex) {
				_talkSpritesEx.add(spr);
			} else {
				_talkSprites.add(spr);
			}
			stack->pushBool(true);
		}
		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// RemoveTalkSprite
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "RemoveTalkSprite") == 0) {
		stack->correctParams(2);

		const char *filename = stack->pop()->getString();
		bool ex = stack->pop()->getBool();

		bool setCurrent = false;
		bool setTemp2 = false;

		if (ex) {
			for (uint32 i = 0; i < _talkSpritesEx.size(); i++) {
				if (scumm_stricmp(_talkSpritesEx[i]->getFilename(), filename) == 0) {
					if (_currentSprite == _talkSpritesEx[i]) {
						setCurrent = true;
					}
					if (_tempSprite2 == _talkSpritesEx[i]) {
						setTemp2 = true;
					}
					delete _talkSpritesEx[i];
					_talkSpritesEx.remove_at(i);
					break;
				}
			}
		} else {
			for (uint32 i = 0; i < _talkSprites.size(); i++) {
				if (scumm_stricmp(_talkSprites[i]->getFilename(), filename) == 0) {
					if (_currentSprite == _talkSprites[i]) {
						setCurrent = true;
					}
					if (_tempSprite2 == _talkSprites[i]) {
						setTemp2 = true;
					}
					delete _talkSprites[i];
					_talkSprites.remove_at(i);
					break;
				}
			}

		}

		stack->pushBool(true);
		if (setCurrent) {
			_currentSprite = _sprite;
		}
		if (setTemp2) {
			_tempSprite2 = _sprite;
		}

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SetTalkSprite
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "SetTalkSprite") == 0) {
		stack->correctParams(2);

		const char *filename = stack->pop()->getString();
		bool ex = stack->pop()->getBool();
		bool setCurrent = false;
		bool setTemp2 = false;

		BaseSprite *spr = new BaseSprite(_gameRef, this);
		if (!spr || DID_FAIL(spr->loadFile(filename))) {
			stack->pushBool(false);
			script->runtimeError("SetTalkSprite method failed for file '%s'", filename);
		} else {

			// delete current
			if (ex) {
				for (uint32 i = 0; i < _talkSpritesEx.size(); i++) {
					if (_talkSpritesEx[i] == _currentSprite) {
						setCurrent = true;
					}
					if (_talkSpritesEx[i] == _tempSprite2) {
						setTemp2 = true;
					}
					delete _talkSpritesEx[i];
				}
				_talkSpritesEx.clear();
			} else {
				for (uint32 i = 0; i < _talkSprites.size(); i++) {
					if (_talkSprites[i] == _currentSprite) {
						setCurrent = true;
					}
					if (_talkSprites[i] == _tempSprite2) {
						setTemp2 = true;
					}
					delete _talkSprites[i];
				}
				_talkSprites.clear();
			}

			// set new
			if (ex) {
				_talkSpritesEx.add(spr);
			} else {
				_talkSprites.add(spr);
			}
			stack->pushBool(true);

			if (setCurrent) {
				_currentSprite = spr;
			}
			if (setTemp2) {
				_tempSprite2 = spr;
			}
		}
		return STATUS_OK;
	} else {
		return AdObject::scCallMethod(script, stack, thisStack, name);
	}
}
예제 #16
0
//////////////////////////////////////////////////////////////////////////
// high level scripting interface
//////////////////////////////////////////////////////////////////////////
bool UIButton::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
	//////////////////////////////////////////////////////////////////////////
	// SetDisabledFont
	//////////////////////////////////////////////////////////////////////////
	if (strcmp(name, "SetDisabledFont") == 0) {
		stack->correctParams(1);
		ScValue *val = stack->pop();

		if (_fontDisable) {
			_gameRef->_fontStorage->removeFont(_fontDisable);
		}
		if (val->isNULL()) {
			_fontDisable = nullptr;
			stack->pushBool(true);
		} else {
			_fontDisable = _gameRef->_fontStorage->addFont(val->getString());
			stack->pushBool(_fontDisable != nullptr);
		}
		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SetHoverFont
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "SetHoverFont") == 0) {
		stack->correctParams(1);
		ScValue *val = stack->pop();

		if (_fontHover) {
			_gameRef->_fontStorage->removeFont(_fontHover);
		}
		if (val->isNULL()) {
			_fontHover = nullptr;
			stack->pushBool(true);
		} else {
			_fontHover = _gameRef->_fontStorage->addFont(val->getString());
			stack->pushBool(_fontHover != nullptr);
		}
		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SetPressedFont
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "SetPressedFont") == 0) {
		stack->correctParams(1);
		ScValue *val = stack->pop();

		if (_fontPress) {
			_gameRef->_fontStorage->removeFont(_fontPress);
		}
		if (val->isNULL()) {
			_fontPress = nullptr;
			stack->pushBool(true);
		} else {
			_fontPress = _gameRef->_fontStorage->addFont(val->getString());
			stack->pushBool(_fontPress != nullptr);
		}
		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SetFocusedFont
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "SetFocusedFont") == 0) {
		stack->correctParams(1);
		ScValue *val = stack->pop();

		if (_fontFocus) {
			_gameRef->_fontStorage->removeFont(_fontFocus);
		}
		if (val->isNULL()) {
			_fontFocus = nullptr;
			stack->pushBool(true);
		} else {
			_fontFocus = _gameRef->_fontStorage->addFont(val->getString());
			stack->pushBool(_fontFocus != nullptr);
		}
		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SetDisabledImage
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "SetDisabledImage") == 0) {
		stack->correctParams(1);

		delete _imageDisable;
		_imageDisable = new BaseSprite(_gameRef);
		const char *filename = stack->pop()->getString();
		if (!_imageDisable || DID_FAIL(_imageDisable->loadFile(filename))) {
			delete _imageDisable;
			_imageDisable = nullptr;
			stack->pushBool(false);
		} else {
			stack->pushBool(true);
		}

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetDisabledImage
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "GetDisabledImage") == 0) {
		stack->correctParams(0);
		if (!_imageDisable || !_imageDisable->getFilename()) {
			stack->pushNULL();
		} else {
			stack->pushString(_imageDisable->getFilename());
		}

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetDisabledImageObject
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "GetDisabledImageObject") == 0) {
		stack->correctParams(0);
		if (!_imageDisable) {
			stack->pushNULL();
		} else {
			stack->pushNative(_imageDisable, true);
		}

		return STATUS_OK;
	}


	//////////////////////////////////////////////////////////////////////////
	// SetHoverImage
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "SetHoverImage") == 0) {
		stack->correctParams(1);

		delete _imageHover;
		_imageHover = new BaseSprite(_gameRef);
		const char *filename = stack->pop()->getString();
		if (!_imageHover || DID_FAIL(_imageHover->loadFile(filename))) {
			delete _imageHover;
			_imageHover = nullptr;
			stack->pushBool(false);
		} else {
			stack->pushBool(true);
		}

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetHoverImage
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "GetHoverImage") == 0) {
		stack->correctParams(0);
		if (!_imageHover || !_imageHover->getFilename()) {
			stack->pushNULL();
		} else {
			stack->pushString(_imageHover->getFilename());
		}

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetHoverImageObject
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "GetHoverImageObject") == 0) {
		stack->correctParams(0);
		if (!_imageHover) {
			stack->pushNULL();
		} else {
			stack->pushNative(_imageHover, true);
		}

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SetPressedImage
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "SetPressedImage") == 0) {
		stack->correctParams(1);

		delete _imagePress;
		_imagePress = new BaseSprite(_gameRef);
		const char *filename = stack->pop()->getString();
		if (!_imagePress || DID_FAIL(_imagePress->loadFile(filename))) {
			delete _imagePress;
			_imagePress = nullptr;
			stack->pushBool(false);
		} else {
			stack->pushBool(true);
		}

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetPressedImage
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "GetPressedImage") == 0) {
		stack->correctParams(0);
		if (!_imagePress || !_imagePress->getFilename()) {
			stack->pushNULL();
		} else {
			stack->pushString(_imagePress->getFilename());
		}

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetPressedImageObject
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "GetPressedImageObject") == 0) {
		stack->correctParams(0);
		if (!_imagePress) {
			stack->pushNULL();
		} else {
			stack->pushNative(_imagePress, true);
		}

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SetFocusedImage
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "SetFocusedImage") == 0) {
		stack->correctParams(1);

		delete _imageFocus;
		_imageFocus = new BaseSprite(_gameRef);
		const char *filename = stack->pop()->getString();
		if (!_imageFocus || DID_FAIL(_imageFocus->loadFile(filename))) {
			delete _imageFocus;
			_imageFocus = nullptr;
			stack->pushBool(false);
		} else {
			stack->pushBool(true);
		}

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetFocusedImage
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "GetFocusedImage") == 0) {
		stack->correctParams(0);
		if (!_imageFocus || !_imageFocus->getFilename()) {
			stack->pushNULL();
		} else {
			stack->pushString(_imageFocus->getFilename());
		}

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetFocusedImageObject
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "GetFocusedImageObject") == 0) {
		stack->correctParams(0);
		if (!_imageFocus) {
			stack->pushNULL();
		} else {
			stack->pushNative(_imageFocus, true);
		}

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// Press
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "Press") == 0) {
		stack->correctParams(0);

		if (_visible && !_disable) {
			_oneTimePress = true;
			_oneTimePressTime = g_system->getMillis();
		}
		stack->pushNULL();

		return STATUS_OK;
	} else {
		return UIObject::scCallMethod(script, stack, thisStack, name);
	}
}
예제 #17
0
//////////////////////////////////////////////////////////////////////////
// high level scripting interface
//////////////////////////////////////////////////////////////////////////
bool BaseScriptHolder::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
	//////////////////////////////////////////////////////////////////////////
	// DEBUG_CrashMe
	//////////////////////////////////////////////////////////////////////////
	if (strcmp(name, "DEBUG_CrashMe") == 0) {
		stack->correctParams(0);
		byte *p = 0;
		*p = 10;
		stack->pushNULL();

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// ApplyEvent
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "ApplyEvent") == 0) {
		stack->correctParams(1);
		ScValue *val = stack->pop();
		bool ret;
		ret = applyEvent(val->getString());

		if (DID_SUCCEED(ret)) {
			stack->pushBool(true);
		} else {
			stack->pushBool(false);
		}

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// CanHandleEvent
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "CanHandleEvent") == 0) {
		stack->correctParams(1);
		stack->pushBool(canHandleEvent(stack->pop()->getString()));

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// CanHandleMethod
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "CanHandleMethod") == 0) {
		stack->correctParams(1);
		stack->pushBool(canHandleMethod(stack->pop()->getString()));

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// AttachScript
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "AttachScript") == 0) {
		stack->correctParams(1);
		stack->pushBool(DID_SUCCEED(addScript(stack->pop()->getString())));

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// DetachScript
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "DetachScript") == 0) {
		stack->correctParams(2);
		const char *filename = stack->pop()->getString();
		bool killThreads = stack->pop()->getBool(false);
		bool ret = false;
		for (uint32 i = 0; i < _scripts.size(); i++) {
			if (scumm_stricmp(_scripts[i]->_filename, filename) == 0) {
				_scripts[i]->finish(killThreads);
				ret = true;
				break;
			}
		}
		stack->pushBool(ret);

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// IsScriptRunning
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "IsScriptRunning") == 0) {
		stack->correctParams(1);
		const char *filename = stack->pop()->getString();
		bool ret = false;
		for (uint32 i = 0; i < _scripts.size(); i++) {
			if (scumm_stricmp(_scripts[i]->_filename, filename) == 0 && _scripts[i]->_state != SCRIPT_FINISHED && _scripts[i]->_state != SCRIPT_ERROR) {
				ret = true;
				break;
			}
		}
		stack->pushBool(ret);

		return STATUS_OK;
	} else {
		return BaseScriptable::scCallMethod(script, stack, thisStack, name);
	}
}
예제 #18
0
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
bool BaseScriptHolder::parseProperty(byte *buffer, bool complete) {
	TOKEN_TABLE_START(commands)
	TOKEN_TABLE(PROPERTY)
	TOKEN_TABLE(NAME)
	TOKEN_TABLE(VALUE)
	TOKEN_TABLE_END

	byte *params;
	int cmd;
	BaseParser parser;

	if (complete) {
		if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_PROPERTY) {
			_gameRef->LOG(0, "'PROPERTY' keyword expected.");
			return STATUS_FAILED;
		}
		buffer = params;
	}

	char *propName = NULL;
	char *propValue = NULL;

	while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
		switch (cmd) {
		case TOKEN_NAME:
			delete[] propName;
			propName = new char[strlen((char *)params) + 1];
			if (propName) {
				strcpy(propName, (char *)params);
			} else {
				cmd = PARSERR_GENERIC;
			}
			break;

		case TOKEN_VALUE:
			delete[] propValue;
			propValue = new char[strlen((char *)params) + 1];
			if (propValue) {
				strcpy(propValue, (char *)params);
			} else {
				cmd = PARSERR_GENERIC;
			}
			break;
		}

	}
	if (cmd == PARSERR_TOKENNOTFOUND) {
		delete[] propName;
		delete[] propValue;
		propName = NULL;
		propValue = NULL;
		_gameRef->LOG(0, "Syntax error in PROPERTY definition");
		return STATUS_FAILED;
	}
	if (cmd == PARSERR_GENERIC || propName == NULL || propValue == NULL) {
		delete[] propName;
		delete[] propValue;
		propName = NULL;
		propValue = NULL;
		_gameRef->LOG(0, "Error loading PROPERTY definition");
		return STATUS_FAILED;
	}


	ScValue *val = new ScValue(_gameRef);
	val->setString(propValue);
	scSetProperty(propName, val);

	delete val;
	delete[] propName;
	delete[] propValue;
	propName = NULL;
	propValue = NULL;

	return STATUS_OK;
}
예제 #19
0
//////////////////////////////////////////////////////////////////////////
// high level scripting interface
//////////////////////////////////////////////////////////////////////////
bool BaseRegion::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {

	//////////////////////////////////////////////////////////////////////////
	// AddPoint
	//////////////////////////////////////////////////////////////////////////
	if (strcmp(name, "AddPoint") == 0) {
		stack->correctParams(2);
		int x = stack->pop()->getInt();
		int y = stack->pop()->getInt();

		_points.add(new BasePoint(x, y));
		createRegion();

		stack->pushBool(true);

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// InsertPoint
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "InsertPoint") == 0) {
		stack->correctParams(3);
		int index = stack->pop()->getInt();
		int x = stack->pop()->getInt();
		int y = stack->pop()->getInt();

		if (index >= 0 && index < (int32)_points.size()) {
			_points.insert_at(index, new BasePoint(x, y));
			createRegion();

			stack->pushBool(true);
		} else {
			stack->pushBool(false);
		}

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SetPoint
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "SetPoint") == 0) {
		stack->correctParams(3);
		int index = stack->pop()->getInt();
		int x = stack->pop()->getInt();
		int y = stack->pop()->getInt();

		if (index >= 0 && index < (int32)_points.size()) {
			_points[index]->x = x;
			_points[index]->y = y;
			createRegion();

			stack->pushBool(true);
		} else {
			stack->pushBool(false);
		}

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// RemovePoint
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "RemovePoint") == 0) {
		stack->correctParams(1);
		int index = stack->pop()->getInt();

		if (index >= 0 && index < (int32)_points.size()) {
			delete _points[index];
			_points[index] = nullptr;

			_points.remove_at(index);
			createRegion();

			stack->pushBool(true);
		} else {
			stack->pushBool(false);
		}

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetPoint
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "GetPoint") == 0) {
		stack->correctParams(1);
		int index = stack->pop()->getInt();

		if (index >= 0 && index < (int32)_points.size()) {
			ScValue *val = stack->getPushValue();
			if (val) {
				val->setProperty("X", _points[index]->x);
				val->setProperty("Y", _points[index]->y);
			}
		} else {
			stack->pushNULL();
		}

		return STATUS_OK;
	} else {
		return BaseObject::scCallMethod(script, stack, thisStack, name);
	}
}
예제 #20
0
//////////////////////////////////////////////////////////////////////////
// high level scripting interface
//////////////////////////////////////////////////////////////////////////
bool AdEntity::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
	//////////////////////////////////////////////////////////////////////////
	// StopSound
	//////////////////////////////////////////////////////////////////////////
	if (strcmp(name, "StopSound") == 0 && _subtype == ENTITY_SOUND) {
		stack->correctParams(0);

		if (DID_FAIL(stopSFX(false))) {
			stack->pushBool(false);
		} else {
			stack->pushBool(true);
		}
		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// PlayTheora
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "PlayTheora") == 0) {
		stack->correctParams(4);
		const char *filename = stack->pop()->getString();
		bool looping = stack->pop()->getBool(false);
		ScValue *valAlpha = stack->pop();
		int startTime = stack->pop()->getInt();

		delete _theora;
		_theora = new VideoTheoraPlayer(_gameRef);
		if (_theora && DID_SUCCEED(_theora->initialize(filename))) {
			if (!valAlpha->isNULL()) {
				_theora->setAlphaImage(valAlpha->getString());
			}
			_theora->play(VID_PLAY_POS, 0, 0, false, false, looping, startTime, _scale >= 0.0f ? _scale : -1.0f, _sFXVolume);
			//if (_scale>=0) _theora->_playZoom = _scale;
			stack->pushBool(true);
		} else {
			script->runtimeError("Entity.PlayTheora - error playing video '%s'", filename);
			stack->pushBool(false);
		}

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// StopTheora
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "StopTheora") == 0) {
		stack->correctParams(0);
		if (_theora) {
			_theora->stop();
			delete _theora;
			_theora = nullptr;
			stack->pushBool(true);
		} else {
			stack->pushBool(false);
		}

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// IsTheoraPlaying
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "IsTheoraPlaying") == 0) {
		stack->correctParams(0);
		if (_theora && _theora->isPlaying()) {
			stack->pushBool(true);
		} else {
			stack->pushBool(false);
		}

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// PauseTheora
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "PauseTheora") == 0) {
		stack->correctParams(0);
		if (_theora && _theora->isPlaying()) {
			_theora->pause();
			stack->pushBool(true);
		} else {
			stack->pushBool(false);
		}

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// ResumeTheora
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "ResumeTheora") == 0) {
		stack->correctParams(0);
		if (_theora && _theora->isPaused()) {
			_theora->resume();
			stack->pushBool(true);
		} else {
			stack->pushBool(false);
		}

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// IsTheoraPaused
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "IsTheoraPaused") == 0) {
		stack->correctParams(0);
		if (_theora && _theora->isPaused()) {
			stack->pushBool(true);
		} else {
			stack->pushBool(false);
		}

		return STATUS_OK;
	}


	//////////////////////////////////////////////////////////////////////////
	// CreateRegion
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "CreateRegion") == 0) {
		stack->correctParams(0);
		if (!_region) {
			_region = new BaseRegion(_gameRef);
			_gameRef->registerObject(_region);
		}
		if (_region) {
			stack->pushNative(_region, true);
		} else {
			stack->pushNULL();
		}

		return STATUS_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// DeleteRegion
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(name, "DeleteRegion") == 0) {
		stack->correctParams(0);
		if (_region) {
			_gameRef->unregisterObject(_region);
			_region = nullptr;
			stack->pushBool(true);
		} else {
			stack->pushBool(false);
		}

		return STATUS_OK;
	} else {
		return AdTalkHolder::scCallMethod(script, stack, thisStack, name);
	}
}