SprPoP: звук мигания, равномерные часы, полоса HP после рестарта, надпись ждёт мелодию
Четыре правки прогона 2026-08-31. Две ПРОВЕРЕНЫ пользователем в MAME (звук мигания, порядок «мелодия -> надпись»), две ждут проверки — образ собран. ЗВУК МИГАНИЯ (проверено). Упаковщик научился синтезировать ноты PC- спикера в обычный сэмпл: заголовок с темпом, тройки «частота + длина», меандр на нашей частоте вывода. Берём из нот ТОЛЬКО номера, которых нет ни в оцифровке, ни среди мелодий, — иначе синтез перекрыл бы музыку, которую мы играем из MUS/. На поставке SDLPoP это ровно один номер: 38, сигнал под мигание «Press Button»; 31, 34 и 42 там пустые заглушки. Громкость по слуховой проверке снижена вдвое (44 -> 22): на полном размахе сигнал перекрикивал игру. EXE не меняется — раскладка читается с диска, набор занял те же 9 страниц. НАДПИСЬ ЖДЁТ МЕЛОДИЮ (проверено). Порядок оригинала: ветка мёртвого (seg006:1351) на седьмом шаге выходит, пока звук играет, и «Press Button» появляется только после музыки смерти. Чтобы ожидание не было принудительным, три быстрых пути (Ctrl+A, обе быстрые загрузки, пункты меню) музыку глушат — оригинал при Ctrl+A делает то же (seg000:0617). Обычная кнопка во время мелодии не действует: она ответ НА надпись. ЧАСЫ (ждёт проверки). Тик стоит столько кадров ЛУЧА, сколько их в кадре режима NORMAL, поэтому FAST/FASTEST больше не ускоряют время. Считаем ФАКТИЧЕСКИ прошедшие кадры луча, а не ожидаемый делитель: логический кадр не всегда укладывается в бюджет, и часы «по делителю» шли рывками (первый прогон это показал — «несколько секунд быстро, потом притормаживание»). Вклад одного вызова ограничен, иначе пауза и меню прыгнули бы вперёд. Четыре новых теста: NORMAL не сдвинулся ни на тик (и вне боя, и в бою), FAST и FASTEST держат реальное время. ПОЛОСА HP ПОСЛЕ Ctrl+A (ждёт проверки). Корень: счётчик считает СТРАНИЦЫ, а тратился по КАДРАМ — между двумя вызовами переворота может не быть, и оба прохода уходили в одну страницу, вторая оставалась с делениями прошлого боя. Теперь проход тратится только при смене gfx_get_draw_page(). Плюс полная чистка всей ширины при инвалидации: старая полоса могла заходить под статус-текст, где щадящая чистка её не трогала; текст сразу перезапрашивается. Все 16 наборов host-тестов зелёные, check_bank_calls чист. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011MsUsEFAQfsjjQpJ7RtKVY
This commit is contained in:
@@ -40,6 +40,7 @@
|
||||
#include <gfx.h>
|
||||
#include <kbd_raw.h>
|
||||
#include "pop_status.h"
|
||||
#include "pop_music.h" /* ждём конец музыки смерти и глушим её по ответу */
|
||||
#include "pop_ui.h"
|
||||
#include "pop_font.h"
|
||||
#include "pop_bg.h" /* POP_YOFF */
|
||||
@@ -461,14 +462,25 @@ static void dbg_scan(uint8_t room)
|
||||
#define DEAD_BLINK 72 /* последние 72 тика строка мигает */
|
||||
#define SND_BLINK 38 /* sound_38_blink на каждом появлении */
|
||||
|
||||
/* Кадр, с которого пошёл отсчёт надписи. НЕ равен DEAD_SETTLE: оригинал
|
||||
* не показывает «Press Button», пока звучит музыка смерти — ветка мёртвого
|
||||
* (seg006:1351) на седьмом шаге просто выходит, если звук ещё играет, и
|
||||
* надпись появляется только после него. Поэтому момент старта отсчёта
|
||||
* заранее не известен и запоминается здесь. */
|
||||
static uint16_t dead_base;
|
||||
static uint8_t dead_armed; /* всё отпущено — можно принимать нажатие */
|
||||
|
||||
uint8_t pop_dead_prompt(uint16_t frames) __banked
|
||||
{
|
||||
uint16_t rem;
|
||||
|
||||
if (frames < DEAD_SETTLE) return 0;
|
||||
if (frames == DEAD_SETTLE) {
|
||||
if (frames < DEAD_SETTLE) { dead_base = 0; return 0; }
|
||||
if (dead_base == 0) {
|
||||
/* Ждём, пока домолчит музыка смерти — порядок оригинала. Пока она
|
||||
* играет, надписи нет и отсчёт 288 не идёт; прервать ожидание можно
|
||||
* Ctrl+A или быстрой загрузкой, они музыку глушат. */
|
||||
if (pop_music_active()) return 0;
|
||||
dead_base = frames;
|
||||
msg_set(POP_MSG_PRESS_BUTTON, 0, MSG_HOLD);
|
||||
pop_show_time = 0; /* иначе поверх ляжет время (seg006:1365) */
|
||||
dead_armed = 0;
|
||||
@@ -477,7 +489,7 @@ uint8_t pop_dead_prompt(uint16_t frames) __banked
|
||||
|
||||
/* Свой отсчёт, а не pop_status_ticks: тот 8-битный, а здесь нужно 288.
|
||||
* Кадры смерти считает вызывающий, так что хватает вычитания. */
|
||||
rem = (uint16_t)(frames - DEAD_SETTLE);
|
||||
rem = (uint16_t)(frames - dead_base);
|
||||
rem = (uint16_t)(rem >= DEAD_TICKS ? 0 : DEAD_TICKS - rem);
|
||||
if (rem == 0) {
|
||||
/* Игрок промолчал все 24 секунды — оригинал зовёт start_game(),
|
||||
@@ -519,6 +531,8 @@ uint8_t pop_dead_prompt(uint16_t frames) __banked
|
||||
if (!any) return 0;
|
||||
}
|
||||
dead_armed = 0;
|
||||
dead_base = 0;
|
||||
pop_music_stop(); /* игрок ответил — доигрывать не заставляем */
|
||||
msg_set(POP_MSG_NONE, 0, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user