In process of migrating to ANSI C.

This commit is contained in:
2026-03-21 17:08:46 -07:00
parent a9573a440e
commit 8af1c59bb6
6 changed files with 222 additions and 133 deletions
+8 -7
View File
@@ -12,18 +12,19 @@ else
endif
endif
CC = clang++
CC = clang
UFLAGS =
FLAGS = -Wall -Wextra -ggdb -fno-caret-diagnostics -fno-show-column -Wno-missing-field-initializers -Wno-unused-function -Wno-unused-parameter -Wno-unused-variable -Wno-unused-but-set-variable
#-std=c99 -pedantic
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
ifeq ($(DETECTED_OS),macos)
UFLAGS = -gldb
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
else ifeq ($(DETECTED_OS),linux)
UFLAGS = -ggdb
INCLUDE = -I./sdl/include/
LIBS = ./sdl/lib/x86_64-linux/libSDL2.a -lm -lX11
FRAMEWORKS =
@@ -41,11 +42,11 @@ EXE=handmadehero
default: libhandmade $(EXE)
libhandmade: handmade.cpp
libhandmade: handmade.c
@ $(CC) $(FLAGS) $(UFLAGS) -fPIC -shared $(INCLUDE) $^ $(LIBS) $(FRAMEWORKS) -o libhandmade.so
$(EXE): sdl_handmade.cpp libhandmade
@ $(CC) $(FLAGS) $(UFLAGS) $(INCLUDE) sdl_handmade.cpp $(LIBS) $(FRAMEWORKS) -o $@
$(EXE): sdl_handmade.c libhandmade
@ $(CC) $(FLAGS) $(UFLAGS) $(INCLUDE) sdl_handmade.c $(LIBS) $(FRAMEWORKS) -o $@
run:
./$(EXE)
+8
View File
@@ -3,6 +3,14 @@
/* ---- Types ---------------------------------------------------------- */
#ifndef BUILD_DEBUG
#define BUILD_DEBUG 1
#endif
#ifndef BUILD_INTERNAL
#define BUILD_INTERNAL 1
#endif
#ifndef TRUE
#define TRUE 1
#endif
+22 -14
View File
@@ -1,3 +1,4 @@
#include "core.h"
#include "handmade.h"
#include "sdl_handmade.h"
@@ -9,9 +10,11 @@ static void GameOutputSound(game_state *GameState, game_sound_output_buffer *Sou
S32 WavePeriod = SoundBuffer->SamplesPerSecond / ToneHz;
S16 *SampleOut = SoundBuffer->Samples;
for(S32 SampleIndex = 0; SampleIndex < SoundBuffer->SampleCount; SampleIndex++) {
S32 SampleIndex;
for(SampleIndex = 0; SampleIndex < SoundBuffer->SampleCount; SampleIndex++) {
F32 SineValue = sinf(GameState->tSine);
S16 SampleValue = S16(SineValue * ToneVolume);
S16 SampleValue = (S16)(SineValue * ToneVolume);
*SampleOut++ = SampleValue;
*SampleOut++ = SampleValue;
@@ -28,9 +31,11 @@ static void RenderWeirdGradient(game_offscreen_buffer *Buffer, S32 XOffset, S32
S32 Height = Buffer->Height;
U8 *Row = (U8 *)Buffer->Memory;
for(S32 Y = 0; Y < Height; Y++) {
S32 Y;
for(Y = 0; Y < Height; Y++) {
U32 *Pixel = (U32 *)Row;
for(S32 X = 0; X < Width; X++) {
S32 X;
for(X = 0; X < Width; X++) {
U8 Blue = (U8)(X + XOffset);
U8 Green = (U8)(Y + YOffset);
@@ -48,24 +53,27 @@ void UpdateAndRender(game_memory *Memory, game_input *Input, game_offscreen_buff
game_state *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);
if(BitmapMemory.Contents) {
Memory->DEBUGPlatformWriteEntireFile("test.out", BitmapMemory.ContentsSize, BitmapMemory.Contents);
Memory->DEBUGPlatformFreeFileMemory(BitmapMemory.Contents);
}
#endif
GameState->ToneHz = 256;
GameState->tSine = 0.0f;
// TODO: Maybe more appropriate to do in the platform layer?
Memory->IsInitialized = true;
/* TODO: Maybe more appropriate to do in the platform layer? */
Memory->IsInitialized = TRUE;
}
// GameState.ToneHz;
// GameState.GreenOffset;
// GameState.BlueOffset;
/* GameState.ToneHz; */
/* GameState.GreenOffset; */
/* GameState.BlueOffset; */
for(U32 ControllerIndex = 0; ControllerIndex < ARRAY_SIZE(Input->Controllers); ControllerIndex++) {
U32 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));
@@ -73,16 +81,16 @@ void UpdateAndRender(game_memory *Memory, game_input *Input, game_offscreen_buff
GameState->ToneHz = 256 + (S32)(128.0f*(Controller->StickAverageY));
} else {
if(Controller->MoveUp.EndedDown) {
GameState->GreenOffset -= 1;
GameState->GreenOffset -= 5;
}
if(Controller->MoveDown.EndedDown) {
GameState->GreenOffset += 2;
GameState->GreenOffset += 5;
}
if(Controller->MoveLeft.EndedDown) {
GameState->BlueOffset -= 1;
GameState->BlueOffset -= 5;
}
if(Controller->MoveRight.EndedDown) {
GameState->BlueOffset += 1;
GameState->BlueOffset += 5;
}
}
}
+25 -26
View File
@@ -1,16 +1,13 @@
#ifndef HANDMADE_H
#define HANDMADE_H
#ifndef HANDMADE_H_SENTRY
#define HANDMADE_H_SENTRY
#include "sdl_handmade.h"
#include "core.h"
///////////////////////////////////////////////////////////////////////////////
// NOTE: Servcies that the platform layer provides to the game. //
///////////////////////////////////////////////////////////////////////////////
/* --------------------------------------------------------------------- */
/* NOTE: Servcies that the platform layer provides to the game. */
/* --------------------------------------------------------------------- */
#if BUILD_INTERNAL
// NOTE: WARNING: Not for the shipping game.
typedef struct debug_read_file_result {
U32 ContentsSize;
void *Contents;
@@ -21,12 +18,12 @@ B32 DEBUGPlatformWriteEntireFile(const char *Filename, U32 MemorySize, void *Mem
void DEBUGPlatformFreeFileMemory(void *Memory);
#endif
///////////////////////////////////////////////////////////////////////////////
// NOTE: Servcies that the game provides to the platform layer. //
///////////////////////////////////////////////////////////////////////////////
/* --------------------------------------------------------------------- */
/* NOTE: Servcies that the game provides to the platform layer. */
/* --------------------------------------------------------------------- */
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,7 +67,7 @@ typedef struct game_controller_input {
game_button_state Start;
game_button_state Back;
// NOTE: All buttons must be added above this line.
/* NOTE: All buttons must be added above this line. */
game_button_state Terminator;
};
@@ -78,11 +75,11 @@ typedef struct game_controller_input {
} game_controller_input;
typedef struct game_input {
// TODO: Insert clock value here . . .
/* TODO: Insert clock value here . . . */
game_controller_input Controllers[5];
} game_input;
inline game_controller_input *GetController(game_input *Input, S32 ControllerIndex)
game_controller_input *GetController(game_input *Input, S32 ControllerIndex)
{
Assert((U32)ControllerIndex < ARRAY_SIZE(Input->Controllers));
game_controller_input *Result = &(Input->Controllers[ControllerIndex]);
@@ -93,26 +90,28 @@ 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 *);
B32 (*DEBUGPlatformWriteEntireFile)(const char *, U32, void *);
void (*DEBUGPlatformFreeFileMemory)(void *);
#endif
} game_memory;
// typedef struct game_clocks {
// U64 Ticks;
// F32 SecondsElapsed;
// } game_clocks;
/*typedef struct game_clocks {
U64 Ticks;
F32 SecondsElapsed;
} game_clocks;*/
extern "C" 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;
@@ -122,4 +121,4 @@ typedef struct game_state {
F32 tSine;
} game_state;
#endif // HANDMADE_H
#endif
+145 -77
View File
@@ -1,29 +1,31 @@
/* NOTE: This layer only supports MacOS and Linux, for now. */
#include "core.h"
#include "handmade.h"
#include "sdl_handmade.h"
#include <SDL.h>
#include <sys/mman.h> // mmap
#include <stdlib.h> // malloc, calloc
#include <string.h> // memset
#include <sys/mman.h> /* mmap */
#include <stdlib.h> /* malloc, calloc */
#include <string.h> /* memset */
#include <stdio.h>
#include <sys/stat.h> // fstat
#include <fcntl.h> // open
#include <unistd.h> // close, read, readlink
#include <dlfcn.h> // dlopen
#include <sys/stat.h> // stat
#include <sys/stat.h> /* fstat */
#include <fcntl.h> /* open */
#include <unistd.h> /* close, write, read, readlink */
#include <dlfcn.h> /* dlopen */
#include <sys/stat.h> /* stat */
#if __APPLE__ && __MACH__
#include <mach-o/dyld.h>
#include <mach-o/dyld.h> /* _NSGetExecutablePath */
#endif
// NOTE: This is so it compiles on ARM.
/* NOTE: This is so it compiles on ARM. */
#if __x86_64__ || __i386__
#include <x86intrin.h>
#endif
static bool GlobalRunning;
static B32 GlobalRunning;
static U64 GlobalPerfCountFrequency;
@@ -86,7 +88,7 @@ B32 DEBUGPlatformWriteEntireFile(const char *Filename, U32 MemorySize, void *Mem
{
S32 FileHandle = open(Filename, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if(FileHandle == -1)
return false;
return FALSE;
U32 BytesToWrite = MemorySize;
U8 *NextByteLocation = (U8*)Memory;
@@ -94,7 +96,7 @@ B32 DEBUGPlatformWriteEntireFile(const char *Filename, U32 MemorySize, void *Mem
U32 BytesWritten = write(FileHandle, NextByteLocation, BytesToWrite);
if(BytesWritten == (U32)-1) {
close(FileHandle);
return false;
return FALSE;
}
BytesToWrite -= BytesWritten;
NextByteLocation += BytesWritten;
@@ -102,7 +104,7 @@ B32 DEBUGPlatformWriteEntireFile(const char *Filename, U32 MemorySize, void *Mem
close(FileHandle);
return true;
return TRUE;
}
void DEBUGPlatformFreeFileMemory(void *Memory)
@@ -140,7 +142,7 @@ static void SDLResizeTexture(offscreen_buffer *Buffer, SDL_Renderer *Renderer, i
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!
/* TODO: Do something about this error! */
}
SDL_RenderCopy(Renderer, Buffer.Texture, 0, 0);
@@ -198,7 +200,7 @@ static void SDLClearSoundBuffer(sdl_sound_output *SoundOutput)
memset(SoundOutput->Samples, 0, SoundOutput->SecondaryBufferSize);
}
static void SDLProcessKeyboardMessage(game_button_state *NewState, bool IsDown)
static void SDLProcessKeyboardMessage(game_button_state *NewState, B32 IsDown)
{
Assert(NewState->EndedDown != IsDown);
NewState->EndedDown = IsDown;
@@ -216,7 +218,7 @@ static void HandleEvent(SDL_Event *Event)
{
switch(Event->type) {
case SDL_QUIT: {
GlobalRunning = false;
GlobalRunning = FALSE;
} break;
case SDL_WINDOWEVENT: {
@@ -236,7 +238,49 @@ static void HandleEvent(SDL_Event *Event)
}
}
static void SDLProcessMessages(game_controller_input *KeyboardController)
static void SDLBeginRecordingInput(sdl_state *SDLState, S32 InputRecordingIndex)
{
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));
}
static void SDLEndRecordingInput(sdl_state *SDLState)
{
close(SDLState->RecordingHandle);
SDLState->InputRecordingIndex = 0;
}
static void SDLBeginInputPlayback(sdl_state *SDLState, S32 InputPlayingIndex)
{
SDLState->InputPlayingIndex = InputPlayingIndex;
const char *FileName = "foo.hmi";
SDLState->PlaybackHandle = open(FileName, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
}
static void SDLEndInputPlayback(sdl_state *SDLState)
{
close(SDLState->PlaybackHandle);
SDLState->InputPlayingIndex = 0;
}
static void SDLRecordInput(sdl_state *SDLState, game_input *NewInput)
{
write(SDLState->RecordingHandle, NewInput, sizeof(*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;
SDLEndInputPlayback(SDLState);
SDLBeginInputPlayback(SDLState, PlayingIndex);
}
}
static void SDLProcessMessages(sdl_state *SDLState, game_controller_input *KeyboardController)
{
SDL_Event Event;
while(SDL_PollEvent(&Event)) {
@@ -244,12 +288,12 @@ static void SDLProcessMessages(game_controller_input *KeyboardController)
case SDL_KEYDOWN:
case SDL_KEYUP: {
SDL_Keycode KeyCode = Event.key.keysym.sym;
bool IsDown = (Event.key.state == SDL_PRESSED);
bool WasDown = false;
B32 IsDown = (Event.key.state == SDL_PRESSED);
B32 WasDown = FALSE;
if(Event.key.state == SDL_RELEASED) {
WasDown = true;
WasDown = TRUE;
} else if(Event.key.repeat != 0) {
WasDown = true;
WasDown = TRUE;
}
if(Event.key.repeat == 0) {
@@ -280,12 +324,27 @@ static void SDLProcessMessages(game_controller_input *KeyboardController)
}
}
// 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.
bool AltKeyWasDown = (Event.key.keysym.mod & KMOD_ALT);
if(KeyCode == SDLK_F4 && AltKeyWasDown)
GlobalRunning = false;
if(KeyCode == SDLK_ESCAPE)
GlobalRunning = false;
if(WasDown) {
#if BUILD_INTERNAL
if(KeyCode == SDLK_l) {
if(SDLState->InputRecordingIndex == 0) {
SDLBeginRecordingInput(SDLState, 1);
} else {
SDLEndRecordingInput(SDLState);
SDLBeginInputPlayback(SDLState, 1);
}
}
#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);
if(KeyCode == SDLK_F4 && AltKeyWasDown)
GlobalRunning = FALSE;
#if BUILD_INTERNAL
if(KeyCode == SDLK_ESCAPE)
GlobalRunning = FALSE;
#endif
}
} break;
default: {
@@ -342,7 +401,7 @@ static U32 GetLastWriteTime(const char *FileName)
struct stat file_info = {0};
if(stat(FileName, &file_info) != 0) {
// TODO: Diagnostic. perror("stat failed");
/* TODO: Diagnostic. perror("stat failed"); */
}
return (U32)file_info.st_mtime;
@@ -360,12 +419,12 @@ static sdl_game_code SDLLoadGameCode(char *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()
/* TODO: Diagnostic. dlerror() */
}
Result.IsValid = Result.UpdateAndRender ? TRUE : FALSE;
} else {
// TODO: Diagnostic. dlerror()
/* TODO: Diagnostic. dlerror() */
}
if(!Result.IsValid) {
@@ -378,26 +437,27 @@ static sdl_game_code SDLLoadGameCode(char *DLLPath)
static void SDLUnloadGameCode(sdl_game_code *GameCode)
{
if(GameCode->GameCodeDLL)
dlclose(GameCode->GameCodeDLL); // NOTE: Might fail.
dlclose(GameCode->GameCodeDLL); /* NOTE: Might fail. */
GameCode->IsValid = FALSE;
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.
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);
#if __APPLE__ && __MACH__
if(_NSGetExecutablePath(path, &size) != 0) { // NOTE: Not an absolute path.
// TODO: Diagnostics.
U32 size = path_size;
if(_NSGetExecutablePath(path, &size) != 0) { /* NOTE: Not an absolute path. */
/* TODO: Diagnostics. */
}
#else
size = readlink("/proc/self/exe", path, size - 1);
ssize_t size = readlink("/proc/self/exe", path, path_size - 1);
if(size != -1) {
path[size] = '\0';
} else {
// TODO: Diagnostics.
/* TODO: Diagnostics. */
}
#endif
@@ -426,13 +486,14 @@ S32 main(S32 argc, char *argv[])
SDL_Window *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, 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_RenderPresent(Renderer) is enough to display the window.
/* "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) {
GlobalRunning = true;
sdl_state SDLState = {0};
GlobalRunning = TRUE;
sdl_window_dimension Dimension = SDLGetWindowDimension(Window);
SDLResizeTexture(&GlobalBackbuffer, Renderer, Dimension.Width, Dimension.Height);
@@ -448,8 +509,8 @@ S32 main(S32 argc, char *argv[])
SDL_PauseAudio(0);
SoundOutput.Samples = calloc(SoundOutput.SamplesPerSecond, SoundOutput.BytesPerSample);
// SoundOutput.Samples = malloc(SoundOutput.SecondaryBufferSize);
// SDLClearSoundBuffer(&SoundOutput); // NOTE: calloc auto clears to zero
/* SoundOutput.Samples = malloc(SoundOutput.SecondaryBufferSize); */
/* SDLClearSoundBuffer(&SoundOutput); */ /* NOTE: calloc auto clears to zero */
#if BUILD_DEBUG
void *BaseAddress = (void *)TB(2);
@@ -458,19 +519,17 @@ S32 main(S32 argc, char *argv[])
#endif
game_memory GameMemory = {0};
GameMemory.PermanentStorageSize = MB(64);
GameMemory.TransientStorageSize = GB(4);
U64 TotalStorageSize = GameMemory.PermanentStorageSize + GameMemory.TransientStorageSize;
// NOTE: On MacOS and Linux, mmap seems to zero-fill anonymous memory as a side-effect of security.
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;
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. */
GameMemory.PermanentStorage = SDLState.GameMmemoryBlock;
GameMemory.TransientStorage = (U8 *)(GameMemory.PermanentStorage) + GameMemory.PermanentStorageSize;
if(SoundOutput.Samples && GameMemory.PermanentStorage && GameMemory.TransientStorage) {
game_input Input[2];
game_input *NewInput = &Input[0];
@@ -490,11 +549,11 @@ S32 main(S32 argc, char *argv[])
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.
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. */
S32 MonitorRefreshHz = SDLGetWindowRefreshRate(Window);
S32 GameUpdateHz = MonitorRefreshHz / 2;
S32 GameUpdateHz = MonitorRefreshHz;
F32 TargetSecondsPerFrame = 1.0f / (F32)GameUpdateHz;
U32 NewDLLWriteTime = GetLastWriteTime(game_dll_path);
@@ -507,50 +566,50 @@ S32 main(S32 argc, char *argv[])
game_controller_input *NewKeyboardController = GetController(NewInput, 0);
game_controller_input ZeroController = {0};
*NewKeyboardController = ZeroController;
NewKeyboardController->IsConnected = true;
NewKeyboardController->IsConnected = TRUE;
for(unsigned int ButtonIndex = 0; ButtonIndex < ARRAY_SIZE(NewKeyboardController->Buttons); ButtonIndex++) {
NewKeyboardController->Buttons[ButtonIndex].EndedDown = OldKeyboardController->Buttons[ButtonIndex].EndedDown;
}
SDLProcessMessages(NewKeyboardController);
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);
if(ControllerHandles[ControllerIndex] != 0 && SDL_GameControllerGetAttached(ControllerHandles[ControllerIndex])) {
NewController->IsConnected = true;
NewController->IsConnected = TRUE;
S16 StickX = SDL_GameControllerGetAxis(ControllerHandles[ControllerIndex], SDL_CONTROLLER_AXIS_LEFTX);
S16 StickY = SDL_GameControllerGetAxis(ControllerHandles[ControllerIndex], SDL_CONTROLLER_AXIS_LEFTY);
NewController->IsAnalog = true;
NewController->IsAnalog = TRUE;
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)) {
NewController->IsAnalog = true;
NewController->IsAnalog = TRUE;
}
if(SDL_GameControllerGetButton(ControllerHandles[ControllerIndex], SDL_CONTROLLER_BUTTON_DPAD_UP)) {
NewController->StickAverageY = -1.0f;
NewController->IsAnalog = false;
NewController->IsAnalog = FALSE;
}
if(SDL_GameControllerGetButton(ControllerHandles[ControllerIndex], SDL_CONTROLLER_BUTTON_DPAD_DOWN)) {
NewController->StickAverageY = 1.0f;
NewController->IsAnalog = false;
NewController->IsAnalog = FALSE;
}
if(SDL_GameControllerGetButton(ControllerHandles[ControllerIndex], SDL_CONTROLLER_BUTTON_DPAD_LEFT)) {
NewController->StickAverageX = -1.0f;
NewController->IsAnalog = false;
NewController->IsAnalog = FALSE;
}
if(SDL_GameControllerGetButton(ControllerHandles[ControllerIndex], SDL_CONTROLLER_BUTTON_DPAD_RIGHT)) {
NewController->StickAverageX = 1.0f;
NewController->IsAnalog = false;
NewController->IsAnalog = FALSE;
}
float Threshold = 0.5f;
@@ -569,8 +628,8 @@ S32 main(S32 argc, char *argv[])
SDLProcessInputDigitalButton(ControllerHandles[ControllerIndex], &OldController->Start, SDL_CONTROLLER_BUTTON_START, &NewController->Start);
SDLProcessInputDigitalButton(ControllerHandles[ControllerIndex], &OldController->Back, SDL_CONTROLLER_BUTTON_BACK, &NewController->Back);
} else {
// NOTE: This controller is not plugged in.
NewController->IsConnected = false;
/* NOTE: This controller is not plugged in. */
NewController->IsConnected = FALSE;
}
}
@@ -586,8 +645,17 @@ S32 main(S32 argc, char *argv[])
Buffer.Width = GlobalBackbuffer.Width;
Buffer.Height = GlobalBackbuffer.Height;
Buffer.Pitch = GlobalBackbuffer.Pitch;
if(SDLState.InputRecordingIndex) {
SDLRecordInput(&SDLState, NewInput);
}
if(SDLState.InputPlayingIndex) {
SDLPlaybackInput(&SDLState, NewInput);
}
if(Game.UpdateAndRender)
Game.UpdateAndRender(&GameMemory, NewInput, &Buffer, &SoundBuffer);
SDLFillSoundBuffer(&SoundOutput, BytesToWrite);
U64 WorkCounter = SDLGetWallClock();
@@ -600,8 +668,8 @@ S32 main(S32 argc, char *argv[])
SDL_Delay((unsigned int)((TargetSecondsPerFrame - SecondsElapsedForFrame) * 1000.0));
}
} else {
// TODO: Missed frame rate!
// TODO: Logging.
/* TODO: Missed frame rate! */
/* TODO: Logging. */
}
U64 EndCounter = SDLGetWallClock();
@@ -626,21 +694,21 @@ S32 main(S32 argc, char *argv[])
SWAP(game_input *, NewInput, OldInput);
}
} else {
// TODO: Failed to allocate Samples and Sound memory . . .
/* TODO: Failed to allocate Samples and Sound memory . . . */
}
} else {
// TODO: This didn't work . . .
/* TODO: This didn't work . . . */
}
} else {
// TODO: This didn't work . . .
/* TODO: This didn't work . . . */
}
// 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?
// SDL_CloseAudio();
// SDL_DestroyRenderer(Renderer);
// SDL_DestroyWindow(Window);
// SDL_Quit();
/* 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? */
/* SDL_CloseAudio(); */
/* SDL_DestroyRenderer(Renderer); */
/* SDL_DestroyWindow(Window); */
/* SDL_Quit(); */
return 0;
}
+14 -9
View File
@@ -1,16 +1,10 @@
#ifndef SDL_HANDMADE_H
#define SDL_HANDMADE_H
#include "core.h"
#include <SDL.h>
#if !defined(BUILD_DEBUG)
# define BUILD_DEBUG 1
#endif
#if !defined(BUILD_INTERNAL) // NOTE: Added in by igor.
# define BUILD_INTERNAL 1
#endif
#include "core.h"
#include "handmade.h"
typedef struct sdl_window_dimension {
S32 Width;
@@ -18,7 +12,7 @@ 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;
@@ -35,4 +29,15 @@ typedef struct sdl_sound_output {
void *Samples;
} sdl_sound_output;
typedef struct sdl_state {
U64 TotalSize;
void *GameMmemoryBlock;
S32 RecordingHandle;
S32 InputRecordingIndex;
S32 PlaybackHandle;
S32 InputPlayingIndex;
} sdl_state;
#endif