mirror of
https://github.com/libretro/retroluxury.git
synced 2025-02-17 05:37:57 +00:00
better organization of modules for the tools
This commit is contained in:
parent
c1a895f4fa
commit
9fea973eb0
10
etc/luai/lua/djb2.lua
Normal file
10
etc/luai/lua/djb2.lua
Normal file
@ -0,0 +1,10 @@
|
||||
return function( str )
|
||||
local hash = 5381
|
||||
|
||||
for i = 1, #str do
|
||||
hash = hash * 33 + str:byte( i )
|
||||
hash = hash & 0xffffffff
|
||||
end
|
||||
|
||||
return hash
|
||||
end
|
16
etc/luai/lua/mkis.lua
Normal file
16
etc/luai/lua/mkis.lua
Normal file
@ -0,0 +1,16 @@
|
||||
local writer = require 'writer'
|
||||
local mkrle = require 'mkrle'
|
||||
|
||||
return function( images, limit )
|
||||
local out = writer()
|
||||
|
||||
out:add16( #images )
|
||||
|
||||
for _, png in ipairs( images ) do
|
||||
local rle = mkrle( png, limit )
|
||||
out:add32( rle:getsize() )
|
||||
out:addwriter( rle )
|
||||
end
|
||||
|
||||
return out
|
||||
end
|
115
etc/luai/lua/mkrle.lua
Normal file
115
etc/luai/lua/mkrle.lua
Normal file
@ -0,0 +1,115 @@
|
||||
local image = require 'image'
|
||||
local rgbto16 = require 'rgbto16'
|
||||
local writer = require 'writer'
|
||||
|
||||
local function getpixel( png, x, y, transp )
|
||||
local r, g, b, a = image.split( png:getPixel( x, y ) )
|
||||
local c = rgbto16( r, g, b )
|
||||
|
||||
if c == transp then
|
||||
r, g, b, a = 0, 0, 0, 0
|
||||
end
|
||||
|
||||
if a >= 0 and a <= 31 then
|
||||
a = 0 -- transparent
|
||||
elseif a >= 32 and a <= 95 then
|
||||
a = 1 -- 25%
|
||||
elseif a >= 96 and a <= 159 then
|
||||
a = 2 -- 50%
|
||||
elseif a >= 160 and a <= 223 then
|
||||
a = 3 -- 75%
|
||||
else
|
||||
a = 4 -- opaque
|
||||
end
|
||||
|
||||
return rgbto16( r, g, b ), a
|
||||
end
|
||||
|
||||
local function rlerow( png, y, limit, transp )
|
||||
local rle = {}
|
||||
local width = png:getWidth()
|
||||
local used = 0
|
||||
|
||||
local numcols = ( width + ( limit - 1 ) ) // limit
|
||||
|
||||
for i = 1, numcols do
|
||||
rle[ #rle + 1 ] = 0
|
||||
end
|
||||
|
||||
for xx = 0, width - 1, limit do
|
||||
rle[ xx // limit + 1 ] = #rle
|
||||
|
||||
local x = xx
|
||||
rle[ #rle + 1 ] = 0
|
||||
local runs = #rle
|
||||
|
||||
while x < ( xx + limit ) and x < width do
|
||||
local _, a = getpixel( png, x, y, transp )
|
||||
local count = 0
|
||||
local xsave = x
|
||||
|
||||
while x < ( xx + limit ) and x < width do
|
||||
local c, aa = getpixel( png, x, y, transp )
|
||||
|
||||
if aa ~= a then
|
||||
break
|
||||
end
|
||||
|
||||
count = count + 1
|
||||
x = x + 1
|
||||
end
|
||||
|
||||
rle[ #rle + 1 ] = ( a << 13 | count )
|
||||
rle[ runs ] = rle[ runs ] + 1
|
||||
|
||||
if a ~= 0 then
|
||||
for i = 0, count - 1 do
|
||||
local c = getpixel( png, xsave + i, y, transp )
|
||||
rle[ #rle + 1 ] = c
|
||||
used = used + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local final = writer()
|
||||
|
||||
for i = 1, #rle do
|
||||
final:add16( rle[ i ] )
|
||||
end
|
||||
|
||||
return final, used
|
||||
end
|
||||
|
||||
return function( png, limit, transp )
|
||||
local width, height = png:getSize()
|
||||
local rows = {}
|
||||
local used = 0
|
||||
|
||||
limit = limit or 1e10
|
||||
|
||||
for y = 0, height - 1 do
|
||||
local row, u = rlerow( png, y, limit, transp )
|
||||
rows[ y ] = row
|
||||
used = used + u
|
||||
end
|
||||
|
||||
local rle = writer()
|
||||
|
||||
rle:add16( width )
|
||||
rle:add16( height )
|
||||
rle:add32( used )
|
||||
|
||||
local count = 0
|
||||
|
||||
for y = 0, height - 1 do
|
||||
rle:add32( count )
|
||||
count = count + rows[ y ]:getsize()
|
||||
end
|
||||
|
||||
for y = 0, height - 1 do
|
||||
rle:addwriter( rows[ y ] )
|
||||
end
|
||||
|
||||
return rle
|
||||
end
|
19
etc/luai/lua/mkts.lua
Normal file
19
etc/luai/lua/mkts.lua
Normal file
@ -0,0 +1,19 @@
|
||||
local writer = require 'writer'
|
||||
|
||||
return function( images )
|
||||
local res = writer()
|
||||
|
||||
res:add16( images[ 1 ]:getWidth() )
|
||||
res:add16( images[ 1 ]:getHeight() )
|
||||
res:add16( #images )
|
||||
|
||||
for _, img in pairs( images ) do
|
||||
for y = 0, img:getHeight() - 1 do
|
||||
for x = 0, img:getWidth() - 1 do
|
||||
res:add16( getpixel( img, x, y ) )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return res
|
||||
end
|
7
etc/luai/lua/rgbto16.lua
Normal file
7
etc/luai/lua/rgbto16.lua
Normal file
@ -0,0 +1,7 @@
|
||||
return function( r, g, b )
|
||||
r = r * 32 // 256
|
||||
g = g * 64 // 256
|
||||
b = b * 32 // 256
|
||||
|
||||
return ( r << 11 ) | ( g << 5 ) | b
|
||||
end
|
169
etc/luai/lua/tmx.lua
Normal file
169
etc/luai/lua/tmx.lua
Normal file
@ -0,0 +1,169 @@
|
||||
local image = require 'xml'
|
||||
local xml = require 'xml'
|
||||
|
||||
return {
|
||||
load = function( filename )
|
||||
local dir = path.split( filename ) .. path.separator
|
||||
local file = assert( io.open( filename ) )
|
||||
|
||||
file:read( '*l' ) -- skip <?xml ... ?>
|
||||
local contents = file:read( '*a' )
|
||||
file:close()
|
||||
|
||||
local tmx = xml.parse( contents )
|
||||
|
||||
local map = {}
|
||||
|
||||
map.version = xml.findAttr( tmx, 'version' )
|
||||
map.orientation = xml.findAttr( tmx, 'orientation' )
|
||||
map.width = tonumber( xml.findAttr( tmx, 'width' ) )
|
||||
map.height = tonumber( xml.findAttr( tmx, 'height' ) )
|
||||
map.tilewidth = tonumber( xml.findAttr( tmx, 'tilewidth' ) )
|
||||
map.tileheight = tonumber( xml.findAttr( tmx, 'tileheight' ) )
|
||||
map.widthpixels = map.width * map.tilewidth
|
||||
map.heightpixels = map.height * map.tileheight
|
||||
map.backgroundcolor = image.color( 0, 0, 0 )
|
||||
|
||||
local backgroundcolor = xml.findAttr( tmx, 'backgroundcolor' )
|
||||
|
||||
if backgroundcolor then
|
||||
backgroundcolor = tonumber( backgroundcolor, 16 )
|
||||
local r = backgroundcolor >> 16
|
||||
local g = backgroundcolor >> 8 & 255
|
||||
local b = backgroundcolor & 255
|
||||
map.backgroundcolor = image.color( r, g, b )
|
||||
end
|
||||
|
||||
local tilesets = {}
|
||||
map.tilesets = tilesets
|
||||
|
||||
local gids = {}
|
||||
map.gids = gids
|
||||
|
||||
for _, child in ipairs( tmx ) do
|
||||
if child.label == 'tileset' then
|
||||
local tileset =
|
||||
{
|
||||
firstgid = tonumber( xml.findAttr( child, 'firstgid' ) ),
|
||||
name = xml.findAttr( child, 'name' ),
|
||||
tilewidth = tonumber( xml.findAttr( child, 'tilewidth' ) ),
|
||||
tileheight = tonumber( xml.findAttr( child, 'tileheight' ) )
|
||||
}
|
||||
|
||||
if map.tilewidth ~= tileset.tilewidth or map.tileheight ~= tileset.tileheight then
|
||||
error( string.format( 'tile dimensions in %s are different from tile dimensions in map', tileset.name ) )
|
||||
end
|
||||
|
||||
for _, child2 in ipairs( child ) do
|
||||
if child2.label == 'image' then
|
||||
local filename = path.realpath( dir .. xml.findAttr( child2, 'source' ) )
|
||||
tileset.image = image.load( filename )
|
||||
local trans = xml.findAttr( child2, 'trans' )
|
||||
|
||||
if trans then
|
||||
trans = tonumber( trans, 16 )
|
||||
local r = trans >> 16
|
||||
local g = trans >> 8 & 255
|
||||
local b = trans & 255
|
||||
trans = image.color( r, g, b )
|
||||
tileset.image:colorToAlpha( trans )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
tileset.lastgid = tileset.firstgid + ( tileset.image:getWidth() // tileset.tilewidth ) * ( tileset.image:getHeight() // tileset.tileheight ) - 1
|
||||
|
||||
local imagewidth = tileset.image:getWidth()
|
||||
local tilewidth = tileset.tilewidth
|
||||
local tileheight = tileset.tileheight
|
||||
|
||||
for i = tileset.firstgid, tileset.lastgid do
|
||||
local id = i - tileset.firstgid
|
||||
local j = id * tileset.tilewidth
|
||||
local x = j % imagewidth
|
||||
local y = math.floor( j / imagewidth ) * tileset.tileheight
|
||||
gids[ i ] =
|
||||
{
|
||||
tileset = tileset,
|
||||
id = id,
|
||||
x = x,
|
||||
y = y,
|
||||
width = tilewidth,
|
||||
height = tileheight,
|
||||
image = tileset.image:sub( x, y, x + tilewidth - 1, y + tileheight - 1 )
|
||||
}
|
||||
end
|
||||
|
||||
tilesets[ #tilesets + 1 ] = tileset
|
||||
end
|
||||
end
|
||||
|
||||
local layers = {}
|
||||
map.layers = layers
|
||||
|
||||
for _, child in ipairs( tmx ) do
|
||||
if child.label == 'layer' then
|
||||
local layer =
|
||||
{
|
||||
name = xml.findAttr( child, 'name' ),
|
||||
width = tonumber( xml.findAttr( child, 'width' ) ),
|
||||
height = tonumber( xml.findAttr( child, 'height' ) ),
|
||||
tiles = {}
|
||||
}
|
||||
|
||||
for _, child2 in ipairs( child ) do
|
||||
if child2.label == 'data' then
|
||||
local index = 1
|
||||
|
||||
for y = 1, layer.height do
|
||||
local row = {}
|
||||
layer.tiles[ y ] = row
|
||||
|
||||
for x = 1, layer.width do
|
||||
local tile = child2[ index ]
|
||||
index = index + 1
|
||||
row[ x ] = tonumber( xml.findAttr( tile, 'gid' ) )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
layers[ #layers + 1 ] = layer
|
||||
end
|
||||
end
|
||||
|
||||
return map
|
||||
end,
|
||||
render = function( map, layers )
|
||||
local png = image.create( map.widthpixels, map.heightpixels, image.color( 0, 0, 0, 0 ) )
|
||||
|
||||
for _, layer in ipairs( map.layers ) do
|
||||
if layers[ layer.name ] then
|
||||
local yy = 0
|
||||
|
||||
for y = 1, layer.height do
|
||||
local row = layer.tiles[ y ]
|
||||
local xx = 0
|
||||
|
||||
for x = 1, layer.width do
|
||||
if row[ x ] ~= 0 then
|
||||
local tile = map.gids[ row[ x ] ]
|
||||
|
||||
if not tile then
|
||||
error( 'Unknown gid ' .. row[ x ] .. ' in layer ' .. layer.name )
|
||||
end
|
||||
|
||||
tile.image:blit( png, xx, yy )
|
||||
end
|
||||
|
||||
xx = xx + map.tilewidth
|
||||
end
|
||||
|
||||
yy = yy + map.tileheight
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return png
|
||||
end
|
||||
}
|
41
etc/luai/lua/writer.lua
Normal file
41
etc/luai/lua/writer.lua
Normal file
@ -0,0 +1,41 @@
|
||||
return function()
|
||||
return {
|
||||
bytes = {},
|
||||
add8 = function( self, x )
|
||||
self.bytes[ #self.bytes + 1 ] = string.char( x & 255 )
|
||||
end,
|
||||
add16 = function( self, x )
|
||||
self.bytes[ #self.bytes + 1 ] = string.char( ( x >> 8 ) & 255, x & 255 )
|
||||
end,
|
||||
add32 = function( self, x )
|
||||
self.bytes[ #self.bytes + 1 ] = string.char( ( x >> 24 ) & 255, ( x >> 16 ) & 255, ( x >> 8 ) & 255, x & 255 )
|
||||
end,
|
||||
addstring = function( self, str )
|
||||
self.bytes[ #self.bytes + 1 ] = str
|
||||
end,
|
||||
addwriter = function( self, rle )
|
||||
self.bytes[ #self.bytes + 1 ] = table.concat( rle.bytes )
|
||||
end,
|
||||
align = function( self, x )
|
||||
local size = self:getsize()
|
||||
local new_size = ( size + x - 1 ) & -x
|
||||
|
||||
while size < new_size do
|
||||
self:add8( 0 )
|
||||
size = size + 1
|
||||
end
|
||||
end,
|
||||
getbytes = function( self )
|
||||
self.bytes = { table.concat( self.bytes ) }
|
||||
return self.bytes[ 1 ]
|
||||
end,
|
||||
getsize = function( self )
|
||||
return #self:getbytes()
|
||||
end,
|
||||
save = function( self, name )
|
||||
local file = assert( io.open( name, 'wb' ) )
|
||||
file:write( self:getbytes() )
|
||||
file:close()
|
||||
end
|
||||
}
|
||||
end
|
105
etc/luai/lua/xml.lua
Normal file
105
etc/luai/lua/xml.lua
Normal file
@ -0,0 +1,105 @@
|
||||
local function prettyPrint( node, file, ident )
|
||||
file = file or io.stdout
|
||||
ident = ident or 0
|
||||
|
||||
if type( node ) == 'table' then
|
||||
file:write( ( ' ' ):rep( ident ), '<', node.label )
|
||||
|
||||
for attr, value in pairs( node.xarg ) do
|
||||
file:write( ' ', attr, '="', value, '"' )
|
||||
end
|
||||
|
||||
if node.empty then
|
||||
file:write( '/>\n' )
|
||||
else
|
||||
file:write( '>\n' )
|
||||
|
||||
for _, child in ipairs( node ) do
|
||||
prettyPrint( child, file, ident + 2 )
|
||||
end
|
||||
|
||||
file:write( ( ' ' ):rep( ident ), '</', node.label, '>\n' )
|
||||
end
|
||||
else
|
||||
file:write( ( ' ' ):rep( ident ), node, '\n' )
|
||||
end
|
||||
end
|
||||
|
||||
local function findNode( node, label )
|
||||
if type( node ) == 'table' then
|
||||
if node.label == label then
|
||||
return node
|
||||
end
|
||||
|
||||
for i = 1, #node do
|
||||
local res = findNode( node[ i ], label )
|
||||
|
||||
if res then
|
||||
return res
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function parseargs(s)
|
||||
local arg = {}
|
||||
string.gsub(s, "([%w:]+)=([\"'])(.-)%2", function (w, _, a)
|
||||
arg[w] = a
|
||||
end)
|
||||
return arg
|
||||
end
|
||||
|
||||
return {
|
||||
parse = function(s)
|
||||
local stack = {}
|
||||
local top = {}
|
||||
table.insert(stack, top)
|
||||
local ni,c,label,xarg, empty
|
||||
local i, j = 1, 1
|
||||
while true do
|
||||
ni,j,c,label,xarg, empty = string.find(s, "<(%/?)([%w:]+)(.-)(%/?)>", i)
|
||||
if not ni then break end
|
||||
local text = string.sub(s, i, ni-1)
|
||||
if not string.find(text, "^%s*$") then
|
||||
table.insert(top, text)
|
||||
end
|
||||
if empty == "/" then -- empty element tag
|
||||
table.insert(top, {label=label, xarg=parseargs(xarg), empty=1})
|
||||
elseif c == "" then -- start tag
|
||||
top = {label=label, xarg=parseargs(xarg)}
|
||||
table.insert(stack, top) -- new level
|
||||
else -- end tag
|
||||
local toclose = table.remove(stack) -- remove top
|
||||
top = stack[#stack]
|
||||
if #stack < 1 then
|
||||
error("nothing to close with "..label)
|
||||
end
|
||||
if toclose.label ~= label then
|
||||
error("trying to close "..toclose.label.." with "..label)
|
||||
end
|
||||
table.insert(top, toclose)
|
||||
end
|
||||
i = j+1
|
||||
end
|
||||
local text = string.sub(s, i)
|
||||
if not string.find(text, "^%s*$") then
|
||||
table.insert(stack[#stack], text)
|
||||
end
|
||||
if #stack > 1 then
|
||||
error("unclosed "..stack[#stack].label)
|
||||
end
|
||||
return stack[1][1]
|
||||
end,
|
||||
|
||||
findNode = findNode,
|
||||
|
||||
findAttr = function( node, name )
|
||||
for key, value in pairs( node.xarg ) do
|
||||
if key == name then
|
||||
return value
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
prettyPrint = prettyPrint
|
||||
}
|
45
etc/rlimageset.lua
Normal file
45
etc/rlimageset.lua
Normal file
@ -0,0 +1,45 @@
|
||||
local image = require 'image'
|
||||
local mkis = require 'mkis'
|
||||
|
||||
return function( args )
|
||||
if #args == 0 then
|
||||
io.write[[
|
||||
rlimageset.lua creates an imageset containing all files given on the command
|
||||
line.
|
||||
|
||||
Usage: luai rlimageset.lua [ options ] images...
|
||||
|
||||
--output <file> writes the imageset to the given file
|
||||
--margin x sets the pixel limit on RLE runs on a row (must be equal to
|
||||
RL_BACKGRND_MARGIN)
|
||||
]]
|
||||
|
||||
return 0
|
||||
end
|
||||
|
||||
local output, limit
|
||||
local images = {}
|
||||
|
||||
do
|
||||
local i = 1
|
||||
|
||||
while i <= #args do
|
||||
if args[ i ] == '--output' then
|
||||
i = i + 1
|
||||
output = args[ i ]
|
||||
elseif args[ i ] == '--margin' then
|
||||
i = i + 1
|
||||
limit = tonumber( args[ i ] )
|
||||
else
|
||||
images[ #images + 1 ] = image.load( args[ i ] )
|
||||
end
|
||||
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
|
||||
local out = mkis( images, limit )
|
||||
out:save( output )
|
||||
|
||||
return 0
|
||||
end
|
377
etc/rlmap.lua
377
etc/rlmap.lua
@ -1,118 +1,8 @@
|
||||
local image = require 'image'
|
||||
local path = require 'path'
|
||||
|
||||
local rleimage
|
||||
|
||||
local xml = [===[
|
||||
local function prettyPrint( node, file, ident )
|
||||
file = file or io.stdout
|
||||
ident = ident or 0
|
||||
|
||||
if type( node ) == 'table' then
|
||||
file:write( ( ' ' ):rep( ident ), '<', node.label )
|
||||
|
||||
for attr, value in pairs( node.xarg ) do
|
||||
file:write( ' ', attr, '="', value, '"' )
|
||||
end
|
||||
|
||||
if node.empty then
|
||||
file:write( '/>\n' )
|
||||
else
|
||||
file:write( '>\n' )
|
||||
|
||||
for _, child in ipairs( node ) do
|
||||
prettyPrint( child, file, ident + 2 )
|
||||
end
|
||||
|
||||
file:write( ( ' ' ):rep( ident ), '</', node.label, '>\n' )
|
||||
end
|
||||
else
|
||||
file:write( ( ' ' ):rep( ident ), node, '\n' )
|
||||
end
|
||||
end
|
||||
|
||||
local function findNode( node, label )
|
||||
if type( node ) == 'table' then
|
||||
if node.label == label then
|
||||
return node
|
||||
end
|
||||
|
||||
for i = 1, #node do
|
||||
local res = findNode( node[ i ], label )
|
||||
|
||||
if res then
|
||||
return res
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function parseargs(s)
|
||||
local arg = {}
|
||||
string.gsub(s, "([%w:]+)=([\"'])(.-)%2", function (w, _, a)
|
||||
arg[w] = a
|
||||
end)
|
||||
return arg
|
||||
end
|
||||
|
||||
return
|
||||
{
|
||||
parse = function(s)
|
||||
local stack = {}
|
||||
local top = {}
|
||||
table.insert(stack, top)
|
||||
local ni,c,label,xarg, empty
|
||||
local i, j = 1, 1
|
||||
while true do
|
||||
ni,j,c,label,xarg, empty = string.find(s, "<(%/?)([%w:]+)(.-)(%/?)>", i)
|
||||
if not ni then break end
|
||||
local text = string.sub(s, i, ni-1)
|
||||
if not string.find(text, "^%s*$") then
|
||||
table.insert(top, text)
|
||||
end
|
||||
if empty == "/" then -- empty element tag
|
||||
table.insert(top, {label=label, xarg=parseargs(xarg), empty=1})
|
||||
elseif c == "" then -- start tag
|
||||
top = {label=label, xarg=parseargs(xarg)}
|
||||
table.insert(stack, top) -- new level
|
||||
else -- end tag
|
||||
local toclose = table.remove(stack) -- remove top
|
||||
top = stack[#stack]
|
||||
if #stack < 1 then
|
||||
error("nothing to close with "..label)
|
||||
end
|
||||
if toclose.label ~= label then
|
||||
error("trying to close "..toclose.label.." with "..label)
|
||||
end
|
||||
table.insert(top, toclose)
|
||||
end
|
||||
i = j+1
|
||||
end
|
||||
local text = string.sub(s, i)
|
||||
if not string.find(text, "^%s*$") then
|
||||
table.insert(stack[#stack], text)
|
||||
end
|
||||
if #stack > 1 then
|
||||
error("unclosed "..stack[#stack].label)
|
||||
end
|
||||
return stack[1][1]
|
||||
end,
|
||||
|
||||
findNode = findNode,
|
||||
|
||||
findAttr = function( node, name )
|
||||
for key, value in pairs( node.xarg ) do
|
||||
if key == name then
|
||||
return value
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
prettyPrint = prettyPrint
|
||||
}
|
||||
]===]
|
||||
|
||||
xml = load( xml, 'xml.lua' )()
|
||||
local image = require 'image'
|
||||
local path = require 'path'
|
||||
local tmx = require 'tmx'
|
||||
local mkrle = require 'mkrle'
|
||||
local writer = require 'writer'
|
||||
|
||||
local function dump( t, i )
|
||||
i = i or 0
|
||||
@ -151,213 +41,8 @@ local function split( str, sep )
|
||||
return res
|
||||
end
|
||||
|
||||
local function loadtmx( filename )
|
||||
local dir = path.split( filename ) .. path.separator
|
||||
local file, err = io.open( filename )
|
||||
|
||||
if not file then
|
||||
error( err )
|
||||
end
|
||||
|
||||
file:read( '*l' ) -- skip <?xml ... ?>
|
||||
local contents = file:read( '*a' )
|
||||
file:close()
|
||||
|
||||
local tmx = xml.parse( contents )
|
||||
|
||||
local map = {}
|
||||
|
||||
map.version = xml.findAttr( tmx, 'version' )
|
||||
map.orientation = xml.findAttr( tmx, 'orientation' )
|
||||
map.width = tonumber( xml.findAttr( tmx, 'width' ) )
|
||||
map.height = tonumber( xml.findAttr( tmx, 'height' ) )
|
||||
map.tilewidth = tonumber( xml.findAttr( tmx, 'tilewidth' ) )
|
||||
map.tileheight = tonumber( xml.findAttr( tmx, 'tileheight' ) )
|
||||
map.widthpixels = map.width * map.tilewidth
|
||||
map.heightpixels = map.height * map.tileheight
|
||||
map.backgroundcolor = image.color( 0, 0, 0 )
|
||||
|
||||
local backgroundcolor = xml.findAttr( tmx, 'backgroundcolor' )
|
||||
|
||||
if backgroundcolor then
|
||||
backgroundcolor = tonumber( backgroundcolor, 16 )
|
||||
local r = backgroundcolor >> 16
|
||||
local g = backgroundcolor >> 8 & 255
|
||||
local b = backgroundcolor & 255
|
||||
map.backgroundcolor = image.color( r, g, b )
|
||||
end
|
||||
|
||||
local tilesets = {}
|
||||
map.tilesets = tilesets
|
||||
|
||||
local gids = {}
|
||||
map.gids = gids
|
||||
|
||||
for _, child in ipairs( tmx ) do
|
||||
if child.label == 'tileset' then
|
||||
local tileset =
|
||||
{
|
||||
firstgid = tonumber( xml.findAttr( child, 'firstgid' ) ),
|
||||
name = xml.findAttr( child, 'name' ),
|
||||
tilewidth = tonumber( xml.findAttr( child, 'tilewidth' ) ),
|
||||
tileheight = tonumber( xml.findAttr( child, 'tileheight' ) )
|
||||
}
|
||||
|
||||
if map.tilewidth ~= tileset.tilewidth or map.tileheight ~= tileset.tileheight then
|
||||
error( string.format( 'tile dimensions in %s are different from tile dimensions in map', tileset.name ) )
|
||||
end
|
||||
|
||||
for _, child2 in ipairs( child ) do
|
||||
if child2.label == 'image' then
|
||||
local filename = path.realpath( dir .. xml.findAttr( child2, 'source' ) )
|
||||
tileset.image = image.load( filename )
|
||||
local trans = xml.findAttr( child2, 'trans' )
|
||||
|
||||
if trans then
|
||||
trans = tonumber( trans, 16 )
|
||||
local r = trans >> 16
|
||||
local g = trans >> 8 & 255
|
||||
local b = trans & 255
|
||||
trans = image.color( r, g, b )
|
||||
tileset.image:colorToAlpha( trans )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
tileset.lastgid = tileset.firstgid + ( tileset.image:getWidth() // tileset.tilewidth ) * ( tileset.image:getHeight() // tileset.tileheight ) - 1
|
||||
|
||||
local imagewidth = tileset.image:getWidth()
|
||||
local tilewidth = tileset.tilewidth
|
||||
local tileheight = tileset.tileheight
|
||||
|
||||
for i = tileset.firstgid, tileset.lastgid do
|
||||
local id = i - tileset.firstgid
|
||||
local j = id * tileset.tilewidth
|
||||
local x = j % imagewidth
|
||||
local y = math.floor( j / imagewidth ) * tileset.tileheight
|
||||
gids[ i ] =
|
||||
{
|
||||
tileset = tileset,
|
||||
id = id,
|
||||
x = x,
|
||||
y = y,
|
||||
width = tilewidth,
|
||||
height = tileheight,
|
||||
image = tileset.image:sub( x, y, x + tilewidth - 1, y + tileheight - 1 )
|
||||
}
|
||||
end
|
||||
|
||||
tilesets[ #tilesets + 1 ] = tileset
|
||||
end
|
||||
end
|
||||
|
||||
local layers = {}
|
||||
map.layers = layers
|
||||
|
||||
for _, child in ipairs( tmx ) do
|
||||
if child.label == 'layer' then
|
||||
local layer =
|
||||
{
|
||||
name = xml.findAttr( child, 'name' ),
|
||||
width = tonumber( xml.findAttr( child, 'width' ) ),
|
||||
height = tonumber( xml.findAttr( child, 'height' ) ),
|
||||
tiles = {}
|
||||
}
|
||||
|
||||
for _, child2 in ipairs( child ) do
|
||||
if child2.label == 'data' then
|
||||
local index = 1
|
||||
|
||||
for y = 1, layer.height do
|
||||
local row = {}
|
||||
layer.tiles[ y ] = row
|
||||
|
||||
for x = 1, layer.width do
|
||||
local tile = child2[ index ]
|
||||
index = index + 1
|
||||
row[ x ] = tonumber( xml.findAttr( tile, 'gid' ) )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
layers[ #layers + 1 ] = layer
|
||||
end
|
||||
end
|
||||
|
||||
return map
|
||||
end
|
||||
|
||||
local function render( map, layers )
|
||||
local png = image.create( map.widthpixels, map.heightpixels, image.color( 0, 0, 0, 0 ) )
|
||||
|
||||
for _, layer in ipairs( map.layers ) do
|
||||
if layers[ layer.name ] then
|
||||
local yy = 0
|
||||
|
||||
for y = 1, layer.height do
|
||||
local row = layer.tiles[ y ]
|
||||
local xx = 0
|
||||
|
||||
for x = 1, layer.width do
|
||||
if row[ x ] ~= 0 then
|
||||
local tile = map.gids[ row[ x ] ]
|
||||
|
||||
if not tile then
|
||||
error( 'Unknown gid ' .. row[ x ] .. ' in layer ' .. layer.name )
|
||||
end
|
||||
|
||||
tile.image:blit( png, xx, yy )
|
||||
end
|
||||
|
||||
xx = xx + map.tilewidth
|
||||
end
|
||||
|
||||
yy = yy + map.tileheight
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return png
|
||||
end
|
||||
|
||||
local function newwriter()
|
||||
return {
|
||||
content = {},
|
||||
writeu8 = function( self, x )
|
||||
self.content[ #self.content + 1 ] = string.char( x & 255 )
|
||||
end,
|
||||
writeu16 = function( self, x )
|
||||
self.content[ #self.content + 1 ] = string.char( ( x >> 8 ) & 255, x & 255 )
|
||||
end,
|
||||
writeu32 = function( self, x )
|
||||
self.content[ #self.content + 1 ] = string.char( ( x >> 24 ) & 255, ( x >> 16 ) & 255, ( x >> 8 ) & 255, x & 255 )
|
||||
end,
|
||||
prependu32 = function( self, x )
|
||||
table.insert( self.content, 1, string.char( ( x >> 24 ) & 255, ( x >> 16 ) & 255, ( x >> 8 ) & 255, x & 255 ) )
|
||||
end,
|
||||
append = function( self, bytes )
|
||||
self.content[ #self.content + 1 ] = bytes
|
||||
end,
|
||||
save = function( self, filename )
|
||||
local file, err = io.open( filename, 'wb' )
|
||||
if not file then error( err ) end
|
||||
file:write( table.concat( self.content ) )
|
||||
file:close()
|
||||
end,
|
||||
size = function( self, filename )
|
||||
self.content = { table.concat( self.content ) }
|
||||
return #self.content[ 1 ]
|
||||
end,
|
||||
getcontent = function( self )
|
||||
self.content = { table.concat( self.content ) }
|
||||
return self.content[ 1 ]
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
local function list_cmd( args )
|
||||
local map = loadtmx( args[ 1 ] )
|
||||
local map = tmx.load( args[ 1 ] )
|
||||
local layers = false
|
||||
local tilesets = false
|
||||
|
||||
@ -389,7 +74,7 @@ local function list_cmd( args )
|
||||
end
|
||||
|
||||
local function render_cmd( args )
|
||||
local map = loadtmx( args[ 1 ] )
|
||||
local map = tmx.load( args[ 1 ] )
|
||||
local layers = {}
|
||||
|
||||
for i = 3, #args do
|
||||
@ -403,11 +88,11 @@ local function render_cmd( args )
|
||||
end
|
||||
|
||||
local dir, name, ext = path.split( args[ 1 ] )
|
||||
render( map, layers ):save( dir .. path.separator .. name .. '.png' )
|
||||
tmx.render( map, layers ):save( dir .. path.separator .. name .. '.png' )
|
||||
end
|
||||
|
||||
local function compile_cmd( args )
|
||||
local map = loadtmx( args[ 1 ] )
|
||||
local map = tmx.load( args[ 1 ] )
|
||||
local layers = {}
|
||||
local coll, limit
|
||||
|
||||
@ -515,18 +200,18 @@ local function compile_cmd( args )
|
||||
|
||||
-- rl_tileset_t
|
||||
do
|
||||
local out = newwriter()
|
||||
local out = writer()
|
||||
|
||||
out:writeu16( map.tilewidth )
|
||||
out:writeu16( map.tileheight )
|
||||
out:writeu16( #built.tiles )
|
||||
out:add16( map.tilewidth )
|
||||
out:add16( map.tileheight )
|
||||
out:add16( #built.tiles )
|
||||
|
||||
for _, tile in ipairs( built.tiles ) do
|
||||
for y = 0, map.tileheight - 1 do
|
||||
for x = 0, map.tilewidth - 1 do
|
||||
local r, g, b = image.split( tile:getPixel( x, y ) )
|
||||
r, g, b = r * 31 // 255, g * 63 // 255, b * 31 // 255
|
||||
out:writeu16( ( r << 11 ) | ( g << 5 ) | b )
|
||||
out:add16( ( r << 11 ) | ( g << 5 ) | b )
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -536,14 +221,14 @@ local function compile_cmd( args )
|
||||
|
||||
-- rl_imageset_t
|
||||
do
|
||||
local out = newwriter()
|
||||
local out = writer()
|
||||
|
||||
out:writeu16( #built.images )
|
||||
out:add16( #built.images )
|
||||
|
||||
for _, image in ipairs( built.images ) do
|
||||
local rle = rleimage( image, limit ):get()
|
||||
out:writeu32( #rle )
|
||||
out:append( rle )
|
||||
local res = mkrle( image, limit )
|
||||
out:add32( res:getsize() )
|
||||
out:addwriter( res )
|
||||
end
|
||||
|
||||
out:save( filename .. '.ims' )
|
||||
@ -551,22 +236,22 @@ local function compile_cmd( args )
|
||||
|
||||
-- rl_map_t
|
||||
do
|
||||
local out = newwriter()
|
||||
local out = writer()
|
||||
|
||||
out:writeu16( map.width )
|
||||
out:writeu16( map.height )
|
||||
out:writeu16( 1 + #built.layers ) -- layer count
|
||||
out:add16( map.width )
|
||||
out:add16( map.height )
|
||||
out:add16( 1 + #built.layers ) -- layer count
|
||||
|
||||
-- map flags
|
||||
local flags = 0
|
||||
flags = flags | ( coll and 1 or 0 ) -- has collision bits
|
||||
|
||||
out:writeu16( flags )
|
||||
out:add16( flags )
|
||||
|
||||
-- rl_layer0
|
||||
for y = 1, map.height do
|
||||
for x = 1, map.width do
|
||||
out:writeu16( built.layer0[ y ][ x ] )
|
||||
out:add16( built.layer0[ y ][ x ] )
|
||||
end
|
||||
end
|
||||
|
||||
@ -574,7 +259,7 @@ local function compile_cmd( args )
|
||||
for _, layer in ipairs( built.layers ) do
|
||||
for y = 1, map.height do
|
||||
for x = 1, map.width do
|
||||
out:writeu16( layer[ y ][ x ] )
|
||||
out:add16( layer[ y ][ x ] )
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -597,7 +282,7 @@ local function compile_cmd( args )
|
||||
end
|
||||
|
||||
if bit == 0x80000000 then
|
||||
out:writeu32( bits )
|
||||
out:add32( bits )
|
||||
bits, bit = 0, 1
|
||||
else
|
||||
bit = bit << 1
|
||||
@ -606,7 +291,7 @@ local function compile_cmd( args )
|
||||
end
|
||||
|
||||
if bit ~= 1 then
|
||||
out:writeu32( bits )
|
||||
out:add32( bits )
|
||||
end
|
||||
end
|
||||
|
||||
@ -660,12 +345,6 @@ Commands:
|
||||
return 0
|
||||
end
|
||||
|
||||
do
|
||||
local dir, _, _ = path.split( args[ 0 ] )
|
||||
local ok
|
||||
ok, rleimage = loadfile( dir .. path.separator .. 'rlrle.lua' )()
|
||||
end
|
||||
|
||||
args[ 1 ] = path.realpath( args[ 1 ] )
|
||||
|
||||
local commands = {
|
||||
|
104
etc/rlpack.lua
104
etc/rlpack.lua
@ -1,77 +1,13 @@
|
||||
local function djb2( str )
|
||||
local hash = 5381
|
||||
|
||||
for i = 1, #str do
|
||||
hash = hash * 33 + str:byte( i )
|
||||
hash = hash & 0xffffffff
|
||||
end
|
||||
|
||||
return hash
|
||||
end
|
||||
local djb2 = require 'djb2'
|
||||
local writer = require 'writer'
|
||||
|
||||
local function filesize( path )
|
||||
local file, err = io.open( path, 'rb' )
|
||||
|
||||
if not file then
|
||||
error( err )
|
||||
end
|
||||
|
||||
local size, err = file:seek( 'end' )
|
||||
|
||||
if not size then
|
||||
file:close()
|
||||
error( err )
|
||||
end
|
||||
|
||||
local file = assert( io.open( path, 'rb' ) )
|
||||
local size = assert( file:seek( 'end' ) )
|
||||
file:close()
|
||||
return size
|
||||
end
|
||||
|
||||
local function newwriter()
|
||||
return {
|
||||
bytes = {},
|
||||
write8 = function( self, x )
|
||||
self.bytes[ #self.bytes + 1 ] = string.char( x & 255 )
|
||||
end,
|
||||
write16 = function( self, x )
|
||||
self.bytes[ #self.bytes + 1 ] = string.char( ( x >> 8 ) & 255, x & 255 )
|
||||
end,
|
||||
write32 = function( self, x )
|
||||
self.bytes[ #self.bytes + 1 ] = string.char( ( x >> 24 ) & 255, ( x >> 16 ) & 255, ( x >> 8 ) & 255, x & 255 )
|
||||
end,
|
||||
writestr = function( self, str )
|
||||
self.bytes[ #self.bytes + 1 ] = str
|
||||
end,
|
||||
append = function( self, rle )
|
||||
self.bytes[ #self.bytes + 1 ] = table.concat( rle.bytes )
|
||||
end,
|
||||
align = function( self, x )
|
||||
local size = self:size()
|
||||
local new_size = ( size + x - 1 ) & -x
|
||||
|
||||
while size < new_size do
|
||||
self:write8( 0 )
|
||||
size = size + 1
|
||||
end
|
||||
end,
|
||||
get = function( self )
|
||||
self.bytes = { table.concat( self.bytes ) }
|
||||
return self.bytes[ 1 ]
|
||||
end,
|
||||
size = function( self )
|
||||
self.bytes = { table.concat( self.bytes ) }
|
||||
return #self.bytes[ 1 ]
|
||||
end,
|
||||
save = function( self, name )
|
||||
local file, err = io.open( name, 'wb' )
|
||||
if not file then error( err ) end
|
||||
self.bytes = { table.concat( self.bytes ) }
|
||||
file:write( self.bytes[ 1 ] )
|
||||
file:close()
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
return function( args )
|
||||
if #args < 2 then
|
||||
io.write[[
|
||||
@ -164,33 +100,33 @@ Usage: luai rlpack.lua cuts <filename.pak> files...
|
||||
end
|
||||
end
|
||||
|
||||
local out = newwriter()
|
||||
out:write32( num_entries )
|
||||
out:write32( 0 )
|
||||
local out = writer()
|
||||
out:add32( num_entries )
|
||||
out:add32( 0 )
|
||||
|
||||
for i = 0, num_entries - 1 do
|
||||
if map[ i ] then
|
||||
local entry = map[ i ]
|
||||
|
||||
out:write32( entry.name_hash )
|
||||
out:write32( entry.name_offset )
|
||||
out:write32( entry.data_offset )
|
||||
out:write32( entry.data_size )
|
||||
out:write32( 0 )
|
||||
out:add32( entry.name_hash )
|
||||
out:add32( entry.name_offset )
|
||||
out:add32( entry.data_offset )
|
||||
out:add32( entry.data_size )
|
||||
out:add32( 0 )
|
||||
else
|
||||
out:write32( 0 )
|
||||
out:write32( 0 )
|
||||
out:write32( 0 )
|
||||
out:write32( 0 )
|
||||
out:write32( 0 )
|
||||
out:add32( 0 )
|
||||
out:add32( 0 )
|
||||
out:add32( 0 )
|
||||
out:add32( 0 )
|
||||
out:add32( 0 )
|
||||
end
|
||||
end
|
||||
|
||||
for i = 0, num_entries - 1 do
|
||||
if map[ i ] then
|
||||
out:align( 4 )
|
||||
out:writestr( map[ i ].name )
|
||||
out:write8( 0 )
|
||||
out:addstring( map[ i ].name )
|
||||
out:add8( 0 )
|
||||
end
|
||||
end
|
||||
|
||||
@ -206,7 +142,7 @@ Usage: luai rlpack.lua cuts <filename.pak> files...
|
||||
file:close()
|
||||
|
||||
out:align( 16 )
|
||||
out:writestr( all )
|
||||
out:addstring( all )
|
||||
end
|
||||
end
|
||||
|
||||
|
167
etc/rlrle.lua
167
etc/rlrle.lua
@ -1,160 +1,9 @@
|
||||
local image = require 'image'
|
||||
local path = require 'path'
|
||||
local image = require 'image'
|
||||
local path = require 'path'
|
||||
local rgbto16 = require 'rgbto16'
|
||||
local mkrle = require 'mkrle'
|
||||
|
||||
local function newwriter()
|
||||
return {
|
||||
bytes = {},
|
||||
write8 = function( self, x )
|
||||
self.bytes[ #self.bytes + 1 ] = string.char( x & 255 )
|
||||
end,
|
||||
write16 = function( self, x )
|
||||
self.bytes[ #self.bytes + 1 ] = string.char( ( x >> 8 ) & 255, x & 255 )
|
||||
end,
|
||||
write32 = function( self, x )
|
||||
self.bytes[ #self.bytes + 1 ] = string.char( ( x >> 24 ) & 255, ( x >> 16 ) & 255, ( x >> 8 ) & 255, x & 255 )
|
||||
end,
|
||||
append = function( self, rle )
|
||||
self.bytes[ #self.bytes + 1 ] = table.concat( rle.bytes )
|
||||
end,
|
||||
get = function( self )
|
||||
self.bytes = { table.concat( self.bytes ) }
|
||||
return self.bytes[ 1 ]
|
||||
end,
|
||||
size = function( self )
|
||||
self.bytes = { table.concat( self.bytes ) }
|
||||
return #self.bytes[ 1 ]
|
||||
end,
|
||||
save = function( self, name )
|
||||
local file, err = io.open( name, 'wb' )
|
||||
if not file then error( err ) end
|
||||
self.bytes = { table.concat( self.bytes ) }
|
||||
file:write( self.bytes[ 1 ] )
|
||||
file:close()
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
local function rgbto16( r, g, b )
|
||||
r = r * 31 // 255
|
||||
g = g * 63 // 255
|
||||
b = b * 31 // 255
|
||||
|
||||
return ( r << 11 ) | ( g << 5 ) | b
|
||||
end
|
||||
|
||||
local function getpixel( png, x, y, transp )
|
||||
local r, g, b, a = image.split( png:getPixel( x, y ) )
|
||||
local c = rgbto16( r, g, b )
|
||||
|
||||
if c == transp then
|
||||
r, g, b, a = 0, 0, 0, 0
|
||||
end
|
||||
|
||||
if a >= 0 and a <= 31 then
|
||||
a = 0 -- transparent
|
||||
elseif a >= 32 and a <= 95 then
|
||||
a = 1 -- 25%
|
||||
elseif a >= 96 and a <= 159 then
|
||||
a = 2 -- 50%
|
||||
elseif a >= 160 and a <= 223 then
|
||||
a = 3 -- 75%
|
||||
else
|
||||
a = 4 -- opaque
|
||||
end
|
||||
|
||||
return rgbto16( r, g, b ), a
|
||||
end
|
||||
|
||||
local function rlerow( png, y, limit, transp )
|
||||
local rle = {}
|
||||
local width = png:getWidth()
|
||||
local used = 0
|
||||
|
||||
local numcols = ( width + ( limit - 1 ) ) // limit
|
||||
|
||||
for i = 1, numcols do
|
||||
rle[ #rle + 1 ] = 0
|
||||
end
|
||||
|
||||
for xx = 0, width - 1, limit do
|
||||
rle[ xx // limit + 1 ] = #rle
|
||||
|
||||
local x = xx
|
||||
rle[ #rle + 1 ] = 0
|
||||
local runs = #rle
|
||||
|
||||
while x < ( xx + limit ) and x < width do
|
||||
local _, a = getpixel( png, x, y, transp )
|
||||
local count = 0
|
||||
local xsave = x
|
||||
|
||||
while x < ( xx + limit ) and x < width do
|
||||
local c, aa = getpixel( png, x, y, transp )
|
||||
|
||||
if aa ~= a then
|
||||
break
|
||||
end
|
||||
|
||||
count = count + 1
|
||||
x = x + 1
|
||||
end
|
||||
|
||||
rle[ #rle + 1 ] = ( a << 13 | count )
|
||||
rle[ runs ] = rle[ runs ] + 1
|
||||
|
||||
if a ~= 0 then
|
||||
for i = 0, count - 1 do
|
||||
local c = getpixel( png, xsave + i, y, transp )
|
||||
rle[ #rle + 1 ] = c
|
||||
used = used + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local final = newwriter()
|
||||
|
||||
for i = 1, #rle do
|
||||
final:write16( rle[ i ] )
|
||||
end
|
||||
|
||||
return final, used
|
||||
end
|
||||
|
||||
local function rleimage( png, limit, transp )
|
||||
local width, height = png:getSize()
|
||||
local rows = {}
|
||||
local used = 0
|
||||
|
||||
limit = limit or 1e10
|
||||
|
||||
for y = 0, height - 1 do
|
||||
local row, u = rlerow( png, y, limit, transp )
|
||||
rows[ y ] = row
|
||||
used = used + u
|
||||
end
|
||||
|
||||
local rle = newwriter()
|
||||
|
||||
rle:write16( width )
|
||||
rle:write16( height )
|
||||
rle:write32( used )
|
||||
|
||||
local count = 0
|
||||
|
||||
for y = 0, height - 1 do
|
||||
rle:write32( count )
|
||||
count = count + rows[ y ]:size()
|
||||
end
|
||||
|
||||
for y = 0, height - 1 do
|
||||
rle:append( rows[ y ] )
|
||||
end
|
||||
|
||||
return rle
|
||||
end
|
||||
|
||||
local function main( args )
|
||||
return function( args )
|
||||
if #args == 0 then
|
||||
io.write[[
|
||||
RLE-encodes an image to a format ready to be used with rl_image_create. The
|
||||
@ -207,10 +56,8 @@ Usage: luai rlrle.lua [ options ] <image>
|
||||
transp = rgbto16( image.split( png:getPixel( png:getWidth() - 1, png:getHeight() - 1 ) ) )
|
||||
end
|
||||
|
||||
local rle = rleimage( png, limit, transp )
|
||||
local res = mkrle( png, limit, transp )
|
||||
local dir, name, ext = path.split( name )
|
||||
rle:save( dir .. path.separator .. name .. '.rle' )
|
||||
res:save( dir .. path.separator .. name .. '.rle' )
|
||||
return 0
|
||||
end
|
||||
|
||||
return main, rleimage
|
||||
|
@ -1,13 +1,6 @@
|
||||
local image = require 'image'
|
||||
local path = require 'path'
|
||||
|
||||
local function rgbto16( r, g, b )
|
||||
r = r * 31 // 255
|
||||
g = g * 63 // 255
|
||||
b = b * 31 // 255
|
||||
|
||||
return ( r << 11 ) | ( g << 5 ) | b
|
||||
end
|
||||
local image = require 'image'
|
||||
local path = require 'path'
|
||||
local rgbto16 = require 'rgbto16'
|
||||
|
||||
return function( args )
|
||||
if #args == 0 then
|
||||
@ -41,9 +34,7 @@ Usage: luai rltile.lua <image>
|
||||
end
|
||||
|
||||
local dir, name, ext = path.split( name )
|
||||
local file, err = io.open( dir .. path.separator .. name .. '.h', 'w' )
|
||||
if not file then error( err ) end
|
||||
|
||||
local file = assert( io.open( dir .. path.separator .. name .. '.h', 'w' ) )
|
||||
local array = string.gsub( name .. ext, '[^a-zA-Z0-9_]', '_' )
|
||||
|
||||
file:write( 'const uint16_t ', array, '[] = {\n' )
|
||||
|
@ -1,67 +1,7 @@
|
||||
local image = require 'image'
|
||||
local path = require 'path'
|
||||
local mkts = require 'mkts'
|
||||
|
||||
local function newwriter()
|
||||
return {
|
||||
bytes = {},
|
||||
write8 = function( self, x )
|
||||
self.bytes[ #self.bytes + 1 ] = string.char( x & 255 )
|
||||
end,
|
||||
write16 = function( self, x )
|
||||
self.bytes[ #self.bytes + 1 ] = string.char( ( x >> 8 ) & 255, x & 255 )
|
||||
end,
|
||||
write32 = function( self, x )
|
||||
self.bytes[ #self.bytes + 1 ] = string.char( ( x >> 24 ) & 255, ( x >> 16 ) & 255, ( x >> 8 ) & 255, x & 255 )
|
||||
end,
|
||||
append = function( self, rle )
|
||||
self.bytes[ #self.bytes + 1 ] = table.concat( rle.bytes )
|
||||
end,
|
||||
size = function( self )
|
||||
self.bytes = { table.concat( self.bytes ) }
|
||||
return #self.bytes[ 1 ]
|
||||
end,
|
||||
save = function( self, name )
|
||||
local file, err = io.open( name, 'wb' )
|
||||
if not file then error( err ) end
|
||||
self.bytes = { table.concat( self.bytes ) }
|
||||
file:write( self.bytes[ 1 ] )
|
||||
file:close()
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
local function rgbto16( r, g, b )
|
||||
r = r * 31 // 255
|
||||
g = g * 63 // 255
|
||||
b = b * 31 // 255
|
||||
|
||||
return ( r << 11 ) | ( g << 5 ) | b
|
||||
end
|
||||
|
||||
local function getpixel( png, x, y )
|
||||
local r, g, b = image.split( png:getPixel( x, y ) )
|
||||
return rgbto16( r, g, b )
|
||||
end
|
||||
|
||||
local function mktileset( images )
|
||||
local writer = newwriter()
|
||||
|
||||
writer:write16( images[ 1 ]:getWidth() )
|
||||
writer:write16( images[ 1 ]:getHeight() )
|
||||
writer:write16( #images )
|
||||
|
||||
for _, img in pairs( images ) do
|
||||
for y = 0, img:getHeight() - 1 do
|
||||
for x = 0, img:getWidth() - 1 do
|
||||
writer:write16( getpixel( img, x, y ) )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return writer
|
||||
end
|
||||
|
||||
local function main( args )
|
||||
return function( args )
|
||||
if #args == 0 then
|
||||
io.write[[
|
||||
rltileset.lua reads all images in the given directory and writes tileset data
|
||||
@ -119,19 +59,17 @@ Usage: luai rltileset.lua [ options ] <directory>
|
||||
end
|
||||
|
||||
if #images ~= 0 then
|
||||
local writer = mktileset( images )
|
||||
local out = mkts( images )
|
||||
|
||||
if not output then
|
||||
local dir, name, ext = path.split( dir )
|
||||
output = dir .. path.separator .. name .. '.tls'
|
||||
end
|
||||
|
||||
writer:save( output )
|
||||
out:save( output )
|
||||
else
|
||||
io.write( 'no images were found\n' )
|
||||
end
|
||||
|
||||
return 0
|
||||
end
|
||||
|
||||
return main, mktileset
|
||||
|
Loading…
x
Reference in New Issue
Block a user