mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-24 02:30:46 +00:00
Lunatic: revamp sector changing/updating functions of sprites.
git-svn-id: https://svn.eduke32.com/eduke32@3953 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
b9dfcc902d
commit
d7ad2c36d4
5 changed files with 108 additions and 19 deletions
|
@ -1456,6 +1456,21 @@ function _movesprite(spritenum, x, y, z, cliptype)
|
|||
return ffiC.A_MoveSprite(spritenum, vel, cliptype)
|
||||
end
|
||||
|
||||
-- CON's 'setsprite' function on top of the Lunatic-provided ones.
|
||||
-- (Lunatic's sprite setting functions have slightly different semantics.)
|
||||
local updatesect = sprite.updatesect
|
||||
function _setsprite(i, pos)
|
||||
check_sprite_idx(i)
|
||||
local spr = ffiC.sprite[i]
|
||||
|
||||
-- First, unconditionally set the sprite's position.
|
||||
spr:setpos(pos)
|
||||
|
||||
-- Next, update the sector number, but if updatesector() returns -1, don't
|
||||
-- change it. (This is exactly what sprite.updatesect() provides.)
|
||||
updatesect(i)
|
||||
end
|
||||
|
||||
-- NOTE: returns two args (in C version, hit sprite is a pointer input arg)
|
||||
local function A_CheckHitSprite(spr, angadd)
|
||||
local zoff = (spr:isenemy() and 42*256) or (ispic(spr.picnum, "APLAYER") and 39*256) or 0
|
||||
|
|
|
@ -665,6 +665,10 @@ end
|
|||
|
||||
local tspritetype_mt = deep_copy(spritetype_mt)
|
||||
|
||||
-- Get the sprite index of a sprite reference.
|
||||
-- This is relatively slow if the code doesn't get compiled, see related
|
||||
-- discussion here:
|
||||
-- http://www.freelists.org/post/luajit/FFI-versus-Lua-C-API-in-purely-interpreted-mode
|
||||
local function get_sprite_idx(spr)
|
||||
local i = ffi.cast(spritetype_ptr_ct, spr)-ffi.cast(spritetype_ptr_ct, ffiC.sprite)
|
||||
assert(not (i >= ffiC.MAXSPRITES+0ULL))
|
||||
|
@ -674,36 +678,65 @@ end
|
|||
---=== Methods that are specific to sprites ===---
|
||||
|
||||
local l_updatesector -- fwd-decl
|
||||
local l_changesect -- fwd-decl
|
||||
|
||||
function spritetype_mt.__index.setpos(spr, pos) -- setsprite() clone
|
||||
-- The 'setpos' method is available for sprite and tsprite objects.
|
||||
-- spr:setpos(pos [, newsect]),
|
||||
-- where <newsect> is taken to mean "set the sprite's sector number to <newsect>";
|
||||
-- don't run update/search routines or anything like this.
|
||||
function spritetype_mt.__index.setpos(spr, pos, newsect)
|
||||
spr.x, spr.y, spr.z = pos.x, pos.y, pos.z
|
||||
local newsect = l_updatesector(spr, spr.sectnum)
|
||||
|
||||
if (newsect >= 0 and spr.sectnum ~= newsect) then
|
||||
ffiC.changespritesect(get_sprite_idx(spr), newsect)
|
||||
if (newsect ~= nil) then
|
||||
spr:changesect(newsect)
|
||||
end
|
||||
return spr
|
||||
end
|
||||
|
||||
-- spr:changesect(newsect)
|
||||
-- changes the sector number of <spr> in an 'unforgiving' fashion (<newsect> of
|
||||
-- -1 is error)
|
||||
function spritetype_mt.__index.changesect(spr, newsect)
|
||||
if (newsect ~= spr.sectnum) then
|
||||
l_changesect(get_sprite_idx(spr), newsect)
|
||||
end
|
||||
end
|
||||
|
||||
-- spr:updatesect(flags)
|
||||
-- updates <spr>'s sectnum; if no matching sector is found, no-op
|
||||
-- returns the updated sector number
|
||||
function spritetype_mt.__index.updatesect(spr, flags)
|
||||
local newsect = l_updatesector(spr, spr.sectnum, flags)
|
||||
if (newsect ~= -1) then
|
||||
spr:changesect(newsect)
|
||||
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
|
||||
-- This ought to be called 'set_sectnum', but 'changesect' is for consistency
|
||||
-- with the sprite method.
|
||||
function tspritetype_mt.__index.changesect(tspr, sectnum)
|
||||
if (tspr.sectnum ~= sectnum) then
|
||||
check_sector_idx(sectnum)
|
||||
ffi.cast(spritetype_ptr_ct, tspr).sectnum = sectnum
|
||||
end
|
||||
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)
|
||||
function tspritetype_mt.__index.setpos(tspr, pos, newsect)
|
||||
tspr.x, tspr.y, tspr.z = pos.x, pos.y, pos.z
|
||||
local newsect = l_updatesector(tspr, tspr.sectnum)
|
||||
|
||||
if (newsect >= 0 and tspr.sectnum ~= newsect) then
|
||||
if (newsect ~= nil) then
|
||||
tspr:set_sectnum(newsect)
|
||||
end
|
||||
return tspr
|
||||
end
|
||||
|
||||
function tspritetype_mt.__index.updatesect(tspr, flags)
|
||||
local newsect = l_updatesector(tspr, tspr.sectnum, flags)
|
||||
if (newsect ~= -1 and newsect ~= tspr.sectnum) then
|
||||
tspr:set_sectnum(newsect)
|
||||
end
|
||||
return newsect
|
||||
end
|
||||
|
||||
|
@ -816,6 +849,7 @@ static_members.sector.NEARTAG_FLAGS = conststruct
|
|||
static_members.sector.UPDATE_FLAGS = conststruct
|
||||
{
|
||||
BREADTH = 1,
|
||||
Z = 2,
|
||||
}
|
||||
|
||||
static_members.wall.CSTAT = conststruct
|
||||
|
@ -874,6 +908,12 @@ function static_members.wall.dragto(wallnum, pos)
|
|||
ffiC.dragpoint(wallnum, pos.x, pos.y, 0)
|
||||
end
|
||||
|
||||
-- Functions changing the sector/status number of a sprite, without asking.
|
||||
|
||||
-- Changes sector number of sprite with index <spritenum> to <sectnum>,
|
||||
-- unconditionally and "unforgiving" (oob <sectnum> gives error).
|
||||
-- <noerr> is for CON compatibility and prevents error on *sprite not in the
|
||||
-- game world* if true.
|
||||
function static_members.sprite.changesect(spritenum, sectnum, noerr)
|
||||
check_sprite_idx(spritenum)
|
||||
check_sector_idx(sectnum)
|
||||
|
@ -882,6 +922,8 @@ function static_members.sprite.changesect(spritenum, sectnum, noerr)
|
|||
end
|
||||
end
|
||||
|
||||
l_changesect = static_members.sprite.changesect
|
||||
|
||||
function static_members.sprite.changestat(spritenum, statnum, noerr)
|
||||
-- TODO: see gameexec.c's CON_CHANGESPRITESTAT.
|
||||
check_sprite_idx(spritenum)
|
||||
|
@ -893,6 +935,18 @@ function static_members.sprite.changestat(spritenum, statnum, noerr)
|
|||
end
|
||||
end
|
||||
|
||||
-- Update a sprite's sector number from its current position and sector number.
|
||||
function static_members.sprite.updatesect(spritenum, flags)
|
||||
check_sprite_idx(spritenum)
|
||||
local spr = ffiC.sprite[spritenum]
|
||||
|
||||
local newsect = l_updatesector(spr, spr.sectnum, flags)
|
||||
if (newsect ~= -1 and newsect ~= spr.sectnum) then
|
||||
l_changesect(spritenum, newsect)
|
||||
end
|
||||
return newsect
|
||||
end
|
||||
|
||||
function GenStructMetatable(Structname, Boundname, StaticMembersTab)
|
||||
StaticMembersTab = StaticMembersTab or static_members[Structname]
|
||||
|
||||
|
@ -1118,6 +1172,10 @@ function updatesector(pos, sectnum, flags)
|
|||
ffiC.updatesector(pos.x, pos.y, us_retsect)
|
||||
elseif (flags==USF.BREADTH) then
|
||||
ffiC.updatesectorbreadth(pos.x, pos.y, us_retsect)
|
||||
elseif (flags==USF.Z) then
|
||||
-- Same as updatesectorz, but useful if we are called from
|
||||
-- e.g. sprite.updatesect().
|
||||
ffiC.updatesectorz(pos.x, pos.y, pos.z, us_retsect)
|
||||
else
|
||||
error("invalid argument #3 (flags)", 2)
|
||||
end
|
||||
|
|
|
@ -301,6 +301,7 @@ local function new_initial_codetab()
|
|||
"local _div, _mod, _mulTR, _mulWR = _con._div, _con._mod, _con._mulTR, _con._mulWR",
|
||||
"local _band, _bor, _bxor = _bit.band, _bit.bor, _bit.bxor",
|
||||
"local _lsh, _rsh, _arsh = _bit.lshift, _bit.rshift, _bit.arshift",
|
||||
"local _setsprite = _con._setsprite",
|
||||
|
||||
-- * CON "states" (subroutines) and
|
||||
-- * Switch function table, indexed by global switch sequence number:
|
||||
|
@ -2689,7 +2690,7 @@ local Cinner = {
|
|||
ssp = cmd(R,R)
|
||||
/ handle.NYI,
|
||||
setsprite = cmd(R,R,R,R)
|
||||
/ "sprite[%1]:setpos(_IV(1,%2,%3,%4))",
|
||||
/ "_setsprite(%1,_IV(1,%2,%3,%4))",
|
||||
updatesector = cmd(R,R,W)
|
||||
/ format("%%3=updatesector(_IV(1,%%1,%%2,0),%s)", SPS".sectnum"),
|
||||
updatesectorz = cmd(R,R,R,W)
|
||||
|
|
|
@ -371,6 +371,8 @@ gameevent{"LOADACTOR", function(i)
|
|||
if (i==614 and spr.picnum==930) then
|
||||
-- "police line" ribbon in E1L1
|
||||
-- clear the hitag so that it doesn't spawn as FALLER from premap
|
||||
-- Rather a HACK: relies on an implementation detail (A_Spawn()
|
||||
-- "hard-wired" code).
|
||||
spr.hitag = 0
|
||||
end
|
||||
end}
|
||||
|
@ -386,7 +388,7 @@ gameactor
|
|||
local d = 20
|
||||
-- NOTE: __add metamethod is called because of the RHS:
|
||||
local v = spr + xmath.vec3(r(-d,d), r(-d,d))
|
||||
spr:setpos(v)
|
||||
spr:setpos(v):updatesect()
|
||||
|
||||
-- Test vec3 constructor with cdata.
|
||||
local tempvec = xmath.vec3(player[0].pos)
|
||||
|
@ -486,8 +488,7 @@ gameactor
|
|||
if (aimtspr) then
|
||||
aimtspr.pal = 2
|
||||
aimtspr:set_picnum(555)
|
||||
aimtspr:setpos(hit.pos)
|
||||
aimtspr:set_sectnum(hit.sect)
|
||||
aimtspr:setpos(hit.pos, hit.sect)
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
@ -550,6 +551,7 @@ gameevent
|
|||
-- in such a sector or an adjoining one.)
|
||||
-- XXX: We need a better place to do this, maybe an event in
|
||||
-- G_DisplayRest() where show2dsector[] is tweaked?
|
||||
-- NOT YET OFFICIAL API.
|
||||
local show2dsector = sector.showbitmap
|
||||
for i=0,gv.numsectors-1 do
|
||||
if (sector[i].floorpicnum==815) then
|
||||
|
|
|
@ -53,12 +53,12 @@ gameactor
|
|||
func = function(aci)
|
||||
-- NOTE: this is prettier than calling it 'a', even if 'act' is used to
|
||||
-- denote an action in other places:
|
||||
local spr = sprite[aci]
|
||||
local act = actor[aci]
|
||||
|
||||
if (act:has_action(0)) then
|
||||
act:set_action(1) -- TODO: actor constructors, i.e. 'init' callbacks
|
||||
|
||||
local spr = sprite[aci]
|
||||
local decasec = math.floor((gv.gametic - nukeswStart[spr.owner])/(GTICSPERSEC*10))
|
||||
|
||||
local pal = COLOR[decasec+1]
|
||||
|
@ -74,6 +74,19 @@ gameactor
|
|||
if (act:checkbump()) then
|
||||
con.killit()
|
||||
end
|
||||
|
||||
-- Test spr:changesect() vs. sprite.changesect()
|
||||
local sectnum = spr.sectnum
|
||||
|
||||
for i=0,gv.numsectors-1 do
|
||||
if (spr.pal ~= 2 and spr.pal ~= 7) then
|
||||
sprite.changesect(aci, i) -- noticeably faster...
|
||||
else
|
||||
spr:changesect(i) -- ...than this
|
||||
end
|
||||
end
|
||||
|
||||
sprite.changesect(aci, sectnum)
|
||||
end
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue