|
@@ -7,7 +7,7 @@ |
|
|
#include "handmade.cpp" |
|
|
#include "handmade.cpp" |
|
|
|
|
|
|
|
|
global ATOM HH_CTRLW; |
|
|
global ATOM HH_CTRLW; |
|
|
global bool running; |
|
|
|
|
|
|
|
|
global bool globalRunning; |
|
|
global Win32OffscreenBuffer globalBackBuffer; |
|
|
global Win32OffscreenBuffer globalBackBuffer; |
|
|
global LPDIRECTSOUNDBUFFER globalSecondaryBuffer; |
|
|
global LPDIRECTSOUNDBUFFER globalSecondaryBuffer; |
|
|
|
|
|
|
|
@@ -29,6 +29,61 @@ 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) { |
|
|
|
|
|
if (fileMemory) { |
|
|
|
|
|
VirtualFree(fileMemory, NULL, MEM_RELEASE); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DebugReadFileResult DEBUG_platformReadEntireFile(char *filename) { |
|
|
|
|
|
DebugReadFileResult result = {}; |
|
|
|
|
|
HANDLE fileHandle = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL); |
|
|
|
|
|
if (fileHandle != INVALID_HANDLE_VALUE) { |
|
|
|
|
|
LARGE_INTEGER fileSize; |
|
|
|
|
|
if (GetFileSizeEx(fileHandle, &fileSize)) { |
|
|
|
|
|
uint32 fileSize32 = safeTruncateUInt64(fileSize.QuadPart); |
|
|
|
|
|
result.contents = VirtualAlloc(NULL, fileSize.QuadPart, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); |
|
|
|
|
|
if (result.contents) { |
|
|
|
|
|
DWORD bytesRead; |
|
|
|
|
|
if (ReadFile(fileHandle, result.contents, (DWORD)fileSize.QuadPart, &bytesRead, NULL) && (fileSize32 == (uint32)bytesRead)) { |
|
|
|
|
|
result.contentsSize = fileSize32; |
|
|
|
|
|
} else { |
|
|
|
|
|
DEBUG_platformFreeFileMemory(result.contents); |
|
|
|
|
|
result.contents = NULL; |
|
|
|
|
|
// logging |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
result.contents = NULL; |
|
|
|
|
|
// logging |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
// logging |
|
|
|
|
|
} |
|
|
|
|
|
CloseHandle(fileHandle); |
|
|
|
|
|
} else { |
|
|
|
|
|
// logging |
|
|
|
|
|
} |
|
|
|
|
|
return result; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool32 DEBUG_platformWriteEntireFile(char *filename, uint32 memorySize, void *memory) { |
|
|
|
|
|
bool32 result = false; |
|
|
|
|
|
HANDLE fileHandle = CreateFileA(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, NULL, NULL); |
|
|
|
|
|
if (fileHandle != INVALID_HANDLE_VALUE) { |
|
|
|
|
|
DWORD bytesWritten; |
|
|
|
|
|
if (WriteFile(fileHandle, memory, memorySize, &bytesWritten, NULL)) { |
|
|
|
|
|
// file written successfully |
|
|
|
|
|
result = bytesWritten == memorySize; |
|
|
|
|
|
} else { |
|
|
|
|
|
// logging |
|
|
|
|
|
} |
|
|
|
|
|
CloseHandle(fileHandle); |
|
|
|
|
|
} else { |
|
|
|
|
|
// logging |
|
|
|
|
|
} |
|
|
|
|
|
return result; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
internal void resizeDIBSection(Win32OffscreenBuffer *buffer, int width, int height) { |
|
|
internal void resizeDIBSection(Win32OffscreenBuffer *buffer, int width, int height) { |
|
|
if (buffer->memory) { |
|
|
if (buffer->memory) { |
|
|
VirtualFree(buffer->memory, NULL, MEM_RELEASE); |
|
|
VirtualFree(buffer->memory, NULL, MEM_RELEASE); |
|
@@ -82,6 +137,16 @@ internal void win32LoadXInput() { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
internal void win32ProcessKeyboardKeypress(GameButtonState *newState, bool32 isDown) { |
|
|
|
|
|
newState->endedDown = isDown; |
|
|
|
|
|
newState->halfTransitionCount++; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
internal void win32ProcessXInputDigitalButton(DWORD xInputButtonState, GameButtonState *oldState, GameButtonState *newState, DWORD buttonBit) { |
|
|
|
|
|
newState->endedDown = (xInputButtonState & buttonBit) == buttonBit; |
|
|
|
|
|
newState->halfTransitionCount = (oldState->endedDown != newState->endedDown) ? 1 : 0; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
internal void win32InitSound(HWND window, int32 samplesPerSec, int bufferSize) { |
|
|
internal void win32InitSound(HWND window, int32 samplesPerSec, int bufferSize) { |
|
|
HMODULE dSoundLibrary = LoadLibraryA("dsound.dll"); |
|
|
HMODULE dSoundLibrary = LoadLibraryA("dsound.dll"); |
|
|
if (dSoundLibrary) { |
|
|
if (dSoundLibrary) { |
|
@@ -145,7 +210,7 @@ LRESULT mainWindowCallback( |
|
|
} break; |
|
|
} break; |
|
|
|
|
|
|
|
|
case WM_CLOSE: { |
|
|
case WM_CLOSE: { |
|
|
running = false; |
|
|
|
|
|
|
|
|
globalRunning = false; |
|
|
} break; |
|
|
} break; |
|
|
|
|
|
|
|
|
case WM_PAINT: { |
|
|
case WM_PAINT: { |
|
@@ -164,7 +229,7 @@ LRESULT mainWindowCallback( |
|
|
|
|
|
|
|
|
case WM_HOTKEY: { |
|
|
case WM_HOTKEY: { |
|
|
if (wParam == HH_CTRLW) { |
|
|
if (wParam == HH_CTRLW) { |
|
|
running = false; |
|
|
|
|
|
|
|
|
globalRunning = false; |
|
|
} |
|
|
} |
|
|
} break; |
|
|
} break; |
|
|
|
|
|
|
|
@@ -172,29 +237,7 @@ LRESULT mainWindowCallback( |
|
|
case WM_SYSKEYUP: |
|
|
case WM_SYSKEYUP: |
|
|
case WM_KEYUP: |
|
|
case WM_KEYUP: |
|
|
case WM_KEYDOWN: { |
|
|
case WM_KEYDOWN: { |
|
|
uint32 VKCode = wParam; |
|
|
|
|
|
bool wasDown = (lParam & (1 << 30)) != 0; |
|
|
|
|
|
bool isDown = (lParam & (1 << 31)) == 0; |
|
|
|
|
|
if (wasDown != isDown) { |
|
|
|
|
|
if (VKCode == 'W') { |
|
|
|
|
|
} else if (VKCode == 'A') { |
|
|
|
|
|
} else if (VKCode == 'S') { |
|
|
|
|
|
} else if (VKCode == 'D') { |
|
|
|
|
|
} else if (VKCode == 'Q') { |
|
|
|
|
|
} else if (VKCode == 'E') { |
|
|
|
|
|
} else if (VKCode == VK_ESCAPE) { |
|
|
|
|
|
} else if (VKCode == VK_UP) { |
|
|
|
|
|
} else if (VKCode == VK_LEFT) { |
|
|
|
|
|
} else if (VKCode == VK_DOWN) { |
|
|
|
|
|
} else if (VKCode == VK_RIGHT) { |
|
|
|
|
|
} else if (VKCode == VK_SPACE) { |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool32 altKeyWasDown = lParam & (1 << 29); |
|
|
|
|
|
if (altKeyWasDown && VKCode == VK_F4) { |
|
|
|
|
|
running = false; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
Assert(!"Keyboard input came in through a non-dispatch message."); |
|
|
} break; |
|
|
} break; |
|
|
|
|
|
|
|
|
default: { |
|
|
default: { |
|
@@ -253,6 +296,61 @@ internal void win32FillSoundBuffer(Win32SoundOutput *soundOutput, DWORD byteToLo |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
internal void win32ProcessPendingMessages(GameControllerInput *keyboardController) { |
|
|
|
|
|
MSG message; |
|
|
|
|
|
while (PeekMessageA(&message, NULL, NULL, NULL, PM_REMOVE)) { |
|
|
|
|
|
if (message.message == WM_QUIT) { |
|
|
|
|
|
globalRunning = false; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
switch (message.message) { |
|
|
|
|
|
case WM_SYSKEYDOWN: |
|
|
|
|
|
case WM_SYSKEYUP: |
|
|
|
|
|
case WM_KEYUP: |
|
|
|
|
|
case WM_KEYDOWN: { |
|
|
|
|
|
uint32 VKCode = (uint32)message.wParam; |
|
|
|
|
|
bool wasDown = (message.lParam & (1 << 30)) != 0; |
|
|
|
|
|
bool isDown = (message.lParam & (1 << 31)) == 0; |
|
|
|
|
|
if (wasDown != isDown) { |
|
|
|
|
|
if (VKCode == 'W') { |
|
|
|
|
|
win32ProcessKeyboardKeypress(&keyboardController->stickUp, isDown); |
|
|
|
|
|
} else if (VKCode == 'A') { |
|
|
|
|
|
win32ProcessKeyboardKeypress(&keyboardController->stickLeft, isDown); |
|
|
|
|
|
} else if (VKCode == 'S') { |
|
|
|
|
|
win32ProcessKeyboardKeypress(&keyboardController->stickDown, isDown); |
|
|
|
|
|
} else if (VKCode == 'D') { |
|
|
|
|
|
win32ProcessKeyboardKeypress(&keyboardController->stickRight, isDown); |
|
|
|
|
|
} else if (VKCode == 'Q') { |
|
|
|
|
|
win32ProcessKeyboardKeypress(&keyboardController->leftShoulder, isDown); |
|
|
|
|
|
} else if (VKCode == 'E') { |
|
|
|
|
|
win32ProcessKeyboardKeypress(&keyboardController->rightShoulder, isDown); |
|
|
|
|
|
} else if (VKCode == VK_ESCAPE) { |
|
|
|
|
|
} else if (VKCode == VK_UP) { |
|
|
|
|
|
win32ProcessKeyboardKeypress(&keyboardController->btnUp, isDown); |
|
|
|
|
|
} else if (VKCode == VK_LEFT) { |
|
|
|
|
|
win32ProcessKeyboardKeypress(&keyboardController->btnLeft, isDown); |
|
|
|
|
|
} else if (VKCode == VK_DOWN) { |
|
|
|
|
|
win32ProcessKeyboardKeypress(&keyboardController->btnDown, isDown); |
|
|
|
|
|
} else if (VKCode == VK_RIGHT) { |
|
|
|
|
|
win32ProcessKeyboardKeypress(&keyboardController->btnRight, isDown); |
|
|
|
|
|
} else if (VKCode == VK_SPACE) { |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool32 altKeyWasDown = message.lParam & (1 << 29); |
|
|
|
|
|
if (altKeyWasDown && VKCode == VK_F4) { |
|
|
|
|
|
globalRunning = false; |
|
|
|
|
|
} |
|
|
|
|
|
} break; |
|
|
|
|
|
|
|
|
|
|
|
default: { |
|
|
|
|
|
TranslateMessage(&message); |
|
|
|
|
|
DispatchMessage(&message); |
|
|
|
|
|
} break; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prevInstance, PSTR commandLine, int commandShow) { |
|
|
int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prevInstance, PSTR commandLine, int commandShow) { |
|
|
LARGE_INTEGER performanceFrequencyResult; |
|
|
LARGE_INTEGER performanceFrequencyResult; |
|
|
QueryPerformanceFrequency(&performanceFrequencyResult); |
|
|
QueryPerformanceFrequency(&performanceFrequencyResult); |
|
@@ -285,26 +383,36 @@ int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prevInstance, PSTR commandLin |
|
|
HH_CTRLW = GlobalAddAtomA("HH_CTRLW"); |
|
|
HH_CTRLW = GlobalAddAtomA("HH_CTRLW"); |
|
|
RegisterHotKey(window, HH_CTRLW, MOD_CONTROL, 'W'); |
|
|
RegisterHotKey(window, HH_CTRLW, MOD_CONTROL, 'W'); |
|
|
|
|
|
|
|
|
MSG message; |
|
|
|
|
|
running = true; |
|
|
|
|
|
|
|
|
globalRunning = true; |
|
|
|
|
|
GameInput input[2] = {}; |
|
|
|
|
|
GameInput *oldInput = &input[0]; |
|
|
|
|
|
GameInput *newInput = &input[1]; |
|
|
|
|
|
|
|
|
win32LoadXInput(); |
|
|
win32LoadXInput(); |
|
|
|
|
|
|
|
|
// graphics test |
|
|
|
|
|
int xOffset = 0; |
|
|
|
|
|
int yOffset = 0; |
|
|
|
|
|
|
|
|
|
|
|
// sound test |
|
|
// sound test |
|
|
Win32SoundOutput soundOutput = {}; |
|
|
Win32SoundOutput soundOutput = {}; |
|
|
soundOutput.samplesPerSecond = 48000; |
|
|
soundOutput.samplesPerSecond = 48000; |
|
|
soundOutput.wavePeriod = soundOutput.samplesPerSecond / soundOutput.toneHz; |
|
|
|
|
|
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.latencySampleCount = soundOutput.samplesPerSecond / 15.0f; |
|
|
|
|
|
|
|
|
soundOutput.latencySampleCount = (int)(soundOutput.samplesPerSecond / 15.0f); |
|
|
|
|
|
|
|
|
int16 *samples = (int16*)VirtualAlloc(NULL, soundOutput.secondaryBufferSize, MEM_COMMIT, PAGE_READWRITE); |
|
|
int16 *samples = (int16*)VirtualAlloc(NULL, soundOutput.secondaryBufferSize, MEM_COMMIT, PAGE_READWRITE); |
|
|
|
|
|
|
|
|
|
|
|
#if HANDMADE_INTERNAL |
|
|
|
|
|
LPVOID baseAddress = (LPVOID)Terabytes((uint64)2); |
|
|
|
|
|
#else |
|
|
|
|
|
LPVOID baseAddress = 0; |
|
|
|
|
|
#endif |
|
|
|
|
|
GameMemory gameMemory = {}; |
|
|
|
|
|
gameMemory.permanentStorageSize = Megabytes(64); |
|
|
|
|
|
gameMemory.transientStorageSize = Gigabytes((uint64)4); |
|
|
|
|
|
|
|
|
|
|
|
uint64 totalSize = gameMemory.permanentStorageSize + gameMemory.transientStorageSize; |
|
|
|
|
|
gameMemory.permanentStorage = VirtualAlloc(baseAddress, totalSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); |
|
|
|
|
|
gameMemory.transientStorage = ((uint8 *)gameMemory.permanentStorage + gameMemory.permanentStorageSize); |
|
|
|
|
|
|
|
|
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); |
|
@@ -312,70 +420,90 @@ int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prevInstance, PSTR commandLin |
|
|
LARGE_INTEGER lastCounter; |
|
|
LARGE_INTEGER lastCounter; |
|
|
QueryPerformanceCounter(&lastCounter); |
|
|
QueryPerformanceCounter(&lastCounter); |
|
|
int64 lastCycleCount = __rdtsc(); |
|
|
int64 lastCycleCount = __rdtsc(); |
|
|
while (running) { |
|
|
|
|
|
while (PeekMessageA(&message, NULL, NULL, NULL, PM_REMOVE)) { |
|
|
|
|
|
if (message.message == WM_QUIT) { |
|
|
|
|
|
running = false; |
|
|
|
|
|
} |
|
|
|
|
|
TranslateMessage(&message); |
|
|
|
|
|
DispatchMessage(&message); |
|
|
|
|
|
|
|
|
while (globalRunning) { |
|
|
|
|
|
GameControllerInput *oldKeyboardController = &oldInput->controllers[0]; |
|
|
|
|
|
GameControllerInput *newKeyboardController = &newInput->controllers[0]; |
|
|
|
|
|
GameControllerInput zeroController = {}; |
|
|
|
|
|
*newKeyboardController = zeroController; |
|
|
|
|
|
for (int buttonIndex = 0; buttonIndex < ArrayCount(oldKeyboardController->buttons); buttonIndex++) { |
|
|
|
|
|
newKeyboardController->buttons[buttonIndex].endedDown = oldKeyboardController->buttons[buttonIndex].endedDown; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
win32ProcessPendingMessages(newKeyboardController); |
|
|
|
|
|
|
|
|
XINPUT_STATE controllerState; |
|
|
XINPUT_STATE controllerState; |
|
|
|
|
|
int maxControllerCount = 1 + XUSER_MAX_COUNT; |
|
|
|
|
|
if (maxControllerCount > ArrayCount(newInput->controllers)) { |
|
|
|
|
|
maxControllerCount = ArrayCount(newInput->controllers); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
for (DWORD controllerIndex = 0; controllerIndex < XUSER_MAX_COUNT; controllerIndex++) { |
|
|
for (DWORD controllerIndex = 0; controllerIndex < XUSER_MAX_COUNT; controllerIndex++) { |
|
|
if (XInputGetState(controllerIndex, &controllerState) == ERROR_SUCCESS) { |
|
|
if (XInputGetState(controllerIndex, &controllerState) == ERROR_SUCCESS) { |
|
|
break; |
|
|
|
|
|
|
|
|
DWORD ourControllerIndex = controllerIndex + 1; |
|
|
|
|
|
GameControllerInput *oldController = &oldInput->controllers[ourControllerIndex]; |
|
|
|
|
|
GameControllerInput *newController = &newInput->controllers[ourControllerIndex]; |
|
|
|
|
|
|
|
|
|
|
|
newController->isAnalog = true; |
|
|
|
|
|
|
|
|
|
|
|
XINPUT_GAMEPAD *pad = &controllerState.Gamepad; |
|
|
|
|
|
|
|
|
|
|
|
int16 stickX = pad->sThumbLX; |
|
|
|
|
|
int16 stickY = pad->sThumbLY; |
|
|
|
|
|
real32 stickYNorm = 0; |
|
|
|
|
|
real32 stickXNorm = 0; |
|
|
|
|
|
if (stickY != 0 && abs(stickY) > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) { |
|
|
|
|
|
stickYNorm = stickY / 32767.0f; |
|
|
|
|
|
} |
|
|
|
|
|
if (stickX != 0 && abs(stickX) > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) { |
|
|
|
|
|
stickXNorm = stickX / 32767.0f; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
newController->stickAvgX = stickXNorm; |
|
|
|
|
|
newController->stickAvgY = stickYNorm; |
|
|
|
|
|
if (pad->wButtons & XINPUT_GAMEPAD_DPAD_UP) { |
|
|
|
|
|
newController->stickAvgY = 1.0f; |
|
|
|
|
|
} |
|
|
|
|
|
if (pad->wButtons & XINPUT_GAMEPAD_DPAD_DOWN) { |
|
|
|
|
|
newController->stickAvgY = -1.0f; |
|
|
|
|
|
} |
|
|
|
|
|
if (pad->wButtons & XINPUT_GAMEPAD_DPAD_LEFT) { |
|
|
|
|
|
newController->stickAvgX = -1.0f; |
|
|
|
|
|
} |
|
|
|
|
|
if (pad->wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) { |
|
|
|
|
|
newController->stickAvgX = 1.0f; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//bool start = (pad->wButtons & XINPUT_GAMEPAD_START); |
|
|
|
|
|
//bool back = (pad->wButtons & XINPUT_GAMEPAD_BACK); |
|
|
|
|
|
|
|
|
|
|
|
win32ProcessXInputDigitalButton(pad->wButtons, &oldController->btnDown, &newController->btnDown, XINPUT_GAMEPAD_A); |
|
|
|
|
|
win32ProcessXInputDigitalButton(pad->wButtons, &oldController->btnRight, &newController->btnRight, XINPUT_GAMEPAD_B); |
|
|
|
|
|
win32ProcessXInputDigitalButton(pad->wButtons, &oldController->btnLeft, &newController->btnLeft, XINPUT_GAMEPAD_X); |
|
|
|
|
|
win32ProcessXInputDigitalButton(pad->wButtons, &oldController->btnUp, &newController->btnUp, XINPUT_GAMEPAD_Y); |
|
|
|
|
|
win32ProcessXInputDigitalButton(pad->wButtons, &oldController->leftShoulder, &newController->leftShoulder, XINPUT_GAMEPAD_LEFT_SHOULDER); |
|
|
|
|
|
win32ProcessXInputDigitalButton(pad->wButtons, &oldController->rightShoulder, &newController->rightShoulder, XINPUT_GAMEPAD_RIGHT_SHOULDER); |
|
|
|
|
|
|
|
|
|
|
|
real32 threshold = 0.5f; |
|
|
|
|
|
win32ProcessXInputDigitalButton((DWORD)(newController->stickAvgY < -threshold), &oldController->stickDown, &newController->stickDown, 1); |
|
|
|
|
|
win32ProcessXInputDigitalButton((DWORD)(newController->stickAvgX > threshold), &oldController->stickRight, &newController->stickRight, 1); |
|
|
|
|
|
win32ProcessXInputDigitalButton((DWORD)(newController->stickAvgX < -threshold), &oldController->stickLeft, &newController->stickLeft, 1); |
|
|
|
|
|
win32ProcessXInputDigitalButton((DWORD)(newController->stickAvgY > threshold), &oldController->stickUp, &newController->stickUp, 1); |
|
|
} else { |
|
|
} else { |
|
|
// controller not available |
|
|
// controller not available |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
XINPUT_GAMEPAD *Pad = &controllerState.Gamepad; |
|
|
|
|
|
bool up = (Pad->wButtons & XINPUT_GAMEPAD_DPAD_UP); |
|
|
|
|
|
bool down = (Pad->wButtons & XINPUT_GAMEPAD_DPAD_DOWN); |
|
|
|
|
|
bool left = (Pad->wButtons & XINPUT_GAMEPAD_DPAD_LEFT); |
|
|
|
|
|
bool right = (Pad->wButtons & XINPUT_GAMEPAD_DPAD_RIGHT); |
|
|
|
|
|
bool start = (Pad->wButtons & XINPUT_GAMEPAD_START); |
|
|
|
|
|
bool back = (Pad->wButtons & XINPUT_GAMEPAD_BACK); |
|
|
|
|
|
bool leftShoulder = (Pad->wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER); |
|
|
|
|
|
bool rightShoulder = (Pad->wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER); |
|
|
|
|
|
bool aButton = (Pad->wButtons & XINPUT_GAMEPAD_A); |
|
|
|
|
|
bool bButton = (Pad->wButtons & XINPUT_GAMEPAD_B); |
|
|
|
|
|
bool xButton = (Pad->wButtons & XINPUT_GAMEPAD_X); |
|
|
|
|
|
bool yButton = (Pad->wButtons & XINPUT_GAMEPAD_Y); |
|
|
|
|
|
int16 stickX = Pad->sThumbLX; |
|
|
|
|
|
int16 stickY = Pad->sThumbLY; |
|
|
|
|
|
|
|
|
|
|
|
float stickYNorm = 0; |
|
|
|
|
|
float stickXNorm = 0; |
|
|
|
|
|
if (stickY != 0 && abs(stickY) > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) { |
|
|
|
|
|
stickYNorm = stickY / 32767.0; |
|
|
|
|
|
} |
|
|
|
|
|
if (stickX != 0 && abs(stickX) > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) { |
|
|
|
|
|
stickXNorm = stickX / 32767.0; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
float factor = leftShoulder ? 2.5 : 1.0; |
|
|
|
|
|
yOffset += stickY/5000.0 * factor; |
|
|
|
|
|
xOffset -= stickX/5000.0 * factor; |
|
|
|
|
|
|
|
|
|
|
|
soundOutput.toneHz = 220 + (stickYNorm + 1.0)/2.0 * 220.0; |
|
|
|
|
|
soundOutput.wavePeriod = soundOutput.samplesPerSecond / soundOutput.toneHz; |
|
|
|
|
|
|
|
|
|
|
|
GameOffscreenBuffer videoBuffer = {}; |
|
|
GameOffscreenBuffer videoBuffer = {}; |
|
|
videoBuffer.memory = globalBackBuffer.memory; |
|
|
videoBuffer.memory = globalBackBuffer.memory; |
|
|
videoBuffer.width = globalBackBuffer.width; |
|
|
videoBuffer.width = globalBackBuffer.width; |
|
|
videoBuffer.height = globalBackBuffer.height; |
|
|
videoBuffer.height = globalBackBuffer.height; |
|
|
|
|
|
|
|
|
GameInput input = {}; |
|
|
|
|
|
input.xOffset = xOffset; |
|
|
|
|
|
input.yOffset = yOffset; |
|
|
|
|
|
|
|
|
|
|
|
// Sound test |
|
|
// Sound test |
|
|
DWORD playCursor; |
|
|
|
|
|
DWORD writeCursor; |
|
|
|
|
|
DWORD byteToLock; |
|
|
|
|
|
DWORD targetCursor; |
|
|
|
|
|
DWORD bytesToWrite; |
|
|
|
|
|
|
|
|
DWORD playCursor = 0; |
|
|
|
|
|
DWORD writeCursor = 0; |
|
|
|
|
|
DWORD byteToLock = 0; |
|
|
|
|
|
DWORD targetCursor = 0; |
|
|
|
|
|
DWORD bytesToWrite = 0; |
|
|
bool soundIsValid = true; |
|
|
bool soundIsValid = true; |
|
|
if (SUCCEEDED(globalSecondaryBuffer->GetCurrentPosition(&playCursor, &writeCursor))) { |
|
|
if (SUCCEEDED(globalSecondaryBuffer->GetCurrentPosition(&playCursor, &writeCursor))) { |
|
|
byteToLock = (soundOutput.runningSampleIndex*soundOutput.bytesPerSample) % soundOutput.secondaryBufferSize; |
|
|
byteToLock = (soundOutput.runningSampleIndex*soundOutput.bytesPerSample) % soundOutput.secondaryBufferSize; |
|
@@ -395,7 +523,7 @@ int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prevInstance, PSTR commandLin |
|
|
soundBuffer.sampleCount = bytesToWrite / soundOutput.bytesPerSample; |
|
|
soundBuffer.sampleCount = bytesToWrite / soundOutput.bytesPerSample; |
|
|
soundBuffer.samples = samples; |
|
|
soundBuffer.samples = samples; |
|
|
|
|
|
|
|
|
gameUpdateAndRender(&videoBuffer, &input, &soundBuffer); |
|
|
|
|
|
|
|
|
gameUpdateAndRender(&gameMemory, &videoBuffer, newInput, &soundBuffer); |
|
|
|
|
|
|
|
|
if (soundIsValid) { |
|
|
if (soundIsValid) { |
|
|
win32FillSoundBuffer(&soundOutput, byteToLock, bytesToWrite, &soundBuffer); |
|
|
win32FillSoundBuffer(&soundOutput, byteToLock, bytesToWrite, &soundBuffer); |
|
@@ -405,14 +533,18 @@ int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prevInstance, PSTR commandLin |
|
|
LARGE_INTEGER endCounter; |
|
|
LARGE_INTEGER endCounter; |
|
|
QueryPerformanceCounter(&endCounter); |
|
|
QueryPerformanceCounter(&endCounter); |
|
|
int64 endCycleCount = __rdtsc(); |
|
|
int64 endCycleCount = __rdtsc(); |
|
|
int32 cyclesElapsed = endCycleCount - lastCycleCount; |
|
|
|
|
|
|
|
|
int64 cyclesElapsed = endCycleCount - lastCycleCount; |
|
|
lastCycleCount = endCycleCount; |
|
|
lastCycleCount = endCycleCount; |
|
|
|
|
|
|
|
|
int64 counterElapsed = endCounter.QuadPart - lastCounter.QuadPart; |
|
|
int64 counterElapsed = endCounter.QuadPart - lastCounter.QuadPart; |
|
|
real32 msElapsed = (real32)(1000.0f*counterElapsed) / performanceFrequency; |
|
|
real32 msElapsed = (real32)(1000.0f*counterElapsed) / performanceFrequency; |
|
|
real32 fps = (real32)(1000.0f*performanceFrequency/(real32)counterElapsed)/1000.0f; |
|
|
real32 fps = (real32)(1000.0f*performanceFrequency/(real32)counterElapsed)/1000.0f; |
|
|
debug_printf(L"%f ms, %f fps, %f Mcl, %fGHz\n", msElapsed, fps, cyclesElapsed / 1000000.0f, (cyclesElapsed/(msElapsed*1000))/1000000.0f); |
|
|
|
|
|
|
|
|
|
|
|
lastCounter = endCounter; |
|
|
lastCounter = endCounter; |
|
|
|
|
|
|
|
|
|
|
|
GameInput *temp = newInput; |
|
|
|
|
|
newInput = oldInput; |
|
|
|
|
|
oldInput = temp; |
|
|
} |
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
// failed |
|
|
// failed |
|
|