Files
Sprinter-SDCC/applications/PoP
snark13 c312e4a043 Найдены 8791 тактов на вызов блита: uint16_t габарит в pop_blit_b
Точки на цепочку вызовов (libbgi живёт в резиденте W1, адреса однозначны —
пересборка не нужна) разложили постоянные накладные блита:

  pop_blit_b ДО вызова ядра ....... 6 683   <- НАШ код, 77% накладных
  gfx_blit_noclip + _bgi_begin
    + _gfx_blit_sprite_noclip ..... 1 938
  пролог _bgi_blit_rows_raw ....... 457
  строчный цикл ................... 389/строку  (= 198 + 5,96*32, сходится
                                                 с регрессией)
  эпилог + _bgi_end + возврат ..... 1 355
  «вне цикла» ..................... 8 725 при ЛЮБОЙ высоте (h=9..60)

Причина в pop_blit_b, подтверждена чтением .asm: `w`/`h` объявлены
uint16_t, 16-битные значения не влезли в регистры, и SDCC увёл функцию в
14-байтовый стековый кадр (`ld iy,#-14 / add iy,sp / ld sp,iy`), после чего
`w = img[0] | (img[1] << 8)` развернулось в ДВА ДЕСЯТКА IX-относительных
пересылок между ячейками -7..-13 кадра.

Правка: габарит читается БАЙТАМИ.  Корректно по построению — обе ветки и
так требовали w<256 && h<256 (эти проверки теперь убраны как тождественные),
а кадры атласов не крупнее 32x63; формат .atl допускает больше, такой кадр
уходит на общий путь (blit_b_oversize).

Замер A/B на той же детерминированной сцене, те же выборки:
  gfx_blit_noclip  13 679 -> 11 530  (-16%)
  blit_b_clip      18 853 -> 15 340  (-19%)
Стековый кадр 14 -> 6 байт, _CODE -42 Б.  Тайл ~107 000 -> ~95 000.

Все 8 наборов tests-host проходят, комната 23 в MAME рисуется корректно.

Плюс TASKS_OPEN.md: OPT-BLIT — руководство на следующую сессию (где ещё
uint16->uint8, как искать IX-спиллы по asm, что НЕ делать, и грабли с
несколькими экземплярами MAME на один error.log).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-13 23:51:20 +03:00
..

Prince of Persia на ZX Sprinter

Порт Prince of Persia на компьютер Sprinter Sp2000 поверх нашего target-слоя SDCC (sprinter-cc / libc / libbgi). Цель — 320×256×256 (режим 0x81), VGA-256 ассеты оригинала переносятся почти впрямую.

Состояние (2026-08-01): играется весь уровень 1 — комнаты и переходы, Kid со всем набором действий, ловушки, ворота, дверь уровня, меч и бой, стражи с ИИ, HP и зелья. Нет: перехода на следующий уровень, звука, таймера/HUD, сохранений.

Что где

Папка Назначение
roomtest/ Активная разработка. Уровень 1 целиком: фон композицией тайлов, Kid (seqtbl-анимация, ввод, коллизия, падение, зацеп, окклюзия), ловушки, ворота, стражи, бой. Свой README/CLAUDE/TASKS.
docs/ Планы и разбор форматов ресурсов Apple II / DOS — см. индекс в docs/README.md.
toolchain/ Python-упаковщики ассетов под Sprinter (рендер комнат, атласы тайлов/Kid, извлечение данных анимации) + эталонные скриншоты.
poc/ Ранний proof-of-concept (снег, атлас, raw-клавиатура). Ассеты в poc/res/.
bgtest/, coltest/ Точечные проверки фона и коллизии.
SDLPoP/, PR/, mininim/ Референсные реализации движка (GPL) — читаем логику/константы, НЕ копируем код. SDLPoP/data/ — источник распакованных VGA-ассетов.
Prince-of-Persia-Apple-II/ Оригинальный 6502-исходник 1989 г.
MSDOS/ Локальные .DAT-ресурсы DOS-версии.

Референсы = только справочник

SDLPoP/, PR/, mininim/, Prince-of-Persia-Apple-II/ используются как справочник структур/логики и как источник готовых ассетов — их код НЕ копируется в наш порт (лицензии несовместимы, ABI другой). Любая механика сверяется с SDLPoP/src/ до реализации.

Форматы ресурсов

Формат уровня почти идентичен в Apple II и DOS (2304 / 2305 байт, blueprnt). Графика различается принципиально, но брать распакованные PNG из SDLPoP/data/ практичнее, чем декодировать сырой .DAT. Подробности — docs/README.md.