Lunatic: various stuff

- hitscan & related types and constants
- profiling with gethitickms
- translator: eval the opening parts of block commands early
- fix getbunch

git-svn-id: https://svn.eduke32.com/eduke32@2779 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2012-06-22 21:40:01 +00:00
parent bfd1700ceb
commit ff9cae033a
5 changed files with 85 additions and 9 deletions

View file

@ -63,7 +63,7 @@ labels =
},
{
EVENT_INIT = 0,
EVENT_INIT = 0, -- TODO: currently can't run since we init Lunatic state only afterwards
EVENT_ENTERLEVEL = 1,
EVENT_RESETWEAPONS = 2,
EVENT_RESETINVENTORY = 3,

View file

@ -63,9 +63,17 @@ typedef struct {
typedef struct {
int32_t x, y, z;
} vec3_t;
typedef struct {
vec3_t pos;
int16_t hitsprite, hitwall, hitsect;
} hitdata_t;
#pragma pack(pop)
]]
local vec3_t = ffi.typeof("vec3_t")
local hitdata_ct = ffi.typeof("hitdata_t")
assert(ffi.sizeof('sectortype')==40)
assert(ffi.sizeof('walltype')==32)
assert(ffi.sizeof('spritetype')==44)
@ -124,6 +132,9 @@ enum {
MAXBUNCHES = 256,
CEILING = 0,
FLOOR = 1,
CLIPMASK0 = (1<<16)+1, // blocking
CLIPMASK1 = (256<<16)+64, // hittable
};
]]
@ -139,6 +150,9 @@ const int16_t headsectbunch[2][MAXBUNCHES], nextsectbunch[2][MAXSECTORS];
int16_t yax_getbunch(int16_t i, int16_t cf);
int32_t hitscan(const vec3_t *sv, int16_t sectnum, int32_t vx, int32_t vy, int32_t vz,
hitdata_t *hitinfo, uint32_t cliptype);
]]
@ -277,6 +291,11 @@ actor_t actor[MAXSPRITES];
user_defs ud;
]]
-- functions
ffi.cdef[[
double gethitickms(void);
]]
--- default defines
local con = require("con_lang")
@ -404,8 +423,9 @@ gv = {
actor = det,
ud = det,
luaJIT_BC_con_lang = det,
luaJIT_BC_lunacon = det,
-- functions, too!
yax_getbunch = det,
hitscan = det,
}
local tmpmt = {
__index = ffiC,
@ -535,16 +555,30 @@ end
function getbunch(sectnum, cf)
if (sectnum < 0 or sectnum >= ffiC.numsectors) then
error('out-of-bounds sector[] read access', 2)
error('passed out-of-bounds sector number'..sectnum, 2)
end
if (cf ~= 0 and cf ~= 1) then
error("passed invalid 'cf' to getbunch, must be 0 or 1", 2)
end
return yax_getbunch(sectnum, cf)
return ffiC.yax_getbunch(sectnum, cf)
end
---=== Engine functions, wrapped for Lua convenience ===---
-- returns a hitdata_ct
function hitscan(x,y,z, sectnum, vx,vy,vz, cliptype)
if (sectnum < 0 or sectnum >= ffiC.numsectors) then
error('passed out-of-bounds sector number'..sectnum, 2)
end
local vec = vec3_t(x,y,z)
local hitdata = hitdata_ct()
ffiC.hitscan(vec, sectnum, vx,vy,vz, hitdata, cliptype)
return hitdata
end
---=== Game variables ===---
-- gamevarNames[name] is true if that gamevar was declared

View file

@ -23,8 +23,12 @@ nextspritestat;
headsectbunch;
nextsectbunch;
hitscan;
actor;
ud;
luaJIT_BC_*;
gethitickms;
};

View file

@ -103,6 +103,7 @@ local LABEL_NO = { [2]=MOVE_NO_, [3]={ACTION_NO_,MOVE_NO_,0}, [5]=ACTION_NO_ }
-- - move: { hvel <num>, vvel <num> }
-- - ai: { action <label str>, move <label str, or scalar 0 or 1>, flags <num> }
-- - action: { startframe, numframes, viewtype, incval, delay } (all <num>)
-- TODO: IDs for comparison with if*
local g_labeldef = {}
local function reset_labels()
@ -1138,6 +1139,11 @@ local function warn_on_lonely_else()
warnprintf("found `else' with no `if'")
end
function EvalEarly(pat)
-- force warnings and the like early
return lpeg.Cmt(pat, function() return true end)
end
local con_inner_command = all_alt_pattern(Ci)
local con_if_begs = all_alt_pattern(Cif)
@ -1150,24 +1156,24 @@ local stmt_list_or_eps = (stmt_list * sp1)^-1
local stmt_list_nosp_or_eps = (stmt_list * (sp1 * stmt_list)^0)^-1
-- common to actor and useractor: <name/tilenum> [<strength> [<action> [<move> [<flags>... ]]]]
local common_actor_end = sp1 * t_define *
local common_actor_end = sp1 * t_define * EvalEarly(
(sp1 * t_define *
(sp1 * t_action *
(sp1 * t_move *
(sp1 * t_define)^0
)^-1
)^-1
)^-1
)^-1)
* sp1 * stmt_list_or_eps * "enda"
--== block delimiters (no recursion) ==--
local Cb = {
-- actor (...)
actor = common_actor_end,
-- eventloadactor <name/tilenum>
eventloadactor = sp1 * t_define * sp1 * stmt_list_or_eps * "enda",
-- useractor <actortype> (...)
useractor = sp1 * t_define * common_actor_end,
-- eventloadactor <name/tilenum>
eventloadactor = sp1 * t_define * sp1 * stmt_list_or_eps * "enda",
onevent = sp1 * t_define * sp1 * stmt_list_or_eps * "endevent",

View file

@ -111,6 +111,10 @@ checkfail('string.dump(gameevent)') -- string.dump is unavailable
-- "missing declaration" error.
-- See http://luajit.org/ext_ffi_api.html#ffi_C about what stuff ffi.C contains.
checkfail('gv.luaJIT_setmode(nil, 0, 0)')
checkfail('gv.luaJIT_BC_con_lang')
checkfail('gv.yax_getbunch(0,0)')
printf('ceilingbunch of sector 0: %d', getbunch(0, gv.CEILING))
gameevent(gv.EVENT_JUMP,
function(actori, playeri, dist)
@ -118,10 +122,38 @@ gameevent(gv.EVENT_JUMP,
end
)
gameevent(gv.EVENT_ENTERLEVEL,
function()
local i
local N = 1e6
local t = gv.gethitickms()
for i=3,N do
gv.gethitickms()
end
t = gv.gethitickms()-t
-- NOTE: for me (helixhorned), about 40 ns per call
printf("%d gethitickms() calls took %.03f ms (%.03f us/call)",
N, t, (t*1000)/N)
end
)
gameactor(1680, -- LIZTROOP
function(i, playeri, dist)
sprite[i].pal = math.random(32)
-- sprite[i].ang = bit.band(sprite[i].ang-20, 2047)
local spr = sprite[i]
-- print(type(spr)) --> cdata
assert(pcall("print(spr+1)") == false) -- no ptr arith!
local x,y,z = spr.x, spr.y, spr.z
local t = gv.gethitickms()
local hit = hitscan(x,y,z, spr.sectnum, 10, 10, 0, gv.CLIPMASK0)
printf("hitscan took %.03f us, sec=%d, wal=%d, spr=%d", 1000*(gv.gethitickms()-t),
hit.hitsect, hit.hitwall, hit.hitsprite)
end
)