Day 25 done.
This commit is contained in:
+112
-44
@@ -8,7 +8,7 @@
|
||||
#include <SDL.h>
|
||||
#include <sys/mman.h> /* mmap */
|
||||
#include <stdlib.h> /* malloc, calloc */
|
||||
#include <string.h> /* memset */
|
||||
#include <string.h> /* memset, memcpy */
|
||||
#include <stdio.h>
|
||||
|
||||
#include <sys/stat.h> /* fstat */
|
||||
@@ -47,12 +47,13 @@ static U32 SafeTruncateUInt64(U64 Value)
|
||||
{
|
||||
U32 Result;
|
||||
|
||||
Assert(Value <= 0xFFFFFFFF);
|
||||
ASSERT(Value <= 0xFFFFFFFF);
|
||||
Result = (U32)Value;
|
||||
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;
|
||||
S32 FileHandle;
|
||||
@@ -101,7 +102,8 @@ debug_read_file_result DEBUGPlatformReadEntireFile(const char *Filename)
|
||||
return Result;
|
||||
}
|
||||
|
||||
B32 DEBUGPlatformWriteEntireFile(const char *Filename, U32 MemorySize,
|
||||
B32 DEBUGPlatformWriteEntireFile(thread_context *Thread,
|
||||
const char *Filename, U32 MemorySize,
|
||||
void *Memory)
|
||||
{
|
||||
S32 FileHandle;
|
||||
@@ -132,7 +134,7 @@ B32 DEBUGPlatformWriteEntireFile(const char *Filename, U32 MemorySize,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void DEBUGPlatformFreeFileMemory(void *Memory)
|
||||
void DEBUGPlatformFreeFileMemory(thread_context *Thread, void *Memory)
|
||||
{
|
||||
if(Memory)
|
||||
free(Memory);
|
||||
@@ -254,9 +256,10 @@ static void SDLClearSoundBuffer(sdl_sound_output *SoundOutput)
|
||||
static void SDLProcessKeyboardMessage(game_button_state *NewState,
|
||||
B32 IsDown)
|
||||
{
|
||||
Assert(NewState->EndedDown != IsDown);
|
||||
NewState->EndedDown = IsDown;
|
||||
++NewState->HalfTransitionCount;
|
||||
if(NewState->EndedDown != IsDown) {
|
||||
NewState->EndedDown = IsDown;
|
||||
++NewState->HalfTransitionCount;
|
||||
}
|
||||
}
|
||||
|
||||
static void SDLProcessInputDigitalButton(SDL_GameController *Controller,
|
||||
@@ -308,7 +311,7 @@ static void HandleEvent(SDL_Event *Event)
|
||||
} break;
|
||||
|
||||
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() */
|
||||
}
|
||||
} break;
|
||||
@@ -322,30 +325,43 @@ static void SDLGetInputFileLocation(sdl_state *SDLState, char *path,
|
||||
{
|
||||
const char *file_name = "loop.hmi";
|
||||
|
||||
Assert(SlotIndex == 1);
|
||||
ASSERT(SlotIndex == 1);
|
||||
|
||||
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,
|
||||
S32 InputRecordingIndex)
|
||||
{
|
||||
char FileName[SDL_STATE_PATH_SIZE];
|
||||
sdl_replay_buffer *ReplayBuffer =
|
||||
SDLGetReplayBuffer(SDLState, InputRecordingIndex);
|
||||
if(ReplayBuffer->MemoryBlock) {
|
||||
char FileName[SDL_STATE_PATH_SIZE];
|
||||
|
||||
SDLGetInputFileLocation(SDLState, FileName, sizeof(FileName),
|
||||
InputRecordingIndex);
|
||||
SDLGetInputFileLocation(SDLState, FileName, sizeof(FileName),
|
||||
InputRecordingIndex);
|
||||
|
||||
SDLState->InputRecordingIndex = InputRecordingIndex;
|
||||
SDLState->InputRecordingIndex = InputRecordingIndex;
|
||||
|
||||
if(unlink(FileName) != 0) {
|
||||
/* TODO: Diagnostics . . . */
|
||||
if(unlink(FileName) != 0) {
|
||||
/* TODO: Diagnostics . . . */
|
||||
}
|
||||
|
||||
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)); */
|
||||
memcpy(ReplayBuffer->MemoryBlock, SDLState->GameMmemoryBlock,
|
||||
(size_t)(SDLState->TotalSize));
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -357,18 +373,24 @@ static void SDLEndRecordingInput(sdl_state *SDLState)
|
||||
static void SDLBeginInputPlayback(sdl_state *SDLState,
|
||||
S32 InputPlayingIndex)
|
||||
{
|
||||
char FileName[SDL_STATE_PATH_SIZE];
|
||||
ssize_t size;
|
||||
sdl_replay_buffer *ReplayBuffer =
|
||||
SDLGetReplayBuffer(SDLState, InputPlayingIndex);
|
||||
if(ReplayBuffer->MemoryBlock) {
|
||||
char FileName[SDL_STATE_PATH_SIZE];
|
||||
ssize_t size;
|
||||
|
||||
SDLGetInputFileLocation(SDLState, FileName, sizeof(FileName),
|
||||
InputPlayingIndex);
|
||||
SDLGetInputFileLocation(SDLState, FileName, sizeof(FileName),
|
||||
InputPlayingIndex);
|
||||
|
||||
SDLState->InputPlayingIndex = InputPlayingIndex;
|
||||
SDLState->PlaybackHandle =
|
||||
open(FileName, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR |
|
||||
S_IRGRP | S_IROTH);
|
||||
size = read(SDLState->PlaybackHandle, SDLState->GameMmemoryBlock,
|
||||
(size_t)(SDLState->TotalSize));
|
||||
SDLState->InputPlayingIndex = InputPlayingIndex;
|
||||
SDLState->PlaybackHandle =
|
||||
open(FileName, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR |
|
||||
S_IRGRP | S_IROTH);
|
||||
/* size = read(SDLState->PlaybackHandle, SDLState->GameMmemoryBlock,
|
||||
(size_t)(SDLState->TotalSize)); */
|
||||
memcpy(SDLState->GameMmemoryBlock, ReplayBuffer->MemoryBlock,
|
||||
(size_t)(SDLState->TotalSize));
|
||||
}
|
||||
}
|
||||
|
||||
static void SDLEndInputPlayback(sdl_state *SDLState)
|
||||
@@ -475,11 +497,15 @@ static void SDLProcessMessages(sdl_state *SDLState,
|
||||
#if BUILD_INTERNAL
|
||||
|
||||
if(KeyCode == SDLK_l) {
|
||||
if(SDLState->InputRecordingIndex == 0) {
|
||||
SDLBeginRecordingInput(SDLState, 1);
|
||||
if(SDLState->InputPlayingIndex == 0) {
|
||||
if(SDLState->InputRecordingIndex == 0) {
|
||||
SDLBeginRecordingInput(SDLState, 1);
|
||||
} else {
|
||||
SDLEndRecordingInput(SDLState);
|
||||
SDLBeginInputPlayback(SDLState, 1);
|
||||
}
|
||||
} else {
|
||||
SDLEndRecordingInput(SDLState);
|
||||
SDLBeginInputPlayback(SDLState, 1);
|
||||
SDLEndInputPlayback(SDLState);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -550,8 +576,8 @@ typedef struct sdl_game_code {
|
||||
void *GameCodeDLL;
|
||||
U32 DLLLastWriteTime;
|
||||
|
||||
void (*UpdateAndRender)(game_memory *, game_input *,
|
||||
game_offscreen_buffer *,
|
||||
void (*UpdateAndRender)(thread_context *Thread, game_memory *,
|
||||
game_input *, game_offscreen_buffer *,
|
||||
game_sound_output_buffer *);
|
||||
|
||||
B32 IsValid;
|
||||
@@ -582,9 +608,9 @@ static sdl_game_code SDLLoadGameCode(char *DLLPath)
|
||||
Result.DLLLastWriteTime = GetLastWriteTime(DLLPath);
|
||||
|
||||
Result.UpdateAndRender =
|
||||
(void(*)(game_memory *, game_input *, game_offscreen_buffer *,
|
||||
game_sound_output_buffer *))dlsym(Result.GameCodeDLL,
|
||||
"UpdateAndRender");
|
||||
(void(*)(thread_context *, game_memory *, game_input *,
|
||||
game_offscreen_buffer *, game_sound_output_buffer *))
|
||||
dlsym(Result.GameCodeDLL, "UpdateAndRender");
|
||||
if(!Result.UpdateAndRender) {
|
||||
/* TODO: Diagnostic. dlerror() */
|
||||
}
|
||||
@@ -696,6 +722,7 @@ S32 main(S32 argc, char *argv[])
|
||||
sdl_window_dimension Dimension;
|
||||
sdl_sound_output SoundOutput;
|
||||
game_memory GameMemory;
|
||||
S32 ReplayIndex;
|
||||
|
||||
#if BUILD_DEBUG
|
||||
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
|
||||
* memory as a side-effect of security. */
|
||||
SDLState.GameMmemoryBlock =
|
||||
mmap(BaseAddress, SDLState.TotalSize, PROT_READ |
|
||||
mmap(BaseAddress, (size_t)SDLState.TotalSize, PROT_READ |
|
||||
PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||
GameMemory.PermanentStorage = SDLState.GameMmemoryBlock;
|
||||
GameMemory.TransientStorage =
|
||||
(U8 *)(GameMemory.PermanentStorage) +
|
||||
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 &&
|
||||
GameMemory.PermanentStorage &&
|
||||
GameMemory.TransientStorage)
|
||||
@@ -775,9 +819,11 @@ S32 main(S32 argc, char *argv[])
|
||||
Game = SDLLoadGameCode(SDLState.DLLPath);
|
||||
|
||||
while(GlobalRunning) {
|
||||
thread_context Context;
|
||||
S32 MonitorRefreshHz, GameUpdateHz;
|
||||
F32 TargetSecondsPerFrame;
|
||||
U32 NewDLLWriteTime, ButtonIndex, ControllerIndex;
|
||||
U32 NewDLLWriteTime, ButtonIndex, ControllerIndex,
|
||||
SDLMouseButtons;
|
||||
game_controller_input *OldKeyboardController,
|
||||
*NewKeyboardController;
|
||||
game_controller_input ZeroController;
|
||||
@@ -813,6 +859,23 @@ S32 main(S32 argc, char *argv[])
|
||||
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);
|
||||
NewKeyboardController = GetController(NewInput, 0);
|
||||
memset(&ZeroController, 0, sizeof(ZeroController));
|
||||
@@ -997,6 +1060,8 @@ S32 main(S32 argc, char *argv[])
|
||||
BytesToWrite / SoundOutput.BytesPerSample;
|
||||
SoundBuffer.Samples = (short *)SoundOutput.Samples;
|
||||
|
||||
memset(&Context, 0, sizeof(Context));
|
||||
|
||||
Buffer.Memory = GlobalBackbuffer.Memory;
|
||||
Buffer.Width = GlobalBackbuffer.Width;
|
||||
Buffer.Height = GlobalBackbuffer.Height;
|
||||
@@ -1010,7 +1075,8 @@ S32 main(S32 argc, char *argv[])
|
||||
}
|
||||
|
||||
if(Game.UpdateAndRender)
|
||||
Game.UpdateAndRender(&GameMemory, NewInput, &Buffer,
|
||||
Game.UpdateAndRender(&Context, &GameMemory,
|
||||
NewInput, &Buffer,
|
||||
&SoundBuffer);
|
||||
|
||||
SDLFillSoundBuffer(&SoundOutput, BytesToWrite);
|
||||
@@ -1044,6 +1110,7 @@ S32 main(S32 argc, char *argv[])
|
||||
|
||||
LastCounter = EndCounter;
|
||||
|
||||
#if 0
|
||||
#if __x86_64__ || __i386__
|
||||
EndCycleCount = __rdtsc();
|
||||
CyclesElapsed = EndCycleCount - LastCycleCount;
|
||||
@@ -1054,6 +1121,7 @@ S32 main(S32 argc, char *argv[])
|
||||
#else
|
||||
fprintf(stderr, "%.02f ms/f, %.02f/s\n",
|
||||
MSPerFrame, FPS);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
SWAP(game_input *, NewInput, OldInput);
|
||||
|
||||
Reference in New Issue
Block a user