diff options
Diffstat (limited to 'src/core/hle/service')
29 files changed, 1156 insertions, 532 deletions
diff --git a/src/core/hle/service/am/applets/applet_controller.cpp b/src/core/hle/service/am/applets/applet_controller.cpp index 655f2e936..0a5603d18 100644 --- a/src/core/hle/service/am/applets/applet_controller.cpp +++ b/src/core/hle/service/am/applets/applet_controller.cpp @@ -178,7 +178,7 @@ ResultCode Controller::GetStatus() const { } void Controller::ExecuteInteractive() { - UNREACHABLE_MSG("Attempted to call interactive execution on non-interactive applet."); + ASSERT_MSG(false, "Attempted to call interactive execution on non-interactive applet."); } void Controller::Execute() { diff --git a/src/core/hle/service/am/applets/applet_error.cpp b/src/core/hle/service/am/applets/applet_error.cpp index 911b2c229..0b87c60b9 100644 --- a/src/core/hle/service/am/applets/applet_error.cpp +++ b/src/core/hle/service/am/applets/applet_error.cpp @@ -156,7 +156,7 @@ ResultCode Error::GetStatus() const { } void Error::ExecuteInteractive() { - UNREACHABLE_MSG("Unexpected interactive applet data!"); + ASSERT_MSG(false, "Unexpected interactive applet data!"); } void Error::Execute() { diff --git a/src/core/hle/service/am/applets/applet_general_backend.cpp b/src/core/hle/service/am/applets/applet_general_backend.cpp index 3fe1a390a..41c002ef2 100644 --- a/src/core/hle/service/am/applets/applet_general_backend.cpp +++ b/src/core/hle/service/am/applets/applet_general_backend.cpp @@ -76,7 +76,7 @@ ResultCode Auth::GetStatus() const { } void Auth::ExecuteInteractive() { - UNREACHABLE_MSG("Unexpected interactive applet data."); + ASSERT_MSG(false, "Unexpected interactive applet data."); } void Auth::Execute() { @@ -175,7 +175,7 @@ ResultCode PhotoViewer::GetStatus() const { } void PhotoViewer::ExecuteInteractive() { - UNREACHABLE_MSG("Unexpected interactive applet data."); + ASSERT_MSG(false, "Unexpected interactive applet data."); } void PhotoViewer::Execute() { diff --git a/src/core/hle/service/am/applets/applet_mii_edit.cpp b/src/core/hle/service/am/applets/applet_mii_edit.cpp index 3acde1630..8d847c3f6 100644 --- a/src/core/hle/service/am/applets/applet_mii_edit.cpp +++ b/src/core/hle/service/am/applets/applet_mii_edit.cpp @@ -67,7 +67,7 @@ ResultCode MiiEdit::GetStatus() const { } void MiiEdit::ExecuteInteractive() { - UNREACHABLE_MSG("Attempted to call interactive execution on non-interactive applet."); + ASSERT_MSG(false, "Attempted to call interactive execution on non-interactive applet."); } void MiiEdit::Execute() { diff --git a/src/core/hle/service/am/applets/applet_profile_select.cpp b/src/core/hle/service/am/applets/applet_profile_select.cpp index fd16f2e49..02049fd9f 100644 --- a/src/core/hle/service/am/applets/applet_profile_select.cpp +++ b/src/core/hle/service/am/applets/applet_profile_select.cpp @@ -44,7 +44,7 @@ ResultCode ProfileSelect::GetStatus() const { } void ProfileSelect::ExecuteInteractive() { - UNREACHABLE_MSG("Attempted to call interactive execution on non-interactive applet."); + ASSERT_MSG(false, "Attempted to call interactive execution on non-interactive applet."); } void ProfileSelect::Execute() { diff --git a/src/core/hle/service/am/applets/applet_software_keyboard.cpp b/src/core/hle/service/am/applets/applet_software_keyboard.cpp index 7c21365e4..4116fbaa7 100644 --- a/src/core/hle/service/am/applets/applet_software_keyboard.cpp +++ b/src/core/hle/service/am/applets/applet_software_keyboard.cpp @@ -71,7 +71,7 @@ void SoftwareKeyboard::Initialize() { InitializeBackground(applet_mode); break; default: - UNREACHABLE_MSG("Invalid LibraryAppletMode={}", applet_mode); + ASSERT_MSG(false, "Invalid LibraryAppletMode={}", applet_mode); break; } } diff --git a/src/core/hle/service/am/applets/applet_web_browser.cpp b/src/core/hle/service/am/applets/applet_web_browser.cpp index 2aa4a00ad..7b3f77a51 100644 --- a/src/core/hle/service/am/applets/applet_web_browser.cpp +++ b/src/core/hle/service/am/applets/applet_web_browser.cpp @@ -279,7 +279,7 @@ void WebBrowser::Initialize() { InitializeLobby(); break; default: - UNREACHABLE_MSG("Invalid ShimKind={}", web_arg_header.shim_kind); + ASSERT_MSG(false, "Invalid ShimKind={}", web_arg_header.shim_kind); break; } } @@ -320,7 +320,7 @@ void WebBrowser::Execute() { ExecuteLobby(); break; default: - UNREACHABLE_MSG("Invalid ShimKind={}", web_arg_header.shim_kind); + ASSERT_MSG(false, "Invalid ShimKind={}", web_arg_header.shim_kind); WebBrowserExit(WebExitReason::EndButtonPressed); break; } diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index ddfcba0f1..fae6e5aff 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp @@ -899,7 +899,7 @@ void FSP_SRV::OpenSaveDataFileSystem(Kernel::HLERequestContext& ctx) { case FileSys::SaveDataSpaceId::TemporaryStorage: case FileSys::SaveDataSpaceId::ProperSystem: case FileSys::SaveDataSpaceId::SafeMode: - UNREACHABLE(); + ASSERT(false); } auto filesystem = std::make_shared<IFileSystem>(system, std::move(dir.Unwrap()), diff --git a/src/core/hle/service/hid/controllers/gesture.cpp b/src/core/hle/service/hid/controllers/gesture.cpp index 3eae1ae35..32e0708ba 100644 --- a/src/core/hle/service/hid/controllers/gesture.cpp +++ b/src/core/hle/service/hid/controllers/gesture.cpp @@ -61,6 +61,7 @@ void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) { } last_update_timestamp = shared_memory->gesture_lifo.timestamp; + UpdateGestureSharedMemory(gesture, time_difference); } void Controller_Gesture::ReadTouchInput() { @@ -94,8 +95,7 @@ bool Controller_Gesture::ShouldUpdateGesture(const GestureProperties& gesture, return false; } -void Controller_Gesture::UpdateGestureSharedMemory(u8* data, std::size_t size, - GestureProperties& gesture, +void Controller_Gesture::UpdateGestureSharedMemory(GestureProperties& gesture, f32 time_difference) { GestureType type = GestureType::Idle; GestureAttribute attributes{}; diff --git a/src/core/hle/service/hid/controllers/gesture.h b/src/core/hle/service/hid/controllers/gesture.h index c62a341bf..0d6099ea0 100644 --- a/src/core/hle/service/hid/controllers/gesture.h +++ b/src/core/hle/service/hid/controllers/gesture.h @@ -107,8 +107,7 @@ private: bool ShouldUpdateGesture(const GestureProperties& gesture, f32 time_difference); // Updates the shared memory to the next state - void UpdateGestureSharedMemory(u8* data, std::size_t size, GestureProperties& gesture, - f32 time_difference); + void UpdateGestureSharedMemory(GestureProperties& gesture, f32 time_difference); // Initializes new gesture void NewGesture(GestureProperties& gesture, GestureType& type, GestureAttribute& attributes); diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 17f71beaf..ac5c38cc6 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -3,7 +3,9 @@ #include <algorithm> #include <array> +#include <chrono> #include <cstring> + #include "common/assert.h" #include "common/bit_field.h" #include "common/common_types.h" @@ -54,11 +56,22 @@ bool Controller_NPad::IsDeviceHandleValid(const Core::HID::VibrationDeviceHandle return npad_id && npad_type && device_index; } -bool Controller_NPad::IsDeviceHandleValid(const Core::HID::SixAxisSensorHandle& device_handle) { +ResultCode Controller_NPad::VerifyValidSixAxisSensorHandle( + const Core::HID::SixAxisSensorHandle& device_handle) { const auto npad_id = IsNpadIdValid(static_cast<Core::HID::NpadIdType>(device_handle.npad_id)); - const bool npad_type = device_handle.npad_type < Core::HID::NpadStyleIndex::MaxNpadType; + if (!npad_id) { + return InvalidNpadId; + } const bool device_index = device_handle.device_index < Core::HID::DeviceIndex::MaxDeviceIndex; - return npad_id && npad_type && device_index; + if (!device_index) { + return NpadDeviceIndexOutOfRange; + } + // This doesn't get validated on nnsdk + const bool npad_type = device_handle.npad_type < Core::HID::NpadStyleIndex::MaxNpadType; + if (!npad_type) { + return NpadInvalidHandle; + } + return ResultSuccess; } Controller_NPad::Controller_NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_, @@ -147,7 +160,7 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) { shared_memory->system_properties.raw = 0; switch (controller_type) { case Core::HID::NpadStyleIndex::None: - UNREACHABLE(); + ASSERT(false); break; case Core::HID::NpadStyleIndex::ProController: shared_memory->style_tag.fullkey.Assign(1); @@ -156,6 +169,7 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) { shared_memory->system_properties.use_plus.Assign(1); shared_memory->system_properties.use_minus.Assign(1); shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::SwitchProController; + shared_memory->sixaxis_fullkey_properties.is_newly_assigned.Assign(1); break; case Core::HID::NpadStyleIndex::Handheld: shared_memory->style_tag.handheld.Assign(1); @@ -168,16 +182,19 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) { shared_memory->assignment_mode = NpadJoyAssignmentMode::Dual; shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::HandheldJoyConLeftJoyConRight; + shared_memory->sixaxis_handheld_properties.is_newly_assigned.Assign(1); break; case Core::HID::NpadStyleIndex::JoyconDual: shared_memory->style_tag.joycon_dual.Assign(1); if (controller.is_dual_left_connected) { shared_memory->device_type.joycon_left.Assign(1); shared_memory->system_properties.use_minus.Assign(1); + shared_memory->sixaxis_dual_left_properties.is_newly_assigned.Assign(1); } if (controller.is_dual_right_connected) { shared_memory->device_type.joycon_right.Assign(1); shared_memory->system_properties.use_plus.Assign(1); + shared_memory->sixaxis_dual_right_properties.is_newly_assigned.Assign(1); } shared_memory->system_properties.use_directional_buttons.Assign(1); shared_memory->system_properties.is_vertical.Assign(1); @@ -196,6 +213,7 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) { shared_memory->system_properties.is_horizontal.Assign(1); shared_memory->system_properties.use_minus.Assign(1); shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyLeftHorizontal; + shared_memory->sixaxis_left_properties.is_newly_assigned.Assign(1); break; case Core::HID::NpadStyleIndex::JoyconRight: shared_memory->style_tag.joycon_right.Assign(1); @@ -203,6 +221,7 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) { shared_memory->system_properties.is_horizontal.Assign(1); shared_memory->system_properties.use_plus.Assign(1); shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyRightHorizontal; + shared_memory->sixaxis_right_properties.is_newly_assigned.Assign(1); break; case Core::HID::NpadStyleIndex::GameCube: shared_memory->style_tag.gamecube.Assign(1); @@ -213,6 +232,7 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) { case Core::HID::NpadStyleIndex::Pokeball: shared_memory->style_tag.palma.Assign(1); shared_memory->device_type.palma.Assign(1); + shared_memory->sixaxis_fullkey_properties.is_newly_assigned.Assign(1); break; case Core::HID::NpadStyleIndex::NES: shared_memory->style_tag.lark.Assign(1); @@ -402,7 +422,7 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { libnx_state.connection_status.is_connected.Assign(1); switch (controller_type) { case Core::HID::NpadStyleIndex::None: - UNREACHABLE(); + ASSERT(false); break; case Core::HID::NpadStyleIndex::ProController: case Core::HID::NpadStyleIndex::NES: @@ -529,6 +549,14 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing auto& sixaxis_left_lifo_state = controller.sixaxis_left_lifo_state; auto& sixaxis_right_lifo_state = controller.sixaxis_right_lifo_state; + // Clear previous state + sixaxis_fullkey_state = {}; + sixaxis_handheld_state = {}; + sixaxis_dual_left_state = {}; + sixaxis_dual_right_state = {}; + sixaxis_left_lifo_state = {}; + sixaxis_right_lifo_state = {}; + if (controller.sixaxis_sensor_enabled && Settings::values.motion_enabled.GetValue()) { controller.sixaxis_at_rest = true; for (std::size_t e = 0; e < motion_state.size(); ++e) { @@ -537,69 +565,56 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing } } + const auto set_motion_state = [&](SixAxisSensorState& state, + const Core::HID::ControllerMotion& hid_state) { + using namespace std::literals::chrono_literals; + static constexpr SixAxisSensorState default_motion_state = { + .delta_time = std::chrono::nanoseconds(5ms).count(), + .accel = {0, 0, -1.0f}, + .orientation = + { + Common::Vec3f{1.0f, 0, 0}, + Common::Vec3f{0, 1.0f, 0}, + Common::Vec3f{0, 0, 1.0f}, + }, + .attribute = {1}, + }; + if (!controller.sixaxis_sensor_enabled) { + state = default_motion_state; + return; + } + if (!Settings::values.motion_enabled.GetValue()) { + state = default_motion_state; + return; + } + state.attribute.is_connected.Assign(1); + state.delta_time = std::chrono::nanoseconds(5ms).count(); + state.accel = hid_state.accel; + state.gyro = hid_state.gyro; + state.rotation = hid_state.rotation; + state.orientation = hid_state.orientation; + }; + switch (controller_type) { case Core::HID::NpadStyleIndex::None: - UNREACHABLE(); + ASSERT(false); break; case Core::HID::NpadStyleIndex::ProController: - sixaxis_fullkey_state.attribute.raw = 0; - if (controller.sixaxis_sensor_enabled) { - sixaxis_fullkey_state.attribute.is_connected.Assign(1); - sixaxis_fullkey_state.accel = motion_state[0].accel; - sixaxis_fullkey_state.gyro = motion_state[0].gyro; - sixaxis_fullkey_state.rotation = motion_state[0].rotation; - sixaxis_fullkey_state.orientation = motion_state[0].orientation; - } + case Core::HID::NpadStyleIndex::Pokeball: + set_motion_state(sixaxis_fullkey_state, motion_state[0]); break; case Core::HID::NpadStyleIndex::Handheld: - sixaxis_handheld_state.attribute.raw = 0; - if (controller.sixaxis_sensor_enabled) { - sixaxis_handheld_state.attribute.is_connected.Assign(1); - sixaxis_handheld_state.accel = motion_state[0].accel; - sixaxis_handheld_state.gyro = motion_state[0].gyro; - sixaxis_handheld_state.rotation = motion_state[0].rotation; - sixaxis_handheld_state.orientation = motion_state[0].orientation; - } + set_motion_state(sixaxis_handheld_state, motion_state[0]); break; case Core::HID::NpadStyleIndex::JoyconDual: - sixaxis_dual_left_state.attribute.raw = 0; - sixaxis_dual_right_state.attribute.raw = 0; - if (controller.sixaxis_sensor_enabled) { - // Set motion for the left joycon - sixaxis_dual_left_state.attribute.is_connected.Assign(1); - sixaxis_dual_left_state.accel = motion_state[0].accel; - sixaxis_dual_left_state.gyro = motion_state[0].gyro; - sixaxis_dual_left_state.rotation = motion_state[0].rotation; - sixaxis_dual_left_state.orientation = motion_state[0].orientation; - } - if (controller.sixaxis_sensor_enabled) { - // Set motion for the right joycon - sixaxis_dual_right_state.attribute.is_connected.Assign(1); - sixaxis_dual_right_state.accel = motion_state[1].accel; - sixaxis_dual_right_state.gyro = motion_state[1].gyro; - sixaxis_dual_right_state.rotation = motion_state[1].rotation; - sixaxis_dual_right_state.orientation = motion_state[1].orientation; - } + set_motion_state(sixaxis_dual_left_state, motion_state[0]); + set_motion_state(sixaxis_dual_right_state, motion_state[1]); break; case Core::HID::NpadStyleIndex::JoyconLeft: - sixaxis_left_lifo_state.attribute.raw = 0; - if (controller.sixaxis_sensor_enabled) { - sixaxis_left_lifo_state.attribute.is_connected.Assign(1); - sixaxis_left_lifo_state.accel = motion_state[0].accel; - sixaxis_left_lifo_state.gyro = motion_state[0].gyro; - sixaxis_left_lifo_state.rotation = motion_state[0].rotation; - sixaxis_left_lifo_state.orientation = motion_state[0].orientation; - } + set_motion_state(sixaxis_left_lifo_state, motion_state[0]); break; case Core::HID::NpadStyleIndex::JoyconRight: - sixaxis_right_lifo_state.attribute.raw = 0; - if (controller.sixaxis_sensor_enabled) { - sixaxis_right_lifo_state.attribute.is_connected.Assign(1); - sixaxis_right_lifo_state.accel = motion_state[1].accel; - sixaxis_right_lifo_state.gyro = motion_state[1].gyro; - sixaxis_right_lifo_state.rotation = motion_state[1].rotation; - sixaxis_right_lifo_state.orientation = motion_state[1].orientation; - } + set_motion_state(sixaxis_right_lifo_state, motion_state[1]); break; default: break; @@ -676,6 +691,12 @@ std::size_t Controller_NPad::GetSupportedNpadIdTypesSize() const { } void Controller_NPad::SetHoldType(NpadJoyHoldType joy_hold_type) { + if (joy_hold_type != NpadJoyHoldType::Horizontal && + joy_hold_type != NpadJoyHoldType::Vertical) { + LOG_ERROR(Service_HID, "Npad joy hold type needs to be valid, joy_hold_type={}", + joy_hold_type); + return; + } hold_type = joy_hold_type; } @@ -699,11 +720,12 @@ Controller_NPad::NpadCommunicationMode Controller_NPad::GetNpadCommunicationMode return communication_mode; } -void Controller_NPad::SetNpadMode(Core::HID::NpadIdType npad_id, NpadJoyDeviceType npad_device_type, - NpadJoyAssignmentMode assignment_mode) { +ResultCode Controller_NPad::SetNpadMode(Core::HID::NpadIdType npad_id, + NpadJoyDeviceType npad_device_type, + NpadJoyAssignmentMode assignment_mode) { if (!IsNpadIdValid(npad_id)) { LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); - return; + return InvalidNpadId; } auto& controller = GetControllerFromNpadIdType(npad_id); @@ -712,7 +734,7 @@ void Controller_NPad::SetNpadMode(Core::HID::NpadIdType npad_id, NpadJoyDeviceTy } if (!controller.device->IsConnected()) { - return; + return ResultSuccess; } if (assignment_mode == NpadJoyAssignmentMode::Dual) { @@ -721,34 +743,34 @@ void Controller_NPad::SetNpadMode(Core::HID::NpadIdType npad_id, NpadJoyDeviceTy controller.is_dual_left_connected = true; controller.is_dual_right_connected = false; UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id, true); - return; + return ResultSuccess; } if (controller.device->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconRight) { DisconnectNpad(npad_id); controller.is_dual_left_connected = false; controller.is_dual_right_connected = true; UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id, true); - return; + return ResultSuccess; } - return; + return ResultSuccess; } // This is for NpadJoyAssignmentMode::Single // Only JoyconDual get affected by this function if (controller.device->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::JoyconDual) { - return; + return ResultSuccess; } if (controller.is_dual_left_connected && !controller.is_dual_right_connected) { DisconnectNpad(npad_id); UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconLeft, npad_id, true); - return; + return ResultSuccess; } if (!controller.is_dual_left_connected && controller.is_dual_right_connected) { DisconnectNpad(npad_id); UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconRight, npad_id, true); - return; + return ResultSuccess; } // We have two controllers connected to the same npad_id we need to split them @@ -766,6 +788,7 @@ void Controller_NPad::SetNpadMode(Core::HID::NpadIdType npad_id, NpadJoyDeviceTy controller_2.is_dual_right_connected = false; UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id_2, true); } + return ResultSuccess; } bool Controller_NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, @@ -833,7 +856,7 @@ void Controller_NPad::VibrateController( } if (vibration_device_handle.device_index == Core::HID::DeviceIndex::None) { - UNREACHABLE_MSG("DeviceIndex should never be None!"); + ASSERT_MSG(false, "DeviceIndex should never be None!"); return; } @@ -961,10 +984,10 @@ void Controller_NPad::UpdateControllerAt(Core::HID::NpadStyleIndex type, InitNewlyAddedController(npad_id); } -void Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) { +ResultCode Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) { if (!IsNpadIdValid(npad_id)) { LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); - return; + return InvalidNpadId; } LOG_DEBUG(Service_HID, "Npad disconnected {}", npad_id); @@ -981,6 +1004,12 @@ void Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) { shared_memory->device_type.raw = 0; shared_memory->system_properties.raw = 0; shared_memory->button_properties.raw = 0; + shared_memory->sixaxis_fullkey_properties.raw = 0; + shared_memory->sixaxis_handheld_properties.raw = 0; + shared_memory->sixaxis_dual_left_properties.raw = 0; + shared_memory->sixaxis_dual_right_properties.raw = 0; + shared_memory->sixaxis_left_properties.raw = 0; + shared_memory->sixaxis_right_properties.raw = 0; shared_memory->battery_level_dual = 0; shared_memory->battery_level_left = 0; shared_memory->battery_level_right = 0; @@ -1001,346 +1030,268 @@ void Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) { controller.device->Disconnect(); SignalStyleSetChangedEvent(npad_id); WriteEmptyEntry(shared_memory); + return ResultSuccess; } - -ResultCode Controller_NPad::SetGyroscopeZeroDriftMode(Core::HID::SixAxisSensorHandle sixaxis_handle, - GyroscopeZeroDriftMode drift_mode) { - if (!IsDeviceHandleValid(sixaxis_handle)) { - LOG_ERROR(Service_HID, "Invalid handle"); - return NpadInvalidHandle; +ResultCode Controller_NPad::SetGyroscopeZeroDriftMode( + const Core::HID::SixAxisSensorHandle& sixaxis_handle, GyroscopeZeroDriftMode drift_mode) { + const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); + if (is_valid.IsError()) { + LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); + return is_valid; } - auto& controller = GetControllerFromHandle(sixaxis_handle); - switch (sixaxis_handle.npad_type) { - case Core::HID::NpadStyleIndex::ProController: - controller.sixaxis_fullkey.gyroscope_zero_drift_mode = drift_mode; - break; - case Core::HID::NpadStyleIndex::Handheld: - controller.sixaxis_handheld.gyroscope_zero_drift_mode = drift_mode; - break; - case Core::HID::NpadStyleIndex::JoyconDual: - case Core::HID::NpadStyleIndex::GameCube: - case Core::HID::NpadStyleIndex::Pokeball: - if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) { - controller.sixaxis_dual_left.gyroscope_zero_drift_mode = drift_mode; - break; - } - controller.sixaxis_dual_right.gyroscope_zero_drift_mode = drift_mode; - break; - case Core::HID::NpadStyleIndex::JoyconLeft: - controller.sixaxis_left.gyroscope_zero_drift_mode = drift_mode; - break; - case Core::HID::NpadStyleIndex::JoyconRight: - controller.sixaxis_right.gyroscope_zero_drift_mode = drift_mode; - break; - default: - LOG_ERROR(Service_HID, "Invalid Npad type {}", sixaxis_handle.npad_type); - return NpadInvalidHandle; - } + auto& sixaxis = GetSixaxisState(sixaxis_handle); + sixaxis.gyroscope_zero_drift_mode = drift_mode; return ResultSuccess; } -ResultCode Controller_NPad::GetGyroscopeZeroDriftMode(Core::HID::SixAxisSensorHandle sixaxis_handle, - GyroscopeZeroDriftMode& drift_mode) const { - if (!IsDeviceHandleValid(sixaxis_handle)) { - LOG_ERROR(Service_HID, "Invalid handle"); - return NpadInvalidHandle; +ResultCode Controller_NPad::GetGyroscopeZeroDriftMode( + const Core::HID::SixAxisSensorHandle& sixaxis_handle, + GyroscopeZeroDriftMode& drift_mode) const { + const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); + if (is_valid.IsError()) { + LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); + return is_valid; } - auto& controller = GetControllerFromHandle(sixaxis_handle); - switch (sixaxis_handle.npad_type) { - case Core::HID::NpadStyleIndex::ProController: - drift_mode = controller.sixaxis_fullkey.gyroscope_zero_drift_mode; - break; - case Core::HID::NpadStyleIndex::Handheld: - drift_mode = controller.sixaxis_handheld.gyroscope_zero_drift_mode; - break; - case Core::HID::NpadStyleIndex::JoyconDual: - case Core::HID::NpadStyleIndex::GameCube: - case Core::HID::NpadStyleIndex::Pokeball: - if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) { - drift_mode = controller.sixaxis_dual_left.gyroscope_zero_drift_mode; - break; - } - drift_mode = controller.sixaxis_dual_right.gyroscope_zero_drift_mode; - break; - case Core::HID::NpadStyleIndex::JoyconLeft: - drift_mode = controller.sixaxis_left.gyroscope_zero_drift_mode; - break; - case Core::HID::NpadStyleIndex::JoyconRight: - drift_mode = controller.sixaxis_right.gyroscope_zero_drift_mode; - break; - default: - LOG_ERROR(Service_HID, "Invalid Npad type {}", sixaxis_handle.npad_type); - return NpadInvalidHandle; - } + const auto& sixaxis = GetSixaxisState(sixaxis_handle); + drift_mode = sixaxis.gyroscope_zero_drift_mode; return ResultSuccess; } -ResultCode Controller_NPad::IsSixAxisSensorAtRest(Core::HID::SixAxisSensorHandle sixaxis_handle, - bool& is_at_rest) const { - if (!IsDeviceHandleValid(sixaxis_handle)) { - LOG_ERROR(Service_HID, "Invalid handle"); - return NpadInvalidHandle; +ResultCode Controller_NPad::IsSixAxisSensorAtRest( + const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_at_rest) const { + const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); + if (is_valid.IsError()) { + LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); + return is_valid; } + const auto& controller = GetControllerFromHandle(sixaxis_handle); is_at_rest = controller.sixaxis_at_rest; return ResultSuccess; } ResultCode Controller_NPad::IsFirmwareUpdateAvailableForSixAxisSensor( - Core::HID::SixAxisSensorHandle sixaxis_handle, bool& is_firmware_available) const { - if (!IsDeviceHandleValid(sixaxis_handle)) { - LOG_ERROR(Service_HID, "Invalid handle"); - return NpadInvalidHandle; + const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_firmware_available) const { + const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); + if (is_valid.IsError()) { + LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); + return is_valid; } - // We don't support joycon firmware updates - is_firmware_available = false; + const auto& sixaxis_properties = GetSixaxisProperties(sixaxis_handle); + is_firmware_available = sixaxis_properties.is_firmware_update_available != 0; return ResultSuccess; } -ResultCode Controller_NPad::SetSixAxisEnabled(Core::HID::SixAxisSensorHandle sixaxis_handle, +ResultCode Controller_NPad::EnableSixAxisSensorUnalteredPassthrough( + const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_enabled) { + const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); + if (is_valid.IsError()) { + LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); + return is_valid; + } + + auto& sixaxis = GetSixaxisState(sixaxis_handle); + sixaxis.unaltered_passtrough = is_enabled; + return ResultSuccess; +} + +ResultCode Controller_NPad::IsSixAxisSensorUnalteredPassthroughEnabled( + const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_enabled) const { + const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); + if (is_valid.IsError()) { + LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); + return is_valid; + } + + const auto& sixaxis = GetSixaxisState(sixaxis_handle); + is_enabled = sixaxis.unaltered_passtrough; + return ResultSuccess; +} + +ResultCode Controller_NPad::LoadSixAxisSensorCalibrationParameter( + const Core::HID::SixAxisSensorHandle& sixaxis_handle, + Core::HID::SixAxisSensorCalibrationParameter& calibration) const { + const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); + if (is_valid.IsError()) { + LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); + return is_valid; + } + + // TODO: Request this data to the controller. On error return 0xd8ca + const auto& sixaxis = GetSixaxisState(sixaxis_handle); + calibration = sixaxis.calibration; + return ResultSuccess; +} + +ResultCode Controller_NPad::GetSixAxisSensorIcInformation( + const Core::HID::SixAxisSensorHandle& sixaxis_handle, + Core::HID::SixAxisSensorIcInformation& ic_information) const { + const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); + if (is_valid.IsError()) { + LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); + return is_valid; + } + + // TODO: Request this data to the controller. On error return 0xd8ca + const auto& sixaxis = GetSixaxisState(sixaxis_handle); + ic_information = sixaxis.ic_information; + return ResultSuccess; +} + +ResultCode Controller_NPad::ResetIsSixAxisSensorDeviceNewlyAssigned( + const Core::HID::SixAxisSensorHandle& sixaxis_handle) { + const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); + if (is_valid.IsError()) { + LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); + return is_valid; + } + + auto& sixaxis_properties = GetSixaxisProperties(sixaxis_handle); + sixaxis_properties.is_newly_assigned.Assign(0); + + return ResultSuccess; +} + +ResultCode Controller_NPad::SetSixAxisEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool sixaxis_status) { - if (!IsDeviceHandleValid(sixaxis_handle)) { - LOG_ERROR(Service_HID, "Invalid handle"); - return NpadInvalidHandle; + const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); + if (is_valid.IsError()) { + LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); + return is_valid; } + auto& controller = GetControllerFromHandle(sixaxis_handle); controller.sixaxis_sensor_enabled = sixaxis_status; return ResultSuccess; } ResultCode Controller_NPad::IsSixAxisSensorFusionEnabled( - Core::HID::SixAxisSensorHandle sixaxis_handle, bool& is_fusion_enabled) const { - if (!IsDeviceHandleValid(sixaxis_handle)) { - LOG_ERROR(Service_HID, "Invalid handle"); - return NpadInvalidHandle; + const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_fusion_enabled) const { + const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); + if (is_valid.IsError()) { + LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); + return is_valid; } - auto& controller = GetControllerFromHandle(sixaxis_handle); - switch (sixaxis_handle.npad_type) { - case Core::HID::NpadStyleIndex::ProController: - is_fusion_enabled = controller.sixaxis_fullkey.is_fusion_enabled; - break; - case Core::HID::NpadStyleIndex::Handheld: - is_fusion_enabled = controller.sixaxis_handheld.is_fusion_enabled; - break; - case Core::HID::NpadStyleIndex::JoyconDual: - case Core::HID::NpadStyleIndex::GameCube: - case Core::HID::NpadStyleIndex::Pokeball: - if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) { - is_fusion_enabled = controller.sixaxis_dual_left.is_fusion_enabled; - break; - } - is_fusion_enabled = controller.sixaxis_dual_right.is_fusion_enabled; - break; - case Core::HID::NpadStyleIndex::JoyconLeft: - is_fusion_enabled = controller.sixaxis_left.is_fusion_enabled; - break; - case Core::HID::NpadStyleIndex::JoyconRight: - is_fusion_enabled = controller.sixaxis_right.is_fusion_enabled; - break; - default: - LOG_ERROR(Service_HID, "Invalid Npad type {}", sixaxis_handle.npad_type); - return NpadInvalidHandle; - } + const auto& sixaxis = GetSixaxisState(sixaxis_handle); + is_fusion_enabled = sixaxis.is_fusion_enabled; return ResultSuccess; } -ResultCode Controller_NPad::SetSixAxisFusionEnabled(Core::HID::SixAxisSensorHandle sixaxis_handle, - bool is_fusion_enabled) { - if (!IsDeviceHandleValid(sixaxis_handle)) { - LOG_ERROR(Service_HID, "Invalid handle"); - return NpadInvalidHandle; +ResultCode Controller_NPad::SetSixAxisFusionEnabled( + const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_fusion_enabled) { + const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); + if (is_valid.IsError()) { + LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); + return is_valid; } - auto& controller = GetControllerFromHandle(sixaxis_handle); - switch (sixaxis_handle.npad_type) { - case Core::HID::NpadStyleIndex::ProController: - controller.sixaxis_fullkey.is_fusion_enabled = is_fusion_enabled; - break; - case Core::HID::NpadStyleIndex::Handheld: - controller.sixaxis_handheld.is_fusion_enabled = is_fusion_enabled; - break; - case Core::HID::NpadStyleIndex::JoyconDual: - case Core::HID::NpadStyleIndex::GameCube: - case Core::HID::NpadStyleIndex::Pokeball: - if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) { - controller.sixaxis_dual_left.is_fusion_enabled = is_fusion_enabled; - break; - } - controller.sixaxis_dual_right.is_fusion_enabled = is_fusion_enabled; - break; - case Core::HID::NpadStyleIndex::JoyconLeft: - controller.sixaxis_left.is_fusion_enabled = is_fusion_enabled; - break; - case Core::HID::NpadStyleIndex::JoyconRight: - controller.sixaxis_right.is_fusion_enabled = is_fusion_enabled; - break; - default: - LOG_ERROR(Service_HID, "Invalid Npad type {}", sixaxis_handle.npad_type); - return NpadInvalidHandle; - } + auto& sixaxis = GetSixaxisState(sixaxis_handle); + sixaxis.is_fusion_enabled = is_fusion_enabled; return ResultSuccess; } ResultCode Controller_NPad::SetSixAxisFusionParameters( - Core::HID::SixAxisSensorHandle sixaxis_handle, + const Core::HID::SixAxisSensorHandle& sixaxis_handle, Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters) { - if (!IsDeviceHandleValid(sixaxis_handle)) { - LOG_ERROR(Service_HID, "Invalid handle"); - return NpadInvalidHandle; + const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); + if (is_valid.IsError()) { + LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); + return is_valid; } + const auto param1 = sixaxis_fusion_parameters.parameter1; if (param1 < 0.0f || param1 > 1.0f) { return InvalidSixAxisFusionRange; } - auto& controller = GetControllerFromHandle(sixaxis_handle); - switch (sixaxis_handle.npad_type) { - case Core::HID::NpadStyleIndex::ProController: - controller.sixaxis_fullkey.fusion = sixaxis_fusion_parameters; - break; - case Core::HID::NpadStyleIndex::Handheld: - controller.sixaxis_handheld.fusion = sixaxis_fusion_parameters; - break; - case Core::HID::NpadStyleIndex::JoyconDual: - case Core::HID::NpadStyleIndex::GameCube: - case Core::HID::NpadStyleIndex::Pokeball: - if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) { - controller.sixaxis_dual_left.fusion = sixaxis_fusion_parameters; - break; - } - controller.sixaxis_dual_right.fusion = sixaxis_fusion_parameters; - break; - case Core::HID::NpadStyleIndex::JoyconLeft: - controller.sixaxis_left.fusion = sixaxis_fusion_parameters; - break; - case Core::HID::NpadStyleIndex::JoyconRight: - controller.sixaxis_right.fusion = sixaxis_fusion_parameters; - break; - default: - LOG_ERROR(Service_HID, "Invalid Npad type {}", sixaxis_handle.npad_type); - return NpadInvalidHandle; - } + auto& sixaxis = GetSixaxisState(sixaxis_handle); + sixaxis.fusion = sixaxis_fusion_parameters; return ResultSuccess; } ResultCode Controller_NPad::GetSixAxisFusionParameters( - Core::HID::SixAxisSensorHandle sixaxis_handle, + const Core::HID::SixAxisSensorHandle& sixaxis_handle, Core::HID::SixAxisSensorFusionParameters& parameters) const { - if (!IsDeviceHandleValid(sixaxis_handle)) { - LOG_ERROR(Service_HID, "Invalid handle"); - return NpadInvalidHandle; + const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); + if (is_valid.IsError()) { + LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); + return is_valid; } - const auto& controller = GetControllerFromHandle(sixaxis_handle); - switch (sixaxis_handle.npad_type) { - case Core::HID::NpadStyleIndex::ProController: - parameters = controller.sixaxis_fullkey.fusion; - break; - case Core::HID::NpadStyleIndex::Handheld: - parameters = controller.sixaxis_handheld.fusion; - break; - case Core::HID::NpadStyleIndex::JoyconDual: - case Core::HID::NpadStyleIndex::GameCube: - case Core::HID::NpadStyleIndex::Pokeball: - if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) { - parameters = controller.sixaxis_dual_left.fusion; - break; - } - parameters = controller.sixaxis_dual_right.fusion; - break; - case Core::HID::NpadStyleIndex::JoyconLeft: - parameters = controller.sixaxis_left.fusion; - break; - case Core::HID::NpadStyleIndex::JoyconRight: - parameters = controller.sixaxis_right.fusion; - break; - default: - LOG_ERROR(Service_HID, "Invalid Npad type {}", sixaxis_handle.npad_type); - return NpadInvalidHandle; - } + const auto& sixaxis = GetSixaxisState(sixaxis_handle); + parameters = sixaxis.fusion; return ResultSuccess; } -void Controller_NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1, - Core::HID::NpadIdType npad_id_2) { +ResultCode Controller_NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1, + Core::HID::NpadIdType npad_id_2) { if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) { LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1, npad_id_2); - return; + return InvalidNpadId; } auto& controller_1 = GetControllerFromNpadIdType(npad_id_1); auto& controller_2 = GetControllerFromNpadIdType(npad_id_2); - const auto controller_style_1 = controller_1.device->GetNpadStyleIndex(); - const auto controller_style_2 = controller_2.device->GetNpadStyleIndex(); - bool merge_controllers = false; + auto controller_style_1 = controller_1.device->GetNpadStyleIndex(); + auto controller_style_2 = controller_2.device->GetNpadStyleIndex(); - // If the controllers at both npad indices form a pair of left and right joycons, merge them. - // Otherwise, do nothing. + // Simplify this code by converting dualjoycon with only a side connected to single joycons + if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual) { + if (controller_1.is_dual_left_connected && !controller_1.is_dual_right_connected) { + controller_style_1 = Core::HID::NpadStyleIndex::JoyconLeft; + } + if (!controller_1.is_dual_left_connected && controller_1.is_dual_right_connected) { + controller_style_1 = Core::HID::NpadStyleIndex::JoyconRight; + } + } + if (controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual) { + if (controller_2.is_dual_left_connected && !controller_2.is_dual_right_connected) { + controller_style_2 = Core::HID::NpadStyleIndex::JoyconLeft; + } + if (!controller_2.is_dual_left_connected && controller_2.is_dual_right_connected) { + controller_style_2 = Core::HID::NpadStyleIndex::JoyconRight; + } + } + + // Invalid merge errors + if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual || + controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual) { + return NpadIsDualJoycon; + } if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconLeft && + controller_style_2 == Core::HID::NpadStyleIndex::JoyconLeft) { + return NpadIsSameType; + } + if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconRight && controller_style_2 == Core::HID::NpadStyleIndex::JoyconRight) { - merge_controllers = true; - } - if (controller_style_2 == Core::HID::NpadStyleIndex::JoyconLeft && - controller_style_1 == Core::HID::NpadStyleIndex::JoyconRight) { - merge_controllers = true; - } - if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual && - controller_style_2 == Core::HID::NpadStyleIndex::JoyconRight && - controller_1.is_dual_left_connected && !controller_1.is_dual_right_connected) { - merge_controllers = true; - } - if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual && - controller_style_2 == Core::HID::NpadStyleIndex::JoyconLeft && - !controller_1.is_dual_left_connected && controller_1.is_dual_right_connected) { - merge_controllers = true; - } - if (controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual && - controller_style_1 == Core::HID::NpadStyleIndex::JoyconRight && - controller_2.is_dual_left_connected && !controller_2.is_dual_right_connected) { - merge_controllers = true; - } - if (controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual && - controller_style_1 == Core::HID::NpadStyleIndex::JoyconLeft && - !controller_2.is_dual_left_connected && controller_2.is_dual_right_connected) { - merge_controllers = true; - } - if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual && - controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual && - controller_1.is_dual_left_connected && !controller_1.is_dual_right_connected && - !controller_2.is_dual_left_connected && controller_2.is_dual_right_connected) { - merge_controllers = true; - } - if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual && - controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual && - !controller_1.is_dual_left_connected && controller_1.is_dual_right_connected && - controller_2.is_dual_left_connected && !controller_2.is_dual_right_connected) { - merge_controllers = true; - } - - if (merge_controllers) { - // Disconnect the joycon at the second id and connect the dual joycon at the first index. - DisconnectNpad(npad_id_2); - controller_1.is_dual_left_connected = true; - controller_1.is_dual_right_connected = true; - AddNewControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id_1); - return; + return NpadIsSameType; + } + + // These exceptions are handled as if they where dual joycon + if (controller_style_1 != Core::HID::NpadStyleIndex::JoyconLeft && + controller_style_1 != Core::HID::NpadStyleIndex::JoyconRight) { + return NpadIsDualJoycon; + } + if (controller_style_2 != Core::HID::NpadStyleIndex::JoyconLeft && + controller_style_2 != Core::HID::NpadStyleIndex::JoyconRight) { + return NpadIsDualJoycon; } - LOG_WARNING(Service_HID, - "Controllers can't be merged npad_id_1:{}, npad_id_2:{}, type_1:{}, type_2:{}, " - "dual_1(left/right):{}/{}, dual_2(left/right):{}/{}", - npad_id_1, npad_id_2, controller_1.device->GetNpadStyleIndex(), - controller_2.device->GetNpadStyleIndex(), controller_1.is_dual_left_connected, - controller_1.is_dual_right_connected, controller_2.is_dual_left_connected, - controller_2.is_dual_right_connected); + + // Disconnect the joycon at the second id and connect the dual joycon at the first index. + DisconnectNpad(npad_id_2); + controller_1.is_dual_left_connected = true; + controller_1.is_dual_right_connected = true; + AddNewControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id_1); + return ResultSuccess; } void Controller_NPad::StartLRAssignmentMode() { @@ -1353,17 +1304,17 @@ void Controller_NPad::StopLRAssignmentMode() { is_in_lr_assignment_mode = false; } -bool Controller_NPad::SwapNpadAssignment(Core::HID::NpadIdType npad_id_1, - Core::HID::NpadIdType npad_id_2) { +ResultCode Controller_NPad::SwapNpadAssignment(Core::HID::NpadIdType npad_id_1, + Core::HID::NpadIdType npad_id_2) { if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) { LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1, npad_id_2); - return false; + return InvalidNpadId; } if (npad_id_1 == Core::HID::NpadIdType::Handheld || npad_id_2 == Core::HID::NpadIdType::Handheld || npad_id_1 == Core::HID::NpadIdType::Other || npad_id_2 == Core::HID::NpadIdType::Other) { - return true; + return ResultSuccess; } const auto& controller_1 = GetControllerFromNpadIdType(npad_id_1).device; const auto& controller_2 = GetControllerFromNpadIdType(npad_id_2).device; @@ -1373,46 +1324,49 @@ bool Controller_NPad::SwapNpadAssignment(Core::HID::NpadIdType npad_id_1, const auto is_connected_2 = controller_2->IsConnected(); if (!IsControllerSupported(type_index_1) && is_connected_1) { - return false; + return NpadNotConnected; } if (!IsControllerSupported(type_index_2) && is_connected_2) { - return false; + return NpadNotConnected; } UpdateControllerAt(type_index_2, npad_id_1, is_connected_2); UpdateControllerAt(type_index_1, npad_id_2, is_connected_1); - return true; + return ResultSuccess; } -Core::HID::LedPattern Controller_NPad::GetLedPattern(Core::HID::NpadIdType npad_id) { +ResultCode Controller_NPad::GetLedPattern(Core::HID::NpadIdType npad_id, + Core::HID::LedPattern& pattern) const { if (!IsNpadIdValid(npad_id)) { LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); - return Core::HID::LedPattern{0, 0, 0, 0}; + return InvalidNpadId; } const auto& controller = GetControllerFromNpadIdType(npad_id).device; - return controller->GetLedPattern(); + pattern = controller->GetLedPattern(); + return ResultSuccess; } -bool Controller_NPad::IsUnintendedHomeButtonInputProtectionEnabled( - Core::HID::NpadIdType npad_id) const { +ResultCode Controller_NPad::IsUnintendedHomeButtonInputProtectionEnabled( + Core::HID::NpadIdType npad_id, bool& is_valid) const { if (!IsNpadIdValid(npad_id)) { LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); - // Return the default value - return false; + return InvalidNpadId; } const auto& controller = GetControllerFromNpadIdType(npad_id); - return controller.unintended_home_button_input_protection; + is_valid = controller.unintended_home_button_input_protection; + return ResultSuccess; } -void Controller_NPad::SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled, - Core::HID::NpadIdType npad_id) { +ResultCode Controller_NPad::SetUnintendedHomeButtonInputProtectionEnabled( + bool is_protection_enabled, Core::HID::NpadIdType npad_id) { if (!IsNpadIdValid(npad_id)) { LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); - return; + return InvalidNpadId; } auto& controller = GetControllerFromNpadIdType(npad_id); controller.unintended_home_button_input_protection = is_protection_enabled; + return ResultSuccess; } void Controller_NPad::SetAnalogStickUseCenterClamp(bool use_center_clamp) { @@ -1550,4 +1504,96 @@ const Controller_NPad::NpadControllerData& Controller_NPad::GetControllerFromNpa return controller_data[npad_index]; } +Core::HID::SixAxisSensorProperties& Controller_NPad::GetSixaxisProperties( + const Core::HID::SixAxisSensorHandle& sixaxis_handle) { + auto& controller = GetControllerFromHandle(sixaxis_handle); + switch (sixaxis_handle.npad_type) { + case Core::HID::NpadStyleIndex::ProController: + case Core::HID::NpadStyleIndex::Pokeball: + return controller.shared_memory->sixaxis_fullkey_properties; + case Core::HID::NpadStyleIndex::Handheld: + return controller.shared_memory->sixaxis_handheld_properties; + case Core::HID::NpadStyleIndex::JoyconDual: + if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) { + return controller.shared_memory->sixaxis_dual_left_properties; + } + return controller.shared_memory->sixaxis_dual_right_properties; + case Core::HID::NpadStyleIndex::JoyconLeft: + return controller.shared_memory->sixaxis_left_properties; + case Core::HID::NpadStyleIndex::JoyconRight: + return controller.shared_memory->sixaxis_right_properties; + default: + return controller.shared_memory->sixaxis_fullkey_properties; + } +} + +const Core::HID::SixAxisSensorProperties& Controller_NPad::GetSixaxisProperties( + const Core::HID::SixAxisSensorHandle& sixaxis_handle) const { + const auto& controller = GetControllerFromHandle(sixaxis_handle); + switch (sixaxis_handle.npad_type) { + case Core::HID::NpadStyleIndex::ProController: + case Core::HID::NpadStyleIndex::Pokeball: + return controller.shared_memory->sixaxis_fullkey_properties; + case Core::HID::NpadStyleIndex::Handheld: + return controller.shared_memory->sixaxis_handheld_properties; + case Core::HID::NpadStyleIndex::JoyconDual: + if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) { + return controller.shared_memory->sixaxis_dual_left_properties; + } + return controller.shared_memory->sixaxis_dual_right_properties; + case Core::HID::NpadStyleIndex::JoyconLeft: + return controller.shared_memory->sixaxis_left_properties; + case Core::HID::NpadStyleIndex::JoyconRight: + return controller.shared_memory->sixaxis_right_properties; + default: + return controller.shared_memory->sixaxis_fullkey_properties; + } +} + +Controller_NPad::SixaxisParameters& Controller_NPad::GetSixaxisState( + const Core::HID::SixAxisSensorHandle& sixaxis_handle) { + auto& controller = GetControllerFromHandle(sixaxis_handle); + switch (sixaxis_handle.npad_type) { + case Core::HID::NpadStyleIndex::ProController: + case Core::HID::NpadStyleIndex::Pokeball: + return controller.sixaxis_fullkey; + case Core::HID::NpadStyleIndex::Handheld: + return controller.sixaxis_handheld; + case Core::HID::NpadStyleIndex::JoyconDual: + if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) { + return controller.sixaxis_dual_left; + } + return controller.sixaxis_dual_right; + case Core::HID::NpadStyleIndex::JoyconLeft: + return controller.sixaxis_left; + case Core::HID::NpadStyleIndex::JoyconRight: + return controller.sixaxis_right; + default: + return controller.sixaxis_unknown; + } +} + +const Controller_NPad::SixaxisParameters& Controller_NPad::GetSixaxisState( + const Core::HID::SixAxisSensorHandle& sixaxis_handle) const { + const auto& controller = GetControllerFromHandle(sixaxis_handle); + switch (sixaxis_handle.npad_type) { + case Core::HID::NpadStyleIndex::ProController: + case Core::HID::NpadStyleIndex::Pokeball: + return controller.sixaxis_fullkey; + case Core::HID::NpadStyleIndex::Handheld: + return controller.sixaxis_handheld; + case Core::HID::NpadStyleIndex::JoyconDual: + if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) { + return controller.sixaxis_dual_left; + } + return controller.sixaxis_dual_right; + case Core::HID::NpadStyleIndex::JoyconLeft: + return controller.sixaxis_left; + case Core::HID::NpadStyleIndex::JoyconRight: + return controller.sixaxis_right; + default: + return controller.sixaxis_unknown; + } +} + } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 0a96825a5..0b662b7f8 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -107,8 +107,8 @@ public: void SetNpadCommunicationMode(NpadCommunicationMode communication_mode_); NpadCommunicationMode GetNpadCommunicationMode() const; - void SetNpadMode(Core::HID::NpadIdType npad_id, NpadJoyDeviceType npad_device_type, - NpadJoyAssignmentMode assignment_mode); + ResultCode SetNpadMode(Core::HID::NpadIdType npad_id, NpadJoyDeviceType npad_device_type, + NpadJoyAssignmentMode assignment_mode); bool VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, std::size_t device_index, const Core::HID::VibrationValue& vibration_value); @@ -141,50 +141,65 @@ public: void UpdateControllerAt(Core::HID::NpadStyleIndex controller, Core::HID::NpadIdType npad_id, bool connected); - void DisconnectNpad(Core::HID::NpadIdType npad_id); + ResultCode DisconnectNpad(Core::HID::NpadIdType npad_id); - ResultCode SetGyroscopeZeroDriftMode(Core::HID::SixAxisSensorHandle sixaxis_handle, + ResultCode SetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle, GyroscopeZeroDriftMode drift_mode); - ResultCode GetGyroscopeZeroDriftMode(Core::HID::SixAxisSensorHandle sixaxis_handle, + ResultCode GetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle, GyroscopeZeroDriftMode& drift_mode) const; - ResultCode IsSixAxisSensorAtRest(Core::HID::SixAxisSensorHandle sixaxis_handle, + ResultCode IsSixAxisSensorAtRest(const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_at_rest) const; ResultCode IsFirmwareUpdateAvailableForSixAxisSensor( - Core::HID::SixAxisSensorHandle sixaxis_handle, bool& is_firmware_available) const; - ResultCode SetSixAxisEnabled(Core::HID::SixAxisSensorHandle sixaxis_handle, + const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_firmware_available) const; + ResultCode EnableSixAxisSensorUnalteredPassthrough( + const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_enabled); + ResultCode IsSixAxisSensorUnalteredPassthroughEnabled( + const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_enabled) const; + ResultCode LoadSixAxisSensorCalibrationParameter( + const Core::HID::SixAxisSensorHandle& sixaxis_handle, + Core::HID::SixAxisSensorCalibrationParameter& calibration) const; + ResultCode GetSixAxisSensorIcInformation( + const Core::HID::SixAxisSensorHandle& sixaxis_handle, + Core::HID::SixAxisSensorIcInformation& ic_information) const; + ResultCode ResetIsSixAxisSensorDeviceNewlyAssigned( + const Core::HID::SixAxisSensorHandle& sixaxis_handle); + ResultCode SetSixAxisEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool sixaxis_status); - ResultCode IsSixAxisSensorFusionEnabled(Core::HID::SixAxisSensorHandle sixaxis_handle, + ResultCode IsSixAxisSensorFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_fusion_enabled) const; - ResultCode SetSixAxisFusionEnabled(Core::HID::SixAxisSensorHandle sixaxis_handle, + ResultCode SetSixAxisFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_fusion_enabled); ResultCode SetSixAxisFusionParameters( - Core::HID::SixAxisSensorHandle sixaxis_handle, + const Core::HID::SixAxisSensorHandle& sixaxis_handle, Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters); ResultCode GetSixAxisFusionParameters( - Core::HID::SixAxisSensorHandle sixaxis_handle, + const Core::HID::SixAxisSensorHandle& sixaxis_handle, Core::HID::SixAxisSensorFusionParameters& parameters) const; - Core::HID::LedPattern GetLedPattern(Core::HID::NpadIdType npad_id); - bool IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id) const; - void SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled, - Core::HID::NpadIdType npad_id); + ResultCode GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const; + ResultCode IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id, + bool& is_enabled) const; + ResultCode SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled, + Core::HID::NpadIdType npad_id); void SetAnalogStickUseCenterClamp(bool use_center_clamp); void ClearAllConnectedControllers(); void DisconnectAllConnectedControllers(); void ConnectAllDisconnectedControllers(); void ClearAllControllers(); - void MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1, Core::HID::NpadIdType npad_id_2); + ResultCode MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1, + Core::HID::NpadIdType npad_id_2); void StartLRAssignmentMode(); void StopLRAssignmentMode(); - bool SwapNpadAssignment(Core::HID::NpadIdType npad_id_1, Core::HID::NpadIdType npad_id_2); + ResultCode SwapNpadAssignment(Core::HID::NpadIdType npad_id_1, Core::HID::NpadIdType npad_id_2); // Logical OR for all buttons presses on all controllers // Specifically for cheat engine and other features. Core::HID::NpadButton GetAndResetPressState(); static bool IsNpadIdValid(Core::HID::NpadIdType npad_id); - static bool IsDeviceHandleValid(const Core::HID::SixAxisSensorHandle& device_handle); static bool IsDeviceHandleValid(const Core::HID::VibrationDeviceHandle& device_handle); + static ResultCode VerifyValidSixAxisSensorHandle( + const Core::HID::SixAxisSensorHandle& device_handle); private: static constexpr std::size_t NPAD_COUNT = 10; @@ -451,9 +466,13 @@ private: NpadLuciaType lucia_type{}; NpadLagonType lagon_type{}; NpadLagerType lager_type{}; - // FW 13.x Investigate there is some sort of bitflag related to joycons - INSERT_PADDING_BYTES(0x4); - INSERT_PADDING_BYTES(0xc08); // Unknown + Core::HID::SixAxisSensorProperties sixaxis_fullkey_properties; + Core::HID::SixAxisSensorProperties sixaxis_handheld_properties; + Core::HID::SixAxisSensorProperties sixaxis_dual_left_properties; + Core::HID::SixAxisSensorProperties sixaxis_dual_right_properties; + Core::HID::SixAxisSensorProperties sixaxis_left_properties; + Core::HID::SixAxisSensorProperties sixaxis_right_properties; + INSERT_PADDING_BYTES(0xc06); // Unknown }; static_assert(sizeof(NpadInternalState) == 0x5000, "NpadInternalState is an invalid size"); @@ -465,7 +484,10 @@ private: struct SixaxisParameters { bool is_fusion_enabled{true}; + bool unaltered_passtrough{false}; Core::HID::SixAxisSensorFusionParameters fusion{}; + Core::HID::SixAxisSensorCalibrationParameter calibration{}; + Core::HID::SixAxisSensorIcInformation ic_information{}; GyroscopeZeroDriftMode gyroscope_zero_drift_mode{GyroscopeZeroDriftMode::Standard}; }; @@ -491,6 +513,7 @@ private: SixaxisParameters sixaxis_dual_right{}; SixaxisParameters sixaxis_left{}; SixaxisParameters sixaxis_right{}; + SixaxisParameters sixaxis_unknown{}; // Current pad state NPadGenericState npad_pad_state{}; @@ -522,6 +545,14 @@ private: NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id); const NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id) const; + Core::HID::SixAxisSensorProperties& GetSixaxisProperties( + const Core::HID::SixAxisSensorHandle& device_handle); + const Core::HID::SixAxisSensorProperties& GetSixaxisProperties( + const Core::HID::SixAxisSensorHandle& device_handle) const; + SixaxisParameters& GetSixaxisState(const Core::HID::SixAxisSensorHandle& device_handle); + const SixaxisParameters& GetSixaxisState( + const Core::HID::SixAxisSensorHandle& device_handle) const; + std::atomic<u64> press_state{}; std::array<NpadControllerData, NPAD_COUNT> controller_data{}; diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/core/hle/service/hid/controllers/touchscreen.cpp index 108ce5a41..1da8d3eb0 100644 --- a/src/core/hle/service/hid/controllers/touchscreen.cpp +++ b/src/core/hle/service/hid/controllers/touchscreen.cpp @@ -44,7 +44,6 @@ void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timin for (std::size_t id = 0; id < MAX_FINGERS; id++) { const auto& current_touch = touch_status[id]; auto& finger = fingers[id]; - finger.position = current_touch.position; finger.id = current_touch.id; if (finger.attribute.start_touch) { @@ -61,13 +60,18 @@ void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timin if (!finger.pressed && current_touch.pressed) { finger.attribute.start_touch.Assign(1); finger.pressed = true; + finger.position = current_touch.position; continue; } if (finger.pressed && !current_touch.pressed) { finger.attribute.raw = 0; finger.attribute.end_touch.Assign(1); + continue; } + + // Only update position if touch is not on a special frame + finger.position = current_touch.position; } std::array<Core::HID::TouchFinger, MAX_FINGERS> active_fingers; diff --git a/src/core/hle/service/hid/errors.h b/src/core/hle/service/hid/errors.h index b31834074..6c8ad04af 100644 --- a/src/core/hle/service/hid/errors.h +++ b/src/core/hle/service/hid/errors.h @@ -8,7 +8,11 @@ namespace Service::HID { constexpr ResultCode NpadInvalidHandle{ErrorModule::HID, 100}; +constexpr ResultCode NpadDeviceIndexOutOfRange{ErrorModule::HID, 107}; constexpr ResultCode InvalidSixAxisFusionRange{ErrorModule::HID, 423}; +constexpr ResultCode NpadIsDualJoycon{ErrorModule::HID, 601}; +constexpr ResultCode NpadIsSameType{ErrorModule::HID, 602}; +constexpr ResultCode InvalidNpadId{ErrorModule::HID, 709}; constexpr ResultCode NpadNotConnected{ErrorModule::HID, 710}; } // namespace Service::HID diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index eba44eda8..dc5d0366d 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -37,8 +37,7 @@ namespace Service::HID { // Period time is obtained by measuring the number of samples in a second on HW using a homebrew constexpr auto pad_update_ns = std::chrono::nanoseconds{4 * 1000 * 1000}; // (4ms, 250Hz) constexpr auto mouse_keyboard_update_ns = std::chrono::nanoseconds{8 * 1000 * 1000}; // (8ms, 125Hz) -// TODO: Correct update rate for motion is 5ms. Check why some games don't behave at that speed -constexpr auto motion_update_ns = std::chrono::nanoseconds{10 * 1000 * 1000}; // (10ms, 100Hz) +constexpr auto motion_update_ns = std::chrono::nanoseconds{5 * 1000 * 1000}; // (5ms, 200Hz) IAppletResource::IAppletResource(Core::System& system_, KernelHelpers::ServiceContext& service_context_) @@ -258,12 +257,12 @@ Hid::Hid(Core::System& system_) {81, &Hid::ResetGyroscopeZeroDriftMode, "ResetGyroscopeZeroDriftMode"}, {82, &Hid::IsSixAxisSensorAtRest, "IsSixAxisSensorAtRest"}, {83, &Hid::IsFirmwareUpdateAvailableForSixAxisSensor, "IsFirmwareUpdateAvailableForSixAxisSensor"}, - {84, nullptr, "EnableSixAxisSensorUnalteredPassthrough"}, - {85, nullptr, "IsSixAxisSensorUnalteredPassthroughEnabled"}, + {84, &Hid::EnableSixAxisSensorUnalteredPassthrough, "EnableSixAxisSensorUnalteredPassthrough"}, + {85, &Hid::IsSixAxisSensorUnalteredPassthroughEnabled, "IsSixAxisSensorUnalteredPassthroughEnabled"}, {86, nullptr, "StoreSixAxisSensorCalibrationParameter"}, - {87, nullptr, "LoadSixAxisSensorCalibrationParameter"}, - {88, nullptr, "GetSixAxisSensorIcInformation"}, - {89, nullptr, "ResetIsSixAxisSensorDeviceNewlyAssigned"}, + {87, &Hid::LoadSixAxisSensorCalibrationParameter, "LoadSixAxisSensorCalibrationParameter"}, + {88, &Hid::GetSixAxisSensorIcInformation, "GetSixAxisSensorIcInformation"}, + {89, &Hid::ResetIsSixAxisSensorDeviceNewlyAssigned, "ResetIsSixAxisSensorDeviceNewlyAssigned"}, {91, &Hid::ActivateGesture, "ActivateGesture"}, {100, &Hid::SetSupportedNpadStyleSet, "SetSupportedNpadStyleSet"}, {101, &Hid::GetSupportedNpadStyleSet, "GetSupportedNpadStyleSet"}, @@ -695,11 +694,7 @@ void Hid::ResetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) { rb.Push(result1); return; } - if (result2.IsError()) { - rb.Push(result2); - return; - } - rb.Push(ResultSuccess); + rb.Push(result2); } void Hid::SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) { @@ -822,6 +817,144 @@ void Hid::IsFirmwareUpdateAvailableForSixAxisSensor(Kernel::HLERequestContext& c rb.Push(is_firmware_available); } +void Hid::EnableSixAxisSensorUnalteredPassthrough(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + struct Parameters { + bool enabled; + Core::HID::SixAxisSensorHandle sixaxis_handle; + u64 applet_resource_user_id; + }; + static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw<Parameters>()}; + + auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); + const auto result = controller.EnableSixAxisSensorUnalteredPassthrough( + parameters.sixaxis_handle, parameters.enabled); + + LOG_WARNING(Service_HID, + "(STUBBED) called, enabled={}, npad_type={}, npad_id={}, device_index={}, " + "applet_resource_user_id={}", + parameters.enabled, parameters.sixaxis_handle.npad_type, + parameters.sixaxis_handle.npad_id, parameters.sixaxis_handle.device_index, + parameters.applet_resource_user_id); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); +} + +void Hid::IsSixAxisSensorUnalteredPassthroughEnabled(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + struct Parameters { + Core::HID::SixAxisSensorHandle sixaxis_handle; + INSERT_PADDING_WORDS_NOINIT(1); + u64 applet_resource_user_id; + }; + static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw<Parameters>()}; + + bool is_unaltered_sisxaxis_enabled{}; + auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); + const auto result = controller.IsSixAxisSensorUnalteredPassthroughEnabled( + parameters.sixaxis_handle, is_unaltered_sisxaxis_enabled); + + LOG_WARNING( + Service_HID, + "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", + parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, + parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(result); + rb.Push(is_unaltered_sisxaxis_enabled); +} + +void Hid::LoadSixAxisSensorCalibrationParameter(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + struct Parameters { + Core::HID::SixAxisSensorHandle sixaxis_handle; + INSERT_PADDING_WORDS_NOINIT(1); + u64 applet_resource_user_id; + }; + static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw<Parameters>()}; + + Core::HID::SixAxisSensorCalibrationParameter calibration{}; + auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); + const auto result = + controller.LoadSixAxisSensorCalibrationParameter(parameters.sixaxis_handle, calibration); + + LOG_WARNING( + Service_HID, + "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", + parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, + parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); + + if (result.IsSuccess()) { + ctx.WriteBuffer(calibration); + } + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); +} + +void Hid::GetSixAxisSensorIcInformation(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + struct Parameters { + Core::HID::SixAxisSensorHandle sixaxis_handle; + INSERT_PADDING_WORDS_NOINIT(1); + u64 applet_resource_user_id; + }; + static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw<Parameters>()}; + + Core::HID::SixAxisSensorIcInformation ic_information{}; + auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); + const auto result = + controller.GetSixAxisSensorIcInformation(parameters.sixaxis_handle, ic_information); + + LOG_WARNING( + Service_HID, + "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", + parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, + parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); + + if (result.IsSuccess()) { + ctx.WriteBuffer(ic_information); + } + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); +} + +void Hid::ResetIsSixAxisSensorDeviceNewlyAssigned(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + struct Parameters { + Core::HID::SixAxisSensorHandle sixaxis_handle; + INSERT_PADDING_WORDS_NOINIT(1); + u64 applet_resource_user_id; + }; + static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw<Parameters>()}; + + auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); + const auto result = + controller.ResetIsSixAxisSensorDeviceNewlyAssigned(parameters.sixaxis_handle); + + LOG_WARNING( + Service_HID, + "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", + parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, + parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); +} + void Hid::ActivateGesture(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; struct Parameters { @@ -949,27 +1082,29 @@ void Hid::DisconnectNpad(Kernel::HLERequestContext& ctx) { const auto parameters{rp.PopRaw<Parameters>()}; - applet_resource->GetController<Controller_NPad>(HidController::NPad) - .DisconnectNpad(parameters.npad_id); + auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); + const auto result = controller.DisconnectNpad(parameters.npad_id); LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); + rb.Push(result); } void Hid::GetPlayerLedPattern(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto npad_id{rp.PopEnum<Core::HID::NpadIdType>()}; + Core::HID::LedPattern pattern{0, 0, 0, 0}; + auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); + const auto result = controller.GetLedPattern(npad_id, pattern); + LOG_DEBUG(Service_HID, "called, npad_id={}", npad_id); IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(ResultSuccess); - rb.Push(applet_resource->GetController<Controller_NPad>(HidController::NPad) - .GetLedPattern(npad_id) - .raw); + rb.Push(result); + rb.Push(pattern.raw); } void Hid::ActivateNpadWithRevision(Kernel::HLERequestContext& ctx) { @@ -1029,15 +1164,16 @@ void Hid::SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx const auto parameters{rp.PopRaw<Parameters>()}; - applet_resource->GetController<Controller_NPad>(HidController::NPad) - .SetNpadMode(parameters.npad_id, Controller_NPad::NpadJoyDeviceType::Left, - Controller_NPad::NpadJoyAssignmentMode::Single); + auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); + const auto result = + controller.SetNpadMode(parameters.npad_id, Controller_NPad::NpadJoyDeviceType::Left, + Controller_NPad::NpadJoyAssignmentMode::Single); LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); + rb.Push(result); } void Hid::SetNpadJoyAssignmentModeSingle(Kernel::HLERequestContext& ctx) { @@ -1052,16 +1188,16 @@ void Hid::SetNpadJoyAssignmentModeSingle(Kernel::HLERequestContext& ctx) { const auto parameters{rp.PopRaw<Parameters>()}; - applet_resource->GetController<Controller_NPad>(HidController::NPad) - .SetNpadMode(parameters.npad_id, parameters.npad_joy_device_type, - Controller_NPad::NpadJoyAssignmentMode::Single); + auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); + const auto result = controller.SetNpadMode(parameters.npad_id, parameters.npad_joy_device_type, + Controller_NPad::NpadJoyAssignmentMode::Single); LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}", parameters.npad_id, parameters.applet_resource_user_id, parameters.npad_joy_device_type); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); + rb.Push(result); } void Hid::SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) { @@ -1075,14 +1211,15 @@ void Hid::SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) { const auto parameters{rp.PopRaw<Parameters>()}; - applet_resource->GetController<Controller_NPad>(HidController::NPad) - .SetNpadMode(parameters.npad_id, {}, Controller_NPad::NpadJoyAssignmentMode::Dual); + auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); + const auto result = controller.SetNpadMode(parameters.npad_id, {}, + Controller_NPad::NpadJoyAssignmentMode::Dual); LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); + rb.Push(result); } void Hid::MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) { @@ -1091,14 +1228,14 @@ void Hid::MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) { const auto npad_id_2{rp.PopEnum<Core::HID::NpadIdType>()}; const auto applet_resource_user_id{rp.Pop<u64>()}; - applet_resource->GetController<Controller_NPad>(HidController::NPad) - .MergeSingleJoyAsDualJoy(npad_id_1, npad_id_2); + auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); + const auto result = controller.MergeSingleJoyAsDualJoy(npad_id_1, npad_id_2); LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}", npad_id_1, npad_id_2, applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); + rb.Push(result); } void Hid::StartLrAssignmentMode(Kernel::HLERequestContext& ctx) { @@ -1158,19 +1295,14 @@ void Hid::SwapNpadAssignment(Kernel::HLERequestContext& ctx) { const auto npad_id_2{rp.PopEnum<Core::HID::NpadIdType>()}; const auto applet_resource_user_id{rp.Pop<u64>()}; - const bool res = applet_resource->GetController<Controller_NPad>(HidController::NPad) - .SwapNpadAssignment(npad_id_1, npad_id_2); + auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); + const auto result = controller.SwapNpadAssignment(npad_id_1, npad_id_2); LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}", npad_id_1, npad_id_2, applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; - if (res) { - rb.Push(ResultSuccess); - } else { - LOG_ERROR(Service_HID, "Npads are not connected!"); - rb.Push(NpadNotConnected); - } + rb.Push(result); } void Hid::IsUnintendedHomeButtonInputProtectionEnabled(Kernel::HLERequestContext& ctx) { @@ -1184,13 +1316,17 @@ void Hid::IsUnintendedHomeButtonInputProtectionEnabled(Kernel::HLERequestContext const auto parameters{rp.PopRaw<Parameters>()}; + bool is_enabled = false; + auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); + const auto result = + controller.IsUnintendedHomeButtonInputProtectionEnabled(parameters.npad_id, is_enabled); + LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(applet_resource->GetController<Controller_NPad>(HidController::NPad) - .IsUnintendedHomeButtonInputProtectionEnabled(parameters.npad_id)); + rb.Push(result); + rb.Push(is_enabled); } void Hid::EnableUnintendedHomeButtonInputProtection(Kernel::HLERequestContext& ctx) { @@ -1205,9 +1341,9 @@ void Hid::EnableUnintendedHomeButtonInputProtection(Kernel::HLERequestContext& c const auto parameters{rp.PopRaw<Parameters>()}; - applet_resource->GetController<Controller_NPad>(HidController::NPad) - .SetUnintendedHomeButtonInputProtectionEnabled( - parameters.unintended_home_button_input_protection, parameters.npad_id); + auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); + const auto result = controller.SetUnintendedHomeButtonInputProtectionEnabled( + parameters.unintended_home_button_input_protection, parameters.npad_id); LOG_WARNING(Service_HID, "(STUBBED) called, unintended_home_button_input_protection={}, npad_id={}," @@ -1216,7 +1352,7 @@ void Hid::EnableUnintendedHomeButtonInputProtection(Kernel::HLERequestContext& c parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); + rb.Push(result); } void Hid::SetNpadAnalogStickUseCenterClamp(Kernel::HLERequestContext& ctx) { @@ -1305,7 +1441,7 @@ void Hid::GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) { break; case Core::HID::DeviceIndex::None: default: - UNREACHABLE_MSG("DeviceIndex should never be None!"); + ASSERT_MSG(false, "DeviceIndex should never be None!"); vibration_device_info.position = Core::HID::VibrationDevicePosition::None; break; } @@ -1378,6 +1514,8 @@ void Hid::PermitVibration(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto can_vibrate{rp.Pop<bool>()}; + // nnSDK saves this value as a float. Since it can only be 1.0f or 0.0f we simplify this value + // by converting it to a bool Settings::values.vibration_enabled.SetValue(can_vibrate); LOG_DEBUG(Service_HID, "called, can_vibrate={}", can_vibrate); @@ -1389,9 +1527,12 @@ void Hid::PermitVibration(Kernel::HLERequestContext& ctx) { void Hid::IsVibrationPermitted(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_HID, "called"); + // nnSDK checks if a float is greater than zero. We return the bool we stored earlier + const auto is_enabled = Settings::values.vibration_enabled.GetValue(); + IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); - rb.Push(Settings::values.vibration_enabled.GetValue()); + rb.Push(is_enabled); } void Hid::SendVibrationValues(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index 1be04c22b..ac4333022 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -113,6 +113,11 @@ private: void ResetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx); void IsSixAxisSensorAtRest(Kernel::HLERequestContext& ctx); void IsFirmwareUpdateAvailableForSixAxisSensor(Kernel::HLERequestContext& ctx); + void EnableSixAxisSensorUnalteredPassthrough(Kernel::HLERequestContext& ctx); + void IsSixAxisSensorUnalteredPassthroughEnabled(Kernel::HLERequestContext& ctx); + void LoadSixAxisSensorCalibrationParameter(Kernel::HLERequestContext& ctx); + void GetSixAxisSensorIcInformation(Kernel::HLERequestContext& ctx); + void ResetIsSixAxisSensorDeviceNewlyAssigned(Kernel::HLERequestContext& ctx); void ActivateGesture(Kernel::HLERequestContext& ctx); void SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx); void GetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx); diff --git a/src/core/hle/service/hid/irs.cpp b/src/core/hle/service/hid/irs.cpp index 9e32f3e60..d2a91d913 100644 --- a/src/core/hle/service/hid/irs.cpp +++ b/src/core/hle/service/hid/irs.cpp @@ -5,7 +5,9 @@ #include "core/core_timing.h" #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/k_shared_memory.h" +#include "core/hle/kernel/k_transfer_memory.h" #include "core/hle/kernel/kernel.h" +#include "core/hle/service/hid/errors.h" #include "core/hle/service/hid/irs.h" namespace Service::HID { @@ -38,21 +40,32 @@ IRS::IRS(Core::System& system_) : ServiceFramework{system_, "irs"} { } void IRS::ActivateIrsensor(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_IRS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + const auto applet_resource_user_id{rp.Pop<u64>()}; + + LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}", + applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void IRS::DeactivateIrsensor(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_IRS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + const auto applet_resource_user_id{rp.Pop<u64>()}; + + LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}", + applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void IRS::GetIrsensorSharedMemoryHandle(Kernel::HLERequestContext& ctx) { - LOG_DEBUG(Service_IRS, "called"); + IPC::RequestParser rp{ctx}; + const auto applet_resource_user_id{rp.Pop<u64>()}; + + LOG_DEBUG(Service_IRS, "called, applet_resource_user_id={}", applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(ResultSuccess); @@ -60,35 +73,109 @@ void IRS::GetIrsensorSharedMemoryHandle(Kernel::HLERequestContext& ctx) { } void IRS::StopImageProcessor(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_IRS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + struct Parameters { + IrCameraHandle camera_handle; + INSERT_PADDING_WORDS_NOINIT(1); + u64 applet_resource_user_id; + }; + static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw<Parameters>()}; + + LOG_WARNING(Service_IRS, + "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}", + parameters.camera_handle.npad_type, parameters.camera_handle.npad_id, + parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void IRS::RunMomentProcessor(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_IRS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + struct Parameters { + IrCameraHandle camera_handle; + INSERT_PADDING_WORDS_NOINIT(1); + u64 applet_resource_user_id; + PackedMomentProcessorConfig processor_config; + }; + static_assert(sizeof(Parameters) == 0x30, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw<Parameters>()}; + + LOG_WARNING(Service_IRS, + "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}", + parameters.camera_handle.npad_type, parameters.camera_handle.npad_id, + parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void IRS::RunClusteringProcessor(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_IRS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + struct Parameters { + IrCameraHandle camera_handle; + INSERT_PADDING_WORDS_NOINIT(1); + u64 applet_resource_user_id; + PackedClusteringProcessorConfig processor_config; + }; + static_assert(sizeof(Parameters) == 0x40, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw<Parameters>()}; + + LOG_WARNING(Service_IRS, + "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}", + parameters.camera_handle.npad_type, parameters.camera_handle.npad_id, + parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void IRS::RunImageTransferProcessor(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_IRS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + struct Parameters { + IrCameraHandle camera_handle; + INSERT_PADDING_WORDS_NOINIT(1); + u64 applet_resource_user_id; + PackedImageTransferProcessorConfig processor_config; + u32 transfer_memory_size; + }; + static_assert(sizeof(Parameters) == 0x30, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw<Parameters>()}; + const auto t_mem_handle{ctx.GetCopyHandle(0)}; + + auto t_mem = + system.CurrentProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(t_mem_handle); + + LOG_WARNING(Service_IRS, + "(STUBBED) called, npad_type={}, npad_id={}, transfer_memory_size={}, " + "applet_resource_user_id={}", + parameters.camera_handle.npad_type, parameters.camera_handle.npad_id, + parameters.transfer_memory_size, parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void IRS::GetImageTransferProcessorState(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_IRS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + struct Parameters { + IrCameraHandle camera_handle; + INSERT_PADDING_WORDS_NOINIT(1); + u64 applet_resource_user_id; + }; + static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw<Parameters>()}; + + LOG_WARNING(Service_IRS, + "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}", + parameters.camera_handle.npad_type, parameters.camera_handle.npad_id, + parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 5}; rb.Push(ResultSuccess); @@ -97,71 +184,195 @@ void IRS::GetImageTransferProcessorState(Kernel::HLERequestContext& ctx) { } void IRS::RunTeraPluginProcessor(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_IRS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + const auto camera_handle{rp.PopRaw<IrCameraHandle>()}; + const auto processor_config{rp.PopRaw<PackedTeraPluginProcessorConfig>()}; + const auto applet_resource_user_id{rp.Pop<u64>()}; + + LOG_WARNING(Service_IRS, + "(STUBBED) called, npad_type={}, npad_id={}, mode={}, mcu_version={}.{}, " + "applet_resource_user_id={}", + camera_handle.npad_type, camera_handle.npad_id, processor_config.mode, + processor_config.required_mcu_version.major, + processor_config.required_mcu_version.minor, applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void IRS::GetNpadIrCameraHandle(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_IRS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + const auto npad_id{rp.PopEnum<Core::HID::NpadIdType>()}; + + if (npad_id > Core::HID::NpadIdType::Player8 && npad_id != Core::HID::NpadIdType::Invalid && + npad_id != Core::HID::NpadIdType::Handheld) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(InvalidNpadId); + return; + } + + IrCameraHandle camera_handle{ + .npad_id = static_cast<u8>(NpadIdTypeToIndex(npad_id)), + .npad_type = Core::HID::NpadStyleIndex::None, + }; + + LOG_WARNING(Service_IRS, "(STUBBED) called, npad_id={}, camera_npad_id={}, camera_npad_type={}", + npad_id, camera_handle.npad_id, camera_handle.npad_type); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); - rb.PushRaw<u32>(device_handle); + rb.PushRaw(camera_handle); } void IRS::RunPointingProcessor(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_IRS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + const auto camera_handle{rp.PopRaw<IrCameraHandle>()}; + const auto processor_config{rp.PopRaw<PackedPointingProcessorConfig>()}; + const auto applet_resource_user_id{rp.Pop<u64>()}; + + LOG_WARNING( + Service_IRS, + "(STUBBED) called, npad_type={}, npad_id={}, mcu_version={}.{}, applet_resource_user_id={}", + camera_handle.npad_type, camera_handle.npad_id, processor_config.required_mcu_version.major, + processor_config.required_mcu_version.minor, applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void IRS::SuspendImageProcessor(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_IRS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + struct Parameters { + IrCameraHandle camera_handle; + INSERT_PADDING_WORDS_NOINIT(1); + u64 applet_resource_user_id; + }; + static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw<Parameters>()}; + + LOG_WARNING(Service_IRS, + "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}", + parameters.camera_handle.npad_type, parameters.camera_handle.npad_id, + parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void IRS::CheckFirmwareVersion(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_IRS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + const auto camera_handle{rp.PopRaw<IrCameraHandle>()}; + const auto mcu_version{rp.PopRaw<PackedMcuVersion>()}; + const auto applet_resource_user_id{rp.Pop<u64>()}; + + LOG_WARNING( + Service_IRS, + "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}, mcu_version={}.{}", + camera_handle.npad_type, camera_handle.npad_id, applet_resource_user_id, mcu_version.major, + mcu_version.minor); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void IRS::SetFunctionLevel(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_IRS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + struct Parameters { + IrCameraHandle camera_handle; + PackedFunctionLevel function_level; + u64 applet_resource_user_id; + }; + static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw<Parameters>()}; + + LOG_WARNING(Service_IRS, + "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}", + parameters.camera_handle.npad_type, parameters.camera_handle.npad_id, + parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void IRS::RunImageTransferExProcessor(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_IRS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + struct Parameters { + IrCameraHandle camera_handle; + INSERT_PADDING_WORDS_NOINIT(1); + u64 applet_resource_user_id; + PackedImageTransferProcessorExConfig processor_config; + u64 transfer_memory_size; + }; + static_assert(sizeof(Parameters) == 0x38, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw<Parameters>()}; + const auto t_mem_handle{ctx.GetCopyHandle(0)}; + + auto t_mem = + system.CurrentProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(t_mem_handle); + + LOG_WARNING(Service_IRS, + "(STUBBED) called, npad_type={}, npad_id={}, transfer_memory_size={}, " + "applet_resource_user_id={}", + parameters.camera_handle.npad_type, parameters.camera_handle.npad_id, + parameters.transfer_memory_size, parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void IRS::RunIrLedProcessor(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_IRS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + const auto camera_handle{rp.PopRaw<IrCameraHandle>()}; + const auto processor_config{rp.PopRaw<PackedIrLedProcessorConfig>()}; + const auto applet_resource_user_id{rp.Pop<u64>()}; + + LOG_WARNING(Service_IRS, + "(STUBBED) called, npad_type={}, npad_id={}, light_target={}, mcu_version={}.{} " + "applet_resource_user_id={}", + camera_handle.npad_type, camera_handle.npad_id, processor_config.light_target, + processor_config.required_mcu_version.major, + processor_config.required_mcu_version.minor, applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void IRS::StopImageProcessorAsync(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_IRS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + struct Parameters { + IrCameraHandle camera_handle; + INSERT_PADDING_WORDS_NOINIT(1); + u64 applet_resource_user_id; + }; + static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw<Parameters>()}; + + LOG_WARNING(Service_IRS, + "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}", + parameters.camera_handle.npad_type, parameters.camera_handle.npad_id, + parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void IRS::ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_IRS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + struct Parameters { + PackedFunctionLevel function_level; + INSERT_PADDING_WORDS_NOINIT(1); + u64 applet_resource_user_id; + }; + static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw<Parameters>()}; + + LOG_WARNING(Service_IRS, "(STUBBED) called, function_level={}, applet_resource_user_id={}", + parameters.function_level.function_level, parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); diff --git a/src/core/hle/service/hid/irs.h b/src/core/hle/service/hid/irs.h index efb29d3fd..361dc2213 100644 --- a/src/core/hle/service/hid/irs.h +++ b/src/core/hle/service/hid/irs.h @@ -3,6 +3,7 @@ #pragma once +#include "core/hid/hid_types.h" #include "core/hle/service/service.h" namespace Core { @@ -17,6 +18,235 @@ public: ~IRS() override; private: + // This is nn::irsensor::IrCameraStatus + enum IrCameraStatus : u32 { + Available, + Unsupported, + Unconnected, + }; + + // This is nn::irsensor::IrCameraInternalStatus + enum IrCameraInternalStatus : u32 { + Stopped, + FirmwareUpdateNeeded, + Unkown2, + Unkown3, + Unkown4, + FirmwareVersionRequested, + FirmwareVersionIsInvalid, + Ready, + Setting, + }; + + // This is nn::irsensor::detail::StatusManager::IrSensorMode + enum IrSensorMode : u64 { + None, + MomentProcessor, + ClusteringProcessor, + ImageTransferProcessor, + PointingProcessorMarker, + TeraPluginProcessor, + IrLedProcessor, + }; + + // This is nn::irsensor::ImageProcessorStatus + enum ImageProcessorStatus : u8 { + stopped, + running, + }; + + // This is nn::irsensor::ImageTransferProcessorFormat + enum ImageTransferProcessorFormat : u8 { + Size320x240, + Size160x120, + Size80x60, + Size40x30, + Size20x15, + }; + + // This is nn::irsensor::AdaptiveClusteringMode + enum AdaptiveClusteringMode : u8 { + StaticFov, + DynamicFov, + }; + + // This is nn::irsensor::AdaptiveClusteringTargetDistance + enum AdaptiveClusteringTargetDistance : u8 { + Near, + Middle, + Far, + }; + + // This is nn::irsensor::IrsHandAnalysisMode + enum IrsHandAnalysisMode : u8 { + Silhouette, + Image, + SilhoueteAndImage, + SilhuetteOnly, + }; + + // This is nn::irsensor::IrSensorFunctionLevel + enum IrSensorFunctionLevel : u8 { + unknown0, + unknown1, + unknown2, + unknown3, + unknown4, + }; + + // This is nn::irsensor::IrCameraHandle + struct IrCameraHandle { + u8 npad_id{}; + Core::HID::NpadStyleIndex npad_type{Core::HID::NpadStyleIndex::None}; + INSERT_PADDING_BYTES(2); + }; + static_assert(sizeof(IrCameraHandle) == 4, "IrCameraHandle is an invalid size"); + + struct IrsRect { + s16 x; + s16 y; + s16 width; + s16 height; + }; + + // This is nn::irsensor::PackedMcuVersion + struct PackedMcuVersion { + u16 major; + u16 minor; + }; + static_assert(sizeof(PackedMcuVersion) == 4, "PackedMcuVersion is an invalid size"); + + // This is nn::irsensor::MomentProcessorConfig + struct MomentProcessorConfig { + u64 exposire_time; + u8 light_target; + u8 gain; + u8 is_negative_used; + INSERT_PADDING_BYTES(7); + IrsRect window_of_interest; + u8 preprocess; + u8 preprocess_intensity_threshold; + INSERT_PADDING_BYTES(5); + }; + static_assert(sizeof(MomentProcessorConfig) == 0x28, + "MomentProcessorConfig is an invalid size"); + + // This is nn::irsensor::PackedMomentProcessorConfig + struct PackedMomentProcessorConfig { + u64 exposire_time; + u8 light_target; + u8 gain; + u8 is_negative_used; + INSERT_PADDING_BYTES(5); + IrsRect window_of_interest; + PackedMcuVersion required_mcu_version; + u8 preprocess; + u8 preprocess_intensity_threshold; + INSERT_PADDING_BYTES(2); + }; + static_assert(sizeof(PackedMomentProcessorConfig) == 0x20, + "PackedMomentProcessorConfig is an invalid size"); + + // This is nn::irsensor::ClusteringProcessorConfig + struct ClusteringProcessorConfig { + u64 exposire_time; + u32 light_target; + u32 gain; + u8 is_negative_used; + INSERT_PADDING_BYTES(7); + IrsRect window_of_interest; + u32 pixel_count_min; + u32 pixel_count_max; + u32 object_intensity_min; + u8 is_external_light_filter_enabled; + INSERT_PADDING_BYTES(3); + }; + static_assert(sizeof(ClusteringProcessorConfig) == 0x30, + "ClusteringProcessorConfig is an invalid size"); + + // This is nn::irsensor::PackedClusteringProcessorConfig + struct PackedClusteringProcessorConfig { + u64 exposire_time; + u8 light_target; + u8 gain; + u8 is_negative_used; + INSERT_PADDING_BYTES(5); + IrsRect window_of_interest; + PackedMcuVersion required_mcu_version; + u32 pixel_count_min; + u32 pixel_count_max; + u32 object_intensity_min; + u8 is_external_light_filter_enabled; + INSERT_PADDING_BYTES(2); + }; + static_assert(sizeof(PackedClusteringProcessorConfig) == 0x30, + "PackedClusteringProcessorConfig is an invalid size"); + + // This is nn::irsensor::PackedImageTransferProcessorConfig + struct PackedImageTransferProcessorConfig { + u64 exposire_time; + u8 light_target; + u8 gain; + u8 is_negative_used; + INSERT_PADDING_BYTES(5); + PackedMcuVersion required_mcu_version; + u8 format; + INSERT_PADDING_BYTES(3); + }; + static_assert(sizeof(PackedImageTransferProcessorConfig) == 0x18, + "PackedImageTransferProcessorConfig is an invalid size"); + + // This is nn::irsensor::PackedTeraPluginProcessorConfig + struct PackedTeraPluginProcessorConfig { + PackedMcuVersion required_mcu_version; + u8 mode; + INSERT_PADDING_BYTES(3); + }; + static_assert(sizeof(PackedTeraPluginProcessorConfig) == 0x8, + "PackedTeraPluginProcessorConfig is an invalid size"); + + // This is nn::irsensor::PackedPointingProcessorConfig + struct PackedPointingProcessorConfig { + IrsRect window_of_interest; + PackedMcuVersion required_mcu_version; + }; + static_assert(sizeof(PackedPointingProcessorConfig) == 0xC, + "PackedPointingProcessorConfig is an invalid size"); + + // This is nn::irsensor::PackedFunctionLevel + struct PackedFunctionLevel { + IrSensorFunctionLevel function_level; + INSERT_PADDING_BYTES(3); + }; + static_assert(sizeof(PackedFunctionLevel) == 0x4, "PackedFunctionLevel is an invalid size"); + + // This is nn::irsensor::PackedImageTransferProcessorExConfig + struct PackedImageTransferProcessorExConfig { + u64 exposire_time; + u8 light_target; + u8 gain; + u8 is_negative_used; + INSERT_PADDING_BYTES(5); + PackedMcuVersion required_mcu_version; + ImageTransferProcessorFormat origin_format; + ImageTransferProcessorFormat trimming_format; + u16 trimming_start_x; + u16 trimming_start_y; + u8 is_external_light_filter_enabled; + INSERT_PADDING_BYTES(3); + }; + static_assert(sizeof(PackedImageTransferProcessorExConfig) == 0x20, + "PackedImageTransferProcessorExConfig is an invalid size"); + + // This is nn::irsensor::PackedIrLedProcessorConfig + struct PackedIrLedProcessorConfig { + PackedMcuVersion required_mcu_version; + u8 light_target; + INSERT_PADDING_BYTES(3); + }; + static_assert(sizeof(PackedIrLedProcessorConfig) == 0x8, + "PackedIrLedProcessorConfig is an invalid size"); + void ActivateIrsensor(Kernel::HLERequestContext& ctx); void DeactivateIrsensor(Kernel::HLERequestContext& ctx); void GetIrsensorSharedMemoryHandle(Kernel::HLERequestContext& ctx); @@ -35,8 +265,6 @@ private: void RunIrLedProcessor(Kernel::HLERequestContext& ctx); void StopImageProcessorAsync(Kernel::HLERequestContext& ctx); void ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx); - - const u32 device_handle{0xABCD}; }; class IRS_SYS final : public ServiceFramework<IRS_SYS> { diff --git a/src/core/hle/service/jit/jit_context.cpp b/src/core/hle/service/jit/jit_context.cpp index 19bd85b6c..4ed3f02e2 100644 --- a/src/core/hle/service/jit/jit_context.cpp +++ b/src/core/hle/service/jit/jit_context.cpp @@ -11,10 +11,13 @@ #include "common/alignment.h" #include "common/common_funcs.h" #include "common/div_ceil.h" +#include "common/elf.h" #include "common/logging/log.h" #include "core/hle/service/jit/jit_context.h" #include "core/memory.h" +using namespace Common::ELF; + namespace Service::JIT { constexpr std::array<u8, 8> SVC0_ARM64 = { @@ -26,25 +29,6 @@ constexpr std::array HELPER_FUNCTIONS{ "_stop", "_resolve", "_panic", "memcpy", "memmove", "memset", }; -struct Elf64_Dyn { - u64 d_tag; - u64 d_un; -}; - -struct Elf64_Rela { - u64 r_offset; - u64 r_info; - s64 r_addend; -}; - -static constexpr u32 Elf64_RelaType(const Elf64_Rela* rela) { - return static_cast<u32>(rela->r_info); -} - -constexpr int DT_RELA = 7; /* Address of Rela relocs */ -constexpr int DT_RELASZ = 8; /* Total size of Rela relocs */ -constexpr int R_AARCH64_RELATIVE = 1027; /* Adjust by program base. */ - constexpr size_t STACK_ALIGN = 16; class JITContextImpl; @@ -206,17 +190,17 @@ public: if (!dyn.d_tag) { break; } - if (dyn.d_tag == DT_RELA) { - rela_dyn = dyn.d_un; + if (dyn.d_tag == ElfDtRela) { + rela_dyn = dyn.d_un.d_ptr; } - if (dyn.d_tag == DT_RELASZ) { - num_rela = dyn.d_un / sizeof(Elf64_Rela); + if (dyn.d_tag == ElfDtRelasz) { + num_rela = dyn.d_un.d_val / sizeof(Elf64_Rela); } } for (size_t i = 0; i < num_rela; i++) { const auto rela{callbacks->ReadMemory<Elf64_Rela>(rela_dyn + i * sizeof(Elf64_Rela))}; - if (Elf64_RelaType(&rela) != R_AARCH64_RELATIVE) { + if (Elf64RelType(rela.r_info) != ElfAArch64Relative) { continue; } const VAddr contents{callbacks->MemoryRead64(rela.r_offset)}; diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp index fa72fcba9..72e4902cb 100644 --- a/src/core/hle/service/ldr/ldr.cpp +++ b/src/core/hle/service/ldr/ldr.cpp @@ -347,7 +347,7 @@ public: } if (!succeeded) { - UNREACHABLE_MSG("Out of address space!"); + ASSERT_MSG(false, "Out of address space!"); return Kernel::ResultOutOfMemory; } diff --git a/src/core/hle/service/mii/mii_manager.cpp b/src/core/hle/service/mii/mii_manager.cpp index 4964539f9..08300a1a6 100644 --- a/src/core/hle/service/mii/mii_manager.cpp +++ b/src/core/hle/service/mii/mii_manager.cpp @@ -290,7 +290,7 @@ MiiStoreData BuildRandomStoreData(Age age, Gender gender, Race race, const Commo u8 glasses_type{}; while (glasses_type_start < glasses_type_info.values[glasses_type]) { if (++glasses_type >= glasses_type_info.values_count) { - UNREACHABLE(); + ASSERT(false); break; } } diff --git a/src/core/hle/service/nvdrv/syncpoint_manager.cpp b/src/core/hle/service/nvdrv/syncpoint_manager.cpp index f77f0df27..a6fa943e8 100644 --- a/src/core/hle/service/nvdrv/syncpoint_manager.cpp +++ b/src/core/hle/service/nvdrv/syncpoint_manager.cpp @@ -23,7 +23,7 @@ u32 SyncpointManager::AllocateSyncpoint() { return syncpoint_id; } } - UNREACHABLE_MSG("No more available syncpoints!"); + ASSERT_MSG(false, "No more available syncpoints!"); return {}; } diff --git a/src/core/hle/service/nvflinger/buffer_queue_consumer.cpp b/src/core/hle/service/nvflinger/buffer_queue_consumer.cpp index d7db77aff..4b3d5efd6 100644 --- a/src/core/hle/service/nvflinger/buffer_queue_consumer.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue_consumer.cpp @@ -89,14 +89,6 @@ Status BufferQueueConsumer::AcquireBuffer(BufferItem* out_buffer, LOG_DEBUG(Service_NVFlinger, "acquiring slot={}", slot); - // If the front buffer is still being tracked, update its slot state - if (core->StillTracking(*front)) { - slots[slot].acquire_called = true; - slots[slot].needs_cleanup_on_release = false; - slots[slot].buffer_state = BufferState::Acquired; - slots[slot].fence = Fence::NoFence(); - } - // If the buffer has previously been acquired by the consumer, set graphic_buffer to nullptr to // avoid unnecessarily remapping this buffer on the consumer side. if (out_buffer->acquire_called) { @@ -139,26 +131,11 @@ Status BufferQueueConsumer::ReleaseBuffer(s32 slot, u64 frame_number, const Fenc ++current; } - if (slots[slot].buffer_state == BufferState::Acquired) { - slots[slot].fence = release_fence; - slots[slot].buffer_state = BufferState::Free; - - listener = core->connected_producer_listener; - - LOG_DEBUG(Service_NVFlinger, "releasing slot {}", slot); - } else if (slots[slot].needs_cleanup_on_release) { - LOG_DEBUG(Service_NVFlinger, "releasing a stale buffer slot {} (state = {})", slot, - slots[slot].buffer_state); + slots[slot].buffer_state = BufferState::Free; - slots[slot].needs_cleanup_on_release = false; + listener = core->connected_producer_listener; - return Status::StaleBufferSlot; - } else { - LOG_ERROR(Service_NVFlinger, "attempted to release buffer slot {} but its state was {}", - slot, slots[slot].buffer_state); - - return Status::BadValue; - } + LOG_DEBUG(Service_NVFlinger, "releasing slot {}", slot); core->SignalDequeueCondition(); } diff --git a/src/core/hle/service/nvflinger/buffer_queue_core.cpp b/src/core/hle/service/nvflinger/buffer_queue_core.cpp index d4e8b44d0..ea4a14ea4 100644 --- a/src/core/hle/service/nvflinger/buffer_queue_core.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue_core.cpp @@ -84,10 +84,6 @@ void BufferQueueCore::FreeBufferLocked(s32 slot) { slots[slot].graphic_buffer.reset(); - if (slots[slot].buffer_state == BufferState::Acquired) { - slots[slot].needs_cleanup_on_release = true; - } - slots[slot].buffer_state = BufferState::Free; slots[slot].frame_number = UINT32_MAX; slots[slot].acquire_called = false; diff --git a/src/core/hle/service/nvflinger/buffer_queue_producer.cpp b/src/core/hle/service/nvflinger/buffer_queue_producer.cpp index fe95d1b73..337431488 100644 --- a/src/core/hle/service/nvflinger/buffer_queue_producer.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue_producer.cpp @@ -659,7 +659,7 @@ Status BufferQueueProducer::Query(NativeWindow what, s32* out_value) { value = core->consumer_usage_bit; break; default: - UNREACHABLE(); + ASSERT(false); return Status::BadValue; } diff --git a/src/core/hle/service/nvflinger/buffer_slot.h b/src/core/hle/service/nvflinger/buffer_slot.h index 6b3e87446..0cd0e9964 100644 --- a/src/core/hle/service/nvflinger/buffer_slot.h +++ b/src/core/hle/service/nvflinger/buffer_slot.h @@ -31,7 +31,6 @@ struct BufferSlot final { u64 frame_number{}; Fence fence; bool acquire_called{}; - bool needs_cleanup_on_release{}; bool attached_by_consumer{}; bool is_preallocated{}; }; diff --git a/src/core/hle/service/time/standard_user_system_clock_core.cpp b/src/core/hle/service/time/standard_user_system_clock_core.cpp index f0cc9a155..508091dc2 100644 --- a/src/core/hle/service/time/standard_user_system_clock_core.cpp +++ b/src/core/hle/service/time/standard_user_system_clock_core.cpp @@ -48,12 +48,12 @@ ResultCode StandardUserSystemClockCore::GetClockContext(Core::System& system, } ResultCode StandardUserSystemClockCore::Flush(const SystemClockContext&) { - UNREACHABLE(); + UNIMPLEMENTED(); return ERROR_NOT_IMPLEMENTED; } ResultCode StandardUserSystemClockCore::SetClockContext(const SystemClockContext&) { - UNREACHABLE(); + UNIMPLEMENTED(); return ERROR_NOT_IMPLEMENTED; } diff --git a/src/core/hle/service/time/time_manager.cpp b/src/core/hle/service/time/time_manager.cpp index acc038dbf..28667710e 100644 --- a/src/core/hle/service/time/time_manager.cpp +++ b/src/core/hle/service/time/time_manager.cpp @@ -111,7 +111,7 @@ struct TimeManager::Impl final { FileSys::VirtualFile& vfs_file) { if (time_zone_content_manager.GetTimeZoneManager().SetDeviceLocationNameWithTimeZoneRule( location_name, vfs_file) != ResultSuccess) { - UNREACHABLE(); + ASSERT(false); return; } @@ -155,7 +155,7 @@ struct TimeManager::Impl final { } else { if (standard_local_system_clock_core.SetCurrentTime(system_, posix_time) != ResultSuccess) { - UNREACHABLE(); + ASSERT(false); return; } } @@ -170,7 +170,7 @@ struct TimeManager::Impl final { if (standard_network_system_clock_core.SetSystemClockContext(clock_context) != ResultSuccess) { - UNREACHABLE(); + ASSERT(false); return; } @@ -183,7 +183,7 @@ struct TimeManager::Impl final { Clock::SteadyClockTimePoint steady_clock_time_point) { if (standard_user_system_clock_core.SetAutomaticCorrectionEnabled( system_, is_automatic_correction_enabled) != ResultSuccess) { - UNREACHABLE(); + ASSERT(false); return; } @@ -203,7 +203,7 @@ struct TimeManager::Impl final { if (GetStandardLocalSystemClockCore() .SetCurrentTime(system_, timespan.ToSeconds()) .IsError()) { - UNREACHABLE(); + ASSERT(false); return; } } diff --git a/src/core/hle/service/time/time_zone_manager.cpp b/src/core/hle/service/time/time_zone_manager.cpp index 449a5ac96..fee05ec7a 100644 --- a/src/core/hle/service/time/time_zone_manager.cpp +++ b/src/core/hle/service/time/time_zone_manager.cpp @@ -110,10 +110,9 @@ static constexpr s64 GetLeapDaysFromYear(s64 year) { } } -static constexpr int GetMonthLength(bool is_leap_year, int month) { - constexpr std::array<int, 12> month_lengths{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - constexpr std::array<int, 12> month_lengths_leap{31, 29, 31, 30, 31, 30, - 31, 31, 30, 31, 30, 31}; +static constexpr s8 GetMonthLength(bool is_leap_year, int month) { + constexpr std::array<s8, 12> month_lengths{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + constexpr std::array<s8, 12> month_lengths_leap{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; return is_leap_year ? month_lengths_leap[month] : month_lengths[month]; } @@ -280,7 +279,7 @@ static constexpr int TransitionTime(int year, Rule rule, int offset) { break; } default: - UNREACHABLE(); + ASSERT(false); } return value + rule.transition_time + offset; } |