Day 25 done.
This commit is contained in:
@@ -51,13 +51,13 @@ typedef double F64;
|
|||||||
|
|
||||||
/* ---- Asserts -------------------------------------------------------- */
|
/* ---- Asserts -------------------------------------------------------- */
|
||||||
|
|
||||||
#define Trap() __builtin_trap()
|
#define TRAP() __builtin_trap()
|
||||||
|
|
||||||
#define AssertAlways(x) do { if(!(x)) { Trap(); } } while(0)
|
#define ASSERT_ALWAYS(x) do { if(!(x)) { TRAP(); } } while(0)
|
||||||
#if BUILD_DEBUG
|
#if BUILD_DEBUG
|
||||||
#define Assert(x) AssertAlways(x)
|
#define ASSERT(x) ASSERT_ALWAYS(x)
|
||||||
#else
|
#else
|
||||||
#define Assert(x) (void)(x)
|
#define ASSERT(x) (void)(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ---- Helper Macros -------------------------------------------------- */
|
/* ---- Helper Macros -------------------------------------------------- */
|
||||||
|
|||||||
+39
-7
@@ -63,17 +63,39 @@ static void RenderWeirdGradient(game_offscreen_buffer *Buffer, S32 XOffset,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateAndRender(game_memory *Memory, game_input *Input,
|
static void RenderRectangle(game_offscreen_buffer *Buffer, S32 MouseX,
|
||||||
game_offscreen_buffer *Buffer,
|
S32 MouseY)
|
||||||
|
{
|
||||||
|
U8 *Row;
|
||||||
|
U32 *Pixel;
|
||||||
|
S32 X, Y;
|
||||||
|
|
||||||
|
for(Y = MouseY; Y < MouseY+10; Y++) {
|
||||||
|
if(Y >= Buffer->Height)
|
||||||
|
break;
|
||||||
|
|
||||||
|
Row = (U8 *)Buffer->Memory + (Buffer->Pitch * Y);
|
||||||
|
for(X = MouseX; X < MouseX+10; X++) {
|
||||||
|
if(X >= Buffer->Width)
|
||||||
|
break;
|
||||||
|
|
||||||
|
Pixel = (U32 *)Row + X;
|
||||||
|
*Pixel = 0xFFFFFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateAndRender(thread_context *Thread, game_memory *Memory,
|
||||||
|
game_input *Input, game_offscreen_buffer *Buffer,
|
||||||
game_sound_output_buffer *SoundBuffer)
|
game_sound_output_buffer *SoundBuffer)
|
||||||
{
|
{
|
||||||
game_state *GameState;
|
game_state *GameState;
|
||||||
U32 ControllerIndex;
|
U32 ControllerIndex;
|
||||||
|
|
||||||
Assert((&Input->Controllers[0].u.buttons.Terminator -
|
ASSERT((&Input->Controllers[0].u.buttons.Terminator -
|
||||||
&Input->Controllers[0].u.Buttons[0]) ==
|
&Input->Controllers[0].u.Buttons[0]) ==
|
||||||
ARRAY_SIZE(Input->Controllers[0].u.Buttons));
|
ARRAY_SIZE(Input->Controllers[0].u.Buttons));
|
||||||
Assert(sizeof(game_state) <= Memory->PermanentStorageSize);
|
ASSERT(sizeof(game_state) <= Memory->PermanentStorageSize);
|
||||||
|
|
||||||
GameState = (game_state *)Memory->PermanentStorage;
|
GameState = (game_state *)Memory->PermanentStorage;
|
||||||
if(!Memory->IsInitialized) {
|
if(!Memory->IsInitialized) {
|
||||||
@@ -82,12 +104,13 @@ void UpdateAndRender(game_memory *Memory, game_input *Input,
|
|||||||
debug_read_file_result BitmapMemory;
|
debug_read_file_result BitmapMemory;
|
||||||
|
|
||||||
FileName = "/home/igor/Developer/handmade/sdl_handmade.cpp";
|
FileName = "/home/igor/Developer/handmade/sdl_handmade.cpp";
|
||||||
BitmapMemory = Memory->DEBUGPlatformReadEntireFile(FileName);
|
BitmapMemory = Memory->DEBUGPlatformReadEntireFile(Thread, FileName);
|
||||||
if(BitmapMemory.Contents) {
|
if(BitmapMemory.Contents) {
|
||||||
Memory->DEBUGPlatformWriteEntireFile("test.out",
|
Memory->DEBUGPlatformWriteEntireFile(Thread, "test.out",
|
||||||
BitmapMemory.ContentsSize,
|
BitmapMemory.ContentsSize,
|
||||||
BitmapMemory.Contents);
|
BitmapMemory.Contents);
|
||||||
Memory->DEBUGPlatformFreeFileMemory(BitmapMemory.Contents);
|
Memory->DEBUGPlatformFreeFileMemory(Thread,
|
||||||
|
BitmapMemory.Contents);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -133,4 +156,13 @@ void UpdateAndRender(game_memory *Memory, game_input *Input,
|
|||||||
GameOutputSound(GameState, SoundBuffer, GameState->ToneHz);
|
GameOutputSound(GameState, SoundBuffer, GameState->ToneHz);
|
||||||
RenderWeirdGradient(Buffer, GameState->BlueOffset,
|
RenderWeirdGradient(Buffer, GameState->BlueOffset,
|
||||||
GameState->GreenOffset);
|
GameState->GreenOffset);
|
||||||
|
{
|
||||||
|
S32 i;
|
||||||
|
for(i = 0; i < (S32)ARRAY_SIZE(Input->MouseButtons); i++) {
|
||||||
|
if(Input->MouseButtons[i].EndedDown)
|
||||||
|
RenderRectangle(Buffer, 10 + 20 * i, 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderRectangle(Buffer, Input->MouseX, Input->MouseY);
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-9
@@ -7,16 +7,22 @@
|
|||||||
/* NOTE: Servcies that the platform layer provides to the game. */
|
/* NOTE: Servcies that the platform layer provides to the game. */
|
||||||
/* --------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
typedef struct thread_context {
|
||||||
|
S32 Placeholder;
|
||||||
|
} thread_context;
|
||||||
|
|
||||||
#if BUILD_INTERNAL
|
#if BUILD_INTERNAL
|
||||||
typedef struct debug_read_file_result {
|
typedef struct debug_read_file_result {
|
||||||
U32 ContentsSize;
|
U32 ContentsSize;
|
||||||
void *Contents;
|
void *Contents;
|
||||||
} debug_read_file_result;
|
} debug_read_file_result;
|
||||||
|
|
||||||
debug_read_file_result DEBUGPlatformReadEntireFile(const char *Filename);
|
debug_read_file_result DEBUGPlatformReadEntireFile(thread_context *Thread,
|
||||||
B32 DEBUGPlatformWriteEntireFile(const char *Filename, U32 MemorySize,
|
const char *Filename);
|
||||||
|
B32 DEBUGPlatformWriteEntireFile(thread_context *Thread,
|
||||||
|
const char *Filename, U32 MemorySize,
|
||||||
void *Memory);
|
void *Memory);
|
||||||
void DEBUGPlatformFreeFileMemory(void *Memory);
|
void DEBUGPlatformFreeFileMemory(thread_context *Thread, void *Memory);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------- */
|
||||||
@@ -77,6 +83,9 @@ typedef struct game_controller_input {
|
|||||||
} game_controller_input;
|
} game_controller_input;
|
||||||
|
|
||||||
typedef struct game_input {
|
typedef struct game_input {
|
||||||
|
game_button_state MouseButtons[5];
|
||||||
|
S32 MouseX, MouseY, MouseZ; /* NOTE: MouseZ is the wheel. */
|
||||||
|
|
||||||
/* TODO: Insert clock value here . . . */
|
/* TODO: Insert clock value here . . . */
|
||||||
game_controller_input Controllers[5];
|
game_controller_input Controllers[5];
|
||||||
} game_input;
|
} game_input;
|
||||||
@@ -85,7 +94,7 @@ game_controller_input *GetController(game_input *Input, S32 ControllerIndex)
|
|||||||
{
|
{
|
||||||
game_controller_input *Result;
|
game_controller_input *Result;
|
||||||
|
|
||||||
Assert((U32)ControllerIndex < ARRAY_SIZE(Input->Controllers));
|
ASSERT((U32)ControllerIndex < ARRAY_SIZE(Input->Controllers));
|
||||||
Result = &(Input->Controllers[ControllerIndex]);
|
Result = &(Input->Controllers[ControllerIndex]);
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
@@ -104,9 +113,11 @@ typedef struct game_memory {
|
|||||||
layer.) */
|
layer.) */
|
||||||
|
|
||||||
#if BUILD_INTERNAL
|
#if BUILD_INTERNAL
|
||||||
debug_read_file_result (*DEBUGPlatformReadEntireFile)(const char *);
|
debug_read_file_result (*DEBUGPlatformReadEntireFile)(
|
||||||
B32 (*DEBUGPlatformWriteEntireFile)(const char *, U32, void *);
|
thread_context *Thread,const char *);
|
||||||
void (*DEBUGPlatformFreeFileMemory)(void *);
|
B32 (*DEBUGPlatformWriteEntireFile)(thread_context *Thread,
|
||||||
|
const char *, U32, void *);
|
||||||
|
void (*DEBUGPlatformFreeFileMemory)(thread_context *Thread, void *);
|
||||||
#endif
|
#endif
|
||||||
} game_memory;
|
} game_memory;
|
||||||
|
|
||||||
@@ -115,8 +126,8 @@ typedef struct game_memory {
|
|||||||
F32 SecondsElapsed;
|
F32 SecondsElapsed;
|
||||||
} game_clocks;*/
|
} game_clocks;*/
|
||||||
|
|
||||||
void UpdateAndRender(game_memory *Memory, game_input *Input,
|
void UpdateAndRender(thread_context *Thread, game_memory *Memory,
|
||||||
game_offscreen_buffer *Buffer,
|
game_input *Input, game_offscreen_buffer *Buffer,
|
||||||
game_sound_output_buffer *SoundBuffer);
|
game_sound_output_buffer *SoundBuffer);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
+86
-18
@@ -8,7 +8,7 @@
|
|||||||
#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, memcpy */
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <sys/stat.h> /* fstat */
|
#include <sys/stat.h> /* fstat */
|
||||||
@@ -47,12 +47,13 @@ static U32 SafeTruncateUInt64(U64 Value)
|
|||||||
{
|
{
|
||||||
U32 Result;
|
U32 Result;
|
||||||
|
|
||||||
Assert(Value <= 0xFFFFFFFF);
|
ASSERT(Value <= 0xFFFFFFFF);
|
||||||
Result = (U32)Value;
|
Result = (U32)Value;
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_read_file_result DEBUGPlatformReadEntireFile(const char *Filename)
|
debug_read_file_result DEBUGPlatformReadEntireFile(thread_context *Thread,
|
||||||
|
const char *Filename)
|
||||||
{
|
{
|
||||||
debug_read_file_result Result;
|
debug_read_file_result Result;
|
||||||
S32 FileHandle;
|
S32 FileHandle;
|
||||||
@@ -101,7 +102,8 @@ debug_read_file_result DEBUGPlatformReadEntireFile(const char *Filename)
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
B32 DEBUGPlatformWriteEntireFile(const char *Filename, U32 MemorySize,
|
B32 DEBUGPlatformWriteEntireFile(thread_context *Thread,
|
||||||
|
const char *Filename, U32 MemorySize,
|
||||||
void *Memory)
|
void *Memory)
|
||||||
{
|
{
|
||||||
S32 FileHandle;
|
S32 FileHandle;
|
||||||
@@ -132,7 +134,7 @@ B32 DEBUGPlatformWriteEntireFile(const char *Filename, U32 MemorySize,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DEBUGPlatformFreeFileMemory(void *Memory)
|
void DEBUGPlatformFreeFileMemory(thread_context *Thread, void *Memory)
|
||||||
{
|
{
|
||||||
if(Memory)
|
if(Memory)
|
||||||
free(Memory);
|
free(Memory);
|
||||||
@@ -254,10 +256,11 @@ static void SDLClearSoundBuffer(sdl_sound_output *SoundOutput)
|
|||||||
static void SDLProcessKeyboardMessage(game_button_state *NewState,
|
static void SDLProcessKeyboardMessage(game_button_state *NewState,
|
||||||
B32 IsDown)
|
B32 IsDown)
|
||||||
{
|
{
|
||||||
Assert(NewState->EndedDown != IsDown);
|
if(NewState->EndedDown != IsDown) {
|
||||||
NewState->EndedDown = IsDown;
|
NewState->EndedDown = IsDown;
|
||||||
++NewState->HalfTransitionCount;
|
++NewState->HalfTransitionCount;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void SDLProcessInputDigitalButton(SDL_GameController *Controller,
|
static void SDLProcessInputDigitalButton(SDL_GameController *Controller,
|
||||||
game_button_state *OldState,
|
game_button_state *OldState,
|
||||||
@@ -308,7 +311,7 @@ static void HandleEvent(SDL_Event *Event)
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case SDL_WINDOWEVENT_FOCUS_LOST: {
|
case SDL_WINDOWEVENT_FOCUS_LOST: {
|
||||||
if(SDL_SetWindowOpacity(Window, 0.5f) != 0) {
|
if(SDL_SetWindowOpacity(Window, 0.3f) != 0) {
|
||||||
/* TODO: This didn't work . . . SDL_GetError() */
|
/* TODO: This didn't work . . . SDL_GetError() */
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
@@ -322,14 +325,24 @@ static void SDLGetInputFileLocation(sdl_state *SDLState, char *path,
|
|||||||
{
|
{
|
||||||
const char *file_name = "loop.hmi";
|
const char *file_name = "loop.hmi";
|
||||||
|
|
||||||
Assert(SlotIndex == 1);
|
ASSERT(SlotIndex == 1);
|
||||||
|
|
||||||
snprintf(path, path_size, "%s%s", SDLState->EXEDirPath, file_name);
|
snprintf(path, path_size, "%s%s", SDLState->EXEDirPath, file_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sdl_replay_buffer *SDLGetReplayBuffer(sdl_state *SDLState,
|
||||||
|
S32 Index)
|
||||||
|
{
|
||||||
|
ASSERT(Index < (S32)ARRAY_SIZE(SDLState->ReplayBuffers));
|
||||||
|
return &(SDLState->ReplayBuffers[Index]);
|
||||||
|
}
|
||||||
|
|
||||||
static void SDLBeginRecordingInput(sdl_state *SDLState,
|
static void SDLBeginRecordingInput(sdl_state *SDLState,
|
||||||
S32 InputRecordingIndex)
|
S32 InputRecordingIndex)
|
||||||
{
|
{
|
||||||
|
sdl_replay_buffer *ReplayBuffer =
|
||||||
|
SDLGetReplayBuffer(SDLState, InputRecordingIndex);
|
||||||
|
if(ReplayBuffer->MemoryBlock) {
|
||||||
char FileName[SDL_STATE_PATH_SIZE];
|
char FileName[SDL_STATE_PATH_SIZE];
|
||||||
|
|
||||||
SDLGetInputFileLocation(SDLState, FileName, sizeof(FileName),
|
SDLGetInputFileLocation(SDLState, FileName, sizeof(FileName),
|
||||||
@@ -344,9 +357,12 @@ static void SDLBeginRecordingInput(sdl_state *SDLState,
|
|||||||
SDLState->RecordingHandle =
|
SDLState->RecordingHandle =
|
||||||
open(FileName, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR |
|
open(FileName, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR |
|
||||||
S_IRGRP | S_IROTH);
|
S_IRGRP | S_IROTH);
|
||||||
write(SDLState->RecordingHandle, SDLState->GameMmemoryBlock,
|
/* write(SDLState->RecordingHandle, SDLState->GameMmemoryBlock,
|
||||||
|
(size_t)(SDLState->TotalSize)); */
|
||||||
|
memcpy(ReplayBuffer->MemoryBlock, SDLState->GameMmemoryBlock,
|
||||||
(size_t)(SDLState->TotalSize));
|
(size_t)(SDLState->TotalSize));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void SDLEndRecordingInput(sdl_state *SDLState)
|
static void SDLEndRecordingInput(sdl_state *SDLState)
|
||||||
{
|
{
|
||||||
@@ -357,6 +373,9 @@ static void SDLEndRecordingInput(sdl_state *SDLState)
|
|||||||
static void SDLBeginInputPlayback(sdl_state *SDLState,
|
static void SDLBeginInputPlayback(sdl_state *SDLState,
|
||||||
S32 InputPlayingIndex)
|
S32 InputPlayingIndex)
|
||||||
{
|
{
|
||||||
|
sdl_replay_buffer *ReplayBuffer =
|
||||||
|
SDLGetReplayBuffer(SDLState, InputPlayingIndex);
|
||||||
|
if(ReplayBuffer->MemoryBlock) {
|
||||||
char FileName[SDL_STATE_PATH_SIZE];
|
char FileName[SDL_STATE_PATH_SIZE];
|
||||||
ssize_t size;
|
ssize_t size;
|
||||||
|
|
||||||
@@ -367,9 +386,12 @@ static void SDLBeginInputPlayback(sdl_state *SDLState,
|
|||||||
SDLState->PlaybackHandle =
|
SDLState->PlaybackHandle =
|
||||||
open(FileName, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR |
|
open(FileName, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR |
|
||||||
S_IRGRP | S_IROTH);
|
S_IRGRP | S_IROTH);
|
||||||
size = read(SDLState->PlaybackHandle, SDLState->GameMmemoryBlock,
|
/* size = read(SDLState->PlaybackHandle, SDLState->GameMmemoryBlock,
|
||||||
|
(size_t)(SDLState->TotalSize)); */
|
||||||
|
memcpy(SDLState->GameMmemoryBlock, ReplayBuffer->MemoryBlock,
|
||||||
(size_t)(SDLState->TotalSize));
|
(size_t)(SDLState->TotalSize));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void SDLEndInputPlayback(sdl_state *SDLState)
|
static void SDLEndInputPlayback(sdl_state *SDLState)
|
||||||
{
|
{
|
||||||
@@ -475,12 +497,16 @@ static void SDLProcessMessages(sdl_state *SDLState,
|
|||||||
#if BUILD_INTERNAL
|
#if BUILD_INTERNAL
|
||||||
|
|
||||||
if(KeyCode == SDLK_l) {
|
if(KeyCode == SDLK_l) {
|
||||||
|
if(SDLState->InputPlayingIndex == 0) {
|
||||||
if(SDLState->InputRecordingIndex == 0) {
|
if(SDLState->InputRecordingIndex == 0) {
|
||||||
SDLBeginRecordingInput(SDLState, 1);
|
SDLBeginRecordingInput(SDLState, 1);
|
||||||
} else {
|
} else {
|
||||||
SDLEndRecordingInput(SDLState);
|
SDLEndRecordingInput(SDLState);
|
||||||
SDLBeginInputPlayback(SDLState, 1);
|
SDLBeginInputPlayback(SDLState, 1);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
SDLEndInputPlayback(SDLState);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -550,8 +576,8 @@ typedef struct sdl_game_code {
|
|||||||
void *GameCodeDLL;
|
void *GameCodeDLL;
|
||||||
U32 DLLLastWriteTime;
|
U32 DLLLastWriteTime;
|
||||||
|
|
||||||
void (*UpdateAndRender)(game_memory *, game_input *,
|
void (*UpdateAndRender)(thread_context *Thread, game_memory *,
|
||||||
game_offscreen_buffer *,
|
game_input *, game_offscreen_buffer *,
|
||||||
game_sound_output_buffer *);
|
game_sound_output_buffer *);
|
||||||
|
|
||||||
B32 IsValid;
|
B32 IsValid;
|
||||||
@@ -582,9 +608,9 @@ static sdl_game_code SDLLoadGameCode(char *DLLPath)
|
|||||||
Result.DLLLastWriteTime = GetLastWriteTime(DLLPath);
|
Result.DLLLastWriteTime = GetLastWriteTime(DLLPath);
|
||||||
|
|
||||||
Result.UpdateAndRender =
|
Result.UpdateAndRender =
|
||||||
(void(*)(game_memory *, game_input *, game_offscreen_buffer *,
|
(void(*)(thread_context *, game_memory *, game_input *,
|
||||||
game_sound_output_buffer *))dlsym(Result.GameCodeDLL,
|
game_offscreen_buffer *, game_sound_output_buffer *))
|
||||||
"UpdateAndRender");
|
dlsym(Result.GameCodeDLL, "UpdateAndRender");
|
||||||
if(!Result.UpdateAndRender) {
|
if(!Result.UpdateAndRender) {
|
||||||
/* TODO: Diagnostic. dlerror() */
|
/* TODO: Diagnostic. dlerror() */
|
||||||
}
|
}
|
||||||
@@ -696,6 +722,7 @@ S32 main(S32 argc, char *argv[])
|
|||||||
sdl_window_dimension Dimension;
|
sdl_window_dimension Dimension;
|
||||||
sdl_sound_output SoundOutput;
|
sdl_sound_output SoundOutput;
|
||||||
game_memory GameMemory;
|
game_memory GameMemory;
|
||||||
|
S32 ReplayIndex;
|
||||||
|
|
||||||
#if BUILD_DEBUG
|
#if BUILD_DEBUG
|
||||||
void *BaseAddress = (void *)TB(2);
|
void *BaseAddress = (void *)TB(2);
|
||||||
@@ -747,13 +774,30 @@ S32 main(S32 argc, char *argv[])
|
|||||||
/* NOTE: On MacOS and Linux, mmap seems to zero-fill anonymous
|
/* NOTE: On MacOS and Linux, mmap seems to zero-fill anonymous
|
||||||
* memory as a side-effect of security. */
|
* memory as a side-effect of security. */
|
||||||
SDLState.GameMmemoryBlock =
|
SDLState.GameMmemoryBlock =
|
||||||
mmap(BaseAddress, SDLState.TotalSize, PROT_READ |
|
mmap(BaseAddress, (size_t)SDLState.TotalSize, PROT_READ |
|
||||||
PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
|
PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||||
GameMemory.PermanentStorage = SDLState.GameMmemoryBlock;
|
GameMemory.PermanentStorage = SDLState.GameMmemoryBlock;
|
||||||
GameMemory.TransientStorage =
|
GameMemory.TransientStorage =
|
||||||
(U8 *)(GameMemory.PermanentStorage) +
|
(U8 *)(GameMemory.PermanentStorage) +
|
||||||
GameMemory.PermanentStorageSize;
|
GameMemory.PermanentStorageSize;
|
||||||
|
|
||||||
|
for(ReplayIndex = 0;
|
||||||
|
ReplayIndex < (S32)ARRAY_SIZE(SDLState.ReplayBuffers);
|
||||||
|
ReplayIndex++)
|
||||||
|
{
|
||||||
|
sdl_replay_buffer *ReplayBuffer =
|
||||||
|
&SDLState.ReplayBuffers[ReplayIndex];
|
||||||
|
ReplayBuffer->MemoryBlock = mmap(NULL,
|
||||||
|
(size_t)SDLState.TotalSize,
|
||||||
|
PROT_READ | PROT_WRITE,
|
||||||
|
MAP_ANON | MAP_PRIVATE,
|
||||||
|
-1, 0);
|
||||||
|
if(ReplayBuffer->MemoryBlock) {
|
||||||
|
} else {
|
||||||
|
/* TODO: Change this to log message. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(SoundOutput.Samples &&
|
if(SoundOutput.Samples &&
|
||||||
GameMemory.PermanentStorage &&
|
GameMemory.PermanentStorage &&
|
||||||
GameMemory.TransientStorage)
|
GameMemory.TransientStorage)
|
||||||
@@ -775,9 +819,11 @@ S32 main(S32 argc, char *argv[])
|
|||||||
Game = SDLLoadGameCode(SDLState.DLLPath);
|
Game = SDLLoadGameCode(SDLState.DLLPath);
|
||||||
|
|
||||||
while(GlobalRunning) {
|
while(GlobalRunning) {
|
||||||
|
thread_context Context;
|
||||||
S32 MonitorRefreshHz, GameUpdateHz;
|
S32 MonitorRefreshHz, GameUpdateHz;
|
||||||
F32 TargetSecondsPerFrame;
|
F32 TargetSecondsPerFrame;
|
||||||
U32 NewDLLWriteTime, ButtonIndex, ControllerIndex;
|
U32 NewDLLWriteTime, ButtonIndex, ControllerIndex,
|
||||||
|
SDLMouseButtons;
|
||||||
game_controller_input *OldKeyboardController,
|
game_controller_input *OldKeyboardController,
|
||||||
*NewKeyboardController;
|
*NewKeyboardController;
|
||||||
game_controller_input ZeroController;
|
game_controller_input ZeroController;
|
||||||
@@ -813,6 +859,23 @@ S32 main(S32 argc, char *argv[])
|
|||||||
Game = SDLLoadGameCode(SDLState.DLLPath);
|
Game = SDLLoadGameCode(SDLState.DLLPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDLMouseButtons = SDL_GetMouseState(&(NewInput->MouseX),
|
||||||
|
&(NewInput->MouseY));
|
||||||
|
NewInput->MouseZ = 0; /* TODO: Support mouse wheel? */
|
||||||
|
SDLProcessKeyboardMessage(&(NewInput->MouseButtons[0]),
|
||||||
|
SDL_BUTTON_LMASK & SDLMouseButtons);
|
||||||
|
SDLProcessKeyboardMessage(&(NewInput->MouseButtons[1]),
|
||||||
|
SDL_BUTTON_MMASK & SDLMouseButtons);
|
||||||
|
SDLProcessKeyboardMessage(&(NewInput->MouseButtons[2]),
|
||||||
|
SDL_BUTTON_RMASK & SDLMouseButtons);
|
||||||
|
/* WARNING: TODO: SDL_BUTTON_X1MASK and
|
||||||
|
* SDL_BUTTON_X2MASK cannot be on at the
|
||||||
|
* same time for some reason. */
|
||||||
|
SDLProcessKeyboardMessage(&(NewInput->MouseButtons[3]),
|
||||||
|
SDL_BUTTON_X1MASK & SDLMouseButtons);
|
||||||
|
SDLProcessKeyboardMessage(&(NewInput->MouseButtons[4]),
|
||||||
|
SDL_BUTTON_X2MASK & SDLMouseButtons);
|
||||||
|
|
||||||
OldKeyboardController = GetController(OldInput, 0);
|
OldKeyboardController = GetController(OldInput, 0);
|
||||||
NewKeyboardController = GetController(NewInput, 0);
|
NewKeyboardController = GetController(NewInput, 0);
|
||||||
memset(&ZeroController, 0, sizeof(ZeroController));
|
memset(&ZeroController, 0, sizeof(ZeroController));
|
||||||
@@ -997,6 +1060,8 @@ S32 main(S32 argc, char *argv[])
|
|||||||
BytesToWrite / SoundOutput.BytesPerSample;
|
BytesToWrite / SoundOutput.BytesPerSample;
|
||||||
SoundBuffer.Samples = (short *)SoundOutput.Samples;
|
SoundBuffer.Samples = (short *)SoundOutput.Samples;
|
||||||
|
|
||||||
|
memset(&Context, 0, sizeof(Context));
|
||||||
|
|
||||||
Buffer.Memory = GlobalBackbuffer.Memory;
|
Buffer.Memory = GlobalBackbuffer.Memory;
|
||||||
Buffer.Width = GlobalBackbuffer.Width;
|
Buffer.Width = GlobalBackbuffer.Width;
|
||||||
Buffer.Height = GlobalBackbuffer.Height;
|
Buffer.Height = GlobalBackbuffer.Height;
|
||||||
@@ -1010,7 +1075,8 @@ S32 main(S32 argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(Game.UpdateAndRender)
|
if(Game.UpdateAndRender)
|
||||||
Game.UpdateAndRender(&GameMemory, NewInput, &Buffer,
|
Game.UpdateAndRender(&Context, &GameMemory,
|
||||||
|
NewInput, &Buffer,
|
||||||
&SoundBuffer);
|
&SoundBuffer);
|
||||||
|
|
||||||
SDLFillSoundBuffer(&SoundOutput, BytesToWrite);
|
SDLFillSoundBuffer(&SoundOutput, BytesToWrite);
|
||||||
@@ -1044,6 +1110,7 @@ S32 main(S32 argc, char *argv[])
|
|||||||
|
|
||||||
LastCounter = EndCounter;
|
LastCounter = EndCounter;
|
||||||
|
|
||||||
|
#if 0
|
||||||
#if __x86_64__ || __i386__
|
#if __x86_64__ || __i386__
|
||||||
EndCycleCount = __rdtsc();
|
EndCycleCount = __rdtsc();
|
||||||
CyclesElapsed = EndCycleCount - LastCycleCount;
|
CyclesElapsed = EndCycleCount - LastCycleCount;
|
||||||
@@ -1054,6 +1121,7 @@ S32 main(S32 argc, char *argv[])
|
|||||||
#else
|
#else
|
||||||
fprintf(stderr, "%.02f ms/f, %.02f/s\n",
|
fprintf(stderr, "%.02f ms/f, %.02f/s\n",
|
||||||
MSPerFrame, FPS);
|
MSPerFrame, FPS);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SWAP(game_input *, NewInput, OldInput);
|
SWAP(game_input *, NewInput, OldInput);
|
||||||
|
|||||||
@@ -33,9 +33,16 @@ typedef struct sdl_sound_output {
|
|||||||
/* NOTE: We choose 1024 only because MacOS's MAXPATHLEN says such a value.
|
/* NOTE: We choose 1024 only because MacOS's MAXPATHLEN says such a value.
|
||||||
* For example, linux/limits.h PATH_MAX says 4096. */
|
* For example, linux/limits.h PATH_MAX says 4096. */
|
||||||
#define SDL_STATE_PATH_SIZE 1024
|
#define SDL_STATE_PATH_SIZE 1024
|
||||||
|
|
||||||
|
typedef struct sdl_replay_buffer {
|
||||||
|
char ReplayFilename[SDL_STATE_PATH_SIZE];
|
||||||
|
void *MemoryBlock;
|
||||||
|
} sdl_replay_buffer;
|
||||||
|
|
||||||
typedef struct sdl_state {
|
typedef struct sdl_state {
|
||||||
U64 TotalSize;
|
U64 TotalSize;
|
||||||
void *GameMmemoryBlock;
|
void *GameMmemoryBlock;
|
||||||
|
sdl_replay_buffer ReplayBuffers[4];
|
||||||
|
|
||||||
S32 RecordingHandle;
|
S32 RecordingHandle;
|
||||||
S32 InputRecordingIndex;
|
S32 InputRecordingIndex;
|
||||||
|
|||||||
Reference in New Issue
Block a user