diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_32.cpp | 6 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_64.cpp | 6 | ||||
| -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 | 
8 files changed, 140 insertions, 31 deletions
| diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index 2e0e16b6e..1638bc41d 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp @@ -144,7 +144,7 @@ public:      u64 GetTicksRemaining() override {          if (parent.uses_wall_clock) { -            if (!parent.interrupt_handlers[parent.core_index].IsInterrupted()) { +            if (!IsInterrupted()) {                  return minimum_run_cycles;              }              return 0U; @@ -174,6 +174,10 @@ public:          parent.jit.load()->HaltExecution(hr);      } +    bool IsInterrupted() { +        return parent.system.Kernel().PhysicalCore(parent.core_index).IsInterrupted(); +    } +      ARM_Dynarmic_32& parent;      Core::Memory::Memory& memory;      std::size_t num_interpreted_instructions{}; diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index bf971b7dc..921a5a734 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -183,7 +183,7 @@ public:      u64 GetTicksRemaining() override {          if (parent.uses_wall_clock) { -            if (!parent.interrupt_handlers[parent.core_index].IsInterrupted()) { +            if (!IsInterrupted()) {                  return minimum_run_cycles;              }              return 0U; @@ -217,6 +217,10 @@ public:          parent.jit.load()->HaltExecution(hr);      } +    bool IsInterrupted() { +        return parent.system.Kernel().PhysicalCore(parent.core_index).IsInterrupted(); +    } +      ARM_Dynarmic_64& parent;      Core::Memory::Memory& memory;      u64 tpidrro_el0 = 0; 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); | 
