Skip to content

Commit

Permalink
InputManager: Support multiple mice via raw input
Browse files Browse the repository at this point in the history
Only on Windows for now.
  • Loading branch information
stenzek committed Aug 23, 2024
1 parent 8b3fd53 commit 9e3507e
Show file tree
Hide file tree
Showing 37 changed files with 1,495 additions and 1,055 deletions.
4 changes: 2 additions & 2 deletions src/core/analog_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -885,9 +885,9 @@ const Controller::ControllerInfo AnalogController::INFO = {ControllerType::Analo
s_settings,
Controller::VibrationCapabilities::LargeSmallMotors};

void AnalogController::LoadSettings(SettingsInterface& si, const char* section)
void AnalogController::LoadSettings(SettingsInterface& si, const char* section, bool initial)
{
Controller::LoadSettings(si, section);
Controller::LoadSettings(si, section, initial);
m_force_analog_on_reset = si.GetBoolValue(section, "ForceAnalogOnReset", true);
m_analog_dpad_in_digital_mode = si.GetBoolValue(section, "AnalogDPadInDigitalMode", true);
m_analog_deadzone = std::clamp(si.GetFloatValue(section, "AnalogDeadzone", DEFAULT_STICK_DEADZONE), 0.0f, 1.0f);
Expand Down
2 changes: 1 addition & 1 deletion src/core/analog_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class AnalogController final : public Controller
void ResetTransferState() override;
bool Transfer(const u8 data_in, u8* data_out) override;

void LoadSettings(SettingsInterface& si, const char* section) override;
void LoadSettings(SettingsInterface& si, const char* section, bool initial) override;

private:
using MotorState = std::array<u8, NUM_MOTORS>;
Expand Down
4 changes: 2 additions & 2 deletions src/core/analog_joystick.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -413,9 +413,9 @@ const Controller::ControllerInfo AnalogJoystick::INFO = {ControllerType::AnalogJ
s_settings,
Controller::VibrationCapabilities::NoVibration};

void AnalogJoystick::LoadSettings(SettingsInterface& si, const char* section)
void AnalogJoystick::LoadSettings(SettingsInterface& si, const char* section, bool initial)
{
Controller::LoadSettings(si, section);
Controller::LoadSettings(si, section, initial);
m_analog_deadzone = std::clamp(si.GetFloatValue(section, "AnalogDeadzone", DEFAULT_STICK_DEADZONE), 0.0f, 1.0f);
m_analog_sensitivity =
std::clamp(si.GetFloatValue(section, "AnalogSensitivity", DEFAULT_STICK_SENSITIVITY), 0.01f, 3.0f);
Expand Down
2 changes: 1 addition & 1 deletion src/core/analog_joystick.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class AnalogJoystick final : public Controller
void ResetTransferState() override;
bool Transfer(const u8 data_in, u8* data_out) override;

void LoadSettings(SettingsInterface& si, const char* section) override;
void LoadSettings(SettingsInterface& si, const char* section, bool initial) override;

private:
enum class TransferState : u8
Expand Down
2 changes: 1 addition & 1 deletion src/core/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ u32 Controller::GetInputOverlayIconColor() const
return 0xFFFFFFFFu;
}

void Controller::LoadSettings(SettingsInterface& si, const char* section)
void Controller::LoadSettings(SettingsInterface& si, const char* section, bool initial)
{
}

Expand Down
2 changes: 1 addition & 1 deletion src/core/controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ class Controller
virtual u32 GetInputOverlayIconColor() const;

/// Loads/refreshes any per-controller settings.
virtual void LoadSettings(SettingsInterface& si, const char* section);
virtual void LoadSettings(SettingsInterface& si, const char* section, bool initial);

/// Creates a new controller of the specified type.
static std::unique_ptr<Controller> Create(ControllerType type, u32 index);
Expand Down
4 changes: 2 additions & 2 deletions src/core/digital_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,9 @@ const Controller::ControllerInfo DigitalController::INFO = {ControllerType::Digi
s_settings,
Controller::VibrationCapabilities::NoVibration};

void DigitalController::LoadSettings(SettingsInterface& si, const char* section)
void DigitalController::LoadSettings(SettingsInterface& si, const char* section, bool initial)
{
Controller::LoadSettings(si, section);
Controller::LoadSettings(si, section, initial);
m_popn_controller_mode = si.GetBoolValue(section, "ForcePopnControllerMode", false);
}

Expand Down
2 changes: 1 addition & 1 deletion src/core/digital_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class DigitalController final : public Controller
void ResetTransferState() override;
bool Transfer(const u8 data_in, u8* data_out) override;

void LoadSettings(SettingsInterface& si, const char* section) override;
void LoadSettings(SettingsInterface& si, const char* section, bool initial) override;

private:
enum class TransferState : u8
Expand Down
15 changes: 9 additions & 6 deletions src/core/guncon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,8 @@ bool GunCon::Transfer(const u8 data_in, u8* data_out)
void GunCon::UpdatePosition()
{
float display_x, display_y;
const auto& [window_x, window_y] =
(m_has_relative_binds) ? GetAbsolutePositionFromRelativeAxes() : InputManager::GetPointerAbsolutePosition(0);
const auto& [window_x, window_y] = (m_has_relative_binds) ? GetAbsolutePositionFromRelativeAxes() :
InputManager::GetPointerAbsolutePosition(m_cursor_index);
g_gpu->ConvertScreenCoordinatesToDisplayCoordinates(window_x, window_y, &display_x, &display_y);

// are we within the active display area?
Expand Down Expand Up @@ -245,7 +245,7 @@ bool GunCon::CanUseSoftwareCursor() const

u32 GunCon::GetSoftwarePointerIndex() const
{
return m_has_relative_binds ? (InputManager::MAX_POINTER_DEVICES + m_index) : 0;
return m_has_relative_binds ? (InputManager::MAX_POINTER_DEVICES + m_index) : m_cursor_index;
}

void GunCon::UpdateSoftwarePointerPosition()
Expand Down Expand Up @@ -273,6 +273,7 @@ static const Controller::ControllerBindingInfo s_binding_info[] = {
}

// clang-format off
{"Pointer", TRANSLATE_NOOP("GunCon", "Pointer/Aiming"), ICON_PF_MOUSE, static_cast<u32>(GunCon::Binding::ButtonCount), InputBindingInfo::Type::AbsolutePointer, GenericInputBinding::Unknown},
BUTTON("Trigger", TRANSLATE_NOOP("GunCon", "Trigger"), ICON_PF_CROSS, GunCon::Binding::Trigger, GenericInputBinding::R2),
BUTTON("ShootOffscreen", TRANSLATE_NOOP("GunCon", "Shoot Offscreen"), nullptr, GunCon::Binding::ShootOffscreen, GenericInputBinding::L2),
BUTTON("A", TRANSLATE_NOOP("GunCon", "A"), ICON_PF_BUTTON_A, GunCon::Binding::A, GenericInputBinding::Cross),
Expand Down Expand Up @@ -306,9 +307,9 @@ const Controller::ControllerInfo GunCon::INFO = {
ControllerType::GunCon, "GunCon", TRANSLATE_NOOP("ControllerType", "GunCon"), nullptr,
s_binding_info, s_settings, Controller::VibrationCapabilities::NoVibration};

void GunCon::LoadSettings(SettingsInterface& si, const char* section)
void GunCon::LoadSettings(SettingsInterface& si, const char* section, bool initial)
{
Controller::LoadSettings(si, section);
Controller::LoadSettings(si, section, initial);

m_x_scale = si.GetFloatValue(section, "XScale", 1.0f);

Expand All @@ -334,13 +335,15 @@ void GunCon::LoadSettings(SettingsInterface& si, const char* section)

m_has_relative_binds = (si.ContainsValue(section, "RelativeLeft") || si.ContainsValue(section, "RelativeRight") ||
si.ContainsValue(section, "RelativeUp") || si.ContainsValue(section, "RelativeDown"));
m_cursor_index =
static_cast<u8>(InputManager::GetIndexFromPointerBinding(si.GetStringValue(section, "Pointer")).value_or(0));

const s32 new_pointer_index = GetSoftwarePointerIndex();

if (prev_pointer_index != new_pointer_index || m_cursor_path != cursor_path || m_cursor_scale != cursor_scale ||
m_cursor_color != cursor_color)
{
if (prev_pointer_index != new_pointer_index &&
if (!initial && prev_pointer_index != new_pointer_index &&
static_cast<u32>(prev_pointer_index) < InputManager::MAX_SOFTWARE_CURSORS)
{
ImGuiManager::ClearSoftwareCursor(prev_pointer_index);
Expand Down
3 changes: 2 additions & 1 deletion src/core/guncon.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class GunCon final : public Controller
void Reset() override;
bool DoState(StateWrapper& sw, bool apply_input_state) override;

void LoadSettings(SettingsInterface& si, const char* section) override;
void LoadSettings(SettingsInterface& si, const char* section, bool initial) override;

float GetBindState(u32 index) const override;
void SetBindState(u32 index, float value) override;
Expand Down Expand Up @@ -80,6 +80,7 @@ class GunCon final : public Controller
u16 m_position_y = 0;
bool m_shoot_offscreen = false;
bool m_has_relative_binds = false;
u8 m_cursor_index = 0;

TransferState m_transfer_state = TransferState::Idle;
};
14 changes: 12 additions & 2 deletions src/core/host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#include "util/gpu_device.h"
#include "util/imgui_manager.h"
#include "util/input_manager.h"

#include "common/assert.h"
#include "common/error.h"
Expand Down Expand Up @@ -308,6 +309,8 @@ bool Host::CreateGPUDevice(RenderAPI api, Error* error)
return false;
}

InputManager::SetDisplayWindowSize(static_cast<float>(g_gpu_device->GetWindowWidth()),
static_cast<float>(g_gpu_device->GetWindowHeight()));
return true;
}

Expand All @@ -322,7 +325,10 @@ void Host::UpdateDisplayWindow()
return;
}

ImGuiManager::WindowResized();
const float f_width = static_cast<float>(g_gpu_device->GetWindowWidth());
const float f_height = static_cast<float>(g_gpu_device->GetWindowHeight());
ImGuiManager::WindowResized(f_width, f_height);
InputManager::SetDisplayWindowSize(f_width, f_height);

if (System::IsValid())
{
Expand All @@ -343,7 +349,11 @@ void Host::ResizeDisplayWindow(s32 width, s32 height, float scale)
DEV_LOG("Display window resized to {}x{}", width, height);

g_gpu_device->ResizeWindow(width, height, scale);
ImGuiManager::WindowResized();

const float f_width = static_cast<float>(g_gpu_device->GetWindowWidth());
const float f_height = static_cast<float>(g_gpu_device->GetWindowHeight());
ImGuiManager::WindowResized(f_width, f_height);
InputManager::SetDisplayWindowSize(f_width, f_height);

// If we're paused, re-present the current frame at the new window size.
if (System::IsValid())
Expand Down
4 changes: 2 additions & 2 deletions src/core/input_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ struct InputBindingInfo
Axis,
HalfAxis,
Motor,
Pointer, // Receive relative mouse movement events, bind_index is offset by the axis.
Pointer, // Receive relative mouse movement events, bind_index is offset by the axis.
AbsolutePointer, // Allows selection of specific pointers, but defaults to the first.
Macro,
};

Expand Down Expand Up @@ -68,4 +69,3 @@ enum class GenericInputBinding : u8

Count,
};

15 changes: 9 additions & 6 deletions src/core/justifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,8 @@ void Justifier::UpdatePosition()
}

float display_x, display_y;
const auto [window_x, window_y] =
(m_has_relative_binds) ? GetAbsolutePositionFromRelativeAxes() : InputManager::GetPointerAbsolutePosition(0);
const auto [window_x, window_y] = (m_has_relative_binds) ? GetAbsolutePositionFromRelativeAxes() :
InputManager::GetPointerAbsolutePosition(m_cursor_index);
g_gpu->ConvertScreenCoordinatesToDisplayCoordinates(window_x, window_y, &display_x, &display_y);

// are we within the active display area?
Expand Down Expand Up @@ -308,7 +308,7 @@ bool Justifier::CanUseSoftwareCursor() const

u32 Justifier::GetSoftwarePointerIndex() const
{
return m_has_relative_binds ? (InputManager::MAX_POINTER_DEVICES + m_index) : 0;
return m_has_relative_binds ? (InputManager::MAX_POINTER_DEVICES + m_index) : m_cursor_index;
}

void Justifier::UpdateSoftwarePointerPosition()
Expand Down Expand Up @@ -336,6 +336,7 @@ static const Controller::ControllerBindingInfo s_binding_info[] = {
}

// clang-format off
{"Pointer", TRANSLATE_NOOP("Justifier", "Pointer/Aiming"), ICON_PF_MOUSE, static_cast<u32>(Justifier::Binding::ButtonCount), InputBindingInfo::Type::AbsolutePointer, GenericInputBinding::Unknown},
BUTTON("Trigger", TRANSLATE_NOOP("Justifier", "Trigger"), ICON_PF_CROSS, Justifier::Binding::Trigger, GenericInputBinding::R2),
BUTTON("ShootOffscreen", TRANSLATE_NOOP("Justifier", "Shoot Offscreen"), nullptr, Justifier::Binding::ShootOffscreen, GenericInputBinding::L2),
BUTTON("Start", TRANSLATE_NOOP("Justifier", "Start"), ICON_PF_START, Justifier::Binding::Start, GenericInputBinding::Cross),
Expand Down Expand Up @@ -395,9 +396,9 @@ const Controller::ControllerInfo Justifier::INFO = {ControllerType::Justifier,
s_settings,
Controller::VibrationCapabilities::NoVibration};

void Justifier::LoadSettings(SettingsInterface& si, const char* section)
void Justifier::LoadSettings(SettingsInterface& si, const char* section, bool initial)
{
Controller::LoadSettings(si, section);
Controller::LoadSettings(si, section, initial);

m_x_scale = si.GetFloatValue(section, "XScale", 1.0f);

Expand All @@ -423,13 +424,15 @@ void Justifier::LoadSettings(SettingsInterface& si, const char* section)

m_has_relative_binds = (si.ContainsValue(section, "RelativeLeft") || si.ContainsValue(section, "RelativeRight") ||
si.ContainsValue(section, "RelativeUp") || si.ContainsValue(section, "RelativeDown"));
m_cursor_index =
static_cast<u8>(InputManager::GetIndexFromPointerBinding(si.GetStringValue(section, "Pointer")).value_or(0));

const s32 new_pointer_index = GetSoftwarePointerIndex();

if (prev_pointer_index != new_pointer_index || m_cursor_path != cursor_path || m_cursor_scale != cursor_scale ||
m_cursor_color != cursor_color)
{
if (prev_pointer_index != new_pointer_index &&
if (!initial && prev_pointer_index != new_pointer_index &&
static_cast<u32>(prev_pointer_index) < InputManager::MAX_SOFTWARE_CURSORS)
{
ImGuiManager::ClearSoftwareCursor(prev_pointer_index);
Expand Down
3 changes: 2 additions & 1 deletion src/core/justifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class Justifier final : public Controller
void Reset() override;
bool DoState(StateWrapper& sw, bool apply_input_state) override;

void LoadSettings(SettingsInterface& si, const char* section) override;
void LoadSettings(SettingsInterface& si, const char* section, bool initial) override;

float GetBindState(u32 index) const override;
void SetBindState(u32 index, float value) override;
Expand Down Expand Up @@ -100,6 +100,7 @@ class Justifier final : public Controller
TimingEvent m_irq_event;

bool m_has_relative_binds = false;
u8 m_cursor_index = 0;
float m_relative_pos[4] = {};

std::string m_cursor_path;
Expand Down
4 changes: 2 additions & 2 deletions src/core/negcon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -345,9 +345,9 @@ const Controller::ControllerInfo NeGcon::INFO = {
ControllerType::NeGcon, "NeGcon", TRANSLATE_NOOP("ControllerType", "NeGcon"), ICON_PF_GAMEPAD,
s_binding_info, s_settings, Controller::VibrationCapabilities::NoVibration};

void NeGcon::LoadSettings(SettingsInterface& si, const char* section)
void NeGcon::LoadSettings(SettingsInterface& si, const char* section, bool initial)
{
Controller::LoadSettings(si, section);
Controller::LoadSettings(si, section, initial);
m_steering_modifier = {
.deadzone = si.GetFloatValue(section, "SteeringDeadzone", DEFAULT_STEERING_MODIFIER.deadzone),
.saturation = si.GetFloatValue(section, "SteeringSaturation", DEFAULT_STEERING_MODIFIER.saturation),
Expand Down
2 changes: 1 addition & 1 deletion src/core/negcon.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class NeGcon final : public Controller
u32 GetButtonStateBits() const override;
std::optional<u32> GetAnalogInputBytes() const override;

void LoadSettings(SettingsInterface& si, const char* section) override;
void LoadSettings(SettingsInterface& si, const char* section, bool initial) override;

private:
enum class TransferState : u8
Expand Down
4 changes: 2 additions & 2 deletions src/core/negcon_rumble.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -766,9 +766,9 @@ const Controller::ControllerInfo NeGconRumble::INFO = {ControllerType::NeGconRum
s_settings,
Controller::VibrationCapabilities::LargeSmallMotors};

void NeGconRumble::LoadSettings(SettingsInterface& si, const char* section)
void NeGconRumble::LoadSettings(SettingsInterface& si, const char* section, bool initial)
{
Controller::LoadSettings(si, section);
Controller::LoadSettings(si, section, initial);
m_steering_deadzone = si.GetFloatValue(section, "SteeringDeadzone", 0.10f);
m_steering_sensitivity = si.GetFloatValue(section, "SteeringSensitivity", 1.00f);
m_rumble_bias = static_cast<u8>(std::min<u32>(si.GetIntValue(section, "VibrationBias", 8), 255));
Expand Down
2 changes: 1 addition & 1 deletion src/core/negcon_rumble.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class NeGconRumble final : public Controller
u32 GetButtonStateBits() const override;
std::optional<u32> GetAnalogInputBytes() const override;

void LoadSettings(SettingsInterface& si, const char* section) override;
void LoadSettings(SettingsInterface& si, const char* section, bool initial) override;

private:
using MotorState = std::array<u8, NUM_MOTORS>;
Expand Down
6 changes: 3 additions & 3 deletions src/core/playstation_mouse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,9 @@ bool PlayStationMouse::Transfer(const u8 data_in, u8* data_out)
}
}

void PlayStationMouse::LoadSettings(SettingsInterface& si, const char* section)
void PlayStationMouse::LoadSettings(SettingsInterface& si, const char* section, bool initial)
{
Controller::LoadSettings(si, section);
Controller::LoadSettings(si, section, initial);

m_sensitivity_x = si.GetFloatValue(section, "SensitivityX", 1.0f);
m_sensitivity_y = si.GetFloatValue(section, "SensitivityY", 1.0f);
Expand Down Expand Up @@ -219,7 +219,7 @@ static const SettingInfo s_settings[] = {

const Controller::ControllerInfo PlayStationMouse::INFO = {ControllerType::PlayStationMouse,
"PlayStationMouse",
TRANSLATE_NOOP("ControllerType", "PlayStation Mouse"),
TRANSLATE_NOOP("ControllerType", "Mouse"),
ICON_PF_MOUSE,
s_binding_info,
s_settings,
Expand Down
2 changes: 1 addition & 1 deletion src/core/playstation_mouse.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class PlayStationMouse final : public Controller
void ResetTransferState() override;
bool Transfer(const u8 data_in, u8* data_out) override;

void LoadSettings(SettingsInterface& si, const char* section) override;
void LoadSettings(SettingsInterface& si, const char* section, bool initial) override;

private:
enum class TransferState : u8
Expand Down
Loading

0 comments on commit 9e3507e

Please sign in to comment.