#include #include #include #include #include "include/raylib.h" #include "game.h" #include "game_data.h" struct GameAPI { void* lib_handle; time_t last_write_time; void (*init)(GameState*); void (*update)(GameState*); void (*draw)(GameState*); void (*cleanup)(GameState*); }; time_t get_file_write_time(const char* path) { struct stat file_stat; if (stat(path, &file_stat) == 0) { return file_stat.st_mtime; } return 0; } bool load_game_api(GameAPI* api) { const char* lib_path = "./game.so"; time_t write_time = get_file_write_time(lib_path); if (write_time <= api->last_write_time) { return false; // No changes } if (api->lib_handle) { dlclose(api->lib_handle); } api->lib_handle = dlopen(lib_path, RTLD_NOW); if (!api->lib_handle) { printf("Failed to load game.so: %s\n", dlerror()); return false; } api->init = (void(*)(GameState*))dlsym(api->lib_handle, "game_init"); api->update = (void(*)(GameState*))dlsym(api->lib_handle, "game_update"); api->draw = (void(*)(GameState*))dlsym(api->lib_handle, "game_draw"); api->cleanup = (void(*)(GameState*))dlsym(api->lib_handle, "game_cleanup"); api->last_write_time = write_time; printf("Reloaded game.so\n"); return true; } int main(void) { SetTraceLogLevel(4); InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Tiny Knights"); int monitor = GetCurrentMonitor(); int monitor_width = GetMonitorWidth(monitor); int monitor_height = GetMonitorHeight(monitor); int win_pos_x = monitor_width / 2 - SCREEN_WIDTH / 2; int win_pos_y = monitor_height / 2 - SCREEN_HEIGHT / 2; SetWindowPosition(win_pos_x, win_pos_y); SetTargetFPS(TARGET_FPS); HideCursor(); GameAPI api = {}; GameState state = {}; state.camera.zoom = 1.0f; api.init(&state); // Assets assets = api.init(&state); GameState game = {}; game.knights = (Knight*)calloc(MAX_KNIGHTS, sizeof(Knight)); game.anim_playbacks = (SpriteAnimationPlayback*)calloc(MAX_KNIGHTS, sizeof(SpriteAnimationPlayback)); const int entities = MAX_KNIGHTS; for (int i = 0; i < entities; i++) { f32 rand_x = GetRandomValue(165, 1130); f32 rand_y = 100 + ((float)950 / (float)entities) * i; game.knights[i].position = {rand_x,rand_y}; PlayAnimation(ANIM_KNIGHT_IDLE, knight_anims, &game.anim_playbacks[i]); int rand_frame = GetRandomValue(0, knight_anims[ANIM_KNIGHT_IDLE].total_frames); game.anim_playbacks[i].current_frame = rand_frame; } game.entity_count = entities; api.update(&game); while (!WindowShouldClose()) { game.frame_count++; // float dt = GetFrameTime(); api.update(&state); api.draw(&state); } free(game.knights); free(game.anim_playbacks); // for (int i = 0; i < TEXTURES_BUF_SIZE; i++) { // UnloadTexture(assets.textures[i]); // } // free(assets.textures); CloseWindow(); return 0; }