service: irs: Split processors and implement ImageTransferProcessor

This commit is contained in:
german77
2022-06-18 23:45:06 -05:00
parent 57311b2c8b
commit 4539700595
18 changed files with 1090 additions and 290 deletions

View File

@ -4,12 +4,18 @@
#pragma once
#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"
namespace Core {
class System;
}
namespace Core::HID {
class EmulatedController;
} // namespace Core::HID
namespace Service::HID {
class IRS final : public ServiceFramework<IRS> {
@ -18,234 +24,19 @@ public:
~IRS() override;
private:
// This is nn::irsensor::IrCameraStatus
enum IrCameraStatus : u32 {
Available,
Unsupported,
Unconnected,
// This is nn::irsensor::detail::AruidFormat
struct AruidFormat {
u64 sensor_aruid;
u64 sensor_aruid_status;
};
static_assert(sizeof(AruidFormat) == 0x10, "AruidFormat is an invalid size");
// This is nn::irsensor::IrCameraInternalStatus
enum IrCameraInternalStatus : u32 {
Stopped,
FirmwareUpdateNeeded,
Unkown2,
Unkown3,
Unkown4,
FirmwareVersionRequested,
FirmwareVersionIsInvalid,
Ready,
Setting,
// This is nn::irsensor::detail::StatusManager
struct StatusManager {
std::array<Core::IrSensor::DeviceFormat, 9> device;
std::array<AruidFormat, 5> aruid;
};
// 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");
static_assert(sizeof(StatusManager) == 0x8000, "StatusManager is an invalid size");
void ActivateIrsensor(Kernel::HLERequestContext& ctx);
void DeactivateIrsensor(Kernel::HLERequestContext& ctx);
@ -265,6 +56,56 @@ private:
void RunIrLedProcessor(Kernel::HLERequestContext& ctx);
void StopImageProcessorAsync(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> {