2011-09-20 19:12:24 +00:00
|
|
|
-- definitions of BUILD and game types for the Lunatic Interpreter
|
|
|
|
-- INTERNAL!
|
|
|
|
|
|
|
|
local ffi = require("ffi")
|
|
|
|
|
2011-09-25 15:11:47 +00:00
|
|
|
---- sector, wall, sprite ----
|
2011-09-20 19:12:24 +00:00
|
|
|
ffi.cdef[[
|
|
|
|
#pragma pack(push,1)
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
const int16_t wallptr, wallnum;
|
|
|
|
int32_t ceilingz, floorz;
|
|
|
|
int16_t ceilingstat, floorstat;
|
|
|
|
int16_t ceilingpicnum, ceilingheinum;
|
|
|
|
int8_t ceilingshade;
|
|
|
|
uint8_t ceilingpal, ceilingxpanning, ceilingypanning;
|
|
|
|
int16_t floorpicnum, floorheinum;
|
|
|
|
int8_t floorshade;
|
|
|
|
uint8_t floorpal, floorxpanning, floorypanning;
|
|
|
|
uint8_t visibility, filler;
|
|
|
|
int16_t lotag, hitag, extra;
|
|
|
|
} sectortype;
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
int32_t x, y;
|
2011-09-25 15:11:47 +00:00
|
|
|
const int16_t point2, nextwall, nextsector; int16_t cstat;
|
2011-09-20 19:12:24 +00:00
|
|
|
int16_t picnum, overpicnum;
|
|
|
|
int8_t shade;
|
|
|
|
uint8_t pal, xrepeat, yrepeat, xpanning, ypanning;
|
|
|
|
int16_t lotag, hitag, extra;
|
|
|
|
} walltype;
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
int32_t x, y, z;
|
|
|
|
int16_t cstat, picnum;
|
|
|
|
int8_t shade;
|
|
|
|
uint8_t pal, clipdist, filler;
|
|
|
|
uint8_t xrepeat, yrepeat;
|
|
|
|
int8_t xoffset, yoffset;
|
|
|
|
int16_t sectnum, statnum;
|
|
|
|
int16_t ang, owner, xvel, yvel, zvel;
|
|
|
|
int16_t lotag, hitag, extra;
|
|
|
|
} spritetype;
|
|
|
|
#pragma pack(pop)
|
|
|
|
]]
|
|
|
|
|
|
|
|
ffi.cdef[[
|
|
|
|
sectortype *sector;
|
|
|
|
walltype *wall;
|
|
|
|
spritetype *sprite;
|
|
|
|
|
|
|
|
const int16_t numsectors, numwalls;
|
2011-09-25 15:11:47 +00:00
|
|
|
|
|
|
|
const int16_t headspritesect[16384+1], headspritestat[1024+1];
|
|
|
|
const int16_t prevspritesect[16384], prevspritestat[16384];
|
|
|
|
const int16_t nextspritesect[16384], nextspritestat[16384];
|
2011-09-20 19:12:24 +00:00
|
|
|
]]
|
|
|
|
|
2011-10-11 16:53:15 +00:00
|
|
|
---- _G tweaks -- pull in only 'safe' stuff ----
|
|
|
|
|
|
|
|
local G_ = {} -- our soon-to-be global environment
|
|
|
|
local oG = _G
|
|
|
|
|
|
|
|
G_.coroutine = coroutine
|
|
|
|
G_.assert = assert
|
|
|
|
G_.tostring = tostring
|
|
|
|
G_.tonumber = tonumber
|
|
|
|
--rawget
|
|
|
|
G_.xpcall = xpcall
|
|
|
|
G_.ipairs = ipairs
|
|
|
|
G_.print = print
|
|
|
|
G_.pcall = pcall
|
|
|
|
--gcinfo --DEPRECATED
|
|
|
|
--module
|
|
|
|
--setfenv
|
|
|
|
--require
|
|
|
|
--rawset
|
|
|
|
--jit
|
|
|
|
G_.bit = bit
|
|
|
|
--package
|
|
|
|
G_.error = error
|
|
|
|
--debug
|
|
|
|
--loadfile
|
|
|
|
--rawequal
|
|
|
|
--load
|
|
|
|
G_.unpack = unpack
|
|
|
|
G_.pairs = pairs
|
|
|
|
G_.table = table
|
|
|
|
G_._VERSION = _VERSION
|
|
|
|
--newproxy --NOT STD?
|
|
|
|
--collectgarbage
|
|
|
|
--dofile
|
|
|
|
G_.next = next
|
|
|
|
G_.math = math
|
|
|
|
--loadstring
|
|
|
|
--_G
|
|
|
|
G_.select = select
|
|
|
|
G_.string = string
|
|
|
|
G_.type = type
|
|
|
|
--getmetatable
|
|
|
|
--getfenv
|
|
|
|
--setmetatable
|
|
|
|
|
|
|
|
G_._G = G_
|
|
|
|
|
|
|
|
-- REMOVE this for release
|
|
|
|
DBG_ = {}
|
|
|
|
DBG_.loadstring = oG.loadstring
|
2011-09-20 19:12:24 +00:00
|
|
|
|
2011-09-25 15:11:47 +00:00
|
|
|
---- Set up restricted access to ffi.C from lunatic. ----
|
|
|
|
local ffiC = ffi.C
|
|
|
|
|
|
|
|
local det = {} -- dummy empty table
|
|
|
|
local tmpmt = {
|
|
|
|
__index = function() error('dummy variable: read access forbidden') end,
|
|
|
|
__newindex = function() error('dummy variable: write access forbidden') end,
|
|
|
|
__metatable = true -- forbid setting the metatable
|
|
|
|
}
|
2011-10-11 16:53:15 +00:00
|
|
|
oG.setmetatable(det, tmpmt)
|
2011-09-25 15:11:47 +00:00
|
|
|
|
|
|
|
-- GLOBAL gv: provides access to C global *scalars*
|
|
|
|
gv = {
|
|
|
|
-- all non-scalars need to be explicitly listed
|
|
|
|
-- and access to them is redirected to the dummy
|
|
|
|
-- empty table... this is somewhat ugly
|
|
|
|
sector = det,
|
|
|
|
wall = det,
|
|
|
|
sprite = det,
|
|
|
|
|
|
|
|
headspritesect = det, headspritestat = det,
|
|
|
|
prevspritesect = det, prevspritestat = det,
|
|
|
|
nextspritesect = det, nextspritestat = det,
|
|
|
|
}
|
|
|
|
local tmpmt = {
|
|
|
|
__index = ffiC,
|
|
|
|
__newindex = function() error("cannot create new fields in 'gv'") end,
|
|
|
|
__metatable = true,
|
|
|
|
}
|
2011-10-11 16:53:15 +00:00
|
|
|
oG.setmetatable(gv, tmpmt)
|
2011-09-25 15:11:47 +00:00
|
|
|
|
|
|
|
---- indirect C array access ----
|
2011-09-20 19:12:24 +00:00
|
|
|
sector = {}
|
|
|
|
local tmpmt = {
|
|
|
|
__index = function(tab, key)
|
2011-09-25 15:11:47 +00:00
|
|
|
if (key >= 0 and key < ffiC.numsectors) then return ffiC.sector[key] end
|
2011-09-20 19:12:24 +00:00
|
|
|
error('out-of-bounds sector[] read access')
|
|
|
|
end,
|
|
|
|
|
2011-09-25 15:11:47 +00:00
|
|
|
__newindex = function(tab, key, val) error('cannot write to sector[] struct directly') end,
|
|
|
|
__metatable = true,
|
2011-09-20 19:12:24 +00:00
|
|
|
}
|
2011-10-11 16:53:15 +00:00
|
|
|
oG.setmetatable(sector, tmpmt)
|
2011-09-20 19:12:24 +00:00
|
|
|
|
|
|
|
wall = {}
|
|
|
|
local tmpmt = {
|
|
|
|
__index = function(tab, key)
|
2011-09-25 15:11:47 +00:00
|
|
|
if (key >= 0 and key < ffiC.numwalls) then return ffiC.wall[key] end
|
2011-09-20 19:12:24 +00:00
|
|
|
error('out-of-bounds wall[] read access')
|
|
|
|
end,
|
|
|
|
|
2011-09-25 15:11:47 +00:00
|
|
|
__newindex = function(tab, key, val) error('cannot write to wall[] struct directly') end,
|
|
|
|
__metatable = true,
|
2011-09-20 19:12:24 +00:00
|
|
|
}
|
2011-10-11 16:53:15 +00:00
|
|
|
oG.setmetatable(wall, tmpmt)
|
2011-09-20 19:12:24 +00:00
|
|
|
|
2011-09-25 15:11:47 +00:00
|
|
|
-- create a safe indirection for a ffi.C array
|
|
|
|
local function creategtab(ctab, maxidx, name)
|
|
|
|
local tab = {}
|
|
|
|
local tmpmt = {
|
|
|
|
__index = function(tab, key)
|
|
|
|
if (key>=0 and key < maxidx) then
|
|
|
|
return ctab[key]
|
|
|
|
end
|
|
|
|
error('out-of-bounds '..name..' read access')
|
|
|
|
end,
|
|
|
|
__newindex = function(tab, key, val)
|
|
|
|
error('cannot write to '..name)
|
|
|
|
end,
|
|
|
|
__metatable = true,
|
|
|
|
}
|
2011-10-11 16:53:15 +00:00
|
|
|
oG.setmetatable(tab, tmpmt)
|
2011-09-25 15:11:47 +00:00
|
|
|
return tab
|
|
|
|
end
|
2011-09-20 19:12:24 +00:00
|
|
|
|
2011-09-25 15:11:47 +00:00
|
|
|
sprite = creategtab(ffiC.sprite, 16384, 'sprite[] struct')
|
|
|
|
headspritesect = creategtab(ffiC.headspritesect, 16384, 'headspritesect[]')
|
|
|
|
headspritestat = creategtab(ffiC.headspritestat, 1024, 'headspritestat[]')
|
|
|
|
nextspritesect = creategtab(ffiC.nextspritesect, 16384, 'nextspritesect[]')
|
|
|
|
nextspritestat = creategtab(ffiC.nextspritestat, 16384, 'nextspritestat[]')
|
|
|
|
prevspritesect = creategtab(ffiC.prevspritesect, 16384, 'prevspritesect[]')
|
|
|
|
prevspritestat = creategtab(ffiC.prevspritestat, 16384, 'prevspritestat[]')
|
|
|
|
|
|
|
|
---- per-sector/per-statnum sprite iterators ----
|
|
|
|
local function iter_spritesofsect(sect, i)
|
|
|
|
if (i < 0) then
|
|
|
|
i = ffiC.headspritesect[sect]
|
|
|
|
else
|
|
|
|
i = ffiC.nextspritesect[i]
|
|
|
|
end
|
|
|
|
|
|
|
|
if (i >= 0) then return i, i end
|
|
|
|
end
|
|
|
|
|
|
|
|
function spritesofsect(sect)
|
|
|
|
assert(sect >= 0 and sect < ffiC.numsectors, "passed invalid sectnum to spritesofsect iterator")
|
|
|
|
|
|
|
|
return iter_spritesofsect, sect, -1
|
|
|
|
end
|
|
|
|
|
|
|
|
local function iter_spritesofstat(stat, i)
|
|
|
|
if (i < 0) then
|
|
|
|
i = ffiC.headspritestat[stat]
|
|
|
|
else
|
|
|
|
i = ffiC.nextspritestat[i]
|
|
|
|
end
|
|
|
|
|
|
|
|
if (i >= 0) then return i, i end
|
|
|
|
end
|
|
|
|
|
|
|
|
function spritesofstat(stat)
|
|
|
|
assert(stat >= 0 and stat < 1024, "passed invalid statnum to spritesofstat iterator")
|
2011-09-20 19:12:24 +00:00
|
|
|
|
2011-09-25 15:11:47 +00:00
|
|
|
return iter_spritesofstat , stat, -1
|
|
|
|
end
|
2011-09-20 19:12:24 +00:00
|
|
|
|
2011-10-11 16:53:15 +00:00
|
|
|
|
|
|
|
-- add new variables/functions living in the global environment
|
|
|
|
G_.DBG_ = DBG_ -- REMOVE this for release
|
|
|
|
G_.gv = gv
|
|
|
|
G_.sector = sector
|
|
|
|
G_.wall = wall
|
|
|
|
G_.sprite = sprite
|
|
|
|
G_.headspritesect = headspritesect
|
|
|
|
G_.headspritestat = headspritestat
|
|
|
|
G_.nextspritesect = nextspritesect
|
|
|
|
G_.nextspritestat = nextspritestat
|
|
|
|
G_.prevspritesect = prevspritesect
|
|
|
|
G_.prevspritestat = prevspritestat
|
|
|
|
G_.spritesofsect = spritesofsect
|
|
|
|
G_.spritesofstat = spritesofstat
|
|
|
|
|
|
|
|
-- change the environment of the running Lua thread to the table G_
|
|
|
|
setfenv(0, G_)
|