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