From b6f7e027b6d1eb78e3887591b3296fddc2b2eb05 Mon Sep 17 00:00:00 2001 From: igor Date: Sun, 22 Mar 2026 11:34:06 -0700 Subject: [PATCH] Shall not pass 80 characters in width. --- Makefile | 28 ++- handmade.c | 100 +++++--- handmade.h | 32 ++- sdl_handmade.c | 655 +++++++++++++++++++++++++++++++++++-------------- sdl_handmade.h | 3 +- 5 files changed, 589 insertions(+), 229 deletions(-) diff --git a/Makefile b/Makefile index 71a3329..604cdb2 100644 --- a/Makefile +++ b/Makefile @@ -15,16 +15,28 @@ endif CC = clang UFLAGS = -FLAGS = -ansi -D_POSIX_C_SOURCE=200809L -pedantic -pedantic-errors -Wall -Wextra -fno-caret-diagnostics -fno-show-column -Wno-missing-field-initializers -Wno-unused-function -Wno-unused-parameter -Wno-unused-variable -Wno-unused-but-set-variable - # -pedantic-errors +# NOTE: We comply with C89 (plain C), however the standard has no 64-bit +# support. But, every compiler at that time supported long long, +# hence we ignore the incompliance in our code. +# NOTE: We allow function declrations with specifying void +# (ex, void test() is allowed). +FLAGS = -ansi -pedantic -pedantic-errors -Wno-long-long \ + -Wno-strict-prototypes -Wall -Wextra -fno-caret-diagnostics \ + -fno-show-column -Wno-missing-field-initializers \ + -Wno-unused-function -Wno-unused-parameter -Wno-unused-variable \ + -Wno-unused-but-set-variable ifeq ($(DETECTED_OS),macos) - UFLAGS = -gldb + UFLAGS = -glldb INCLUDE = -I./sdl/include/ LIBS = ./sdl/lib/arm-macos/libSDL2.a -lm - FRAMEWORKS = -framework Cocoa -framework IOKit -framework CoreAudio -framework AudioToolbox -framework ForceFeedback -framework Carbon -framework GameController -framework Metal -framework QuartzCore -framework CoreHaptics + FRAMEWORKS = -framework Cocoa -framework IOKit -framework CoreAudio \ + -framework AudioToolbox -framework ForceFeedback \ + -framework Carbon -framework GameController \ + -framework Metal -framework QuartzCore \ + -framework CoreHaptics else ifeq ($(DETECTED_OS),linux) - UFLAGS = -ggdb + UFLAGS = -ggdb -D_POSIX_C_SOURCE=200809L INCLUDE = -I./sdl/include/ LIBS = ./sdl/lib/x86_64-linux/libSDL2.a -lm -lX11 FRAMEWORKS = @@ -43,10 +55,12 @@ EXE=handmadehero default: libhandmade $(EXE) libhandmade: handmade.c - @ $(CC) $(FLAGS) $(UFLAGS) -fPIC -shared $(INCLUDE) $^ $(LIBS) $(FRAMEWORKS) -o libhandmade.so + @ $(CC) $(FLAGS) $(UFLAGS) -fPIC -shared $(INCLUDE) $^ $(LIBS) \ + $(FRAMEWORKS) -o libhandmade.so $(EXE): sdl_handmade.c libhandmade - @ $(CC) $(FLAGS) $(UFLAGS) $(INCLUDE) sdl_handmade.c $(LIBS) $(FRAMEWORKS) -o $@ + @ $(CC) $(FLAGS) $(UFLAGS) $(INCLUDE) sdl_handmade.c $(LIBS) \ + $(FRAMEWORKS) -o $@ run: ./$(EXE) diff --git a/handmade.c b/handmade.c index 89d84b1..ae0af4f 100644 --- a/handmade.c +++ b/handmade.c @@ -4,17 +4,27 @@ #include -static void GameOutputSound(game_state *GameState, game_sound_output_buffer *SoundBuffer, S32 ToneHz) +static void GameOutputSound(game_state *GameState, + game_sound_output_buffer *SoundBuffer, + S32 ToneHz) { - S16 ToneVolume = 8000; - S32 WavePeriod = SoundBuffer->SamplesPerSecond / ToneHz; + S16 ToneVolume, *SampleOut; + S32 WavePeriod, SampleIndex; - S16 *SampleOut = SoundBuffer->Samples; + ToneVolume = 8000; + WavePeriod = SoundBuffer->SamplesPerSecond / ToneHz; - S32 SampleIndex; - for(SampleIndex = 0; SampleIndex < SoundBuffer->SampleCount; SampleIndex++) { - F32 SineValue = sinf(GameState->tSine); - S16 SampleValue = (S16)(SineValue * ToneVolume); + SampleOut = SoundBuffer->Samples; + + for(SampleIndex = 0; + SampleIndex < SoundBuffer->SampleCount; + SampleIndex++) + { + F32 SineValue; + S16 SampleValue; + + SineValue = sinf(GameState->tSine); + SampleValue = (S16)(SineValue * ToneVolume); *SampleOut++ = SampleValue; *SampleOut++ = SampleValue; @@ -25,19 +35,26 @@ static void GameOutputSound(game_state *GameState, game_sound_output_buffer *Sou } } -static void RenderWeirdGradient(game_offscreen_buffer *Buffer, S32 XOffset, S32 YOffset) +static void RenderWeirdGradient(game_offscreen_buffer *Buffer, S32 XOffset, + S32 YOffset) { - S32 Width = Buffer->Width; - S32 Height = Buffer->Height; + S32 Width, Height, Y; + U8 *Row; - U8 *Row = (U8 *)Buffer->Memory; - S32 Y; + Width = Buffer->Width; + Height = Buffer->Height; + + Row = (U8 *)Buffer->Memory; for(Y = 0; Y < Height; Y++) { U32 *Pixel = (U32 *)Row; S32 X; + + Pixel = (U32 *)Row; for(X = 0; X < Width; X++) { - U8 Blue = (U8)(X + XOffset); - U8 Green = (U8)(Y + YOffset); + U8 Blue, Green; + + Blue = (U8)(X + XOffset); + Green = (U8)(Y + YOffset); *Pixel = (Green << 8) | Blue; Pixel++; @@ -46,18 +63,30 @@ static void RenderWeirdGradient(game_offscreen_buffer *Buffer, S32 XOffset, S32 } } -void UpdateAndRender(game_memory *Memory, game_input *Input, game_offscreen_buffer *Buffer, game_sound_output_buffer *SoundBuffer) +void UpdateAndRender(game_memory *Memory, game_input *Input, + game_offscreen_buffer *Buffer, + game_sound_output_buffer *SoundBuffer) { - Assert((&Input->Controllers[0].Terminator - &Input->Controllers[0].Buttons[0]) == ARRAY_SIZE(Input->Controllers[0].Buttons)); + game_state *GameState; + U32 ControllerIndex; + + Assert((&Input->Controllers[0].u.buttons.Terminator - + &Input->Controllers[0].u.Buttons[0]) == + ARRAY_SIZE(Input->Controllers[0].u.Buttons)); Assert(sizeof(game_state) <= Memory->PermanentStorageSize); - game_state *GameState = (game_state *)Memory->PermanentStorage; + GameState = (game_state *)Memory->PermanentStorage; if(!Memory->IsInitialized) { #if BUILD_INTERNAL - char FileName[] = "/home/igor/Developer/handmade/sdl_handmade.cpp"; - debug_read_file_result BitmapMemory = Memory->DEBUGPlatformReadEntireFile(FileName); + char *FileName; + debug_read_file_result BitmapMemory; + + FileName = "/home/igor/Developer/handmade/sdl_handmade.cpp"; + BitmapMemory = Memory->DEBUGPlatformReadEntireFile(FileName); if(BitmapMemory.Contents) { - Memory->DEBUGPlatformWriteEntireFile("test.out", BitmapMemory.ContentsSize, BitmapMemory.Contents); + Memory->DEBUGPlatformWriteEntireFile("test.out", + BitmapMemory.ContentsSize, + BitmapMemory.Contents); Memory->DEBUGPlatformFreeFileMemory(BitmapMemory.Contents); } #endif @@ -72,29 +101,36 @@ void UpdateAndRender(game_memory *Memory, game_input *Input, game_offscreen_buff /* GameState.GreenOffset; */ /* GameState.BlueOffset; */ - U32 ControllerIndex; - for(ControllerIndex = 0; ControllerIndex < ARRAY_SIZE(Input->Controllers); ControllerIndex++) { - game_controller_input *Controller = GetController(Input, ControllerIndex); + for(ControllerIndex = 0; + ControllerIndex < ARRAY_SIZE(Input->Controllers); + ControllerIndex++) + { + game_controller_input *Controller = + GetController(Input, ControllerIndex); if(Controller->IsAnalog) { - GameState->GreenOffset += (int)(4.0f*(Controller->StickAverageY)); - GameState->BlueOffset += (int)(4.0f*(Controller->StickAverageX)); - GameState->ToneHz = 256 + (S32)(128.0f*(Controller->StickAverageY)); + GameState->GreenOffset += + (int)(4.0f*(Controller->StickAverageY)); + GameState->BlueOffset += + (int)(4.0f*(Controller->StickAverageX)); + GameState->ToneHz = + 256 + (S32)(128.0f*(Controller->StickAverageY)); } else { - if(Controller->MoveUp.EndedDown) { + if(Controller->u.buttons.MoveUp.EndedDown) { GameState->GreenOffset -= 5; } - if(Controller->MoveDown.EndedDown) { + if(Controller->u.buttons.MoveDown.EndedDown) { GameState->GreenOffset += 5; } - if(Controller->MoveLeft.EndedDown) { + if(Controller->u.buttons.MoveLeft.EndedDown) { GameState->BlueOffset -= 5; } - if(Controller->MoveRight.EndedDown) { + if(Controller->u.buttons.MoveRight.EndedDown) { GameState->BlueOffset += 5; } } } GameOutputSound(GameState, SoundBuffer, GameState->ToneHz); - RenderWeirdGradient(Buffer, GameState->BlueOffset, GameState->GreenOffset); + RenderWeirdGradient(Buffer, GameState->BlueOffset, + GameState->GreenOffset); } diff --git a/handmade.h b/handmade.h index 2d63469..d11478e 100644 --- a/handmade.h +++ b/handmade.h @@ -14,7 +14,8 @@ typedef struct debug_read_file_result { } debug_read_file_result; debug_read_file_result DEBUGPlatformReadEntireFile(const char *Filename); -B32 DEBUGPlatformWriteEntireFile(const char *Filename, U32 MemorySize, void *Memory); +B32 DEBUGPlatformWriteEntireFile(const char *Filename, U32 MemorySize, + void *Memory); void DEBUGPlatformFreeFileMemory(void *Memory); #endif @@ -23,7 +24,8 @@ void DEBUGPlatformFreeFileMemory(void *Memory); /* --------------------------------------------------------------------- */ typedef struct game_offscreen_buffer { - /* Pixels are always 32-bit and have the bytes in BGRX (little-endian). */ + /* Pixels are always 32-bit and have the bytes in BGRX + * (little-endian). */ void *Memory; S32 Width; S32 Height; @@ -70,8 +72,8 @@ typedef struct game_controller_input { /* NOTE: All buttons must be added above this line. */ game_button_state Terminator; - }; - }; + } buttons; + } u; } game_controller_input; typedef struct game_input { @@ -81,8 +83,10 @@ typedef struct game_input { game_controller_input *GetController(game_input *Input, S32 ControllerIndex) { + game_controller_input *Result; + Assert((U32)ControllerIndex < ARRAY_SIZE(Input->Controllers)); - game_controller_input *Result = &(Input->Controllers[ControllerIndex]); + Result = &(Input->Controllers[ControllerIndex]); return Result; } @@ -90,10 +94,14 @@ typedef struct game_memory { B32 IsInitialized; U64 PermanentStorageSize; - void *PermanentStorage; /* WARNING: This memory is REQUIRED to be zero initialized!!! (Done by the OS layer.) */ + void *PermanentStorage; /* WARNING: This memory is REQUIRED to be zero + initialized!!! (Done by the OS + layer.) */ U64 TransientStorageSize; - void *TransientStorage; /* WARNING: This memory is REQUIRED to be zero initialized!!! (Done by the OS layer.) */ + void *TransientStorage; /* WARNING: This memory is REQUIRED to be zero + initialized!!! (Done by the OS + layer.) */ #if BUILD_INTERNAL debug_read_file_result (*DEBUGPlatformReadEntireFile)(const char *); @@ -107,11 +115,13 @@ typedef struct game_memory { F32 SecondsElapsed; } game_clocks;*/ -void UpdateAndRender(game_memory *Memory, game_input *Input, game_offscreen_buffer *Buffer, game_sound_output_buffer *SoundBuffer); +void UpdateAndRender(game_memory *Memory, game_input *Input, + game_offscreen_buffer *Buffer, + game_sound_output_buffer *SoundBuffer); -/**/ -/**/ -/**/ +/* + * + */ typedef struct game_state { S32 ToneHz; diff --git a/sdl_handmade.c b/sdl_handmade.c index 7353ac5..7eed8f6 100644 --- a/sdl_handmade.c +++ b/sdl_handmade.c @@ -37,20 +37,27 @@ static offscreen_buffer GlobalBackbuffer; static U32 SafeTruncateUInt64(U64 Value) { + U32 Result; + Assert(Value <= 0xFFFFFFFF); - U32 Result = (U32)Value; + Result = (U32)Value; return Result; } debug_read_file_result DEBUGPlatformReadEntireFile(const char *Filename) { - debug_read_file_result Result = {0}; - S32 FileHandle = open(Filename, O_RDONLY); + debug_read_file_result Result; + S32 FileHandle; + struct stat FileStatus; + U32 BytesToRead; + U8 *NextByteLocation; + + memset(&Result, 0, sizeof(Result)); + FileHandle = open(Filename, O_RDONLY); if(FileHandle == -1) { return Result; } - struct stat FileStatus; if(fstat(FileHandle, &FileStatus) == -1) { close(FileHandle); return Result; @@ -64,10 +71,12 @@ debug_read_file_result DEBUGPlatformReadEntireFile(const char *Filename) return Result; } - U32 BytesToRead = Result.ContentsSize; - U8 *NextByteLocation = (U8 *)Result.Contents; + BytesToRead = Result.ContentsSize; + NextByteLocation = (U8 *)Result.Contents; while(BytesToRead) { - U32 BytesRead = read(FileHandle, NextByteLocation, BytesToRead); + U32 BytesRead; + + BytesRead = read(FileHandle, NextByteLocation, BytesToRead); if(BytesRead == (U32)-1) { free(Result.Contents); Result.Contents = 0; @@ -84,16 +93,24 @@ debug_read_file_result DEBUGPlatformReadEntireFile(const char *Filename) return Result; } -B32 DEBUGPlatformWriteEntireFile(const char *Filename, U32 MemorySize, void *Memory) +B32 DEBUGPlatformWriteEntireFile(const char *Filename, U32 MemorySize, + void *Memory) { - S32 FileHandle = open(Filename, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + S32 FileHandle; + U32 BytesToWrite; + U8 *NextByteLocation; + + FileHandle = open(Filename, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | + S_IRGRP | S_IROTH); if(FileHandle == -1) return FALSE; - U32 BytesToWrite = MemorySize; - U8 *NextByteLocation = (U8*)Memory; + BytesToWrite = MemorySize; + NextByteLocation = (U8*)Memory; while(BytesToWrite) { - U32 BytesWritten = write(FileHandle, NextByteLocation, BytesToWrite); + U32 BytesWritten; + + BytesWritten = write(FileHandle, NextByteLocation, BytesToWrite); if(BytesWritten == (U32)-1) { close(FileHandle); return FALSE; @@ -121,17 +138,22 @@ static sdl_window_dimension SDLGetWindowDimension(SDL_Window *Window) return Dimension; } -static void SDLResizeTexture(offscreen_buffer *Buffer, SDL_Renderer *Renderer, int Width, int Height) +static void SDLResizeTexture(offscreen_buffer *Buffer, + SDL_Renderer *Renderer, int Width, int Height) { + S32 BytesPerPixel; + if(Buffer->Texture) SDL_DestroyTexture(Buffer->Texture); if(Buffer->Memory) free(Buffer->Memory); - S32 BytesPerPixel = 4; + BytesPerPixel = 4; - Buffer->Texture = SDL_CreateTexture(Renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, Width, Height); + Buffer->Texture = SDL_CreateTexture(Renderer, SDL_PIXELFORMAT_ARGB8888, + SDL_TEXTUREACCESS_STREAMING, + Width, Height); Buffer->Memory = malloc(Width * Height * BytesPerPixel); Buffer->Height = Height; @@ -139,7 +161,9 @@ static void SDLResizeTexture(offscreen_buffer *Buffer, SDL_Renderer *Renderer, i Buffer->Pitch = Width * BytesPerPixel; } -static void SDLDisplayBufferInWindow(offscreen_buffer Buffer, SDL_Window *Window, SDL_Renderer *Renderer) +static void SDLDisplayBufferInWindow(offscreen_buffer Buffer, + SDL_Window *Window, + SDL_Renderer *Renderer) { if(SDL_UpdateTexture(Buffer.Texture, 0, Buffer.Memory, Buffer.Pitch)) { /* TODO: Do something about this error! */ @@ -151,14 +175,17 @@ static void SDLDisplayBufferInWindow(offscreen_buffer Buffer, SDL_Window *Window static void SDLInitControllers() { - int MaxJoysticks = SDL_NumJoysticks(); - int ControllerIndex = 0; - for(int JoystickIndex = 0; JoystickIndex < MaxJoysticks; JoystickIndex++) { + S32 MaxJoysticks, ControllerIndex, JoystickIndex; + + MaxJoysticks = SDL_NumJoysticks(); + ControllerIndex = 0; + for(JoystickIndex = 0; JoystickIndex < MaxJoysticks; JoystickIndex++) { if(!SDL_IsGameController(JoystickIndex)) continue; if(ControllerIndex >= MAX_CONTROLLERS) break; - ControllerHandles[ControllerIndex] = SDL_GameControllerOpen(JoystickIndex); + ControllerHandles[ControllerIndex] = + SDL_GameControllerOpen(JoystickIndex); ControllerIndex++; } } @@ -166,17 +193,23 @@ static void SDLInitControllers() /* static void SDLDeinitControllers() { - for(int ControllerIndex = 0; ControllerIndex < MAX_CONTROLLERS; ControllerIndex++) { - if (ControllerHandles[ControllerIndex]) + S32 ControllerIndex; + + for(ControllerIndex = 0; + ControllerIndex < MAX_CONTROLLERS; + ControllerIndex++) + { + if(ControllerHandles[ControllerIndex]) SDL_GameControllerClose(ControllerHandles[ControllerIndex]); } } */ - static void SDLInitSound(S32 SamplesPerSecond, S32 BufferSize) { - SDL_AudioSpec AudioSettings = {0}; + SDL_AudioSpec AudioSettings; + + memset(&AudioSettings, 0, sizeof(AudioSettings)); AudioSettings.freq = SamplesPerSecond; AudioSettings.format = AUDIO_S16LSB; @@ -190,7 +223,8 @@ static void SDLInitSound(S32 SamplesPerSecond, S32 BufferSize) } } -static void SDLFillSoundBuffer(sdl_sound_output *SoundOutput, S32 BytesToWrite) +static void SDLFillSoundBuffer(sdl_sound_output *SoundOutput, + S32 BytesToWrite) { SDL_QueueAudio(1, SoundOutput->Samples, BytesToWrite); } @@ -200,18 +234,22 @@ static void SDLClearSoundBuffer(sdl_sound_output *SoundOutput) memset(SoundOutput->Samples, 0, SoundOutput->SecondaryBufferSize); } -static void SDLProcessKeyboardMessage(game_button_state *NewState, B32 IsDown) +static void SDLProcessKeyboardMessage(game_button_state *NewState, + B32 IsDown) { Assert(NewState->EndedDown != IsDown); NewState->EndedDown = IsDown; ++NewState->HalfTransitionCount; } -static void SDLProcessInputDigitalButton(SDL_GameController *Controller, game_button_state *OldState, - SDL_GameControllerButton Button, game_button_state *NewState) +static void SDLProcessInputDigitalButton(SDL_GameController *Controller, + game_button_state *OldState, + SDL_GameControllerButton Button, + game_button_state *NewState) { NewState->EndedDown = SDL_GameControllerGetButton(Controller, Button); - NewState->HalfTransitionCount = (OldState->EndedDown != NewState->EndedDown) ? 1 : 0; + NewState->HalfTransitionCount = + (OldState->EndedDown != NewState->EndedDown) ? 1 : 0; } static void HandleEvent(SDL_Event *Event) @@ -224,11 +262,16 @@ static void HandleEvent(SDL_Event *Event) case SDL_WINDOWEVENT: { switch(Event->window.event) { case SDL_WINDOWEVENT_SIZE_CHANGED: { - SDL_Window *Window = SDL_GetWindowFromID(Event->window.windowID); - SDL_Renderer *Renderer = SDL_GetRenderer(Window); + SDL_Window *Window; + SDL_Renderer *Renderer; + sdl_window_dimension Dimension; - sdl_window_dimension Dimension = SDLGetWindowDimension(Window); - SDLResizeTexture(&GlobalBackbuffer, Renderer, Dimension.Width, Dimension.Height); + Window = SDL_GetWindowFromID(Event->window.windowID); + Renderer = SDL_GetRenderer(Window); + + Dimension = SDLGetWindowDimension(Window); + SDLResizeTexture(&GlobalBackbuffer, Renderer, + Dimension.Width, Dimension.Height); } break; case SDL_WINDOWEVENT_EXPOSED: { @@ -238,12 +281,18 @@ static void HandleEvent(SDL_Event *Event) } } -static void SDLBeginRecordingInput(sdl_state *SDLState, S32 InputRecordingIndex) +static void SDLBeginRecordingInput(sdl_state *SDLState, + S32 InputRecordingIndex) { + char *FileName; + SDLState->InputRecordingIndex = InputRecordingIndex; - const char *FileName = "foo.hmi"; - SDLState->RecordingHandle = open(FileName, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - write(SDLState->RecordingHandle, SDLState->GameMmemoryBlock, (size_t)(SDLState->TotalSize)); + FileName = "foo.hmi"; + SDLState->RecordingHandle = + open((const char *)FileName, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | + S_IRGRP | S_IROTH); + write(SDLState->RecordingHandle, SDLState->GameMmemoryBlock, + (size_t)(SDLState->TotalSize)); } static void SDLEndRecordingInput(sdl_state *SDLState) @@ -252,11 +301,19 @@ static void SDLEndRecordingInput(sdl_state *SDLState) SDLState->InputRecordingIndex = 0; } -static void SDLBeginInputPlayback(sdl_state *SDLState, S32 InputPlayingIndex) +static void SDLBeginInputPlayback(sdl_state *SDLState, + S32 InputPlayingIndex) { + ssize_t size; + char *FileName; + SDLState->InputPlayingIndex = InputPlayingIndex; - const char *FileName = "foo.hmi"; - SDLState->PlaybackHandle = open(FileName, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + FileName = "foo.hmi"; + SDLState->PlaybackHandle = + open((const char *)FileName, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | + S_IRGRP | S_IROTH); + size = read(SDLState->PlaybackHandle, SDLState->GameMmemoryBlock, + (size_t)(SDLState->TotalSize)); } static void SDLEndInputPlayback(sdl_state *SDLState) @@ -272,24 +329,32 @@ static void SDLRecordInput(sdl_state *SDLState, game_input *NewInput) static void SDLPlaybackInput(sdl_state *SDLState, game_input *NewInput) { - ssize_t size = read(SDLState->PlaybackHandle, NewInput, sizeof(*NewInput)); - if(size == EOF || size == -1) { - S32 PlayingIndex = SDLState->InputPlayingIndex; + ssize_t size; + + size = read(SDLState->PlaybackHandle, NewInput, sizeof(*NewInput)); + if(size == 0 || size == -1) { + S32 PlayingIndex; + + PlayingIndex = SDLState->InputPlayingIndex; SDLEndInputPlayback(SDLState); SDLBeginInputPlayback(SDLState, PlayingIndex); } } -static void SDLProcessMessages(sdl_state *SDLState, game_controller_input *KeyboardController) +static void SDLProcessMessages(sdl_state *SDLState, + game_controller_input *KeyboardController) { SDL_Event Event; while(SDL_PollEvent(&Event)) { switch(Event.type) { case SDL_KEYDOWN: case SDL_KEYUP: { - SDL_Keycode KeyCode = Event.key.keysym.sym; - B32 IsDown = (Event.key.state == SDL_PRESSED); - B32 WasDown = FALSE; + SDL_Keycode KeyCode; + B32 IsDown, WasDown; + + KeyCode = Event.key.keysym.sym; + IsDown = (Event.key.state == SDL_PRESSED); + WasDown = FALSE; if(Event.key.state == SDL_RELEASED) { WasDown = TRUE; } else if(Event.key.repeat != 0) { @@ -298,34 +363,61 @@ static void SDLProcessMessages(sdl_state *SDLState, game_controller_input *Keybo if(Event.key.repeat == 0) { if(KeyCode == SDLK_w) { - SDLProcessKeyboardMessage(&KeyboardController->MoveUp, IsDown); + SDLProcessKeyboardMessage( + &KeyboardController->u.buttons.MoveUp, + IsDown); } else if(KeyCode == SDLK_s) { - SDLProcessKeyboardMessage(&KeyboardController->MoveDown, IsDown); + SDLProcessKeyboardMessage( + &KeyboardController->u.buttons.MoveDown, + IsDown); } else if(KeyCode == SDLK_a) { - SDLProcessKeyboardMessage(&KeyboardController->MoveLeft, IsDown); + SDLProcessKeyboardMessage( + &KeyboardController->u.buttons.MoveLeft, + IsDown); } else if(KeyCode == SDLK_d) { - SDLProcessKeyboardMessage(&KeyboardController->MoveRight, IsDown); + SDLProcessKeyboardMessage( + &KeyboardController->u.buttons.MoveRight, + IsDown); } else if(KeyCode == SDLK_q) { - SDLProcessKeyboardMessage(&KeyboardController->LeftShoulder, IsDown); + SDLProcessKeyboardMessage( + &KeyboardController->u.buttons.LeftShoulder, + IsDown); } else if(KeyCode == SDLK_e) { - SDLProcessKeyboardMessage(&KeyboardController->RightShoulder, IsDown); + SDLProcessKeyboardMessage( + &KeyboardController->u.buttons.RightShoulder, + IsDown); } else if(KeyCode == SDLK_UP) { - SDLProcessKeyboardMessage(&KeyboardController->ActionUp, IsDown); + SDLProcessKeyboardMessage( + &KeyboardController->u.buttons.ActionUp, + IsDown); } else if(KeyCode == SDLK_DOWN) { - SDLProcessKeyboardMessage(&KeyboardController->ActionDown, IsDown); + SDLProcessKeyboardMessage( + &KeyboardController->u.buttons.ActionDown, + IsDown); } else if(KeyCode == SDLK_LEFT) { - SDLProcessKeyboardMessage(&KeyboardController->ActionLeft, IsDown); + SDLProcessKeyboardMessage( + &KeyboardController->u.buttons.ActionLeft, + IsDown); } else if(KeyCode == SDLK_RIGHT) { - SDLProcessKeyboardMessage(&KeyboardController->ActionRight, IsDown); + SDLProcessKeyboardMessage( + &KeyboardController->u.buttons.ActionRight, + IsDown); } else if(KeyCode == SDLK_ESCAPE) { - SDLProcessKeyboardMessage(&KeyboardController->Start, IsDown); + SDLProcessKeyboardMessage( + &KeyboardController->u.buttons.Start, + IsDown); } else if(KeyCode == SDLK_SPACE) { - SDLProcessKeyboardMessage(&KeyboardController->Back, IsDown); + SDLProcessKeyboardMessage( + &KeyboardController->u.buttons.Back, + IsDown); } } if(WasDown) { + B32 AltKeyWasDown; + #if BUILD_INTERNAL + if(KeyCode == SDLK_l) { if(SDLState->InputRecordingIndex == 0) { SDLBeginRecordingInput(SDLState, 1); @@ -336,8 +428,11 @@ static void SDLProcessMessages(sdl_state *SDLState, game_controller_input *Keybo } #endif - /* NOTE: If your window manager already uses an Alt+F4 keybind to close programs, then we are likely to see SDL_QUIT event occur before our keybind. */ - B32 AltKeyWasDown = (Event.key.keysym.mod & KMOD_ALT); + /* NOTE: If your window manager already uses an Alt+F4 + * keybind to close programs, then we are likely + * to see SDL_QUIT event occur before our + * keybind. */ + AltKeyWasDown = (Event.key.keysym.mod & KMOD_ALT); if(KeyCode == SDLK_F4 && AltKeyWasDown) GlobalRunning = FALSE; #if BUILD_INTERNAL @@ -356,24 +451,32 @@ static void SDLProcessMessages(sdl_state *SDLState, game_controller_input *Keybo static F32 SDLProcessInputStickValue(F32 Value, S32 DeadZoneThreshold) { - F32 Result = 0.0f; + F32 Result; + + Result = 0.0f; if(Value < -DeadZoneThreshold) - Result = (F32)((Value + DeadZoneThreshold) / (32768.0f - DeadZoneThreshold)); + Result = (F32)((Value + DeadZoneThreshold) / + (32768.0f - DeadZoneThreshold)); else if(Value > DeadZoneThreshold) - Result = (F32)((Value + DeadZoneThreshold) / (32767.0f - DeadZoneThreshold)); + Result = (F32)((Value + DeadZoneThreshold) / + (32767.0f - DeadZoneThreshold)); + return Result; } #define DEFAULT_REFRESH_RATE 60 static S32 SDLGetWindowRefreshRate(SDL_Window *Window) { - int DisplayIndex = SDL_GetWindowDisplayIndex(Window); + S32 DisplayIndex; SDL_DisplayMode Mode; + DisplayIndex = SDL_GetWindowDisplayIndex(Window); + if(SDL_GetDesktopDisplayMode(DisplayIndex, &Mode) != 0) return DEFAULT_REFRESH_RATE; if(Mode.refresh_rate == 0) return DEFAULT_REFRESH_RATE; + return Mode.refresh_rate; } @@ -391,15 +494,18 @@ typedef struct sdl_game_code { 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; } sdl_game_code; static U32 GetLastWriteTime(const char *FileName) { - struct stat file_info = {0}; + struct stat file_info; + memset(&file_info, 0, sizeof(file_info)); if(stat(FileName, &file_info) != 0) { /* TODO: Diagnostic. perror("stat failed"); */ } @@ -411,13 +517,17 @@ static U32 GetLastWriteTime(const char *FileName) static sdl_game_code SDLLoadGameCode(char *DLLPath) { - sdl_game_code Result = {0}; + sdl_game_code Result; + memset(&Result, 0, sizeof(Result)); 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"); + Result.UpdateAndRender = + (void(*)(game_memory *, game_input *, game_offscreen_buffer *, + game_sound_output_buffer *))dlsym(Result.GameCodeDLL, + "UpdateAndRender"); if(!Result.UpdateAndRender) { /* TODO: Diagnostic. dlerror() */ } @@ -444,16 +554,27 @@ static void SDLUnloadGameCode(sdl_game_code *GameCode) char *GetExecutablePath() { - static char path[1024] = ""; /* NOTE: We choose 1024 only because MacOS's MAXPATHLEN says such a value. For example, linux/limits.h PATH_MAX says 4096. */ - size_t path_size = sizeof(path); + 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 __APPLE__ && __MACH__ - U32 size = path_size; - if(_NSGetExecutablePath(path, &size) != 0) { /* NOTE: Not an absolute path. */ + size = path_size; + if(_NSGetExecutablePath(path, &size) != 0) { /* NOTE: Not an absolute + path. */ /* TODO: Diagnostics. */ } #else - ssize_t size = readlink("/proc/self/exe", path, path_size - 1); + size = readlink("/proc/self/exe", path, path_size - 1); if(size != -1) { path[size] = '\0'; } else { @@ -466,51 +587,48 @@ char *GetExecutablePath() S32 main(S32 argc, char *argv[]) { - char *path = GetExecutablePath(); - U32 len = strlen(path); - U32 i = len; + char *path; + U32 len, i; + char game_dll_path[1024]; + SDL_Window *Window; + + path = GetExecutablePath(); + len = strlen(path); + 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); + 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 . . . */ } SDLInitControllers(); - SDL_Window *Window = SDL_CreateWindow("Handmade Hero", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 700, 500, SDL_WINDOW_RESIZABLE); - + Window = SDL_CreateWindow("Handmade Hero", SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, 700, 500, + SDL_WINDOW_RESIZABLE); if(Window) { - /*SDL_Renderer *Renderer = SDL_CreateRenderer(Window, -1, 0); */ - SDL_Renderer *Renderer = SDL_CreateRenderer(Window, -1, SDL_RENDERER_PRESENTVSYNC); - /* "Wayland needs an event loop and rendering or it won't function." https://github.com/libsdl-org/SDL/issues/7699#issuecomment-1545684792 */ - /* NOTE: This means that we need to readraw to even resize the window, otherwise the window frame will appear outdated to its actual size. */ + SDL_Renderer *Renderer; + + Renderer = SDL_CreateRenderer(Window, -1, SDL_RENDERER_PRESENTVSYNC); + /* "Wayland needs an event loop and rendering or it won't function." + * https://github.com/libsdl-org/SDL/issues/7699#issuecomment-1545684792 */ + /* NOTE: This means that we need to readraw to even resize the + * window, otherwise the window frame will appear outdated to + * its actual size. */ /* SDL_RenderPresent(Renderer) is enough to display the window. */ if(Renderer) { - sdl_state SDLState = {0}; - GlobalRunning = TRUE; - - sdl_window_dimension Dimension = SDLGetWindowDimension(Window); - SDLResizeTexture(&GlobalBackbuffer, Renderer, Dimension.Width, Dimension.Height); - - sdl_sound_output SoundOutput = {0}; - SoundOutput.SamplesPerSecond = 48000; - SoundOutput.BytesPerSample = sizeof(S16) * 2; - SoundOutput.SecondaryBufferSize = SoundOutput.SamplesPerSecond * SoundOutput.BytesPerSample; - SoundOutput.tSine = 0; - SoundOutput.LatencySampleCount = SoundOutput.SamplesPerSecond / 15; - - SDLInitSound(SoundOutput.SamplesPerSecond, SoundOutput.SamplesPerSecond * SoundOutput.BytesPerSample / 60); - SDL_PauseAudio(0); - - SoundOutput.Samples = calloc(SoundOutput.SamplesPerSecond, SoundOutput.BytesPerSample); - /* SoundOutput.Samples = malloc(SoundOutput.SecondaryBufferSize); */ - /* SDLClearSoundBuffer(&SoundOutput); */ /* NOTE: calloc auto clears to zero */ + sdl_state SDLState; + sdl_window_dimension Dimension; + sdl_sound_output SoundOutput; + game_memory GameMemory; #if BUILD_DEBUG void *BaseAddress = (void *)TB(2); @@ -518,129 +636,299 @@ S32 main(S32 argc, char *argv[]) void *BaseAddress = (void *)(0); #endif - game_memory GameMemory = {0}; + memset(&SDLState, 0, sizeof(SDLState)); + GlobalRunning = TRUE; + + Dimension = SDLGetWindowDimension(Window); + SDLResizeTexture(&GlobalBackbuffer, Renderer, Dimension.Width, + Dimension.Height); + + memset(&SoundOutput, 0, sizeof(SoundOutput)); + SoundOutput.SamplesPerSecond = 48000; + SoundOutput.BytesPerSample = sizeof(S16) * 2; + SoundOutput.SecondaryBufferSize = + SoundOutput.SamplesPerSecond * SoundOutput.BytesPerSample; + SoundOutput.tSine = 0; + SoundOutput.LatencySampleCount = + SoundOutput.SamplesPerSecond / 15; + + SDLInitSound(SoundOutput.SamplesPerSecond, + SoundOutput.SamplesPerSecond * SoundOutput.BytesPerSample / + 60); + SDL_PauseAudio(0); + + SoundOutput.Samples = + calloc(SoundOutput.SamplesPerSecond, + SoundOutput.BytesPerSample); + /* SoundOutput.Samples = + * malloc(SoundOutput.SecondaryBufferSize); */ + /* NOTE: calloc auto clears to zero */ + /* SDLClearSoundBuffer(&SoundOutput); */ + + memset(&GameMemory, 0, sizeof(GameMemory)); GameMemory.PermanentStorageSize = MB(64); GameMemory.TransientStorageSize = GB(4); - GameMemory.DEBUGPlatformReadEntireFile = &DEBUGPlatformReadEntireFile; - GameMemory.DEBUGPlatformWriteEntireFile = &DEBUGPlatformWriteEntireFile; - GameMemory.DEBUGPlatformFreeFileMemory = &DEBUGPlatformFreeFileMemory; + GameMemory.DEBUGPlatformReadEntireFile = + &DEBUGPlatformReadEntireFile; + GameMemory.DEBUGPlatformWriteEntireFile = + &DEBUGPlatformWriteEntireFile; + GameMemory.DEBUGPlatformFreeFileMemory = + &DEBUGPlatformFreeFileMemory; - SDLState.TotalSize = GameMemory.PermanentStorageSize + GameMemory.TransientStorageSize; - SDLState.GameMmemoryBlock = mmap(BaseAddress, SDLState.TotalSize, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); /* NOTE: On MacOS and Linux, mmap seems to zero-fill anonymous memory as a side-effect of security. */ + SDLState.TotalSize = + GameMemory.PermanentStorageSize + + GameMemory.TransientStorageSize; + /* NOTE: On MacOS and Linux, mmap seems to zero-fill anonymous + * memory as a side-effect of security. */ + SDLState.GameMmemoryBlock = + mmap(BaseAddress, SDLState.TotalSize, PROT_READ | + PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); GameMemory.PermanentStorage = SDLState.GameMmemoryBlock; - GameMemory.TransientStorage = (U8 *)(GameMemory.PermanentStorage) + GameMemory.PermanentStorageSize; + GameMemory.TransientStorage = + (U8 *)(GameMemory.PermanentStorage) + + GameMemory.PermanentStorageSize; - if(SoundOutput.Samples && GameMemory.PermanentStorage && GameMemory.TransientStorage) { + if(SoundOutput.Samples && + GameMemory.PermanentStorage && + GameMemory.TransientStorage) + { game_input Input[2]; - game_input *NewInput = &Input[0]; - game_input *OldInput = &Input[1]; - memset(&Input, 0, sizeof(Input)); - - GlobalPerfCountFrequency = SDL_GetPerformanceFrequency(); + game_input *NewInput, *OldInput; + sdl_game_code Game; U64 LastCounter; #if __x86_64__ || __i386__ U64 LastCycleCount; #endif + NewInput = &Input[0]; + OldInput = &Input[1]; + memset(&Input, 0, sizeof(Input)); - sdl_game_code Game = SDLLoadGameCode(game_dll_path); + GlobalPerfCountFrequency = SDL_GetPerformanceFrequency(); + + Game = SDLLoadGameCode(game_dll_path); while(GlobalRunning) { + S32 MonitorRefreshHz, GameUpdateHz; + F32 TargetSecondsPerFrame; + U32 NewDLLWriteTime, ButtonIndex, ControllerIndex; + game_controller_input *OldKeyboardController, + *NewKeyboardController; + game_controller_input ZeroController; + S32 TargetQueueBytes, BytesToWrite; + game_sound_output_buffer SoundBuffer; + game_offscreen_buffer Buffer; + U64 WorkCounter, EndCounter; + F32 WorkSecondsElapsed, SecondsElapsedForFrame; + F64 MSPerFrame, FPS; +#if __x86_64__ || __i386__ + U64 EndCycleCount, CyclesElapsed; + F64 MCPF; +#endif + LastCounter = SDLGetWallClock(); #if __x86_64__ || __i386__ - LastCycleCount = __rdtsc(); /* NOTE: rdtsc reports clock cylces, however it is not meant for really precise profiler work as the value returned is varied. */ -#endif /* Also, __rdtsc is not available on MacOS ARM; I have not checked MacOS x64. */ + /* NOTE: rdtsc reports clock cylces, however it is not + * meant for really precise profiler work as the + * value returned is varied. */ + /* Also, __rdtsc is not available on MacOS ARM; I + * have not checked MacOS x64. */ + LastCycleCount = __rdtsc(); +#endif - S32 MonitorRefreshHz = SDLGetWindowRefreshRate(Window); - S32 GameUpdateHz = MonitorRefreshHz; - F32 TargetSecondsPerFrame = 1.0f / (F32)GameUpdateHz; + MonitorRefreshHz = SDLGetWindowRefreshRate(Window); + GameUpdateHz = MonitorRefreshHz; + TargetSecondsPerFrame = 1.0f / (F32)GameUpdateHz; - U32 NewDLLWriteTime = GetLastWriteTime(game_dll_path); + NewDLLWriteTime = GetLastWriteTime(game_dll_path); if(NewDLLWriteTime > Game.DLLLastWriteTime) { SDLUnloadGameCode(&Game); Game = SDLLoadGameCode(game_dll_path); } - game_controller_input *OldKeyboardController = GetController(OldInput, 0); - game_controller_input *NewKeyboardController = GetController(NewInput, 0); - game_controller_input ZeroController = {0}; + OldKeyboardController = GetController(OldInput, 0); + NewKeyboardController = GetController(NewInput, 0); + memset(&ZeroController, 0, sizeof(ZeroController)); *NewKeyboardController = ZeroController; NewKeyboardController->IsConnected = TRUE; - for(unsigned int ButtonIndex = 0; ButtonIndex < ARRAY_SIZE(NewKeyboardController->Buttons); ButtonIndex++) { - NewKeyboardController->Buttons[ButtonIndex].EndedDown = OldKeyboardController->Buttons[ButtonIndex].EndedDown; + for(ButtonIndex = 0; + ButtonIndex < ARRAY_SIZE( + NewKeyboardController->u.Buttons); + ButtonIndex++) + { + NewKeyboardController-> + u.Buttons[ButtonIndex].EndedDown = + OldKeyboardController-> + u.Buttons[ButtonIndex]. + EndedDown; } SDLProcessMessages(&SDLState, NewKeyboardController); - for(unsigned int ControllerIndex = 0; ControllerIndex < MAX_CONTROLLERS; ControllerIndex++) { - game_controller_input *OldController = GetController(OldInput, ControllerIndex+1); - game_controller_input *NewController = GetController(NewInput, ControllerIndex+1); + for(ControllerIndex = 0; + ControllerIndex < MAX_CONTROLLERS; + ControllerIndex++) + { + game_controller_input *OldController, *NewController; + + OldController = + GetController(OldInput, ControllerIndex+1); + NewController = + GetController(NewInput, ControllerIndex+1); + + if(ControllerHandles[ControllerIndex] != 0 && + SDL_GameControllerGetAttached( + ControllerHandles[ControllerIndex])) + { + S16 StickX, StickY; + float Threshold; - if(ControllerHandles[ControllerIndex] != 0 && SDL_GameControllerGetAttached(ControllerHandles[ControllerIndex])) { NewController->IsConnected = TRUE; - S16 StickX = SDL_GameControllerGetAxis(ControllerHandles[ControllerIndex], SDL_CONTROLLER_AXIS_LEFTX); - S16 StickY = SDL_GameControllerGetAxis(ControllerHandles[ControllerIndex], SDL_CONTROLLER_AXIS_LEFTY); + StickX = + SDL_GameControllerGetAxis( + ControllerHandles[ControllerIndex], + SDL_CONTROLLER_AXIS_LEFTX); + StickY = + SDL_GameControllerGetAxis( + ControllerHandles[ControllerIndex], + SDL_CONTROLLER_AXIS_LEFTY); NewController->IsAnalog = TRUE; - NewController->StickAverageX = SDLProcessInputStickValue((F32)StickX, CONTROLLER_LEFT_THUMB_DEADZONE); - NewController->StickAverageY = SDLProcessInputStickValue((F32)StickY, CONTROLLER_LEFT_THUMB_DEADZONE); + NewController->StickAverageX = + SDLProcessInputStickValue((F32)StickX, + CONTROLLER_LEFT_THUMB_DEADZONE); + NewController->StickAverageY = + SDLProcessInputStickValue((F32)StickY, + CONTROLLER_LEFT_THUMB_DEADZONE); - if((NewController->StickAverageX != 0.0f) || (NewController->StickAverageY != 0.0f)) { + if((NewController->StickAverageX != 0.0f) || + (NewController->StickAverageY != 0.0f)) + { NewController->IsAnalog = TRUE; } - if(SDL_GameControllerGetButton(ControllerHandles[ControllerIndex], SDL_CONTROLLER_BUTTON_DPAD_UP)) { + if(SDL_GameControllerGetButton( + ControllerHandles[ControllerIndex], + SDL_CONTROLLER_BUTTON_DPAD_UP)) + { NewController->StickAverageY = -1.0f; NewController->IsAnalog = FALSE; } - if(SDL_GameControllerGetButton(ControllerHandles[ControllerIndex], SDL_CONTROLLER_BUTTON_DPAD_DOWN)) { + if(SDL_GameControllerGetButton( + ControllerHandles[ControllerIndex], + SDL_CONTROLLER_BUTTON_DPAD_DOWN)) + { NewController->StickAverageY = 1.0f; NewController->IsAnalog = FALSE; } - if(SDL_GameControllerGetButton(ControllerHandles[ControllerIndex], SDL_CONTROLLER_BUTTON_DPAD_LEFT)) { + if(SDL_GameControllerGetButton( + ControllerHandles[ControllerIndex], + SDL_CONTROLLER_BUTTON_DPAD_LEFT)) + { NewController->StickAverageX = -1.0f; NewController->IsAnalog = FALSE; } - if(SDL_GameControllerGetButton(ControllerHandles[ControllerIndex], SDL_CONTROLLER_BUTTON_DPAD_RIGHT)) { + if(SDL_GameControllerGetButton( + ControllerHandles[ControllerIndex], + SDL_CONTROLLER_BUTTON_DPAD_RIGHT)) + { NewController->StickAverageX = 1.0f; NewController->IsAnalog = FALSE; } - float Threshold = 0.5f; - SDLProcessInputDigitalButton(ControllerHandles[(NewController->StickAverageY < -Threshold) ? 1 : 0], &OldController->MoveUp, SDL_CONTROLLER_BUTTON_A, &NewController->MoveUp); - SDLProcessInputDigitalButton(ControllerHandles[(NewController->StickAverageY > Threshold) ? 1 : 0], &OldController->MoveDown, SDL_CONTROLLER_BUTTON_A, &NewController->MoveDown); - SDLProcessInputDigitalButton(ControllerHandles[(NewController->StickAverageX < -Threshold) ? 1 : 0], &OldController->MoveLeft, SDL_CONTROLLER_BUTTON_A, &NewController->MoveLeft); - SDLProcessInputDigitalButton(ControllerHandles[(NewController->StickAverageX > Threshold) ? 1 : 0], &OldController->MoveRight, SDL_CONTROLLER_BUTTON_A, &NewController->MoveRight); + Threshold = 0.5f; + SDLProcessInputDigitalButton( + ControllerHandles[ + (NewController->StickAverageY < + -Threshold) ? 1 : 0], + &OldController->u.buttons.MoveUp, + SDL_CONTROLLER_BUTTON_A, + &NewController->u.buttons.MoveUp); + SDLProcessInputDigitalButton( + ControllerHandles[ + (NewController->StickAverageY > + Threshold) ? 1 : 0], + &OldController->u.buttons.MoveDown, + SDL_CONTROLLER_BUTTON_A, + &NewController->u.buttons.MoveDown); + SDLProcessInputDigitalButton( + ControllerHandles[ + (NewController->StickAverageX < + -Threshold) ? 1 : 0], + &OldController->u.buttons.MoveLeft, + SDL_CONTROLLER_BUTTON_A, + &NewController->u.buttons.MoveLeft); + SDLProcessInputDigitalButton( + ControllerHandles[ + (NewController->StickAverageX > + Threshold) ? 1 : 0], + &OldController->u.buttons.MoveRight, + SDL_CONTROLLER_BUTTON_A, + &NewController->u.buttons.MoveRight); - SDLProcessInputDigitalButton(ControllerHandles[ControllerIndex], &OldController->ActionDown, SDL_CONTROLLER_BUTTON_A, &NewController->ActionDown); - SDLProcessInputDigitalButton(ControllerHandles[ControllerIndex], &OldController->ActionRight, SDL_CONTROLLER_BUTTON_B, &NewController->ActionRight); - SDLProcessInputDigitalButton(ControllerHandles[ControllerIndex], &OldController->ActionLeft, SDL_CONTROLLER_BUTTON_X, &NewController->ActionLeft); - SDLProcessInputDigitalButton(ControllerHandles[ControllerIndex], &OldController->ActionUp, SDL_CONTROLLER_BUTTON_Y, &NewController->ActionUp); - SDLProcessInputDigitalButton(ControllerHandles[ControllerIndex], &OldController->LeftShoulder, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, &NewController->LeftShoulder); - SDLProcessInputDigitalButton(ControllerHandles[ControllerIndex], &OldController->RightShoulder, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, &NewController->RightShoulder); + SDLProcessInputDigitalButton( + ControllerHandles[ControllerIndex], + &OldController->u.buttons.ActionDown, + SDL_CONTROLLER_BUTTON_A, + &NewController->u.buttons.ActionDown); + SDLProcessInputDigitalButton( + ControllerHandles[ControllerIndex], + &OldController->u.buttons.ActionRight, + SDL_CONTROLLER_BUTTON_B, + &NewController->u.buttons.ActionRight); + SDLProcessInputDigitalButton( + ControllerHandles[ControllerIndex], + &OldController->u.buttons.ActionLeft, + SDL_CONTROLLER_BUTTON_X, + &NewController->u.buttons.ActionLeft); + SDLProcessInputDigitalButton( + ControllerHandles[ControllerIndex], + &OldController->u.buttons.ActionUp, + SDL_CONTROLLER_BUTTON_Y, + &NewController->u.buttons.ActionUp); + SDLProcessInputDigitalButton( + ControllerHandles[ControllerIndex], + &OldController->u.buttons.LeftShoulder, + SDL_CONTROLLER_BUTTON_LEFTSHOULDER, + &NewController->u.buttons.LeftShoulder); + SDLProcessInputDigitalButton( + ControllerHandles[ControllerIndex], + &OldController->u.buttons.RightShoulder, + SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, + &NewController->u.buttons.RightShoulder); - SDLProcessInputDigitalButton(ControllerHandles[ControllerIndex], &OldController->Start, SDL_CONTROLLER_BUTTON_START, &NewController->Start); - SDLProcessInputDigitalButton(ControllerHandles[ControllerIndex], &OldController->Back, SDL_CONTROLLER_BUTTON_BACK, &NewController->Back); + SDLProcessInputDigitalButton( + ControllerHandles[ControllerIndex], + &OldController->u.buttons.Start, + SDL_CONTROLLER_BUTTON_START, + &NewController->u.buttons.Start); + SDLProcessInputDigitalButton( + ControllerHandles[ControllerIndex], + &OldController->u.buttons.Back, + SDL_CONTROLLER_BUTTON_BACK, + &NewController->u.buttons.Back); } else { /* NOTE: This controller is not plugged in. */ NewController->IsConnected = FALSE; } } - S32 TargetQueueBytes = SoundOutput.LatencySampleCount * SoundOutput.BytesPerSample; - S32 BytesToWrite = TargetQueueBytes - SDL_GetQueuedAudioSize(1); - game_sound_output_buffer SoundBuffer; - SoundBuffer.SamplesPerSecond = SoundOutput.SamplesPerSecond; - SoundBuffer.SampleCount = BytesToWrite / SoundOutput.BytesPerSample; + TargetQueueBytes = SoundOutput.LatencySampleCount * + SoundOutput.BytesPerSample; + BytesToWrite = + TargetQueueBytes - SDL_GetQueuedAudioSize(1); + SoundBuffer.SamplesPerSecond = + SoundOutput.SamplesPerSecond; + SoundBuffer.SampleCount = + BytesToWrite / SoundOutput.BytesPerSample; SoundBuffer.Samples = (short *)SoundOutput.Samples; - game_offscreen_buffer Buffer; Buffer.Memory = GlobalBackbuffer.Memory; Buffer.Width = GlobalBackbuffer.Width; Buffer.Height = GlobalBackbuffer.Height; @@ -654,41 +942,50 @@ S32 main(S32 argc, char *argv[]) } if(Game.UpdateAndRender) - Game.UpdateAndRender(&GameMemory, NewInput, &Buffer, &SoundBuffer); + Game.UpdateAndRender(&GameMemory, NewInput, &Buffer, + &SoundBuffer); SDLFillSoundBuffer(&SoundOutput, BytesToWrite); - U64 WorkCounter = SDLGetWallClock(); - F32 WorkSecondsElapsed = SDLGetSecondsElapsed(LastCounter, WorkCounter); + WorkCounter = SDLGetWallClock(); + WorkSecondsElapsed = SDLGetSecondsElapsed(LastCounter, + WorkCounter); - F32 SecondsElapsedForFrame = WorkSecondsElapsed; + SecondsElapsedForFrame = WorkSecondsElapsed; if(SecondsElapsedForFrame < TargetSecondsPerFrame) { while(SecondsElapsedForFrame < TargetSecondsPerFrame) { - SecondsElapsedForFrame = SDLGetSecondsElapsed(LastCounter, SDLGetWallClock()); - SDL_Delay((unsigned int)((TargetSecondsPerFrame - SecondsElapsedForFrame) * 1000.0)); + SecondsElapsedForFrame = + SDLGetSecondsElapsed(LastCounter, + SDLGetWallClock()); + SDL_Delay((U32)((TargetSecondsPerFrame - + SecondsElapsedForFrame) * 1000.0)); } } else { /* TODO: Missed frame rate! */ /* TODO: Logging. */ } - U64 EndCounter = SDLGetWallClock(); + EndCounter = SDLGetWallClock(); - SDLDisplayBufferInWindow(GlobalBackbuffer, Window, Renderer); + SDLDisplayBufferInWindow(GlobalBackbuffer, Window, + Renderer); - F64 MSPerFrame = 1000.0 * SDLGetSecondsElapsed(LastCounter, EndCounter); - F64 FPS = 0.0; + MSPerFrame = 1000.0 * SDLGetSecondsElapsed(LastCounter, + EndCounter); + FPS = 0.0; LastCounter = EndCounter; #if __x86_64__ || __i386__ - U64 EndCycleCount = __rdtsc(); - U64 CyclesElapsed = EndCycleCount - LastCycleCount; - F64 MCPF = ((double)CyclesElapsed / (1000.0 * 1000.0)); - fprintf(stderr, "%.02f ms/f, %.02f/s, %.02f mc/f\n", MSPerFrame, FPS, MCPF); + EndCycleCount = __rdtsc(); + CyclesElapsed = EndCycleCount - LastCycleCount; + MCPF = ((double)CyclesElapsed / (1000.0 * 1000.0)); + fprintf(stderr, "%.02f ms/f, %.02f/s, %.02f mc/f\n", + MSPerFrame, FPS, MCPF); LastCycleCount = EndCycleCount; #else - fprintf(stderr, "%.02f ms/f, %.02f/s\n", MSPerFrame, FPS); + fprintf(stderr, "%.02f ms/f, %.02f/s\n", + MSPerFrame, FPS); #endif SWAP(game_input *, NewInput, OldInput); @@ -704,7 +1001,9 @@ S32 main(S32 argc, char *argv[]) } /* NOTE: Let the OS clean things up. */ - /* SDLDeinitControllers(); // NOTE: This, however, might need to be closed? Is there maybe some clean up state that close communicates to the controller? */ + /* NOTE: This, however, might need to be closed? Is there maybe some + * clean up state that close communicates to the controller? */ + /* SDLDeinitControllers(); */ /* SDL_CloseAudio(); */ /* SDL_DestroyRenderer(Renderer); */ /* SDL_DestroyWindow(Window); */ diff --git a/sdl_handmade.h b/sdl_handmade.h index 9f42391..77e6554 100644 --- a/sdl_handmade.h +++ b/sdl_handmade.h @@ -12,7 +12,8 @@ typedef struct sdl_window_dimension { } sdl_window_dimension; typedef struct offscreen_buffer { - /* Pixels are always 32-bit and have the bytes in BGRX (little-endian). */ + /* Pixels are always 32-bit and have the bytes in BGRX + * (little-endian). */ SDL_Texture *Texture; void *Memory; S32 Width;