diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index edf5fcc44..35b61dada 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -26,6 +26,7 @@ set(SRCS hle/config_mem.cpp hle/hle.cpp hle/applets/applet.cpp + hle/applets/mii_selector.cpp hle/applets/swkbd.cpp hle/kernel/address_arbiter.cpp hle/kernel/event.cpp @@ -155,6 +156,7 @@ set(HEADERS hle/function_wrappers.h hle/hle.h hle/applets/applet.h + hle/applets/mii_selector.h hle/applets/swkbd.h hle/kernel/address_arbiter.h hle/kernel/event.h diff --git a/src/core/hle/applets/applet.cpp b/src/core/hle/applets/applet.cpp index bc2a1829e..90e134437 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/mii_selector.h" #include "core/hle/applets/swkbd.h" #include "core/hle/result.h" #include "core/hle/service/apt/apt.h" @@ -47,7 +48,12 @@ ResultCode Applet::Create(Service::APT::AppletId id) { case Service::APT::AppletId::SoftwareKeyboard2: applets[id] = std::make_shared(id); break; + case Service::APT::AppletId::Ed1: + case Service::APT::AppletId::Ed2: + 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 return ResultCode(ErrorDescription::NotFound, ErrorModule::Applet, ErrorSummary::NotSupported, ErrorLevel::Permanent); } diff --git a/src/core/hle/applets/mii_selector.cpp b/src/core/hle/applets/mii_selector.cpp new file mode 100644 index 000000000..708d2f630 --- /dev/null +++ b/src/core/hle/applets/mii_selector.cpp @@ -0,0 +1,75 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include +#include + +#include "common/assert.h" +#include "common/logging/log.h" +#include "common/string_util.h" + +#include "core/hle/applets/mii_selector.h" +#include "core/hle/kernel/kernel.h" +#include "core/hle/kernel/shared_memory.h" +#include "core/hle/result.h" + +#include "video_core/video_core.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +namespace HLE { +namespace Applets { + +MiiSelector::MiiSelector(Service::APT::AppletId id) : Applet(id), started(false) { + // Create the SharedMemory that will hold the framebuffer data + // TODO(Subv): What size should we use here? + using Kernel::MemoryPermission; + framebuffer_memory = Kernel::SharedMemory::Create(0x1000, MemoryPermission::ReadWrite, MemoryPermission::ReadWrite, "MiiSelector Memory"); +} + +ResultCode MiiSelector::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); + } + + Service::APT::MessageParameter result; + // The buffer passed in parameter contains the data returned by GSPGPU::ImportDisplayCaptureInfo + result.signal = static_cast(Service::APT::SignalType::LibAppFinished); + result.data = nullptr; + result.buffer_size = 0; + 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 MiiSelector::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 Mii Selector + + // Let the application know that we're closing + Service::APT::MessageParameter message; + message.buffer_size = parameter.buffer_size; + message.data = parameter.data; + 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 MiiSelector::Update() { +} + +} +} // namespace diff --git a/src/core/hle/applets/mii_selector.h b/src/core/hle/applets/mii_selector.h new file mode 100644 index 000000000..6a3e7c8eb --- /dev/null +++ b/src/core/hle/applets/mii_selector.h @@ -0,0 +1,37 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "common/common_types.h" +#include "common/common_funcs.h" + +#include "core/hle/applets/applet.h" +#include "core/hle/kernel/kernel.h" +#include "core/hle/kernel/shared_memory.h" +#include "core/hle/result.h" +#include "core/hle/service/apt/apt.h" + +namespace HLE { +namespace Applets { + +class MiiSelector final : public Applet { +public: + MiiSelector(Service::APT::AppletId 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; } + + /// TODO(Subv): Find out what this is actually used for. + /// It is believed that the application stores the current screen image here. + Kernel::SharedPtr framebuffer_memory; + + /// Whether this applet is currently running instead of the host application or not. + bool started; +}; + +} +} // namespace diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp index 69255e2ef..98c72fc32 100644 --- a/src/core/hle/service/apt/apt.cpp +++ b/src/core/hle/service/apt/apt.cpp @@ -12,6 +12,7 @@ #include "core/hle/service/apt/apt_a.h" #include "core/hle/service/apt/apt_s.h" #include "core/hle/service/apt/apt_u.h" +#include "core/hle/service/fs/archive.h" #include "core/hle/kernel/event.h" #include "core/hle/kernel/mutex.h" @@ -378,6 +379,24 @@ void StartLibraryApplet(Service::Interface* self) { cmd_buff[1] = applet->Start(parameter).raw; } +void GetAppletInfo(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + auto app_id = static_cast(cmd_buff[1]); + + if (auto applet = HLE::Applets::Applet::Get(app_id)) { + // TODO(Subv): Get the title id for the current applet and write it in the response[2-3] + cmd_buff[1] = RESULT_SUCCESS.raw; + cmd_buff[4] = static_cast(Service::FS::MediaType::NAND); + cmd_buff[5] = 1; // Registered + cmd_buff[6] = 1; // Loaded + cmd_buff[7] = 0; // Applet Attributes + } else { + cmd_buff[1] = ResultCode(ErrorDescription::NotFound, ErrorModule::Applet, + ErrorSummary::NotFound, ErrorLevel::Status).raw; + } + LOG_WARNING(Service_APT, "(stubbed) called appid=%u", app_id); +} + void Init() { AddService(new APT_A_Interface); AddService(new APT_S_Interface); diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h index 4a72b6b5c..47a97c1a1 100644 --- a/src/core/hle/service/apt/apt.h +++ b/src/core/hle/service/apt/apt.h @@ -54,7 +54,7 @@ enum class AppletId : u32 { Notifications = 0x116, Miiverse = 0x117, SoftwareKeyboard1 = 0x201, - Ed = 0x202, + Ed1 = 0x202, PnoteApp = 0x204, SnoteApp = 0x205, Error = 0x206, @@ -64,6 +64,7 @@ enum class AppletId : u32 { Application = 0x300, AnyLibraryApplet = 0x400, SoftwareKeyboard2 = 0x401, + Ed2 = 0x402, }; /// Send a parameter to the currently-running application, which will read it via ReceiveParameter @@ -132,6 +133,20 @@ void Enable(Service::Interface* self); */ void GetAppletManInfo(Service::Interface* self); +/** + * APT::GetAppletInfo service function. + * Inputs: + * 1 : AppId + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2-3 : Title ID + * 4 : Media Type + * 5 : Registered + * 6 : Loaded + * 7 : Attributes + */ +void GetAppletInfo(Service::Interface* self); + /** * APT::IsRegistered service function. This returns whether the specified AppID is registered with NS yet. * An AppID is "registered" once the process associated with the AppID uses APT:Enable. Home Menu uses this diff --git a/src/core/hle/service/apt/apt_u.cpp b/src/core/hle/service/apt/apt_u.cpp index 209a0055b..b13b51549 100644 --- a/src/core/hle/service/apt/apt_u.cpp +++ b/src/core/hle/service/apt/apt_u.cpp @@ -14,7 +14,7 @@ const Interface::FunctionInfo FunctionTable[] = { {0x00030040, Enable, "Enable"}, {0x00040040, nullptr, "Finalize"}, {0x00050040, GetAppletManInfo, "GetAppletManInfo"}, - {0x00060040, nullptr, "GetAppletInfo"}, + {0x00060040, GetAppletInfo, "GetAppletInfo"}, {0x00070000, nullptr, "GetLastSignaledAppletId"}, {0x00080000, nullptr, "CountRegisteredApplet"}, {0x00090040, IsRegistered, "IsRegistered"},