Спуск Кида с кнопки (room8, кромка (0,6)) рисовался неверно: Кид просвечивал в щель между кнопкой и ближним столбом, а ближняя рука была срезана до одного оторванного пикселя. Две независимые причины. 1. Не был портирован clip_char() (seg006:1749) — оригинал перед add_objtable обрезает спрайт персонажа сверху по y_clip[curr_row+1], когда тайл над головой стена или пол. Порт: pop_clip_char_top() (pop_map.c, метрики по set_char_collision) + новый примитив gfx_blit_cols_part() в libbgi (блит column-major с пропуском skip верхних строк; обрезка сверху бесплатна — колонка непрерывна в ОЗУ, сдвигается только старт). gfx_blit_cols стал тонкой обёрткой над ним. kid_heal чистит уже ОБРЕЗАННЫЙ прямоугольник, иначе стирается кромка пола над срезом. 2. climb_overlay_tile (порт draw_floor_overlay, seg008:1E3A) выбирал ветку по СЫРОМУ коду тайла, а get_tile_to_draw (seg008:240) подменяет нажатую кнопку на floor/stuck. Тайл-кнопка не проходил тест floor → уходил в draw_other_overlay, который кладёт поверх Кида ВЕСЬ тайл вместо узкой кромки floor_left_overlay[frame-137]. Фикс — tile_code_drawn(): одна подстановка на все слои (fore_only_tile/overlay_mid_tile перестали её дублировать, W3 −293 Б). Проверено покадрово в MAME (шаг gv + снимок): кадры спуска 148..138 чистые, после приземления на кнопке мусора нет. Заодно: gfx_heal_noclip() (пара к gfx_blit_noclip; heal 11658 -> 8982 тактов) и rest_pending в pop_trob — холостой проход по 30 тайлам только когда есть отложенные редрои пик/кнопок (pop_process_trobs 89-111К -> 70-92К тактов). START_ROOM временно = 8 (отладка спуска с кнопки), вернуть на 6/старт уровня. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Форматы ресурсов Prince of Persia — сводка
Каноническая спецификация форматов — POP-DAT-FormatSpecifications.pdf
(+ текстовая конверсия POP-DAT-FormatSpecifications.txt для grep/цитирования):
«Prince of Persia — Specifications of File Formats», Princed Development Team,
2008. Это первоисточник формата DAT v1.0 (контейнер, индекс, чек-сумма,
кодеки RLE/LZG, палитры, уровни, звук), на котором построены и SDLPoP, и
Princed Resources. Документы ниже — наши практические заметки/сверки; при
расхождении источником истины считать спецификацию.
Цель этих документов — подготовить почву для будущего порта Prince of Persia на ZX Sprinter, разобрав, как устроены ресурсы игры в двух доступных нам версиях:
APPLEII_RESOURCE_FORMAT.md— формат уровней и графики по официально опубликованным исходникам 1989 года (6502-ассемблер). Уверенность высокая везде — восстановлено прямым чтением кода движка, а не догадками.MSDOS_RESOURCE_FORMAT.md— формат.DATресурсов DOS-версии (исходников нет). Восстановлено эмпирически (разбор байтов + перепроверка скриптами) и сверено с документацией открытых сторонних инструментов (SDLPoP, Princed Resources).
Главный вывод
Формат уровня практически идентичен в обеих версиях: Apple II LEVELn
занимает ровно 2304 байта (структура blueprnt — тайлы, связи
плит/дверей, граф экранов, метаданные старта Кида/стражников), а запись
уровня в DOS levels.dat занимает 2305 байт с байтовыми значениями тайлов
того же диапазона. То есть Джордан Мехнер перенёс формат карты уровня в
DOS-порт практически без изменений (+1 байт, вероятно контрольная сумма от
DOS-упаковщика). Это значит: раскладку BLUETYPE/BLUESPEC/LINKLOC/
LINKMAP/MAP/INFO, задокументированную по Apple II исходникам, можно
применять напрямую и к DOS levels.dat.
Формат же графики отличается принципиально: на Apple II это простой
несжатый rowbyte-формат hi-res экрана с плоской таблицей указателей; в DOS —
контейнер с оглавлением ресурсов (id/size/offset), с отдельными вариантами
под CGA/EGA/VGA — точный кодек пикселей внутри сырого .DAT-чанка не
восстановлен ни для той, ни для другой версии до конца. Но для DOS-графики
это не блокирует работу: в репозитории github.com/NagyD/SDLPoP (папка
data/) уже лежат готовые распакованные PNG для каждого спрайта/фона
(включая VGA-256-цветный вариант VPALACE/VDUNGEON — то, что нужно под
320×256×256 Sprinter), см. §5 MSDOS_RESOURCE_FORMAT.md. Это другой
релиз/сборка данных, чем наш локальный MSDOS/ (некоторые звуковые .dat
отличаются по размеру), но нумерация ресурсов и формат контейнера — те же,
что подтверждено побайтовой сверкой уровня res2001.bin.
Общий контейнерный формат DOS .DAT (кратко)
[0x00] u32 LE tableOffset — смещение начала таблицы оглавления
[0x04] u16 LE tableSize — размер таблицы оглавления
[0x06..tableOffset) — данные ресурсов (конкатенация чанков)
[tableOffset..tableOffset+tableSize)
— массив записей по 8 байт:
u16 size, u16 id, u16 offset(абсолютный), u16 reserved(=0)
Инвариант tableOffset + tableSize == размер файла подтверждён на всех 28
.dat-файлах в MSDOS/, и независимо — именованием файлов res<id>.* в
data/ репозитория SDLPoP.
Готовые ассеты для порта (важно для практической работы)
github.com/NagyD/SDLPoP/tree/master/data содержит не только код движка, но
и сами ресурсы игры — как сырые .DAT, так и распакованные поштучно файлы
(res<id>.png для спрайтов/фонов, res<id>.pal для палитр, res<id>.bin
для уровней). Для арт-ассетов (в т.ч. нужного полноцветного VGA-варианта
дворца/подземелий) практичнее взять их оттуда напрямую, чем писать свой
декодер сжатия пикселей DOS .DAT.
Что дальше (не сделано в этом заходе)
- Точный кодек сжатия пикселей спрайтов в сыром DOS
.DAT(нужен только если понадобится читать именно нашу локальную копиюMSDOS/*.dat"как есть", а не ассеты из SDLPoPdata/) — сверка с исходником SDLPoP,src/seg009.c. - Семантика служебных полей
digisnd*.dat/ibm_snd*.datперед сырыми сэмплами/нотами (частично прояснено документацией Princed Resources — PC speaker: 1 байт заголовка + повторяющиеся тройки байт "2 байта частоты- 1 байт длительности"; WAV: 8 бит, моно, unsigned, 11025 Гц).
- Назначение бит
secmaskвBLUETYPE(Apple II) и служебного блокаid=2000в начале DOSlevels.dat(16 байт в нашей копии, но 2305 байт в версии SDLPoP — расхождение между релизами, не разобрано). - Оценка, какие видеорежимы/цветовые палитры ZX Sprinter реалистично покрывают исходную графику (CGA/EGA/VGA варианты в DOS-ресурсах против hi-res Apple II) — отдельная архитектурная задача порта, не формат ресурсов как таковой.