update
This commit is contained in:
@@ -1,2 +1,2 @@
|
|||||||
call build || exit /b %errorlevel%
|
call build || exit /b %errorlevel%
|
||||||
devenv .\build\handmade.exe
|
devenv .\build\handmade_win32.exe
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
call build || exit /b %errorlevel%
|
call build || exit /b %errorlevel%
|
||||||
.\build\handmade.exe
|
.\build\handmade_win32.exe
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
@echo off
|
@echo off
|
||||||
if NOT EXIST .\build mkdir .\build
|
if NOT EXIST .\build mkdir .\build
|
||||||
pushd .\build
|
|
||||||
cl ^
|
set commonLinkerFlags= -opt:ref user32.lib Gdi32.lib winmm.lib
|
||||||
|
set commonCompilerFlags=^
|
||||||
-MT %= Make sure the C runtime library is statically linked =%^
|
-MT %= Make sure the C runtime library is statically linked =%^
|
||||||
-Fmwin32_handmade.map %= Create a map file =%^
|
|
||||||
-Gm- %= Turns off incremently building =%^
|
-Gm- %= Turns off incremently building =%^
|
||||||
-nologo %= No one cares you made the compiler Microsoft =%^
|
-nologo %= No one cares you made the compiler Microsoft =%^
|
||||||
-Oi %= Always use intrinsics =%^
|
-Oi %= Always use intrinsics =%^
|
||||||
@@ -12,10 +12,12 @@ cl ^
|
|||||||
-WX -W4 -wd4201 -wd4100 -wd4189 %= Compiler warnings, -WX warnings as errors, -W4 warning level 4, -wdXXXX disable warning XXXX =%^
|
-WX -W4 -wd4201 -wd4100 -wd4189 %= Compiler warnings, -WX warnings as errors, -W4 warning level 4, -wdXXXX disable warning XXXX =%^
|
||||||
-DHANDMADE_INTERNAL=1 -DHANDMADE_SLOW=1 -DHANDMADE_WIN32=1 %= Custom #defines =%^
|
-DHANDMADE_INTERNAL=1 -DHANDMADE_SLOW=1 -DHANDMADE_WIN32=1 %= Custom #defines =%^
|
||||||
-FC %= Full path of source code file in diagnostics =%^
|
-FC %= Full path of source code file in diagnostics =%^
|
||||||
-Zi %= Generate debugger info =%^
|
-Zi %= Generate debugger info =%
|
||||||
-Fe:handmade.exe ..\src\win32_handmade.cpp %= Output filename, input filename =%^
|
|
||||||
user32.lib Gdi32.lib winmm.lib %= Linked libraries =%^
|
pushd .\build
|
||||||
/link -subsystem:windows,5.1 %= Linker stuff =%
|
|
||||||
|
cl %commonCompilerFlags% -Fe:handmade.dll ..\src\handmade.cpp -Fmhandmade.map /link /DLL /EXPORT:gameGetSoundSamples /EXPORT:gameUpdateAndRender
|
||||||
|
cl %commonCompilerFlags% -Fe:handmade_win32.exe ..\src\win32_handmade.cpp -Fmwin32_handmade.map /link %commonLinkerFlags%
|
||||||
popd
|
popd
|
||||||
exit /b
|
exit /b
|
||||||
|
|
||||||
|
|||||||
@@ -2,16 +2,6 @@
|
|||||||
|
|
||||||
#define PI32 3.141592653589f
|
#define PI32 3.141592653589f
|
||||||
|
|
||||||
void debug_printf(wchar_t* format, ...) {
|
|
||||||
size_t bufsize = wcslen(format)*10;
|
|
||||||
wchar_t *output = (wchar_t*)malloc(bufsize);
|
|
||||||
va_list list;
|
|
||||||
va_start(list, format);
|
|
||||||
vswprintf(output, bufsize, format, list);
|
|
||||||
OutputDebugStringW(output);
|
|
||||||
free(output);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void outputSineSound(GameSoundOutputBuffer *soundBuffer, GameState *state) {
|
internal void outputSineSound(GameSoundOutputBuffer *soundBuffer, GameState *state) {
|
||||||
int16 toneVolume = 3000;
|
int16 toneVolume = 3000;
|
||||||
int wavePeriod = soundBuffer->samplesPerSecond/state->toneHz;
|
int wavePeriod = soundBuffer->samplesPerSecond/state->toneHz;
|
||||||
@@ -34,23 +24,25 @@ internal void renderWeirdGradient(GameOffscreenBuffer *buffer, int xOffset, int
|
|||||||
for (int x = 0; x < buffer->width; x++) {
|
for (int x = 0; x < buffer->width; x++) {
|
||||||
uint8 blue = (uint8)(x + xOffset);
|
uint8 blue = (uint8)(x + xOffset);
|
||||||
uint8 green = (uint8)(y + yOffset);
|
uint8 green = (uint8)(y + yOffset);
|
||||||
*pixel++ = (green << 8) | blue;
|
*pixel++ = (green << 16) | blue;
|
||||||
}
|
}
|
||||||
row += pitch;
|
row += pitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void gameUpdateAndRender(GameMemory *memory, GameOffscreenBuffer *videoBuf, GameInput *input) {
|
extern "C" GAME_UPDATE_AND_RENDER(gameUpdateAndRender) {
|
||||||
Assert(sizeof(GameState) <= memory->permanentStorageSize);
|
Assert(sizeof(GameState) <= memory->permanentStorageSize);
|
||||||
|
|
||||||
GameState *state = (GameState*)memory->permanentStorage;
|
GameState *state = (GameState*)memory->permanentStorage;
|
||||||
|
|
||||||
if (!memory->isInitialised) {
|
if (!memory->isInitialised) {
|
||||||
//DebugReadFileResult bmpMem = DEBUG_platformReadEntireFile(__FILE__);
|
DebugReadFileResult bmpMem = memory->debugReadEntireFile(__FILE__);
|
||||||
//if (bmpMem.contents) {
|
if (bmpMem.contents) {
|
||||||
// DEBUG_platformWriteEntireFile("c:/source/repos/handmade/src/test.cpp", bmpMem.contentsSize, bmpMem.contents);
|
if (false) {
|
||||||
// DEBUG_platformFreeFileMemory(bmpMem.contents);
|
memory->debugWriteEntireFile("c:/source/repos/handmade/src/test.cpp", bmpMem.contentsSize, bmpMem.contents);
|
||||||
//}
|
}
|
||||||
|
memory->debugFreeFileMemory(bmpMem.contents);
|
||||||
|
}
|
||||||
|
|
||||||
state->toneHz = 440;
|
state->toneHz = 440;
|
||||||
state->tSine = 0;
|
state->tSine = 0;
|
||||||
@@ -70,8 +62,6 @@ internal void gameUpdateAndRender(GameMemory *memory, GameOffscreenBuffer *video
|
|||||||
} else if (controllerInput->stickLeft.endedDown) {
|
} else if (controllerInput->stickLeft.endedDown) {
|
||||||
state->toneHz = 440 - 128;
|
state->toneHz = 440 - 128;
|
||||||
state->greenOffset += 10;
|
state->greenOffset += 10;
|
||||||
} else {
|
|
||||||
//state->toneHz = 440;
|
|
||||||
}
|
}
|
||||||
if (controllerInput->stickUp.endedDown) {
|
if (controllerInput->stickUp.endedDown) {
|
||||||
state->blueOffset += 10;
|
state->blueOffset += 10;
|
||||||
@@ -84,6 +74,14 @@ internal void gameUpdateAndRender(GameMemory *memory, GameOffscreenBuffer *video
|
|||||||
renderWeirdGradient(videoBuf, state->greenOffset, state->blueOffset);
|
renderWeirdGradient(videoBuf, state->greenOffset, state->blueOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void gameGetSoundSamples(GameMemory *memory, GameSoundOutputBuffer *soundBuf) {
|
extern "C" GAME_GET_SOUND_SAMPLES(gameGetSoundSamples) {
|
||||||
outputSineSound(soundBuf, (GameState*)memory->permanentStorage);
|
outputSineSound(soundBuf, (GameState*)memory->permanentStorage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if HANDMADE_WIN32
|
||||||
|
#include "windows.h"
|
||||||
|
|
||||||
|
BOOL DllMain() {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -64,6 +64,28 @@ inline uint32 safeTruncateUInt64(uint64 val) {
|
|||||||
return (uint32)val;
|
return (uint32)val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// === Platform to game services ===
|
||||||
|
#if HANDMADE_INTERNAL
|
||||||
|
|
||||||
|
struct DebugReadFileResult {
|
||||||
|
uint32 contentsSize;
|
||||||
|
void *contents;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DEBUG_PLATFORM_READ_ENTIRE_FILE(name) DebugReadFileResult name(char *filename)
|
||||||
|
typedef DEBUG_PLATFORM_READ_ENTIRE_FILE(DebugPlatformReadEntireFileFn);
|
||||||
|
|
||||||
|
#define DEBUG_PLATFORM_FREE_FILE_MEMORY(name) void name(void *fileMemory)
|
||||||
|
typedef DEBUG_PLATFORM_FREE_FILE_MEMORY(DebugPlatformFreeFileMemoryFn);
|
||||||
|
|
||||||
|
#define DEBUG_PLATFORM_WRITE_ENTIRE_FILE(name) bool32 name(char *filename, uint32 memorySize, void *memory)
|
||||||
|
typedef DEBUG_PLATFORM_WRITE_ENTIRE_FILE(DebugPlatformWriteEntireFileFn);
|
||||||
|
|
||||||
|
#define DEBUG_PLATFORM_PRINTF(name) void name(wchar_t* format, ...)
|
||||||
|
typedef DEBUG_PLATFORM_PRINTF(DebugPrintfFn);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
// Game to platform layer services
|
// Game to platform layer services
|
||||||
struct GameSoundOutputBuffer {
|
struct GameSoundOutputBuffer {
|
||||||
int samplesPerSecond;
|
int samplesPerSecond;
|
||||||
@@ -111,10 +133,17 @@ struct GameInput {
|
|||||||
|
|
||||||
struct GameMemory {
|
struct GameMemory {
|
||||||
bool32 isInitialised;
|
bool32 isInitialised;
|
||||||
|
|
||||||
uint64 permanentStorageSize;
|
uint64 permanentStorageSize;
|
||||||
void *permanentStorage; // required to be initialised to zero at startup
|
void *permanentStorage; // required to be initialised to zero at startup
|
||||||
|
|
||||||
uint64 transientStorageSize;
|
uint64 transientStorageSize;
|
||||||
void *transientStorage; // required to be initialised to zero at startup
|
void *transientStorage; // required to be initialised to zero at startup
|
||||||
|
|
||||||
|
DebugPlatformReadEntireFileFn *debugReadEntireFile;
|
||||||
|
DebugPlatformFreeFileMemoryFn *debugFreeFileMemory;
|
||||||
|
DebugPlatformWriteEntireFileFn *debugWriteEntireFile;
|
||||||
|
DebugPrintfFn *debug_printf;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GameState {
|
struct GameState {
|
||||||
@@ -125,22 +154,11 @@ struct GameState {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// === Game to platform services ===
|
// === Game to platform services ===
|
||||||
internal void gameUpdateAndRender(GameMemory *memory, GameInput *input, GameOffscreenBuffer *videoBuf);
|
|
||||||
internal void gameGetSoundSamples(GameMemory *memory, GameSoundOutputBuffer *soundBuf);
|
|
||||||
|
|
||||||
// === Platform to game services ===
|
|
||||||
#if HANDMADE_INTERNAL
|
|
||||||
|
|
||||||
struct DebugReadFileResult {
|
|
||||||
uint32 contentsSize;
|
|
||||||
void *contents;
|
|
||||||
};
|
|
||||||
|
|
||||||
DebugReadFileResult DEBUG_platformReadEntireFile(char *filename);
|
|
||||||
void DEBUG_platformFreeFileMemory(void *memory);
|
|
||||||
bool32 DEBUG_platformWriteEntireFile(char *filename, uint32 memorySize, void *memory);
|
|
||||||
void debug_printf(wchar_t* format, ...);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
#define GAME_UPDATE_AND_RENDER(name) void name(GameMemory *memory, GameOffscreenBuffer *videoBuf, GameInput *input)
|
||||||
|
typedef GAME_UPDATE_AND_RENDER(GameUpdateAndRenderFn);
|
||||||
|
GAME_UPDATE_AND_RENDER(gameUpdateAndRenderStub) {}
|
||||||
|
|
||||||
|
#define GAME_GET_SOUND_SAMPLES(name) void name(GameMemory *memory, GameSoundOutputBuffer *soundBuf)
|
||||||
|
typedef GAME_GET_SOUND_SAMPLES(GameGetSoundSamplesFn);
|
||||||
|
GAME_GET_SOUND_SAMPLES(gameGetSoundSamplesStub) {}
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
#include <dsound.h>
|
#include <dsound.h>
|
||||||
|
|
||||||
// Local imports
|
// Local imports
|
||||||
|
#include "handmade.h"
|
||||||
#include "win32_handmade.h"
|
#include "win32_handmade.h"
|
||||||
#include "handmade.cpp"
|
|
||||||
|
|
||||||
global ATOM HH_CTRLW;
|
global ATOM HH_CTRLW;
|
||||||
global bool globalRunning;
|
global bool globalRunning;
|
||||||
@@ -31,13 +31,23 @@ typedef HRESULT WINAPI DirectSoundCreateFn(LPCGUID pcGuidDevice, LPDIRECTSOUND *
|
|||||||
|
|
||||||
#define stackAlloc(size, type) (type*)_alloca(size*sizeof(type))
|
#define stackAlloc(size, type) (type*)_alloca(size*sizeof(type))
|
||||||
|
|
||||||
void DEBUG_platformFreeFileMemory(void *fileMemory) {
|
DEBUG_PLATFORM_PRINTF(debug_printf) {
|
||||||
|
size_t bufsize = wcslen(format)*10;
|
||||||
|
wchar_t *output = (wchar_t*)malloc(bufsize);
|
||||||
|
va_list list;
|
||||||
|
va_start(list, format);
|
||||||
|
vswprintf(output, bufsize, format, list);
|
||||||
|
OutputDebugStringW(output);
|
||||||
|
free(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG_PLATFORM_FREE_FILE_MEMORY(debugFreeFileMemory) {
|
||||||
if (fileMemory) {
|
if (fileMemory) {
|
||||||
VirtualFree(fileMemory, NULL, MEM_RELEASE);
|
VirtualFree(fileMemory, NULL, MEM_RELEASE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DebugReadFileResult DEBUG_platformReadEntireFile(char *filename) {
|
DEBUG_PLATFORM_READ_ENTIRE_FILE(debugReadEntireFile) {
|
||||||
DebugReadFileResult result = {};
|
DebugReadFileResult result = {};
|
||||||
HANDLE fileHandle = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
|
HANDLE fileHandle = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
|
||||||
if (fileHandle != INVALID_HANDLE_VALUE) {
|
if (fileHandle != INVALID_HANDLE_VALUE) {
|
||||||
@@ -50,7 +60,7 @@ DebugReadFileResult DEBUG_platformReadEntireFile(char *filename) {
|
|||||||
if (ReadFile(fileHandle, result.contents, (DWORD)fileSize.QuadPart, &bytesRead, NULL) && (fileSize32 == (uint32)bytesRead)) {
|
if (ReadFile(fileHandle, result.contents, (DWORD)fileSize.QuadPart, &bytesRead, NULL) && (fileSize32 == (uint32)bytesRead)) {
|
||||||
result.contentsSize = fileSize32;
|
result.contentsSize = fileSize32;
|
||||||
} else {
|
} else {
|
||||||
DEBUG_platformFreeFileMemory(result.contents);
|
debugFreeFileMemory(result.contents);
|
||||||
result.contents = NULL;
|
result.contents = NULL;
|
||||||
// logging
|
// logging
|
||||||
}
|
}
|
||||||
@@ -68,7 +78,7 @@ DebugReadFileResult DEBUG_platformReadEntireFile(char *filename) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool32 DEBUG_platformWriteEntireFile(char *filename, uint32 memorySize, void *memory) {
|
DEBUG_PLATFORM_WRITE_ENTIRE_FILE(debugWriteEntireFile) {
|
||||||
bool32 result = false;
|
bool32 result = false;
|
||||||
HANDLE fileHandle = CreateFileA(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, NULL, NULL);
|
HANDLE fileHandle = CreateFileA(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, NULL, NULL);
|
||||||
if (fileHandle != INVALID_HANDLE_VALUE) {
|
if (fileHandle != INVALID_HANDLE_VALUE) {
|
||||||
@@ -128,6 +138,42 @@ internal void win32DrawBufferInWindow(Win32OffscreenBuffer *buffer, HWND window)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Win32GameCode {
|
||||||
|
HMODULE gameCodeLib;
|
||||||
|
GameUpdateAndRenderFn *updateAndRender;
|
||||||
|
GameGetSoundSamplesFn *getSoundSamples;
|
||||||
|
bool isValid;
|
||||||
|
};
|
||||||
|
|
||||||
|
internal Win32GameCode win32LoadGameCode() {
|
||||||
|
Win32GameCode result = {};
|
||||||
|
|
||||||
|
CopyFile("handmade.dll", "handmade_temp.dll", FALSE);
|
||||||
|
HMODULE gameCodeLib = LoadLibrary("handmade_temp.dll");
|
||||||
|
result.gameCodeLib = gameCodeLib;
|
||||||
|
|
||||||
|
if (gameCodeLib) {
|
||||||
|
result.updateAndRender = (GameUpdateAndRenderFn *)GetProcAddress(result.gameCodeLib, "gameUpdateAndRender");
|
||||||
|
result.getSoundSamples = (GameGetSoundSamplesFn *)GetProcAddress(result.gameCodeLib, "gameGetSoundSamples");
|
||||||
|
result.isValid = (result.updateAndRender && result.getSoundSamples);
|
||||||
|
}
|
||||||
|
if (!result.isValid) {
|
||||||
|
result.getSoundSamples = gameGetSoundSamplesStub;
|
||||||
|
result.updateAndRender = gameUpdateAndRenderStub;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void win32UnloadGameCode(Win32GameCode *gameCode) {
|
||||||
|
if (gameCode->gameCodeLib) {
|
||||||
|
FreeLibrary(gameCode->gameCodeLib);
|
||||||
|
}
|
||||||
|
gameCode->isValid = false;
|
||||||
|
gameCode->getSoundSamples = gameGetSoundSamplesStub;
|
||||||
|
gameCode->updateAndRender = gameUpdateAndRenderStub;
|
||||||
|
}
|
||||||
|
|
||||||
internal void win32LoadXInput() {
|
internal void win32LoadXInput() {
|
||||||
HMODULE xInputLib = LoadLibrary("xinput1_4.dll");
|
HMODULE xInputLib = LoadLibrary("xinput1_4.dll");
|
||||||
if (!xInputLib) {
|
if (!xInputLib) {
|
||||||
@@ -472,6 +518,10 @@ int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prevInstance, PSTR commandLin
|
|||||||
GameMemory gameMemory = {};
|
GameMemory gameMemory = {};
|
||||||
gameMemory.permanentStorageSize = Megabytes(64);
|
gameMemory.permanentStorageSize = Megabytes(64);
|
||||||
gameMemory.transientStorageSize = Gigabytes((uint64)4);
|
gameMemory.transientStorageSize = Gigabytes((uint64)4);
|
||||||
|
gameMemory.debugFreeFileMemory = debugFreeFileMemory;
|
||||||
|
gameMemory.debugWriteEntireFile = debugWriteEntireFile;
|
||||||
|
gameMemory.debugReadEntireFile = debugReadEntireFile;
|
||||||
|
gameMemory.debug_printf = debug_printf;
|
||||||
|
|
||||||
uint64 totalSize = gameMemory.permanentStorageSize + gameMemory.transientStorageSize;
|
uint64 totalSize = gameMemory.permanentStorageSize + gameMemory.transientStorageSize;
|
||||||
gameMemory.permanentStorage = VirtualAlloc(baseAddress, totalSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
gameMemory.permanentStorage = VirtualAlloc(baseAddress, totalSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
||||||
@@ -484,12 +534,23 @@ int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prevInstance, PSTR commandLin
|
|||||||
LARGE_INTEGER lastWorkCounter = win32GetWallClock();
|
LARGE_INTEGER lastWorkCounter = win32GetWallClock();
|
||||||
LARGE_INTEGER flipWallClock = win32GetWallClock();
|
LARGE_INTEGER flipWallClock = win32GetWallClock();
|
||||||
|
|
||||||
int64 lastCycleCount = __rdtsc();
|
|
||||||
|
|
||||||
DWORD audioLatencyBytes = 0;
|
DWORD audioLatencyBytes = 0;
|
||||||
real32 audioLatencySeconds = 0;
|
real32 audioLatencySeconds = 0;
|
||||||
|
bool soundIsValid = false;
|
||||||
|
|
||||||
|
Win32GameCode game = win32LoadGameCode();
|
||||||
|
uint32 loadCounter = 0;
|
||||||
|
|
||||||
|
int64 lastCycleCount = __rdtsc();
|
||||||
while (globalRunning) {
|
while (globalRunning) {
|
||||||
|
if (loadCounter++ > 60) {
|
||||||
|
win32UnloadGameCode(&game);
|
||||||
|
game = win32LoadGameCode();
|
||||||
|
loadCounter = 0;
|
||||||
|
// TODO(dledda): handmade hero episode 22 (from the beginning)
|
||||||
|
}
|
||||||
|
|
||||||
GameControllerInput *oldKeyboardController = &oldInput->controllers[0];
|
GameControllerInput *oldKeyboardController = &oldInput->controllers[0];
|
||||||
GameControllerInput *newKeyboardController = &newInput->controllers[0];
|
GameControllerInput *newKeyboardController = &newInput->controllers[0];
|
||||||
GameControllerInput zeroController = {};
|
GameControllerInput zeroController = {};
|
||||||
@@ -566,11 +627,10 @@ int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prevInstance, PSTR commandLin
|
|||||||
videoBuffer.memory = globalBackBuffer.memory;
|
videoBuffer.memory = globalBackBuffer.memory;
|
||||||
videoBuffer.width = globalBackBuffer.width;
|
videoBuffer.width = globalBackBuffer.width;
|
||||||
videoBuffer.height = globalBackBuffer.height;
|
videoBuffer.height = globalBackBuffer.height;
|
||||||
gameUpdateAndRender(&gameMemory, &videoBuffer, newInput);
|
game.updateAndRender(&gameMemory, &videoBuffer, newInput);
|
||||||
|
|
||||||
DWORD playCursor = 0;
|
DWORD playCursor = 0;
|
||||||
DWORD writeCursor = 0;
|
DWORD writeCursor = 0;
|
||||||
bool soundIsValid = false;
|
|
||||||
|
|
||||||
if (SUCCEEDED(globalSecondaryBuffer->GetCurrentPosition(&playCursor, &writeCursor))) {
|
if (SUCCEEDED(globalSecondaryBuffer->GetCurrentPosition(&playCursor, &writeCursor))) {
|
||||||
if (!soundIsValid) {
|
if (!soundIsValid) {
|
||||||
@@ -579,17 +639,17 @@ int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prevInstance, PSTR commandLin
|
|||||||
}
|
}
|
||||||
DWORD byteToLock = (soundOutput.runningSampleIndex*soundOutput.bytesPerSample) % soundOutput.secondaryBufferSize;
|
DWORD byteToLock = (soundOutput.runningSampleIndex*soundOutput.bytesPerSample) % soundOutput.secondaryBufferSize;
|
||||||
|
|
||||||
// TODO(dledda): episode 20 ~2:00, something's wrong though, gotta sort it out.
|
|
||||||
|
|
||||||
DWORD expectedSoundBytesPerFrame = (soundOutput.samplesPerSecond * soundOutput.bytesPerSample) / gameUpdateHz;
|
DWORD expectedSoundBytesPerFrame = (soundOutput.samplesPerSecond * soundOutput.bytesPerSample) / gameUpdateHz;
|
||||||
DWORD expectedFrameBoundaryByte = playCursor + expectedSoundBytesPerFrame;
|
DWORD expectedFrameBoundaryByte = playCursor + expectedSoundBytesPerFrame;
|
||||||
|
|
||||||
DWORD safeWriteCursor = writeCursor;
|
DWORD safeWriteCursor = writeCursor;
|
||||||
if (safeWriteCursor < playCursor) {
|
if (safeWriteCursor < playCursor) {
|
||||||
safeWriteCursor += soundOutput.secondaryBufferSize;
|
safeWriteCursor += soundOutput.secondaryBufferSize;
|
||||||
}
|
}
|
||||||
Assert(safeWriteCursor >= playCursor);
|
Assert(safeWriteCursor >= playCursor);
|
||||||
safeWriteCursor += soundOutput.safetyBytes + 2000;
|
safeWriteCursor += soundOutput.safetyBytes;
|
||||||
bool audioIsLowLatency = safeWriteCursor >= expectedFrameBoundaryByte;
|
|
||||||
|
bool audioIsLowLatency = safeWriteCursor < expectedFrameBoundaryByte;
|
||||||
|
|
||||||
DWORD targetCursor = 0;
|
DWORD targetCursor = 0;
|
||||||
if (audioIsLowLatency) {
|
if (audioIsLowLatency) {
|
||||||
@@ -610,7 +670,7 @@ int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prevInstance, PSTR commandLin
|
|||||||
soundBuffer.samplesPerSecond = soundOutput.samplesPerSecond;
|
soundBuffer.samplesPerSecond = soundOutput.samplesPerSecond;
|
||||||
soundBuffer.sampleCount = bytesToWrite / soundOutput.bytesPerSample;
|
soundBuffer.sampleCount = bytesToWrite / soundOutput.bytesPerSample;
|
||||||
soundBuffer.samples = samples;
|
soundBuffer.samples = samples;
|
||||||
gameGetSoundSamples(&gameMemory, &soundBuffer);
|
game.getSoundSamples(&gameMemory, &soundBuffer);
|
||||||
#if HANDMADE_INTERNAL
|
#if HANDMADE_INTERNAL
|
||||||
Assert(debugTimeMarkerIndex < ArrayCount(debugMarkers));
|
Assert(debugTimeMarkerIndex < ArrayCount(debugMarkers));
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user