update
This commit is contained in:
@@ -2,7 +2,6 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <windows.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -252,12 +252,7 @@ internal void win32InitSound(HWND window, int32 samplesPerSec, int bufferSize) {
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT mainWindowCallback(
|
||||
HWND window,
|
||||
UINT message,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam
|
||||
) {
|
||||
LRESULT mainWindowCallback(HWND window, UINT message, WPARAM wParam, LPARAM lParam) {
|
||||
LRESULT result = 0;
|
||||
switch (message) {
|
||||
case WM_SIZE: {
|
||||
@@ -354,18 +349,24 @@ internal void win32FillSoundBuffer(Win32SoundOutput *soundOutput, DWORD byteToLo
|
||||
}
|
||||
}
|
||||
|
||||
internal void win32BeginRecordingInput(Win32State *win32State, int inputRecordingIndex) {
|
||||
win32State->inputRecordingIndex = inputRecordingIndex;
|
||||
char *filename = "replay.ipt";
|
||||
win32State->recordingHandle = CreateFileA(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, NULL, NULL);
|
||||
DWORD bytesToWrite = (DWORD)win32State->gameMemoryTotalSize;
|
||||
Assert(bytesToWrite < 0xFFFFFFFF);
|
||||
DWORD bytesWritten;
|
||||
WriteFile(win32State->recordingHandle, win32State->gameMemoryBlock, bytesToWrite, &bytesWritten, NULL);
|
||||
internal Win32ReplayBuffer* win32GetReplayBuffer(Win32State *state, int unsigned index) {
|
||||
Win32ReplayBuffer *result = &state->replayBuffers[index - 1];
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void win32BeginRecordingInput(Win32State *state, int inputRecordingIndex) {
|
||||
Win32ReplayBuffer *replayBuffer = win32GetReplayBuffer(state, inputRecordingIndex);
|
||||
if (replayBuffer->memoryBlock) {
|
||||
state->inputRecordingIndex = inputRecordingIndex;
|
||||
state->recordingHandle = replayBuffer->fileHandle;
|
||||
LARGE_INTEGER filePosition;
|
||||
filePosition.QuadPart = state->gameMemoryTotalSize;
|
||||
SetFilePointerEx(state->recordingHandle, filePosition, NULL, FILE_BEGIN);
|
||||
CopyMemory(replayBuffer->memoryBlock, state->gameMemoryBlock, state->gameMemoryTotalSize);
|
||||
}
|
||||
}
|
||||
|
||||
internal void win32EndRecordingInput(Win32State *win32State) {
|
||||
CloseHandle(win32State->recordingHandle);
|
||||
win32State->inputRecordingIndex = 0;
|
||||
}
|
||||
|
||||
@@ -374,18 +375,19 @@ internal void win32RecordInput(Win32State *win32State, GameInput *newInput) {
|
||||
WriteFile(win32State->recordingHandle, newInput, sizeof(*newInput), &bytesWritten, NULL);
|
||||
}
|
||||
|
||||
internal void win32BeginInputPlayback(Win32State *win32State, int inputPlayingIndex) {
|
||||
win32State->inputPlayingIndex = inputPlayingIndex;
|
||||
char *filename = "replay.ipt";
|
||||
win32State->playbackHandle = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
|
||||
DWORD bytesToRead = (DWORD)win32State->gameMemoryTotalSize;
|
||||
Assert(bytesToRead < 0xFFFFFFFF);
|
||||
DWORD bytesRead;
|
||||
ReadFile(win32State->playbackHandle, win32State->gameMemoryBlock, bytesToRead, &bytesRead, NULL);
|
||||
internal void win32BeginInputPlayback(Win32State *state, int inputPlayingIndex) {
|
||||
Win32ReplayBuffer *replayBuffer = win32GetReplayBuffer(state, inputPlayingIndex);
|
||||
if (replayBuffer->memoryBlock) {
|
||||
state->inputPlayingIndex = inputPlayingIndex;
|
||||
state->playbackHandle = replayBuffer->fileHandle;
|
||||
LARGE_INTEGER filePosition;
|
||||
filePosition.QuadPart = state->gameMemoryTotalSize;
|
||||
SetFilePointerEx(state->playbackHandle, filePosition, NULL, FILE_BEGIN);
|
||||
CopyMemory(state->gameMemoryBlock, replayBuffer->memoryBlock, state->gameMemoryTotalSize);
|
||||
}
|
||||
}
|
||||
|
||||
internal void win32EndInputPlayback(Win32State *win32State) {
|
||||
CloseHandle(win32State->playbackHandle);
|
||||
win32State->inputPlayingIndex = 0;
|
||||
}
|
||||
|
||||
@@ -443,11 +445,13 @@ internal void win32ProcessPendingMessages(Win32State *win32State, GameController
|
||||
} else if (VKCode == VK_SPACE) {
|
||||
} else if (VKCode == 'L') {
|
||||
if (isDown) {
|
||||
if (win32State->inputRecordingIndex == 0) {
|
||||
if (win32State->inputRecordingIndex == 0 && win32State->inputPlayingIndex == 0) {
|
||||
win32BeginRecordingInput(win32State, 1);
|
||||
} else {
|
||||
} else if (win32State->inputRecordingIndex != 0 && win32State->inputPlayingIndex == 0) {
|
||||
win32EndRecordingInput(win32State);
|
||||
win32BeginInputPlayback(win32State, 1);
|
||||
} else if (win32State->inputRecordingIndex == 0 && win32State->inputPlayingIndex != 0) {
|
||||
win32EndInputPlayback(win32State);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -501,30 +505,34 @@ void catStrings(size_t sourceACount, char *sourceA, size_t sourceBCount, char *s
|
||||
*dest++ = 0;
|
||||
}
|
||||
|
||||
void win32GetExeFilename(Win32State *win32State) {
|
||||
DWORD sizeOfFilename = GetModuleFileNameA(NULL, win32State->exeFilename, sizeof(win32State->exeFilename));
|
||||
win32State->onePastLastExeFilenameSlash = win32State->exeFilename;
|
||||
for (char *scan = win32State->exeFilename; *scan; scan++) {
|
||||
if (*scan == '\\') {
|
||||
win32State->onePastLastExeFilenameSlash = scan + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void win32GetFullPathToLocalFile(Win32State *state, char *filename, int filenameSize, char *maxPathBuffer) {
|
||||
catStrings(state->onePastLastExeFilenameSlash - state->exeFilename, state->exeFilename, filenameSize, filename, (size_t)MAX_PATH, maxPathBuffer);
|
||||
}
|
||||
|
||||
#define WINDOW_WIDTH 1280
|
||||
#define WINDOW_HEIGHT 720
|
||||
|
||||
int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prevInstance, PSTR commandLine, int commandShow) {
|
||||
char exeFileName[MAX_PATH];
|
||||
DWORD sizeOfFilename = GetModuleFileNameA(NULL, exeFileName, sizeof(exeFileName));
|
||||
char *onePastLastSlash = exeFileName;
|
||||
for (char *scan = exeFileName; *scan; scan++) {
|
||||
if (*scan == '\\') {
|
||||
onePastLastSlash = scan + 1;
|
||||
}
|
||||
}
|
||||
Win32State win32State = {};
|
||||
win32GetExeFilename(&win32State);
|
||||
|
||||
char sourceGameCodeDLLFilename[] = "handmade.dll";
|
||||
char *sourceGameCodeDLLFilename = "handmade.dll";
|
||||
char sourceGameCodeDLLFullPath[MAX_PATH];
|
||||
catStrings(onePastLastSlash - exeFileName, exeFileName,
|
||||
sizeof(sourceGameCodeDLLFilename) - 1, sourceGameCodeDLLFilename,
|
||||
sizeof(sourceGameCodeDLLFullPath) - 1, sourceGameCodeDLLFullPath);
|
||||
win32GetFullPathToLocalFile(&win32State, sourceGameCodeDLLFilename, sizeof(sourceGameCodeDLLFullPath) - 1, sourceGameCodeDLLFullPath);
|
||||
|
||||
char tempGameCodeDLLFilename[] = "handmade_temp.dll";
|
||||
char tempGameCodeDLLFullPath[MAX_PATH];
|
||||
catStrings(onePastLastSlash - exeFileName, exeFileName,
|
||||
sizeof(tempGameCodeDLLFilename) - 1, tempGameCodeDLLFilename,
|
||||
sizeof(tempGameCodeDLLFullPath) - 1, tempGameCodeDLLFullPath);
|
||||
win32GetFullPathToLocalFile(&win32State, tempGameCodeDLLFilename, sizeof(tempGameCodeDLLFullPath) - 1, tempGameCodeDLLFullPath);
|
||||
|
||||
LARGE_INTEGER performanceFrequencyResult;
|
||||
QueryPerformanceFrequency(&performanceFrequencyResult);
|
||||
@@ -572,7 +580,6 @@ int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prevInstance, PSTR commandLin
|
||||
RegisterHotKey(window, HH_CTRLW, MOD_CONTROL, 'W');
|
||||
|
||||
globalRunning = true;
|
||||
Win32State win32State = {};
|
||||
|
||||
GameInput input[2] = {};
|
||||
GameInput *oldInput = &input[0];
|
||||
@@ -597,7 +604,7 @@ int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prevInstance, PSTR commandLin
|
||||
#endif
|
||||
GameMemory gameMemory = {};
|
||||
gameMemory.permanentStorageSize = Megabytes(64);
|
||||
gameMemory.transientStorageSize = Gigabytes((uint64)4);
|
||||
gameMemory.transientStorageSize = Gigabytes((uint64)1);
|
||||
gameMemory.debugFreeFileMemory = debugFreeFileMemory;
|
||||
gameMemory.debugWriteEntireFile = debugWriteEntireFile;
|
||||
gameMemory.debugReadEntireFile = debugReadEntireFile;
|
||||
@@ -608,6 +615,25 @@ int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prevInstance, PSTR commandLin
|
||||
gameMemory.permanentStorage = win32State.gameMemoryBlock;
|
||||
gameMemory.transientStorage = ((uint8 *)gameMemory.permanentStorage + gameMemory.permanentStorageSize);
|
||||
|
||||
for (int i = 0; i < ArrayCount(win32State.replayBuffers); i++) {
|
||||
// Filename
|
||||
char prefix[] = "replay-";
|
||||
char suffix[] = ".hmr";
|
||||
const int totalLen = ArrayCount(prefix) + 1 + ArrayCount(suffix);
|
||||
char replayFilename[totalLen] = {};
|
||||
char digit[] = {(char)(48 + i)};
|
||||
catStrings(ArrayCount(prefix) - 1, prefix, 1, digit, ArrayCount(replayFilename) - 1, replayFilename);
|
||||
catStrings(ArrayCount(prefix), replayFilename, ArrayCount(suffix) - 1, suffix, ArrayCount(replayFilename) - 1, replayFilename);
|
||||
win32GetFullPathToLocalFile(&win32State, replayFilename, sizeof(replayFilename) - 1, win32State.replayBuffers[i].replayFilename);
|
||||
Win32ReplayBuffer *replayBuffer = &win32State.replayBuffers[i];
|
||||
|
||||
replayBuffer->fileHandle = CreateFileA(replayBuffer->replayFilename, GENERIC_WRITE | GENERIC_READ, NULL, NULL, CREATE_ALWAYS, NULL, NULL);
|
||||
DWORD maxSizeLow = (win32State.gameMemoryTotalSize & 0xFFFFFFFF);
|
||||
DWORD maxSizeHigh = (win32State.gameMemoryTotalSize >> 32);
|
||||
replayBuffer->memoryMap = CreateFileMappingA(replayBuffer->fileHandle, NULL, PAGE_READWRITE, maxSizeHigh, maxSizeLow, NULL);
|
||||
replayBuffer->memoryBlock = MapViewOfFile(replayBuffer->memoryMap, FILE_MAP_ALL_ACCESS, NULL, NULL, win32State.gameMemoryTotalSize);
|
||||
}
|
||||
|
||||
win32InitSound(window, soundOutput.samplesPerSecond, soundOutput.secondaryBufferSize);
|
||||
win32ClearBuffer(&soundOutput);
|
||||
globalSecondaryBuffer->Play(0, 0, DSBPLAY_LOOPING);
|
||||
@@ -651,8 +677,6 @@ int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prevInstance, PSTR commandLin
|
||||
win32ProcessKeyboardKeypress(&newInput->mouseButtons[3], GetKeyState(VK_XBUTTON1) & (1 << 15));
|
||||
win32ProcessKeyboardKeypress(&newInput->mouseButtons[4], GetKeyState(VK_XBUTTON2) & (1 << 15));
|
||||
|
||||
// TODO(dledda): day 25 34:00
|
||||
|
||||
XINPUT_STATE controllerState;
|
||||
int maxControllerCount = XUSER_MAX_COUNT;
|
||||
if (maxControllerCount > ArrayCount(newInput->controllers) - 1) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "handmade.h"
|
||||
#include <windows.h>
|
||||
|
||||
struct Win32OffscreenBuffer {
|
||||
BITMAPINFO info;
|
||||
@@ -29,13 +30,27 @@ struct Win32RecordedInput {
|
||||
GameInput *inputStream;
|
||||
};
|
||||
|
||||
#define WIN32_STATE_FILE_NAME_LENGTH MAX_PATH
|
||||
struct Win32ReplayBuffer {
|
||||
HANDLE memoryMap;
|
||||
HANDLE fileHandle;
|
||||
void *memoryBlock;
|
||||
char replayFilename[WIN32_STATE_FILE_NAME_LENGTH];
|
||||
};
|
||||
|
||||
struct Win32State {
|
||||
HANDLE recordingHandle;
|
||||
uint32 inputRecordingIndex;
|
||||
|
||||
HANDLE playbackHandle;
|
||||
uint32 inputPlayingIndex;
|
||||
|
||||
uint64 gameMemoryTotalSize;
|
||||
void *gameMemoryBlock;
|
||||
Win32ReplayBuffer replayBuffers[4];
|
||||
|
||||
char exeFilename[WIN32_STATE_FILE_NAME_LENGTH];
|
||||
char *onePastLastExeFilenameSlash;
|
||||
};
|
||||
|
||||
struct Win32GameCode {
|
||||
|
||||
Reference in New Issue
Block a user