diff options
| author | 2018-10-18 14:11:15 +1100 | |
|---|---|---|
| committer | 2018-11-18 23:21:33 -0500 | |
| commit | beab38601badd54930881858b4a021fe76a92b39 (patch) | |
| tree | 1e385dee587c3b7b09d191a11c425983ec659b84 /src | |
| parent | Merge pull request #1717 from FreddyFunk/swizzle-gob (diff) | |
| download | yuzu-beab38601badd54930881858b4a021fe76a92b39.tar.gz yuzu-beab38601badd54930881858b4a021fe76a92b39.tar.xz yuzu-beab38601badd54930881858b4a021fe76a92b39.zip | |
Added multi-input support and controller assignment at any port
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/service/hid/controllers/npad.cpp | 287 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/npad.h | 16 |
2 files changed, 181 insertions, 122 deletions
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() { | |||
| 164 | 164 | ||
| 165 | void Controller_NPad::OnRelease() {} | 165 | void Controller_NPad::OnRelease() {} |
| 166 | 166 | ||
| 167 | void Controller_NPad::RequestPadStateUpdate(u32 npad_id) { | ||
| 168 | const auto controller_idx = NPadIdToIndex(npad_id); | ||
| 169 | const auto controller_type = connected_controllers[controller_idx].type; | ||
| 170 | if (!connected_controllers[controller_idx].is_connected) { | ||
| 171 | return; | ||
| 172 | } | ||
| 173 | auto& pad_state = npad_pad_states[controller_idx].pad_states; | ||
| 174 | auto& lstick_entry = npad_pad_states[controller_idx].l_stick; | ||
| 175 | auto& rstick_entry = npad_pad_states[controller_idx].r_stick; | ||
| 176 | using namespace Settings::NativeButton; | ||
| 177 | pad_state.a.Assign(buttons[A - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 178 | pad_state.b.Assign(buttons[B - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 179 | pad_state.x.Assign(buttons[X - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 180 | pad_state.y.Assign(buttons[Y - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 181 | pad_state.l_stick.Assign(buttons[LStick - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 182 | pad_state.r_stick.Assign(buttons[RStick - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 183 | pad_state.l.Assign(buttons[L - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 184 | pad_state.r.Assign(buttons[R - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 185 | pad_state.zl.Assign(buttons[ZL - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 186 | pad_state.zr.Assign(buttons[ZR - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 187 | pad_state.plus.Assign(buttons[Plus - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 188 | pad_state.minus.Assign(buttons[Minus - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 189 | |||
| 190 | pad_state.d_left.Assign(buttons[DLeft - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 191 | pad_state.d_up.Assign(buttons[DUp - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 192 | pad_state.d_right.Assign(buttons[DRight - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 193 | pad_state.d_down.Assign(buttons[DDown - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 194 | |||
| 195 | pad_state.l_stick_left.Assign(buttons[LStick_Left - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 196 | pad_state.l_stick_up.Assign(buttons[LStick_Up - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 197 | pad_state.l_stick_right.Assign(buttons[LStick_Right - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 198 | pad_state.l_stick_down.Assign(buttons[LStick_Down - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 199 | |||
| 200 | pad_state.r_stick_left.Assign(buttons[RStick_Left - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 201 | pad_state.r_stick_up.Assign(buttons[RStick_Up - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 202 | pad_state.r_stick_right.Assign(buttons[RStick_Right - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 203 | pad_state.r_stick_down.Assign(buttons[RStick_Down - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 204 | |||
| 205 | pad_state.sl.Assign(buttons[SL - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 206 | pad_state.sr.Assign(buttons[SR - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 207 | |||
| 208 | const auto [stick_l_x_f, stick_l_y_f] = | ||
| 209 | sticks[static_cast<std::size_t>(JoystickId::Joystick_Left)]->GetStatus(); | ||
| 210 | const auto [stick_r_x_f, stick_r_y_f] = | ||
| 211 | sticks[static_cast<std::size_t>(JoystickId::Joystick_Right)]->GetStatus(); | ||
| 212 | lstick_entry.x = static_cast<s32>(stick_l_x_f * HID_JOYSTICK_MAX); | ||
| 213 | lstick_entry.y = static_cast<s32>(stick_l_y_f * HID_JOYSTICK_MAX); | ||
| 214 | rstick_entry.x = static_cast<s32>(stick_r_x_f * HID_JOYSTICK_MAX); | ||
| 215 | rstick_entry.y = static_cast<s32>(stick_r_y_f * HID_JOYSTICK_MAX); | ||
| 216 | } | ||
| 217 | |||
| 167 | void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) { | 218 | void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) { |
| 168 | if (!IsControllerActivated()) | 219 | if (!IsControllerActivated()) |
| 169 | return; | 220 | return; |
| @@ -199,97 +250,9 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) { | |||
| 199 | if (controller_type == NPadControllerType::None || !connected_controllers[i].is_connected) { | 250 | if (controller_type == NPadControllerType::None || !connected_controllers[i].is_connected) { |
| 200 | continue; | 251 | continue; |
| 201 | } | 252 | } |
| 202 | 253 | const u32 npad_index = static_cast<u32>(i); | |
| 203 | // Pad states | 254 | RequestPadStateUpdate(npad_index); |
| 204 | ControllerPadState pad_state{}; | 255 | auto& pad_state = npad_pad_states[npad_index]; |
| 205 | using namespace Settings::NativeButton; | ||
| 206 | pad_state.a.Assign(buttons[A - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 207 | pad_state.b.Assign(buttons[B - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 208 | pad_state.x.Assign(buttons[X - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 209 | pad_state.y.Assign(buttons[Y - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 210 | pad_state.l_stick.Assign(buttons[LStick - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 211 | pad_state.r_stick.Assign(buttons[RStick - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 212 | pad_state.l.Assign(buttons[L - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 213 | pad_state.r.Assign(buttons[R - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 214 | pad_state.zl.Assign(buttons[ZL - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 215 | pad_state.zr.Assign(buttons[ZR - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 216 | pad_state.plus.Assign(buttons[Plus - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 217 | pad_state.minus.Assign(buttons[Minus - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 218 | |||
| 219 | pad_state.d_left.Assign(buttons[DLeft - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 220 | pad_state.d_up.Assign(buttons[DUp - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 221 | pad_state.d_right.Assign(buttons[DRight - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 222 | pad_state.d_down.Assign(buttons[DDown - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 223 | |||
| 224 | pad_state.l_stick_left.Assign(buttons[LStick_Left - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 225 | pad_state.l_stick_up.Assign(buttons[LStick_Up - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 226 | pad_state.l_stick_right.Assign(buttons[LStick_Right - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 227 | pad_state.l_stick_down.Assign(buttons[LStick_Down - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 228 | |||
| 229 | pad_state.r_stick_left.Assign(buttons[RStick_Left - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 230 | pad_state.r_stick_up.Assign(buttons[RStick_Up - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 231 | pad_state.r_stick_right.Assign(buttons[RStick_Right - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 232 | pad_state.r_stick_down.Assign(buttons[RStick_Down - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 233 | |||
| 234 | pad_state.sl.Assign(buttons[SL - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 235 | pad_state.sr.Assign(buttons[SR - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 236 | |||
| 237 | AnalogPosition lstick_entry{}; | ||
| 238 | AnalogPosition rstick_entry{}; | ||
| 239 | |||
| 240 | const auto [stick_l_x_f, stick_l_y_f] = | ||
| 241 | sticks[static_cast<std::size_t>(JoystickId::Joystick_Left)]->GetStatus(); | ||
| 242 | const auto [stick_r_x_f, stick_r_y_f] = | ||
| 243 | sticks[static_cast<std::size_t>(JoystickId::Joystick_Right)]->GetStatus(); | ||
| 244 | lstick_entry.x = static_cast<s32>(stick_l_x_f * HID_JOYSTICK_MAX); | ||
| 245 | lstick_entry.y = static_cast<s32>(stick_l_y_f * HID_JOYSTICK_MAX); | ||
| 246 | rstick_entry.x = static_cast<s32>(stick_r_x_f * HID_JOYSTICK_MAX); | ||
| 247 | rstick_entry.y = static_cast<s32>(stick_r_y_f * HID_JOYSTICK_MAX); | ||
| 248 | |||
| 249 | if (controller_type == NPadControllerType::JoyLeft || | ||
| 250 | controller_type == NPadControllerType::JoyRight) { | ||
| 251 | if (npad.properties.is_horizontal) { | ||
| 252 | ControllerPadState state{}; | ||
| 253 | AnalogPosition temp_lstick_entry{}; | ||
| 254 | AnalogPosition temp_rstick_entry{}; | ||
| 255 | if (controller_type == NPadControllerType::JoyLeft) { | ||
| 256 | state.d_down.Assign(pad_state.d_left.Value()); | ||
| 257 | state.d_left.Assign(pad_state.d_up.Value()); | ||
| 258 | state.d_right.Assign(pad_state.d_down.Value()); | ||
| 259 | state.d_up.Assign(pad_state.d_right.Value()); | ||
| 260 | state.l.Assign(pad_state.l.Value() | pad_state.sl.Value()); | ||
| 261 | state.r.Assign(pad_state.r.Value() | pad_state.sr.Value()); | ||
| 262 | |||
| 263 | state.zl.Assign(pad_state.zl.Value()); | ||
| 264 | state.plus.Assign(pad_state.minus.Value()); | ||
| 265 | |||
| 266 | temp_lstick_entry = lstick_entry; | ||
| 267 | temp_rstick_entry = rstick_entry; | ||
| 268 | std::swap(temp_lstick_entry.x, temp_lstick_entry.y); | ||
| 269 | std::swap(temp_rstick_entry.x, temp_rstick_entry.y); | ||
| 270 | temp_lstick_entry.y *= -1; | ||
| 271 | } else if (controller_type == NPadControllerType::JoyRight) { | ||
| 272 | state.x.Assign(pad_state.a.Value()); | ||
| 273 | state.a.Assign(pad_state.b.Value()); | ||
| 274 | state.b.Assign(pad_state.y.Value()); | ||
| 275 | state.y.Assign(pad_state.b.Value()); | ||
| 276 | |||
| 277 | state.l.Assign(pad_state.l.Value() | pad_state.sl.Value()); | ||
| 278 | state.r.Assign(pad_state.r.Value() | pad_state.sr.Value()); | ||
| 279 | state.zr.Assign(pad_state.zr.Value()); | ||
| 280 | state.plus.Assign(pad_state.plus.Value()); | ||
| 281 | |||
| 282 | temp_lstick_entry = lstick_entry; | ||
| 283 | temp_rstick_entry = rstick_entry; | ||
| 284 | std::swap(temp_lstick_entry.x, temp_lstick_entry.y); | ||
| 285 | std::swap(temp_rstick_entry.x, temp_rstick_entry.y); | ||
| 286 | temp_rstick_entry.x *= -1; | ||
| 287 | } | ||
| 288 | pad_state.raw = state.raw; | ||
| 289 | lstick_entry = temp_lstick_entry; | ||
| 290 | rstick_entry = temp_rstick_entry; | ||
| 291 | } | ||
| 292 | } | ||
| 293 | 256 | ||
| 294 | auto& main_controller = | 257 | auto& main_controller = |
| 295 | npad.main_controller_states.npad[npad.main_controller_states.common.last_entry_index]; | 258 | 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) { | |||
| 304 | auto& libnx_entry = npad.libnx.npad[npad.libnx.common.last_entry_index]; | 267 | auto& libnx_entry = npad.libnx.npad[npad.libnx.common.last_entry_index]; |
| 305 | 268 | ||
| 306 | if (hold_type == NpadHoldType::Horizontal) { | 269 | if (hold_type == NpadHoldType::Horizontal) { |
| 307 | // TODO(ogniK): Remap buttons for different orientations | 270 | ControllerPadState state{}; |
| 271 | AnalogPosition temp_lstick_entry{}; | ||
| 272 | AnalogPosition temp_rstick_entry{}; | ||
| 273 | if (controller_type == NPadControllerType::JoyLeft) { | ||
| 274 | state.d_down.Assign(pad_state.pad_states.d_left.Value()); | ||
| 275 | state.d_left.Assign(pad_state.pad_states.d_up.Value()); | ||
| 276 | state.d_right.Assign(pad_state.pad_states.d_down.Value()); | ||
| 277 | state.d_up.Assign(pad_state.pad_states.d_right.Value()); | ||
| 278 | state.l.Assign(pad_state.pad_states.l.Value() | pad_state.pad_states.sl.Value()); | ||
| 279 | state.r.Assign(pad_state.pad_states.r.Value() | pad_state.pad_states.sr.Value()); | ||
| 280 | |||
| 281 | state.zl.Assign(pad_state.pad_states.zl.Value()); | ||
| 282 | state.plus.Assign(pad_state.pad_states.minus.Value()); | ||
| 283 | |||
| 284 | temp_lstick_entry = pad_state.l_stick; | ||
| 285 | temp_rstick_entry = pad_state.r_stick; | ||
| 286 | std::swap(temp_lstick_entry.x, temp_lstick_entry.y); | ||
| 287 | std::swap(temp_rstick_entry.x, temp_rstick_entry.y); | ||
| 288 | temp_lstick_entry.y *= -1; | ||
| 289 | } else if (controller_type == NPadControllerType::JoyRight) { | ||
| 290 | state.x.Assign(pad_state.pad_states.a.Value()); | ||
| 291 | state.a.Assign(pad_state.pad_states.b.Value()); | ||
| 292 | state.b.Assign(pad_state.pad_states.y.Value()); | ||
| 293 | state.y.Assign(pad_state.pad_states.b.Value()); | ||
| 294 | |||
| 295 | state.l.Assign(pad_state.pad_states.l.Value() | pad_state.pad_states.sl.Value()); | ||
| 296 | state.r.Assign(pad_state.pad_states.r.Value() | pad_state.pad_states.sr.Value()); | ||
| 297 | state.zr.Assign(pad_state.pad_states.zr.Value()); | ||
| 298 | state.plus.Assign(pad_state.pad_states.plus.Value()); | ||
| 299 | |||
| 300 | temp_lstick_entry = pad_state.l_stick; | ||
| 301 | temp_rstick_entry = pad_state.r_stick; | ||
| 302 | std::swap(temp_lstick_entry.x, temp_lstick_entry.y); | ||
| 303 | std::swap(temp_rstick_entry.x, temp_rstick_entry.y); | ||
| 304 | temp_rstick_entry.x *= -1; | ||
| 305 | } | ||
| 306 | pad_state.pad_states.raw = state.raw; | ||
| 307 | pad_state.l_stick = temp_lstick_entry; | ||
| 308 | pad_state.r_stick = temp_rstick_entry; | ||
| 308 | } | 309 | } |
| 309 | libnx_entry.connection_status.raw = 0; | 310 | libnx_entry.connection_status.raw = 0; |
| 310 | 311 | ||
| @@ -316,9 +317,9 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) { | |||
| 316 | handheld_entry.connection_status.IsRightJoyConnected.Assign(1); | 317 | handheld_entry.connection_status.IsRightJoyConnected.Assign(1); |
| 317 | handheld_entry.connection_status.IsLeftJoyWired.Assign(1); | 318 | handheld_entry.connection_status.IsLeftJoyWired.Assign(1); |
| 318 | handheld_entry.connection_status.IsRightJoyWired.Assign(1); | 319 | handheld_entry.connection_status.IsRightJoyWired.Assign(1); |
| 319 | handheld_entry.pad_states.raw = pad_state.raw; | 320 | handheld_entry.pad.pad_states.raw = pad_state.pad_states.raw; |
| 320 | handheld_entry.l_stick = lstick_entry; | 321 | handheld_entry.pad.l_stick = pad_state.l_stick; |
| 321 | handheld_entry.r_stick = rstick_entry; | 322 | handheld_entry.pad.r_stick = pad_state.r_stick; |
| 322 | break; | 323 | break; |
| 323 | case NPadControllerType::JoyDual: | 324 | case NPadControllerType::JoyDual: |
| 324 | dual_entry.connection_status.raw = 0; | 325 | dual_entry.connection_status.raw = 0; |
| @@ -339,17 +340,17 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) { | |||
| 339 | left_entry.connection_status.raw = 0; | 340 | left_entry.connection_status.raw = 0; |
| 340 | 341 | ||
| 341 | left_entry.connection_status.IsConnected.Assign(1); | 342 | left_entry.connection_status.IsConnected.Assign(1); |
| 342 | left_entry.pad_states.raw = pad_state.raw; | 343 | left_entry.pad.pad_states.raw = pad_state.pad_states.raw; |
| 343 | left_entry.l_stick = lstick_entry; | 344 | left_entry.pad.l_stick = pad_state.l_stick; |
| 344 | left_entry.r_stick = rstick_entry; | 345 | left_entry.pad.r_stick = pad_state.r_stick; |
| 345 | break; | 346 | break; |
| 346 | case NPadControllerType::JoyRight: | 347 | case NPadControllerType::JoyRight: |
| 347 | right_entry.connection_status.raw = 0; | 348 | right_entry.connection_status.raw = 0; |
| 348 | 349 | ||
| 349 | right_entry.connection_status.IsConnected.Assign(1); | 350 | right_entry.connection_status.IsConnected.Assign(1); |
| 350 | right_entry.pad_states.raw = pad_state.raw; | 351 | right_entry.pad.pad_states.raw = pad_state.pad_states.raw; |
| 351 | right_entry.l_stick = lstick_entry; | 352 | right_entry.pad.l_stick = pad_state.l_stick; |
| 352 | right_entry.r_stick = rstick_entry; | 353 | right_entry.pad.r_stick = pad_state.r_stick; |
| 353 | break; | 354 | break; |
| 354 | case NPadControllerType::Pokeball: | 355 | case NPadControllerType::Pokeball: |
| 355 | pokeball_entry.connection_status.raw = 0; | 356 | pokeball_entry.connection_status.raw = 0; |
| @@ -357,26 +358,26 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) { | |||
| 357 | pokeball_entry.connection_status.IsConnected.Assign(1); | 358 | pokeball_entry.connection_status.IsConnected.Assign(1); |
| 358 | pokeball_entry.connection_status.IsWired.Assign(1); | 359 | pokeball_entry.connection_status.IsWired.Assign(1); |
| 359 | 360 | ||
| 360 | pokeball_entry.pad_states.raw = pad_state.raw; | 361 | pokeball_entry.pad.pad_states.raw = pad_state.pad_states.raw; |
| 361 | pokeball_entry.l_stick = lstick_entry; | 362 | pokeball_entry.pad.l_stick = pad_state.l_stick; |
| 362 | pokeball_entry.r_stick = rstick_entry; | 363 | pokeball_entry.pad.r_stick = pad_state.r_stick; |
| 363 | break; | 364 | break; |
| 364 | case NPadControllerType::ProController: | 365 | case NPadControllerType::ProController: |
| 365 | main_controller.connection_status.raw = 0; | 366 | main_controller.connection_status.raw = 0; |
| 366 | 367 | ||
| 367 | main_controller.connection_status.IsConnected.Assign(1); | 368 | main_controller.connection_status.IsConnected.Assign(1); |
| 368 | main_controller.connection_status.IsWired.Assign(1); | 369 | main_controller.connection_status.IsWired.Assign(1); |
| 369 | main_controller.pad_states.raw = pad_state.raw; | 370 | main_controller.pad.pad_states.raw = pad_state.pad_states.raw; |
| 370 | main_controller.l_stick = lstick_entry; | 371 | main_controller.pad.l_stick = pad_state.l_stick; |
| 371 | main_controller.r_stick = rstick_entry; | 372 | main_controller.pad.r_stick = pad_state.r_stick; |
| 372 | break; | 373 | break; |
| 373 | } | 374 | } |
| 374 | 375 | ||
| 375 | // LibNX exclusively uses this section, so we always update it since LibNX doesn't activate | 376 | // LibNX exclusively uses this section, so we always update it since LibNX doesn't activate |
| 376 | // any controllers. | 377 | // any controllers. |
| 377 | libnx_entry.pad_states.raw = pad_state.raw; | 378 | libnx_entry.pad.pad_states.raw = pad_state.pad_states.raw; |
| 378 | libnx_entry.l_stick = lstick_entry; | 379 | libnx_entry.pad.l_stick = pad_state.l_stick; |
| 379 | libnx_entry.r_stick = rstick_entry; | 380 | libnx_entry.pad.r_stick = pad_state.r_stick; |
| 380 | } | 381 | } |
| 381 | std::memcpy(data + NPAD_OFFSET, shared_memory_entries.data(), | 382 | std::memcpy(data + NPAD_OFFSET, shared_memory_entries.data(), |
| 382 | shared_memory_entries.size() * sizeof(NPadEntry)); | 383 | shared_memory_entries.size() * sizeof(NPadEntry)); |
| @@ -450,15 +451,7 @@ void Controller_NPad::VibrateController(const std::vector<u32>& controller_ids, | |||
| 450 | return; | 451 | return; |
| 451 | } | 452 | } |
| 452 | for (std::size_t i = 0; i < controller_ids.size(); i++) { | 453 | for (std::size_t i = 0; i < controller_ids.size(); i++) { |
| 453 | std::size_t controller_pos = i; | 454 | std::size_t controller_pos = NPadIdToIndex(static_cast<u32>(i)); |
| 454 | // Handheld controller conversion | ||
| 455 | if (controller_pos == NPAD_HANDHELD) { | ||
| 456 | controller_pos = 8; | ||
| 457 | } | ||
| 458 | // Unknown controller conversion | ||
| 459 | if (controller_pos == NPAD_UNKNOWN) { | ||
| 460 | controller_pos = 9; | ||
| 461 | } | ||
| 462 | if (connected_controllers[controller_pos].is_connected) { | 455 | if (connected_controllers[controller_pos].is_connected) { |
| 463 | // TODO(ogniK): Vibrate the physical controller | 456 | // TODO(ogniK): Vibrate the physical controller |
| 464 | } | 457 | } |
| @@ -477,6 +470,51 @@ Kernel::SharedPtr<Kernel::Event> Controller_NPad::GetStyleSetChangedEvent() cons | |||
| 477 | Controller_NPad::Vibration Controller_NPad::GetLastVibration() const { | 470 | Controller_NPad::Vibration Controller_NPad::GetLastVibration() const { |
| 478 | return last_processed_vibration; | 471 | return last_processed_vibration; |
| 479 | } | 472 | } |
| 473 | |||
| 474 | std::size_t Controller_NPad::NPadIdToIndex(u32 npad_id) { | ||
| 475 | switch (npad_id) { | ||
| 476 | case 0: | ||
| 477 | case 1: | ||
| 478 | case 2: | ||
| 479 | case 3: | ||
| 480 | case 4: | ||
| 481 | case 5: | ||
| 482 | case 6: | ||
| 483 | case 7: | ||
| 484 | return static_cast<std::size_t>(npad_id); | ||
| 485 | case 8: | ||
| 486 | case 32: | ||
| 487 | return 8; | ||
| 488 | case 9: | ||
| 489 | case 16: | ||
| 490 | return 9; | ||
| 491 | default: | ||
| 492 | UNIMPLEMENTED_MSG("Unknown npad id {}", npad_id); | ||
| 493 | return 0; | ||
| 494 | } | ||
| 495 | } | ||
| 496 | |||
| 497 | u32 Controller_NPad::IndexToNPad(std::size_t index) { | ||
| 498 | switch (index) { | ||
| 499 | case 0: | ||
| 500 | case 1: | ||
| 501 | case 2: | ||
| 502 | case 3: | ||
| 503 | case 4: | ||
| 504 | case 5: | ||
| 505 | case 6: | ||
| 506 | case 7: | ||
| 507 | return static_cast<u32>(index); | ||
| 508 | case 8: | ||
| 509 | return 32; | ||
| 510 | case 9: | ||
| 511 | return 16; | ||
| 512 | default: | ||
| 513 | UNIMPLEMENTED_MSG("Unknown npad index {}", index); | ||
| 514 | return 0; | ||
| 515 | }; | ||
| 516 | } | ||
| 517 | |||
| 480 | void Controller_NPad::AddNewController(NPadControllerType controller) { | 518 | void Controller_NPad::AddNewController(NPadControllerType controller) { |
| 481 | if (controller == NPadControllerType::Handheld) { | 519 | if (controller == NPadControllerType::Handheld) { |
| 482 | connected_controllers[8] = {controller, true}; | 520 | connected_controllers[8] = {controller, true}; |
| @@ -495,6 +533,17 @@ void Controller_NPad::AddNewController(NPadControllerType controller) { | |||
| 495 | InitNewlyAddedControler(controller_id); | 533 | InitNewlyAddedControler(controller_id); |
| 496 | } | 534 | } |
| 497 | 535 | ||
| 536 | void Controller_NPad::AddNewControllerAt(NPadControllerType controller, u32 npad_id) { | ||
| 537 | if (controller == NPadControllerType::Handheld) { | ||
| 538 | connected_controllers[8] = {controller, true}; | ||
| 539 | InitNewlyAddedControler(8); | ||
| 540 | return; | ||
| 541 | } | ||
| 542 | const size_t controller_id = static_cast<std::size_t>(npad_id); | ||
| 543 | connected_controllers[controller_id] = {controller, true}; | ||
| 544 | InitNewlyAddedControler(controller_id); | ||
| 545 | } | ||
| 546 | |||
| 498 | void Controller_NPad::ConnectNPad(u32 npad_id) { | 547 | void Controller_NPad::ConnectNPad(u32 npad_id) { |
| 499 | connected_controllers[NPadIdToIndex(npad_id)].is_connected = true; | 548 | connected_controllers[NPadIdToIndex(npad_id)].is_connected = true; |
| 500 | } | 549 | } |
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: | |||
| 107 | Vibration GetLastVibration() const; | 107 | Vibration GetLastVibration() const; |
| 108 | 108 | ||
| 109 | void AddNewController(NPadControllerType controller); | 109 | void AddNewController(NPadControllerType controller); |
| 110 | void AddNewControllerAt(NPadControllerType controller, u32 npad_id); | ||
| 110 | 111 | ||
| 111 | void ConnectNPad(u32 npad_id); | 112 | void ConnectNPad(u32 npad_id); |
| 112 | void DisconnectNPad(u32 npad_id); | 113 | void DisconnectNPad(u32 npad_id); |
| @@ -189,12 +190,17 @@ private: | |||
| 189 | }; | 190 | }; |
| 190 | static_assert(sizeof(ConnectionState) == 4, "ConnectionState is an invalid size"); | 191 | static_assert(sizeof(ConnectionState) == 4, "ConnectionState is an invalid size"); |
| 191 | 192 | ||
| 192 | struct GenericStates { | 193 | struct ControllerPad { |
| 193 | s64_le timestamp; | ||
| 194 | s64_le timestamp2; | ||
| 195 | ControllerPadState pad_states; | 194 | ControllerPadState pad_states; |
| 196 | AnalogPosition l_stick; | 195 | AnalogPosition l_stick; |
| 197 | AnalogPosition r_stick; | 196 | AnalogPosition r_stick; |
| 197 | }; | ||
| 198 | static_assert(sizeof(ControllerPad) == 0x18, "ControllerPad is an invalid size"); | ||
| 199 | |||
| 200 | struct GenericStates { | ||
| 201 | s64_le timestamp; | ||
| 202 | s64_le timestamp2; | ||
| 203 | ControllerPad pad; | ||
| 198 | ConnectionState connection_status; | 204 | ConnectionState connection_status; |
| 199 | }; | 205 | }; |
| 200 | static_assert(sizeof(GenericStates) == 0x30, "NPadGenericStates is an invalid size"); | 206 | static_assert(sizeof(GenericStates) == 0x30, "NPadGenericStates is an invalid size"); |
| @@ -285,5 +291,9 @@ private: | |||
| 285 | void InitNewlyAddedControler(std::size_t controller_idx); | 291 | void InitNewlyAddedControler(std::size_t controller_idx); |
| 286 | bool IsControllerSupported(NPadControllerType controller) const; | 292 | bool IsControllerSupported(NPadControllerType controller) const; |
| 287 | NPadControllerType DecideBestController(NPadControllerType priority) const; | 293 | NPadControllerType DecideBestController(NPadControllerType priority) const; |
| 294 | void RequestPadStateUpdate(u32 npad_id); | ||
| 295 | std::size_t NPadIdToIndex(u32 npad_id); | ||
| 296 | u32 IndexToNPad(std::size_t index); | ||
| 297 | std::array<ControllerPad, 10> npad_pad_states{}; | ||
| 288 | }; | 298 | }; |
| 289 | } // namespace Service::HID | 299 | } // namespace Service::HID |