This commit is contained in:
german77 2023-07-24 07:10:34 -06:00
parent 21a98b3fc7
commit 34a85b5a1e
4 changed files with 187 additions and 66 deletions

View File

@ -14,11 +14,21 @@ constexpr Result VibrationInvalidStyleIndex{ErrorModule::HID, 122};
constexpr Result VibrationInvalidNpadId{ErrorModule::HID, 123};
constexpr Result VibrationDeviceIndexOutOfRange{ErrorModule::HID, 124};
constexpr Result InvalidSixAxisFusionRange{ErrorModule::HID, 423};
constexpr Result ResultMcuInvalidHandle{ErrorModule::HID, 541};
constexpr Result ResultMcuNotEnabled{ErrorModule::HID, 542};
constexpr Result ResultMcuNoDeviceConnected{ErrorModule::HID, 543};
constexpr Result ResultMcuUnknown544{ErrorModule::HID, 544};
constexpr Result ResultMcuUnknown546{ErrorModule::HID, 546};
constexpr Result ResultMcuUnknown548{ErrorModule::HID, 548};
constexpr Result NpadIsDualJoycon{ErrorModule::HID, 601};
constexpr Result NpadIsSameType{ErrorModule::HID, 602};
constexpr Result InvalidNpadId{ErrorModule::HID, 709};
constexpr Result NpadNotConnected{ErrorModule::HID, 710};
constexpr Result InvalidArraySize{ErrorModule::HID, 715};
constexpr Result ResultControllerUpdateFailed{ErrorModule::HID, 3201};
constexpr Result InvalidPalmaHandle{ErrorModule::HID, 3302};
} // namespace Service::HID
@ -29,3 +39,17 @@ constexpr Result InvalidProcessorState{ErrorModule::Irsensor, 78};
constexpr Result InvalidIrCameraHandle{ErrorModule::Irsensor, 204};
} // namespace Service::IRS
namespace Service::HIDBUS {
constexpr Result ResultNotEnabled{ErrorModule::HIDBUS, 1};
constexpr Result ResultControllerUpdateFailed{ErrorModule::HIDBUS, 3};
constexpr Result ResultInvalidBusHandle{ErrorModule::HIDBUS, 4};
constexpr Result ResultNoDeviceConnected{ErrorModule::HIDBUS, 5};
constexpr Result ResultUknown6{ErrorModule::HIDBUS, 6};
constexpr Result ResultPollingRecieveDataNotAvailable{ErrorModule::HIDBUS, 7};
constexpr Result ResultDeviceEnabledNotSet{ErrorModule::HIDBUS, 8};
constexpr Result ResultBusHandleAlreadyInitialized{ErrorModule::HIDBUS, 10};
constexpr Result ResultInvalidBusType{ErrorModule::HIDBUS, 11};
} // namespace Service::HIDBUS

View File

@ -10,6 +10,8 @@
#include "core/hle/kernel/k_readable_event.h"
#include "core/hle/kernel/k_shared_memory.h"
#include "core/hle/kernel/k_transfer_memory.h"
#include "core/hle/service/hid/controllers/npad.h"
#include "core/hle/service/hid/errors.h"
#include "core/hle/service/hid/hidbus.h"
#include "core/hle/service/hid/hidbus/ringcon.h"
#include "core/hle/service/hid/hidbus/starlink.h"
@ -64,25 +66,7 @@ HidBus::~HidBus() {
system.CoreTiming().UnscheduleEvent(hidbus_update_event, 0);
}
void HidBus::UpdateHidbus(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
if (is_hidbus_enabled) {
for (std::size_t i = 0; i < devices.size(); ++i) {
if (!devices[i].is_device_initializated) {
continue;
}
auto& device = devices[i].device;
device->OnUpdate();
auto& cur_entry = hidbus_status.entries[devices[i].handle.internal_index];
cur_entry.is_polling_mode = device->IsPollingMode();
cur_entry.polling_mode = device->GetPollingMode();
cur_entry.is_enabled = device->IsEnabled();
u8* shared_memory = system.Kernel().GetHidBusSharedMem().GetPointer();
std::memcpy(shared_memory + (i * sizeof(HidbusStatusManagerEntry)), &hidbus_status,
sizeof(HidbusStatusManagerEntry));
}
}
}
void HidBus::UpdateHidbus(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {}
std::optional<std::size_t> HidBus::GetDeviceIndexFromHandle(BusHandle handle) const {
for (std::size_t i = 0; i < devices.size(); ++i) {
@ -108,45 +92,6 @@ void HidBus::GetBusHandle(HLERequestContext& ctx) {
};
static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()};
LOG_INFO(Service_HID, "called, npad_id={}, bus_type={}, applet_resource_user_id={}",
parameters.npad_id, parameters.bus_type, parameters.applet_resource_user_id);
bool is_handle_found = 0;
std::size_t handle_index = 0;
for (std::size_t i = 0; i < devices.size(); i++) {
const auto& handle = devices[i].handle;
if (!handle.is_valid) {
continue;
}
if (static_cast<Core::HID::NpadIdType>(handle.player_number) == parameters.npad_id &&
handle.bus_type_id == static_cast<u8>(parameters.bus_type)) {
is_handle_found = true;
handle_index = i;
break;
}
}
// Handle not found. Create a new one
if (!is_handle_found) {
for (std::size_t i = 0; i < devices.size(); i++) {
if (devices[i].handle.is_valid) {
continue;
}
devices[i].handle = {
.abstracted_pad_id = static_cast<u8>(i),
.internal_index = static_cast<u8>(i),
.player_number = static_cast<u8>(parameters.npad_id),
.bus_type_id = static_cast<u8>(parameters.bus_type),
.is_valid = true,
};
handle_index = i;
break;
}
}
struct OutData {
bool is_valid;
INSERT_PADDING_BYTES(7);
@ -154,16 +99,158 @@ void HidBus::GetBusHandle(HLERequestContext& ctx) {
};
static_assert(sizeof(OutData) == 0x10, "OutData has incorrect size.");
const OutData out_data{
.is_valid = true,
.handle = devices[handle_index].handle,
};
const auto parameters{rp.PopRaw<Parameters>()};
LOG_INFO(Service_HID, "called, npad_id={}, bus_type={}, applet_resource_user_id={}",
parameters.npad_id, parameters.bus_type, parameters.applet_resource_user_id);
if (parameters.bus_type >= BusType::MaxBusType) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(HIDBUS::ResultInvalidBusType);
return;
}
OutData out_data{};
out_data.is_valid = GetBusHandleImpl(out_data.handle, parameters.npad_id, parameters.bus_type);
IPC::ResponseBuilder rb{ctx, 6};
rb.Push(ResultSuccess);
rb.PushRaw(out_data);
}
bool HidBus::GetBusHandleImpl(BusHandle& handle, Core::HID::NpadIdType npad_id,
BusType bus_type) const {
if (!Controller_NPad::IsNpadIdValid(npad_id)) {
return false;
}
if (MakeBusHandle(handle, npad_id, bus_type).IsError()) {
return false;
}
if (bus_type == BusType::LeftJoyRail || bus_type == BusType::RightJoyRail) {
// TODO: IsBusHandleValid(*npad_id,bus_type)
return true;
}
if (bus_type == BusType::InternalBus) {
// TODO: IsBusHandleValid(*npad_id,BusType::RightJoyRail)
return true;
}
return false;
}
Result HidBus::MakeBusHandle(BusHandle& handle, Core::HID::NpadIdType npad_id,
BusType bus_type) const {
u32 abstracted_pad_id{};
const Result result = GetAbstractedHidbusPadId(abstracted_pad_id, npad_id, bus_type);
if (result.IsError()) {
return result;
}
u8 internal_index = static_cast<u8>(npad_id);
if (bus_type < BusType::MaxBusType) {
internal_index = internal_index << 1 | 1;
}
if (bus_type == BusType::LeftJoyRail) {
internal_index = internal_index << 1;
}
if (npad_id == Core::HID::NpadIdType::Handheld) {
switch (bus_type) {
case BusType::LeftJoyRail:
internal_index = 0x10;
break;
case BusType::InternalBus:
internal_index = 0;
break;
default:
internal_index = 0x11;
break;
}
}
handle = {
.abstracted_pad_id = abstracted_pad_id,
.internal_index = internal_index,
.player_number = static_cast<u8>(npad_id) && 0xff,
.bus_type_id = static_cast<u8>(bus_type) && 0xff,
.is_valid = true, // This is hardcoded on the sysmodule
};
return ResultSuccess;
}
Result HidBus::GetAbstractedHidbusPadId(u32& abstracted_pad_id, Core::HID::NpadIdType npad_id,
BusType bus_type) const {
// This struct is unknown
struct LeftData {
std::array<u8, 4> data;
};
struct ControllerData {
u32 data_1;
u32 data_2;
u32 is_connected; // ((d + 0x8) >> 1 & 1)
u32 abstracted_pad_id;
u32 data_5;
u32 data_6;
u32 data_7;
u32 data_8;
LeftData left_data;
u32 right_data;
u32 data_11;
u32 data_12;
u32 data_13;
u32 has_battery; // ((d + 0x3a) & 6) ((d + 0x38) & 0x60000)
u32 data_15;
u32 data_16;
};
static_assert(sizeof(ControllerData) == 0x40, "ControllerData has incorrect size.");
// auto& controller = GetControllerFromNpadIdType(npad_id);
const std::array<ControllerData, 5> data_pointer{}; // controller->GetControllerData(5);
if (data_pointer.size() == 0) {
return ResultMcuInvalidHandle;
}
for (const ControllerData& data : data_pointer) {
bool is_valid = false;
switch (bus_type) {
case BusType::LeftJoyRail:
if ((data.left_data.data[3] >> 1 & 1) != 0) {
is_valid = true;
}
break;
case BusType::RightJoyRail: {
if (((data.right_data >> 9 & 1) == 0) && ((data.right_data >> 10 & 1) != 0)) {
is_valid = true;
}
break;
}
case BusType::InternalBus:
if ((data.right_data & 0xe00) == 0x800) {
is_valid = true;
}
break;
default:
break;
}
if (is_valid) {
abstracted_pad_id = data.abstracted_pad_id;
return ResultSuccess;
}
}
// STUB this function for now
abstracted_pad_id = static_cast<u32>(npad_id);
return ResultSuccess;
return ResultMcuInvalidHandle;
}
void HidBus::IsExternalDeviceConnected(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto bus_handle_{rp.PopRaw<BusHandle>()};

View File

@ -95,6 +95,10 @@ private:
};
void GetBusHandle(HLERequestContext& ctx);
bool GetBusHandleImpl(BusHandle& handle, Core::HID::NpadIdType npad_id, BusType bus_type) const;
Result MakeBusHandle(BusHandle& handle, Core::HID::NpadIdType npad_id, BusType bus_type) const;
Result GetAbstractedHidbusPadId(u32& abstracted_pad_id, Core::HID::NpadIdType npad_id,
BusType bus_type) const;
void IsExternalDeviceConnected(HLERequestContext& ctx);
void Initialize(HLERequestContext& ctx);
void Finalize(HLERequestContext& ctx);

View File

@ -74,7 +74,7 @@ Common::Input::DriverResult JoyconDriver::InitializeDevice() {
passive_enabled = false;
irs_enabled = false;
input_only_device = false;
gyro_sensitivity = Joycon::GyroSensitivity::DPS2000;
gyro_sensitivity = Joycon::GyroSensitivity::DPS250;
gyro_performance = Joycon::GyroPerformance::HZ833;
accelerometer_sensitivity = Joycon::AccelerometerSensitivity::G8;
accelerometer_performance = Joycon::AccelerometerPerformance::HZ100;
@ -173,6 +173,12 @@ void JoyconDriver::InputThread(std::stop_token stop_token) {
void JoyconDriver::OnNewData(std::span<u8> buffer) {
const auto report_mode = static_cast<ReportMode>(buffer[0]);
std::string str = "";
for (u8 dat : buffer) {
str += fmt::format("{:02x} ", dat);
}
LOG_CRITICAL(Input, "{}", str);
// Packages can be a little bit inconsistent. Average the delta time to provide a smoother
// motion experience
@ -203,7 +209,7 @@ void JoyconDriver::OnNewData(std::span<u8> buffer) {
if (ring_connected && report_mode == ReportMode::STANDARD_FULL_60HZ) {
InputReportActive data{};
memcpy(&data, buffer.data(), sizeof(InputReportActive));
calibration_protocol->GetRingCalibration(ring_calibration, data.ring_input);
//calibration_protocol->GetRingCalibration(ring_calibration, data.ring_input);
}
const RingStatus ring_status{
@ -264,8 +270,8 @@ Common::Input::DriverResult JoyconDriver::SetPollingMode() {
if (motion_enabled && supported_features.motion) {
generic_protocol->EnableImu(true);
generic_protocol->SetImuConfig(gyro_sensitivity, gyro_performance,
accelerometer_sensitivity, accelerometer_performance);
//generic_protocol->SetImuConfig(gyro_sensitivity, gyro_performance,
// accelerometer_sensitivity, accelerometer_performance);
} else {
generic_protocol->EnableImu(false);
}