117 lines
4.3 KiB
Python
Executable File
117 lines
4.3 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
from PIL import BdfFontFile, Image
|
|
import os
|
|
import serial
|
|
import argparse
|
|
|
|
compiled_output_path = 'compiled_eeprom'
|
|
header_path = 'eeprom_address.h'
|
|
eeprom_length = 131072 # 128 kib
|
|
|
|
data_path = "./eeprom_data"
|
|
|
|
output = open(compiled_output_path, 'wb')
|
|
header = open(header_path, 'w')
|
|
|
|
page_bit_width = 128
|
|
page_bit_height = 8
|
|
page_cnt = 4
|
|
|
|
|
|
|
|
#fonts
|
|
# for some reason BdfFontFile.BdfFontFile.bitmap doesn't have proper spacing
|
|
# so we'll just manually go through each character ourselves
|
|
# it's expected I'll rename fonts to how I think they should be refrenced beorehand
|
|
# also note we have no protection from using unsed chars, I can't let this project
|
|
# get to big for litteraly no reason
|
|
|
|
header.write("/** GENERATED BY EEPROM COMPILER SCRIPT **/\r\n\r\n")
|
|
header.write("// FONTS\r\n")
|
|
|
|
for file in os.listdir("{}/fonts/".format(data_path)):
|
|
path = "{}/fonts/{}".format(data_path, file)
|
|
if os.path.isfile(path) and path.split('.')[-1] == 'bdf':
|
|
with open(path, 'rb') as font_fd:
|
|
font_bdf = BdfFontFile.BdfFontFile(font_fd)
|
|
font_name = file.split('.')[0].capitalize()
|
|
|
|
header.write("#define FONT_{}_ADDR\t0x{:04x}\r\n".format(font_name, output.tell()))
|
|
|
|
first_char = False
|
|
for char in enumerate(font_bdf.glyph):
|
|
if char[1]:
|
|
if not first_char:
|
|
first_char = True
|
|
header.write(("#define FONT_{}_FIRST_CHAR\t{}\r\n"
|
|
"#define FONT_{}_WIDTH\t{}\r\n"
|
|
"#define FONT_{}_HEIGHT\t{}\r\n").format(
|
|
font_name, char[0],
|
|
font_name, char[1][-1].size[0],
|
|
font_name, char[1][-1].size[1]))
|
|
output.write(char[1][-1].tobytes('raw'))
|
|
|
|
header.write("\r\n\r\n// IMAGES\r\n#define IMG_BEGIN\t0x{:04x}\r\n".format(output.tell()))
|
|
|
|
image_cnt = 0
|
|
|
|
# images
|
|
for file in os.listdir("{}/images/".format(data_path)):
|
|
path = "{}/images/{}".format(data_path, file)
|
|
if os.path.isfile(path) and path.split('.')[-1] == 'png':
|
|
with open(path, 'rb') as image_fd:
|
|
image_cnt += 1
|
|
image_bitmap = []
|
|
image_bitmap_remapped = []
|
|
image = Image.open(image_fd)
|
|
if not image.mode == 'RGB':
|
|
print("this script only compiles RGB formatted photos! (I'm lazy\r\n")
|
|
exit(1)
|
|
header.write("#define IMG_{}_ADDR\t0x{:04x}\r\n".format(
|
|
file.split('.')[0].capitalize(),
|
|
output.tell()))
|
|
for byte in range(0, len(image.tobytes()), 3):
|
|
if (byte / 3) % 8 == 0:
|
|
image_bitmap.append(0)
|
|
if sum(image.tobytes()[byte:byte+3]) > 0:
|
|
image_bitmap[-1] |= (int(byte / 3)) % 8
|
|
|
|
# is this supposed to be big endian?
|
|
image_bitmap_remapped = [0] * len(image_bitmap)
|
|
for bit in range(0, page_bit_width * page_bit_height * page_cnt):
|
|
w = page_bit_width
|
|
h = page_bit_height
|
|
i = bit
|
|
#I am so sorry.
|
|
extract_bit = (((i % w) * page_bit_height) +
|
|
(int(i / w) % page_bit_height) +
|
|
(int(i / (w * page_bit_height)) *
|
|
(w * page_bit_height)))
|
|
|
|
if (extract_bit % 8) - (bit % 8) >= 0:
|
|
image_bitmap_remapped[int(bit / 8)] |= \
|
|
(image_bitmap[int(extract_bit / 8)] & (extract_bit % 8)) >> \
|
|
((extract_bit % 8) - (bit % 8))
|
|
else:
|
|
image_bitmap_remapped[int(bit / 8)] |= \
|
|
(image_bitmap[int(extract_bit / 8)] & (extract_bit % 8)) << \
|
|
((bit % 8) - (extract_bit % 8))
|
|
[output.write(byte.to_bytes(1, 'big')) for byte in image_bitmap_remapped]
|
|
|
|
header.write("#define IMG_COUNT\t{}\r\n\r\n".format(image_cnt))
|
|
|
|
|
|
|
|
print("EEPROM used: {}% ({} out of {} bits)".format(
|
|
(output.tell() / eeprom_length) * 100,
|
|
output.tell(), eeprom_length))
|
|
|
|
if(output.tell() > eeprom_length):
|
|
print("WARNING: You've used more eeprom then there is available!\r\n")
|
|
|
|
output.close()
|
|
header.close()
|
|
|
|
|
|
|