mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-04 00:49:02 -06:00 
			
		
		
		
	hid: avoid direct pointer access of transfer memory objects
This commit is contained in:
		@@ -1,17 +1,18 @@
 | 
			
		||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
 | 
			
		||||
// SPDX-License-Identifier: GPL-2.0-or-later
 | 
			
		||||
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
#include "core/core_timing.h"
 | 
			
		||||
#include "core/hid/emulated_console.h"
 | 
			
		||||
#include "core/hid/hid_core.h"
 | 
			
		||||
#include "core/hle/service/hid/controllers/console_sixaxis.h"
 | 
			
		||||
#include "core/memory.h"
 | 
			
		||||
 | 
			
		||||
namespace Service::HID {
 | 
			
		||||
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C200;
 | 
			
		||||
 | 
			
		||||
Controller_ConsoleSixAxis::Controller_ConsoleSixAxis(Core::HID::HIDCore& hid_core_,
 | 
			
		||||
                                                     u8* raw_shared_memory_)
 | 
			
		||||
    : ControllerBase{hid_core_} {
 | 
			
		||||
Controller_ConsoleSixAxis::Controller_ConsoleSixAxis(Core::System& system_, u8* raw_shared_memory_)
 | 
			
		||||
    : ControllerBase{system_.HIDCore()}, system{system_} {
 | 
			
		||||
    console = hid_core.GetEmulatedConsole();
 | 
			
		||||
    static_assert(SHARED_MEMORY_OFFSET + sizeof(ConsoleSharedMemory) < shared_memory_size,
 | 
			
		||||
                  "ConsoleSharedMemory is bigger than the shared memory");
 | 
			
		||||
@@ -26,7 +27,7 @@ void Controller_ConsoleSixAxis::OnInit() {}
 | 
			
		||||
void Controller_ConsoleSixAxis::OnRelease() {}
 | 
			
		||||
 | 
			
		||||
void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
 | 
			
		||||
    if (!IsControllerActivated() || !is_transfer_memory_set) {
 | 
			
		||||
    if (!IsControllerActivated() || transfer_memory == 0) {
 | 
			
		||||
        seven_sixaxis_lifo.buffer_count = 0;
 | 
			
		||||
        seven_sixaxis_lifo.buffer_tail = 0;
 | 
			
		||||
        return;
 | 
			
		||||
@@ -59,11 +60,10 @@ void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_ti
 | 
			
		||||
 | 
			
		||||
    // Update seven six axis transfer memory
 | 
			
		||||
    seven_sixaxis_lifo.WriteNextEntry(next_seven_sixaxis_state);
 | 
			
		||||
    std::memcpy(transfer_memory, &seven_sixaxis_lifo, sizeof(seven_sixaxis_lifo));
 | 
			
		||||
    system.Memory().WriteBlock(transfer_memory, &seven_sixaxis_lifo, sizeof(seven_sixaxis_lifo));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Controller_ConsoleSixAxis::SetTransferMemoryPointer(u8* t_mem) {
 | 
			
		||||
    is_transfer_memory_set = true;
 | 
			
		||||
void Controller_ConsoleSixAxis::SetTransferMemoryAddress(VAddr t_mem) {
 | 
			
		||||
    transfer_memory = t_mem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,10 @@
 | 
			
		||||
#include "core/hle/service/hid/controllers/controller_base.h"
 | 
			
		||||
#include "core/hle/service/hid/ring_lifo.h"
 | 
			
		||||
 | 
			
		||||
namespace Core {
 | 
			
		||||
class System;
 | 
			
		||||
} // namespace Core
 | 
			
		||||
 | 
			
		||||
namespace Core::HID {
 | 
			
		||||
class EmulatedConsole;
 | 
			
		||||
} // namespace Core::HID
 | 
			
		||||
@@ -17,7 +21,7 @@ class EmulatedConsole;
 | 
			
		||||
namespace Service::HID {
 | 
			
		||||
class Controller_ConsoleSixAxis final : public ControllerBase {
 | 
			
		||||
public:
 | 
			
		||||
    explicit Controller_ConsoleSixAxis(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
 | 
			
		||||
    explicit Controller_ConsoleSixAxis(Core::System& system_, u8* raw_shared_memory_);
 | 
			
		||||
    ~Controller_ConsoleSixAxis() override;
 | 
			
		||||
 | 
			
		||||
    // Called when the controller is initialized
 | 
			
		||||
@@ -30,7 +34,7 @@ public:
 | 
			
		||||
    void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
 | 
			
		||||
 | 
			
		||||
    // Called on InitializeSevenSixAxisSensor
 | 
			
		||||
    void SetTransferMemoryPointer(u8* t_mem);
 | 
			
		||||
    void SetTransferMemoryAddress(VAddr t_mem);
 | 
			
		||||
 | 
			
		||||
    // Called on ResetSevenSixAxisSensorTimestamp
 | 
			
		||||
    void ResetTimestamp();
 | 
			
		||||
@@ -62,12 +66,13 @@ private:
 | 
			
		||||
    static_assert(sizeof(seven_sixaxis_lifo) == 0xA70, "SevenSixAxisState is an invalid size");
 | 
			
		||||
 | 
			
		||||
    SevenSixAxisState next_seven_sixaxis_state{};
 | 
			
		||||
    u8* transfer_memory = nullptr;
 | 
			
		||||
    VAddr transfer_memory{};
 | 
			
		||||
    ConsoleSharedMemory* shared_memory = nullptr;
 | 
			
		||||
    Core::HID::EmulatedConsole* console = nullptr;
 | 
			
		||||
 | 
			
		||||
    bool is_transfer_memory_set = false;
 | 
			
		||||
    u64 last_saved_timestamp{};
 | 
			
		||||
    u64 last_global_timestamp{};
 | 
			
		||||
 | 
			
		||||
    Core::System& system;
 | 
			
		||||
};
 | 
			
		||||
} // namespace Service::HID
 | 
			
		||||
 
 | 
			
		||||
@@ -152,7 +152,7 @@ Result Controller_Palma::WritePalmaRgbLedPatternEntry(const PalmaConnectionHandl
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Result Controller_Palma::WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave,
 | 
			
		||||
                                             u8* t_mem, u64 size) {
 | 
			
		||||
                                             VAddr t_mem, u64 size) {
 | 
			
		||||
    if (handle.npad_id != active_handle.npad_id) {
 | 
			
		||||
        return InvalidPalmaHandle;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -125,7 +125,7 @@ public:
 | 
			
		||||
    Result ReadPalmaUniqueCode(const PalmaConnectionHandle& handle);
 | 
			
		||||
    Result SetPalmaUniqueCodeInvalid(const PalmaConnectionHandle& handle);
 | 
			
		||||
    Result WritePalmaRgbLedPatternEntry(const PalmaConnectionHandle& handle, u64 unknown);
 | 
			
		||||
    Result WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave, u8* t_mem,
 | 
			
		||||
    Result WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave, VAddr t_mem,
 | 
			
		||||
                               u64 size);
 | 
			
		||||
    Result SetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle,
 | 
			
		||||
                                                 s32 database_id_version_);
 | 
			
		||||
 
 | 
			
		||||
@@ -1858,7 +1858,7 @@ void Hid::InitializeSevenSixAxisSensor(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
        .ActivateController();
 | 
			
		||||
 | 
			
		||||
    applet_resource->GetController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor)
 | 
			
		||||
        .SetTransferMemoryPointer(system.Memory().GetPointer(t_mem_1->GetSourceAddress()));
 | 
			
		||||
        .SetTransferMemoryAddress(t_mem_1->GetSourceAddress());
 | 
			
		||||
 | 
			
		||||
    LOG_WARNING(Service_HID,
 | 
			
		||||
                "called, t_mem_1_handle=0x{:08X}, t_mem_2_handle=0x{:08X}, "
 | 
			
		||||
@@ -2145,8 +2145,7 @@ void Hid::WritePalmaWaveEntry(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
                connection_handle.npad_id, wave_set, unknown, t_mem_handle, t_mem_size, size);
 | 
			
		||||
 | 
			
		||||
    applet_resource->GetController<Controller_Palma>(HidController::Palma)
 | 
			
		||||
        .WritePalmaWaveEntry(connection_handle, wave_set,
 | 
			
		||||
                             system.Memory().GetPointer(t_mem->GetSourceAddress()), t_mem_size);
 | 
			
		||||
        .WritePalmaWaveEntry(connection_handle, wave_set, t_mem->GetSourceAddress(), t_mem_size);
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 2};
 | 
			
		||||
    rb.Push(ResultSuccess);
 | 
			
		||||
 
 | 
			
		||||
@@ -60,9 +60,15 @@ public:
 | 
			
		||||
private:
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    void MakeController(HidController controller, u8* shared_memory) {
 | 
			
		||||
        controllers[static_cast<std::size_t>(controller)] =
 | 
			
		||||
            std::make_unique<T>(system.HIDCore(), shared_memory);
 | 
			
		||||
        if constexpr (std::is_constructible_v<T, Core::System&, u8*>) {
 | 
			
		||||
            controllers[static_cast<std::size_t>(controller)] =
 | 
			
		||||
                std::make_unique<T>(system, shared_memory);
 | 
			
		||||
        } else {
 | 
			
		||||
            controllers[static_cast<std::size_t>(controller)] =
 | 
			
		||||
                std::make_unique<T>(system.HIDCore(), shared_memory);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    void MakeControllerWithServiceContext(HidController controller, u8* shared_memory) {
 | 
			
		||||
        controllers[static_cast<std::size_t>(controller)] =
 | 
			
		||||
 
 | 
			
		||||
@@ -472,7 +472,7 @@ void HidBus::EnableJoyPollingReceiveMode(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
    if (device_index) {
 | 
			
		||||
        auto& device = devices[device_index.value()].device;
 | 
			
		||||
        device->SetPollingMode(polling_mode_);
 | 
			
		||||
        device->SetTransferMemoryPointer(system.Memory().GetPointer(t_mem->GetSourceAddress()));
 | 
			
		||||
        device->SetTransferMemoryAddress(t_mem->GetSourceAddress());
 | 
			
		||||
 | 
			
		||||
        IPC::ResponseBuilder rb{ctx, 2};
 | 
			
		||||
        rb.Push(ResultSuccess);
 | 
			
		||||
 
 | 
			
		||||
@@ -115,8 +115,7 @@ private:
 | 
			
		||||
    void MakeDevice(BusHandle handle) {
 | 
			
		||||
        const auto device_index = GetDeviceIndexFromHandle(handle);
 | 
			
		||||
        if (device_index) {
 | 
			
		||||
            devices[device_index.value()].device =
 | 
			
		||||
                std::make_unique<T>(system.HIDCore(), service_context);
 | 
			
		||||
            devices[device_index.value()].device = std::make_unique<T>(system, service_context);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -9,8 +9,8 @@
 | 
			
		||||
 | 
			
		||||
namespace Service::HID {
 | 
			
		||||
 | 
			
		||||
HidbusBase::HidbusBase(KernelHelpers::ServiceContext& service_context_)
 | 
			
		||||
    : service_context(service_context_) {
 | 
			
		||||
HidbusBase::HidbusBase(Core::System& system_, KernelHelpers::ServiceContext& service_context_)
 | 
			
		||||
    : system(system_), service_context(service_context_) {
 | 
			
		||||
    send_command_async_event = service_context.CreateEvent("hidbus:SendCommandAsyncEvent");
 | 
			
		||||
}
 | 
			
		||||
HidbusBase::~HidbusBase() = default;
 | 
			
		||||
@@ -59,8 +59,7 @@ void HidbusBase::DisablePollingMode() {
 | 
			
		||||
    polling_mode_enabled = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HidbusBase::SetTransferMemoryPointer(u8* t_mem) {
 | 
			
		||||
    is_transfer_memory_set = true;
 | 
			
		||||
void HidbusBase::SetTransferMemoryAddress(VAddr t_mem) {
 | 
			
		||||
    transfer_memory = t_mem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,10 @@
 | 
			
		||||
#include "common/common_types.h"
 | 
			
		||||
#include "core/hle/result.h"
 | 
			
		||||
 | 
			
		||||
namespace Core {
 | 
			
		||||
class System;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace Kernel {
 | 
			
		||||
class KEvent;
 | 
			
		||||
class KReadableEvent;
 | 
			
		||||
@@ -106,7 +110,7 @@ static_assert(sizeof(ButtonOnlyPollingDataAccessor) == 0x2F0,
 | 
			
		||||
 | 
			
		||||
class HidbusBase {
 | 
			
		||||
public:
 | 
			
		||||
    explicit HidbusBase(KernelHelpers::ServiceContext& service_context_);
 | 
			
		||||
    explicit HidbusBase(Core::System& system_, KernelHelpers::ServiceContext& service_context_);
 | 
			
		||||
    virtual ~HidbusBase();
 | 
			
		||||
 | 
			
		||||
    void ActivateDevice();
 | 
			
		||||
@@ -134,7 +138,7 @@ public:
 | 
			
		||||
    void DisablePollingMode();
 | 
			
		||||
 | 
			
		||||
    // Called on EnableJoyPollingReceiveMode
 | 
			
		||||
    void SetTransferMemoryPointer(u8* t_mem);
 | 
			
		||||
    void SetTransferMemoryAddress(VAddr t_mem);
 | 
			
		||||
 | 
			
		||||
    Kernel::KReadableEvent& GetSendCommandAsycEvent() const;
 | 
			
		||||
 | 
			
		||||
@@ -170,9 +174,9 @@ protected:
 | 
			
		||||
    JoyEnableSixAxisDataAccessor enable_sixaxis_data{};
 | 
			
		||||
    ButtonOnlyPollingDataAccessor button_only_data{};
 | 
			
		||||
 | 
			
		||||
    u8* transfer_memory{nullptr};
 | 
			
		||||
    bool is_transfer_memory_set{};
 | 
			
		||||
    VAddr transfer_memory{};
 | 
			
		||||
 | 
			
		||||
    Core::System& system;
 | 
			
		||||
    Kernel::KEvent* send_command_async_event;
 | 
			
		||||
    KernelHelpers::ServiceContext& service_context;
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -1,18 +1,20 @@
 | 
			
		||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
 | 
			
		||||
// SPDX-License-Identifier: GPL-2.0-or-later
 | 
			
		||||
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
#include "core/hid/emulated_controller.h"
 | 
			
		||||
#include "core/hid/hid_core.h"
 | 
			
		||||
#include "core/hle/kernel/k_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_readable_event.h"
 | 
			
		||||
#include "core/hle/service/hid/hidbus/ringcon.h"
 | 
			
		||||
#include "core/memory.h"
 | 
			
		||||
 | 
			
		||||
namespace Service::HID {
 | 
			
		||||
 | 
			
		||||
RingController::RingController(Core::HID::HIDCore& hid_core_,
 | 
			
		||||
RingController::RingController(Core::System& system_,
 | 
			
		||||
                               KernelHelpers::ServiceContext& service_context_)
 | 
			
		||||
    : HidbusBase(service_context_) {
 | 
			
		||||
    input = hid_core_.GetEmulatedController(Core::HID::NpadIdType::Player1);
 | 
			
		||||
    : HidbusBase(system_, service_context_) {
 | 
			
		||||
    input = system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RingController::~RingController() = default;
 | 
			
		||||
@@ -38,7 +40,7 @@ void RingController::OnUpdate() {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!polling_mode_enabled || !is_transfer_memory_set) {
 | 
			
		||||
    if (!polling_mode_enabled || transfer_memory == 0) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -62,7 +64,8 @@ void RingController::OnUpdate() {
 | 
			
		||||
        curr_entry.polling_data.out_size = sizeof(ringcon_value);
 | 
			
		||||
        std::memcpy(curr_entry.polling_data.data.data(), &ringcon_value, sizeof(ringcon_value));
 | 
			
		||||
 | 
			
		||||
        std::memcpy(transfer_memory, &enable_sixaxis_data, sizeof(enable_sixaxis_data));
 | 
			
		||||
        system.Memory().WriteBlock(transfer_memory, &enable_sixaxis_data,
 | 
			
		||||
                                   sizeof(enable_sixaxis_data));
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    default:
 | 
			
		||||
 
 | 
			
		||||
@@ -17,8 +17,7 @@ namespace Service::HID {
 | 
			
		||||
 | 
			
		||||
class RingController final : public HidbusBase {
 | 
			
		||||
public:
 | 
			
		||||
    explicit RingController(Core::HID::HIDCore& hid_core_,
 | 
			
		||||
                            KernelHelpers::ServiceContext& service_context_);
 | 
			
		||||
    explicit RingController(Core::System& system_, KernelHelpers::ServiceContext& service_context_);
 | 
			
		||||
    ~RingController() override;
 | 
			
		||||
 | 
			
		||||
    void OnInit() override;
 | 
			
		||||
 
 | 
			
		||||
@@ -8,8 +8,8 @@
 | 
			
		||||
namespace Service::HID {
 | 
			
		||||
constexpr u8 DEVICE_ID = 0x28;
 | 
			
		||||
 | 
			
		||||
Starlink::Starlink(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service_context_)
 | 
			
		||||
    : HidbusBase(service_context_) {}
 | 
			
		||||
Starlink::Starlink(Core::System& system_, KernelHelpers::ServiceContext& service_context_)
 | 
			
		||||
    : HidbusBase(system_, service_context_) {}
 | 
			
		||||
Starlink::~Starlink() = default;
 | 
			
		||||
 | 
			
		||||
void Starlink::OnInit() {
 | 
			
		||||
@@ -27,7 +27,7 @@ void Starlink::OnUpdate() {
 | 
			
		||||
    if (!device_enabled) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    if (!polling_mode_enabled || !is_transfer_memory_set) {
 | 
			
		||||
    if (!polling_mode_enabled || transfer_memory == 0) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -14,8 +14,7 @@ namespace Service::HID {
 | 
			
		||||
 | 
			
		||||
class Starlink final : public HidbusBase {
 | 
			
		||||
public:
 | 
			
		||||
    explicit Starlink(Core::HID::HIDCore& hid_core_,
 | 
			
		||||
                      KernelHelpers::ServiceContext& service_context_);
 | 
			
		||||
    explicit Starlink(Core::System& system_, KernelHelpers::ServiceContext& service_context_);
 | 
			
		||||
    ~Starlink() override;
 | 
			
		||||
 | 
			
		||||
    void OnInit() override;
 | 
			
		||||
 
 | 
			
		||||
@@ -8,9 +8,8 @@
 | 
			
		||||
namespace Service::HID {
 | 
			
		||||
constexpr u8 DEVICE_ID = 0xFF;
 | 
			
		||||
 | 
			
		||||
HidbusStubbed::HidbusStubbed(Core::HID::HIDCore& hid_core_,
 | 
			
		||||
                             KernelHelpers::ServiceContext& service_context_)
 | 
			
		||||
    : HidbusBase(service_context_) {}
 | 
			
		||||
HidbusStubbed::HidbusStubbed(Core::System& system_, KernelHelpers::ServiceContext& service_context_)
 | 
			
		||||
    : HidbusBase(system_, service_context_) {}
 | 
			
		||||
HidbusStubbed::~HidbusStubbed() = default;
 | 
			
		||||
 | 
			
		||||
void HidbusStubbed::OnInit() {
 | 
			
		||||
@@ -28,7 +27,7 @@ void HidbusStubbed::OnUpdate() {
 | 
			
		||||
    if (!device_enabled) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    if (!polling_mode_enabled || !is_transfer_memory_set) {
 | 
			
		||||
    if (!polling_mode_enabled || transfer_memory == 0) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -14,8 +14,7 @@ namespace Service::HID {
 | 
			
		||||
 | 
			
		||||
class HidbusStubbed final : public HidbusBase {
 | 
			
		||||
public:
 | 
			
		||||
    explicit HidbusStubbed(Core::HID::HIDCore& hid_core_,
 | 
			
		||||
                           KernelHelpers::ServiceContext& service_context_);
 | 
			
		||||
    explicit HidbusStubbed(Core::System& system_, KernelHelpers::ServiceContext& service_context_);
 | 
			
		||||
    ~HidbusStubbed() override;
 | 
			
		||||
 | 
			
		||||
    void OnInit() override;
 | 
			
		||||
 
 | 
			
		||||
@@ -208,8 +208,6 @@ void IRS::RunImageTransferProcessor(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
 | 
			
		||||
    ASSERT_MSG(t_mem->GetSize() == parameters.transfer_memory_size, "t_mem has incorrect size");
 | 
			
		||||
 | 
			
		||||
    u8* transfer_memory = system.Memory().GetPointer(t_mem->GetSourceAddress());
 | 
			
		||||
 | 
			
		||||
    LOG_INFO(Service_IRS,
 | 
			
		||||
             "called, npad_type={}, npad_id={}, transfer_memory_size={}, transfer_memory_size={}, "
 | 
			
		||||
             "applet_resource_user_id={}",
 | 
			
		||||
@@ -224,7 +222,7 @@ void IRS::RunImageTransferProcessor(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
        auto& image_transfer_processor =
 | 
			
		||||
            GetProcessor<ImageTransferProcessor>(parameters.camera_handle);
 | 
			
		||||
        image_transfer_processor.SetConfig(parameters.processor_config);
 | 
			
		||||
        image_transfer_processor.SetTransferMemoryPointer(transfer_memory);
 | 
			
		||||
        image_transfer_processor.SetTransferMemoryAddress(t_mem->GetSourceAddress());
 | 
			
		||||
        npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
 | 
			
		||||
                                    Common::Input::PollingMode::IR);
 | 
			
		||||
    }
 | 
			
		||||
@@ -448,8 +446,6 @@ void IRS::RunImageTransferExProcessor(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
    auto t_mem = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(
 | 
			
		||||
        t_mem_handle);
 | 
			
		||||
 | 
			
		||||
    u8* transfer_memory = system.Memory().GetPointer(t_mem->GetSourceAddress());
 | 
			
		||||
 | 
			
		||||
    LOG_INFO(Service_IRS,
 | 
			
		||||
             "called, npad_type={}, npad_id={}, transfer_memory_size={}, "
 | 
			
		||||
             "applet_resource_user_id={}",
 | 
			
		||||
@@ -464,7 +460,7 @@ void IRS::RunImageTransferExProcessor(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
        auto& image_transfer_processor =
 | 
			
		||||
            GetProcessor<ImageTransferProcessor>(parameters.camera_handle);
 | 
			
		||||
        image_transfer_processor.SetConfig(parameters.processor_config);
 | 
			
		||||
        image_transfer_processor.SetTransferMemoryPointer(transfer_memory);
 | 
			
		||||
        image_transfer_processor.SetTransferMemoryAddress(t_mem->GetSourceAddress());
 | 
			
		||||
        npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
 | 
			
		||||
                                    Common::Input::PollingMode::IR);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -80,7 +80,13 @@ private:
 | 
			
		||||
            LOG_CRITICAL(Service_IRS, "Invalid index {}", index);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        processors[index] = std::make_unique<T>(system.HIDCore(), device_state, index);
 | 
			
		||||
 | 
			
		||||
        if constexpr (std::is_constructible_v<T, Core::System&, Core::IrSensor::DeviceFormat&,
 | 
			
		||||
                                              std::size_t>) {
 | 
			
		||||
            processors[index] = std::make_unique<T>(system, device_state, index);
 | 
			
		||||
        } else {
 | 
			
		||||
            processors[index] = std::make_unique<T>(system.HIDCore(), device_state, index);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <typename T>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,16 +1,18 @@
 | 
			
		||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
 | 
			
		||||
// SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
#include "core/hid/emulated_controller.h"
 | 
			
		||||
#include "core/hid/hid_core.h"
 | 
			
		||||
#include "core/hle/service/hid/irsensor/image_transfer_processor.h"
 | 
			
		||||
#include "core/memory.h"
 | 
			
		||||
 | 
			
		||||
namespace Service::IRS {
 | 
			
		||||
ImageTransferProcessor::ImageTransferProcessor(Core::HID::HIDCore& hid_core_,
 | 
			
		||||
ImageTransferProcessor::ImageTransferProcessor(Core::System& system_,
 | 
			
		||||
                                               Core::IrSensor::DeviceFormat& device_format,
 | 
			
		||||
                                               std::size_t npad_index)
 | 
			
		||||
    : device{device_format} {
 | 
			
		||||
    npad_device = hid_core_.GetEmulatedControllerByIndex(npad_index);
 | 
			
		||||
    : device{device_format}, system{system_} {
 | 
			
		||||
    npad_device = system.HIDCore().GetEmulatedControllerByIndex(npad_index);
 | 
			
		||||
 | 
			
		||||
    Core::HID::ControllerUpdateCallback engine_callback{
 | 
			
		||||
        .on_change = [this](Core::HID::ControllerTriggerType type) { OnControllerUpdate(type); },
 | 
			
		||||
@@ -43,7 +45,7 @@ void ImageTransferProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType
 | 
			
		||||
    if (type != Core::HID::ControllerTriggerType::IrSensor) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    if (!is_transfer_memory_set) {
 | 
			
		||||
    if (transfer_memory == 0) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -56,14 +58,16 @@ void ImageTransferProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType
 | 
			
		||||
    if (camera_data.format != current_config.origin_format) {
 | 
			
		||||
        LOG_WARNING(Service_IRS, "Wrong Input format {} expected {}", camera_data.format,
 | 
			
		||||
                    current_config.origin_format);
 | 
			
		||||
        memset(transfer_memory, 0, GetDataSize(current_config.trimming_format));
 | 
			
		||||
        system.Memory().ZeroBlock(*system.ApplicationProcess(), transfer_memory,
 | 
			
		||||
                                  GetDataSize(current_config.trimming_format));
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (current_config.origin_format > current_config.trimming_format) {
 | 
			
		||||
        LOG_WARNING(Service_IRS, "Origin format {} is smaller than trimming format {}",
 | 
			
		||||
                    current_config.origin_format, current_config.trimming_format);
 | 
			
		||||
        memset(transfer_memory, 0, GetDataSize(current_config.trimming_format));
 | 
			
		||||
        system.Memory().ZeroBlock(*system.ApplicationProcess(), transfer_memory,
 | 
			
		||||
                                  GetDataSize(current_config.trimming_format));
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -80,7 +84,8 @@ void ImageTransferProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType
 | 
			
		||||
                    "Trimming area ({}, {}, {}, {}) is outside of origin area ({}, {})",
 | 
			
		||||
                    current_config.trimming_start_x, current_config.trimming_start_y,
 | 
			
		||||
                    trimming_width, trimming_height, origin_width, origin_height);
 | 
			
		||||
        memset(transfer_memory, 0, GetDataSize(current_config.trimming_format));
 | 
			
		||||
        system.Memory().ZeroBlock(*system.ApplicationProcess(), transfer_memory,
 | 
			
		||||
                                  GetDataSize(current_config.trimming_format));
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -94,7 +99,8 @@ void ImageTransferProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    memcpy(transfer_memory, window_data.data(), GetDataSize(current_config.trimming_format));
 | 
			
		||||
    system.Memory().WriteBlock(transfer_memory, window_data.data(),
 | 
			
		||||
                               GetDataSize(current_config.trimming_format));
 | 
			
		||||
 | 
			
		||||
    if (!IsProcessorActive()) {
 | 
			
		||||
        StartProcessor();
 | 
			
		||||
@@ -134,8 +140,7 @@ void ImageTransferProcessor::SetConfig(
 | 
			
		||||
    npad_device->SetCameraFormat(current_config.origin_format);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ImageTransferProcessor::SetTransferMemoryPointer(u8* t_mem) {
 | 
			
		||||
    is_transfer_memory_set = true;
 | 
			
		||||
void ImageTransferProcessor::SetTransferMemoryAddress(VAddr t_mem) {
 | 
			
		||||
    transfer_memory = t_mem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -143,7 +148,7 @@ Core::IrSensor::ImageTransferProcessorState ImageTransferProcessor::GetState(
 | 
			
		||||
    std::vector<u8>& data) const {
 | 
			
		||||
    const auto size = GetDataSize(current_config.trimming_format);
 | 
			
		||||
    data.resize(size);
 | 
			
		||||
    memcpy(data.data(), transfer_memory, size);
 | 
			
		||||
    system.Memory().ReadBlock(transfer_memory, data.data(), size);
 | 
			
		||||
    return processor_state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,10 @@
 | 
			
		||||
#include "core/hid/irs_types.h"
 | 
			
		||||
#include "core/hle/service/hid/irsensor/processor_base.h"
 | 
			
		||||
 | 
			
		||||
namespace Core {
 | 
			
		||||
class System;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace Core::HID {
 | 
			
		||||
class EmulatedController;
 | 
			
		||||
} // namespace Core::HID
 | 
			
		||||
@@ -14,7 +18,7 @@ class EmulatedController;
 | 
			
		||||
namespace Service::IRS {
 | 
			
		||||
class ImageTransferProcessor final : public ProcessorBase {
 | 
			
		||||
public:
 | 
			
		||||
    explicit ImageTransferProcessor(Core::HID::HIDCore& hid_core_,
 | 
			
		||||
    explicit ImageTransferProcessor(Core::System& system_,
 | 
			
		||||
                                    Core::IrSensor::DeviceFormat& device_format,
 | 
			
		||||
                                    std::size_t npad_index);
 | 
			
		||||
    ~ImageTransferProcessor() override;
 | 
			
		||||
@@ -33,7 +37,7 @@ public:
 | 
			
		||||
    void SetConfig(Core::IrSensor::PackedImageTransferProcessorExConfig config);
 | 
			
		||||
 | 
			
		||||
    // Transfer memory where the image data will be stored
 | 
			
		||||
    void SetTransferMemoryPointer(u8* t_mem);
 | 
			
		||||
    void SetTransferMemoryAddress(VAddr t_mem);
 | 
			
		||||
 | 
			
		||||
    Core::IrSensor::ImageTransferProcessorState GetState(std::vector<u8>& data) const;
 | 
			
		||||
 | 
			
		||||
@@ -67,7 +71,7 @@ private:
 | 
			
		||||
    Core::HID::EmulatedController* npad_device;
 | 
			
		||||
    int callback_key{};
 | 
			
		||||
 | 
			
		||||
    u8* transfer_memory = nullptr;
 | 
			
		||||
    bool is_transfer_memory_set = false;
 | 
			
		||||
    Core::System& system;
 | 
			
		||||
    VAddr transfer_memory{};
 | 
			
		||||
};
 | 
			
		||||
} // namespace Service::IRS
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user