From 70b7b9f719ab673ff776cfc0f9b7bc67dc88bac1 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Sun, 28 May 2023 18:54:58 +0200 Subject: Add initial settings page --- src/main.c | 174 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 166 insertions(+), 8 deletions(-) diff --git a/src/main.c b/src/main.c index f9fa018..b2d7a23 100644 --- a/src/main.c +++ b/src/main.c @@ -20,18 +20,20 @@ WITH REGARD TO THIS SOFTWARE. // to act as metronome and achieve analog sync. // // Quality of life improvements. -// - Pattern chaining for more than 1 queue and/or song mode. -// - Undo/Redo. -// - Add a settings page to change some configuration parameters. -// - Select + up/down to queue the next pattern as we move to it? +// + Add a settings page to change some configuration parameters. // - Change the cursor, the line is difficult to see. // - When not on play mode, adjusting a note or a parameter triggers the sound. // This could get annoying, so maybe it should be a configuration option to // enable it? +// - Pattern chaining for more than 1 queue and/or song mode. +// - Undo/Redo. +// - Select + up/down to queue the next pattern as we move to it? // // Advanced +// + Sync via CV by using the link cable. +// - Audio sync by panning left the sound and using right as a click (or +// viceversa, needs to check the standard.) // - Sync via MIDI via arduinoboy or something similar. -// - Sync via CV by using the link cable. // - Add an FM channel using Direct Sound. // - Per trig note probability. // - Add an envelope to ch3, would need to work with a timer in order to make @@ -44,6 +46,10 @@ WITH REGARD TO THIS SOFTWARE. // Not sure if this is an emulator thing or happens also in hardware. // - Cursor can stay in position instead of dissapering, again I can't // reproduce this right now, just happened randomly. Needs investigation. +// + Pattern chaining seems off, it plays the first note of the pattern before +// switching +// + Memory corruption when trying to load a save file. Regression due to +// removal of filesystem.c // #include "gba/gba.h" @@ -55,7 +61,7 @@ WITH REGARD TO THIS SOFTWARE. #include "profiling.c" void -render(void) { +render_sequencer(void) { PROF(draw_rect(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1, 1), clear_cycles); if (redraw_trigs) { PROF(draw_triggers(), draw_trigs_cycles); @@ -90,12 +96,164 @@ render(void) { PROF(draw_parameters(), draw_param_cycles); redraw_params = false; } - PROF(draw_cursors(), draw_cursor_cycles); } +bool clear_screen = false; + +typedef enum Scene { + SCENE_SEQUENCER = 0, + SCENE_SETTINGS, +} Scene; + +static scene = SCENE_SETTINGS; +static next_scene = SCENE_SETTINGS; + +typedef enum SyncSetting { + SYNC_NONE = 0, + SYNC_OUT_LINK_16, + SYNC_OUT_LINK_8, + SYNC_OUT_LINK_4, + SYNC_NUM, +} SyncSetting; + +char * sync_setting_str[] = { + "NONE", + "LINK OUT (16)", + "LINK OUT (8)", + "LINK OUT (4)", +}; + +typedef enum ThemeSetting { + THEME_DEFAULT = 0, +} ThemeSetting; + +char * theme_setting_str[] = { + "DEFAULT", +}; + +typedef enum CursorSetting { + CURSOR_DEFAULT = 0, +} CursorSetting; + +char * cursor_setting_str[] = { + "LINE", +}; + +typedef struct Settings { + SyncSetting sync; + ThemeSetting theme; + CursorSetting cursor; +} Settings; + +static Settings settings = {0}; +static settings_cursor_loc = 0; + +void +draw_settings_cursor(void) { + int x = 6; + int y = 17 + settings_cursor_loc * 12; + draw_line(x + 1, y + 3, x + 1, y + 7, COL_CYAN); + draw_line(x + 2, y + 4, x + 2, y + 6, COL_CYAN); + draw_line(x + 3, y + 5, x + 3, y + 5, COL_CYAN); +} + +void +render_settings(void) { + PROF(draw_rect(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1, 1), clear_cycles); + txt_drawf_small("settings", 11, 5, COL_FG) + txt_printf("\n\n\n"); + txt_printf(" SYNC: %s\n\n", sync_setting_str[settings.sync]); + txt_printf(" THEME: %s\n\n", theme_setting_str[settings.theme]); + txt_printf(" CURSOR: %s\n\n", cursor_setting_str[settings.cursor]); + txt_render(); + txt_clear(); + draw_settings_cursor(); +} + +#define N_SETTINGS 3 + +void +handle_settings_input(void) { + if (key_tap(KEY_DOWN)) { + if (settings_cursor_loc == (N_SETTINGS - 1)) { + settings_cursor_loc = 0; + } else { + settings_cursor_loc++; + } + clear_screen = true; + } + if (key_tap(KEY_UP)) { + if (settings_cursor_loc == 0) { + settings_cursor_loc = N_SETTINGS - 1; + } else { + settings_cursor_loc--; + } + clear_screen = true; + } + if (key_tap(KEY_R)) { + switch (settings_cursor_loc) { + case 0: { + if ((settings.sync + 1) >= SYNC_NUM) { + settings.sync = 0; + } else { + settings.sync++; + } + } break; + } + clear_screen = true; + } + if (key_tap(KEY_L)) { + switch (settings_cursor_loc) { + case 0: { + if (settings.sync == 0) { + settings.sync = SYNC_NUM - 1; + } else { + settings.sync--; + } + } break; + } + clear_screen = true; + } + if (key_tap(KEY_B)) { + next_scene = SCENE_SEQUENCER; + } +} + +void +render(void) { + if (clear_screen) { + screen_fill(COL_BG); + clear_screen = false; + } + switch (scene) { + case SCENE_SETTINGS: { + render_settings(); + } break; + case SCENE_SEQUENCER: { + render_sequencer(); + } break; + } +} + +void +handle_input(void) { + switch (scene) { + case SCENE_SETTINGS: { + handle_settings_input(); + } break; + case SCENE_SEQUENCER: { + handle_sequencer_input(); + } break; + } +} + void update(void) { + if (next_scene != scene) { + scene = next_scene; + clear_screen = true; + } last_trig_loc = trig_selection_loc; last_channel_loc = channel_selection_loc; last_pattern_loc = pattern_selection_loc; @@ -130,7 +288,7 @@ main(void) { FRAME_START(); PROF(flip_buffer(), flip_cycles); PROF(update(), update_cycles); - PROF(handle_sequencer_input(), input_cycles); + PROF(handle_input(), input_cycles); PROF(render(), render_cycles); FRAME_END(); } -- cgit v1.2.1