WiiDuktape/source/duktape/duktape_engine.c

99 lines
2.5 KiB
C
Raw Normal View History

#include <grrlib.h>
#include <duktape.h>
#include <stdio.h>
#include <stdlib.h>
#include <ogc/lwp_watchdog.h>
#include <data.h>
#include <wii_duk.h>
#include <game.h>
#include <microsecond.h>
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 = "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);
while (1) {
GRRLIB_PrintfTTF(0, 0, font, message, 12, green);
GRRLIB_Render();
}
}
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);
// create a wii object on the global object (globalThis)
duk_define_wii_object(ctx, font, running, &deltatime);
duk_put_global_string(ctx, "wii");
// evaluate functions from game.js
duk_eval_string_noresult(ctx, program);
// call start function
duk_get_global_string(ctx, "start");
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) {
const unsigned int beginningOfFrame = ticks_to_microsecs(gettime());
PAD_ScanPads();
// call update function
duk_get_global_string(ctx, "update");
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();
const unsigned int endOfFrame = ticks_to_microsecs(gettime());
deltatime = (endOfFrame - beginningOfFrame) * MICROSECOND;
}
duk_destroy_heap(ctx);
}