Lunatic: provide access to actor-tsprite.

git-svn-id: https://svn.eduke32.com/eduke32@3452 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2013-02-01 13:05:20 +00:00
parent f1ac4a63d0
commit 163c019209
9 changed files with 133 additions and 35 deletions

View file

@ -9999,11 +9999,11 @@ bool fatInit (uint32_t cacheSize, bool setAsDefaultDevice);
#ifdef LUNATIC #ifdef LUNATIC
const char *g_sizes_of_what[] = { const char *g_sizes_of_what[] = {
"sectortype", "walltype", "spritetype", "sectortype", "walltype", "spritetype", "spriteext_t",
"actor_t", "DukePlayer_t", "playerdata_t", "actor_t", "DukePlayer_t", "playerdata_t",
"user_defs", "tiledata_t" }; "user_defs", "tiledata_t" };
int32_t g_sizes_of[] = { int32_t g_sizes_of[] = {
sizeof(sectortype), sizeof(walltype), sizeof(spritetype), sizeof(sectortype), sizeof(walltype), sizeof(spritetype), sizeof(spriteext_t),
sizeof(actor_t), sizeof(DukePlayer_t), sizeof(playerdata_t), sizeof(actor_t), sizeof(DukePlayer_t), sizeof(playerdata_t),
sizeof(user_defs), sizeof(tiledata_t) }; sizeof(user_defs), sizeof(tiledata_t) };
#endif #endif

View file

@ -560,7 +560,7 @@ string.dump = nil
-- sanity-check struct type sizes -- sanity-check struct type sizes
local good = true local good = true
for i=0,7 do for i=0,8 do
local what = ffi.string(ffiC.g_sizes_of_what[i]) local what = ffi.string(ffiC.g_sizes_of_what[i])
local fsz = ffi.sizeof(what) local fsz = ffi.sizeof(what)
local csz = ffiC.g_sizes_of[i] local csz = ffiC.g_sizes_of[i]
@ -599,10 +599,12 @@ local con = require("control")
local MV, AC, AI = con.MV, con.AC, con.AI local MV, AC, AI = con.MV, con.AC, con.AI
-- Add game-side metamethods to "spritetype" and register it with "metatype" -- Add game-side metamethods to "spritetype" and register it with "metatype"
defs_c.spritetype_mt.__index.isenemy = function(s) local spr_mt_index_add = {
return con.isenemytile(s.picnum) isenemy = function(s)
end return con.isenemytile(s.picnum)
ffi.metatype("spritetype", defs_c.spritetype_mt) end,
}
defs_c.finish_spritetype(spr_mt_index_add)
-- All-zero action and move -- All-zero action and move
local nullac, nullmv = ffi.new("const struct action"), ffi.new("const struct move") local nullac, nullmv = ffi.new("const struct action"), ffi.new("const struct move")

View file

@ -18,6 +18,7 @@ local pairs = pairs
local require = require local require = require
local setmetatable = setmetatable local setmetatable = setmetatable
local tostring = tostring local tostring = tostring
local type = type
local decl = decl local decl = decl
local getfenv = getfenv local getfenv = getfenv
@ -100,6 +101,7 @@ ffi.cdef([[
typedef $ sectortype; typedef $ sectortype;
typedef $ walltype; typedef $ walltype;
typedef $ spritetype; typedef $ spritetype;
typedef $ tspritetype;
typedef struct { typedef struct {
const uint32_t mdanimtims; const uint32_t mdanimtims;
@ -110,8 +112,10 @@ typedef struct {
uint8_t xpanning, ypanning; uint8_t xpanning, ypanning;
const uint8_t filler; const uint8_t filler;
float alpha; float alpha;
const int32_t _do_not_use1; union {
const int32_t _do_not_use2; const intptr_t _tspr;
struct { const int32_t _dummy0, _dummy1; };
};
} spriteext_t; } spriteext_t;
typedef struct { typedef struct {
@ -123,7 +127,11 @@ typedef struct {
int16_t sprite, wall, sect; int16_t sprite, wall, sect;
} hitdata_t; } hitdata_t;
#pragma pack(pop) #pragma pack(pop)
]], ffi.typeof(SECTOR_STRUCT), ffi.typeof(WALL_STRUCT), ffi.typeof(SPRITE_STRUCT)) ]],
ffi.typeof(SECTOR_STRUCT), ffi.typeof(WALL_STRUCT),
ffi.typeof(SPRITE_STRUCT), ffi.typeof(SPRITE_STRUCT))
-- NOTE: spritetype and tspritetype are different types with the same layout.
-- (XXX: is there a better way?)
-- Define the "palette_t" type, which for us has .{r,g,b} fields and a -- Define the "palette_t" type, which for us has .{r,g,b} fields and a
-- bound-checking array of length 3 overlaid. -- bound-checking array of length 3 overlaid.
@ -154,6 +162,7 @@ if (ffiC.engine_main_arrays_are_static ~= 0) then
sectortype sector[]; sectortype sector[];
walltype wall[]; walltype wall[];
spritetype sprite[]; spritetype sprite[];
tspritetype tsprite[];
spriteext_t spriteext[]; spriteext_t spriteext[];
]] ]]
else else
@ -161,6 +170,7 @@ else
sectortype *sector; sectortype *sector;
walltype *wall; walltype *wall;
spritetype *sprite; spritetype *sprite;
tspritetype *tsprite;
spriteext_t *spriteext; spriteext_t *spriteext;
]] ]]
end end
@ -191,6 +201,7 @@ ffi.cdef[[
enum { enum {
MAXSTATUS = 1024, MAXSTATUS = 1024,
MAXTILES = 30720, MAXTILES = 30720,
MAXSPRITESONSCREEN = 4096,
MAXBUNCHES = 256, MAXBUNCHES = 256,
CEILING = 0, CEILING = 0,
@ -211,6 +222,7 @@ const int32_t windowx1, windowy1, windowx2, windowy2;
]] ]]
decl[[ decl[[
int32_t spritesortcnt;
const int32_t rendmode; const int32_t rendmode;
const int16_t headspritesect[MAXSECTORS+1], headspritestat[MAXSTATUS+1]; const int16_t headspritesect[MAXSECTORS+1], headspritestat[MAXSTATUS+1];
const int16_t prevspritesect[MAXSPRITES], prevspritestat[MAXSPRITES]; const int16_t prevspritesect[MAXSPRITES], prevspritestat[MAXSPRITES];
@ -257,6 +269,7 @@ int32_t __fastcall getangle(int32_t xvect, int32_t yvect);
local bcheck = require("bcheck") local bcheck = require("bcheck")
local check_sector_idx = bcheck.sector_idx local check_sector_idx = bcheck.sector_idx
local check_sprite_idx = bcheck.sprite_idx
local check_tile_idx = bcheck.tile_idx local check_tile_idx = bcheck.tile_idx
local ivec3_ local ivec3_
@ -368,9 +381,19 @@ local walltype_mt = {
} }
ffi.metatype("walltype", walltype_mt) ffi.metatype("walltype", walltype_mt)
local spriteext_mt = {
__index = {
-- Enable EVENT_ANIMATESPRITES for this sprite.
make_animated = function(sx)
sx.flags = bit.bor(sx.flags, 16)
end,
},
}
ffi.metatype("spriteext_t", spriteext_mt)
local spritetype_ptr_ct = ffi.typeof("$ *", ffi.typeof(strip_const(SPRITE_STRUCT))) local spritetype_ptr_ct = ffi.typeof("$ *", ffi.typeof(strip_const(SPRITE_STRUCT)))
spritetype_mt = { local spritetype_mt = {
__pow = function(s, zofs) __pow = function(s, zofs)
return ivec3_(s.x, s.y, s.z-zofs) return ivec3_(s.x, s.y, s.z-zofs)
end, end,
@ -387,8 +410,46 @@ spritetype_mt = {
end, end,
}, },
} }
-- The user of this module can insert additional "spritetype" metamethods and
-- register them with "ffi.metatype". local function deep_copy(tab)
local ntab = {}
for key, val in pairs(tab) do
if (type(val)=="table") then
ntab[key] = deep_copy(val)
else
assert(type(val)=="function")
ntab[key] = val
end
end
return ntab
end
local tspritetype_mt = deep_copy(spritetype_mt)
-- Methods that are specific to tsprites
-- XXX: doesn't work with LuaJIT git f772bed34b39448e3a9ab8d07f6d5c0c26300e1b
function tspritetype_mt.__index.dup(tspr)
if (ffiC.spritesortcnt >= ffiC.MAXSPRITESONSCREEN+0ULL) then
return nil
end
local newtspr = ffi.tsprite[ffiC.spritesortcnt]
ffi.copy(newtspr, tspr, ffi.sizeof(tspr))
ffiC.spritesortcnt = ffiC.spritesortcnt+1
return newtspr
end
-- The user of this module can insert additional "spritetype" index
-- methods and register them with "ffi.metatype".
function finish_spritetype(mt_index)
for name, func in pairs(mt_index) do
spritetype_mt.__index[name] = func
tspritetype_mt.__index[name] = func
end
ffi.metatype("spritetype", spritetype_mt)
ffi.metatype("tspritetype", tspritetype_mt)
end
---=== Restricted access to C variables from Lunatic ===--- ---=== Restricted access to C variables from Lunatic ===---
@ -406,7 +467,7 @@ local sector_mt = {
error('out-of-bounds sector[] read access', 2) error('out-of-bounds sector[] read access', 2)
end, end,
__newindex = function(tab, key, val) error('cannot write directly to sector[] struct', 2) end, __newindex = function() error('cannot write directly to sector[]', 2) end,
} }
local wall_mt = { local wall_mt = {
@ -415,7 +476,23 @@ local wall_mt = {
error('out-of-bounds wall[] read access', 2) error('out-of-bounds wall[] read access', 2)
end, end,
__newindex = function(tab, key, val) error('cannot write directly to wall[] struct', 2) end, __newindex = function() error('cannot write directly to wall[]', 2) end,
}
local atsprite_mt = {
__index = function(tab, idx)
check_sprite_idx(idx)
local tspr = ffi.cast(spritetype_ptr_ct, ffiC.spriteext[idx]._tspr)
if (tspr == nil) then
error("tsprite of actor "..idx.." unavailable", 2)
end
-- Return a reference to a tsprite[] element.
return tspr[0]
end,
__newindex = function() error('cannot write directly to atsprite[]', 2) end,
} }
-- create a safe indirection for an ffi.C array -- create a safe indirection for an ffi.C array
@ -428,7 +505,7 @@ function creategtab(ctab, maxidx, name)
end end
error('out-of-bounds '..name..' read access', 2) error('out-of-bounds '..name..' read access', 2)
end, end,
__newindex = function(tab, key, val) __newindex = function()
error('cannot write directly to '..name, 2) error('cannot write directly to '..name, 2)
end, end,
} }
@ -449,8 +526,9 @@ end
sector = setmtonce({}, sector_mt) sector = setmtonce({}, sector_mt)
wall = setmtonce({}, wall_mt) wall = setmtonce({}, wall_mt)
sprite = creategtab(ffiC.sprite, ffiC.MAXSPRITES, 'sprite[] struct') sprite = creategtab(ffiC.sprite, ffiC.MAXSPRITES, 'sprite[]')
spriteext = creategtab(ffiC.spriteext, ffiC.MAXSPRITES, 'spriteext[] struct') spriteext = creategtab(ffiC.spriteext, ffiC.MAXSPRITES, 'spriteext[]')
atsprite = setmtonce({}, atsprite_mt)
headspritesect = creategtab(ffiC.headspritesect, ffiC.MAXSECTORS, 'headspritesect[]') headspritesect = creategtab(ffiC.headspritesect, ffiC.MAXSECTORS, 'headspritesect[]')
-- TODO: allow sprite freelist access via the status list for CON compatibility? -- TODO: allow sprite freelist access via the status list for CON compatibility?

View file

@ -7,7 +7,7 @@ local ffiC = ffi.C
--== First, load the definitions common to the game's and editor's Lua interface. --== First, load the definitions common to the game's and editor's Lua interface.
decl = ffi.cdef decl = ffi.cdef
local defs_c = require("defs_common") local defs_c = require("defs_common")
ffi.metatype("spritetype", defs_c.spritetype_mt) defs_c.finish_spritetype({})
defs_c.create_globals(_G) defs_c.create_globals(_G)

View file

@ -5,11 +5,13 @@ engine_v8;
sector; sector;
wall; wall;
sprite; sprite;
tsprite;
spriteext; spriteext;
numsectors; numsectors;
numwalls; numwalls;
numyaxbunches; numyaxbunches;
spritesortcnt;
rendmode; rendmode;
totalclock; totalclock;

View file

@ -5,11 +5,13 @@ engine_v8;
sector; sector;
wall; wall;
sprite; sprite;
tsprite;
spriteext; spriteext;
numsectors; numsectors;
numwalls; numwalls;
numyaxbunches; numyaxbunches;
spritesortcnt;
rendmode; rendmode;
totalclock; totalclock;

View file

@ -1274,10 +1274,10 @@ local Cinner = {
getactor = GetStructCmd(Access.xsprite), getactor = GetStructCmd(Access.xsprite),
getplayer = GetStructCmd(Access.player), getplayer = GetStructCmd(Access.player),
getinput = getstructcmd, getinput = getstructcmd / handle.NYI,
getprojectile = getstructcmd, getprojectile = getstructcmd / handle.NYI,
getthisprojectile = getstructcmd, getthisprojectile = getstructcmd / handle.NYI,
gettspr = getstructcmd, gettspr = getstructcmd / handle.NYI,
-- NOTE: {get,set}userdef is the only struct that can be accessed without -- NOTE: {get,set}userdef is the only struct that can be accessed without
-- an "array part", e.g. H266MOD has "setuserdef .weaponswitch 0" (space -- an "array part", e.g. H266MOD has "setuserdef .weaponswitch 0" (space
-- between keyword and "." is mandatory). -- between keyword and "." is mandatory).
@ -1286,21 +1286,21 @@ local Cinner = {
-- arrays, I highly doubt that they worked (much less were safe) in CON. -- arrays, I highly doubt that they worked (much less were safe) in CON.
-- We disallow them unless CONs in the wild crop up that actually used -- We disallow them unless CONs in the wild crop up that actually used
-- these. -- these.
getuserdef = (arraypat + sp1)/{} * singlememberpat * sp1 * tok.wvar, getuserdef = (arraypat + sp1)/{} * singlememberpat * sp1 * tok.wvar / handle.NYI,
getactorvar = getperxvarcmd, getactorvar = getperxvarcmd / handle.NYI,
getplayervar = getperxvarcmd, getplayervar = getperxvarcmd / handle.NYI,
setsector = SetStructCmd(Access.sector), setsector = SetStructCmd(Access.sector),
setwall = SetStructCmd(Access.wall), setwall = SetStructCmd(Access.wall),
setactor = SetStructCmd(Access.xsprite), setactor = SetStructCmd(Access.xsprite),
setplayer = SetStructCmd(Access.player), setplayer = SetStructCmd(Access.player),
setinput = setstructcmd, setinput = setstructcmd / handle.NYI,
setprojectile = setstructcmd, setprojectile = setstructcmd / handle.NYI,
setthisprojectile = setstructcmd, setthisprojectile = setstructcmd / handle.NYI,
settspr = setstructcmd, settspr = setstructcmd / handle.NYI,
setuserdef = (arraypat + sp1)/{} * singlememberpat * sp1 * tok.rvar, setuserdef = (arraypat + sp1)/{} * singlememberpat * sp1 * tok.rvar / handle.NYI,
setactorvar = setperxvarcmd, setactorvar = setperxvarcmd,
setplayervar = setperxvarcmd, setplayervar = setperxvarcmd,

View file

@ -133,7 +133,7 @@ checkfail('gv.numsectors = 4', "write access forbidden")
checkfail('gv.QWE = 4', "write access forbidden") checkfail('gv.QWE = 4', "write access forbidden")
-- direct sector write access forbidden -- direct sector write access forbidden
checkfail('sector[4] = sector[6]', "cannot write directly to sector[] struct") checkfail('sector[4] = sector[6]', "cannot write directly to sector[]")
-- that would be horrible... -- that would be horrible...
checkfail('nextspritesect[4] = -666', "cannot write directly to nextspritesect[]") checkfail('nextspritesect[4] = -666', "cannot write directly to nextspritesect[]")
@ -285,6 +285,8 @@ local TROOPSTRENGTH = 30
gameactor(1680, TROOPSTRENGTH, "TROOPSTAND", -- LIZTROOP gameactor(1680, TROOPSTRENGTH, "TROOPSTAND", -- LIZTROOP
function(i, playeri, dist) 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)
@ -320,6 +322,18 @@ gameevent("DISPLAYROOMS",
end end
) )
gameevent("ANIMATESPRITES",
function(aci)
local tspr = atsprite[aci]
if (tspr.picnum==1680) then
--[[
local tspr2 = tspr:dup()
tspr2.x = tspr2.x + 512*math.cos(gv.totalclock/120)
tspr2.y = tspr2.y + 512*math.sin(gv.totalclock/120)
--]]
end
end)
printf("EVENT_INIT = %d", gv.EVENT_INIT) -- tests default defines printf("EVENT_INIT = %d", gv.EVENT_INIT) -- tests default defines
local bittest = require "bittest" local bittest = require "bittest"

View file

@ -40,17 +40,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define PIPEBOMB_TIMER 0x00000002 #define PIPEBOMB_TIMER 0x00000002
enum dukeinv_t { enum dukeinv_t {
GET_STEROIDS, GET_STEROIDS, // 0
GET_SHIELD, GET_SHIELD,
GET_SCUBA, GET_SCUBA,
GET_HOLODUKE, GET_HOLODUKE,
GET_JETPACK, GET_JETPACK,
GET_DUMMY1, GET_DUMMY1, // 5
GET_ACCESS, GET_ACCESS,
GET_HEATS, GET_HEATS,
GET_DUMMY2, GET_DUMMY2,
GET_FIRSTAID, GET_FIRSTAID,
GET_BOOTS, GET_BOOTS, // 10
GET_MAX GET_MAX
}; };