Lunatic: access to show2dsector[], fix some permit-negative bound checks.

git-svn-id: https://svn.eduke32.com/eduke32@3650 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2013-04-07 15:20:28 +00:00
parent c91363d7f9
commit abcc98d5c1
6 changed files with 55 additions and 9 deletions

View file

@ -16,7 +16,12 @@ local tostring = tostring
module(...) module(...)
local bitar_ct = ffi.typeof("struct { const double maxbidx, maxidx; const intptr_t arptr; }") local bitar_ct = ffi.typeof[[
struct {
const double maxbidx; // last permissible bit index
const double maxidx; // last permissible int32_t index
const intptr_t arptr; // address of the int32_t array
}]]
local ptr_to_int = ffi.typeof("int32_t *") local ptr_to_int = ffi.typeof("int32_t *")
local anchor = {} local anchor = {}
@ -110,6 +115,8 @@ local mt = {
--- Additional operations --- Additional operations
__index = { __index = {
-- TODO: Rename to 'testi', 'seti', 'cleari'; add 'flipi'?
-- Is bit i set? -- Is bit i set?
isset = function(s, i) isset = function(s, i)
if (not (i >= 0 and i<=s.maxbidx)) then if (not (i >= 0 and i<=s.maxbidx)) then
@ -212,20 +219,31 @@ local mt = {
end, end,
} }
local bitar = ffi.metatype(bitar_ct, mt) ffi.metatype(bitar_ct, mt)
-- Create new bit array. -- Create new bit array.
function new(maxbidx, initval) function new(maxbidx, initval)
if (type(maxbidx) ~= "number" or not (maxbidx >= 0 and maxbidx <= (2^31)-2)) then if (type(maxbidx) ~= "number" or not (maxbidx >= 0 and maxbidx <= (2^31)-2)) then
error("bad argument #1 to bitar.new (must be a number in [0..(2^31)-2])", 2) -- NOTE: Uh-oh, we can't write '2^31' because that would be interpreted
-- as color by OSD_Printf.
error("bad argument #1 to bitar.new (must be a number in [0..(2**31)-2])", 2)
end end
if (math.floor(maxbidx) ~= maxbidx) then if (math.floor(maxbidx) ~= maxbidx) then
error("bad argument #1 to bitar.new (must be an integral number)") error("bad argument #1 to bitar.new (must be an integral number)")
end end
if (type(initval)=="string") then if (ffi.istype(ptr_to_int, initval)) then
-- string containing hex digits (a..p) given, for INTERNAL use -- Initialization from an array on the C side. INTERNAL.
-- Cannot be reached by user code since there's no access to the FFI
-- (and thus no way to create pointers).
return bitar_from_intar(maxbidx, (maxbidx+1)/32-1, initval)
elseif (type(initval)=="string") then
-- String containing hex digits (a..p) given, for INTERNAL use only.
-- XXX: Can be reached by user code.
local lstr = initval local lstr = initval
@ -249,6 +267,7 @@ function new(maxbidx, initval)
end end
end end
-- NOTE: <maxbidx> cannot be extracted from the string, use the passed one.
return bitar_from_intar(maxbidx, maxidx, ar) return bitar_from_intar(maxbidx, maxidx, ar)
else else

View file

@ -929,7 +929,7 @@ local actor_mt = {
end, end,
set_picnum = function(a, picnum) set_picnum = function(a, picnum)
if (picnum >= 0) then if (not (picnum < 0)) then
check_tile_idx(picnum) check_tile_idx(picnum)
end end
ffi.cast(actor_ptr_ct, a).picnum = picnum ffi.cast(actor_ptr_ct, a).picnum = picnum
@ -1043,7 +1043,7 @@ local player_mt = {
end, end,
set_customexitsound = function(p, soundnum) set_customexitsound = function(p, soundnum)
if (soundnum >= 0) then if (not (soundnum < 0)) then
check_sound_idx(soundnum) check_sound_idx(soundnum)
end end
ffi.cast(player_ptr_ct, p).customexitsound = soundnum ffi.cast(player_ptr_ct, p).customexitsound = soundnum
@ -1110,7 +1110,7 @@ ffi.metatype("DukePlayer_t", player_mt)
local function GenProjectileSetFunc(Member) local function GenProjectileSetFunc(Member)
return function(self, picnum) return function(self, picnum)
if (picnum >= 0) then if (not (picnum < 0)) then
check_tile_idx(picnum) check_tile_idx(picnum)
end end
ffi.cast(projectile_ptr_ct, self)[Member] = picnum ffi.cast(projectile_ptr_ct, self)[Member] = picnum
@ -1900,7 +1900,11 @@ function DBG_.testmembread()
membaccode = membaccode[1] membaccode = membaccode[1]
end end
if (membaccode) then if (membaccode) then
local codestr = "do local _bit,_math=require'bit',require'math'; local tmp=".. local codestr = [[
do
local _bit,_math=require'bit',require'math'
local _band,_gv=_bit.band,gv
local tmp=]]..
membaccode:gsub("%%s","0").." end" membaccode:gsub("%%s","0").." end"
local code = assert(loadstring(codestr)) local code = assert(loadstring(codestr))
code() code()

View file

@ -312,6 +312,8 @@ const int16_t prevspritesect[MAXSPRITES], prevspritestat[MAXSPRITES];
const int16_t nextspritesect[MAXSPRITES], nextspritestat[MAXSPRITES]; const int16_t nextspritesect[MAXSPRITES], nextspritestat[MAXSPRITES];
const int16_t tilesizx[MAXTILES], tilesizy[MAXTILES]; const int16_t tilesizx[MAXTILES], tilesizy[MAXTILES];
uint8_t show2dsector[(MAXSECTORS+7)>>3];
const int16_t headsectbunch[2][MAXBUNCHES], nextsectbunch[2][MAXSECTORS]; const int16_t headsectbunch[2][MAXBUNCHES], nextsectbunch[2][MAXSECTORS];
int16_t yax_getbunch(int16_t i, int16_t cf); int16_t yax_getbunch(int16_t i, int16_t cf);
@ -707,6 +709,12 @@ static_members.sprite.CSTAT = conststruct
TRANSLUCENT_BOTH_BITS = 512+2, TRANSLUCENT_BOTH_BITS = 512+2,
} }
local bitar = require("bitar")
-- XXX: bitar uses int32_t arrays, while show2dsector[] is a uint8_t
-- array. Potential unaligned access. Also, only works on little-endian
-- machines. This sucks.
static_members.sector.showbitmap = bitar.new(ffiC.MAXSECTORS-1, ffi.cast("int32_t *", ffiC.show2dsector))
local sms = static_members.sprite local sms = static_members.sprite
sms._headspritesect = creategtab(ffiC.headspritesect, ffiC.MAXSECTORS, 'headspritesect[]') sms._headspritesect = creategtab(ffiC.headspritesect, ffiC.MAXSECTORS, 'headspritesect[]')
-- NOTE: don't allow freelist access -- NOTE: don't allow freelist access

View file

@ -43,6 +43,8 @@ nextspritestat;
tilesizx; tilesizx;
tilesizy; tilesizy;
show2dsector;
headsectbunch; headsectbunch;
nextsectbunch; nextsectbunch;

View file

@ -43,6 +43,8 @@ nextspritestat;
tilesizx; tilesizx;
tilesizy; tilesizy;
show2dsector;
headsectbunch; headsectbunch;
nextsectbunch; nextsectbunch;

View file

@ -430,6 +430,17 @@ gameevent("DISPLAYREST", function()
-- con._gametext(2822, j, i, 12, 0, 0, 16, 0,0,gv.xdim,gv.ydim,8192) -- con._gametext(2822, j, i, 12, 0, 0, 16, 0,0,gv.xdim,gv.ydim,8192)
end end
end end
-- Clear showing every sector with the pavement floor tile. (Unless we're
-- 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?
local show2dsector = sector.showbitmap
for i=0,gv.numsectors-1 do
if (sector[i].floorpicnum==815) then
show2dsector:set0(i)
end
end
end) end)
-- APLAYER -- APLAYER