Example #1
0
void LUAh_NetArchiveHook(lua_CFunction archFunc)
{
	hook_p hookp;

	if (!gL || !(hooksAvailable[hook_NetVars/8] & (1<<(hook_NetVars%8))))
		return;

	// stack: tables
	I_Assert(lua_gettop(gL) > 0);
	I_Assert(lua_istable(gL, -1));

	// tables becomes an upvalue of archFunc
	lua_pushvalue(gL, -1);
	lua_pushcclosure(gL, archFunc, 1);
	// stack: tables, archFunc

	for (hookp = roothook; hookp; hookp = hookp->next)
		if (hookp->type == hook_NetVars)
		{
			lua_pushfstring(gL, FMT_HOOKID, hookp->id);
			lua_gettable(gL, LUA_REGISTRYINDEX);
			lua_pushvalue(gL, -2); // archFunc
			LUA_Call(gL, 1);
		}

	lua_pop(gL, 1); // pop archFunc
	// stack: tables
}
Example #2
0
// Hook for HUD rendering
void LUAh_GameHUD(player_t *stplyr)
{
	if (!gL || !(hudAvailable & (1<<hudhook_game)))
		return;

	hud_running = true;
	lua_pop(gL, -1);

	lua_getfield(gL, LUA_REGISTRYINDEX, "HUD");
	I_Assert(lua_istable(gL, -1));
	lua_rawgeti(gL, -1, 2); // HUD[2] = rendering funcs
	I_Assert(lua_istable(gL, -1));

	lua_rawgeti(gL, -2, 1); // HUD[1] = lib_draw
	I_Assert(lua_istable(gL, -1));
	lua_remove(gL, -3); // pop HUD
	LUA_PushUserdata(gL, stplyr, META_PLAYER);

	lua_pushnil(gL);
	while (lua_next(gL, -4) != 0) {
		lua_pushvalue(gL, -4); // graphics library (HUD[1])
		lua_pushvalue(gL, -4); // stplyr
		LUA_Call(gL, 2);
	}
	lua_pop(gL, -1);
	lua_gc(gL, LUA_GCCOLLECT, 0);

	hud_running = false;
}
Example #3
0
boolean LUA_SetLuaAction(void *stv, const char *action)
{
	state_t *st = (state_t *)stv;

	I_Assert(st != NULL);
	//I_Assert(st >= states && st < states+NUMSTATES); // if you REALLY want to be paranoid...
	I_Assert(action != NULL);

	if (!gL) // Lua isn't loaded,
		return false; // action not set.

	// action is assumed to be in all-caps already !!
	// the registry is case-sensitive, so we strupr everything that enters it.

	lua_getfield(gL, LUA_REGISTRYINDEX, LREG_ACTIONS);
	lua_getfield(gL, -1, action);

	if (lua_isnil(gL, -1)) // no match
	{
		lua_pop(gL, 2); // pop nil and LREG_ACTIONS
		return false; // action not set.
	}

	lua_getfield(gL, LUA_REGISTRYINDEX, LREG_STATEACTION);
	I_Assert(lua_istable(gL, -1));
	lua_pushlightuserdata(gL, stv); // We'll store this function by the state's pointer in the registry.
	lua_pushvalue(gL, -3); // Bring it to the top of the stack
	lua_rawset(gL, -3); // Set it in the registry
	lua_pop(gL, 1); // pop LREG_STATEACTION

	lua_pop(gL, 2); // pop the function and LREG_ACTIONS
	st->action.acp1 = (actionf_p1)A_Lua; // Set the action for the userdata.
	return true; // action successfully set.
}
Example #4
0
void LUAh_ScoresHUD(void)
{
	if (!gL || !(hudAvailable & (1<<hudhook_scores)))
		return;

	hud_running = true;
	lua_pop(gL, -1);

	lua_getfield(gL, LUA_REGISTRYINDEX, "HUD");
	I_Assert(lua_istable(gL, -1));
	lua_rawgeti(gL, -1, 3); // HUD[3] = rendering funcs
	I_Assert(lua_istable(gL, -1));

	lua_rawgeti(gL, -2, 1); // HUD[1] = lib_draw
	I_Assert(lua_istable(gL, -1));
	lua_remove(gL, -3); // pop HUD
	lua_pushnil(gL);
	while (lua_next(gL, -3) != 0) {
		lua_pushvalue(gL, -3); // graphics library (HUD[1])
		LUA_Call(gL, 1);
	}
	lua_pop(gL, -1);
	lua_gc(gL, LUA_GCCOLLECT, 0);

	hud_running = false;
}
Example #5
0
static void UnArchiveExtVars(void *pointer)
{
	int TABLESINDEX;
	UINT16 field_count = READUINT16(save_p);
	UINT16 i;
	char field[1024];

	if (field_count == 0)
		return;
	I_Assert(gL != NULL);

	TABLESINDEX = lua_gettop(gL);
	lua_createtable(gL, 0, field_count); // pointer's ext vars subtable

	for (i = 0; i < field_count; i++)
	{
		READSTRING(save_p, field);
		UnArchiveValue(TABLESINDEX);
		lua_setfield(gL, -2, field);
	}

	lua_getfield(gL, LUA_REGISTRYINDEX, LREG_EXTVARS);
	I_Assert(lua_istable(gL, -1));
	lua_pushlightuserdata(gL, pointer);
	lua_pushvalue(gL, -3); // pointer's ext vars subtable
	lua_rawset(gL, -3);
	lua_pop(gL, 2); // pop LREG_EXTVARS and pointer's subtable
}
Example #6
0
// When userdata is freed, use this function to remove it from Lua.
void LUA_InvalidateUserdata(void *data)
{
	void **userdata;
	if (!gL)
		return;

	// fetch the userdata
	lua_getfield(gL, LUA_REGISTRYINDEX, LREG_VALID);
	I_Assert(lua_istable(gL, -1));
		lua_pushlightuserdata(gL, data);
		lua_rawget(gL, -2);
			if (lua_isnil(gL, -1)) { // not found, not in lua
				lua_pop(gL, 2); // pop nil and LREG_VALID
				return;
			}

			// nullify any additional data
			lua_getfield(gL, LUA_REGISTRYINDEX, LREG_EXTVARS);
			I_Assert(lua_istable(gL, -1));
				lua_pushlightuserdata(gL, data);
				lua_pushnil(gL);
				lua_rawset(gL, -3);
			lua_pop(gL, 1);

			// invalidate the userdata
			userdata = lua_touserdata(gL, -1);
			*userdata = NULL;
		lua_pop(gL, 1);

		// remove it from the registry
		lua_pushlightuserdata(gL, data);
		lua_pushnil(gL);
		lua_rawset(gL, -3);
	lua_pop(gL, 1); // pop LREG_VALID
}
Example #7
0
static int sfxinfo_num(lua_State *L)
{
	sfxinfo_t *sfx = *((sfxinfo_t **)luaL_checkudata(L, 1, META_SFXINFO));

	I_Assert(sfx != NULL);
	I_Assert(sfx >= S_sfx);

	lua_pushinteger(L, (UINT32)(sfx-S_sfx));
	return 1;
}
Example #8
0
// mobjinfo_t * -> MT_*
static int mobjinfo_num(lua_State *L)
{
	mobjinfo_t *info = *((mobjinfo_t **)luaL_checkudata(L, 1, META_MOBJINFO));

	I_Assert(info != NULL);
	I_Assert(info >= mobjinfo);

	lua_pushinteger(L, info-mobjinfo);
	return 1;
}
Example #9
0
boolean LUA_CallAction(const char *csaction, mobj_t *actor)
{
	I_Assert(csaction != NULL);
	I_Assert(actor != NULL);

	if (!gL) // Lua isn't loaded,
		return false; // action not called.

	if (superstack && fasticmp(csaction, superactions[superstack-1])) // the action is calling itself,
		return false; // let it call the hardcoded function instead.

	// grab function by uppercase name.
	lua_getfield(gL, LUA_REGISTRYINDEX, LREG_ACTIONS);
	{
		char *action = Z_StrDup(csaction);
		strupr(action);
		lua_getfield(gL, -1, action);
		Z_Free(action);
	}
	lua_remove(gL, -2); // pop LREG_ACTIONS

	if (lua_isnil(gL, -1)) // no match
	{
		lua_pop(gL, 1); // pop nil
		return false; // action not called.
	}

	if (superstack == MAXRECURSION)
	{
		CONS_Alert(CONS_WARNING, "Max Lua Action recursion reached! Cool it on the calling A_Action functions from inside A_Action functions!\n");
		return true;
	}

	// Found a function.
	// Call it with (actor, var1, var2)
	I_Assert(lua_isfunction(gL, -1));
	LUA_PushUserdata(gL, actor, META_MOBJ);
	lua_pushinteger(gL, var1);
	lua_pushinteger(gL, var2);

	superactions[superstack] = csaction;
	++superstack;

	LUA_Call(gL, 3);

	--superstack;
	superactions[superstack] = NULL;
	return true; // action successfully called.
}
Example #10
0
static void ArchiveExtVars(void *pointer, const char *ptype)
{
	int TABLESINDEX;
	UINT16 i;

	if (!gL) {
		if (fastcmp(ptype,"player")) // players must always be included, even if no vars
			WRITEUINT16(save_p, 0);
		return;
	}

	TABLESINDEX = lua_gettop(gL);

	lua_getfield(gL, LUA_REGISTRYINDEX, LREG_EXTVARS);
	I_Assert(lua_istable(gL, -1));
	lua_pushlightuserdata(gL, pointer);
	lua_rawget(gL, -2);
	lua_remove(gL, -2); // pop LREG_EXTVARS

	if (!lua_istable(gL, -1))
	{ // no extra values table
		lua_pop(gL, 1);
		if (fastcmp(ptype,"player")) // players must always be included, even if no vars
			WRITEUINT16(save_p, 0);
		return;
	}

	lua_pushnil(gL);
	for (i = 0; lua_next(gL, -2); i++)
		lua_pop(gL, 1);

	if (i == 0 && !fastcmp(ptype,"player")) // skip anything that has an empty table and isn't a player.
		return;
	if (fastcmp(ptype,"mobj")) // mobjs must write their mobjnum as a header
		WRITEUINT32(save_p, ((mobj_t *)pointer)->mobjnum);
	WRITEUINT16(save_p, i);
	lua_pushnil(gL);
	while (lua_next(gL, -2))
	{
		I_Assert(lua_type(gL, -2) == LUA_TSTRING);
		WRITESTRING(save_p, lua_tostring(gL, -2));
		if (ArchiveValue(TABLESINDEX, -1) == 2)
			CONS_Alert(CONS_ERROR, "Type of value for %s entry '%s' (%s) could not be archived!\n", ptype, lua_tostring(gL, -2), luaL_typename(gL, -1));
		lua_pop(gL, 1);
	}

	lua_pop(gL, 1);
}
Example #11
0
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority)
{
	FMOD_SOUND *sound;
	FMOD_CHANNEL *chan;
	INT32 i;
	float frequency;

	sound = (FMOD_SOUND *)S_sfx[id].data;
	I_Assert(sound != NULL);

	FMR(FMOD_System_PlaySound(fsys, FMOD_CHANNEL_FREE, sound, true, &chan));

	if (sep == 0)
		sep = 1;

	FMR(FMOD_Channel_SetVolume(chan, (vol / 255.0) * (sfx_volume / 31.0)));
	FMR(FMOD_Channel_SetPan(chan, (sep - 128) / 127.0));

	FMR(FMOD_Sound_GetDefaults(sound, &frequency, NULL, NULL, NULL));
	FMR(FMOD_Channel_SetFrequency(chan, (pitch / 128.0) * frequency));

	FMR(FMOD_Channel_SetPriority(chan, priority));
	//UNREFERENCED_PARAMETER(priority);
	//FMR(FMOD_Channel_SetPriority(chan, 1 + ((0xff-vol)>>1))); // automatic priority 1 - 128 based on volume (priority 0 is music)

	FMR(FMOD_Channel_GetIndex(chan, &i));
	FMR(FMOD_Channel_SetPaused(chan, false));
	return i;
}
Example #12
0
// Takes a pointer, any pointer, and a metatable name
// Creates a userdata for that pointer with the given metatable
// Pushes it to the stack and stores it in the registry.
void LUA_PushUserdata(lua_State *L, void *data, const char *meta)
{
	void **userdata;

	if (!data) { // push a NULL
		lua_pushnil(L);
		return;
	}

	lua_getfield(L, LUA_REGISTRYINDEX, LREG_VALID);
	I_Assert(lua_istable(L, -1));
	lua_pushlightuserdata(L, data);
	lua_rawget(L, -2);
	if (lua_isnil(L, -1)) { // no userdata? deary me, we'll have to make one.
		lua_pop(L, 1); // pop the nil

		// create the userdata
		userdata = lua_newuserdata(L, sizeof(void *));
		*userdata = data;
		luaL_getmetatable(L, meta);
		lua_setmetatable(L, -2);

		// Set it in the registry so we can find it again
		lua_pushlightuserdata(L, data); // k (store the userdata via the data's pointer)
		lua_pushvalue(L, -2); // v (copy of the userdata)
		lua_rawset(L, -4);

		// stack is left with the userdata on top, as if getting it had originally succeeded.
	}
	lua_remove(L, -2); // remove LREG_VALID
}
Example #13
0
// sfxinfo_t *, field, value
static int sfxinfo_set(lua_State *L)
{
	sfxinfo_t *sfx = *((sfxinfo_t **)luaL_checkudata(L, 1, META_SFXINFO));
	enum sfxinfo_e field = luaL_checkoption(L, 2, NULL, sfxinfo_opt);

	if (hud_running)
		return luaL_error(L, "Do not alter S_sfx in HUD rendering code!");

	I_Assert(sfx != NULL);

	lua_remove(L, 1); // remove sfxinfo
	lua_remove(L, 1); // remove field
	lua_settop(L, 1); // leave only one value

	switch (field)
	{
	case sfxinfo_singularity:
		sfx->singularity = luaL_checkboolean(L, 1);
		break;
	case sfxinfo_priority:
		sfx->priority = luaL_checkinteger(L, 1);
		break;
	case sfxinfo_flags:
		sfx->pitch = luaL_checkinteger(L, 1);
		break;
	case sfxinfo_volume:
		sfx->volume = luaL_checkinteger(L, 1);
		break;
	default:
		return luaL_error(L, "Can't set 'S_sfx[%u].%s' here.", (UINT32)(sfx-S_sfx), sfxinfo_opt[field]);
	}

	return 0;
}
Example #14
0
// sfxinfo_t *, field
static int sfxinfo_get(lua_State *L)
{
	sfxinfo_t *sfx = *((sfxinfo_t **)luaL_checkudata(L, 1, META_SFXINFO));
	enum sfxinfo_e field = luaL_checkoption(L, 2, NULL, sfxinfo_opt);

	I_Assert(sfx != NULL);

	switch (field)
	{
	case sfxinfo_name:
		lua_pushstring(L, sfx->name);
		return 1;
	case sfxinfo_singularity:
		lua_pushboolean(L, sfx->singularity);
		return 1;
	case sfxinfo_priority:
		lua_pushinteger(L, sfx->priority);
		return 1;
	case sfxinfo_flags:
		lua_pushinteger(L, sfx->pitch);
		return 1;
	case sfxinfo_volume:
		lua_pushinteger(L, sfx->volume);
		return 1;
	case sfxinfo_skinsound:
		lua_pushinteger(L, sfx->skinsound);
		return 1;
	}
	return luaL_error(L, "impossible error");
}
Example #15
0
static int patch_get(lua_State *L)
{
	patch_t *patch = *((patch_t **)luaL_checkudata(L, 1, META_PATCH));
	enum patch field = luaL_checkoption(L, 2, NULL, patch_opt);

	// patches are CURRENTLY always valid, expected to be cached with PU_STATIC
	// this may change in the future, so patch.valid still exists
	I_Assert(patch != NULL);

	switch (field)
	{
	case patch_valid:
		lua_pushboolean(L, patch != NULL);
		break;
	case patch_width:
		lua_pushinteger(L, SHORT(patch->width));
		break;
	case patch_height:
		lua_pushinteger(L, SHORT(patch->height));
		break;
	case patch_leftoffset:
		lua_pushinteger(L, SHORT(patch->leftoffset));
		break;
	case patch_topoffset:
		lua_pushinteger(L, SHORT(patch->topoffset));
		break;
	}
	return 1;
}
Example #16
0
// must match lua_Writer
static int dumpWriter(lua_State *L, const void *p, size_t sz, void *ud)
{
	FILE *handle = (FILE*)ud;
	I_Assert(handle != NULL);
	(void)L;
	if (!sz) return 0; // nothing to write? can't fail that! :D
	return (fwrite(p, 1, sz, handle) != sz); // if fwrite != sz, we've failed.
}
Example #17
0
// Uses astate to determine which state is calling it
// Then looks up which Lua action is assigned to that state and calls it
static void A_Lua(mobj_t *actor)
{
	boolean found = false;
	I_Assert(actor != NULL);

	// get the action for this state
	lua_getfield(gL, LUA_REGISTRYINDEX, LREG_STATEACTION);
	I_Assert(lua_istable(gL, -1));
	lua_pushlightuserdata(gL, astate);
	lua_rawget(gL, -2);
	I_Assert(lua_isfunction(gL, -1));
	lua_remove(gL, -2); // pop LREG_STATEACTION

	// get the name for this action, if possible.
	lua_getfield(gL, LUA_REGISTRYINDEX, LREG_ACTIONS);
	lua_pushnil(gL);
	while (lua_next(gL, -2))
	{
		if (lua_rawequal(gL, -1, -4))
		{
			found = true;
			superactions[superstack] = lua_tostring(gL, -2); // "A_ACTION"
			++superstack;
			lua_pop(gL, 2); // pop the name and function
			break;
		}
		lua_pop(gL, 1);
	}
	lua_pop(gL, 1); // pop LREG_ACTION

	LUA_PushUserdata(gL, actor, META_MOBJ);
	lua_pushinteger(gL, var1);
	lua_pushinteger(gL, var2);
	LUA_Call(gL, 3);

	if (found)
	{
		--superstack;
		superactions[superstack] = NULL;
	}

	lua_gc(gL, LUA_GCSTEP, 1);
}
Example #18
0
// add a HUD element for rendering
static int lib_hudadd(lua_State *L)
{
	enum hudhook field;

	luaL_checktype(L, 1, LUA_TFUNCTION);
	field = luaL_checkoption(L, 2, "game", hudhook_opt);

	lua_getfield(L, LUA_REGISTRYINDEX, "HUD");
	I_Assert(lua_istable(L, -1));
	lua_rawgeti(L, -1, field+2); // HUD[2+]
	I_Assert(lua_istable(L, -1));
	lua_remove(L, -2);

	lua_pushvalue(L, 1);
	lua_rawseti(L, -2, (int)(lua_objlen(L, -2) + 1));

	hudAvailable |= 1<<field;
	return 0;
}
Example #19
0
static int camera_get(lua_State *L)
{
	camera_t *cam = *((camera_t **)luaL_checkudata(L, 1, META_CAMERA));
	enum cameraf field = luaL_checkoption(L, 2, NULL, camera_opt);

	// cameras should always be valid unless I'm a nutter
	I_Assert(cam != NULL);

	switch (field)
	{
	case camera_chase:
		lua_pushboolean(L, cam->chase);
		break;
	case camera_aiming:
		lua_pushinteger(L, cam->aiming);
		break;
	case camera_x:
		lua_pushinteger(L, cam->x);
		break;
	case camera_y:
		lua_pushinteger(L, cam->y);
		break;
	case camera_z:
		lua_pushinteger(L, cam->z);
		break;
	case camera_angle:
		lua_pushinteger(L, cam->angle);
		break;
	case camera_subsector:
		LUA_PushUserdata(L, cam->subsector, META_SUBSECTOR);
		break;
	case camera_floorz:
		lua_pushinteger(L, cam->floorz);
		break;
	case camera_ceilingz:
		lua_pushinteger(L, cam->ceilingz);
		break;
	case camera_radius:
		lua_pushinteger(L, cam->radius);
		break;
	case camera_height:
		lua_pushinteger(L, cam->height);
		break;
	case camera_momx:
		lua_pushinteger(L, cam->momx);
		break;
	case camera_momy:
		lua_pushinteger(L, cam->momy);
		break;
	case camera_momz:
		lua_pushinteger(L, cam->momz);
		break;
	}
	return 1;
}
Example #20
0
void I_ShutdownSound(void)
{
	I_Assert(sound_started);
	sound_started = false;

#ifdef HAVE_LIBGME
	if (gme)
		gme_delete(gme);
#endif
	FMR(FMOD_System_Release(fsys));
}
Example #21
0
static void Lua_OnChange(void)
{
	I_Assert(gL != NULL);
	I_Assert(cvname != NULL);

	/// \todo Network this! XD_LUAVAR

	// From CV_OnChange registry field, get the function for this cvar by name.
	lua_getfield(gL, LUA_REGISTRYINDEX, "CV_OnChange");
	I_Assert(lua_istable(gL, -1));
	lua_getfield(gL, -1, cvname); // get function

	// From the CV_Vars registry field, get the cvar's userdata by name.
	lua_getfield(gL, LUA_REGISTRYINDEX, "CV_Vars");
	I_Assert(lua_istable(gL, -1));
	lua_getfield(gL, -1, cvname); // get consvar_t* userdata.
	lua_remove(gL, -2); // pop the CV_Vars table.

	LUA_Call(gL, 1); // call function(cvar)
	lua_pop(gL, 1); // pop CV_OnChange table
}
Example #22
0
// Wrapper for COM_AddCommand
static int lib_comAddCommand(lua_State *L)
{
	int com_return = -1;
	const char *luaname = luaL_checkstring(L, 1);

	// must store in all lowercase
	char *name = Z_StrDup(luaname);
	strlwr(name);

	luaL_checktype(L, 2, LUA_TFUNCTION);
	NOHUD
	if (lua_gettop(L) >= 3)
	{ // For the third argument, only take a boolean or a number.
		lua_settop(L, 3);
		if (lua_type(L, 3) != LUA_TBOOLEAN)
			luaL_checktype(L, 3, LUA_TNUMBER);
	}
	else
	{ // No third argument? Default to 0.
		lua_settop(L, 2);
		lua_pushinteger(L, 0);
	}

	lua_getfield(L, LUA_REGISTRYINDEX, "COM_Command");
	I_Assert(lua_istable(L, -1));

	lua_createtable(L, 2, 0);
		lua_pushvalue(L, 2);
		lua_rawseti(L, -2, 1);

		lua_pushvalue(L, 3);
		lua_rawseti(L, -2, 2);
	lua_setfield(L, -2, name);

	// Try to add the Lua command
	com_return = COM_AddLuaCommand(name);

	if (com_return < 0)
	{ // failed to add -- free the lowercased name and return error
		Z_Free(name);
		return luaL_error(L, "Couldn't add a new console command \"%s\"", luaname);
	}
	else if (com_return == 1)
	{ // command existed already -- free our name as the old string will continue to be used
		CONS_Printf("Replaced command \"%s\"\n", name);
		Z_Free(name);
	}
	else
	{ // new command was added -- do NOT free the string as it will forever be used by the console
		CONS_Printf("Added command \"%s\"\n", name);
	}
	return 0;
}
Example #23
0
// state_t *, field, number -> states[]
static int state_set(lua_State *L)
{
	state_t *st = *((state_t **)luaL_checkudata(L, 1, META_STATE));
	const char *field = luaL_checkstring(L, 2);
	lua_Integer value;

	if (hud_running)
		return luaL_error(L, "Do not alter states in HUD rendering code!");

	if (fastcmp(field,"sprite")) {
		value = luaL_checknumber(L, 3);
		if (value < SPR_NULL || value >= NUMSPRITES)
			return luaL_error(L, "sprite number %d is invalid.", value);
		st->sprite = (spritenum_t)value;
	} else if (fastcmp(field,"frame"))
		st->frame = (UINT32)luaL_checknumber(L, 3);
	else if (fastcmp(field,"tics"))
		st->tics = (INT32)luaL_checknumber(L, 3);
	else if (fastcmp(field,"action")) {
		switch(lua_type(L, 3))
		{
		case LUA_TNIL: // Null? Set the action to nothing, then.
			st->action.acp1 = NULL;
			break;
		case LUA_TSTRING: // It's a string, expect the name of a built-in action
			LUA_SetActionByName(st, lua_tostring(L, 3));
			break;
		case LUA_TFUNCTION: // It's a function (a Lua function or a C function? either way!)
			lua_getfield(L, LUA_REGISTRYINDEX, LREG_STATEACTION);
			I_Assert(lua_istable(L, -1));
			lua_pushlightuserdata(L, st); // We'll store this function by the state's pointer in the registry.
			lua_pushvalue(L, 3); // Bring it to the top of the stack
			lua_rawset(L, -3); // Set it in the registry
			lua_pop(L, 1); // pop LREG_STATEACTION
			st->action.acp1 = (actionf_p1)A_Lua; // Set the action for the userdata.
			break;
		default: // ?!
			return luaL_typerror(L, 3, "function");
		}
	} else if (fastcmp(field,"var1"))
		st->var1 = (INT32)luaL_checknumber(L, 3);
	else if (fastcmp(field,"var2"))
		st->var2 = (INT32)luaL_checknumber(L, 3);
	else if (fastcmp(field,"nextstate")) {
		value = luaL_checkinteger(L, 3);
		if (value < S_NULL || value >= NUMSTATES)
			return luaL_error(L, "nextstate number %d is invalid.", value);
		st->nextstate = (statenum_t)value;
	} else
		return luaL_error(L, LUA_QL("state_t") " has no field named " LUA_QS, field);

	return 0;
}
Example #24
0
void I_StartupSound(void)
{
	I_Assert(!sound_started);
	sound_started = true;

	FMR(FMOD_System_Create(&fsys));
	FMR(FMOD_System_SetDSPBufferSize(fsys, 44100 / 30, 2));
	FMR(FMOD_System_Init(fsys, 64, FMOD_INIT_VOL0_BECOMES_VIRTUAL, NULL));
	music_stream = NULL;
#ifdef HAVE_LIBGME
	gme = NULL;
#endif
	current_track = -1;
}
Example #25
0
static void NetArchiveHook(lua_CFunction archFunc)
{
	int TABLESINDEX;

	if (!gL)
		return;

	TABLESINDEX = lua_gettop(gL);
	lua_getfield(gL, LUA_REGISTRYINDEX, "hook");
	I_Assert(lua_istable(gL, -1));
	lua_rawgeti(gL, -1, hook_NetVars);
	lua_remove(gL, -2);
	I_Assert(lua_istable(gL, -1));

	lua_pushvalue(gL, TABLESINDEX);
	lua_pushcclosure(gL, archFunc, 1);
	lua_pushnil(gL);
	while (lua_next(gL, -3) != 0) {
		lua_pushvalue(gL, -3); // function
		LUA_Call(gL, 1);
	}
	lua_pop(gL, 2);
}
Example #26
0
// state_t *, field -> number
static int state_get(lua_State *L)
{
	state_t *st = *((state_t **)luaL_checkudata(L, 1, META_STATE));
	const char *field = luaL_checkstring(L, 2);
	lua_Integer number;

	if (fastcmp(field,"sprite"))
		number = st->sprite;
	else if (fastcmp(field,"frame"))
		number = st->frame;
	else if (fastcmp(field,"tics"))
		number = st->tics;
	else if (fastcmp(field,"action")) {
		const char *name;
		if (!st->action.acp1) // Action is NULL.
			return 0; // return nil.
		if (st->action.acp1 == (actionf_p1)A_Lua) { // This is a Lua function?
			lua_getfield(L, LUA_REGISTRYINDEX, LREG_STATEACTION);
			I_Assert(lua_istable(L, -1));
			lua_pushlightuserdata(L, st); // Push the state pointer and
			lua_rawget(L, -2); // use it to get the actual Lua function.
			lua_remove(L, -2); // pop LREG_STATEACTION
			return 1; // Return the Lua function.
		}
		name = LUA_GetActionName(&st->action); // find a hardcoded function name
		if (!name) // If it's not a hardcoded function and it's not a Lua function...
			return 0; // Just what is this??
		// get the function from the global
		// because the metatable will trigger.
		lua_getglobal(L, name); // actually gets from LREG_ACTIONS if applicable, and pushes a new C closure if not.
		lua_pushstring(L, name); // push the name we found.
		return 2; // return both the function and its name, in case somebody wanted to do a comparison by name or something?
	} else if (fastcmp(field,"var1"))
		number = st->var1;
	else if (fastcmp(field,"var2"))
		number = st->var2;
	else if (fastcmp(field,"nextstate"))
		number = st->nextstate;
	else if (devparm)
		return luaL_error(L, LUA_QL("state_t") " has no field named " LUA_QS, field);
	else
		return 0;

	lua_pushinteger(L, number);
	return 1;
}
Example #27
0
static int hudinfo_set(lua_State *L)
{
	hudinfo_t *info = *((hudinfo_t **)luaL_checkudata(L, 1, META_HUDINFO));
	enum hudinfo field = luaL_checkoption(L, 2, hudinfo_opt[0], hudinfo_opt);
	I_Assert(info != NULL);

	switch(field)
	{
	case hudinfo_x:
		info->x = (INT32)luaL_checkinteger(L, 3);
		break;
	case hudinfo_y:
		info->y = (INT32)luaL_checkinteger(L, 3);
		break;
	}
	return 0;
}
Example #28
0
static int hudinfo_get(lua_State *L)
{
	hudinfo_t *info = *((hudinfo_t **)luaL_checkudata(L, 1, META_HUDINFO));
	enum hudinfo field = luaL_checkoption(L, 2, hudinfo_opt[0], hudinfo_opt);
	I_Assert(info != NULL); // huditems are always valid

	switch(field)
	{
	case hudinfo_x:
		lua_pushinteger(L, info->x);
		break;
	case hudinfo_y:
		lua_pushinteger(L, info->y);
		break;
	}
	return 1;
}
Example #29
0
// Wrapper for COM_AddCommand commands
void COM_Lua_f(void)
{
	char *buf, *p;
	UINT8 i, flags;
	UINT16 len;
	INT32 playernum = consoleplayer;

	I_Assert(gL != NULL);
	lua_getfield(gL, LUA_REGISTRYINDEX, "COM_Command"); // push COM_Command
	I_Assert(lua_istable(gL, -1));

	// use buf temporarily -- must use lowercased string
	buf = Z_StrDup(COM_Argv(0));
	strlwr(buf);
	lua_getfield(gL, -1, buf); // push command info table
	I_Assert(lua_istable(gL, -1));
	lua_remove(gL, -2); // pop COM_Command
	Z_Free(buf);

	lua_rawgeti(gL, -1, 2); // push flags from command info table
	if (lua_isboolean(gL, -1))
		flags = (lua_toboolean(gL, -1) ? 1 : 0);
	else
		flags = (UINT8)lua_tointeger(gL, -1);
	lua_pop(gL, 1); // pop flags

	if (flags & 2) // flag 2: splitscreen player command.
	{
		if (!splitscreen)
		{
			lua_pop(gL, 1); // pop command info table
			return; // can't execute splitscreen command without player 2!
		}
		playernum = secondarydisplayplayer;
	}

	if (netgame)
	{ // Send the command through the network
		UINT8 argc;
		lua_pop(gL, 1); // pop command info table

		if (flags & 1 && !server && !IsPlayerAdmin(playernum)) // flag 1: only server/admin can use this command.
		{
			CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
			return;
		}

		if (COM_Argc() > UINT8_MAX)
			argc = UINT8_MAX;
		else
			argc = (UINT8)COM_Argc();
		if (argc == UINT8_MAX)
			len = UINT16_MAX;
		else
			len = (argc+1)*256;

		buf = malloc(len);
		p = buf;
		WRITEUINT8(p, argc);
		for (i = 0; i < argc; i++)
			WRITESTRINGN(p, COM_Argv(i), 255);
		if (flags & 2)
			SendNetXCmd2(XD_LUACMD, buf, p-buf);
		else
			SendNetXCmd(XD_LUACMD, buf, p-buf);
		free(buf);
		return;
	}

	// Do the command locally, NetXCmds don't go through outside of GS_LEVEL || GS_INTERMISSION
	lua_rawgeti(gL, -1, 1); // push function from command info table
	I_Assert(lua_isfunction(gL, -1));
	lua_remove(gL, -2); // pop command info table

	LUA_PushUserdata(gL, &players[playernum], META_PLAYER);
	for (i = 1; i < COM_Argc(); i++)
		lua_pushstring(gL, COM_Argv(i));
	LUA_Call(gL, (int)COM_Argc()); // COM_Argc is 1-based, so this will cover the player we passed too.
}
Example #30
0
static int lib_cvRegisterVar(lua_State *L)
{
	const char *k;
	lua_Integer i;
	consvar_t *cvar;
	luaL_checktype(L, 1, LUA_TTABLE);
	lua_settop(L, 1); // Clear out all other possible arguments, leaving only the first one.
	NOHUD
	cvar = lua_newuserdata(L, sizeof(consvar_t));
	luaL_getmetatable(L, META_CVAR);
	lua_setmetatable(L, -2);

#define FIELDERROR(f, e) luaL_error(L, "bad value for " LUA_QL(f) " in table passed to " LUA_QL("CV_RegisterVar") " (%s)", e);
#define TYPEERROR(f, t) FIELDERROR(f, va("%s expected, got %s", lua_typename(L, t), luaL_typename(L, -1)))

	lua_pushnil(L);
	while (lua_next(L, 1)) {
		// stack: cvar table, cvar userdata, key/index, value
		//            1             2            3        4
		i = 0;
		k = NULL;
		if (lua_isnumber(L, 3))
			i = lua_tointeger(L, 3);
		else if (lua_isstring(L, 3))
			k = lua_tostring(L, 3);

		if (i == 1 || (k && fasticmp(k, "name"))) {
			if (!lua_isstring(L, 4))
				TYPEERROR("name", LUA_TSTRING)
			cvar->name = Z_StrDup(lua_tostring(L, 4));
		} else if (i == 2 || (k && fasticmp(k, "defaultvalue"))) {
			if (!lua_isstring(L, 4))
				TYPEERROR("defaultvalue", LUA_TSTRING)
			cvar->defaultvalue = Z_StrDup(lua_tostring(L, 4));
		} else if (i == 3 || (k && fasticmp(k, "flags"))) {
			if (!lua_isnumber(L, 4))
				TYPEERROR("flags", LUA_TNUMBER)
			cvar->flags = (INT32)lua_tointeger(L, 4);
		} else if (i == 4 || (k && fasticmp(k, "PossibleValue"))) {
			if (lua_islightuserdata(L, 4)) {
				CV_PossibleValue_t *pv = lua_touserdata(L, 4);
				if (pv == CV_OnOff || pv == CV_YesNo || pv == CV_Unsigned || pv == CV_Natural)
					cvar->PossibleValue = pv;
				else
					FIELDERROR("PossibleValue", "CV_PossibleValue_t expected, got unrecognised pointer")
			} else if (lua_istable(L, 4)) {
				// Accepts tables in the form of {MIN=0, MAX=9999} or {Red=0, Green=1, Blue=2}
				// and converts them to CV_PossibleValue_t {{0,"MIN"},{9999,"MAX"}} or {{0,"Red"},{1,"Green"},{2,"Blue"}}
				//
				// I don't really like the way this does it because a single PossibleValue table
				// being used for multiple cvars will be converted and stored multiple times.
				// So maybe instead it should be a seperate function which must be run beforehand or something.
				size_t count = 0;
				CV_PossibleValue_t *cvpv;

				lua_pushnil(L);
				while (lua_next(L, 4)) {
					count++;
					lua_pop(L, 1);
				}

				lua_getfield(L, LUA_REGISTRYINDEX, "CV_PossibleValue");
				I_Assert(lua_istable(L, 5));
				lua_pushvalue(L, 2); // cvar userdata
				cvpv = lua_newuserdata(L, sizeof(CV_PossibleValue_t) * (count+1));
				lua_rawset(L, 5);
				lua_pop(L, 1); // pop CV_PossibleValue registry table

				i = 0;
				lua_pushnil(L);
				while (lua_next(L, 4)) {
					// stack: [...] PossibleValue table, index, value
					//                       4             5      6
					if (lua_type(L, 5) != LUA_TSTRING
					|| lua_type(L, 6) != LUA_TNUMBER)
						FIELDERROR("PossibleValue", "custom PossibleValue table requires a format of string=integer, i.e. {MIN=0, MAX=9999}");
					cvpv[i].strvalue = Z_StrDup(lua_tostring(L, 5));
					cvpv[i].value = (INT32)lua_tonumber(L, 6);
					i++;
					lua_pop(L, 1);
				}
				cvpv[i].value = 0;
				cvpv[i].strvalue = NULL;
				cvar->PossibleValue = cvpv;
			} else
				FIELDERROR("PossibleValue", va("%s or CV_PossibleValue_t expected, got %s", lua_typename(L, LUA_TTABLE), luaL_typename(L, -1)))
		} else if (cvar->flags & CV_CALL && (i == 5 || (k && fasticmp(k, "func")))) {