From 5fc9bb977995ac156beeb8fe7576b7a74467d50e Mon Sep 17 00:00:00 2001 From: helixhorned Date: Sat, 29 Dec 2012 15:21:32 +0000 Subject: [PATCH] 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 --- polymer/eduke32/build/include/lunatic.h | 1 + polymer/eduke32/build/src/lunatic.c | 13 +++-- polymer/eduke32/source/gameexec.c | 16 +++++-- polymer/eduke32/source/lunatic/control.lua | 48 +++++++++---------- polymer/eduke32/source/lunatic/defs.ilua | 15 +++--- polymer/eduke32/source/lunatic/dynsymlist | 1 + polymer/eduke32/source/lunatic/lunacon.lua | 2 +- polymer/eduke32/source/lunatic/lunatic_game.c | 9 +++- 8 files changed, 66 insertions(+), 39 deletions(-) diff --git a/polymer/eduke32/build/include/lunatic.h b/polymer/eduke32/build/include/lunatic.h index 3af4c14c5..d63f7bec4 100644 --- a/polymer/eduke32/build/include/lunatic.h +++ b/polymer/eduke32/build/include/lunatic.h @@ -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. must be used immediately or strdup'd. diff --git a/polymer/eduke32/build/src/lunatic.c b/polymer/eduke32/build/src/lunatic.c index d3ee9bc9c..d072cce1d 100644 --- a/polymer/eduke32/build/src/lunatic.c +++ b/polymer/eduke32/build/src/lunatic.c @@ -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); diff --git a/polymer/eduke32/source/gameexec.c b/polymer/eduke32/source/gameexec.c index c993fedac..b53ddcbbd 100644 --- a/polymer/eduke32/source/gameexec.c +++ b/polymer/eduke32/source/gameexec.c @@ -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 diff --git a/polymer/eduke32/source/lunatic/control.lua b/polymer/eduke32/source/lunatic/control.lua index e4043d217..360f585c9 100644 --- a/polymer/eduke32/source/lunatic/control.lua +++ b/polymer/eduke32/source/lunatic/control.lua @@ -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 diff --git a/polymer/eduke32/source/lunatic/defs.ilua b/polymer/eduke32/source/lunatic/defs.ilua index 3ca77008d..f070bc064 100644 --- a/polymer/eduke32/source/lunatic/defs.ilua +++ b/polymer/eduke32/source/lunatic/defs.ilua @@ -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 diff --git a/polymer/eduke32/source/lunatic/dynsymlist b/polymer/eduke32/source/lunatic/dynsymlist index 6406a11f8..3d05d8a43 100644 --- a/polymer/eduke32/source/lunatic/dynsymlist +++ b/polymer/eduke32/source/lunatic/dynsymlist @@ -69,6 +69,7 @@ G_DoGameStartup; actor; ud; g_player; +g_tile; playerswhenstarted; lastvisinc; diff --git a/polymer/eduke32/source/lunatic/lunacon.lua b/polymer/eduke32/source/lunatic/lunacon.lua index 247cce40e..96de5c83e 100644 --- a/polymer/eduke32/source/lunatic/lunacon.lua +++ b/polymer/eduke32/source/lunatic/lunacon.lua @@ -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) diff --git a/polymer/eduke32/source/lunatic/lunatic_game.c b/polymer/eduke32/source/lunatic/lunatic_game.c index fb09e28f5..1cff69db2 100644 --- a/polymer/eduke32/source/lunatic/lunatic_game.c +++ b/polymer/eduke32/source/lunatic/lunatic_game.c @@ -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);