mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-11-13 07:58:04 +00:00
build.lua: add "artfile" class, allowing to open and get pics from an ART file.
git-svn-id: https://svn.eduke32.com/eduke32@4104 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
fddc700cd6
commit
78e8f476e1
3 changed files with 191 additions and 12 deletions
|
@ -299,7 +299,7 @@ Miscellaneous
|
||||||
^^^^^^^^^^^^^
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
* Issuing `break` inside a part of an event chain (defined using multiple
|
* Issuing `break` inside a part of an event chain (defined using multiple
|
||||||
`onevent` blocks for one event) does not abort the whole chain.
|
`onevent` blocks for one event kind) does not abort the whole chain.
|
||||||
|
|
||||||
|
|
||||||
Unavailable functionality
|
Unavailable functionality
|
||||||
|
|
|
@ -2,15 +2,17 @@ definequote 125 FIRST
|
||||||
definequote 126 SECOND
|
definequote 126 SECOND
|
||||||
definequote 127 THIRD
|
definequote 127 THIRD
|
||||||
|
|
||||||
onevent EVENT_INIT
|
onevent EVENT_ENTERLEVEL
|
||||||
echo 125
|
echo 125
|
||||||
endevent
|
endevent
|
||||||
|
|
||||||
onevent EVENT_INIT
|
onevent EVENT_ENTERLEVEL
|
||||||
|
echo 126
|
||||||
|
break
|
||||||
echo 126
|
echo 126
|
||||||
endevent
|
endevent
|
||||||
|
|
||||||
onevent EVENT_INIT
|
onevent EVENT_ENTERLEVEL
|
||||||
echo 127
|
echo 127
|
||||||
endevent
|
endevent
|
||||||
|
|
||||||
|
@ -23,7 +25,19 @@ eventloadactor 2491 // DUKECAR
|
||||||
killit
|
killit
|
||||||
enda
|
enda
|
||||||
|
|
||||||
// output:
|
/*
|
||||||
// THIRD
|
Outputs:
|
||||||
// SECOND
|
========
|
||||||
// FIRST
|
|
||||||
|
C-CON:
|
||||||
|
------
|
||||||
|
THIRD
|
||||||
|
SECOND
|
||||||
|
|
||||||
|
LunaCON:
|
||||||
|
--------
|
||||||
|
THIRD
|
||||||
|
SECOND
|
||||||
|
FIRST
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
|
@ -74,14 +74,20 @@ MAX =
|
||||||
|
|
||||||
TILES = 30720,
|
TILES = 30720,
|
||||||
}
|
}
|
||||||
|
local MAX = MAX
|
||||||
|
|
||||||
local function doread(fh, basectype, numelts)
|
|
||||||
|
-- <dontclose>: if true, don't close file on error
|
||||||
|
local function doread(fh, basectype, numelts, dontclose)
|
||||||
assert(numelts > 0)
|
assert(numelts > 0)
|
||||||
local cd = ffi.new(basectype.."[?]", numelts)
|
local typ = ffi.typeof("$ [?]", ffi.typeof(basectype))
|
||||||
|
local cd = ffi.new(typ, numelts)
|
||||||
|
|
||||||
if (C.fread(cd, ffi.sizeof(basectype), numelts, fh) ~= numelts) then
|
if (C.fread(cd, ffi.sizeof(basectype), numelts, fh) ~= numelts) then
|
||||||
fh:close()
|
if (not dontclose) then
|
||||||
return nil
|
fh:close()
|
||||||
|
end
|
||||||
|
return nil, "Failed reading"
|
||||||
end
|
end
|
||||||
|
|
||||||
return cd
|
return cd
|
||||||
|
@ -298,6 +304,165 @@ function loadboard(filename, do_canonicalize_sprite)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local picanm_t = ffi.typeof[[
|
||||||
|
struct {
|
||||||
|
uint8_t num; // animate number
|
||||||
|
int8_t xofs, yofs;
|
||||||
|
uint8_t sf; // anim. speed and flags
|
||||||
|
}
|
||||||
|
]]
|
||||||
|
|
||||||
|
local artfile_mt = {
|
||||||
|
__index = {
|
||||||
|
-- Global -> local tile index (-1 if gtile is not in this ART file)
|
||||||
|
toltile = function(self, gtile)
|
||||||
|
if (self.tbeg <= gtile and gtile <= self.tend) then
|
||||||
|
return gtile - self.tbeg
|
||||||
|
end
|
||||||
|
return -1
|
||||||
|
end,
|
||||||
|
|
||||||
|
_check_ltile = function(self, ltile)
|
||||||
|
if (not (ltile >= 0 and ltile < self.numtiles)) then
|
||||||
|
error("Invalid local tile number "..ltile, 3)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
_getofs = function(self, ltile)
|
||||||
|
return self.tiledataofs + self.offs[ltile]
|
||||||
|
end,
|
||||||
|
|
||||||
|
dims = function(self, ltile)
|
||||||
|
return self.sizx[ltile], self.sizy[ltile]
|
||||||
|
end,
|
||||||
|
|
||||||
|
getpic = function(self, ltile)
|
||||||
|
self:_check_ltile(ltile)
|
||||||
|
|
||||||
|
local sx, sy = self:dims(ltile)
|
||||||
|
if (sx == 0 or sy == 0) then
|
||||||
|
-- Tile nonexistent/empty in this ART file
|
||||||
|
return nil, "Empty tile"
|
||||||
|
end
|
||||||
|
|
||||||
|
assert(self.fh:seek("set", self:_getofs(ltile)))
|
||||||
|
return doread(self.fh, "uint8_t", sx*sy, self.grpfh ~= false) -- GRPFH_FALSE
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
|
||||||
|
__metatable = true,
|
||||||
|
}
|
||||||
|
|
||||||
|
-- af, errmsg = artfile(filename [, grpfh, grpofs])
|
||||||
|
--
|
||||||
|
-- <filename>: File name of the file to get data from, expect if <grpfh>
|
||||||
|
-- passed. Always closed on error. Kept open on success.
|
||||||
|
-- <grpfh>: io.open() file handle to grouping file containing ART
|
||||||
|
-- uncompressed. Never closed, even on error.
|
||||||
|
-- <grpofs>: offset of the ART file in file given by <grpfh>
|
||||||
|
--
|
||||||
|
-- Returns:
|
||||||
|
-- * on error: nil, <errmsg>
|
||||||
|
-- * on success:
|
||||||
|
function artfile(filename, grpfh, grpofs)
|
||||||
|
local ogrpofs
|
||||||
|
local fh
|
||||||
|
|
||||||
|
if (grpfh) then
|
||||||
|
ogrpofs = grpfh:seek()
|
||||||
|
assert(grpfh:seek("set", grpofs))
|
||||||
|
fh = grpfh
|
||||||
|
else
|
||||||
|
local errmsg
|
||||||
|
fh, errmsg = io.open(filename, "rb")
|
||||||
|
if (fh == nil) then
|
||||||
|
return nil, errmsg
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Close file on error?
|
||||||
|
local dontclose = (grpfh ~= nil)
|
||||||
|
|
||||||
|
-- Maybe close file handle and return error message <msg>
|
||||||
|
local function err(msg, ...)
|
||||||
|
if (not dontclose) then
|
||||||
|
fh:close()
|
||||||
|
end
|
||||||
|
return nil, string.format(msg, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
local hdr = doread(fh, "int32_t", 4, dontclose)
|
||||||
|
-- artversion, numtiles, localtilestart, localtileend
|
||||||
|
if (hdr == nil) then
|
||||||
|
return err("Couldn't read header")
|
||||||
|
end
|
||||||
|
|
||||||
|
local af = {
|
||||||
|
filename = filename,
|
||||||
|
fh = fh,
|
||||||
|
grpfh = grpfh or false, -- GRPFH_FALSE
|
||||||
|
|
||||||
|
tbeg = hdr[2],
|
||||||
|
tend = hdr[3],
|
||||||
|
numtiles = hdr[3]-hdr[2]+1,
|
||||||
|
|
||||||
|
-- Members inserted later:
|
||||||
|
-- sizx, sizy: picanm: arrays of length af.numtiles
|
||||||
|
-- tiledataofs: byte offset in `fh' to beginning of tile data
|
||||||
|
-- offs: local byte offsets of each tile, relative of af.tiledataofs
|
||||||
|
--
|
||||||
|
-- Thus,
|
||||||
|
-- af.tiledataofs + af.offs[localtilenum]
|
||||||
|
-- is the byte offset of global tile
|
||||||
|
-- af.tbeg + localtilenum
|
||||||
|
-- in `fh'.
|
||||||
|
}
|
||||||
|
|
||||||
|
if (af.numtiles <= 0) then
|
||||||
|
return err("Invalid tile start/end or empty ART file")
|
||||||
|
end
|
||||||
|
|
||||||
|
local lasttile = af.tbeg + af.numtiles
|
||||||
|
if (lasttile >= MAX.TILES) then
|
||||||
|
return err("Last tile %d beyond MAXTILES-1 (%d)", lasttile, MAX.TILES-1)
|
||||||
|
end
|
||||||
|
|
||||||
|
af.sizx = doread(fh, "int16_t", af.numtiles, dontclose)
|
||||||
|
af.sizy = doread(fh, "int16_t", af.numtiles, dontclose)
|
||||||
|
|
||||||
|
if (af.sizx==nil or af.sizy==nil) then
|
||||||
|
return err("Couldn't read sizx or sizy arrays")
|
||||||
|
end
|
||||||
|
|
||||||
|
af.picanm = doread(fh, picanm_t, af.numtiles, dontclose)
|
||||||
|
|
||||||
|
if (af.picanm == nil) then
|
||||||
|
return err("Couldn't read picanm array")
|
||||||
|
end
|
||||||
|
|
||||||
|
af.tiledataofs = assert(fh:seek())
|
||||||
|
af.offs = ffi.new("uint32_t [?]", af.numtiles)
|
||||||
|
|
||||||
|
local curofs = 0
|
||||||
|
|
||||||
|
for i=0,af.numtiles-1 do
|
||||||
|
local sx, sy = af.sizx[i], af.sizy[i]
|
||||||
|
|
||||||
|
if (sx > 0 and sy > 0) then
|
||||||
|
af.offs[i] = curofs
|
||||||
|
curofs = curofs + sx*sy
|
||||||
|
elseif (sx < 0 or sy < 0) then
|
||||||
|
-- Let's sanity-check stuff a little
|
||||||
|
return err("Local tile %d has negative x or y size", i)
|
||||||
|
else
|
||||||
|
af.offs[i] = -1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return setmetatable(af, artfile_mt)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
local function set_sizarray_mt(sizar)
|
local function set_sizarray_mt(sizar)
|
||||||
local mt = {
|
local mt = {
|
||||||
__index = function(tab, idx)
|
__index = function(tab, idx)
|
||||||
|
|
Loading…
Reference in a new issue