pop_hof.c был написан, но никуда не вызывался: после финала автомат уходил
мимо него в title, а на титрах экран получался чёрным. Теперь это хвост
end_sequence и шаг show_title между credits и attract-demo, как в оригинале.
Два корня пустого экрана:
- story.pal — 256 записей, и запись 0x3F (цвет глифов шрифта) в ней чёрная:
текст рисовался, но был не виден. Генератор кладёт туда золотой 0xB7;
- полосовой переход копирует страницу акселератором, а тот читает ОЗУ-копию,
куда прозрачный блит текста не пишет. Строки рисуются после перехода,
прямо в видимую страницу.
Попутно:
- s5 в архиве PV — фон таблицы (рамка story + логотип на y=24, HOF_POP);
- отдельный индекс палитры под фон текстовой рамки: финал красит его в
#800000, титры оставляют #100060 (load_title_images(bgcolor)). Прежний
ремап в индекс 9 подменить было нельзя — им нарисована сама титульная
картинка;
- второй набор глифов в font.atl цветом 0x3E: у SDLPoP шрифт маска и
show_hof_text рисует текст дважды разным цветом, у нас цвет запечён в
пиксели. Каталог SPA1 держит счётчик в байте, поэтому набор обрезан по '_';
- общий pop_screen_present_ltr(): им теперь пользуются story-переход интро,
титры, таблица и титульная картинка финала. Заодно вернулся пропущенный
шаг show_title — экран с логотипом и Jordan Mechner между «свадьбой» и
титрами (BUGS_CLOSED#cutscene-ltr).
Формат POP.HOF — 6 записей, имя до 15 символов, версия 2. Проверено в MAME
на сборке LEVEL=14: HAIL → титульная картинка → таблица с полосой ввода и
временем справа → ввод имени → титульная картинка; на следующем запуске
таблица показывается между credits и demo.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* Порт show_time() целиком: «N MINUTES LEFT», «N SECONDS LEFT» (у
единственной секунды свой total=12, как у оригинала), «TIME HAS
EXPIRED!». Флаг pop_show_time — это is_show_time: взводит и само ядро
таймера (круглые пятёрки, каждая секунда последней минуты), и старт
уровня, и читы времени. Значение 2 = «перебить текущую строку», как
оригинал делает в последнюю минуту и после читов.
* Отладочная полоса показывает оставшееся время ##:## у правого края.
На табло уходит minutes-1: rem_min у оригинала — НОМЕР идущей минуты, а
не остаток целых (старт 60 при rem_tick 719 = «почти 60:00»). Секунды
считаются делением раз в 12 кадров, а не каждый кадр — это единственное
деление на кадровом пути.
* Смерть Кида по образцу оригинала: строка «Press Button to Continue» с
7-го кадра (Kid.alive > 6), 288 тиков = 24 секунды, последние 72 тика
мигание с периодом 12 и звуком 38 на появлении. Промолчал — start_game
(title), нажал Enter/Shift — рестарт уровня. Авто-респавна по таймеру
больше нет. Отпускания клавиш оригинал не ждёт, а мы ждём: Shift у нас
клавиша действия — см. impl_diff.md.
* POP_APP_PLAYING принимает EV_RESTART_INTRO: start_game зовётся прямо из
геймплея, раньше это событие принимал только pause menu.
* expired() загейчен уровнем 13 (seg000:910). Время на уровне Джафара
идёт до открытия двери, но КОНЧИТЬСЯ игра там уже не может — у нас
этого гейта не было, и партия завершалась.
Бюджет: _CODE 23979, куча 263 Б. Host-тесты: 15 наборов.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Эта сессия (меню + текст в служебных полосах):
* Меню: рамка выделения считается от силуэта текста (SEL_PAD сверху и
снизу), а не «на глаз»; все экраны центрируются в игровых 200 строках
(UI_CENTER_TOP/UI_CENTER_FIELD) и в них помещаются; Enter и Space —
равноправные клавиши действия (ui_action_down).
* Settings: убраны SHOW SPRINTER SCREEN и BACK, добавлены DEBUG BAR и
ABOUT. About показывает тот же текст, что стартовый Sprinter screen,
минус строка про клавиши — общий about_text(), чтобы экраны не
разъехались. CONTROLS собирается таблицей и центрируется по
фактическому числу строк.
* GAME PAUSED переехала в нижнюю статус-строку, как в оригинале
(SDLPoP rect_bottom_text = {193,70,202,250}): это состояние программы,
а не пункт меню. POP_HP_Y вынесен в pop_cdraw.h — полосу делят два
модуля.
* pop_status.c (банк 9) — текст в обеих служебных полосах. Нижняя:
порт display_text_bottom + таймера (QUICKSAVE/QUICKLOAD/SOUND ON/OFF,
24 тика). Верхняя отладочная переведена с палочек на текст
«Level ##, Room ##, Speed: …, Sound: …, Immortal #» малым шрифтом, с
своим форматированием чисел (без printf и без деления).
Заявка сообщения — запись одного байта pop_status_msg: резидент W1/W2
не растёт, весь рендер в банке. Бюджет после правок не изменился
(_CODE 23981, куча 267 Б).
* Цена вывода: блит глифа ~4,6 тыс. тактов независимо от размера, поэтому
всё change-driven, отладочная строка перерисовывается ПО ПОЛЯМ, пробелы
не блитятся вовсе, а вход в комнату заливает только игровое поле
(pop_screen_fill_field) — борта от комнаты к комнате не меняются.
* Интро: в PV-сцене зазвучали пропавшие эффекты оригинала — закрытие
ворот (4) и открытие двери покоев (51), из которой входит Джафар.
* docs/status_line_text.md — полная инвентаризация ВСЕХ текстов SDLPoP в
статус-строке: геометрия, семантика text_time_total как идентификатора
сообщения, мигание, рестарт по истечении 36/288.
Вместе с этим выкладывается накопленная работа по оболочке полной игры:
автомат состояний (pop_app), title, intro/PV и cutscene, attract-demo,
Hall of Fame, глобальный таймер, настройки и POP.CFG, модуль палитр и
fade, звуковой набор, host-тесты на новые швы.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>