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
const char *g_sizes_of_what[] = {
"sectortype", "walltype", "spritetype",
"sectortype", "walltype", "spritetype", "spriteext_t",
"actor_t", "DukePlayer_t", "playerdata_t",
"user_defs", "tiledata_t" };
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(user_defs), sizeof(tiledata_t) };
#endif

View file

@ -560,7 +560,7 @@ string.dump = nil
-- sanity-check struct type sizes
local good = true
for i=0,7 do
for i=0,8 do
local what = ffi.string(ffiC.g_sizes_of_what[i])
local fsz = ffi.sizeof(what)
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
-- Add game-side metamethods to "spritetype" and register it with "metatype"
defs_c.spritetype_mt.__index.isenemy = function(s)
return con.isenemytile(s.picnum)
end
ffi.metatype("spritetype", defs_c.spritetype_mt)
local spr_mt_index_add = {
isenemy = function(s)
return con.isenemytile(s.picnum)
end,
}
defs_c.finish_spritetype(spr_mt_index_add)
-- All-zero action and 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 setmetatable = setmetatable
local tostring = tostring
local type = type
local decl = decl
local getfenv = getfenv
@ -100,6 +101,7 @@ ffi.cdef([[
typedef $ sectortype;
typedef $ walltype;
typedef $ spritetype;
typedef $ tspritetype;
typedef struct {
const uint32_t mdanimtims;
@ -110,8 +112,10 @@ typedef struct {
uint8_t xpanning, ypanning;
const uint8_t filler;
float alpha;
const int32_t _do_not_use1;
const int32_t _do_not_use2;
union {
const intptr_t _tspr;
struct { const int32_t _dummy0, _dummy1; };
};
} spriteext_t;
typedef struct {
@ -123,7 +127,11 @@ typedef struct {
int16_t sprite, wall, sect;
} hitdata_t;
#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
-- bound-checking array of length 3 overlaid.
@ -154,6 +162,7 @@ if (ffiC.engine_main_arrays_are_static ~= 0) then
sectortype sector[];
walltype wall[];
spritetype sprite[];
tspritetype tsprite[];
spriteext_t spriteext[];
]]
else
@ -161,6 +170,7 @@ else
sectortype *sector;
walltype *wall;
spritetype *sprite;
tspritetype *tsprite;
spriteext_t *spriteext;
]]
end
@ -191,6 +201,7 @@ ffi.cdef[[
enum {
MAXSTATUS = 1024,
MAXTILES = 30720,
MAXSPRITESONSCREEN = 4096,
MAXBUNCHES = 256,
CEILING = 0,
@ -211,6 +222,7 @@ const int32_t windowx1, windowy1, windowx2, windowy2;
]]
decl[[
int32_t spritesortcnt;
const int32_t rendmode;
const int16_t headspritesect[MAXSECTORS+1], headspritestat[MAXSTATUS+1];
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 check_sector_idx = bcheck.sector_idx
local check_sprite_idx = bcheck.sprite_idx
local check_tile_idx = bcheck.tile_idx
local ivec3_
@ -368,9 +381,19 @@ local 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)))
spritetype_mt = {
local spritetype_mt = {
__pow = function(s, zofs)
return ivec3_(s.x, s.y, s.z-zofs)
end,
@ -387,8 +410,46 @@ spritetype_mt = {
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 ===---
@ -406,7 +467,7 @@ local sector_mt = {
error('out-of-bounds sector[] read access', 2)
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 = {
@ -415,7 +476,23 @@ local wall_mt = {
error('out-of-bounds wall[] read access', 2)
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
@ -428,7 +505,7 @@ function creategtab(ctab, maxidx, name)
end
error('out-of-bounds '..name..' read access', 2)
end,
__newindex = function(tab, key, val)
__newindex = function()
error('cannot write directly to '..name, 2)
end,
}
@ -449,8 +526,9 @@ end
sector = setmtonce({}, sector_mt)
wall = setmtonce({}, wall_mt)
sprite = creategtab(ffiC.sprite, ffiC.MAXSPRITES, 'sprite[] struct')
spriteext = creategtab(ffiC.spriteext, ffiC.MAXSPRITES, 'spriteext[] struct')
sprite = creategtab(ffiC.sprite, ffiC.MAXSPRITES, 'sprite[]')
spriteext = creategtab(ffiC.spriteext, ffiC.MAXSPRITES, 'spriteext[]')
atsprite = setmtonce({}, atsprite_mt)
headspritesect = creategtab(ffiC.headspritesect, ffiC.MAXSECTORS, 'headspritesect[]')
-- 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.
decl = ffi.cdef
local defs_c = require("defs_common")
ffi.metatype("spritetype", defs_c.spritetype_mt)
defs_c.finish_spritetype({})
defs_c.create_globals(_G)

View file

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

View file

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

View file

@ -1274,10 +1274,10 @@ local Cinner = {
getactor = GetStructCmd(Access.xsprite),
getplayer = GetStructCmd(Access.player),
getinput = getstructcmd,
getprojectile = getstructcmd,
getthisprojectile = getstructcmd,
gettspr = getstructcmd,
getinput = getstructcmd / handle.NYI,
getprojectile = getstructcmd / handle.NYI,
getthisprojectile = getstructcmd / handle.NYI,
gettspr = getstructcmd / handle.NYI,
-- NOTE: {get,set}userdef is the only struct that can be accessed without
-- an "array part", e.g. H266MOD has "setuserdef .weaponswitch 0" (space
-- between keyword and "." is mandatory).
@ -1286,21 +1286,21 @@ local Cinner = {
-- 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
-- these.
getuserdef = (arraypat + sp1)/{} * singlememberpat * sp1 * tok.wvar,
getuserdef = (arraypat + sp1)/{} * singlememberpat * sp1 * tok.wvar / handle.NYI,
getactorvar = getperxvarcmd,
getplayervar = getperxvarcmd,
getactorvar = getperxvarcmd / handle.NYI,
getplayervar = getperxvarcmd / handle.NYI,
setsector = SetStructCmd(Access.sector),
setwall = SetStructCmd(Access.wall),
setactor = SetStructCmd(Access.xsprite),
setplayer = SetStructCmd(Access.player),
setinput = setstructcmd,
setprojectile = setstructcmd,
setthisprojectile = setstructcmd,
settspr = setstructcmd,
setuserdef = (arraypat + sp1)/{} * singlememberpat * sp1 * tok.rvar,
setinput = setstructcmd / handle.NYI,
setprojectile = setstructcmd / handle.NYI,
setthisprojectile = setstructcmd / handle.NYI,
settspr = setstructcmd / handle.NYI,
setuserdef = (arraypat + sp1)/{} * singlememberpat * sp1 * tok.rvar / handle.NYI,
setactorvar = setperxvarcmd,
setplayervar = setperxvarcmd,

View file

@ -133,7 +133,7 @@ checkfail('gv.numsectors = 4', "write access forbidden")
checkfail('gv.QWE = 4', "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...
checkfail('nextspritesect[4] = -666', "cannot write directly to nextspritesect[]")
@ -285,6 +285,8 @@ local TROOPSTRENGTH = 30
gameactor(1680, TROOPSTRENGTH, "TROOPSTAND", -- LIZTROOP
function(i, playeri, dist)
spriteext[i]:make_animated()
sprite[i].pal = math.random(32)
-- sprite[i].ang = bit.band(sprite[i].ang-20, 2047)
@ -320,6 +322,18 @@ gameevent("DISPLAYROOMS",
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
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
enum dukeinv_t {
GET_STEROIDS,
GET_STEROIDS, // 0
GET_SHIELD,
GET_SCUBA,
GET_HOLODUKE,
GET_JETPACK,
GET_DUMMY1,
GET_DUMMY1, // 5
GET_ACCESS,
GET_HEATS,
GET_DUMMY2,
GET_FIRSTAID,
GET_BOOTS,
GET_BOOTS, // 10
GET_MAX
};