bool LuaScriptContext::ExecuteString(const char* string)
{
	//lua_pushcfunction(L, LuaErrorHandlerCallback);
	luaL_loadstring(L, string);

	return LuaCall(0, LUA_MULTRET);
}
Example #2
0
/**
**  Call a Lua handler
*/
void CallHandler(unsigned int handle, int value)
{
	lua_getglobal(Lua, "_handlers_");
	lua_rawgeti(Lua, -1, handle);
	lua_pushnumber(Lua, value);
	LuaCall(1, 1);
	lua_pop(Lua, 1);
}
Example #3
0
static PyObject *Lua_require(PyObject *self, PyObject *args)
{
    lua_getglobal(LuaState, "require");
    if (lua_isnil(LuaState, -1)) {
        lua_pop(LuaState, 1);
        PyErr_SetString(PyExc_RuntimeError, "require is not defined");
        return NULL;
    }
    return LuaCall(LuaState, args);
}
Example #4
0
/**
**  Send command to ccl.
**
**  @param command      Zero terminated command string.
**  @param exitOnError  Exit if an error occurs.
*/
int CclCommand(const std::string &command, bool exitOnError)
{
	int status;

	if (!(status = luaL_loadbuffer(Lua, command.c_str(), command.size(), command.c_str()))) {
		LuaCall(0, 1, exitOnError);
	} else {
		report(status, exitOnError);
	}
	return status;
}
Example #5
0
static PyObject *Lua_require(PyObject *self, PyObject *args)
{
	lua_pushliteral(L, "require");
	lua_rawget(L, LUA_GLOBALSINDEX);
	if (lua_isnil(L, -1)) {
		lua_pop(L, 1);
		PyErr_SetString(PyExc_RuntimeError, "require is not defined");
		return NULL;
	}
	return LuaCall(L, args);
}
Example #6
0
/**
**  Execute the AI Script.
*/
static void AiExecuteScript()
{
	if (AiPlayer->Script.empty()) {
		return;
	}
	lua_getglobal(Lua, "_ai_scripts_");
	lua_pushstring(Lua, AiPlayer->Script.c_str());
	lua_rawget(Lua, -2);
	LuaCall(0, 1);
	lua_pop(Lua, 1);
}
Example #7
0
/**
**  Initialize the trigger module.
*/
void InitTriggers()
{
	// Setup default triggers

	// FIXME: choose the triggers for game type

	lua_getglobal(Lua, "_triggers_");
	if (lua_isnil(Lua, -1)) {
		lua_getglobal(Lua, "SinglePlayerTriggers");
		LuaCall(0, 1);
	}
	lua_pop(Lua, 1);
}
Example #8
0
/**
**  Handle cheats
**
**  @return  1 if a cheat was handled, 0 otherwise
*/
int HandleCheats(const std::string &input)
{
	int ret;

#if defined(DEBUG) || defined(PROF)
	if (input == "ai me") {
		if (ThisPlayer->AiEnabled) {
			// FIXME: UnitGoesUnderFog and UnitGoesOutOfFog change unit refs
			// for human players.  We can't switch back to a human player or
			// we'll be using the wrong ref counts.
#if 0
			ThisPlayer->AiEnabled = false;
			ThisPlayer->Type = PlayerPerson;
			SetMessage("AI is off, Normal Player");
#else
			SetMessage("Cannot disable 'ai me' cheat");
#endif
		} else {
			ThisPlayer->AiEnabled = true;
			ThisPlayer->Type = PlayerComputer;
			if (!ThisPlayer->Ai) {
				AiInit(*ThisPlayer);
			}
			SetMessage("I'm the BORG, resistance is futile!");
		}
		return 1;
	}
#endif
	int base = lua_gettop(Lua);
	lua_getglobal(Lua, "HandleCheats");
	if (!lua_isfunction(Lua, -1)) {
		DebugPrint("No HandleCheats function in lua.\n");
		return 0;
	}
	lua_pushstring(Lua, input.c_str());
	LuaCall(1, 0, false);
	if (lua_gettop(Lua) - base == 1) {
		ret = LuaToBoolean(Lua, -1);
		lua_pop(Lua, 1);
	} else {
		DebugPrint("HandleCheats must return a boolean");
		ret = 0;
	}
	return ret;
}
Example #9
0
/**
**  Execute a Lua function of the AI type.
*/
static void AiExecuteFunction(const char *field)
{
	if (AiPlayer->AiType != NULL)
	{
		lua_getfield(Lua, LUA_GLOBALSINDEX, "AiTypes");
		lua_getfield(Lua, -1, AiPlayer->AiType->Name.c_str());
		lua_getfield(Lua, -1, field);
		if (!lua_isnil(Lua, -1))
		{
			LuaCall(0, 1);	// removes the function from the stack
			lua_pop(Lua, 2); // remove the tables too
		}
		else
		{
			lua_pop(Lua, 3);
		}
	}
}
Example #10
0
/**
**  Check if music is finished and play the next song
*/
void CheckMusicFinished(bool force)
{
	bool proceed;

	SDL_LockMutex(MusicFinishedMutex);
	proceed = MusicFinished;
	MusicFinished = false;
	SDL_UnlockMutex(MusicFinishedMutex);

	if ((proceed || force) && SoundEnabled() && IsMusicEnabled() && CallbackMusic) {
		lua_getglobal(Lua, "MusicStopped");
		if (!lua_isfunction(Lua, -1)) {
			fprintf(stderr, "No MusicStopped function in Lua\n");
			StopMusic();
		} else {
			LuaCall(0, 1);
		}
	}
}
Example #11
0
/**
**  Check trigger each game cycle.
*/
void TriggersEachCycle()
{
	const int base = lua_gettop(Lua);

	lua_getglobal(Lua, "_triggers_");
	int triggers = lua_rawlen(Lua, -1);

	if (Trigger >= triggers) {
		Trigger = 0;
	}

	if (GamePaused) {
		lua_pop(Lua, 1);
		return;
	}

	// Skip to the next trigger
	while (Trigger < triggers) {
		lua_rawgeti(Lua, -1, Trigger + 1);
		if (!lua_isnumber(Lua, -1)) {
			break;
		}
		lua_pop(Lua, 1);
		Trigger += 2;
	}
	if (Trigger < triggers) {
		int currentTrigger = Trigger;
		Trigger += 2;
		LuaCall(0, 0);
		// If condition is true execute action
		if (lua_gettop(Lua) > base + 1 && lua_toboolean(Lua, -1)) {
			lua_settop(Lua, base + 1);
			if (TriggerExecuteAction(currentTrigger + 1)) {
				TriggerRemoveTrigger(currentTrigger);
			}
		}
		lua_settop(Lua, base + 1);
	}
	lua_pop(Lua, 1);
}
Example #12
0
/**
**  Execute a trigger action
**
**  @param script  Script to execute
**
**  @return        1 if the trigger should be removed
*/
static int TriggerExecuteAction(int script)
{
	const int base = lua_gettop(Lua);
	int ret = 0;

	lua_rawgeti(Lua, -1, script + 1);
	const int args = lua_rawlen(Lua, -1);
	for (int j = 0; j < args; ++j) {
		lua_rawgeti(Lua, -1, j + 1);
		LuaCall(0, 0);
		if (lua_gettop(Lua) > base + 1 && lua_toboolean(Lua, -1)) {
			ret = 1;
		} else {
			ret = 0;
		}
		lua_settop(Lua, base + 1);
	}
	lua_pop(Lua, 1);

	// If action returns false remove it
	return !ret;
}
Example #13
0
/**
**  Call the lua function HandleCommandKey
*/
bool HandleCommandKey(int key)
{
	int base = lua_gettop(Lua);

	lua_getglobal(Lua, "HandleCommandKey");
	if (!lua_isfunction(Lua, -1)) {
		DebugPrint("No HandleCommandKey function in lua.\n");
		return false;
	}
	lua_pushstring(Lua, SdlKey2Str(key));
	lua_pushboolean(Lua, (KeyModifiers & ModifierControl));
	lua_pushboolean(Lua, (KeyModifiers & ModifierAlt));
	lua_pushboolean(Lua, (KeyModifiers & ModifierShift));
	LuaCall(4, 0);
	if (lua_gettop(Lua) - base == 1) {
		bool ret = LuaToBoolean(Lua, base + 1);
		lua_pop(Lua, 1);
		return ret;
	} else {
		LuaError(Lua, "HandleCommandKey must return a boolean");
		return false;
	}
}
Example #14
0
/**
**  Load a file and execute it
**
**  @param file  File to load and execute
**
**  @return      0 for success, else exit.
*/
int LuaLoadFile(const std::string &file)
{
	int status;
	std::string PreviousLuaFile;
	std::string buf;

	PreviousLuaFile = CurrentLuaFile;
	CurrentLuaFile = file;

	LuaLoadBuffer(file, buf);
	if (buf.empty()) {
		return -1;
	}

	if (!(status = luaL_loadbuffer(Lua, buf.c_str(), buf.size(), file.c_str()))) {
		LuaCall(0, 1);
	} else {
		report(status, true);
	}
	CurrentLuaFile = PreviousLuaFile;

	return status;
}
//Returns -1 if this thread is dead and needs to be killed
int CCobThread::Tick(int deltaTime)
{
	if (state == Sleep) {
		logOutput.Print("CobError: sleeping thread ticked!");
	}
	if (state == Dead || !owner) {
		return -1;
	}

	state = Run;
	GCobEngine.SetCurThread(this);

	int r1, r2, r3, r4, r5, r6;
	vector<int> args;
	CCobThread *thread;

	execTrace.clear();
	delayedAnims.clear();
	//list<int>::iterator ei;
	vector<int>::iterator ei;

#if COB_DEBUG > 0
	if (COB_DEBUG_FILTER)
		logOutput.Print("Executing in %s (from %s)", script.scriptNames[callStack.back().functionId].c_str(), GetName().c_str());
#endif

	while (state == Run) {
		//int opcode = *(int *)&script.code[PC];

		//Disabling exec trace gives about a 50% speedup on vm-intensive code
		//execTrace.push_back(PC);

		int opcode = GET_LONG_PC();

#if COB_DEBUG > 1
		if (COB_DEBUG_FILTER)
			logOutput.Print("PC: %x opcode: %x (%s)", PC - 1, opcode, GetOpcodeName(opcode).c_str());
#endif

		switch(opcode) {
			case PUSH_CONSTANT:
				r1 = GET_LONG_PC();
				stack.push_back(r1);
				break;
			case SLEEP:
				r1 = POP();
				wakeTime = GCurrentTime + r1;
				state = Sleep;
				GCobEngine.AddThread(this);
				GCobEngine.SetCurThread(NULL);

#if COB_DEBUG > 0
				if (COB_DEBUG_FILTER)
					logOutput.Print("%s sleeping for %d ms", script.scriptNames[callStack.back().functionId].c_str(), r1);
#endif
				return 0;
			case SPIN:
				r1 = GET_LONG_PC();
				r2 = GET_LONG_PC();
				r3 = POP();				//speed
				r4 = POP();				//accel
				owner->Spin(r1, r2, r3, r4);
				break;
			case STOP_SPIN:
				r1 = GET_LONG_PC();
				r2 = GET_LONG_PC();
				r3 = POP();				//decel
				//logOutput.Print("Stop spin of %s around %d", script.pieceNames[r1].c_str(), r2);
				owner->StopSpin(r1, r2, r3);
				break;
			case RETURN:
				retCode = POP();
				if (callStack.back().returnAddr == -1) {

#if COB_DEBUG > 0
					if (COB_DEBUG_FILTER)
						logOutput.Print("%s returned %d", script.scriptNames[callStack.back().functionId].c_str(), retCode);
#endif

					state = Dead;
					GCobEngine.SetCurThread(NULL);
					//callStack.pop_back();
					//Leave values intact on stack in case caller wants to check them
					return -1;
				}

				PC = callStack.back().returnAddr;
				while (stack.size() > callStack.back().stackTop) {
					stack.pop_back();
				}
				callStack.pop_back();

#if COB_DEBUG > 0
				if (COB_DEBUG_FILTER)
					logOutput.Print("Returning to %s", script.scriptNames[callStack.back().functionId].c_str());
#endif

				break;
			case SHADE:
				r1 = GET_LONG_PC();
				break;
			case DONT_SHADE:
				r1 = GET_LONG_PC();
				break;
			case CACHE:
				r1 = GET_LONG_PC();
				break;
			case DONT_CACHE:
				r1 = GET_LONG_PC();
				break;
			case CALL: {
				r1 = GET_LONG_PC();
				PC--;
				const string& name = script.scriptNames[r1];
				if (name.find("lua_") == 0) {
					script.code[PC - 1] = LUA_CALL;
					LuaCall();
					break;
				}
				script.code[PC - 1] = REAL_CALL;

				// fall through //
			}
			case REAL_CALL:
				r1 = GET_LONG_PC();
				r2 = GET_LONG_PC();

				if (script.scriptLengths[r1] == 0) {
					//logOutput.Print("Preventing call to zero-len script %s", script.scriptNames[r1].c_str());
					break;
				}

				struct callInfo ci;
				ci.functionId = r1;
				ci.returnAddr = PC;
				ci.stackTop = stack.size() - r2;
				callStack.push_back(ci);
				paramCount = r2;

				PC = script.scriptOffsets[r1];
#if COB_DEBUG > 0
				if (COB_DEBUG_FILTER)
					logOutput.Print("Calling %s", script.scriptNames[r1].c_str());
#endif
				break;
			case LUA_CALL:
				LuaCall();
				break;
			case POP_STATIC:
				r1 = GET_LONG_PC();
				r2 = POP();
				owner->staticVars[r1] = r2;
				//logOutput.Print("Pop static var %d val %d", r1, r2);
				break;
			case POP_STACK:
				POP();
				break;
			case START:
				r1 = GET_LONG_PC();
				r2 = GET_LONG_PC();

				if (script.scriptLengths[r1] == 0) {
					//logOutput.Print("Preventing start of zero-len script %s", script.scriptNames[r1].c_str());
					break;
				}

				args.clear();
				for (r3 = 0; r3 < r2; ++r3) {
					r4 = POP();
					args.push_back(r4);
				}

				thread = SAFE_NEW CCobThread(script, owner);
				thread->Start(r1, args, true);

				//Seems that threads should inherit signal mask from creator
				thread->signalMask = signalMask;

#if COB_DEBUG > 0
				if (COB_DEBUG_FILTER)
					logOutput.Print("Starting %s %d", script.scriptNames[r1].c_str(), signalMask);
#endif

				break;
			case CREATE_LOCAL_VAR:
				if (paramCount == 0) {
					stack.push_back(0);
				}
				else {
					paramCount--;
				}
				break;
			case GET_UNIT_VALUE:
				r1 = POP();
				if ((r1 >= LUA0) && (r1 <= LUA9)) {
					stack.push_back(luaArgs[r1 - LUA0]);
					break;
				}
				ForceCommitAllAnims();			// getunitval could possibly read piece locations
				r1 = owner->GetUnitVal(r1, 0, 0, 0, 0);
				stack.push_back(r1);
				break;
			case JUMP_NOT_EQUAL:
				r1 = GET_LONG_PC();
				r2 = POP();
				if (r2 == 0) {
					PC = r1;
				}
				break;
			case JUMP:
				r1 = GET_LONG_PC();
				//this seem to be an error in the docs..
				//r2 = script.scriptOffsets[callStack.back().functionId] + r1;
				PC = r1;
				break;
			case POP_LOCAL_VAR:
				r1 = GET_LONG_PC();
				r2 = POP();
				stack[callStack.back().stackTop + r1] = r2;
				break;
			case PUSH_LOCAL_VAR:
				r1 = GET_LONG_PC();
				r2 = stack[callStack.back().stackTop + r1];
				stack.push_back(r2);
				break;
			case SET_LESS_OR_EQUAL:
				r2 = POP();
				r1 = POP();
				if (r1 <= r2)
					stack.push_back(1);
				else
					stack.push_back(0);
				break;
			case BITWISE_AND:
				r1 = POP();
				r2 = POP();
				stack.push_back(r1 & r2);
				break;
			case BITWISE_OR:	//seems to want stack contents or'd, result places on stack
				r1 = POP();
				r2 = POP();
				stack.push_back(r1 | r2);
				break;
			case BITWISE_XOR:
				r1 = POP();
				r2 = POP();
				stack.push_back(r1 ^ r2);
				break;
			case BITWISE_NOT:
				r1 = POP();
				stack.push_back(~r1);
				break;
			case EXPLODE:
				r1 = GET_LONG_PC();
				r2 = POP();
				owner->Explode(r1, r2);
				break;
			case PLAY_SOUND:
				r1 = GET_LONG_PC();
				r2 = POP();
				owner->PlayUnitSound(r1, r2);
				break;
			case PUSH_STATIC:
				r1 = GET_LONG_PC();
				stack.push_back(owner->staticVars[r1]);
				//logOutput.Print("Push static %d val %d", r1, owner->staticVars[r1]);
				break;
			case SET_NOT_EQUAL:
				r1 = POP();
				r2 = POP();
				if (r1 != r2)
					stack.push_back(1);
				else
					stack.push_back(0);
				break;
			case SET_EQUAL:
				r1 = POP();
				r2 = POP();
				if (r1 == r2)
					stack.push_back(1);
				else
					stack.push_back(0);
				break;
			case SET_LESS:
				r2 = POP();
				r1 = POP();
				if (r1 < r2)
					stack.push_back(1);
				else
					stack.push_back(0);
				break;
			case SET_GREATER:
				r2 = POP();
				r1 = POP();
				if (r1 > r2)
					stack.push_back(1);
				else
					stack.push_back(0);
				break;
			case SET_GREATER_OR_EQUAL:
				r2 = POP();
				r1 = POP();
				if (r1 >= r2)
					stack.push_back(1);
				else
					stack.push_back(0);
				break;
			case RAND:
				r2 = POP();
				r1 = POP();
				r3 = gs->randInt() % (r2 - r1 + 1) + r1;
				stack.push_back(r3);
				break;
			case EMIT_SFX:
				r1 = POP();
				r2 = GET_LONG_PC();
				owner->EmitSfx(r1, r2);
				break;
			case MUL:
				r1 = POP();
				r2 = POP();
				stack.push_back(r1 * r2);
				break;
			case SIGNAL:
				r1 = POP();
				owner->Signal(r1);
				break;
			case SET_SIGNAL_MASK:
				r1 = POP();
				signalMask = r1;
				break;
			case TURN:
				r2 = POP();
				r1 = POP();
				r3 = GET_LONG_PC();
				r4 = GET_LONG_PC();
				//logOutput.Print("Turning piece %s axis %d to %d speed %d", script.pieceNames[r3].c_str(), r4, r2, r1);
				ForceCommitAnim(1, r3, r4);
				owner->Turn(r3, r4, r1, r2);
				break;
			case GET:
				r5 = POP();
				r4 = POP();
				r3 = POP();
				r2 = POP();
				r1 = POP();
				if ((r1 >= LUA0) && (r1 <= LUA9)) {
					stack.push_back(luaArgs[r1 - LUA0]);
					break;
				}
				ForceCommitAllAnims();
				r6 = owner->GetUnitVal(r1, r2, r3, r4, r5);
				stack.push_back(r6);
				break;
			case ADD:
				r2 = POP();
				r1 = POP();
				stack.push_back(r1 + r2);
				break;
			case SUB:
				r2 = POP();
				r1 = POP();
				r3 = r1 - r2;
				stack.push_back(r3);
				break;
			case DIV:
				r2 = POP();
				r1 = POP();
				if (r2 != 0)
					r3 = r1 / r2;
				else {
					r3 = 1000;	//infinity!
					logOutput.Print("CobError: division by zero");
				}
				stack.push_back(r3);
				break;
			case MOD:
				r2 = POP();
				r1 = POP();
				if (r2 != 0)
					stack.push_back(r1 % r2);
				else {
					stack.push_back(0);
					logOutput.Print("CobError: modulo division by zero");
				}
				break;
			case MOVE:
				r1 = GET_LONG_PC();
				r2 = GET_LONG_PC();
				r4 = POP();
				r3 = POP();
				ForceCommitAnim(2, r1, r2);
				owner->Move(r1, r2, r3, r4);
				break;
			case MOVE_NOW:{
				r1 = GET_LONG_PC();
				r2 = GET_LONG_PC();
				r3 = POP();

				if (owner->smoothAnim) {
					DelayedAnim a;
					a.type = 2;
					a.piece = r1;
					a.axis = r2;
					a.dest = r3;
					delayedAnims.push_back(a);

					//logOutput.Print("Delayed move %s %d %d", owner->pieces[r1].name.c_str(), r2, r3);
				}
				else {
					owner->MoveNow(r1, r2, r3);
				}

				break;}
			case TURN_NOW:{
				r1 = GET_LONG_PC();
				r2 = GET_LONG_PC();
				r3 = POP();

				if (owner->smoothAnim) {
					DelayedAnim a;
					a.type = 1;
					a.piece = r1;
					a.axis = r2;
					a.dest = r3;
					delayedAnims.push_back(a);
				}
				else {
					owner->TurnNow(r1, r2, r3);
				}

				break;}
			case WAIT_TURN:
				r1 = GET_LONG_PC();
				r2 = GET_LONG_PC();
				//logOutput.Print("Waiting for turn on piece %s around axis %d", script.pieceNames[r1].c_str(), r2);
				if (owner->AddTurnListener(r1, r2, this)) {
					state = WaitTurn;
					GCobEngine.SetCurThread(NULL);
					return 0;
				}
				else
					break;
			case WAIT_MOVE:
				r1 = GET_LONG_PC();
				r2 = GET_LONG_PC();
				//logOutput.Print("Waiting for move on piece %s on axis %d", script.pieceNames[r1].c_str(), r2);
				if (owner->AddMoveListener(r1, r2, this)) {
					state = WaitMove;
					GCobEngine.SetCurThread(NULL);
					return 0;
				}
				break;
			case SET:
				r2 = POP();
				r1 = POP();
				//logOutput.Print("Setting unit value %d to %d", r1, r2);
				if ((r1 >= LUA0) && (r1 <= LUA9)) {
					luaArgs[r1 - LUA0] = r2;
					break;
				}
				owner->SetUnitVal(r1, r2);
				break;
			case ATTACH:
				r3 = POP();
				r2 = POP();
				r1 = POP();
				owner->AttachUnit(r2, r1);
				break;
			case DROP:
				r1 = POP();
				owner->DropUnit(r1);
				break;
			case LOGICAL_NOT:		//Like bitwise, but only on values 1 and 0.
				r1 = POP();
				if (r1 == 0)
					stack.push_back(1);
				else
					stack.push_back(0);
				break;
			case LOGICAL_AND:
				r1 = POP();
				r2 = POP();
				if (r1 && r2)
					stack.push_back(1);
				else
					stack.push_back(0);
				break;
			case LOGICAL_OR:
				r1 = POP();
				r2 = POP();
				if (r1 || r2)
					stack.push_back(1);
				else
					stack.push_back(0);
				break;
			case LOGICAL_XOR:
				r1 = POP();
				r2 = POP();
				if (!!r1 ^ !!r2)
					stack.push_back(1);
				else
					stack.push_back(0);
				break;
			case HIDE:
				r1 = GET_LONG_PC();
				owner->SetVisibility(r1, false);
				//logOutput.Print("Hiding %d", r1);
				break;
			case SHOW:{
				r1 = GET_LONG_PC();
				int i;
				for (i = 0; i < COB_MaxWeapons; ++i)
					if (callStack.back().functionId == script.scriptIndex[COBFN_FirePrimary + i])
						break;

				// If true, we are in a Fire-script and should show a special flare effect
				if (i < COB_MaxWeapons) {
					owner->ShowFlare(r1);
				}
				else {
					owner->SetVisibility(r1, true);
				}
				//logOutput.Print("Showing %d", r1);
				break;}
			default:
				logOutput.Print("CobError: Unknown opcode %x (in %s:%s at %x)", opcode, script.name.c_str(), script.scriptNames[callStack.back().functionId].c_str(), PC - 1);
				logOutput.Print("Exec trace:");
				ei = execTrace.begin();
				while (ei != execTrace.end()) {
					logOutput.Print("PC: %3x  opcode: %s", *ei, GetOpcodeName(script.code[*ei]).c_str());
					ei++;
				}
				state = Dead;
				GCobEngine.SetCurThread(NULL);
				return -1;
				break;
		}

	}

	GCobEngine.SetCurThread(NULL);
	return 0;
}
Example #16
0
static PyObject *LuaObject_call(PyObject *obj, PyObject *args)
{
    lua_settop(LuaState, 0);
    lua_rawgeti(LuaState, LUA_REGISTRYINDEX, ((LuaObject*)obj)->ref);
    return LuaCall(LuaState, args);
}
Example #17
0
int main(int argc,char **argv){
	if(argc < 2){
		printf("usage testlua luafile\n");
		return 0;
	}
	lua_State *L = luaL_newstate();
	luaL_openlibs(L);
	if (luaL_dofile(L,argv[1])) {
		const char * error = lua_tostring(L, -1);
		lua_pop(L,1);
		printf("%s\n",error);
	}
	const char *err;
	printf("------makeLuaObjByStr---------\n\n");
	//dynamic build a lua table and return
	luaRef tabRef = makeLuaObjByStr(L,"return {a=100}");
	if(tabRef.L){
		int a = 0;
		err = LuaRef_Get(tabRef,"si","a",&a);
		if(err) printf("%s\n",err);
		else{
			printf("a == %d\n",a);	
		}
		release_luaRef(&tabRef);
	}


	printf("------call 0 arg---------\n\n");
	err = LuaCall(L,"fun0",NULL);
	if(err) printf("error on fun0:%s\n",err);
	

	printf("------call 2 arg(integer,str),1 ret(integer)---------\n\n");

	unsigned int iret1;
	err = LuaCall(L,"fun1","is:i",0xfffffffff,"hello",&iret1);
	if(err) printf("error on fun1:%s\n",err);
	else printf("ret1=%u\n",iret1);
	
	printf("------call 2 arg(str),1 ret(str)---------\n\n");
	char *sret1;
	err = LuaCall(L,"fun2","ss:s","hello","kenny",&sret1);
	if(err) printf("error on fun2:%s\n",err);
	else printf("sret1=%s\n",sret1);
	
	printf("------call 3 arg(str,str,lua str),2 ret(lua str)---------\n\n");
	char  *Sret1,*Sret2;
	size_t Lret1,Lret2;
	err = LuaCall(L,"fun3","ssS:SS","1","2","3",sizeof("3"),&Sret1,&Lret1,&Sret2,&Lret2);
	if(err) printf("error on fun3:%s\n",err); 
	else{
		printf("%s %ld\n",Sret1,Lret1);
		printf("%s %ld\n",Sret2,Lret2);		
	}
	
	printf("------call 0 arg, 1 ret(luaobj)---------\n\n");
	luaRef funRef;
	err = LuaCall(L,"fun5",":r",&funRef);
	if(err) printf("error on fun5:%s\n",err);
	int num = -1;
	int num2 = -1;
	LuaCallRefFunc(funRef,":ii",&num,&num2);
	printf("%d,%d\n",num,num2);	
	
	
	printf("------call lua obj function---------\n\n");	
	err = LuaCall(L,"fun6",":ri",&tabRef,&num);
	if(err) printf("error on fun6:%s\n",err);
	printf("%d\n",num);
	err = LuaCallTabFuncS(tabRef,"hello",NULL);
	if(err) printf("%s\n",err);
	
	printf("------set and get luaobj field---------\n\n");	
	err = LuaRef_Set(tabRef,"siss","f1",99,"f2","hello haha");
	if(err) printf("%s\n",err);
	else{
		int f1;
		const char *f2;
		err = LuaRef_Get(tabRef,"siss","f1",&f1,"f2",&f2);
		if(err) printf("%s\n",err);
		else printf("get %d,%s\n",f1,f2);
	}

	err = LuaRef_Set(tabRef,"sp","f1",NULL);
	if(err) printf("%s\n",err);
	else{
		err = LuaCall(L,"fun7",NULL);
		if(err) printf("error on fun7:%s\n",err);		
	}
	
	printf("------iterate luaobj-------------\n\n");
	lua_getglobal(L,"ttab4");
	tabRef = toluaRef(L,-1);
	LuaTabForEach(tabRef){
		const char *key = lua_tostring(L,EnumKey);
		const char *val = lua_tostring(L,EnumVal);
		printf("%s,%s\n",key,val);
	}

	printf("end\n");	
	return 0;	
}
Example #18
0
bool CCobThread::Tick()
{
	if (state == Sleep) {
		LOG_L(L_ERROR, "sleeping thread ticked!");
	}
	if (state == Dead || owner == nullptr) {
		return false;
	}

	state = Run;

	int r1, r2, r3, r4, r5, r6;

	vector<int> args;
	vector<int>::iterator ei;

	//execTrace.clear();

	//LOG_L(L_DEBUG, "Executing in %s (from %s)", script.scriptNames[callStack.back().functionId].c_str(), GetName().c_str());

	while (state == Run) {
		//int opcode = *(int*)&script.code[PC];

		// Disabling exec trace gives about a 50% speedup on vm-intensive code
		//execTrace.push_back(PC);

		int opcode = GET_LONG_PC();

		//LOG_L(L_DEBUG, "PC: %x opcode: %x (%s)", PC - 1, opcode, GetOpcodeName(opcode).c_str());

		switch(opcode) {
			case PUSH_CONSTANT:
				r1 = GET_LONG_PC();
				stack.push_back(r1);
				break;
			case SLEEP:
				r1 = POP();
				wakeTime = cobEngine->GetCurrentTime() + r1;
				state = Sleep;
				cobEngine->AddThread(this);
				//LOG_L(L_DEBUG, "%s sleeping for %d ms", script.scriptNames[callStack.back().functionId].c_str(), r1);
				return true;
			case SPIN:
				r1 = GET_LONG_PC();
				r2 = GET_LONG_PC();
				r3 = POP();         // speed
				r4 = POP();         // accel
				owner->Spin(r1, r2, r3, r4);
				break;
			case STOP_SPIN:
				r1 = GET_LONG_PC();
				r2 = GET_LONG_PC();
				r3 = POP();         // decel
				//LOG_L(L_DEBUG, "Stop spin of %s around %d", script.pieceNames[r1].c_str(), r2);
				owner->StopSpin(r1, r2, r3);
				break;
			case RETURN:
				retCode = POP();
				if (callStack.back().returnAddr == -1) {
					//LOG_L(L_DEBUG, "%s returned %d", script.scriptNames[callStack.back().functionId].c_str(), retCode);
					state = Dead;
					//callStack.pop_back();
					// Leave values intact on stack in case caller wants to check them
					return false;
				}

				PC = callStack.back().returnAddr;
				while (stack.size() > callStack.back().stackTop) {
					stack.pop_back();
				}
				callStack.pop_back();
				//LOG_L(L_DEBUG, "Returning to %s", owner->script->scriptNames[callStack.back().functionId].c_str());
				break;
			case SHADE:
				r1 = GET_LONG_PC();
				break;
			case DONT_SHADE:
				r1 = GET_LONG_PC();
				break;
			case CACHE:
				r1 = GET_LONG_PC();
				break;
			case DONT_CACHE:
				r1 = GET_LONG_PC();
				break;
			case CALL: {
				r1 = GET_LONG_PC();
				PC--;
				const string& name = owner->script->scriptNames[r1];
				if (name.find("lua_") == 0) {
					owner->script->code[PC - 1] = LUA_CALL;
					LuaCall();
					break;
				}
				owner->script->code[PC - 1] = REAL_CALL;

				// fall through //
			}
			case REAL_CALL:
				r1 = GET_LONG_PC();
				r2 = GET_LONG_PC();

				if (owner->script->scriptLengths[r1] == 0) {
					//LOG_L(L_DEBUG, "Preventing call to zero-len script %s", owner->script->scriptNames[r1].c_str());
					break;
				}

				CallInfo ci;
				ci.functionId = r1;
				ci.returnAddr = PC;
				ci.stackTop = stack.size() - r2;
				callStack.push_back(ci);
				paramCount = r2;

				PC = owner->script->scriptOffsets[r1];
				//LOG_L(L_DEBUG, "Calling %s", owner->script->scriptNames[r1].c_str());
				break;
			case LUA_CALL:
				LuaCall();
				break;
			case POP_STATIC:
				r1 = GET_LONG_PC();
				r2 = POP();
				owner->staticVars[r1] = r2;
				//LOG_L(L_DEBUG, "Pop static var %d val %d", r1, r2);
				break;
			case POP_STACK:
				POP();
				break;
			case START: {
				r1 = GET_LONG_PC();
				r2 = GET_LONG_PC();

				if (owner->script->scriptLengths[r1] == 0) {
					//LOG_L(L_DEBUG, "Preventing start of zero-len script %s", owner->script->scriptNames[r1].c_str());
					break;
				}

				args.clear();
				args.reserve(r2);
				for (r3 = 0; r3 < r2; ++r3) {
					r4 = POP();
					args.push_back(r4);
				}

				CCobThread* thread = new CCobThread(owner);
				thread->Start(r1, args, true);

				// Seems that threads should inherit signal mask from creator
				thread->signalMask = signalMask;
				//LOG_L(L_DEBUG, "Starting %s %d", owner->script->scriptNames[r1].c_str(), signalMask);
			} break;
			case CREATE_LOCAL_VAR:
				if (paramCount == 0) {
					stack.push_back(0);
				} else {
					paramCount--;
				}
				break;
			case GET_UNIT_VALUE:
				r1 = POP();
				if ((r1 >= LUA0) && (r1 <= LUA9)) {
					stack.push_back(luaArgs[r1 - LUA0]);
					break;
				}
				r1 = owner->GetUnitVal(r1, 0, 0, 0, 0);
				stack.push_back(r1);
				break;
			case JUMP_NOT_EQUAL:
				r1 = GET_LONG_PC();
				r2 = POP();
				if (r2 == 0) {
					PC = r1;
				}
				break;
			case JUMP:
				r1 = GET_LONG_PC();
				// this seem to be an error in the docs..
				//r2 = owner->script->scriptOffsets[callStack.back().functionId] + r1;
				PC = r1;
				break;
			case POP_LOCAL_VAR:
				r1 = GET_LONG_PC();
				r2 = POP();
				stack[callStack.back().stackTop + r1] = r2;
				break;
			case PUSH_LOCAL_VAR:
				r1 = GET_LONG_PC();
				r2 = stack[callStack.back().stackTop + r1];
				stack.push_back(r2);
				break;
			case SET_LESS_OR_EQUAL:
				r2 = POP();
				r1 = POP();
				if (r1 <= r2)
					stack.push_back(1);
				else
					stack.push_back(0);
				break;
			case BITWISE_AND:
				r1 = POP();
				r2 = POP();
				stack.push_back(r1 & r2);
				break;
			case BITWISE_OR: // seems to want stack contents or'd, result places on stack
				r1 = POP();
				r2 = POP();
				stack.push_back(r1 | r2);
				break;
			case BITWISE_XOR:
				r1 = POP();
				r2 = POP();
				stack.push_back(r1 ^ r2);
				break;
			case BITWISE_NOT:
				r1 = POP();
				stack.push_back(~r1);
				break;
			case EXPLODE:
				r1 = GET_LONG_PC();
				r2 = POP();
				owner->Explode(r1, r2);
				break;
			case PLAY_SOUND:
				r1 = GET_LONG_PC();
				r2 = POP();
				owner->PlayUnitSound(r1, r2);
				break;
			case PUSH_STATIC:
				r1 = GET_LONG_PC();
				stack.push_back(owner->staticVars[r1]);
				//LOG_L(L_DEBUG, "Push static %d val %d", r1, owner->staticVars[r1]);
				break;
			case SET_NOT_EQUAL:
				r1 = POP();
				r2 = POP();
				if (r1 != r2)
					stack.push_back(1);
				else
					stack.push_back(0);
				break;
			case SET_EQUAL:
				r1 = POP();
				r2 = POP();
				if (r1 == r2)
					stack.push_back(1);
				else
					stack.push_back(0);
				break;
			case SET_LESS:
				r2 = POP();
				r1 = POP();
				if (r1 < r2)
					stack.push_back(1);
				else
					stack.push_back(0);
				break;
			case SET_GREATER:
				r2 = POP();
				r1 = POP();
				if (r1 > r2)
					stack.push_back(1);
				else
					stack.push_back(0);
				break;
			case SET_GREATER_OR_EQUAL:
				r2 = POP();
				r1 = POP();
				if (r1 >= r2)
					stack.push_back(1);
				else
					stack.push_back(0);
				break;
			case RAND:
				r2 = POP();
				r1 = POP();
				r3 = gs->randInt() % (r2 - r1 + 1) + r1;
				stack.push_back(r3);
				break;
			case EMIT_SFX:
				r1 = POP();
				r2 = GET_LONG_PC();
				owner->EmitSfx(r1, r2);
				break;
			case MUL:
				r1 = POP();
				r2 = POP();
				stack.push_back(r1 * r2);
				break;
			case SIGNAL:
				r1 = POP();
				owner->Signal(r1);
				break;
			case SET_SIGNAL_MASK:
				r1 = POP();
				signalMask = r1;
				break;
			case TURN:
				r2 = POP();
				r1 = POP();
				r3 = GET_LONG_PC();
				r4 = GET_LONG_PC();
				//LOG_L(L_DEBUG, "Turning piece %s axis %d to %d speed %d", owner->script->pieceNames[r3].c_str(), r4, r2, r1);
				owner->Turn(r3, r4, r1, r2);
				break;
			case GET:
				r5 = POP();
				r4 = POP();
				r3 = POP();
				r2 = POP();
				r1 = POP();
				if ((r1 >= LUA0) && (r1 <= LUA9)) {
					stack.push_back(luaArgs[r1 - LUA0]);
					break;
				}
				r6 = owner->GetUnitVal(r1, r2, r3, r4, r5);
				stack.push_back(r6);
				break;
			case ADD:
				r2 = POP();
				r1 = POP();
				stack.push_back(r1 + r2);
				break;
			case SUB:
				r2 = POP();
				r1 = POP();
				r3 = r1 - r2;
				stack.push_back(r3);
				break;
			case DIV:
				r2 = POP();
				r1 = POP();
				if (r2 != 0)
					r3 = r1 / r2;
				else {
					r3 = 1000; // infinity!
					ShowError("division by zero");
				}
				stack.push_back(r3);
				break;
			case MOD:
				r2 = POP();
				r1 = POP();
				if (r2 != 0)
					stack.push_back(r1 % r2);
				else {
					stack.push_back(0);
					ShowError("modulo division by zero");
				}
				break;
			case MOVE:
				r1 = GET_LONG_PC();
				r2 = GET_LONG_PC();
				r4 = POP();
				r3 = POP();
				owner->Move(r1, r2, r3, r4);
				break;
			case MOVE_NOW:{
				r1 = GET_LONG_PC();
				r2 = GET_LONG_PC();
				r3 = POP();
				owner->MoveNow(r1, r2, r3);
				break;}
			case TURN_NOW:{
				r1 = GET_LONG_PC();
				r2 = GET_LONG_PC();
				r3 = POP();
				owner->TurnNow(r1, r2, r3);
				break;}
			case WAIT_TURN:
				r1 = GET_LONG_PC();
				r2 = GET_LONG_PC();
				//LOG_L(L_DEBUG, "Waiting for turn on piece %s around axis %d", owner->script->pieceNames[r1].c_str(), r2);
				if (owner->NeedsWait(CCobInstance::ATurn, r1, r2)) {
					state = WaitTurn;
					waitPiece = r1;
					waitAxis = r2;
					return true;
				}
				else
					break;
			case WAIT_MOVE:
				r1 = GET_LONG_PC();
				r2 = GET_LONG_PC();
				//LOG_L(L_DEBUG, "Waiting for move on piece %s on axis %d", owner->script->pieceNames[r1].c_str(), r2);
				if (owner->NeedsWait(CCobInstance::AMove, r1, r2)) {
					state = WaitMove;
					waitPiece = r1;
					waitAxis = r2;
					return true;
				}
				break;
			case SET:
				r2 = POP();
				r1 = POP();
				//LOG_L(L_DEBUG, "Setting unit value %d to %d", r1, r2);
				if ((r1 >= LUA0) && (r1 <= LUA9)) {
					luaArgs[r1 - LUA0] = r2;
					break;
				}
				owner->SetUnitVal(r1, r2);
				break;
			case ATTACH:
				r3 = POP();
				r2 = POP();
				r1 = POP();
				owner->AttachUnit(r2, r1);
				break;
			case DROP:
				r1 = POP();
				owner->DropUnit(r1);
				break;
			case LOGICAL_NOT: // Like bitwise, but only on values 1 and 0.
				r1 = POP();
				if (r1 == 0)
					stack.push_back(1);
				else
					stack.push_back(0);
				break;
			case LOGICAL_AND:
				r1 = POP();
				r2 = POP();
				if (r1 && r2)
					stack.push_back(1);
				else
					stack.push_back(0);
				break;
			case LOGICAL_OR:
				r1 = POP();
				r2 = POP();
				if (r1 || r2)
					stack.push_back(1);
				else
					stack.push_back(0);
				break;
			case LOGICAL_XOR:
				r1 = POP();
				r2 = POP();
				if ( (!!r1) ^ (!!r2))
					stack.push_back(1);
				else
					stack.push_back(0);
				break;
			case HIDE:
				r1 = GET_LONG_PC();
				owner->SetVisibility(r1, false);
				//LOG_L(L_DEBUG, "Hiding %d", r1);
				break;
			case SHOW:{
				r1 = GET_LONG_PC();
				int i;
				for (i = 0; i < MAX_WEAPONS_PER_UNIT; ++i)
					if (callStack.back().functionId == owner->script->scriptIndex[COBFN_FirePrimary + COBFN_Weapon_Funcs * i])
						break;

				// If true, we are in a Fire-script and should show a special flare effect
				if (i < MAX_WEAPONS_PER_UNIT) {
					owner->ShowFlare(r1);
				}
				else {
					owner->SetVisibility(r1, true);
				}
				//LOG_L(L_DEBUG, "Showing %d", r1);
				break;}
			default:
				LOG_L(L_ERROR, "Unknown opcode %x (in %s:%s at %x)",
						opcode, owner->script->name.c_str(),
						owner->script->scriptNames[callStack.back().functionId].c_str(),
						PC - 1);
				LOG_L(L_ERROR, "Exec trace:");
				// ei = execTrace.begin();
				// while (ei != execTrace.end()) {
					// LOG_L(L_ERROR, "PC: %3x  opcode: %s", *ei, GetOpcodeName(owner->script->code[*ei]).c_str());
					// ++ei;
				// }
				state = Dead;
				return false;
		}
	}

	return (state != Dead); // can arrive here as dead, through CCobInstance::Signal()
}
Example #19
0
void View::mouseUp(int button, double x, double y, bool shift, bool control, bool alt, bool command) {
	if (_scripts[ScriptOnMouseUp].L) {
		LuaCall(_scripts[ScriptOnMouseUp].L, _scripts[ScriptOnMouseUp].function, _luaRef, button, x, y, shift, control, alt, command);
	}
}