config: added Allow Background Input option

This commit is contained in:
Hyper 2024-11-19 03:08:08 +00:00
parent 5c954c5427
commit 8c67886539
5 changed files with 53 additions and 46 deletions

View file

@ -21,6 +21,7 @@ public:
CONFIG_DEFINE_LOCALISED("Controls", bool, CameraYInvert, false);
CONFIG_DEFINE_LOCALISED("Controls", bool, XButtonHoming, true);
CONFIG_DEFINE_LOCALISED("Controls", bool, UnleashCancel, false);
CONFIG_DEFINE_LOCALISED("Controls", bool, BackgroundInput, false);
CONFIG_DEFINE_LOCALISED("Audio", float, MusicVolume, 1.0f);
CONFIG_DEFINE_LOCALISED("Audio", float, SEVolume, 1.0f);

View file

@ -137,6 +137,16 @@ CONFIG_DEFINE_DESCRIPTION_LOCALE(LogoSkip)
{ ELanguage::English, "Show the logos during the game's boot sequence." }
};
CONFIG_DEFINE_LOCALE(BackgroundInput)
{
{ ELanguage::English, "Allow Background Input" }
};
CONFIG_DEFINE_DESCRIPTION_LOCALE(BackgroundInput)
{
{ ELanguage::English, "Set whether to accept controller input whilst the game window is unfocused." }
};
CONFIG_DEFINE_LOCALE(CameraXInvert)
{
{ ELanguage::English, "Invert Camera X" }

View file

@ -1,6 +1,10 @@
#include <stdafx.h>
#include <SDL.h>
#include <cfg/config.h>
#include <hid/hid_detail.h>
#include <ui/window.h>
#define TRANSLATE_INPUT(S, X) SDL_GameControllerGetButton(controller, S) << FirstBitLow(X)
#define VIBRATION_TIMEOUT_MS 5000
class Controller
@ -13,17 +17,12 @@ public:
XAMINPUT_VIBRATION vibration{ 0, 0 };
Controller() = default;
explicit Controller(int index) : Controller(SDL_GameControllerOpen(index))
{
}
explicit Controller(int index) : Controller(SDL_GameControllerOpen(index)) {}
Controller(SDL_GameController* controller) : controller(controller)
{
if (!controller)
{
return;
}
joystick = SDL_GameControllerGetJoystick(controller);
id = SDL_JoystickInstanceID(joystick);
@ -31,20 +30,28 @@ public:
void Close()
{
if (controller == nullptr)
{
if (!controller)
return;
}
SDL_GameControllerClose(controller);
controller = nullptr;
joystick = nullptr;
id = -1;
}
bool CanPoll()
{
return controller && (Window::s_isFocused || Config::BackgroundInput);
}
void PollAxis()
{
if (!CanPoll())
return;
auto& pad = state;
pad.sThumbLX = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_LEFTX);
pad.sThumbLY = ~SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_LEFTY);
@ -55,14 +62,13 @@ public:
pad.bRightTrigger = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_TRIGGERRIGHT) >> 7;
}
#define TRANSLATE_INPUT(S, X) SDL_GameControllerGetButton(controller, S) << FirstBitLow(X)
void Poll()
{
if (controller == nullptr)
{
if (!CanPoll())
return;
}
auto& pad = state;
pad.wButtons = 0;
pad.wButtons |= TRANSLATE_INPUT(SDL_CONTROLLER_BUTTON_DPAD_UP, XAMINPUT_GAMEPAD_DPAD_UP);
@ -87,12 +93,11 @@ public:
void SetVibration(const XAMINPUT_VIBRATION& vibration)
{
if (controller == nullptr)
{
if (!CanPoll())
return;
}
this->vibration = vibration;
SDL_GameControllerRumble(controller, vibration.wLeftMotorSpeed * 256, vibration.wRightMotorSpeed * 256, VIBRATION_TIMEOUT_MS);
}
};
@ -102,9 +107,7 @@ std::array<Controller, 4> g_controllers;
inline Controller* EnsureController(DWORD dwUserIndex)
{
if (!g_controllers[dwUserIndex].controller)
{
return nullptr;
}
return &g_controllers[dwUserIndex];
}
@ -114,9 +117,7 @@ inline size_t FindFreeController()
for (size_t i = 0; i < g_controllers.size(); i++)
{
if (!g_controllers[i].controller)
{
return i;
}
}
return -1;
@ -127,9 +128,7 @@ inline Controller* FindController(int which)
for (auto& controller : g_controllers)
{
if (controller.id == which)
{
return &controller;
}
}
return nullptr;
@ -142,22 +141,21 @@ int HID_OnSDLEvent(void*, SDL_Event* event)
if (event->type == SDL_CONTROLLERDEVICEADDED)
{
const auto freeIndex = FindFreeController();
if (freeIndex != -1)
{
g_controllers[freeIndex] = Controller(event->cdevice.which);
}
}
if (event->type == SDL_CONTROLLERDEVICEREMOVED)
{
auto* controller = FindController(event->cdevice.which);
if (controller)
{
controller->Close();
}
}
else if (event->type == SDL_CONTROLLERBUTTONDOWN || event->type == SDL_CONTROLLERBUTTONUP || event->type == SDL_CONTROLLERAXISMOTION)
{
auto* controller = FindController(event->cdevice.which);
if (controller)
{
if (event->type == SDL_CONTROLLERAXISMOTION)
@ -181,6 +179,7 @@ void hid::detail::Init()
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS4, "1");
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS5, "1");
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_WII, "1");
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
SDL_SetHint(SDL_HINT_XINPUT_ENABLED, "1");
SDL_InitSubSystem(SDL_INIT_EVENTS);
@ -193,62 +192,58 @@ void hid::detail::Init()
uint32_t hid::detail::GetState(uint32_t dwUserIndex, XAMINPUT_STATE* pState)
{
static DWORD packet;
if (!pState)
{
return ERROR_BAD_ARGUMENTS;
}
memset(pState, 0, sizeof(*pState));
pState->dwPacketNumber = packet++;
SDL_JoystickUpdate();
auto* controller = EnsureController(dwUserIndex);
if (controller == nullptr)
{
if (!EnsureController(dwUserIndex))
return ERROR_DEVICE_NOT_CONNECTED;
}
pState->Gamepad = g_controllers[dwUserIndex].state;
return ERROR_SUCCESS;
}
uint32_t hid::detail::SetState(uint32_t dwUserIndex, XAMINPUT_VIBRATION* pVibration)
{
if (!pVibration)
{
return ERROR_BAD_ARGUMENTS;
}
SDL_JoystickUpdate();
auto* controller = EnsureController(dwUserIndex);
if (controller == nullptr)
{
if (!controller)
return ERROR_DEVICE_NOT_CONNECTED;
}
controller->SetVibration(*pVibration);
return ERROR_SUCCESS;
}
uint32_t hid::detail::GetCapabilities(uint32_t dwUserIndex, XAMINPUT_CAPABILITIES* pCaps)
{
if (!pCaps)
{
return ERROR_BAD_ARGUMENTS;
}
SDL_JoystickUpdate();
auto* controller = EnsureController(dwUserIndex);
if (controller == nullptr)
{
if (!controller)
return ERROR_DEVICE_NOT_CONNECTED;
}
memset(pCaps, 0, sizeof(*pCaps));
pCaps->Type = XAMINPUT_DEVTYPE_GAMEPAD;
pCaps->SubType = XAMINPUT_DEVSUBTYPE_GAMEPAD; // TODO: other types?
pCaps->Flags = 0;
pCaps->Gamepad = controller->state;
pCaps->Vibration = controller->vibration;

View file

@ -333,9 +333,6 @@ SWA_API uint32_t XamInputGetState(uint32_t userIndex, uint32_t flags, XAMINPUT_S
{
//printf("!!! STUB !!! XamInputGetState\n");
if (!Window::s_isFocused)
return 0;
uint32_t result = hid::GetState(userIndex, state);
if (result == ERROR_SUCCESS)
@ -349,6 +346,9 @@ SWA_API uint32_t XamInputGetState(uint32_t userIndex, uint32_t flags, XAMINPUT_S
}
else if (userIndex == 0)
{
if (!Window::s_isFocused)
return ERROR_SUCCESS;
memset(state, 0, sizeof(*state));
if (GetAsyncKeyState('W') & 0x8000)
state->Gamepad.wButtons |= XAMINPUT_GAMEPAD_Y;

View file

@ -663,6 +663,7 @@ static void DrawConfigOptions()
DrawConfigOption(rowCount++, yOffset, &Config::CameraYInvert);
DrawConfigOption(rowCount++, yOffset, &Config::XButtonHoming);
DrawConfigOption(rowCount++, yOffset, &Config::UnleashCancel);
DrawConfigOption(rowCount++, yOffset, &Config::BackgroundInput);
break;
case 2: // AUDIO
DrawConfigOption(rowCount++, yOffset, &Config::MusicVolume);