From beab38601badd54930881858b4a021fe76a92b39 Mon Sep 17 00:00:00 2001 From: David Marcec Date: Thu, 18 Oct 2018 14:11:15 +1100 Subject: Added multi-input support and controller assignment at any port --- src/core/hle/service/hid/controllers/npad.cpp | 287 +++++++++++++++----------- src/core/hle/service/hid/controllers/npad.h | 16 +- 2 files changed, 181 insertions(+), 122 deletions(-) (limited to 'src/core/hle') diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 205e4fd14..5b0ca57f8 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -164,6 +164,57 @@ void Controller_NPad::OnLoadInputDevices() { void Controller_NPad::OnRelease() {} +void Controller_NPad::RequestPadStateUpdate(u32 npad_id) { + const auto controller_idx = NPadIdToIndex(npad_id); + const auto controller_type = connected_controllers[controller_idx].type; + if (!connected_controllers[controller_idx].is_connected) { + return; + } + auto& pad_state = npad_pad_states[controller_idx].pad_states; + auto& lstick_entry = npad_pad_states[controller_idx].l_stick; + auto& rstick_entry = npad_pad_states[controller_idx].r_stick; + using namespace Settings::NativeButton; + pad_state.a.Assign(buttons[A - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.b.Assign(buttons[B - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.x.Assign(buttons[X - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.y.Assign(buttons[Y - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.l_stick.Assign(buttons[LStick - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.r_stick.Assign(buttons[RStick - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.l.Assign(buttons[L - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.r.Assign(buttons[R - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.zl.Assign(buttons[ZL - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.zr.Assign(buttons[ZR - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.plus.Assign(buttons[Plus - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.minus.Assign(buttons[Minus - BUTTON_HID_BEGIN]->GetStatus()); + + pad_state.d_left.Assign(buttons[DLeft - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.d_up.Assign(buttons[DUp - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.d_right.Assign(buttons[DRight - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.d_down.Assign(buttons[DDown - BUTTON_HID_BEGIN]->GetStatus()); + + pad_state.l_stick_left.Assign(buttons[LStick_Left - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.l_stick_up.Assign(buttons[LStick_Up - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.l_stick_right.Assign(buttons[LStick_Right - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.l_stick_down.Assign(buttons[LStick_Down - BUTTON_HID_BEGIN]->GetStatus()); + + pad_state.r_stick_left.Assign(buttons[RStick_Left - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.r_stick_up.Assign(buttons[RStick_Up - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.r_stick_right.Assign(buttons[RStick_Right - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.r_stick_down.Assign(buttons[RStick_Down - BUTTON_HID_BEGIN]->GetStatus()); + + pad_state.sl.Assign(buttons[SL - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.sr.Assign(buttons[SR - BUTTON_HID_BEGIN]->GetStatus()); + + const auto [stick_l_x_f, stick_l_y_f] = + sticks[static_cast(JoystickId::Joystick_Left)]->GetStatus(); + const auto [stick_r_x_f, stick_r_y_f] = + sticks[static_cast(JoystickId::Joystick_Right)]->GetStatus(); + lstick_entry.x = static_cast(stick_l_x_f * HID_JOYSTICK_MAX); + lstick_entry.y = static_cast(stick_l_y_f * HID_JOYSTICK_MAX); + rstick_entry.x = static_cast(stick_r_x_f * HID_JOYSTICK_MAX); + rstick_entry.y = static_cast(stick_r_y_f * HID_JOYSTICK_MAX); +} + void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) { if (!IsControllerActivated()) return; @@ -199,97 +250,9 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) { if (controller_type == NPadControllerType::None || !connected_controllers[i].is_connected) { continue; } - - // Pad states - ControllerPadState pad_state{}; - using namespace Settings::NativeButton; - pad_state.a.Assign(buttons[A - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.b.Assign(buttons[B - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.x.Assign(buttons[X - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.y.Assign(buttons[Y - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.l_stick.Assign(buttons[LStick - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.r_stick.Assign(buttons[RStick - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.l.Assign(buttons[L - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.r.Assign(buttons[R - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.zl.Assign(buttons[ZL - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.zr.Assign(buttons[ZR - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.plus.Assign(buttons[Plus - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.minus.Assign(buttons[Minus - BUTTON_HID_BEGIN]->GetStatus()); - - pad_state.d_left.Assign(buttons[DLeft - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.d_up.Assign(buttons[DUp - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.d_right.Assign(buttons[DRight - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.d_down.Assign(buttons[DDown - BUTTON_HID_BEGIN]->GetStatus()); - - pad_state.l_stick_left.Assign(buttons[LStick_Left - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.l_stick_up.Assign(buttons[LStick_Up - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.l_stick_right.Assign(buttons[LStick_Right - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.l_stick_down.Assign(buttons[LStick_Down - BUTTON_HID_BEGIN]->GetStatus()); - - pad_state.r_stick_left.Assign(buttons[RStick_Left - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.r_stick_up.Assign(buttons[RStick_Up - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.r_stick_right.Assign(buttons[RStick_Right - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.r_stick_down.Assign(buttons[RStick_Down - BUTTON_HID_BEGIN]->GetStatus()); - - pad_state.sl.Assign(buttons[SL - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.sr.Assign(buttons[SR - BUTTON_HID_BEGIN]->GetStatus()); - - AnalogPosition lstick_entry{}; - AnalogPosition rstick_entry{}; - - const auto [stick_l_x_f, stick_l_y_f] = - sticks[static_cast(JoystickId::Joystick_Left)]->GetStatus(); - const auto [stick_r_x_f, stick_r_y_f] = - sticks[static_cast(JoystickId::Joystick_Right)]->GetStatus(); - lstick_entry.x = static_cast(stick_l_x_f * HID_JOYSTICK_MAX); - lstick_entry.y = static_cast(stick_l_y_f * HID_JOYSTICK_MAX); - rstick_entry.x = static_cast(stick_r_x_f * HID_JOYSTICK_MAX); - rstick_entry.y = static_cast(stick_r_y_f * HID_JOYSTICK_MAX); - - if (controller_type == NPadControllerType::JoyLeft || - controller_type == NPadControllerType::JoyRight) { - if (npad.properties.is_horizontal) { - ControllerPadState state{}; - AnalogPosition temp_lstick_entry{}; - AnalogPosition temp_rstick_entry{}; - if (controller_type == NPadControllerType::JoyLeft) { - state.d_down.Assign(pad_state.d_left.Value()); - state.d_left.Assign(pad_state.d_up.Value()); - state.d_right.Assign(pad_state.d_down.Value()); - state.d_up.Assign(pad_state.d_right.Value()); - state.l.Assign(pad_state.l.Value() | pad_state.sl.Value()); - state.r.Assign(pad_state.r.Value() | pad_state.sr.Value()); - - state.zl.Assign(pad_state.zl.Value()); - state.plus.Assign(pad_state.minus.Value()); - - temp_lstick_entry = lstick_entry; - temp_rstick_entry = rstick_entry; - std::swap(temp_lstick_entry.x, temp_lstick_entry.y); - std::swap(temp_rstick_entry.x, temp_rstick_entry.y); - temp_lstick_entry.y *= -1; - } else if (controller_type == NPadControllerType::JoyRight) { - state.x.Assign(pad_state.a.Value()); - state.a.Assign(pad_state.b.Value()); - state.b.Assign(pad_state.y.Value()); - state.y.Assign(pad_state.b.Value()); - - state.l.Assign(pad_state.l.Value() | pad_state.sl.Value()); - state.r.Assign(pad_state.r.Value() | pad_state.sr.Value()); - state.zr.Assign(pad_state.zr.Value()); - state.plus.Assign(pad_state.plus.Value()); - - temp_lstick_entry = lstick_entry; - temp_rstick_entry = rstick_entry; - std::swap(temp_lstick_entry.x, temp_lstick_entry.y); - std::swap(temp_rstick_entry.x, temp_rstick_entry.y); - temp_rstick_entry.x *= -1; - } - pad_state.raw = state.raw; - lstick_entry = temp_lstick_entry; - rstick_entry = temp_rstick_entry; - } - } + const u32 npad_index = static_cast(i); + RequestPadStateUpdate(npad_index); + auto& pad_state = npad_pad_states[npad_index]; auto& main_controller = npad.main_controller_states.npad[npad.main_controller_states.common.last_entry_index]; @@ -304,7 +267,45 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) { auto& libnx_entry = npad.libnx.npad[npad.libnx.common.last_entry_index]; if (hold_type == NpadHoldType::Horizontal) { - // TODO(ogniK): Remap buttons for different orientations + ControllerPadState state{}; + AnalogPosition temp_lstick_entry{}; + AnalogPosition temp_rstick_entry{}; + if (controller_type == NPadControllerType::JoyLeft) { + state.d_down.Assign(pad_state.pad_states.d_left.Value()); + state.d_left.Assign(pad_state.pad_states.d_up.Value()); + state.d_right.Assign(pad_state.pad_states.d_down.Value()); + state.d_up.Assign(pad_state.pad_states.d_right.Value()); + state.l.Assign(pad_state.pad_states.l.Value() | pad_state.pad_states.sl.Value()); + state.r.Assign(pad_state.pad_states.r.Value() | pad_state.pad_states.sr.Value()); + + state.zl.Assign(pad_state.pad_states.zl.Value()); + state.plus.Assign(pad_state.pad_states.minus.Value()); + + temp_lstick_entry = pad_state.l_stick; + temp_rstick_entry = pad_state.r_stick; + std::swap(temp_lstick_entry.x, temp_lstick_entry.y); + std::swap(temp_rstick_entry.x, temp_rstick_entry.y); + temp_lstick_entry.y *= -1; + } else if (controller_type == NPadControllerType::JoyRight) { + state.x.Assign(pad_state.pad_states.a.Value()); + state.a.Assign(pad_state.pad_states.b.Value()); + state.b.Assign(pad_state.pad_states.y.Value()); + state.y.Assign(pad_state.pad_states.b.Value()); + + state.l.Assign(pad_state.pad_states.l.Value() | pad_state.pad_states.sl.Value()); + state.r.Assign(pad_state.pad_states.r.Value() | pad_state.pad_states.sr.Value()); + state.zr.Assign(pad_state.pad_states.zr.Value()); + state.plus.Assign(pad_state.pad_states.plus.Value()); + + temp_lstick_entry = pad_state.l_stick; + temp_rstick_entry = pad_state.r_stick; + std::swap(temp_lstick_entry.x, temp_lstick_entry.y); + std::swap(temp_rstick_entry.x, temp_rstick_entry.y); + temp_rstick_entry.x *= -1; + } + pad_state.pad_states.raw = state.raw; + pad_state.l_stick = temp_lstick_entry; + pad_state.r_stick = temp_rstick_entry; } libnx_entry.connection_status.raw = 0; @@ -316,9 +317,9 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) { handheld_entry.connection_status.IsRightJoyConnected.Assign(1); handheld_entry.connection_status.IsLeftJoyWired.Assign(1); handheld_entry.connection_status.IsRightJoyWired.Assign(1); - handheld_entry.pad_states.raw = pad_state.raw; - handheld_entry.l_stick = lstick_entry; - handheld_entry.r_stick = rstick_entry; + handheld_entry.pad.pad_states.raw = pad_state.pad_states.raw; + handheld_entry.pad.l_stick = pad_state.l_stick; + handheld_entry.pad.r_stick = pad_state.r_stick; break; case NPadControllerType::JoyDual: dual_entry.connection_status.raw = 0; @@ -339,17 +340,17 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) { left_entry.connection_status.raw = 0; left_entry.connection_status.IsConnected.Assign(1); - left_entry.pad_states.raw = pad_state.raw; - left_entry.l_stick = lstick_entry; - left_entry.r_stick = rstick_entry; + left_entry.pad.pad_states.raw = pad_state.pad_states.raw; + left_entry.pad.l_stick = pad_state.l_stick; + left_entry.pad.r_stick = pad_state.r_stick; break; case NPadControllerType::JoyRight: right_entry.connection_status.raw = 0; right_entry.connection_status.IsConnected.Assign(1); - right_entry.pad_states.raw = pad_state.raw; - right_entry.l_stick = lstick_entry; - right_entry.r_stick = rstick_entry; + right_entry.pad.pad_states.raw = pad_state.pad_states.raw; + right_entry.pad.l_stick = pad_state.l_stick; + right_entry.pad.r_stick = pad_state.r_stick; break; case NPadControllerType::Pokeball: pokeball_entry.connection_status.raw = 0; @@ -357,26 +358,26 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) { pokeball_entry.connection_status.IsConnected.Assign(1); pokeball_entry.connection_status.IsWired.Assign(1); - pokeball_entry.pad_states.raw = pad_state.raw; - pokeball_entry.l_stick = lstick_entry; - pokeball_entry.r_stick = rstick_entry; + pokeball_entry.pad.pad_states.raw = pad_state.pad_states.raw; + pokeball_entry.pad.l_stick = pad_state.l_stick; + pokeball_entry.pad.r_stick = pad_state.r_stick; break; case NPadControllerType::ProController: main_controller.connection_status.raw = 0; main_controller.connection_status.IsConnected.Assign(1); main_controller.connection_status.IsWired.Assign(1); - main_controller.pad_states.raw = pad_state.raw; - main_controller.l_stick = lstick_entry; - main_controller.r_stick = rstick_entry; + main_controller.pad.pad_states.raw = pad_state.pad_states.raw; + main_controller.pad.l_stick = pad_state.l_stick; + main_controller.pad.r_stick = pad_state.r_stick; break; } // LibNX exclusively uses this section, so we always update it since LibNX doesn't activate // any controllers. - libnx_entry.pad_states.raw = pad_state.raw; - libnx_entry.l_stick = lstick_entry; - libnx_entry.r_stick = rstick_entry; + libnx_entry.pad.pad_states.raw = pad_state.pad_states.raw; + libnx_entry.pad.l_stick = pad_state.l_stick; + libnx_entry.pad.r_stick = pad_state.r_stick; } std::memcpy(data + NPAD_OFFSET, shared_memory_entries.data(), shared_memory_entries.size() * sizeof(NPadEntry)); @@ -450,15 +451,7 @@ void Controller_NPad::VibrateController(const std::vector& controller_ids, return; } for (std::size_t i = 0; i < controller_ids.size(); i++) { - std::size_t controller_pos = i; - // Handheld controller conversion - if (controller_pos == NPAD_HANDHELD) { - controller_pos = 8; - } - // Unknown controller conversion - if (controller_pos == NPAD_UNKNOWN) { - controller_pos = 9; - } + std::size_t controller_pos = NPadIdToIndex(static_cast(i)); if (connected_controllers[controller_pos].is_connected) { // TODO(ogniK): Vibrate the physical controller } @@ -477,6 +470,51 @@ Kernel::SharedPtr Controller_NPad::GetStyleSetChangedEvent() cons Controller_NPad::Vibration Controller_NPad::GetLastVibration() const { return last_processed_vibration; } + +std::size_t Controller_NPad::NPadIdToIndex(u32 npad_id) { + switch (npad_id) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + return static_cast(npad_id); + case 8: + case 32: + return 8; + case 9: + case 16: + return 9; + default: + UNIMPLEMENTED_MSG("Unknown npad id {}", npad_id); + return 0; + } +} + +u32 Controller_NPad::IndexToNPad(std::size_t index) { + switch (index) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + return static_cast(index); + case 8: + return 32; + case 9: + return 16; + default: + UNIMPLEMENTED_MSG("Unknown npad index {}", index); + return 0; + }; +} + void Controller_NPad::AddNewController(NPadControllerType controller) { if (controller == NPadControllerType::Handheld) { connected_controllers[8] = {controller, true}; @@ -495,6 +533,17 @@ void Controller_NPad::AddNewController(NPadControllerType controller) { InitNewlyAddedControler(controller_id); } +void Controller_NPad::AddNewControllerAt(NPadControllerType controller, u32 npad_id) { + if (controller == NPadControllerType::Handheld) { + connected_controllers[8] = {controller, true}; + InitNewlyAddedControler(8); + return; + } + const size_t controller_id = static_cast(npad_id); + connected_controllers[controller_id] = {controller, true}; + InitNewlyAddedControler(controller_id); +} + void Controller_NPad::ConnectNPad(u32 npad_id) { connected_controllers[NPadIdToIndex(npad_id)].is_connected = true; } diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index ac86985ff..1192cfcd9 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -107,6 +107,7 @@ public: Vibration GetLastVibration() const; void AddNewController(NPadControllerType controller); + void AddNewControllerAt(NPadControllerType controller, u32 npad_id); void ConnectNPad(u32 npad_id); void DisconnectNPad(u32 npad_id); @@ -189,12 +190,17 @@ private: }; static_assert(sizeof(ConnectionState) == 4, "ConnectionState is an invalid size"); - struct GenericStates { - s64_le timestamp; - s64_le timestamp2; + struct ControllerPad { ControllerPadState pad_states; AnalogPosition l_stick; AnalogPosition r_stick; + }; + static_assert(sizeof(ControllerPad) == 0x18, "ControllerPad is an invalid size"); + + struct GenericStates { + s64_le timestamp; + s64_le timestamp2; + ControllerPad pad; ConnectionState connection_status; }; static_assert(sizeof(GenericStates) == 0x30, "NPadGenericStates is an invalid size"); @@ -285,5 +291,9 @@ private: void InitNewlyAddedControler(std::size_t controller_idx); bool IsControllerSupported(NPadControllerType controller) const; NPadControllerType DecideBestController(NPadControllerType priority) const; + void RequestPadStateUpdate(u32 npad_id); + std::size_t NPadIdToIndex(u32 npad_id); + u32 IndexToNPad(std::size_t index); + std::array npad_pad_states{}; }; } // namespace Service::HID -- cgit v1.2.3 From b9c1e4b0e75f13cde0508bc3d0bd252add03ae85 Mon Sep 17 00:00:00 2001 From: David Marcec Date: Thu, 18 Oct 2018 15:09:55 +1100 Subject: Added automatic npad switch based on supported stylesets --- src/core/hle/service/hid/controllers/npad.cpp | 124 +++++++++++++++++++++++++- src/core/hle/service/hid/controllers/npad.h | 4 +- 2 files changed, 124 insertions(+), 4 deletions(-) (limited to 'src/core/hle') diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 5b0ca57f8..a9060fa2c 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -89,12 +89,12 @@ void Controller_NPad::InitNewlyAddedControler(std::size_t controller_idx) { case NPadControllerType::JoyLeft: controller.joy_styles.joycon_left.Assign(1); controller.device_type.joycon_left.Assign(1); - controller.pad_assignment = NPadAssignments::Dual; + controller.pad_assignment = NPadAssignments::Single; break; case NPadControllerType::JoyRight: controller.joy_styles.joycon_right.Assign(1); controller.device_type.joycon_right.Assign(1); - controller.pad_assignment = NPadAssignments::Dual; + controller.pad_assignment = NPadAssignments::Single; break; case NPadControllerType::Pokeball: controller.joy_styles.pokeball.Assign(1); @@ -381,7 +381,7 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) { } std::memcpy(data + NPAD_OFFSET, shared_memory_entries.data(), shared_memory_entries.size() * sizeof(NPadEntry)); -} // namespace Service::HID +} void Controller_NPad::SetSupportedStyleSet(NPadType style_set) { style.raw = style_set.raw; @@ -516,6 +516,7 @@ u32 Controller_NPad::IndexToNPad(std::size_t index) { } void Controller_NPad::AddNewController(NPadControllerType controller) { + controller = DecideBestController(controller); if (controller == NPadControllerType::Handheld) { connected_controllers[8] = {controller, true}; InitNewlyAddedControler(8); @@ -534,6 +535,7 @@ void Controller_NPad::AddNewController(NPadControllerType controller) { } void Controller_NPad::AddNewControllerAt(NPadControllerType controller, u32 npad_id) { + controller = DecideBestController(controller); if (controller == NPadControllerType::Handheld) { connected_controllers[8] = {controller, true}; InitNewlyAddedControler(8); @@ -552,6 +554,122 @@ void Controller_NPad::DisconnectNPad(u32 npad_id) { connected_controllers[NPadIdToIndex(npad_id)].is_connected = false; } +Controller_NPad::NPadControllerType Controller_NPad::DecideBestController( + NPadControllerType priority) { + if (IsControllerSupported(priority)) { + return priority; + } + const auto is_docked = Settings::values->use_docked_mode; + if (is_docked && priority == NPadControllerType::Handheld) { + priority = NPadControllerType::JoyDual; + if (IsControllerSupported(priority)) { + return priority; + } + } + std::vector priority_list{}; + switch (priority) { + case NPadControllerType::ProController: + priority_list.push_back(NPadControllerType::JoyDual); + if (!is_docked) { + priority_list.push_back(NPadControllerType::Handheld); + } + priority_list.push_back(NPadControllerType::JoyLeft); + priority_list.push_back(NPadControllerType::JoyRight); + priority_list.push_back(NPadControllerType::Pokeball); + break; + case NPadControllerType::Handheld: + priority_list.push_back(NPadControllerType::JoyDual); + priority_list.push_back(NPadControllerType::ProController); + priority_list.push_back(NPadControllerType::JoyLeft); + priority_list.push_back(NPadControllerType::JoyRight); + priority_list.push_back(NPadControllerType::Pokeball); + break; + case NPadControllerType::JoyDual: + if (!is_docked) { + priority_list.push_back(NPadControllerType::Handheld); + } + priority_list.push_back(NPadControllerType::ProController); + priority_list.push_back(NPadControllerType::JoyLeft); + priority_list.push_back(NPadControllerType::JoyRight); + priority_list.push_back(NPadControllerType::Pokeball); + break; + case NPadControllerType::JoyLeft: + priority_list.push_back(NPadControllerType::JoyRight); + priority_list.push_back(NPadControllerType::JoyDual); + if (!is_docked) { + priority_list.push_back(NPadControllerType::Handheld); + } + priority_list.push_back(NPadControllerType::ProController); + priority_list.push_back(NPadControllerType::Pokeball); + break; + case NPadControllerType::JoyRight: + priority_list.push_back(NPadControllerType::JoyLeft); + priority_list.push_back(NPadControllerType::JoyDual); + if (!is_docked) { + priority_list.push_back(NPadControllerType::Handheld); + } + priority_list.push_back(NPadControllerType::ProController); + priority_list.push_back(NPadControllerType::Pokeball); + break; + case NPadControllerType::Pokeball: + priority_list.push_back(NPadControllerType::JoyLeft); + priority_list.push_back(NPadControllerType::JoyRight); + priority_list.push_back(NPadControllerType::JoyDual); + if (!is_docked) { + priority_list.push_back(NPadControllerType::Handheld); + } + priority_list.push_back(NPadControllerType::ProController); + break; + default: + priority_list.push_back(NPadControllerType::JoyDual); + if (!is_docked) { + priority_list.push_back(NPadControllerType::Handheld); + } + priority_list.push_back(NPadControllerType::ProController); + priority_list.push_back(NPadControllerType::JoyLeft); + priority_list.push_back(NPadControllerType::JoyRight); + priority_list.push_back(NPadControllerType::JoyDual); + } + + for (const auto controller_type : priority_list) { + if (IsControllerSupported(controller_type)) { + return controller_type; + } + } + UNIMPLEMENTED_MSG("Could not find supported controller!"); + return priority; +} + +bool Controller_NPad::IsControllerSupported(NPadControllerType controller) { + if (controller == NPadControllerType::Handheld) { + // Handheld is not even a supported type, lets stop here + if (std::find(supported_npad_id_types.begin(), supported_npad_id_types.end(), 32) == + supported_npad_id_types.end()) { + return false; + } + // Handheld should not be supported in docked mode + if (Settings::values->use_docked_mode) { + return false; + } + } + switch (controller) { + case NPadControllerType::ProController: + return style.pro_controller; + case NPadControllerType::Handheld: + return style.handheld; + case NPadControllerType::JoyDual: + return style.joycon_dual; + case NPadControllerType::JoyLeft: + return style.joycon_left; + case NPadControllerType::JoyRight: + return style.joycon_right; + case NPadControllerType::Pokeball: + return style.pokeball; + default: + return false; + } +} + Controller_NPad::LedPattern Controller_NPad::GetLedPattern(u32 npad_id) { if (npad_id == npad_id_list.back() || npad_id == npad_id_list[npad_id_list.size() - 2]) { // These are controllers without led patterns diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 1192cfcd9..ea12646f8 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -272,7 +272,7 @@ private: static_assert(sizeof(NPadEntry) == 0x5000, "NPadEntry is an invalid size"); struct ControllerHolder { - Controller_NPad::NPadControllerType type; + NPadControllerType type; bool is_connected; }; @@ -295,5 +295,7 @@ private: std::size_t NPadIdToIndex(u32 npad_id); u32 IndexToNPad(std::size_t index); std::array npad_pad_states{}; + NPadControllerType DecideBestController(NPadControllerType priority); + bool IsControllerSupported(NPadControllerType controller); }; } // namespace Service::HID -- cgit v1.2.3 From 7fbe2c83a7e3de06624f0ab2f14f760fbccc89e3 Mon Sep 17 00:00:00 2001 From: David Marcec Date: Thu, 18 Oct 2018 19:00:16 +1100 Subject: Left joycon rotation button remapping --- src/core/hle/service/hid/controllers/npad.cpp | 21 ++++++++++++++++----- src/core/hle/service/hid/controllers/npad.h | 7 +++++-- 2 files changed, 21 insertions(+), 7 deletions(-) (limited to 'src/core/hle') diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index a9060fa2c..fd677d281 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -79,21 +79,31 @@ void Controller_NPad::InitNewlyAddedControler(std::size_t controller_idx) { controller.joy_styles.handheld.Assign(1); controller.device_type.handheld.Assign(1); controller.pad_assignment = NPadAssignments::Dual; + controller.properties.is_vertical.Assign(1); + controller.properties.use_plus.Assign(1); + controller.properties.use_minus.Assign(1); break; case NPadControllerType::JoyDual: controller.joy_styles.joycon_dual.Assign(1); controller.device_type.joycon_left.Assign(1); controller.device_type.joycon_right.Assign(1); + controller.properties.is_vertical.Assign(1); + controller.properties.use_plus.Assign(1); + controller.properties.use_minus.Assign(1); controller.pad_assignment = NPadAssignments::Dual; break; case NPadControllerType::JoyLeft: controller.joy_styles.joycon_left.Assign(1); controller.device_type.joycon_left.Assign(1); + controller.properties.is_horizontal.Assign(1); + controller.properties.use_minus.Assign(1); controller.pad_assignment = NPadAssignments::Single; break; case NPadControllerType::JoyRight: controller.joy_styles.joycon_right.Assign(1); controller.device_type.joycon_right.Assign(1); + controller.properties.is_horizontal.Assign(1); + controller.properties.use_plus.Assign(1); controller.pad_assignment = NPadAssignments::Single; break; case NPadControllerType::Pokeball: @@ -104,6 +114,9 @@ void Controller_NPad::InitNewlyAddedControler(std::size_t controller_idx) { case NPadControllerType::ProController: controller.joy_styles.pro_controller.Assign(1); controller.device_type.pro_controller.Assign(1); + controller.properties.is_vertical.Assign(1); + controller.properties.use_plus.Assign(1); + controller.properties.use_minus.Assign(1); controller.pad_assignment = NPadAssignments::Single; break; } @@ -118,9 +131,6 @@ void Controller_NPad::InitNewlyAddedControler(std::size_t controller_idx) { controller.right_color.body_color = JOYCON_BODY_NEON_RED; controller.right_color.button_color = JOYCON_BUTTONS_NEON_RED; - controller.properties.is_vertical.Assign(1); // TODO(ogniK): Swap joycons orientations - controller.properties.use_plus.Assign(1); - controller.properties.use_minus.Assign(1); controller.battery_level[0] = BATTERY_FULL; controller.battery_level[1] = BATTERY_FULL; controller.battery_level[2] = BATTERY_FULL; @@ -202,8 +212,8 @@ void Controller_NPad::RequestPadStateUpdate(u32 npad_id) { pad_state.r_stick_right.Assign(buttons[RStick_Right - BUTTON_HID_BEGIN]->GetStatus()); pad_state.r_stick_down.Assign(buttons[RStick_Down - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.sl.Assign(buttons[SL - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.sr.Assign(buttons[SR - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.left_sl.Assign(buttons[SL - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.left_sr.Assign(buttons[SR - BUTTON_HID_BEGIN]->GetStatus()); const auto [stick_l_x_f, stick_l_y_f] = sticks[static_cast(JoystickId::Joystick_Left)]->GetStatus(); @@ -307,6 +317,7 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) { pad_state.l_stick = temp_lstick_entry; pad_state.r_stick = temp_rstick_entry; } + libnx_entry.connection_status.raw = 0; switch (controller_type) { diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index ea12646f8..f702990c7 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -165,8 +165,11 @@ private: BitField<23, 1, u64_le> r_stick_down; // Not always active? - BitField<24, 1, u64_le> sl; - BitField<25, 1, u64_le> sr; + BitField<24, 1, u64_le> left_sl; + BitField<25, 1, u64_le> left_sr; + + BitField<26, 1, u64_le> right_sl; + BitField<27, 1, u64_le> right_sr; }; }; static_assert(sizeof(ControllerPadState) == 8, "ControllerPadState is an invalid size"); -- cgit v1.2.3 From a69b9d73f501395a0522f9e8227402c251281bbe Mon Sep 17 00:00:00 2001 From: David Marcec Date: Thu, 18 Oct 2018 21:04:45 +1100 Subject: Changed polling rate of hid and Right joycon rotation --- src/core/hle/service/hid/hid.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/core/hle') diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 39631b14f..7c0dac5dc 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -34,8 +34,8 @@ namespace Service::HID { // Updating period for each HID device. -// TODO(shinyquagsire23): These need better values. -constexpr u64 pad_update_ticks = CoreTiming::BASE_CLOCK_RATE / 100; +// TODO(ogniK): Find actual polling rate of hid +constexpr u64 pad_update_ticks = CoreTiming::BASE_CLOCK_RATE / 66; constexpr u64 accelerometer_update_ticks = CoreTiming::BASE_CLOCK_RATE / 100; constexpr u64 gyroscope_update_ticks = CoreTiming::BASE_CLOCK_RATE / 100; constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000; -- cgit v1.2.3 From 362b28d0529eeb815f428594200c611d525a0d6f Mon Sep 17 00:00:00 2001 From: David Marcec Date: Thu, 18 Oct 2018 21:45:10 +1100 Subject: Added controller helper funcs --- src/core/hle/service/hid/controllers/npad.cpp | 31 +++++++++++++++++++++++++++ src/core/hle/service/hid/controllers/npad.h | 4 ++++ 2 files changed, 35 insertions(+) (limited to 'src/core/hle') diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index fd677d281..3eb59599f 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -712,6 +712,37 @@ void Controller_NPad::SetVibrationEnabled(bool can_vibrate) { can_controllers_vibrate = can_vibrate; } +void Controller_NPad::ClearAllConnectedControllers() { + std::for_each(connected_controllers.begin(), connected_controllers.end(), + [](ControllerHolder& controller) { + if (controller.is_connected && controller.type != NPadControllerType::None) { + controller.type = NPadControllerType::None; + controller.is_connected = false; + } + }); +} +void Controller_NPad::DisconnectAllConnectedControllers() { + std::for_each(connected_controllers.begin(), connected_controllers.end(), + [](ControllerHolder& controller) { controller.is_connected = false; }); +} + +void Controller_NPad::ConnectAllDisconnectedControllers() { + std::for_each(connected_controllers.begin(), connected_controllers.end(), + [](ControllerHolder& controller) { + if (controller.type != NPadControllerType::None && !controller.is_connected) { + controller.is_connected = false; + } + }); +} + +void Controller_NPad::ClearAllControllers() { + std::for_each(connected_controllers.begin(), connected_controllers.end(), + [](ControllerHolder& controller) { + controller.type = NPadControllerType::None; + controller.is_connected = false; + }); +} + bool Controller_NPad::IsControllerSupported(NPadControllerType controller) const { const bool support_handheld = std::find(supported_npad_id_types.begin(), supported_npad_id_types.end(), NPAD_HANDHELD) != diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index f702990c7..7222bca72 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -113,6 +113,10 @@ public: void DisconnectNPad(u32 npad_id); LedPattern GetLedPattern(u32 npad_id); void SetVibrationEnabled(bool can_vibrate); + void ClearAllConnectedControllers(); + void DisconnectAllConnectedControllers(); + void ConnectAllDisconnectedControllers(); + void ClearAllControllers(); private: struct CommonHeader { -- cgit v1.2.3 From f66c6fe55424c229728c5dc2e36efe51386a0dd0 Mon Sep 17 00:00:00 2001 From: David Marcec Date: Thu, 18 Oct 2018 22:01:55 +1100 Subject: Added debugpad skeleton --- src/core/hle/service/hid/controllers/debug_pad.cpp | 23 +++++++++++++++ src/core/hle/service/hid/controllers/debug_pad.h | 34 ++++++++++++++++++++-- 2 files changed, 55 insertions(+), 2 deletions(-) (limited to 'src/core/hle') diff --git a/src/core/hle/service/hid/controllers/debug_pad.cpp b/src/core/hle/service/hid/controllers/debug_pad.cpp index 3d100763f..ac9b23bb8 100644 --- a/src/core/hle/service/hid/controllers/debug_pad.cpp +++ b/src/core/hle/service/hid/controllers/debug_pad.cpp @@ -34,6 +34,29 @@ void Controller_DebugPad::OnUpdate(u8* data, std::size_t size) { cur_entry.sampling_number = last_entry.sampling_number + 1; cur_entry.sampling_number2 = cur_entry.sampling_number; // TODO(ogniK): Update debug pad states + cur_entry.attribute.connected.Assign(1); + auto& pad = cur_entry.pad_state; + + pad.a.Assign(0); + pad.b.Assign(0); + pad.x.Assign(0); + pad.y.Assign(0); + pad.l.Assign(0); + pad.r.Assign(0); + pad.zl.Assign(0); + pad.zr.Assign(0); + pad.plus.Assign(0); + pad.minus.Assign(0); + pad.d_left.Assign(0); + pad.d_up.Assign(0); + pad.d_right.Assign(0); + pad.d_down.Assign(0); + + cur_entry.l_stick.x = 0; + cur_entry.l_stick.y = 0; + + cur_entry.r_stick.x = 0; + cur_entry.r_stick.y = 0; std::memcpy(data, &shared_memory, sizeof(SharedMemory)); } diff --git a/src/core/hle/service/hid/controllers/debug_pad.h b/src/core/hle/service/hid/controllers/debug_pad.h index 62b4f2682..a41564b4d 100644 --- a/src/core/hle/service/hid/controllers/debug_pad.h +++ b/src/core/hle/service/hid/controllers/debug_pad.h @@ -5,6 +5,7 @@ #pragma once #include +#include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" #include "common/swap.h" @@ -35,11 +36,40 @@ private: }; static_assert(sizeof(AnalogStick) == 0x8); + struct PadState { + union { + u32_le raw{}; + BitField<0, 1, u32_le> a; + BitField<1, 1, u32_le> b; + BitField<2, 1, u32_le> x; + BitField<3, 1, u32_le> y; + BitField<4, 1, u32_le> l; + BitField<5, 1, u32_le> r; + BitField<6, 1, u32_le> zl; + BitField<7, 1, u32_le> zr; + BitField<8, 1, u32_le> plus; + BitField<9, 1, u32_le> minus; + BitField<10, 1, u32_le> d_left; + BitField<11, 1, u32_le> d_up; + BitField<12, 1, u32_le> d_right; + BitField<13, 1, u32_le> d_down; + }; + }; + static_assert(sizeof(PadState) == 0x4, "PadState is an invalid size"); + + struct Attributes { + union { + u32_le raw{}; + BitField<0, 1, u32_le> connected; + }; + }; + static_assert(sizeof(Attributes) == 0x4, "Attributes is an invalid size"); + struct PadStates { s64_le sampling_number; s64_le sampling_number2; - u32_le attribute; - u32_le button_state; + Attributes attribute; + PadState pad_state; AnalogStick r_stick; AnalogStick l_stick; }; -- cgit v1.2.3 From 0c3e7b708684fb17cb29c491fca46125d7d716b9 Mon Sep 17 00:00:00 2001 From: David Marcec Date: Thu, 18 Oct 2018 22:34:30 +1100 Subject: Added missing start/end touch attributes to touchscreen --- src/core/hle/service/hid/controllers/touchscreen.cpp | 7 +++++++ src/core/hle/service/hid/controllers/touchscreen.h | 12 +++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) (limited to 'src/core/hle') diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/core/hle/service/hid/controllers/touchscreen.cpp index 43efef803..07244fe4e 100644 --- a/src/core/hle/service/hid/controllers/touchscreen.cpp +++ b/src/core/hle/service/hid/controllers/touchscreen.cpp @@ -41,7 +41,11 @@ void Controller_Touchscreen::OnUpdate(u8* data, std::size_t size) { const auto [x, y, pressed] = touch_device->GetStatus(); auto& touch_entry = cur_entry.states[0]; + touch_entry.attribute.raw = 0; if (pressed) { + if (cur_entry.entry_count == 0) { + touch_entry.attribute.start_touch.Assign(1); + } touch_entry.x = static_cast(x * Layout::ScreenUndocked::Width); touch_entry.y = static_cast(y * Layout::ScreenUndocked::Height); touch_entry.diameter_x = 15; @@ -53,6 +57,9 @@ void Controller_Touchscreen::OnUpdate(u8* data, std::size_t size) { touch_entry.finger = 0; cur_entry.entry_count = 1; } else { + if (cur_entry.entry_count == 1) { + touch_entry.attribute.end_touch.Assign(1); + } cur_entry.entry_count = 0; } diff --git a/src/core/hle/service/hid/controllers/touchscreen.h b/src/core/hle/service/hid/controllers/touchscreen.h index e5db6e6ba..94cd0eba9 100644 --- a/src/core/hle/service/hid/controllers/touchscreen.h +++ b/src/core/hle/service/hid/controllers/touchscreen.h @@ -4,6 +4,7 @@ #pragma once +#include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" #include "common/swap.h" @@ -29,9 +30,18 @@ public: void OnLoadInputDevices() override; private: + struct Attributes { + union { + u32 raw{}; + BitField<0, 1, u32_le> start_touch; + BitField<1, 1, u32_le> end_touch; + }; + }; + static_assert(sizeof(Attributes) == 0x4, "Attributes is an invalid size"); + struct TouchState { u64_le delta_time; - u32_le attribute; + Attributes attribute; u32_le finger; u32_le x; u32_le y; -- cgit v1.2.3 From 06cf050c0a541bc0bf9b4ca41fdec75f133c91d3 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Thu, 1 Nov 2018 22:01:11 -0400 Subject: hid: Add controller bindings for DebugPad controller Used by developers to test games, not present on retail systems. Some games are known to respond to DebugPad input though, for example Kirby Star Allies. --- src/core/hle/service/hid/controllers/debug_pad.cpp | 57 ++++++++++++++-------- src/core/hle/service/hid/controllers/debug_pad.h | 7 +++ 2 files changed, 43 insertions(+), 21 deletions(-) (limited to 'src/core/hle') diff --git a/src/core/hle/service/hid/controllers/debug_pad.cpp b/src/core/hle/service/hid/controllers/debug_pad.cpp index ac9b23bb8..e76c83aee 100644 --- a/src/core/hle/service/hid/controllers/debug_pad.cpp +++ b/src/core/hle/service/hid/controllers/debug_pad.cpp @@ -6,9 +6,14 @@ #include "common/common_types.h" #include "core/core_timing.h" #include "core/hle/service/hid/controllers/debug_pad.h" +#include "core/settings.h" namespace Service::HID { +constexpr s32 HID_JOYSTICK_MAX = 0x7fff; +constexpr s32 HID_JOYSTICK_MIN = -0x7fff; +enum class JoystickId : std::size_t { Joystick_Left, Joystick_Right }; + Controller_DebugPad::Controller_DebugPad() = default; Controller_DebugPad::~Controller_DebugPad() = default; @@ -33,33 +38,43 @@ void Controller_DebugPad::OnUpdate(u8* data, std::size_t size) { cur_entry.sampling_number = last_entry.sampling_number + 1; cur_entry.sampling_number2 = cur_entry.sampling_number; - // TODO(ogniK): Update debug pad states cur_entry.attribute.connected.Assign(1); auto& pad = cur_entry.pad_state; - pad.a.Assign(0); - pad.b.Assign(0); - pad.x.Assign(0); - pad.y.Assign(0); - pad.l.Assign(0); - pad.r.Assign(0); - pad.zl.Assign(0); - pad.zr.Assign(0); - pad.plus.Assign(0); - pad.minus.Assign(0); - pad.d_left.Assign(0); - pad.d_up.Assign(0); - pad.d_right.Assign(0); - pad.d_down.Assign(0); - - cur_entry.l_stick.x = 0; - cur_entry.l_stick.y = 0; + using namespace Settings::NativeButton; + pad.a.Assign(buttons[A - BUTTON_HID_BEGIN]->GetStatus()); + pad.b.Assign(buttons[B - BUTTON_HID_BEGIN]->GetStatus()); + pad.x.Assign(buttons[X - BUTTON_HID_BEGIN]->GetStatus()); + pad.y.Assign(buttons[Y - BUTTON_HID_BEGIN]->GetStatus()); + pad.l.Assign(buttons[L - BUTTON_HID_BEGIN]->GetStatus()); + pad.r.Assign(buttons[R - BUTTON_HID_BEGIN]->GetStatus()); + pad.zl.Assign(buttons[ZL - BUTTON_HID_BEGIN]->GetStatus()); + pad.zr.Assign(buttons[ZR - BUTTON_HID_BEGIN]->GetStatus()); + pad.plus.Assign(buttons[Plus - BUTTON_HID_BEGIN]->GetStatus()); + pad.minus.Assign(buttons[Minus - BUTTON_HID_BEGIN]->GetStatus()); + pad.d_left.Assign(buttons[DLeft - BUTTON_HID_BEGIN]->GetStatus()); + pad.d_up.Assign(buttons[DUp - BUTTON_HID_BEGIN]->GetStatus()); + pad.d_right.Assign(buttons[DRight - BUTTON_HID_BEGIN]->GetStatus()); + pad.d_down.Assign(buttons[DDown - BUTTON_HID_BEGIN]->GetStatus()); - cur_entry.r_stick.x = 0; - cur_entry.r_stick.y = 0; + const auto [stick_l_x_f, stick_l_y_f] = + analogs[static_cast(JoystickId::Joystick_Left)]->GetStatus(); + const auto [stick_r_x_f, stick_r_y_f] = + analogs[static_cast(JoystickId::Joystick_Right)]->GetStatus(); + cur_entry.l_stick.x = static_cast(stick_l_x_f * HID_JOYSTICK_MAX); + cur_entry.l_stick.y = static_cast(stick_l_y_f * HID_JOYSTICK_MAX); + cur_entry.r_stick.x = static_cast(stick_r_x_f * HID_JOYSTICK_MAX); + cur_entry.r_stick.y = static_cast(stick_r_y_f * HID_JOYSTICK_MAX); std::memcpy(data, &shared_memory, sizeof(SharedMemory)); } -void Controller_DebugPad::OnLoadInputDevices() {} +void Controller_DebugPad::OnLoadInputDevices() { + std::transform(Settings::values.debug_pad_buttons.begin(), + Settings::values.debug_pad_buttons.end(), buttons.begin(), + Input::CreateDevice); + std::transform(Settings::values.debug_pad_analogs.begin(), + Settings::values.debug_pad_analogs.end(), analogs.begin(), + Input::CreateDevice); +} } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/debug_pad.h b/src/core/hle/service/hid/controllers/debug_pad.h index a41564b4d..68b734248 100644 --- a/src/core/hle/service/hid/controllers/debug_pad.h +++ b/src/core/hle/service/hid/controllers/debug_pad.h @@ -9,7 +9,9 @@ #include "common/common_funcs.h" #include "common/common_types.h" #include "common/swap.h" +#include "core/frontend/input.h" #include "core/hle/service/hid/controllers/controller_base.h" +#include "core/settings.h" namespace Service::HID { class Controller_DebugPad final : public ControllerBase { @@ -82,5 +84,10 @@ private: }; static_assert(sizeof(SharedMemory) == 0x400, "SharedMemory is an invalid size"); SharedMemory shared_memory{}; + + std::array, Settings::NativeButton::NUM_BUTTONS_HID> + buttons; + std::array, Settings::NativeAnalog::NUM_STICKS_HID> + analogs; }; } // namespace Service::HID -- cgit v1.2.3 From 0fd45e78f453c2afad4fe508c2fe181604ff821e Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Thu, 1 Nov 2018 22:01:36 -0400 Subject: hid: Add keyboard bindings for Keyboard controller --- src/core/hle/service/hid/controllers/keyboard.cpp | 19 +++++++++++++++++-- src/core/hle/service/hid/controllers/keyboard.h | 7 +++++++ 2 files changed, 24 insertions(+), 2 deletions(-) (limited to 'src/core/hle') diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/core/hle/service/hid/controllers/keyboard.cpp index ccfbce9ac..088f00b43 100644 --- a/src/core/hle/service/hid/controllers/keyboard.cpp +++ b/src/core/hle/service/hid/controllers/keyboard.cpp @@ -6,6 +6,7 @@ #include "common/common_types.h" #include "core/core_timing.h" #include "core/hle/service/hid/controllers/keyboard.h" +#include "core/settings.h" namespace Service::HID { constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3800; @@ -34,10 +35,24 @@ void Controller_Keyboard::OnUpdate(u8* data, std::size_t size) { cur_entry.sampling_number = last_entry.sampling_number + 1; cur_entry.sampling_number2 = cur_entry.sampling_number; - // TODO(ogniK): Update keyboard states + + for (std::size_t i = 0; i < keyboard_keys.size(); ++i) { + for (std::size_t k = 0; k < 8; ++k) { + cur_entry.key[i / 8] |= (keyboard_keys[i]->GetStatus() << k); + } + } + + for (std::size_t i = 0; i < keyboard_mods.size(); ++i) { + cur_entry.modifier |= (keyboard_mods[i]->GetStatus() << i); + } std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory)); } -void Controller_Keyboard::OnLoadInputDevices() {} +void Controller_Keyboard::OnLoadInputDevices() { + std::transform(Settings::values.keyboard_keys.begin(), Settings::values.keyboard_keys.end(), + keyboard_keys.begin(), Input::CreateDevice); + std::transform(Settings::values.keyboard_mods.begin(), Settings::values.keyboard_mods.end(), + keyboard_mods.begin(), Input::CreateDevice); +} } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/keyboard.h b/src/core/hle/service/hid/controllers/keyboard.h index 493e68fce..f52775456 100644 --- a/src/core/hle/service/hid/controllers/keyboard.h +++ b/src/core/hle/service/hid/controllers/keyboard.h @@ -8,7 +8,9 @@ #include "common/common_funcs.h" #include "common/common_types.h" #include "common/swap.h" +#include "core/frontend/input.h" #include "core/hle/service/hid/controllers/controller_base.h" +#include "core/settings.h" namespace Service::HID { class Controller_Keyboard final : public ControllerBase { @@ -46,5 +48,10 @@ private: }; static_assert(sizeof(SharedMemory) == 0x400, "SharedMemory is an invalid size"); SharedMemory shared_memory{}; + + std::array, Settings::NativeKeyboard::NumKeyboardKeys> + keyboard_keys; + std::array, Settings::NativeKeyboard::NumKeyboardMods> + keyboard_mods; }; } // namespace Service::HID -- cgit v1.2.3 From 3b25426bd95423f74bca25145c67e350d3745d5a Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Thu, 1 Nov 2018 22:01:59 -0400 Subject: hid: Add controller bindings for Mouse controller --- src/core/hle/service/hid/controllers/mouse.cpp | 25 ++++++++++++++++++++++--- src/core/hle/service/hid/controllers/mouse.h | 9 ++++++++- 2 files changed, 30 insertions(+), 4 deletions(-) (limited to 'src/core/hle') diff --git a/src/core/hle/service/hid/controllers/mouse.cpp b/src/core/hle/service/hid/controllers/mouse.cpp index 4e246a57d..63391dbe9 100644 --- a/src/core/hle/service/hid/controllers/mouse.cpp +++ b/src/core/hle/service/hid/controllers/mouse.cpp @@ -5,6 +5,7 @@ #include #include "common/common_types.h" #include "core/core_timing.h" +#include "core/frontend/emu_window.h" #include "core/hle/service/hid/controllers/mouse.h" namespace Service::HID { @@ -14,7 +15,6 @@ Controller_Mouse::Controller_Mouse() = default; Controller_Mouse::~Controller_Mouse() = default; void Controller_Mouse::OnInit() {} - void Controller_Mouse::OnRelease() {} void Controller_Mouse::OnUpdate(u8* data, std::size_t size) { @@ -34,10 +34,29 @@ void Controller_Mouse::OnUpdate(u8* data, std::size_t size) { cur_entry.sampling_number = last_entry.sampling_number + 1; cur_entry.sampling_number2 = cur_entry.sampling_number; - // TODO(ogniK): Update mouse states + + if (Settings::values.mouse_enabled) { + const auto [px, py, sx, sy] = mouse_device->GetStatus(); + const auto x = static_cast(px * Layout::ScreenUndocked::Width); + const auto y = static_cast(py * Layout::ScreenUndocked::Height); + cur_entry.x = x; + cur_entry.y = y; + cur_entry.delta_x = x - last_entry.x; + cur_entry.delta_y = y - last_entry.y; + cur_entry.mouse_wheel_x = sx; + cur_entry.mouse_wheel_y = sy; + + for (std::size_t i = 0; i < mouse_button_devices.size(); ++i) { + cur_entry.button |= (mouse_button_devices[i]->GetStatus() << i); + } + } std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory)); } -void Controller_Mouse::OnLoadInputDevices() {} +void Controller_Mouse::OnLoadInputDevices() { + mouse_device = Input::CreateDevice(Settings::values.mouse_device); + std::transform(Settings::values.mouse_buttons.begin(), Settings::values.mouse_buttons.end(), + mouse_button_devices.begin(), Input::CreateDevice); +} } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/mouse.h b/src/core/hle/service/hid/controllers/mouse.h index 543b0b71f..70b654d07 100644 --- a/src/core/hle/service/hid/controllers/mouse.h +++ b/src/core/hle/service/hid/controllers/mouse.h @@ -7,7 +7,9 @@ #include #include "common/common_types.h" #include "common/swap.h" +#include "core/frontend/input.h" #include "core/hle/service/hid/controllers/controller_base.h" +#include "core/settings.h" namespace Service::HID { class Controller_Mouse final : public ControllerBase { @@ -35,7 +37,8 @@ private: s32_le y; s32_le delta_x; s32_le delta_y; - s32_le mouse_wheel; + s32_le mouse_wheel_x; + s32_le mouse_wheel_y; s32_le button; s32_le attribute; }; @@ -46,5 +49,9 @@ private: std::array mouse_states; }; SharedMemory shared_memory{}; + + std::unique_ptr mouse_device; + std::array, Settings::NativeMouseButton::NumMouseButtons> + mouse_button_devices; }; } // namespace Service::HID -- cgit v1.2.3 From e9145c3e1671d0a3d2293e5b11f70649918a3d45 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Thu, 1 Nov 2018 22:02:44 -0400 Subject: hid/touchscreen: Update Touchscreen to use advanced parameters Including finger ID, diamater x/y, and angle. Additionally, checks if the touchscreen is enabled. --- src/core/hle/service/hid/controllers/touchscreen.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/core/hle') diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/core/hle/service/hid/controllers/touchscreen.cpp index 07244fe4e..8b9763de6 100644 --- a/src/core/hle/service/hid/controllers/touchscreen.cpp +++ b/src/core/hle/service/hid/controllers/touchscreen.cpp @@ -42,19 +42,19 @@ void Controller_Touchscreen::OnUpdate(u8* data, std::size_t size) { const auto [x, y, pressed] = touch_device->GetStatus(); auto& touch_entry = cur_entry.states[0]; touch_entry.attribute.raw = 0; - if (pressed) { + if (pressed && Settings::values.touchscreen.enabled) { if (cur_entry.entry_count == 0) { touch_entry.attribute.start_touch.Assign(1); } touch_entry.x = static_cast(x * Layout::ScreenUndocked::Width); touch_entry.y = static_cast(y * Layout::ScreenUndocked::Height); - touch_entry.diameter_x = 15; - touch_entry.diameter_y = 15; - touch_entry.rotation_angle = 0; + touch_entry.diameter_x = Settings::values.touchscreen.diameter_x; + touch_entry.diameter_y = Settings::values.touchscreen.diameter_y; + touch_entry.rotation_angle = Settings::values.touchscreen.rotation_angle; const u64 tick = CoreTiming::GetTicks(); touch_entry.delta_time = tick - last_touch; last_touch = tick; - touch_entry.finger = 0; + touch_entry.finger = Settings::values.touchscreen.finger; cur_entry.entry_count = 1; } else { if (cur_entry.entry_count == 1) { @@ -67,6 +67,6 @@ void Controller_Touchscreen::OnUpdate(u8* data, std::size_t size) { } void Controller_Touchscreen::OnLoadInputDevices() { - touch_device = Input::CreateDevice(Settings::values.touch_device); + touch_device = Input::CreateDevice(Settings::values.touchscreen.device); } } // namespace Service::HID -- cgit v1.2.3 From 55ded706d67a6f2dd6e01d0abf7351e69588ac3a Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Thu, 1 Nov 2018 22:03:17 -0400 Subject: hid/npad: Update NPad to use player controller bindings and type --- src/core/hle/service/hid/controllers/npad.cpp | 154 +++++++++++++++++--------- src/core/hle/service/hid/controllers/npad.h | 9 +- 2 files changed, 108 insertions(+), 55 deletions(-) (limited to 'src/core/hle') diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 3eb59599f..911ba3574 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -17,11 +17,6 @@ #include "core/settings.h" namespace Service::HID { - -constexpr u32 JOYCON_BODY_NEON_RED = 0xFF3C28; -constexpr u32 JOYCON_BUTTONS_NEON_RED = 0x1E0A0A; -constexpr u32 JOYCON_BODY_NEON_BLUE = 0x0AB9E6; -constexpr u32 JOYCON_BUTTONS_NEON_BLUE = 0x001E1E; constexpr s32 HID_JOYSTICK_MAX = 0x7fff; constexpr s32 HID_JOYSTICK_MIN = -0x7fff; constexpr std::size_t NPAD_OFFSET = 0x9A00; @@ -40,6 +35,22 @@ enum class JoystickId : std::size_t { Joystick_Right, }; +static Controller_NPad::NPadControllerType MapSettingsTypeToNPad(Settings::ControllerType type) { + switch (type) { + case Settings::ControllerType::ProController: + return Controller_NPad::NPadControllerType::ProController; + case Settings::ControllerType::DualJoycon: + return Controller_NPad::NPadControllerType::JoyDual; + case Settings::ControllerType::LeftJoycon: + return Controller_NPad::NPadControllerType::JoyLeft; + case Settings::ControllerType::RightJoycon: + return Controller_NPad::NPadControllerType::JoyRight; + default: + UNREACHABLE(); + return Controller_NPad::NPadControllerType::JoyDual; + } +} + static std::size_t NPadIdToIndex(u32 npad_id) { switch (npad_id) { case 0: @@ -126,10 +137,11 @@ void Controller_NPad::InitNewlyAddedControler(std::size_t controller_idx) { controller.single_color.button_color = 0; controller.dual_color_error = ColorReadError::ReadOk; - controller.left_color.body_color = JOYCON_BODY_NEON_BLUE; - controller.left_color.button_color = JOYCON_BUTTONS_NEON_BLUE; - controller.right_color.body_color = JOYCON_BODY_NEON_RED; - controller.right_color.button_color = JOYCON_BUTTONS_NEON_RED; + controller.left_color.body_color = Settings::values.players[controller_idx].body_color_left; + controller.left_color.button_color = Settings::values.players[controller_idx].button_color_left; + controller.right_color.body_color = Settings::values.players[controller_idx].body_color_right; + controller.right_color.button_color = + Settings::values.players[controller_idx].button_color_right; controller.battery_level[0] = BATTERY_FULL; controller.battery_level[1] = BATTERY_FULL; @@ -154,6 +166,25 @@ void Controller_NPad::OnInit() { style.pro_controller.Assign(1); style.pokeball.Assign(1); } + + std::transform( + Settings::values.players.begin(), Settings::values.players.end(), + connected_controllers.begin(), [](const Settings::PlayerInput& player) { + return ControllerHolder{MapSettingsTypeToNPad(player.type), player.connected}; + }); + + std::stable_partition(connected_controllers.begin(), connected_controllers.begin() + 8, + [](const ControllerHolder& holder) { return holder.is_connected; }); + + // Account for handheld + if (connected_controllers[8].is_connected) + connected_controllers[8].type = NPadControllerType::Handheld; + + supported_npad_id_types.resize(npad_id_list.size()); + std::memcpy(supported_npad_id_types.data(), npad_id_list.data(), + npad_id_list.size() * sizeof(u32)); + + // Add a default dual joycon controller if none are present. if (std::none_of(connected_controllers.begin(), connected_controllers.end(), [](const ControllerHolder& controller) { return controller.is_connected; })) { supported_npad_id_types.resize(npad_id_list.size()); @@ -161,15 +192,25 @@ void Controller_NPad::OnInit() { npad_id_list.size() * sizeof(u32)); AddNewController(PREFERRED_CONTROLLER); } + + for (std::size_t i = 0; i < connected_controllers.size(); ++i) { + const auto& controller = connected_controllers[i]; + if (controller.is_connected) { + AddNewControllerAt(controller.type, IndexToNPad(i)); + } + } } void Controller_NPad::OnLoadInputDevices() { - std::transform(Settings::values.buttons.begin() + Settings::NativeButton::BUTTON_HID_BEGIN, - Settings::values.buttons.begin() + Settings::NativeButton::BUTTON_HID_END, - buttons.begin(), Input::CreateDevice); - std::transform(Settings::values.analogs.begin() + Settings::NativeAnalog::STICK_HID_BEGIN, - Settings::values.analogs.begin() + Settings::NativeAnalog::STICK_HID_END, - sticks.begin(), Input::CreateDevice); + const auto& players = Settings::values.players; + for (std::size_t i = 0; i < players.size(); ++i) { + std::transform(players[i].buttons.begin() + Settings::NativeButton::BUTTON_HID_BEGIN, + players[i].buttons.begin() + Settings::NativeButton::BUTTON_HID_END, + buttons[i].begin(), Input::CreateDevice); + std::transform(players[i].analogs.begin() + Settings::NativeAnalog::STICK_HID_BEGIN, + players[i].analogs.begin() + Settings::NativeAnalog::STICK_HID_END, + sticks[i].begin(), Input::CreateDevice); + } } void Controller_NPad::OnRelease() {} @@ -183,42 +224,45 @@ void Controller_NPad::RequestPadStateUpdate(u32 npad_id) { auto& pad_state = npad_pad_states[controller_idx].pad_states; auto& lstick_entry = npad_pad_states[controller_idx].l_stick; auto& rstick_entry = npad_pad_states[controller_idx].r_stick; + const auto& button_state = buttons[controller_idx]; + const auto& analog_state = sticks[controller_idx]; + using namespace Settings::NativeButton; - pad_state.a.Assign(buttons[A - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.b.Assign(buttons[B - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.x.Assign(buttons[X - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.y.Assign(buttons[Y - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.l_stick.Assign(buttons[LStick - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.r_stick.Assign(buttons[RStick - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.l.Assign(buttons[L - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.r.Assign(buttons[R - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.zl.Assign(buttons[ZL - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.zr.Assign(buttons[ZR - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.plus.Assign(buttons[Plus - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.minus.Assign(buttons[Minus - BUTTON_HID_BEGIN]->GetStatus()); - - pad_state.d_left.Assign(buttons[DLeft - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.d_up.Assign(buttons[DUp - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.d_right.Assign(buttons[DRight - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.d_down.Assign(buttons[DDown - BUTTON_HID_BEGIN]->GetStatus()); - - pad_state.l_stick_left.Assign(buttons[LStick_Left - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.l_stick_up.Assign(buttons[LStick_Up - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.l_stick_right.Assign(buttons[LStick_Right - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.l_stick_down.Assign(buttons[LStick_Down - BUTTON_HID_BEGIN]->GetStatus()); - - pad_state.r_stick_left.Assign(buttons[RStick_Left - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.r_stick_up.Assign(buttons[RStick_Up - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.r_stick_right.Assign(buttons[RStick_Right - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.r_stick_down.Assign(buttons[RStick_Down - BUTTON_HID_BEGIN]->GetStatus()); - - pad_state.left_sl.Assign(buttons[SL - BUTTON_HID_BEGIN]->GetStatus()); - pad_state.left_sr.Assign(buttons[SR - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.a.Assign(button_state[A - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.b.Assign(button_state[B - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.x.Assign(button_state[X - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.y.Assign(button_state[Y - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.l_stick.Assign(button_state[LStick - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.r_stick.Assign(button_state[RStick - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.l.Assign(button_state[L - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.r.Assign(button_state[R - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.zl.Assign(button_state[ZL - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.zr.Assign(button_state[ZR - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.plus.Assign(button_state[Plus - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.minus.Assign(button_state[Minus - BUTTON_HID_BEGIN]->GetStatus()); + + pad_state.d_left.Assign(button_state[DLeft - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.d_up.Assign(button_state[DUp - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.d_right.Assign(button_state[DRight - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.d_down.Assign(button_state[DDown - BUTTON_HID_BEGIN]->GetStatus()); + + pad_state.l_stick_left.Assign(button_state[LStick_Left - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.l_stick_up.Assign(button_state[LStick_Up - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.l_stick_right.Assign(button_state[LStick_Right - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.l_stick_down.Assign(button_state[LStick_Down - BUTTON_HID_BEGIN]->GetStatus()); + + pad_state.r_stick_left.Assign(button_state[RStick_Left - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.r_stick_up.Assign(button_state[RStick_Up - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.r_stick_right.Assign(button_state[RStick_Right - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.r_stick_down.Assign(button_state[RStick_Down - BUTTON_HID_BEGIN]->GetStatus()); + + pad_state.left_sl.Assign(button_state[SL - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.left_sr.Assign(button_state[SR - BUTTON_HID_BEGIN]->GetStatus()); const auto [stick_l_x_f, stick_l_y_f] = - sticks[static_cast(JoystickId::Joystick_Left)]->GetStatus(); + analog_state[static_cast(JoystickId::Joystick_Left)]->GetStatus(); const auto [stick_r_x_f, stick_r_y_f] = - sticks[static_cast(JoystickId::Joystick_Right)]->GetStatus(); + analog_state[static_cast(JoystickId::Joystick_Right)]->GetStatus(); lstick_entry.x = static_cast(stick_l_x_f * HID_JOYSTICK_MAX); lstick_entry.y = static_cast(stick_l_y_f * HID_JOYSTICK_MAX); rstick_entry.x = static_cast(stick_r_x_f * HID_JOYSTICK_MAX); @@ -285,8 +329,10 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) { state.d_left.Assign(pad_state.pad_states.d_up.Value()); state.d_right.Assign(pad_state.pad_states.d_down.Value()); state.d_up.Assign(pad_state.pad_states.d_right.Value()); - state.l.Assign(pad_state.pad_states.l.Value() | pad_state.pad_states.sl.Value()); - state.r.Assign(pad_state.pad_states.r.Value() | pad_state.pad_states.sr.Value()); + state.l.Assign(pad_state.pad_states.l.Value() | + pad_state.pad_states.left_sl.Value()); + state.r.Assign(pad_state.pad_states.r.Value() | + pad_state.pad_states.left_sr.Value()); state.zl.Assign(pad_state.pad_states.zl.Value()); state.plus.Assign(pad_state.pad_states.minus.Value()); @@ -302,8 +348,10 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) { state.b.Assign(pad_state.pad_states.y.Value()); state.y.Assign(pad_state.pad_states.b.Value()); - state.l.Assign(pad_state.pad_states.l.Value() | pad_state.pad_states.sl.Value()); - state.r.Assign(pad_state.pad_states.r.Value() | pad_state.pad_states.sr.Value()); + state.l.Assign(pad_state.pad_states.l.Value() | + pad_state.pad_states.right_sl.Value()); + state.r.Assign(pad_state.pad_states.r.Value() | + pad_state.pad_states.right_sr.Value()); state.zr.Assign(pad_state.pad_states.zr.Value()); state.plus.Assign(pad_state.pad_states.plus.Value()); @@ -570,7 +618,7 @@ Controller_NPad::NPadControllerType Controller_NPad::DecideBestController( if (IsControllerSupported(priority)) { return priority; } - const auto is_docked = Settings::values->use_docked_mode; + const auto is_docked = Settings::values.use_docked_mode; if (is_docked && priority == NPadControllerType::Handheld) { priority = NPadControllerType::JoyDual; if (IsControllerSupported(priority)) { @@ -659,7 +707,7 @@ bool Controller_NPad::IsControllerSupported(NPadControllerType controller) { return false; } // Handheld should not be supported in docked mode - if (Settings::values->use_docked_mode) { + if (Settings::values.use_docked_mode) { return false; } } diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 7222bca72..52f92a4f1 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -285,9 +285,14 @@ private: NPadType style{}; std::array shared_memory_entries{}; - std::array, Settings::NativeButton::NUM_BUTTONS_HID> + std::array< + std::array, Settings::NativeButton::NUM_BUTTONS_HID>, + 10> buttons; - std::array, Settings::NativeAnalog::NUM_STICKS_HID> sticks; + std::array< + std::array, Settings::NativeAnalog::NUM_STICKS_HID>, + 10> + sticks; std::vector supported_npad_id_types{}; NpadHoldType hold_type{NpadHoldType::Vertical}; Kernel::SharedPtr styleset_changed_event; -- cgit v1.2.3 From 3a6cd5b3c8dec11cc88c6aebdc4773233f615c91 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Sat, 3 Nov 2018 12:55:39 -0400 Subject: hid: Use player-defined controller type as PREFERRED_CONTROLLER --- src/core/hle/service/hid/controllers/keyboard.cpp | 5 +- src/core/hle/service/hid/controllers/npad.cpp | 213 +++++---------------- src/core/hle/service/hid/controllers/npad.h | 11 +- .../hle/service/hid/controllers/touchscreen.cpp | 6 - src/core/settings.cpp | 50 +++++ src/core/settings.h | 44 +---- src/yuzu/configuration/config.cpp | 127 +++++++----- src/yuzu/configuration/config.h | 10 + src/yuzu/configuration/configure_input.cpp | 27 +-- src/yuzu/configuration/configure_input.h | 2 +- src/yuzu/configuration/configure_input_player.cpp | 6 +- src/yuzu/configuration/configure_input_player.h | 4 +- .../configuration/configure_mouse_advanced.cpp | 6 +- src/yuzu/configuration/configure_mouse_advanced.h | 4 +- .../configure_touchscreen_advanced.cpp | 14 +- .../configuration/configure_touchscreen_advanced.h | 1 + 16 files changed, 234 insertions(+), 296 deletions(-) (limited to 'src/core/hle') diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/core/hle/service/hid/controllers/keyboard.cpp index 088f00b43..ca75adc2b 100644 --- a/src/core/hle/service/hid/controllers/keyboard.cpp +++ b/src/core/hle/service/hid/controllers/keyboard.cpp @@ -10,6 +10,7 @@ namespace Service::HID { constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3800; +constexpr u8 KEYS_PER_BYTE = 8; Controller_Keyboard::Controller_Keyboard() = default; Controller_Keyboard::~Controller_Keyboard() = default; @@ -37,8 +38,8 @@ void Controller_Keyboard::OnUpdate(u8* data, std::size_t size) { cur_entry.sampling_number2 = cur_entry.sampling_number; for (std::size_t i = 0; i < keyboard_keys.size(); ++i) { - for (std::size_t k = 0; k < 8; ++k) { - cur_entry.key[i / 8] |= (keyboard_keys[i]->GetStatus() << k); + for (std::size_t k = 0; k < KEYS_PER_BYTE; ++k) { + cur_entry.key[i / KEYS_PER_BYTE] |= (keyboard_keys[i]->GetStatus() << k); } } diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 911ba3574..46604887c 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -21,13 +21,9 @@ constexpr s32 HID_JOYSTICK_MAX = 0x7fff; constexpr s32 HID_JOYSTICK_MIN = -0x7fff; constexpr std::size_t NPAD_OFFSET = 0x9A00; constexpr u32 BATTERY_FULL = 2; -constexpr u32 NPAD_HANDHELD = 32; -constexpr u32 NPAD_UNKNOWN = 16; // TODO(ogniK): What is this? constexpr u32 MAX_NPAD_ID = 7; -constexpr Controller_NPad::NPadControllerType PREFERRED_CONTROLLER = - Controller_NPad::NPadControllerType::JoyDual; constexpr std::array npad_id_list{ - 0, 1, 2, 3, 4, 5, 6, 7, 32, 16, + 0, 1, 2, 3, 4, 5, 6, 7, NPAD_HANDHELD, NPAD_UNKNOWN, }; enum class JoystickId : std::size_t { @@ -51,7 +47,7 @@ static Controller_NPad::NPadControllerType MapSettingsTypeToNPad(Settings::Contr } } -static std::size_t NPadIdToIndex(u32 npad_id) { +std::size_t Controller_NPad::NPadIdToIndex(u32 npad_id) { switch (npad_id) { case 0: case 1: @@ -74,6 +70,27 @@ static std::size_t NPadIdToIndex(u32 npad_id) { } } +u32 Controller_NPad::IndexToNPad(std::size_t index) { + switch (index) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + return static_cast(index); + case 8: + return NPAD_HANDHELD; + case 9: + return NPAD_UNKNOWN; + default: + UNIMPLEMENTED_MSG("Unknown npad index {}", index); + return 0; + }; +} + Controller_NPad::Controller_NPad() = default; Controller_NPad::~Controller_NPad() = default; @@ -190,7 +207,7 @@ void Controller_NPad::OnInit() { supported_npad_id_types.resize(npad_id_list.size()); std::memcpy(supported_npad_id_types.data(), npad_id_list.data(), npad_id_list.size() * sizeof(u32)); - AddNewController(PREFERRED_CONTROLLER); + AddNewController(NPadControllerType::JoyDual); } for (std::size_t i = 0; i < connected_controllers.size(); ++i) { @@ -391,9 +408,9 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) { libnx_entry.connection_status.IsRightJoyConnected.Assign(1); libnx_entry.connection_status.IsConnected.Assign(1); - dual_entry.pad_states.raw = pad_state.raw; - dual_entry.l_stick = lstick_entry; - dual_entry.r_stick = rstick_entry; + dual_entry.pad.pad_states.raw = pad_state.pad_states.raw; + dual_entry.pad.l_stick = pad_state.l_stick; + dual_entry.pad.r_stick = pad_state.r_stick; break; case NPadControllerType::JoyLeft: left_entry.connection_status.raw = 0; @@ -461,23 +478,24 @@ void Controller_NPad::SetSupportedNPadIdTypes(u8* data, std::size_t length) { if (!controller.is_connected) { continue; } - if (!IsControllerSupported(PREFERRED_CONTROLLER)) { - const auto best_type = DecideBestController(PREFERRED_CONTROLLER); - const bool is_handheld = (best_type == NPadControllerType::Handheld || - PREFERRED_CONTROLLER == NPadControllerType::Handheld); + const auto requested_controller = + i <= MAX_NPAD_ID ? MapSettingsTypeToNPad(Settings::values.players[i].type) + : NPadControllerType::Handheld; + if (!IsControllerSupported(requested_controller)) { + const auto is_handheld = requested_controller == NPadControllerType::Handheld; if (is_handheld) { controller.type = NPadControllerType::None; controller.is_connected = false; - AddNewController(best_type); + AddNewController(requested_controller); } else { - controller.type = best_type; + controller.type = requested_controller; InitNewlyAddedControler(i); } had_controller_update = true; } - } - if (had_controller_update) { - styleset_changed_event->Signal(); + if (had_controller_update) { + styleset_changed_event->Signal(); + } } } @@ -530,50 +548,6 @@ Controller_NPad::Vibration Controller_NPad::GetLastVibration() const { return last_processed_vibration; } -std::size_t Controller_NPad::NPadIdToIndex(u32 npad_id) { - switch (npad_id) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - return static_cast(npad_id); - case 8: - case 32: - return 8; - case 9: - case 16: - return 9; - default: - UNIMPLEMENTED_MSG("Unknown npad id {}", npad_id); - return 0; - } -} - -u32 Controller_NPad::IndexToNPad(std::size_t index) { - switch (index) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - return static_cast(index); - case 8: - return 32; - case 9: - return 16; - default: - UNIMPLEMENTED_MSG("Unknown npad index {}", index); - return 0; - }; -} - void Controller_NPad::AddNewController(NPadControllerType controller) { controller = DecideBestController(controller); if (controller == NPadControllerType::Handheld) { @@ -596,13 +570,13 @@ void Controller_NPad::AddNewController(NPadControllerType controller) { void Controller_NPad::AddNewControllerAt(NPadControllerType controller, u32 npad_id) { controller = DecideBestController(controller); if (controller == NPadControllerType::Handheld) { - connected_controllers[8] = {controller, true}; - InitNewlyAddedControler(8); + connected_controllers[NPadIdToIndex(NPAD_HANDHELD)] = {controller, true}; + InitNewlyAddedControler(NPadIdToIndex(NPAD_HANDHELD)); return; } - const size_t controller_id = static_cast(npad_id); - connected_controllers[controller_id] = {controller, true}; - InitNewlyAddedControler(controller_id); + + connected_controllers[npad_id] = {controller, true}; + InitNewlyAddedControler(npad_id); } void Controller_NPad::ConnectNPad(u32 npad_id) { @@ -613,97 +587,11 @@ void Controller_NPad::DisconnectNPad(u32 npad_id) { connected_controllers[NPadIdToIndex(npad_id)].is_connected = false; } -Controller_NPad::NPadControllerType Controller_NPad::DecideBestController( - NPadControllerType priority) { - if (IsControllerSupported(priority)) { - return priority; - } - const auto is_docked = Settings::values.use_docked_mode; - if (is_docked && priority == NPadControllerType::Handheld) { - priority = NPadControllerType::JoyDual; - if (IsControllerSupported(priority)) { - return priority; - } - } - std::vector priority_list{}; - switch (priority) { - case NPadControllerType::ProController: - priority_list.push_back(NPadControllerType::JoyDual); - if (!is_docked) { - priority_list.push_back(NPadControllerType::Handheld); - } - priority_list.push_back(NPadControllerType::JoyLeft); - priority_list.push_back(NPadControllerType::JoyRight); - priority_list.push_back(NPadControllerType::Pokeball); - break; - case NPadControllerType::Handheld: - priority_list.push_back(NPadControllerType::JoyDual); - priority_list.push_back(NPadControllerType::ProController); - priority_list.push_back(NPadControllerType::JoyLeft); - priority_list.push_back(NPadControllerType::JoyRight); - priority_list.push_back(NPadControllerType::Pokeball); - break; - case NPadControllerType::JoyDual: - if (!is_docked) { - priority_list.push_back(NPadControllerType::Handheld); - } - priority_list.push_back(NPadControllerType::ProController); - priority_list.push_back(NPadControllerType::JoyLeft); - priority_list.push_back(NPadControllerType::JoyRight); - priority_list.push_back(NPadControllerType::Pokeball); - break; - case NPadControllerType::JoyLeft: - priority_list.push_back(NPadControllerType::JoyRight); - priority_list.push_back(NPadControllerType::JoyDual); - if (!is_docked) { - priority_list.push_back(NPadControllerType::Handheld); - } - priority_list.push_back(NPadControllerType::ProController); - priority_list.push_back(NPadControllerType::Pokeball); - break; - case NPadControllerType::JoyRight: - priority_list.push_back(NPadControllerType::JoyLeft); - priority_list.push_back(NPadControllerType::JoyDual); - if (!is_docked) { - priority_list.push_back(NPadControllerType::Handheld); - } - priority_list.push_back(NPadControllerType::ProController); - priority_list.push_back(NPadControllerType::Pokeball); - break; - case NPadControllerType::Pokeball: - priority_list.push_back(NPadControllerType::JoyLeft); - priority_list.push_back(NPadControllerType::JoyRight); - priority_list.push_back(NPadControllerType::JoyDual); - if (!is_docked) { - priority_list.push_back(NPadControllerType::Handheld); - } - priority_list.push_back(NPadControllerType::ProController); - break; - default: - priority_list.push_back(NPadControllerType::JoyDual); - if (!is_docked) { - priority_list.push_back(NPadControllerType::Handheld); - } - priority_list.push_back(NPadControllerType::ProController); - priority_list.push_back(NPadControllerType::JoyLeft); - priority_list.push_back(NPadControllerType::JoyRight); - priority_list.push_back(NPadControllerType::JoyDual); - } - - for (const auto controller_type : priority_list) { - if (IsControllerSupported(controller_type)) { - return controller_type; - } - } - UNIMPLEMENTED_MSG("Could not find supported controller!"); - return priority; -} - bool Controller_NPad::IsControllerSupported(NPadControllerType controller) { if (controller == NPadControllerType::Handheld) { // Handheld is not even a supported type, lets stop here - if (std::find(supported_npad_id_types.begin(), supported_npad_id_types.end(), 32) == - supported_npad_id_types.end()) { + if (std::find(supported_npad_id_types.begin(), supported_npad_id_types.end(), + NPAD_HANDHELD) == supported_npad_id_types.end()) { return false; } // Handheld should not be supported in docked mode @@ -761,13 +649,12 @@ void Controller_NPad::SetVibrationEnabled(bool can_vibrate) { } void Controller_NPad::ClearAllConnectedControllers() { - std::for_each(connected_controllers.begin(), connected_controllers.end(), - [](ControllerHolder& controller) { - if (controller.is_connected && controller.type != NPadControllerType::None) { - controller.type = NPadControllerType::None; - controller.is_connected = false; - } - }); + for (auto& controller : connected_controllers) { + if (controller.is_connected && controller.type != NPadControllerType::None) { + controller.type = NPadControllerType::None; + controller.is_connected = false; + } + } } void Controller_NPad::DisconnectAllConnectedControllers() { std::for_each(connected_controllers.begin(), connected_controllers.end(), diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 52f92a4f1..ea8057b80 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -5,13 +5,18 @@ #pragma once #include +#include "common/bit_field.h" #include "common/common_types.h" #include "core/frontend/input.h" +#include "core/hle/kernel/event.h" #include "core/hle/service/hid/controllers/controller_base.h" #include "core/settings.h" namespace Service::HID { +constexpr u32 NPAD_HANDHELD = 32; +constexpr u32 NPAD_UNKNOWN = 16; // TODO(ogniK): What is this? + class Controller_NPad final : public ControllerBase { public: Controller_NPad(); @@ -118,6 +123,9 @@ public: void ConnectAllDisconnectedControllers(); void ClearAllControllers(); + static std::size_t NPadIdToIndex(u32 npad_id); + static u32 IndexToNPad(std::size_t index); + private: struct CommonHeader { s64_le timestamp; @@ -304,10 +312,7 @@ private: bool IsControllerSupported(NPadControllerType controller) const; NPadControllerType DecideBestController(NPadControllerType priority) const; void RequestPadStateUpdate(u32 npad_id); - std::size_t NPadIdToIndex(u32 npad_id); - u32 IndexToNPad(std::size_t index); std::array npad_pad_states{}; - NPadControllerType DecideBestController(NPadControllerType priority); bool IsControllerSupported(NPadControllerType controller); }; } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/core/hle/service/hid/controllers/touchscreen.cpp index 8b9763de6..f666b1bd8 100644 --- a/src/core/hle/service/hid/controllers/touchscreen.cpp +++ b/src/core/hle/service/hid/controllers/touchscreen.cpp @@ -43,9 +43,6 @@ void Controller_Touchscreen::OnUpdate(u8* data, std::size_t size) { auto& touch_entry = cur_entry.states[0]; touch_entry.attribute.raw = 0; if (pressed && Settings::values.touchscreen.enabled) { - if (cur_entry.entry_count == 0) { - touch_entry.attribute.start_touch.Assign(1); - } touch_entry.x = static_cast(x * Layout::ScreenUndocked::Width); touch_entry.y = static_cast(y * Layout::ScreenUndocked::Height); touch_entry.diameter_x = Settings::values.touchscreen.diameter_x; @@ -57,9 +54,6 @@ void Controller_Touchscreen::OnUpdate(u8* data, std::size_t size) { touch_entry.finger = Settings::values.touchscreen.finger; cur_entry.entry_count = 1; } else { - if (cur_entry.entry_count == 1) { - touch_entry.attribute.end_touch.Assign(1); - } cur_entry.entry_count = 0; } diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 0da159559..26fcd3405 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -10,6 +10,56 @@ namespace Settings { +namespace NativeButton { +const std::array mapping = {{ + "button_a", + "button_b", + "button_x", + "button_y", + "button_lstick", + "button_rstick", + "button_l", + "button_r", + "button_zl", + "button_zr", + "button_plus", + "button_minus", + "button_dleft", + "button_dup", + "button_dright", + "button_ddown", + "button_lstick_left", + "button_lstick_up", + "button_lstick_right", + "button_lstick_down", + "button_rstick_left", + "button_rstick_up", + "button_rstick_right", + "button_rstick_down", + "button_sl", + "button_sr", + "button_home", + "button_screenshot", +}}; +} + +namespace NativeAnalog { +const std::array mapping = {{ + "lstick", + "rstick", +}}; +} + +namespace NativeMouseButton { +const std::array mapping = {{ + "left", + "right", + "middle", + "forward", + "back", +}}; +} + Values values = {}; void Apply() { diff --git a/src/core/settings.h b/src/core/settings.h index 9cc3c1dc8..e63134f80 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -60,36 +60,7 @@ constexpr int BUTTON_NS_END = NumButtons; constexpr int NUM_BUTTONS_HID = BUTTON_HID_END - BUTTON_HID_BEGIN; constexpr int NUM_BUTTONS_NS = BUTTON_NS_END - BUTTON_NS_BEGIN; -static const std::array mapping = {{ - "button_a", - "button_b", - "button_x", - "button_y", - "button_lstick", - "button_rstick", - "button_l", - "button_r", - "button_zl", - "button_zr", - "button_plus", - "button_minus", - "button_dleft", - "button_dup", - "button_dright", - "button_ddown", - "button_lstick_left", - "button_lstick_up", - "button_lstick_right", - "button_lstick_down", - "button_rstick_left", - "button_rstick_up", - "button_rstick_right", - "button_rstick_down", - "button_sl", - "button_sr", - "button_home", - "button_screenshot", -}}; +extern const std::array mapping; } // namespace NativeButton @@ -105,10 +76,7 @@ constexpr int STICK_HID_BEGIN = LStick; constexpr int STICK_HID_END = NumAnalogs; constexpr int NUM_STICKS_HID = NumAnalogs; -static const std::array mapping = {{ - "lstick", - "rstick", -}}; +extern const std::array mapping; } // namespace NativeAnalog namespace NativeMouseButton { @@ -126,13 +94,7 @@ constexpr int MOUSE_HID_BEGIN = Left; constexpr int MOUSE_HID_END = NumMouseButtons; constexpr int NUM_MOUSE_HID = NumMouseButtons; -static const std::array mapping = {{ - "left", - "right", - "middle", - "forward", - "back", -}}; +extern const std::array mapping; } // namespace NativeMouseButton namespace NativeKeyboard { diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index c931c7cd6..652f6a0b7 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -203,9 +203,8 @@ const std::array Config::default Qt::Key_Control, Qt::Key_Shift, Qt::Key_AltGr, Qt::Key_ApplicationRight, }; -void Config::ReadValues() { - qt_config->beginGroup("Controls"); - for (std::size_t p = 0; p < 10; ++p) { +void Config::ReadPlayerValues() { + for (std::size_t p = 0; p < Settings::values.players.size(); ++p) { Settings::values.players[p].connected = qt_config->value(QString("player_%1_connected").arg(p), false).toBool(); @@ -265,28 +264,9 @@ void Config::ReadValues() { std::stable_partition(Settings::values.players.begin(), Settings::values.players.end(), [](const auto& player) { return player.connected; }); +} - Settings::values.motion_device = - qt_config->value("motion_device", "engine:motion_emu,update_period:100,sensitivity:0.01") - .toString() - .toStdString(); - - Settings::values.mouse_enabled = qt_config->value("mouse_enabled", false).toBool(); - - for (int i = 0; i < Settings::NativeMouseButton::NumMouseButtons; ++i) { - std::string default_param = InputCommon::GenerateKeyboardParam(default_mouse_buttons[i]); - Settings::values.mouse_buttons[i] = - qt_config - ->value(QString("mouse_") + Settings::NativeMouseButton::mapping[i], - QString::fromStdString(default_param)) - .toString() - .toStdString(); - if (Settings::values.mouse_buttons[i].empty()) - Settings::values.mouse_buttons[i] = default_param; - } - - Settings::values.keyboard_enabled = qt_config->value("keyboard_enabled", false).toBool(); - +void Config::ReadDebugValues() { Settings::values.debug_pad_enabled = qt_config->value("debug_pad_enabled", false).toBool(); for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) { std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]); @@ -313,7 +293,38 @@ void Config::ReadValues() { if (Settings::values.debug_pad_analogs[i].empty()) Settings::values.debug_pad_analogs[i] = default_param; } +} + +void Config::ReadKeyboardValues() { + Settings::values.keyboard_enabled = qt_config->value("keyboard_enabled", false).toBool(); + std::transform(default_keyboard_keys.begin(), default_keyboard_keys.end(), + Settings::values.keyboard_keys.begin(), InputCommon::GenerateKeyboardParam); + std::transform(default_keyboard_mods.begin(), default_keyboard_mods.end(), + Settings::values.keyboard_keys.begin() + + Settings::NativeKeyboard::LeftControlKey, + InputCommon::GenerateKeyboardParam); + std::transform(default_keyboard_mods.begin(), default_keyboard_mods.end(), + Settings::values.keyboard_mods.begin(), InputCommon::GenerateKeyboardParam); +} + +void Config::ReadMouseValues() { + Settings::values.mouse_enabled = qt_config->value("mouse_enabled", false).toBool(); + + for (int i = 0; i < Settings::NativeMouseButton::NumMouseButtons; ++i) { + std::string default_param = InputCommon::GenerateKeyboardParam(default_mouse_buttons[i]); + Settings::values.mouse_buttons[i] = + qt_config + ->value(QString("mouse_") + Settings::NativeMouseButton::mapping[i], + QString::fromStdString(default_param)) + .toString() + .toStdString(); + if (Settings::values.mouse_buttons[i].empty()) + Settings::values.mouse_buttons[i] = default_param; + } +} + +void Config::ReadTouchscreenValues() { Settings::values.touchscreen.enabled = qt_config->value("touchscreen_enabled", true).toBool(); Settings::values.touchscreen.device = qt_config->value("touchscreen_device", "engine:emu_window").toString().toStdString(); @@ -325,6 +336,21 @@ void Config::ReadValues() { Settings::values.touchscreen.diameter_y = qt_config->value("touchscreen_diameter_y", 15).toUInt(); qt_config->endGroup(); +} + +void Config::ReadValues() { + qt_config->beginGroup("Controls"); + + ReadPlayerValues(); + ReadDebugValues(); + ReadKeyboardValues(); + ReadMouseValues(); + ReadTouchscreenValues(); + + Settings::values.motion_device = + qt_config->value("motion_device", "engine:motion_emu,update_period:100,sensitivity:0.01") + .toString() + .toStdString(); qt_config->beginGroup("Core"); Settings::values.use_cpu_jit = qt_config->value("use_cpu_jit", true).toBool(); @@ -370,15 +396,6 @@ void Config::ReadValues() { .toStdString()); qt_config->endGroup(); - std::transform(default_keyboard_keys.begin(), default_keyboard_keys.end(), - Settings::values.keyboard_keys.begin(), InputCommon::GenerateKeyboardParam); - std::transform(default_keyboard_mods.begin(), default_keyboard_mods.end(), - Settings::values.keyboard_keys.begin() + - Settings::NativeKeyboard::LeftControlKey, - InputCommon::GenerateKeyboardParam); - std::transform(default_keyboard_mods.begin(), default_keyboard_mods.end(), - Settings::values.keyboard_mods.begin(), InputCommon::GenerateKeyboardParam); - qt_config->beginGroup("Core"); Settings::values.use_cpu_jit = qt_config->value("use_cpu_jit", true).toBool(); Settings::values.use_multi_core = qt_config->value("use_multi_core", false).toBool(); @@ -488,9 +505,8 @@ void Config::ReadValues() { qt_config->endGroup(); } -void Config::SaveValues() { - qt_config->beginGroup("Controls"); - for (int p = 0; p < 10; ++p) { +void Config::SavePlayerValues() { + for (int p = 0; p < Settings::values.players.size(); ++p) { qt_config->setValue(QString("player_%1_connected").arg(p), Settings::values.players[p].connected); qt_config->setValue(QString("player_%1_type").arg(p), @@ -516,19 +532,9 @@ void Config::SaveValues() { QString::fromStdString(Settings::values.players[p].analogs[i])); } } +} - qt_config->setValue("motion_device", QString::fromStdString(Settings::values.motion_device)); - - qt_config->setValue("mouse_enabled", Settings::values.mouse_enabled); - - for (int i = 0; i < Settings::NativeMouseButton::NumMouseButtons; ++i) { - qt_config->setValue(QString("mouse_") + - QString::fromStdString(Settings::NativeMouseButton::mapping[i]), - QString::fromStdString(Settings::values.mouse_buttons[i])); - } - - qt_config->setValue("keyboard_enabled", Settings::values.keyboard_enabled); - +void Config::SaveDebugValues() { qt_config->setValue("debug_pad_enabled", Settings::values.debug_pad_enabled); for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) { qt_config->setValue(QString("debug_pad_") + @@ -540,7 +546,19 @@ void Config::SaveValues() { QString::fromStdString(Settings::NativeAnalog::mapping[i]), QString::fromStdString(Settings::values.debug_pad_analogs[i])); } +} + +void Config::SaveMouseValues() { + qt_config->setValue("mouse_enabled", Settings::values.mouse_enabled); + + for (int i = 0; i < Settings::NativeMouseButton::NumMouseButtons; ++i) { + qt_config->setValue(QString("mouse_") + + QString::fromStdString(Settings::NativeMouseButton::mapping[i]), + QString::fromStdString(Settings::values.mouse_buttons[i])); + } +} +void Config::SaveTouchscreenValues() { qt_config->setValue("touchscreen_enabled", Settings::values.touchscreen.enabled); qt_config->setValue("touchscreen_device", QString::fromStdString(Settings::values.touchscreen.device)); @@ -549,6 +567,19 @@ void Config::SaveValues() { qt_config->setValue("touchscreen_angle", Settings::values.touchscreen.rotation_angle); qt_config->setValue("touchscreen_diameter_x", Settings::values.touchscreen.diameter_x); qt_config->setValue("touchscreen_diameter_y", Settings::values.touchscreen.diameter_y); +} + +void Config::SaveValues() { + qt_config->beginGroup("Controls"); + + SavePlayerValues(); + SaveDebugValues(); + SaveMouseValues(); + SaveTouchscreenValues(); + + qt_config->setValue("motion_device", QString::fromStdString(Settings::values.motion_device)); + qt_config->setValue("keyboard_enabled", Settings::values.keyboard_enabled); + qt_config->endGroup(); qt_config->beginGroup("Core"); diff --git a/src/yuzu/configuration/config.h b/src/yuzu/configuration/config.h index 1facd6b55..a1c27bbf9 100644 --- a/src/yuzu/configuration/config.h +++ b/src/yuzu/configuration/config.h @@ -29,7 +29,17 @@ public: private: void ReadValues(); + void ReadPlayerValues(); + void ReadDebugValues(); + void ReadKeyboardValues(); + void ReadMouseValues(); + void ReadTouchscreenValues(); + void SaveValues(); + void SavePlayerValues(); + void SaveDebugValues(); + void SaveMouseValues(); + void SaveTouchscreenValues(); std::unique_ptr qt_config; std::string qt_config_loc; diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp index 9ae9827fe..a52abdd8f 100644 --- a/src/yuzu/configuration/configure_input.cpp +++ b/src/yuzu/configuration/configure_input.cpp @@ -11,6 +11,7 @@ #include "common/param_package.h" #include "configuration/configure_touchscreen_advanced.h" #include "core/core.h" +#include "core/hle/service/hid/controllers/npad.h" #include "input_common/main.h" #include "ui_configure_input.h" #include "ui_configure_input_player.h" @@ -83,9 +84,9 @@ ConfigureInput::ConfigureInput(QWidget* parent) } template -void ConfigureInput::CallConfigureDialog(Args... args) { +void ConfigureInput::CallConfigureDialog(Args&&... args) { this->applyConfiguration(); - Dialog dialog(this, args...); + Dialog dialog(this, std::forward(args)...); const auto res = dialog.exec(); if (res == QDialog::Accepted) { @@ -94,14 +95,16 @@ void ConfigureInput::CallConfigureDialog(Args... args) { } void ConfigureInput::applyConfiguration() { - for (std::size_t i = 0; i < 8; ++i) { + for (std::size_t i = 0; i < players_enabled.size(); ++i) { Settings::values.players[i].connected = players_enabled[i]->isChecked(); Settings::values.players[i].type = static_cast(player_controller[i]->currentIndex()); } Settings::values.use_docked_mode = ui->use_docked_mode->isChecked(); - Settings::values.players[8].connected = ui->handheld_connected->isChecked(); + Settings::values + .players[Service::HID::Controller_NPad::NPadIdToIndex(Service::HID::NPAD_HANDHELD)] + .connected = ui->handheld_connected->isChecked(); Settings::values.debug_pad_enabled = ui->debug_enabled->isChecked(); Settings::values.mouse_enabled = ui->mouse_enabled->isChecked(); Settings::values.keyboard_enabled = ui->keyboard_enabled->isChecked(); @@ -109,7 +112,7 @@ void ConfigureInput::applyConfiguration() { } void ConfigureInput::updateUIEnabled() { - for (std::size_t i = 0; i < 8; ++i) { + for (std::size_t i = 0; i < players_enabled.size(); ++i) { const auto enabled = players_enabled[i]->checkState() == Qt::Checked; player_controller[i]->setEnabled(enabled); @@ -118,10 +121,7 @@ void ConfigureInput::updateUIEnabled() { bool hit_disabled = false; for (auto* player : players_enabled) { - if (hit_disabled) - player->setDisabled(true); - else - player->setEnabled(true); + player->setDisabled(hit_disabled); if (!player->isChecked()) hit_disabled = true; } @@ -138,13 +138,16 @@ void ConfigureInput::loadConfiguration() { std::stable_partition(Settings::values.players.begin(), Settings::values.players.end(), [](const auto& player) { return player.connected; }); - for (std::size_t i = 0; i < 8; ++i) { + for (std::size_t i = 0; i < players_enabled.size(); ++i) { players_enabled[i]->setChecked(Settings::values.players[i].connected); player_controller[i]->setCurrentIndex(static_cast(Settings::values.players[i].type)); } ui->use_docked_mode->setChecked(Settings::values.use_docked_mode); - ui->handheld_connected->setChecked(Settings::values.players[8].connected); + ui->handheld_connected->setChecked( + Settings::values + .players[Service::HID::Controller_NPad::NPadIdToIndex(Service::HID::NPAD_HANDHELD)] + .connected); ui->debug_enabled->setChecked(Settings::values.debug_pad_enabled); ui->mouse_enabled->setChecked(Settings::values.mouse_enabled); ui->keyboard_enabled->setChecked(Settings::values.keyboard_enabled); @@ -157,7 +160,7 @@ void ConfigureInput::restoreDefaults() { players_enabled[0]->setCheckState(Qt::Checked); player_controller[0]->setCurrentIndex(1); - for (std::size_t i = 1; i < 8; ++i) { + for (std::size_t i = 1; i < players_enabled.size(); ++i) { players_enabled[i]->setCheckState(Qt::Unchecked); player_controller[i]->setCurrentIndex(0); } diff --git a/src/yuzu/configuration/configure_input.h b/src/yuzu/configuration/configure_input.h index 0ba77c5ef..51b8e609c 100644 --- a/src/yuzu/configuration/configure_input.h +++ b/src/yuzu/configuration/configure_input.h @@ -41,7 +41,7 @@ private: void updateUIEnabled(); template - void CallConfigureDialog(Args... args); + void CallConfigureDialog(Args&&... args); /// Load configuration settings. void loadConfiguration(); diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index 5de7dd962..995725b0f 100644 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp @@ -41,7 +41,7 @@ static void LayerGridElements(QGridLayout* grid, QWidget* item, QWidget* onTopOf grid->addWidget(item, row, column, rowSpan, columnSpan); } -static QString getKeyName(int key_code) { +static QString GetKeyName(int key_code) { switch (key_code) { case Qt::Key_Shift: return QObject::tr("Shift"); @@ -71,7 +71,7 @@ static QString ButtonToText(const Common::ParamPackage& param) { if (!param.Has("engine")) { return QObject::tr("[not set]"); } else if (param.Get("engine", "") == "keyboard") { - return getKeyName(param.Get("code", 0)); + return GetKeyName(param.Get("code", 0)); } else if (param.Get("engine", "") == "sdl") { if (param.Has("hat")) { return QString(QObject::tr("Hat %1 %2")) @@ -486,7 +486,7 @@ void ConfigureInputPlayer::setPollingResult(const Common::ParamPackage& params, } updateButtonLabels(); - input_setter = boost::none; + input_setter = std::nullopt; } void ConfigureInputPlayer::keyPressEvent(QKeyEvent* event) { diff --git a/src/yuzu/configuration/configure_input_player.h b/src/yuzu/configuration/configure_input_player.h index 67cc6a8ca..8248cd7de 100644 --- a/src/yuzu/configuration/configure_input_player.h +++ b/src/yuzu/configuration/configure_input_player.h @@ -7,11 +7,11 @@ #include #include #include +#include #include #include #include #include -#include #include "common/param_package.h" #include "core/settings.h" #include "input_common/main.h" @@ -44,7 +44,7 @@ private: std::unique_ptr poll_timer; /// This will be the the setting function when an input is awaiting configuration. - boost::optional> input_setter; + std::optional> input_setter; std::array buttons_param; std::array analogs_param; diff --git a/src/yuzu/configuration/configure_mouse_advanced.cpp b/src/yuzu/configuration/configure_mouse_advanced.cpp index 8cfcd1679..ac9c84096 100644 --- a/src/yuzu/configuration/configure_mouse_advanced.cpp +++ b/src/yuzu/configuration/configure_mouse_advanced.cpp @@ -16,7 +16,7 @@ #include "yuzu/configuration/config.h" #include "yuzu/configuration/configure_mouse_advanced.h" -static QString getKeyName(int key_code) { +static QString GetKeyName(int key_code) { switch (key_code) { case Qt::Key_Shift: return QObject::tr("Shift"); @@ -35,7 +35,7 @@ static QString ButtonToText(const Common::ParamPackage& param) { if (!param.Has("engine")) { return QObject::tr("[not set]"); } else if (param.Get("engine", "") == "keyboard") { - return getKeyName(param.Get("code", 0)); + return GetKeyName(param.Get("code", 0)); } else if (param.Get("engine", "") == "sdl") { if (param.Has("hat")) { return QString(QObject::tr("Hat %1 %2")) @@ -191,7 +191,7 @@ void ConfigureMouseAdvanced::setPollingResult(const Common::ParamPackage& params } updateButtonLabels(); - input_setter = boost::none; + input_setter = std::nullopt; } void ConfigureMouseAdvanced::keyPressEvent(QKeyEvent* event) { diff --git a/src/yuzu/configuration/configure_mouse_advanced.h b/src/yuzu/configuration/configure_mouse_advanced.h index f897d9044..983ac4158 100644 --- a/src/yuzu/configuration/configure_mouse_advanced.h +++ b/src/yuzu/configuration/configure_mouse_advanced.h @@ -5,9 +5,9 @@ #pragma once #include +#include #include #include -#include #include "core/settings.h" class QCheckBox; @@ -30,7 +30,7 @@ private: std::unique_ptr ui; /// This will be the the setting function when an input is awaiting configuration. - boost::optional> input_setter; + std::optional> input_setter; std::array button_map; std::array buttons_param; diff --git a/src/yuzu/configuration/configure_touchscreen_advanced.cpp b/src/yuzu/configuration/configure_touchscreen_advanced.cpp index 6cf3dab97..9c1561e9d 100644 --- a/src/yuzu/configuration/configure_touchscreen_advanced.cpp +++ b/src/yuzu/configuration/configure_touchscreen_advanced.cpp @@ -2,15 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include #include -#include -#include -#include -#include -#include "common/assert.h" -#include "common/param_package.h" -#include "input_common/main.h" #include "ui_configure_touchscreen_advanced.h" #include "yuzu/configuration/config.h" #include "yuzu/configuration/configure_touchscreen_advanced.h" @@ -22,10 +14,12 @@ ConfigureTouchscreenAdvanced::ConfigureTouchscreenAdvanced(QWidget* parent) connect(ui->restore_defaults_button, &QPushButton::pressed, this, &ConfigureTouchscreenAdvanced::restoreDefaults); - this->loadConfiguration(); - this->resize(0, 0); + loadConfiguration(); + resize(0, 0); } +ConfigureTouchscreenAdvanced::~ConfigureTouchscreenAdvanced() = default; + void ConfigureTouchscreenAdvanced::applyConfiguration() { Settings::values.touchscreen.finger = ui->finger_box->value(); Settings::values.touchscreen.diameter_x = ui->diameter_x_box->value(); diff --git a/src/yuzu/configuration/configure_touchscreen_advanced.h b/src/yuzu/configuration/configure_touchscreen_advanced.h index 938a62ed3..41cd255fb 100644 --- a/src/yuzu/configuration/configure_touchscreen_advanced.h +++ b/src/yuzu/configuration/configure_touchscreen_advanced.h @@ -18,6 +18,7 @@ class ConfigureTouchscreenAdvanced : public QDialog { public: explicit ConfigureTouchscreenAdvanced(QWidget* parent); + ~ConfigureTouchscreenAdvanced() override; void applyConfiguration(); -- cgit v1.2.3