In process of migrating to ANSI C.
This commit is contained in:
@@ -12,18 +12,19 @@ else
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CC = clang++
|
CC = clang
|
||||||
|
|
||||||
UFLAGS =
|
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
|
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
|
||||||
#-std=c99 -pedantic
|
# -pedantic-errors
|
||||||
|
|
||||||
ifeq ($(DETECTED_OS),macos)
|
ifeq ($(DETECTED_OS),macos)
|
||||||
|
UFLAGS = -gldb
|
||||||
INCLUDE = -I./sdl/include/
|
INCLUDE = -I./sdl/include/
|
||||||
LIBS = ./sdl/lib/arm-macos/libSDL2.a -lm
|
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)
|
else ifeq ($(DETECTED_OS),linux)
|
||||||
|
UFLAGS = -ggdb
|
||||||
INCLUDE = -I./sdl/include/
|
INCLUDE = -I./sdl/include/
|
||||||
LIBS = ./sdl/lib/x86_64-linux/libSDL2.a -lm -lX11
|
LIBS = ./sdl/lib/x86_64-linux/libSDL2.a -lm -lX11
|
||||||
FRAMEWORKS =
|
FRAMEWORKS =
|
||||||
@@ -41,11 +42,11 @@ EXE=handmadehero
|
|||||||
|
|
||||||
default: libhandmade $(EXE)
|
default: libhandmade $(EXE)
|
||||||
|
|
||||||
libhandmade: handmade.cpp
|
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.cpp libhandmade
|
$(EXE): sdl_handmade.c libhandmade
|
||||||
@ $(CC) $(FLAGS) $(UFLAGS) $(INCLUDE) sdl_handmade.cpp $(LIBS) $(FRAMEWORKS) -o $@
|
@ $(CC) $(FLAGS) $(UFLAGS) $(INCLUDE) sdl_handmade.c $(LIBS) $(FRAMEWORKS) -o $@
|
||||||
|
|
||||||
run:
|
run:
|
||||||
./$(EXE)
|
./$(EXE)
|
||||||
|
|||||||
@@ -3,6 +3,14 @@
|
|||||||
|
|
||||||
/* ---- Types ---------------------------------------------------------- */
|
/* ---- Types ---------------------------------------------------------- */
|
||||||
|
|
||||||
|
#ifndef BUILD_DEBUG
|
||||||
|
#define BUILD_DEBUG 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BUILD_INTERNAL
|
||||||
|
#define BUILD_INTERNAL 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef TRUE
|
#ifndef TRUE
|
||||||
#define TRUE 1
|
#define TRUE 1
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+22
-14
@@ -1,3 +1,4 @@
|
|||||||
|
#include "core.h"
|
||||||
#include "handmade.h"
|
#include "handmade.h"
|
||||||
#include "sdl_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;
|
S32 WavePeriod = SoundBuffer->SamplesPerSecond / ToneHz;
|
||||||
|
|
||||||
S16 *SampleOut = SoundBuffer->Samples;
|
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);
|
F32 SineValue = sinf(GameState->tSine);
|
||||||
S16 SampleValue = S16(SineValue * ToneVolume);
|
S16 SampleValue = (S16)(SineValue * ToneVolume);
|
||||||
*SampleOut++ = SampleValue;
|
*SampleOut++ = SampleValue;
|
||||||
*SampleOut++ = SampleValue;
|
*SampleOut++ = SampleValue;
|
||||||
|
|
||||||
@@ -28,9 +31,11 @@ static void RenderWeirdGradient(game_offscreen_buffer *Buffer, S32 XOffset, S32
|
|||||||
S32 Height = Buffer->Height;
|
S32 Height = Buffer->Height;
|
||||||
|
|
||||||
U8 *Row = (U8 *)Buffer->Memory;
|
U8 *Row = (U8 *)Buffer->Memory;
|
||||||
for(S32 Y = 0; Y < Height; Y++) {
|
S32 Y;
|
||||||
|
for(Y = 0; Y < Height; Y++) {
|
||||||
U32 *Pixel = (U32 *)Row;
|
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 Blue = (U8)(X + XOffset);
|
||||||
U8 Green = (U8)(Y + YOffset);
|
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;
|
game_state *GameState = (game_state *)Memory->PermanentStorage;
|
||||||
if(!Memory->IsInitialized) {
|
if(!Memory->IsInitialized) {
|
||||||
|
#if BUILD_INTERNAL
|
||||||
char FileName[] = "/home/igor/Developer/handmade/sdl_handmade.cpp";
|
char FileName[] = "/home/igor/Developer/handmade/sdl_handmade.cpp";
|
||||||
debug_read_file_result BitmapMemory = Memory->DEBUGPlatformReadEntireFile(FileName);
|
debug_read_file_result BitmapMemory = Memory->DEBUGPlatformReadEntireFile(FileName);
|
||||||
if(BitmapMemory.Contents) {
|
if(BitmapMemory.Contents) {
|
||||||
Memory->DEBUGPlatformWriteEntireFile("test.out", BitmapMemory.ContentsSize, BitmapMemory.Contents);
|
Memory->DEBUGPlatformWriteEntireFile("test.out", BitmapMemory.ContentsSize, BitmapMemory.Contents);
|
||||||
Memory->DEBUGPlatformFreeFileMemory(BitmapMemory.Contents);
|
Memory->DEBUGPlatformFreeFileMemory(BitmapMemory.Contents);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
GameState->ToneHz = 256;
|
GameState->ToneHz = 256;
|
||||||
GameState->tSine = 0.0f;
|
GameState->tSine = 0.0f;
|
||||||
|
|
||||||
// TODO: Maybe more appropriate to do in the platform layer?
|
/* TODO: Maybe more appropriate to do in the platform layer? */
|
||||||
Memory->IsInitialized = true;
|
Memory->IsInitialized = TRUE;
|
||||||
}
|
}
|
||||||
// GameState.ToneHz;
|
/* GameState.ToneHz; */
|
||||||
// GameState.GreenOffset;
|
/* GameState.GreenOffset; */
|
||||||
// GameState.BlueOffset;
|
/* 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);
|
game_controller_input *Controller = GetController(Input, ControllerIndex);
|
||||||
if(Controller->IsAnalog) {
|
if(Controller->IsAnalog) {
|
||||||
GameState->GreenOffset += (int)(4.0f*(Controller->StickAverageY));
|
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));
|
GameState->ToneHz = 256 + (S32)(128.0f*(Controller->StickAverageY));
|
||||||
} else {
|
} else {
|
||||||
if(Controller->MoveUp.EndedDown) {
|
if(Controller->MoveUp.EndedDown) {
|
||||||
GameState->GreenOffset -= 1;
|
GameState->GreenOffset -= 5;
|
||||||
}
|
}
|
||||||
if(Controller->MoveDown.EndedDown) {
|
if(Controller->MoveDown.EndedDown) {
|
||||||
GameState->GreenOffset += 2;
|
GameState->GreenOffset += 5;
|
||||||
}
|
}
|
||||||
if(Controller->MoveLeft.EndedDown) {
|
if(Controller->MoveLeft.EndedDown) {
|
||||||
GameState->BlueOffset -= 1;
|
GameState->BlueOffset -= 5;
|
||||||
}
|
}
|
||||||
if(Controller->MoveRight.EndedDown) {
|
if(Controller->MoveRight.EndedDown) {
|
||||||
GameState->BlueOffset += 1;
|
GameState->BlueOffset += 5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+25
-26
@@ -1,16 +1,13 @@
|
|||||||
#ifndef HANDMADE_H
|
#ifndef HANDMADE_H_SENTRY
|
||||||
#define HANDMADE_H
|
#define HANDMADE_H_SENTRY
|
||||||
|
|
||||||
#include "sdl_handmade.h"
|
|
||||||
#include "core.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
|
#if BUILD_INTERNAL
|
||||||
// NOTE: WARNING: Not for the shipping game.
|
|
||||||
|
|
||||||
typedef struct debug_read_file_result {
|
typedef struct debug_read_file_result {
|
||||||
U32 ContentsSize;
|
U32 ContentsSize;
|
||||||
void *Contents;
|
void *Contents;
|
||||||
@@ -21,12 +18,12 @@ B32 DEBUGPlatformWriteEntireFile(const char *Filename, U32 MemorySize, void *Mem
|
|||||||
void DEBUGPlatformFreeFileMemory(void *Memory);
|
void DEBUGPlatformFreeFileMemory(void *Memory);
|
||||||
#endif
|
#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 {
|
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;
|
void *Memory;
|
||||||
S32 Width;
|
S32 Width;
|
||||||
S32 Height;
|
S32 Height;
|
||||||
@@ -70,7 +67,7 @@ typedef struct game_controller_input {
|
|||||||
game_button_state Start;
|
game_button_state Start;
|
||||||
game_button_state Back;
|
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;
|
game_button_state Terminator;
|
||||||
};
|
};
|
||||||
@@ -78,11 +75,11 @@ typedef struct game_controller_input {
|
|||||||
} game_controller_input;
|
} game_controller_input;
|
||||||
|
|
||||||
typedef struct game_input {
|
typedef struct game_input {
|
||||||
// TODO: Insert clock value here . . .
|
/* TODO: Insert clock value here . . . */
|
||||||
game_controller_input Controllers[5];
|
game_controller_input Controllers[5];
|
||||||
} game_input;
|
} 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));
|
Assert((U32)ControllerIndex < ARRAY_SIZE(Input->Controllers));
|
||||||
game_controller_input *Result = &(Input->Controllers[ControllerIndex]);
|
game_controller_input *Result = &(Input->Controllers[ControllerIndex]);
|
||||||
@@ -93,26 +90,28 @@ typedef struct game_memory {
|
|||||||
B32 IsInitialized;
|
B32 IsInitialized;
|
||||||
|
|
||||||
U64 PermanentStorageSize;
|
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;
|
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 *);
|
debug_read_file_result (*DEBUGPlatformReadEntireFile)(const char *);
|
||||||
B32 (*DEBUGPlatformWriteEntireFile)(const char *, U32, void *);
|
B32 (*DEBUGPlatformWriteEntireFile)(const char *, U32, void *);
|
||||||
void (*DEBUGPlatformFreeFileMemory)(void *);
|
void (*DEBUGPlatformFreeFileMemory)(void *);
|
||||||
|
#endif
|
||||||
} game_memory;
|
} game_memory;
|
||||||
|
|
||||||
// typedef struct game_clocks {
|
/*typedef struct game_clocks {
|
||||||
// U64 Ticks;
|
U64 Ticks;
|
||||||
// F32 SecondsElapsed;
|
F32 SecondsElapsed;
|
||||||
// } game_clocks;
|
} 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 {
|
typedef struct game_state {
|
||||||
S32 ToneHz;
|
S32 ToneHz;
|
||||||
@@ -122,4 +121,4 @@ typedef struct game_state {
|
|||||||
F32 tSine;
|
F32 tSine;
|
||||||
} game_state;
|
} game_state;
|
||||||
|
|
||||||
#endif // HANDMADE_H
|
#endif
|
||||||
|
|||||||
@@ -1,29 +1,31 @@
|
|||||||
|
/* NOTE: This layer only supports MacOS and Linux, for now. */
|
||||||
|
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
|
|
||||||
#include "handmade.h"
|
#include "handmade.h"
|
||||||
#include "sdl_handmade.h"
|
#include "sdl_handmade.h"
|
||||||
|
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#include <sys/mman.h> // mmap
|
#include <sys/mman.h> /* mmap */
|
||||||
#include <stdlib.h> // malloc, calloc
|
#include <stdlib.h> /* malloc, calloc */
|
||||||
#include <string.h> // memset
|
#include <string.h> /* memset */
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <sys/stat.h> // fstat
|
#include <sys/stat.h> /* fstat */
|
||||||
#include <fcntl.h> // open
|
#include <fcntl.h> /* open */
|
||||||
#include <unistd.h> // close, read, readlink
|
#include <unistd.h> /* close, write, read, readlink */
|
||||||
#include <dlfcn.h> // dlopen
|
#include <dlfcn.h> /* dlopen */
|
||||||
#include <sys/stat.h> // stat
|
#include <sys/stat.h> /* stat */
|
||||||
#if __APPLE__ && __MACH__
|
#if __APPLE__ && __MACH__
|
||||||
#include <mach-o/dyld.h>
|
#include <mach-o/dyld.h> /* _NSGetExecutablePath */
|
||||||
#endif
|
#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__
|
||||||
#include <x86intrin.h>
|
#include <x86intrin.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static bool GlobalRunning;
|
static B32 GlobalRunning;
|
||||||
|
|
||||||
static U64 GlobalPerfCountFrequency;
|
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);
|
S32 FileHandle = open(Filename, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||||
if(FileHandle == -1)
|
if(FileHandle == -1)
|
||||||
return false;
|
return FALSE;
|
||||||
|
|
||||||
U32 BytesToWrite = MemorySize;
|
U32 BytesToWrite = MemorySize;
|
||||||
U8 *NextByteLocation = (U8*)Memory;
|
U8 *NextByteLocation = (U8*)Memory;
|
||||||
@@ -94,7 +96,7 @@ B32 DEBUGPlatformWriteEntireFile(const char *Filename, U32 MemorySize, void *Mem
|
|||||||
U32 BytesWritten = write(FileHandle, NextByteLocation, BytesToWrite);
|
U32 BytesWritten = write(FileHandle, NextByteLocation, BytesToWrite);
|
||||||
if(BytesWritten == (U32)-1) {
|
if(BytesWritten == (U32)-1) {
|
||||||
close(FileHandle);
|
close(FileHandle);
|
||||||
return false;
|
return FALSE;
|
||||||
}
|
}
|
||||||
BytesToWrite -= BytesWritten;
|
BytesToWrite -= BytesWritten;
|
||||||
NextByteLocation += BytesWritten;
|
NextByteLocation += BytesWritten;
|
||||||
@@ -102,7 +104,7 @@ B32 DEBUGPlatformWriteEntireFile(const char *Filename, U32 MemorySize, void *Mem
|
|||||||
|
|
||||||
close(FileHandle);
|
close(FileHandle);
|
||||||
|
|
||||||
return true;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DEBUGPlatformFreeFileMemory(void *Memory)
|
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)
|
static void SDLDisplayBufferInWindow(offscreen_buffer Buffer, SDL_Window *Window, SDL_Renderer *Renderer)
|
||||||
{
|
{
|
||||||
if(SDL_UpdateTexture(Buffer.Texture, 0, Buffer.Memory, Buffer.Pitch)) {
|
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);
|
SDL_RenderCopy(Renderer, Buffer.Texture, 0, 0);
|
||||||
@@ -198,7 +200,7 @@ static void SDLClearSoundBuffer(sdl_sound_output *SoundOutput)
|
|||||||
memset(SoundOutput->Samples, 0, SoundOutput->SecondaryBufferSize);
|
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);
|
Assert(NewState->EndedDown != IsDown);
|
||||||
NewState->EndedDown = IsDown;
|
NewState->EndedDown = IsDown;
|
||||||
@@ -216,7 +218,7 @@ static void HandleEvent(SDL_Event *Event)
|
|||||||
{
|
{
|
||||||
switch(Event->type) {
|
switch(Event->type) {
|
||||||
case SDL_QUIT: {
|
case SDL_QUIT: {
|
||||||
GlobalRunning = false;
|
GlobalRunning = FALSE;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case SDL_WINDOWEVENT: {
|
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;
|
SDL_Event Event;
|
||||||
while(SDL_PollEvent(&Event)) {
|
while(SDL_PollEvent(&Event)) {
|
||||||
@@ -244,12 +288,12 @@ static void SDLProcessMessages(game_controller_input *KeyboardController)
|
|||||||
case SDL_KEYDOWN:
|
case SDL_KEYDOWN:
|
||||||
case SDL_KEYUP: {
|
case SDL_KEYUP: {
|
||||||
SDL_Keycode KeyCode = Event.key.keysym.sym;
|
SDL_Keycode KeyCode = Event.key.keysym.sym;
|
||||||
bool IsDown = (Event.key.state == SDL_PRESSED);
|
B32 IsDown = (Event.key.state == SDL_PRESSED);
|
||||||
bool WasDown = false;
|
B32 WasDown = FALSE;
|
||||||
if(Event.key.state == SDL_RELEASED) {
|
if(Event.key.state == SDL_RELEASED) {
|
||||||
WasDown = true;
|
WasDown = TRUE;
|
||||||
} else if(Event.key.repeat != 0) {
|
} else if(Event.key.repeat != 0) {
|
||||||
WasDown = true;
|
WasDown = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Event.key.repeat == 0) {
|
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.
|
if(WasDown) {
|
||||||
bool AltKeyWasDown = (Event.key.keysym.mod & KMOD_ALT);
|
#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)
|
if(KeyCode == SDLK_F4 && AltKeyWasDown)
|
||||||
GlobalRunning = false;
|
GlobalRunning = FALSE;
|
||||||
|
#if BUILD_INTERNAL
|
||||||
if(KeyCode == SDLK_ESCAPE)
|
if(KeyCode == SDLK_ESCAPE)
|
||||||
GlobalRunning = false;
|
GlobalRunning = FALSE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
@@ -342,7 +401,7 @@ static U32 GetLastWriteTime(const char *FileName)
|
|||||||
struct stat file_info = {0};
|
struct stat file_info = {0};
|
||||||
|
|
||||||
if(stat(FileName, &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;
|
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");
|
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() */
|
||||||
}
|
}
|
||||||
|
|
||||||
Result.IsValid = Result.UpdateAndRender ? TRUE : FALSE;
|
Result.IsValid = Result.UpdateAndRender ? TRUE : FALSE;
|
||||||
} else {
|
} else {
|
||||||
// TODO: Diagnostic. dlerror()
|
/* TODO: Diagnostic. dlerror() */
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!Result.IsValid) {
|
if(!Result.IsValid) {
|
||||||
@@ -378,26 +437,27 @@ static sdl_game_code SDLLoadGameCode(char *DLLPath)
|
|||||||
static void SDLUnloadGameCode(sdl_game_code *GameCode)
|
static void SDLUnloadGameCode(sdl_game_code *GameCode)
|
||||||
{
|
{
|
||||||
if(GameCode->GameCodeDLL)
|
if(GameCode->GameCodeDLL)
|
||||||
dlclose(GameCode->GameCodeDLL); // NOTE: Might fail.
|
dlclose(GameCode->GameCodeDLL); /* NOTE: Might fail. */
|
||||||
GameCode->IsValid = FALSE;
|
GameCode->IsValid = FALSE;
|
||||||
GameCode->UpdateAndRender = NULL;
|
GameCode->UpdateAndRender = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *GetExecutablePath()
|
char *GetExecutablePath()
|
||||||
{
|
{
|
||||||
static char path[1024] = ""; // NOTE: We choose 1024 only because MacOS's MAXPATHLEN says such a value.
|
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. */
|
||||||
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.
|
size_t path_size = sizeof(path);
|
||||||
|
|
||||||
#if __APPLE__ && __MACH__
|
#if __APPLE__ && __MACH__
|
||||||
if(_NSGetExecutablePath(path, &size) != 0) { // NOTE: Not an absolute path.
|
U32 size = path_size;
|
||||||
// TODO: Diagnostics.
|
if(_NSGetExecutablePath(path, &size) != 0) { /* NOTE: Not an absolute path. */
|
||||||
|
/* TODO: Diagnostics. */
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
size = readlink("/proc/self/exe", path, size - 1);
|
ssize_t size = readlink("/proc/self/exe", path, path_size - 1);
|
||||||
if(size != -1) {
|
if(size != -1) {
|
||||||
path[size] = '\0';
|
path[size] = '\0';
|
||||||
} else {
|
} else {
|
||||||
// TODO: Diagnostics.
|
/* TODO: Diagnostics. */
|
||||||
}
|
}
|
||||||
#endif
|
#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);
|
SDL_Window *Window = SDL_CreateWindow("Handmade Hero", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 700, 500, SDL_WINDOW_RESIZABLE);
|
||||||
|
|
||||||
if(Window) {
|
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);
|
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
|
/* "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.
|
/* 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.
|
/* SDL_RenderPresent(Renderer) is enough to display the window. */
|
||||||
if(Renderer) {
|
if(Renderer) {
|
||||||
GlobalRunning = true;
|
sdl_state SDLState = {0};
|
||||||
|
GlobalRunning = TRUE;
|
||||||
|
|
||||||
sdl_window_dimension Dimension = SDLGetWindowDimension(Window);
|
sdl_window_dimension Dimension = SDLGetWindowDimension(Window);
|
||||||
SDLResizeTexture(&GlobalBackbuffer, Renderer, Dimension.Width, Dimension.Height);
|
SDLResizeTexture(&GlobalBackbuffer, Renderer, Dimension.Width, Dimension.Height);
|
||||||
@@ -448,8 +509,8 @@ S32 main(S32 argc, char *argv[])
|
|||||||
SDL_PauseAudio(0);
|
SDL_PauseAudio(0);
|
||||||
|
|
||||||
SoundOutput.Samples = calloc(SoundOutput.SamplesPerSecond, SoundOutput.BytesPerSample);
|
SoundOutput.Samples = calloc(SoundOutput.SamplesPerSecond, SoundOutput.BytesPerSample);
|
||||||
// SoundOutput.Samples = malloc(SoundOutput.SecondaryBufferSize);
|
/* SoundOutput.Samples = malloc(SoundOutput.SecondaryBufferSize); */
|
||||||
// SDLClearSoundBuffer(&SoundOutput); // NOTE: calloc auto clears to zero
|
/* SDLClearSoundBuffer(&SoundOutput); */ /* NOTE: calloc auto clears to zero */
|
||||||
|
|
||||||
#if BUILD_DEBUG
|
#if BUILD_DEBUG
|
||||||
void *BaseAddress = (void *)TB(2);
|
void *BaseAddress = (void *)TB(2);
|
||||||
@@ -458,19 +519,17 @@ S32 main(S32 argc, char *argv[])
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
game_memory GameMemory = {0};
|
game_memory GameMemory = {0};
|
||||||
|
|
||||||
GameMemory.PermanentStorageSize = MB(64);
|
GameMemory.PermanentStorageSize = MB(64);
|
||||||
GameMemory.TransientStorageSize = GB(4);
|
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.DEBUGPlatformReadEntireFile = &DEBUGPlatformReadEntireFile;
|
||||||
GameMemory.DEBUGPlatformWriteEntireFile = &DEBUGPlatformWriteEntireFile;
|
GameMemory.DEBUGPlatformWriteEntireFile = &DEBUGPlatformWriteEntireFile;
|
||||||
GameMemory.DEBUGPlatformFreeFileMemory = &DEBUGPlatformFreeFileMemory;
|
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) {
|
if(SoundOutput.Samples && GameMemory.PermanentStorage && GameMemory.TransientStorage) {
|
||||||
game_input Input[2];
|
game_input Input[2];
|
||||||
game_input *NewInput = &Input[0];
|
game_input *NewInput = &Input[0];
|
||||||
@@ -490,11 +549,11 @@ S32 main(S32 argc, char *argv[])
|
|||||||
LastCounter = SDLGetWallClock();
|
LastCounter = SDLGetWallClock();
|
||||||
|
|
||||||
#if __x86_64__ || __i386__
|
#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.
|
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.
|
#endif /* Also, __rdtsc is not available on MacOS ARM; I have not checked MacOS x64. */
|
||||||
|
|
||||||
S32 MonitorRefreshHz = SDLGetWindowRefreshRate(Window);
|
S32 MonitorRefreshHz = SDLGetWindowRefreshRate(Window);
|
||||||
S32 GameUpdateHz = MonitorRefreshHz / 2;
|
S32 GameUpdateHz = MonitorRefreshHz;
|
||||||
F32 TargetSecondsPerFrame = 1.0f / (F32)GameUpdateHz;
|
F32 TargetSecondsPerFrame = 1.0f / (F32)GameUpdateHz;
|
||||||
|
|
||||||
U32 NewDLLWriteTime = GetLastWriteTime(game_dll_path);
|
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 *NewKeyboardController = GetController(NewInput, 0);
|
||||||
game_controller_input ZeroController = {0};
|
game_controller_input ZeroController = {0};
|
||||||
*NewKeyboardController = ZeroController;
|
*NewKeyboardController = ZeroController;
|
||||||
NewKeyboardController->IsConnected = true;
|
NewKeyboardController->IsConnected = TRUE;
|
||||||
|
|
||||||
for(unsigned int ButtonIndex = 0; ButtonIndex < ARRAY_SIZE(NewKeyboardController->Buttons); ButtonIndex++) {
|
for(unsigned int ButtonIndex = 0; ButtonIndex < ARRAY_SIZE(NewKeyboardController->Buttons); ButtonIndex++) {
|
||||||
NewKeyboardController->Buttons[ButtonIndex].EndedDown = OldKeyboardController->Buttons[ButtonIndex].EndedDown;
|
NewKeyboardController->Buttons[ButtonIndex].EndedDown = OldKeyboardController->Buttons[ButtonIndex].EndedDown;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDLProcessMessages(NewKeyboardController);
|
SDLProcessMessages(&SDLState, NewKeyboardController);
|
||||||
|
|
||||||
for(unsigned int ControllerIndex = 0; ControllerIndex < MAX_CONTROLLERS; ControllerIndex++) {
|
for(unsigned int ControllerIndex = 0; ControllerIndex < MAX_CONTROLLERS; ControllerIndex++) {
|
||||||
game_controller_input *OldController = GetController(OldInput, ControllerIndex+1);
|
game_controller_input *OldController = GetController(OldInput, ControllerIndex+1);
|
||||||
game_controller_input *NewController = GetController(NewInput, ControllerIndex+1);
|
game_controller_input *NewController = GetController(NewInput, ControllerIndex+1);
|
||||||
|
|
||||||
if(ControllerHandles[ControllerIndex] != 0 && SDL_GameControllerGetAttached(ControllerHandles[ControllerIndex])) {
|
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 StickX = SDL_GameControllerGetAxis(ControllerHandles[ControllerIndex], SDL_CONTROLLER_AXIS_LEFTX);
|
||||||
S16 StickY = SDL_GameControllerGetAxis(ControllerHandles[ControllerIndex], SDL_CONTROLLER_AXIS_LEFTY);
|
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->StickAverageX = SDLProcessInputStickValue((F32)StickX, CONTROLLER_LEFT_THUMB_DEADZONE);
|
||||||
NewController->StickAverageY = SDLProcessInputStickValue((F32)StickY, 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;
|
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->StickAverageY = -1.0f;
|
||||||
NewController->IsAnalog = false;
|
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->StickAverageY = 1.0f;
|
||||||
NewController->IsAnalog = false;
|
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->StickAverageX = -1.0f;
|
||||||
NewController->IsAnalog = false;
|
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->StickAverageX = 1.0f;
|
||||||
NewController->IsAnalog = false;
|
NewController->IsAnalog = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Threshold = 0.5f;
|
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->Start, SDL_CONTROLLER_BUTTON_START, &NewController->Start);
|
||||||
SDLProcessInputDigitalButton(ControllerHandles[ControllerIndex], &OldController->Back, SDL_CONTROLLER_BUTTON_BACK, &NewController->Back);
|
SDLProcessInputDigitalButton(ControllerHandles[ControllerIndex], &OldController->Back, SDL_CONTROLLER_BUTTON_BACK, &NewController->Back);
|
||||||
} else {
|
} else {
|
||||||
// NOTE: This controller is not plugged in.
|
/* NOTE: This controller is not plugged in. */
|
||||||
NewController->IsConnected = false;
|
NewController->IsConnected = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -586,8 +645,17 @@ S32 main(S32 argc, char *argv[])
|
|||||||
Buffer.Width = GlobalBackbuffer.Width;
|
Buffer.Width = GlobalBackbuffer.Width;
|
||||||
Buffer.Height = GlobalBackbuffer.Height;
|
Buffer.Height = GlobalBackbuffer.Height;
|
||||||
Buffer.Pitch = GlobalBackbuffer.Pitch;
|
Buffer.Pitch = GlobalBackbuffer.Pitch;
|
||||||
|
|
||||||
|
if(SDLState.InputRecordingIndex) {
|
||||||
|
SDLRecordInput(&SDLState, NewInput);
|
||||||
|
}
|
||||||
|
if(SDLState.InputPlayingIndex) {
|
||||||
|
SDLPlaybackInput(&SDLState, NewInput);
|
||||||
|
}
|
||||||
|
|
||||||
if(Game.UpdateAndRender)
|
if(Game.UpdateAndRender)
|
||||||
Game.UpdateAndRender(&GameMemory, NewInput, &Buffer, &SoundBuffer);
|
Game.UpdateAndRender(&GameMemory, NewInput, &Buffer, &SoundBuffer);
|
||||||
|
|
||||||
SDLFillSoundBuffer(&SoundOutput, BytesToWrite);
|
SDLFillSoundBuffer(&SoundOutput, BytesToWrite);
|
||||||
|
|
||||||
U64 WorkCounter = SDLGetWallClock();
|
U64 WorkCounter = SDLGetWallClock();
|
||||||
@@ -600,8 +668,8 @@ S32 main(S32 argc, char *argv[])
|
|||||||
SDL_Delay((unsigned int)((TargetSecondsPerFrame - SecondsElapsedForFrame) * 1000.0));
|
SDL_Delay((unsigned int)((TargetSecondsPerFrame - SecondsElapsedForFrame) * 1000.0));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// TODO: Missed frame rate!
|
/* TODO: Missed frame rate! */
|
||||||
// TODO: Logging.
|
/* TODO: Logging. */
|
||||||
}
|
}
|
||||||
|
|
||||||
U64 EndCounter = SDLGetWallClock();
|
U64 EndCounter = SDLGetWallClock();
|
||||||
@@ -626,21 +694,21 @@ S32 main(S32 argc, char *argv[])
|
|||||||
SWAP(game_input *, NewInput, OldInput);
|
SWAP(game_input *, NewInput, OldInput);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// TODO: Failed to allocate Samples and Sound memory . . .
|
/* TODO: Failed to allocate Samples and Sound memory . . . */
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// TODO: This didn't work . . .
|
/* TODO: This didn't work . . . */
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// TODO: This didn't work . . .
|
/* TODO: This didn't work . . . */
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Let the OS clean things up.
|
/* 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?
|
/* 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_CloseAudio(); */
|
||||||
// SDL_DestroyRenderer(Renderer);
|
/* SDL_DestroyRenderer(Renderer); */
|
||||||
// SDL_DestroyWindow(Window);
|
/* SDL_DestroyWindow(Window); */
|
||||||
// SDL_Quit();
|
/* SDL_Quit(); */
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
+14
-9
@@ -1,16 +1,10 @@
|
|||||||
#ifndef SDL_HANDMADE_H
|
#ifndef SDL_HANDMADE_H
|
||||||
#define SDL_HANDMADE_H
|
#define SDL_HANDMADE_H
|
||||||
|
|
||||||
#include "core.h"
|
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
|
|
||||||
#if !defined(BUILD_DEBUG)
|
#include "core.h"
|
||||||
# define BUILD_DEBUG 1
|
#include "handmade.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(BUILD_INTERNAL) // NOTE: Added in by igor.
|
|
||||||
# define BUILD_INTERNAL 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct sdl_window_dimension {
|
typedef struct sdl_window_dimension {
|
||||||
S32 Width;
|
S32 Width;
|
||||||
@@ -18,7 +12,7 @@ typedef struct sdl_window_dimension {
|
|||||||
} sdl_window_dimension;
|
} sdl_window_dimension;
|
||||||
|
|
||||||
typedef struct offscreen_buffer {
|
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;
|
SDL_Texture *Texture;
|
||||||
void *Memory;
|
void *Memory;
|
||||||
S32 Width;
|
S32 Width;
|
||||||
@@ -35,4 +29,15 @@ typedef struct sdl_sound_output {
|
|||||||
void *Samples;
|
void *Samples;
|
||||||
} sdl_sound_output;
|
} sdl_sound_output;
|
||||||
|
|
||||||
|
typedef struct sdl_state {
|
||||||
|
U64 TotalSize;
|
||||||
|
void *GameMmemoryBlock;
|
||||||
|
|
||||||
|
S32 RecordingHandle;
|
||||||
|
S32 InputRecordingIndex;
|
||||||
|
|
||||||
|
S32 PlaybackHandle;
|
||||||
|
S32 InputPlayingIndex;
|
||||||
|
} sdl_state;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user