You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

71 lines
1.7 KiB

  1. import argparse
  2. import pathlib
  3. import sys
  4. from PIL import Image
  5. GREEN = (0, 255, 0)
  6. RED = (255, 0, 0)
  7. def generate_coll_map(in_path: str, out_path: str) -> None:
  8. png = Image.open(in_path).convert("RGB")
  9. assert png.height % 8 == 0 and png.width % 8 == 0
  10. out_bytes = []
  11. bits = []
  12. for y in range(png.height // 8):
  13. for x in range(png.width // 8):
  14. pixel = png.getpixel((x * 8, y * 8))
  15. bit = None
  16. if pixel == RED:
  17. bit = 1
  18. elif pixel == GREEN:
  19. bit = 0
  20. else:
  21. print(f"unsupported pixel in collision map {pixel}", file=sys.stderr)
  22. return
  23. bits.append(bit)
  24. if len(bits) == 8:
  25. byte = sum([bit << i for i, bit in enumerate(bits)])
  26. out_bytes.append(byte)
  27. bits = []
  28. lines = []
  29. for line_no in range(0, len(out_bytes), 16):
  30. line = out_bytes[line_no : line_no + 16]
  31. lines.append(" DB " + ", ".join(["$%02X" % b for b in line]))
  32. section = pathlib.Path(in_path).name.replace("_coll.png", "")
  33. all_lines = "\n".join(lines)
  34. with open(out_path, "wb") as outf:
  35. outf.write(
  36. f"""SECTION "{section.upper()} MAP", ROM0
  37. ; Values are provided in tiles
  38. DEF {section}_width EQU {png.width // 8}
  39. DEF {section}_height EQU {png.height // 8}
  40. {section}_collision_map::
  41. {all_lines}
  42. """.encode(
  43. "utf-8"
  44. )
  45. )
  46. def main() -> None:
  47. parser = argparse.ArgumentParser("generate_coll_map")
  48. parser.add_argument("-o", "--output", required=True)
  49. parser.add_argument("png")
  50. args = parser.parse_args()
  51. generate_coll_map(args.png, args.output)
  52. if __name__ == "__main__":
  53. main()