static uint64_t GenRandom64() { uint64_t buf; BCryptGenRandom(nullptr, (uint8_t*)&buf, sizeof(buf), BCRYPT_USE_SYSTEM_PREFERRED_RNG); return buf; } static uint32_t GetNumberOfCores() { return S->SysInfo.dwNumberOfProcessors; } auto CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -> LRESULT; auto win32_WinGetHandle() -> HWND { ASSERT(g_HWnd); return g_HWnd; } auto win32_GetHInstance() -> HINSTANCE { return g_HInstance; } void win32_SetHInstance(HINSTANCE hInstance) { g_HInstance = hInstance; } // auto UpdateGamepad(uint32_t index) -> bool { auto& state = Gamepads[index]; MemZero(&state.Gamepad); const DWORD dwResult = XInputGetState(0, &state); return (dwResult == ERROR_SUCCESS); } namespace { void GetGamepadStick(auto rawX, auto rawY, auto rawDeadzone, float* outX, float* outY) { const float x = (float)rawX / (float)limits::Max(); const float y = (float)rawY / (float)limits::Max(); const float magnitude = Sqrt(x * x + y * y); const float deadzone = (float)rawDeadzone / (float)limits::Max(); if (magnitude < deadzone) { *outX = 0.f; *outY = 0.f; } else { // Renormalize so movement starts smoothly from the edge of the deadzone const float scale = (magnitude - deadzone) / (1.0f - deadzone); *outX = (x / magnitude) * scale; *outY = (y / magnitude) * scale; } } auto GetGamepadTrigger(uint8_t rawValue, uint8_t rawDeadzone) -> float { const float val = (float)rawValue / (float)limits::Max(); const float deadzone = (float)rawDeadzone / (float)limits::Max(); if (val < deadzone) { return 0.0f; } // Renormalize so movement starts smoothly from the edge of the deadzone return (val - deadzone) / (1.0f - deadzone); } } // namespace auto API GetGamepadLeftStick(uint32_t index) -> float2 { auto& gamepad = Gamepads[index].Gamepad; float2 ret; GetGamepadStick(gamepad.sThumbLX, gamepad.sThumbLY, XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, &ret.x, &ret.y); return ret; } auto API GetGamepadRightStick(uint32_t index) -> float2 { auto& gamepad = Gamepads[index].Gamepad; float2 ret; GetGamepadStick(gamepad.sThumbRX, gamepad.sThumbRY, XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE, &ret.x, &ret.y); return ret; } auto API GetGamepadLeftTrigger(uint32_t index) -> float { auto& gamepad = Gamepads[index].Gamepad; return GetGamepadTrigger(gamepad.bLeftTrigger, XINPUT_GAMEPAD_TRIGGER_THRESHOLD); } auto API GetGamepadRightTrigger(uint32_t index) -> float { auto& gamepad = Gamepads[index].Gamepad; return GetGamepadTrigger(gamepad.bRightTrigger, XINPUT_GAMEPAD_TRIGGER_THRESHOLD); }