Day 24 done.

This commit is contained in:
2026-03-23 20:15:02 -07:00
parent 907d4e9dde
commit e9d0377882
2 changed files with 101 additions and 44 deletions
+94 -44
View File
@@ -13,7 +13,7 @@
#include <sys/stat.h> /* fstat */
#include <fcntl.h> /* open */
#include <unistd.h> /* close, write, read, readlink */
#include <unistd.h> /* close, write, read, readlink, unlink */
#include <dlfcn.h> /* dlopen */
#include <sys/stat.h> /* stat */
#if __APPLE__ && __MACH__
@@ -35,13 +35,21 @@ SDL_GameController *ControllerHandles[MAX_CONTROLLERS];
static offscreen_buffer GlobalBackbuffer;
static S32 str_len(char *str)
{
S32 count = 0;
while(*str++)
count++;
return count;
}
static U32 SafeTruncateUInt64(U64 Value)
{
U32 Result;
Assert(Value <= 0xFFFFFFFF);
Result = (U32)Value;
return Result;
return Result;
}
debug_read_file_result DEBUGPlatformReadEntireFile(const char *Filename)
@@ -165,11 +173,20 @@ static void SDLDisplayBufferInWindow(offscreen_buffer Buffer,
SDL_Window *Window,
SDL_Renderer *Renderer)
{
SDL_Rect dest_rect;
if(SDL_UpdateTexture(Buffer.Texture, 0, Buffer.Memory, Buffer.Pitch)) {
/* TODO: Do something about this error! */
}
SDL_RenderCopy(Renderer, Buffer.Texture, 0, 0);
/* TODO: We temporarily introduce the target rectangle to avoid
* stretching the canvas. */
/* SDL_RenderCopy(Renderer, Buffer.Texture, 0, 0); */
dest_rect.x = 0;
dest_rect.y = 0;
dest_rect.w = 500;
dest_rect.h = 500;
SDL_RenderCopy(Renderer, Buffer.Texture, 0, (const SDL_Rect *)(&dest_rect));
SDL_RenderPresent(Renderer);
}
@@ -268,13 +285,18 @@ static void HandleEvent(SDL_Event *Event)
case SDL_WINDOWEVENT: {
switch(Event->window.event) {
/* TODO: We temporarily disable for ease of writing the
* rendering code. */
#if 0
case SDL_WINDOWEVENT_SIZE_CHANGED: {
sdl_window_dimension Dimension;
Dimension = SDLGetWindowDimension(Window);
/* TODO: For now we fix the width and height. */
SDLResizeTexture(&GlobalBackbuffer, Renderer,
Dimension.Width, Dimension.Height);
} break;
#endif
case SDL_WINDOWEVENT_EXPOSED: {
} break;
@@ -295,15 +317,32 @@ static void HandleEvent(SDL_Event *Event)
}
}
static void SDLGetInputFileLocation(sdl_state *SDLState, char *path,
size_t path_size, S32 SlotIndex)
{
const char *file_name = "loop.hmi";
Assert(SlotIndex == 1);
snprintf(path, path_size, "%s%s", SDLState->EXEDirPath, file_name);
}
static void SDLBeginRecordingInput(sdl_state *SDLState,
S32 InputRecordingIndex)
{
char *FileName;
char FileName[SDL_STATE_PATH_SIZE];
SDLGetInputFileLocation(SDLState, FileName, sizeof(FileName),
InputRecordingIndex);
SDLState->InputRecordingIndex = InputRecordingIndex;
FileName = "foo.hmi";
if(unlink(FileName) != 0) {
/* TODO: Diagnostics . . . */
}
SDLState->RecordingHandle =
open((const char *)FileName, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR |
open(FileName, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR |
S_IRGRP | S_IROTH);
write(SDLState->RecordingHandle, SDLState->GameMmemoryBlock,
(size_t)(SDLState->TotalSize));
@@ -318,13 +357,15 @@ static void SDLEndRecordingInput(sdl_state *SDLState)
static void SDLBeginInputPlayback(sdl_state *SDLState,
S32 InputPlayingIndex)
{
char FileName[SDL_STATE_PATH_SIZE];
ssize_t size;
char *FileName;
SDLGetInputFileLocation(SDLState, FileName, sizeof(FileName),
InputPlayingIndex);
SDLState->InputPlayingIndex = InputPlayingIndex;
FileName = "foo.hmi";
SDLState->PlaybackHandle =
open((const char *)FileName, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR |
open(FileName, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR |
S_IRGRP | S_IROTH);
size = read(SDLState->PlaybackHandle, SDLState->GameMmemoryBlock,
(size_t)(SDLState->TotalSize));
@@ -352,6 +393,7 @@ static void SDLPlaybackInput(sdl_state *SDLState, game_input *NewInput)
PlayingIndex = SDLState->InputPlayingIndex;
SDLEndInputPlayback(SDLState);
SDLBeginInputPlayback(SDLState, PlayingIndex);
size = read(SDLState->PlaybackHandle, NewInput, sizeof(*NewInput));
}
}
@@ -522,6 +564,7 @@ static U32 GetLastWriteTime(const char *FileName)
memset(&file_info, 0, sizeof(file_info));
if(stat(FileName, &file_info) != 0) {
/* TODO: Diagnostic. perror("stat failed"); */
perror("stat failed");
}
return (U32)file_info.st_mtime;
@@ -566,56 +609,63 @@ static void SDLUnloadGameCode(sdl_game_code *GameCode)
GameCode->UpdateAndRender = NULL;
}
char *GetExecutablePath()
void GetExecutablePath(char *path, size_t path_size)
{
static char path[1024];
size_t path_size;
#if __APPLE__ && __MACH__
U32 size;
#else
ssize_t size;
#endif
/* NOTE: We choose 1024 only because MacOS's MAXPATHLEN says such a
* value. For example, linux/limits.h PATH_MAX says 4096. */
path[0] = '\0';
path_size = sizeof(path);
if(path_size > 0) {
path[0] = '\0';
#if __APPLE__ && __MACH__
size = path_size;
if(_NSGetExecutablePath(path, &size) != 0) { /* NOTE: Not an absolute
path. */
/* TODO: Diagnostics. */
}
size = path_size;
if(_NSGetExecutablePath(path, &size) != 0) { /* NOTE: Not an
absolute
path. */
/* TODO: Diagnostics. */
}
#else
size = readlink("/proc/self/exe", path, path_size - 1);
if(size != -1) {
path[size] = '\0';
} else {
/* TODO: Diagnostics. */
}
size = readlink("/proc/self/exe", path, path_size - 1);
if(size != -1) {
path[size] = '\0';
} else {
/* TODO: Diagnostics. */
}
#endif
return path;
}
}
S32 main(S32 argc, char *argv[])
static void SDLGetEXEDirPath(char *path, size_t path_size)
{
char *path;
U32 len, i;
char game_dll_path[1024];
SDL_Window *Window;
path = GetExecutablePath();
len = strlen(path);
GetExecutablePath(path, path_size);
len = str_len(path);
i = len;
while(path[i] != '/' || i == 0) {
i--;
}
path[i+1] = '\0';
}
snprintf(game_dll_path, sizeof(game_dll_path), "%s%s", path,
GAME_DLL_NAME);
static void SDLGetDLLPath(char *path, size_t path_size, char *exe_path)
{
snprintf(path, path_size, "%s%s", exe_path, GAME_DLL_NAME);
}
S32 main(S32 argc, char *argv[])
{
sdl_state SDLState;
SDL_Window *Window;
memset(&SDLState, 0, sizeof(SDLState));
SDLGetEXEDirPath(SDLState.EXEDirPath, sizeof(SDLState.EXEDirPath));
SDLGetDLLPath(SDLState.DLLPath, sizeof(SDLState.DLLPath),
SDLState.EXEDirPath);
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER |
SDL_INIT_AUDIO))
@@ -629,7 +679,7 @@ S32 main(S32 argc, char *argv[])
* protocol. However, SDL_WINDOW_ALWAYS_ON_TOP does work on KDE
* under Wayland. I have not tested GNOME. */
Window = SDL_CreateWindow("Handmade Hero", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, 700, 500,
SDL_WINDOWPOS_UNDEFINED, 500, 500,
SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALWAYS_ON_TOP);
if(Window) {
@@ -643,7 +693,6 @@ S32 main(S32 argc, char *argv[])
* its actual size. */
/* SDL_RenderPresent(Renderer) is enough to display the window. */
if(Renderer) {
sdl_state SDLState;
sdl_window_dimension Dimension;
sdl_sound_output SoundOutput;
game_memory GameMemory;
@@ -654,7 +703,6 @@ S32 main(S32 argc, char *argv[])
void *BaseAddress = (void *)(0);
#endif
memset(&SDLState, 0, sizeof(SDLState));
GlobalRunning = TRUE;
Dimension = SDLGetWindowDimension(Window);
@@ -685,7 +733,7 @@ S32 main(S32 argc, char *argv[])
memset(&GameMemory, 0, sizeof(GameMemory));
GameMemory.PermanentStorageSize = MB(64);
GameMemory.TransientStorageSize = GB(4);
GameMemory.TransientStorageSize = GB(1);
GameMemory.DEBUGPlatformReadEntireFile =
&DEBUGPlatformReadEntireFile;
GameMemory.DEBUGPlatformWriteEntireFile =
@@ -724,7 +772,7 @@ S32 main(S32 argc, char *argv[])
GlobalPerfCountFrequency = SDL_GetPerformanceFrequency();
Game = SDLLoadGameCode(game_dll_path);
Game = SDLLoadGameCode(SDLState.DLLPath);
while(GlobalRunning) {
S32 MonitorRefreshHz, GameUpdateHz;
@@ -759,10 +807,10 @@ S32 main(S32 argc, char *argv[])
GameUpdateHz = MonitorRefreshHz;
TargetSecondsPerFrame = 1.0f / (F32)GameUpdateHz;
NewDLLWriteTime = GetLastWriteTime(game_dll_path);
NewDLLWriteTime = GetLastWriteTime(SDLState.DLLPath);
if(NewDLLWriteTime > Game.DLLLastWriteTime) {
SDLUnloadGameCode(&Game);
Game = SDLLoadGameCode(game_dll_path);
Game = SDLLoadGameCode(SDLState.DLLPath);
}
OldKeyboardController = GetController(OldInput, 0);
@@ -803,6 +851,8 @@ S32 main(S32 argc, char *argv[])
S16 StickX, StickY;
float Threshold;
NewController->IsAnalog =
OldController->IsAnalog;
NewController->IsConnected = TRUE;
StickX =
+7
View File
@@ -30,6 +30,9 @@ typedef struct sdl_sound_output {
void *Samples;
} sdl_sound_output;
/* NOTE: We choose 1024 only because MacOS's MAXPATHLEN says such a value.
* For example, linux/limits.h PATH_MAX says 4096. */
#define SDL_STATE_PATH_SIZE 1024
typedef struct sdl_state {
U64 TotalSize;
void *GameMmemoryBlock;
@@ -37,8 +40,12 @@ typedef struct sdl_state {
S32 RecordingHandle;
S32 InputRecordingIndex;
// NOTE: These functions might be NULL. Check before calling them!
S32 PlaybackHandle;
S32 InputPlayingIndex;
char EXEDirPath[SDL_STATE_PATH_SIZE];
char DLLPath[SDL_STATE_PATH_SIZE];
} sdl_state;
#endif