Lunatic (translator): provide checked write access to a couple more members.

git-svn-id: https://svn.eduke32.com/eduke32@3446 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2013-02-01 13:05:00 +00:00
parent 627c0625ae
commit 9230ec7ba7
4 changed files with 106 additions and 58 deletions

View file

@ -1,3 +1,4 @@
-- Bound-checking functions for engine and game "things".
local ffiC = require("ffi").C local ffiC = require("ffi").C
@ -11,6 +12,12 @@ function bcheck.sector_idx(sectnum)
end end
end end
function bcheck.wall_idx(wallnum)
if (wallnum >= ffiC.numwalls+0ULL) then
error("invalid wall number "..wallnum, 3)
end
end
-- TODO: Provide another function that also checks whether the sprite exists in -- TODO: Provide another function that also checks whether the sprite exists in
-- the game world (statnum != MAXSTATUS). -- the game world (statnum != MAXSTATUS).
function bcheck.sprite_idx(spritenum) function bcheck.sprite_idx(spritenum)

View file

@ -342,8 +342,6 @@ local ActorLabels = {
hitag = SP".hitag", hitag = SP".hitag",
extra = SP".extra", extra = SP".extra",
-- { get, set }
-- Read access differs from write:
ulotag = S2U(SP".lotag"), ulotag = S2U(SP".lotag"),
uhitag = S2U(SP".hitag"), uhitag = S2U(SP".hitag"),
@ -365,8 +363,8 @@ local ActorLabels = {
htbposx = AC".bpos.x", htbposx = AC".bpos.x",
htbposy = AC".bpos.y", htbposy = AC".bpos.y",
htbposz = AC".bpos.z", htbposz = AC".bpos.z",
-- Read access differs from write, write not available: -- Read access differs from write ({ get, set }):
htg_t = { AC":get_t_data(%s)" }, htg_t = { AC":get_t_data(%s)", AC":_set_t_data(%s,%%s)" },
htflags = AC".flags", htflags = AC".flags",
-- model flags -- model flags
@ -380,6 +378,7 @@ local ActorLabels = {
xpanning = SX".xpanning", xpanning = SX".xpanning",
ypanning = SX".ypanning", ypanning = SX".ypanning",
-- Read access differs from write, write not available:
alpha = { "_math.floor(spriteext[%s].alpha*255)" }, alpha = { "_math.floor(spriteext[%s].alpha*255)" },
} }
@ -612,7 +611,7 @@ local SectorLabels = {
floorstat = SEC".floorstat", floorstat = SEC".floorstat",
-- CEILING -- CEILING
ceilingpicnum = SECRO".ceilingpicnum", ceilingpicnum = { SEC".ceilingpicnum", SEC":set_ceilingpicnum(%%s)" },
ceilingslope = SEC".ceilingheinum", -- NAME ceilingslope = SEC".ceilingheinum", -- NAME
ceilingshade = SEC".ceilingshade", ceilingshade = SEC".ceilingshade",
@ -622,7 +621,7 @@ local SectorLabels = {
ceilingypanning = SEC".ceilingypanning", ceilingypanning = SEC".ceilingypanning",
-- FLOOR -- FLOOR
floorpicnum = SECRO".floorpicnum", floorpicnum = { SEC".floorpicnum", SEC":set_floorpicnum(%%s)" },
floorslope = SEC".floorheinum", -- NAME floorslope = SEC".floorheinum", -- NAME
floorshade = SEC".floorshade", floorshade = SEC".floorshade",
@ -653,11 +652,11 @@ local WallLabels = {
x = WAL".x", x = WAL".x",
y = WAL".y", y = WAL".y",
point2 = WALRO".point2", point2 = WALRO".point2",
nextwall = WALRO".nextwall", nextwall = { WAL".nextwall", WAL":_set_nextwall(%%s)" },
nextsector = WALRO".nextsector", nextsector = { WAL".nextsector", WAL":_set_nextsector(%%s)" },
cstat = WAL".cstat", cstat = WAL".cstat",
picnum = WALRO".picnum", picnum = { WAL".picnum", WAL":set_picnum(%%s)" },
overpicnum = WALRO".overpicnum", overpicnum = { WAL".overpicnum", WAL":set_overpicnum(%%s)" },
shade = WAL".shade", shade = WAL".shade",
pal = WAL".pal", pal = WAL".pal",
xrepeat = WAL".xrepeat", xrepeat = WAL".xrepeat",

View file

@ -751,12 +751,20 @@ local actor_mt = {
end, end,
-- Getters/setters. -- Getters/setters.
-- TODO: make a bcarray instead.
get_t_data = function(a, idx) get_t_data = function(a, idx)
if (idx >= 10ULL) then if (idx >= 10ULL) then
error("Invalid t_data index "..idx, 2) error("Invalid t_data index "..idx, 2)
end end
return ffi.cast(actor_ptr_ct, a).t_data[idx] return ffi.cast(actor_ptr_ct, a).t_data[idx]
end, end,
_set_t_data = function(a, idx, val)
if (idx >= 10ULL) then
error("Invalid t_data index "..idx, 2)
end
ffi.cast(actor_ptr_ct, a).t_data[idx] = val
end,
}, },
} }
ffi.metatype("actor_t", actor_mt) ffi.metatype("actor_t", actor_mt)

View file

@ -39,39 +39,8 @@ module(...)
--== Core engine structs ==-- --== Core engine structs ==--
local SPRITE_STRUCT = [[ local SECTOR_STRUCT = [[
{ struct {
int32_t x, y, z;
uint16_t cstat;
const int16_t picnum;
int8_t shade;
uint8_t pal, clipdist, filler;
uint8_t xrepeat, yrepeat;
int8_t xoffset, yoffset;
const int16_t sectnum, statnum;
int16_t ang;
// NOTE: yvel is often used as player index in game code. Make xvel/zvel
// "const" for consistency, too.
const int16_t owner, xvel, yvel, zvel;
int16_t lotag, hitag, extra;
}
]]
-- Converts a template struct definition to an internal, unrestricted one.
function strip_const(structstr)
return string.gsub(structstr, "const ", "");
end
-- NOTE for FFI definitions: we're compiling EDuke32 with -funsigned-char, so
-- we need to take care to declare chars as unsigned whenever it matters, for
-- example if it represents a palette index. (I think it's harmless for stuff
-- like passing a function argument, but it should be done there for clarity.)
-- TODO: provide getters for unsigned {hi,lo}tag?
ffi.cdef([[
#pragma pack(push,1)
typedef struct
{
const int16_t wallptr, wallnum; const int16_t wallptr, wallnum;
int32_t ceilingz, floorz; int32_t ceilingz, floorz;
uint16_t ceilingstat, floorstat; uint16_t ceilingstat, floorstat;
@ -85,10 +54,27 @@ typedef struct
uint8_t floorpal, floorxpanning, floorypanning; uint8_t floorpal, floorxpanning, floorypanning;
uint8_t visibility, filler; uint8_t visibility, filler;
int16_t lotag, hitag, extra; int16_t lotag, hitag, extra;
} sectortype; }]]
typedef struct local SPRITE_STRUCT = [[
{ struct {
int32_t x, y, z;
uint16_t cstat;
const int16_t picnum;
int8_t shade;
uint8_t pal, clipdist, filler;
uint8_t xrepeat, yrepeat;
int8_t xoffset, yoffset;
const int16_t sectnum, statnum;
int16_t ang;
// NOTE: yvel is often used as player index in game code. Make xvel/zvel
// "const" for consistency, too.
const int16_t owner, xvel, yvel, zvel;
int16_t lotag, hitag, extra;
}]]
local WALL_STRUCT = [[
struct {
int32_t x, y; int32_t x, y;
const int16_t point2, nextwall, nextsector; const int16_t point2, nextwall, nextsector;
uint16_t cstat; uint16_t cstat;
@ -96,15 +82,24 @@ typedef struct
int8_t shade; int8_t shade;
uint8_t pal, xrepeat, yrepeat, xpanning, ypanning; uint8_t pal, xrepeat, yrepeat, xpanning, ypanning;
int16_t lotag, hitag, extra; int16_t lotag, hitag, extra;
} walltype; }]]
typedef struct -- Converts a template struct definition to an internal, unrestricted one.
]].. SPRITE_STRUCT ..[[ function strip_const(structstr)
spritetype; return (string.gsub(structstr, "const ", ""));
end
typedef struct -- NOTE for FFI definitions: we're compiling EDuke32 with -funsigned-char, so
]].. strip_const(SPRITE_STRUCT) ..[[ -- we need to take care to declare chars as unsigned whenever it matters, for
spritetype_u_t; -- example if it represents a palette index. (I think it's harmless for stuff
-- like passing a function argument, but it should be done there for clarity.)
-- TODO: provide getters for unsigned {hi,lo}tag?
ffi.cdef([[
#pragma pack(push,1)
typedef $ sectortype;
typedef $ walltype;
typedef $ spritetype;
typedef struct { typedef struct {
const uint32_t mdanimtims; const uint32_t mdanimtims;
@ -128,7 +123,7 @@ 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))
-- 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.
@ -262,6 +257,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_tile_idx = bcheck.tile_idx
local ivec3_ local ivec3_
local ivec3_mt = { local ivec3_mt = {
@ -275,8 +271,22 @@ ivec3_ = ffi.metatype(vec3_ct, ivec3_mt)
local xor = bit.bxor local xor = bit.bxor
local wallsofsec -- fwd-decl local wallsofsec -- fwd-decl
local sectortype_ptr_ct = ffi.typeof("$ *", ffi.typeof(strip_const(SECTOR_STRUCT)))
local sectortype_mt = { local sectortype_mt = {
__index = { __index = {
--- Setters
set_ceilingpicnum = function(s, picnum)
check_tile_idx(picnum)
ffi.cast(sectortype_ptr_ct, s).ceilingpicnum = picnum
end,
set_floorpicnum = function(s, picnum)
check_tile_idx(picnum)
ffi.cast(sectortype_ptr_ct, s).floorpicnum = picnum
end,
--- Other methods
ceilingzat = function(s, pos) ceilingzat = function(s, pos)
return ffiC.getceilzofslopeptr(s, pos.x, pos.y) return ffiC.getceilzofslopeptr(s, pos.x, pos.y)
end, end,
@ -311,8 +321,34 @@ local sectortype_mt = {
} }
ffi.metatype("sectortype", sectortype_mt) ffi.metatype("sectortype", sectortype_mt)
local walltype_ptr_ct = ffi.typeof("$ *", ffi.typeof(strip_const(WALL_STRUCT)))
local walltype_mt = { local walltype_mt = {
__index = { __index = {
--- Setters
set_picnum = function(w, picnum)
check_tile_idx(picnum)
ffi.cast(walltype_ptr_ct, w).picnum = picnum
end,
set_overpicnum = function(w, picnum)
check_tile_idx(picnum)
ffi.cast(walltype_ptr_ct, w).overpicnum = picnum
end,
_set_nextwall = function(w, nextwall)
-- XXX: this disallows making a red wall white
bcheck.wall_idx(nextwall)
ffi.cast(walltype_ptr_ct, w).nextwall = nextwall
end,
_set_nextsector = function(w, nextsector)
-- XXX: this disallows making a red wall white
check_sector_idx(nextsector)
ffi.cast(walltype_ptr_ct, w).nextsector = nextsector
end,
--- Predicates
isblocking = function(w) isblocking = function(w)
return (bit.band(w.cstat, 1)~=0) return (bit.band(w.cstat, 1)~=0)
end, end,
@ -332,7 +368,7 @@ local walltype_mt = {
} }
ffi.metatype("walltype", walltype_mt) ffi.metatype("walltype", walltype_mt)
local spritetype_ptr_ct = ffi.typeof("spritetype_u_t *") local spritetype_ptr_ct = ffi.typeof("$ *", ffi.typeof(strip_const(SPRITE_STRUCT)))
spritetype_mt = { spritetype_mt = {
__pow = function(s, zofs) __pow = function(s, zofs)
@ -341,9 +377,7 @@ spritetype_mt = {
__index = { __index = {
set_picnum = function(s, tilenum) set_picnum = function(s, tilenum)
if (tilenum >= ffiC.MAXTILES+0ULL) then check_tile_idx(tilenum)
error("attempt to set invalid picnum "..tilenum, 2)
end
ffi.cast(spritetype_ptr_ct, s).picnum = tilenum ffi.cast(spritetype_ptr_ct, s).picnum = tilenum
end, end,