Skip to content

Instantly share code, notes, and snippets.

@arachonteur
Created March 16, 2019 16:09
Show Gist options
  • Save arachonteur/334bfcfa7dfe7265ddbe089e4a51e522 to your computer and use it in GitHub Desktop.
Save arachonteur/334bfcfa7dfe7265ddbe089e4a51e522 to your computer and use it in GitHub Desktop.
A lightweight REXPaint .xp file reader for LOVE2D.
--
-- A lightweight REXPaint .xp reader for LOVE2D.
-- By Vriska Serket / @arachonteur
--
-- Output table looks like this.
--[[
{
version = 0,
layerCount = 0,
layers = {
[1] = {
width = 20,
height = 20,
index = 1,
cells = {
[1] = {
x = 0,
y = 0,
char = 0,
fg = {255, 255, 255},
bg = {0, 0, 0}
},
[...]
}
},
[...]
}
}
]]
--
--
local exp = {
version_bytes = 4,
layer_count_bytes = 4,
layer_width_bytes = 4,
layer_height_bytes = 4,
layer_keycode_bytes = 4,
layer_fore_rgb_bytes = 3,
layer_back_rgb_bytes = 3,
transparent = {
r = 255,
g = 0,
b = 255
}
}
exp.layer_cell_bytes = exp.layer_keycode_bytes + exp.layer_fore_rgb_bytes + exp.layer_back_rgb_bytes
function exp:read(file)
if love.filesystem.exists(file) then
self.file = love.filesystem.read(file)
else
error(string.format("REXPaint Reader: File %s does not exist.", file))
end
self.fileString = love.math.decompress(self.file, "gzip")
local xp = {
version = 0,
layerCount = 0,
layers = {}
}
local offset = 0
local version = {self.fileString:byte(offset, self.version_bytes)}
offset = offset + self.version_bytes + 1
local layer_count = {self.fileString:byte(offset, offset + self.layer_count_bytes)}
offset = offset + self.layer_count_bytes
xp.version = version
xp.layerCount = layer_count[1]
for i = 1, layer_count[1] do
local layerWidth = {self.fileString:byte(offset, offset + self.layer_width_bytes)}
offset = offset + self.layer_width_bytes
local layerHeight = {self.fileString:byte(offset, offset + self.layer_height_bytes)}
offset = offset + self.layer_height_bytes
local layerSize = self.layer_cell_bytes * layerWidth[1] * layerHeight[1]
local layer = {
index = i,
width = layerWidth[1],
height = layerHeight[1],
cells = {}
}
for j = 1, layerWidth[1] * layerHeight[1] do
local cell = {
x = 0,
y = 0,
char = 0,
fg = {
r = 255,
g = 255,
b = 255
},
bg = {
r = 255,
g = 255,
b = 255
}
}
cell.y = j % layer.height
cell.x = (j - cell.y) / layer.height
local tempOffset = offset
local keycode = {self.fileString:byte(tempOffset, tempOffset + self.layer_keycode_bytes - 1)}
cell.char = string.char(keycode[1])
tempOffset = tempOffset + self.layer_keycode_bytes
local fg = {self.fileString:byte(tempOffset, tempOffset + self.layer_fore_rgb_bytes - 1)}
cell.fg = fg
tempOffset = tempOffset + self.layer_fore_rgb_bytes
local bg = {self.fileString:byte(tempOffset, tempOffset + self.layer_back_rgb_bytes - 1)}
cell.bg = bg
tempOffset = tempOffset + self.layer_back_rgb_bytes
offset = tempOffset
table.insert(layer.cells, cell)
end
table.insert(xp.layers, layer)
end
return xp
end
return exp
@stanles75
Copy link

Howdy @vriska-serket,

I found your script from a listing on the RexPaint site. It has really come in handy! I'm using in LÖVE 11.3 and I noticed some deprecation warnings for love.filesystem.exists() on line 54 and love.math.decompress() on line 60 when launching my game. I replaced them with love.filesystem.getInfo() and love.data.decompress() (the signature changed slightly) respectively and that seemed to make those messages go away. But hey, I can handle those kinds of changes. I can't imagine having to start from scratch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment