Files
Sprinter-SDCC/applications/PoP/roomtest/pop_status.h
T
snark13 4a939e42f8 Катсцены: тайминги, часы и «время вышло» — по оригиналу; тумблер музыки
ТАЙМИНГИ. Треки заставок между уровнями длиннее самих сцен (27 — 10,7 с
против 2,6 с картинки), и оригинал их не обрывает: load_intro гасит экран
и возвращает управление, а звук продолжает играть поверх загрузки уровня
и первых секунд игры (seg001:690). Мы глушили CBL на выходе — музыка
обрывалась на полуслове. Больше не глушим.

«ВРЕМЯ ВЫШЛО». Оригинал (seg001:04D3) не зовёт ни одного init_*: на
экране пустая комната и ОСТАНОВИВШИЕСЯ часы (state 7, струйки песка
нет). Мы показывали готовую композицию с принцессой и полными часами —
противоположное по смыслу. Теперь это живая сцена без персонажей,
102 кадра, и трек 36 дослушивается под чёрным экраном, как в оригинале.

ПЕСОЧНЫЕ ЧАСЫ. Сцена «времени мало» (cutscene_12) шла статической
композицией, куда упаковщик запёк res953 — ПОЛНЫЕ часы. Отсюда и
наблюдение «чем меньше времени, тем полнее часы»: картинка была одна и та
же независимо от таймера. Сделана живой (cut_scene_12_short: принцесса
стоит правее, через два кадра оборачивается), часы берутся от
pre_hourglass_state. Заодно: при state 7 струйка песка не рисуется.

МУЗЫКА — СВОЙ ТУМБЛЕР. Settings -> MUSIC, Ctrl+M и статус в debug bar.
Флаг pop_mus_want отдельный от звукового: музыка у нас поток с диска, и
выключают её по другим причинам, чем эффекты; выключение обрывает текущий
трек, эффекты продолжают звучать. Строка-заглушка GAMEPLAY PROFILE
(«VANILLA ONLY») уступила место MUSIC — на десятую строку экрана не
хватает. Подписи тумблеров в debug bar сокращены до S:/M:/I:.

БАГИ. После меню персонаж оставался невидимым до первого движения:
снимок слота продолжал утверждать, что кадр на странице уже нарисован.
Общая pop_cd_forget() теперь зовётся после меню, QuickLoad и переворота
экрана. «QUICKLOAD» мигал через кадр — pop_status_show_now снимал бит
видимой страницы, а её успевало переписать восстановление комнаты.

Host-тесты: 15 наборов. Проверено в MAME: debug bar, выход из меню.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-26 09:28:36 +03:00

85 lines
5.6 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* pop_status.h — ТЕКСТ в двух служебных полосах экрана (банк 9).
*
* Нижняя (полоса HP) — статус-строка оригинала: порт display_text_bottom
* (seg008:2644) и пары text_time_total/text_time_remaining. Полный
* разбор всех сообщений SDLPoP — ../docs/status_line_text.md.
* Верхняя — наша отладочная строка (была палочками, теперь текст).
*
* ЗАЯВКА — ОДИН БАЙТ. `pop_status_msg` лежит в W2 и пишется откуда
* угодно простым присваиванием: ни трамплина, ни функции. Всё остальное
* (таймер, перерисовка на обеих страницах, шрифт) делает pop_status_frame()
* из банка 9 — один банковый вызов на кадр, рядом с прежним ярлыком
* комнаты. Так в резиденте W1/W2 не появляется ни кода, ни таблиц строк.
*/
#ifndef POP_STATUS_H
#define POP_STATUS_H
#include <stdint.h>
/* Сообщения нижней полосы. Порядок = таблица строк в pop_status.c. */
enum {
POP_MSG_NONE = 0,
POP_MSG_QUICKSAVE, /* F6 успешно */
POP_MSG_NO_QUICKSAVE, /* F6 не удалось */
POP_MSG_QUICKLOAD, /* F9 успешно */
POP_MSG_NO_QUICKLOAD, /* F9 нечего грузить / битый слот */
POP_MSG_SOUND_ON, /* Ctrl+S */
POP_MSG_SOUND_OFF,
POP_MSG_MUSIC_ON, /* Ctrl+M */
POP_MSG_MUSIC_OFF,
POP_MSG_LEVEL, /* «LEVEL N» — строка собирается с номером */
POP_MSG_MINUTES, /* «N MINUTES LEFT» */
POP_MSG_SECONDS, /* «N SECONDS LEFT» / «1 SECOND LEFT» */
POP_MSG_EXPIRED, /* «TIME HAS EXPIRED!» */
POP_MSG_PRESS_BUTTON, /* Кид мёртв — ждём кнопку (висит бессрочно)*/
POP_MSG_N
};
/* Заявка/текущее сообщение. Пишется откуда угодно: 0 — снять строку,
* POP_MSG_* — показать. Повторная заявка того же номера продлевает показ
* только если строка уже погасла (как у оригинала: он тоже сравнивает). */
extern uint8_t pop_status_msg;
/* Показать сообщение НЕМЕДЛЕННО, до конца кадра: строка выкладывается в
* видимую страницу прямо сейчас. Нужна там, где сразу за вызовом идёт
* длинная операция (QuickSave/QuickLoad): обычная заявка напечаталась бы
* уже ПОСЛЕ фриза, когда объяснять его поздно. */
void pop_status_show_now(uint8_t msg) __banked;
/* Порт show_level (seg008:25A8): заявить «LEVEL N» на старте уровня.
* Сама решает, показывать ли (демо-уровень и финальные номера молчат) —
* вызывающему условий знать не нужно. */
void pop_status_level(void) __banked;
/* Сколько логических кадров сообщение ещё висит; 0 — не висит. Читает
* pop_hp_draw (банк 4), чтобы не затирать чужой текст своим фоном. */
extern uint8_t pop_status_ticks;
/* Горизонтальные границы ТЕКСТА в полосе HP. Ровно промежуток между
* делениями Кида (слева) и стража (справа) — как rect_bottom_text
* {193,70,202,250} у оригинала. */
#define POP_STATUS_L 70
#define POP_STATUS_R 250
/* Раз в логический кадр, ПОСЛЕ pop_hp_draw: тик таймера, перерисовка
* нижней строки и обновление верхней отладочной. Всё change-driven —
* пока ничего не менялось, не рисует вовсе. */
void pop_status_frame(uint8_t room) __banked;
/* Кид мёртв: показать «Press Button to Continue» и ждать кнопку. frames —
* сколько кадров прошло со смерти (труп должен успеть лечь). Возвращает 1
* ОДИН раз, когда игрок нажал — вызывающему остаётся перезапустить уровень.
* Логика живёт в банке, потому что резидент W1 переполнен, а зовут её лишь
* в кадрах смерти.
*
* Возвращает: 0 — ждём дальше; 1 — игрок нажал Enter/Shift, перезапустить
* УРОВЕНЬ; 2 — 288 тиков истекли, уйти в title (порт start_game). */
uint8_t pop_dead_prompt(uint16_t frames) __banked;
/* Заставить перерисовать ОБЕ страницы: звать после того, как полосы
* затёрли чужим содержимым (вход в комнату, выход из меню). */
void pop_status_invalidate(void) __banked;
#endif /* POP_STATUS_H */