|
@@ -143,13 +143,27 @@ struct Win32GameCode { |
|
|
GameUpdateAndRenderFn *updateAndRender; |
|
|
GameUpdateAndRenderFn *updateAndRender; |
|
|
GameGetSoundSamplesFn *getSoundSamples; |
|
|
GameGetSoundSamplesFn *getSoundSamples; |
|
|
bool isValid; |
|
|
bool isValid; |
|
|
|
|
|
FILETIME lastWriteTime; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
internal Win32GameCode win32LoadGameCode() { |
|
|
|
|
|
|
|
|
inline FILETIME win32GetLastWriteTime(char *filename) { |
|
|
|
|
|
FILETIME lastWriteTime = {}; |
|
|
|
|
|
WIN32_FIND_DATA findData; |
|
|
|
|
|
HANDLE findHandle = FindFirstFileA(filename, &findData); |
|
|
|
|
|
if (findHandle != INVALID_HANDLE_VALUE) { |
|
|
|
|
|
lastWriteTime = findData.ftLastWriteTime; |
|
|
|
|
|
FindClose(findHandle); |
|
|
|
|
|
} |
|
|
|
|
|
return lastWriteTime; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
internal Win32GameCode win32LoadGameCode(char *filename, char *tempname) { |
|
|
Win32GameCode result = {}; |
|
|
Win32GameCode result = {}; |
|
|
|
|
|
|
|
|
CopyFile("handmade.dll", "handmade_temp.dll", FALSE); |
|
|
|
|
|
HMODULE gameCodeLib = LoadLibrary("handmade_temp.dll"); |
|
|
|
|
|
|
|
|
result.lastWriteTime = win32GetLastWriteTime(filename); |
|
|
|
|
|
|
|
|
|
|
|
CopyFile(filename, tempname, FALSE); |
|
|
|
|
|
HMODULE gameCodeLib = LoadLibrary(tempname); |
|
|
result.gameCodeLib = gameCodeLib; |
|
|
result.gameCodeLib = gameCodeLib; |
|
|
|
|
|
|
|
|
if (gameCodeLib) { |
|
|
if (gameCodeLib) { |
|
@@ -453,7 +467,38 @@ internal void win32DebugSyncDisplay(Win32OffscreenBuffer *screenBuffer, int mark |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void catStrings(size_t sourceACount, char *sourceA, size_t sourceBCount, char *sourceB, size_t destCount, char *dest) { |
|
|
|
|
|
for (int i = 0; i < sourceACount; i++) { |
|
|
|
|
|
*dest++ = *sourceA++; |
|
|
|
|
|
} |
|
|
|
|
|
for (int i = 0; i < sourceBCount; i++) { |
|
|
|
|
|
*dest++ = *sourceB++; |
|
|
|
|
|
} |
|
|
|
|
|
*dest++ = 0; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
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]; |
|
|
|
|
|
DWORD sizeOfFilename = GetModuleFileNameA(NULL, exeFileName, sizeof(exeFileName)); |
|
|
|
|
|
char *onePastLastSlash = exeFileName; |
|
|
|
|
|
for (char *scan = exeFileName; *scan; scan++) { |
|
|
|
|
|
if (*scan == '\\') { |
|
|
|
|
|
onePastLastSlash = scan + 1; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
char sourceGameCodeDLLFilename[] = "handmade.dll"; |
|
|
|
|
|
char sourceGameCodeDLLFullPath[MAX_PATH]; |
|
|
|
|
|
catStrings(onePastLastSlash - exeFileName, exeFileName, |
|
|
|
|
|
sizeof(sourceGameCodeDLLFilename) - 1, 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); |
|
|
|
|
|
|
|
|
LARGE_INTEGER performanceFrequencyResult; |
|
|
LARGE_INTEGER performanceFrequencyResult; |
|
|
QueryPerformanceFrequency(&performanceFrequencyResult); |
|
|
QueryPerformanceFrequency(&performanceFrequencyResult); |
|
|
globalPerfCountFrequency = performanceFrequencyResult.QuadPart; |
|
|
globalPerfCountFrequency = performanceFrequencyResult.QuadPart; |
|
@@ -506,7 +551,7 @@ int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prevInstance, PSTR commandLin |
|
|
soundOutput.runningSampleIndex = 0; |
|
|
soundOutput.runningSampleIndex = 0; |
|
|
soundOutput.bytesPerSample = sizeof(int16)*2; |
|
|
soundOutput.bytesPerSample = sizeof(int16)*2; |
|
|
soundOutput.secondaryBufferSize = soundOutput.samplesPerSecond*soundOutput.bytesPerSample; |
|
|
soundOutput.secondaryBufferSize = soundOutput.samplesPerSecond*soundOutput.bytesPerSample; |
|
|
soundOutput.safetyBytes = (soundOutput.samplesPerSecond * soundOutput.bytesPerSample / gameUpdateHz) / 3; |
|
|
|
|
|
|
|
|
soundOutput.safetyBytes = (soundOutput.samplesPerSecond * soundOutput.bytesPerSample / gameUpdateHz) / 2; |
|
|
|
|
|
|
|
|
int16 *samples = (int16*)VirtualAlloc(NULL, soundOutput.secondaryBufferSize, MEM_COMMIT, PAGE_READWRITE); |
|
|
int16 *samples = (int16*)VirtualAlloc(NULL, soundOutput.secondaryBufferSize, MEM_COMMIT, PAGE_READWRITE); |
|
|
|
|
|
|
|
@@ -539,16 +584,14 @@ int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prevInstance, PSTR commandLin |
|
|
real32 audioLatencySeconds = 0; |
|
|
real32 audioLatencySeconds = 0; |
|
|
bool soundIsValid = false; |
|
|
bool soundIsValid = false; |
|
|
|
|
|
|
|
|
Win32GameCode game = win32LoadGameCode(); |
|
|
|
|
|
uint32 loadCounter = 0; |
|
|
|
|
|
|
|
|
Win32GameCode game = win32LoadGameCode(sourceGameCodeDLLFullPath, tempGameCodeDLLFullPath); |
|
|
|
|
|
|
|
|
int64 lastCycleCount = __rdtsc(); |
|
|
int64 lastCycleCount = __rdtsc(); |
|
|
while (globalRunning) { |
|
|
while (globalRunning) { |
|
|
if (loadCounter++ > 60) { |
|
|
|
|
|
|
|
|
FILETIME newWriteTime = win32GetLastWriteTime(sourceGameCodeDLLFullPath); |
|
|
|
|
|
if (CompareFileTime(&newWriteTime, &game.lastWriteTime) != 0) { |
|
|
win32UnloadGameCode(&game); |
|
|
win32UnloadGameCode(&game); |
|
|
game = win32LoadGameCode(); |
|
|
|
|
|
loadCounter = 0; |
|
|
|
|
|
// TODO(dledda): handmade hero episode 22 (from the beginning) |
|
|
|
|
|
|
|
|
game = win32LoadGameCode(sourceGameCodeDLLFullPath, tempGameCodeDLLFullPath); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
GameControllerInput *oldKeyboardController = &oldInput->controllers[0]; |
|
|
GameControllerInput *oldKeyboardController = &oldInput->controllers[0]; |
|
|