mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-26 05:32:07 -04:00
171 lines
6.7 KiB
Lua
171 lines
6.7 KiB
Lua
-- Bank02.asm Map32ToMap16; Kakariko $18/$19/$20/$21; Bank0F.asm Map16ToMap8.
|
|
local HOUSE = {
|
|
{ 0x3F7, 0x3F8, 0x3F9, 0x3F9, 0x3FA, 0x3FB },
|
|
{ 0x3FC, 0x3FD, 0x3FE, 0x3FE, 0x3FF, 0x400 },
|
|
{ 0x402, 0x403, 0x404, 0x404, 0x405, 0x406 },
|
|
{ 0x40A, 0x40B, 0x40C, 0x40D, 0x40B, 0x40E },
|
|
{ 0x0F9, 0x0FA, 0x0FB, 0x0FC, 0x0FD, 0x0FE },
|
|
}
|
|
local LAB = {
|
|
{ 0x5AC, 0x5AD, 0x5AE, 0x5AE, 0x5AF, 0x5B0 },
|
|
{ 0x5B1, 0x5B6, 0x5B3, 0x5B3, 0x5B7, 0x5B5 },
|
|
{ 0x5B8, 0x5B9, 0x5BA, 0x5BA, 0x5BB, 0x5BC },
|
|
{ 0x5BD, 0x5BE, 0x5BF, 0x5C0, 0x5BE, 0x5C1 },
|
|
HOUSE[5],
|
|
}
|
|
local TREE = {
|
|
{ 0x0AE, 0x0AF, 0x07E, 0x07F },
|
|
{ 0x0B0, 0x014, 0x015, 0x0A8 },
|
|
{ 0x089, 0x01C, 0x01D, 0x076 },
|
|
{ 0x0F1, 0x04E, 0x04F, 0x0D9 },
|
|
{ 0x09A, 0x09B, 0x09C, 0x095 },
|
|
}
|
|
|
|
return function(mod, base, map, imagePath)
|
|
local source = love.image.newImageData(imagePath)
|
|
local function tile(image, id, x, y)
|
|
image:paste(source, x, y, id % 64 * 16, math.floor(id / 64) * 16, 16, 16)
|
|
end
|
|
local function mosaic(rows)
|
|
local image = love.image.newImageData(#rows[1] * 16, #rows * 16)
|
|
for y, row in ipairs(rows) do
|
|
for x, id in ipairs(row) do tile(image, id, (x - 1) * 16, (y - 1) * 16) end
|
|
end
|
|
return image
|
|
end
|
|
local function scale(target, image, x, y, w, h, sx, sy, sw, sh)
|
|
sx, sy = sx or 0, sy or 0
|
|
sw, sh = sw or image:getWidth(), sh or image:getHeight()
|
|
for py = 0, h - 1 do
|
|
for px = 0, w - 1 do
|
|
target:setPixel(x + px, y + py, image:getPixel(
|
|
sx + math.floor((px + 0.5) * sw / w),
|
|
sy + math.floor((py + 0.5) * sh / h)))
|
|
end
|
|
end
|
|
end
|
|
local width, height = map.width * 32, map.height * 32
|
|
local canvas = love.image.newImageData(width, height + 32)
|
|
local tree = mosaic(TREE)
|
|
local Map = require("src.world.Map")
|
|
local function water(x, y)
|
|
if x < 0 or y < 0 or x >= width / 16 or y >= height / 16 then return true end
|
|
local id = Map.defCellTile(map, base, x, y)
|
|
return id == 0x14 or id == 0x32
|
|
end
|
|
local function shoreline(x, y)
|
|
local sx, sy = 0x2DB % 64 * 16, math.floor(0x2DB / 64) * 16
|
|
for n = 0, 15 do
|
|
for depth = 0, 3 do
|
|
local r, g, b, a = source:getPixel(sx + n, sy + 12 + depth)
|
|
if not water(x - 1, y) then canvas:setPixel(x * 16 + 3 - depth, y * 16 + n, r, g, b, a) end
|
|
if not water(x + 1, y) then canvas:setPixel(x * 16 + 12 + depth, y * 16 + n, r, g, b, a) end
|
|
if not water(x, y - 1) then canvas:setPixel(x * 16 + n, y * 16 + 3 - depth, r, g, b, a) end
|
|
if not water(x, y + 1) then canvas:setPixel(x * 16 + n, y * 16 + 12 + depth, r, g, b, a) end
|
|
end
|
|
end
|
|
end
|
|
for y = 0, height / 16 - 1 do
|
|
for x = 0, width / 16 - 1 do
|
|
local original = Map.defCellTile(map, base, x, y)
|
|
tile(canvas, (x + y) % 7 == 0 and 0x10E or 0x034, x * 16, y * 16)
|
|
if original == 0x3A then
|
|
scale(canvas, tree, x * 16, y * 16, 16, 16)
|
|
elseif original == 0x14 or original == 0x32 then
|
|
local ripple = (x + y * 3) % 5
|
|
tile(canvas, ripple == 0 and 0x2D8 or ripple == 2 and 0x2D9 or 0x2CD,
|
|
x * 16, y * 16)
|
|
shoreline(x, y)
|
|
elseif original == 0x55 then
|
|
tile(canvas, 0x334, x * 16, y * 16)
|
|
elseif original == 0x56 then
|
|
tile(canvas, 0x413, x * 16, y * 16)
|
|
elseif original == 0x52 then
|
|
tile(canvas, 0x3F6, x * 16, y * 16)
|
|
elseif (y == 6 and x >= 3 and x <= 15)
|
|
or (x == 9 and y >= 2 and y <= 16)
|
|
or (y == 12 and x >= 9 and x <= 15) then
|
|
tile(canvas, 0x3D2, x * 16, y * 16)
|
|
elseif original == 0x2C and x > 1 and x < 18 and y > 1 then
|
|
tile(canvas, 0x3C6, x * 16, y * 16)
|
|
end
|
|
end
|
|
end
|
|
local function building(rows, x, y, w, h, doorX)
|
|
local image = mosaic(rows)
|
|
local door = love.image.newImageData(32, 32)
|
|
door:paste(image, 0, 0, 32, 48, 32, 32)
|
|
tile(image, rows[4][2], 32, 48)
|
|
tile(image, rows[4][2], 48, 48)
|
|
tile(image, rows[5][2], 32, 64)
|
|
tile(image, rows[5][5], 48, 64)
|
|
scale(canvas, image, x, y, w, h - 16, 0, 0, 96, 64)
|
|
scale(canvas, image, x, y + h - 16, w, 16, 0, 64, 96, 16)
|
|
scale(canvas, door, doorX, y + h - 24, 16, 24)
|
|
local r, g, b = source:getPixel(0x0FB % 64 * 16 + 14,
|
|
math.floor(0x0FB / 64) * 16 + 7)
|
|
for py = y + h - 17, y + h - 2 do
|
|
for px = doorX + 4, doorX + 11 do canvas:setPixel(px, py, r * 0.15, g * 0.15, b * 0.15, 1) end
|
|
end
|
|
image:release()
|
|
door:release()
|
|
end
|
|
building(HOUSE, 64, 48, 64, 48, 80)
|
|
building(HOUSE, 192, 48, 64, 48, 208)
|
|
building(LAB, 160, 128, 96, 64, 192)
|
|
for y = 0, 1 do
|
|
for x = 0, 1 do scale(canvas, tree, x * 16, height + y * 16, 16, 16) end
|
|
end
|
|
local atlas = love.image.newImageData(256, math.ceil((width * height / 64 + 16) / 32) * 8)
|
|
local blocks, mapBlocks, variants, count = {}, {}, {}, 0
|
|
local sets = {}
|
|
for _, name in ipairs({ "walkable", "doorTiles", "warpTiles", "counterTiles", "waterTiles", "shoreTiles" }) do
|
|
sets[name] = {}
|
|
local fallback = name == "waterTiles" and { 0x14 }
|
|
or name == "shoreTiles" and { 0x32, 0x48 } or {}
|
|
for _, id in ipairs(base[name] or fallback) do sets[name][id] = true end
|
|
end
|
|
local result = { image = "mod_cache/" .. mod.id .. "/pallet.png",
|
|
imageWidth = atlas:getWidth(), imageHeight = atlas:getHeight(),
|
|
tilesPerRow = 32, blocks = blocks, trueColor = true,
|
|
walkable = {}, doorTiles = {}, warpTiles = {}, counterTiles = {}, waterTiles = {}, shoreTiles = {} }
|
|
local piece = love.image.newImageData(8, 8)
|
|
local function addBlock(original, bx, by)
|
|
local row = {}
|
|
for i, old in ipairs(original) do
|
|
local tx, ty = (i - 1) % 4, math.floor((i - 1) / 4)
|
|
piece:paste(canvas, 0, 0, bx * 32 + tx * 8, by * 32 + ty * 8, 8, 8)
|
|
if old == base.grassTile then
|
|
piece:paste(source, 0, 0, 0x3F6 % 64 * 16, math.floor(0x3F6 / 64) * 16, 8, 8)
|
|
end
|
|
local key = old .. ":" .. piece:getString()
|
|
local id = variants[key]
|
|
if id == nil then
|
|
id = count
|
|
count = count + 1
|
|
variants[key] = id
|
|
atlas:paste(piece, id % 32 * 8, math.floor(id / 32) * 8, 0, 0, 8, 8)
|
|
for name, set in pairs(sets) do
|
|
if set[old] then result[name][#result[name] + 1] = id end
|
|
end
|
|
if old == base.grassTile then result.grassTile = id end
|
|
end
|
|
row[i] = id
|
|
end
|
|
blocks[#blocks + 1] = row
|
|
return #blocks - 1
|
|
end
|
|
for i, id in ipairs(map.blocks) do
|
|
mapBlocks[i] = addBlock(assert(base.blocks[id + 1]), (i - 1) % map.width,
|
|
math.floor((i - 1) / map.width))
|
|
end
|
|
local border = addBlock(assert(base.blocks[(map.borderBlock or 0) + 1]), 0, map.height)
|
|
assert(mod.cache:write("pallet.png", atlas:encode("png"):getString()))
|
|
source:release()
|
|
tree:release()
|
|
canvas:release()
|
|
atlas:release()
|
|
piece:release()
|
|
return result, mapBlocks, border
|
|
end
|