Skip to content

Instantly share code, notes, and snippets.

@JettMonstersGoBoom
Created December 2, 2020 00:19
Show Gist options
  • Save JettMonstersGoBoom/ec1585912743cca5053424a528b84bd9 to your computer and use it in GitHub Desktop.
Save JettMonstersGoBoom/ec1585912743cca5053424a528b84bd9 to your computer and use it in GitHub Desktop.
Asesprite script to export chars from the current frame ( removing duplicates )
local byte = string.char
local binfile = nil
local map = {}
local images = { }
local output_message = ""
local errors = 0
--
-- seperate platform from code
--
local C64 = {
luminance = {0x0,0xf,0x3,0xb,0x5,0x9,0x1,0xd,0x6,0x2,0xa,0x4,0x8,0xe,0x7,0xc,0xff}
}
function C64:Export(tile)
if #tile.colors<=4 then
-- sort the colors table by brightness
-- this seems to be quite nice
table.sort(tile.colors, function(a, b) return C64.luminance[1+(a&0xf)] < C64.luminance[1+(b&0xf)] end)
for y=0,7 do
-- clear the byte we write
c = 0
-- for the bits we scan every 2 pixels ( MC mode )
-- we assume odd pixels are the same and don't care
for xp = 0, 7, 2 do
-- get the pixel from the tile data
px = tile.pixels[1+((y*8) + xp)]
-- double check for nil
if px==nil then
px = 0
end
-- output color is an index between 0-#ncolors
local oc = 0
-- check the colors array for this color to find it's index
for ci = 1, #tile.colors do
if tile.colors[ci] == px then
oc = ci-1
break
end
end
-- output the color 0-3 into the byte for this line
c = c | ( oc << (6-xp))
end
-- write the byte out
io.write(byte(c))
end
else
-- kinda raster bar for chars with too many colors
errors = errors + 1
io.write(byte(0x00))
io.write(byte(0x55))
io.write(byte(0xaa))
io.write(byte(0xff))
io.write(byte(0xff))
io.write(byte(0xaa))
io.write(byte(0x55))
io.write(byte(0x00))
end
end
-- We create a string for each char for comparison later
-- note this is the raw 8bpp tile
local function getTileData(img, x, y ,tw , th)
local res = {}
res.pixels = {}
res.colors = {}
res.string = ""
table.insert(res.colors,0)
for cy = 0, th-1 do
for cx = 0, tw-1 do
-- get the pixel
px = img:getPixel(cx+x, cy+y)
-- store it in the string for comparison
res.string = res.string .. string.format("%02x",px)
-- mask only the bottom 4 bits
px = px & 0xf
-- check the colors for this tile
local found = -1
for i,v in ipairs(res.colors) do
if px==v then
found = i
break
end
end
-- if we didn't find that color, insert it
if found==-1 then
table.insert(res.colors,px)
found = #res.colors
end
-- insert the pixel itself
table.insert(res.pixels,px)
end
end
-- check for repeated tiles
for i,v in ipairs(images) do
if res.string==v.string then
return i -- Return the existent tile index that matches the "newTileImg"
end
end
-- we add it and return the index of it.
table.insert(images, res)
return #images
end
local function EncodeMap(input,tw,th)
local sprite = input.sprite
local img = Image(sprite.spec)
output_message = output_message .. " map " .. (img.width//8) .. " " .. (img.height//8)
img:drawSprite(sprite, input)
-- collect the tiles this frame
for y = 0, img.height-1, tw do
for x = 0, img.width-1, th do
local data = getTileData(img, x, y , tw, th)
table.insert(map,data)
end
end
end
local dlg = Dialog("Tiled Data")
dlg:file{ id="exportChars",
label="Chars",
title="C64 Char Export",
open=false,
save=true,
filename="chars.bin",
filetypes={"bin"}}
dlg:file{ id="exportMap",
label="Map",
title="C64 Map Export",
open=false,
save=true,
filename="map.bin",
filetypes={"bin"}}
--[[
dlg:combobox{ id="TileFormat",
label="TileFormat",
option="C64",
options={ "C64","8BPP"} }
]]--
dlg:button{ id="ok", text="OK" }
dlg:show()
local data = dlg.data
if data.ok then
-- ok was pressed
EncodeMap(app.activeFrame,8,8)
binfile = io.open(data.exportChars, "wb")
io.output(binfile)
for key,tile in pairs(images) do
C64:Export(tile)
end
io.close(binfile)
output_message = output_message .. " tiles " .. #images
-- for now no metatiles
binfile = io.open(data.exportMap, "wb")
io.output(binfile)
for k,v in pairs(map) do
io.write(byte(v-1))
end
io.close(binfile)
if errors~=0 then
output_message = output_message .. " Errors " .. errors
end
app.alert(output_message)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment