Date 22 complete.
This commit is contained in:
@@ -47,6 +47,9 @@ libhandmade: handmade.cpp
|
|||||||
$(EXE): sdl_handmade.cpp libhandmade
|
$(EXE): sdl_handmade.cpp libhandmade
|
||||||
$(CC) $(FLAGS) $(UFLAGS) $(INCLUDE) sdl_handmade.cpp $(LIBS) $(FRAMEWORKS) -o $@
|
$(CC) $(FLAGS) $(UFLAGS) $(INCLUDE) sdl_handmade.cpp $(LIBS) $(FRAMEWORKS) -o $@
|
||||||
|
|
||||||
|
run:
|
||||||
|
./$(EXE)
|
||||||
|
|
||||||
tags: $(OBJS)
|
tags: $(OBJS)
|
||||||
ctags -R *.h *.c
|
ctags -R *.h *.c
|
||||||
|
|
||||||
|
|||||||
+60
-9
@@ -11,8 +11,12 @@
|
|||||||
|
|
||||||
#include <sys/stat.h> // fstat
|
#include <sys/stat.h> // fstat
|
||||||
#include <fcntl.h> // open
|
#include <fcntl.h> // open
|
||||||
#include <unistd.h> // close, read
|
#include <unistd.h> // close, read, readlink
|
||||||
#include <dlfcn.h> // dlopen
|
#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.
|
// NOTE: This is so it compiles on ARM.
|
||||||
#if __x86_64__ || __i386__
|
#if __x86_64__ || __i386__
|
||||||
@@ -326,17 +330,34 @@ static F32 SDLGetSecondsElapsed(U64 Start, U64 End)
|
|||||||
|
|
||||||
typedef struct sdl_game_code {
|
typedef struct sdl_game_code {
|
||||||
void *GameCodeDLL;
|
void *GameCodeDLL;
|
||||||
|
U32 DLLLastWriteTime;
|
||||||
|
|
||||||
void (*UpdateAndRender)(game_memory *, game_input *, game_offscreen_buffer *, game_sound_output_buffer *);
|
void (*UpdateAndRender)(game_memory *, game_input *, game_offscreen_buffer *, game_sound_output_buffer *);
|
||||||
|
|
||||||
B32 IsValid;
|
B32 IsValid;
|
||||||
} sdl_game_code;
|
} 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};
|
sdl_game_code Result = {0};
|
||||||
|
|
||||||
Result.GameCodeDLL = dlopen("./libhandmade.so", RTLD_NOW);
|
Result.GameCodeDLL = dlopen(DLLPath, RTLD_NOW);
|
||||||
if(Result.GameCodeDLL) {
|
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");
|
Result.UpdateAndRender = (void(*)(game_memory *, game_input *, game_offscreen_buffer *, game_sound_output_buffer *))dlsym(Result.GameCodeDLL, "UpdateAndRender");
|
||||||
if(!Result.UpdateAndRender) {
|
if(!Result.UpdateAndRender) {
|
||||||
// TODO: Diagnostic. dlerror()
|
// TODO: Diagnostic. dlerror()
|
||||||
@@ -362,8 +383,40 @@ static void SDLUnloadGameCode(sdl_game_code *GameCode)
|
|||||||
GameCode->UpdateAndRender = NULL;
|
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[])
|
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)) {
|
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER | SDL_INIT_AUDIO)) {
|
||||||
/* TODO: This didn't work . . . */
|
/* TODO: This didn't work . . . */
|
||||||
}
|
}
|
||||||
@@ -431,8 +484,7 @@ S32 main(S32 argc, char *argv[])
|
|||||||
U64 LastCycleCount;
|
U64 LastCycleCount;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
sdl_game_code Game = SDLLoadGameCode();
|
sdl_game_code Game = SDLLoadGameCode(game_dll_path);
|
||||||
U32 LoadCounter = 0;
|
|
||||||
|
|
||||||
while(GlobalRunning) {
|
while(GlobalRunning) {
|
||||||
LastCounter = SDLGetWallClock();
|
LastCounter = SDLGetWallClock();
|
||||||
@@ -445,12 +497,11 @@ S32 main(S32 argc, char *argv[])
|
|||||||
S32 GameUpdateHz = MonitorRefreshHz / 2;
|
S32 GameUpdateHz = MonitorRefreshHz / 2;
|
||||||
F32 TargetSecondsPerFrame = 1.0f / (F32)GameUpdateHz;
|
F32 TargetSecondsPerFrame = 1.0f / (F32)GameUpdateHz;
|
||||||
|
|
||||||
if(LoadCounter > (U32)(GameUpdateHz * 2)) {
|
U32 NewDLLWriteTime = GetLastWriteTime(game_dll_path);
|
||||||
|
if(NewDLLWriteTime > Game.DLLLastWriteTime) {
|
||||||
SDLUnloadGameCode(&Game);
|
SDLUnloadGameCode(&Game);
|
||||||
Game = SDLLoadGameCode();
|
Game = SDLLoadGameCode(game_dll_path);
|
||||||
LoadCounter = 0;
|
|
||||||
}
|
}
|
||||||
LoadCounter++;
|
|
||||||
|
|
||||||
game_controller_input *OldKeyboardController = GetController(OldInput, 0);
|
game_controller_input *OldKeyboardController = GetController(OldInput, 0);
|
||||||
game_controller_input *NewKeyboardController = GetController(NewInput, 0);
|
game_controller_input *NewKeyboardController = GetController(NewInput, 0);
|
||||||
|
|||||||
Reference in New Issue
Block a user