@@ -72,6 +72,7 @@ typedef struct {
7272 uint8_t last_state ;
7373 uint8_t ring_i ;
7474} ButtonState ;
75+ // W, S, A, D, I, K, J, L
7576uint button_pins [] = { 5 , 7 , 6 , 8 , 12 , 14 , 13 , 15 };
7677static ButtonState button_states [ARR_LEN (button_pins )] = {0 };
7778
@@ -248,6 +249,25 @@ static int load_new_scripts(void) {
248249 }
249250#endif
250251
252+ typedef enum {
253+ NEW_SLOT ,
254+ RUN_GAME ,
255+ DELETE_CONFIRM
256+ } Welcome_Screen ;
257+
258+ int count_digits (uint32_t number ) {
259+ if (number < 10 ) return 1 ;
260+ if (number < 100 ) return 2 ;
261+ if (number < 1000 ) return 3 ;
262+ if (number < 10000 ) return 4 ;
263+ if (number < 100000 ) return 5 ;
264+ if (number < 1000000 ) return 6 ;
265+ if (number < 10000000 ) return 7 ;
266+ if (number < 100000000 ) return 8 ;
267+ if (number < 1000000000 ) return 9 ;
268+ return 10 ;
269+ }
270+
251271int main () {
252272 timer_hw -> dbgpause = 0 ;
253273
@@ -265,74 +285,173 @@ int main() {
265285 jerry_init (JERRY_INIT_MEM_STATS );
266286 init (sprite_free_jerry_object ); // TODO: document
267287
268- while (!save_read ()) {
269- // No game stored in memory
270- strcpy (errorbuf , " \n"
271- " \n"
272- " \n"
273- " \n"
274- " \n"
275- " \n"
276- " \n"
277- " PLEASE UPLOAD \n"
278- " A GAME \n"
279- " \n"
280- " \n"
281- " \n"
282- " \n"
283- " \n"
284- " sprig.hackclub.com \n" );
285- render_errorbuf ();
286- st7735_fill_start ();
287- render (st7735_fill_send );
288- st7735_fill_finish ();
288+ // Start a core to listen for keypresses.
289+ multicore_reset_core1 ();
289290
290- load_new_scripts ();
291- }
291+ // update_save_version(); // init here to avoid irqs on other core
292292
293- // Start a core to listen for keypresses.
294- multicore_launch_core1 (core1_entry );
293+ multicore_launch_core1 (core1_entry );
295294
296- /**
297- * We get a bunch of fake keypresses at startup, so we need to
298- * drain them from the FIFO queue.
299- *
300- * What really needs to be done here is to have button_init
301- * record when it starts so that we can ignore keypresses after
302- * that timestamp.
303- */
304- sleep_ms (50 );
305- while (multicore_fifo_rvalid ()) multicore_fifo_pop_blocking ();
295+ /**
296+ * We get a bunch of fake keypresses at startup, so we need to
297+ * drain them from the FIFO queue.
298+ *
299+ * What really needs to be done here is to have button_init
300+ * record when it starts so that we can ignore keypresses after
301+ * that timestamp.
302+ */
303+ sleep_ms (50 );
304+ while (multicore_fifo_rvalid ()) multicore_fifo_pop_blocking ();
306305
307- /**
308- * Wait for a keypress to start the game.
309- *
310- * This is important so games with e.g. infinite loops don't
311- * brick the device as soon as they start up.
312- */
313- while (!multicore_fifo_rvalid ()) {
314- strcpy (errorbuf , " \n"
315- " \n"
316- " \n"
317- " \n"
318- " \n"
319- " \n"
320- " \n"
321- " PRESS ANY BUTTON \n"
322- " TO RUN \n"
323- " \n"
324- " \n"
325- " \n"
326- " \n"
327- " \n"
328- " sprig.hackclub.com \n" );
329- render_errorbuf ();
330- st7735_fill_start ();
331- render (st7735_fill_send );
332- st7735_fill_finish ();
306+ int games_i = 0 ;
333307
334- load_new_scripts ();
335- }
308+ int games_len = 8 ;
309+ Game * games = malloc (games_len * sizeof (Game ));
310+
311+ Welcome_Screen welcome_state = NEW_SLOT ;
312+
313+ for (;;) {
314+
315+ if (games_i >= games_len && games_i != 0 ) {
316+ games_i = games_len - 1 ;
317+ }
318+
319+ if (welcome_state == DELETE_CONFIRM ) {
320+ // no-op
321+ } else if (games_len == 0 ) {
322+ welcome_state = NEW_SLOT ;
323+ } else {
324+ welcome_state = RUN_GAME ;
325+ set_game (games [games_i ]);
326+ }
327+
328+ /**
329+ * Wait for a keypress to start the game.
330+ * This is important so games with e.g. infinite loops don't
331+ * brick the device as soon as they start up.
332+ */
333+
334+ if (multicore_fifo_rvalid ()) {
335+ uint32_t c = multicore_fifo_pop_blocking ();
336+
337+ if (welcome_state == DELETE_CONFIRM ) {
338+ if (c == 7 ) { // S
339+ welcome_state = RUN_GAME ;
340+ } else if (c == 5 ) { // W
341+ delete_game (games [games_i ]);
342+ welcome_state = RUN_GAME ;
343+ continue ;
344+ }
345+ } else if (c == 6 ) { // A
346+ if (games_i > 0 ) games_i -- ;
347+ } else if (c == 8 ) { // D
348+ if (games_i < games_len - 1 ) games_i ++ ;
349+ } else if (c == 7 && welcome_state == RUN_GAME ) { // S
350+ welcome_state = DELETE_CONFIRM ;
351+ } else if (welcome_state == RUN_GAME && c == 5 ) { // other button
352+ break ;
353+ }
354+ }
355+
356+ games_len = get_games (& games , games_len );
357+
358+ switch (welcome_state ) {
359+ case NEW_SLOT :
360+ strcpy (errorbuf , " \n"
361+ " \n"
362+ " \n"
363+ " \n"
364+ " \n"
365+ " \n"
366+ " Please upload \n"
367+ " a game. \n"
368+ " \n"
369+ " \n"
370+ " \n"
371+ " \n"
372+ " \n"
373+ " \n"
374+ " sprig.hackclub.com \n"
375+ );
376+ break ;
377+ case RUN_GAME : {
378+ char game_padding [] = " " ;
379+ char size_padding [] = " " ;
380+
381+ game_padding [
382+ 20
383+ - count_digits (games_i + 1 )
384+ - count_digits (games_len )
385+ - 8 // 7 at first + 1 slash
386+ ] = '\0' ;
387+
388+ size_padding [
389+ 20
390+ - count_digits (GAME_SLOTS (games [games_i ].size_b ))
391+ - count_digits (MAX_SLOTS )
392+ - 8 // 7 at first + 1 slash
393+ ] = '\0' ;
394+
395+ // 6lines
396+ char game_split_lines [] = {
397+ " \n"
398+ " \n"
399+ " \n"
400+ " \n"
401+ " \n"
402+ " \n"
403+ };
404+
405+ for (int i = 0 ; i * 17 < strlen (games [games_i ].name ); i ++ ) { // 20 - 3 buffer = 17
406+ memcpy (& game_split_lines [i * 21 + 1 ], & games [games_i ].name [i * 17 ],
407+ strlen (games [games_i ].name ) - i * 17 < 17 ? strlen (games [games_i ].name ) - i * 17 : 17 );
408+ }
409+
410+
411+ sprintf (errorbuf ,
412+ " \n"
413+ " \n"
414+ "%s"
415+ " \n"
416+ " Game: %d/%d%s\n"
417+ " Size: %lu/%d%s\n"
418+ " \n"
419+ " W: PLAY \n"
420+ " S: DELETE \n"
421+ " <- A , D -> \n" ,
422+ game_split_lines ,
423+ games_i + 1 , games_len , game_padding ,
424+ GAME_SLOTS (games [games_i ].size_b ), MAX_SLOTS , size_padding );
425+ break ;
426+ }
427+ case DELETE_CONFIRM : {
428+ strcpy (errorbuf , " \n"
429+ " \n"
430+ " \n"
431+ " \n"
432+ " \n"
433+ " Do you really \n"
434+ " want to delete \n"
435+ " this game? \n"
436+ " \n"
437+ " \n"
438+ " W: confirm \n"
439+ " S: exit \n"
440+ " \n"
441+ " \n"
442+ " sprig.hackclub.com \n"
443+ );
444+ break ;
445+ }
446+ }
447+
448+ render_errorbuf ();
449+ st7735_fill_start ();
450+ render (st7735_fill_send );
451+ st7735_fill_finish ();
452+
453+ load_new_scripts ();
454+ }
336455
337456 // Wow, we can actually run a game now!
338457
0 commit comments