diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 02d902bb5..0773339a9 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -27,6 +27,7 @@ set(SRCS hle/config_mem.cpp hle/hle.cpp hle/applets/applet.cpp + hle/applets/erreula.cpp hle/applets/mii_selector.cpp hle/applets/swkbd.cpp hle/kernel/address_arbiter.cpp @@ -168,6 +169,7 @@ set(HEADERS hle/function_wrappers.h hle/hle.h hle/applets/applet.h + hle/applets/erreula.h hle/applets/mii_selector.h hle/applets/swkbd.h hle/kernel/address_arbiter.h diff --git a/src/core/hle/applets/applet.cpp b/src/core/hle/applets/applet.cpp index 90e134437..ccf35fa07 100644 --- a/src/core/hle/applets/applet.cpp +++ b/src/core/hle/applets/applet.cpp @@ -12,6 +12,7 @@ #include "core/core_timing.h" #include "core/hle/applets/applet.h" +#include "core/hle/applets/erreula.h" #include "core/hle/applets/mii_selector.h" #include "core/hle/applets/swkbd.h" #include "core/hle/result.h" @@ -52,6 +53,10 @@ ResultCode Applet::Create(Service::APT::AppletId id) { case Service::APT::AppletId::Ed2: applets[id] = std::make_shared(id); break; + case Service::APT::AppletId::Error: + case Service::APT::AppletId::Error2: + applets[id] = std::make_shared(id); + break; default: LOG_ERROR(Service_APT, "Could not create applet %u", id); // TODO(Subv): Find the right error code diff --git a/src/core/hle/applets/erreula.cpp b/src/core/hle/applets/erreula.cpp new file mode 100644 index 000000000..92a4b2323 --- /dev/null +++ b/src/core/hle/applets/erreula.cpp @@ -0,0 +1,72 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "common/string_util.h" + +#include "core/hle/applets/erreula.h" +#include "core/hle/service/apt/apt.h" + +namespace HLE { +namespace Applets { + +ResultCode ErrEula::ReceiveParameter(const Service::APT::MessageParameter& parameter) { + if (parameter.signal != static_cast(Service::APT::SignalType::LibAppJustStarted)) { + LOG_ERROR(Service_APT, "unsupported signal %u", parameter.signal); + UNIMPLEMENTED(); + // TODO(Subv): Find the right error code + return ResultCode(-1); + } + + // The LibAppJustStarted message contains a buffer with the size of the framebuffer shared memory. + // Create the SharedMemory that will hold the framebuffer data + Service::APT::CaptureBufferInfo capture_info; + ASSERT(sizeof(capture_info) == parameter.buffer.size()); + + memcpy(&capture_info, parameter.buffer.data(), sizeof(capture_info)); + + // TODO: allocated memory never released + using Kernel::MemoryPermission; + // Allocate a heap block of the required size for this applet. + heap_memory = std::make_shared>(capture_info.size); + // Create a SharedMemory that directly points to this heap block. + framebuffer_memory = Kernel::SharedMemory::CreateForApplet(heap_memory, 0, heap_memory->size(), + MemoryPermission::ReadWrite, MemoryPermission::ReadWrite, + "ErrEula Memory"); + + // Send the response message with the newly created SharedMemory + Service::APT::MessageParameter result; + result.signal = static_cast(Service::APT::SignalType::LibAppFinished); + result.buffer.clear(); + result.destination_id = static_cast(Service::APT::AppletId::Application); + result.sender_id = static_cast(id); + result.object = framebuffer_memory; + + Service::APT::SendParameter(result); + return RESULT_SUCCESS; +} + +ResultCode ErrEula::StartImpl(const Service::APT::AppletStartupParameter& parameter) { + started = true; + + // TODO(Subv): Set the expected fields in the response buffer before resending it to the application. + // TODO(Subv): Reverse the parameter format for the ErrEula applet + + // Let the application know that we're closing + Service::APT::MessageParameter message; + message.buffer.resize(parameter.buffer.size()); + std::fill(message.buffer.begin(), message.buffer.end(), 0); + message.signal = static_cast(Service::APT::SignalType::LibAppClosed); + message.destination_id = static_cast(Service::APT::AppletId::Application); + message.sender_id = static_cast(id); + Service::APT::SendParameter(message); + + started = false; + return RESULT_SUCCESS; +} + +void ErrEula::Update() { +} + +} // namespace Applets +} // namespace HLE diff --git a/src/core/hle/applets/erreula.h b/src/core/hle/applets/erreula.h new file mode 100644 index 000000000..9fe72ae07 --- /dev/null +++ b/src/core/hle/applets/erreula.h @@ -0,0 +1,31 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/applets/applet.h" +#include "core/hle/kernel/shared_memory.h" + +namespace HLE { +namespace Applets { + +class ErrEula final : public Applet { +public: + explicit ErrEula(Service::APT::AppletId id): Applet(id) { } + + ResultCode ReceiveParameter(const Service::APT::MessageParameter& parameter) override; + ResultCode StartImpl(const Service::APT::AppletStartupParameter& parameter) override; + void Update() override; + bool IsRunning() const override { return started; } + + /// This SharedMemory will be created when we receive the LibAppJustStarted message. + /// It holds the framebuffer info retrieved by the application with GSPGPU::ImportDisplayCaptureInfo + Kernel::SharedPtr framebuffer_memory; +private: + /// Whether this applet is currently running instead of the host application or not. + bool started = false; +}; + +} // namespace Applets +} // namespace HLE diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h index 76b3a3807..53cee4867 100644 --- a/src/core/hle/service/apt/apt.h +++ b/src/core/hle/service/apt/apt.h @@ -66,6 +66,8 @@ enum class AppletId : u32 { InstructionManual = 0x115, Notifications = 0x116, Miiverse = 0x117, + MiiversePost = 0x118, + AmiiboSettings = 0x119, SoftwareKeyboard1 = 0x201, Ed1 = 0x202, PnoteApp = 0x204, @@ -78,6 +80,12 @@ enum class AppletId : u32 { AnyLibraryApplet = 0x400, SoftwareKeyboard2 = 0x401, Ed2 = 0x402, + PnoteApp2 = 0x404, + SnoteApp2 = 0x405, + Error2 = 0x406, + Mint2 = 0x407, + Extrapad2 = 0x408, + Memolib2 = 0x409, }; enum class StartupArgumentType : u32 {