mirror of
https://github.com/switchbrew/libnx.git
synced 2025-08-06 16:19:25 +02:00
Implemented more irs.
This commit is contained in:
parent
e9f07a314a
commit
07ec16a8e7
@ -10,6 +10,45 @@
|
|||||||
#include "../services/sm.h"
|
#include "../services/sm.h"
|
||||||
#include "../services/hid.h"
|
#include "../services/hid.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u64 unk_x0;
|
||||||
|
u8 unk_x8;
|
||||||
|
u8 unk_x9;
|
||||||
|
u8 unk_xa;
|
||||||
|
u8 pad[5];
|
||||||
|
u16 unk_x10;
|
||||||
|
u32 unk_x12;
|
||||||
|
u16 unk_x16;
|
||||||
|
u32 unk_constant;//offset 0x18
|
||||||
|
u8 unk_x1c;
|
||||||
|
u8 unk_x1d;
|
||||||
|
u8 pad2[2];
|
||||||
|
} PACKED irsPackedMomentProcessorConfig;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u64 unk_x0;
|
||||||
|
u32 unk_x8;
|
||||||
|
u32 unk_xc;
|
||||||
|
u8 unk_x10;
|
||||||
|
u8 pad[7];
|
||||||
|
u32 unk_x18;
|
||||||
|
} irsImageTransferProcessorConfig;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u64 unk_x0;
|
||||||
|
u8 unk_x8;
|
||||||
|
u8 unk_x9;
|
||||||
|
u8 unk_xa;
|
||||||
|
u8 pad[5];
|
||||||
|
u32 unk_constant;//offset 0x10
|
||||||
|
u8 unk_x14;
|
||||||
|
u8 pad2[3];
|
||||||
|
} irsPackedImageTransferProcessorConfig;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u8 unk_x0[0x10];
|
||||||
|
} PACKED irsImageTransferProcessorState;
|
||||||
|
|
||||||
Result irsInitialize(void);
|
Result irsInitialize(void);
|
||||||
void irsExit(void);
|
void irsExit(void);
|
||||||
|
|
||||||
@ -20,3 +59,24 @@ void* irsGetSharedmemAddr(void);
|
|||||||
Result irsActivateIrsensor(bool activate);
|
Result irsActivateIrsensor(bool activate);
|
||||||
|
|
||||||
Result irsGetIrCameraHandle(u32 *IrCameraHandle, HidControllerID id);
|
Result irsGetIrCameraHandle(u32 *IrCameraHandle, HidControllerID id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Start ImageTransferProcessor.
|
||||||
|
* @param[in] IrCameraHandle Camera handle.
|
||||||
|
* @param[in] config Input config.
|
||||||
|
* @param[in] size Work-buffer size, must be 0x1000-byte aligned.
|
||||||
|
* @note Do not use if already started.
|
||||||
|
*/
|
||||||
|
Result irsRunImageTransferProcessor(u32 IrCameraHandle, irsImageTransferProcessorConfig *config, size_t size);
|
||||||
|
|
||||||
|
Result irsGetImageTransferProcessorState(u32 IrCameraHandle, void* buffer, size_t size, irsImageTransferProcessorState *state);
|
||||||
|
|
||||||
|
/// Stop ImageTransferProcessor. Do not use if already stopped.
|
||||||
|
/// \ref irsExit calls this with all IrCameraHandles which were not already used with \ref irsStopImageProcessor.
|
||||||
|
Result irsStopImageProcessor(u32 IrCameraHandle);
|
||||||
|
|
||||||
|
/// "Suspend" ImageTransferProcessor.
|
||||||
|
/// TODO: What does this really do?
|
||||||
|
Result irsSuspendImageProcessor(u32 IrCameraHandle);
|
||||||
|
|
||||||
|
void irsGetDefaultImageTransferProcessorConfig(irsImageTransferProcessorConfig *config);
|
||||||
|
@ -7,10 +7,19 @@
|
|||||||
#include "services/hid.h"
|
#include "services/hid.h"
|
||||||
#include "services/sm.h"
|
#include "services/sm.h"
|
||||||
#include "kernel/shmem.h"
|
#include "kernel/shmem.h"
|
||||||
|
#include "kernel/tmem.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool initialized;
|
||||||
|
u32 IrCameraHandle;
|
||||||
|
TransferMemory transfermem;
|
||||||
|
} irsCameraEntry;
|
||||||
|
|
||||||
static Service g_irsSrv;
|
static Service g_irsSrv;
|
||||||
static SharedMemory g_irsSharedmem;
|
static SharedMemory g_irsSharedmem;
|
||||||
bool g_irsSensorActivated;
|
static bool g_irsSensorActivated;
|
||||||
|
|
||||||
|
static irsCameraEntry g_irsCameras[8];
|
||||||
|
|
||||||
static Result _irsGetIrsensorSharedMemoryHandle(Handle* handle_out, u64 AppletResourceUserId);
|
static Result _irsGetIrsensorSharedMemoryHandle(Handle* handle_out, u64 AppletResourceUserId);
|
||||||
|
|
||||||
@ -23,6 +32,9 @@ Result irsInitialize(void)
|
|||||||
Handle sharedmem_handle;
|
Handle sharedmem_handle;
|
||||||
u64 AppletResourceUserId=0;
|
u64 AppletResourceUserId=0;
|
||||||
|
|
||||||
|
g_irsSensorActivated = 0;
|
||||||
|
memset(g_irsCameras, 0, sizeof(g_irsCameras));
|
||||||
|
|
||||||
rc = appletGetAppletResourceUserId(&AppletResourceUserId);
|
rc = appletGetAppletResourceUserId(&AppletResourceUserId);
|
||||||
if (R_FAILED(rc))
|
if (R_FAILED(rc))
|
||||||
return rc;
|
return rc;
|
||||||
@ -48,12 +60,75 @@ Result irsInitialize(void)
|
|||||||
|
|
||||||
void irsExit(void)
|
void irsExit(void)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
size_t entrycount = sizeof(g_irsCameras)/sizeof(irsCameraEntry);
|
||||||
|
irsCameraEntry *entry;
|
||||||
|
|
||||||
|
for(i=0; i<entrycount; i++) {
|
||||||
|
entry = &g_irsCameras[i];
|
||||||
|
if (!entry->initialized) continue;
|
||||||
|
irsStopImageProcessor(entry->IrCameraHandle);
|
||||||
|
}
|
||||||
|
|
||||||
irsActivateIrsensor(0);
|
irsActivateIrsensor(0);
|
||||||
|
|
||||||
serviceClose(&g_irsSrv);
|
serviceClose(&g_irsSrv);
|
||||||
shmemClose(&g_irsSharedmem);
|
shmemClose(&g_irsSharedmem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Result _irsCameraEntryAlloc(u32 IrCameraHandle, irsCameraEntry **out_entry) {
|
||||||
|
int i;
|
||||||
|
size_t entrycount = sizeof(g_irsCameras)/sizeof(irsCameraEntry);
|
||||||
|
int empty_entry = -1;
|
||||||
|
irsCameraEntry *entry;
|
||||||
|
|
||||||
|
if (out_entry) *out_entry = NULL;
|
||||||
|
|
||||||
|
for(i=0; i<entrycount; i++) {
|
||||||
|
entry = &g_irsCameras[i];
|
||||||
|
if (entry->initialized) {
|
||||||
|
if (entry->IrCameraHandle == IrCameraHandle)
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized);
|
||||||
|
}
|
||||||
|
else if (empty_entry == -1)
|
||||||
|
empty_entry = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty_entry == -1)
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized);
|
||||||
|
|
||||||
|
entry = &g_irsCameras[empty_entry];
|
||||||
|
|
||||||
|
entry->initialized = 1;
|
||||||
|
entry->IrCameraHandle = IrCameraHandle;
|
||||||
|
|
||||||
|
if (out_entry) *out_entry = entry;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Result _irsCameraEntryGet(u32 IrCameraHandle, irsCameraEntry **out_entry) {
|
||||||
|
int i;
|
||||||
|
size_t entrycount = sizeof(g_irsCameras)/sizeof(irsCameraEntry);
|
||||||
|
irsCameraEntry *entry;
|
||||||
|
*out_entry = NULL;
|
||||||
|
|
||||||
|
for(i=0; i<entrycount; i++) {
|
||||||
|
entry = &g_irsCameras[i];
|
||||||
|
if (entry->initialized && entry->IrCameraHandle == IrCameraHandle) {
|
||||||
|
*out_entry = entry;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _irsCameraEntryFree(irsCameraEntry *entry) {
|
||||||
|
tmemClose(&entry->transfermem);
|
||||||
|
memset(entry, 0, sizeof(irsCameraEntry));
|
||||||
|
}
|
||||||
|
|
||||||
Service* irsGetSessionService(void) {
|
Service* irsGetSessionService(void) {
|
||||||
return &g_irsSrv;
|
return &g_irsSrv;
|
||||||
}
|
}
|
||||||
@ -147,6 +222,204 @@ static Result _irsGetIrsensorSharedMemoryHandle(Handle* handle_out, u64 AppletRe
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Result _irsStopImageProcessor(u32 IrCameraHandle, u64 AppletResourceUserId) {
|
||||||
|
IpcCommand c;
|
||||||
|
ipcInitialize(&c);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 cmd_id;
|
||||||
|
u32 IrCameraHandle;
|
||||||
|
u64 AppletResourceUserId;
|
||||||
|
} *raw;
|
||||||
|
|
||||||
|
ipcSendPid(&c);
|
||||||
|
|
||||||
|
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||||
|
|
||||||
|
raw->magic = SFCI_MAGIC;
|
||||||
|
raw->cmd_id = 305;
|
||||||
|
raw->IrCameraHandle = IrCameraHandle;
|
||||||
|
raw->AppletResourceUserId = AppletResourceUserId;
|
||||||
|
|
||||||
|
Result rc = serviceIpcDispatch(&g_irsSrv);
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
IpcParsedCommand r;
|
||||||
|
ipcParse(&r);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 result;
|
||||||
|
} *resp = r.Raw;
|
||||||
|
|
||||||
|
rc = resp->result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result irsStopImageProcessor(u32 IrCameraHandle) {
|
||||||
|
Result rc=0;
|
||||||
|
u64 AppletResourceUserId=0;
|
||||||
|
irsCameraEntry *entry = NULL;
|
||||||
|
|
||||||
|
if (!serviceIsActive(&g_irsSrv))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||||
|
|
||||||
|
rc = appletGetAppletResourceUserId(&AppletResourceUserId);
|
||||||
|
if (R_FAILED(rc))
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
rc = _irsCameraEntryGet(IrCameraHandle, &entry);
|
||||||
|
if (R_FAILED(rc))
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
if (entry->transfermem.handle == INVALID_HANDLE)
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||||
|
|
||||||
|
rc = _irsStopImageProcessor(IrCameraHandle, AppletResourceUserId);
|
||||||
|
_irsCameraEntryFree(entry);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Result _irsRunImageTransferProcessor(u32 IrCameraHandle, u64 AppletResourceUserId, irsPackedImageTransferProcessorConfig *config, Handle transfermem, u64 transfermem_size) {
|
||||||
|
IpcCommand c;
|
||||||
|
ipcInitialize(&c);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 cmd_id;
|
||||||
|
u32 IrCameraHandle;
|
||||||
|
u64 AppletResourceUserId;
|
||||||
|
irsPackedImageTransferProcessorConfig config;
|
||||||
|
u64 TransferMemory_size;
|
||||||
|
} *raw;
|
||||||
|
|
||||||
|
ipcSendPid(&c);
|
||||||
|
ipcSendHandleCopy(&c, transfermem);
|
||||||
|
|
||||||
|
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||||
|
|
||||||
|
raw->magic = SFCI_MAGIC;
|
||||||
|
raw->cmd_id = 308;
|
||||||
|
raw->IrCameraHandle = IrCameraHandle;
|
||||||
|
raw->AppletResourceUserId = AppletResourceUserId;
|
||||||
|
raw->TransferMemory_size = transfermem_size;
|
||||||
|
|
||||||
|
memcpy(&raw->config, config, sizeof(raw->config));
|
||||||
|
|
||||||
|
Result rc = serviceIpcDispatch(&g_irsSrv);
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
IpcParsedCommand r;
|
||||||
|
ipcParse(&r);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 result;
|
||||||
|
} *resp = r.Raw;
|
||||||
|
|
||||||
|
rc = resp->result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result irsRunImageTransferProcessor(u32 IrCameraHandle, irsImageTransferProcessorConfig *config, size_t size) {
|
||||||
|
Result rc=0;
|
||||||
|
u64 AppletResourceUserId=0;
|
||||||
|
irsCameraEntry *entry = NULL;
|
||||||
|
irsPackedImageTransferProcessorConfig packed_config;
|
||||||
|
|
||||||
|
memset(&packed_config, 0, sizeof(packed_config));
|
||||||
|
|
||||||
|
packed_config.unk_x0 = config->unk_x0;
|
||||||
|
packed_config.unk_x8 = config->unk_x8;
|
||||||
|
packed_config.unk_x9 = config->unk_xc;
|
||||||
|
packed_config.unk_xa = config->unk_x10;
|
||||||
|
packed_config.unk_constant = 0xa0003;
|
||||||
|
packed_config.unk_x14 = config->unk_x18;
|
||||||
|
|
||||||
|
rc = appletGetAppletResourceUserId(&AppletResourceUserId);
|
||||||
|
if (R_FAILED(rc))
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
rc = _irsCameraEntryAlloc(IrCameraHandle, &entry);
|
||||||
|
if (R_FAILED(rc))
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
rc = tmemCreate(&entry->transfermem, size, Perm_None);
|
||||||
|
if (R_FAILED(rc)) return rc;
|
||||||
|
|
||||||
|
rc = _irsRunImageTransferProcessor(IrCameraHandle, AppletResourceUserId, &packed_config, entry->transfermem.handle, size);
|
||||||
|
|
||||||
|
if (R_FAILED(rc)) _irsCameraEntryFree(entry);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Result _irsGetImageTransferProcessorState(u32 IrCameraHandle, u64 AppletResourceUserId, void* buffer, size_t size, irsImageTransferProcessorState *state) {
|
||||||
|
IpcCommand c;
|
||||||
|
ipcInitialize(&c);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 cmd_id;
|
||||||
|
u32 IrCameraHandle;
|
||||||
|
u64 AppletResourceUserId;
|
||||||
|
} *raw;
|
||||||
|
|
||||||
|
ipcSendPid(&c);
|
||||||
|
ipcAddRecvBuffer(&c, buffer, size, 0);
|
||||||
|
|
||||||
|
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||||
|
|
||||||
|
raw->magic = SFCI_MAGIC;
|
||||||
|
raw->cmd_id = 309;
|
||||||
|
raw->IrCameraHandle = IrCameraHandle;
|
||||||
|
raw->AppletResourceUserId = AppletResourceUserId;
|
||||||
|
|
||||||
|
Result rc = serviceIpcDispatch(&g_irsSrv);
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
IpcParsedCommand r;
|
||||||
|
ipcParse(&r);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 result;
|
||||||
|
irsImageTransferProcessorState state;
|
||||||
|
} *resp = r.Raw;
|
||||||
|
|
||||||
|
rc = resp->result;
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc) && state)
|
||||||
|
memcpy(state, &resp->state, sizeof(irsImageTransferProcessorState));
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result irsGetImageTransferProcessorState(u32 IrCameraHandle, void* buffer, size_t size, irsImageTransferProcessorState *state) {
|
||||||
|
Result rc=0;
|
||||||
|
u64 AppletResourceUserId=0;
|
||||||
|
|
||||||
|
rc = appletGetAppletResourceUserId(&AppletResourceUserId);
|
||||||
|
if (R_FAILED(rc))
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
rc = _irsGetImageTransferProcessorState(IrCameraHandle, AppletResourceUserId, buffer, size, state);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void irsGetDefaultImageTransferProcessorConfig(irsImageTransferProcessorConfig *config) {
|
||||||
|
memset(config, 0, sizeof(irsImageTransferProcessorConfig));
|
||||||
|
|
||||||
|
config->unk_x0 = 0x493E0;
|
||||||
|
config->unk_xc = 0x8;
|
||||||
|
}
|
||||||
|
|
||||||
Result irsGetIrCameraHandle(u32 *IrCameraHandle, HidControllerID id) {
|
Result irsGetIrCameraHandle(u32 *IrCameraHandle, HidControllerID id) {
|
||||||
IpcCommand c;
|
IpcCommand c;
|
||||||
ipcInitialize(&c);
|
ipcInitialize(&c);
|
||||||
@ -185,3 +458,52 @@ Result irsGetIrCameraHandle(u32 *IrCameraHandle, HidControllerID id) {
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Result _irsSuspendImageProcessor(u32 IrCameraHandle, u64 AppletResourceUserId) {
|
||||||
|
IpcCommand c;
|
||||||
|
ipcInitialize(&c);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 cmd_id;
|
||||||
|
u32 IrCameraHandle;
|
||||||
|
u64 AppletResourceUserId;
|
||||||
|
} *raw;
|
||||||
|
|
||||||
|
ipcSendPid(&c);
|
||||||
|
|
||||||
|
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||||
|
|
||||||
|
raw->magic = SFCI_MAGIC;
|
||||||
|
raw->cmd_id = 313;
|
||||||
|
raw->IrCameraHandle = IrCameraHandle;
|
||||||
|
raw->AppletResourceUserId = AppletResourceUserId;
|
||||||
|
|
||||||
|
Result rc = serviceIpcDispatch(&g_irsSrv);
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
IpcParsedCommand r;
|
||||||
|
ipcParse(&r);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 result;
|
||||||
|
} *resp = r.Raw;
|
||||||
|
|
||||||
|
rc = resp->result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result irsSuspendImageProcessor(u32 IrCameraHandle) {
|
||||||
|
Result rc=0;
|
||||||
|
u64 AppletResourceUserId=0;
|
||||||
|
|
||||||
|
rc = appletGetAppletResourceUserId(&AppletResourceUserId);
|
||||||
|
if (R_FAILED(rc))
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
rc = _irsSuspendImageProcessor(IrCameraHandle, AppletResourceUserId);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user