applications/PoP: порт Prince of Persia — PoC (roomtest) + пайплайн
Порт PoP на Sprinter. Текущий PoC — applications/PoP/roomtest/: комната 1 (фон-композиция тайлов) + Kid с управлением на raw-клавиатуре и коллизией с картой. - roomtest — pop_bg (фон), pop_kid (спрайты Kid, column-major флип, seqtbl-анимация), pop_ctrl (порт control() PoP на held-state kbd_raw), pop_map (коллизия seg004/005: бег/стоп у стены, падение/приземление, отскок seq_47, вертикальный прыжок K4.1). MEMORY=small (DATA сразу за CODE, ~23КБ кода не лезет в huge). - toolchain (PoP) — pop_pack_kid/pop_pack_bg/render_room/extract — распаковка res-графики MSDOS в атласы + композиция комнат. - toolchain/ (корень) — make_hdd.sh (быстрый HDD-тест вместо FDD), png_strip.py / room_compose.py (ассет-пайплайн). - docs — PORT_PLAN, KID_PLAN, форматы ресурсов (Apple II / MSDOS / DAT). - bgtest/coltest/poc — ранние PoC (фон, коллизия, первый прототип). .gitignore: build-артефакты applications/*/*/*; исключены внешние референс-репозитории (SDLPoP/mininim/PR/Apple-II — свои git-клоны) и оригинальные game-данные MSDOS/ (копирайт, только для реверса форматов). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
gen_kid_placeholder.py — временная ЗАГЛУШКА персонажа для PoC.
|
||||
|
||||
НЕ используем графику оригинальной Prince of Persia (авторские права
|
||||
Broderbund/Ubisoft) — PoC проверяет управление/коллизии/движок, не
|
||||
визуальную точность (applications/PoP/docs/PORT_PLAN.md §5). Вместо
|
||||
этого берём уже лицензированный спрайт-пак, который в проекте и так
|
||||
используется (examples/rpgwalk/conv_sprites.py) —
|
||||
third_party/16x16-RPG-characters, один персонаж (индекс 0) той же
|
||||
раскладкой: 12 кадров (dir*3+frame, dir 0=вниз/1=влево/2=вправо/3=вверх,
|
||||
3 кадра маятника на направление).
|
||||
|
||||
Замену на настоящую графику Кида (если/когда появится легально чистый
|
||||
источник) пользователь делает сам — вне этого скрипта.
|
||||
|
||||
Выход: kid.raw (16×192, 12 кадров) + kid.pal (EGA 16 + цвета спрайта).
|
||||
"""
|
||||
from PIL import Image
|
||||
|
||||
SRC = ("../../../../third_party/16x16-RPG-characters/sprites/"
|
||||
"old-style/02-bard.png")
|
||||
CHAR = 0 # какой из 8 персонажей листа берём
|
||||
|
||||
EGA = [ # B, G, R, pad — как в libbgi/bgi256/_bgi_mode_set.c
|
||||
(0, 0, 0), (168, 0, 0), (0, 168, 0), (168, 168, 0),
|
||||
(0, 0, 168), (168, 0, 168), (0, 84, 168), (168, 168, 168),
|
||||
(84, 84, 84), (255, 84, 84), (84, 255, 84), (255, 255, 84),
|
||||
(84, 84, 255), (255, 84, 255), (84, 255, 255), (255, 255, 255),
|
||||
]
|
||||
BASE = 16
|
||||
|
||||
im = Image.open(SRC).convert("RGBA")
|
||||
assert im.size == (192, 128), im.size
|
||||
|
||||
colors = {}
|
||||
|
||||
|
||||
def px(x, y):
|
||||
r, g, b, a = im.getpixel((x, y))
|
||||
if a < 128:
|
||||
return 0xFF
|
||||
key = (r, g, b)
|
||||
if key not in colors:
|
||||
assert BASE + len(colors) < 0xFF
|
||||
colors[key] = BASE + len(colors)
|
||||
return colors[key]
|
||||
|
||||
|
||||
bx, by = (CHAR % 4) * 48, (CHAR // 4) * 64
|
||||
data = bytearray()
|
||||
for d in range(4):
|
||||
for f in range(3):
|
||||
for y in range(16):
|
||||
for x in range(16):
|
||||
data.append(px(bx + f * 16 + x, by + d * 16 + y))
|
||||
open("kid.raw", "wb").write(data)
|
||||
|
||||
pal = bytearray()
|
||||
for b, g, r in EGA:
|
||||
pal += bytes((b, g, r, 0))
|
||||
for (r, g, b) in colors:
|
||||
pal += bytes((b, g, r, 0))
|
||||
open("kid.pal", "wb").write(pal)
|
||||
|
||||
print(f"gen_kid_placeholder: kid.raw 16x192 (12 кадров), "
|
||||
f"kid.pal EGA+{len(colors)} цветов ({len(pal)} Б)")
|
||||
Reference in New Issue
Block a user