diff --git a/src/interpreter.cpp b/src/interpreter.cpp index defcc86..6197eb7 100644 --- a/src/interpreter.cpp +++ b/src/interpreter.cpp @@ -208,6 +208,14 @@ void execute_line(int line_index) 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) return; @@ -297,13 +305,36 @@ void init(float clock_multiplier) state.line_index = 0; state.pattern_order_table_index = -1; 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); } +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() { - state.tmp_paused = state.paused; + stop_sound(); state.paused = true; } @@ -312,9 +343,29 @@ void unpause() 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(); } } diff --git a/src/interpreter.hpp b/src/interpreter.hpp index 0465282..f70d0cf 100644 --- a/src/interpreter.hpp +++ b/src/interpreter.hpp @@ -22,7 +22,9 @@ struct interpreter_state { int line_index; int next_line_index; // within the current pattern bool paused; - bool tmp_paused; + + int deferred_load_tick; + int sample_data_ix; struct xm_state xm; @@ -35,4 +37,6 @@ void init(float clock_multiplier); void pause(); void unpause(); +void deferred_load(int buf); +void deferred_load_finish(); } diff --git a/src/main.cpp b/src/main.cpp index a0cb425..d1fba35 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -46,7 +46,7 @@ void vbr600() ; //scene::logo::sound::interrupt(); - //interpreter::interrupt(); + interpreter::interrupt(); } else { serial::string("vbr600\n"); interrupt_exception(); diff --git a/src/playlist.cpp b/src/playlist.cpp index e078123..555b3ae 100644 --- a/src/playlist.cpp +++ b/src/playlist.cpp @@ -1,34 +1,46 @@ +#include "interpreter.hpp" +#include "sound.hpp" +#include "playlist.hpp" + #include "xm.h" #include "xm/milkypack01.xm.h" - -const float aica_clock_multiplier = 44.1; +#include "xm/CottageFantasy2.xm.h" namespace playlist { - static playlist_item playlist[] = { - { - "milkypack01" - } + struct state state = { + .playlist_ix = -1 }; + 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]; - const int sample_data_length = (sizeof (sample_data)); + printf("deferred_load\n"); + 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, - 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(); + interpreter::deferred_load(playlist[state.playlist_ix].start); } } diff --git a/src/playlist.hpp b/src/playlist.hpp index 6c304aa..d8c413d 100644 --- a/src/playlist.hpp +++ b/src/playlist.hpp @@ -1,6 +1,17 @@ +#pragma once + namespace playlist { struct playlist_item { - const char * const name; + const char * const artist; const int start; }; + + struct state { + int playlist_ix; + }; + + void next(); + void prev(); + + extern struct state state; } diff --git a/src/scene/tracker/scene.cpp b/src/scene/tracker/scene.cpp index 27af01b..08246a1 100644 --- a/src/scene/tracker/scene.cpp +++ b/src/scene/tracker/scene.cpp @@ -10,19 +10,28 @@ #include "widget/button.hpp" #include "widget/left_aligned.hpp" #include "widget/top_aligned.hpp" +#include "playlist.hpp" +#include "interpreter.hpp" #include "cursor.hpp" void prev_click() { printf("prev\n"); + playlist::prev(); +} + +void next_click() +{ + printf("next\n"); + playlist::prev(); } widget::button prev_button(50, 50, "prev", prev_click); widget::button play_button(50, 50, "play"); widget::button pause_button(50, 50, "pause"); 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[] = { &prev_button, @@ -75,6 +84,7 @@ namespace scene::tracker { void init() { top.freeze(0, 0); + playlist::next(); } void update() diff --git a/xm/CottageFantasy2.xm b/xm/CottageFantasy2.xm new file mode 100644 index 0000000..67e836a Binary files /dev/null and b/xm/CottageFantasy2.xm differ diff --git a/xm/CottageFantasy2.xm.h b/xm/CottageFantasy2.xm.h new file mode 100644 index 0000000..038316a --- /dev/null +++ b/xm/CottageFantasy2.xm.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#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 diff --git a/xm/milkypack01.xm b/xm/milkypack01.xm index 7bc7008..84d6531 100644 Binary files a/xm/milkypack01.xm and b/xm/milkypack01.xm differ diff --git a/xm_player.mk b/xm_player.mk index 3cec341..c421959 100644 --- a/xm_player.mk +++ b/xm_player.mk @@ -1,5 +1,6 @@ XM_OBJ = \ - xm/milkypack01.xm.o + xm/milkypack01.xm.o \ + xm/CottageFantasy2.xm.o TEXTURE_OBJ = \ font/tandy1k.data.o \ @@ -28,6 +29,7 @@ XM_PLAYER_OBJ = \ src/interpreter.o \ src/main.o \ src/malloc.o \ + src/playlist.o \ src/scene/logo/scene.o \ src/scene/logo/sound.o \ src/scene/scene.o \