mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-25 03:00:46 +00:00
Lunatic: retire per-sprite tsprite access for per-tile animation callback reg.
Don't yet make this official API though, since there are unresolved issues with newly created tsprites potentially being fed back to the animation loop. Add xmath.angvec(), xmath.bangvec(), tspr:set_sectnum(), tspr:setpos(). git-svn-id: https://svn.eduke32.com/eduke32@3937 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
c243bab0e7
commit
7f2175fcec
10 changed files with 133 additions and 47 deletions
|
@ -7051,6 +7051,7 @@ static void G_DoEventAnimSprites(int32_t j)
|
||||||
if ((unsigned)ow < MAXSPRITES && spriteext[ow].flags & SPREXT_TSPRACCESS)
|
if ((unsigned)ow < MAXSPRITES && spriteext[ow].flags & SPREXT_TSPRACCESS)
|
||||||
{
|
{
|
||||||
spriteext[ow].tspr = &tsprite[j];
|
spriteext[ow].tspr = &tsprite[j];
|
||||||
|
// XXX: wouldn't screenpeek be more meaningful as current player?
|
||||||
VM_OnEvent(EVENT_ANIMATESPRITES, ow, myconnectindex, -1, 0);
|
VM_OnEvent(EVENT_ANIMATESPRITES, ow, myconnectindex, -1, 0);
|
||||||
spriteext[ow].tspr = NULL;
|
spriteext[ow].tspr = NULL;
|
||||||
}
|
}
|
||||||
|
@ -7884,6 +7885,11 @@ skip:
|
||||||
for (j = spritesortcnt-1; j>=0; j--)
|
for (j = spritesortcnt-1; j>=0; j--)
|
||||||
G_DoEventAnimSprites(j);
|
G_DoEventAnimSprites(j);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef LUNATIC
|
||||||
|
if (G_HaveEvent(EVENT_ANIMATEALLSPRITES))
|
||||||
|
VM_OnEvent(EVENT_ANIMATEALLSPRITES, -1, -1, -1, 0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -694,7 +694,10 @@ const char *EventNames[MAXEVENTS] =
|
||||||
"EVENT_LOADGAME",
|
"EVENT_LOADGAME",
|
||||||
"EVENT_SAVEGAME",
|
"EVENT_SAVEGAME",
|
||||||
"EVENT_PREGAME",
|
"EVENT_PREGAME",
|
||||||
"EVENT_CHANGEMENU"
|
"EVENT_CHANGEMENU",
|
||||||
|
#ifdef LUNATIC
|
||||||
|
"EVENT_ANIMATEALLSPRITES",
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#if !defined LUNATIC
|
#if !defined LUNATIC
|
||||||
|
|
|
@ -125,6 +125,9 @@ enum GameEvent_t {
|
||||||
EVENT_SAVEGAME,
|
EVENT_SAVEGAME,
|
||||||
EVENT_PREGAME,
|
EVENT_PREGAME,
|
||||||
EVENT_CHANGEMENU,
|
EVENT_CHANGEMENU,
|
||||||
|
#ifdef LUNATIC
|
||||||
|
EVENT_ANIMATEALLSPRITES, // 95
|
||||||
|
#endif
|
||||||
MAXEVENTS
|
MAXEVENTS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -168,6 +168,7 @@ EVENT = {
|
||||||
EVENT_SAVEGAME = 92,
|
EVENT_SAVEGAME = 92,
|
||||||
EVENT_PREGAME = 93,
|
EVENT_PREGAME = 93,
|
||||||
EVENT_CHANGEMENU = 94,
|
EVENT_CHANGEMENU = 94,
|
||||||
|
-- EVENT_ANIMATEALLSPRITES = 95, -- internal
|
||||||
}
|
}
|
||||||
|
|
||||||
-- NOTE: negated values are not exported to the ffi.C namespace or CON.
|
-- NOTE: negated values are not exported to the ffi.C namespace or CON.
|
||||||
|
@ -331,7 +332,7 @@ wdata_members =
|
||||||
|
|
||||||
|
|
||||||
local SP = function(memb) return "sprite[%s]"..memb end
|
local SP = function(memb) return "sprite[%s]"..memb end
|
||||||
local ATSP = function(memb) return "atsprite[%s]"..memb end
|
local ATSP = function(memb) return "_atsprite[%s]"..memb end
|
||||||
local AC = function(memb) return "actor[%s]"..memb end
|
local AC = function(memb) return "actor[%s]"..memb end
|
||||||
local SX = function(memb) return "spriteext[%s]"..memb end
|
local SX = function(memb) return "spriteext[%s]"..memb end
|
||||||
|
|
||||||
|
|
|
@ -1928,8 +1928,31 @@ local g_firstRun = (ffiC.g_elCONSize == 0)
|
||||||
|
|
||||||
-- Actor functions, saved for actor chaining
|
-- Actor functions, saved for actor chaining
|
||||||
local actor_funcs = {}
|
local actor_funcs = {}
|
||||||
|
-- Event functions, saved for event chaining
|
||||||
|
local event_funcs = {}
|
||||||
|
|
||||||
|
-- Per-actor sprite animation callbacks
|
||||||
|
local animsprite_funcs = {}
|
||||||
|
|
||||||
local gameactor_internal = gameactor_internal -- included in lunatic.c
|
local gameactor_internal = gameactor_internal -- included in lunatic.c
|
||||||
|
local gameevent_internal = gameevent_internal -- included in lunatic.c
|
||||||
|
|
||||||
|
local function animate_all_sprites()
|
||||||
|
for i=0,ffiC.spritesortcnt-1 do
|
||||||
|
local tspr = ffiC.tsprite[i]
|
||||||
|
|
||||||
|
if (tspr.owner < ffiC.MAXSPRITES+0ULL) then
|
||||||
|
local spr = tspr:getspr()
|
||||||
|
local animfunc = animsprite_funcs[spr.picnum]
|
||||||
|
|
||||||
|
if (animfunc) then
|
||||||
|
animfunc(tspr)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
-- gameactor{tilenum [, flags [, strength [, action [, move [, movflags]]]]], func}
|
-- gameactor{tilenum [, flags [, strength [, action [, move [, movflags]]]]], func}
|
||||||
-- Every arg may be positional OR key=val (with the name indicated above as key),
|
-- Every arg may be positional OR key=val (with the name indicated above as key),
|
||||||
-- but not both.
|
-- but not both.
|
||||||
|
@ -2018,6 +2041,24 @@ local function our_gameactor(args)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Register a potentially passed drawn sprite animation callback function.
|
||||||
|
-- TODO: allow registering without main actor execution callback.
|
||||||
|
local animfunc = args.animate
|
||||||
|
if (animfunc ~= nil) then
|
||||||
|
if (type(animfunc) ~= "function") then
|
||||||
|
error("invalid 'animate' argument to gameactor: must be a function", 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
animsprite_funcs[tilenum] = replacep and func
|
||||||
|
or (chainflags==AF.chain_beg) and chain_func3(animfunc, animsprite_funcs[tilenum])
|
||||||
|
or (chainflags==AF.chain_end) and chain_func3(animsprite_funcs[tilenum], animfunc)
|
||||||
|
or assert(false)
|
||||||
|
|
||||||
|
-- Register our EVENT_ANIMATEALLSPRITES only now so that it is not
|
||||||
|
-- called if there are no 'animate' definitions.
|
||||||
|
gameevent_internal(95, animate_all_sprites) -- EVENT_ANIMATEALLSPRITES
|
||||||
|
end
|
||||||
|
|
||||||
-- All good, set the tile bits in initial run and register the actor!
|
-- All good, set the tile bits in initial run and register the actor!
|
||||||
-- XXX: Need to see if some other state living on the C side is clobbered
|
-- XXX: Need to see if some other state living on the C side is clobbered
|
||||||
-- by Lua state recreation.
|
-- by Lua state recreation.
|
||||||
|
@ -2040,10 +2081,7 @@ local function our_gameactor(args)
|
||||||
actor_funcs[tilenum] = newfunc
|
actor_funcs[tilenum] = newfunc
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Event functions, saved for event chaining
|
|
||||||
local event_funcs = {}
|
|
||||||
|
|
||||||
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(args)
|
local function our_gameevent(args)
|
||||||
bcheck.top_level("gameevent")
|
bcheck.top_level("gameevent")
|
||||||
|
@ -2313,7 +2351,6 @@ gv = setmtonce(gv_, tmpmt)
|
||||||
-- This will create 'sprite', 'wall', etc. HERE, i.e. in the environment of this chunk
|
-- This will create 'sprite', 'wall', etc. HERE, i.e. in the environment of this chunk
|
||||||
defs_c.create_globals(_G)
|
defs_c.create_globals(_G)
|
||||||
|
|
||||||
|
|
||||||
-- REMOVE this for release
|
-- REMOVE this for release
|
||||||
DBG_ = {}
|
DBG_ = {}
|
||||||
DBG_.debug = require("debug")
|
DBG_.debug = require("debug")
|
||||||
|
|
|
@ -155,6 +155,7 @@ string.format([[
|
||||||
|
|
||||||
local SPRITE_STRUCT = [[
|
local SPRITE_STRUCT = [[
|
||||||
struct {
|
struct {
|
||||||
|
// TODO: transparent union with vec3_t pos?
|
||||||
int32_t x, y, z;
|
int32_t x, y, z;
|
||||||
]]..bitint_member("UBit16", "cstat")..[[
|
]]..bitint_member("UBit16", "cstat")..[[
|
||||||
const int16_t picnum;
|
const int16_t picnum;
|
||||||
|
@ -597,6 +598,7 @@ ffi.metatype("walltype", walltype_mt)
|
||||||
local spriteext_mt = {
|
local spriteext_mt = {
|
||||||
__index = {
|
__index = {
|
||||||
-- Enable EVENT_ANIMATESPRITES for this sprite.
|
-- Enable EVENT_ANIMATESPRITES for this sprite.
|
||||||
|
-- XXX: unused?
|
||||||
make_animated = function(sx)
|
make_animated = function(sx)
|
||||||
sx.flags = bor(sx.flags, 16)
|
sx.flags = bor(sx.flags, 16)
|
||||||
end,
|
end,
|
||||||
|
@ -669,22 +671,40 @@ local function get_sprite_idx(spr)
|
||||||
return i
|
return i
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Methods that are specific to sprites
|
---=== Methods that are specific to sprites ===---
|
||||||
|
|
||||||
function spritetype_mt.__index.setpos(spr, pos) -- setsprite() clone
|
function spritetype_mt.__index.setpos(spr, pos) -- setsprite() clone
|
||||||
spr.x, spr.y, spr.z = pos.x, pos.y, pos.z
|
spr.x, spr.y, spr.z = pos.x, pos.y, pos.z
|
||||||
|
|
||||||
local newsect = updatesector(spr, spr.sectnum)
|
local newsect = updatesector(spr, spr.sectnum)
|
||||||
if (newsect < 0) then
|
|
||||||
return -1
|
|
||||||
end
|
|
||||||
|
|
||||||
if (spr.sectnum ~= newsect) then
|
if (newsect >= 0 and spr.sectnum ~= newsect) then
|
||||||
ffiC.changespritesect(get_sprite_idx(spr), newsect)
|
ffiC.changespritesect(get_sprite_idx(spr), newsect)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
return newsect
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
---=== Methods that are specific to tsprites ===---
|
||||||
|
|
||||||
|
function tspritetype_mt.__index.set_sectnum(tspr, sectnum)
|
||||||
|
check_sector_idx(sectnum)
|
||||||
|
ffi.cast(spritetype_ptr_ct, tspr).sectnum = sectnum
|
||||||
|
end
|
||||||
|
|
||||||
|
-- TODO: flags (the same as sprite.UPDATE_FLAGS + "provide own sectnum",
|
||||||
|
-- e.g. for example because it's already there from "hitscan").
|
||||||
|
function tspritetype_mt.__index.setpos(tspr, pos)
|
||||||
|
tspr.x, tspr.y, tspr.z = pos.x, pos.y, pos.z
|
||||||
|
local newsect = updatesector(tspr, tspr.sectnum)
|
||||||
|
|
||||||
|
if (newsect >= 0 and tspr.sectnum ~= newsect) then
|
||||||
|
tspr:set_sectnum(newsect)
|
||||||
|
end
|
||||||
|
|
||||||
return newsect
|
return newsect
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Methods that are specific to tsprites
|
|
||||||
function tspritetype_mt.__index.dup(tspr)
|
function tspritetype_mt.__index.dup(tspr)
|
||||||
if (ffiC.spritesortcnt >= ffiC.MAXSPRITESONSCREEN+0ULL) then
|
if (ffiC.spritesortcnt >= ffiC.MAXSPRITESONSCREEN+0ULL) then
|
||||||
return nil
|
return nil
|
||||||
|
@ -698,9 +718,11 @@ function tspritetype_mt.__index.dup(tspr)
|
||||||
end
|
end
|
||||||
|
|
||||||
function tspritetype_mt.__index.getspr(tspr)
|
function tspritetype_mt.__index.getspr(tspr)
|
||||||
return sprite[tspr.owner]
|
check_sprite_idx(tspr.owner)
|
||||||
|
return ffiC.sprite[tspr.owner]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---======---
|
||||||
|
|
||||||
-- The user of this module can insert additional "spritetype" index
|
-- The user of this module can insert additional "spritetype" index
|
||||||
-- methods and register them with "ffi.metatype".
|
-- methods and register them with "ffi.metatype".
|
||||||
|
@ -923,7 +945,7 @@ sector = setmtonce({}, sector_mt)
|
||||||
wall = setmtonce({}, wall_mt)
|
wall = setmtonce({}, wall_mt)
|
||||||
sprite = setmtonce({}, sprite_mt)
|
sprite = setmtonce({}, sprite_mt)
|
||||||
spriteext = creategtab(ffiC.spriteext, ffiC.MAXSPRITES, 'spriteext[]')
|
spriteext = creategtab(ffiC.spriteext, ffiC.MAXSPRITES, 'spriteext[]')
|
||||||
atsprite = setmtonce({}, atsprite_mt)
|
_atsprite = setmtonce({}, atsprite_mt)
|
||||||
|
|
||||||
local function iter_wallsofsec(endwall, w)
|
local function iter_wallsofsec(endwall, w)
|
||||||
w = w+1
|
w = w+1
|
||||||
|
@ -1039,7 +1061,7 @@ end
|
||||||
|
|
||||||
-- returns a hitdata_ct
|
-- returns a hitdata_ct
|
||||||
-- TODO: make v[xyz] be passed as one aggregate, too?
|
-- TODO: make v[xyz] be passed as one aggregate, too?
|
||||||
-- Additionally, permit different coordinates? (ang&horiz, ...)
|
-- TODO: make cliptype optional? What should be the default?
|
||||||
function hitscan(pos, sectnum, vx,vy,vz, cliptype)
|
function hitscan(pos, sectnum, vx,vy,vz, cliptype)
|
||||||
check_sector_idx(sectnum)
|
check_sector_idx(sectnum)
|
||||||
local vec = vec3_ct(pos.x, pos.y, pos.z)
|
local vec = vec3_ct(pos.x, pos.y, pos.z)
|
||||||
|
|
|
@ -182,7 +182,7 @@ local function new_initial_codetab()
|
||||||
"local _xmath = require'xmath'",
|
"local _xmath = require'xmath'",
|
||||||
|
|
||||||
-- Cache globals into locals.
|
-- Cache globals into locals.
|
||||||
"local sector, sprite, wall, spriteext, atsprite = sector, sprite, wall, spriteext, atsprite",
|
"local sector, sprite, wall, spriteext, _atsprite = sector, sprite, wall, spriteext, _atsprite",
|
||||||
"local actor, player, projectile, g_tile = actor, player, projectile, g_tile",
|
"local actor, player, projectile, g_tile = actor, player, projectile, g_tile",
|
||||||
"local gameactor, gameevent, _gv = gameactor, gameevent, gv",
|
"local gameactor, gameevent, _gv = gameactor, gameevent, gv",
|
||||||
"local updatesector, updatesectorz, cansee = updatesector, updatesectorz, cansee",
|
"local updatesector, updatesectorz, cansee = updatesector, updatesectorz, cansee",
|
||||||
|
|
|
@ -418,8 +418,6 @@ gameactor
|
||||||
action = AC.TROOPSTAND,
|
action = AC.TROOPSTAND,
|
||||||
|
|
||||||
func = function(i, playeri, dist)
|
func = function(i, playeri, dist)
|
||||||
spriteext[i]:make_animated()
|
|
||||||
|
|
||||||
sprite[i].pal = math.random(32)
|
sprite[i].pal = math.random(32)
|
||||||
-- sprite[i].ang = bit.band(sprite[i].ang-20, 2047)
|
-- sprite[i].ang = bit.band(sprite[i].ang-20, 2047)
|
||||||
|
|
||||||
|
@ -459,7 +457,36 @@ gameactor
|
||||||
actr.movflagsbits:flip(actor.MOVFLAGS.spin)
|
actr.movflagsbits:flip(actor.MOVFLAGS.spin)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
-- NOTE: the animate callback is not yet documented and thus not official API!
|
||||||
|
animate = function(tspr)
|
||||||
|
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
|
||||||
|
|
||||||
|
-- XXX: inserted tsprites have floor shadow in classic! (r_shadow)
|
||||||
|
-- G_DoSpriteAnimations() is passed as callback to the engine on occasion,
|
||||||
|
-- in other words, created tsprites may be fed back to G_DoSpriteAnimations()!
|
||||||
|
-- classic: shows shadow for both "ghost" liztroop and aim "reticle"
|
||||||
|
-- Polymost: only for "ghost"
|
||||||
|
-- Polymer: none
|
||||||
|
local aimv = 256*xmath.bangvec(tspr.ang)
|
||||||
|
local hit = hitscan(tspr^(16*256), tspr.sectnum, aimv.x, aimv.y, 0, gv.CLIPMASK1)
|
||||||
|
|
||||||
|
if (hit.wall >= 0) then
|
||||||
|
local aimtspr = tspr:dup()
|
||||||
|
if (aimtspr) then
|
||||||
|
aimtspr.pal = 2
|
||||||
|
aimtspr:set_picnum(555)
|
||||||
|
aimtspr:setpos(hit.pos)
|
||||||
|
aimtspr:set_sectnum(hit.sect)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
gameactor
|
gameactor
|
||||||
|
@ -539,24 +566,6 @@ gameactor
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
gameevent
|
|
||||||
{
|
|
||||||
"ANIMATESPRITES",
|
|
||||||
|
|
||||||
function(aci)
|
|
||||||
local tspr = atsprite[aci]
|
|
||||||
if (tspr:getspr().picnum==D.LIZTROOP) 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
|
|
||||||
}
|
|
||||||
|
|
||||||
local function testbit(num, b)
|
local function testbit(num, b)
|
||||||
return bit.band(num,b)~=0 and 1 or 0
|
return bit.band(num,b)~=0 and 1 or 0
|
||||||
end
|
end
|
||||||
|
|
|
@ -31,14 +31,8 @@ local starPal = con.actorvar(0)
|
||||||
require("end_gamevars")
|
require("end_gamevars")
|
||||||
|
|
||||||
|
|
||||||
local function bangvec(bang)
|
local bangvec = xmath.bangvec
|
||||||
bang = math.floor(bang)
|
local angvec = xmath.angvec
|
||||||
return xmath.vec3(xmath.cosb(bang), xmath.sinb(bang))
|
|
||||||
end
|
|
||||||
|
|
||||||
local function angvec(ang)
|
|
||||||
return xmath.vec3(math.cos(ang), math.sin(ang))
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
local D = require("CON.DEFS")
|
local D = require("CON.DEFS")
|
||||||
|
|
|
@ -285,6 +285,17 @@ end
|
||||||
|
|
||||||
---=== MISCELLANEOUS MATH ===---
|
---=== MISCELLANEOUS MATH ===---
|
||||||
|
|
||||||
|
local intarg = ffi.new("int32_t [1]")
|
||||||
|
function bangvec(bang)
|
||||||
|
intarg[0] = bang -- round towards zero
|
||||||
|
return vec3(cosb(intarg[0]), sinb(intarg[0]))
|
||||||
|
end
|
||||||
|
|
||||||
|
function angvec(ang)
|
||||||
|
return vec3(cos(ang), sin(ang))
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
local zerovec = vec3()
|
local zerovec = vec3()
|
||||||
-- Point rotation. Note the different order of arguments from engine function.
|
-- Point rotation. Note the different order of arguments from engine function.
|
||||||
-- XXX: passing mixed vec2/vec3 is problematic. Get rid of vec2?
|
-- XXX: passing mixed vec2/vec3 is problematic. Get rid of vec2?
|
||||||
|
|
Loading…
Reference in a new issue