mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-04 00:49:02 -06:00 
			
		
		
		
	service: irs: Split processors and implement ImageTransferProcessor
This commit is contained in:
		@@ -478,6 +478,20 @@ add_library(core STATIC
 | 
				
			|||||||
    hle/service/hid/hidbus/starlink.h
 | 
					    hle/service/hid/hidbus/starlink.h
 | 
				
			||||||
    hle/service/hid/hidbus/stubbed.cpp
 | 
					    hle/service/hid/hidbus/stubbed.cpp
 | 
				
			||||||
    hle/service/hid/hidbus/stubbed.h
 | 
					    hle/service/hid/hidbus/stubbed.h
 | 
				
			||||||
 | 
					    hle/service/hid/irsensor/clustering_processor.cpp
 | 
				
			||||||
 | 
					    hle/service/hid/irsensor/clustering_processor.h
 | 
				
			||||||
 | 
					    hle/service/hid/irsensor/image_transfer_processor.cpp
 | 
				
			||||||
 | 
					    hle/service/hid/irsensor/image_transfer_processor.h
 | 
				
			||||||
 | 
					    hle/service/hid/irsensor/ir_led_processor.cpp
 | 
				
			||||||
 | 
					    hle/service/hid/irsensor/ir_led_processor.h
 | 
				
			||||||
 | 
					    hle/service/hid/irsensor/moment_processor.cpp
 | 
				
			||||||
 | 
					    hle/service/hid/irsensor/moment_processor.h
 | 
				
			||||||
 | 
					    hle/service/hid/irsensor/pointing_processor.cpp
 | 
				
			||||||
 | 
					    hle/service/hid/irsensor/pointing_processor.h
 | 
				
			||||||
 | 
					    hle/service/hid/irsensor/processor_base.cpp
 | 
				
			||||||
 | 
					    hle/service/hid/irsensor/processor_base.h
 | 
				
			||||||
 | 
					    hle/service/hid/irsensor/tera_plugin_processor.cpp
 | 
				
			||||||
 | 
					    hle/service/hid/irsensor/tera_plugin_processor.h
 | 
				
			||||||
    hle/service/jit/jit_context.cpp
 | 
					    hle/service/jit/jit_context.cpp
 | 
				
			||||||
    hle/service/jit/jit_context.h
 | 
					    hle/service/jit/jit_context.h
 | 
				
			||||||
    hle/service/jit/jit.cpp
 | 
					    hle/service/jit/jit.cpp
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,4 +18,7 @@ constexpr Result NpadIsSameType{ErrorModule::HID, 602};
 | 
				
			|||||||
constexpr Result InvalidNpadId{ErrorModule::HID, 709};
 | 
					constexpr Result InvalidNpadId{ErrorModule::HID, 709};
 | 
				
			||||||
constexpr Result NpadNotConnected{ErrorModule::HID, 710};
 | 
					constexpr Result NpadNotConnected{ErrorModule::HID, 710};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					constexpr ResultCode InvalidProcessorState{ErrorModule::Irsensor, 78};
 | 
				
			||||||
 | 
					constexpr ResultCode InvalidIrCameraHandle{ErrorModule::Irsensor, 204};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace Service::HID
 | 
					} // namespace Service::HID
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,14 +1,26 @@
 | 
				
			|||||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
 | 
					// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
 | 
				
			||||||
// SPDX-License-Identifier: GPL-2.0-or-later
 | 
					// SPDX-License-Identifier: GPL-2.0-or-later
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <algorithm>
 | 
				
			||||||
 | 
					#include <random>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "core/core.h"
 | 
					#include "core/core.h"
 | 
				
			||||||
#include "core/core_timing.h"
 | 
					#include "core/core_timing.h"
 | 
				
			||||||
 | 
					#include "core/hid/emulated_controller.h"
 | 
				
			||||||
 | 
					#include "core/hid/hid_core.h"
 | 
				
			||||||
#include "core/hle/ipc_helpers.h"
 | 
					#include "core/hle/ipc_helpers.h"
 | 
				
			||||||
#include "core/hle/kernel/k_shared_memory.h"
 | 
					#include "core/hle/kernel/k_shared_memory.h"
 | 
				
			||||||
#include "core/hle/kernel/k_transfer_memory.h"
 | 
					#include "core/hle/kernel/k_transfer_memory.h"
 | 
				
			||||||
#include "core/hle/kernel/kernel.h"
 | 
					#include "core/hle/kernel/kernel.h"
 | 
				
			||||||
#include "core/hle/service/hid/errors.h"
 | 
					#include "core/hle/service/hid/errors.h"
 | 
				
			||||||
#include "core/hle/service/hid/irs.h"
 | 
					#include "core/hle/service/hid/irs.h"
 | 
				
			||||||
 | 
					#include "core/hle/service/hid/irsensor/clustering_processor.h"
 | 
				
			||||||
 | 
					#include "core/hle/service/hid/irsensor/image_transfer_processor.h"
 | 
				
			||||||
 | 
					#include "core/hle/service/hid/irsensor/ir_led_processor.h"
 | 
				
			||||||
 | 
					#include "core/hle/service/hid/irsensor/moment_processor.h"
 | 
				
			||||||
 | 
					#include "core/hle/service/hid/irsensor/pointing_processor.h"
 | 
				
			||||||
 | 
					#include "core/hle/service/hid/irsensor/tera_plugin_processor.h"
 | 
				
			||||||
 | 
					#include "core/memory.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Service::HID {
 | 
					namespace Service::HID {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -36,8 +48,13 @@ IRS::IRS(Core::System& system_) : ServiceFramework{system_, "irs"} {
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
    // clang-format on
 | 
					    // clang-format on
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    u8* raw_shared_memory = system.Kernel().GetIrsSharedMem().GetPointer();
 | 
				
			||||||
    RegisterHandlers(functions);
 | 
					    RegisterHandlers(functions);
 | 
				
			||||||
 | 
					    shared_memory = std::construct_at(reinterpret_cast<StatusManager*>(raw_shared_memory));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    npad_device = system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					IRS::~IRS() = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void IRS::ActivateIrsensor(Kernel::HLERequestContext& ctx) {
 | 
					void IRS::ActivateIrsensor(Kernel::HLERequestContext& ctx) {
 | 
				
			||||||
    IPC::RequestParser rp{ctx};
 | 
					    IPC::RequestParser rp{ctx};
 | 
				
			||||||
@@ -75,7 +92,7 @@ void IRS::GetIrsensorSharedMemoryHandle(Kernel::HLERequestContext& ctx) {
 | 
				
			|||||||
void IRS::StopImageProcessor(Kernel::HLERequestContext& ctx) {
 | 
					void IRS::StopImageProcessor(Kernel::HLERequestContext& ctx) {
 | 
				
			||||||
    IPC::RequestParser rp{ctx};
 | 
					    IPC::RequestParser rp{ctx};
 | 
				
			||||||
    struct Parameters {
 | 
					    struct Parameters {
 | 
				
			||||||
        IrCameraHandle camera_handle;
 | 
					        Core::IrSensor::IrCameraHandle camera_handle;
 | 
				
			||||||
        INSERT_PADDING_WORDS_NOINIT(1);
 | 
					        INSERT_PADDING_WORDS_NOINIT(1);
 | 
				
			||||||
        u64 applet_resource_user_id;
 | 
					        u64 applet_resource_user_id;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
@@ -88,17 +105,23 @@ void IRS::StopImageProcessor(Kernel::HLERequestContext& ctx) {
 | 
				
			|||||||
                parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
 | 
					                parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
 | 
				
			||||||
                parameters.applet_resource_user_id);
 | 
					                parameters.applet_resource_user_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    auto result = IsIrCameraHandleValid(parameters.camera_handle);
 | 
				
			||||||
 | 
					    if (result.IsSuccess()) {
 | 
				
			||||||
 | 
					        // TODO: Stop Image processor
 | 
				
			||||||
 | 
					        result = ResultSuccess;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    IPC::ResponseBuilder rb{ctx, 2};
 | 
					    IPC::ResponseBuilder rb{ctx, 2};
 | 
				
			||||||
    rb.Push(ResultSuccess);
 | 
					    rb.Push(result);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void IRS::RunMomentProcessor(Kernel::HLERequestContext& ctx) {
 | 
					void IRS::RunMomentProcessor(Kernel::HLERequestContext& ctx) {
 | 
				
			||||||
    IPC::RequestParser rp{ctx};
 | 
					    IPC::RequestParser rp{ctx};
 | 
				
			||||||
    struct Parameters {
 | 
					    struct Parameters {
 | 
				
			||||||
        IrCameraHandle camera_handle;
 | 
					        Core::IrSensor::IrCameraHandle camera_handle;
 | 
				
			||||||
        INSERT_PADDING_WORDS_NOINIT(1);
 | 
					        INSERT_PADDING_WORDS_NOINIT(1);
 | 
				
			||||||
        u64 applet_resource_user_id;
 | 
					        u64 applet_resource_user_id;
 | 
				
			||||||
        PackedMomentProcessorConfig processor_config;
 | 
					        Core::IrSensor::PackedMomentProcessorConfig processor_config;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    static_assert(sizeof(Parameters) == 0x30, "Parameters has incorrect size.");
 | 
					    static_assert(sizeof(Parameters) == 0x30, "Parameters has incorrect size.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -109,17 +132,26 @@ void IRS::RunMomentProcessor(Kernel::HLERequestContext& ctx) {
 | 
				
			|||||||
                parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
 | 
					                parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
 | 
				
			||||||
                parameters.applet_resource_user_id);
 | 
					                parameters.applet_resource_user_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const auto result = IsIrCameraHandleValid(parameters.camera_handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (result.IsSuccess()) {
 | 
				
			||||||
 | 
					        auto& device = GetIrCameraSharedMemoryDeviceEntry(parameters.camera_handle);
 | 
				
			||||||
 | 
					        MakeProcessor<MomentProcessor>(parameters.camera_handle, device);
 | 
				
			||||||
 | 
					        auto& image_transfer_processor = GetProcessor<MomentProcessor>(parameters.camera_handle);
 | 
				
			||||||
 | 
					        image_transfer_processor.SetConfig(parameters.processor_config);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    IPC::ResponseBuilder rb{ctx, 2};
 | 
					    IPC::ResponseBuilder rb{ctx, 2};
 | 
				
			||||||
    rb.Push(ResultSuccess);
 | 
					    rb.Push(result);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void IRS::RunClusteringProcessor(Kernel::HLERequestContext& ctx) {
 | 
					void IRS::RunClusteringProcessor(Kernel::HLERequestContext& ctx) {
 | 
				
			||||||
    IPC::RequestParser rp{ctx};
 | 
					    IPC::RequestParser rp{ctx};
 | 
				
			||||||
    struct Parameters {
 | 
					    struct Parameters {
 | 
				
			||||||
        IrCameraHandle camera_handle;
 | 
					        Core::IrSensor::IrCameraHandle camera_handle;
 | 
				
			||||||
        INSERT_PADDING_WORDS_NOINIT(1);
 | 
					        INSERT_PADDING_WORDS_NOINIT(1);
 | 
				
			||||||
        u64 applet_resource_user_id;
 | 
					        u64 applet_resource_user_id;
 | 
				
			||||||
        PackedClusteringProcessorConfig processor_config;
 | 
					        Core::IrSensor::PackedClusteringProcessorConfig processor_config;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    static_assert(sizeof(Parameters) == 0x40, "Parameters has incorrect size.");
 | 
					    static_assert(sizeof(Parameters) == 0x40, "Parameters has incorrect size.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -130,17 +162,27 @@ void IRS::RunClusteringProcessor(Kernel::HLERequestContext& ctx) {
 | 
				
			|||||||
                parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
 | 
					                parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
 | 
				
			||||||
                parameters.applet_resource_user_id);
 | 
					                parameters.applet_resource_user_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    auto result = IsIrCameraHandleValid(parameters.camera_handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (result.IsSuccess()) {
 | 
				
			||||||
 | 
					        auto& device = GetIrCameraSharedMemoryDeviceEntry(parameters.camera_handle);
 | 
				
			||||||
 | 
					        MakeProcessor<ClusteringProcessor>(parameters.camera_handle, device);
 | 
				
			||||||
 | 
					        auto& image_transfer_processor =
 | 
				
			||||||
 | 
					            GetProcessor<ClusteringProcessor>(parameters.camera_handle);
 | 
				
			||||||
 | 
					        image_transfer_processor.SetConfig(parameters.processor_config);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    IPC::ResponseBuilder rb{ctx, 2};
 | 
					    IPC::ResponseBuilder rb{ctx, 2};
 | 
				
			||||||
    rb.Push(ResultSuccess);
 | 
					    rb.Push(result);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void IRS::RunImageTransferProcessor(Kernel::HLERequestContext& ctx) {
 | 
					void IRS::RunImageTransferProcessor(Kernel::HLERequestContext& ctx) {
 | 
				
			||||||
    IPC::RequestParser rp{ctx};
 | 
					    IPC::RequestParser rp{ctx};
 | 
				
			||||||
    struct Parameters {
 | 
					    struct Parameters {
 | 
				
			||||||
        IrCameraHandle camera_handle;
 | 
					        Core::IrSensor::IrCameraHandle camera_handle;
 | 
				
			||||||
        INSERT_PADDING_WORDS_NOINIT(1);
 | 
					        INSERT_PADDING_WORDS_NOINIT(1);
 | 
				
			||||||
        u64 applet_resource_user_id;
 | 
					        u64 applet_resource_user_id;
 | 
				
			||||||
        PackedImageTransferProcessorConfig processor_config;
 | 
					        Core::IrSensor::PackedImageTransferProcessorConfig processor_config;
 | 
				
			||||||
        u32 transfer_memory_size;
 | 
					        u32 transfer_memory_size;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    static_assert(sizeof(Parameters) == 0x30, "Parameters has incorrect size.");
 | 
					    static_assert(sizeof(Parameters) == 0x30, "Parameters has incorrect size.");
 | 
				
			||||||
@@ -151,20 +193,42 @@ void IRS::RunImageTransferProcessor(Kernel::HLERequestContext& ctx) {
 | 
				
			|||||||
    auto t_mem =
 | 
					    auto t_mem =
 | 
				
			||||||
        system.CurrentProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(t_mem_handle);
 | 
					        system.CurrentProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(t_mem_handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    LOG_WARNING(Service_IRS,
 | 
					    if (t_mem.IsNull()) {
 | 
				
			||||||
                "(STUBBED) called, npad_type={}, npad_id={}, transfer_memory_size={}, "
 | 
					        LOG_ERROR(Service_HID, "t_mem is a nullptr for handle=0x{:08X}", t_mem_handle);
 | 
				
			||||||
                "applet_resource_user_id={}",
 | 
					        IPC::ResponseBuilder rb{ctx, 2};
 | 
				
			||||||
                parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
 | 
					        rb.Push(ResultUnknown);
 | 
				
			||||||
                parameters.transfer_memory_size, parameters.applet_resource_user_id);
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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={}",
 | 
				
			||||||
 | 
					             parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
 | 
				
			||||||
 | 
					             parameters.transfer_memory_size, t_mem->GetSize(), parameters.applet_resource_user_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const auto result = IsIrCameraHandleValid(parameters.camera_handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (result.IsSuccess()) {
 | 
				
			||||||
 | 
					        auto& device = GetIrCameraSharedMemoryDeviceEntry(parameters.camera_handle);
 | 
				
			||||||
 | 
					        MakeProcessorWithCoreContext<ImageTransferProcessor>(parameters.camera_handle, device);
 | 
				
			||||||
 | 
					        auto& image_transfer_processor =
 | 
				
			||||||
 | 
					            GetProcessor<ImageTransferProcessor>(parameters.camera_handle);
 | 
				
			||||||
 | 
					        image_transfer_processor.SetConfig(parameters.processor_config);
 | 
				
			||||||
 | 
					        image_transfer_processor.SetTransferMemoryPointer(transfer_memory);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    IPC::ResponseBuilder rb{ctx, 2};
 | 
					    IPC::ResponseBuilder rb{ctx, 2};
 | 
				
			||||||
    rb.Push(ResultSuccess);
 | 
					    rb.Push(result);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void IRS::GetImageTransferProcessorState(Kernel::HLERequestContext& ctx) {
 | 
					void IRS::GetImageTransferProcessorState(Kernel::HLERequestContext& ctx) {
 | 
				
			||||||
    IPC::RequestParser rp{ctx};
 | 
					    IPC::RequestParser rp{ctx};
 | 
				
			||||||
    struct Parameters {
 | 
					    struct Parameters {
 | 
				
			||||||
        IrCameraHandle camera_handle;
 | 
					        Core::IrSensor::IrCameraHandle camera_handle;
 | 
				
			||||||
        INSERT_PADDING_WORDS_NOINIT(1);
 | 
					        INSERT_PADDING_WORDS_NOINIT(1);
 | 
				
			||||||
        u64 applet_resource_user_id;
 | 
					        u64 applet_resource_user_id;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
@@ -172,21 +236,40 @@ void IRS::GetImageTransferProcessorState(Kernel::HLERequestContext& ctx) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    const auto parameters{rp.PopRaw<Parameters>()};
 | 
					    const auto parameters{rp.PopRaw<Parameters>()};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    LOG_WARNING(Service_IRS,
 | 
					    LOG_DEBUG(Service_IRS, "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
 | 
				
			||||||
                "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
 | 
					              parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
 | 
				
			||||||
                parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
 | 
					              parameters.applet_resource_user_id);
 | 
				
			||||||
                parameters.applet_resource_user_id);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    IPC::ResponseBuilder rb{ctx, 5};
 | 
					    const auto result = IsIrCameraHandleValid(parameters.camera_handle);
 | 
				
			||||||
 | 
					    if (result.IsError()) {
 | 
				
			||||||
 | 
					        IPC::ResponseBuilder rb{ctx, 2};
 | 
				
			||||||
 | 
					        rb.Push(result);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const auto& device = GetIrCameraSharedMemoryDeviceEntry(parameters.camera_handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (device.mode != Core::IrSensor::IrSensorMode::ImageTransferProcessor) {
 | 
				
			||||||
 | 
					        IPC::ResponseBuilder rb{ctx, 2};
 | 
				
			||||||
 | 
					        rb.Push(InvalidProcessorState);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::vector<u8> data{};
 | 
				
			||||||
 | 
					    const auto& image_transfer_processor =
 | 
				
			||||||
 | 
					        GetProcessor<ImageTransferProcessor>(parameters.camera_handle);
 | 
				
			||||||
 | 
					    const auto& state = image_transfer_processor.GetState(data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ctx.WriteBuffer(data);
 | 
				
			||||||
 | 
					    IPC::ResponseBuilder rb{ctx, 6};
 | 
				
			||||||
    rb.Push(ResultSuccess);
 | 
					    rb.Push(ResultSuccess);
 | 
				
			||||||
    rb.PushRaw<u64>(system.CoreTiming().GetCPUTicks());
 | 
					    rb.PushRaw(state);
 | 
				
			||||||
    rb.PushRaw<u32>(0);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void IRS::RunTeraPluginProcessor(Kernel::HLERequestContext& ctx) {
 | 
					void IRS::RunTeraPluginProcessor(Kernel::HLERequestContext& ctx) {
 | 
				
			||||||
    IPC::RequestParser rp{ctx};
 | 
					    IPC::RequestParser rp{ctx};
 | 
				
			||||||
    const auto camera_handle{rp.PopRaw<IrCameraHandle>()};
 | 
					    const auto camera_handle{rp.PopRaw<Core::IrSensor::IrCameraHandle>()};
 | 
				
			||||||
    const auto processor_config{rp.PopRaw<PackedTeraPluginProcessorConfig>()};
 | 
					    const auto processor_config{rp.PopRaw<Core::IrSensor::PackedTeraPluginProcessorConfig>()};
 | 
				
			||||||
    const auto applet_resource_user_id{rp.Pop<u64>()};
 | 
					    const auto applet_resource_user_id{rp.Pop<u64>()};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    LOG_WARNING(Service_IRS,
 | 
					    LOG_WARNING(Service_IRS,
 | 
				
			||||||
@@ -196,8 +279,17 @@ void IRS::RunTeraPluginProcessor(Kernel::HLERequestContext& ctx) {
 | 
				
			|||||||
                processor_config.required_mcu_version.major,
 | 
					                processor_config.required_mcu_version.major,
 | 
				
			||||||
                processor_config.required_mcu_version.minor, applet_resource_user_id);
 | 
					                processor_config.required_mcu_version.minor, applet_resource_user_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const auto result = IsIrCameraHandleValid(camera_handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (result.IsSuccess()) {
 | 
				
			||||||
 | 
					        auto& device = GetIrCameraSharedMemoryDeviceEntry(camera_handle);
 | 
				
			||||||
 | 
					        MakeProcessor<TeraPluginProcessor>(camera_handle, device);
 | 
				
			||||||
 | 
					        auto& image_transfer_processor = GetProcessor<TeraPluginProcessor>(camera_handle);
 | 
				
			||||||
 | 
					        image_transfer_processor.SetConfig(processor_config);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    IPC::ResponseBuilder rb{ctx, 2};
 | 
					    IPC::ResponseBuilder rb{ctx, 2};
 | 
				
			||||||
    rb.Push(ResultSuccess);
 | 
					    rb.Push(result);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void IRS::GetNpadIrCameraHandle(Kernel::HLERequestContext& ctx) {
 | 
					void IRS::GetNpadIrCameraHandle(Kernel::HLERequestContext& ctx) {
 | 
				
			||||||
@@ -211,13 +303,13 @@ void IRS::GetNpadIrCameraHandle(Kernel::HLERequestContext& ctx) {
 | 
				
			|||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    IrCameraHandle camera_handle{
 | 
					    Core::IrSensor::IrCameraHandle camera_handle{
 | 
				
			||||||
        .npad_id = static_cast<u8>(NpadIdTypeToIndex(npad_id)),
 | 
					        .npad_id = static_cast<u8>(NpadIdTypeToIndex(npad_id)),
 | 
				
			||||||
        .npad_type = Core::HID::NpadStyleIndex::None,
 | 
					        .npad_type = Core::HID::NpadStyleIndex::None,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    LOG_WARNING(Service_IRS, "(STUBBED) called, npad_id={}, camera_npad_id={}, camera_npad_type={}",
 | 
					    LOG_INFO(Service_IRS, "called, npad_id={}, camera_npad_id={}, camera_npad_type={}", npad_id,
 | 
				
			||||||
                npad_id, camera_handle.npad_id, camera_handle.npad_type);
 | 
					             camera_handle.npad_id, camera_handle.npad_type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    IPC::ResponseBuilder rb{ctx, 3};
 | 
					    IPC::ResponseBuilder rb{ctx, 3};
 | 
				
			||||||
    rb.Push(ResultSuccess);
 | 
					    rb.Push(ResultSuccess);
 | 
				
			||||||
@@ -226,8 +318,8 @@ void IRS::GetNpadIrCameraHandle(Kernel::HLERequestContext& ctx) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void IRS::RunPointingProcessor(Kernel::HLERequestContext& ctx) {
 | 
					void IRS::RunPointingProcessor(Kernel::HLERequestContext& ctx) {
 | 
				
			||||||
    IPC::RequestParser rp{ctx};
 | 
					    IPC::RequestParser rp{ctx};
 | 
				
			||||||
    const auto camera_handle{rp.PopRaw<IrCameraHandle>()};
 | 
					    const auto camera_handle{rp.PopRaw<Core::IrSensor::IrCameraHandle>()};
 | 
				
			||||||
    const auto processor_config{rp.PopRaw<PackedPointingProcessorConfig>()};
 | 
					    const auto processor_config{rp.PopRaw<Core::IrSensor::PackedPointingProcessorConfig>()};
 | 
				
			||||||
    const auto applet_resource_user_id{rp.Pop<u64>()};
 | 
					    const auto applet_resource_user_id{rp.Pop<u64>()};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    LOG_WARNING(
 | 
					    LOG_WARNING(
 | 
				
			||||||
@@ -236,14 +328,23 @@ void IRS::RunPointingProcessor(Kernel::HLERequestContext& ctx) {
 | 
				
			|||||||
        camera_handle.npad_type, camera_handle.npad_id, processor_config.required_mcu_version.major,
 | 
					        camera_handle.npad_type, camera_handle.npad_id, processor_config.required_mcu_version.major,
 | 
				
			||||||
        processor_config.required_mcu_version.minor, applet_resource_user_id);
 | 
					        processor_config.required_mcu_version.minor, applet_resource_user_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    auto result = IsIrCameraHandleValid(camera_handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (result.IsSuccess()) {
 | 
				
			||||||
 | 
					        auto& device = GetIrCameraSharedMemoryDeviceEntry(camera_handle);
 | 
				
			||||||
 | 
					        MakeProcessor<PointingProcessor>(camera_handle, device);
 | 
				
			||||||
 | 
					        auto& image_transfer_processor = GetProcessor<PointingProcessor>(camera_handle);
 | 
				
			||||||
 | 
					        image_transfer_processor.SetConfig(processor_config);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    IPC::ResponseBuilder rb{ctx, 2};
 | 
					    IPC::ResponseBuilder rb{ctx, 2};
 | 
				
			||||||
    rb.Push(ResultSuccess);
 | 
					    rb.Push(result);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void IRS::SuspendImageProcessor(Kernel::HLERequestContext& ctx) {
 | 
					void IRS::SuspendImageProcessor(Kernel::HLERequestContext& ctx) {
 | 
				
			||||||
    IPC::RequestParser rp{ctx};
 | 
					    IPC::RequestParser rp{ctx};
 | 
				
			||||||
    struct Parameters {
 | 
					    struct Parameters {
 | 
				
			||||||
        IrCameraHandle camera_handle;
 | 
					        Core::IrSensor::IrCameraHandle camera_handle;
 | 
				
			||||||
        INSERT_PADDING_WORDS_NOINIT(1);
 | 
					        INSERT_PADDING_WORDS_NOINIT(1);
 | 
				
			||||||
        u64 applet_resource_user_id;
 | 
					        u64 applet_resource_user_id;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
@@ -256,14 +357,20 @@ void IRS::SuspendImageProcessor(Kernel::HLERequestContext& ctx) {
 | 
				
			|||||||
                parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
 | 
					                parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
 | 
				
			||||||
                parameters.applet_resource_user_id);
 | 
					                parameters.applet_resource_user_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    auto result = IsIrCameraHandleValid(parameters.camera_handle);
 | 
				
			||||||
 | 
					    if (result.IsSuccess()) {
 | 
				
			||||||
 | 
					        // TODO: Suspend image processor
 | 
				
			||||||
 | 
					        result = ResultSuccess;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    IPC::ResponseBuilder rb{ctx, 2};
 | 
					    IPC::ResponseBuilder rb{ctx, 2};
 | 
				
			||||||
    rb.Push(ResultSuccess);
 | 
					    rb.Push(result);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void IRS::CheckFirmwareVersion(Kernel::HLERequestContext& ctx) {
 | 
					void IRS::CheckFirmwareVersion(Kernel::HLERequestContext& ctx) {
 | 
				
			||||||
    IPC::RequestParser rp{ctx};
 | 
					    IPC::RequestParser rp{ctx};
 | 
				
			||||||
    const auto camera_handle{rp.PopRaw<IrCameraHandle>()};
 | 
					    const auto camera_handle{rp.PopRaw<Core::IrSensor::IrCameraHandle>()};
 | 
				
			||||||
    const auto mcu_version{rp.PopRaw<PackedMcuVersion>()};
 | 
					    const auto mcu_version{rp.PopRaw<Core::IrSensor::PackedMcuVersion>()};
 | 
				
			||||||
    const auto applet_resource_user_id{rp.Pop<u64>()};
 | 
					    const auto applet_resource_user_id{rp.Pop<u64>()};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    LOG_WARNING(
 | 
					    LOG_WARNING(
 | 
				
			||||||
@@ -272,37 +379,45 @@ void IRS::CheckFirmwareVersion(Kernel::HLERequestContext& ctx) {
 | 
				
			|||||||
        camera_handle.npad_type, camera_handle.npad_id, applet_resource_user_id, mcu_version.major,
 | 
					        camera_handle.npad_type, camera_handle.npad_id, applet_resource_user_id, mcu_version.major,
 | 
				
			||||||
        mcu_version.minor);
 | 
					        mcu_version.minor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    auto result = IsIrCameraHandleValid(camera_handle);
 | 
				
			||||||
 | 
					    if (result.IsSuccess()) {
 | 
				
			||||||
 | 
					        // TODO: Check firmware version
 | 
				
			||||||
 | 
					        result = ResultSuccess;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    IPC::ResponseBuilder rb{ctx, 2};
 | 
					    IPC::ResponseBuilder rb{ctx, 2};
 | 
				
			||||||
    rb.Push(ResultSuccess);
 | 
					    rb.Push(result);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void IRS::SetFunctionLevel(Kernel::HLERequestContext& ctx) {
 | 
					void IRS::SetFunctionLevel(Kernel::HLERequestContext& ctx) {
 | 
				
			||||||
    IPC::RequestParser rp{ctx};
 | 
					    IPC::RequestParser rp{ctx};
 | 
				
			||||||
    struct Parameters {
 | 
					    const auto camera_handle{rp.PopRaw<Core::IrSensor::IrCameraHandle>()};
 | 
				
			||||||
        IrCameraHandle camera_handle;
 | 
					    const auto function_level{rp.PopRaw<Core::IrSensor::PackedFunctionLevel>()};
 | 
				
			||||||
        PackedFunctionLevel function_level;
 | 
					    const auto applet_resource_user_id{rp.Pop<u64>()};
 | 
				
			||||||
        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={}, function_level={}, applet_resource_user_id={}",
 | 
				
			||||||
 | 
					        camera_handle.npad_type, camera_handle.npad_id, function_level.function_level,
 | 
				
			||||||
 | 
					        applet_resource_user_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    LOG_WARNING(Service_IRS,
 | 
					    auto result = IsIrCameraHandleValid(camera_handle);
 | 
				
			||||||
                "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
 | 
					    if (result.IsSuccess()) {
 | 
				
			||||||
                parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
 | 
					        // TODO: Set Function level
 | 
				
			||||||
                parameters.applet_resource_user_id);
 | 
					        result = ResultSuccess;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    IPC::ResponseBuilder rb{ctx, 2};
 | 
					    IPC::ResponseBuilder rb{ctx, 2};
 | 
				
			||||||
    rb.Push(ResultSuccess);
 | 
					    rb.Push(result);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void IRS::RunImageTransferExProcessor(Kernel::HLERequestContext& ctx) {
 | 
					void IRS::RunImageTransferExProcessor(Kernel::HLERequestContext& ctx) {
 | 
				
			||||||
    IPC::RequestParser rp{ctx};
 | 
					    IPC::RequestParser rp{ctx};
 | 
				
			||||||
    struct Parameters {
 | 
					    struct Parameters {
 | 
				
			||||||
        IrCameraHandle camera_handle;
 | 
					        Core::IrSensor::IrCameraHandle camera_handle;
 | 
				
			||||||
        INSERT_PADDING_WORDS_NOINIT(1);
 | 
					        INSERT_PADDING_WORDS_NOINIT(1);
 | 
				
			||||||
        u64 applet_resource_user_id;
 | 
					        u64 applet_resource_user_id;
 | 
				
			||||||
        PackedImageTransferProcessorExConfig processor_config;
 | 
					        Core::IrSensor::PackedImageTransferProcessorExConfig processor_config;
 | 
				
			||||||
        u64 transfer_memory_size;
 | 
					        u64 transfer_memory_size;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    static_assert(sizeof(Parameters) == 0x38, "Parameters has incorrect size.");
 | 
					    static_assert(sizeof(Parameters) == 0x38, "Parameters has incorrect size.");
 | 
				
			||||||
@@ -313,20 +428,33 @@ void IRS::RunImageTransferExProcessor(Kernel::HLERequestContext& ctx) {
 | 
				
			|||||||
    auto t_mem =
 | 
					    auto t_mem =
 | 
				
			||||||
        system.CurrentProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(t_mem_handle);
 | 
					        system.CurrentProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(t_mem_handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    LOG_WARNING(Service_IRS,
 | 
					    u8* transfer_memory = system.Memory().GetPointer(t_mem->GetSourceAddress());
 | 
				
			||||||
                "(STUBBED) called, npad_type={}, npad_id={}, transfer_memory_size={}, "
 | 
					
 | 
				
			||||||
                "applet_resource_user_id={}",
 | 
					    LOG_INFO(Service_IRS,
 | 
				
			||||||
                parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
 | 
					             "called, npad_type={}, npad_id={}, transfer_memory_size={}, "
 | 
				
			||||||
                parameters.transfer_memory_size, parameters.applet_resource_user_id);
 | 
					             "applet_resource_user_id={}",
 | 
				
			||||||
 | 
					             parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
 | 
				
			||||||
 | 
					             parameters.transfer_memory_size, parameters.applet_resource_user_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    auto result = IsIrCameraHandleValid(parameters.camera_handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (result.IsSuccess()) {
 | 
				
			||||||
 | 
					        auto& device = GetIrCameraSharedMemoryDeviceEntry(parameters.camera_handle);
 | 
				
			||||||
 | 
					        MakeProcessorWithCoreContext<ImageTransferProcessor>(parameters.camera_handle, device);
 | 
				
			||||||
 | 
					        auto& image_transfer_processor =
 | 
				
			||||||
 | 
					            GetProcessor<ImageTransferProcessor>(parameters.camera_handle);
 | 
				
			||||||
 | 
					        image_transfer_processor.SetConfig(parameters.processor_config);
 | 
				
			||||||
 | 
					        image_transfer_processor.SetTransferMemoryPointer(transfer_memory);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    IPC::ResponseBuilder rb{ctx, 2};
 | 
					    IPC::ResponseBuilder rb{ctx, 2};
 | 
				
			||||||
    rb.Push(ResultSuccess);
 | 
					    rb.Push(result);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void IRS::RunIrLedProcessor(Kernel::HLERequestContext& ctx) {
 | 
					void IRS::RunIrLedProcessor(Kernel::HLERequestContext& ctx) {
 | 
				
			||||||
    IPC::RequestParser rp{ctx};
 | 
					    IPC::RequestParser rp{ctx};
 | 
				
			||||||
    const auto camera_handle{rp.PopRaw<IrCameraHandle>()};
 | 
					    const auto camera_handle{rp.PopRaw<Core::IrSensor::IrCameraHandle>()};
 | 
				
			||||||
    const auto processor_config{rp.PopRaw<PackedIrLedProcessorConfig>()};
 | 
					    const auto processor_config{rp.PopRaw<Core::IrSensor::PackedIrLedProcessorConfig>()};
 | 
				
			||||||
    const auto applet_resource_user_id{rp.Pop<u64>()};
 | 
					    const auto applet_resource_user_id{rp.Pop<u64>()};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    LOG_WARNING(Service_IRS,
 | 
					    LOG_WARNING(Service_IRS,
 | 
				
			||||||
@@ -336,14 +464,23 @@ void IRS::RunIrLedProcessor(Kernel::HLERequestContext& ctx) {
 | 
				
			|||||||
                processor_config.required_mcu_version.major,
 | 
					                processor_config.required_mcu_version.major,
 | 
				
			||||||
                processor_config.required_mcu_version.minor, applet_resource_user_id);
 | 
					                processor_config.required_mcu_version.minor, applet_resource_user_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    auto result = IsIrCameraHandleValid(camera_handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (result.IsSuccess()) {
 | 
				
			||||||
 | 
					        auto& device = GetIrCameraSharedMemoryDeviceEntry(camera_handle);
 | 
				
			||||||
 | 
					        MakeProcessor<IrLedProcessor>(camera_handle, device);
 | 
				
			||||||
 | 
					        auto& image_transfer_processor = GetProcessor<IrLedProcessor>(camera_handle);
 | 
				
			||||||
 | 
					        image_transfer_processor.SetConfig(processor_config);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    IPC::ResponseBuilder rb{ctx, 2};
 | 
					    IPC::ResponseBuilder rb{ctx, 2};
 | 
				
			||||||
    rb.Push(ResultSuccess);
 | 
					    rb.Push(result);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void IRS::StopImageProcessorAsync(Kernel::HLERequestContext& ctx) {
 | 
					void IRS::StopImageProcessorAsync(Kernel::HLERequestContext& ctx) {
 | 
				
			||||||
    IPC::RequestParser rp{ctx};
 | 
					    IPC::RequestParser rp{ctx};
 | 
				
			||||||
    struct Parameters {
 | 
					    struct Parameters {
 | 
				
			||||||
        IrCameraHandle camera_handle;
 | 
					        Core::IrSensor::IrCameraHandle camera_handle;
 | 
				
			||||||
        INSERT_PADDING_WORDS_NOINIT(1);
 | 
					        INSERT_PADDING_WORDS_NOINIT(1);
 | 
				
			||||||
        u64 applet_resource_user_id;
 | 
					        u64 applet_resource_user_id;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
@@ -356,14 +493,20 @@ void IRS::StopImageProcessorAsync(Kernel::HLERequestContext& ctx) {
 | 
				
			|||||||
                parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
 | 
					                parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
 | 
				
			||||||
                parameters.applet_resource_user_id);
 | 
					                parameters.applet_resource_user_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    auto result = IsIrCameraHandleValid(parameters.camera_handle);
 | 
				
			||||||
 | 
					    if (result.IsSuccess()) {
 | 
				
			||||||
 | 
					        // TODO: Stop image processor async
 | 
				
			||||||
 | 
					        result = ResultSuccess;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    IPC::ResponseBuilder rb{ctx, 2};
 | 
					    IPC::ResponseBuilder rb{ctx, 2};
 | 
				
			||||||
    rb.Push(ResultSuccess);
 | 
					    rb.Push(result);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void IRS::ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx) {
 | 
					void IRS::ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx) {
 | 
				
			||||||
    IPC::RequestParser rp{ctx};
 | 
					    IPC::RequestParser rp{ctx};
 | 
				
			||||||
    struct Parameters {
 | 
					    struct Parameters {
 | 
				
			||||||
        PackedFunctionLevel function_level;
 | 
					        Core::IrSensor::PackedFunctionLevel function_level;
 | 
				
			||||||
        INSERT_PADDING_WORDS_NOINIT(1);
 | 
					        INSERT_PADDING_WORDS_NOINIT(1);
 | 
				
			||||||
        u64 applet_resource_user_id;
 | 
					        u64 applet_resource_user_id;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
@@ -378,7 +521,22 @@ void IRS::ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx) {
 | 
				
			|||||||
    rb.Push(ResultSuccess);
 | 
					    rb.Push(ResultSuccess);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
IRS::~IRS() = default;
 | 
					ResultCode IRS::IsIrCameraHandleValid(const Core::IrSensor::IrCameraHandle& camera_handle) const {
 | 
				
			||||||
 | 
					    if (camera_handle.npad_id >
 | 
				
			||||||
 | 
					        static_cast<u8>(NpadIdTypeToIndex(Core::HID::NpadIdType::Handheld))) {
 | 
				
			||||||
 | 
					        return InvalidIrCameraHandle;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (camera_handle.npad_type != Core::HID::NpadStyleIndex::None) {
 | 
				
			||||||
 | 
					        return InvalidIrCameraHandle;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return ResultSuccess;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Core::IrSensor::DeviceFormat& IRS::GetIrCameraSharedMemoryDeviceEntry(
 | 
				
			||||||
 | 
					    const Core::IrSensor::IrCameraHandle& camera_handle) {
 | 
				
			||||||
 | 
					    ASSERT_MSG(sizeof(StatusManager::device) > camera_handle.npad_id, "invalid npad_id");
 | 
				
			||||||
 | 
					    return shared_memory->device[camera_handle.npad_id];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
IRS_SYS::IRS_SYS(Core::System& system_) : ServiceFramework{system_, "irs:sys"} {
 | 
					IRS_SYS::IRS_SYS(Core::System& system_) : ServiceFramework{system_, "irs:sys"} {
 | 
				
			||||||
    // clang-format off
 | 
					    // clang-format off
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,12 +4,18 @@
 | 
				
			|||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "core/hid/hid_types.h"
 | 
					#include "core/hid/hid_types.h"
 | 
				
			||||||
 | 
					#include "core/hid/irs_types.h"
 | 
				
			||||||
 | 
					#include "core/hle/service/hid/irsensor/processor_base.h"
 | 
				
			||||||
#include "core/hle/service/service.h"
 | 
					#include "core/hle/service/service.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Core {
 | 
					namespace Core {
 | 
				
			||||||
class System;
 | 
					class System;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Core::HID {
 | 
				
			||||||
 | 
					class EmulatedController;
 | 
				
			||||||
 | 
					} // namespace Core::HID
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Service::HID {
 | 
					namespace Service::HID {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class IRS final : public ServiceFramework<IRS> {
 | 
					class IRS final : public ServiceFramework<IRS> {
 | 
				
			||||||
@@ -18,234 +24,19 @@ public:
 | 
				
			|||||||
    ~IRS() override;
 | 
					    ~IRS() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
    // This is nn::irsensor::IrCameraStatus
 | 
					    // This is nn::irsensor::detail::AruidFormat
 | 
				
			||||||
    enum IrCameraStatus : u32 {
 | 
					    struct AruidFormat {
 | 
				
			||||||
        Available,
 | 
					        u64 sensor_aruid;
 | 
				
			||||||
        Unsupported,
 | 
					        u64 sensor_aruid_status;
 | 
				
			||||||
        Unconnected,
 | 
					 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					    static_assert(sizeof(AruidFormat) == 0x10, "AruidFormat is an invalid size");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // This is nn::irsensor::IrCameraInternalStatus
 | 
					    // This is nn::irsensor::detail::StatusManager
 | 
				
			||||||
    enum IrCameraInternalStatus : u32 {
 | 
					    struct StatusManager {
 | 
				
			||||||
        Stopped,
 | 
					        std::array<Core::IrSensor::DeviceFormat, 9> device;
 | 
				
			||||||
        FirmwareUpdateNeeded,
 | 
					        std::array<AruidFormat, 5> aruid;
 | 
				
			||||||
        Unkown2,
 | 
					 | 
				
			||||||
        Unkown3,
 | 
					 | 
				
			||||||
        Unkown4,
 | 
					 | 
				
			||||||
        FirmwareVersionRequested,
 | 
					 | 
				
			||||||
        FirmwareVersionIsInvalid,
 | 
					 | 
				
			||||||
        Ready,
 | 
					 | 
				
			||||||
        Setting,
 | 
					 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					    static_assert(sizeof(StatusManager) == 0x8000, "StatusManager is an invalid size");
 | 
				
			||||||
    // 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 ActivateIrsensor(Kernel::HLERequestContext& ctx);
 | 
				
			||||||
    void DeactivateIrsensor(Kernel::HLERequestContext& ctx);
 | 
					    void DeactivateIrsensor(Kernel::HLERequestContext& ctx);
 | 
				
			||||||
@@ -265,6 +56,56 @@ private:
 | 
				
			|||||||
    void RunIrLedProcessor(Kernel::HLERequestContext& ctx);
 | 
					    void RunIrLedProcessor(Kernel::HLERequestContext& ctx);
 | 
				
			||||||
    void StopImageProcessorAsync(Kernel::HLERequestContext& ctx);
 | 
					    void StopImageProcessorAsync(Kernel::HLERequestContext& ctx);
 | 
				
			||||||
    void ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx);
 | 
					    void ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ResultCode IsIrCameraHandleValid(const Core::IrSensor::IrCameraHandle& camera_handle) const;
 | 
				
			||||||
 | 
					    Core::IrSensor::DeviceFormat& GetIrCameraSharedMemoryDeviceEntry(
 | 
				
			||||||
 | 
					        const Core::IrSensor::IrCameraHandle& camera_handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template <typename T>
 | 
				
			||||||
 | 
					    void MakeProcessor(const Core::IrSensor::IrCameraHandle& handle,
 | 
				
			||||||
 | 
					                       Core::IrSensor::DeviceFormat& device_state) {
 | 
				
			||||||
 | 
					        const auto index = static_cast<std::size_t>(handle.npad_id);
 | 
				
			||||||
 | 
					        if (index > sizeof(processors)) {
 | 
				
			||||||
 | 
					            LOG_CRITICAL(Service_IRS, "Invalid index {}", index);
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        processors[index] = std::make_unique<T>(device_state);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template <typename T>
 | 
				
			||||||
 | 
					    void MakeProcessorWithCoreContext(const Core::IrSensor::IrCameraHandle& handle,
 | 
				
			||||||
 | 
					                                      Core::IrSensor::DeviceFormat& device_state) {
 | 
				
			||||||
 | 
					        const auto index = static_cast<std::size_t>(handle.npad_id);
 | 
				
			||||||
 | 
					        if (index > sizeof(processors)) {
 | 
				
			||||||
 | 
					            LOG_CRITICAL(Service_IRS, "Invalid index {}", index);
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        processors[index] = std::make_unique<T>(system.HIDCore(), device_state, index);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template <typename T>
 | 
				
			||||||
 | 
					    T& GetProcessor(const Core::IrSensor::IrCameraHandle& handle) {
 | 
				
			||||||
 | 
					        const auto index = static_cast<std::size_t>(handle.npad_id);
 | 
				
			||||||
 | 
					        if (index > sizeof(processors)) {
 | 
				
			||||||
 | 
					            LOG_CRITICAL(Service_IRS, "Invalid index {}", index);
 | 
				
			||||||
 | 
					            return static_cast<T&>(*processors[0]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return static_cast<T&>(*processors[index]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template <typename T>
 | 
				
			||||||
 | 
					    const T& GetProcessor(const Core::IrSensor::IrCameraHandle& handle) const {
 | 
				
			||||||
 | 
					        const auto index = static_cast<std::size_t>(handle.npad_id);
 | 
				
			||||||
 | 
					        if (index > sizeof(processors)) {
 | 
				
			||||||
 | 
					            LOG_CRITICAL(Service_IRS, "Invalid index {}", index);
 | 
				
			||||||
 | 
					            return static_cast<T&>(*processors[0]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return static_cast<T&>(*processors[index]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Core::HID::EmulatedController* npad_device = nullptr;
 | 
				
			||||||
 | 
					    StatusManager* shared_memory = nullptr;
 | 
				
			||||||
 | 
					    std::array<std::unique_ptr<ProcessorBase>, 9> processors{};
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class IRS_SYS final : public ServiceFramework<IRS_SYS> {
 | 
					class IRS_SYS final : public ServiceFramework<IRS_SYS> {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										36
									
								
								src/core/hle/service/hid/irsensor/clustering_processor.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/core/hle/service/hid/irsensor/clustering_processor.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: GPL-3.0-or-later
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "core/hle/service/hid/irsensor/clustering_processor.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Service::HID {
 | 
				
			||||||
 | 
					ClusteringProcessor::ClusteringProcessor(Core::IrSensor::DeviceFormat& device_format)
 | 
				
			||||||
 | 
					    : device(device_format) {
 | 
				
			||||||
 | 
					    device.mode = Core::IrSensor::IrSensorMode::ClusteringProcessor;
 | 
				
			||||||
 | 
					    device.camera_status = Core::IrSensor::IrCameraStatus::Unconnected;
 | 
				
			||||||
 | 
					    device.camera_internal_status = Core::IrSensor::IrCameraInternalStatus::Stopped;
 | 
				
			||||||
 | 
					    device.state.start = 0;
 | 
				
			||||||
 | 
					    device.state.count = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ClusteringProcessor::~ClusteringProcessor() = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ClusteringProcessor::StartProcessor() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ClusteringProcessor::SuspendProcessor() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ClusteringProcessor::StopProcessor() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ClusteringProcessor::SetConfig(Core::IrSensor::PackedClusteringProcessorConfig config) {
 | 
				
			||||||
 | 
					    current_config.camera_config.exposure_time = config.camera_config.exposure_time;
 | 
				
			||||||
 | 
					    current_config.camera_config.gain = config.camera_config.gain;
 | 
				
			||||||
 | 
					    current_config.camera_config.is_negative_used = config.camera_config.is_negative_used;
 | 
				
			||||||
 | 
					    current_config.camera_config.light_target =
 | 
				
			||||||
 | 
					        static_cast<Core::IrSensor::CameraLightTarget>(config.camera_config.light_target);
 | 
				
			||||||
 | 
					    current_config.pixel_count_min = config.pixel_count_min;
 | 
				
			||||||
 | 
					    current_config.pixel_count_max = config.pixel_count_max;
 | 
				
			||||||
 | 
					    current_config.is_external_light_filter_enabled = config.is_external_light_filter_enabled;
 | 
				
			||||||
 | 
					    current_config.object_intensity_min = config.object_intensity_min;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace Service::HID
 | 
				
			||||||
							
								
								
									
										74
									
								
								src/core/hle/service/hid/irsensor/clustering_processor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								src/core/hle/service/hid/irsensor/clustering_processor.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,74 @@
 | 
				
			|||||||
 | 
					// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: GPL-3.0-or-later
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "common/common_types.h"
 | 
				
			||||||
 | 
					#include "core/hid/irs_types.h"
 | 
				
			||||||
 | 
					#include "core/hle/service/hid/irsensor/processor_base.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Service::HID {
 | 
				
			||||||
 | 
					class ClusteringProcessor final : public ProcessorBase {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    explicit ClusteringProcessor(Core::IrSensor::DeviceFormat& device_format);
 | 
				
			||||||
 | 
					    ~ClusteringProcessor() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Called when the processor is initialized
 | 
				
			||||||
 | 
					    void StartProcessor() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Called when the processor is suspended
 | 
				
			||||||
 | 
					    void SuspendProcessor() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Called when the processor is stopped
 | 
				
			||||||
 | 
					    void StopProcessor() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Sets config parameters of the camera
 | 
				
			||||||
 | 
					    void SetConfig(Core::IrSensor::PackedClusteringProcessorConfig config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    // This is nn::irsensor::ClusteringProcessorConfig
 | 
				
			||||||
 | 
					    struct ClusteringProcessorConfig {
 | 
				
			||||||
 | 
					        Core::IrSensor::CameraConfig camera_config;
 | 
				
			||||||
 | 
					        Core::IrSensor::IrsRect window_of_interest;
 | 
				
			||||||
 | 
					        u32 pixel_count_min;
 | 
				
			||||||
 | 
					        u32 pixel_count_max;
 | 
				
			||||||
 | 
					        u32 object_intensity_min;
 | 
				
			||||||
 | 
					        bool is_external_light_filter_enabled;
 | 
				
			||||||
 | 
					        INSERT_PADDING_BYTES(3);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    static_assert(sizeof(ClusteringProcessorConfig) == 0x30,
 | 
				
			||||||
 | 
					                  "ClusteringProcessorConfig is an invalid size");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // This is nn::irsensor::AdaptiveClusteringProcessorConfig
 | 
				
			||||||
 | 
					    struct AdaptiveClusteringProcessorConfig {
 | 
				
			||||||
 | 
					        Core::IrSensor::AdaptiveClusteringMode mode;
 | 
				
			||||||
 | 
					        Core::IrSensor::AdaptiveClusteringTargetDistance target_distance;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    static_assert(sizeof(AdaptiveClusteringProcessorConfig) == 0x8,
 | 
				
			||||||
 | 
					                  "AdaptiveClusteringProcessorConfig is an invalid size");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // This is nn::irsensor::ClusteringData
 | 
				
			||||||
 | 
					    struct ClusteringData {
 | 
				
			||||||
 | 
					        f32 average_intensity;
 | 
				
			||||||
 | 
					        Core::IrSensor::IrsCentroid centroid;
 | 
				
			||||||
 | 
					        u32 pixel_count;
 | 
				
			||||||
 | 
					        Core::IrSensor::IrsRect bound;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    static_assert(sizeof(ClusteringData) == 0x18, "ClusteringData is an invalid size");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // This is nn::irsensor::ClusteringProcessorState
 | 
				
			||||||
 | 
					    struct ClusteringProcessorState {
 | 
				
			||||||
 | 
					        s64 sampling_number;
 | 
				
			||||||
 | 
					        u64 timestamp;
 | 
				
			||||||
 | 
					        u8 object_count;
 | 
				
			||||||
 | 
					        INSERT_PADDING_BYTES(3);
 | 
				
			||||||
 | 
					        Core::IrSensor::CameraAmbientNoiseLevel ambient_noise_level;
 | 
				
			||||||
 | 
					        std::array<ClusteringData, 0x10> data;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    static_assert(sizeof(ClusteringProcessorState) == 0x198,
 | 
				
			||||||
 | 
					                  "ClusteringProcessorState is an invalid size");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ClusteringProcessorConfig current_config{};
 | 
				
			||||||
 | 
					    Core::IrSensor::DeviceFormat& device;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					} // namespace Service::HID
 | 
				
			||||||
							
								
								
									
										154
									
								
								src/core/hle/service/hid/irsensor/image_transfer_processor.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								src/core/hle/service/hid/irsensor/image_transfer_processor.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,154 @@
 | 
				
			|||||||
 | 
					// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: GPL-3.0-or-later
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "core/hid/emulated_controller.h"
 | 
				
			||||||
 | 
					#include "core/hid/hid_core.h"
 | 
				
			||||||
 | 
					#include "core/hle/service/hid/irsensor/image_transfer_processor.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Service::HID {
 | 
				
			||||||
 | 
					ImageTransferProcessor::ImageTransferProcessor(Core::HID::HIDCore& hid_core_,
 | 
				
			||||||
 | 
					                                               Core::IrSensor::DeviceFormat& device_format,
 | 
				
			||||||
 | 
					                                               std::size_t npad_index)
 | 
				
			||||||
 | 
					    : device{device_format} {
 | 
				
			||||||
 | 
					    npad_device = hid_core_.GetEmulatedControllerByIndex(npad_index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Core::HID::ControllerUpdateCallback engine_callback{
 | 
				
			||||||
 | 
					        .on_change = [this](Core::HID::ControllerTriggerType type) { OnControllerUpdate(type); },
 | 
				
			||||||
 | 
					        .is_npad_service = true,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    callback_key = npad_device->SetCallback(engine_callback);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    device.mode = Core::IrSensor::IrSensorMode::ImageTransferProcessor;
 | 
				
			||||||
 | 
					    device.camera_status = Core::IrSensor::IrCameraStatus::Unconnected;
 | 
				
			||||||
 | 
					    device.camera_internal_status = Core::IrSensor::IrCameraInternalStatus::Stopped;
 | 
				
			||||||
 | 
					    device.state.start = 0;
 | 
				
			||||||
 | 
					    device.state.count = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ImageTransferProcessor::~ImageTransferProcessor() {
 | 
				
			||||||
 | 
					    npad_device->DeleteCallback(callback_key);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ImageTransferProcessor::StartProcessor() {
 | 
				
			||||||
 | 
					    is_active = true;
 | 
				
			||||||
 | 
					    device.camera_status = Core::IrSensor::IrCameraStatus::Available;
 | 
				
			||||||
 | 
					    device.camera_internal_status = Core::IrSensor::IrCameraInternalStatus::Ready;
 | 
				
			||||||
 | 
					    device.state.start = 0;
 | 
				
			||||||
 | 
					    device.state.count = 1;
 | 
				
			||||||
 | 
					    processor_state.sampling_number = 0;
 | 
				
			||||||
 | 
					    processor_state.ambient_noise_level = Core::IrSensor::CameraAmbientNoiseLevel::Low;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ImageTransferProcessor::SuspendProcessor() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ImageTransferProcessor::StopProcessor() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ImageTransferProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType type) {
 | 
				
			||||||
 | 
					    if (type != Core::HID::ControllerTriggerType::IrSensor) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (!is_transfer_memory_set) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const auto camera_data = npad_device->GetCamera();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // This indicates how much ambient light is precent
 | 
				
			||||||
 | 
					    processor_state.ambient_noise_level = Core::IrSensor::CameraAmbientNoiseLevel::Low;
 | 
				
			||||||
 | 
					    processor_state.sampling_number = camera_data.sample;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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));
 | 
				
			||||||
 | 
					        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));
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::vector<u8> window_data{};
 | 
				
			||||||
 | 
					    const auto origin_width = GetDataWidth(current_config.origin_format);
 | 
				
			||||||
 | 
					    const auto origin_height = GetDataHeight(current_config.origin_format);
 | 
				
			||||||
 | 
					    const auto trimming_width = GetDataWidth(current_config.trimming_format);
 | 
				
			||||||
 | 
					    const auto trimming_height = GetDataHeight(current_config.trimming_format);
 | 
				
			||||||
 | 
					    window_data.resize(GetDataSize(current_config.trimming_format));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (trimming_width + current_config.trimming_start_x > origin_width ||
 | 
				
			||||||
 | 
					        trimming_height + current_config.trimming_start_y > origin_height) {
 | 
				
			||||||
 | 
					        LOG_WARNING(Service_IRS,
 | 
				
			||||||
 | 
					                    "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));
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (std::size_t y = 0; y < trimming_height; y++) {
 | 
				
			||||||
 | 
					        for (std::size_t x = 0; x < trimming_width; x++) {
 | 
				
			||||||
 | 
					            const std::size_t window_index = (y * trimming_width) + x;
 | 
				
			||||||
 | 
					            const std::size_t origin_index =
 | 
				
			||||||
 | 
					                ((y + current_config.trimming_start_y) * origin_width) + x +
 | 
				
			||||||
 | 
					                current_config.trimming_start_x;
 | 
				
			||||||
 | 
					            window_data[window_index] = camera_data.data[origin_index];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memcpy(transfer_memory, window_data.data(), GetDataSize(current_config.trimming_format));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!IsProcessorActive()) {
 | 
				
			||||||
 | 
					        StartProcessor();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ImageTransferProcessor::SetConfig(Core::IrSensor::PackedImageTransferProcessorConfig config) {
 | 
				
			||||||
 | 
					    current_config.camera_config.exposure_time = config.camera_config.exposure_time;
 | 
				
			||||||
 | 
					    current_config.camera_config.gain = config.camera_config.gain;
 | 
				
			||||||
 | 
					    current_config.camera_config.is_negative_used = config.camera_config.is_negative_used;
 | 
				
			||||||
 | 
					    current_config.camera_config.light_target =
 | 
				
			||||||
 | 
					        static_cast<Core::IrSensor::CameraLightTarget>(config.camera_config.light_target);
 | 
				
			||||||
 | 
					    current_config.origin_format =
 | 
				
			||||||
 | 
					        static_cast<Core::IrSensor::ImageTransferProcessorFormat>(config.format);
 | 
				
			||||||
 | 
					    current_config.trimming_format =
 | 
				
			||||||
 | 
					        static_cast<Core::IrSensor::ImageTransferProcessorFormat>(config.format);
 | 
				
			||||||
 | 
					    current_config.trimming_start_x = 0;
 | 
				
			||||||
 | 
					    current_config.trimming_start_y = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    npad_device->SetCameraFormat(current_config.origin_format);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ImageTransferProcessor::SetConfig(
 | 
				
			||||||
 | 
					    Core::IrSensor::PackedImageTransferProcessorExConfig config) {
 | 
				
			||||||
 | 
					    current_config.camera_config.exposure_time = config.camera_config.exposure_time;
 | 
				
			||||||
 | 
					    current_config.camera_config.gain = config.camera_config.gain;
 | 
				
			||||||
 | 
					    current_config.camera_config.is_negative_used = config.camera_config.is_negative_used;
 | 
				
			||||||
 | 
					    current_config.camera_config.light_target =
 | 
				
			||||||
 | 
					        static_cast<Core::IrSensor::CameraLightTarget>(config.camera_config.light_target);
 | 
				
			||||||
 | 
					    current_config.origin_format =
 | 
				
			||||||
 | 
					        static_cast<Core::IrSensor::ImageTransferProcessorFormat>(config.origin_format);
 | 
				
			||||||
 | 
					    current_config.trimming_format =
 | 
				
			||||||
 | 
					        static_cast<Core::IrSensor::ImageTransferProcessorFormat>(config.trimming_format);
 | 
				
			||||||
 | 
					    current_config.trimming_start_x = config.trimming_start_x;
 | 
				
			||||||
 | 
					    current_config.trimming_start_y = config.trimming_start_y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    npad_device->SetCameraFormat(current_config.origin_format);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ImageTransferProcessor::SetTransferMemoryPointer(u8* t_mem) {
 | 
				
			||||||
 | 
					    is_transfer_memory_set = true;
 | 
				
			||||||
 | 
					    transfer_memory = t_mem;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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);
 | 
				
			||||||
 | 
					    return processor_state;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace Service::HID
 | 
				
			||||||
							
								
								
									
										73
									
								
								src/core/hle/service/hid/irsensor/image_transfer_processor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								src/core/hle/service/hid/irsensor/image_transfer_processor.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,73 @@
 | 
				
			|||||||
 | 
					// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: GPL-3.0-or-later
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "common/common_types.h"
 | 
				
			||||||
 | 
					#include "core/hid/irs_types.h"
 | 
				
			||||||
 | 
					#include "core/hle/service/hid/irsensor/processor_base.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Core::HID {
 | 
				
			||||||
 | 
					class EmulatedController;
 | 
				
			||||||
 | 
					} // namespace Core::HID
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Service::HID {
 | 
				
			||||||
 | 
					class ImageTransferProcessor final : public ProcessorBase {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    explicit ImageTransferProcessor(Core::HID::HIDCore& hid_core_,
 | 
				
			||||||
 | 
					                                    Core::IrSensor::DeviceFormat& device_format,
 | 
				
			||||||
 | 
					                                    std::size_t npad_index);
 | 
				
			||||||
 | 
					    ~ImageTransferProcessor() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Called when the processor is initialized
 | 
				
			||||||
 | 
					    void StartProcessor() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Called when the processor is suspended
 | 
				
			||||||
 | 
					    void SuspendProcessor() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Called when the processor is stopped
 | 
				
			||||||
 | 
					    void StopProcessor() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Sets config parameters of the camera
 | 
				
			||||||
 | 
					    void SetConfig(Core::IrSensor::PackedImageTransferProcessorConfig config);
 | 
				
			||||||
 | 
					    void SetConfig(Core::IrSensor::PackedImageTransferProcessorExConfig config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Transfer memory where the image data will be stored
 | 
				
			||||||
 | 
					    void SetTransferMemoryPointer(u8* t_mem);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Core::IrSensor::ImageTransferProcessorState GetState(std::vector<u8>& data) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    // This is nn::irsensor::ImageTransferProcessorConfig
 | 
				
			||||||
 | 
					    struct ImageTransferProcessorConfig {
 | 
				
			||||||
 | 
					        Core::IrSensor::CameraConfig camera_config;
 | 
				
			||||||
 | 
					        Core::IrSensor::ImageTransferProcessorFormat format;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    static_assert(sizeof(ImageTransferProcessorConfig) == 0x20,
 | 
				
			||||||
 | 
					                  "ImageTransferProcessorConfig is an invalid size");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // This is nn::irsensor::ImageTransferProcessorExConfig
 | 
				
			||||||
 | 
					    struct ImageTransferProcessorExConfig {
 | 
				
			||||||
 | 
					        Core::IrSensor::CameraConfig camera_config;
 | 
				
			||||||
 | 
					        Core::IrSensor::ImageTransferProcessorFormat origin_format;
 | 
				
			||||||
 | 
					        Core::IrSensor::ImageTransferProcessorFormat trimming_format;
 | 
				
			||||||
 | 
					        u16 trimming_start_x;
 | 
				
			||||||
 | 
					        u16 trimming_start_y;
 | 
				
			||||||
 | 
					        bool is_external_light_filter_enabled;
 | 
				
			||||||
 | 
					        INSERT_PADDING_BYTES(3);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    static_assert(sizeof(ImageTransferProcessorExConfig) == 0x28,
 | 
				
			||||||
 | 
					                  "ImageTransferProcessorExConfig is an invalid size");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void OnControllerUpdate(Core::HID::ControllerTriggerType type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ImageTransferProcessorExConfig current_config{};
 | 
				
			||||||
 | 
					    Core::IrSensor::ImageTransferProcessorState processor_state{};
 | 
				
			||||||
 | 
					    Core::IrSensor::DeviceFormat& device;
 | 
				
			||||||
 | 
					    Core::HID::EmulatedController* npad_device;
 | 
				
			||||||
 | 
					    int callback_key{};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    u8* transfer_memory = nullptr;
 | 
				
			||||||
 | 
					    bool is_transfer_memory_set = false;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					} // namespace Service::HID
 | 
				
			||||||
							
								
								
									
										29
									
								
								src/core/hle/service/hid/irsensor/ir_led_processor.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/core/hle/service/hid/irsensor/ir_led_processor.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
				
			|||||||
 | 
					// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: GPL-3.0-or-later
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "core/hle/service/hid/irsensor/ir_led_processor.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Service::HID {
 | 
				
			||||||
 | 
					IrLedProcessor::IrLedProcessor(Core::IrSensor::DeviceFormat& device_format)
 | 
				
			||||||
 | 
					    : device(device_format) {
 | 
				
			||||||
 | 
					    device.mode = Core::IrSensor::IrSensorMode::IrLedProcessor;
 | 
				
			||||||
 | 
					    device.camera_status = Core::IrSensor::IrCameraStatus::Unconnected;
 | 
				
			||||||
 | 
					    device.camera_internal_status = Core::IrSensor::IrCameraInternalStatus::Stopped;
 | 
				
			||||||
 | 
					    device.state.start = 0;
 | 
				
			||||||
 | 
					    device.state.count = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					IrLedProcessor::~IrLedProcessor() = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void IrLedProcessor::StartProcessor() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void IrLedProcessor::SuspendProcessor() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void IrLedProcessor::StopProcessor() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void IrLedProcessor::SetConfig(Core::IrSensor::PackedIrLedProcessorConfig config) {
 | 
				
			||||||
 | 
					    current_config.light_target =
 | 
				
			||||||
 | 
					        static_cast<Core::IrSensor::CameraLightTarget>(config.light_target);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace Service::HID
 | 
				
			||||||
							
								
								
									
										47
									
								
								src/core/hle/service/hid/irsensor/ir_led_processor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/core/hle/service/hid/irsensor/ir_led_processor.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
				
			|||||||
 | 
					// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: GPL-3.0-or-later
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "common/bit_field.h"
 | 
				
			||||||
 | 
					#include "common/common_types.h"
 | 
				
			||||||
 | 
					#include "core/hid/irs_types.h"
 | 
				
			||||||
 | 
					#include "core/hle/service/hid/irsensor/processor_base.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Service::HID {
 | 
				
			||||||
 | 
					class IrLedProcessor final : public ProcessorBase {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    explicit IrLedProcessor(Core::IrSensor::DeviceFormat& device_format);
 | 
				
			||||||
 | 
					    ~IrLedProcessor() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Called when the processor is initialized
 | 
				
			||||||
 | 
					    void StartProcessor() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Called when the processor is suspended
 | 
				
			||||||
 | 
					    void SuspendProcessor() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Called when the processor is stopped
 | 
				
			||||||
 | 
					    void StopProcessor() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Sets config parameters of the camera
 | 
				
			||||||
 | 
					    void SetConfig(Core::IrSensor::PackedIrLedProcessorConfig config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    // This is nn::irsensor::IrLedProcessorConfig
 | 
				
			||||||
 | 
					    struct IrLedProcessorConfig {
 | 
				
			||||||
 | 
					        Core::IrSensor::CameraLightTarget light_target;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    static_assert(sizeof(IrLedProcessorConfig) == 0x4, "IrLedProcessorConfig is an invalid size");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    struct IrLedProcessorState {
 | 
				
			||||||
 | 
					        s64 sampling_number;
 | 
				
			||||||
 | 
					        u64 timestamp;
 | 
				
			||||||
 | 
					        std::array<u8, 0x8> data;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    static_assert(sizeof(IrLedProcessorState) == 0x18, "IrLedProcessorState is an invalid size");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    IrLedProcessorConfig current_config{};
 | 
				
			||||||
 | 
					    Core::IrSensor::DeviceFormat& device;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace Service::HID
 | 
				
			||||||
							
								
								
									
										36
									
								
								src/core/hle/service/hid/irsensor/moment_processor.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/core/hle/service/hid/irsensor/moment_processor.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: GPL-3.0-or-later
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "core/hle/service/hid/irsensor/moment_processor.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Service::HID {
 | 
				
			||||||
 | 
					MomentProcessor::MomentProcessor(Core::IrSensor::DeviceFormat& device_format)
 | 
				
			||||||
 | 
					    : device(device_format) {
 | 
				
			||||||
 | 
					    device.mode = Core::IrSensor::IrSensorMode::MomentProcessor;
 | 
				
			||||||
 | 
					    device.camera_status = Core::IrSensor::IrCameraStatus::Unconnected;
 | 
				
			||||||
 | 
					    device.camera_internal_status = Core::IrSensor::IrCameraInternalStatus::Stopped;
 | 
				
			||||||
 | 
					    device.state.start = 0;
 | 
				
			||||||
 | 
					    device.state.count = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MomentProcessor::~MomentProcessor() = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MomentProcessor::StartProcessor() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MomentProcessor::SuspendProcessor() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MomentProcessor::StopProcessor() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MomentProcessor::SetConfig(Core::IrSensor::PackedMomentProcessorConfig config) {
 | 
				
			||||||
 | 
					    current_config.camera_config.exposure_time = config.camera_config.exposure_time;
 | 
				
			||||||
 | 
					    current_config.camera_config.gain = config.camera_config.gain;
 | 
				
			||||||
 | 
					    current_config.camera_config.is_negative_used = config.camera_config.is_negative_used;
 | 
				
			||||||
 | 
					    current_config.camera_config.light_target =
 | 
				
			||||||
 | 
					        static_cast<Core::IrSensor::CameraLightTarget>(config.camera_config.light_target);
 | 
				
			||||||
 | 
					    current_config.window_of_interest = config.window_of_interest;
 | 
				
			||||||
 | 
					    current_config.preprocess =
 | 
				
			||||||
 | 
					        static_cast<Core::IrSensor::MomentProcessorPreprocess>(config.preprocess);
 | 
				
			||||||
 | 
					    current_config.preprocess_intensity_threshold = config.preprocess_intensity_threshold;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace Service::HID
 | 
				
			||||||
							
								
								
									
										61
									
								
								src/core/hle/service/hid/irsensor/moment_processor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								src/core/hle/service/hid/irsensor/moment_processor.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
				
			|||||||
 | 
					// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: GPL-3.0-or-later
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "common/bit_field.h"
 | 
				
			||||||
 | 
					#include "common/common_types.h"
 | 
				
			||||||
 | 
					#include "core/hid/irs_types.h"
 | 
				
			||||||
 | 
					#include "core/hle/service/hid/irsensor/processor_base.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Service::HID {
 | 
				
			||||||
 | 
					class MomentProcessor final : public ProcessorBase {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    explicit MomentProcessor(Core::IrSensor::DeviceFormat& device_format);
 | 
				
			||||||
 | 
					    ~MomentProcessor() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Called when the processor is initialized
 | 
				
			||||||
 | 
					    void StartProcessor() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Called when the processor is suspended
 | 
				
			||||||
 | 
					    void SuspendProcessor() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Called when the processor is stopped
 | 
				
			||||||
 | 
					    void StopProcessor() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Sets config parameters of the camera
 | 
				
			||||||
 | 
					    void SetConfig(Core::IrSensor::PackedMomentProcessorConfig config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    // This is nn::irsensor::MomentProcessorConfig
 | 
				
			||||||
 | 
					    struct MomentProcessorConfig {
 | 
				
			||||||
 | 
					        Core::IrSensor::CameraConfig camera_config;
 | 
				
			||||||
 | 
					        Core::IrSensor::IrsRect window_of_interest;
 | 
				
			||||||
 | 
					        Core::IrSensor::MomentProcessorPreprocess preprocess;
 | 
				
			||||||
 | 
					        u32 preprocess_intensity_threshold;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    static_assert(sizeof(MomentProcessorConfig) == 0x28,
 | 
				
			||||||
 | 
					                  "MomentProcessorConfig is an invalid size");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // This is nn::irsensor::MomentStatistic
 | 
				
			||||||
 | 
					    struct MomentStatistic {
 | 
				
			||||||
 | 
					        f32 average_intensity;
 | 
				
			||||||
 | 
					        Core::IrSensor::IrsCentroid centroid;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    static_assert(sizeof(MomentStatistic) == 0xC, "MomentStatistic is an invalid size");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // This is nn::irsensor::MomentProcessorState
 | 
				
			||||||
 | 
					    struct MomentProcessorState {
 | 
				
			||||||
 | 
					        s64 sampling_number;
 | 
				
			||||||
 | 
					        u64 timestamp;
 | 
				
			||||||
 | 
					        Core::IrSensor::CameraAmbientNoiseLevel ambient_noise_level;
 | 
				
			||||||
 | 
					        INSERT_PADDING_BYTES(4);
 | 
				
			||||||
 | 
					        std::array<MomentStatistic, 0x30> stadistic;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    static_assert(sizeof(MomentProcessorState) == 0x258, "MomentProcessorState is an invalid size");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    MomentProcessorConfig current_config{};
 | 
				
			||||||
 | 
					    Core::IrSensor::DeviceFormat& device;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace Service::HID
 | 
				
			||||||
							
								
								
									
										28
									
								
								src/core/hle/service/hid/irsensor/pointing_processor.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/core/hle/service/hid/irsensor/pointing_processor.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
				
			|||||||
 | 
					// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: GPL-3.0-or-later
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "core/hle/service/hid/irsensor/pointing_processor.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Service::HID {
 | 
				
			||||||
 | 
					PointingProcessor::PointingProcessor(Core::IrSensor::DeviceFormat& device_format)
 | 
				
			||||||
 | 
					    : device(device_format) {
 | 
				
			||||||
 | 
					    device.mode = Core::IrSensor::IrSensorMode::PointingProcessorMarker;
 | 
				
			||||||
 | 
					    device.camera_status = Core::IrSensor::IrCameraStatus::Unconnected;
 | 
				
			||||||
 | 
					    device.camera_internal_status = Core::IrSensor::IrCameraInternalStatus::Stopped;
 | 
				
			||||||
 | 
					    device.state.start = 0;
 | 
				
			||||||
 | 
					    device.state.count = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PointingProcessor::~PointingProcessor() = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void PointingProcessor::StartProcessor() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void PointingProcessor::SuspendProcessor() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void PointingProcessor::StopProcessor() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void PointingProcessor::SetConfig(Core::IrSensor::PackedPointingProcessorConfig config) {
 | 
				
			||||||
 | 
					    current_config.window_of_interest = config.window_of_interest;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace Service::HID
 | 
				
			||||||
							
								
								
									
										62
									
								
								src/core/hle/service/hid/irsensor/pointing_processor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								src/core/hle/service/hid/irsensor/pointing_processor.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
				
			|||||||
 | 
					// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: GPL-3.0-or-later
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "common/bit_field.h"
 | 
				
			||||||
 | 
					#include "common/common_types.h"
 | 
				
			||||||
 | 
					#include "core/hid/irs_types.h"
 | 
				
			||||||
 | 
					#include "core/hle/service/hid/irsensor/processor_base.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Service::HID {
 | 
				
			||||||
 | 
					class PointingProcessor final : public ProcessorBase {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    explicit PointingProcessor(Core::IrSensor::DeviceFormat& device_format);
 | 
				
			||||||
 | 
					    ~PointingProcessor() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Called when the processor is initialized
 | 
				
			||||||
 | 
					    void StartProcessor() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Called when the processor is suspended
 | 
				
			||||||
 | 
					    void SuspendProcessor() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Called when the processor is stopped
 | 
				
			||||||
 | 
					    void StopProcessor() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Sets config parameters of the camera
 | 
				
			||||||
 | 
					    void SetConfig(Core::IrSensor::PackedPointingProcessorConfig config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    // This is nn::irsensor::PointingProcessorConfig
 | 
				
			||||||
 | 
					    struct PointingProcessorConfig {
 | 
				
			||||||
 | 
					        Core::IrSensor::IrsRect window_of_interest;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    static_assert(sizeof(PointingProcessorConfig) == 0x8,
 | 
				
			||||||
 | 
					                  "PointingProcessorConfig is an invalid size");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    struct PointingProcessorMarkerData {
 | 
				
			||||||
 | 
					        u8 pointing_status;
 | 
				
			||||||
 | 
					        INSERT_PADDING_BYTES(3);
 | 
				
			||||||
 | 
					        u32 unknown;
 | 
				
			||||||
 | 
					        float unkown_float1;
 | 
				
			||||||
 | 
					        float position_x;
 | 
				
			||||||
 | 
					        float position_y;
 | 
				
			||||||
 | 
					        float unkown_float2;
 | 
				
			||||||
 | 
					        Core::IrSensor::IrsRect window_of_interest;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    static_assert(sizeof(PointingProcessorMarkerData) == 0x20,
 | 
				
			||||||
 | 
					                  "PointingProcessorMarkerData is an invalid size");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    struct PointingProcessorMarkerState {
 | 
				
			||||||
 | 
					        s64 sampling_number;
 | 
				
			||||||
 | 
					        u64 timestamp;
 | 
				
			||||||
 | 
					        std::array<PointingProcessorMarkerData, 0x3> data;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    static_assert(sizeof(PointingProcessorMarkerState) == 0x70,
 | 
				
			||||||
 | 
					                  "PointingProcessorMarkerState is an invalid size");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    PointingProcessorConfig current_config{};
 | 
				
			||||||
 | 
					    Core::IrSensor::DeviceFormat& device;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace Service::HID
 | 
				
			||||||
							
								
								
									
										67
									
								
								src/core/hle/service/hid/irsensor/processor_base.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								src/core/hle/service/hid/irsensor/processor_base.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,67 @@
 | 
				
			|||||||
 | 
					// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: GPL-3.0-or-later
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "core/hle/service/hid/irsensor/processor_base.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Service::HID {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ProcessorBase::ProcessorBase() {}
 | 
				
			||||||
 | 
					ProcessorBase::~ProcessorBase() = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool ProcessorBase::IsProcessorActive() const {
 | 
				
			||||||
 | 
					    return is_active;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::size_t ProcessorBase::GetDataSize(Core::IrSensor::ImageTransferProcessorFormat format) const {
 | 
				
			||||||
 | 
					    switch (format) {
 | 
				
			||||||
 | 
					    case Core::IrSensor::ImageTransferProcessorFormat::Size320x240:
 | 
				
			||||||
 | 
					        return 320 * 240;
 | 
				
			||||||
 | 
					    case Core::IrSensor::ImageTransferProcessorFormat::Size160x120:
 | 
				
			||||||
 | 
					        return 160 * 120;
 | 
				
			||||||
 | 
					    case Core::IrSensor::ImageTransferProcessorFormat::Size80x60:
 | 
				
			||||||
 | 
					        return 80 * 60;
 | 
				
			||||||
 | 
					    case Core::IrSensor::ImageTransferProcessorFormat::Size40x30:
 | 
				
			||||||
 | 
					        return 40 * 30;
 | 
				
			||||||
 | 
					    case Core::IrSensor::ImageTransferProcessorFormat::Size20x15:
 | 
				
			||||||
 | 
					        return 20 * 15;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::size_t ProcessorBase::GetDataWidth(Core::IrSensor::ImageTransferProcessorFormat format) const {
 | 
				
			||||||
 | 
					    switch (format) {
 | 
				
			||||||
 | 
					    case Core::IrSensor::ImageTransferProcessorFormat::Size320x240:
 | 
				
			||||||
 | 
					        return 320;
 | 
				
			||||||
 | 
					    case Core::IrSensor::ImageTransferProcessorFormat::Size160x120:
 | 
				
			||||||
 | 
					        return 160;
 | 
				
			||||||
 | 
					    case Core::IrSensor::ImageTransferProcessorFormat::Size80x60:
 | 
				
			||||||
 | 
					        return 80;
 | 
				
			||||||
 | 
					    case Core::IrSensor::ImageTransferProcessorFormat::Size40x30:
 | 
				
			||||||
 | 
					        return 40;
 | 
				
			||||||
 | 
					    case Core::IrSensor::ImageTransferProcessorFormat::Size20x15:
 | 
				
			||||||
 | 
					        return 20;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::size_t ProcessorBase::GetDataHeight(
 | 
				
			||||||
 | 
					    Core::IrSensor::ImageTransferProcessorFormat format) const {
 | 
				
			||||||
 | 
					    switch (format) {
 | 
				
			||||||
 | 
					    case Core::IrSensor::ImageTransferProcessorFormat::Size320x240:
 | 
				
			||||||
 | 
					        return 240;
 | 
				
			||||||
 | 
					    case Core::IrSensor::ImageTransferProcessorFormat::Size160x120:
 | 
				
			||||||
 | 
					        return 120;
 | 
				
			||||||
 | 
					    case Core::IrSensor::ImageTransferProcessorFormat::Size80x60:
 | 
				
			||||||
 | 
					        return 60;
 | 
				
			||||||
 | 
					    case Core::IrSensor::ImageTransferProcessorFormat::Size40x30:
 | 
				
			||||||
 | 
					        return 30;
 | 
				
			||||||
 | 
					    case Core::IrSensor::ImageTransferProcessorFormat::Size20x15:
 | 
				
			||||||
 | 
					        return 15;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace Service::HID
 | 
				
			||||||
							
								
								
									
										33
									
								
								src/core/hle/service/hid/irsensor/processor_base.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/core/hle/service/hid/irsensor/processor_base.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
				
			|||||||
 | 
					// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: GPL-3.0-or-later
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "common/common_types.h"
 | 
				
			||||||
 | 
					#include "core/hid/irs_types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Service::HID {
 | 
				
			||||||
 | 
					class ProcessorBase {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    explicit ProcessorBase();
 | 
				
			||||||
 | 
					    virtual ~ProcessorBase();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    virtual void StartProcessor() = 0;
 | 
				
			||||||
 | 
					    virtual void SuspendProcessor() = 0;
 | 
				
			||||||
 | 
					    virtual void StopProcessor() = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool IsProcessorActive() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
					    /// Returns the number of bytes the image uses
 | 
				
			||||||
 | 
					    std::size_t GetDataSize(Core::IrSensor::ImageTransferProcessorFormat format) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Returns the width of the image
 | 
				
			||||||
 | 
					    std::size_t GetDataWidth(Core::IrSensor::ImageTransferProcessorFormat format) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Returns the height of the image
 | 
				
			||||||
 | 
					    std::size_t GetDataHeight(Core::IrSensor::ImageTransferProcessorFormat format) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool is_active{false};
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					} // namespace Service::HID
 | 
				
			||||||
							
								
								
									
										31
									
								
								src/core/hle/service/hid/irsensor/tera_plugin_processor.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/core/hle/service/hid/irsensor/tera_plugin_processor.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
				
			|||||||
 | 
					// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: GPL-3.0-or-later
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "core/hle/service/hid/irsensor/tera_plugin_processor.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Service::HID {
 | 
				
			||||||
 | 
					TeraPluginProcessor::TeraPluginProcessor(Core::IrSensor::DeviceFormat& device_format)
 | 
				
			||||||
 | 
					    : device(device_format) {
 | 
				
			||||||
 | 
					    device.mode = Core::IrSensor::IrSensorMode::TeraPluginProcessor;
 | 
				
			||||||
 | 
					    device.camera_status = Core::IrSensor::IrCameraStatus::Unconnected;
 | 
				
			||||||
 | 
					    device.camera_internal_status = Core::IrSensor::IrCameraInternalStatus::Stopped;
 | 
				
			||||||
 | 
					    device.state.start = 0;
 | 
				
			||||||
 | 
					    device.state.count = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TeraPluginProcessor::~TeraPluginProcessor() = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TeraPluginProcessor::StartProcessor() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TeraPluginProcessor::SuspendProcessor() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TeraPluginProcessor::StopProcessor() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TeraPluginProcessor::SetConfig(Core::IrSensor::PackedTeraPluginProcessorConfig config) {
 | 
				
			||||||
 | 
					    current_config.mode = config.mode;
 | 
				
			||||||
 | 
					    current_config.unknown_1 = config.unknown_1;
 | 
				
			||||||
 | 
					    current_config.unknown_2 = config.unknown_2;
 | 
				
			||||||
 | 
					    current_config.unknown_3 = config.unknown_3;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace Service::HID
 | 
				
			||||||
							
								
								
									
										53
									
								
								src/core/hle/service/hid/irsensor/tera_plugin_processor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								src/core/hle/service/hid/irsensor/tera_plugin_processor.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
				
			|||||||
 | 
					// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: GPL-3.0-or-later
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "common/bit_field.h"
 | 
				
			||||||
 | 
					#include "common/common_types.h"
 | 
				
			||||||
 | 
					#include "core/hid/irs_types.h"
 | 
				
			||||||
 | 
					#include "core/hle/service/hid/irsensor/processor_base.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Service::HID {
 | 
				
			||||||
 | 
					class TeraPluginProcessor final : public ProcessorBase {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    explicit TeraPluginProcessor(Core::IrSensor::DeviceFormat& device_format);
 | 
				
			||||||
 | 
					    ~TeraPluginProcessor() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Called when the processor is initialized
 | 
				
			||||||
 | 
					    void StartProcessor() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Called when the processor is suspended
 | 
				
			||||||
 | 
					    void SuspendProcessor() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Called when the processor is stopped
 | 
				
			||||||
 | 
					    void StopProcessor() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Sets config parameters of the camera
 | 
				
			||||||
 | 
					    void SetConfig(Core::IrSensor::PackedTeraPluginProcessorConfig config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    // This is nn::irsensor::TeraPluginProcessorConfig
 | 
				
			||||||
 | 
					    struct TeraPluginProcessorConfig {
 | 
				
			||||||
 | 
					        u8 mode;
 | 
				
			||||||
 | 
					        u8 unknown_1;
 | 
				
			||||||
 | 
					        u8 unknown_2;
 | 
				
			||||||
 | 
					        u8 unknown_3;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    static_assert(sizeof(TeraPluginProcessorConfig) == 0x4,
 | 
				
			||||||
 | 
					                  "TeraPluginProcessorConfig is an invalid size");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    struct TeraPluginProcessorState {
 | 
				
			||||||
 | 
					        s64 sampling_number;
 | 
				
			||||||
 | 
					        u64 timestamp;
 | 
				
			||||||
 | 
					        Core::IrSensor::CameraAmbientNoiseLevel ambient_noise_level;
 | 
				
			||||||
 | 
					        std::array<u8, 0x12c> data;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    static_assert(sizeof(TeraPluginProcessorState) == 0x140,
 | 
				
			||||||
 | 
					                  "TeraPluginProcessorState is an invalid size");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    TeraPluginProcessorConfig current_config{};
 | 
				
			||||||
 | 
					    Core::IrSensor::DeviceFormat& device;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace Service::HID
 | 
				
			||||||
		Reference in New Issue
	
	Block a user