SprPoP: единые часы в сцене с Джафаром + конец уровня ждёт свою мелодию
1. СЦЕНА С ДЖАФАРОМ — ОДНИ ЧАСЫ, КАДРЫ ЛУЧА. Было две шкалы, и выбор между ними делался гонкой на старте сцены: одна выборка pop_snd_tick через кадр, «успел ли диск раскрутить звук». От прогона к прогону сцена шла то по тикам насоса CBL, то по кадрам луча, и кода реплики приходилась каждый раз на другое место картинки (наблюдение пользователя). Насос был нужен потому, что кадр рисовался дольше своего интервала; теперь отрисовка разложена по интервалам (pv_restore_bg), и счёт кадров честен — ветка насоса убрана целиком. 2. ПОДКАЧКА ТРЕКА — ПОЛСТРАНИЦЫ ЗА ШАГ (pop_music_load_step). 8 КБ ≈ 16 мс влезают в кадровый интервал, целая страница (33 мс) не влезала и растягивала кадр сцены. В сцене шаг остаётся безусловным (иначе реплики не успевали грузиться, memory pv_music_stall_regression) и оплачивается ровно одним интервалом. 3. КОНЕЦ УРОВНЯ ЖДЁТ МЕЛОДИЮ. Оригинал (seg003:387, play_level_2) не сменяет уровень, пока `check_sound_playing()`: экран пройденного уровня живёт с анимацией факелов, пока звучит трек. Мы уходили на смену сразу и обрывали мелодию на первых нотах. Теперь ждём большего из двух: pop_music_busy() и счётчика pop_endmus_left по длине записи (gen/pop_music_ticks.h) — второе нужно потому, что при ВЫКЛЮЧЕННОЙ музыке busy ложен, а оригинал выдерживает паузу и молча. Стартовый уровень возвращён на 1 (отладочный LEVEL=14 был только для замера). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -357,6 +357,7 @@ int main(void)
|
||||
* девелоперская сборка может до title держать дворец LEVEL=11. */
|
||||
if (pop_app_state == POP_APP_DEMO) {
|
||||
pop_next_level = 0;
|
||||
pop_endmus_left = 0;
|
||||
pop_seamless = 0;
|
||||
pop_checkpoint = 0;
|
||||
if (pop_level_switch() != 0) {
|
||||
@@ -765,9 +766,28 @@ int main(void)
|
||||
/* Смена уровня целиком уехала в банк 8 (pop_level_change): это
|
||||
* событие раз в несколько минут, а кода на нём было под сотню строк
|
||||
* в самом горячем месте программы — резидент W1 у нас в дефиците. */
|
||||
if (!is_demo && pop_next_level != pop_current_level &&
|
||||
pop_level_change(back) != 0) {
|
||||
failed = 1; quit = 1; break;
|
||||
if (!is_demo && pop_next_level != pop_current_level) {
|
||||
/* КОНЕЦ УРОВНЯ ЖДЁТ МЕЛОДИЮ (порт seg003:387, play_level_2):
|
||||
*
|
||||
* if (next_level == current_level || check_sound_playing())
|
||||
* draw_game_frame(); ... // экран уровня живёт
|
||||
* else { stop_sounds(); return next_level; }
|
||||
*
|
||||
* То есть пройденный уровень остаётся на экране — с анимацией
|
||||
* факелов, идущим таймером и всем прочим — ровно столько,
|
||||
* сколько звучит трек конца уровня; мы же уходили на смену
|
||||
* уровня сразу и обрывали мелодию на первых нотах.
|
||||
*
|
||||
* «Звучит» проверяем двумя способами: pop_music_busy() пока
|
||||
* трек играет и счётчик pop_endmus_left по длине записи (его
|
||||
* взводит play_seq вместе с самим треком) — иначе с
|
||||
* ВЫКЛЮЧЕННОЙ музыкой паузы не было бы вовсе, а оригинал
|
||||
* выдерживает её и молча. */
|
||||
if (pop_endmus_left) pop_endmus_left--;
|
||||
if (!pop_endmus_left && !pop_music_busy() &&
|
||||
pop_level_change(back) != 0) {
|
||||
failed = 1; quit = 1; break;
|
||||
}
|
||||
}
|
||||
if (!is_demo && pop_kid_dead) { /* demo после смерти завершается, без respawn */
|
||||
dead_frames++;
|
||||
|
||||
Reference in New Issue
Block a user