mirror of
https://github.com/ZDoom/Raze.git
synced 2024-11-16 09:21:36 +00:00
Add LuaJIT-based BUILD map loader and batch processing script + example.
git-svn-id: https://svn.eduke32.com/eduke32@2813 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
886f2e5a26
commit
6b0f6176f6
3 changed files with 235 additions and 0 deletions
175
polymer/eduke32/source/lunatic/build.lua
Normal file
175
polymer/eduke32/source/lunatic/build.lua
Normal file
|
@ -0,0 +1,175 @@
|
|||
|
||||
-- Loaders for various BUILD structures for LuaJIT
|
||||
|
||||
-- TODO: bound-checking, load ART
|
||||
|
||||
|
||||
local ffi = require "ffi"
|
||||
local io = require "io"
|
||||
|
||||
local assert = assert
|
||||
local print = print
|
||||
|
||||
module(...)
|
||||
|
||||
ffi.cdef[[
|
||||
#pragma pack(push,1)
|
||||
typedef struct
|
||||
{
|
||||
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;
|
||||
int16_t point2, nextwall, nextsector;
|
||||
int16_t cstat;
|
||||
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;
|
||||
]]
|
||||
|
||||
local C = ffi.C
|
||||
|
||||
|
||||
local MAX =
|
||||
{
|
||||
SECTORS = { [7]=1024, [8]=4096, [9]=4096 },
|
||||
WALLS = { [7]=8192, [8]=16384, [9]=16384 },
|
||||
SPRITES = { [7]=4096, [8]=16384, [9]=16384 },
|
||||
}
|
||||
|
||||
local function doread(fh, basectype, numelts)
|
||||
local cd = ffi.new(basectype.."[?]", numelts)
|
||||
local size = ffi.sizeof(cd)
|
||||
|
||||
if (numelts==0) then
|
||||
return nil
|
||||
end
|
||||
|
||||
assert(size % numelts == 0)
|
||||
local datstr = fh:read(size)
|
||||
|
||||
if (datstr == nil or #datstr < size) then
|
||||
fh:close()
|
||||
return nil
|
||||
end
|
||||
|
||||
ffi.copy(cd, datstr, size)
|
||||
|
||||
return cd
|
||||
end
|
||||
|
||||
--== LOADBOARD ==--
|
||||
-- returns:
|
||||
-- on failure, nil, errmsg
|
||||
-- on success, a table
|
||||
-- {
|
||||
-- version = <num>,
|
||||
-- numsectors=<num>, numwalls=<num>, numsprites=<num>,
|
||||
-- sector=<cdata (array of sectortype)>,
|
||||
-- wall=<cdata (array of walltype)>,
|
||||
-- sprite=nil or <cdata> (array of spritetype),
|
||||
-- start =
|
||||
-- { x=<num>, y=<num>, z=<num>, ang=<num>, sectnum=<num> }
|
||||
-- }
|
||||
function loadboard(filename)
|
||||
local fh, errmsg = io.open(filename)
|
||||
|
||||
if (fh==nil) then
|
||||
return nil, errmsg
|
||||
end
|
||||
|
||||
-- The table we'll return on success
|
||||
local map = { start={} }
|
||||
|
||||
local cd = doread(fh, "int32_t", 4)
|
||||
if (cd==nil) then
|
||||
return nil, "Couldn't read header"
|
||||
end
|
||||
|
||||
map.version = cd[0]
|
||||
map.start.x = cd[1]
|
||||
map.start.y = cd[2]
|
||||
map.start.z = cd[3]
|
||||
|
||||
if (map.version < 7 or map.version > 9) then
|
||||
fh:close()
|
||||
return nil, "Invalid map version"
|
||||
end
|
||||
|
||||
cd = doread(fh, "int16_t", 3)
|
||||
if (cd==nil) then
|
||||
return nil, "Couldn't read header (2)"
|
||||
end
|
||||
|
||||
map.start.ang = cd[0]
|
||||
map.start.sectnum = cd[1]
|
||||
|
||||
-- sectors
|
||||
map.numsectors = cd[2]
|
||||
if (map.numsectors <= 0 or map.numsectors > MAX.SECTORS[map.version]) then
|
||||
fh:close()
|
||||
return nil, "Invalid number of sectors"
|
||||
end
|
||||
|
||||
map.sector = doread(fh, "sectortype", map.numsectors)
|
||||
if (map.sector == nil) then
|
||||
return nil, "Couldn't read sectors"
|
||||
end
|
||||
|
||||
-- walls
|
||||
cd = doread(fh, "int16_t", 1)
|
||||
map.numwalls = cd[0]
|
||||
if (map.numwalls <= 0 or map.numwalls > MAX.WALLS[map.version]) then
|
||||
fh:close()
|
||||
return nil, "Invalid number of walls"
|
||||
end
|
||||
|
||||
map.wall = doread(fh, "walltype", map.numwalls)
|
||||
if (map.wall == nil) then
|
||||
return nil, "Couldn't read walls"
|
||||
end
|
||||
|
||||
-- sprites
|
||||
cd = doread(fh, "int16_t", 1)
|
||||
map.numsprites = cd[0]
|
||||
if (map.numsprites < 0 or map.numsprites > MAX.SPRITES[map.version]) then
|
||||
fh:close()
|
||||
return nil, "Invalid number of sprites"
|
||||
end
|
||||
|
||||
map.sprite = doread(fh, "spritetype", map.numsprites)
|
||||
if (map.numsprites~=0 and map.sprite == nil) then
|
||||
return nil, "Couldn't read sprites"
|
||||
end
|
||||
|
||||
-- done
|
||||
fh:close()
|
||||
return map
|
||||
end
|
34
polymer/eduke32/source/lunatic/foreachmap.lua
Executable file
34
polymer/eduke32/source/lunatic/foreachmap.lua
Executable file
|
@ -0,0 +1,34 @@
|
|||
#!/usr/local/bin/luajit
|
||||
|
||||
-- Generic map iterator.
|
||||
|
||||
-- The first cmdline arg is a name of a lua file (may be sans .lua) which must
|
||||
-- be a module and is `require'd into this script, e.g. "stats" or "stats.lua".
|
||||
-- Then, for each 2nd and following argument, if map loading succeeds,
|
||||
-- .success(map, filename) is run, otherwise .failure(filename, errmsg) --
|
||||
-- these must be functions in the loaded module.
|
||||
|
||||
-- TODO: aggregate batch mode
|
||||
|
||||
|
||||
if (#arg < 1) then
|
||||
error("Usage: luajit ./foreachmap <module[.lua]> <filename.map> ...")
|
||||
end
|
||||
|
||||
local B = require "build"
|
||||
local string = require "string"
|
||||
|
||||
local modname = string.gsub(arg[1], "%.lua$", "")
|
||||
local mod = require(modname)
|
||||
|
||||
|
||||
for i=2,#arg do
|
||||
local fn = arg[i]
|
||||
local map, errmsg = B.loadboard(fn)
|
||||
|
||||
if (map ~= nil) then
|
||||
mod.success(map, fn)
|
||||
else
|
||||
mod.failure(fn, errmsg)
|
||||
end
|
||||
end
|
26
polymer/eduke32/source/lunatic/mapstats.lua
Normal file
26
polymer/eduke32/source/lunatic/mapstats.lua
Normal file
|
@ -0,0 +1,26 @@
|
|||
|
||||
-- Print out some statistics for a BUILD map,
|
||||
-- foreachmap module.
|
||||
|
||||
local string = require "string"
|
||||
local print = print
|
||||
|
||||
module(...)
|
||||
|
||||
|
||||
local function printf(fmt, ...)
|
||||
print(string.format(fmt, ...))
|
||||
end
|
||||
|
||||
|
||||
function success(map, fn)
|
||||
printf("--- %s:", fn)
|
||||
|
||||
printf(" version: %d", map.version)
|
||||
printf(" numsectors: %d\n numwalls: %d\n numsprites: %d",
|
||||
map.numsectors, map.numwalls, map.numsprites)
|
||||
end
|
||||
|
||||
function failure(fn, errmsg)
|
||||
printf("--- %s: %s", fn, errmsg)
|
||||
end
|
Loading…
Reference in a new issue