2024-02-27 01:04:37 +00:00
|
|
|
from typing import Tuple
|
|
|
|
from PIL import Image
|
|
|
|
import sys
|
|
|
|
import shared
|
|
|
|
|
|
|
|
TEMPLATE = """
|
|
|
|
// generated code! be nice!
|
|
|
|
#include "sys/sys.h"
|
2024-02-28 00:00:57 +00:00
|
|
|
sys_sprite spr_{{spritesheet_name}}_data[{{n_sprites}}] = {
|
2024-02-27 01:04:37 +00:00
|
|
|
{% for sprite in sprites -%}
|
|
|
|
{ .pixels={
|
|
|
|
{% for row in sprite -%}
|
|
|
|
{ {{ row|join(",") }} }{% if not loop.last %},{% endif %}
|
|
|
|
{% endfor %}
|
|
|
|
} }{% if not loop.last %},{% endif %}
|
|
|
|
{%- endfor %}
|
|
|
|
};
|
2024-02-28 00:00:57 +00:00
|
|
|
sys_spritesheet spr_{{spritesheet_name}} = {
|
|
|
|
.sprites=spr_{{spritesheet_name}}_data,
|
2024-02-27 01:31:58 +00:00
|
|
|
.width={{width}},
|
|
|
|
.height={{height}},
|
|
|
|
};
|
2024-02-27 01:04:37 +00:00
|
|
|
""".lstrip()
|
|
|
|
|
|
|
|
|
|
|
|
def main(spritesheet_name, n_sprites, key_color, fname_png, fname_c):
|
2024-02-27 01:31:58 +00:00
|
|
|
sprites, width, height = load_sprites(fname_png, key_color)
|
2024-02-27 23:57:37 +00:00
|
|
|
assert(len(sprites) == n_sprites), f"must be exactly {n_sprites} sprites, not {len(sprites)}"
|
2024-02-27 01:04:37 +00:00
|
|
|
|
|
|
|
with open(fname_c, "wt") as output:
|
|
|
|
output.write(
|
|
|
|
shared.templates.from_string(TEMPLATE).render(
|
|
|
|
spritesheet_name=spritesheet_name,
|
|
|
|
n_sprites=n_sprites,
|
|
|
|
sprites=sprites,
|
2024-02-27 01:31:58 +00:00
|
|
|
width=width,
|
|
|
|
height=height,
|
2024-02-27 01:04:37 +00:00
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def load_sprites(fname_png: str, key_color: int):
|
|
|
|
width, height, data = shared.load_image(fname_png)
|
|
|
|
|
|
|
|
sprites = []
|
|
|
|
for gy in range(0, height, 8):
|
|
|
|
for gx in range(0, width, 8):
|
|
|
|
pixels = []
|
|
|
|
for py in range(0, 8):
|
|
|
|
row = []
|
|
|
|
for px in range(0, 8):
|
|
|
|
x = gx + px
|
|
|
|
y = gy + py
|
|
|
|
pal = pixel_to_palette(data[y * width + x], key_color, x, y)
|
|
|
|
row.append(pal)
|
|
|
|
pixels.append(row)
|
|
|
|
sprites.append(pixels)
|
|
|
|
|
2024-02-27 01:31:58 +00:00
|
|
|
return sprites, width//8, height//8
|
2024-02-27 01:04:37 +00:00
|
|
|
|
|
|
|
|
|
|
|
palette_colors = {
|
|
|
|
(0, 0, 0): 0,
|
|
|
|
(29, 43, 83): 1,
|
|
|
|
(126, 37, 83): 2,
|
|
|
|
(0, 135, 81): 3,
|
|
|
|
(171, 82, 54): 4,
|
|
|
|
(95, 87, 79): 5,
|
|
|
|
(194, 195, 199): 6,
|
|
|
|
(255, 241, 232): 7,
|
|
|
|
(255, 0, 77): 8,
|
|
|
|
(255, 163, 0): 9,
|
|
|
|
(255, 236, 39): 10,
|
|
|
|
(0, 228, 54): 11,
|
|
|
|
(41, 173, 255): 12,
|
|
|
|
(131, 118, 156): 13,
|
|
|
|
(255, 119, 168): 14,
|
|
|
|
(255, 204, 170): 15,
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
def pixel_to_palette(rgba, key_color, x, y):
|
|
|
|
(r, g, b, a) = rgba
|
|
|
|
|
|
|
|
if a < 128:
|
|
|
|
return 255
|
|
|
|
|
|
|
|
rgb = (r, g, b)
|
|
|
|
ix = palette_colors.get(rgb)
|
|
|
|
if ix is None:
|
|
|
|
raise ValueError(f"unrecognized color at ({x}, {y}): {rgb}")
|
|
|
|
|
|
|
|
if ix == key_color:
|
|
|
|
return 255
|
|
|
|
|
|
|
|
return ix
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
assert len(sys.argv) == 6, \
|
|
|
|
"there must be five args (spritesheet name, n sprites, key color, src png, out c)"
|
|
|
|
main(sys.argv[1], int(sys.argv[2]), int(sys.argv[3]), sys.argv[4], sys.argv[5])
|