From 92c5a75c05cf5aff2d3bb9f7368b5f804815d94a Mon Sep 17 00:00:00 2001 From: igor Date: Wed, 18 Mar 2026 17:02:29 -0700 Subject: [PATCH] Day 21 complete. --- handmade.cpp | 16 ++++++++++------ handmade.h | 2 ++ sdl_handmade.cpp | 46 +++++++++++++++++++++++++++++++++------------- 3 files changed, 45 insertions(+), 19 deletions(-) diff --git a/handmade.cpp b/handmade.cpp index 61480bc..e50ce68 100644 --- a/handmade.cpp +++ b/handmade.cpp @@ -3,20 +3,22 @@ #include -static void GameOutputSound(game_sound_output_buffer *SoundBuffer, S32 ToneHz) +static void GameOutputSound(game_state *GameState, game_sound_output_buffer *SoundBuffer, S32 ToneHz) { - static F32 tSine; S16 ToneVolume = 8000; S32 WavePeriod = SoundBuffer->SamplesPerSecond / ToneHz; S16 *SampleOut = SoundBuffer->Samples; for(S32 SampleIndex = 0; SampleIndex < SoundBuffer->SampleCount; SampleIndex++) { - F32 SineValue = sinf(tSine); + F32 SineValue = sinf(GameState->tSine); S16 SampleValue = S16(SineValue * ToneVolume); *SampleOut++ = SampleValue; *SampleOut++ = SampleValue; - tSine += 2.0f * PI * 1.0f / (F32)WavePeriod; + GameState->tSine += 2.0f * (F32)PI * 1.0f / (F32)WavePeriod; + if(GameState->tSine > 2.0f*(F32)PI) { + GameState->tSine -= 2.0f*(F32)PI; + } } } @@ -31,6 +33,7 @@ static void RenderWeirdGradient(game_offscreen_buffer *Buffer, S32 XOffset, S32 for(S32 X = 0; X < Width; X++) { U8 Blue = (U8)(X + XOffset); U8 Green = (U8)(Y + YOffset); + *Pixel = (Green << 8) | Blue; Pixel++; } @@ -45,7 +48,7 @@ void UpdateAndRender(game_memory *Memory, game_input *Input, game_offscreen_buff game_state *GameState = (game_state *)Memory->PermanentStorage; if(!Memory->IsInitialized) { - char FileName[] = "/Users/igor/Developer/handmade_hero_course/handmade/code/sdl_handmade.cpp"; + char FileName[] = "/home/igor/Developer/handmade/sdl_handmade.cpp"; debug_read_file_result BitmapMemory = Memory->DEBUGPlatformReadEntireFile(FileName); if(BitmapMemory.Contents) { Memory->DEBUGPlatformWriteEntireFile("test.out", BitmapMemory.ContentsSize, BitmapMemory.Contents); @@ -53,6 +56,7 @@ void UpdateAndRender(game_memory *Memory, game_input *Input, game_offscreen_buff } GameState->ToneHz = 256; + GameState->tSine = 0.0f; // TODO: Maybe more appropriate to do in the platform layer? Memory->IsInitialized = true; @@ -83,6 +87,6 @@ void UpdateAndRender(game_memory *Memory, game_input *Input, game_offscreen_buff } } - GameOutputSound(SoundBuffer, GameState->ToneHz); + GameOutputSound(GameState, SoundBuffer, GameState->ToneHz); RenderWeirdGradient(Buffer, GameState->BlueOffset, GameState->GreenOffset); } diff --git a/handmade.h b/handmade.h index 3fba5a1..f95f6a3 100644 --- a/handmade.h +++ b/handmade.h @@ -118,6 +118,8 @@ typedef struct game_state { S32 ToneHz; S32 GreenOffset; S32 BlueOffset; + + F32 tSine; } game_state; #endif // HANDMADE_H diff --git a/sdl_handmade.cpp b/sdl_handmade.cpp index b34186d..4232287 100644 --- a/sdl_handmade.cpp +++ b/sdl_handmade.cpp @@ -325,7 +325,7 @@ static F32 SDLGetSecondsElapsed(U64 Start, U64 End) } typedef struct sdl_game_code { - void *GameCode; + void *GameCodeDLL; void (*UpdateAndRender)(game_memory *, game_input *, game_offscreen_buffer *, game_sound_output_buffer *); B32 IsValid; @@ -335,25 +335,35 @@ static sdl_game_code SDLLoadGameCode() { sdl_game_code Result = {0}; - Result.GameCode = dlopen("./libhandmade.so", RTLD_NOW); - if(Result.GameCode) { - Result.UpdateAndRender = (void(*)(game_memory *, game_input *, game_offscreen_buffer *, game_sound_output_buffer *))dlsym(Result.GameCode, "UpdateAndRender"); + Result.GameCodeDLL = dlopen("./libhandmade.so", RTLD_NOW); + if(Result.GameCodeDLL) { + Result.UpdateAndRender = (void(*)(game_memory *, game_input *, game_offscreen_buffer *, game_sound_output_buffer *))dlsym(Result.GameCodeDLL, "UpdateAndRender"); if(!Result.UpdateAndRender) { - // TODO: Diagnostic. - fprintf(stderr, "%s\n", dlerror()); + // TODO: Diagnostic. dlerror() } + + Result.IsValid = Result.UpdateAndRender ? TRUE : FALSE; } else { - // TODO: Diagnostic. - fprintf(stderr, "%s\n", dlerror()); + // TODO: Diagnostic. dlerror() + } + + if(!Result.IsValid) { + Result.UpdateAndRender = NULL; } return Result; } +static void SDLUnloadGameCode(sdl_game_code *GameCode) +{ + if(GameCode->GameCodeDLL) + dlclose(GameCode->GameCodeDLL); // NOTE: Might fail. + GameCode->IsValid = FALSE; + GameCode->UpdateAndRender = NULL; +} + S32 main(S32 argc, char *argv[]) { - sdl_game_code Game = SDLLoadGameCode(); - if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER | SDL_INIT_AUDIO)) { /* TODO: This didn't work . . . */ } @@ -404,9 +414,9 @@ S32 main(S32 argc, char *argv[]) GameMemory.PermanentStorage = mmap(BaseAddress, TotalStorageSize, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); GameMemory.TransientStorage = (U8 *)(GameMemory.PermanentStorage) + GameMemory.PermanentStorageSize; - GameMemory.DEBUGPlatformReadEntireFile = DEBUGPlatformReadEntireFile; - GameMemory.DEBUGPlatformWriteEntireFile = DEBUGPlatformWriteEntireFile; - GameMemory.DEBUGPlatformFreeFileMemory = DEBUGPlatformFreeFileMemory; + GameMemory.DEBUGPlatformReadEntireFile = &DEBUGPlatformReadEntireFile; + GameMemory.DEBUGPlatformWriteEntireFile = &DEBUGPlatformWriteEntireFile; + GameMemory.DEBUGPlatformFreeFileMemory = &DEBUGPlatformFreeFileMemory; if(SoundOutput.Samples && GameMemory.PermanentStorage && GameMemory.TransientStorage) { game_input Input[2]; @@ -421,6 +431,9 @@ S32 main(S32 argc, char *argv[]) U64 LastCycleCount; #endif + sdl_game_code Game = SDLLoadGameCode(); + U32 LoadCounter = 0; + while(GlobalRunning) { LastCounter = SDLGetWallClock(); @@ -432,6 +445,13 @@ S32 main(S32 argc, char *argv[]) S32 GameUpdateHz = MonitorRefreshHz / 2; F32 TargetSecondsPerFrame = 1.0f / (F32)GameUpdateHz; + if(LoadCounter > (U32)(GameUpdateHz * 2)) { + SDLUnloadGameCode(&Game); + Game = SDLLoadGameCode(); + LoadCounter = 0; + } + LoadCounter++; + game_controller_input *OldKeyboardController = GetController(OldInput, 0); game_controller_input *NewKeyboardController = GetController(NewInput, 0); game_controller_input ZeroController = {0};