diff --git a/source/duktape/duktape_engine.c b/source/duktape/duktape_engine.c index 489672b..19de8e3 100644 --- a/source/duktape/duktape_engine.c +++ b/source/duktape/duktape_engine.c @@ -14,8 +14,8 @@ static float deltatime = 1.0f/60; static unsigned int green = RGBA(0, 255, 0, 255); static GRRLIB_ttfFont * font; -static void duk_fatal_error(void *udata, const char *msg) { - const char * err_message_format = "an error has occured: %s"; +static void duk_fatal_error(void *udata, const char * msg) { + const char * err_message_format = "a fatal error has occured: %s"; size_t message_size = strlen(err_message_format) + strlen(msg) * sizeof(char *); char * message = malloc(message_size); snprintf(message, message_size, err_message_format, msg); @@ -25,6 +25,29 @@ static void duk_fatal_error(void *udata, const char *msg) { } } +static void duk_error_loop(duk_context * ctx, const char * msg) { + const char * err_message_format = "an error has occured: %s"; + size_t message_size = strlen(err_message_format) + strlen(msg) * sizeof(char *); + char * message = malloc(message_size); + snprintf(message, message_size, err_message_format, msg); + bool error_loop_running = true; + + while (error_loop_running) { + PAD_ScanPads(); + unsigned int pressed = PAD_ButtonsDown(0); + + GRRLIB_PrintfTTF(0, 0, font, message, 12, green); + GRRLIB_PrintfTTF(0, 20, font, "Press A to exit", 12, green); + GRRLIB_Render(); + + if (pressed & PAD_BUTTON_A) { + error_loop_running = false; + } + } + + duk_destroy_heap(ctx); +} + void duktape(GRRLIB_ttfFont * global_font, bool * running) { font = global_font; duk_context * ctx = duk_create_heap(NULL, NULL, NULL, NULL, duk_fatal_error); @@ -38,7 +61,14 @@ void duktape(GRRLIB_ttfFont * global_font, bool * running) { // call start function duk_get_global_string(ctx, "start"); - duk_call(ctx, 0); + duk_int_t status = duk_pcall(ctx, 0); + + if (status == DUK_EXEC_ERROR) { + duk_error_loop(ctx, duk_safe_to_string(ctx, -1)); + *running = false; + return; + } + duk_pop(ctx); while (*running) { @@ -48,7 +78,14 @@ void duktape(GRRLIB_ttfFont * global_font, bool * running) { // call update function duk_get_global_string(ctx, "update"); - duk_call(ctx, 0); + duk_int_t status = duk_pcall(ctx, 0); + + if (status == DUK_EXEC_ERROR) { + duk_error_loop(ctx, duk_safe_to_string(ctx, -1)); + *running = false; + return; + } + duk_pop(ctx); GRRLIB_Render(); @@ -56,5 +93,7 @@ void duktape(GRRLIB_ttfFont * global_font, bool * running) { const unsigned int endOfFrame = ticks_to_microsecs(gettime()); deltatime = (endOfFrame - beginningOfFrame) * MICROSECOND; } + + duk_destroy_heap(ctx); } diff --git a/source/main.c b/source/main.c index ae0bf59..6420cc2 100644 --- a/source/main.c +++ b/source/main.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -7,10 +8,102 @@ #include #include -static bool running = true; +#define LENGTH(arr) (sizeof(arr) / sizeof(arr[0])) + +static bool launcher_running = true; +static bool running = false; static GRRLIB_ttfFont * font; +static unsigned int green = RGBA(0, 255, 0, 255); +static unsigned int white = RGBA(255, 255, 255, 255); + +struct menu_item { + const char * message; + void (*entrypoint)(); +}; + +struct menu_items { + size_t selected_index; + struct menu_item * items[2]; +}; + +static struct menu_items items = { + .selected_index = 0, + .items = {} +}; + +static struct menu_item * create_menu_item(const char * message, void (*entrypoint)()) { + struct menu_item * item = malloc(sizeof(struct menu_item)); + item->message = message; + item->entrypoint = entrypoint; + return item; +} + +static void start_duktape() { + running = true; + duktape(font, &running); +} + +static void start_quickjs() { + running = true; + while (running) { + PAD_ScanPads(); + unsigned int pressed = PAD_ButtonsDown(0); + GRRLIB_PrintfTTF(0, 0, font, "QuickJS is not implemented, yet..", 48, RGBA(255, 255, 255, 255)); + GRRLIB_Render(); + if (pressed & PAD_BUTTON_START) { + running = false; + } + } +} + +static void update_menu(unsigned int * pressed) { + if (*pressed & PAD_BUTTON_DOWN) { + int selected_index = items.selected_index; + selected_index += 1; + if (selected_index >= LENGTH(items.items)) { + selected_index = 0; + } + items.selected_index = selected_index; + } else if (*pressed & PAD_BUTTON_UP) { + int selected_index = items.selected_index; + selected_index -= 1; + if (selected_index < 0) { + selected_index = LENGTH(items.items) - 1; + } + items.selected_index = selected_index; + } + + if (*pressed & PAD_BUTTON_A) { + items.items[items.selected_index]->entrypoint(); + } + + for (size_t i = 0; i < LENGTH(items.items); i++) { + unsigned int color; + if (items.selected_index == i) { + color = green; + } else { + color = white; + } + GRRLIB_PrintfTTF(0, 80 + (50 * i), font, items.items[i]->message, 64, color); + } +} + +static void launcher_loop() { + while (launcher_running) { + PAD_ScanPads(); + unsigned int pressed = PAD_ButtonsDown(0); + if (pressed & PAD_BUTTON_START) { + launcher_running = false; + return; + } + GRRLIB_PrintfTTF(0, 0, font, "WiiDuktape Launcher", 64, RGBA(255, 255, 255, 255)); + update_menu(&pressed); + GRRLIB_Render(); + } +} int main(int argc, char **argv) { + GRRLIB_SetAntiAliasing(false); GRRLIB_Init(); PAD_Init(); @@ -21,8 +114,16 @@ int main(int argc, char **argv) { font = GRRLIB_LoadTTF(pixel_operator_font, pixel_operator_font_size); - duktape(font, &running); - + items.items[0] = create_menu_item("Duktape", start_duktape); + items.items[1] = create_menu_item("QuickJS", start_quickjs); + + launcher_loop(); + + for (size_t i = 0; i < LENGTH(items.items); i++) { + // clear out heap allocated memory. + free(items.items[i]); + } + GRRLIB_Exit(); return 0;