Added GetLedPattern and HandheldVariant

HandheldVariant is for specific games which expect handheld controllers to be at position 8(kirby), however this doesn't fix all games as some games require handhelds to be at position 0(snipperclips)
master
David Marcec 2018-10-10 21:38:43 +07:00
parent 46cdeb4549
commit 3d75c9cd7a
3 changed files with 63 additions and 6 deletions

@ -41,6 +41,7 @@ void Controller_NPad::InitNewlyAddedControler(std::size_t controller_idx) {
controller.joy_styles.raw = 0; // Zero out
controller.device_type.raw = 0;
switch (controller_type) {
case NPadControllerType::HandheldVariant:
case NPadControllerType::Handheld:
controller.joy_styles.handheld.Assign(1);
controller.device_type.handheld.Assign(1);
@ -220,9 +221,12 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) {
}
switch (controller_type) {
case NPadControllerType::HandheldVariant:
case NPadControllerType::Handheld:
handheld_entry.connection_status.IsConnected.Assign(1);
if (!Settings::values.use_docked_mode) {
handheld_entry.connection_status.IsWired.Assign(1);
}
handheld_entry.pad_states.raw = pad_state.raw;
handheld_entry.l_stick = lstick_entry;
handheld_entry.r_stick = rstick_entry;
@ -334,7 +338,7 @@ void Controller_NPad::AddNewController(NPadControllerType controller) {
LOG_ERROR(Service_HID, "Cannot connect any more controllers!");
return;
}
if (controller == NPadControllerType::Handheld) {
if (controller == NPadControllerType::HandheldVariant) {
connected_controllers[8] = {controller, true};
InitNewlyAddedControler(8);
return;
@ -354,4 +358,32 @@ void Controller_NPad::DisconnectNPad(u32 npad_id) {
return;
connected_controllers[npad_id].is_connected = 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
return LedPattern{0, 0, 0, 0};
}
switch (npad_id) {
case 0:
return LedPattern{1, 0, 0, 0};
case 1:
return LedPattern{0, 1, 0, 0};
case 2:
return LedPattern{0, 0, 1, 0};
case 3:
return LedPattern{0, 0, 0, 1};
case 4:
return LedPattern{1, 0, 0, 1};
case 5:
return LedPattern{1, 0, 1, 0};
case 6:
return LedPattern{1, 0, 1, 1};
case 7:
return LedPattern{0, 1, 1, 0};
default:
UNIMPLEMENTED_MSG("Unhandled npad_id {}", npad_id);
return LedPattern{0, 0, 0, 0};
};
}
} // namespace Service::HID

@ -65,12 +65,29 @@ public:
None,
ProController,
Handheld,
HandheldVariant, // Games which require the handheld controller to be at index 8
JoyLeft,
JoyRight,
Tabletop,
Pokeball,
};
struct LedPattern {
explicit LedPattern(u64 light1, u64 light2, u64 light3, u64 light4) {
position1.Assign(light1);
position1.Assign(light2);
position1.Assign(light3);
position1.Assign(light4);
};
union {
u64 raw{};
BitField<0, 1, u64> position1;
BitField<1, 1, u64> position2;
BitField<2, 1, u64> position3;
BitField<3, 1, u64> position4;
};
};
void SetSupportedStyleSet(NPadType style_set);
NPadType GetSupportedStyleSet() const;
@ -93,6 +110,7 @@ public:
void ConnectNPad(u32 npad_id);
void DisconnectNPad(u32 npad_id);
LedPattern GetLedPattern(u32 npad_id);
private:
struct CommonHeader {
@ -255,8 +273,8 @@ private:
std::size_t dump_idx{};
Vibration last_processed_vibration{};
std::size_t controller_count{};
static constexpr std::array<u32, 9> npad_id_list{0, 1, 2, 3, 4, 5, 6, 7, 32};
std::array<ControllerHolder, 9> connected_controllers{};
static constexpr std::array<u32, 10> npad_id_list{0, 1, 2, 3, 4, 5, 6, 7, 32, 16};
std::array<ControllerHolder, 10> connected_controllers{};
void InitNewlyAddedControler(std::size_t controller_idx);
};

@ -421,9 +421,14 @@ private:
}
void GetPlayerLedPattern(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2};
IPC::RequestParser rp{ctx};
auto npad_id = rp.PopRaw<u32>();
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_HID, "(STUBBED) called");
rb.PushRaw<u64>(applet_resource->GetController<Controller_NPad>(HidController::NPad)
.GetLedPattern(npad_id)
.raw);
LOG_DEBUG(Service_HID, "called");
}
void SetNpadJoyHoldType(Kernel::HLERequestContext& ctx) {
@ -513,6 +518,8 @@ private:
}
void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
auto mode = rp.PopRaw<u32>();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_HID, "(STUBBED) called");