Browse Source

Add script for generating collision maps from PNGs

master
Forest Belton 3 years ago
parent
commit
dff8f6f186
6 changed files with 85 additions and 7 deletions
  1. +3
    -2
      .gitignore
  2. +10
    -4
      Makefile
  3. BIN
      png/map/intro_coll.png
  4. +0
    -0
      png/sprite/player.png
  5. +71
    -0
      scripts/generate_coll_map.py
  6. +1
    -1
      src/player.s

+ 3
- 2
.gitignore View File

@ -1,4 +1,5 @@
*.o
*.2bpp
is.gb is.gb
is.gb.sym is.gb.sym
*.o
*.2bpp
png/map/*.s

+ 10
- 4
Makefile View File

@ -1,12 +1,15 @@
PNGFILES := $(shell find png -type f -name '*.png')
PNGFILES := $(shell find png/sprite -type f -name '*.png')
IMGFILES := $(PNGFILES:%.png=%.2bpp) IMGFILES := $(PNGFILES:%.png=%.2bpp)
COLLFILES := $(shell find png/map -type f -name '*_coll.png')
BUILT_COLLFILES := $(COLLFILES:%_coll.png=%.s)
SFILES := $(shell find src -type f -name '*.s') SFILES := $(shell find src -type f -name '*.s')
OFILES := $(SFILES:%.s=%.o) OFILES := $(SFILES:%.s=%.o)
.PHONY: clean .PHONY: clean
is.gb is.gb.sym: $(IMGFILES) $(OFILES)
is.gb is.gb.sym: $(IMGFILES) $(OFILES) $(BUILT_COLLFILES)
rgblink -o $@ -n $@.sym $(OFILES) rgblink -o $@ -n $@.sym $(OFILES)
rgbfix -v $@ rgbfix -v $@
@ -15,8 +18,11 @@ $(OFILES): $(IMGFILES)
%.o: %.s %.o: %.s
rgbasm -i inc -o $@ $< rgbasm -i inc -o $@ $<
%.2bpp: %.png
png/map/%.s: png/map/%_coll.png
python scripts/generate_coll_map.py -o $@ $<
png/sprite/%.2bpp: png/sprite/%.png
rgbgfx -o $@ $< rgbgfx -o $@ $<
clean: clean:
rm -f is.gb is.gb.sym $(IMGFILES) $(OFILES)
rm -f is.gb is.gb.sym $(IMGFILES) $(OFILES) $(BUILT_COLLFILES)

BIN
png/map/intro_coll.png View File

Before After
Width: 160  |  Height: 144  |  Size: 545 B

png/player.png → png/sprite/player.png View File


+ 71
- 0
scripts/generate_coll_map.py View File

@ -0,0 +1,71 @@
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()

+ 1
- 1
src/player.s View File

@ -9,7 +9,7 @@ playerWorldY: dw
Section "Player Code", ROM0 Section "Player Code", ROM0
spriteData: spriteData:
INCBIN "png/player.2bpp"
INCBIN "png/sprite/player.2bpp"
DEF SPRITE_IDX EQU 32 DEF SPRITE_IDX EQU 32
DEF SPRITE_WIDTH EQU 2 DEF SPRITE_WIDTH EQU 2

Loading…
Cancel
Save