diff --git a/DiskRef/WC/VGMPLAY.WMF b/DiskRef/WC/VGMPLAY.WMF index 8531f8a..6f253eb 100644 Binary files a/DiskRef/WC/VGMPLAY.WMF and b/DiskRef/WC/VGMPLAY.WMF differ diff --git a/VGMPLAY.WMF b/VGMPLAY.WMF index 8531f8a..6f253eb 100644 Binary files a/VGMPLAY.WMF and b/VGMPLAY.WMF differ diff --git a/src_sdcc/inc/vgm.h b/src_sdcc/inc/vgm.h index c40cfc7..8943782 100644 --- a/src_sdcc/inc/vgm.h +++ b/src_sdcc/inc/vgm.h @@ -165,9 +165,6 @@ typedef struct { /* ── Состояние парсера (глобальные переменные) ───────────────────── */ -/** 1 = достигнут конец VGM-данных (команда 0x66 или конец файла) */ -extern volatile uint8_t vgm_song_ended; - /** 1 = пауза (буферы заполняются тишиной) */ extern uint8_t vgm_paused; @@ -249,7 +246,6 @@ void vgm_fill_buffer(uint8_t buf_idx); /** * Перемотать VGM на точку петли (если установлена). - * Сбрасывает vgm_song_ended = 0 при успехе. * @return 1 = петля есть (перемотано), 0 = нет петли */ uint8_t vgm_rewind_to_loop(void); diff --git a/src_sdcc/lib/vgm.c b/src_sdcc/lib/vgm.c index ae059c1..e246b96 100644 --- a/src_sdcc/lib/vgm.c +++ b/src_sdcc/lib/vgm.c @@ -33,7 +33,6 @@ #include "../inc/freq_lut_map.h" /* ── Состояние парсера ──────────────────────────────────────────────── */ -volatile uint8_t vgm_song_ended; // 1 = достигнут конец (0x66), main loop может остановить воспроизведение uint8_t vgm_paused; // 1 = пауза (остановить таймер, не обнулять vgm_sec_budget) uint8_t vgm_cur_page; // текущая VPL-страница для чтения данных (0..N) uint16_t vgm_read_ptr; // смещение в окне #C000 для чтения следующего байта VGM-потока @@ -249,7 +248,6 @@ uint8_t vgm_parse_header(void) uint32_t clk; vgm_chip_entry_t *e; - vgm_song_ended = 0; vgm_paused = 0; vgm_chip_count = 0; vgm_chip_type = VGM_CHIP_NONE; @@ -1752,7 +1750,6 @@ ym2_fm_passthru:; if (fb_op == 0x66) { if (fb_is_vgm) { - vgm_song_ended = 1; vgm_cur_page = fb_cpg; vgm_read_ptr = (uint16_t)fb_rp; vgm_wait_accum = fb_wacc; @@ -2009,7 +2006,6 @@ uint8_t vgm_rewind_to_loop(void) vgm_cur_page = vgm_loop_page; vgm_read_ptr = vgm_loop_addr; - vgm_song_ended = 0; vgm_wait_accum = 0; vgm_sec_budget = ISR_FREQ; wc_mngcvpl(vgm_cur_page); diff --git a/src_sdcc/main.c b/src_sdcc/main.c index dfa1cad..a647348 100644 --- a/src_sdcc/main.c +++ b/src_sdcc/main.c @@ -861,6 +861,18 @@ void update_playback_info(void) sec = isr_play_seconds; + /* Страховка для VGM без разрешённого loop. Нормальный путь + * заканчивается на opcode 0x66; если нестандартный хвост до него не + * дошёл, не оставляем OPL4 удерживать последнюю ноту бесконечно. + * Две секунды запаса покрывают округление total_samples и уже + * поставленные в ISR команды. */ + if (!vgm_loop_enabled && vgm_total_seconds && + sec >= (uint16_t)(vgm_total_seconds + 2u)) + { + vgm_hl_pos = vgm_hl_abort_pos; + instant_abort(); + } + sec_changed = (sec != s_last_displayed_sec); loop_changed = (vgm_loop_count != s_last_loop_count); @@ -1124,21 +1136,18 @@ void main(void) if (key == KEY_NEXT) { vgm_hl_pos = vgm_hl_abort_pos; - vgm_song_ended = 0; wc_exit_code = WC_EXIT_NEXT; instant_abort(); } else if (key == KEY_PREV) { vgm_hl_pos = vgm_hl_abort_pos; - vgm_song_ended = 0; wc_exit_code = WC_EXIT_PREV; instant_abort(); } else if (key == KEY_ESC) { vgm_hl_pos = vgm_hl_abort_pos; - vgm_song_ended = 0; wc_exit_code = WC_EXIT_ESC; instant_abort(); }