splat *_bg.png assets

This commit is contained in:
Alex Bates 2021-02-06 17:36:35 +00:00
parent 137a93231d
commit 1df36e757a
4 changed files with 83 additions and 7 deletions

View File

@ -123,7 +123,7 @@ def build_image(f: str, segment):
out = "$builddir/" + path + "." + img_type + ".png"
flags = ""
if img_type != "palette":
if img_type != "palette" and not isinstance(segment, dict):
if segment.flip_horizontal:
flags += "--flip-x"
if segment.flip_vertical:
@ -481,8 +481,8 @@ async def main():
for asset_name in ASSETS:
if asset_name.endswith("_tex"): # uncompressed
asset_files.append(find_asset(f"map/texture/{asset_name}.bin"))
asset_files.append(find_asset(f"map/texture/{asset_name}.bin"))
asset_files.append(find_asset(f"map/{asset_name}.bin"))
asset_files.append(find_asset(f"map/{asset_name}.bin"))
elif asset_name.startswith("party_"):
source_file = f"$builddir/{asset_name}.bin"
asset_file = f"$builddir/{asset_name}.Yay0"
@ -495,7 +495,19 @@ async def main():
asset_files.append(source_file)
asset_files.append(asset_file)
n.build(asset_file, "yay0compress", source_file, implicit="tools/Yay0compress")
else: # uncompressed
elif asset_name.endswith("_bg"):
source_file = f"$builddir/{asset_name}.bin"
asset_file = f"$builddir/{asset_name}.Yay0"
n.build(source_file, "img", find_asset(f"map/{asset_name}.png"), implicit="tools/img/build.py", variables={
"img_type": "bg",
"img_flags": "",
})
asset_files.append(source_file)
asset_files.append(asset_file)
n.build(asset_file, "yay0compress", source_file, implicit="tools/Yay0compress")
else:
source_file = find_asset(f"{asset_name}.bin")
asset_file = f"$builddir/assets/{asset_name}.Yay0"

View File

@ -1418,8 +1418,8 @@ typedef struct TileDescriptor {
} TileDescriptor; // size = 0x30
typedef struct BackgroundHeader {
/* 0x00 */ UNK_PTR raster;
/* 0x04 */ UNK_PTR palette;
/* 0x00 */ void* raster;
/* 0x04 */ void* palette;
/* 0x08 */ u16 startX;
/* 0x0A */ u16 startY;
/* 0x0C */ u16 width;

View File

@ -3,6 +3,7 @@
from sys import argv, stderr
from math import floor, ceil
from itertools import zip_longest
from glob import glob
import png
def unpack_color(s):
@ -202,6 +203,46 @@ class Converter():
f.write(row)
f.write(b"\0\0\0\0\0\0\0\0\0\0") # padding
elif self.mode == "bg":
width, height, data, info = img.read()
img.preamble(True)
palettes = [img.palette(alpha="force")]
for palettepath in glob(self.infile.split(".")[0] + ".*.png"):
pal = png.Reader(palettepath)
pal.preamble(True)
palettes.append(pal.palette(alpha="force"))
with open(self.outfile, "wb") as f:
baseaddr = 0x80200000 # gBackgroundImage
headers_len = 0x10 * len(palettes)
palettes_len = 0x200 * len(palettes)
# header (struct BackgroundHeader)
for i, palette in enumerate(palettes):
f.write((baseaddr + palettes_len + headers_len).to_bytes(4, byteorder="big")) # raster offset
f.write((baseaddr + headers_len + 0x200 * i).to_bytes(4, byteorder="big")) # palette offset
f.write((12).to_bytes(2, byteorder="big")) # startX
f.write((20).to_bytes(2, byteorder="big")) # startY
f.write((width).to_bytes(2, byteorder="big")) # width
f.write((height).to_bytes(2, byteorder="big")) # height
assert f.tell() == headers_len
for palette in palettes:
# palette
for rgba in palette:
if rgba[3] not in (0, 0xFF):
self.warn("alpha mask mode but translucent pixels used")
color = pack_color(*rgba)
f.write(color.to_bytes(2, byteorder="big"))
assert f.tell() == palettes_len + headers_len
# ci 8
for row in reversed_if(data, self.flip_y):
f.write(row)
else:
print("unsupported mode", file=stderr)
exit(1)

View File

@ -58,8 +58,11 @@ class N64SegPaperMarioMapFS(N64Segment):
path = os.path.join(map_dir, "{}.bin".format(name))
elif name.endswith("_tex"):
map_dir = self.create_split_dir(base_path, self.options.get("assets_dir", "bin") + f"/map/texture")
map_dir = self.create_split_dir(base_path, self.options.get("assets_dir", "bin") + f"/map")
path = os.path.join(map_dir, "{}.bin".format(name))
elif name.endswith("_bg"):
map_dir = self.create_split_dir(base_path, self.options.get("assets_dir", "bin") + f"/map")
path = os.path.join(map_dir, "{}.png".format(name))
else:
path = os.path.join(bin_dir, "{}.bin".format(name))
@ -80,6 +83,26 @@ class N64SegPaperMarioMapFS(N64Segment):
# CI-8
w = png.Writer(150, 105, palette=parse_palette(bytes[:0x200]))
w.write_array(f, bytes[0x200:])
elif name.endswith("_bg"):
def write_bg_png(bytes, path, header_offset=0):
header = bytes[header_offset:header_offset+0x10]
raster_offset = int.from_bytes(header[0:4], byteorder="big") - 0x80200000
palette_offset = int.from_bytes(header[4:8], byteorder="big") - 0x80200000
assert int.from_bytes(header[8:12], byteorder="big") == 0x000C0014 # draw pos
width = int.from_bytes(header[12:14], byteorder="big")
height = int.from_bytes(header[14:16], byteorder="big")
with open(path, "wb") as f:
# CI-8
w = png.Writer(width, height, palette=parse_palette(bytes[palette_offset:palette_offset+512]))
w.write_array(f, bytes[raster_offset:])
write_bg_png(bytes, path)
# sbk_bg has an alternative palette
if name == "sbk_bg":
write_bg_png(bytes, path.split(".")[0] + ".alt.png", header_offset=0x10)
else:
with open(path, "wb") as f:
f.write(bytes)