Lunatic: more glue, fixes, backtrace for code called back from C.

git-svn-id: https://svn.eduke32.com/eduke32@3345 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2012-12-29 15:21:32 +00:00
parent 80f3e132b0
commit 5fc9bb9779
8 changed files with 66 additions and 39 deletions

View file

@ -17,6 +17,7 @@ typedef struct
// helpers taking the lua_State directly:
void L_SetupDebugTraceback(lua_State *L);
void L_PushDebugTraceback(lua_State *L);
void L_CheckAndRegisterFunction(lua_State *L, void *regkeyaddr);
// Callback on Lua error. <str> must be used immediately or strdup'd.

View file

@ -35,6 +35,14 @@ void L_SetupDebugTraceback(lua_State *L)
lua_pop(L, 2);
}
void L_PushDebugTraceback(lua_State *L)
{
// get debug.traceback
lua_pushlightuserdata(L, &debug_traceback_key);
lua_gettable(L, LUA_REGISTRYINDEX);
Bassert(lua_isfunction(L, -1));
}
static int32_t read_whole_file(const char *fn, char **retbufptr)
{
@ -122,10 +130,7 @@ int L_RunString(L_State *estate, char *buf, int dofreebuf)
// -- lua --
Bassert(lua_gettop(L)==0);
// get debug.traceback
lua_pushlightuserdata(L, &debug_traceback_key);
lua_gettable(L, LUA_REGISTRYINDEX);
Bassert(lua_isfunction(L, -1));
L_PushDebugTraceback(L);
i = luaL_loadstring(L, buf);
Bassert(lua_gettop(L)==2);

View file

@ -106,6 +106,7 @@ int32_t VM_OnEvent(int32_t iEventID, int32_t iActor, int32_t iPlayer, int32_t lD
#ifdef LUNATIC
const double t = gethitickms();
// TODO: handling of RETURN gamevar / iReturn / this function's return value
if (L_IsInitialized(&g_ElState) && El_HaveEvent(iEventID))
El_CallEvent(&g_ElState, iEventID, iActor, iPlayer, lDist);
#endif
@ -2002,6 +2003,8 @@ nullquote:
actor[i].flags = 0;
sprite[i].hitag = 0;
#if !defined LUNATIC_ONLY
// TODO: Lunatic
if (g_tile[sprite[i].picnum].execPtr)
{
// offsets
@ -2009,6 +2012,7 @@ nullquote:
T2 = *(g_tile[sprite[i].picnum].execPtr+2); // move
sprite[i].hitag = *(g_tile[sprite[i].picnum].execPtr+3); // ai bits
}
#endif
}
changespritestat(i,j);
continue;
@ -5230,13 +5234,19 @@ void A_Execute(int32_t iActor,int32_t iPlayer,int32_t lDist)
if (L_IsInitialized(&g_ElState) && El_HaveActor(vm.g_sp->picnum))
killit = (El_CallActor(&g_ElState, vm.g_sp->picnum, iActor, iPlayer, lDist)==1);
else if (g_tile[vm.g_sp->picnum].execPtr)
{
#endif
insptr = 4 + (g_tile[vm.g_sp->picnum].execPtr);
VM_Execute(1);
insptr = NULL;
#if !defined LUNATIC_ONLY
insptr = 4 + (g_tile[vm.g_sp->picnum].execPtr);
VM_Execute(1);
insptr = NULL;
#endif
#ifdef LUNATIC
}
g_actorTotalMs[vm.g_sp->picnum] += gethitickms()-t;
g_actorCalls[vm.g_sp->picnum]++;
#endif

View file

@ -13,14 +13,13 @@ local error = error
local type = type
local unpack = unpack
local player = assert(player)
local defs_c = require("defs_common")
local cansee = defs_c.cansee
local neartag = defs_c.neartag
local inside = defs_c.inside
local actor, player = assert(actor), assert(player)
local dc = require("defs_common")
local cansee, hitscan, neartag = dc.cansee, dc.hitscan, dc.neartag
local inside = dc.inside
-- NOTE FOR RELEASE: the usually global stuff like "sprite" etc. ought to be
-- accessed as locals here
local sector, wall, sprite = dc.sector, dc.wall, dc.sprite
local spritesofsect = dc.spritesofsect
module(...)
@ -155,9 +154,9 @@ function insertsprite(tab_or_tilenum, ...)
local tilenum, pos, sectnum -- mandatory
-- optional with defaults:
local owner, statnum
local shade, xrepeat, yrepeat, xvel, zvel = 0, 48, 48, 0, 0
local shade, xrepeat, yrepeat, ang, xvel, zvel = 0, 48, 48, 0, 0, 0
if (type(tab_or_sectnum)=="table") then
if (type(tab_or_tilenum)=="table") then
local tab = tab_or_tilenum
tilenum, pos, sectnum = unpack(tab, 1, 3)
owner = tab[4] or tab.owner or -1
@ -165,10 +164,11 @@ function insertsprite(tab_or_tilenum, ...)
shade = shade and tab.shade
xrepeat = xrepeat and tab.xrepeat
yrepeat = yrepeat and tab.yrepeat
ang = ang and (tab.ang % 2048)
xvel = xvel and tab.xvel
zvel = zvel and tab.zvel
else
tilenum = table_or_tilenum
tilenum = tab_or_tilenum
local args = {...}
pos, sectnum = unpack(args, 1, 2)
owner = args[3] or -1
@ -179,7 +179,7 @@ function insertsprite(tab_or_tilenum, ...)
error("invalid insertsprite call: 'sectnum' and 'tilenum' must be numbers", 2)
end
check_tile_idx(tilenum)
defs_c.check_sector_idx(sectnum)
dc.check_sector_idx(sectnum)
if (statnum >= ffiC.MAXSTATUS) then
error("invalid 'statnum' argument to insertsprite: must be a status number (0 .. MAXSTATUS-1)", 2)
end
@ -231,7 +231,7 @@ function _spawnmany(ow, tilenum, n)
end
function isenemytile(tilenum)
return (bit.band(ffiC.g_tile[tilenum], ffiC.SFLAG_BADGUY)~=0)
return (bit.band(ffiC.g_tile[tilenum].flags, ffiC.SFLAG_BADGUY)~=0)
end
function rotatesprite(x, y, zoom, ang, tilenum, shade, pal, orientation,
@ -577,12 +577,12 @@ local function manhatdist(v1, v2)
end
-- "otherspr" is either player or holoduke sprite
local function A_GetFurthestVisiblePoint(aci, otherspr)
if (bit.band(actor[aci].get_t_data(0), 63) ~= 0) then
local function A_FurthestVisiblePoint(aci, otherspr)
if (bit.band(actor[aci]:get_t_data(0), 63) ~= 0) then
return
end
local angincs = (ud.player_skill < 3) and 1024 or 2048/(1+krandand(1))
local angincs = (ffiC.ud.player_skill < 3) and 1024 or 2048/(1+krandand(1))
local j = 0
repeat
@ -590,7 +590,7 @@ local function A_GetFurthestVisiblePoint(aci, otherspr)
local hit = hitscan(otherspr^(16*256), otherspr.sectnum,
c, s, 16384-krandand(32767), ffiC.CLIPMASK1)
local dother = manhatdist(hit.pos, otherspr)
local dactor = manhatdist(hit.pos, spr)
local dactor = manhatdist(hit.pos, sprite[aci])
if (dother < dactor and hit.sect >= 0) then
if (cansee(hit.pos, hit.sect, otherspr^(16*256), otherspr.sectnum)) then
@ -609,7 +609,7 @@ function _cansee(aci, ps)
local spr = sprite[aci]
local s = sprite[ps.i]
if (ps.holoduke_on) then
if (ps.holoduke_on >= 0) then
-- If holoduke is on, let them target holoduke first.
local hs = sprite[ps.holoduke_on]
@ -623,7 +623,7 @@ function _cansee(aci, ps)
if (not can) then
-- Search around for target player.
local hit = A_GetFurthestVisiblePoint(aci, s)
local hit = A_FurthestVisiblePoint(aci, s)
if (hit ~= nil) then
can = true
actor[aci].lastvx = hit.pos.x
@ -728,7 +728,7 @@ local SK = {
RUN = 5,
}
local function _ifp(flags, pli, aci)
function _ifp(flags, pli, aci)
local l = flags
local ps = player[pli]
local vel = sprite[ps.i].xvel
@ -747,7 +747,7 @@ local function _ifp(flags, pli, aci)
j = true
elseif (band(l,4)~=0 and vel >= 8 and _testkey(pli, SK.RUN)) then
j = true
elseif (band(l,64)~=0 and ps.pos.z < (sprite[_aci].z-(48*256))) then
elseif (band(l,64)~=0 and ps.pos.z < (sprite[aci].z-(48*256))) then
j = true
elseif (band(l,128)~=0 and vel <= -8 and not _testkey(pli, SK.RUN)) then
j = true
@ -769,7 +769,7 @@ local function _ifp(flags, pli, aci)
j = true
elseif (band(l,65536)~=0) then
-- TODO: multiplayer branch
if (_angdiffabs(ps.ang, ffiC.getangle(sprite[_aci].x-ps.pos.x, sprite[_aci].y-ps.pos.y)) < 128) then
if (_angdiffabs(ps.ang, ffiC.getangle(sprite[aci].x-ps.pos.x, sprite[aci].y-ps.pos.y)) < 128) then
j = true
end
end
@ -803,12 +803,12 @@ local INVENTILE = {
function _checkrespawn(spr)
if (spr:isenemy()) then
return (ud.respawn_monsters~=0)
return (ffiC.ud.respawn_monsters~=0)
end
if (INVENTILE[spr.picnum]) then
return (ud.respawn_inventory~=0)
return (ffiC.ud.respawn_inventory~=0)
end
return (ud.respawn_items~=0)
return (ffiC.ud.respawn_items~=0)
end

View file

@ -451,6 +451,7 @@ int32_t g_elCallDepth;
actor_t actor[MAXSPRITES];
user_defs ud;
playerdata_t g_player[MAXPLAYERS];
tiledata_t g_tile[MAXTILES];
const int32_t playerswhenstarted;
int32_t lastvisinc;
@ -510,7 +511,7 @@ end
-- Add game-side metamethods to "spritetype" and register it with "metatype"
defs_c.spritetype_mt.__index.isenemy = function(s)
return (bit.band(ffiC.g_tile[s.picnum], ffiC.SFLAG_BADGUY)~=0)
return (bit.band(ffiC.g_tile[s.picnum].flags, ffiC.SFLAG_BADGUY)~=0)
end
ffi.metatype("spritetype", defs_c.spritetype_mt)
@ -527,9 +528,12 @@ local tmpmt = {
}
player = setmtonce({}, tmpmt)
-- needed by "control"
actor = defs_c.creategtab(ffiC.actor, ffiC.MAXSPRITES, "actor[]")
--== Custom operations for BUILD data structures ==--
-- declares struct action and struct move, and their ID-wrapped types
-- con_action_t and con_move_t
-- Among other things, declares struct action and struct move, and their
-- ID-wrapped types con_action_t and con_move_t
local con = require("control")
local MV, AC, AI = con.MV, con.AC, con.AI
@ -623,6 +627,7 @@ local actor_mt = {
a.t_data[0] = 0
local i = a-ffi.cast(actor_ptr_ct, ffiC.actor[0])
assert(not (i >= ffiC.MAXSPRITES+0ULL))
ffiC.sprite[i].hitag = movflags or 0
-- TODO: random angle moveflag
@ -1102,6 +1107,7 @@ end
G_.gameevent = our_gameevent
G_.gameactor = our_gameactor
G_.player = player -- from above
G_.actor = actor -- from above
---=== Lunatic interpreter setup ===---
@ -1154,9 +1160,6 @@ setmtonce(gv, tmpmt)
-- This will create 'sprite', 'wall', etc. HERE, i.e. in the environment of this chunk
defs_c.create_globals(_G)
---- indirect C array access ----
actor = defs_c.creategtab(ffiC.actor, ffiC.MAXSPRITES, "actor[]")
function TEMP_getvollev() -- REMOVE
return ffiC.ud.volume_number+1, ffiC.ud.level_number+1
end

View file

@ -69,6 +69,7 @@ G_DoGameStartup;
actor;
ud;
g_player;
g_tile;
playerswhenstarted;
lastvisinc;

View file

@ -870,7 +870,7 @@ local Ci = {
clipdist = cmd(D)
/ SPS".clipdist=%1",
sizeto = cmd(D,D)
/ "_con._sizeto(_aci)", -- TODO: see control.lua:_sizeto
/ "_con._sizeto(_aci,%1,%2)", -- TODO: see control.lua:_sizeto
sizeat = cmd(D,D)
/ (SPS".xrepeat,"..SPS".yrepeat=%1,%2"),
strength = cmd(D)

View file

@ -281,7 +281,9 @@ static int32_t call_regd_function3(lua_State *L, void *keyaddr,
int32_t iActor, int32_t iPlayer, int32_t lDist)
{
int32_t i;
#ifdef DEBUGGINGAIDS
L_PushDebugTraceback(L);
#endif
// get the Lua function from the registry
lua_pushlightuserdata(L, keyaddr);
lua_gettable(L, LUA_REGISTRYINDEX);
@ -292,7 +294,12 @@ static int32_t call_regd_function3(lua_State *L, void *keyaddr,
// -- call it! --
#ifdef DEBUGGINGAIDS
i = lua_pcall(L, 3, 0, 1);
#else
i = lua_pcall(L, 3, 0, 0);
#endif
if (i == LUA_ERRMEM)
{
lua_pop(L, 1);