Prevent non-loop VGM playback overrun
This commit is contained in:
Binary file not shown.
BIN
Binary file not shown.
@@ -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);
|
||||||
|
|||||||
@@ -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
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user