summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/CMakeLists.txt2
-rw-r--r--src/core/hle/service/am/am.cpp333
-rw-r--r--src/core/hle/service/am/am.h93
-rw-r--r--src/core/hle/service/am/applet_ae.cpp112
-rw-r--r--src/core/hle/service/am/applet_ae.h30
-rw-r--r--src/core/hle/service/am/applet_oe.cpp374
-rw-r--r--src/core/hle/service/am/applet_oe.h6
7 files changed, 571 insertions, 379 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 2e32ff35b..848b17b18 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -84,6 +84,8 @@ add_library(core STATIC
hle/service/acc/acc_u0.h
hle/service/am/am.cpp
hle/service/am/am.h
+ hle/service/am/applet_ae.cpp
+ hle/service/am/applet_ae.h
hle/service/am/applet_oe.cpp
hle/service/am/applet_oe.h
hle/service/aoc/aoc_u.cpp
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index b6896852e..2825abd1a 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -2,14 +2,347 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include "core/hle/ipc_helpers.h"
+#include "core/hle/kernel/event.h"
#include "core/hle/service/am/am.h"
+#include "core/hle/service/am/applet_ae.h"
#include "core/hle/service/am/applet_oe.h"
+#include "core/hle/service/apm/apm.h"
+#include "core/hle/service/nvflinger/nvflinger.h"
namespace Service {
namespace AM {
+IWindowController::IWindowController() : ServiceFramework("IWindowController") {
+ static const FunctionInfo functions[] = {
+ {1, &IWindowController::GetAppletResourceUserId, "GetAppletResourceUserId"},
+ {10, &IWindowController::AcquireForegroundRights, "AcquireForegroundRights"},
+ };
+ RegisterHandlers(functions);
+}
+
+void IWindowController::GetAppletResourceUserId(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service, "(STUBBED) called");
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(RESULT_SUCCESS);
+ rb.Push<u64>(0);
+}
+
+void IWindowController::AcquireForegroundRights(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service, "(STUBBED) called");
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+}
+
+IAudioController::IAudioController() : ServiceFramework("IAudioController") {}
+
+IDisplayController::IDisplayController() : ServiceFramework("IDisplayController") {}
+
+IDebugFunctions::IDebugFunctions() : ServiceFramework("IDebugFunctions") {}
+
+ISelfController::ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
+ : ServiceFramework("ISelfController"), nvflinger(std::move(nvflinger)) {
+ static const FunctionInfo functions[] = {
+ {1, &ISelfController::LockExit, "LockExit"},
+ {2, &ISelfController::UnlockExit, "UnlockExit"},
+ {11, &ISelfController::SetOperationModeChangedNotification,
+ "SetOperationModeChangedNotification"},
+ {12, &ISelfController::SetPerformanceModeChangedNotification,
+ "SetPerformanceModeChangedNotification"},
+ {13, &ISelfController::SetFocusHandlingMode, "SetFocusHandlingMode"},
+ {14, &ISelfController::SetRestartMessageEnabled, "SetRestartMessageEnabled"},
+ {16, &ISelfController::SetOutOfFocusSuspendingEnabled, "SetOutOfFocusSuspendingEnabled"},
+ {40, &ISelfController::CreateManagedDisplayLayer, "CreateManagedDisplayLayer"},
+ };
+ RegisterHandlers(functions);
+}
+
+void ISelfController::SetFocusHandlingMode(Kernel::HLERequestContext& ctx) {
+ // Takes 3 input u8s with each field located immediately after the previous u8, these are
+ // bool flags. No output.
+
+ IPC::RequestParser rp{ctx};
+
+ struct FocusHandlingModeParams {
+ u8 unknown0;
+ u8 unknown1;
+ u8 unknown2;
+ };
+ auto flags = rp.PopRaw<FocusHandlingModeParams>();
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+
+ LOG_WARNING(Service, "(STUBBED) called");
+}
+
+void ISelfController::SetRestartMessageEnabled(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+
+ LOG_WARNING(Service, "(STUBBED) called");
+}
+
+void ISelfController::SetPerformanceModeChangedNotification(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+
+ bool flag = rp.Pop<bool>();
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+
+ LOG_WARNING(Service, "(STUBBED) called flag=%u", static_cast<u32>(flag));
+}
+
+void ISelfController::SetOperationModeChangedNotification(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+
+ bool flag = rp.Pop<bool>();
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+
+ LOG_WARNING(Service, "(STUBBED) called flag=%u", static_cast<u32>(flag));
+}
+
+void ISelfController::SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& ctx) {
+ // Takes 3 input u8s with each field located immediately after the previous u8, these are
+ // bool flags. No output.
+ IPC::RequestParser rp{ctx};
+
+ bool enabled = rp.Pop<bool>();
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+
+ LOG_WARNING(Service, "(STUBBED) called enabled=%u", static_cast<u32>(enabled));
+}
+
+void ISelfController::LockExit(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+
+ LOG_WARNING(Service, "(STUBBED) called");
+}
+
+void ISelfController::UnlockExit(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+
+ LOG_WARNING(Service, "(STUBBED) called");
+}
+
+void ISelfController::CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx) {
+ // TODO(Subv): Find out how AM determines the display to use, for now just create the layer
+ // in the Default display.
+ u64 display_id = nvflinger->OpenDisplay("Default");
+ u64 layer_id = nvflinger->CreateLayer(display_id);
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(RESULT_SUCCESS);
+ rb.Push(layer_id);
+
+ LOG_WARNING(Service, "(STUBBED) called");
+}
+
+ICommonStateGetter::ICommonStateGetter() : ServiceFramework("ICommonStateGetter") {
+ static const FunctionInfo functions[] = {
+ {0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"},
+ {1, &ICommonStateGetter::ReceiveMessage, "ReceiveMessage"},
+ {5, &ICommonStateGetter::GetOperationMode, "GetOperationMode"},
+ {6, &ICommonStateGetter::GetPerformanceMode, "GetPerformanceMode"},
+ {9, &ICommonStateGetter::GetCurrentFocusState, "GetCurrentFocusState"},
+ };
+ RegisterHandlers(functions);
+
+ event = Kernel::Event::Create(Kernel::ResetType::OneShot, "ICommonStateGetter:Event");
+}
+
+void ICommonStateGetter::GetEventHandle(Kernel::HLERequestContext& ctx) {
+ event->Signal();
+
+ IPC::ResponseBuilder rb{ctx, 2, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushCopyObjects(event);
+
+ LOG_WARNING(Service, "(STUBBED) called");
+}
+
+void ICommonStateGetter::ReceiveMessage(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(RESULT_SUCCESS);
+ rb.Push<u32>(15);
+
+ LOG_WARNING(Service, "(STUBBED) called");
+}
+
+void ICommonStateGetter::GetCurrentFocusState(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(RESULT_SUCCESS);
+ rb.Push(static_cast<u8>(FocusState::InFocus));
+
+ LOG_WARNING(Service, "(STUBBED) called");
+}
+
+void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(RESULT_SUCCESS);
+ rb.Push(static_cast<u8>(OperationMode::Handheld));
+
+ LOG_WARNING(Service, "(STUBBED) called");
+}
+
+void ICommonStateGetter::GetPerformanceMode(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(RESULT_SUCCESS);
+ rb.Push(static_cast<u32>(APM::PerformanceMode::Handheld));
+
+ LOG_WARNING(Service, "(STUBBED) called");
+}
+
+ILibraryAppletCreator::ILibraryAppletCreator() : ServiceFramework("ILibraryAppletCreator") {}
+
+class IStorageAccessor final : public ServiceFramework<IStorageAccessor> {
+public:
+ explicit IStorageAccessor(std::vector<u8> buffer)
+ : ServiceFramework("IStorageAccessor"), buffer(std::move(buffer)) {
+ static const FunctionInfo functions[] = {
+ {0, &IStorageAccessor::GetSize, "GetSize"},
+ {11, &IStorageAccessor::Read, "Read"},
+ };
+ RegisterHandlers(functions);
+ }
+
+private:
+ std::vector<u8> buffer;
+
+ void GetSize(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 4};
+
+ rb.Push(RESULT_SUCCESS);
+ rb.Push(static_cast<u64>(buffer.size()));
+
+ LOG_DEBUG(Service, "called");
+ }
+
+ void Read(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+
+ u64 offset = rp.Pop<u64>();
+
+ const auto& output_buffer = ctx.BufferDescriptorC()[0];
+
+ ASSERT(offset + output_buffer.Size() <= buffer.size());
+
+ Memory::WriteBlock(output_buffer.Address(), buffer.data() + offset, output_buffer.Size());
+
+ IPC::ResponseBuilder rb{ctx, 2};
+
+ rb.Push(RESULT_SUCCESS);
+
+ LOG_DEBUG(Service, "called");
+ }
+};
+
+class IStorage final : public ServiceFramework<IStorage> {
+public:
+ explicit IStorage(std::vector<u8> buffer)
+ : ServiceFramework("IStorage"), buffer(std::move(buffer)) {
+ static const FunctionInfo functions[] = {
+ {0, &IStorage::Open, "Open"},
+ };
+ RegisterHandlers(functions);
+ }
+
+private:
+ std::vector<u8> buffer;
+
+ void Open(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+
+ rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<AM::IStorageAccessor>(buffer);
+
+ LOG_DEBUG(Service, "called");
+ }
+};
+
+IApplicationFunctions::IApplicationFunctions() : ServiceFramework("IApplicationFunctions") {
+ static const FunctionInfo functions[] = {
+ {1, &IApplicationFunctions::PopLaunchParameter, "PopLaunchParameter"},
+ {21, &IApplicationFunctions::GetDesiredLanguage, "GetDesiredLanguage"},
+ {22, &IApplicationFunctions::SetTerminateResult, "SetTerminateResult"},
+ {66, &IApplicationFunctions::InitializeGamePlayRecording, "InitializeGamePlayRecording"},
+ {67, &IApplicationFunctions::SetGamePlayRecordingState, "SetGamePlayRecordingState"},
+ {40, &IApplicationFunctions::NotifyRunning, "NotifyRunning"},
+ };
+ RegisterHandlers(functions);
+}
+
+void IApplicationFunctions::PopLaunchParameter(Kernel::HLERequestContext& ctx) {
+ constexpr u8 data[0x88] = {
+ 0xca, 0x97, 0x94, 0xc7, // Magic
+ 1, 0, 0, 0, // IsAccountSelected (bool)
+ 1, 0, 0, 0, // User Id (word 0)
+ 0, 0, 0, 0, // User Id (word 1)
+ 0, 0, 0, 0, // User Id (word 2)
+ 0, 0, 0, 0 // User Id (word 3)
+ };
+
+ std::vector<u8> buffer(data, data + sizeof(data));
+
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+
+ rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<AM::IStorage>(buffer);
+
+ LOG_DEBUG(Service, "called");
+}
+
+void IApplicationFunctions::SetTerminateResult(Kernel::HLERequestContext& ctx) {
+ // Takes an input u32 Result, no output.
+ // For example, in some cases official apps use this with error 0x2A2 then uses svcBreak.
+
+ IPC::RequestParser rp{ctx};
+ u32 result = rp.Pop<u32>();
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+
+ LOG_WARNING(Service, "(STUBBED) called, result=0x%08X", result);
+}
+
+void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(RESULT_SUCCESS);
+ rb.Push<u64>(SystemLanguage::English);
+ LOG_WARNING(Service, "(STUBBED) called");
+}
+
+void IApplicationFunctions::InitializeGamePlayRecording(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+ LOG_WARNING(Service, "(STUBBED) called");
+}
+
+void IApplicationFunctions::SetGamePlayRecordingState(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+
+ LOG_WARNING(Service, "(STUBBED) called");
+}
+
+void IApplicationFunctions::NotifyRunning(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(RESULT_SUCCESS);
+ rb.Push<u8>(0); // Unknown, seems to be ignored by official processes
+
+ LOG_WARNING(Service, "(STUBBED) called");
+}
+
void InstallInterfaces(SM::ServiceManager& service_manager,
std::shared_ptr<NVFlinger::NVFlinger> nvflinger) {
+ std::make_shared<AppletAE>(nvflinger)->InstallAsService(service_manager);
std::make_shared<AppletOE>(nvflinger)->InstallAsService(service_manager);
}
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h
index 3b8a06c1d..b603c17dd 100644
--- a/src/core/hle/service/am/am.h
+++ b/src/core/hle/service/am/am.h
@@ -7,6 +7,10 @@
#include <memory>
#include "core/hle/service/service.h"
+namespace Kernel {
+class Event;
+}
+
namespace Service {
namespace NVFlinger {
class NVFlinger;
@@ -14,6 +18,95 @@ class NVFlinger;
namespace AM {
+// TODO: Add more languages
+enum SystemLanguage {
+ Japanese = 0,
+ English = 1,
+};
+
+class IWindowController final : public ServiceFramework<IWindowController> {
+public:
+ IWindowController();
+
+private:
+ void GetAppletResourceUserId(Kernel::HLERequestContext& ctx);
+ void AcquireForegroundRights(Kernel::HLERequestContext& ctx);
+};
+
+class IAudioController final : public ServiceFramework<IAudioController> {
+public:
+ IAudioController();
+};
+
+class IDisplayController final : public ServiceFramework<IDisplayController> {
+public:
+ IDisplayController();
+};
+
+class IDebugFunctions final : public ServiceFramework<IDebugFunctions> {
+public:
+ IDebugFunctions();
+};
+
+class ISelfController final : public ServiceFramework<ISelfController> {
+public:
+ ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger);
+
+private:
+ void SetFocusHandlingMode(Kernel::HLERequestContext& ctx);
+ void SetRestartMessageEnabled(Kernel::HLERequestContext& ctx);
+ void SetPerformanceModeChangedNotification(Kernel::HLERequestContext& ctx);
+ void SetOperationModeChangedNotification(Kernel::HLERequestContext& ctx);
+ void SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& ctx);
+ void LockExit(Kernel::HLERequestContext& ctx);
+ void UnlockExit(Kernel::HLERequestContext& ctx);
+ void CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx);
+
+ std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
+};
+
+class ICommonStateGetter final : public ServiceFramework<ICommonStateGetter> {
+public:
+ ICommonStateGetter();
+
+private:
+ enum class FocusState : u8 {
+ InFocus = 1,
+ NotInFocus = 2,
+ };
+
+ enum class OperationMode : u8 {
+ Handheld = 0,
+ Docked = 1,
+ };
+
+ void GetEventHandle(Kernel::HLERequestContext& ctx);
+ void ReceiveMessage(Kernel::HLERequestContext& ctx);
+ void GetCurrentFocusState(Kernel::HLERequestContext& ctx);
+ void GetOperationMode(Kernel::HLERequestContext& ctx);
+ void GetPerformanceMode(Kernel::HLERequestContext& ctx);
+
+ Kernel::SharedPtr<Kernel::Event> event;
+};
+
+class ILibraryAppletCreator final : public ServiceFramework<ILibraryAppletCreator> {
+public:
+ ILibraryAppletCreator();
+};
+
+class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> {
+public:
+ IApplicationFunctions();
+
+private:
+ void PopLaunchParameter(Kernel::HLERequestContext& ctx);
+ void SetTerminateResult(Kernel::HLERequestContext& ctx);
+ void GetDesiredLanguage(Kernel::HLERequestContext& ctx);
+ void InitializeGamePlayRecording(Kernel::HLERequestContext& ctx);
+ void SetGamePlayRecordingState(Kernel::HLERequestContext& ctx);
+ void NotifyRunning(Kernel::HLERequestContext& ctx);
+};
+
/// Registers all AM services with the specified service manager.
void InstallInterfaces(SM::ServiceManager& service_manager,
std::shared_ptr<NVFlinger::NVFlinger> nvflinger);
diff --git a/src/core/hle/service/am/applet_ae.cpp b/src/core/hle/service/am/applet_ae.cpp
new file mode 100644
index 000000000..a63fb6210
--- /dev/null
+++ b/src/core/hle/service/am/applet_ae.cpp
@@ -0,0 +1,112 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/logging/log.h"
+#include "core/hle/ipc_helpers.h"
+#include "core/hle/service/am/am.h"
+#include "core/hle/service/am/applet_ae.h"
+#include "core/hle/service/nvflinger/nvflinger.h"
+
+namespace Service {
+namespace AM {
+
+class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> {
+public:
+ ILibraryAppletProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
+ : ServiceFramework("ILibraryAppletProxy"), nvflinger(std::move(nvflinger)) {
+ static const FunctionInfo functions[] = {
+ {0, &ILibraryAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"},
+ {1, &ILibraryAppletProxy::GetSelfController, "GetSelfController"},
+ {2, &ILibraryAppletProxy::GetWindowController, "GetWindowController"},
+ {3, &ILibraryAppletProxy::GetAudioController, "GetAudioController"},
+ {4, &ILibraryAppletProxy::GetDisplayController, "GetDisplayController"},
+ {11, &ILibraryAppletProxy::GetLibraryAppletCreator, "GetLibraryAppletCreator"},
+ {20, &ILibraryAppletProxy::GetApplicationFunctions, "GetApplicationFunctions"},
+ {1000, &ILibraryAppletProxy::GetDebugFunctions, "GetDebugFunctions"},
+ };
+ RegisterHandlers(functions);
+ }
+
+private:
+ void GetCommonStateGetter(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<ICommonStateGetter>();
+ LOG_DEBUG(Service, "called");
+ }
+
+ void GetSelfController(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<ISelfController>(nvflinger);
+ LOG_DEBUG(Service, "called");
+ }
+
+ void GetWindowController(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<IWindowController>();
+ LOG_DEBUG(Service, "called");
+ }
+
+ void GetAudioController(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<IAudioController>();
+ LOG_DEBUG(Service, "called");
+ }
+
+ void GetDisplayController(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<IDisplayController>();
+ LOG_DEBUG(Service, "called");
+ }
+
+ void GetDebugFunctions(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<IDebugFunctions>();
+ LOG_DEBUG(Service, "called");
+ }
+
+ void GetLibraryAppletCreator(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<ILibraryAppletCreator>();
+ LOG_DEBUG(Service, "called");
+ }
+
+ void GetApplicationFunctions(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<IApplicationFunctions>();
+ LOG_DEBUG(Service, "called");
+ }
+
+ std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
+};
+
+void AppletAE::OpenLibraryAppletProxyOld(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<ILibraryAppletProxy>(nvflinger);
+ LOG_DEBUG(Service, "called");
+}
+
+AppletAE::AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
+ : ServiceFramework("appletAE"), nvflinger(std::move(nvflinger)) {
+ static const FunctionInfo functions[] = {
+ {100, nullptr, "OpenSystemAppletProxy"},
+ {200, &AppletAE::OpenLibraryAppletProxyOld, "OpenLibraryAppletProxyOld"},
+ {201, nullptr, "OpenLibraryAppletProxy"},
+ {300, nullptr, "OpenOverlayAppletProxy"},
+ {350, nullptr, "OpenSystemApplicationProxy"},
+ {400, nullptr, "CreateSelfLibraryAppletCreatorForDevelop"},
+ };
+ RegisterHandlers(functions);
+}
+
+} // namespace AM
+} // namespace Service
diff --git a/src/core/hle/service/am/applet_ae.h b/src/core/hle/service/am/applet_ae.h
new file mode 100644
index 000000000..38fc428fb
--- /dev/null
+++ b/src/core/hle/service/am/applet_ae.h
@@ -0,0 +1,30 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <memory>
+#include "core/hle/kernel/hle_ipc.h"
+#include "core/hle/service/service.h"
+
+namespace Service {
+namespace NVFlinger {
+class NVFlinger;
+}
+
+namespace AM {
+
+class AppletAE final : public ServiceFramework<AppletAE> {
+public:
+ AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger);
+ ~AppletAE() = default;
+
+private:
+ void OpenLibraryAppletProxyOld(Kernel::HLERequestContext& ctx);
+
+ std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
+};
+
+} // namespace AM
+} // namespace Service
diff --git a/src/core/hle/service/am/applet_oe.cpp b/src/core/hle/service/am/applet_oe.cpp
index 15b7701e0..5aa765770 100644
--- a/src/core/hle/service/am/applet_oe.cpp
+++ b/src/core/hle/service/am/applet_oe.cpp
@@ -4,385 +4,13 @@
#include "common/logging/log.h"
#include "core/hle/ipc_helpers.h"
-#include "core/hle/kernel/event.h"
+#include "core/hle/service/am/am.h"
#include "core/hle/service/am/applet_oe.h"
-#include "core/hle/service/apm/apm.h"
#include "core/hle/service/nvflinger/nvflinger.h"
namespace Service {
namespace AM {
-class IWindowController final : public ServiceFramework<IWindowController> {
-public:
- IWindowController() : ServiceFramework("IWindowController") {
- static const FunctionInfo functions[] = {
- {1, &IWindowController::GetAppletResourceUserId, "GetAppletResourceUserId"},
- {10, &IWindowController::AcquireForegroundRights, "AcquireForegroundRights"},
- };
- RegisterHandlers(functions);
- }
-
-private:
- void GetAppletResourceUserId(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service, "(STUBBED) called");
- IPC::ResponseBuilder rb{ctx, 4};
- rb.Push(RESULT_SUCCESS);
- rb.Push<u64>(0);
- }
-
- void AcquireForegroundRights(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service, "(STUBBED) called");
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(RESULT_SUCCESS);
- }
-};
-
-class IAudioController final : public ServiceFramework<IAudioController> {
-public:
- IAudioController() : ServiceFramework("IAudioController") {}
-};
-
-class IDisplayController final : public ServiceFramework<IDisplayController> {
-public:
- IDisplayController() : ServiceFramework("IDisplayController") {}
-};
-
-class IDebugFunctions final : public ServiceFramework<IDebugFunctions> {
-public:
- IDebugFunctions() : ServiceFramework("IDebugFunctions") {}
-};
-
-class ISelfController final : public ServiceFramework<ISelfController> {
-public:
- ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
- : ServiceFramework("ISelfController"), nvflinger(std::move(nvflinger)) {
- static const FunctionInfo functions[] = {
- {1, &ISelfController::LockExit, "LockExit"},
- {2, &ISelfController::UnlockExit, "UnlockExit"},
- {11, &ISelfController::SetOperationModeChangedNotification,
- "SetOperationModeChangedNotification"},
- {12, &ISelfController::SetPerformanceModeChangedNotification,
- "SetPerformanceModeChangedNotification"},
- {13, &ISelfController::SetFocusHandlingMode, "SetFocusHandlingMode"},
- {14, &ISelfController::SetRestartMessageEnabled, "SetRestartMessageEnabled"},
- {16, &ISelfController::SetOutOfFocusSuspendingEnabled,
- "SetOutOfFocusSuspendingEnabled"},
- {40, &ISelfController::CreateManagedDisplayLayer, "CreateManagedDisplayLayer"},
- };
- RegisterHandlers(functions);
- }
-
-private:
- void SetFocusHandlingMode(Kernel::HLERequestContext& ctx) {
- // Takes 3 input u8s with each field located immediately after the previous u8, these are
- // bool flags. No output.
-
- IPC::RequestParser rp{ctx};
-
- struct FocusHandlingModeParams {
- u8 unknown0;
- u8 unknown1;
- u8 unknown2;
- };
- auto flags = rp.PopRaw<FocusHandlingModeParams>();
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(RESULT_SUCCESS);
-
- LOG_WARNING(Service, "(STUBBED) called");
- }
-
- void SetRestartMessageEnabled(Kernel::HLERequestContext& ctx) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(RESULT_SUCCESS);
-
- LOG_WARNING(Service, "(STUBBED) called");
- }
-
- void SetPerformanceModeChangedNotification(Kernel::HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
-
- bool flag = rp.Pop<bool>();
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(RESULT_SUCCESS);
-
- LOG_WARNING(Service, "(STUBBED) called flag=%u", static_cast<u32>(flag));
- }
-
- void SetOperationModeChangedNotification(Kernel::HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
-
- bool flag = rp.Pop<bool>();
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(RESULT_SUCCESS);
-
- LOG_WARNING(Service, "(STUBBED) called flag=%u", static_cast<u32>(flag));
- }
-
- void SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& ctx) {
- // Takes 3 input u8s with each field located immediately after the previous u8, these are
- // bool flags. No output.
- IPC::RequestParser rp{ctx};
-
- bool enabled = rp.Pop<bool>();
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(RESULT_SUCCESS);
-
- LOG_WARNING(Service, "(STUBBED) called enabled=%u", static_cast<u32>(enabled));
- }
-
- void LockExit(Kernel::HLERequestContext& ctx) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(RESULT_SUCCESS);
-
- LOG_WARNING(Service, "(STUBBED) called");
- }
-
- void UnlockExit(Kernel::HLERequestContext& ctx) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(RESULT_SUCCESS);
-
- LOG_WARNING(Service, "(STUBBED) called");
- }
-
- void CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx) {
- // TODO(Subv): Find out how AM determines the display to use, for now just create the layer
- // in the Default display.
- u64 display_id = nvflinger->OpenDisplay("Default");
- u64 layer_id = nvflinger->CreateLayer(display_id);
-
- IPC::ResponseBuilder rb{ctx, 4};
- rb.Push(RESULT_SUCCESS);
- rb.Push(layer_id);
-
- LOG_WARNING(Service, "(STUBBED) called");
- }
-
- std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
-};
-
-class ICommonStateGetter final : public ServiceFramework<ICommonStateGetter> {
-public:
- ICommonStateGetter() : ServiceFramework("ICommonStateGetter") {
- static const FunctionInfo functions[] = {
- {0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"},
- {1, &ICommonStateGetter::ReceiveMessage, "ReceiveMessage"},
- {5, &ICommonStateGetter::GetOperationMode, "GetOperationMode"},
- {6, &ICommonStateGetter::GetPerformanceMode, "GetPerformanceMode"},
- {9, &ICommonStateGetter::GetCurrentFocusState, "GetCurrentFocusState"},
- };
- RegisterHandlers(functions);
-
- event = Kernel::Event::Create(Kernel::ResetType::OneShot, "ICommonStateGetter:Event");
- }
-
-private:
- enum class FocusState : u8 {
- InFocus = 1,
- NotInFocus = 2,
- };
-
- enum class OperationMode : u8 {
- Handheld = 0,
- Docked = 1,
- };
-
- void GetEventHandle(Kernel::HLERequestContext& ctx) {
- event->Signal();
-
- IPC::ResponseBuilder rb{ctx, 2, 1};
- rb.Push(RESULT_SUCCESS);
- rb.PushCopyObjects(event);
-
- LOG_WARNING(Service, "(STUBBED) called");
- }
-
- void ReceiveMessage(Kernel::HLERequestContext& ctx) {
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(RESULT_SUCCESS);
- rb.Push<u32>(15);
-
- LOG_WARNING(Service, "(STUBBED) called");
- }
-
- void GetCurrentFocusState(Kernel::HLERequestContext& ctx) {
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(RESULT_SUCCESS);
- rb.Push(static_cast<u8>(FocusState::InFocus));
-
- LOG_WARNING(Service, "(STUBBED) called");
- }
-
- void GetOperationMode(Kernel::HLERequestContext& ctx) {
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(RESULT_SUCCESS);
- rb.Push(static_cast<u8>(OperationMode::Handheld));
-
- LOG_WARNING(Service, "(STUBBED) called");
- }
-
- void GetPerformanceMode(Kernel::HLERequestContext& ctx) {
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(RESULT_SUCCESS);
- rb.Push(static_cast<u32>(APM::PerformanceMode::Handheld));
-
- LOG_WARNING(Service, "(STUBBED) called");
- }
-
- Kernel::SharedPtr<Kernel::Event> event;
-};
-
-class IStorageAccessor final : public ServiceFramework<IStorageAccessor> {
-public:
- explicit IStorageAccessor(std::vector<u8> buffer)
- : ServiceFramework("IStorageAccessor"), buffer(std::move(buffer)) {
- static const FunctionInfo functions[] = {
- {0, &IStorageAccessor::GetSize, "GetSize"},
- {11, &IStorageAccessor::Read, "Read"},
- };
- RegisterHandlers(functions);
- }
-
-private:
- std::vector<u8> buffer;
-
- void GetSize(Kernel::HLERequestContext& ctx) {
- IPC::ResponseBuilder rb{ctx, 4};
-
- rb.Push(RESULT_SUCCESS);
- rb.Push(static_cast<u64>(buffer.size()));
-
- LOG_DEBUG(Service, "called");
- }
-
- void Read(Kernel::HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
-
- u64 offset = rp.Pop<u64>();
-
- const auto& output_buffer = ctx.BufferDescriptorC()[0];
-
- ASSERT(offset + output_buffer.Size() <= buffer.size());
-
- Memory::WriteBlock(output_buffer.Address(), buffer.data() + offset, output_buffer.Size());
-
- IPC::ResponseBuilder rb{ctx, 2};
-
- rb.Push(RESULT_SUCCESS);
-
- LOG_DEBUG(Service, "called");
- }
-};
-
-class IStorage final : public ServiceFramework<IStorage> {
-public:
- explicit IStorage(std::vector<u8> buffer)
- : ServiceFramework("IStorage"), buffer(std::move(buffer)) {
- static const FunctionInfo functions[] = {
- {0, &IStorage::Open, "Open"},
- };
- RegisterHandlers(functions);
- }
-
-private:
- std::vector<u8> buffer;
-
- void Open(Kernel::HLERequestContext& ctx) {
- IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-
- rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<AM::IStorageAccessor>(buffer);
-
- LOG_DEBUG(Service, "called");
- }
-};
-
-class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> {
-public:
- IApplicationFunctions() : ServiceFramework("IApplicationFunctions") {
- static const FunctionInfo functions[] = {
- {1, &IApplicationFunctions::PopLaunchParameter, "PopLaunchParameter"},
- {21, &IApplicationFunctions::GetDesiredLanguage, "GetDesiredLanguage"},
- {22, &IApplicationFunctions::SetTerminateResult, "SetTerminateResult"},
- {66, &IApplicationFunctions::InitializeGamePlayRecording,
- "InitializeGamePlayRecording"},
- {67, &IApplicationFunctions::SetGamePlayRecordingState, "SetGamePlayRecordingState"},
- {40, &IApplicationFunctions::NotifyRunning, "NotifyRunning"},
- };
- RegisterHandlers(functions);
- }
-
-private:
- void PopLaunchParameter(Kernel::HLERequestContext& ctx) {
- constexpr u8 data[0x88] = {
- 0xca, 0x97, 0x94, 0xc7, // Magic
- 1, 0, 0, 0, // IsAccountSelected (bool)
- 1, 0, 0, 0, // User Id (word 0)
- 0, 0, 0, 0, // User Id (word 1)
- 0, 0, 0, 0, // User Id (word 2)
- 0, 0, 0, 0 // User Id (word 3)
- };
-
- std::vector<u8> buffer(data, data + sizeof(data));
-
- IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-
- rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<AM::IStorage>(buffer);
-
- LOG_DEBUG(Service, "called");
- }
-
- void SetTerminateResult(Kernel::HLERequestContext& ctx) {
- // Takes an input u32 Result, no output.
- // For example, in some cases official apps use this with error 0x2A2 then uses svcBreak.
-
- IPC::RequestParser rp{ctx};
- u32 result = rp.Pop<u32>();
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(RESULT_SUCCESS);
-
- LOG_WARNING(Service, "(STUBBED) called, result=0x%08X", result);
- }
-
- void GetDesiredLanguage(Kernel::HLERequestContext& ctx) {
- IPC::ResponseBuilder rb{ctx, 4};
- rb.Push(RESULT_SUCCESS);
- rb.Push<u64>(SystemLanguage::English);
- LOG_WARNING(Service, "(STUBBED) called");
- }
-
- void InitializeGamePlayRecording(Kernel::HLERequestContext& ctx) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(RESULT_SUCCESS);
- LOG_WARNING(Service, "(STUBBED) called");
- }
-
- void SetGamePlayRecordingState(Kernel::HLERequestContext& ctx) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(RESULT_SUCCESS);
-
- LOG_WARNING(Service, "(STUBBED) called");
- }
-
- void NotifyRunning(Kernel::HLERequestContext& ctx) {
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(RESULT_SUCCESS);
- rb.Push<u8>(0); // Unknown, seems to be ignored by official processes
-
- LOG_WARNING(Service, "(STUBBED) called");
- }
-};
-
-class ILibraryAppletCreator final : public ServiceFramework<ILibraryAppletCreator> {
-public:
- ILibraryAppletCreator() : ServiceFramework("ILibraryAppletCreator") {}
-};
-
class IApplicationProxy final : public ServiceFramework<IApplicationProxy> {
public:
IApplicationProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
diff --git a/src/core/hle/service/am/applet_oe.h b/src/core/hle/service/am/applet_oe.h
index 8083135c3..d2ab44c67 100644
--- a/src/core/hle/service/am/applet_oe.h
+++ b/src/core/hle/service/am/applet_oe.h
@@ -15,12 +15,6 @@ class NVFlinger;
namespace AM {
-// TODO: Add more languages
-enum SystemLanguage {
- Japanese = 0,
- English = 1,
-};
-
class AppletOE final : public ServiceFramework<AppletOE> {
public:
AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger);