diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.c | 174 |
1 files changed, 166 insertions, 8 deletions
@@ -20,18 +20,20 @@ WITH REGARD TO THIS SOFTWARE. | |||
20 | // to act as metronome and achieve analog sync. | 20 | // to act as metronome and achieve analog sync. |
21 | // | 21 | // |
22 | // Quality of life improvements. | 22 | // Quality of life improvements. |
23 | // - Pattern chaining for more than 1 queue and/or song mode. | 23 | // + Add a settings page to change some configuration parameters. |
24 | // - Undo/Redo. | ||
25 | // - Add a settings page to change some configuration parameters. | ||
26 | // - Select + up/down to queue the next pattern as we move to it? | ||
27 | // - Change the cursor, the line is difficult to see. | 24 | // - Change the cursor, the line is difficult to see. |
28 | // - When not on play mode, adjusting a note or a parameter triggers the sound. | 25 | // - When not on play mode, adjusting a note or a parameter triggers the sound. |
29 | // This could get annoying, so maybe it should be a configuration option to | 26 | // This could get annoying, so maybe it should be a configuration option to |
30 | // enable it? | 27 | // enable it? |
28 | // - Pattern chaining for more than 1 queue and/or song mode. | ||
29 | // - Undo/Redo. | ||
30 | // - Select + up/down to queue the next pattern as we move to it? | ||
31 | // | 31 | // |
32 | // Advanced | 32 | // Advanced |
33 | // + Sync via CV by using the link cable. | ||
34 | // - Audio sync by panning left the sound and using right as a click (or | ||
35 | // viceversa, needs to check the standard.) | ||
33 | // - Sync via MIDI via arduinoboy or something similar. | 36 | // - Sync via MIDI via arduinoboy or something similar. |
34 | // - Sync via CV by using the link cable. | ||
35 | // - Add an FM channel using Direct Sound. | 37 | // - Add an FM channel using Direct Sound. |
36 | // - Per trig note probability. | 38 | // - Per trig note probability. |
37 | // - Add an envelope to ch3, would need to work with a timer in order to make | 39 | // - 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. | |||
44 | // Not sure if this is an emulator thing or happens also in hardware. | 46 | // Not sure if this is an emulator thing or happens also in hardware. |
45 | // - Cursor can stay in position instead of dissapering, again I can't | 47 | // - Cursor can stay in position instead of dissapering, again I can't |
46 | // reproduce this right now, just happened randomly. Needs investigation. | 48 | // reproduce this right now, just happened randomly. Needs investigation. |
49 | // + Pattern chaining seems off, it plays the first note of the pattern before | ||
50 | // switching | ||
51 | // + Memory corruption when trying to load a save file. Regression due to | ||
52 | // removal of filesystem.c | ||
47 | // | 53 | // |
48 | 54 | ||
49 | #include "gba/gba.h" | 55 | #include "gba/gba.h" |
@@ -55,7 +61,7 @@ WITH REGARD TO THIS SOFTWARE. | |||
55 | #include "profiling.c" | 61 | #include "profiling.c" |
56 | 62 | ||
57 | void | 63 | void |
58 | render(void) { | 64 | render_sequencer(void) { |
59 | PROF(draw_rect(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1, 1), clear_cycles); | 65 | PROF(draw_rect(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1, 1), clear_cycles); |
60 | if (redraw_trigs) { | 66 | if (redraw_trigs) { |
61 | PROF(draw_triggers(), draw_trigs_cycles); | 67 | PROF(draw_triggers(), draw_trigs_cycles); |
@@ -90,12 +96,164 @@ render(void) { | |||
90 | PROF(draw_parameters(), draw_param_cycles); | 96 | PROF(draw_parameters(), draw_param_cycles); |
91 | redraw_params = false; | 97 | redraw_params = false; |
92 | } | 98 | } |
93 | |||
94 | PROF(draw_cursors(), draw_cursor_cycles); | 99 | PROF(draw_cursors(), draw_cursor_cycles); |
95 | } | 100 | } |
96 | 101 | ||
102 | bool clear_screen = false; | ||
103 | |||
104 | typedef enum Scene { | ||
105 | SCENE_SEQUENCER = 0, | ||
106 | SCENE_SETTINGS, | ||
107 | } Scene; | ||
108 | |||
109 | static scene = SCENE_SETTINGS; | ||
110 | static next_scene = SCENE_SETTINGS; | ||
111 | |||
112 | typedef enum SyncSetting { | ||
113 | SYNC_NONE = 0, | ||
114 | SYNC_OUT_LINK_16, | ||
115 | SYNC_OUT_LINK_8, | ||
116 | SYNC_OUT_LINK_4, | ||
117 | SYNC_NUM, | ||
118 | } SyncSetting; | ||
119 | |||
120 | char * sync_setting_str[] = { | ||
121 | "NONE", | ||
122 | "LINK OUT (16)", | ||
123 | "LINK OUT (8)", | ||
124 | "LINK OUT (4)", | ||
125 | }; | ||
126 | |||
127 | typedef enum ThemeSetting { | ||
128 | THEME_DEFAULT = 0, | ||
129 | } ThemeSetting; | ||
130 | |||
131 | char * theme_setting_str[] = { | ||
132 | "DEFAULT", | ||
133 | }; | ||
134 | |||
135 | typedef enum CursorSetting { | ||
136 | CURSOR_DEFAULT = 0, | ||
137 | } CursorSetting; | ||
138 | |||
139 | char * cursor_setting_str[] = { | ||
140 | "LINE", | ||
141 | }; | ||
142 | |||
143 | typedef struct Settings { | ||
144 | SyncSetting sync; | ||
145 | ThemeSetting theme; | ||
146 | CursorSetting cursor; | ||
147 | } Settings; | ||
148 | |||
149 | static Settings settings = {0}; | ||
150 | static settings_cursor_loc = 0; | ||
151 | |||
152 | void | ||
153 | draw_settings_cursor(void) { | ||
154 | int x = 6; | ||
155 | int y = 17 + settings_cursor_loc * 12; | ||
156 | draw_line(x + 1, y + 3, x + 1, y + 7, COL_CYAN); | ||
157 | draw_line(x + 2, y + 4, x + 2, y + 6, COL_CYAN); | ||
158 | draw_line(x + 3, y + 5, x + 3, y + 5, COL_CYAN); | ||
159 | } | ||
160 | |||
161 | void | ||
162 | render_settings(void) { | ||
163 | PROF(draw_rect(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1, 1), clear_cycles); | ||
164 | txt_drawf_small("settings", 11, 5, COL_FG) | ||
165 | txt_printf("\n\n\n"); | ||
166 | txt_printf(" SYNC: %s\n\n", sync_setting_str[settings.sync]); | ||
167 | txt_printf(" THEME: %s\n\n", theme_setting_str[settings.theme]); | ||
168 | txt_printf(" CURSOR: %s\n\n", cursor_setting_str[settings.cursor]); | ||
169 | txt_render(); | ||
170 | txt_clear(); | ||
171 | draw_settings_cursor(); | ||
172 | } | ||
173 | |||
174 | #define N_SETTINGS 3 | ||
175 | |||
176 | void | ||
177 | handle_settings_input(void) { | ||
178 | if (key_tap(KEY_DOWN)) { | ||
179 | if (settings_cursor_loc == (N_SETTINGS - 1)) { | ||
180 | settings_cursor_loc = 0; | ||
181 | } else { | ||
182 | settings_cursor_loc++; | ||
183 | } | ||
184 | clear_screen = true; | ||
185 | } | ||
186 | if (key_tap(KEY_UP)) { | ||
187 | if (settings_cursor_loc == 0) { | ||
188 | settings_cursor_loc = N_SETTINGS - 1; | ||
189 | } else { | ||
190 | settings_cursor_loc--; | ||
191 | } | ||
192 | clear_screen = true; | ||
193 | } | ||
194 | if (key_tap(KEY_R)) { | ||
195 | switch (settings_cursor_loc) { | ||
196 | case 0: { | ||
197 | if ((settings.sync + 1) >= SYNC_NUM) { | ||
198 | settings.sync = 0; | ||
199 | } else { | ||
200 | settings.sync++; | ||
201 | } | ||
202 | } break; | ||
203 | } | ||
204 | clear_screen = true; | ||
205 | } | ||
206 | if (key_tap(KEY_L)) { | ||
207 | switch (settings_cursor_loc) { | ||
208 | case 0: { | ||
209 | if (settings.sync == 0) { | ||
210 | settings.sync = SYNC_NUM - 1; | ||
211 | } else { | ||
212 | settings.sync--; | ||
213 | } | ||
214 | } break; | ||
215 | } | ||
216 | clear_screen = true; | ||
217 | } | ||
218 | if (key_tap(KEY_B)) { | ||
219 | next_scene = SCENE_SEQUENCER; | ||
220 | } | ||
221 | } | ||
222 | |||
223 | void | ||
224 | render(void) { | ||
225 | if (clear_screen) { | ||
226 | screen_fill(COL_BG); | ||
227 | clear_screen = false; | ||
228 | } | ||
229 | switch (scene) { | ||
230 | case SCENE_SETTINGS: { | ||
231 | render_settings(); | ||
232 | } break; | ||
233 | case SCENE_SEQUENCER: { | ||
234 | render_sequencer(); | ||
235 | } break; | ||
236 | } | ||
237 | } | ||
238 | |||
239 | void | ||
240 | handle_input(void) { | ||
241 | switch (scene) { | ||
242 | case SCENE_SETTINGS: { | ||
243 | handle_settings_input(); | ||
244 | } break; | ||
245 | case SCENE_SEQUENCER: { | ||
246 | handle_sequencer_input(); | ||
247 | } break; | ||
248 | } | ||
249 | } | ||
250 | |||
97 | void | 251 | void |
98 | update(void) { | 252 | update(void) { |
253 | if (next_scene != scene) { | ||
254 | scene = next_scene; | ||
255 | clear_screen = true; | ||
256 | } | ||
99 | last_trig_loc = trig_selection_loc; | 257 | last_trig_loc = trig_selection_loc; |
100 | last_channel_loc = channel_selection_loc; | 258 | last_channel_loc = channel_selection_loc; |
101 | last_pattern_loc = pattern_selection_loc; | 259 | last_pattern_loc = pattern_selection_loc; |
@@ -130,7 +288,7 @@ main(void) { | |||
130 | FRAME_START(); | 288 | FRAME_START(); |
131 | PROF(flip_buffer(), flip_cycles); | 289 | PROF(flip_buffer(), flip_cycles); |
132 | PROF(update(), update_cycles); | 290 | PROF(update(), update_cycles); |
133 | PROF(handle_sequencer_input(), input_cycles); | 291 | PROF(handle_input(), input_cycles); |
134 | PROF(render(), render_cycles); | 292 | PROF(render(), render_cycles); |
135 | FRAME_END(); | 293 | FRAME_END(); |
136 | } | 294 | } |