Просмотр исходного кода

Merge pull request #1266 from Subv/miiapplet

HLE/Applets: Implemented a dummy Mii Selector applet.
bunnei 10 лет назад
Родитель
Сommit
2f0a61debf

+ 2 - 0
src/core/CMakeLists.txt

@@ -26,6 +26,7 @@ set(SRCS
             hle/config_mem.cpp
             hle/config_mem.cpp
             hle/hle.cpp
             hle/hle.cpp
             hle/applets/applet.cpp
             hle/applets/applet.cpp
+            hle/applets/mii_selector.cpp
             hle/applets/swkbd.cpp
             hle/applets/swkbd.cpp
             hle/kernel/address_arbiter.cpp
             hle/kernel/address_arbiter.cpp
             hle/kernel/event.cpp
             hle/kernel/event.cpp
@@ -155,6 +156,7 @@ set(HEADERS
             hle/function_wrappers.h
             hle/function_wrappers.h
             hle/hle.h
             hle/hle.h
             hle/applets/applet.h
             hle/applets/applet.h
+            hle/applets/mii_selector.h
             hle/applets/swkbd.h
             hle/applets/swkbd.h
             hle/kernel/address_arbiter.h
             hle/kernel/address_arbiter.h
             hle/kernel/event.h
             hle/kernel/event.h

+ 6 - 0
src/core/hle/applets/applet.cpp

@@ -12,6 +12,7 @@
 
 
 #include "core/core_timing.h"
 #include "core/core_timing.h"
 #include "core/hle/applets/applet.h"
 #include "core/hle/applets/applet.h"
+#include "core/hle/applets/mii_selector.h"
 #include "core/hle/applets/swkbd.h"
 #include "core/hle/applets/swkbd.h"
 #include "core/hle/result.h"
 #include "core/hle/result.h"
 #include "core/hle/service/apt/apt.h"
 #include "core/hle/service/apt/apt.h"
@@ -47,7 +48,12 @@ ResultCode Applet::Create(Service::APT::AppletId id) {
     case Service::APT::AppletId::SoftwareKeyboard2:
     case Service::APT::AppletId::SoftwareKeyboard2:
         applets[id] = std::make_shared<SoftwareKeyboard>(id);
         applets[id] = std::make_shared<SoftwareKeyboard>(id);
         break;
         break;
+    case Service::APT::AppletId::Ed1:
+    case Service::APT::AppletId::Ed2:
+        applets[id] = std::make_shared<MiiSelector>(id);
+        break;
     default:
     default:
+        LOG_ERROR(Service_APT, "Could not create applet %u", id);
         // TODO(Subv): Find the right error code
         // TODO(Subv): Find the right error code
         return ResultCode(ErrorDescription::NotFound, ErrorModule::Applet, ErrorSummary::NotSupported, ErrorLevel::Permanent);
         return ResultCode(ErrorDescription::NotFound, ErrorModule::Applet, ErrorSummary::NotSupported, ErrorLevel::Permanent);
     }
     }

+ 75 - 0
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 <cstring>
+#include <string>
+
+#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<u32>(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<u32>(Service::APT::SignalType::LibAppFinished);
+    result.data = nullptr;
+    result.buffer_size = 0;
+    result.destination_id = static_cast<u32>(Service::APT::AppletId::Application);
+    result.sender_id = static_cast<u32>(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<u32>(Service::APT::SignalType::LibAppClosed);
+    message.destination_id = static_cast<u32>(Service::APT::AppletId::Application);
+    message.sender_id = static_cast<u32>(id);
+    Service::APT::SendParameter(message);
+
+    started = false;
+    return RESULT_SUCCESS;
+}
+
+void MiiSelector::Update() {
+}
+
+}
+} // namespace

+ 37 - 0
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<Kernel::SharedMemory> framebuffer_memory;
+
+    /// Whether this applet is currently running instead of the host application or not.
+    bool started;
+};
+
+}
+} // namespace

+ 19 - 0
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_a.h"
 #include "core/hle/service/apt/apt_s.h"
 #include "core/hle/service/apt/apt_s.h"
 #include "core/hle/service/apt/apt_u.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/event.h"
 #include "core/hle/kernel/mutex.h"
 #include "core/hle/kernel/mutex.h"
@@ -378,6 +379,24 @@ void StartLibraryApplet(Service::Interface* self) {
     cmd_buff[1] = applet->Start(parameter).raw;
     cmd_buff[1] = applet->Start(parameter).raw;
 }
 }
 
 
+void GetAppletInfo(Service::Interface* self) {
+    u32* cmd_buff = Kernel::GetCommandBuffer();
+    auto app_id = static_cast<AppletId>(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<u32>(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() {
 void Init() {
     AddService(new APT_A_Interface);
     AddService(new APT_A_Interface);
     AddService(new APT_S_Interface);
     AddService(new APT_S_Interface);

+ 16 - 1
src/core/hle/service/apt/apt.h

@@ -54,7 +54,7 @@ enum class AppletId : u32 {
     Notifications      = 0x116,
     Notifications      = 0x116,
     Miiverse           = 0x117,
     Miiverse           = 0x117,
     SoftwareKeyboard1  = 0x201,
     SoftwareKeyboard1  = 0x201,
-    Ed                 = 0x202,
+    Ed1                = 0x202,
     PnoteApp           = 0x204,
     PnoteApp           = 0x204,
     SnoteApp           = 0x205,
     SnoteApp           = 0x205,
     Error              = 0x206,
     Error              = 0x206,
@@ -64,6 +64,7 @@ enum class AppletId : u32 {
     Application        = 0x300,
     Application        = 0x300,
     AnyLibraryApplet   = 0x400,
     AnyLibraryApplet   = 0x400,
     SoftwareKeyboard2  = 0x401,
     SoftwareKeyboard2  = 0x401,
+    Ed2                = 0x402,
 };
 };
 
 
 /// Send a parameter to the currently-running application, which will read it via ReceiveParameter
 /// 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);
 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.
  * 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
  * An AppID is "registered" once the process associated with the AppID uses APT:Enable. Home Menu uses this

+ 1 - 1
src/core/hle/service/apt/apt_u.cpp

@@ -14,7 +14,7 @@ const Interface::FunctionInfo FunctionTable[] = {
     {0x00030040, Enable,                          "Enable"},
     {0x00030040, Enable,                          "Enable"},
     {0x00040040, nullptr,                         "Finalize"},
     {0x00040040, nullptr,                         "Finalize"},
     {0x00050040, GetAppletManInfo,                "GetAppletManInfo"},
     {0x00050040, GetAppletManInfo,                "GetAppletManInfo"},
-    {0x00060040, nullptr,                         "GetAppletInfo"},
+    {0x00060040, GetAppletInfo,                   "GetAppletInfo"},
     {0x00070000, nullptr,                         "GetLastSignaledAppletId"},
     {0x00070000, nullptr,                         "GetLastSignaledAppletId"},
     {0x00080000, nullptr,                         "CountRegisteredApplet"},
     {0x00080000, nullptr,                         "CountRegisteredApplet"},
     {0x00090040, IsRegistered,                    "IsRegistered"},
     {0x00090040, IsRegistered,                    "IsRegistered"},