From e9095c847064b00e8614a3b8da2cf87c5f978d8b Mon Sep 17 00:00:00 2001 From: helixhorned Date: Sun, 19 Aug 2012 12:52:18 +0000 Subject: [PATCH] Lunatic: rotatesprite+test, player access, misc. git-svn-id: https://svn.eduke32.com/eduke32@2923 1a8010ca-5511-0410-912e-c29ae57300e0 --- polymer/eduke32/source/game.c | 3 ++ polymer/eduke32/source/gameexec.c | 12 +++-- polymer/eduke32/source/lunatic/control.lua | 16 +++++++ polymer/eduke32/source/lunatic/defs.ilua | 39 ++++++++++++---- polymer/eduke32/source/lunatic/dynsymlist | 7 +++ polymer/eduke32/source/lunatic/geom.lua | 5 ++- polymer/eduke32/source/lunatic/randgen.lua | 3 +- polymer/eduke32/source/lunatic/stat.lua | 12 ++++- polymer/eduke32/source/lunatic/test.elua | 9 ++-- .../eduke32/source/lunatic/test/test_geom.lua | 5 ++- .../source/lunatic/test/test_rotspr.lua | 44 +++++++++++++++++++ 11 files changed, 131 insertions(+), 24 deletions(-) create mode 100644 polymer/eduke32/source/lunatic/test/test_rotspr.lua diff --git a/polymer/eduke32/source/game.c b/polymer/eduke32/source/game.c index 4ad3eeba7..5f468a5fd 100644 --- a/polymer/eduke32/source/game.c +++ b/polymer/eduke32/source/game.c @@ -2768,7 +2768,10 @@ void G_DisplayRest(int32_t smoothratio) } } +#ifndef LUNATIC + // TODO: get rid of the other outer apScriptGameEvent checks, too if (apScriptGameEvent[EVENT_DISPLAYREST]) +#endif VM_OnEvent(EVENT_DISPLAYREST, g_player[screenpeek].ps->i, screenpeek, -1, 0); if (g_player[myconnectindex].ps->newowner == -1 && ud.overhead_on == 0 && ud.crosshair && ud.camerasprite == -1) diff --git a/polymer/eduke32/source/gameexec.c b/polymer/eduke32/source/gameexec.c index af3008943..f8d951f57 100644 --- a/polymer/eduke32/source/gameexec.c +++ b/polymer/eduke32/source/gameexec.c @@ -102,9 +102,7 @@ int32_t VM_OnEvent(int32_t iEventID, int32_t iActor, int32_t iPlayer, int32_t lD if (El_IsInitialized(&g_ElState) && El_HaveEvent(iEventID)) El_CallEvent(&g_ElState, iEventID, iActor, iPlayer, lDist); #endif - if (!apScriptGameEvent[iEventID]) - return iReturn; - + if (apScriptGameEvent[iEventID]) { intptr_t *oinsptr=insptr; vmstate_t vm_backup; @@ -141,13 +139,13 @@ int32_t VM_OnEvent(int32_t iEventID, int32_t iActor, int32_t iPlayer, int32_t lD g_currentEventExec = backupEventExec; iReturn = aGameVars[g_iReturnVarID].val.lValue; aGameVars[g_iReturnVarID].val.lValue = backupReturnVar; + } #ifdef LUNATIC - g_eventTotalMs[iEventID] += gethitickms()-t; - g_eventCalls[iEventID]++; + g_eventTotalMs[iEventID] += gethitickms()-t; + g_eventCalls[iEventID]++; #endif - return iReturn; - } + return iReturn; } static inline int32_t VM_CheckSquished(void) diff --git a/polymer/eduke32/source/lunatic/control.lua b/polymer/eduke32/source/lunatic/control.lua index 5b0a59652..b2db38d7b 100644 --- a/polymer/eduke32/source/lunatic/control.lua +++ b/polymer/eduke32/source/lunatic/control.lua @@ -1,6 +1,9 @@ -- Game control module for Lunatic. local ffi = require("ffi") +local ffiC = ffi.C + +local bit = require("bit") local setmetatable = setmetatable @@ -98,3 +101,16 @@ function ai(name, action, move, flags) def.ai[name] = ffi.new("const con_ai_t", lastid.ai, act, mov, flags) end + + +--== RUNTIME CON FUNCTIONS ==-- + +function rotatesprite(x, y, zoom, ang, tilenum, shade, pal, orientation, + cx1, cy1, cx2, cy2) + if (type(tilenum) ~= "number" or not (tilenum >= 0 and tilenum < ffiC.MAXTILES)) then + error("bad argument #5 to rotatesprite: must be number in [0.."..ffiC.MAXTILES.."]") + end + + ffiC.rotatesprite(65536*x, 65536*y, zoom, ang, tilenum, shade, pal, bit.bor(2,orientation), + cx1, cy1, cx2, cy2) +end diff --git a/polymer/eduke32/source/lunatic/defs.ilua b/polymer/eduke32/source/lunatic/defs.ilua index 9b8555a03..fc774e64a 100644 --- a/polymer/eduke32/source/lunatic/defs.ilua +++ b/polymer/eduke32/source/lunatic/defs.ilua @@ -149,6 +149,7 @@ end ffi.cdef[[ enum { MAXSTATUS = 1024, + MAXTILES = 30720, MAXBUNCHES = 256, CEILING = 0, @@ -162,6 +163,8 @@ enum { ffi.cdef[[ const int16_t numsectors, numwalls; const int32_t numyaxbunches; +const int32_t totalclock; +const int32_t xdim, ydim; ]] decl[[ @@ -175,6 +178,10 @@ 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); + +void rotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum, + int8_t dashade, char dapalnum, int32_t dastat, + int32_t cx1, int32_t cy1, int32_t cx2, int32_t cy2); ]] -- array -> element flattening inside structs, @@ -515,6 +522,8 @@ int32_t g_sizes_of[]; actor_t actor[MAXSPRITES]; user_defs ud; playerdata_t g_player[MAXPLAYERS]; + +const int32_t playerswhenstarted; ]] -- functions @@ -582,9 +591,9 @@ local con = require("control") -- All-zero action and move local nullac, nullmv = ffi.new("const struct action"), ffi.new("const struct move") -local function check_literal_am(am) +local function check_literal_am(am, typename) if (type(am) ~= "number") then - error("bad argument: expected number", 3) + error("bad argument: expected number or "..typename, 3) end if (not (am >= 0 and am <= 32767)) then @@ -606,7 +615,7 @@ local actor_mt = { a.t_data[4] = act.id a.ac = act.ac else - check_literal_am(act) + check_literal_am(act, "action") a.t_data[4] = act a.ac = nullac end @@ -620,7 +629,7 @@ local actor_mt = { if (ffi.istype(con_action_ct, act)) then return (a.t_data[4]==act.id) else - check_literal_am(act) + check_literal_am(act, "action") return (a.t_data[4]==act) end end, @@ -650,7 +659,7 @@ local actor_mt = { a.t_data[1] = mov.id a.mv = mov.mv else - check_literal_am(mov) + check_literal_am(mov, "move") a.t_data[1] = mov a.mv = nullmv end @@ -667,7 +676,7 @@ local actor_mt = { if (ffi.istype(con_move_ct, mov)) then return (a.t_data[1]==mov.id) else - check_literal_am(mov) + check_literal_am(mov, "move") return (a.t_data[1]==mov) end end, @@ -678,7 +687,9 @@ local actor_mt = { a = ffi.cast(actor_ptr_ct, a) -- TODO: literal number AIs? - assert(ffi.istype(con_ai_ct, ai)) + if (not ffi.istype(con_ai_ct, ai)) then + error("bad argument: expected ai", 2) + end -- NOTE: compare with gameexec.c a.t_data[5] = ai.id @@ -695,7 +706,7 @@ local actor_mt = { if (ffi.istype(con_ai_ct, ai)) then return (a.t_data[5]==ai.id) else - check_literal_am(ai) + check_literal_am(ai, "ai") return (a.t_data[5]==ai) end end, @@ -996,6 +1007,18 @@ local tmpmt = { } wall = setmtonce({}, tmpmt) +local tmpmt = { + __index = function(tab, key) + if (key >= 0 and key < ffiC.playerswhenstarted) then + return ffiC.g_player[key].ps[0] + end + error('out-of-bounds player[] read access', 2) + end, + + __newindex = function(tab, key, val) error('cannot write directly to player[] struct', 2) end, +} +player = setmtonce({}, tmpmt) + -- create a safe indirection for an ffi.C array local function creategtab(ctab, maxidx, name) local tab = {} diff --git a/polymer/eduke32/source/lunatic/dynsymlist b/polymer/eduke32/source/lunatic/dynsymlist index 10b023dd0..7ac3a22f1 100644 --- a/polymer/eduke32/source/lunatic/dynsymlist +++ b/polymer/eduke32/source/lunatic/dynsymlist @@ -14,6 +14,10 @@ numsectors; numwalls; numyaxbunches; +totalclock; +xdim; +ydim; + yax_getbunch; headspritesect; @@ -33,11 +37,14 @@ kread; ksqrt; hitscan; +rotatesprite; actor; ud; g_player; +playerswhenstarted; + luaJIT_BC_lunacon; luaJIT_BC_con_lang; luaJIT_BC_geom; diff --git a/polymer/eduke32/source/lunatic/geom.lua b/polymer/eduke32/source/lunatic/geom.lua index 92a605804..f750af363 100644 --- a/polymer/eduke32/source/lunatic/geom.lua +++ b/polymer/eduke32/source/lunatic/geom.lua @@ -33,11 +33,14 @@ local mt = { assert(type(b)=="number") return vec2_(a.x/b, a.y/b) end, +--[[ +-- NOTE: metamethods from metatype() are invoken on *any mix of types* +-- This means that we can't check a "maybe-vec2" variable like "v ~= nil". __eq = function(a,b) return (a.x==b.x and a.y==b.y) end, - +--]] __len = function(a) return math.sqrt(a.x*a.x + a.y*a.y) end, __tostring = function(a) return "vec2("..a.x..", "..a.y..")" end, diff --git a/polymer/eduke32/source/lunatic/randgen.lua b/polymer/eduke32/source/lunatic/randgen.lua index b6b6de10f..b82e8624c 100644 --- a/polymer/eduke32/source/lunatic/randgen.lua +++ b/polymer/eduke32/source/lunatic/randgen.lua @@ -55,7 +55,8 @@ local jkiss = ffi.metatype("rng_jkiss_t", mt) function new(x,y,z,c) local s if (x == nil or type(x)=="boolean") then - s = jkiss(0,0,0,0) -- invalid state, must be initialized first + -- initialize with arbitrary but fixed state + s = jkiss(123456789, 987654321, 43219876, 6543217) if (x) then s:init_time_md4() end diff --git a/polymer/eduke32/source/lunatic/stat.lua b/polymer/eduke32/source/lunatic/stat.lua index c70a0a700..3b5001111 100644 --- a/polymer/eduke32/source/lunatic/stat.lua +++ b/polymer/eduke32/source/lunatic/stat.lua @@ -12,6 +12,7 @@ module(...) ffi.cdef[[ typedef struct { double n; + // vvv internal vvv double m, s; double min, max; } runningstat_t; @@ -24,6 +25,8 @@ typedef struct { ]] +local NaN = 0/0 + local res_mt = { __tostring = function(s) return @@ -68,9 +71,14 @@ local mt = { end, getstats = function(s) - local var = s.n > 1 and s.s/(s.n-1) or 0/0 + local var = s.n > 1 and s.s/(s.n-1) or NaN return rstatres(s.n, s.m, var, math.sqrt(var), s.min, s.max) end, + + reset = function(s) + s.n, s.m = 0, 0 + s.s, s.min, s.max = NaN, NaN, NaN + end, }, } local rstat = ffi.metatype("runningstat_t", mt) @@ -78,7 +86,7 @@ local rstat = ffi.metatype("runningstat_t", mt) function new(n,m,s, min,max) if (n == nil) then -- initialization containing no elements - return rstat(0, 0, 0/0, 0/0, 0/0) + return rstat(0, 0, NaN, NaN, NaN) elseif (m == nil) then -- same as initialization with N==0 above (one element) return rstat(1, n, 0, n, n) diff --git a/polymer/eduke32/source/lunatic/test.elua b/polymer/eduke32/source/lunatic/test.elua index 4f4a3be88..9e34dc518 100644 --- a/polymer/eduke32/source/lunatic/test.elua +++ b/polymer/eduke32/source/lunatic/test.elua @@ -174,13 +174,13 @@ checkfail('gv.gethitickms = nil', "cannot create new or write into existing fiel checkfail('local i = actor[0].t_data[15]', "has no member named 't_data'") -- no pointer arithmetic! -checkfail('local spr = sprite[0]; local x=spr+1', - "attempt to perform arithmetic on") +checkfail('local spr = sprite[0]; local x=spr+1', "attempt to perform arithmetic on") checkfail('gameactor(1680, 0)', "bad argument #3 to 'gameactor' (function expected, got number)") checkfail("do local bt=require'bittest'; bt.QWE=1; end", "modifying module table forbidden") - +-- the cdata returned by player[] is not a pointer! +checkfail("do local pl=player[0]; i=pl[1]") printf('ceilingbunch of sector 0: %d', getbunch(0, gv.CEILING)) @@ -253,7 +253,7 @@ gameactor(1680, -- LIZTROOP if (hs.n == 300) then printf("hitscan: %s", tostring(hs:getstats())) - hs = stat.new() + hs:reset() end if (dist < 4096) then @@ -270,6 +270,7 @@ local bittest = require "bittest" bittest.sieve() require("test/test_geom") +require("test/test_rotspr") print('---=== END TEST SCRIPT ===---') diff --git a/polymer/eduke32/source/lunatic/test/test_geom.lua b/polymer/eduke32/source/lunatic/test/test_geom.lua index 4415d1eca..f829ae915 100755 --- a/polymer/eduke32/source/lunatic/test/test_geom.lua +++ b/polymer/eduke32/source/lunatic/test/test_geom.lua @@ -56,7 +56,10 @@ local t3 = os.clock() local v = geom.vec2(0, 0) for i=1,N do - v = v + geom.intersect(A[i],V[i], B[i],W[i], true) + local intersp = geom.intersect(A[i],V[i], B[i],W[i], true) + if (intersp ~= nil) then + v = v + intersp + end end local t4 = os.clock() diff --git a/polymer/eduke32/source/lunatic/test/test_rotspr.lua b/polymer/eduke32/source/lunatic/test/test_rotspr.lua new file mode 100644 index 000000000..5ce1e0598 --- /dev/null +++ b/polymer/eduke32/source/lunatic/test/test_rotspr.lua @@ -0,0 +1,44 @@ + +local con = require("con") +local bit = require("bit") +local math = require("math") + +local rs = con.rotatesprite + +local DOT1x5 = 3135 +local BAR1x5 = 3163 + +local function draw_hline_dotted(x1, x2, y, pal,stat) + for x=x1,x2,2 do + local tile = (x==x1 or x==x2) and BAR1x5 or DOT1x5 + if (player[0].curr_weapon==2) then + x = x + 16*math.sin(2*math.pi*gv.totalclock/120) + end + rs(x,y, 65536, 0, tile, 0,pal,stat, 0,0,gv.xdim-1,gv.ydim-1) + end +end + +local function draw_two_hlines(y, stat) + if (player[0].curr_weapon ~= 3) then + stat = bit.bor(stat, 8) + end + draw_hline_dotted(0,160, y, 0, stat) + -- XXX: rotatesprite(*, 320, ...) with stat 1024 and classic draws out of + -- bounds (wraps to lower left corner). (Or is it the left one? In any case, + -- weird stuff happens.) + draw_hline_dotted(162,318, y, 2, stat) +end + + +local function rotatesprite_test() + local stats = { [0]=0, 256, 512, 1024 } + for i=0,3 do + local stat = stats[i] + draw_two_hlines(50+25*i, stats[i]) + end + + -- NUKEBUTTON + rs(30,170, 32768, 2047*((gv.totalclock/240)%1), 142, 0,0,8+1024, 0,0,gv.xdim-1,gv.ydim-1) +end + +gameevent(gv.EVENT_DISPLAYREST, rotatesprite_test)