mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-24 10:40:46 +00:00
Lunatic: make gameactor and gameevent be "table-called" functions.
git-svn-id: https://svn.eduke32.com/eduke32@3873 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
bbcf6d6353
commit
f6065e227a
5 changed files with 316 additions and 255 deletions
|
@ -795,9 +795,11 @@ do
|
||||||
-- Callback function chaining control flags.
|
-- Callback function chaining control flags.
|
||||||
our_SFLAG.replace_hard = 0x08000000 -- Replace actor code and flags
|
our_SFLAG.replace_hard = 0x08000000 -- Replace actor code and flags
|
||||||
our_SFLAG.replace_soft = 0x10000000 -- Replace actor code, bitwise OR flags
|
our_SFLAG.replace_soft = 0x10000000 -- Replace actor code, bitwise OR flags
|
||||||
|
our_SFLAG.replace = 0x08000000 -- Should only be used for gameevent
|
||||||
our_SFLAG.chain_beg = 0x20000000
|
our_SFLAG.chain_beg = 0x20000000
|
||||||
our_SFLAG.chain_end = 0x40000000
|
our_SFLAG.chain_end = 0x40000000
|
||||||
our_SFLAG._CHAIN_MASK = 0x78000000
|
our_SFLAG._CHAIN_MASK_ACTOR = 0x78000000
|
||||||
|
our_SFLAG._CHAIN_MASK_EVENT = 0x68000000
|
||||||
|
|
||||||
-- XXX: CON doesn't export BADGUYSTAYPUT or ROTFIXED SFLAGs, but they are considered
|
-- XXX: CON doesn't export BADGUYSTAYPUT or ROTFIXED SFLAGs, but they are considered
|
||||||
-- external for Lunatic.
|
-- external for Lunatic.
|
||||||
|
@ -853,7 +855,8 @@ actor = setmtonce({}, defs_c.GenStructMetatable("actor", "MAXSPRITES", actor_sta
|
||||||
-- Some bitwise NOTs of various actor flag masks.
|
-- Some bitwise NOTs of various actor flag masks.
|
||||||
local BNOT = {
|
local BNOT = {
|
||||||
USER_MASK = bit.bnot(actor.FLAGS.USER_MASK),
|
USER_MASK = bit.bnot(actor.FLAGS.USER_MASK),
|
||||||
CHAIN_MASK = bit.bnot(actor.FLAGS._CHAIN_MASK),
|
CHAIN_MASK_ACTOR = bit.bnot(actor.FLAGS._CHAIN_MASK_ACTOR),
|
||||||
|
CHAIN_MASK_EVENT = bit.bnot(actor.FLAGS._CHAIN_MASK_EVENT),
|
||||||
}
|
}
|
||||||
|
|
||||||
local projectile = defs_c.creategtab(ffiC.ProjectileData, ffiC.MAXTILES, "projectile[]")
|
local projectile = defs_c.creategtab(ffiC.ProjectileData, ffiC.MAXTILES, "projectile[]")
|
||||||
|
@ -1617,6 +1620,15 @@ local function chain_func3(func1, func2)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Determines the last numeric index of a table using *ipairs*.
|
||||||
|
local function ourmaxn(tab)
|
||||||
|
local maxi = 0
|
||||||
|
for i in ipairs(tab) do
|
||||||
|
maxi = math.max(i, maxi)
|
||||||
|
end
|
||||||
|
return maxi
|
||||||
|
end
|
||||||
|
|
||||||
-- Running for the very first time?
|
-- Running for the very first time?
|
||||||
local g_firstRun = (ffiC.g_elCONSize == 0)
|
local g_firstRun = (ffiC.g_elCONSize == 0)
|
||||||
|
|
||||||
|
@ -1624,10 +1636,17 @@ local g_firstRun = (ffiC.g_elCONSize == 0)
|
||||||
local actor_funcs = {}
|
local actor_funcs = {}
|
||||||
|
|
||||||
local gameactor_internal = gameactor_internal -- included in lunatic.c
|
local gameactor_internal = gameactor_internal -- included in lunatic.c
|
||||||
-- gameactor(tilenum [, flags [, strength [, act [, mov [, movflags]]]]], actor_func)
|
-- gameactor{tilenum [, flags [, strength [, action [, move [, movflags]]]]], func}
|
||||||
local function our_gameactor(tilenum, ...)
|
-- Every arg may be positional OR key=val (with the name indicated above as key),
|
||||||
|
-- but not both.
|
||||||
|
local function our_gameactor(args)
|
||||||
bcheck.top_level("gameactor")
|
bcheck.top_level("gameactor")
|
||||||
|
|
||||||
|
if (type(args)~="table") then
|
||||||
|
error("invalid gameactor call: must be passed a table")
|
||||||
|
end
|
||||||
|
|
||||||
|
local tilenum = args[1]
|
||||||
if (type(tilenum) ~= "number") then
|
if (type(tilenum) ~= "number") then
|
||||||
error("invalid argument #1 to gameactor: must be a number", 2)
|
error("invalid argument #1 to gameactor: must be a number", 2)
|
||||||
end
|
end
|
||||||
|
@ -1635,28 +1654,24 @@ local function our_gameactor(tilenum, ...)
|
||||||
error("invalid argument #1 to gameactor: must be a tile number [0..gv.MAXTILES-1]", 2)
|
error("invalid argument #1 to gameactor: must be a tile number [0..gv.MAXTILES-1]", 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
local args = {...}
|
local lastargi = ourmaxn(args)
|
||||||
-- Number of varargs; args may have nil's in the middle!
|
local func = args[lastargi]
|
||||||
local numargs = select('#', ...)
|
if (type(func) ~= "function") then
|
||||||
|
func = args.func
|
||||||
if (numargs == 0) then
|
lastargi = 1/0
|
||||||
error("invalid call to gameactor: must have at least two arguments (tilenum, func)", 2)
|
|
||||||
end
|
end
|
||||||
if (numargs >= 7) then -- sic, because tilenum isn't counted!
|
if (type(func) ~= "function") then
|
||||||
error("invalid call to gameactor: must have at most 7 arguments", 2)
|
error("invalid gameactor call: must provide a function with last numeric arg or .func", 2)
|
||||||
end
|
|
||||||
if (type(args[numargs]) ~= "function") then
|
|
||||||
error("invalid last argument to gameactor: must be a function", 2)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local flags = (numargs > 1) and args[1] or 0
|
local flags = (lastargi > 2 and args[2]) or args.flags or 0
|
||||||
if (type(flags) ~= "number") then
|
if (type(flags) ~= "number") then
|
||||||
error("invalid 'flags' argument to gameactor: must be a number", 2)
|
error("invalid 'flags' argument (#2) to gameactor: must be a number", 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
local AF = actor.FLAGS
|
local AF = actor.FLAGS
|
||||||
local chainflags = bit.band(flags, AF._CHAIN_MASK)
|
local chainflags = bit.band(flags, AF._CHAIN_MASK_ACTOR)
|
||||||
flags = bit.band(flags, BNOT.CHAIN_MASK)
|
flags = bit.band(flags, BNOT.CHAIN_MASK_ACTOR)
|
||||||
|
|
||||||
-- Default chaining behavior: don't, replace the old actor instead, but
|
-- Default chaining behavior: don't, replace the old actor instead, but
|
||||||
-- unlike CON, also replace its flags. (CON ORs them instead.)
|
-- unlike CON, also replace its flags. (CON ORs them instead.)
|
||||||
|
@ -1673,43 +1688,43 @@ local function our_gameactor(tilenum, ...)
|
||||||
|
|
||||||
local flags_rbits = bit.band(flags, BNOT.USER_MASK)
|
local flags_rbits = bit.band(flags, BNOT.USER_MASK)
|
||||||
if (flags_rbits ~= 0) then
|
if (flags_rbits ~= 0) then
|
||||||
error("invalid 'flags' argument to gameactor: must not set reserved bits (0x"
|
error("invalid 'flags' argument (#2) to gameactor: must not set reserved bits (0x"
|
||||||
..(bit.tohex(flags_rbits))..")", 2)
|
..(bit.tohex(flags_rbits))..")", 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
local strength = (numargs > 2) and args[2] or (replacep and 0 or nil)
|
local strength = ((lastargi > 3 and args[3]) or args.strength) or (replacep and 0 or nil)
|
||||||
if (replacep or strength~=nil) then
|
if (replacep or strength~=nil) then
|
||||||
if (type(strength) ~= "number") then
|
if (type(strength) ~= "number") then
|
||||||
error("invalid 'strength' argument to gameactor: must be a number", 2)
|
error("invalid 'strength' argument (#3) to gameactor: must be a number", 2)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- TODO: literal number action other than 0?
|
-- TODO: literal number action other than 0?
|
||||||
local act = (numargs > 3) and args[3] or (replacep and "NO" or nil)
|
local act = ((lastargi > 4 and args[4]) or args.action) or (replacep and "NO" or nil)
|
||||||
if (replacep or act ~= nil) then
|
if (replacep or act ~= nil) then
|
||||||
if (type(act)=="string") then
|
if (type(act)=="string") then
|
||||||
act = AC[act]
|
act = AC[act]
|
||||||
end
|
end
|
||||||
if (not ffi.istype(con_action_ct, act)) then
|
if (not ffi.istype(con_action_ct, act)) then
|
||||||
error("invalid 'act' argument to gameactor: must be a string or action", 2)
|
error("invalid 'action' argument (#4) to gameactor: must be a string or action", 2)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- TODO: literal number move other than 0?
|
-- TODO: literal number move other than 0?
|
||||||
local mov = (numargs > 4) and args[4] or (replacep and "NO" or nil)
|
local mov = ((lastargi > 5 and args[5]) or args.move) or (replacep and "NO" or nil)
|
||||||
if (replacep or mov ~= nil) then
|
if (replacep or mov ~= nil) then
|
||||||
if (type(mov)=="string") then
|
if (type(mov)=="string") then
|
||||||
mov = MV[mov]
|
mov = MV[mov]
|
||||||
end
|
end
|
||||||
if (not ffi.istype(con_move_ct, mov)) then
|
if (not ffi.istype(con_move_ct, mov)) then
|
||||||
error("invalid 'mov' argument to gameactor: must be a string or move", 2)
|
error("invalid 'move' argument (#5) to gameactor: must be a string or move", 2)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local movflags = (numargs > 5) and args[5] or (replacep and 0 or nil)
|
local movflags = ((lastargi > 6 and args[6]) or args.movflags) or (replacep and 0 or nil)
|
||||||
if (replacep or movflags ~= nil) then
|
if (replacep or movflags ~= nil) then
|
||||||
if (type(movflags) ~= "number") then
|
if (type(movflags) ~= "number") then
|
||||||
error("invalid 'movflags' argument to gameactor: must be a number", 2)
|
error("invalid 'movflags' argument (#6) to gameactor: must be a number", 2)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1726,7 +1741,6 @@ local function our_gameactor(tilenum, ...)
|
||||||
tile.flags = (chainflags==AF.replace_hard) and flags or bit.bor(tile.flags, flags)
|
tile.flags = (chainflags==AF.replace_hard) and flags or bit.bor(tile.flags, flags)
|
||||||
end
|
end
|
||||||
|
|
||||||
local func = args[numargs]
|
|
||||||
local newfunc = replacep and func
|
local newfunc = replacep and func
|
||||||
or (chainflags==AF.chain_beg) and chain_func3(func, actor_funcs[tilenum])
|
or (chainflags==AF.chain_beg) and chain_func3(func, actor_funcs[tilenum])
|
||||||
or (chainflags==AF.chain_end) and chain_func3(actor_funcs[tilenum], func)
|
or (chainflags==AF.chain_end) and chain_func3(actor_funcs[tilenum], func)
|
||||||
|
@ -1740,10 +1754,16 @@ end
|
||||||
local event_funcs = {}
|
local event_funcs = {}
|
||||||
|
|
||||||
local gameevent_internal = gameevent_internal -- included in lunatic.c
|
local gameevent_internal = gameevent_internal -- included in lunatic.c
|
||||||
-- gameevent(<event idx or string> [, flags], <event function>)
|
-- gameevent{<event idx or string> [, flags], <event function>}
|
||||||
local function our_gameevent(event, flags, func)
|
local function our_gameevent(args)
|
||||||
bcheck.top_level("gameevent")
|
bcheck.top_level("gameevent")
|
||||||
|
|
||||||
|
if (type(args)~="table") then
|
||||||
|
error("invalid gameevent call: must be passed a table")
|
||||||
|
end
|
||||||
|
|
||||||
|
local event = args[1]
|
||||||
|
|
||||||
if (type(event) == "string") then
|
if (type(event) == "string") then
|
||||||
if (event:sub(1,6) ~= "EVENT_") then
|
if (event:sub(1,6) ~= "EVENT_") then
|
||||||
event = "EVENT_"..event
|
event = "EVENT_"..event
|
||||||
|
@ -1763,27 +1783,28 @@ local function our_gameevent(event, flags, func)
|
||||||
|
|
||||||
local AF = actor.FLAGS
|
local AF = actor.FLAGS
|
||||||
|
|
||||||
-- Event chaining: in Lunatic, chaining at the *end* is the default.
|
-- Kind of CODEDUP from our_gameactor.
|
||||||
if (func==nil) then
|
local lastargi = ourmaxn(args)
|
||||||
func = flags
|
local func = args[lastargi]
|
||||||
flags = AF.chain_end
|
|
||||||
else
|
|
||||||
if (type(flags) ~= "number") then
|
|
||||||
error("invalid 'flags' argument to gameevent: must be a number", 2)
|
|
||||||
end
|
|
||||||
if (bit.band(flags, BNOT.CHAIN_MASK) ~= 0) then
|
|
||||||
error("invalid 'flags' argument to gameevent: must not set reserved bits", 2)
|
|
||||||
end
|
|
||||||
if (flags == 0) then
|
|
||||||
flags = AF.chain_end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if (type(func) ~= "function") then
|
if (type(func) ~= "function") then
|
||||||
error("invalid last argument to gameevent: must be a function", 2)
|
func = args.func
|
||||||
|
lastargi = 1/0
|
||||||
|
end
|
||||||
|
if (type(func) ~= "function") then
|
||||||
|
error("invalid gameevent call: must provide a function with last numeric arg or .func", 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
local newfunc = replacep and func
|
-- Event chaining: in Lunatic, chaining at the *end* is the default.
|
||||||
|
local flags = (lastargi > 2 and args[2]) or args.flags or AF.chain_end
|
||||||
|
if (type(flags) ~= "number") then
|
||||||
|
error("invalid 'flags' argument (#2) to gameevent: must be a number", 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
if (bit.band(flags, BNOT.CHAIN_MASK_EVENT) ~= 0) then
|
||||||
|
error("invalid 'flags' argument to gameevent: must not set reserved bits", 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
local newfunc = (flags==AF.replace) and func
|
||||||
or (flags==AF.chain_beg) and chain_func3(func, event_funcs[event])
|
or (flags==AF.chain_beg) and chain_func3(func, event_funcs[event])
|
||||||
or (flags==AF.chain_end) and chain_func3(event_funcs[event], func)
|
or (flags==AF.chain_end) and chain_func3(event_funcs[event], func)
|
||||||
or assert(false)
|
or assert(false)
|
||||||
|
|
|
@ -418,9 +418,9 @@ function on.actor_end(pos, usertype, tsamm, codetab)
|
||||||
str = str .. movflags..","
|
str = str .. movflags..","
|
||||||
end
|
end
|
||||||
|
|
||||||
paddcodef(pos, "gameactor(%d,%sfunction(_aci, _pli, _dist)", tilenum, str)
|
paddcodef(pos, "gameactor{%d,%sfunction(_aci, _pli, _dist)", tilenum, str)
|
||||||
addcode(get_cache_sap_code())
|
addcode(get_cache_sap_code())
|
||||||
add_code_and_end(codetab, "end)")
|
add_code_and_end(codetab, "end}")
|
||||||
|
|
||||||
if (g_code.actor[tilenum] ~= nil) then
|
if (g_code.actor[tilenum] ~= nil) then
|
||||||
pwarnprintf(pos, "redefined actor %d", tilenum)
|
pwarnprintf(pos, "redefined actor %d", tilenum)
|
||||||
|
@ -476,22 +476,22 @@ end
|
||||||
function on.event_end(pos, eventidx, codetab)
|
function on.event_end(pos, eventidx, codetab)
|
||||||
assert(type(codetab)=="table")
|
assert(type(codetab)=="table")
|
||||||
-- 0x20000000: actor.FLAGS.chain_beg
|
-- 0x20000000: actor.FLAGS.chain_beg
|
||||||
paddcodef(pos, "gameevent(%d,0x20000000,function (_aci, _pli, _dist)", eventidx)
|
paddcodef(pos, "gameevent{%d,0x20000000,function (_aci, _pli, _dist)", eventidx)
|
||||||
addcode(get_cache_sap_code())
|
addcode(get_cache_sap_code())
|
||||||
addcode(codetab)
|
addcode(codetab)
|
||||||
addcode("end)")
|
addcode("end}")
|
||||||
|
|
||||||
g_code.event[eventidx] = codetab
|
g_code.event[eventidx] = codetab
|
||||||
end
|
end
|
||||||
|
|
||||||
function on.eventloadactor_end(pos, tilenum, codetab)
|
function on.eventloadactor_end(pos, tilenum, codetab)
|
||||||
-- Translate eventloadactor into a chained EVENT_LOADACTOR block
|
-- Translate eventloadactor into a chained EVENT_LOADACTOR block
|
||||||
paddcodef(pos, "gameevent('LOADACTOR', function (_aci, _pli, _dist)")
|
paddcodef(pos, "gameevent{'LOADACTOR', function (_aci, _pli, _dist)")
|
||||||
addcode(get_cache_sap_code())
|
addcode(get_cache_sap_code())
|
||||||
addcodef("if (%s==%d) then", SPS".picnum", tilenum)
|
addcodef("if (%s==%d) then", SPS".picnum", tilenum)
|
||||||
addcode(codetab)
|
addcode(codetab)
|
||||||
addcode("end")
|
addcode("end")
|
||||||
addcode("end)")
|
addcode("end}")
|
||||||
|
|
||||||
if (g_code.loadactor[tilenum] ~= nil and g_warn["chained-loadactor"]) then
|
if (g_code.loadactor[tilenum] ~= nil and g_warn["chained-loadactor"]) then
|
||||||
-- NOTE: C-CON redefines loadactor code if encountered multiple times.
|
-- NOTE: C-CON redefines loadactor code if encountered multiple times.
|
||||||
|
|
|
@ -178,7 +178,7 @@ checkfail('local i = actor[0].t_data[15]', "has no member named 't_data'")
|
||||||
-- no pointer arithmetic!
|
-- 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)', "invalid last argument to gameactor: must be a function")
|
checkfail('gameactor{1680, 0}', "must provide a function with last numeric arg or .func")
|
||||||
|
|
||||||
checkfail("do local bt=require'test.test_bitar'; bt.QWE=1; end", "modifying module table forbidden")
|
checkfail("do local bt=require'test.test_bitar'; bt.QWE=1; end", "modifying module table forbidden")
|
||||||
-- the cdata returned by player[] can't be made into a pointer!
|
-- the cdata returned by player[] can't be made into a pointer!
|
||||||
|
@ -195,165 +195,183 @@ player[0].curr_weapon = 1
|
||||||
|
|
||||||
printf('ceilingbunch of sector 0: %d', sector[0].ceilingbunch)
|
printf('ceilingbunch of sector 0: %d', sector[0].ceilingbunch)
|
||||||
|
|
||||||
gameevent(gv.EVENT_JUMP,
|
gameevent{gv.EVENT_JUMP,
|
||||||
function(actori, playeri, dist)
|
function(actori, playeri, dist)
|
||||||
printf("jump i=%d p=%d d=%d", actori, playeri, dist)
|
printf("jump i=%d p=%d d=%d", actori, playeri, dist)
|
||||||
error("greetings from EVENT_JUMP")
|
error("greetings from EVENT_JUMP")
|
||||||
end
|
end
|
||||||
)
|
}
|
||||||
|
|
||||||
gameevent("PROCESSINPUT",
|
gameevent
|
||||||
-- Input test.
|
{
|
||||||
-- NOTE: I don't think that exposing g_player[].sync (aka "input") is a good idea...
|
"PROCESSINPUT",
|
||||||
function(actori, playeri, dist)
|
|
||||||
local IB = player._INPUT_BITS
|
-- Input test.
|
||||||
local input = player[playeri]._input
|
-- NOTE: I don't think that exposing g_player[].sync (aka "input") is a good idea...
|
||||||
if (bit.band(input.bits, IB.JUMP) ~= 0) then
|
func = function(actori, playeri, dist)
|
||||||
print("JUMPED")
|
local IB = player._INPUT_BITS
|
||||||
-- ... because for example this doesn't work
|
local input = player[playeri]._input
|
||||||
-- (P_HandleSharedKeys, where the JETPACK bit is tested, runs
|
if (bit.band(input.bits, IB.JUMP) ~= 0) then
|
||||||
-- before P_ProcessInput):
|
print("JUMPED")
|
||||||
input.bits = bit.bor(input.bits, IB.JETPACK)
|
-- ... because for example this doesn't work
|
||||||
end
|
-- (P_HandleSharedKeys, where the JETPACK bit is tested, runs
|
||||||
end
|
-- before P_ProcessInput):
|
||||||
)
|
input.bits = bit.bor(input.bits, IB.JETPACK)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
-- test event chaining
|
-- test event chaining
|
||||||
gameevent("JUMP", actor.FLAGS.chain_beg,
|
gameevent
|
||||||
function(actori, playeri, dist)
|
{
|
||||||
local ps = player[playeri]
|
"JUMP",
|
||||||
print("\n--- I'm first!")
|
|
||||||
-- DBG_.oom()
|
|
||||||
ps.weapon.PISTOL.shoots = 2605 -- RPG
|
|
||||||
ps.weapon[gv.PISTOL_WEAPON].firesound = 351 -- thunder
|
|
||||||
|
|
||||||
-- XXX: provide either named constants or methods?
|
flags = actor.FLAGS.chain_beg,
|
||||||
ps.pipebombControl = 2
|
|
||||||
ps.tripbombControl = 2
|
|
||||||
|
|
||||||
-- Test of INTERNAL member _pals.
|
function(actori, playeri, dist)
|
||||||
-- NOTE: setting colors partially is bad! E.g. after an item is
|
local ps = player[playeri]
|
||||||
-- picked up, col[0] and col[1] remain and tint everything greenish.
|
print("\n--- I'm first!")
|
||||||
ps._pals[2] = 20
|
-- DBG_.oom()
|
||||||
ps._pals.f = 30
|
ps.weapon.PISTOL.shoots = 2605 -- RPG
|
||||||
end
|
ps.weapon[gv.PISTOL_WEAPON].firesound = 351 -- thunder
|
||||||
)
|
|
||||||
|
|
||||||
gameevent(gv.EVENT_ENTERLEVEL,
|
-- XXX: provide either named constants or methods?
|
||||||
function()
|
ps.pipebombControl = 2
|
||||||
if (gv._DEBUG_LUNATIC) then
|
ps.tripbombControl = 2
|
||||||
DBG_.testmembread()
|
|
||||||
end
|
|
||||||
|
|
||||||
-- NOTE: times are for helixhorned (Core2Duo 3GHz)
|
-- Test of INTERNAL member _pals.
|
||||||
local i
|
-- NOTE: setting colors partially is bad! E.g. after an item is
|
||||||
local N = 1e6
|
-- picked up, col[0] and col[1] remain and tint everything greenish.
|
||||||
local t = gv.gethitickms()
|
ps._pals[2] = 20
|
||||||
|
ps._pals.f = 30
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
for i=3,N do
|
gameevent
|
||||||
gv.gethitickms()
|
{
|
||||||
end
|
gv.EVENT_ENTERLEVEL,
|
||||||
|
|
||||||
t = gv.gethitickms()-t
|
function()
|
||||||
|
if (gv._DEBUG_LUNATIC) then
|
||||||
|
DBG_.testmembread()
|
||||||
|
end
|
||||||
|
|
||||||
-- x86_64: 35ns/call, x86: 280 ns/call
|
-- NOTE: times are for helixhorned (Core2Duo 3GHz)
|
||||||
-- Windows 32-bit: about 1 us/call?
|
local i
|
||||||
printf("%d gethitickms() calls took %.03f ms (%.03f us/call)",
|
local N = 1e6
|
||||||
N, t, (t*1000)/N)
|
local t = gv.gethitickms()
|
||||||
|
|
||||||
local sum=0
|
for i=3,N do
|
||||||
t = gv.gethitickms()
|
gv.gethitickms()
|
||||||
for i=1,N do sum = sum+gv.ksqrt(i) end
|
end
|
||||||
t = gv.gethitickms()-t
|
|
||||||
-- x86_64: 14ns/call
|
|
||||||
printf("%d ksqrt() calls took %.03f ms (%.03f us/call) [sum=%f]",
|
|
||||||
N, t, (t*1000)/N, sum)
|
|
||||||
|
|
||||||
sum=0
|
t = gv.gethitickms()-t
|
||||||
t = gv.gethitickms()
|
|
||||||
for i=1,N do sum = sum+math.sqrt(i) end
|
|
||||||
t = gv.gethitickms()-t
|
|
||||||
-- x86_64: 7ns/call
|
|
||||||
printf("%d math.sqrt() calls took %.03f ms (%.03f us/call) [sum=%f]",
|
|
||||||
N, t, (t*1000)/N, sum)
|
|
||||||
|
|
||||||
printf("sqrt(0xffffffff) = %f(ksqrt) %f(math.sqrt)",
|
-- x86_64: 35ns/call, x86: 280 ns/call
|
||||||
gv.ksqrt(0xffffffff), math.sqrt(0xffffffff))
|
-- Windows 32-bit: about 1 us/call?
|
||||||
|
printf("%d gethitickms() calls took %.03f ms (%.03f us/call)",
|
||||||
|
N, t, (t*1000)/N)
|
||||||
|
|
||||||
local pl = player[0]
|
local sum=0
|
||||||
-- MAX < current is "allowed"
|
t = gv.gethitickms()
|
||||||
pl.max_ammo_amount[gv.RPG_WEAPON] = 17
|
for i=1,N do sum = sum+gv.ksqrt(i) end
|
||||||
pl:give_weapon(gv.RPG_WEAPON)
|
t = gv.gethitickms()-t
|
||||||
pl.ammo_amount[gv.RPG_WEAPON] = 54
|
-- x86_64: 14ns/call
|
||||||
|
printf("%d ksqrt() calls took %.03f ms (%.03f us/call) [sum=%f]",
|
||||||
|
N, t, (t*1000)/N, sum)
|
||||||
|
|
||||||
pl:give_weapon(gv.SHRINKER_WEAPON)
|
sum=0
|
||||||
-- This looks much prettier:
|
t = gv.gethitickms()
|
||||||
pl.ammo_amount.SHRINKER = 2
|
for i=1,N do sum = sum+math.sqrt(i) end
|
||||||
|
t = gv.gethitickms()-t
|
||||||
|
-- x86_64: 7ns/call
|
||||||
|
printf("%d math.sqrt() calls took %.03f ms (%.03f us/call) [sum=%f]",
|
||||||
|
N, t, (t*1000)/N, sum)
|
||||||
|
|
||||||
-- MORTER2 from test/weaponvars.con
|
printf("sqrt(0xffffffff) = %f(ksqrt) %f(math.sqrt)",
|
||||||
player[0].weapon.SHOTGUN.shoots = 1653
|
gv.ksqrt(0xffffffff), math.sqrt(0xffffffff))
|
||||||
local proj = projectile[1653]
|
|
||||||
proj.drop = 0
|
|
||||||
proj:set_trail(2329) -- SMALLSMOKE
|
|
||||||
|
|
||||||
t = gv.gethitickms()
|
local pl = player[0]
|
||||||
local N=1
|
-- MAX < current is "allowed"
|
||||||
for n=1,N do
|
pl.max_ammo_amount[gv.RPG_WEAPON] = 17
|
||||||
for i=0,gv.MAXSPRITES-1 do
|
pl:give_weapon(gv.RPG_WEAPON)
|
||||||
sprite[i].filler = 1
|
pl.ammo_amount[gv.RPG_WEAPON] = 54
|
||||||
end
|
|
||||||
for i=gv.MAXSPRITES-1,0,-1 do
|
|
||||||
sprite[i].shade = 1
|
|
||||||
end
|
|
||||||
for i=0,gv.MAXSPRITES-1 do
|
|
||||||
sprite[i].xoffset = 0
|
|
||||||
end
|
|
||||||
for i=gv.MAXSPRITES-1,0,-1 do
|
|
||||||
sprite[i].yoffset = 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
t = gv.gethitickms()-t
|
|
||||||
printf("%d x four 0..MAXSPRITES-1 iterations took %.03f us per outer iteration", N, (1000*t)/N)
|
|
||||||
-- Results on x86:
|
|
||||||
-- N=1: 480-1000 us (too large variance)
|
|
||||||
-- N=10: 190-210 us * 10 = 1.9-2.1 ms
|
|
||||||
-- N=100: about 160 us * 100 = about 16 ms
|
|
||||||
|
|
||||||
-- Make the DUKECAR in E1L1 into a zombie actor (temporarily)
|
pl:give_weapon(gv.SHRINKER_WEAPON)
|
||||||
if (sprite[24].picnum==2491) then
|
-- This looks much prettier:
|
||||||
sprite.changestat(24, actor.STAT.ZOMBIEACTOR)
|
pl.ammo_amount.SHRINKER = 2
|
||||||
end
|
|
||||||
|
|
||||||
checkfail("gameevent('GAME', function() print('qwe') end)",
|
-- MORTER2 from test/weaponvars.con
|
||||||
"must be called from top level")
|
player[0].weapon.SHOTGUN.shoots = 1653
|
||||||
end
|
local proj = projectile[1653]
|
||||||
)
|
proj.drop = 0
|
||||||
|
proj:set_trail(2329) -- SMALLSMOKE
|
||||||
|
|
||||||
|
t = gv.gethitickms()
|
||||||
|
local N=1
|
||||||
|
for n=1,N do
|
||||||
|
for i=0,gv.MAXSPRITES-1 do
|
||||||
|
sprite[i].filler = 1
|
||||||
|
end
|
||||||
|
for i=gv.MAXSPRITES-1,0,-1 do
|
||||||
|
sprite[i].shade = 1
|
||||||
|
end
|
||||||
|
for i=0,gv.MAXSPRITES-1 do
|
||||||
|
sprite[i].xoffset = 0
|
||||||
|
end
|
||||||
|
for i=gv.MAXSPRITES-1,0,-1 do
|
||||||
|
sprite[i].yoffset = 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
t = gv.gethitickms()-t
|
||||||
|
printf("%d x four 0..MAXSPRITES-1 iterations took %.03f us per outer iteration", N, (1000*t)/N)
|
||||||
|
-- Results on x86:
|
||||||
|
-- N=1: 480-1000 us (too large variance)
|
||||||
|
-- N=10: 190-210 us * 10 = 1.9-2.1 ms
|
||||||
|
-- N=100: about 160 us * 100 = about 16 ms
|
||||||
|
|
||||||
|
-- Make the DUKECAR in E1L1 into a zombie actor (temporarily)
|
||||||
|
if (sprite[24].picnum==2491) then
|
||||||
|
sprite.changestat(24, actor.STAT.ZOMBIEACTOR)
|
||||||
|
end
|
||||||
|
|
||||||
|
checkfail("gameevent('GAME', function() print('qwe') end)",
|
||||||
|
"must be called from top level")
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
local geom = require "geom"
|
local geom = require "geom"
|
||||||
|
|
||||||
gameevent("LOADACTOR", function(i)
|
gameevent{"LOADACTOR", function(i)
|
||||||
local spr = sprite[i]
|
local spr = sprite[i]
|
||||||
if (i==614 and spr.picnum==930) then
|
if (i==614 and spr.picnum==930) then
|
||||||
-- "police line" ribbon in E1L1
|
-- "police line" ribbon in E1L1
|
||||||
-- clear the hitag so that it doesn't spawn as FALLER from premap
|
-- clear the hitag so that it doesn't spawn as FALLER from premap
|
||||||
spr.hitag = 0
|
spr.hitag = 0
|
||||||
end
|
end
|
||||||
end)
|
end}
|
||||||
|
|
||||||
gameactor(930, nil, 1, function(i) -- "police line" ribbon
|
gameactor
|
||||||
local spr = sprite[i]
|
{
|
||||||
local r = math.random
|
-- "police line" ribbon
|
||||||
local d = 20
|
930, nil, 1,
|
||||||
-- NOTE: __add metamethod is called because of the RHS:
|
|
||||||
local v = spr + geom.vec3(r(-d,d), r(-d,d))
|
func = function(i)
|
||||||
spr:setpos(v)
|
local spr = sprite[i]
|
||||||
end)
|
local r = math.random
|
||||||
|
local d = 20
|
||||||
|
-- NOTE: __add metamethod is called because of the RHS:
|
||||||
|
local v = spr + geom.vec3(r(-d,d), r(-d,d))
|
||||||
|
spr:setpos(v)
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
local stat = require("stat")
|
local stat = require("stat")
|
||||||
local hs = stat.new()
|
local hs = stat.new()
|
||||||
|
|
||||||
local con = require("con")
|
local con = require("con")
|
||||||
local AC, MV = con.AC, con.MV
|
local AC, MV = con.AC, con.MV
|
||||||
|
|
||||||
con.action("TROOPSTAND",0,1,5,1,1)
|
con.action("TROOPSTAND",0,1,5,1,1)
|
||||||
con.action("TROOPFLINTCH", 50, 1, 1, 1, 6)
|
con.action("TROOPFLINTCH", 50, 1, 1, 1, 6)
|
||||||
con.move("SHRUNKVELS", 32)
|
con.move("SHRUNKVELS", 32)
|
||||||
|
@ -366,107 +384,129 @@ con.ai("AITEMP", "TROOPFLINTCH", "SHRUNKVELS", 0)
|
||||||
|
|
||||||
local TROOPSTRENGTH = 30
|
local TROOPSTRENGTH = 30
|
||||||
|
|
||||||
|
local D = require("CON.DEFS")
|
||||||
local AF = actor.FLAGS
|
local AF = actor.FLAGS
|
||||||
local CS = sprite.CSTAT
|
local CS = sprite.CSTAT
|
||||||
|
|
||||||
-- Also test actor code chaining: strength is doubled.
|
-- Also test actor code chaining: strength is doubled.
|
||||||
gameactor(1680, AF.chain_end+AF.enemy, 2*TROOPSTRENGTH, "TROOPSTAND", -- LIZTROOP
|
gameactor
|
||||||
function(i, playeri, dist)
|
{
|
||||||
spriteext[i]:make_animated()
|
D.LIZTROOP, AF.chain_end+AF.enemy, 2*TROOPSTRENGTH,
|
||||||
|
|
||||||
sprite[i].pal = math.random(32)
|
action = "TROOPSTAND",
|
||||||
-- sprite[i].ang = bit.band(sprite[i].ang-20, 2047)
|
|
||||||
|
|
||||||
local spr = sprite[i]
|
func = function(i, playeri, dist)
|
||||||
|
spriteext[i]:make_animated()
|
||||||
|
|
||||||
local t = gv.gethitickms()
|
sprite[i].pal = math.random(32)
|
||||||
local hit = hitscan(spr, spr.sectnum, 10, 10, 0, gv.CLIPMASK0)
|
-- sprite[i].ang = bit.band(sprite[i].ang-20, 2047)
|
||||||
|
|
||||||
hs:add(1000*(gv.gethitickms()-t))
|
local spr = sprite[i]
|
||||||
|
|
||||||
if (hs.n == 300) then
|
local t = gv.gethitickms()
|
||||||
printf("hitscan: %s", hs:getstatstr())
|
local hit = hitscan(spr, spr.sectnum, 10, 10, 0, gv.CLIPMASK0)
|
||||||
hs:reset()
|
|
||||||
error("greetings from LIZTROOP actor")
|
|
||||||
end
|
|
||||||
|
|
||||||
local actr = actor[i]
|
hs:add(1000*(gv.gethitickms()-t))
|
||||||
if (actr:get_count() % 30 == 0) then
|
|
||||||
spr.cstatbits:flip(CS.YFLIP)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Test of bitint's ":test()" for actor[].flags.
|
if (hs.n == 300) then
|
||||||
actr.flagsbits:test(AF.NVG)
|
printf("hitscan: %s", hs:getstatstr())
|
||||||
|
hs:reset()
|
||||||
|
error("greetings from LIZTROOP actor")
|
||||||
|
end
|
||||||
|
|
||||||
if (dist < 4096) then
|
local actr = actor[i]
|
||||||
-- Duke Vader / Anakin Nukewalker?
|
if (actr:get_count() % 30 == 0) then
|
||||||
actor[i]:set_action("TROOPFLINTCH")
|
spr.cstatbits:flip(CS.YFLIP)
|
||||||
actor[i]:set_move("SHRUNKVELS")
|
end
|
||||||
|
|
||||||
if (dist < 1024) then
|
-- Test of bitint's ":test()" for actor[].flags.
|
||||||
con.killit()
|
actr.flagsbits:test(AF.NVG)
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
)
|
|
||||||
|
|
||||||
gameevent("DISPLAYROOMS",
|
if (dist < 4096) then
|
||||||
function()
|
-- Duke Vader / Anakin Nukewalker?
|
||||||
local cam = gv.cam
|
actor[i]:set_action("TROOPFLINTCH")
|
||||||
cam.pos.z = cam.pos.z + 64*16*math.sin(gv.totalclock/30)
|
actor[i]:set_move("SHRUNKVELS")
|
||||||
|
|
||||||
local ps = player[0]
|
if (dist < 1024) then
|
||||||
if (ps.cursectnum >= 0) then
|
con.killit()
|
||||||
local hit = sector[ps.cursectnum]:zrangeat(cam.pos)
|
end
|
||||||
if (gv.totalclock%200==0) then
|
|
||||||
printf("hit %s %d at z=%d, %s %d at z=%d",
|
|
||||||
hit.c.spritep and "sprite" or "sector", hit.c.num, hit.c.z,
|
|
||||||
hit.f.spritep and "sprite" or "sector", hit.f.num, hit.f.z)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
)
|
|
||||||
|
|
||||||
gameevent("DISPLAYREST", function()
|
|
||||||
for i=0,10 do
|
|
||||||
for j=1,100 do
|
|
||||||
-- XXX: This is slower in the Polymodes than with classic!
|
|
||||||
-- con._gametext(2822, j, i, 12, 0, 0, 16, 0,0,gv.xdim,gv.ydim,8192)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
}
|
||||||
|
|
||||||
-- Clear showing every sector with the pavement floor tile. (Unless we're
|
gameevent
|
||||||
-- in such a sector or an adjoining one.)
|
{
|
||||||
-- XXX: We need a better place to do this, maybe an event in
|
"DISPLAYROOMS",
|
||||||
-- G_DisplayRest() where show2dsector[] is tweaked?
|
|
||||||
local show2dsector = sector.showbitmap
|
function()
|
||||||
for i=0,gv.numsectors-1 do
|
local cam = gv.cam
|
||||||
if (sector[i].floorpicnum==815) then
|
cam.pos.z = cam.pos.z + 64*16*math.sin(gv.totalclock/30)
|
||||||
show2dsector:set0(i)
|
|
||||||
|
local ps = player[0]
|
||||||
|
if (ps.cursectnum >= 0) then
|
||||||
|
local hit = sector[ps.cursectnum]:zrangeat(cam.pos)
|
||||||
|
if (gv.totalclock%200==0) then
|
||||||
|
printf("hit %s %d at z=%d, %s %d at z=%d",
|
||||||
|
hit.c.spritep and "sprite" or "sector", hit.c.num, hit.c.z,
|
||||||
|
hit.f.spritep and "sprite" or "sector", hit.f.num, hit.f.z)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
}
|
||||||
|
|
||||||
-- APLAYER
|
gameevent
|
||||||
gameactor(1405, actor.FLAGS.chain_beg, function(aci, pli)
|
{
|
||||||
if (con._squished(aci, pli)) then
|
"DISPLAYREST",
|
||||||
printf("Squished LunaCON test")
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
|
function()
|
||||||
|
for i=0,10 do
|
||||||
|
for j=1,100 do
|
||||||
|
-- XXX: This is slower in the Polymodes than with classic!
|
||||||
|
-- con._gametext(2822, j, i, 12, 0, 0, 16, 0,0,gv.xdim,gv.ydim,8192)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
gameevent("ANIMATESPRITES",
|
-- Clear showing every sector with the pavement floor tile. (Unless we're
|
||||||
function(aci)
|
-- in such a sector or an adjoining one.)
|
||||||
local tspr = atsprite[aci]
|
-- XXX: We need a better place to do this, maybe an event in
|
||||||
if (tspr:getspr().picnum==1680) then
|
-- G_DisplayRest() where show2dsector[] is tweaked?
|
||||||
local tspr2 = tspr:dup()
|
local show2dsector = sector.showbitmap
|
||||||
if (tspr2) then
|
for i=0,gv.numsectors-1 do
|
||||||
tspr2.x = tspr2.x + 512*math.cos(gv.totalclock/60)
|
if (sector[i].floorpicnum==815) then
|
||||||
tspr2.y = tspr2.y + 512*math.sin(gv.totalclock/60)
|
show2dsector:set0(i)
|
||||||
tspr2.cstatbits:set(CS.TRANS_BITMASK)
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
}
|
||||||
|
|
||||||
|
gameactor
|
||||||
|
{
|
||||||
|
D.APLAYER, actor.FLAGS.chain_beg,
|
||||||
|
|
||||||
|
function(aci, pli)
|
||||||
|
if (con._squished(aci, pli)) then
|
||||||
|
printf("Squished LunaCON test")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gameevent
|
||||||
|
{
|
||||||
|
"ANIMATESPRITES",
|
||||||
|
|
||||||
|
function(aci)
|
||||||
|
local tspr = atsprite[aci]
|
||||||
|
if (tspr:getspr().picnum==1680) then
|
||||||
|
local tspr2 = tspr:dup()
|
||||||
|
if (tspr2) then
|
||||||
|
tspr2.x = tspr2.x + 512*math.cos(gv.totalclock/60)
|
||||||
|
tspr2.y = tspr2.y + 512*math.sin(gv.totalclock/60)
|
||||||
|
tspr2.cstatbits:set(CS.TRANS_BITMASK)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
printf("EVENT_INIT = %d", gv.EVENT_INIT) -- tests default defines
|
printf("EVENT_INIT = %d", gv.EVENT_INIT) -- tests default defines
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ require "end_gamevars"
|
||||||
local tag = tag
|
local tag = tag
|
||||||
|
|
||||||
|
|
||||||
gameevent("JUMP", actor.FLAGS.chain_beg,
|
gameevent{"JUMP", actor.FLAGS.chain_beg,
|
||||||
function(aci, pli)
|
function(aci, pli)
|
||||||
local ps = player[pli]
|
local ps = player[pli]
|
||||||
|
|
||||||
|
@ -74,4 +74,4 @@ function(aci, pli)
|
||||||
end
|
end
|
||||||
|
|
||||||
insp = not insp
|
insp = not insp
|
||||||
end)
|
end}
|
||||||
|
|
|
@ -47,7 +47,7 @@ local function rotatesprite_test()
|
||||||
rs(30,170, 32768, 2047*((gv.totalclock/240)%1), 142, 0,0,8+1024,0, 0,0,gv.xdim-1,gv.ydim-1)
|
rs(30,170, 32768, 2047*((gv.totalclock/240)%1), 142, 0,0,8+1024,0, 0,0,gv.xdim-1,gv.ydim-1)
|
||||||
end
|
end
|
||||||
|
|
||||||
gameevent(gv.EVENT_DISPLAYREST, rotatesprite_test)
|
gameevent{gv.EVENT_DISPLAYREST, rotatesprite_test}
|
||||||
|
|
||||||
|
|
||||||
module(...) --====================
|
module(...) --====================
|
||||||
|
|
Loading…
Reference in a new issue