From 3935820c051fdd7dc4f929dcdcec8925b57bb0b5 Mon Sep 17 00:00:00 2001 From: wheremyfoodat Date: Mon, 24 Apr 2023 21:33:59 +0300 Subject: [PATCH] [ACT/MIC/NFC] Stub function for Captain Toad --- CMakeLists.txt | 3 ++- include/kernel/handles.hpp | 8 +++++-- include/logger.hpp | 2 ++ include/services/act.hpp | 19 +++++++++++++++ include/services/mic.hpp | 1 + include/services/nfc.hpp | 19 +++++++++++++++ include/services/service_manager.hpp | 4 ++++ src/core/services/act.cpp | 31 +++++++++++++++++++++++++ src/core/services/mic.cpp | 16 ++++++++++++- src/core/services/nfc.cpp | 33 +++++++++++++++++++++++++++ src/core/services/service_manager.cpp | 17 ++++++++++---- 11 files changed, 144 insertions(+), 9 deletions(-) create mode 100644 include/services/act.hpp create mode 100644 include/services/nfc.hpp create mode 100644 src/core/services/act.cpp create mode 100644 src/core/services/nfc.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 401b2494..d023e8a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,6 +64,7 @@ set(SERVICE_SOURCE_FILES src/core/services/service_manager.cpp src/core/services src/core/services/ac.cpp src/core/services/am.cpp src/core/services/boss.cpp src/core/services/frd.cpp src/core/services/nim.cpp src/core/services/shared_font.cpp src/core/services/y2r.cpp src/core/services/cam.cpp src/core/services/ldr_ro.cpp + src/core/services/act.cpp src/core/services/nfc.cpp ) set(PICA_SOURCE_FILES src/core/PICA/gpu.cpp src/core/PICA/regs.cpp src/core/PICA/shader_unit.cpp src/core/PICA/shader_interpreter.cpp @@ -92,7 +93,7 @@ set(HEADER_FILES include/emulator.hpp include/helpers.hpp include/opengl.hpp inc include/services/am.hpp include/services/boss.hpp include/services/frd.hpp include/services/nim.hpp include/fs/archive_ext_save_data.hpp include/services/shared_font.hpp include/fs/archive_ncch.hpp include/renderer_gl/textures.hpp include/colour.hpp include/services/y2r.hpp include/services/cam.hpp - include/services/ldr_ro.hpp include/ipc.hpp + include/services/ldr_ro.hpp include/ipc.hpp include/services/act.hpp include/services/nfc.hpp ) set(THIRD_PARTY_SOURCE_FILES third_party/imgui/imgui.cpp diff --git a/include/kernel/handles.hpp b/include/kernel/handles.hpp index 21fb4e92..32616c97 100644 --- a/include/kernel/handles.hpp +++ b/include/kernel/handles.hpp @@ -11,6 +11,7 @@ namespace KernelHandles { CurrentThread = 0xFFFF8000, // Used by the original kernel CurrentProcess = 0xFFFF8001, // Used by the original kernel AC, // Something network related + ACT, // Handles NNID accounts AM, // Application manager APT, // App Title something service? BOSS, // Streetpass stuff? @@ -25,6 +26,7 @@ namespace KernelHandles { LCD, // LCD service (Used for configuring the displays) LDR_RO, // Loader service. Used for loading CROs. MIC, // MIC service (Controls the microphone) + NFC, // NFC (Duh), used for Amiibo NIM, // Updates, DLC, etc NDM, // ????? PTM, // PTM service (Used for accessing various console info, such as battery, shell and pedometer state) @@ -61,6 +63,7 @@ namespace KernelHandles { static const char* getServiceName(Handle handle) { switch (handle) { case AC: return "AC"; + case ACT: return "ACT"; case AM: return "AM"; case APT: return "APT"; case BOSS: return "BOSS"; @@ -71,11 +74,12 @@ namespace KernelHandles { case FRD: return "FRD"; case FS: return "FS"; case DSP: return "DSP"; - case GPU: return "GPU"; - case LCD: return "LCD"; + case GPU: return "GSP::GPU"; + case LCD: return "GSP::LCD"; case LDR_RO: return "LDR:RO"; case MIC: return "MIC"; case NDM: return "NDM"; + case NFC: return "NFC"; case NIM: return "NIM"; case PTM: return "PTM"; case Y2R: return "Y2R"; diff --git a/include/logger.hpp b/include/logger.hpp index 51505f10..5ffd707b 100644 --- a/include/logger.hpp +++ b/include/logger.hpp @@ -30,6 +30,7 @@ namespace Log { // Service loggers static Logger acLogger; + static Logger actLogger; static Logger amLogger; static Logger aptLogger; static Logger bossLogger; @@ -44,6 +45,7 @@ namespace Log { static Logger gspLCDLogger; static Logger ldrLogger; static Logger micLogger; + static Logger nfcLogger; static Logger nimLogger; static Logger ndmLogger; static Logger ptmLogger; diff --git a/include/services/act.hpp b/include/services/act.hpp new file mode 100644 index 00000000..5502447a --- /dev/null +++ b/include/services/act.hpp @@ -0,0 +1,19 @@ +#pragma once +#include "helpers.hpp" +#include "kernel_types.hpp" +#include "logger.hpp" +#include "memory.hpp" + +class ACTService { + Handle handle = KernelHandles::ACT; + Memory& mem; + MAKE_LOG_FUNCTION(log, actLogger) + + // Service commands + void initialize(u32 messagePointer); + +public: + ACTService(Memory& mem) : mem(mem) {} + void reset(); + void handleSyncRequest(u32 messagePointer); +}; \ No newline at end of file diff --git a/include/services/mic.hpp b/include/services/mic.hpp index ce8d1a4a..943734e1 100644 --- a/include/services/mic.hpp +++ b/include/services/mic.hpp @@ -16,6 +16,7 @@ class MICService { void setGain(u32 messagePointer); void setPower(u32 messagePointer); void startSampling(u32 messagePointer); + void theCaptainToadFunction(u32 messagePointer); u8 gain = 0; // How loud our microphone input signal is bool micEnabled = false; diff --git a/include/services/nfc.hpp b/include/services/nfc.hpp new file mode 100644 index 00000000..13a1a380 --- /dev/null +++ b/include/services/nfc.hpp @@ -0,0 +1,19 @@ +#pragma once +#include "helpers.hpp" +#include "kernel_types.hpp" +#include "logger.hpp" +#include "memory.hpp" + +class NFCService { + Handle handle = KernelHandles::NFC; + Memory& mem; + MAKE_LOG_FUNCTION(log, nfcLogger) + + // Service commands + void initialize(u32 messagePointer); + +public: + NFCService(Memory& mem) : mem(mem) {} + void reset(); + void handleSyncRequest(u32 messagePointer); +}; \ No newline at end of file diff --git a/include/services/service_manager.hpp b/include/services/service_manager.hpp index a174906b..8751de66 100644 --- a/include/services/service_manager.hpp +++ b/include/services/service_manager.hpp @@ -5,6 +5,7 @@ #include "logger.hpp" #include "memory.hpp" #include "services/ac.hpp" +#include "services/act.hpp" #include "services/am.hpp" #include "services/apt.hpp" #include "services/boss.hpp" @@ -19,6 +20,7 @@ #include "services/gsp_lcd.hpp" #include "services/ldr_ro.hpp" #include "services/mic.hpp" +#include "services/nfc.hpp" #include "services/nim.hpp" #include "services/ndm.hpp" #include "services/ptm.hpp" @@ -37,6 +39,7 @@ class ServiceManager { MAKE_LOG_FUNCTION(log, srvLogger) ACService ac; + ACTService act; AMService am; APTService apt; BOSSService boss; @@ -51,6 +54,7 @@ class ServiceManager { LCDService gsp_lcd; LDRService ldr; MICService mic; + NFCService nfc; NIMService nim; NDMService ndm; PTMService ptm; diff --git a/src/core/services/act.cpp b/src/core/services/act.cpp new file mode 100644 index 00000000..7f2f34f7 --- /dev/null +++ b/src/core/services/act.cpp @@ -0,0 +1,31 @@ +#include "services/act.hpp" +#include "ipc.hpp" + +namespace ACTCommands { + enum : u32 { + Initialize = 0x00010084 + }; +} + +namespace Result { + enum : u32 { + Success = 0, + }; +} + +void ACTService::reset() {} + +void ACTService::handleSyncRequest(u32 messagePointer) { + const u32 command = mem.read32(messagePointer); + switch (command) { + case ACTCommands::Initialize: initialize(messagePointer); break; + default: Helpers::panic("ACT service requested. Command: %08X\n", command); + } +} + +void ACTService::initialize(u32 messagePointer) { + log("ACT::Initialize"); + + mem.write32(messagePointer, IPC::responseHeader(0x1, 1, 0)); + mem.write32(messagePointer + 4, Result::Success); +} \ No newline at end of file diff --git a/src/core/services/mic.cpp b/src/core/services/mic.cpp index 828fb1e4..83349a67 100644 --- a/src/core/services/mic.cpp +++ b/src/core/services/mic.cpp @@ -8,7 +8,8 @@ namespace MICCommands { SetGain = 0x00080040, GetGain = 0x00090000, SetPower = 0x000A0040, - SetClamp = 0x000D0040 + SetClamp = 0x000D0040, + CaptainToadFunction = 0x00100040 }; } @@ -33,6 +34,7 @@ void MICService::handleSyncRequest(u32 messagePointer) { case MICCommands::SetGain: setGain(messagePointer); break; case MICCommands::SetPower: setPower(messagePointer); break; case MICCommands::StartSampling: startSampling(messagePointer); break; + case MICCommands::CaptainToadFunction: theCaptainToadFunction(messagePointer); break; default: Helpers::panic("MIC service requested. Command: %08X\n", command); } } @@ -92,4 +94,16 @@ void MICService::startSampling(u32 messagePointer) { mem.write32(messagePointer, IPC::responseHeader(0x3, 1, 0)); mem.write32(messagePointer + 4, Result::Success); +} + +// Found in Captain Toad: Treasure Tracker +// This is what 3DBrew says: +// When the input value is 0, value 1 is written to an u8 MIC module state field. +// Otherwise, value 0 is written there.Normally the input value is non - zero. +// Citra calls it setClientVersion but no idea how they got that +void MICService::theCaptainToadFunction(u32 messagePointer) { + log("MIC: Unknown function 0x00100040\n"); + + mem.write32(messagePointer, IPC::responseHeader(0x10, 1, 0)); + mem.write32(messagePointer + 4, Result::Success); } \ No newline at end of file diff --git a/src/core/services/nfc.cpp b/src/core/services/nfc.cpp new file mode 100644 index 00000000..798f465a --- /dev/null +++ b/src/core/services/nfc.cpp @@ -0,0 +1,33 @@ +#include "services/nfc.hpp" +#include "ipc.hpp" + +namespace NFCCommands { + enum : u32 { + Initialize = 0x00010040 + }; +} + +namespace Result { + enum : u32 { + Success = 0, + }; +} + +void NFCService::reset() {} + +void NFCService::handleSyncRequest(u32 messagePointer) { + const u32 command = mem.read32(messagePointer); + switch (command) { + case NFCCommands::Initialize: initialize(messagePointer); break; + default: Helpers::panic("NFC service requested. Command: %08X\n", command); + } +} + +void NFCService::initialize(u32 messagePointer) { + const u8 type = mem.read8(messagePointer + 4); + log("NFC::Initialize (type = %d)\n", type); + + // TODO: This should error if already initialized. Also sanitize type. + mem.write32(messagePointer, IPC::responseHeader(0x1, 1, 0)); + mem.write32(messagePointer + 4, Result::Success); +} \ No newline at end of file diff --git a/src/core/services/service_manager.cpp b/src/core/services/service_manager.cpp index 64b7be5d..089ee172 100644 --- a/src/core/services/service_manager.cpp +++ b/src/core/services/service_manager.cpp @@ -4,15 +4,16 @@ #include "kernel.hpp" ServiceManager::ServiceManager(std::array& regs, Memory& mem, GPU& gpu, u32& currentPID, Kernel& kernel) - : regs(regs), mem(mem), kernel(kernel), ac(mem), am(mem), boss(mem), apt(mem, kernel), cam(mem), cecd(mem), cfg(mem), - dsp(mem, kernel), hid(mem), frd(mem), fs(mem, kernel), gsp_gpu(mem, gpu, kernel, currentPID), gsp_lcd(mem), ldr(mem), - mic(mem), nim(mem), ndm(mem), ptm(mem), y2r(mem, kernel) {} + : regs(regs), mem(mem), kernel(kernel), ac(mem), am(mem), boss(mem), act(mem), apt(mem, kernel), cam(mem), cecd(mem), + cfg(mem), dsp(mem, kernel), hid(mem), frd(mem), fs(mem, kernel), gsp_gpu(mem, gpu, kernel, currentPID), gsp_lcd(mem), + ldr(mem), mic(mem), nfc(mem), nim(mem), ndm(mem), ptm(mem), y2r(mem, kernel) {} static constexpr int MAX_NOTIFICATION_COUNT = 16; // Reset every single service void ServiceManager::reset() { ac.reset(); + act.reset(); am.reset(); apt.reset(); boss.reset(); @@ -86,6 +87,7 @@ void ServiceManager::registerClient(u32 messagePointer) { static std::map serviceMap = { { "ac:u", KernelHandles::AC }, + { "act:u", KernelHandles::ACT }, { "am:app", KernelHandles::AM }, { "APT:S", KernelHandles::APT }, // TODO: APT:A, APT:S and APT:U are slightly different { "APT:A", KernelHandles::APT }, @@ -103,6 +105,7 @@ static std::map serviceMap = { { "ldr:ro", KernelHandles::LDR_RO }, { "mic:u", KernelHandles::MIC }, { "ndm:u", KernelHandles::NDM }, + { "nfc:u", KernelHandles::NFC }, { "nim:aoc", KernelHandles::NIM }, { "ptm:u", KernelHandles::PTM }, // TODO: ptm:u and ptm:sysm have very different command sets { "ptm:sysm", KernelHandles::PTM }, @@ -162,10 +165,14 @@ void ServiceManager::subscribe(u32 messagePointer) { void ServiceManager::sendCommandToService(u32 messagePointer, Handle handle) { switch (handle) { + // Breaking alphabetical order a bit to place the ones I think are most common at the top case KernelHandles::GPU: [[likely]] gsp_gpu.handleSyncRequest(messagePointer); break; + case KernelHandles::FS: [[likely]] fs.handleSyncRequest(messagePointer); break; + case KernelHandles::APT: [[likely]] apt.handleSyncRequest(messagePointer); break; + case KernelHandles::AC: ac.handleSyncRequest(messagePointer); break; + case KernelHandles::ACT: act.handleSyncRequest(messagePointer); break; case KernelHandles::AM: am.handleSyncRequest(messagePointer); break; - case KernelHandles::APT: apt.handleSyncRequest(messagePointer); break; case KernelHandles::BOSS: boss.handleSyncRequest(messagePointer); break; case KernelHandles::CAM: cam.handleSyncRequest(messagePointer); break; case KernelHandles::CECD: cecd.handleSyncRequest(messagePointer); break; @@ -173,10 +180,10 @@ void ServiceManager::sendCommandToService(u32 messagePointer, Handle handle) { case KernelHandles::DSP: dsp.handleSyncRequest(messagePointer); break; case KernelHandles::HID: hid.handleSyncRequest(messagePointer); break; case KernelHandles::FRD: frd.handleSyncRequest(messagePointer); break; - case KernelHandles::FS: fs.handleSyncRequest(messagePointer); break; case KernelHandles::LCD: gsp_lcd.handleSyncRequest(messagePointer); break; case KernelHandles::LDR_RO: ldr.handleSyncRequest(messagePointer); break; case KernelHandles::MIC: mic.handleSyncRequest(messagePointer); break; + case KernelHandles::NFC: nfc.handleSyncRequest(messagePointer); break; case KernelHandles::NIM: nim.handleSyncRequest(messagePointer); break; case KernelHandles::NDM: ndm.handleSyncRequest(messagePointer); break; case KernelHandles::PTM: ptm.handleSyncRequest(messagePointer); break;