Prevent non-loop VGM playback overrun

This commit is contained in:
2026-09-15 15:11:24 +03:00
parent 1686838e03
commit c6004c19fb
5 changed files with 12 additions and 11 deletions
Binary file not shown.
BIN
View File
Binary file not shown.
-4
View File
@@ -165,9 +165,6 @@ typedef struct {
/* ── Состояние парсера (глобальные переменные) ───────────────────── */ /* ── Состояние парсера (глобальные переменные) ───────────────────── */
/** 1 = достигнут конец VGM-данных (команда 0x66 или конец файла) */
extern volatile uint8_t vgm_song_ended;
/** 1 = пауза (буферы заполняются тишиной) */ /** 1 = пауза (буферы заполняются тишиной) */
extern uint8_t vgm_paused; extern uint8_t vgm_paused;
@@ -249,7 +246,6 @@ void vgm_fill_buffer(uint8_t buf_idx);
/** /**
* Перемотать VGM на точку петли (если установлена). * Перемотать VGM на точку петли (если установлена).
* Сбрасывает vgm_song_ended = 0 при успехе.
* @return 1 = петля есть (перемотано), 0 = нет петли * @return 1 = петля есть (перемотано), 0 = нет петли
*/ */
uint8_t vgm_rewind_to_loop(void); uint8_t vgm_rewind_to_loop(void);
-4
View File
@@ -33,7 +33,6 @@
#include "../inc/freq_lut_map.h" #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_paused; // 1 = пауза (остановить таймер, не обнулять vgm_sec_budget)
uint8_t vgm_cur_page; // текущая VPL-страница для чтения данных (0..N) uint8_t vgm_cur_page; // текущая VPL-страница для чтения данных (0..N)
uint16_t vgm_read_ptr; // смещение в окне #C000 для чтения следующего байта VGM-потока uint16_t vgm_read_ptr; // смещение в окне #C000 для чтения следующего байта VGM-потока
@@ -249,7 +248,6 @@ uint8_t vgm_parse_header(void)
uint32_t clk; uint32_t clk;
vgm_chip_entry_t *e; vgm_chip_entry_t *e;
vgm_song_ended = 0;
vgm_paused = 0; vgm_paused = 0;
vgm_chip_count = 0; vgm_chip_count = 0;
vgm_chip_type = VGM_CHIP_NONE; vgm_chip_type = VGM_CHIP_NONE;
@@ -1752,7 +1750,6 @@ ym2_fm_passthru:;
if (fb_op == 0x66) if (fb_op == 0x66)
{ {
if (fb_is_vgm) { if (fb_is_vgm) {
vgm_song_ended = 1;
vgm_cur_page = fb_cpg; vgm_cur_page = fb_cpg;
vgm_read_ptr = (uint16_t)fb_rp; vgm_read_ptr = (uint16_t)fb_rp;
vgm_wait_accum = fb_wacc; vgm_wait_accum = fb_wacc;
@@ -2009,7 +2006,6 @@ uint8_t vgm_rewind_to_loop(void)
vgm_cur_page = vgm_loop_page; vgm_cur_page = vgm_loop_page;
vgm_read_ptr = vgm_loop_addr; vgm_read_ptr = vgm_loop_addr;
vgm_song_ended = 0;
vgm_wait_accum = 0; vgm_wait_accum = 0;
vgm_sec_budget = ISR_FREQ; vgm_sec_budget = ISR_FREQ;
wc_mngcvpl(vgm_cur_page); wc_mngcvpl(vgm_cur_page);
+12 -3
View File
@@ -861,6 +861,18 @@ void update_playback_info(void)
sec = isr_play_seconds; 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); sec_changed = (sec != s_last_displayed_sec);
loop_changed = (vgm_loop_count != s_last_loop_count); loop_changed = (vgm_loop_count != s_last_loop_count);
@@ -1124,21 +1136,18 @@ void main(void)
if (key == KEY_NEXT) if (key == KEY_NEXT)
{ {
vgm_hl_pos = vgm_hl_abort_pos; vgm_hl_pos = vgm_hl_abort_pos;
vgm_song_ended = 0;
wc_exit_code = WC_EXIT_NEXT; wc_exit_code = WC_EXIT_NEXT;
instant_abort(); instant_abort();
} }
else if (key == KEY_PREV) else if (key == KEY_PREV)
{ {
vgm_hl_pos = vgm_hl_abort_pos; vgm_hl_pos = vgm_hl_abort_pos;
vgm_song_ended = 0;
wc_exit_code = WC_EXIT_PREV; wc_exit_code = WC_EXIT_PREV;
instant_abort(); instant_abort();
} }
else if (key == KEY_ESC) else if (key == KEY_ESC)
{ {
vgm_hl_pos = vgm_hl_abort_pos; vgm_hl_pos = vgm_hl_abort_pos;
vgm_song_ended = 0;
wc_exit_code = WC_EXIT_ESC; wc_exit_code = WC_EXIT_ESC;
instant_abort(); instant_abort();
} }