create a launcher.

this lets you launch into a duktape engine or a quickjs engine, but the
quickjs engine isn't implemented yet.
This commit is contained in:
Fries 2024-06-25 16:39:04 -07:00
parent 63bb2916ca
commit 9369bf4da5
2 changed files with 147 additions and 7 deletions

View file

@ -14,8 +14,8 @@ static float deltatime = 1.0f/60;
static unsigned int green = RGBA(0, 255, 0, 255); static unsigned int green = RGBA(0, 255, 0, 255);
static GRRLIB_ttfFont * font; static GRRLIB_ttfFont * font;
static void duk_fatal_error(void *udata, const char *msg) { static void duk_fatal_error(void *udata, const char * msg) {
const char * err_message_format = "an error has occured: %s"; const char * err_message_format = "a fatal error has occured: %s";
size_t message_size = strlen(err_message_format) + strlen(msg) * sizeof(char *); size_t message_size = strlen(err_message_format) + strlen(msg) * sizeof(char *);
char * message = malloc(message_size); char * message = malloc(message_size);
snprintf(message, message_size, err_message_format, msg); 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) { void duktape(GRRLIB_ttfFont * global_font, bool * running) {
font = global_font; font = global_font;
duk_context * ctx = duk_create_heap(NULL, NULL, NULL, NULL, duk_fatal_error); 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 // call start function
duk_get_global_string(ctx, "start"); 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); duk_pop(ctx);
while (*running) { while (*running) {
@ -48,7 +78,14 @@ void duktape(GRRLIB_ttfFont * global_font, bool * running) {
// call update function // call update function
duk_get_global_string(ctx, "update"); 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); duk_pop(ctx);
GRRLIB_Render(); GRRLIB_Render();
@ -56,5 +93,7 @@ void duktape(GRRLIB_ttfFont * global_font, bool * running) {
const unsigned int endOfFrame = ticks_to_microsecs(gettime()); const unsigned int endOfFrame = ticks_to_microsecs(gettime());
deltatime = (endOfFrame - beginningOfFrame) * MICROSECOND; deltatime = (endOfFrame - beginningOfFrame) * MICROSECOND;
} }
duk_destroy_heap(ctx);
} }

View file

@ -1,5 +1,6 @@
#include <grrlib.h> #include <grrlib.h>
#include <duktape.h> #include <duktape.h>
#include <ogc/pad.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <ogc/lwp_watchdog.h> #include <ogc/lwp_watchdog.h>
@ -7,10 +8,102 @@
#include <data.h> #include <data.h>
#include <duktape_engine.h> #include <duktape_engine.h>
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 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) { int main(int argc, char **argv) {
GRRLIB_SetAntiAliasing(false);
GRRLIB_Init(); GRRLIB_Init();
PAD_Init(); PAD_Init();
@ -21,8 +114,16 @@ int main(int argc, char **argv) {
font = GRRLIB_LoadTTF(pixel_operator_font, pixel_operator_font_size); 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(); GRRLIB_Exit();
return 0; return 0;