Date 22 complete.

This commit is contained in:
2026-03-19 15:54:13 -07:00
parent 92c5a75c05
commit fc0c70ad61
2 changed files with 63 additions and 9 deletions
+60 -9
View File
@@ -11,8 +11,12 @@
#include <sys/stat.h> // fstat
#include <fcntl.h> // open
#include <unistd.h> // close, read
#include <unistd.h> // close, read, readlink
#include <dlfcn.h> // dlopen
#include <sys/stat.h> // stat
#if __APPLE__ && __MACH__
#include <mach-o/dyld.h>
#endif
// NOTE: This is so it compiles on ARM.
#if __x86_64__ || __i386__
@@ -326,17 +330,34 @@ static F32 SDLGetSecondsElapsed(U64 Start, U64 End)
typedef struct sdl_game_code {
void *GameCodeDLL;
U32 DLLLastWriteTime;
void (*UpdateAndRender)(game_memory *, game_input *, game_offscreen_buffer *, game_sound_output_buffer *);
B32 IsValid;
} sdl_game_code;
static sdl_game_code SDLLoadGameCode()
static U32 GetLastWriteTime(const char *FileName)
{
struct stat file_info = {0};
if(stat(FileName, &file_info) != 0) {
// TODO: Diagnostic. perror("stat failed");
}
return (U32)file_info.st_mtime;
}
#define GAME_DLL_NAME "libhandmade.so"
static sdl_game_code SDLLoadGameCode(char *DLLPath)
{
sdl_game_code Result = {0};
Result.GameCodeDLL = dlopen("./libhandmade.so", RTLD_NOW);
Result.GameCodeDLL = dlopen(DLLPath, RTLD_NOW);
if(Result.GameCodeDLL) {
Result.DLLLastWriteTime = GetLastWriteTime(DLLPath);
Result.UpdateAndRender = (void(*)(game_memory *, game_input *, game_offscreen_buffer *, game_sound_output_buffer *))dlsym(Result.GameCodeDLL, "UpdateAndRender");
if(!Result.UpdateAndRender) {
// TODO: Diagnostic. dlerror()
@@ -362,8 +383,40 @@ static void SDLUnloadGameCode(sdl_game_code *GameCode)
GameCode->UpdateAndRender = NULL;
}
char *GetExecutablePath()
{
static char path[1024] = ""; // NOTE: We choose 1024 only because MacOS's MAXPATHLEN says such a value.
ssize_t size = (ssize_t)sizeof(path); // WARNING: size_t is usually an unsigned integer, whilst ssize_t is signed. We don't care because the path is not long.
#if __APPLE__ && __MACH__
if(_NSGetExecutablePath(path, &size) != 0) { // NOTE: Not an absolute path.
// TODO: Diagnostics.
}
#else
size = readlink("/proc/self/exe", path, size - 1);
if(size != -1) {
path[size] = '\0';
} else {
// TODO: Diagnostics.
}
#endif
return path;
}
S32 main(S32 argc, char *argv[])
{
char *path = GetExecutablePath();
U32 len = strlen(path);
U32 i = len;
while(path[i] != '/' || i == 0) {
i--;
}
path[i+1] = '\0';
char game_dll_path[1024];
snprintf(game_dll_path, sizeof(game_dll_path), "%s%s", path, GAME_DLL_NAME);
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER | SDL_INIT_AUDIO)) {
/* TODO: This didn't work . . . */
}
@@ -431,8 +484,7 @@ S32 main(S32 argc, char *argv[])
U64 LastCycleCount;
#endif
sdl_game_code Game = SDLLoadGameCode();
U32 LoadCounter = 0;
sdl_game_code Game = SDLLoadGameCode(game_dll_path);
while(GlobalRunning) {
LastCounter = SDLGetWallClock();
@@ -445,12 +497,11 @@ S32 main(S32 argc, char *argv[])
S32 GameUpdateHz = MonitorRefreshHz / 2;
F32 TargetSecondsPerFrame = 1.0f / (F32)GameUpdateHz;
if(LoadCounter > (U32)(GameUpdateHz * 2)) {
U32 NewDLLWriteTime = GetLastWriteTime(game_dll_path);
if(NewDLLWriteTime > Game.DLLLastWriteTime) {
SDLUnloadGameCode(&Game);
Game = SDLLoadGameCode();
LoadCounter = 0;
Game = SDLLoadGameCode(game_dll_path);
}
LoadCounter++;
game_controller_input *OldKeyboardController = GetController(OldInput, 0);
game_controller_input *NewKeyboardController = GetController(NewInput, 0);