Copy project
This commit is contained in:
parent
ce7a467af7
commit
26a0fd884f
173 changed files with 157458 additions and 1 deletions
110
sprite_generator/main.py
Normal file
110
sprite_generator/main.py
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
import os
|
||||
import zipfile
|
||||
from typing import Tuple
|
||||
from PIL import Image
|
||||
import io
|
||||
from math import ceil
|
||||
|
||||
|
||||
c_header = """#include "sprites.h"
|
||||
|
||||
#include <avr/eeprom.h>
|
||||
|
||||
|
||||
// AUTO-GENERATED
|
||||
|
||||
"""
|
||||
|
||||
h_header = """#ifndef SPRITES_H
|
||||
#define SPRITES_H
|
||||
|
||||
#include <avr/io.h>
|
||||
|
||||
|
||||
// AUTO-GENERATED
|
||||
|
||||
"""
|
||||
|
||||
h_footer = """
|
||||
#endif
|
||||
"""
|
||||
|
||||
|
||||
def generate_content(sprites_directory: str) -> Tuple[str, str]:
|
||||
output_h = h_header
|
||||
output_c = c_header
|
||||
|
||||
for entry in os.scandir(sprites_directory):
|
||||
delta_output_h, delta_output_c = process_spritesheet(entry)
|
||||
output_h += delta_output_h
|
||||
output_c += delta_output_c
|
||||
|
||||
output_h += h_footer
|
||||
return output_h, output_c
|
||||
|
||||
|
||||
def process_spritesheet(entry) -> Tuple[str, str]:
|
||||
sprites_name, _ = entry.name.split('.')
|
||||
sprites_zip = zipfile.ZipFile(entry.path, 'r')
|
||||
width, height = read_sprite(sprites_zip, sprites_zip.filelist[0]).size
|
||||
|
||||
declaration = f'const uint16_t {sprites_name}[{len(sprites_zip.filelist)}][{width}][{ceil(height / 8)}]'
|
||||
output_h = declaration + ';\n'
|
||||
output_c = declaration + ' EEMEM = {' + process_sprites(sprites_zip) + '};\n'
|
||||
|
||||
return output_h, output_c
|
||||
|
||||
|
||||
def process_sprites(sprites_zip) -> str:
|
||||
output = ''
|
||||
width, height = read_sprite(sprites_zip, sprites_zip.filelist[0]).size
|
||||
for sprite in sprites_zip.filelist:
|
||||
output += '{'
|
||||
pixels = list(read_sprite(sprites_zip, sprite).getdata())
|
||||
for x in range(width):
|
||||
output += '{'
|
||||
for y in range(0, height, 8):
|
||||
fill_bits = ''.join(
|
||||
reversed([
|
||||
('1' if is_filled(pixels[(y + i) * width + x]) else '0') if (y + i) * width + x < len(pixels) else '0'
|
||||
for i in range(8)
|
||||
])
|
||||
)
|
||||
|
||||
inverted_mask_bits = ''.join(
|
||||
reversed([
|
||||
('0' if is_translucent(pixels[(y + i) * width + x]) else '1') if (y + i) * width + x < len(pixels) else '0'
|
||||
for i in range(8)
|
||||
])
|
||||
)
|
||||
output += f'{binary_to_hex_with_prefix(inverted_mask_bits + fill_bits)},'
|
||||
output = output[:-1] + '},'
|
||||
output = output[:-1] + '},'
|
||||
|
||||
return output[:-1]
|
||||
|
||||
|
||||
def read_sprite(sprites_zip, entry):
|
||||
return Image.open(io.BytesIO(sprites_zip.read(entry.filename)))
|
||||
|
||||
|
||||
def is_translucent(pixel: Tuple[int, int, int, int]) -> bool:
|
||||
r, g, b, a = pixel
|
||||
return a == 0
|
||||
|
||||
|
||||
def is_filled(pixel: Tuple[int, int, int, int]) -> bool:
|
||||
r, g, b, a = pixel
|
||||
return r != 0 or g != 0 or b != 0
|
||||
|
||||
|
||||
def binary_to_hex_with_prefix(binary: str) -> str:
|
||||
return hex(int(binary, 2))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
dot_h, dot_c = generate_content('spritesheets')
|
||||
with open('output/sprites.h', 'w+') as f:
|
||||
f.write(dot_h)
|
||||
with open('output/sprites.c', 'w+') as f:
|
||||
f.write(dot_c)
|
||||
Loading…
Add table
Add a link
Reference in a new issue