diff --git a/include/applets/applet.hpp b/include/applets/applet.hpp index 8087ab82..98fb6c20 100644 --- a/include/applets/applet.hpp +++ b/include/applets/applet.hpp @@ -1,6 +1,9 @@ #pragma once +#include + #include "helpers.hpp" +#include "kernel/kernel_types.hpp" #include "memory.hpp" #include "result/result.hpp" @@ -65,11 +68,11 @@ namespace Applets { }; struct Parameter { - u32 senderID; // ID of the parameter sender - u32 destID; // ID of the app to receive parameter - u32 signal; // Signal type (eg request) - u32 object; // Some applets will also respond with shared memory handles for transferring data between the sender and called - std::vector data; // Misc data + u32 senderID; // ID of the parameter sender + u32 destID; // ID of the app to receive parameter + u32 signal; // Signal type (eg request) + u32 object; // Some applets will also respond with shared memory handles for transferring data between the sender and called + std::vector data; // Misc data }; class AppletBase { @@ -81,7 +84,7 @@ namespace Applets { virtual const char* name() = 0; // Called by APT::StartLibraryApplet and similar - virtual Result::HorizonResult start() = 0; + virtual Result::HorizonResult start(const MemoryBlock& sharedMem, const std::vector& parameters) = 0; // Transfer parameters from application -> applet virtual Result::HorizonResult receiveParameter(const Parameter& parameter) = 0; virtual void reset() = 0; diff --git a/include/applets/mii_selector.hpp b/include/applets/mii_selector.hpp index c90d4b59..8bd757dd 100644 --- a/include/applets/mii_selector.hpp +++ b/include/applets/mii_selector.hpp @@ -4,7 +4,7 @@ namespace Applets { class MiiSelectorApplet final : public AppletBase { public: virtual const char* name() override { return "Mii Selector"; } - virtual Result::HorizonResult start() override; + virtual Result::HorizonResult start(const MemoryBlock& sharedMem, const std::vector& parameters) override; virtual Result::HorizonResult receiveParameter(const Applets::Parameter& parameter) override; virtual void reset() override; diff --git a/include/applets/software_keyboard.hpp b/include/applets/software_keyboard.hpp index f4179012..785ba20a 100644 --- a/include/applets/software_keyboard.hpp +++ b/include/applets/software_keyboard.hpp @@ -4,7 +4,7 @@ namespace Applets { class SoftwareKeyboardApplet final : public AppletBase { public: virtual const char* name() override { return "Software Keyboard"; } - virtual Result::HorizonResult start() override; + virtual Result::HorizonResult start(const MemoryBlock& sharedMem, const std::vector& parameters) override; virtual Result::HorizonResult receiveParameter(const Applets::Parameter& parameter) override; virtual void reset() override; diff --git a/src/core/applets/mii_selector.cpp b/src/core/applets/mii_selector.cpp index 6a06a01a..ed1c4ad2 100644 --- a/src/core/applets/mii_selector.cpp +++ b/src/core/applets/mii_selector.cpp @@ -5,7 +5,7 @@ using namespace Applets; void MiiSelectorApplet::reset() {} -Result::HorizonResult MiiSelectorApplet::start() { return Result::Success; } +Result::HorizonResult MiiSelectorApplet::start(const MemoryBlock& sharedMem, const std::vector& parameters) { return Result::Success; } Result::HorizonResult MiiSelectorApplet::receiveParameter(const Applets::Parameter& parameter) { Helpers::warn("Mii Selector: Unimplemented ReceiveParameter"); diff --git a/src/core/applets/software_keyboard.cpp b/src/core/applets/software_keyboard.cpp index fd5f4afe..07259d0d 100644 --- a/src/core/applets/software_keyboard.cpp +++ b/src/core/applets/software_keyboard.cpp @@ -5,19 +5,28 @@ using namespace Applets; void SoftwareKeyboardApplet::reset() {} -Result::HorizonResult SoftwareKeyboardApplet::start() { return Result::Success; } +Result::HorizonResult SoftwareKeyboardApplet::start(const MemoryBlock& sharedMem, const std::vector& parameters) { return Result::Success; } Result::HorizonResult SoftwareKeyboardApplet::receiveParameter(const Applets::Parameter& parameter) { Helpers::warn("Software keyboard: Unimplemented ReceiveParameter"); - Applets::Parameter param = Applets::Parameter{ - .senderID = parameter.destID, - .destID = AppletIDs::Application, - .signal = static_cast(APTSignal::Response), - .object = KernelHandles::APTCaptureSharedMemHandle, - .data = {}, - }; + switch (parameter.signal) { + // Signal == request -> Applet is asking swkbd for a shared memory handle for backing up the framebuffer before opening the applet + case u32(APTSignal::Request): { + Applets::Parameter param = Applets::Parameter{ + .senderID = parameter.destID, + .destID = AppletIDs::Application, + .signal = static_cast(APTSignal::Response), + .object = KernelHandles::APTCaptureSharedMemHandle, + .data = {}, + }; + + nextParameter = param; + break; + } + + default: Helpers::panic("SWKBD SIGNAL %d\n", parameter.signal); + } - nextParameter = param; return Result::Success; } \ No newline at end of file diff --git a/src/core/services/apt.cpp b/src/core/services/apt.cpp index 25d063c1..b2f3e849 100644 --- a/src/core/services/apt.cpp +++ b/src/core/services/apt.cpp @@ -64,6 +64,7 @@ void APTService::handleSyncRequest(u32 messagePointer) { case APTCommands::NotifyToWait: notifyToWait(messagePointer); break; case APTCommands::PreloadLibraryApplet: preloadLibraryApplet(messagePointer); break; case APTCommands::PrepareToStartLibraryApplet: prepareToStartLibraryApplet(messagePointer); break; + case APTCommands::StartLibraryApplet: startLibraryApplet(messagePointer); break; case APTCommands::ReceiveParameter: [[likely]] receiveParameter(messagePointer); break; case APTCommands::ReplySleepQuery: replySleepQuery(messagePointer); break; case APTCommands::SetApplicationCpuTimeLimit: setApplicationCpuTimeLimit(messagePointer); break; @@ -140,6 +141,43 @@ void APTService::prepareToStartLibraryApplet(u32 messagePointer) { mem.write32(messagePointer + 4, Result::Success); } +void APTService::startLibraryApplet(u32 messagePointer) { + const u32 appID = mem.read32(messagePointer + 4); + const u32 bufferSize = mem.read32(messagePointer + 8); + const Handle parameters = mem.read32(messagePointer + 16); + const u32 buffer = mem.read32(messagePointer + 24); + log("APT::StartLibraryApplet (app ID = %X)\n", appID); + + mem.write32(messagePointer, IPC::responseHeader(0x16, 1, 0)); + mem.write32(messagePointer + 4, Result::Success); + + Applets::AppletBase* destApplet = appletManager.getApplet(appID); + if (destApplet == nullptr) { + Helpers::warn("APT::StartLibraryApplet: Unimplemented dest applet ID"); + } else { + KernelObject* sharedMemObject = kernel.getObject(parameters); + if (sharedMemObject == nullptr) { + Helpers::warn("Couldn't find shared memory block\n"); + return; + } + + const MemoryBlock* sharedMem = sharedMemObject->getData(); + std::vector data; + data.reserve(bufferSize); + + for (u32 i = 0; i < bufferSize; i++) { + data.push_back(mem.read8(buffer + i)); + } + + Helpers::warn("DONE STARTED DAT STUFF"); + destApplet->start(*sharedMem, data); + + if (resumeEvent.has_value()) { + kernel.signalEvent(resumeEvent.value()); + } + } +} + void APTService::checkNew3DS(u32 messagePointer) { log("APT::CheckNew3DS\n"); mem.write32(messagePointer, IPC::responseHeader(0x102, 2, 0)); @@ -222,7 +260,7 @@ void APTService::sendParameter(u32 messagePointer) { const u32 parameterHandle = mem.read32(messagePointer + 24); // What dis? const u32 parameterPointer = mem.read32(messagePointer + 32); - log("APT::SendParameter (source app = %X, dest app = %X, cmd = %X, size = %X) (Stubbed)", sourceAppID, destAppID, cmd, paramSize); + log("APT::SendParameter (source app = %X, dest app = %X, cmd = %X, size = %X)", sourceAppID, destAppID, cmd, paramSize); mem.write32(messagePointer, IPC::responseHeader(0x0C, 1, 0)); mem.write32(messagePointer + 4, Result::Success); @@ -260,7 +298,7 @@ void APTService::sendParameter(u32 messagePointer) { void APTService::receiveParameter(u32 messagePointer) { const u32 app = mem.read32(messagePointer + 4); const u32 size = mem.read32(messagePointer + 8); - log("APT::ReceiveParameter(app ID = %X, size = %04X) (STUBBED)\n", app, size); + log("APT::ReceiveParameter(app ID = %X, size = %04X)\n", app, size); if (size > 0x1000) Helpers::panic("APT::ReceiveParameter with size > 0x1000"); auto parameter = appletManager.receiveParameter(); @@ -281,7 +319,7 @@ void APTService::receiveParameter(u32 messagePointer) { void APTService::glanceParameter(u32 messagePointer) { const u32 app = mem.read32(messagePointer + 4); const u32 size = mem.read32(messagePointer + 8); - log("APT::GlanceParameter(app ID = %X, size = %04X) (STUBBED)\n", app, size); + log("APT::GlanceParameter(app ID = %X, size = %04X)\n", app, size); if (size > 0x1000) Helpers::panic("APT::GlanceParameter with size > 0x1000"); auto parameter = appletManager.glanceParameter();