import argparse import pathlib import sys from PIL import Image GREEN = (0, 255, 0) RED = (255, 0, 0) def generate_coll_map(in_path: str, out_path: str) -> None: png = Image.open(in_path).convert("RGB") assert png.height % 8 == 0 and png.width % 8 == 0 out_bytes = [] bits = [] for y in range(png.height // 8): for x in range(png.width // 8): pixel = png.getpixel((x * 8, y * 8)) bit = None if pixel == RED: bit = 1 elif pixel == GREEN: bit = 0 else: print(f"unsupported pixel in collision map {pixel}", file=sys.stderr) return bits.append(bit) if len(bits) == 8: byte = sum([bit << i for i, bit in enumerate(bits)]) out_bytes.append(byte) bits = [] lines = [] for line_no in range(0, len(out_bytes), 16): line = out_bytes[line_no : line_no + 16] lines.append(" DB " + ", ".join(["$%02X" % b for b in line])) section = pathlib.Path(in_path).name.replace("_coll.png", "") all_lines = "\n".join(lines) with open(out_path, "wb") as outf: outf.write( f"""SECTION "{section.upper()} MAP", ROM0 ; Values are provided in tiles DEF {section}_width EQU {png.width // 8} DEF {section}_height EQU {png.height // 8} {section}_collision_map:: {all_lines} """.encode( "utf-8" ) ) def main() -> None: parser = argparse.ArgumentParser("generate_coll_map") parser.add_argument("-o", "--output", required=True) parser.add_argument("png") args = parser.parse_args() generate_coll_map(args.png, args.output) if __name__ == "__main__": main()