playlist: implement next and prev

This commit is contained in:
Zack Buhman 2025-06-29 18:57:12 -05:00
parent 4f6fbe2484
commit 19e437d517
10 changed files with 133 additions and 28 deletions

View File

@ -208,6 +208,14 @@ void execute_line(int line_index)
void interrupt() void interrupt()
{ {
if (state.deferred_load_tick == 1) {
deferred_load_finish();
}
if (state.deferred_load_tick > 0) {
state.deferred_load_tick -= 1;
return;
}
if (state.paused) if (state.paused)
return; return;
@ -297,13 +305,36 @@ void init(float clock_multiplier)
state.line_index = 0; state.line_index = 0;
state.pattern_order_table_index = -1; state.pattern_order_table_index = -1;
next_pattern(); next_pattern();
for (int ch = 0; ch < 64; ch++) {
state.channel[ch].keyon = 0;
}
state.paused = false;
printf("tick_rate %d\n", state.tick_rate); printf("tick_rate %d\n", state.tick_rate);
} }
void stop_sound()
{
for (int ch = 0; ch < 64; ch++) {
wait();
bool kyonb = aica_sound.channel[ch].KYONB() != 0;
wait(); aica_sound.channel[ch].KYONB(0);
wait(); aica_sound.channel[ch].RR(0x1f);
state.channel[ch].keyon = kyonb ? 255 : 0;
}
wait(); aica_sound.channel[0].KYONEX(1);
}
void resume_sound()
{
for (int ch = 0; ch < 64; ch++) {
wait(); aica_sound.channel[ch].RR(0xa);
}
}
void pause() void pause()
{ {
state.tmp_paused = state.paused; stop_sound();
state.paused = true; state.paused = true;
} }
@ -312,9 +343,29 @@ void unpause()
state.paused = false; state.paused = false;
} }
void resume() static uint8_t __attribute__((aligned(32))) sample_data[1024 * 1024 * 2];
const int sample_data_length = (sizeof (sample_data));
void deferred_load(int buf)
{ {
state.paused = state.tmp_paused; state.deferred_load_tick = 44100 / 2;
stop_sound();
const float aica_clock_multiplier = 44.1;
state.sample_data_ix = xm_init(&interpreter::state.xm,
buf,
sample_data,
sample_data_length);
interpreter::init(aica_clock_multiplier);
}
void deferred_load_finish()
{
sound::transfer(sample_data, state.sample_data_ix);
resume_sound();
} }
} }

View File

@ -22,7 +22,9 @@ struct interpreter_state {
int line_index; int line_index;
int next_line_index; // within the current pattern int next_line_index; // within the current pattern
bool paused; bool paused;
bool tmp_paused;
int deferred_load_tick;
int sample_data_ix;
struct xm_state xm; struct xm_state xm;
@ -35,4 +37,6 @@ void init(float clock_multiplier);
void pause(); void pause();
void unpause(); void unpause();
void deferred_load(int buf);
void deferred_load_finish();
} }

View File

@ -46,7 +46,7 @@ void vbr600()
; ;
//scene::logo::sound::interrupt(); //scene::logo::sound::interrupt();
//interpreter::interrupt(); interpreter::interrupt();
} else { } else {
serial::string("vbr600\n"); serial::string("vbr600\n");
interrupt_exception(); interrupt_exception();

View File

@ -1,34 +1,46 @@
#include "interpreter.hpp"
#include "sound.hpp"
#include "playlist.hpp"
#include "xm.h" #include "xm.h"
#include "xm/milkypack01.xm.h" #include "xm/milkypack01.xm.h"
#include "xm/CottageFantasy2.xm.h"
const float aica_clock_multiplier = 44.1;
namespace playlist { namespace playlist {
static playlist_item playlist[] = { struct state state = {
{ .playlist_ix = -1
"milkypack01"
}
}; };
const static playlist_item playlist[] = {
{
"leon du star",
(int)&_binary_xm_milkypack01_xm_start,
},
{
"Shiroiii",
(int)&_binary_xm_CottageFantasy2_xm_start,
},
};
void load_xm(float clock_multiplier, int buf) const int playlist_length = (sizeof (playlist)) / (sizeof (playlist[0]));
void next()
{ {
using namespace interpreter; state.playlist_ix += 1;
if (state.playlist_ix >= playlist_length)
state.playlist_ix = 0;
static uint8_t __attribute__((aligned(32))) sample_data[1024 * 1024 * 2]; printf("deferred_load\n");
const int sample_data_length = (sizeof (sample_data)); interpreter::deferred_load(playlist[state.playlist_ix].start);
}
interpreter::pause(); void prev()
{
state.playlist_ix -= 1;
if (state.playlist_ix < 0)
state.playlist_ix = playlist_length - 1;
int sample_data_ix = xm_init(&state.xm, interpreter::deferred_load(playlist[state.playlist_ix].start);
buf,
sample_data,
sample_data_length);
interpreter::init(clock_multiplier);
sound::transfer(sample_data, sample_data_ix);
//printf("tick_rate %d\n", state.tick_rate);
interpreter::resume();
} }
} }

View File

@ -1,6 +1,17 @@
#pragma once
namespace playlist { namespace playlist {
struct playlist_item { struct playlist_item {
const char * const name; const char * const artist;
const int start; const int start;
}; };
struct state {
int playlist_ix;
};
void next();
void prev();
extern struct state state;
} }

View File

@ -10,19 +10,28 @@
#include "widget/button.hpp" #include "widget/button.hpp"
#include "widget/left_aligned.hpp" #include "widget/left_aligned.hpp"
#include "widget/top_aligned.hpp" #include "widget/top_aligned.hpp"
#include "playlist.hpp"
#include "interpreter.hpp"
#include "cursor.hpp" #include "cursor.hpp"
void prev_click() void prev_click()
{ {
printf("prev\n"); printf("prev\n");
playlist::prev();
}
void next_click()
{
printf("next\n");
playlist::prev();
} }
widget::button prev_button(50, 50, "prev", prev_click); widget::button prev_button(50, 50, "prev", prev_click);
widget::button play_button(50, 50, "play"); widget::button play_button(50, 50, "play");
widget::button pause_button(50, 50, "pause"); widget::button pause_button(50, 50, "pause");
widget::button stop_button(50, 50, "stop"); widget::button stop_button(50, 50, "stop");
widget::button next_button(50, 50, "next"); widget::button next_button(50, 50, "next", next_click);
widget::widget * left1_children[] = { widget::widget * left1_children[] = {
&prev_button, &prev_button,
@ -75,6 +84,7 @@ namespace scene::tracker {
void init() void init()
{ {
top.freeze(0, 0); top.freeze(0, 0);
playlist::next();
} }
void update() void update()

BIN
xm/CottageFantasy2.xm Normal file

Binary file not shown.

15
xm/CottageFantasy2.xm.h Normal file
View File

@ -0,0 +1,15 @@
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
extern uint32_t _binary_xm_CottageFantasy2_xm_start __asm("_binary_xm_CottageFantasy2_xm_start");
extern uint32_t _binary_xm_CottageFantasy2_xm_end __asm("_binary_xm_CottageFantasy2_xm_end");
extern uint32_t _binary_xm_CottageFantasy2_xm_size __asm("_binary_xm_CottageFantasy2_xm_size");
#ifdef __cplusplus
}
#endif

Binary file not shown.

View File

@ -1,5 +1,6 @@
XM_OBJ = \ XM_OBJ = \
xm/milkypack01.xm.o xm/milkypack01.xm.o \
xm/CottageFantasy2.xm.o
TEXTURE_OBJ = \ TEXTURE_OBJ = \
font/tandy1k.data.o \ font/tandy1k.data.o \
@ -28,6 +29,7 @@ XM_PLAYER_OBJ = \
src/interpreter.o \ src/interpreter.o \
src/main.o \ src/main.o \
src/malloc.o \ src/malloc.o \
src/playlist.o \
src/scene/logo/scene.o \ src/scene/logo/scene.o \
src/scene/logo/sound.o \ src/scene/logo/sound.o \
src/scene/scene.o \ src/scene/scene.o \