mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-11-11 07:11:39 +00:00
Lunatic: export C functions that may call into CON events using the Lua C API.
We must not call these functions using the FFI, since the Lua state is considered locked across such calls. git-svn-id: https://svn.eduke32.com/eduke32@3520 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
b1320d0ab5
commit
c66b891a38
6 changed files with 155 additions and 57 deletions
|
@ -752,8 +752,7 @@ dead:
|
|||
else vm.g_sp->shade += (sector[vm.g_sp->sectnum].floorshade-vm.g_sp->shade)>>1;
|
||||
}
|
||||
|
||||
// NOTE: Used from Lunatic
|
||||
void P_AddWeaponMaybeSwitch(DukePlayer_t *ps, int32_t weap)
|
||||
static void P_AddWeaponMaybeSwitch(DukePlayer_t *ps, int32_t weap)
|
||||
{
|
||||
if ((ps->weaponswitch & 1) && (ps->weaponswitch & 4))
|
||||
{
|
||||
|
@ -784,7 +783,12 @@ void P_AddWeaponMaybeSwitch(DukePlayer_t *ps, int32_t weap)
|
|||
P_AddWeaponNoSwitch(ps, weap);
|
||||
}
|
||||
|
||||
#if !defined LUNATIC
|
||||
#if defined LUNATIC
|
||||
void P_AddWeaponMaybeSwitchI(int32_t snum, int32_t weap)
|
||||
{
|
||||
P_AddWeaponMaybeSwitch(g_player[snum].ps, weap);
|
||||
}
|
||||
#else
|
||||
static void P_AddWeaponAmmoCommon(DukePlayer_t *ps, int32_t weap, int32_t amount)
|
||||
{
|
||||
P_AddAmmo(weap, ps, amount);
|
||||
|
|
|
@ -4,6 +4,9 @@ local require = require
|
|||
local ffi = require("ffi")
|
||||
local ffiC = ffi.C
|
||||
|
||||
-- Lua C API functions, this comes from El_PushCFunctions() in lunatic_game.c.
|
||||
local CF = CF
|
||||
|
||||
local bit = require("bit")
|
||||
local io = require("io")
|
||||
local math = require("math")
|
||||
|
@ -149,6 +152,13 @@ local function krandand(mask)
|
|||
return bit.band(ffiC.krand(), mask)
|
||||
end
|
||||
|
||||
local function check_isnumber(...)
|
||||
local vals = {...}
|
||||
for i=1,#vals do
|
||||
assert(type(vals[i])=="number")
|
||||
end
|
||||
end
|
||||
|
||||
-- Lunatic's "insertsprite" is a wrapper around the game "A_InsertSprite", not
|
||||
-- the engine "insertsprite".
|
||||
--
|
||||
|
@ -187,20 +197,21 @@ function insertsprite(tab_or_tilenum, ...)
|
|||
|
||||
check_tile_idx(tilenum)
|
||||
check_sector_idx(sectnum)
|
||||
check_isnumber(shade, xrepeat, yrepeat, ang, xvel, zvel, owner)
|
||||
|
||||
if (statnum >= ffiC.MAXSTATUS) then
|
||||
if (statnum >= ffiC.MAXSTATUS+0ULL) then
|
||||
error("invalid 'statnum' argument to insertsprite: must be a status number (0 .. MAXSTATUS-1)", 2)
|
||||
end
|
||||
|
||||
return ffiC.A_InsertSprite(sectnum, pos.x, pos.y, pos.z, tilenum,
|
||||
shade, xrepeat, yrepeat, ang, xvel, zvel,
|
||||
owner, statnum)
|
||||
return CF.A_InsertSprite(sectnum, pos.x, pos.y, pos.z, tilenum,
|
||||
shade, xrepeat, yrepeat, ang, xvel, zvel,
|
||||
owner, statnum)
|
||||
end
|
||||
|
||||
-- INTERNAL USE ONLY.
|
||||
function _addtodelqueue(spritenum)
|
||||
check_sprite_idx(spritenum)
|
||||
ffiC.A_AddToDeleteQueue(spritenum)
|
||||
CF.A_AddToDeleteQueue(spritenum)
|
||||
end
|
||||
|
||||
-- This corresponds to the first (spawn from parent sprite) form of A_Spawn().
|
||||
|
@ -212,9 +223,9 @@ function spawn(parentspritenum, tilenum, addtodelqueue)
|
|||
return -1
|
||||
end
|
||||
|
||||
local i = ffiC.A_Spawn(parentspritenum, tilenum)
|
||||
local i = CF.A_Spawn(parentspritenum, tilenum)
|
||||
if (addtodelqueue) then
|
||||
ffiC.A_AddToDeleteQueue(i)
|
||||
CF.A_AddToDeleteQueue(i)
|
||||
end
|
||||
return i
|
||||
end
|
||||
|
@ -222,7 +233,7 @@ end
|
|||
-- This is the second A_Spawn() form. INTERNAL USE ONLY.
|
||||
function _spawnexisting(spritenum)
|
||||
check_sprite_idx(spritenum)
|
||||
return ffiC.A_Spawn(-1, spritenum)
|
||||
return CF.A_Spawn(-1, spritenum)
|
||||
end
|
||||
|
||||
-- A_SpawnMultiple clone
|
||||
|
@ -247,7 +258,7 @@ function _shoot(i, tilenum, zvel)
|
|||
|
||||
zvel = zvel and int16_st(zvel).s or 0x80000000 -- SHOOT_HARDCODED_ZVEL
|
||||
|
||||
return ffiC.A_ShootWithZvel(i, tilenum, zvel)
|
||||
return CF.A_ShootWithZvel(i, tilenum, zvel)
|
||||
end
|
||||
|
||||
function isenemytile(tilenum)
|
||||
|
@ -418,7 +429,7 @@ local function P_AddWeaponAmmoCommon(ps, weap, amount)
|
|||
P_AddAmmo(ps, weap, amount)
|
||||
|
||||
if (ps.curr_weapon==ffiC.KNEE_WEAPON and ps:have_weapon(weap)) then
|
||||
ffiC.P_AddWeaponMaybeSwitch(ps, weap);
|
||||
CF.P_AddWeaponMaybeSwitchI(ps.weapon._p, weap);
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -808,7 +819,7 @@ end
|
|||
function _A_Shoot(i, atwith)
|
||||
check_sprite_idx(i)
|
||||
check_tile_idx(atwith)
|
||||
return ffiC.A_ShootWithZvel(i, atwith, 0x80000000) -- SHOOT_HARDCODED_ZVEL
|
||||
return CF.A_ShootWithZvel(i, atwith, 0x80000000) -- SHOOT_HARDCODED_ZVEL
|
||||
end
|
||||
|
||||
function _A_IncurDamage(sn)
|
||||
|
@ -818,7 +829,7 @@ end
|
|||
|
||||
function _VM_FallSprite(i)
|
||||
check_sprite_idx(i)
|
||||
ffiC.VM_FallSprite(i)
|
||||
CF.VM_FallSprite(i)
|
||||
end
|
||||
|
||||
function _sizeto(i, xr, yr)
|
||||
|
@ -835,7 +846,7 @@ end
|
|||
function _A_Spawn(j, pn)
|
||||
local bound_check = sector[sprite[j].sectnum] -- two in one whack
|
||||
check_tile_idx(pn)
|
||||
return ffiC.A_Spawn(j, pn)
|
||||
return CF.A_Spawn(j, pn)
|
||||
end
|
||||
|
||||
function _pstomp(ps, i)
|
||||
|
@ -864,8 +875,8 @@ function _pkick(ps, spr)
|
|||
end
|
||||
|
||||
function _VM_ResetPlayer2(snum)
|
||||
local bound_check = player[snum]
|
||||
return (ffiC.VM_ResetPlayer2(snum)~=0)
|
||||
check_player_idx(snum)
|
||||
return (CF.VM_ResetPlayer2(snum)~=0)
|
||||
end
|
||||
|
||||
local PALBITS = { [0]=1, [21]=2, [23]=4 }
|
||||
|
@ -933,7 +944,8 @@ function _selectnextinv(ps)
|
|||
end
|
||||
|
||||
function _checkavailweapon(pli)
|
||||
ffiC.P_CheckWeapon(player[pli])
|
||||
check_player_idx(pli)
|
||||
CF.P_CheckWeaponI(pli)
|
||||
end
|
||||
|
||||
function _addphealth(ps, aci, hlthadd)
|
||||
|
@ -991,7 +1003,7 @@ function _addweapon(ps, weap, amount)
|
|||
end
|
||||
|
||||
if (not ps:have_weapon(weap)) then
|
||||
ffiC.P_AddWeaponMaybeSwitch(ps, weap);
|
||||
CF.P_AddWeaponMaybeSwitchI(ps.weapon._p, weap);
|
||||
elseif (have_ammo_at_max(ps, weap)) then
|
||||
return true
|
||||
end
|
||||
|
@ -1001,7 +1013,8 @@ end
|
|||
|
||||
function _A_RadiusDamage(i, r, hp1, hp2, hp3, hp4)
|
||||
check_sprite_idx(i)
|
||||
ffiC.A_RadiusDamage(i, r, hp1, hp2, hp3, hp4)
|
||||
check_isnumber(r, hp1, hp2, hp3, hp4)
|
||||
CF.A_RadiusDamage(i, r, hp1, hp2, hp3, hp4)
|
||||
end
|
||||
|
||||
function _testkey(pli, synckey)
|
||||
|
@ -1045,7 +1058,7 @@ function _operate(spritenum)
|
|||
return
|
||||
end
|
||||
end
|
||||
ffiC.G_OperateSectors(tag.sector, spritenum)
|
||||
CF.G_OperateSectors(tag.sector, spritenum)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1056,21 +1069,22 @@ end
|
|||
function _operatesectors(sectnum, spritenum)
|
||||
check_sector_idx(sectnum)
|
||||
check_sprite_idx(spritenum) -- XXX: -1 permissible under certain circumstances?
|
||||
ffiC.G_OperateSectors(sectnum, spritenum)
|
||||
CF.G_OperateSectors(sectnum, spritenum)
|
||||
end
|
||||
|
||||
function _operateactivators(tag, playernum)
|
||||
check_player_idx(playernum)
|
||||
-- NOTE: passing oob playernum would be safe because G_OperateActivators
|
||||
-- bound-checks it
|
||||
ffiC.G_OperateActivators(tag, playernum)
|
||||
assert(type(tag)=="number")
|
||||
CF.G_OperateActivators(tag, playernum)
|
||||
end
|
||||
|
||||
function _activatebysector(sectnum, spritenum)
|
||||
local didit = false
|
||||
for i in spriteofsect(sectnum) do
|
||||
if (sprite[i].picnum==D.ACTIVATOR) then
|
||||
ffiC.G_OperateActivators(sprite[i].lotag, -1)
|
||||
CF.G_OperateActivators(sprite[i].lotag, -1)
|
||||
end
|
||||
end
|
||||
if (didit) then
|
||||
|
@ -1463,7 +1477,7 @@ function _sound(aci, sndidx)
|
|||
-- A_PlaySound() returns early if the sound index is oob, but IMO it's good
|
||||
-- style to throw an error instead of silently failing.
|
||||
check_sound_idx(sndidx)
|
||||
ffiC.A_PlaySound(sndidx, aci)
|
||||
CF.A_PlaySound(sndidx, aci)
|
||||
end
|
||||
|
||||
function _globalsound(pli, sndidx)
|
||||
|
|
|
@ -520,26 +520,12 @@ const int32_t g_currentMenu;
|
|||
uint16_t g_earthquakeTime;
|
||||
char CheatKeys[2];
|
||||
|
||||
// Functions marked with 'EVENT' may call events.
|
||||
// http://www.freelists.org/post/luajit/intermitten-lua-pcall-crash-on-x86-64-linux,1
|
||||
// Must not have functions here that may call events directly or
|
||||
// indirectly. See lunatic_game.c.
|
||||
|
||||
int32_t A_IncurDamage(int32_t sn); // not bound-checked!
|
||||
void P_AddWeaponMaybeSwitch(DukePlayer_t *ps, int32_t weap); // EVENT
|
||||
void P_CheckWeapon(DukePlayer_t *p); // EVENT
|
||||
int32_t A_ShootWithZvel(int32_t i, int32_t atwith, int32_t override_zvel); // EVENT
|
||||
int32_t A_Spawn(int32_t j, int32_t pn); // EVENT
|
||||
void VM_FallSprite(int32_t i); // EVENT
|
||||
int32_t VM_ResetPlayer2(int32_t snum); // EVENT
|
||||
void A_RadiusDamage(int32_t i, int32_t r, int32_t, int32_t, int32_t, int32_t); // EVENT
|
||||
void G_OperateSectors(int32_t sn, int32_t ii); // EVENT
|
||||
void G_OperateActivators(int32_t low,int32_t snum); // EVENT
|
||||
int32_t G_CheckActivatorMotion(int32_t lotag);
|
||||
int32_t A_Dodge(spritetype *s);
|
||||
// EVENT:
|
||||
int32_t A_InsertSprite(int32_t whatsect,int32_t s_x,int32_t s_y,int32_t s_z,int32_t s_pn,int32_t s_s,
|
||||
int32_t s_xr,int32_t s_yr,int32_t s_a,int32_t s_ve,int32_t s_zv,int32_t s_ow,int32_t s_ss);
|
||||
int32_t A_Spawn(int32_t j, int32_t pn); // EVENT
|
||||
void A_AddToDeleteQueue(int32_t i); // EVENT
|
||||
int32_t A_MoveSprite(int32_t spritenum, const vec3_t *change, uint32_t cliptype);
|
||||
void P_DoQuote(int32_t q, DukePlayer_t *p);
|
||||
void G_AddUserQuote(const char *daquote);
|
||||
|
@ -554,7 +540,6 @@ int32_t G_StartTrack(int32_t level);
|
|||
const char *KB_ScanCodeToString(uint8_t scancode);
|
||||
|
||||
int32_t A_CheckAnySoundPlaying(int32_t i);
|
||||
int32_t A_PlaySound(uint32_t num, int32_t i); // EVENT
|
||||
int32_t S_CheckSoundPlaying(int32_t i, int32_t num);
|
||||
void S_StopEnvSound(int32_t num, int32_t i);
|
||||
int32_t FX_StopAllSounds(void);
|
||||
|
|
|
@ -133,21 +133,8 @@ rand_jkiss_dbl;
|
|||
md4once;
|
||||
|
||||
A_IncurDamage;
|
||||
P_AddWeaponMaybeSwitch;
|
||||
P_CheckWeapon;
|
||||
A_ShootWithZvel;
|
||||
A_IncurDamage;
|
||||
A_Spawn;
|
||||
VM_FallSprite;
|
||||
VM_ResetPlayer2;
|
||||
A_RadiusDamage;
|
||||
G_OperateSectors;
|
||||
G_OperateActivators;
|
||||
G_CheckActivatorMotion;
|
||||
A_Dodge;
|
||||
A_InsertSprite;
|
||||
A_Spawn;
|
||||
A_AddToDeleteQueue;
|
||||
A_MoveSprite;
|
||||
P_DoQuote;
|
||||
G_AddUserQuote;
|
||||
|
@ -161,7 +148,6 @@ G_StartTrack;
|
|||
KB_ScanCodeToString;
|
||||
|
||||
A_CheckAnySoundPlaying;
|
||||
A_PlaySound;
|
||||
S_CheckSoundPlaying;
|
||||
S_StopEnvSound;
|
||||
FX_StopAllSounds;
|
||||
|
|
|
@ -221,6 +221,106 @@ static int our_traceback_CF(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
////// Lua C-API interfaces for C game functions that may call events.
|
||||
// http://www.freelists.org/post/luajit/intermitten-lua-pcall-crash-on-x86-64-linux,1
|
||||
|
||||
// Some of these are duplicate declarations:
|
||||
extern void P_AddWeaponMaybeSwitchI(int32_t snum, int32_t weap);
|
||||
extern void P_CheckWeaponI(int32_t snum);
|
||||
extern int32_t A_ShootWithZvel(int32_t i, int32_t atwith, int32_t override_zvel);
|
||||
extern int32_t A_Spawn(int32_t j, int32_t pn);
|
||||
extern void VM_FallSprite(int32_t i);
|
||||
extern int32_t VM_ResetPlayer2(int32_t snum);
|
||||
extern void A_RadiusDamage(int32_t i, int32_t r, int32_t, int32_t, int32_t, int32_t);
|
||||
extern void G_OperateSectors(int32_t sn, int32_t ii);
|
||||
extern void G_OperateActivators(int32_t low,int32_t snum);
|
||||
extern int32_t A_InsertSprite(int32_t whatsect,int32_t s_x,int32_t s_y,int32_t s_z,int32_t s_pn,int32_t s_s,
|
||||
int32_t s_xr,int32_t s_yr,int32_t s_a,int32_t s_ve,int32_t s_zv,int32_t s_ow,int32_t s_ss);
|
||||
extern void A_AddToDeleteQueue(int32_t i);
|
||||
extern int32_t A_PlaySound(uint32_t num, int32_t i);
|
||||
|
||||
#define LARG(index) lua_tointeger(L, index)
|
||||
|
||||
#define ONE_ARG LARG(1)
|
||||
#define TWO_ARGS LARG(1), LARG(2)
|
||||
#define THREE_ARGS LARG(1), LARG(2), LARG(3)
|
||||
|
||||
#define CALL_WITH_RET(Name, ...) \
|
||||
int32_t ret = Name(__VA_ARGS__); \
|
||||
lua_pushinteger(L, ret); \
|
||||
return 1
|
||||
|
||||
#define CALL_WITHOUT_RET(Name, ...) \
|
||||
Name(__VA_ARGS__); \
|
||||
return 0
|
||||
|
||||
#define DEFINE_RET_CFUNC(Name, ...) \
|
||||
static int32_t Name##_CF(lua_State *L) \
|
||||
{ \
|
||||
CALL_WITH_RET(Name, __VA_ARGS__); \
|
||||
}
|
||||
|
||||
#define DEFINE_VOID_CFUNC(Name, ...) \
|
||||
static int32_t Name##_CF(lua_State *L) \
|
||||
{ \
|
||||
CALL_WITHOUT_RET(Name, __VA_ARGS__); \
|
||||
}
|
||||
|
||||
// NOTE: player struct -> player index -> player struct ugliness because
|
||||
// pointers to FFI cdata apparently can't be reliably passed via lua_getpointer().
|
||||
// Not to mention that lua_getpointer() returns _const_ void*.
|
||||
DEFINE_VOID_CFUNC(P_AddWeaponMaybeSwitchI, TWO_ARGS)
|
||||
DEFINE_VOID_CFUNC(P_CheckWeaponI, ONE_ARG)
|
||||
DEFINE_RET_CFUNC(A_ShootWithZvel, THREE_ARGS)
|
||||
DEFINE_RET_CFUNC(A_Spawn, TWO_ARGS)
|
||||
DEFINE_VOID_CFUNC(VM_FallSprite, ONE_ARG)
|
||||
DEFINE_RET_CFUNC(VM_ResetPlayer2, ONE_ARG)
|
||||
DEFINE_VOID_CFUNC(A_RadiusDamage, LARG(1), LARG(2), LARG(3), LARG(4), LARG(5), LARG(6))
|
||||
DEFINE_VOID_CFUNC(G_OperateSectors, TWO_ARGS)
|
||||
DEFINE_VOID_CFUNC(G_OperateActivators, TWO_ARGS)
|
||||
DEFINE_RET_CFUNC(A_InsertSprite, LARG(1), LARG(2), LARG(3), LARG(4), LARG(5), LARG(6),
|
||||
LARG(7), LARG(8), LARG(9), LARG(10), LARG(11), LARG(12), LARG(13))
|
||||
DEFINE_VOID_CFUNC(A_AddToDeleteQueue, ONE_ARG)
|
||||
DEFINE_RET_CFUNC(A_PlaySound, TWO_ARGS)
|
||||
|
||||
#define CFUNC_REG(Name) { #Name, Name##_CF }
|
||||
|
||||
struct { const char *name; lua_CFunction func; } cfuncs[] =
|
||||
{
|
||||
CFUNC_REG(P_AddWeaponMaybeSwitchI),
|
||||
CFUNC_REG(P_CheckWeaponI),
|
||||
CFUNC_REG(A_ShootWithZvel),
|
||||
CFUNC_REG(A_Spawn),
|
||||
CFUNC_REG(VM_FallSprite),
|
||||
CFUNC_REG(VM_ResetPlayer2),
|
||||
CFUNC_REG(A_RadiusDamage),
|
||||
CFUNC_REG(G_OperateSectors),
|
||||
CFUNC_REG(G_OperateActivators),
|
||||
CFUNC_REG(A_InsertSprite),
|
||||
CFUNC_REG(A_Spawn),
|
||||
CFUNC_REG(A_AddToDeleteQueue),
|
||||
CFUNC_REG(A_PlaySound),
|
||||
};
|
||||
|
||||
// Creates a global table "CF" containing the functions from cfuncs[].
|
||||
static void El_PushCFunctions(lua_State *L)
|
||||
{
|
||||
int32_t i;
|
||||
|
||||
lua_newtable(L);
|
||||
|
||||
for (i=0; i<(signed)sizeof(cfuncs)/(signed)sizeof(cfuncs[0]); i++)
|
||||
{
|
||||
lua_pushstring(L, cfuncs[i].name);
|
||||
lua_pushcfunction(L, cfuncs[i].func);
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
|
||||
lua_setglobal(L, "CF");
|
||||
}
|
||||
|
||||
//////
|
||||
|
||||
static void El_StateSetup(lua_State *L)
|
||||
{
|
||||
luaopen_lpeg(L);
|
||||
|
@ -232,6 +332,8 @@ static void El_StateSetup(lua_State *L)
|
|||
lua_pushcfunction(L, SetActor_CF);
|
||||
lua_setglobal(L, "gameactor_internal");
|
||||
|
||||
El_PushCFunctions(L);
|
||||
|
||||
Bassert(lua_gettop(L)==0);
|
||||
|
||||
// This is for engine-side Lua:
|
||||
|
|
|
@ -3302,6 +3302,13 @@ void P_CheckWeapon(DukePlayer_t *p)
|
|||
P_ChangeWeapon(p, weapon);
|
||||
}
|
||||
|
||||
#ifdef LUNATIC
|
||||
void P_CheckWeaponI(int32_t snum)
|
||||
{
|
||||
P_CheckWeapon(g_player[snum].ps);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void P_CheckTouchDamage(DukePlayer_t *p, int32_t obj)
|
||||
{
|
||||
if ((obj = VM_OnEvent(EVENT_CHECKTOUCHDAMAGE, p->i, sprite[p->i].yvel, -1, obj)) == -1)
|
||||
|
|
Loading…
Reference in a new issue