Load spritesheet
This commit is contained in:
parent
d05e382063
commit
79eb52e282
20
game/BUILD
20
game/BUILD
@ -1,7 +1,23 @@
|
||||
load("@bazel_skylib//rules:run_binary.bzl", "run_binary")
|
||||
|
||||
cc_library(
|
||||
name = "game",
|
||||
srcs = glob(["*.c"]),
|
||||
hdrs = glob(["*.h"]),
|
||||
srcs = glob(["*.c"]) + [":art/game_demo_sprites.c"],
|
||||
hdrs = glob(["*.h"]) + [":art/game_demo_sprites.h"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["//device:device", "//sys:sys"]
|
||||
)
|
||||
|
||||
run_binary(
|
||||
name = "game_demo_sprites",
|
||||
args = [
|
||||
"game_demo_sprites",
|
||||
"256", # n sprites
|
||||
"0", # key color
|
||||
"$(location :art/game_demo_sprites.png)",
|
||||
"$(location :art/game_demo_sprites.c)"
|
||||
],
|
||||
srcs = [":art/game_demo_sprites.png"],
|
||||
outs = [":art/game_demo_sprites.c"],
|
||||
tool = "//pytools:spritesheet",
|
||||
)
|
8
game/art/game_demo_sprites.h
Normal file
8
game/art/game_demo_sprites.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef CROCPARTY_GAME_DEMO_SPRITES_H
|
||||
#define CROCPARTY_GAME_DEMO_SPRITES_H
|
||||
|
||||
#include "sys/sys.h"
|
||||
|
||||
sys_sprite game_demo_sprites[256];
|
||||
|
||||
#endif // CROCPARTY_GAME_DEMO_SPRITES_H
|
BIN
game/art/game_demo_sprites.png
Normal file
BIN
game/art/game_demo_sprites.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.2 KiB |
@ -8,4 +8,14 @@ py_binary(
|
||||
requirement("Jinja2"),
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
py_binary(
|
||||
name = "spritesheet",
|
||||
srcs = ["spritesheet.py", "shared.py"],
|
||||
deps = [
|
||||
requirement("pillow"),
|
||||
requirement("Jinja2"),
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
@ -26,7 +26,6 @@ def main(font_name, n_glyphs, fname_png, fname_c):
|
||||
|
||||
def load_glyphs(fname_png: str):
|
||||
width, height, data = shared.load_image(fname_png)
|
||||
monochrome = [pixel_to_monochrome(p) for p in data]
|
||||
|
||||
glyphs = []
|
||||
for gy in range(0, height, 8):
|
||||
@ -36,7 +35,7 @@ def load_glyphs(fname_png: str):
|
||||
for px in range(0, 8):
|
||||
x = gx + px
|
||||
y = gy + py
|
||||
if monochrome[y * width + x]:
|
||||
if pixel_to_monochrome(data[y * width + x]):
|
||||
glyph |= 1 << (py * 8 + px)
|
||||
glyphs.append(glyph)
|
||||
|
||||
|
95
pytools/spritesheet.py
Normal file
95
pytools/spritesheet.py
Normal file
@ -0,0 +1,95 @@
|
||||
from typing import Tuple
|
||||
from PIL import Image
|
||||
import sys
|
||||
import shared
|
||||
|
||||
TEMPLATE = """
|
||||
// generated code! be nice!
|
||||
#include "sys/sys.h"
|
||||
sys_sprite {{spritesheet_name}}[{{n_sprites}}] = {
|
||||
{% for sprite in sprites -%}
|
||||
{ .pixels={
|
||||
{% for row in sprite -%}
|
||||
{ {{ row|join(",") }} }{% if not loop.last %},{% endif %}
|
||||
{% endfor %}
|
||||
} }{% if not loop.last %},{% endif %}
|
||||
{%- endfor %}
|
||||
};
|
||||
""".lstrip()
|
||||
|
||||
|
||||
def main(spritesheet_name, n_sprites, key_color, fname_png, fname_c):
|
||||
sprites = load_sprites(fname_png, key_color)
|
||||
assert(len(sprites) == n_sprites), f"must be exactly {n_sprites} sprites"
|
||||
|
||||
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,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
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)
|
||||
|
||||
return sprites
|
||||
|
||||
|
||||
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])
|
Loading…
Reference in New Issue
Block a user