feat(platform): migrate LCD assets to PNG and expand flash partitions

This commit is contained in:
chenjintao
2026-08-10 16:04:23 +08:00
parent 42187ba21d
commit d9660164a6
105 changed files with 10103 additions and 527 deletions
-76
View File
@@ -1,76 +0,0 @@
import os
import re
import struct
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
LCD_ROOT = Path(r"D:\Code\chaowan\lcd\main")
OUT_DIR = ROOT / "components" / "platform" / "assets" / "lcd"
IMAGE_SOURCES = {
"qianzhiwuxing": ["qianzhiwuxing0"],
"shui": ["shui1", "shui2"],
"mu": ["mu1", "mu2"],
"huo": ["huo1", "huo2"],
"tu": ["tu1", "tu2"],
"jin": ["jin1", "jin2"],
"caiwei": ["bei0", "dongbei0", "dong0", "dongnan0", "nan0", "xinan0", "xi0", "xibei0"],
"chouqian_qianzhi": ["chouqianqianzhi0", "chouqianqianzhi1", "chouqianqianzhi2"],
"chouqian_buyun": ["shangshangqian0", "buyunqian1", "buyunqian2"],
"chouqian_heping": [None, "hepingqian1", "hepingqian2"],
"chouqian_shangshang": [None, "shangshangqian1", "shangshangqian2"],
"chouqian_xiaoji": [None, "xiaojiqian1", "xiaojiqian2"],
"chouqian_zhongshang": [None, "zhongshangqian1", "zhongshangqian2"],
}
def extract_arrays(source_text):
arrays = {}
pattern = re.compile(
r"static\s+const\s+(?:rle_structure_t|eye_image_frame_t)\s+([A-Za-z0-9_]+)\[\]\s*=\s*\{",
re.MULTILINE,
)
for match in pattern.finditer(source_text):
name = match.group(1)
cursor = match.end()
depth = 1
while cursor < len(source_text) and depth > 0:
if source_text[cursor] == "{":
depth += 1
elif source_text[cursor] == "}":
depth -= 1
cursor += 1
arrays[name] = source_text[match.end(): cursor - 1]
return arrays
def parse_runs(body):
runs = []
for color, count in re.findall(r"\{\s*0x([0-9A-Fa-f]+)\s*,\s*(\d+)\s*\}", body):
runs.append((int(color, 16), int(count)))
if not runs:
raise ValueError("no runs parsed")
return runs
def write_rle(path, runs):
path.parent.mkdir(parents=True, exist_ok=True)
with path.open("wb") as f:
for color, count in runs:
f.write(struct.pack("<HH", color, count))
def main():
eye_arrays = extract_arrays((LCD_ROOT / "eye_image.c").read_text(encoding="utf-8"))
OUT_DIR.mkdir(parents=True, exist_ok=True)
for asset_dir, frames in IMAGE_SOURCES.items():
for index, array_name in enumerate(frames):
if array_name is None:
continue
write_rle(OUT_DIR / f"{asset_dir}{index}.rle", parse_runs(eye_arrays[array_name]))
if __name__ == "__main__":
main()
-83
View File
@@ -1,83 +0,0 @@
#!/usr/bin/env python3
"""Convert PNG images to standard TGA RLE image files."""
import argparse
from pathlib import Path
def iter_inputs(input_path, recursive):
if input_path.is_file():
if input_path.suffix.lower() != ".png":
raise SystemExit(f"input file is not a PNG: {input_path}")
yield input_path
return
pattern = "**/*.png" if recursive else "*.png"
yield from sorted(input_path.glob(pattern))
def output_path_for(input_file, input_root, output):
if output is None:
return input_file.with_suffix(".rle")
if input_root.is_file():
return output
relative = input_file.relative_to(input_root)
return (output / relative).with_suffix(".rle")
def convert_file(input_file, input_root, output):
try:
from PIL import Image
except ImportError as exc:
raise SystemExit(
"Pillow is required. Install it with: python -m pip install Pillow"
) from exc
out_path = output_path_for(input_file, input_root, output)
out_path.parent.mkdir(parents=True, exist_ok=True)
with Image.open(input_file) as image:
converted = image.convert("RGBA")
width, height = converted.size
converted.save(out_path, format="TGA", compression="tga_rle")
print(f"{input_file} -> {out_path} ({width}x{height})")
def main():
parser = argparse.ArgumentParser(
description="Convert PNG files to standard TGA RLE files using Pillow.",
)
parser.add_argument("input", type=Path, help="PNG file or directory containing PNG files.")
parser.add_argument(
"-o",
"--output",
type=Path,
help="Output .rle file for one input file, or output directory for an input directory.",
)
parser.add_argument(
"-r",
"--recursive",
action="store_true",
help="Recursively convert PNG files when input is a directory.",
)
args = parser.parse_args()
input_path = args.input.resolve()
if not input_path.exists():
raise SystemExit(f"input path does not exist: {input_path}")
output = args.output.resolve() if args.output is not None else None
inputs = list(iter_inputs(input_path, args.recursive))
if not inputs:
raise SystemExit(f"no PNG files found in: {input_path}")
if input_path.is_file() and output is not None and output.suffix.lower() != ".rle":
raise SystemExit("single-file output must use a .rle suffix")
for input_file in inputs:
convert_file(input_file, input_path, output)
if __name__ == "__main__":
main()