140 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			140 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#include "scripting.h"
 | 
						|
#include "util.h"
 | 
						|
#include "context.h"
 | 
						|
 | 
						|
#include <SDL2/SDL.h>
 | 
						|
#include <umka_api.h>
 | 
						|
#include <physfs.h>
 | 
						|
 | 
						|
#include <stdbool.h>
 | 
						|
#include <string.h>
 | 
						|
#include <stdio.h>
 | 
						|
 | 
						|
static void msgbox(UmkaStackSlot *params, UmkaStackSlot *result) {
 | 
						|
    SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION,
 | 
						|
                                params[1].ptrVal, params[0].ptrVal, NULL);
 | 
						|
}
 | 
						|
 | 
						|
static void umka_log_info(UmkaStackSlot *params, UmkaStackSlot *result) {
 | 
						|
    log_info(params[0].ptrVal);
 | 
						|
}
 | 
						|
 | 
						|
static void umka_log_critical(UmkaStackSlot *params, UmkaStackSlot *result) {
 | 
						|
    log_critical(params[0].ptrVal);
 | 
						|
}
 | 
						|
 | 
						|
static void umka_log_warn(UmkaStackSlot *params, UmkaStackSlot *result) {
 | 
						|
    log_warn(params[0].ptrVal);
 | 
						|
}
 | 
						|
 | 
						|
static void is_action_pressed(UmkaStackSlot *params, UmkaStackSlot *result) {
 | 
						|
    struct state *state = params[1].ptrVal;
 | 
						|
    t_ctx *ctx = state->hidden_ptr;
 | 
						|
    
 | 
						|
    bool value = input_is_action_pressed(&ctx->input, params[0].ptrVal);
 | 
						|
    result->uintVal = value;
 | 
						|
}
 | 
						|
 | 
						|
static void is_action_just_pressed(UmkaStackSlot *params, UmkaStackSlot *result) {
 | 
						|
    struct state *state = params[1].ptrVal;
 | 
						|
    t_ctx *ctx = state->hidden_ptr;
 | 
						|
    
 | 
						|
    bool value = input_is_action_just_pressed(&ctx->input, params[0].ptrVal);
 | 
						|
    result->uintVal = value;
 | 
						|
}
 | 
						|
 | 
						|
static void is_action_just_released(UmkaStackSlot *params, UmkaStackSlot *result) {
 | 
						|
    struct state *state = params[1].ptrVal;
 | 
						|
    t_ctx *ctx = state->hidden_ptr;
 | 
						|
    
 | 
						|
    bool value = input_is_action_just_released(&ctx->input, params[0].ptrVal);
 | 
						|
    result->uintVal = value;
 | 
						|
}
 | 
						|
 | 
						|
static void get_action_position(UmkaStackSlot *params, UmkaStackSlot *result) {
 | 
						|
    struct state *state = params[2].ptrVal;
 | 
						|
    t_ctx *ctx = state->hidden_ptr;
 | 
						|
 | 
						|
    t_fvec2 *position = params[0].ptrVal;
 | 
						|
    *position = input_get_action_position(&ctx->input, params[1].ptrVal);
 | 
						|
 | 
						|
    // the result is in a hidden result pointer allocated by Umka
 | 
						|
    result->ptrVal = params[0].ptrVal;
 | 
						|
}
 | 
						|
 | 
						|
static void register_api(void *umka) {
 | 
						|
    umkaAddFunc(umka, "msgbox", msgbox);
 | 
						|
    umkaAddFunc(umka, "logInfo", umka_log_info);
 | 
						|
    umkaAddFunc(umka, "logCritical", umka_log_critical);
 | 
						|
    umkaAddFunc(umka, "logWarn", umka_log_warn);
 | 
						|
    umkaAddFunc(umka, "cImplIsActionPressed", is_action_pressed);
 | 
						|
    umkaAddFunc(umka, "cImplIsActionJustPressed", is_action_just_pressed);
 | 
						|
    umkaAddFunc(umka, "cImplIsActionJustReleased", is_action_just_released);
 | 
						|
    umkaAddFunc(umka, "getActionPosition", get_action_position);
 | 
						|
}
 | 
						|
 | 
						|
bool scripting_init(t_ctx *ctx) {
 | 
						|
    if (!PHYSFS_exists("/scripts/main.um")) {
 | 
						|
        CRY("Failed to initialize scripting", "Could not find a main.um (we need it)");
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
    
 | 
						|
    ctx->umka = umkaAlloc();
 | 
						|
 | 
						|
    char *main_script = file_to_str("/scripts/main.um");
 | 
						|
    bool umka_ok = umkaInit(ctx->umka,
 | 
						|
                            "main.um",
 | 
						|
                            main_script,
 | 
						|
                            UMKA_STACK_SIZE,
 | 
						|
                            NULL,
 | 
						|
                            ctx->argc,
 | 
						|
                            ctx->argv,
 | 
						|
                            false,
 | 
						|
                            false,
 | 
						|
                            NULL);
 | 
						|
    free(main_script);
 | 
						|
 | 
						|
    if (!umka_ok) {
 | 
						|
        CRY("Failed to initialize scripting", "Unknown Umka error");
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    /* all Umka files are compiled even if they're never used */    
 | 
						|
    char **dir_file_names = PHYSFS_enumerateFiles("/scripts");
 | 
						|
    for (char **i = dir_file_names; *i != NULL; ++i) {
 | 
						|
        char *file_name = *i;
 | 
						|
 | 
						|
        if (!strends(file_name, ".um"))
 | 
						|
            continue;
 | 
						|
 | 
						|
        /* got this one already */
 | 
						|
        if (strcmp(file_name, "main.um") == 0)
 | 
						|
            continue;
 | 
						|
        
 | 
						|
        /* need to figure out the actual path (as opposed to the lone file name) */
 | 
						|
        const char *path_prefix = "/scripts/";
 | 
						|
        size_t path_size = snprintf(NULL, 0, "%s%s", path_prefix, file_name) + 1;
 | 
						|
        char *path = cmalloc(path_size);
 | 
						|
        snprintf(path, path_size, "%s%s", path_prefix, file_name);
 | 
						|
 | 
						|
        char *contents = file_to_str(path);
 | 
						|
        umkaAddModule(ctx->umka, file_name, contents);
 | 
						|
 | 
						|
        free(path);
 | 
						|
        free(contents);
 | 
						|
    }
 | 
						|
    PHYSFS_freeList(dir_file_names);
 | 
						|
 | 
						|
    register_api(ctx->umka);
 | 
						|
    if (!umkaCompile(ctx->umka)) {
 | 
						|
        cry_umka(ctx->umka);
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
void scripting_deinit(t_ctx *ctx) {
 | 
						|
    umkaFree(ctx->umka);
 | 
						|
}
 |