From 9230ec7ba71743472f99dd7de36cf7a6160f8c5a Mon Sep 17 00:00:00 2001 From: helixhorned Date: Fri, 1 Feb 2013 13:05:00 +0000 Subject: [PATCH] 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 --- polymer/eduke32/source/lunatic/bcheck.lua | 7 + polymer/eduke32/source/lunatic/con_lang.lua | 19 ++- polymer/eduke32/source/lunatic/defs.ilua | 8 ++ .../eduke32/source/lunatic/defs_common.lua | 130 +++++++++++------- 4 files changed, 106 insertions(+), 58 deletions(-) diff --git a/polymer/eduke32/source/lunatic/bcheck.lua b/polymer/eduke32/source/lunatic/bcheck.lua index 9f9b9edac..b783d549b 100644 --- a/polymer/eduke32/source/lunatic/bcheck.lua +++ b/polymer/eduke32/source/lunatic/bcheck.lua @@ -1,3 +1,4 @@ +-- Bound-checking functions for engine and game "things". local ffiC = require("ffi").C @@ -11,6 +12,12 @@ function bcheck.sector_idx(sectnum) 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 -- the game world (statnum != MAXSTATUS). function bcheck.sprite_idx(spritenum) diff --git a/polymer/eduke32/source/lunatic/con_lang.lua b/polymer/eduke32/source/lunatic/con_lang.lua index 646f62d07..7bea48acd 100644 --- a/polymer/eduke32/source/lunatic/con_lang.lua +++ b/polymer/eduke32/source/lunatic/con_lang.lua @@ -342,8 +342,6 @@ local ActorLabels = { hitag = SP".hitag", extra = SP".extra", - -- { get, set } - -- Read access differs from write: ulotag = S2U(SP".lotag"), uhitag = S2U(SP".hitag"), @@ -365,8 +363,8 @@ local ActorLabels = { htbposx = AC".bpos.x", htbposy = AC".bpos.y", htbposz = AC".bpos.z", - -- Read access differs from write, write not available: - htg_t = { AC":get_t_data(%s)" }, + -- Read access differs from write ({ get, set }): + htg_t = { AC":get_t_data(%s)", AC":_set_t_data(%s,%%s)" }, htflags = AC".flags", -- model flags @@ -380,6 +378,7 @@ local ActorLabels = { xpanning = SX".xpanning", ypanning = SX".ypanning", + -- Read access differs from write, write not available: alpha = { "_math.floor(spriteext[%s].alpha*255)" }, } @@ -612,7 +611,7 @@ local SectorLabels = { floorstat = SEC".floorstat", -- CEILING - ceilingpicnum = SECRO".ceilingpicnum", + ceilingpicnum = { SEC".ceilingpicnum", SEC":set_ceilingpicnum(%%s)" }, ceilingslope = SEC".ceilingheinum", -- NAME ceilingshade = SEC".ceilingshade", @@ -622,7 +621,7 @@ local SectorLabels = { ceilingypanning = SEC".ceilingypanning", -- FLOOR - floorpicnum = SECRO".floorpicnum", + floorpicnum = { SEC".floorpicnum", SEC":set_floorpicnum(%%s)" }, floorslope = SEC".floorheinum", -- NAME floorshade = SEC".floorshade", @@ -653,11 +652,11 @@ local WallLabels = { x = WAL".x", y = WAL".y", point2 = WALRO".point2", - nextwall = WALRO".nextwall", - nextsector = WALRO".nextsector", + nextwall = { WAL".nextwall", WAL":_set_nextwall(%%s)" }, + nextsector = { WAL".nextsector", WAL":_set_nextsector(%%s)" }, cstat = WAL".cstat", - picnum = WALRO".picnum", - overpicnum = WALRO".overpicnum", + picnum = { WAL".picnum", WAL":set_picnum(%%s)" }, + overpicnum = { WAL".overpicnum", WAL":set_overpicnum(%%s)" }, shade = WAL".shade", pal = WAL".pal", xrepeat = WAL".xrepeat", diff --git a/polymer/eduke32/source/lunatic/defs.ilua b/polymer/eduke32/source/lunatic/defs.ilua index 4cc573668..39790dacd 100644 --- a/polymer/eduke32/source/lunatic/defs.ilua +++ b/polymer/eduke32/source/lunatic/defs.ilua @@ -751,12 +751,20 @@ local actor_mt = { end, -- Getters/setters. + -- TODO: make a bcarray instead. get_t_data = function(a, idx) if (idx >= 10ULL) then error("Invalid t_data index "..idx, 2) end return ffi.cast(actor_ptr_ct, a).t_data[idx] 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) diff --git a/polymer/eduke32/source/lunatic/defs_common.lua b/polymer/eduke32/source/lunatic/defs_common.lua index 1b58e44b4..fc19a7938 100644 --- a/polymer/eduke32/source/lunatic/defs_common.lua +++ b/polymer/eduke32/source/lunatic/defs_common.lua @@ -39,39 +39,8 @@ module(...) --== Core engine structs ==-- -local SPRITE_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 -{ +local SECTOR_STRUCT = [[ +struct { const int16_t wallptr, wallnum; int32_t ceilingz, floorz; uint16_t ceilingstat, floorstat; @@ -85,10 +54,27 @@ typedef struct uint8_t floorpal, floorxpanning, floorypanning; uint8_t visibility, filler; 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; const int16_t point2, nextwall, nextsector; uint16_t cstat; @@ -96,15 +82,24 @@ typedef struct int8_t shade; uint8_t pal, xrepeat, yrepeat, xpanning, ypanning; int16_t lotag, hitag, extra; -} walltype; +}]] -typedef struct -]].. SPRITE_STRUCT ..[[ -spritetype; +-- Converts a template struct definition to an internal, unrestricted one. +function strip_const(structstr) + return (string.gsub(structstr, "const ", "")); +end -typedef struct -]].. strip_const(SPRITE_STRUCT) ..[[ -spritetype_u_t; +-- 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 $ sectortype; +typedef $ walltype; +typedef $ spritetype; typedef struct { const uint32_t mdanimtims; @@ -128,7 +123,7 @@ typedef struct { int16_t sprite, wall, sect; } hitdata_t; #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 -- 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 check_sector_idx = bcheck.sector_idx +local check_tile_idx = bcheck.tile_idx local ivec3_ local ivec3_mt = { @@ -275,8 +271,22 @@ ivec3_ = ffi.metatype(vec3_ct, ivec3_mt) local xor = bit.bxor local wallsofsec -- fwd-decl +local sectortype_ptr_ct = ffi.typeof("$ *", ffi.typeof(strip_const(SECTOR_STRUCT))) + local sectortype_mt = { __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) return ffiC.getceilzofslopeptr(s, pos.x, pos.y) end, @@ -311,8 +321,34 @@ local sectortype_mt = { } ffi.metatype("sectortype", sectortype_mt) +local walltype_ptr_ct = ffi.typeof("$ *", ffi.typeof(strip_const(WALL_STRUCT))) + local walltype_mt = { __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) return (bit.band(w.cstat, 1)~=0) end, @@ -332,7 +368,7 @@ local 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 = { __pow = function(s, zofs) @@ -341,9 +377,7 @@ spritetype_mt = { __index = { set_picnum = function(s, tilenum) - if (tilenum >= ffiC.MAXTILES+0ULL) then - error("attempt to set invalid picnum "..tilenum, 2) - end + check_tile_idx(tilenum) ffi.cast(spritetype_ptr_ct, s).picnum = tilenum end,