Lunatic: rotatesprite+test, player access, misc.

git-svn-id: https://svn.eduke32.com/eduke32@2923 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2012-08-19 12:52:18 +00:00
parent df591aba1c
commit e9095c8470
11 changed files with 131 additions and 24 deletions

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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 = {}

View file

@ -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;

View file

@ -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,

View file

@ -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

View file

@ -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)

View file

@ -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 ===---')

View file

@ -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()

View file

@ -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)