/* * Copyright (c) MasaGratoR * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #pragma once #include "ipc.h" Handle saltysd_orig; Result SaltySD_Connect() { for (int i = 0; i < 200; i++) { if (!svcConnectToNamedPort(&saltysd_orig, "SaltySD")) return 0; svcSleepThread(1000*1000); } return 1; } Result SaltySD_Term() { Result ret; IpcCommand c; ipcInitialize(&c); ipcSendPid(&c); struct input { u64 magic; u64 cmd_id; u64 zero; u64 reserved[2]; } *raw; raw = (input*)ipcPrepareHeader(&c, sizeof(*raw)); raw->magic = SFCI_MAGIC; raw->cmd_id = 0; raw->zero = 0; ret = ipcDispatch(saltysd_orig); if (R_SUCCEEDED(ret)) { IpcParsedCommand r; ipcParse(&r); struct output { u64 magic; u64 result; } *resp = (output*)r.Raw; ret = resp->result; } // Session terminated works too. svcCloseHandle(saltysd_orig); if (ret == 0xf601) return 0; return ret; } Result SaltySD_CheckIfSharedMemoryAvailable(ptrdiff_t *offset, u64 size) { Result ret = 0; // Send a command IpcCommand c; ipcInitialize(&c); ipcSendPid(&c); struct input { u64 magic; u64 cmd_id; u64 size; u32 reserved[2]; } *raw; raw = (input*)ipcPrepareHeader(&c, sizeof(*raw)); raw->magic = SFCI_MAGIC; raw->cmd_id = 6; raw->size = size; ret = ipcDispatch(saltysd_orig); if (R_SUCCEEDED(ret)) { IpcParsedCommand r; ipcParse(&r); struct output { u64 magic; u64 result; u64 offset; } *resp = (output*)r.Raw; ret = resp->result; if (!ret) { *offset = resp->offset; } } return ret; } Result SaltySD_GetSharedMemoryHandle(Handle *retrieve) { Result ret = 0; // Send a command IpcCommand c; ipcInitialize(&c); ipcSendPid(&c); struct input { u64 magic; u64 cmd_id; u32 reserved[4]; } *raw; raw = (input*)ipcPrepareHeader(&c, sizeof(*raw)); raw->magic = SFCI_MAGIC; raw->cmd_id = 7; ret = ipcDispatch(saltysd_orig); if (R_SUCCEEDED(ret)) { IpcParsedCommand r; ipcParse(&r); struct output { u64 magic; u64 result; u64 reserved[2]; } *resp = (output*)r.Raw; ret = resp->result; if (!ret) { *retrieve = r.Handles[0]; } } return ret; } Result SaltySD_GetDisplayRefreshRate(uint8_t* refreshRate) { Result ret = 0; // Send a command IpcCommand c; ipcInitialize(&c); ipcSendPid(&c); struct input { u64 magic; u64 cmd_id; u64 zero; u64 reserved; } *raw; raw = (input*)ipcPrepareHeader(&c, sizeof(*raw)); raw->magic = SFCI_MAGIC; raw->cmd_id = 10; raw->zero = 0; ret = ipcDispatch(saltysd_orig); if (R_SUCCEEDED(ret)) { IpcParsedCommand r; ipcParse(&r); struct output { u64 magic; u64 result; u64 refreshRate; u64 reserved; } *resp = (output*)r.Raw; ret = resp->result; if (!ret) { *refreshRate = (uint8_t)(resp->refreshRate); } } return ret; } Result SaltySD_SetDisplayRefreshRate(uint8_t refreshRate) { Result ret = 0; // Send a command IpcCommand c; ipcInitialize(&c); ipcSendPid(&c); struct input { u64 magic; u64 cmd_id; u64 refreshRate; u64 reserved; } *raw; raw = (input*)ipcPrepareHeader(&c, sizeof(*raw)); raw->magic = SFCI_MAGIC; raw->cmd_id = 11; raw->refreshRate = refreshRate; ret = ipcDispatch(saltysd_orig); if (R_SUCCEEDED(ret)) { IpcParsedCommand r; ipcParse(&r); struct output { u64 magic; u64 result; u64 reserved[2]; } *resp = (output*)r.Raw; ret = resp->result; } return ret; }