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:
2026-07-17 17:51:08 +03:00
parent 484b18d10c
commit cd8d566d82
196 changed files with 6630 additions and 0 deletions
+68
View File
@@ -0,0 +1,68 @@
/*
* room.h — отрисовка комнаты из тайлов В РАНТАЙМЕ, через спрайтовые
* атласы (см. пересмотр PORT_PLAN.md §4, 2026-07-15).
*
* Один атлас на ТИП тайла (0x00..0x1F) — лента из N вариантов
* (кадр fw x fh, fw=ROOM_TILE_W, fh=высота ряда, где тип реально
* стоит). Для типов, где backtable — настоящее состояние
* (gate/tapestry/chomp/spike) — вариант = state; для остальных —
* простой псевдослучайный выбор по позиции (свой приём, не алгоритм
* оригинала — просто чтобы плитка не повторялась один-в-один).
*
* Загрузка "всей лентой — копии одной картинки" на старте, до
* появления настоящих вариантов — нормальная стратегия: движок/API
* не меняются, когда картинки заменятся на настоящие.
*
* Фаза 1 (PORT_PLAN.md §5): анимированные типы (факел/дверь/шипы/
* дробилка) НЕ рисуются вообще — просто не грузим для них атлас,
* room_draw пропускает клетки без атласа. Анимация через отдельные
* sprite_t поверх фона — Фаза 2, см. §7 плана.
*
* room_draw() зовётся ОДИН РАЗ при входе в комнату, не в игровом
* цикле — бюджет кадра не затронут (gfx_w0_map/unmap на тайл — тоже
* разовая цена, не per-frame).
*/
#ifndef ROOM_H
#define ROOM_H
#include <stdint.h>
#include <sprite.h> /* atlas_t, atlas_load/free, atlas_image, gfx_w0_map/unmap */
#include "level.h"
#define ROOM_TILE_W 32 /* ширина колонки, px (10 колонок = 320) */
/* Высоты рядов, px — измерено по реальным тайлам подземелья
* (PORT_PLAN.md §3: ~20/60/62) — ПОДТВЕРДИТЬ при подготовке настоящих
* ассетов, значения приблизительные. */
extern uint8_t room_row_h[ROOM_ROWS];
typedef struct {
atlas_t at;
uint8_t loaded; /* 0 = атласа нет — тип не рисуется */
} tile_atlas_t;
/* Индекс — TILE_TYPE (0..31). */
extern tile_atlas_t tile_atlas[32];
/* Грузит "{dir}tileNN.atl" (hex TILE_TYPE, 2 знака, напр. "tile01.atl"
* — Floor) — какие есть, те и грузятся. dir — префикс ПОДКЛЕИВАЕТСЯ
* как есть (без добавления разделителя) — файлы на диске лежат ПЛОСКО
* (см. соглашение других examples: "name.ext" либо "a:\\name.ext"), так что
* dir обычно "" или "a:\\". Каждый файл — ОДНА лента (idx 0) из N
* кадров fw=ROOM_TILE_W x fh=room_row_h[row] (row, где этот тип
* реально стоит) — готовится toolchain/png_strip.py +
* toolchain/mkatlas.py. Возврат: число загруженных (0..32).
*
* room.c — обычный HOME-файл, БЕЗ --bank (см. шапку room.c за
* историей: банк в W3 конфликтовал с gfx_blit_part/atlas_load,
* банк в W1 невозможен при CODE=W1 — трамплин сам уехал бы из W1;
* после чистки sprintf() всё влезает в HOME без банка вообще). */
int tile_atlas_load(const char *dir);
void tile_atlas_free(void);
/* Нарисовать комнату (room 1..24) — только типы с загруженным
* атласом; остальные клетки пропускаются (в т.ч. все анимированные
* типы в Фазе 1 — атлас для них просто не грузится). */
void room_draw(level_t *lv, uint8_t room);
#endif