diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_cp15.cpp | 31 | ||||
-rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_cp15.h | 2 | ||||
-rw-r--r-- | src/core/hid/emulated_controller.cpp | 30 | ||||
-rw-r--r-- | src/core/hid/emulated_controller.h | 7 | ||||
-rw-r--r-- | src/core/hid/hid_types.h | 12 | ||||
-rw-r--r-- | src/core/hle/service/hid/controllers/npad.cpp | 77 |
6 files changed, 130 insertions, 29 deletions
diff --git a/src/core/arm/dynarmic/arm_dynarmic_cp15.cpp b/src/core/arm/dynarmic/arm_dynarmic_cp15.cpp index e9123c13d..200efe4db 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_cp15.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_cp15.cpp @@ -8,6 +8,10 @@ #include "core/core.h" #include "core/core_timing.h" +#ifdef _MSC_VER +#include <intrin.h> +#endif + using Callback = Dynarmic::A32::Coprocessor::Callback; using CallbackOrAccessOneWord = Dynarmic::A32::Coprocessor::CallbackOrAccessOneWord; using CallbackOrAccessTwoWords = Dynarmic::A32::Coprocessor::CallbackOrAccessTwoWords; @@ -47,12 +51,31 @@ CallbackOrAccessOneWord DynarmicCP15::CompileSendOneWord(bool two, unsigned opc1 switch (opc2) { case 4: // CP15_DATA_SYNC_BARRIER - // This is a dummy write, we ignore the value written here. - return &dummy_value; + return Callback{ + [](Dynarmic::A32::Jit*, void*, std::uint32_t, std::uint32_t) -> std::uint64_t { +#ifdef _MSC_VER + _mm_mfence(); + _mm_lfence(); +#else + asm volatile("mfence\n\tlfence\n\t" : : : "memory"); +#endif + return 0; + }, + std::nullopt, + }; case 5: // CP15_DATA_MEMORY_BARRIER - // This is a dummy write, we ignore the value written here. - return &dummy_value; + return Callback{ + [](Dynarmic::A32::Jit*, void*, std::uint32_t, std::uint32_t) -> std::uint64_t { +#ifdef _MSC_VER + _mm_mfence(); +#else + asm volatile("mfence\n\t" : : : "memory"); +#endif + return 0; + }, + std::nullopt, + }; } } diff --git a/src/core/arm/dynarmic/arm_dynarmic_cp15.h b/src/core/arm/dynarmic/arm_dynarmic_cp15.h index 5b2a51636..d90b3e568 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_cp15.h +++ b/src/core/arm/dynarmic/arm_dynarmic_cp15.h @@ -35,6 +35,8 @@ public: ARM_Dynarmic_32& parent; u32 uprw = 0; u32 uro = 0; + + friend class ARM_Dynarmic_32; }; } // namespace Core diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp index 8c3895937..049602e7d 100644 --- a/src/core/hid/emulated_controller.cpp +++ b/src/core/hid/emulated_controller.cpp @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "common/thread.h" #include "core/hid/emulated_controller.h" #include "core/hid/input_converter.h" @@ -84,18 +85,19 @@ void EmulatedController::ReloadFromSettings() { motion_params[index] = Common::ParamPackage(player.motions[index]); } + controller.colors_state.fullkey = { + .body = GetNpadColor(player.body_color_left), + .button = GetNpadColor(player.button_color_left), + }; controller.colors_state.left = { - .body = player.body_color_left, - .button = player.button_color_left, + .body = GetNpadColor(player.body_color_left), + .button = GetNpadColor(player.button_color_left), }; - - controller.colors_state.right = { - .body = player.body_color_right, - .button = player.button_color_right, + controller.colors_state.left = { + .body = GetNpadColor(player.body_color_right), + .button = GetNpadColor(player.button_color_right), }; - controller.colors_state.fullkey = controller.colors_state.left; - // Other or debug controller should always be a pro controller if (npad_id_type != NpadIdType::Other) { SetNpadStyleIndex(MapSettingsTypeToNPad(player.controller_type)); @@ -949,6 +951,9 @@ bool EmulatedController::TestVibration(std::size_t device_index) { // Send a slight vibration to test for rumble support output_devices[device_index]->SetVibration(test_vibration); + // Wait for about 15ms to ensure the controller is ready for the stop command + std::this_thread::sleep_for(std::chrono::milliseconds(15)); + // Stop any vibration and return the result return output_devices[device_index]->SetVibration(zero_vibration) == Common::Input::VibrationError::None; @@ -1310,6 +1315,15 @@ const CameraState& EmulatedController::GetCamera() const { return controller.camera_state; } +NpadColor EmulatedController::GetNpadColor(u32 color) { + return { + .r = static_cast<u8>((color >> 16) & 0xFF), + .g = static_cast<u8>((color >> 8) & 0xFF), + .b = static_cast<u8>(color & 0xFF), + .a = 0xff, + }; +} + void EmulatedController::TriggerOnChange(ControllerTriggerType type, bool is_npad_service_update) { std::scoped_lock lock{callback_mutex}; for (const auto& poller_pair : callback_list) { diff --git a/src/core/hid/emulated_controller.h b/src/core/hid/emulated_controller.h index 823c1700c..cbd7c26d3 100644 --- a/src/core/hid/emulated_controller.h +++ b/src/core/hid/emulated_controller.h @@ -425,6 +425,13 @@ private: void SetCamera(const Common::Input::CallbackStatus& callback); /** + * Converts a color format from bgra to rgba + * @param color in bgra format + * @return NpadColor in rgba format + */ + NpadColor GetNpadColor(u32 color); + + /** * Triggers a callback that something has changed on the controller status * @param type Input type of the event to trigger * @param is_service_update indicates if this event should only be sent to HID services diff --git a/src/core/hid/hid_types.h b/src/core/hid/hid_types.h index e49223016..e3b1cfbc6 100644 --- a/src/core/hid/hid_types.h +++ b/src/core/hid/hid_types.h @@ -327,10 +327,18 @@ struct TouchState { }; static_assert(sizeof(TouchState) == 0x28, "Touchstate is an invalid size"); +struct NpadColor { + u8 r{}; + u8 g{}; + u8 b{}; + u8 a{}; +}; +static_assert(sizeof(NpadColor) == 4, "NpadColor is an invalid size"); + // This is nn::hid::NpadControllerColor struct NpadControllerColor { - u32 body{}; - u32 button{}; + NpadColor body{}; + NpadColor button{}; }; static_assert(sizeof(NpadControllerColor) == 8, "NpadControllerColor is an invalid size"); diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 3c28dee76..cb29004e8 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -163,28 +163,51 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) { } LOG_DEBUG(Service_HID, "Npad connected {}", npad_id); const auto controller_type = controller.device->GetNpadStyleIndex(); + const auto& body_colors = controller.device->GetColors(); + const auto& battery_level = controller.device->GetBattery(); auto* shared_memory = controller.shared_memory; if (controller_type == Core::HID::NpadStyleIndex::None) { controller.styleset_changed_event->GetWritableEvent().Signal(); return; } + + // Reset memory values shared_memory->style_tag.raw = Core::HID::NpadStyleSet::None; shared_memory->device_type.raw = 0; shared_memory->system_properties.raw = 0; + shared_memory->joycon_color.attribute = ColorAttribute::NoController; + shared_memory->joycon_color.attribute = ColorAttribute::NoController; + shared_memory->fullkey_color = {}; + shared_memory->joycon_color.left = {}; + shared_memory->joycon_color.right = {}; + shared_memory->battery_level_dual = {}; + shared_memory->battery_level_left = {}; + shared_memory->battery_level_right = {}; + switch (controller_type) { case Core::HID::NpadStyleIndex::None: ASSERT(false); break; case Core::HID::NpadStyleIndex::ProController: + shared_memory->fullkey_color.attribute = ColorAttribute::Ok; + shared_memory->fullkey_color.fullkey = body_colors.fullkey; + shared_memory->battery_level_dual = battery_level.dual.battery_level; shared_memory->style_tag.fullkey.Assign(1); shared_memory->device_type.fullkey.Assign(1); shared_memory->system_properties.is_vertical.Assign(1); shared_memory->system_properties.use_plus.Assign(1); shared_memory->system_properties.use_minus.Assign(1); + shared_memory->system_properties.is_charging_joy_dual.Assign( + battery_level.dual.is_charging); 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->fullkey_color.attribute = ColorAttribute::Ok; + shared_memory->joycon_color.attribute = ColorAttribute::Ok; + shared_memory->fullkey_color.fullkey = body_colors.fullkey; + shared_memory->joycon_color.left = body_colors.left; + shared_memory->joycon_color.right = body_colors.right; shared_memory->style_tag.handheld.Assign(1); shared_memory->device_type.handheld_left.Assign(1); shared_memory->device_type.handheld_right.Assign(1); @@ -192,47 +215,86 @@ 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->system_properties.use_directional_buttons.Assign(1); + shared_memory->system_properties.is_charging_joy_dual.Assign( + battery_level.left.is_charging); + shared_memory->system_properties.is_charging_joy_left.Assign( + battery_level.left.is_charging); + shared_memory->system_properties.is_charging_joy_right.Assign( + battery_level.right.is_charging); 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->fullkey_color.attribute = ColorAttribute::Ok; + shared_memory->joycon_color.attribute = ColorAttribute::Ok; shared_memory->style_tag.joycon_dual.Assign(1); if (controller.is_dual_left_connected) { + shared_memory->joycon_color.left = body_colors.left; + shared_memory->battery_level_left = battery_level.left.battery_level; shared_memory->device_type.joycon_left.Assign(1); shared_memory->system_properties.use_minus.Assign(1); + shared_memory->system_properties.is_charging_joy_left.Assign( + battery_level.left.is_charging); shared_memory->sixaxis_dual_left_properties.is_newly_assigned.Assign(1); } if (controller.is_dual_right_connected) { + shared_memory->joycon_color.right = body_colors.right; + shared_memory->battery_level_right = battery_level.right.battery_level; shared_memory->device_type.joycon_right.Assign(1); shared_memory->system_properties.use_plus.Assign(1); + shared_memory->system_properties.is_charging_joy_right.Assign( + battery_level.right.is_charging); 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); shared_memory->assignment_mode = NpadJoyAssignmentMode::Dual; + if (controller.is_dual_left_connected && controller.is_dual_right_connected) { shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyDual; + shared_memory->fullkey_color.fullkey = body_colors.left; + shared_memory->battery_level_dual = battery_level.left.battery_level; + shared_memory->system_properties.is_charging_joy_dual.Assign( + battery_level.left.is_charging); } else if (controller.is_dual_left_connected) { shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyDualLeftOnly; + shared_memory->fullkey_color.fullkey = body_colors.left; + shared_memory->battery_level_dual = battery_level.left.battery_level; + shared_memory->system_properties.is_charging_joy_dual.Assign( + battery_level.left.is_charging); } else { shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyDualRightOnly; + shared_memory->fullkey_color.fullkey = body_colors.right; + shared_memory->battery_level_dual = battery_level.right.battery_level; + shared_memory->system_properties.is_charging_joy_dual.Assign( + battery_level.right.is_charging); } break; case Core::HID::NpadStyleIndex::JoyconLeft: + shared_memory->joycon_color.attribute = ColorAttribute::Ok; + shared_memory->joycon_color.left = body_colors.left; + shared_memory->battery_level_dual = battery_level.left.battery_level; shared_memory->style_tag.joycon_left.Assign(1); shared_memory->device_type.joycon_left.Assign(1); shared_memory->system_properties.is_horizontal.Assign(1); shared_memory->system_properties.use_minus.Assign(1); + shared_memory->system_properties.is_charging_joy_left.Assign( + battery_level.left.is_charging); 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->joycon_color.attribute = ColorAttribute::Ok; + shared_memory->joycon_color.right = body_colors.right; + shared_memory->battery_level_right = battery_level.right.battery_level; shared_memory->style_tag.joycon_right.Assign(1); shared_memory->device_type.joycon_right.Assign(1); shared_memory->system_properties.is_horizontal.Assign(1); shared_memory->system_properties.use_plus.Assign(1); + shared_memory->system_properties.is_charging_joy_right.Assign( + battery_level.right.is_charging); shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyRightHorizontal; shared_memory->sixaxis_right_properties.is_newly_assigned.Assign(1); break; @@ -269,21 +331,6 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) { break; } - const auto& body_colors = controller.device->GetColors(); - - shared_memory->fullkey_color.attribute = ColorAttribute::Ok; - shared_memory->fullkey_color.fullkey = body_colors.fullkey; - - shared_memory->joycon_color.attribute = ColorAttribute::Ok; - shared_memory->joycon_color.left = body_colors.left; - shared_memory->joycon_color.right = body_colors.right; - - // TODO: Investigate when we should report all batery types - const auto& battery_level = controller.device->GetBattery(); - shared_memory->battery_level_dual = battery_level.dual.battery_level; - shared_memory->battery_level_left = battery_level.left.battery_level; - shared_memory->battery_level_right = battery_level.right.battery_level; - controller.is_connected = true; controller.device->Connect(); SignalStyleSetChangedEvent(npad_id); |