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: // helpers taking the lua_State directly:
void L_SetupDebugTraceback(lua_State *L); void L_SetupDebugTraceback(lua_State *L);
void L_PushDebugTraceback(lua_State *L);
void L_CheckAndRegisterFunction(lua_State *L, void *regkeyaddr); void L_CheckAndRegisterFunction(lua_State *L, void *regkeyaddr);
// Callback on Lua error. <str> must be used immediately or strdup'd. // 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); 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) 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 -- // -- lua --
Bassert(lua_gettop(L)==0); Bassert(lua_gettop(L)==0);
// get debug.traceback L_PushDebugTraceback(L);
lua_pushlightuserdata(L, &debug_traceback_key);
lua_gettable(L, LUA_REGISTRYINDEX);
Bassert(lua_isfunction(L, -1));
i = luaL_loadstring(L, buf); i = luaL_loadstring(L, buf);
Bassert(lua_gettop(L)==2); 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 #ifdef LUNATIC
const double t = gethitickms(); const double t = gethitickms();
// TODO: handling of RETURN gamevar / iReturn / this function's return value
if (L_IsInitialized(&g_ElState) && El_HaveEvent(iEventID)) if (L_IsInitialized(&g_ElState) && El_HaveEvent(iEventID))
El_CallEvent(&g_ElState, iEventID, iActor, iPlayer, lDist); El_CallEvent(&g_ElState, iEventID, iActor, iPlayer, lDist);
#endif #endif
@ -2002,6 +2003,8 @@ nullquote:
actor[i].flags = 0; actor[i].flags = 0;
sprite[i].hitag = 0; sprite[i].hitag = 0;
#if !defined LUNATIC_ONLY
// TODO: Lunatic
if (g_tile[sprite[i].picnum].execPtr) if (g_tile[sprite[i].picnum].execPtr)
{ {
// offsets // offsets
@ -2009,6 +2012,7 @@ nullquote:
T2 = *(g_tile[sprite[i].picnum].execPtr+2); // move T2 = *(g_tile[sprite[i].picnum].execPtr+2); // move
sprite[i].hitag = *(g_tile[sprite[i].picnum].execPtr+3); // ai bits sprite[i].hitag = *(g_tile[sprite[i].picnum].execPtr+3); // ai bits
} }
#endif
} }
changespritestat(i,j); changespritestat(i,j);
continue; 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)) if (L_IsInitialized(&g_ElState) && El_HaveActor(vm.g_sp->picnum))
killit = (El_CallActor(&g_ElState, vm.g_sp->picnum, iActor, iPlayer, lDist)==1); killit = (El_CallActor(&g_ElState, vm.g_sp->picnum, iActor, iPlayer, lDist)==1);
else if (g_tile[vm.g_sp->picnum].execPtr)
{
#endif #endif
insptr = 4 + (g_tile[vm.g_sp->picnum].execPtr); #if !defined LUNATIC_ONLY
VM_Execute(1); insptr = 4 + (g_tile[vm.g_sp->picnum].execPtr);
insptr = NULL; VM_Execute(1);
insptr = NULL;
#endif
#ifdef LUNATIC #ifdef LUNATIC
}
g_actorTotalMs[vm.g_sp->picnum] += gethitickms()-t; g_actorTotalMs[vm.g_sp->picnum] += gethitickms()-t;
g_actorCalls[vm.g_sp->picnum]++; g_actorCalls[vm.g_sp->picnum]++;
#endif #endif

View file

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

View file

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

View file

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

View file

@ -870,7 +870,7 @@ local Ci = {
clipdist = cmd(D) clipdist = cmd(D)
/ SPS".clipdist=%1", / SPS".clipdist=%1",
sizeto = cmd(D,D) 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) sizeat = cmd(D,D)
/ (SPS".xrepeat,"..SPS".yrepeat=%1,%2"), / (SPS".xrepeat,"..SPS".yrepeat=%1,%2"),
strength = cmd(D) 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 iActor, int32_t iPlayer, int32_t lDist)
{ {
int32_t i; int32_t i;
#ifdef DEBUGGINGAIDS
L_PushDebugTraceback(L);
#endif
// get the Lua function from the registry // get the Lua function from the registry
lua_pushlightuserdata(L, keyaddr); lua_pushlightuserdata(L, keyaddr);
lua_gettable(L, LUA_REGISTRYINDEX); lua_gettable(L, LUA_REGISTRYINDEX);
@ -292,7 +294,12 @@ static int32_t call_regd_function3(lua_State *L, void *keyaddr,
// -- call it! -- // -- call it! --
#ifdef DEBUGGINGAIDS
i = lua_pcall(L, 3, 0, 1);
#else
i = lua_pcall(L, 3, 0, 0); i = lua_pcall(L, 3, 0, 0);
#endif
if (i == LUA_ERRMEM) if (i == LUA_ERRMEM)
{ {
lua_pop(L, 1); lua_pop(L, 1);