commit e5a431066d05cdbffa41e789ebf4a91119d69682 Author: shoofle Date: Thu Jan 2 22:59:10 2025 -0500 first commit diff --git a/gb-export.lua b/gb-export.lua new file mode 100644 index 0000000..005e6fe --- /dev/null +++ b/gb-export.lua @@ -0,0 +1,434 @@ +-- ASEPRITE tileset and tilemap C exporter for use with GBDK -- version 0.3 + --SEPTEMBER/2022-- + + +--DISCLAIMER-- +-- I'm an amateur programer, so the code may not be as optimal as it could be +-- also, some notes may seem over explained, but they are for me to understand and remember what everything does. + +--helpeful resources : + --https://eldred.fr/gb-asm-tutorial/part1/tiles.html + --https://youtu.be/txkHN6izK2Y?t=344 + + -- Big Thanks to Aseprite community, specifically: + -- Jeremy Behreandt, whose tutorial helped get started on the script + -- + -- boombuler, for his version of the plugin, (found here : https://github.com/boombuler/aseprite-gbexport) + -- that helped a lot during debugging, and figuring out how to output the tiles + + -- ONLY WORKS WITH A SINGLE TILEMAP LAYER + + +-- revised by shoofle around new years 2024/2025. this should export just the selection and just the currently active layer. +-- select an area to export just that. +-- exports to assembly as well. +-- + +local sprt = app.activeSprite +local layer = app.activeLayer +local selection = sprt.selection +local tile_layers ={} +local n_layer = 0 +local file_format = "" + +local filepath = sprt.filename + +local plt = sprt.palettes[1] -- DEFINES THE PALETTE + +local tile_amount = 0 +local tile_offset = 0 + +local folder = string.find(filepath,"[^/]+$") -1 +filepath = string.sub(filepath,1,folder) + +local tile_name = "" +local map_name = "" +local do_set = false -- EXPORT TILESET +local do_map = false -- EXPORT TILEMAP + +local w = 0 -- MAP WIDTH +local h = 0 -- MAP HEIGHT + +-- INITIAL CHECKS FOR VALID FILE -- + +if sprt == nil then --CHECKS IF THERE'S AN IMAGE LOADED + app.alert{ + title = "MAJOR ERROR", + text = "THERE'S NO FILE OPEN", + buttons = "Oh crap" + } + return +end + +for i,current_layer in ipairs(sprt.layers) do + if current_layer.isTilemap then + tile_layers[n_layer] = current_layer + n_layer = n_layer+1 + end +end + +if n_layer == 0 then + app.alert{ + title = "ERROR", + text = "There is no Tilemap Layer" + } + return +end + +if ColorMode.TILEMAP == nil then --CHECKS FOR TILEMAP + app.alert{ + title = "ERROR", + text = "This file does not make use of tilemaps" + } + return +end + + +if sprt.height % 8 ~= 0 or sprt.width%8 ~= 0 then --CHECKS FOR IMAGE DIMENSIONS, GAMEBOY USES 8X8 TILES, FOR THE IMAGE MUST BE A MULTIPLE + app.alert { + title = "ERROR", + text = "Canvas width or height is not multiple of 8.", + buttons = "OK" + } + return +end + +if (layer.tileset.grid.tileSize.width ~= 8 or layer.tileset.grid.tileSize.height ~= 8) then + app.alert { + title = "ERROR", + text = "Tile Size is not 8x8 px", + buttons = "OK" + } + return +end + +if sprt.colorMode ~= ColorMode.INDEXED then --CHECKS IF THE COLOR MODE IS SET TO INDEXED + app.alert{ + title = "ERROR", + text = {" Color Mode must be", "INDEXED", "and have only 4 colors"}, + buttons = "Oh, my bad" + } + return +elseif #plt ~= 4 then -- IF IT IS INDEXED, CHECKS IF IT DOES HAVE 4 COLORS + app.alert{ + title = "ERROR", + text = "Number of colors MUST BE 4", + buttont = "Oops" + } + return +end + + +--INITIAL CHECKS DONE-- + +--USER INPUT-- + +local dlg = Dialog {title = "GB TILE EXPORTER"} + +dlg:label{ + id = "label-01", + text = "Pick a location to save the file." +} +dlg:newrow() + +dlg:label{ + id = "label-02", + text = "Only the folder will be used." +} +dlg:file{ + id = "filepath", + label = "Save Location", + save = true, +} + +local tileset_name_prompt = "tileset" +if layer.tileset.name ~= "" then + tileset_name_prompt = layer.tileset.name:gsub(" ", "") +end +dlg:entry{ + id="tilename", + label = "Tileset Name", + text = tileset_name_prompt +} + +local tilemap_name_prompt = "tilemap" +if layer.name ~= "" then + tilemap_name_prompt = layer.name:gsub(" ", "") +end +dlg:entry{ + id = "mapname", + label = "Map Name", + text = tilemap_name_prompt +} + +dlg:entry { + id = "tile_offset", + label = "Tile Index Start", + text = "0" +} + +dlg:combobox{ + id = "fileformat", + label = "File Format", + option = "ASM", + options = {"C", "ASM"} -- FOR FUTURE SUPPORT OF DIFFERENTE TYPES, LIKE ASM MAYBE +} +dlg:newrow() + +dlg:check{ + id = "checkTileset", + text = "Export Tileset", + selected = true, + -- bounds = Rectangle() +} +dlg:check{ + id = "checkTilemap", + text = "Export Tilemap", + selected = true +} +-- NEEDS FILE PATH TO EXPORT +-- NAME FOR TILESET +-- NAME FOR TILEMAP +-- CHECK BOX FOR TILESET(EXPORT TILESET) +-- CHECK BOX FOR TILEMAP(EXPORT TILEMAP) + +dlg:button{ + id="confirm", + text="OK" +} +dlg:button{ + id="cancel", + text="Cancel" +} + + +dlg:show{wait=true} + +--FUNCTIONS ARE DECLARED HERE-- + +local dlg_data = dlg.data -- SAVES USER INPUT + +local function tile_to_hex(tile) -- + + -- ****HOW TO GAMEBOY WORKS WITH 2BITS PER PIXEL (2BPP)****-- + + -- EACH PIXEL IS A SET OF TWO DIGITS (BITS) SO WE TAKE A ROW AS A FULL BYTE + -- SEPARATES THE NUMBER(BINARY) INTO PAIRS OF DIGITS + -- THE PAIRS ARE THEM SEPARATED INTO "HIGH BITE" (LEFT) AND "LOW BITE" (RIGHT) + -- THEM YOU JOIN THE HIGHS AND THE LOWS, AND END UP WITH TWO BYTES (8 DIGITS EACH) + -- THEN YOU PUT THE LOW BYTES FIRST AND THE HIGHS SECOND + + local hex = {} + local range_x = tile.width-1 + local range_y = tile.height-1 + for y = 0, range_y do --LOOPS Y AXIS + local lo_bit = 0; --resets the low bit per each y value (for each row) + local hi_bit = 0; -- resets the high bit per each y value (for each row) + for x = 0, range_x do -- LOOPS X AXIS + local pixel = tile:getPixel(x,y) + if (pixel & 1) ~= 0 then -- 1 IN BINARY = 01 + lo_bit = lo_bit | (1 << range_x-x) -- THE OPERATOR (1<< n-0) would be invalid, so we add (lo_bit |) + end + + if (pixel & 2) ~= 0 then -- 2 IN BINARY == 10 + hi_bit = hi_bit | (1 << range_x-x) + end + -- WAS USING AND INSTEAD OF & AND APARENTLY THAT WAS MESSING UP THE CODE, THANKS AGAIN TO boombuler FOR HIS CODE (LIFE SAVING) + end + table.insert(hex, string.format("%02x", lo_bit)) + table.insert(hex, string.format("%02x", hi_bit)) + end + + return hex -- returns a list of hex values for this tile ; + +end + +local function generate_tileset(tileset) + local t = {} + local grid = tileset.grid + local size = grid.tileSize + tile_amount = #tileset + + for i = 0, #tileset-1 do + local tile = tileset:getTile(i) + local hex = tile_to_hex(tile) + -- t[i] = tile_to_hex(tile) + -- print(hex) + table.insert(t,hex) + + end + + return t + +end + +local function generate_tilemap() + local sprite = app.sprite + local cel = app.cel + local image = cel.image + local layer = app.layer + local grid_size = layer.tileset.grid.tileSize + + --print("cel: " .. cel.bounds.x .. ',' .. cel.bounds.y .. " " .. cel.bounds.width .. "x" .. cel.bounds.height) + --print("sprite: " ..sprite.width .. 'x' .. sprite.height) + --print(image:getPixel(100,100)) + + local xi = 0 + local yi = 0 + local w = sprite.width + local h = sprite.height + + if (not selection.isEmpty) then + xi = selection.bounds.origin.x + yi = selection.bounds.origin.y + w = selection.bounds.width + h = selection.bounds.height + end + + local map = {} + for y = (yi / grid_size.height) - (cel.bounds.y / grid_size.height) , + (yi / grid_size.height) - (cel.bounds.y / grid_size.height) + (h / grid_size.height)-1 do + local line = {} + for x = (xi / grid_size.width) - (cel.bounds.x / grid_size.width), + (xi / grid_size.width) - (cel.bounds.x / grid_size.width) + (w / grid_size.width)-1 do + local value = image:getPixel(x, y) + if value == 0xffffffff then + value = 0 + end + table.insert(line, value) + end + table.insert(map, line) + end + + return map + + +end + + +local function save_to_file(name, contents) + --TODO: FIX IMPLEMENTATION OF THE SAVE TO FILE FUNTION TO INCLUDE DESIRED FOLDER + local file = io.open(name,"w") + file:write(contents) + file:close() +end + + +local function parse_input() + tile_name = dlg_data.tilename + map_name = dlg_data.mapname + if (dlg_data.filepath ~= "") then + filepath = dlg_data.filepath + folder = string.find(filepath,"[^/]+$") -1 + filepath = string.sub(filepath,1,folder) + + print(filepath) + end + do_set = dlg_data.checkTileset + do_map = dlg_data.checkTilemap + file_format = dlg_data.fileformat + tile_offset = tonumber(dlg_data.tile_offset) + + -- print(exp_tileset) + -- print(exp_tilemap) +end + +local function export_c(tab,map) + local c_file = "" + local h_file = "" + c_file = c_file.. "// GENERATED USING ASEPRITE GB EXPORTER BY GABRIEL REIS// \n \n \n" -- header i suppose + h_file = c_file + + if do_map then + h_file = h_file.. "#define "..map_name.."_width "..tostring(#map[1]).."\n" + h_file = h_file.. "#define "..map_name.."_height "..tostring(#map).."\n" + end + + if do_set then --CHECKS IF TILESET IS TO BE EXPORTED + c_file = c_file.. "const unsigned char " .. tile_name .. "[] = {\n" + + h_file = h_file .. "\n#define ".. tile_name.."_size "..tostring(#tab).."\n\n\n" + + h_file = h_file.. "extern const unsigned char ".. tile_name .."[]; \n\n" + + for i, tileset in ipairs(tab) do -- TILESET IN TILESETS + for j, tiles in ipairs(tileset) do -- TILES IN TILESET + c_file = c_file .. tiles + end + end + c_file = c_file .. "}; \n \n \n" + h_file = h_file .. "\n \n \n" + end + + if do_map then -- CHECKS IF MAP IS TO BE EXPORTED + + c_file = c_file .. "const unsigned char " .. map_name .. "[] = {\n" .. map .. "};" + h_file = h_file .. "extern const unsigned char " .. map_name .. "[];" + end + + return c_file, h_file +end + +local function export_asm(tab,map) + local out_contents = "" + out_contents= out_contents.. "\t; original export script by gabriel reis, modified by shoofle\n \n \n" -- header i suppose + + if do_set then --CHECKS IF TILESET IS TO BE EXPORTED + out_contents = out_contents.. tile_name .. ":\n" + + out_contents = out_contents.."\n" + + + for j, hexes in ipairs(tab) do -- TILES IN TILESET + local hexen = {} + for x, h in ipairs(hexes) do + table.insert(hexen, "$" .. h) + end + out_contents = out_contents .. "\tdb " .. table.concat(hexen, ",") .. "\n" + end + + out_contents = out_contents .. "\n \n \n" + end + + if do_map then -- CHECKS IF MAP IS TO BE EXPORTED + out_contents = out_contents .. map_name .. ":\n" + for i, line in ipairs(map) do + local linen = {} + for x, mark in ipairs(line) do + table.insert(linen, string.format("$%02x", mark+tile_offset)) + end + out_contents = out_contents .. "\tdb " .. table.concat(linen, ", ") .. "\n" + end + end + + return out_contents +end + + +local function do_code() + local tiles = generate_tileset(layer.tileset) -- GENERATES TILESET + local map = generate_tilemap() -- GENERATES TILEMAP + + if (file_format == "C") then + local c_file, h_file = export_c(tiles, map) + save_to_file(filepath..tile_name..".c", c_file) + save_to_file(filepath..tile_name..".h", h_file) + + print(h_file.."\n") + print(c_file) + end + if (file_format == "ASM") then + local asm_file = export_asm(tiles, map) + save_to_file(filepath..tile_name..".asm", asm_file) + end + +end +--CODE EXECUTION-- + +if dlg_data.confirm then + parse_input() + do_code() --CODE GOES IN THERE TO STOP EXECUTION IF USER DIDN'T CLICK IN OK +end +if dlg_data.cancel then + return +end \ No newline at end of file diff --git a/tarot.asm b/tarot.asm new file mode 100644 index 0000000..9328dbc --- /dev/null +++ b/tarot.asm @@ -0,0 +1,360 @@ +; From https://gbdev.io/gb-asm-tutorial/part1/hello_world.html + +INCLUDE "hardware.inc" + +SECTION "Header", ROM0[$100] + + jp EntryPoint + + ds $150 - @, 0 ; Make room for the header + +EntryPoint: + ; Shut down audio circuitry + ld a, 0 + ld [rNR52], a + + ; Do not turn the LCD off outside of VBlank +WaitVBlank: + ld a, [rLY] + cp 144 + jp c, WaitVBlank + + ; Turn the LCD off + ld a, 0 + ld [rLCDC], a + + ld de, UITiles ; source + ld hl, $8800 ; destination of copy + ld bc, UITilesEnd - UITiles ; length to copy + call CopyRange + + ld de, BGTiles ; source + ld hl, $8000 ; destination of copy + ld bc, BGTilesEnd - BGTiles ; length to copy + call CopyRange + + ld de, LetterTiles ; source + ld hl, $8000 + (128 + 16)*16 + ld bc, LetterTilesEnd - LetterTiles + call CopyRange + + ld de, BigLetterTiles + ld hl, $8000 + (128 + 16 + 32)*16 + ld bc, BigLetterTilesEnd - BigLetterTiles + call CopyRange + + ld de, UITilemap ; origin + ld hl, $9800 ; destination + ld b, 18 ; height + ld c, 20 ; width + call CopyTilesToMap + + ld de, BGTilemap ; origin + ld hl, $9800 + 32 + 1 ; destination + ld b, 16 ; height + ld c, 8 ; width + call CopyTilesToMap + + ld de, LittleLetters + ld hl, $9800 + 32*5 + 10 + ld b, 5 + ld c, 8 + call CopyTilesToMap + + ld de, BigLetters + ld hl, $9800 + 32*1 + 10 + ld b, 2 + ld c, 8 + call CopyTilesToMap + + ; Turn the LCD on + ld a, LCDCF_BLK01 | LCDCF_ON | LCDCF_BGON + ld [rLCDC], a + + ; During the first (blank) frame, initialize display registers + ld a, %11100100 + ld [rBGP], a + +Done: + jp Done + + + + + + + +CopyRange: + ; de is source + ; hl is destination + ; bc is length to copy + ld a, [de] + ld [hli], a + inc de + dec bc + ld a, b + or a, c ; check if bc is zero + jp nz, CopyRange + ret + +CopyTilesToMap: + ; copy tiles from where they are linearly packed at an origin (de) + ; to a rectangle in the tilemap in vram (hl) + ; assuming it has height in b and width in c. + push bc +CopyTile: + ld a, [de] ; load from the tile map into a + ld [hl], a ; load from a into the destination + inc hl ; this is slower than using hli but i'm trying to work with this here + inc de + dec c + ; check if we've completed a line? + ld a, 0 + or a, c ; check if c is zero, if it's not zero go back and copy more bytes + jp nz, CopyTile +DoneWithLine: + pop bc + + ld a, l + add a, 32 + ld l, a + ld a, h + adc a, 0 + ld h, a + ld a, l + sub a, c + ld l, a + ld a, h + sbc a, 0 + ld h, a + + dec b + ret z + + jp CopyTilesToMap + +SECTION "Tile data", ROM0 + +UITiles: + db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + db $0f,$0f,$10,$10,$10,$10,$10,$10,$0f,$0f,$10,$10,$10,$10,$10,$10 + db $7f,$7f,$80,$80,$80,$80,$80,$80,$7f,$7f,$10,$10,$10,$10,$10,$10 + db $00,$3c,$3c,$7e,$42,$c3,$42,$c3,$42,$c3,$42,$c3,$42,$c3,$42,$c3 + db $42,$c3,$42,$c3,$42,$c3,$42,$c3,$42,$c3,$42,$c3,$3c,$7e,$00,$3c + db $00,$3c,$3c,$7e,$42,$c3,$5a,$db,$5a,$db,$5a,$db,$5a,$db,$5a,$db + db $5a,$db,$5a,$db,$5a,$db,$5a,$db,$5a,$db,$42,$c3,$3c,$7e,$00,$3c + db $0f,$0f,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + db $ce,$f0,$c6,$f8,$0e,$f0,$16,$e8,$5e,$a0,$fe,$00,$fc,$00,$00,$00 + db $ce,$f0,$c6,$f8,$ce,$f0,$c6,$f8,$ce,$f0,$c6,$f8,$ce,$f0,$c6,$f8 + db $00,$00,$fc,$00,$fe,$00,$ae,$50,$1e,$e0,$06,$f8,$ce,$f0,$c6,$f8 + db $00,$00,$3f,$00,$7f,$00,$7a,$05,$68,$17,$70,$0f,$63,$1f,$73,$0f + db $63,$1f,$73,$0f,$60,$1f,$78,$07,$75,$0a,$7f,$00,$3f,$00,$00,$00 + db $00,$00,$ff,$00,$ff,$00,$aa,$55,$00,$ff,$00,$ff,$ff,$ff,$ff,$ff + db $63,$1f,$73,$0f,$63,$1f,$73,$0f,$63,$1f,$73,$0f,$63,$1f,$73,$0f + db $ff,$ff,$ff,$ff,$00,$ff,$00,$ff,$55,$aa,$ff,$00,$ff,$00,$00,$00 +UITilesEnd: + +BGTiles: + db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01,$00,$01,$00,$02 + db $00,$00,$00,$00,$00,$1f,$00,$60,$00,$80,$00,$00,$00,$00,$00,$00 + db $00,$00,$00,$00,$00,$00,$00,$c0,$00,$20,$00,$10,$00,$10,$00,$08 + db $00,$02,$00,$02,$00,$02,$00,$01,$00,$01,$00,$00,$00,$00,$00,$00 + db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$80,$00,$60,$00,$1f + db $00,$08,$00,$08,$00,$08,$00,$10,$00,$10,$00,$20,$00,$c0,$00,$00 + db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 + db $00,$00,$00,$00,$00,$00,$01,$1f,$0e,$3e,$10,$60,$3c,$c4,$ff,$03 + db $00,$00,$00,$00,$00,$00,$f8,$f8,$00,$3c,$7c,$7c,$00,$38,$20,$21 + db $00,$01,$01,$02,$01,$02,$03,$04,$07,$08,$0f,$10,$1f,$20,$1f,$20 + db $f0,$0c,$e0,$10,$e0,$10,$c0,$20,$c0,$21,$80,$43,$80,$42,$01,$85 + db $f0,$fe,$20,$2b,$10,$53,$e8,$eb,$8c,$8e,$42,$43,$00,$01,$00,$03 + db $00,$00,$00,$00,$00,$80,$00,$c0,$00,$40,$00,$20,$00,$60,$00,$20 + db $3f,$40,$3e,$41,$1d,$22,$0a,$14,$01,$0c,$02,$08,$05,$08,$02,$08 + db $00,$f4,$a0,$1a,$50,$05,$a8,$02,$50,$05,$aa,$00,$55,$00,$aa,$00 + db $80,$85,$00,$05,$00,$81,$00,$63,$02,$3d,$1f,$e0,$1c,$e3,$bd,$3c + db $00,$20,$00,$a0,$00,$20,$00,$20,$1f,$3f,$00,$aa,$01,$ab,$01,$6b + db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$80,$80,$c0,$c0,$c0,$c0 + db $05,$08,$02,$08,$04,$0b,$00,$0c,$00,$08,$00,$00,$00,$00,$00,$00 + db $55,$00,$aa,$00,$00,$ff,$00,$01,$00,$01,$00,$01,$00,$01,$00,$01 + db $46,$5c,$8f,$8e,$82,$8e,$86,$8d,$8c,$89,$ca,$b9,$7c,$89,$72,$8d + db $a6,$1e,$50,$08,$a8,$04,$54,$02,$a8,$02,$54,$02,$a8,$02,$54,$02 + db $20,$20,$10,$10,$08,$08,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04 + db $00,$01,$00,$01,$00,$01,$00,$01,$00,$01,$00,$01,$00,$01,$00,$01 + db $78,$85,$3c,$43,$bc,$43,$3c,$43,$be,$41,$5e,$21,$9e,$21,$5d,$22 + db $a8,$02,$54,$02,$a8,$02,$54,$02,$a8,$02,$50,$04,$a8,$04,$50,$04 + db $04,$04,$04,$04,$04,$04,$04,$04,$04,$0c,$08,$08,$08,$18,$10,$30 + db $00,$00,$00,$0f,$00,$30,$00,$40,$00,$40,$00,$40,$00,$40,$00,$42 + db $00,$01,$00,$ff,$00,$01,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + db $9c,$22,$1d,$62,$0c,$b2,$05,$1a,$04,$4a,$01,$86,$00,$82,$01,$82 + db $a8,$04,$50,$04,$a8,$05,$53,$0f,$a0,$08,$50,$08,$a0,$08,$50,$08 + db $20,$60,$40,$c0,$80,$80,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + db $00,$41,$00,$31,$10,$2f,$1c,$23,$1e,$21,$1e,$21,$1e,$21,$1c,$22 + db $00,$c0,$00,$38,$00,$07,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + db $00,$82,$01,$82,$00,$c2,$01,$62,$00,$21,$00,$20,$00,$30,$00,$30 + db $a0,$08,$40,$38,$80,$48,$00,$84,$00,$04,$00,$04,$00,$04,$00,$08 + db $00,$00,$00,$00,$00,$00,$00,$00,$00,$01,$00,$1e,$00,$20,$00,$40 + db $1c,$22,$1c,$22,$1c,$22,$10,$2e,$00,$f2,$00,$02,$00,$01,$00,$01 + db $00,$30,$00,$30,$00,$30,$00,$10,$00,$10,$00,$10,$00,$10,$00,$10 + db $00,$08,$00,$08,$00,$08,$00,$08,$00,$08,$00,$10,$00,$10,$00,$08 + db $00,$38,$00,$07,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + db $00,$01,$00,$fe,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + db $00,$10,$00,$10,$00,$10,$00,$10,$00,$10,$00,$08,$00,$04,$00,$06 + db $00,$08,$00,$08,$00,$08,$00,$04,$00,$0c,$00,$0c,$00,$38,$38,$c4 + db $00,$03,$00,$01,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + db $78,$84,$fc,$02,$7e,$81,$3e,$41,$1f,$20,$0f,$10,$07,$08,$03,$04 + db $00,$00,$00,$00,$00,$00,$00,$00,$00,$80,$00,$80,$80,$40,$c0,$20 + db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$07,$00,$18 + db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$fc,$00,$03 + db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$f0 + db $01,$02,$00,$01,$00,$03,$00,$0f,$00,$70,$00,$80,$00,$c0,$00,$e0 + db $c0,$30,$e0,$18,$00,$fc,$00,$0c,$00,$04,$00,$04,$00,$04,$00,$04 + db $00,$08,$00,$04,$00,$04,$00,$04,$00,$04,$00,$04,$00,$03,$00,$00 + db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$80 + db $00,$0f,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + db $00,$ff,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + db $00,$ff,$00,$03,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + db $00,$fc,$00,$83,$00,$7c,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + db $00,$00,$00,$c0,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + db $00,$00,$00,$01,$00,$01,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + db $00,$80,$00,$00,$00,$00,$00,$80,$00,$c0,$00,$20,$00,$20,$00,$20 + db $00,$20,$00,$20,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 +BGTilesEnd: +LetterTiles: + db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + db $00,$00,$10,$10,$28,$28,$28,$28,$7c,$7c,$44,$44,$82,$82,$82,$82 + db $00,$00,$7c,$7c,$22,$22,$22,$22,$3c,$3c,$22,$22,$22,$22,$7c,$7c + db $00,$00,$3c,$3c,$42,$42,$40,$40,$40,$40,$40,$40,$42,$42,$3c,$3c + db $00,$00,$78,$78,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$78,$78 + db $00,$00,$7c,$7c,$44,$44,$40,$40,$78,$78,$40,$40,$44,$44,$7c,$7c + db $00,$00,$7c,$7c,$24,$24,$20,$20,$38,$38,$20,$20,$20,$20,$20,$20 + db $00,$00,$38,$38,$44,$44,$40,$40,$4c,$4c,$44,$44,$44,$44,$38,$38 + db $00,$00,$44,$44,$44,$44,$44,$44,$7c,$7c,$44,$44,$44,$44,$44,$44 + db $00,$00,$38,$38,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$38,$38 + db $00,$00,$0e,$0e,$04,$04,$04,$04,$04,$04,$04,$04,$44,$44,$38,$38 + db $44,$44,$48,$48,$50,$50,$60,$60,$60,$60,$50,$50,$48,$48,$44,$44 + db $00,$00,$e0,$e0,$40,$40,$40,$40,$40,$40,$40,$40,$44,$44,$fc,$fc + db $00,$00,$42,$42,$66,$66,$5a,$5a,$42,$42,$42,$42,$42,$42,$42,$42 + db $00,$00,$64,$64,$64,$64,$54,$54,$54,$54,$4c,$4c,$4c,$4c,$44,$44 + db $00,$00,$38,$38,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$38,$38 + db $00,$00,$78,$78,$44,$44,$44,$44,$44,$44,$78,$78,$40,$40,$40,$40 + db $00,$00,$38,$38,$44,$44,$44,$44,$44,$44,$4c,$4c,$44,$44,$3a,$3a + db $00,$00,$78,$78,$44,$44,$44,$44,$7c,$7c,$48,$48,$48,$48,$44,$44 + db $00,$00,$1c,$1c,$22,$22,$20,$20,$1c,$1c,$02,$02,$62,$62,$1c,$1c + db $00,$00,$7c,$7c,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10 + db $00,$00,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$3c,$3c + db $00,$00,$44,$44,$44,$44,$28,$28,$28,$28,$28,$28,$10,$10,$10,$10 + db $00,$00,$82,$82,$82,$82,$44,$44,$54,$54,$54,$54,$28,$28,$28,$28 + db $00,$00,$44,$44,$28,$28,$28,$28,$10,$10,$28,$28,$28,$28,$44,$44 + db $00,$00,$44,$44,$28,$28,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10 + db $00,$00,$7c,$7c,$08,$08,$08,$08,$10,$10,$20,$20,$20,$20,$7c,$7c + db $00,$00,$00,$00,$00,$18,$00,$66,$00,$66,$00,$18,$00,$00,$00,$00 +LetterTilesEnd: + +BigLetterTiles: + db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 + db $ee,$ee,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44 + db $7c,$7c,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$ee,$ee + db $10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$38,$38 + db $38,$38,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10 + db $70,$70,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$42,$42,$fe,$fe + db $fe,$fe,$42,$42,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40 + db $48,$48,$44,$44,$44,$44,$44,$44,$44,$44,$42,$42,$42,$42,$e3,$e3 + db $fc,$fc,$42,$42,$42,$42,$42,$42,$42,$42,$7c,$7c,$48,$48,$48,$48 + db $42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$3c,$3c + db $3c,$3c,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42 + db $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$70,$70 + db $7c,$7c,$22,$22,$22,$22,$22,$22,$22,$22,$3c,$3c,$20,$20,$20,$20 + db $38,$38,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$ee,$ee + db $10,$10,$28,$28,$28,$28,$28,$28,$28,$28,$28,$28,$28,$28,$28,$28 + db $ce,$ce,$44,$44,$64,$64,$54,$54,$54,$54,$54,$54,$54,$54,$54,$54 + db $54,$54,$54,$54,$54,$54,$54,$54,$54,$54,$4c,$4c,$44,$44,$e6,$e6 + db $fe,$fe,$92,$92,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10 + db $7e,$7e,$22,$22,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20 + db $38,$38,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$70,$70 + db $70,$70,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20 + db $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$22,$22,$7e,$7e + db $42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$fc,$fc + db $f8,$f8,$44,$44,$42,$42,$42,$42,$44,$44,$78,$78,$44,$44,$42,$42 + db $ee,$ee,$44,$44,$44,$44,$44,$44,$44,$44,$7c,$7c,$44,$44,$44,$44 + db $44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$ee,$ee + db $7e,$7e,$22,$22,$20,$20,$20,$20,$20,$20,$38,$38,$20,$20,$20,$20 + db $fe,$fe,$42,$42,$40,$40,$40,$40,$40,$40,$70,$70,$40,$40,$40,$40 + db $40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$42,$42,$fe,$fe + db $3c,$3c,$42,$42,$42,$42,$42,$42,$40,$40,$40,$40,$40,$40,$40,$40 + db $40,$40,$40,$40,$40,$40,$40,$40,$42,$42,$42,$42,$42,$42,$3c,$3c + db $42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$44,$44,$f8,$f8 + db $f8,$f8,$44,$44,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42,$42 + db $80,$80,$80,$80,$8f,$8f,$8a,$8a,$82,$82,$82,$82,$44,$44,$38,$38 + db $38,$38,$44,$44,$82,$82,$82,$82,$82,$82,$80,$80,$80,$80,$80,$80 + db $04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$44,$44,$44,$44,$38,$38 + db $0e,$0e,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04 + db $ee,$ee,$44,$44,$44,$44,$48,$48,$50,$50,$60,$60,$50,$50,$48,$48 + db $54,$54,$54,$54,$54,$54,$54,$54,$44,$44,$44,$44,$44,$44,$ee,$ee + db $c6,$c6,$6c,$6c,$54,$54,$54,$54,$54,$54,$54,$54,$54,$54,$54,$54 + db $42,$42,$42,$42,$42,$42,$42,$42,$4a,$4a,$4c,$4c,$4c,$4c,$36,$36 + db $3c,$3c,$42,$42,$42,$42,$40,$40,$40,$40,$3c,$3c,$02,$02,$02,$02 + db $02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$42,$42,$42,$42,$3c,$3c + db $44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$28,$28,$10,$10 + db $44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$44,$38,$38 + db $44,$44,$54,$54,$54,$54,$54,$54,$54,$54,$54,$54,$54,$54,$28,$28 + db $10,$10,$10,$10,$28,$28,$28,$28,$28,$28,$44,$44,$44,$44,$ee,$ee + db $ee,$ee,$44,$44,$44,$44,$28,$28,$28,$28,$28,$28,$10,$10,$10,$10 + db $ee,$ee,$44,$44,$44,$44,$28,$28,$10,$10,$10,$10,$10,$10,$10,$10 + db $fe,$fe,$82,$82,$04,$04,$04,$04,$08,$08,$08,$08,$08,$08,$10,$10 + db $10,$10,$20,$20,$20,$20,$20,$20,$40,$40,$40,$40,$82,$82,$fe,$fe +BigLetterTilesEnd: + +SECTION "Tilemap", ROM0 + +UITilemap: + db $8b, $8d, $8d, $8d, $8d, $8d, $8d, $8d, $8d, $8a, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80 + db $8e, $80, $80, $80, $80, $80, $80, $80, $80, $89, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80 + db $8e, $80, $80, $80, $80, $80, $80, $80, $80, $89, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80 + db $8e, $80, $80, $80, $80, $80, $80, $80, $80, $89, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80 + db $8e, $80, $80, $80, $80, $80, $80, $80, $80, $89, $80, $80, $80, $80, $80, $80, $80, $80, $80, $81 + db $8e, $80, $80, $80, $80, $80, $80, $80, $80, $89, $80, $80, $80, $80, $80, $80, $80, $80, $80, $81 + db $8e, $80, $80, $80, $80, $80, $80, $80, $80, $89, $80, $80, $80, $80, $80, $80, $80, $80, $80, $81 + db $8e, $80, $80, $80, $80, $80, $80, $80, $80, $89, $80, $80, $80, $80, $80, $80, $80, $80, $80, $81 + db $8e, $80, $80, $80, $80, $80, $80, $80, $80, $89, $80, $80, $80, $80, $80, $80, $80, $80, $80, $81 + db $8e, $80, $80, $80, $80, $80, $80, $80, $80, $89, $80, $80, $80, $80, $80, $80, $80, $80, $80, $81 + db $8e, $80, $80, $80, $80, $80, $80, $80, $80, $89, $80, $80, $80, $80, $80, $80, $80, $80, $80, $81 + db $8e, $80, $80, $80, $80, $80, $80, $80, $80, $89, $80, $80, $80, $80, $80, $80, $80, $80, $80, $82 + db $8e, $80, $80, $80, $80, $80, $80, $80, $80, $89, $80, $80, $80, $85, $80, $80, $80, $80, $80, $81 + db $8e, $80, $80, $80, $80, $80, $80, $80, $80, $89, $80, $80, $83, $86, $83, $83, $80, $80, $80, $81 + db $8e, $80, $80, $80, $80, $80, $80, $80, $80, $89, $80, $80, $84, $83, $84, $84, $80, $80, $80, $81 + db $8e, $80, $80, $80, $80, $80, $80, $80, $80, $89, $80, $80, $80, $84, $80, $80, $80, $80, $80, $81 + db $8e, $80, $80, $80, $80, $80, $80, $80, $80, $89, $80, $80, $80, $80, $80, $80, $80, $80, $80, $81 + db $8c, $8f, $8f, $8f, $8f, $8f, $8f, $8f, $8f, $88, $80, $80, $80, $80, $80, $80, $80, $80, $80, $87 +UITilemapEnd: + +BGTilemap: + db $00, $00, $01, $02, $03, $00, $00, $00 + db $00, $00, $04, $05, $06, $00, $00, $00 + db $00, $00, $07, $08, $09, $00, $00, $00 + db $00, $00, $0a, $0b, $0c, $0d, $00, $00 + db $00, $00, $0e, $0f, $10, $11, $12, $00 + db $00, $00, $13, $14, $15, $16, $17, $00 + db $00, $00, $00, $18, $19, $1a, $1b, $00 + db $00, $00, $1c, $1d, $1e, $1f, $20, $00 + db $00, $00, $21, $22, $23, $24, $00, $00 + db $00, $25, $26, $00, $27, $28, $00, $00 + db $00, $29, $2a, $00, $2b, $2c, $00, $00 + db $00, $00, $00, $00, $2d, $2e, $2f, $00 + db $00, $30, $31, $32, $00, $33, $34, $00 + db $00, $35, $36, $37, $38, $39, $3a, $3b + db $00, $3c, $3d, $00, $00, $00, $00, $00 + db $00, $00, $3e, $00, $00, $00, $00, $00 +BGTilemapEnd: + +LittleLetters: + db $ab, $92, $95, $97, $99, $9e, $90, $90 + db $90, $90, $90, $90, $90, $90, $90, $90 + db $ab, $9c, $95, $91, $a0, $90, $90, $90 + db $90, $90, $90, $90, $90, $90, $90, $90 + db $ab, $9e, $91, $99, $a6, $95, $a4, $95 +LittleLettersEnd: + +BigLetters: + db $c1, $b1, $b6, $b0, $c2, $ba, $ba, $c4 + db $b3, $b2, $b5, $b0, $c3, $b9, $b9, $c5 +BigLettersEnd: diff --git a/thefool.aseprite b/thefool.aseprite new file mode 100644 index 0000000..03b009e Binary files /dev/null and b/thefool.aseprite differ