diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/arm/cpu_interrupt_handler.cpp | 6 | ||||
| -rw-r--r-- | src/core/arm/cpu_interrupt_handler.h | 3 | ||||
| -rw-r--r-- | src/core/cpu_manager.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/npad.cpp | 235 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/npad.h | 11 | ||||
| -rw-r--r-- | src/core/hle/service/hid/hid.cpp | 14 | ||||
| -rw-r--r-- | src/core/settings.cpp | 50 | ||||
| -rw-r--r-- | src/core/settings.h | 339 |
8 files changed, 140 insertions, 520 deletions
diff --git a/src/core/arm/cpu_interrupt_handler.cpp b/src/core/arm/cpu_interrupt_handler.cpp index df0350881..9c8898700 100644 --- a/src/core/arm/cpu_interrupt_handler.cpp +++ b/src/core/arm/cpu_interrupt_handler.cpp | |||
| @@ -7,9 +7,7 @@ | |||
| 7 | 7 | ||
| 8 | namespace Core { | 8 | namespace Core { |
| 9 | 9 | ||
| 10 | CPUInterruptHandler::CPUInterruptHandler() : is_interrupted{} { | 10 | CPUInterruptHandler::CPUInterruptHandler() : interrupt_event{std::make_unique<Common::Event>()} {} |
| 11 | interrupt_event = std::make_unique<Common::Event>(); | ||
| 12 | } | ||
| 13 | 11 | ||
| 14 | CPUInterruptHandler::~CPUInterruptHandler() = default; | 12 | CPUInterruptHandler::~CPUInterruptHandler() = default; |
| 15 | 13 | ||
| @@ -17,7 +15,7 @@ void CPUInterruptHandler::SetInterrupt(bool is_interrupted_) { | |||
| 17 | if (is_interrupted_) { | 15 | if (is_interrupted_) { |
| 18 | interrupt_event->Set(); | 16 | interrupt_event->Set(); |
| 19 | } | 17 | } |
| 20 | this->is_interrupted = is_interrupted_; | 18 | is_interrupted = is_interrupted_; |
| 21 | } | 19 | } |
| 22 | 20 | ||
| 23 | void CPUInterruptHandler::AwaitInterrupt() { | 21 | void CPUInterruptHandler::AwaitInterrupt() { |
diff --git a/src/core/arm/cpu_interrupt_handler.h b/src/core/arm/cpu_interrupt_handler.h index 3d062d326..71e582f79 100644 --- a/src/core/arm/cpu_interrupt_handler.h +++ b/src/core/arm/cpu_interrupt_handler.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <atomic> | ||
| 7 | #include <memory> | 8 | #include <memory> |
| 8 | 9 | ||
| 9 | namespace Common { | 10 | namespace Common { |
| @@ -32,8 +33,8 @@ public: | |||
| 32 | void AwaitInterrupt(); | 33 | void AwaitInterrupt(); |
| 33 | 34 | ||
| 34 | private: | 35 | private: |
| 35 | bool is_interrupted{}; | ||
| 36 | std::unique_ptr<Common::Event> interrupt_event; | 36 | std::unique_ptr<Common::Event> interrupt_event; |
| 37 | std::atomic_bool is_interrupted{false}; | ||
| 37 | }; | 38 | }; |
| 38 | 39 | ||
| 39 | } // namespace Core | 40 | } // namespace Core |
diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp index ef0bae556..688b99eba 100644 --- a/src/core/cpu_manager.cpp +++ b/src/core/cpu_manager.cpp | |||
| @@ -328,7 +328,7 @@ void CpuManager::RunThread(std::size_t core) { | |||
| 328 | system.RegisterCoreThread(core); | 328 | system.RegisterCoreThread(core); |
| 329 | std::string name; | 329 | std::string name; |
| 330 | if (is_multicore) { | 330 | if (is_multicore) { |
| 331 | name = "yuzu:CoreCPUThread_" + std::to_string(core); | 331 | name = "yuzu:CPUCore_" + std::to_string(core); |
| 332 | } else { | 332 | } else { |
| 333 | name = "yuzu:CPUThread"; | 333 | name = "yuzu:CPUThread"; |
| 334 | } | 334 | } |
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 0e7794dc7..45fde8df2 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp | |||
| @@ -24,6 +24,7 @@ constexpr s32 HID_JOYSTICK_MAX = 0x7fff; | |||
| 24 | constexpr std::size_t NPAD_OFFSET = 0x9A00; | 24 | constexpr std::size_t NPAD_OFFSET = 0x9A00; |
| 25 | constexpr u32 BATTERY_FULL = 2; | 25 | constexpr u32 BATTERY_FULL = 2; |
| 26 | constexpr u32 MAX_NPAD_ID = 7; | 26 | constexpr u32 MAX_NPAD_ID = 7; |
| 27 | constexpr std::size_t HANDHELD_INDEX = 8; | ||
| 27 | constexpr std::array<u32, 10> npad_id_list{ | 28 | constexpr std::array<u32, 10> npad_id_list{ |
| 28 | 0, 1, 2, 3, 4, 5, 6, 7, NPAD_HANDHELD, NPAD_UNKNOWN, | 29 | 0, 1, 2, 3, 4, 5, 6, 7, NPAD_HANDHELD, NPAD_UNKNOWN, |
| 29 | }; | 30 | }; |
| @@ -33,19 +34,41 @@ enum class JoystickId : std::size_t { | |||
| 33 | Joystick_Right, | 34 | Joystick_Right, |
| 34 | }; | 35 | }; |
| 35 | 36 | ||
| 36 | static Controller_NPad::NPadControllerType MapSettingsTypeToNPad(Settings::ControllerType type) { | 37 | Controller_NPad::NPadControllerType Controller_NPad::MapSettingsTypeToNPad( |
| 38 | Settings::ControllerType type) { | ||
| 37 | switch (type) { | 39 | switch (type) { |
| 38 | case Settings::ControllerType::ProController: | 40 | case Settings::ControllerType::ProController: |
| 39 | return Controller_NPad::NPadControllerType::ProController; | 41 | return NPadControllerType::ProController; |
| 40 | case Settings::ControllerType::DualJoycon: | 42 | case Settings::ControllerType::DualJoyconDetached: |
| 41 | return Controller_NPad::NPadControllerType::JoyDual; | 43 | return NPadControllerType::JoyDual; |
| 42 | case Settings::ControllerType::LeftJoycon: | 44 | case Settings::ControllerType::LeftJoycon: |
| 43 | return Controller_NPad::NPadControllerType::JoyLeft; | 45 | return NPadControllerType::JoyLeft; |
| 44 | case Settings::ControllerType::RightJoycon: | 46 | case Settings::ControllerType::RightJoycon: |
| 45 | return Controller_NPad::NPadControllerType::JoyRight; | 47 | return NPadControllerType::JoyRight; |
| 48 | case Settings::ControllerType::Handheld: | ||
| 49 | return NPadControllerType::Handheld; | ||
| 46 | default: | 50 | default: |
| 47 | UNREACHABLE(); | 51 | UNREACHABLE(); |
| 48 | return Controller_NPad::NPadControllerType::JoyDual; | 52 | return NPadControllerType::ProController; |
| 53 | } | ||
| 54 | } | ||
| 55 | |||
| 56 | Settings::ControllerType Controller_NPad::MapNPadToSettingsType( | ||
| 57 | Controller_NPad::NPadControllerType type) { | ||
| 58 | switch (type) { | ||
| 59 | case NPadControllerType::ProController: | ||
| 60 | return Settings::ControllerType::ProController; | ||
| 61 | case NPadControllerType::JoyDual: | ||
| 62 | return Settings::ControllerType::DualJoyconDetached; | ||
| 63 | case NPadControllerType::JoyLeft: | ||
| 64 | return Settings::ControllerType::LeftJoycon; | ||
| 65 | case NPadControllerType::JoyRight: | ||
| 66 | return Settings::ControllerType::RightJoycon; | ||
| 67 | case NPadControllerType::Handheld: | ||
| 68 | return Settings::ControllerType::Handheld; | ||
| 69 | default: | ||
| 70 | UNREACHABLE(); | ||
| 71 | return Settings::ControllerType::ProController; | ||
| 49 | } | 72 | } |
| 50 | } | 73 | } |
| 51 | 74 | ||
| @@ -60,9 +83,9 @@ std::size_t Controller_NPad::NPadIdToIndex(u32 npad_id) { | |||
| 60 | case 6: | 83 | case 6: |
| 61 | case 7: | 84 | case 7: |
| 62 | return npad_id; | 85 | return npad_id; |
| 63 | case 8: | 86 | case HANDHELD_INDEX: |
| 64 | case NPAD_HANDHELD: | 87 | case NPAD_HANDHELD: |
| 65 | return 8; | 88 | return HANDHELD_INDEX; |
| 66 | case 9: | 89 | case 9: |
| 67 | case NPAD_UNKNOWN: | 90 | case NPAD_UNKNOWN: |
| 68 | return 9; | 91 | return 9; |
| @@ -83,7 +106,7 @@ u32 Controller_NPad::IndexToNPad(std::size_t index) { | |||
| 83 | case 6: | 106 | case 6: |
| 84 | case 7: | 107 | case 7: |
| 85 | return static_cast<u32>(index); | 108 | return static_cast<u32>(index); |
| 86 | case 8: | 109 | case HANDHELD_INDEX: |
| 87 | return NPAD_HANDHELD; | 110 | return NPAD_HANDHELD; |
| 88 | case 9: | 111 | case 9: |
| 89 | return NPAD_UNKNOWN; | 112 | return NPAD_UNKNOWN; |
| @@ -96,25 +119,35 @@ u32 Controller_NPad::IndexToNPad(std::size_t index) { | |||
| 96 | Controller_NPad::Controller_NPad(Core::System& system) : ControllerBase(system), system(system) {} | 119 | Controller_NPad::Controller_NPad(Core::System& system) : ControllerBase(system), system(system) {} |
| 97 | Controller_NPad::~Controller_NPad() = default; | 120 | Controller_NPad::~Controller_NPad() = default; |
| 98 | 121 | ||
| 99 | void Controller_NPad::InitNewlyAddedControler(std::size_t controller_idx) { | 122 | void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) { |
| 100 | const auto controller_type = connected_controllers[controller_idx].type; | 123 | const auto controller_type = connected_controllers[controller_idx].type; |
| 101 | auto& controller = shared_memory_entries[controller_idx]; | 124 | auto& controller = shared_memory_entries[controller_idx]; |
| 102 | if (controller_type == NPadControllerType::None) { | 125 | if (controller_type == NPadControllerType::None) { |
| 126 | styleset_changed_events[controller_idx].writable->Signal(); | ||
| 103 | return; | 127 | return; |
| 104 | } | 128 | } |
| 105 | controller.joy_styles.raw = 0; // Zero out | 129 | controller.joy_styles.raw = 0; // Zero out |
| 106 | controller.device_type.raw = 0; | 130 | controller.device_type.raw = 0; |
| 131 | controller.properties.raw = 0; | ||
| 107 | switch (controller_type) { | 132 | switch (controller_type) { |
| 108 | case NPadControllerType::None: | 133 | case NPadControllerType::None: |
| 109 | UNREACHABLE(); | 134 | UNREACHABLE(); |
| 110 | break; | 135 | break; |
| 136 | case NPadControllerType::ProController: | ||
| 137 | controller.joy_styles.pro_controller.Assign(1); | ||
| 138 | controller.device_type.pro_controller.Assign(1); | ||
| 139 | controller.properties.is_vertical.Assign(1); | ||
| 140 | controller.properties.use_plus.Assign(1); | ||
| 141 | controller.properties.use_minus.Assign(1); | ||
| 142 | controller.pad_assignment = NPadAssignments::Single; | ||
| 143 | break; | ||
| 111 | case NPadControllerType::Handheld: | 144 | case NPadControllerType::Handheld: |
| 112 | controller.joy_styles.handheld.Assign(1); | 145 | controller.joy_styles.handheld.Assign(1); |
| 113 | controller.device_type.handheld.Assign(1); | 146 | controller.device_type.handheld.Assign(1); |
| 114 | controller.pad_assignment = NPadAssignments::Dual; | ||
| 115 | controller.properties.is_vertical.Assign(1); | 147 | controller.properties.is_vertical.Assign(1); |
| 116 | controller.properties.use_plus.Assign(1); | 148 | controller.properties.use_plus.Assign(1); |
| 117 | controller.properties.use_minus.Assign(1); | 149 | controller.properties.use_minus.Assign(1); |
| 150 | controller.pad_assignment = NPadAssignments::Dual; | ||
| 118 | break; | 151 | break; |
| 119 | case NPadControllerType::JoyDual: | 152 | case NPadControllerType::JoyDual: |
| 120 | controller.joy_styles.joycon_dual.Assign(1); | 153 | controller.joy_styles.joycon_dual.Assign(1); |
| @@ -144,14 +177,6 @@ void Controller_NPad::InitNewlyAddedControler(std::size_t controller_idx) { | |||
| 144 | controller.device_type.pokeball.Assign(1); | 177 | controller.device_type.pokeball.Assign(1); |
| 145 | controller.pad_assignment = NPadAssignments::Single; | 178 | controller.pad_assignment = NPadAssignments::Single; |
| 146 | break; | 179 | break; |
| 147 | case NPadControllerType::ProController: | ||
| 148 | controller.joy_styles.pro_controller.Assign(1); | ||
| 149 | controller.device_type.pro_controller.Assign(1); | ||
| 150 | controller.properties.is_vertical.Assign(1); | ||
| 151 | controller.properties.use_plus.Assign(1); | ||
| 152 | controller.properties.use_minus.Assign(1); | ||
| 153 | controller.pad_assignment = NPadAssignments::Single; | ||
| 154 | break; | ||
| 155 | } | 180 | } |
| 156 | 181 | ||
| 157 | controller.single_color_error = ColorReadError::ReadOk; | 182 | controller.single_color_error = ColorReadError::ReadOk; |
| @@ -192,36 +217,25 @@ void Controller_NPad::OnInit() { | |||
| 192 | style.pokeball.Assign(1); | 217 | style.pokeball.Assign(1); |
| 193 | } | 218 | } |
| 194 | 219 | ||
| 195 | std::transform( | 220 | std::transform(Settings::values.players.begin(), Settings::values.players.end(), |
| 196 | Settings::values.players.begin(), Settings::values.players.end(), | 221 | connected_controllers.begin(), [](const Settings::PlayerInput& player) { |
| 197 | connected_controllers.begin(), [](const Settings::PlayerInput& player) { | 222 | return ControllerHolder{MapSettingsTypeToNPad(player.controller_type), |
| 198 | return ControllerHolder{MapSettingsTypeToNPad(player.type), player.connected}; | 223 | player.connected}; |
| 199 | }); | 224 | }); |
| 200 | |||
| 201 | std::stable_partition(connected_controllers.begin(), connected_controllers.begin() + 8, | ||
| 202 | [](const ControllerHolder& holder) { return holder.is_connected; }); | ||
| 203 | 225 | ||
| 204 | // Account for handheld | 226 | // Account for handheld |
| 205 | if (connected_controllers[8].is_connected) | 227 | if (connected_controllers[HANDHELD_INDEX].is_connected) { |
| 206 | connected_controllers[8].type = NPadControllerType::Handheld; | 228 | connected_controllers[HANDHELD_INDEX].type = NPadControllerType::Handheld; |
| 229 | } | ||
| 207 | 230 | ||
| 208 | supported_npad_id_types.resize(npad_id_list.size()); | 231 | supported_npad_id_types.resize(npad_id_list.size()); |
| 209 | std::memcpy(supported_npad_id_types.data(), npad_id_list.data(), | 232 | std::memcpy(supported_npad_id_types.data(), npad_id_list.data(), |
| 210 | npad_id_list.size() * sizeof(u32)); | 233 | npad_id_list.size() * sizeof(u32)); |
| 211 | 234 | ||
| 212 | // Add a default dual joycon controller if none are present. | ||
| 213 | if (std::none_of(connected_controllers.begin(), connected_controllers.end(), | ||
| 214 | [](const ControllerHolder& controller) { return controller.is_connected; })) { | ||
| 215 | supported_npad_id_types.resize(npad_id_list.size()); | ||
| 216 | std::memcpy(supported_npad_id_types.data(), npad_id_list.data(), | ||
| 217 | npad_id_list.size() * sizeof(u32)); | ||
| 218 | AddNewController(NPadControllerType::JoyDual); | ||
| 219 | } | ||
| 220 | |||
| 221 | for (std::size_t i = 0; i < connected_controllers.size(); ++i) { | 235 | for (std::size_t i = 0; i < connected_controllers.size(); ++i) { |
| 222 | const auto& controller = connected_controllers[i]; | 236 | const auto& controller = connected_controllers[i]; |
| 223 | if (controller.is_connected) { | 237 | if (controller.is_connected) { |
| 224 | AddNewControllerAt(controller.type, IndexToNPad(i)); | 238 | AddNewControllerAt(controller.type, i); |
| 225 | } | 239 | } |
| 226 | } | 240 | } |
| 227 | } | 241 | } |
| @@ -309,8 +323,9 @@ void Controller_NPad::RequestPadStateUpdate(u32 npad_id) { | |||
| 309 | 323 | ||
| 310 | void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, | 324 | void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, |
| 311 | std::size_t data_len) { | 325 | std::size_t data_len) { |
| 312 | if (!IsControllerActivated()) | 326 | if (!IsControllerActivated()) { |
| 313 | return; | 327 | return; |
| 328 | } | ||
| 314 | for (std::size_t i = 0; i < shared_memory_entries.size(); i++) { | 329 | for (std::size_t i = 0; i < shared_memory_entries.size(); i++) { |
| 315 | auto& npad = shared_memory_entries[i]; | 330 | auto& npad = shared_memory_entries[i]; |
| 316 | const std::array<NPadGeneric*, 7> controller_npads{&npad.main_controller_states, | 331 | const std::array<NPadGeneric*, 7> controller_npads{&npad.main_controller_states, |
| @@ -360,13 +375,25 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* | |||
| 360 | auto& libnx_entry = npad.libnx.npad[npad.libnx.common.last_entry_index]; | 375 | auto& libnx_entry = npad.libnx.npad[npad.libnx.common.last_entry_index]; |
| 361 | 376 | ||
| 362 | libnx_entry.connection_status.raw = 0; | 377 | libnx_entry.connection_status.raw = 0; |
| 378 | libnx_entry.connection_status.IsConnected.Assign(1); | ||
| 363 | 379 | ||
| 364 | switch (controller_type) { | 380 | switch (controller_type) { |
| 365 | case NPadControllerType::None: | 381 | case NPadControllerType::None: |
| 366 | UNREACHABLE(); | 382 | UNREACHABLE(); |
| 367 | break; | 383 | break; |
| 384 | case NPadControllerType::ProController: | ||
| 385 | main_controller.connection_status.raw = 0; | ||
| 386 | main_controller.connection_status.IsConnected.Assign(1); | ||
| 387 | main_controller.connection_status.IsWired.Assign(1); | ||
| 388 | main_controller.pad.pad_states.raw = pad_state.pad_states.raw; | ||
| 389 | main_controller.pad.l_stick = pad_state.l_stick; | ||
| 390 | main_controller.pad.r_stick = pad_state.r_stick; | ||
| 391 | |||
| 392 | libnx_entry.connection_status.IsWired.Assign(1); | ||
| 393 | break; | ||
| 368 | case NPadControllerType::Handheld: | 394 | case NPadControllerType::Handheld: |
| 369 | handheld_entry.connection_status.raw = 0; | 395 | handheld_entry.connection_status.raw = 0; |
| 396 | handheld_entry.connection_status.IsConnected.Assign(1); | ||
| 370 | handheld_entry.connection_status.IsWired.Assign(1); | 397 | handheld_entry.connection_status.IsWired.Assign(1); |
| 371 | handheld_entry.connection_status.IsLeftJoyConnected.Assign(1); | 398 | handheld_entry.connection_status.IsLeftJoyConnected.Assign(1); |
| 372 | handheld_entry.connection_status.IsRightJoyConnected.Assign(1); | 399 | handheld_entry.connection_status.IsRightJoyConnected.Assign(1); |
| @@ -375,57 +402,52 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* | |||
| 375 | handheld_entry.pad.pad_states.raw = pad_state.pad_states.raw; | 402 | handheld_entry.pad.pad_states.raw = pad_state.pad_states.raw; |
| 376 | handheld_entry.pad.l_stick = pad_state.l_stick; | 403 | handheld_entry.pad.l_stick = pad_state.l_stick; |
| 377 | handheld_entry.pad.r_stick = pad_state.r_stick; | 404 | handheld_entry.pad.r_stick = pad_state.r_stick; |
| 405 | |||
| 406 | libnx_entry.connection_status.IsWired.Assign(1); | ||
| 407 | libnx_entry.connection_status.IsLeftJoyConnected.Assign(1); | ||
| 408 | libnx_entry.connection_status.IsRightJoyConnected.Assign(1); | ||
| 409 | libnx_entry.connection_status.IsLeftJoyWired.Assign(1); | ||
| 410 | libnx_entry.connection_status.IsRightJoyWired.Assign(1); | ||
| 378 | break; | 411 | break; |
| 379 | case NPadControllerType::JoyDual: | 412 | case NPadControllerType::JoyDual: |
| 380 | dual_entry.connection_status.raw = 0; | 413 | dual_entry.connection_status.raw = 0; |
| 381 | 414 | dual_entry.connection_status.IsConnected.Assign(1); | |
| 382 | dual_entry.connection_status.IsLeftJoyConnected.Assign(1); | 415 | dual_entry.connection_status.IsLeftJoyConnected.Assign(1); |
| 383 | dual_entry.connection_status.IsRightJoyConnected.Assign(1); | 416 | dual_entry.connection_status.IsRightJoyConnected.Assign(1); |
| 384 | dual_entry.connection_status.IsConnected.Assign(1); | ||
| 385 | |||
| 386 | libnx_entry.connection_status.IsLeftJoyConnected.Assign(1); | ||
| 387 | libnx_entry.connection_status.IsRightJoyConnected.Assign(1); | ||
| 388 | libnx_entry.connection_status.IsConnected.Assign(1); | ||
| 389 | |||
| 390 | dual_entry.pad.pad_states.raw = pad_state.pad_states.raw; | 417 | dual_entry.pad.pad_states.raw = pad_state.pad_states.raw; |
| 391 | dual_entry.pad.l_stick = pad_state.l_stick; | 418 | dual_entry.pad.l_stick = pad_state.l_stick; |
| 392 | dual_entry.pad.r_stick = pad_state.r_stick; | 419 | dual_entry.pad.r_stick = pad_state.r_stick; |
| 420 | |||
| 421 | libnx_entry.connection_status.IsLeftJoyConnected.Assign(1); | ||
| 422 | libnx_entry.connection_status.IsRightJoyConnected.Assign(1); | ||
| 393 | break; | 423 | break; |
| 394 | case NPadControllerType::JoyLeft: | 424 | case NPadControllerType::JoyLeft: |
| 395 | left_entry.connection_status.raw = 0; | 425 | left_entry.connection_status.raw = 0; |
| 396 | |||
| 397 | left_entry.connection_status.IsConnected.Assign(1); | 426 | left_entry.connection_status.IsConnected.Assign(1); |
| 427 | left_entry.connection_status.IsLeftJoyConnected.Assign(1); | ||
| 398 | left_entry.pad.pad_states.raw = pad_state.pad_states.raw; | 428 | left_entry.pad.pad_states.raw = pad_state.pad_states.raw; |
| 399 | left_entry.pad.l_stick = pad_state.l_stick; | 429 | left_entry.pad.l_stick = pad_state.l_stick; |
| 400 | left_entry.pad.r_stick = pad_state.r_stick; | 430 | left_entry.pad.r_stick = pad_state.r_stick; |
| 431 | |||
| 432 | libnx_entry.connection_status.IsLeftJoyConnected.Assign(1); | ||
| 401 | break; | 433 | break; |
| 402 | case NPadControllerType::JoyRight: | 434 | case NPadControllerType::JoyRight: |
| 403 | right_entry.connection_status.raw = 0; | 435 | right_entry.connection_status.raw = 0; |
| 404 | |||
| 405 | right_entry.connection_status.IsConnected.Assign(1); | 436 | right_entry.connection_status.IsConnected.Assign(1); |
| 437 | right_entry.connection_status.IsRightJoyConnected.Assign(1); | ||
| 406 | right_entry.pad.pad_states.raw = pad_state.pad_states.raw; | 438 | right_entry.pad.pad_states.raw = pad_state.pad_states.raw; |
| 407 | right_entry.pad.l_stick = pad_state.l_stick; | 439 | right_entry.pad.l_stick = pad_state.l_stick; |
| 408 | right_entry.pad.r_stick = pad_state.r_stick; | 440 | right_entry.pad.r_stick = pad_state.r_stick; |
| 441 | |||
| 442 | libnx_entry.connection_status.IsRightJoyConnected.Assign(1); | ||
| 409 | break; | 443 | break; |
| 410 | case NPadControllerType::Pokeball: | 444 | case NPadControllerType::Pokeball: |
| 411 | pokeball_entry.connection_status.raw = 0; | 445 | pokeball_entry.connection_status.raw = 0; |
| 412 | |||
| 413 | pokeball_entry.connection_status.IsConnected.Assign(1); | 446 | pokeball_entry.connection_status.IsConnected.Assign(1); |
| 414 | pokeball_entry.connection_status.IsWired.Assign(1); | ||
| 415 | |||
| 416 | pokeball_entry.pad.pad_states.raw = pad_state.pad_states.raw; | 447 | pokeball_entry.pad.pad_states.raw = pad_state.pad_states.raw; |
| 417 | pokeball_entry.pad.l_stick = pad_state.l_stick; | 448 | pokeball_entry.pad.l_stick = pad_state.l_stick; |
| 418 | pokeball_entry.pad.r_stick = pad_state.r_stick; | 449 | pokeball_entry.pad.r_stick = pad_state.r_stick; |
| 419 | break; | 450 | break; |
| 420 | case NPadControllerType::ProController: | ||
| 421 | main_controller.connection_status.raw = 0; | ||
| 422 | |||
| 423 | main_controller.connection_status.IsConnected.Assign(1); | ||
| 424 | main_controller.connection_status.IsWired.Assign(1); | ||
| 425 | main_controller.pad.pad_states.raw = pad_state.pad_states.raw; | ||
| 426 | main_controller.pad.l_stick = pad_state.l_stick; | ||
| 427 | main_controller.pad.r_stick = pad_state.r_stick; | ||
| 428 | break; | ||
| 429 | } | 451 | } |
| 430 | 452 | ||
| 431 | // LibNX exclusively uses this section, so we always update it since LibNX doesn't activate | 453 | // LibNX exclusively uses this section, so we always update it since LibNX doesn't activate |
| @@ -453,26 +475,6 @@ void Controller_NPad::SetSupportedNPadIdTypes(u8* data, std::size_t length) { | |||
| 453 | supported_npad_id_types.clear(); | 475 | supported_npad_id_types.clear(); |
| 454 | supported_npad_id_types.resize(length / sizeof(u32)); | 476 | supported_npad_id_types.resize(length / sizeof(u32)); |
| 455 | std::memcpy(supported_npad_id_types.data(), data, length); | 477 | std::memcpy(supported_npad_id_types.data(), data, length); |
| 456 | for (std::size_t i = 0; i < connected_controllers.size(); i++) { | ||
| 457 | auto& controller = connected_controllers[i]; | ||
| 458 | if (!controller.is_connected) { | ||
| 459 | continue; | ||
| 460 | } | ||
| 461 | const auto requested_controller = | ||
| 462 | i <= MAX_NPAD_ID ? MapSettingsTypeToNPad(Settings::values.players[i].type) | ||
| 463 | : NPadControllerType::Handheld; | ||
| 464 | if (!IsControllerSupported(requested_controller)) { | ||
| 465 | const auto is_handheld = requested_controller == NPadControllerType::Handheld; | ||
| 466 | if (is_handheld) { | ||
| 467 | controller.type = NPadControllerType::None; | ||
| 468 | controller.is_connected = false; | ||
| 469 | AddNewController(requested_controller); | ||
| 470 | } else { | ||
| 471 | controller.type = requested_controller; | ||
| 472 | InitNewlyAddedControler(i); | ||
| 473 | } | ||
| 474 | } | ||
| 475 | } | ||
| 476 | } | 478 | } |
| 477 | 479 | ||
| 478 | void Controller_NPad::GetSupportedNpadIdTypes(u32* data, std::size_t max_length) { | 480 | void Controller_NPad::GetSupportedNpadIdTypes(u32* data, std::size_t max_length) { |
| @@ -504,7 +506,7 @@ void Controller_NPad::VibrateController(const std::vector<u32>& controller_ids, | |||
| 504 | const std::vector<Vibration>& vibrations) { | 506 | const std::vector<Vibration>& vibrations) { |
| 505 | LOG_DEBUG(Service_HID, "(STUBBED) called"); | 507 | LOG_DEBUG(Service_HID, "(STUBBED) called"); |
| 506 | 508 | ||
| 507 | if (!can_controllers_vibrate) { | 509 | if (!Settings::values.vibration_enabled || !can_controllers_vibrate) { |
| 508 | return; | 510 | return; |
| 509 | } | 511 | } |
| 510 | for (std::size_t i = 0; i < controller_ids.size(); i++) { | 512 | for (std::size_t i = 0; i < controller_ids.size(); i++) { |
| @@ -517,8 +519,6 @@ void Controller_NPad::VibrateController(const std::vector<u32>& controller_ids, | |||
| 517 | } | 519 | } |
| 518 | 520 | ||
| 519 | std::shared_ptr<Kernel::ReadableEvent> Controller_NPad::GetStyleSetChangedEvent(u32 npad_id) const { | 521 | std::shared_ptr<Kernel::ReadableEvent> Controller_NPad::GetStyleSetChangedEvent(u32 npad_id) const { |
| 520 | // TODO(ogniK): Figure out the best time to signal this event. This event seems that it should | ||
| 521 | // be signalled at least once, and signaled after a new controller is connected? | ||
| 522 | const auto& styleset_event = styleset_changed_events[NPadIdToIndex(npad_id)]; | 522 | const auto& styleset_event = styleset_changed_events[NPadIdToIndex(npad_id)]; |
| 523 | return styleset_event.readable; | 523 | return styleset_event.readable; |
| 524 | } | 524 | } |
| @@ -527,43 +527,43 @@ Controller_NPad::Vibration Controller_NPad::GetLastVibration() const { | |||
| 527 | return last_processed_vibration; | 527 | return last_processed_vibration; |
| 528 | } | 528 | } |
| 529 | 529 | ||
| 530 | void Controller_NPad::AddNewController(NPadControllerType controller) { | 530 | void Controller_NPad::AddNewControllerAt(NPadControllerType controller, std::size_t npad_index) { |
| 531 | controller = DecideBestController(controller); | 531 | UpdateControllerAt(controller, npad_index, true); |
| 532 | if (controller == NPadControllerType::Handheld) { | 532 | } |
| 533 | connected_controllers[8] = {controller, true}; | 533 | |
| 534 | InitNewlyAddedControler(8); | 534 | void Controller_NPad::UpdateControllerAt(NPadControllerType controller, std::size_t npad_index, |
| 535 | return; | 535 | bool connected) { |
| 536 | } | 536 | if (!connected) { |
| 537 | const auto pos = | 537 | DisconnectNPad(IndexToNPad(npad_index)); |
| 538 | std::find_if(connected_controllers.begin(), connected_controllers.end() - 2, | ||
| 539 | [](const ControllerHolder& holder) { return !holder.is_connected; }); | ||
| 540 | if (pos == connected_controllers.end() - 2) { | ||
| 541 | LOG_ERROR(Service_HID, "Cannot connect any more controllers!"); | ||
| 542 | return; | 538 | return; |
| 543 | } | 539 | } |
| 544 | const auto controller_id = std::distance(connected_controllers.begin(), pos); | ||
| 545 | connected_controllers[controller_id] = {controller, true}; | ||
| 546 | InitNewlyAddedControler(controller_id); | ||
| 547 | } | ||
| 548 | 540 | ||
| 549 | void Controller_NPad::AddNewControllerAt(NPadControllerType controller, u32 npad_id) { | ||
| 550 | controller = DecideBestController(controller); | ||
| 551 | if (controller == NPadControllerType::Handheld) { | 541 | if (controller == NPadControllerType::Handheld) { |
| 552 | connected_controllers[NPadIdToIndex(NPAD_HANDHELD)] = {controller, true}; | 542 | Settings::values.players[HANDHELD_INDEX].controller_type = |
| 553 | InitNewlyAddedControler(NPadIdToIndex(NPAD_HANDHELD)); | 543 | MapNPadToSettingsType(controller); |
| 544 | Settings::values.players[HANDHELD_INDEX].connected = true; | ||
| 545 | connected_controllers[HANDHELD_INDEX] = {controller, true}; | ||
| 546 | InitNewlyAddedController(HANDHELD_INDEX); | ||
| 554 | return; | 547 | return; |
| 555 | } | 548 | } |
| 556 | 549 | ||
| 557 | connected_controllers[NPadIdToIndex(npad_id)] = {controller, true}; | 550 | Settings::values.players[npad_index].controller_type = MapNPadToSettingsType(controller); |
| 558 | InitNewlyAddedControler(NPadIdToIndex(npad_id)); | 551 | Settings::values.players[npad_index].connected = true; |
| 559 | } | 552 | connected_controllers[npad_index] = {controller, true}; |
| 560 | 553 | InitNewlyAddedController(npad_index); | |
| 561 | void Controller_NPad::ConnectNPad(u32 npad_id) { | ||
| 562 | connected_controllers[NPadIdToIndex(npad_id)].is_connected = true; | ||
| 563 | } | 554 | } |
| 564 | 555 | ||
| 565 | void Controller_NPad::DisconnectNPad(u32 npad_id) { | 556 | void Controller_NPad::DisconnectNPad(u32 npad_id) { |
| 566 | connected_controllers[NPadIdToIndex(npad_id)].is_connected = false; | 557 | const auto npad_index = NPadIdToIndex(npad_id); |
| 558 | connected_controllers[npad_index].is_connected = false; | ||
| 559 | Settings::values.players[npad_index].connected = false; | ||
| 560 | |||
| 561 | auto& controller = shared_memory_entries[npad_index]; | ||
| 562 | controller.joy_styles.raw = 0; // Zero out | ||
| 563 | controller.device_type.raw = 0; | ||
| 564 | controller.properties.raw = 0; | ||
| 565 | |||
| 566 | styleset_changed_events[npad_index].writable->Signal(); | ||
| 567 | } | 567 | } |
| 568 | 568 | ||
| 569 | void Controller_NPad::SetGyroscopeZeroDriftMode(GyroscopeZeroDriftMode drift_mode) { | 569 | void Controller_NPad::SetGyroscopeZeroDriftMode(GyroscopeZeroDriftMode drift_mode) { |
| @@ -599,8 +599,8 @@ bool Controller_NPad::SwapNpadAssignment(u32 npad_id_1, u32 npad_id_2) { | |||
| 599 | 599 | ||
| 600 | std::swap(connected_controllers[npad_index_1].type, connected_controllers[npad_index_2].type); | 600 | std::swap(connected_controllers[npad_index_1].type, connected_controllers[npad_index_2].type); |
| 601 | 601 | ||
| 602 | InitNewlyAddedControler(npad_index_1); | 602 | AddNewControllerAt(connected_controllers[npad_index_1].type, npad_index_1); |
| 603 | InitNewlyAddedControler(npad_index_2); | 603 | AddNewControllerAt(connected_controllers[npad_index_2].type, npad_index_2); |
| 604 | 604 | ||
| 605 | return true; | 605 | return true; |
| 606 | } | 606 | } |
| @@ -614,11 +614,11 @@ Controller_NPad::LedPattern Controller_NPad::GetLedPattern(u32 npad_id) { | |||
| 614 | case 0: | 614 | case 0: |
| 615 | return LedPattern{1, 0, 0, 0}; | 615 | return LedPattern{1, 0, 0, 0}; |
| 616 | case 1: | 616 | case 1: |
| 617 | return LedPattern{0, 1, 0, 0}; | 617 | return LedPattern{1, 1, 0, 0}; |
| 618 | case 2: | 618 | case 2: |
| 619 | return LedPattern{0, 0, 1, 0}; | 619 | return LedPattern{1, 1, 1, 0}; |
| 620 | case 3: | 620 | case 3: |
| 621 | return LedPattern{0, 0, 0, 1}; | 621 | return LedPattern{1, 1, 1, 1}; |
| 622 | case 4: | 622 | case 4: |
| 623 | return LedPattern{1, 0, 0, 1}; | 623 | return LedPattern{1, 0, 0, 1}; |
| 624 | case 5: | 624 | case 5: |
| @@ -628,7 +628,6 @@ Controller_NPad::LedPattern Controller_NPad::GetLedPattern(u32 npad_id) { | |||
| 628 | case 7: | 628 | case 7: |
| 629 | return LedPattern{0, 1, 1, 0}; | 629 | return LedPattern{0, 1, 1, 0}; |
| 630 | default: | 630 | default: |
| 631 | UNIMPLEMENTED_MSG("Unhandled npad_id {}", npad_id); | ||
| 632 | return LedPattern{0, 0, 0, 0}; | 631 | return LedPattern{0, 0, 0, 0}; |
| 633 | } | 632 | } |
| 634 | } | 633 | } |
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 5d4c58a43..75ce5b731 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h | |||
| @@ -118,10 +118,11 @@ public: | |||
| 118 | std::shared_ptr<Kernel::ReadableEvent> GetStyleSetChangedEvent(u32 npad_id) const; | 118 | std::shared_ptr<Kernel::ReadableEvent> GetStyleSetChangedEvent(u32 npad_id) const; |
| 119 | Vibration GetLastVibration() const; | 119 | Vibration GetLastVibration() const; |
| 120 | 120 | ||
| 121 | void AddNewController(NPadControllerType controller); | 121 | // Adds a new controller at an index. |
| 122 | void AddNewControllerAt(NPadControllerType controller, u32 npad_id); | 122 | void AddNewControllerAt(NPadControllerType controller, std::size_t npad_index); |
| 123 | // Adds a new controller at an index with connection status. | ||
| 124 | void UpdateControllerAt(NPadControllerType controller, std::size_t npad_index, bool connected); | ||
| 123 | 125 | ||
| 124 | void ConnectNPad(u32 npad_id); | ||
| 125 | void DisconnectNPad(u32 npad_id); | 126 | void DisconnectNPad(u32 npad_id); |
| 126 | void SetGyroscopeZeroDriftMode(GyroscopeZeroDriftMode drift_mode); | 127 | void SetGyroscopeZeroDriftMode(GyroscopeZeroDriftMode drift_mode); |
| 127 | GyroscopeZeroDriftMode GetGyroscopeZeroDriftMode() const; | 128 | GyroscopeZeroDriftMode GetGyroscopeZeroDriftMode() const; |
| @@ -141,6 +142,8 @@ public: | |||
| 141 | // Specifically for cheat engine and other features. | 142 | // Specifically for cheat engine and other features. |
| 142 | u32 GetAndResetPressState(); | 143 | u32 GetAndResetPressState(); |
| 143 | 144 | ||
| 145 | static Controller_NPad::NPadControllerType MapSettingsTypeToNPad(Settings::ControllerType type); | ||
| 146 | static Settings::ControllerType MapNPadToSettingsType(Controller_NPad::NPadControllerType type); | ||
| 144 | static std::size_t NPadIdToIndex(u32 npad_id); | 147 | static std::size_t NPadIdToIndex(u32 npad_id); |
| 145 | static u32 IndexToNPad(std::size_t index); | 148 | static u32 IndexToNPad(std::size_t index); |
| 146 | 149 | ||
| @@ -309,7 +312,7 @@ private: | |||
| 309 | bool is_connected; | 312 | bool is_connected; |
| 310 | }; | 313 | }; |
| 311 | 314 | ||
| 312 | void InitNewlyAddedControler(std::size_t controller_idx); | 315 | void InitNewlyAddedController(std::size_t controller_idx); |
| 313 | bool IsControllerSupported(NPadControllerType controller) const; | 316 | bool IsControllerSupported(NPadControllerType controller) const; |
| 314 | NPadControllerType DecideBestController(NPadControllerType priority) const; | 317 | NPadControllerType DecideBestController(NPadControllerType priority) const; |
| 315 | void RequestPadStateUpdate(u32 npad_id); | 318 | void RequestPadStateUpdate(u32 npad_id); |
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 1e95b7580..33416b5dd 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
| @@ -38,11 +38,9 @@ | |||
| 38 | namespace Service::HID { | 38 | namespace Service::HID { |
| 39 | 39 | ||
| 40 | // Updating period for each HID device. | 40 | // Updating period for each HID device. |
| 41 | // TODO(ogniK): Find actual polling rate of hid | 41 | // HID is polled every 15ms, this value was derived from |
| 42 | constexpr auto pad_update_ns = std::chrono::nanoseconds{1000000000 / 66}; | 42 | // https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering#joy-con-status-data-packet |
| 43 | [[maybe_unused]] constexpr auto accelerometer_update_ns = | 43 | constexpr auto pad_update_ns = std::chrono::nanoseconds{15 * 1000 * 1000}; // (15ms, 66.6Hz) |
| 44 | std::chrono::nanoseconds{1000000000 / 100}; | ||
| 45 | [[maybe_unused]] constexpr auto gyroscope_update_ticks = std::chrono::nanoseconds{1000000000 / 100}; | ||
| 46 | constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000; | 44 | constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000; |
| 47 | 45 | ||
| 48 | IAppletResource::IAppletResource(Core::System& system) | 46 | IAppletResource::IAppletResource(Core::System& system) |
| @@ -845,8 +843,7 @@ void Hid::CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx) { | |||
| 845 | void Hid::PermitVibration(Kernel::HLERequestContext& ctx) { | 843 | void Hid::PermitVibration(Kernel::HLERequestContext& ctx) { |
| 846 | IPC::RequestParser rp{ctx}; | 844 | IPC::RequestParser rp{ctx}; |
| 847 | const auto can_vibrate{rp.Pop<bool>()}; | 845 | const auto can_vibrate{rp.Pop<bool>()}; |
| 848 | applet_resource->GetController<Controller_NPad>(HidController::NPad) | 846 | Settings::values.vibration_enabled = can_vibrate; |
| 849 | .SetVibrationEnabled(can_vibrate); | ||
| 850 | 847 | ||
| 851 | LOG_DEBUG(Service_HID, "called, can_vibrate={}", can_vibrate); | 848 | LOG_DEBUG(Service_HID, "called, can_vibrate={}", can_vibrate); |
| 852 | 849 | ||
| @@ -859,8 +856,7 @@ void Hid::IsVibrationPermitted(Kernel::HLERequestContext& ctx) { | |||
| 859 | 856 | ||
| 860 | IPC::ResponseBuilder rb{ctx, 3}; | 857 | IPC::ResponseBuilder rb{ctx, 3}; |
| 861 | rb.Push(RESULT_SUCCESS); | 858 | rb.Push(RESULT_SUCCESS); |
| 862 | rb.Push( | 859 | rb.Push(Settings::values.vibration_enabled); |
| 863 | applet_resource->GetController<Controller_NPad>(HidController::NPad).IsVibrationEnabled()); | ||
| 864 | } | 860 | } |
| 865 | 861 | ||
| 866 | void Hid::ActivateConsoleSixAxisSensor(Kernel::HLERequestContext& ctx) { | 862 | void Hid::ActivateConsoleSixAxisSensor(Kernel::HLERequestContext& ctx) { |
diff --git a/src/core/settings.cpp b/src/core/settings.cpp index d328fb8b7..28d3f9099 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp | |||
| @@ -13,56 +13,6 @@ | |||
| 13 | 13 | ||
| 14 | namespace Settings { | 14 | namespace Settings { |
| 15 | 15 | ||
| 16 | namespace NativeButton { | ||
| 17 | const std::array<const char*, NumButtons> mapping = {{ | ||
| 18 | "button_a", | ||
| 19 | "button_b", | ||
| 20 | "button_x", | ||
| 21 | "button_y", | ||
| 22 | "button_lstick", | ||
| 23 | "button_rstick", | ||
| 24 | "button_l", | ||
| 25 | "button_r", | ||
| 26 | "button_zl", | ||
| 27 | "button_zr", | ||
| 28 | "button_plus", | ||
| 29 | "button_minus", | ||
| 30 | "button_dleft", | ||
| 31 | "button_dup", | ||
| 32 | "button_dright", | ||
| 33 | "button_ddown", | ||
| 34 | "button_lstick_left", | ||
| 35 | "button_lstick_up", | ||
| 36 | "button_lstick_right", | ||
| 37 | "button_lstick_down", | ||
| 38 | "button_rstick_left", | ||
| 39 | "button_rstick_up", | ||
| 40 | "button_rstick_right", | ||
| 41 | "button_rstick_down", | ||
| 42 | "button_sl", | ||
| 43 | "button_sr", | ||
| 44 | "button_home", | ||
| 45 | "button_screenshot", | ||
| 46 | }}; | ||
| 47 | } | ||
| 48 | |||
| 49 | namespace NativeAnalog { | ||
| 50 | const std::array<const char*, NumAnalogs> mapping = {{ | ||
| 51 | "lstick", | ||
| 52 | "rstick", | ||
| 53 | }}; | ||
| 54 | } | ||
| 55 | |||
| 56 | namespace NativeMouseButton { | ||
| 57 | const std::array<const char*, NumMouseButtons> mapping = {{ | ||
| 58 | "left", | ||
| 59 | "right", | ||
| 60 | "middle", | ||
| 61 | "forward", | ||
| 62 | "back", | ||
| 63 | }}; | ||
| 64 | } | ||
| 65 | |||
| 66 | Values values = {}; | 16 | Values values = {}; |
| 67 | bool configuring_global = true; | 17 | bool configuring_global = true; |
| 68 | 18 | ||
diff --git a/src/core/settings.h b/src/core/settings.h index 3681b5e9d..732c6a894 100644 --- a/src/core/settings.h +++ b/src/core/settings.h | |||
| @@ -12,340 +12,10 @@ | |||
| 12 | #include <string> | 12 | #include <string> |
| 13 | #include <vector> | 13 | #include <vector> |
| 14 | #include "common/common_types.h" | 14 | #include "common/common_types.h" |
| 15 | #include "input_common/settings.h" | ||
| 15 | 16 | ||
| 16 | namespace Settings { | 17 | namespace Settings { |
| 17 | 18 | ||
| 18 | namespace NativeButton { | ||
| 19 | enum Values { | ||
| 20 | A, | ||
| 21 | B, | ||
| 22 | X, | ||
| 23 | Y, | ||
| 24 | LStick, | ||
| 25 | RStick, | ||
| 26 | L, | ||
| 27 | R, | ||
| 28 | ZL, | ||
| 29 | ZR, | ||
| 30 | Plus, | ||
| 31 | Minus, | ||
| 32 | |||
| 33 | DLeft, | ||
| 34 | DUp, | ||
| 35 | DRight, | ||
| 36 | DDown, | ||
| 37 | |||
| 38 | LStick_Left, | ||
| 39 | LStick_Up, | ||
| 40 | LStick_Right, | ||
| 41 | LStick_Down, | ||
| 42 | |||
| 43 | RStick_Left, | ||
| 44 | RStick_Up, | ||
| 45 | RStick_Right, | ||
| 46 | RStick_Down, | ||
| 47 | |||
| 48 | SL, | ||
| 49 | SR, | ||
| 50 | |||
| 51 | Home, | ||
| 52 | Screenshot, | ||
| 53 | |||
| 54 | NumButtons, | ||
| 55 | }; | ||
| 56 | |||
| 57 | constexpr int BUTTON_HID_BEGIN = A; | ||
| 58 | constexpr int BUTTON_NS_BEGIN = Home; | ||
| 59 | |||
| 60 | constexpr int BUTTON_HID_END = BUTTON_NS_BEGIN; | ||
| 61 | constexpr int BUTTON_NS_END = NumButtons; | ||
| 62 | |||
| 63 | constexpr int NUM_BUTTONS_HID = BUTTON_HID_END - BUTTON_HID_BEGIN; | ||
| 64 | constexpr int NUM_BUTTONS_NS = BUTTON_NS_END - BUTTON_NS_BEGIN; | ||
| 65 | |||
| 66 | extern const std::array<const char*, NumButtons> mapping; | ||
| 67 | |||
| 68 | } // namespace NativeButton | ||
| 69 | |||
| 70 | namespace NativeAnalog { | ||
| 71 | enum Values { | ||
| 72 | LStick, | ||
| 73 | RStick, | ||
| 74 | |||
| 75 | NumAnalogs, | ||
| 76 | }; | ||
| 77 | |||
| 78 | constexpr int STICK_HID_BEGIN = LStick; | ||
| 79 | constexpr int STICK_HID_END = NumAnalogs; | ||
| 80 | constexpr int NUM_STICKS_HID = NumAnalogs; | ||
| 81 | |||
| 82 | extern const std::array<const char*, NumAnalogs> mapping; | ||
| 83 | } // namespace NativeAnalog | ||
| 84 | |||
| 85 | namespace NativeMouseButton { | ||
| 86 | enum Values { | ||
| 87 | Left, | ||
| 88 | Right, | ||
| 89 | Middle, | ||
| 90 | Forward, | ||
| 91 | Back, | ||
| 92 | |||
| 93 | NumMouseButtons, | ||
| 94 | }; | ||
| 95 | |||
| 96 | constexpr int MOUSE_HID_BEGIN = Left; | ||
| 97 | constexpr int MOUSE_HID_END = NumMouseButtons; | ||
| 98 | constexpr int NUM_MOUSE_HID = NumMouseButtons; | ||
| 99 | |||
| 100 | extern const std::array<const char*, NumMouseButtons> mapping; | ||
| 101 | } // namespace NativeMouseButton | ||
| 102 | |||
| 103 | namespace NativeKeyboard { | ||
| 104 | enum Keys { | ||
| 105 | None, | ||
| 106 | Error, | ||
| 107 | |||
| 108 | A = 4, | ||
| 109 | B, | ||
| 110 | C, | ||
| 111 | D, | ||
| 112 | E, | ||
| 113 | F, | ||
| 114 | G, | ||
| 115 | H, | ||
| 116 | I, | ||
| 117 | J, | ||
| 118 | K, | ||
| 119 | L, | ||
| 120 | M, | ||
| 121 | N, | ||
| 122 | O, | ||
| 123 | P, | ||
| 124 | Q, | ||
| 125 | R, | ||
| 126 | S, | ||
| 127 | T, | ||
| 128 | U, | ||
| 129 | V, | ||
| 130 | W, | ||
| 131 | X, | ||
| 132 | Y, | ||
| 133 | Z, | ||
| 134 | N1, | ||
| 135 | N2, | ||
| 136 | N3, | ||
| 137 | N4, | ||
| 138 | N5, | ||
| 139 | N6, | ||
| 140 | N7, | ||
| 141 | N8, | ||
| 142 | N9, | ||
| 143 | N0, | ||
| 144 | Enter, | ||
| 145 | Escape, | ||
| 146 | Backspace, | ||
| 147 | Tab, | ||
| 148 | Space, | ||
| 149 | Minus, | ||
| 150 | Equal, | ||
| 151 | LeftBrace, | ||
| 152 | RightBrace, | ||
| 153 | Backslash, | ||
| 154 | Tilde, | ||
| 155 | Semicolon, | ||
| 156 | Apostrophe, | ||
| 157 | Grave, | ||
| 158 | Comma, | ||
| 159 | Dot, | ||
| 160 | Slash, | ||
| 161 | CapsLockKey, | ||
| 162 | |||
| 163 | F1, | ||
| 164 | F2, | ||
| 165 | F3, | ||
| 166 | F4, | ||
| 167 | F5, | ||
| 168 | F6, | ||
| 169 | F7, | ||
| 170 | F8, | ||
| 171 | F9, | ||
| 172 | F10, | ||
| 173 | F11, | ||
| 174 | F12, | ||
| 175 | |||
| 176 | SystemRequest, | ||
| 177 | ScrollLockKey, | ||
| 178 | Pause, | ||
| 179 | Insert, | ||
| 180 | Home, | ||
| 181 | PageUp, | ||
| 182 | Delete, | ||
| 183 | End, | ||
| 184 | PageDown, | ||
| 185 | Right, | ||
| 186 | Left, | ||
| 187 | Down, | ||
| 188 | Up, | ||
| 189 | |||
| 190 | NumLockKey, | ||
| 191 | KPSlash, | ||
| 192 | KPAsterisk, | ||
| 193 | KPMinus, | ||
| 194 | KPPlus, | ||
| 195 | KPEnter, | ||
| 196 | KP1, | ||
| 197 | KP2, | ||
| 198 | KP3, | ||
| 199 | KP4, | ||
| 200 | KP5, | ||
| 201 | KP6, | ||
| 202 | KP7, | ||
| 203 | KP8, | ||
| 204 | KP9, | ||
| 205 | KP0, | ||
| 206 | KPDot, | ||
| 207 | |||
| 208 | Key102, | ||
| 209 | Compose, | ||
| 210 | Power, | ||
| 211 | KPEqual, | ||
| 212 | |||
| 213 | F13, | ||
| 214 | F14, | ||
| 215 | F15, | ||
| 216 | F16, | ||
| 217 | F17, | ||
| 218 | F18, | ||
| 219 | F19, | ||
| 220 | F20, | ||
| 221 | F21, | ||
| 222 | F22, | ||
| 223 | F23, | ||
| 224 | F24, | ||
| 225 | |||
| 226 | Open, | ||
| 227 | Help, | ||
| 228 | Properties, | ||
| 229 | Front, | ||
| 230 | Stop, | ||
| 231 | Repeat, | ||
| 232 | Undo, | ||
| 233 | Cut, | ||
| 234 | Copy, | ||
| 235 | Paste, | ||
| 236 | Find, | ||
| 237 | Mute, | ||
| 238 | VolumeUp, | ||
| 239 | VolumeDown, | ||
| 240 | CapsLockActive, | ||
| 241 | NumLockActive, | ||
| 242 | ScrollLockActive, | ||
| 243 | KPComma, | ||
| 244 | |||
| 245 | KPLeftParenthesis, | ||
| 246 | KPRightParenthesis, | ||
| 247 | |||
| 248 | LeftControlKey = 0xE0, | ||
| 249 | LeftShiftKey, | ||
| 250 | LeftAltKey, | ||
| 251 | LeftMetaKey, | ||
| 252 | RightControlKey, | ||
| 253 | RightShiftKey, | ||
| 254 | RightAltKey, | ||
| 255 | RightMetaKey, | ||
| 256 | |||
| 257 | MediaPlayPause, | ||
| 258 | MediaStopCD, | ||
| 259 | MediaPrevious, | ||
| 260 | MediaNext, | ||
| 261 | MediaEject, | ||
| 262 | MediaVolumeUp, | ||
| 263 | MediaVolumeDown, | ||
| 264 | MediaMute, | ||
| 265 | MediaWebsite, | ||
| 266 | MediaBack, | ||
| 267 | MediaForward, | ||
| 268 | MediaStop, | ||
| 269 | MediaFind, | ||
| 270 | MediaScrollUp, | ||
| 271 | MediaScrollDown, | ||
| 272 | MediaEdit, | ||
| 273 | MediaSleep, | ||
| 274 | MediaCoffee, | ||
| 275 | MediaRefresh, | ||
| 276 | MediaCalculator, | ||
| 277 | |||
| 278 | NumKeyboardKeys, | ||
| 279 | }; | ||
| 280 | |||
| 281 | static_assert(NumKeyboardKeys == 0xFC, "Incorrect number of keyboard keys."); | ||
| 282 | |||
| 283 | enum Modifiers { | ||
| 284 | LeftControl, | ||
| 285 | LeftShift, | ||
| 286 | LeftAlt, | ||
| 287 | LeftMeta, | ||
| 288 | RightControl, | ||
| 289 | RightShift, | ||
| 290 | RightAlt, | ||
| 291 | RightMeta, | ||
| 292 | CapsLock, | ||
| 293 | ScrollLock, | ||
| 294 | NumLock, | ||
| 295 | |||
| 296 | NumKeyboardMods, | ||
| 297 | }; | ||
| 298 | |||
| 299 | constexpr int KEYBOARD_KEYS_HID_BEGIN = None; | ||
| 300 | constexpr int KEYBOARD_KEYS_HID_END = NumKeyboardKeys; | ||
| 301 | constexpr int NUM_KEYBOARD_KEYS_HID = NumKeyboardKeys; | ||
| 302 | |||
| 303 | constexpr int KEYBOARD_MODS_HID_BEGIN = LeftControl; | ||
| 304 | constexpr int KEYBOARD_MODS_HID_END = NumKeyboardMods; | ||
| 305 | constexpr int NUM_KEYBOARD_MODS_HID = NumKeyboardMods; | ||
| 306 | |||
| 307 | } // namespace NativeKeyboard | ||
| 308 | |||
| 309 | using ButtonsRaw = std::array<std::string, NativeButton::NumButtons>; | ||
| 310 | using AnalogsRaw = std::array<std::string, NativeAnalog::NumAnalogs>; | ||
| 311 | using MouseButtonsRaw = std::array<std::string, NativeMouseButton::NumMouseButtons>; | ||
| 312 | using KeyboardKeysRaw = std::array<std::string, NativeKeyboard::NumKeyboardKeys>; | ||
| 313 | using KeyboardModsRaw = std::array<std::string, NativeKeyboard::NumKeyboardMods>; | ||
| 314 | |||
| 315 | constexpr u32 JOYCON_BODY_NEON_RED = 0xFF3C28; | ||
| 316 | constexpr u32 JOYCON_BUTTONS_NEON_RED = 0x1E0A0A; | ||
| 317 | constexpr u32 JOYCON_BODY_NEON_BLUE = 0x0AB9E6; | ||
| 318 | constexpr u32 JOYCON_BUTTONS_NEON_BLUE = 0x001E1E; | ||
| 319 | |||
| 320 | enum class ControllerType { | ||
| 321 | ProController, | ||
| 322 | DualJoycon, | ||
| 323 | RightJoycon, | ||
| 324 | LeftJoycon, | ||
| 325 | }; | ||
| 326 | |||
| 327 | struct PlayerInput { | ||
| 328 | bool connected; | ||
| 329 | ControllerType type; | ||
| 330 | ButtonsRaw buttons; | ||
| 331 | AnalogsRaw analogs; | ||
| 332 | |||
| 333 | u32 body_color_right; | ||
| 334 | u32 button_color_right; | ||
| 335 | u32 body_color_left; | ||
| 336 | u32 button_color_left; | ||
| 337 | }; | ||
| 338 | |||
| 339 | struct TouchscreenInput { | ||
| 340 | bool enabled; | ||
| 341 | std::string device; | ||
| 342 | |||
| 343 | u32 finger; | ||
| 344 | u32 diameter_x; | ||
| 345 | u32 diameter_y; | ||
| 346 | u32 rotation_angle; | ||
| 347 | }; | ||
| 348 | |||
| 349 | enum class RendererBackend { | 19 | enum class RendererBackend { |
| 350 | OpenGL = 0, | 20 | OpenGL = 0, |
| 351 | Vulkan = 1, | 21 | Vulkan = 1, |
| @@ -461,6 +131,8 @@ struct Values { | |||
| 461 | // Controls | 131 | // Controls |
| 462 | std::array<PlayerInput, 10> players; | 132 | std::array<PlayerInput, 10> players; |
| 463 | 133 | ||
| 134 | bool use_docked_mode; | ||
| 135 | |||
| 464 | bool mouse_enabled; | 136 | bool mouse_enabled; |
| 465 | std::string mouse_device; | 137 | std::string mouse_device; |
| 466 | MouseButtonsRaw mouse_buttons; | 138 | MouseButtonsRaw mouse_buttons; |
| @@ -474,14 +146,15 @@ struct Values { | |||
| 474 | AnalogsRaw debug_pad_analogs; | 146 | AnalogsRaw debug_pad_analogs; |
| 475 | 147 | ||
| 476 | std::string motion_device; | 148 | std::string motion_device; |
| 149 | |||
| 150 | bool vibration_enabled; | ||
| 151 | |||
| 477 | TouchscreenInput touchscreen; | 152 | TouchscreenInput touchscreen; |
| 478 | std::atomic_bool is_device_reload_pending{true}; | 153 | std::atomic_bool is_device_reload_pending{true}; |
| 479 | std::string udp_input_address; | 154 | std::string udp_input_address; |
| 480 | u16 udp_input_port; | 155 | u16 udp_input_port; |
| 481 | u8 udp_pad_index; | 156 | u8 udp_pad_index; |
| 482 | 157 | ||
| 483 | bool use_docked_mode; | ||
| 484 | |||
| 485 | // Data Storage | 158 | // Data Storage |
| 486 | bool use_virtual_sd; | 159 | bool use_virtual_sd; |
| 487 | bool gamecard_inserted; | 160 | bool gamecard_inserted; |