Files
Sprinter-SDCC/applications/PoP/roomtest/pop_cutscene.h
T
snark13 d86adc54c4 Музыка: озвучена вся заставка, тайминги сведены со шкалой оригинала
Добавлены треки 54 (тема титров), 50/53/52 (три реплики сцены с
принцессой и Джафаром) — заставка звучит целиком, как в оригинале.

pop_music: два слота EMM. Реплики идут встык, паузы под загрузку нет,
поэтому следующая читается в НЕ играющий слот, а play подменяет
резидентную таблицу страниц. Своей копии таблицы слот не держит — её
хранит блок EMM. Плюс постраничная загрузка (load_begin/load_step):
страница стоит 33 мс, четверть логического кадра сцены, и подкачка
посреди анимации не видна.

Тайминги: все длительности сцен — в тиках оригинала (60 Гц), перевод в
кадры луча делает POP_T60. Пока сцены были немыми, разбег в 20 % был
незаметен; с музыкой реплика кончалась раньше картинки. Переведены
титры, история, хвост после PV и пейсинг самой PV-сцены.

Паузы, которые оригинал отмеряет концом сэмпла, теперь равны реальной
длине наших записей: конец m50 на тике 846, вход Джафара 1046, уход
2073, конец сцены 2500 (было 1959). Fade перед PV сдвинут так, чтобы
полная темнота наступала в тот же момент трека, что у SDLPoP: их fade
длиннее нашего на 123 тика, наш полосовой переход длиннее на 16.

Финальная сцена: убраны песочные часы — end_sequence_anim не трогает
hourglass_state, а reset_cutscene его обнулил. Уровень пройден, время
больше не идёт.

Проверено в MAME: цепочка 54 -> 55 -> 50 -> 53 -> 52 отыгрывается
целиком, интро доходит до демо-режима. Host-тесты: 15 наборов.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 20:17:38 +03:00

57 lines
2.2 KiB
C

/*
* pop_cutscene.h — маленький интерпретатор сценариев экранных сцен (FG8).
*
* Данные сценария статичны, состояние — только pc и счётчик ожидания. Это
* пригодится и PV intro, и сценам перед уровнями FG9: графика/звук остаются
* у вызывающего режима, а не тащатся в общий механизм.
*/
#ifndef POP_CUTSCENE_H
#define POP_CUTSCENE_H
#include <stdint.h>
/* ТИК ОРИГИНАЛА -> НАШ КАДР. Все длительности сцен взяты из SDLPoP в его
* тиках (BASE_FPS = 60), а ждём мы кадрами луча (50 Гц). Без пересчёта
* сцена идёт на 20 % дольше — незаметно, пока она немая, и сразу слышно,
* когда под неё играет музыка: реплика кончается раньше картинки.
* Аргумент — константа сценария, до 2500, так что 32-бит не возникает. */
#define POP_T60(t) ((uint16_t)((uint16_t)(t) * 5u / 6u))
typedef enum {
POP_CS_SHOW = 1, /* arg: номер готового кадра */
POP_CS_WAIT, /* arg: число логических кадров */
POP_CS_PALETTE, /* arg: номер палитрового набора */
POP_CS_FADE_IN,
POP_CS_FADE_OUT,
POP_CS_FLASH, /* arg: длительность белой вспышки */
POP_CS_END
} pop_cs_opcode_t;
typedef struct {
uint8_t op;
uint16_t arg;
} pop_cs_cmd_t;
typedef struct {
const pop_cs_cmd_t *script;
uint8_t pc;
uint16_t waiting;
uint8_t ended;
} pop_cutscene_t;
typedef enum {
POP_CS_EVENT_NONE = 0,
POP_CS_EVENT_SHOW,
POP_CS_EVENT_PALETTE,
POP_CS_EVENT_FADE_IN,
POP_CS_EVENT_FADE_OUT,
POP_CS_EVENT_FLASH,
POP_CS_EVENT_END
} pop_cs_event_t;
void pop_cutscene_begin(pop_cutscene_t *cs, const pop_cs_cmd_t *script) __banked;
void pop_cutscene_abort(pop_cutscene_t *cs) __banked;
pop_cs_event_t pop_cutscene_tick(pop_cutscene_t *cs, uint16_t *arg) __banked;
#endif /* POP_CUTSCENE_H */