mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-11-11 07:11:39 +00:00
Lunatic: reading of map-text prototype.
Also fixes a couple of oversights (introduced) with the saving. git-svn-id: https://svn.eduke32.com/eduke32@3736 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
82d6c2d5f7
commit
e9844d2e51
8 changed files with 370 additions and 59 deletions
|
@ -7652,15 +7652,16 @@ CANCEL:
|
|||
}
|
||||
else
|
||||
{
|
||||
int32_t bakstat=-1;
|
||||
int32_t bakstat=-1, ret;
|
||||
mapinfofull_t bakmap;
|
||||
|
||||
if (highlightsectorcnt > 0)
|
||||
bakstat = backup_highlighted_map(&bakmap);
|
||||
// __old_mapcopy_2__
|
||||
if (LoadBoard(NULL, 4))
|
||||
|
||||
ret = LoadBoard(NULL, 4);
|
||||
if (ret)
|
||||
{
|
||||
message("Invalid map format, nothing loaded.");
|
||||
message("Invalid map format, nothing loaded (code %d).", ret);
|
||||
if (bakstat==0)
|
||||
mapinfofull_free(&bakmap);
|
||||
}
|
||||
|
|
|
@ -9657,6 +9657,11 @@ void drawmapview(int32_t dax, int32_t day, int32_t zoome, int16_t ang)
|
|||
|
||||
//////////////////// LOADING AND SAVING ROUTINES ////////////////////
|
||||
|
||||
static inline int32_t have_maptext(void)
|
||||
{
|
||||
return (mapversion >= 10);
|
||||
}
|
||||
|
||||
static void prepare_loadboard(int32_t fil, vec3_t *dapos, int16_t *daang, int16_t *dacursectnum)
|
||||
{
|
||||
initspritelists();
|
||||
|
@ -9665,11 +9670,14 @@ static void prepare_loadboard(int32_t fil, vec3_t *dapos, int16_t *daang, int16_
|
|||
Bmemset(show2dsprite, 0, sizeof(show2dsprite));
|
||||
Bmemset(show2dwall, 0, sizeof(show2dwall));
|
||||
|
||||
kread(fil,&dapos->x,4); dapos->x = B_LITTLE32(dapos->x);
|
||||
kread(fil,&dapos->y,4); dapos->y = B_LITTLE32(dapos->y);
|
||||
kread(fil,&dapos->z,4); dapos->z = B_LITTLE32(dapos->z);
|
||||
kread(fil,daang,2); *daang = B_LITTLE16(*daang) & 2047;
|
||||
kread(fil,dacursectnum,2); *dacursectnum = B_LITTLE16(*dacursectnum);
|
||||
if (!have_maptext())
|
||||
{
|
||||
kread(fil,&dapos->x,4); dapos->x = B_LITTLE32(dapos->x);
|
||||
kread(fil,&dapos->y,4); dapos->y = B_LITTLE32(dapos->y);
|
||||
kread(fil,&dapos->z,4); dapos->z = B_LITTLE32(dapos->z);
|
||||
kread(fil,daang,2); *daang = B_LITTLE16(*daang) & 2047;
|
||||
kread(fil,dacursectnum,2); *dacursectnum = B_LITTLE16(*dacursectnum);
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t finish_loadboard(const vec3_t *dapos, int16_t *dacursectnum, int16_t numsprites, char myflags)
|
||||
|
@ -9797,11 +9805,17 @@ static void check_sprite(int32_t i)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef NEW_MAP_FORMAT
|
||||
// Returns the number of sprites, or <0 on error.
|
||||
int32_t (*loadboard_maptext)(int32_t fil, vec3_t *dapos, int16_t *daang, int16_t *dacursectnum);
|
||||
#endif
|
||||
|
||||
// flags: 1, 2: former parameter "fromwhere"
|
||||
// 4: don't call polymer_loadboard
|
||||
// returns: -1: file not found
|
||||
// -2: invalid version
|
||||
// -3: invalid number of sectors, walls or sprites
|
||||
// <= -4: map-text error
|
||||
int32_t loadboard(char *filename, char flags, vec3_t *dapos, int16_t *daang, int16_t *dacursectnum)
|
||||
{
|
||||
int32_t fil, i;
|
||||
|
@ -9813,29 +9827,68 @@ int32_t loadboard(char *filename, char flags, vec3_t *dapos, int16_t *daang, int
|
|||
i = Bstrlen(filename)-1;
|
||||
if (filename[i] == 255) { filename[i] = 0; flags = 1; } // JBF 20040119: "compatibility"
|
||||
if ((fil = kopen4load(filename,flags)) == -1)
|
||||
{ mapversion = 7; return(-1); }
|
||||
{ mapversion = 7; return -1; }
|
||||
|
||||
kread(fil,&mapversion,4); mapversion = B_LITTLE32(mapversion);
|
||||
if (kread(fil, &mapversion, 4) != 4)
|
||||
return -2;
|
||||
|
||||
{
|
||||
int32_t ok = (mapversion==7);
|
||||
int32_t ok = 0;
|
||||
|
||||
#ifdef NEW_MAP_FORMAT
|
||||
// Check for map-text first.
|
||||
if (!Bmemcmp(&mapversion, "--ED", 4))
|
||||
{
|
||||
mapversion = 10;
|
||||
ok = 1;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// Not map-text. We expect a little-endian version int now.
|
||||
mapversion = B_LITTLE32(mapversion);
|
||||
#ifdef YAX_ENABLE
|
||||
ok |= (mapversion==9);
|
||||
ok |= (mapversion==9);
|
||||
#endif
|
||||
#if MAXSECTORS==MAXSECTORSV8
|
||||
// v8 engine
|
||||
ok |= (mapversion==8);
|
||||
// v8 engine
|
||||
ok |= (mapversion==8);
|
||||
#endif
|
||||
if (!ok) { kclose(fil); return(-2); }
|
||||
ok |= (mapversion==7);
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
kclose(fil);
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
prepare_loadboard(fil, dapos, daang, dacursectnum);
|
||||
|
||||
#ifdef NEW_MAP_FORMAT
|
||||
if (have_maptext())
|
||||
{
|
||||
int32_t ret = klseek(fil, 0, SEEK_SET);
|
||||
|
||||
if (ret == 0)
|
||||
ret = loadboard_maptext(fil, dapos, daang, dacursectnum);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
kclose(fil);
|
||||
return ret;
|
||||
}
|
||||
|
||||
numsprites = ret;
|
||||
goto skip_reading_mapbin;
|
||||
}
|
||||
#endif
|
||||
|
||||
////////// Read sectors //////////
|
||||
|
||||
kread(fil,&numsectors,2); numsectors = B_LITTLE16(numsectors);
|
||||
if ((unsigned)numsectors >= MYMAXSECTORS()+1) { kclose(fil); return(-1); }
|
||||
if ((unsigned)numsectors >= MYMAXSECTORS()+1) { kclose(fil); return -3; }
|
||||
|
||||
kread(fil, sector, sizeof(sectortypev7)*numsectors);
|
||||
|
||||
|
@ -9867,7 +9920,7 @@ int32_t loadboard(char *filename, char flags, vec3_t *dapos, int16_t *daang, int
|
|||
////////// Read walls //////////
|
||||
|
||||
kread(fil,&numwalls,2); numwalls = B_LITTLE16(numwalls);
|
||||
if ((unsigned)numwalls >= MYMAXWALLS()+1) { kclose(fil); return(-1); }
|
||||
if ((unsigned)numwalls >= MYMAXWALLS()+1) { kclose(fil); return -3; }
|
||||
|
||||
kread(fil, wall, sizeof(walltypev7)*numwalls);
|
||||
|
||||
|
@ -9897,30 +9950,36 @@ int32_t loadboard(char *filename, char flags, vec3_t *dapos, int16_t *daang, int
|
|||
////////// Read sprites //////////
|
||||
|
||||
kread(fil,&numsprites,2); numsprites = B_LITTLE16(numsprites);
|
||||
if ((unsigned)numsprites >= MYMAXSPRITES()+1) { kclose(fil); return(-1); }
|
||||
if ((unsigned)numsprites >= MYMAXSPRITES()+1) { kclose(fil); return -3; }
|
||||
|
||||
kread(fil, sprite, sizeof(spritetype)*numsprites);
|
||||
|
||||
#ifdef NEW_MAP_FORMAT
|
||||
skip_reading_mapbin:
|
||||
#endif
|
||||
kclose(fil);
|
||||
// Done reading file.
|
||||
|
||||
for (i=numsprites-1; i>=0; i--)
|
||||
{
|
||||
sprite[i].x = B_LITTLE32(sprite[i].x);
|
||||
sprite[i].y = B_LITTLE32(sprite[i].y);
|
||||
sprite[i].z = B_LITTLE32(sprite[i].z);
|
||||
sprite[i].cstat = B_LITTLE16(sprite[i].cstat);
|
||||
sprite[i].picnum = B_LITTLE16(sprite[i].picnum);
|
||||
sprite[i].sectnum = B_LITTLE16(sprite[i].sectnum);
|
||||
sprite[i].statnum = B_LITTLE16(sprite[i].statnum);
|
||||
sprite[i].ang = B_LITTLE16(sprite[i].ang);
|
||||
sprite[i].owner = B_LITTLE16(sprite[i].owner);
|
||||
sprite[i].xvel = B_LITTLE16(sprite[i].xvel);
|
||||
sprite[i].yvel = B_LITTLE16(sprite[i].yvel);
|
||||
sprite[i].zvel = B_LITTLE16(sprite[i].zvel);
|
||||
sprite[i].lotag = B_LITTLE16(sprite[i].lotag);
|
||||
sprite[i].hitag = B_LITTLE16(sprite[i].hitag);
|
||||
sprite[i].extra = B_LITTLE16(sprite[i].extra);
|
||||
if (!have_maptext())
|
||||
{
|
||||
sprite[i].x = B_LITTLE32(sprite[i].x);
|
||||
sprite[i].y = B_LITTLE32(sprite[i].y);
|
||||
sprite[i].z = B_LITTLE32(sprite[i].z);
|
||||
sprite[i].cstat = B_LITTLE16(sprite[i].cstat);
|
||||
sprite[i].picnum = B_LITTLE16(sprite[i].picnum);
|
||||
sprite[i].sectnum = B_LITTLE16(sprite[i].sectnum);
|
||||
sprite[i].statnum = B_LITTLE16(sprite[i].statnum);
|
||||
sprite[i].ang = B_LITTLE16(sprite[i].ang);
|
||||
sprite[i].owner = B_LITTLE16(sprite[i].owner);
|
||||
sprite[i].xvel = B_LITTLE16(sprite[i].xvel);
|
||||
sprite[i].yvel = B_LITTLE16(sprite[i].yvel);
|
||||
sprite[i].zvel = B_LITTLE16(sprite[i].zvel);
|
||||
sprite[i].lotag = B_LITTLE16(sprite[i].lotag);
|
||||
sprite[i].hitag = B_LITTLE16(sprite[i].hitag);
|
||||
sprite[i].extra = B_LITTLE16(sprite[i].extra);
|
||||
}
|
||||
|
||||
check_sprite(i);
|
||||
}
|
||||
|
|
|
@ -1285,7 +1285,13 @@ local function errorf(level, fmt, ...)
|
|||
end
|
||||
|
||||
local function readintostr_mod(fn)
|
||||
return defs_c.readintostr(fn, ffiC.kopen4loadfrommod)
|
||||
-- TODO: g_loadFromGroupOnly?
|
||||
local fd = ffiC.kopen4loadfrommod(fn, 0)
|
||||
if (fd < 0) then
|
||||
return nil
|
||||
end
|
||||
|
||||
return defs_c.readintostr(fd)
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -319,34 +319,31 @@ enum {
|
|||
};
|
||||
]]
|
||||
|
||||
ffi.cdef(maybe_strip_const("const int16_t numsectors, numwalls;"))
|
||||
|
||||
ffi.cdef[[
|
||||
const int16_t numsectors, numwalls;
|
||||
const int32_t numyaxbunches; // XXX
|
||||
const int32_t totalclock;
|
||||
int32_t randomseed; // DEPRECATED
|
||||
const int32_t xdim, ydim;
|
||||
const int32_t windowx1, windowy1, windowx2, windowy2;
|
||||
]]
|
||||
|
||||
decl[[
|
||||
int32_t kopen4load(const char *filename, char searchfirst);
|
||||
int32_t kfilelength(int32_t handle);
|
||||
void kclose(int32_t handle);
|
||||
int32_t kread(int32_t handle, void *buffer, int32_t leng);
|
||||
int32_t klseek(int32_t handle, int32_t offset, int32_t whence);
|
||||
|
||||
int32_t sectorofwall_noquick(int16_t theline);
|
||||
]]
|
||||
|
||||
function readintostr(fn, kopen4load_func)
|
||||
-- Reads the whole file given by the k* file descriptor into a Lua string.
|
||||
-- Always closes the file descriptor.
|
||||
function readintostr(fd, kopen4load_func)
|
||||
-- XXX: this is pretty much the same as the code in L_RunOnce()
|
||||
|
||||
if (kopen4load_func == nil) then
|
||||
kopen4load_func = ffiC.kopen4load
|
||||
end
|
||||
|
||||
-- TODO: for game, g_loadFromGroupOnly?
|
||||
local fd = kopen4load_func(fn, 0)
|
||||
if (fd < 0) then
|
||||
return nil
|
||||
end
|
||||
|
||||
local sz = ffiC.kfilelength(fd)
|
||||
if (sz == 0) then
|
||||
ffiC.kclose(fd)
|
||||
|
|
|
@ -29,6 +29,7 @@ viewingrange;
|
|||
|
||||
yax_getbunch;
|
||||
|
||||
sectorofwall_noquick;
|
||||
getceilzofslopeptr;
|
||||
getflorzofslopeptr;
|
||||
getzsofslopeptr;
|
||||
|
|
|
@ -29,6 +29,7 @@ viewingrange;
|
|||
|
||||
yax_getbunch;
|
||||
|
||||
sectorofwall_noquick;
|
||||
getceilzofslopeptr;
|
||||
getflorzofslopeptr;
|
||||
getzsofslopeptr;
|
||||
|
|
|
@ -4,16 +4,22 @@
|
|||
local ffi = require("ffi")
|
||||
local ffiC = ffi.C
|
||||
|
||||
local pairs = pairs
|
||||
local pcall = pcall
|
||||
local print = print
|
||||
local setfenv = setfenv
|
||||
local tonumber = tonumber
|
||||
local type = type
|
||||
|
||||
local readintostr = assert(string.readintostr)
|
||||
|
||||
local io = require("io")
|
||||
local string = require("string")
|
||||
|
||||
|
||||
ffi.cdef[[
|
||||
int32_t (*saveboard_maptext)(const char *filename, const vec3_t *dapos, int16_t daang, int16_t dacursectnum);
|
||||
int32_t (*loadboard_maptext)(int32_t fil, vec3_t *dapos, int16_t *daang, int16_t *dacursectnum);
|
||||
]]
|
||||
|
||||
|
||||
|
@ -46,6 +52,9 @@ local sector_members = {
|
|||
-- a newline should appear in the output.
|
||||
local sector_ord = { mand="1 23 45 67 ", opt="Bb Ff Hh Pp Xx Yy v _ oie" }
|
||||
|
||||
-- KEEPINSYNC with sector_members.
|
||||
local sector_default = ffi.new("const sectortype", { ceilingbunch=-1, floorbunch=-1, extra=-1 })
|
||||
|
||||
|
||||
local wall_members = {
|
||||
-- mandatory
|
||||
|
@ -61,10 +70,12 @@ local wall_members = {
|
|||
f = "cstat",
|
||||
m = "overpicnum",
|
||||
p = "pal",
|
||||
w = { "upwall", -1 }, W = { "dnwall", -1 },
|
||||
o = "lotag", i = "hitag", e = { "extra", -1 }
|
||||
}
|
||||
|
||||
local wall_ord = { mand="1 23 4 5 6 78 90 ", opt="f m p oie" }
|
||||
local wall_ord = { mand="1 23 4 5 6 78 90 ", opt="f m p wW oie" }
|
||||
local wall_default = ffi.new("const walltype", { extra = -1, upwall=-1, dnwall=-1 })
|
||||
|
||||
|
||||
local sprite_members = {
|
||||
|
@ -89,6 +100,7 @@ local sprite_members = {
|
|||
}
|
||||
|
||||
local sprite_ord = { mand="123 4 5 6 7 8 90 ", opt="p c _ xy s w XYZ oie" }
|
||||
local sprite_default = ffi.new("const spritetype", { clipdist=32, owner=-1, extra=-1 })
|
||||
|
||||
|
||||
--== SAVING ==--
|
||||
|
@ -127,15 +139,14 @@ local function write_struct(f, struct, members, ord)
|
|||
end
|
||||
end)
|
||||
|
||||
f:write(str.."},\n")
|
||||
local neednl = (#str>0 and str:sub(-1)~="\n")
|
||||
f:write(str..(neednl and "\n" or "").."},\n")
|
||||
end
|
||||
|
||||
-- In map-text, instead of saving wall[].point2, we store whether a particular
|
||||
-- wall is the last one in its loop instead.
|
||||
local function save_tweak_point2()
|
||||
-- common
|
||||
local function check_bad_point2()
|
||||
local lastloopstart = 0
|
||||
|
||||
-- Check first.
|
||||
for i=0,ffiC.numwalls-1 do
|
||||
local p2 = ffiC.wall[i].point2
|
||||
|
||||
|
@ -149,6 +160,15 @@ local function save_tweak_point2()
|
|||
lastloopstart = i+1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- In map-text, instead of saving wall[].point2, we store whether a particular
|
||||
-- wall is the last one in its loop instead.
|
||||
local function save_tweak_point2()
|
||||
-- Check first.
|
||||
if (check_bad_point2()) then
|
||||
return true
|
||||
end
|
||||
|
||||
-- Do it for real.
|
||||
lastloopstart = 0
|
||||
|
@ -165,7 +185,8 @@ local function save_tweak_point2()
|
|||
end
|
||||
end
|
||||
|
||||
local function save_restore_point2()
|
||||
-- common
|
||||
local function restore_point2()
|
||||
local lastloopstart = 0
|
||||
|
||||
for i=0,ffiC.numwalls-1 do
|
||||
|
@ -193,7 +214,7 @@ local function saveboard_maptext(filename, pos, ang, cursectnum)
|
|||
|
||||
if (f == nil) then
|
||||
print(string.format("Couldn't open \"%s\" for writing: %s\n", filename, msg))
|
||||
save_restore_point2()
|
||||
restore_point2()
|
||||
return -1
|
||||
end
|
||||
|
||||
|
@ -215,14 +236,14 @@ local function saveboard_maptext(filename, pos, ang, cursectnum)
|
|||
for i=0,ffiC.numsectors-1 do
|
||||
write_struct(f, ffiC.sector[i], sector_members, sector_ord)
|
||||
end
|
||||
f:write("}\n\n")
|
||||
f:write("},\n\n")
|
||||
|
||||
-- Walls.
|
||||
f:write("wall={\n")
|
||||
for i=0,ffiC.numwalls-1 do
|
||||
write_struct(f, ffiC.wall[i], wall_members, wall_ord)
|
||||
end
|
||||
f:write("}\n\n")
|
||||
f:write("},\n\n")
|
||||
|
||||
-- Sprites.
|
||||
f:write("sprite={\n")
|
||||
|
@ -231,16 +252,240 @@ local function saveboard_maptext(filename, pos, ang, cursectnum)
|
|||
write_struct(f, ffiC.sprite[i], sprite_members, sprite_ord)
|
||||
end
|
||||
end
|
||||
f:write("}\n\n")
|
||||
f:write("},\n\n")
|
||||
|
||||
f:write("}\n");
|
||||
|
||||
-- Done.
|
||||
f:close()
|
||||
save_restore_point2()
|
||||
restore_point2()
|
||||
return 0
|
||||
end
|
||||
|
||||
|
||||
--== LOADING ==--
|
||||
|
||||
local function isnum(v)
|
||||
return (type(v)=="number")
|
||||
end
|
||||
|
||||
local function istab(v)
|
||||
return (type(v)=="table")
|
||||
end
|
||||
|
||||
-- Checks whether <tab> is a table all values of <tab> are of type <extype>.
|
||||
local function allxtab(tab, extype)
|
||||
if (not istab(tab)) then
|
||||
return false
|
||||
end
|
||||
|
||||
for _,val in pairs(tab) do
|
||||
if (type(val) ~= extype) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-- Is table of all numbers?
|
||||
local function allnumtab(tab) return allxtab(tab, "number") end
|
||||
-- Is table of all tables?
|
||||
local function alltabtab(tab) return allxtab(tab, "table") end
|
||||
|
||||
-- Is table of tables of all numbers? Additionally, each must contain exactly
|
||||
-- as many mandatory positional entries as given by the <members> table.
|
||||
local function tabofnumtabs(tab, members)
|
||||
for i=1,#tab do
|
||||
if (not allnumtab(tab[i])) then
|
||||
return false
|
||||
end
|
||||
|
||||
local nummand = #members -- number of mandatory entries
|
||||
if (#tab[i] ~= nummand) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
-- Read data from Lua table <stab> into C struct <cs>, using the struct
|
||||
-- description <members>.
|
||||
-- Returns true on error.
|
||||
local function read_struct(cs, stab, members, defaults)
|
||||
-- Clear struct to default values.
|
||||
ffi.copy(cs, defaults, ffi.sizeof(defaults))
|
||||
|
||||
-- Read mandatory positional members.
|
||||
for i=1,#members do
|
||||
cs[members[i]] = stab[i]
|
||||
end
|
||||
|
||||
-- Read optional key/value members.
|
||||
for k,val in pairs(stab) do
|
||||
if (members[k]==nil) then
|
||||
-- No such member abbreviation for the given struct.
|
||||
return true
|
||||
end
|
||||
|
||||
local memb = istab(members[k]) and members[k][1] or members[k]
|
||||
cs[memb] = val
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local RETERR = -4
|
||||
|
||||
local function loadboard_maptext(fil, posptr, angptr, cursectnumptr)
|
||||
-- Read the whole map-text as string.
|
||||
local str = readintostr(fil)
|
||||
|
||||
if (str == nil) then
|
||||
return RETERR
|
||||
end
|
||||
|
||||
-- Strip all one-line comments (currently, only the header).
|
||||
str = str:gsub("%-%-.-\n", "")
|
||||
|
||||
--- Preliminary (pseudo-syntactical) validation ---
|
||||
|
||||
-- Whitelist approach: map-text may only contain certain characters. This
|
||||
-- excludes various potentially 'bad' operations (such as calling a
|
||||
-- function) in one blow. Also, this assures (by exclusion) that the Lua
|
||||
-- code contains no long comments, strings, or function calls.
|
||||
if (not str:find("^[ A-Za-z_0-9{},%-\n=]+$")) then
|
||||
return RETERR-1
|
||||
end
|
||||
|
||||
-- The map-text code must return a single table.
|
||||
if (not str:find("^return %b{}\n$")) then
|
||||
return RETERR-2
|
||||
end
|
||||
|
||||
local func, errmsg = loadstring(str, "maptext")
|
||||
if (func == nil) then
|
||||
print("Error preloading map-text Lua code: "..errmsg)
|
||||
return RETERR-3
|
||||
end
|
||||
|
||||
-- Completely empty the function's environment as an additional safety
|
||||
-- measure, then run the chunk protected! (XXX: currently a bit pointless
|
||||
-- because of the asserts below.)
|
||||
local ok, map = pcall(setfenv(func, {}))
|
||||
if (not ok) then
|
||||
print("Error executing map-text Lua code: "..map)
|
||||
return RETERR-4
|
||||
end
|
||||
|
||||
assert(istab(map))
|
||||
-- OK, now 'map' contains the map data.
|
||||
|
||||
--- Structural validation ---
|
||||
|
||||
-- Check types.
|
||||
if (not isnum(map.version) or not allnumtab(map.pos) or #map.pos~=3 or
|
||||
not isnum(map.sectnum) or not isnum(map.ang))
|
||||
then
|
||||
return RETERR-5
|
||||
end
|
||||
|
||||
local msector, mwall, msprite = map.sector, map.wall, map.sprite
|
||||
|
||||
if (not alltabtab(msector) or not alltabtab(mwall) or not alltabtab(msprite)) then
|
||||
return RETERR-6
|
||||
end
|
||||
|
||||
if (not tabofnumtabs(msector, sector_members) or
|
||||
not tabofnumtabs(mwall, wall_members) or
|
||||
not tabofnumtabs(msprite, sprite_members))
|
||||
then
|
||||
return RETERR-7
|
||||
end
|
||||
|
||||
local numsectors, numwalls, numsprites = #msector, #mwall, #msprite
|
||||
local sector, wall, sprite = ffiC.sector, ffiC.wall, ffiC.sprite
|
||||
|
||||
if (numsectors+0ULL > ffiC.MAXSECTORS or numwalls+0ULL > ffiC.MAXWALLS or
|
||||
numsprites > ffiC.MAXSPRITES)
|
||||
then
|
||||
return RETERR-8
|
||||
end
|
||||
|
||||
--- From here on, start filling out C structures. ---
|
||||
|
||||
ffiC.numsectors = numsectors
|
||||
ffiC.numwalls = numwalls
|
||||
|
||||
-- Header.
|
||||
posptr.x = map.pos[1]
|
||||
posptr.y = map.pos[2]
|
||||
posptr.z = map.pos[3]
|
||||
|
||||
angptr[0] = map.ang
|
||||
cursectnumptr[0] = map.sectnum
|
||||
|
||||
-- Sectors.
|
||||
for i=0,numsectors-1 do
|
||||
if (read_struct(sector[i], msector[i+1], sector_members, sector_default)) then
|
||||
return RETERR-9
|
||||
end
|
||||
end
|
||||
|
||||
-- Walls.
|
||||
for i=0,numwalls-1 do
|
||||
if (read_struct(wall[i], mwall[i+1], wall_members, wall_default)) then
|
||||
return RETERR-10
|
||||
end
|
||||
end
|
||||
|
||||
-- Sprites.
|
||||
for i=0,numsprites-1 do
|
||||
if (read_struct(sprite[i], msprite[i+1], sprite_members, sprite_default)) then
|
||||
return RETERR-11
|
||||
end
|
||||
end
|
||||
|
||||
-- XXX: need to consistency-check much more here! Basically, all of
|
||||
-- astub.c's CheckMapCorruption() for corruption level >=4?
|
||||
-- See NOTNICE below.
|
||||
|
||||
--- Tweakery: mostly setting dependent members. ---
|
||||
|
||||
-- sector[]: .wallptr calculated from .wallnum.
|
||||
local numw = 0
|
||||
for i=0,numsectors-1 do
|
||||
assert(numw >= 0 and numw < numwalls) -- NOTNICE, cheap check instead of real one.
|
||||
sector[i].wallptr = numw
|
||||
numw = numw + sector[i].wallnum
|
||||
end
|
||||
|
||||
-- wall[]: .nextsector calculated by using engine's sectorofwall_noquick()
|
||||
for i=0,numwalls-1 do
|
||||
local nw = wall[i].nextwall
|
||||
|
||||
if (nw >= 0) then
|
||||
assert(nw >= 0 and nw < numwalls) -- NOTNICE
|
||||
wall[i].nextsector = ffiC.sectorofwall_noquick(nw)
|
||||
else
|
||||
wall[i].nextsector = -1
|
||||
end
|
||||
end
|
||||
|
||||
-- .point2 in {0, 1} --> wall index
|
||||
restore_point2()
|
||||
|
||||
-- Check .point2 at least.
|
||||
if (check_bad_point2()) then
|
||||
return RETERR-12
|
||||
end
|
||||
|
||||
-- All OK, return the number of sprites for further engine loading code.
|
||||
return numsprites
|
||||
end
|
||||
|
||||
|
||||
-- Register our Lua functions as callbacks from C.
|
||||
ffiC.saveboard_maptext = saveboard_maptext
|
||||
ffiC.loadboard_maptext = loadboard_maptext
|
||||
|
|
|
@ -237,6 +237,7 @@ local function new_initial_gvartab()
|
|||
numsectors = RO "_gv.numsectors",
|
||||
NUMSECTORS = RO "_gv.numsectors",
|
||||
NUMWALLS = RO "_gv.numwalls",
|
||||
-- TODO: Numsprites
|
||||
|
||||
randomseed = RW "_gv.randomseed",
|
||||
totalclock = RO "_gv.totalclock",
|
||||
|
|
Loading…
Reference in a new issue