mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-10-27 01:38:05 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 76592ec6d5 | |||
| 1059202c75 |
@@ -304,16 +304,6 @@ if (ARCHITECTURE_arm64 AND (ANDROID OR LINUX))
|
||||
add_compile_definitions(HAS_NCE=1)
|
||||
endif()
|
||||
|
||||
set(ENABLE_SCARLETNX_DEFAULT ON)
|
||||
if ((NOT LINUX AND NOT FREEBSD) OR (NOT CMAKE_C_COMPILER_ID MATCHES "Clang" OR NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
|
||||
set(ENABLE_SCARLETNX_DEFAULT OFF)
|
||||
endif()
|
||||
option(ENABLE_SCARLETNX "Enable the ScarletNX recompiler CPU backend (requires Clang and LLVM)" "${ENABLE_SCARLETNX_DEFAULT}")
|
||||
if (ENABLE_SCARLETNX)
|
||||
set(HAS_SCARLETNX 1)
|
||||
add_compile_definitions(HAS_SCARLETNX=1)
|
||||
endif()
|
||||
|
||||
if (YUZU_ROOM)
|
||||
add_compile_definitions(YUZU_ROOM)
|
||||
endif()
|
||||
|
||||
@@ -243,27 +243,6 @@
|
||||
"repo": "crosire/reshade",
|
||||
"version": "v6.8.0"
|
||||
},
|
||||
"scarletnx": {
|
||||
"bundled": true,
|
||||
"hash": "93f7e6810644253d6396239092d5769c44b005fa7a17cf39c6d773050a19de74fca1f96bb6eec7cb40384eb158b2595c9e1171ad592d8eb8326fd31f5632f505",
|
||||
"options": [
|
||||
"SNX_BUILD_NX OFF",
|
||||
"SNX_BUILD_GNUABI OFF",
|
||||
"SNX_BUILD_3DS OFF",
|
||||
"SNX_BUILD_VITA OFF",
|
||||
"SNX_BUILD_AGB OFF",
|
||||
"SNX_DEPLOY OFF",
|
||||
"SNX_BUILD_TESTING OFF",
|
||||
"SNX_BUILD_GUI OFF",
|
||||
"SNX_MULTICALL OFF",
|
||||
"SNX_TRACY OFF",
|
||||
"SNX_RECOMPILER_SHARED OFF",
|
||||
"SNX_LLVM_SHARED OFF"
|
||||
],
|
||||
"package": "ScarletNX",
|
||||
"repo": "scarletnx/ScarletNX",
|
||||
"version": "f16810ce9c"
|
||||
},
|
||||
"sdl3": {
|
||||
"hash": "df5a323af7ac366661a3c0e887969c72584d232f3cc211419d59b0487b620b6b2859d4549c9e8df002ee489290062e466fcfddf7edc0872a37b1f2845e81c0f3",
|
||||
"min_version": "3.2.10",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Design Overview
|
||||
|
||||
Modern game consoles require heavy power to be emulated appropriately. This is why the emulator uses an approach known as HLE (High-Level-Emulation), in a nutshell: Instead of accurately emulating every subsystem that forms part of a component, emulate the resulting visible I/O interface instead.
|
||||
Modern game consoles require heavy power to emulate. This is why the emulator uses an approach known as HLE (High-Level-Emulation), in a nutshell: Instead of accurately emulating every subsystem that forms part of a component, emulate the resulting visible output of said interface instead.
|
||||
|
||||
For example, take a disk write, instead of emulating a proper SD card we instead use the C++ standard library for I/O. Additionally we use the abstractions provided by the `fs` service to "lie" to programs about certain SD card properties. Notably this includes making up sizes for the fake SD card, giving "realistic" values or expected outputs for a given card, and so on. And instead of writing to an actual SD card, the emulator simply writes to a file.
|
||||
|
||||
|
||||
@@ -78,9 +78,6 @@ The following options are desktop only.
|
||||
- `ENABLE_OPENGL` (ON) Enable the OpenGL graphics backend
|
||||
- Unavailable on Windows/ARM64 and on Android
|
||||
- You probably shouldn't turn this off.
|
||||
- `ENABLE_SCARLETNX` (OFF) Enable the ScarletNX recompiler
|
||||
- Requires Clang and LLVM's development files
|
||||
- Needs multicore and fastmem
|
||||
|
||||
### Qt
|
||||
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ This contains documentation created by developers, build instructions, guideline
|
||||
- Subsystems:
|
||||
- **[Design Overview](./DesignOverview.md)**
|
||||
- **[Dynarmic](./dynarmic/README.md)**
|
||||
- **[HOS Kernel](./HosKernel.md)**
|
||||
- **[Subsystem: HLE](./SubsystemHLE.md)**
|
||||
- **[Settings](./Settings.md)**
|
||||
|
||||
## Policies
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
# HOS Kernel
|
||||
# Subsystem: HLE
|
||||
|
||||
## HOS Kernel
|
||||
|
||||
In brief, the HOS kernel is a microkernel, all services and programs run in userspace, the primary way to do communication between these is via `HIPC` (not covered here); otherwise most of the primitives reside in the forms of syscalls invoked via `svc #imm`. The kernel supports both 32-bit and 64-bit programs, and has the capacity to use 32, 36 and 39 bits of address space for spawned processes. Most of the networking stack is based off FreeBSD's network stack.
|
||||
|
||||
@@ -29,3 +31,52 @@ Every process keeps it's own tracking of the following structures:
|
||||
The emulator willingly restricts itself to only use 4 threads (to emulate 4 cores), this is because most existing applications do not benefit greatly from the added core count, and in fact can be detrimental due to extra contention. This translates equitatively to about 4 `ArmInterface` slots for each process, these are then redirected to whatever is the last `pc` of the last thread running on the core is meant to be; proceed to run it, then when returning (due to halt or interruption), proceed to reschedule the thread.
|
||||
|
||||
The scheduler as-is isn't 100% faithful to the original (for example the original is cooperative and not preemptive), and has great timing variance (especially due to the fact the emulator can run in systems with wildly different timings).
|
||||
|
||||
## Services
|
||||
|
||||
Consult [SwitchBrew](https://switchbrew.org/) for per-service methods, and implementation details.
|
||||
|
||||
All services are instatiated implicitly using `ServiceFramework`. To register a new interface or service, you can inherit from said class, providing additionally a template parameter that references `Self`, for example:
|
||||
|
||||
```c++
|
||||
// Follows as:
|
||||
// class MyInterface [final] : public ServiceFramework<MyInterface> { ... };
|
||||
// [final] is optional, but should be used whenever there is no intention of this class itself being inherited.
|
||||
class IFloatingRegistrationRequest final : public ServiceFramework<IFloatingRegistrationRequest> {
|
||||
public:
|
||||
// ctor, you can pass extra parameters here (if so required)
|
||||
explicit IFloatingRegistrationRequest(Core::System& system_)
|
||||
: ServiceFramework{system_, "IFloatingRegistrationRequest"}
|
||||
{}
|
||||
|
||||
// Must be placed after all methods are defined (or declared).
|
||||
// Define here your functions and methods, please order them.
|
||||
// Use FindRequestTipc for TIPC handlers.
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, nullptr, "GetSessionId"},
|
||||
FunctionInfo{12, nullptr, "GetAccountId"},
|
||||
FunctionInfo{13, nullptr, "GetLinkedNintendoAccountId"},
|
||||
FunctionInfo{14, nullptr, "GetNickname"},
|
||||
FunctionInfo{15, nullptr, "GetProfileImage"},
|
||||
FunctionInfo{16, nullptr, "GetProfileLargeImage", MakeVersionGate({18,0,0})},
|
||||
FunctionInfo{21, nullptr, "LoadIdTokenCache"},
|
||||
FunctionInfo{100, nullptr, "RegisterUser"},
|
||||
FunctionInfo{101, nullptr, "RegisterUserWithUid"},
|
||||
FunctionInfo{102, nullptr, "RegisterNetworkServiceAccountAsync", MakeVersionGate({4,0,0})},
|
||||
FunctionInfo{103, nullptr, "RegisterNetworkServiceAccountWithUidAsync", MakeVersionGate({4,0,0})},
|
||||
FunctionInfo{110, nullptr, "SetSystemProgramIdentification"},
|
||||
FunctionInfo{111, nullptr, "EnsureIdTokenCacheAsync"}
|
||||
);
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
Try to keep service structures local, that is, don't place them on header files if they're only going to be used by a specific service.
|
||||
|
||||
In each `.cpp` file that uses `D<...>/C<...>` CMIF wrapper helpers, remember to include the corresponding instancer, so you don't face linker errors:
|
||||
```c++
|
||||
#include "core/hle/service/cmif_serialization.h"
|
||||
```
|
||||
This will properly instatiate the corresponding wrappers and decompose the provided arguments in the wiring order.
|
||||
Vendored
-8
@@ -249,14 +249,6 @@ if (YUZU_TESTS OR DYNARMIC_TESTS)
|
||||
AddJsonPackage(catch2)
|
||||
endif()
|
||||
|
||||
# ScarletNX
|
||||
if (ENABLE_SCARLETNX)
|
||||
AddJsonPackage(scarletnx)
|
||||
if (TARGET scarletnx-recompiler)
|
||||
set_target_properties(scarletnx-recompiler PROPERTIES SYSTEM ON)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# getopt
|
||||
if (MSVC)
|
||||
add_subdirectory(getopt)
|
||||
|
||||
@@ -259,7 +259,7 @@ android {
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
version = "3.31.5"
|
||||
version = "3.31.6"
|
||||
path = file("${edenDir}/CMakeLists.txt")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -256,9 +256,7 @@ struct Values {
|
||||
CpuBackend::Dynarmic,
|
||||
#endif
|
||||
CpuBackend::Dynarmic,
|
||||
#if defined(HAS_SCARLETNX)
|
||||
CpuBackend::ScarletNx,
|
||||
#elif defined(HAS_NCE)
|
||||
#ifdef HAS_NCE
|
||||
CpuBackend::Nce,
|
||||
#else
|
||||
CpuBackend::Dynarmic,
|
||||
|
||||
@@ -138,7 +138,7 @@ ENUM(RendererBackend, OpenGL_GLSL, Vulkan, Null, OpenGL_GLASM, OpenGL_SPIRV);
|
||||
ENUM(GpuAccuracy, Low, High);
|
||||
ENUM(DmaAccuracy, Default, Unsafe, Safe);
|
||||
ENUM(GpuFenceBehavior, Default, Immediate, Balanced, Accurate);
|
||||
ENUM(CpuBackend, Dynarmic, Nce, ScarletNx);
|
||||
ENUM(CpuBackend, Dynarmic, Nce);
|
||||
ENUM(CpuAccuracy, Auto, Accurate, Unsafe, Paranoid, Debugging);
|
||||
ENUM(CpuClock, Normal, Boost, Overclock)
|
||||
ENUM(MemoryLayout, Memory_4Gb, Memory_6Gb, Memory_8Gb, Memory_10Gb, Memory_12Gb);
|
||||
|
||||
+1
-81
@@ -444,28 +444,18 @@ add_library(core STATIC
|
||||
hle/service/am/process_creation.h
|
||||
hle/service/am/process_holder.cpp
|
||||
hle/service/am/process_holder.h
|
||||
hle/service/am/service/all_system_applet_proxies_service.cpp
|
||||
hle/service/am/service/all_system_applet_proxies_service.h
|
||||
hle/service/am/service/applet_common_functions.cpp
|
||||
hle/service/am/service/applet_common_functions.h
|
||||
hle/service/am/service/application_accessor.cpp
|
||||
hle/service/am/service/application_accessor.h
|
||||
hle/service/am/service/application_creator.cpp
|
||||
hle/service/am/service/application_creator.h
|
||||
hle/service/am/service/application_functions.cpp
|
||||
hle/service/am/service/application_functions.h
|
||||
hle/service/am/service/application_proxy.cpp
|
||||
hle/service/am/service/application_proxy.h
|
||||
hle/service/am/service/application_proxy_service.cpp
|
||||
hle/service/am/service/application_proxy_service.h
|
||||
hle/service/am/service/audio_controller.cpp
|
||||
hle/service/am/service/audio_controller.h
|
||||
hle/service/am/service/common_state_getter.cpp
|
||||
hle/service/am/service/common_state_getter.h
|
||||
hle/service/am/service/cradle_firmware_updater.cpp
|
||||
hle/service/am/service/cradle_firmware_updater.h
|
||||
hle/service/am/service/debug_functions.cpp
|
||||
hle/service/am/service/debug_functions.h
|
||||
hle/service/am/service/display_controller.cpp
|
||||
hle/service/am/service/display_controller.h
|
||||
hle/service/am/service/global_state_controller.cpp
|
||||
@@ -474,28 +464,14 @@ add_library(core STATIC
|
||||
hle/service/am/service/home_menu_functions.h
|
||||
hle/service/am/service/library_applet_accessor.cpp
|
||||
hle/service/am/service/library_applet_accessor.h
|
||||
hle/service/am/service/library_applet_creator.cpp
|
||||
hle/service/am/service/library_applet_creator.h
|
||||
hle/service/am/service/library_applet_proxy.cpp
|
||||
hle/service/am/service/library_applet_proxy.h
|
||||
hle/service/am/service/library_applet_self_accessor.cpp
|
||||
hle/service/am/service/library_applet_self_accessor.h
|
||||
hle/service/am/service/lock_accessor.cpp
|
||||
hle/service/am/service/lock_accessor.h
|
||||
hle/service/am/service/overlay_functions.cpp
|
||||
hle/service/am/service/overlay_functions.h
|
||||
hle/service/am/service/overlay_applet_proxy.cpp
|
||||
hle/service/am/service/overlay_applet_proxy.h
|
||||
hle/service/am/service/process_winding_controller.cpp
|
||||
hle/service/am/service/process_winding_controller.h
|
||||
hle/service/am/service/self_controller.cpp
|
||||
hle/service/am/service/self_controller.h
|
||||
hle/service/am/service/storage.cpp
|
||||
hle/service/am/service/storage.h
|
||||
hle/service/am/service/storage_accessor.cpp
|
||||
hle/service/am/service/storage_accessor.h
|
||||
hle/service/am/service/system_applet_proxy.cpp
|
||||
hle/service/am/service/system_applet_proxy.h
|
||||
hle/service/am/service/window_controller.cpp
|
||||
hle/service/am/service/window_controller.h
|
||||
hle/service/am/window_system.cpp
|
||||
@@ -580,20 +556,8 @@ add_library(core STATIC
|
||||
hle/service/btdrv/btdrv.h
|
||||
hle/service/btm/btm.cpp
|
||||
hle/service/btm/btm.h
|
||||
hle/service/btm/btm_debug.cpp
|
||||
hle/service/btm/btm_debug.h
|
||||
hle/service/btm/btm_system.cpp
|
||||
hle/service/btm/btm_system.h
|
||||
hle/service/btm/btm_system_core.cpp
|
||||
hle/service/btm/btm_system_core.h
|
||||
hle/service/btm/btm_user.cpp
|
||||
hle/service/btm/btm_user.h
|
||||
hle/service/btm/btm_user_core.cpp
|
||||
hle/service/btm/btm_user_core.h
|
||||
hle/service/caps/caps.cpp
|
||||
hle/service/caps/caps.h
|
||||
hle/service/caps/caps_a.cpp
|
||||
hle/service/caps/caps_a.h
|
||||
hle/service/caps/caps_c.cpp
|
||||
hle/service/caps/caps_c.h
|
||||
hle/service/caps/caps_manager.cpp
|
||||
@@ -618,10 +582,6 @@ add_library(core STATIC
|
||||
hle/service/eupld/eupld.h
|
||||
hle/service/fatal/fatal.cpp
|
||||
hle/service/fatal/fatal.h
|
||||
hle/service/fatal/fatal_p.cpp
|
||||
hle/service/fatal/fatal_p.h
|
||||
hle/service/fatal/fatal_u.cpp
|
||||
hle/service/fatal/fatal_u.h
|
||||
hle/service/fgm/fgm.cpp
|
||||
hle/service/fgm/fgm.h
|
||||
hle/service/filesystem/filesystem.cpp
|
||||
@@ -653,8 +613,6 @@ add_library(core STATIC
|
||||
hle/service/filesystem/save_data_controller.h
|
||||
hle/service/friend/friend.cpp
|
||||
hle/service/friend/friend.h
|
||||
hle/service/friend/friend_interface.cpp
|
||||
hle/service/friend/friend_interface.h
|
||||
hle/service/glue/arp.cpp
|
||||
hle/service/glue/arp.h
|
||||
hle/service/glue/bgtc.cpp
|
||||
@@ -723,8 +681,6 @@ add_library(core STATIC
|
||||
hle/service/ldn/monitor_service.h
|
||||
hle/service/ldn/sf_monitor_service.cpp
|
||||
hle/service/ldn/sf_monitor_service.h
|
||||
hle/service/ldn/sf_service.cpp
|
||||
hle/service/ldn/sf_service.h
|
||||
hle/service/ldn/sf_service_monitor.cpp
|
||||
hle/service/ldn/sf_service_monitor.h
|
||||
hle/service/ldn/system_local_communication_service.cpp
|
||||
@@ -913,8 +869,6 @@ add_library(core STATIC
|
||||
hle/service/olsc/native_handle_holder.h
|
||||
hle/service/olsc/olsc_service_for_application.cpp
|
||||
hle/service/olsc/olsc_service_for_application.h
|
||||
hle/service/olsc/olsc_service_for_system_service.cpp
|
||||
hle/service/olsc/olsc_service_for_system_service.h
|
||||
hle/service/olsc/olsc.cpp
|
||||
hle/service/olsc/olsc.h
|
||||
hle/service/olsc/remote_storage_controller.cpp
|
||||
@@ -944,14 +898,8 @@ add_library(core STATIC
|
||||
hle/service/os/process.h
|
||||
hle/service/pcie/pcie.cpp
|
||||
hle/service/pcie/pcie.h
|
||||
hle/service/pctl/parental_control_service_factory.cpp
|
||||
hle/service/pctl/parental_control_service_factory.h
|
||||
hle/service/pctl/parental_control_service.cpp
|
||||
hle/service/pctl/parental_control_service.h
|
||||
hle/service/pctl/pctl.cpp
|
||||
hle/service/pctl/pctl.h
|
||||
hle/service/pctl/pctl_results.h
|
||||
hle/service/pctl/pctl_types.h
|
||||
hle/service/pcv/pcv.cpp
|
||||
hle/service/pcv/pcv.h
|
||||
hle/service/pm/pm.cpp
|
||||
@@ -961,18 +909,8 @@ add_library(core STATIC
|
||||
hle/service/psc/ovln/ovln_types.h
|
||||
hle/service/psc/ovln/receiver_service.cpp
|
||||
hle/service/psc/ovln/receiver_service.h
|
||||
hle/service/psc/ovln/receiver.cpp
|
||||
hle/service/psc/ovln/receiver.h
|
||||
hle/service/psc/ovln/sender_service.cpp
|
||||
hle/service/psc/ovln/sender_service.h
|
||||
hle/service/psc/ovln/sender.cpp
|
||||
hle/service/psc/ovln/sender.h
|
||||
hle/service/psc/pm_control.cpp
|
||||
hle/service/psc/pm_control.h
|
||||
hle/service/psc/pm_module.cpp
|
||||
hle/service/psc/pm_module.h
|
||||
hle/service/psc/pm_service.cpp
|
||||
hle/service/psc/pm_service.h
|
||||
hle/service/psc/psc.cpp
|
||||
hle/service/psc/psc.h
|
||||
hle/service/psc/time/alarms.cpp
|
||||
@@ -1023,10 +961,6 @@ add_library(core STATIC
|
||||
hle/service/ptm/ts.h
|
||||
hle/service/ro/ro.cpp
|
||||
hle/service/ro/ro.h
|
||||
hle/service/ro/ro_nro_utils.cpp
|
||||
hle/service/ro/ro_nro_utils.h
|
||||
hle/service/ro/ro_results.h
|
||||
hle/service/ro/ro_types.h
|
||||
hle/service/server_manager.cpp
|
||||
hle/service/server_manager.h
|
||||
hle/service/service.cpp
|
||||
@@ -1055,8 +989,6 @@ add_library(core STATIC
|
||||
hle/service/set/system_settings_server.h
|
||||
hle/service/sm/sm.cpp
|
||||
hle/service/sm/sm.h
|
||||
hle/service/sm/sm_controller.cpp
|
||||
hle/service/sm/sm_controller.h
|
||||
hle/service/sockets/bsd.cpp
|
||||
hle/service/sockets/bsd.h
|
||||
hle/service/sockets/nsd.cpp
|
||||
@@ -1222,7 +1154,7 @@ target_link_libraries(core PRIVATE
|
||||
RenderDoc::API
|
||||
ZLIB::ZLIB)
|
||||
|
||||
target_link_libraries(core PUBLIC httplib::httplib zstd::zstd)
|
||||
target_link_libraries(core PUBLIC httplib::httplib zstd::zstd frozen::frozen-headers)
|
||||
|
||||
if (ENABLE_WEB_SERVICE)
|
||||
target_compile_definitions(core PUBLIC ENABLE_WEB_SERVICE)
|
||||
@@ -1248,18 +1180,6 @@ if (HAS_NCE)
|
||||
target_link_libraries(core PRIVATE merry::oaknut)
|
||||
endif()
|
||||
|
||||
if (HAS_SCARLETNX)
|
||||
target_sources(core PRIVATE
|
||||
arm/scarletnx/arm_scarletnx_32.cpp
|
||||
arm/scarletnx/arm_scarletnx_32.h
|
||||
arm/scarletnx/arm_scarletnx_64.cpp
|
||||
arm/scarletnx/arm_scarletnx_64.h
|
||||
arm/scarletnx/scarletnx_api.h
|
||||
arm/scarletnx/scarletnx_process.cpp
|
||||
arm/scarletnx/scarletnx_process.h)
|
||||
target_link_libraries(core PRIVATE ScarletNX::recompiler)
|
||||
endif()
|
||||
|
||||
if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64 OR ARCHITECTURE_riscv64 OR ARCHITECTURE_loongarch64)
|
||||
target_sources(core PRIVATE
|
||||
arm/dynarmic/arm_dynarmic.h
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
/* SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project */
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
@@ -1,227 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include <cstring>
|
||||
#include <utility>
|
||||
#include <atomic>
|
||||
|
||||
#include "common/logging.h"
|
||||
#include "core/arm/scarletnx/arm_scarletnx_32.h"
|
||||
#include "core/core.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/hle/kernel/k_process.h"
|
||||
|
||||
namespace Core {
|
||||
|
||||
namespace {
|
||||
|
||||
// The exit SignalInterrupt sets, which no block sets itself.
|
||||
constexpr u32 InterruptExit = 0x1000;
|
||||
constexpr u32 UserMode = 0x10;
|
||||
constexpr u32 ModeMask = 0x1F;
|
||||
|
||||
// FPSCR splits into FPSR and FPCR as in ArmDynarmic32.
|
||||
std::pair<u32, u32> FpscrToFpsrFpcr(u32 fpscr) {
|
||||
const u32 fpsr = (fpscr & 0xf8000000) | (fpscr & 0x80) | (fpscr & 0x1f);
|
||||
const u32 fpcr = (fpscr & 0x7ff8000) | (fpscr & 0x1f00);
|
||||
return {fpsr, fpcr};
|
||||
}
|
||||
|
||||
u32 FpsrFpcrToFpscr(u64 fpsr, u64 fpcr) {
|
||||
const auto [s, c] = FpscrToFpsrFpcr(u32(fpsr | fpcr));
|
||||
return s | c;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ArmScarletNx32::ArmScarletNx32(std::shared_ptr<ScarletNxProcess> process, std::size_t core_index)
|
||||
: ArmInterface{true}, m_process{std::move(process)}, m_core_index{core_index} {
|
||||
m_rt.coproc = &Coprocessor;
|
||||
m_cpu.parent = this;
|
||||
m_cpu.cpu.mem = m_process->m_arena;
|
||||
m_cpu.cpu.mem_size = 1ULL << 32;
|
||||
m_cpu.cpu.rt = &m_rt;
|
||||
|
||||
m_fault_scope.memory = &m_process->m_process.GetMemory();
|
||||
m_fault_scope.arena = m_process->m_arena;
|
||||
m_fault_scope.arena_size = ScarletNxProcess::ArenaSize;
|
||||
}
|
||||
|
||||
ArmScarletNx32::~ArmScarletNx32() {
|
||||
snx_recompiled32_free(m_module);
|
||||
}
|
||||
|
||||
int ArmScarletNx32::Svc(void* context, u32 imm, u64 number, const u64 arguments[6]) {
|
||||
auto& self = *static_cast<ArmScarletNx32*>(context);
|
||||
self.m_svc = imm;
|
||||
self.m_in_svc = true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ArmScarletNx32::Coprocessor(SnxArmCPU* cpu, u32 word) {
|
||||
auto& self = *reinterpret_cast<Cpu32*>(cpu)->parent;
|
||||
const u32 coproc = (word >> 8) & 0xF;
|
||||
const u32 crm = word & 0xF;
|
||||
|
||||
if (coproc == 15 && (word & 0x0F100010) == 0x0E000010) {
|
||||
// MCR p15
|
||||
const u32 opc1 = (word >> 21) & 7;
|
||||
const u32 crn = (word >> 16) & 0xF;
|
||||
const u32 opc2 = (word >> 5) & 7;
|
||||
if (opc1 == 0 && crn == 7 && crm == 5 && opc2 == 4) {
|
||||
// CP15_FLUSH_PREFETCH_BUFFER
|
||||
return;
|
||||
}
|
||||
if (opc1 == 0 && crn == 7 && crm == 10 && (opc2 == 4 || opc2 == 5)) {
|
||||
// CP15_DATA_SYNC_BARRIER, CP15_DATA_MEMORY_BARRIER
|
||||
std::atomic_thread_fence(std::memory_order_seq_cst);
|
||||
return;
|
||||
}
|
||||
} else if (coproc == 15 && (word & 0x0FF00000) == 0x0C500000) {
|
||||
// MRRC p15
|
||||
const u32 opc1 = (word >> 4) & 0xF;
|
||||
const u32 rt = (word >> 12) & 0xF;
|
||||
const u32 rt2 = (word >> 16) & 0xF;
|
||||
if (opc1 == 0 && crm == 14) {
|
||||
// CNTPCT
|
||||
const u64 ticks = self.m_process->m_system.CoreTiming().GetClockTicks();
|
||||
cpu->r[rt] = u32(ticks);
|
||||
cpu->r[rt2] = u32(ticks >> 32);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// TPIDRURW and TPIDRURO, and undefined for anything else.
|
||||
snx_arm_coproc_user(cpu, word);
|
||||
ASSERT(cpu->exit == SNX_ARM_OK && "unhandled coproc");
|
||||
}
|
||||
|
||||
HaltReason ArmScarletNx32::RunThread(Kernel::KThread* thread) {
|
||||
if (m_interrupt.exchange(false)) {
|
||||
return HaltReason::BreakLoop;
|
||||
}
|
||||
|
||||
// The block cache only covers the code present when it was made.
|
||||
const u64 generation = m_process->CodeGeneration();
|
||||
if (!m_module || generation != m_code_generation) {
|
||||
snx_recompiled32_free(m_module);
|
||||
m_module = m_process->MakeModule32();
|
||||
m_code_generation = generation;
|
||||
}
|
||||
|
||||
LoadCpu();
|
||||
m_in_svc = false;
|
||||
m_fault_scope.last_fault = ~u64{};
|
||||
SetScarletNxFaultScope(&m_fault_scope);
|
||||
if (sigsetjmp(m_fault_scope.env, 1) != 0) {
|
||||
SetScarletNxFaultScope(nullptr);
|
||||
LOG_CRITICAL(Core_ARM, "invalid memory access at {:#x}",
|
||||
m_fault_scope.fault_address);
|
||||
SaveCpu();
|
||||
return HaltReason::PrefetchAbort;
|
||||
}
|
||||
const int exit =
|
||||
m_module ? snx_recompiled32_run(m_module, &m_cpu.cpu, &Svc, this) : SNX_ARM_BAD_ENTRY;
|
||||
SetScarletNxFaultScope(nullptr);
|
||||
|
||||
SaveCpu();
|
||||
return Halt(exit);
|
||||
}
|
||||
|
||||
HaltReason ArmScarletNx32::Halt(int exit) {
|
||||
if (m_in_svc) {
|
||||
return HaltReason::SupervisorCall;
|
||||
}
|
||||
u32 const pc = m_cpu.cpu.r[15];
|
||||
u32 const syndrome = m_cpu.cpu.syndrome;
|
||||
switch (u32(exit)) {
|
||||
case InterruptExit:
|
||||
m_interrupt.store(false);
|
||||
return HaltReason::BreakLoop;
|
||||
case SNX_ARM_BREAKPOINT:
|
||||
// As Dynarmic does without a debugger: report it and go on.
|
||||
LOG_CRITICAL(Core_ARM, "BKPT #{:#x} at {:#x}", syndrome, pc);
|
||||
return HaltReason::BreakLoop;
|
||||
default:
|
||||
LOG_CRITICAL(Core_ARM, "A32 exit {} at {:#x} (syndrome {:#x})", exit, pc, syndrome);
|
||||
return HaltReason::PrefetchAbort;
|
||||
}
|
||||
}
|
||||
|
||||
HaltReason ArmScarletNx32::StepThread(Kernel::KThread* thread) {
|
||||
// Never reached: the debugger selects Dynarmic.
|
||||
LOG_ERROR(Core_ARM, "ScarletNX cannot single step");
|
||||
return HaltReason::BreakLoop;
|
||||
}
|
||||
|
||||
void ArmScarletNx32::LoadCpu() {
|
||||
auto& cpu = m_cpu.cpu;
|
||||
static_assert(sizeof(cpu.d) <= sizeof(m_ctx.v));
|
||||
for (std::size_t i = 0; i < 16; i++)
|
||||
cpu.r[i] = u32(m_ctx.r[i]);
|
||||
cpu.cpsr = (m_ctx.pstate & ~ModeMask) | UserMode;
|
||||
std::memcpy(cpu.d, m_ctx.v.data(), sizeof(cpu.d));
|
||||
cpu.fpscr = FpsrFpcrToFpscr(m_ctx.fpsr, m_ctx.fpcr);
|
||||
cpu.tpidrurw = u32(m_ctx.tpidr);
|
||||
cpu.tpidruro = m_tpidrro;
|
||||
cpu.exclusive_valid = 0;
|
||||
}
|
||||
|
||||
void ArmScarletNx32::SaveCpu() {
|
||||
const auto& cpu = m_cpu.cpu;
|
||||
for (std::size_t i = 0; i < 16; i++)
|
||||
m_ctx.r[i] = cpu.r[i];
|
||||
m_ctx.fp = cpu.r[11];
|
||||
m_ctx.sp = cpu.r[13];
|
||||
m_ctx.lr = cpu.r[14];
|
||||
m_ctx.pc = cpu.r[15];
|
||||
m_ctx.pstate = cpu.cpsr;
|
||||
std::memcpy(m_ctx.v.data(), cpu.d, sizeof(cpu.d));
|
||||
const auto [fpsr, fpcr] = FpscrToFpsrFpcr(cpu.fpscr);
|
||||
m_ctx.fpsr = fpsr;
|
||||
m_ctx.fpcr = fpcr;
|
||||
m_ctx.tpidr = cpu.tpidrurw;
|
||||
}
|
||||
|
||||
void ArmScarletNx32::GetContext(Kernel::Svc::ThreadContext& ctx) const {
|
||||
ctx = m_ctx;
|
||||
}
|
||||
|
||||
void ArmScarletNx32::SetContext(const Kernel::Svc::ThreadContext& ctx) {
|
||||
m_ctx = ctx;
|
||||
}
|
||||
|
||||
void ArmScarletNx32::SetTpidrroEl0(u64 value) {
|
||||
m_tpidrro = u32(value);
|
||||
}
|
||||
|
||||
void ArmScarletNx32::GetSvcArguments(std::span<uint64_t, 8> args) const {
|
||||
for (std::size_t i = 0; i < args.size(); i++)
|
||||
args[i] = u32(m_ctx.r[i]);
|
||||
}
|
||||
|
||||
void ArmScarletNx32::SetSvcArguments(std::span<const uint64_t, 8> args) {
|
||||
for (std::size_t i = 0; i < args.size(); i++)
|
||||
m_ctx.r[i] = u32(args[i]);
|
||||
}
|
||||
|
||||
u32 ArmScarletNx32::GetSvcNumber() const {
|
||||
return m_svc;
|
||||
}
|
||||
|
||||
void ArmScarletNx32::SignalInterrupt(Kernel::KThread* thread) {
|
||||
// The run loop checks the exit between blocks. A block's own exit takes precedence.
|
||||
m_interrupt.store(true);
|
||||
u32 expected = SNX_ARM_OK;
|
||||
__atomic_compare_exchange_n(&m_cpu.cpu.exit, &expected, InterruptExit, false, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED);
|
||||
}
|
||||
|
||||
void ArmScarletNx32::ClearInstructionCache() {
|
||||
m_process->ClearInstructionCache();
|
||||
}
|
||||
|
||||
void ArmScarletNx32::InvalidateCacheRange(u64 addr, std::size_t size) {
|
||||
m_process->InvalidateCacheRange(addr, size);
|
||||
}
|
||||
|
||||
} // namespace Core
|
||||
@@ -1,81 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
|
||||
#include "core/arm/arm_interface.h"
|
||||
#include "core/arm/scarletnx/scarletnx_api.h"
|
||||
#include "core/arm/scarletnx/scarletnx_process.h"
|
||||
|
||||
namespace Core {
|
||||
|
||||
/// Runs A32 and Thumb code through ScarletNX's block compiler. Blocks return to the run loop, so
|
||||
/// an SVC ends the run with r15 past it. The block cache is not thread-safe, so each core has its
|
||||
/// own, rebuilt when the process' code changes.
|
||||
class ArmScarletNx32 final : public ArmInterface {
|
||||
public:
|
||||
ArmScarletNx32(std::shared_ptr<ScarletNxProcess> process, std::size_t core_index);
|
||||
~ArmScarletNx32() override;
|
||||
|
||||
Architecture GetArchitecture() const override {
|
||||
return Architecture::AArch32;
|
||||
}
|
||||
|
||||
HaltReason RunThread(Kernel::KThread* thread) override;
|
||||
HaltReason StepThread(Kernel::KThread* thread) override;
|
||||
|
||||
void GetContext(Kernel::Svc::ThreadContext& ctx) const override;
|
||||
void SetContext(const Kernel::Svc::ThreadContext& ctx) override;
|
||||
void SetTpidrroEl0(u64 value) override;
|
||||
|
||||
void GetSvcArguments(std::span<uint64_t, 8> args) const override;
|
||||
void SetSvcArguments(std::span<const uint64_t, 8> args) override;
|
||||
u32 GetSvcNumber() const override;
|
||||
|
||||
void SignalInterrupt(Kernel::KThread* thread) override;
|
||||
void ClearInstructionCache() override;
|
||||
void InvalidateCacheRange(u64 addr, std::size_t size) override;
|
||||
|
||||
protected:
|
||||
const Kernel::DebugWatchpoint* HaltedWatchpoint() const override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void RewindBreakpointInstruction() override {}
|
||||
|
||||
private:
|
||||
// The CPU first, so the coprocessor hook can find its interface.
|
||||
struct Cpu32 {
|
||||
SnxArmCPU cpu;
|
||||
ArmScarletNx32* parent;
|
||||
};
|
||||
|
||||
static int Svc(void* context, u32 imm, u64 number, const u64 arguments[6]);
|
||||
static void Coprocessor(SnxArmCPU* cpu, u32 word);
|
||||
HaltReason Halt(int exit);
|
||||
void LoadCpu();
|
||||
void SaveCpu();
|
||||
|
||||
std::shared_ptr<ScarletNxProcess> m_process;
|
||||
std::size_t m_core_index{};
|
||||
|
||||
snx_recompiled32* m_module{};
|
||||
u64 m_code_generation{~u64{}};
|
||||
|
||||
// The context the kernel reads and writes; m_cpu holds it while guest code runs.
|
||||
Kernel::Svc::ThreadContext m_ctx{};
|
||||
u32 m_tpidrro{};
|
||||
Cpu32 m_cpu{};
|
||||
SnxArmRt m_rt{};
|
||||
|
||||
bool m_in_svc{};
|
||||
u32 m_svc{};
|
||||
std::atomic<bool> m_interrupt{};
|
||||
|
||||
ScarletNxFaultScope m_fault_scope{};
|
||||
};
|
||||
|
||||
} // namespace Core
|
||||
@@ -1,261 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/literals.h"
|
||||
#include "common/logging.h"
|
||||
#include "core/arm/scarletnx/arm_scarletnx_64.h"
|
||||
#include "core/hle/kernel/k_thread.h"
|
||||
#include "core/hle/kernel/k_process.h"
|
||||
|
||||
namespace Core {
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace Common::Literals;
|
||||
namespace ctx = boost::context::detail;
|
||||
|
||||
// Reserved, not committed: guest calls nest on it, and recompiling a region runs on it too.
|
||||
constexpr std::size_t StackSize = 32_MiB;
|
||||
constexpr std::size_t GuardSize = 64_KiB;
|
||||
|
||||
bool SameContext(const Kernel::Svc::ThreadContext a, const Kernel::Svc::ThreadContext b, bool in_svc) {
|
||||
// An SVC returns its results in x0-x7.
|
||||
for (std::size_t i = in_svc ? 8 : 0; i < a.r.size(); i++)
|
||||
if (a.r[i] != b.r[i])
|
||||
return false;
|
||||
return a.fp == b.fp && a.lr == b.lr && a.sp == b.sp && a.pc == b.pc
|
||||
&& (a.pstate >> 28) == (b.pstate >> 28) && a.v == b.v && a.fpcr == b.fpcr
|
||||
&& a.fpsr == b.fpsr && a.tpidr == b.tpidr;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
const RtAPI* ArmScarletNx64::Runtime() {
|
||||
// this incurs a cost each time we call Runtime() -- but we only ever call it once (ideally)
|
||||
static const RtAPI rt = [] {
|
||||
RtAPI api;
|
||||
snx_runtime_defaults(&api);
|
||||
api.svc = &Svc;
|
||||
api.undef = &Undefined;
|
||||
api.brk = &Breakpoint;
|
||||
api.poll = &Poll;
|
||||
api.miss = &Miss;
|
||||
api.code_changed = &CodeChanged;
|
||||
api.ticks = &ScarletNxTicks;
|
||||
return api;
|
||||
}();
|
||||
return &rt;
|
||||
}
|
||||
|
||||
ArmScarletNx64::ArmScarletNx64(std::shared_ptr<ScarletNxProcess> process, std::size_t core_index)
|
||||
: ArmInterface{true}
|
||||
, m_process{std::move(process)}, m_core_index{core_index}
|
||||
{
|
||||
// can't use virtualbuffer...
|
||||
void* const stack = mmap(nullptr, StackSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
ASSERT_MSG(stack != MAP_FAILED, "cannot allocate a guest stack");
|
||||
m_stack = static_cast<u8*>(stack);
|
||||
mprotect(m_stack, GuardSize, PROT_NONE);
|
||||
|
||||
m_cpu.mem = m_process->m_arena;
|
||||
m_cpu.rt = Runtime();
|
||||
m_cpu.thread = this;
|
||||
|
||||
m_fault_scope.memory = &m_process->m_process.GetMemory();
|
||||
m_fault_scope.arena = m_process->m_arena;
|
||||
m_fault_scope.arena_size = ScarletNxProcess::ArenaSize;
|
||||
}
|
||||
|
||||
ArmScarletNx64::~ArmScarletNx64() {
|
||||
munmap(m_stack, StackSize);
|
||||
}
|
||||
|
||||
void ArmScarletNx64::Svc(CPU* cpu, u32 imm) {
|
||||
auto& self = From(cpu);
|
||||
self.m_svc = imm;
|
||||
self.Yield(HaltReason::SupervisorCall, true, true);
|
||||
}
|
||||
|
||||
void ArmScarletNx64::Undefined(CPU* cpu, u64 pc, u32 word) {
|
||||
// A reserved encoding rejected from inside an instruction, which then goes on.
|
||||
if (cpu->pc != pc) {
|
||||
LOG_ERROR(Core_ARM, "reserved encoding {:08X} at {:#x}", word, pc);
|
||||
return;
|
||||
}
|
||||
LOG_CRITICAL(Core_ARM, "cannot execute {:08X} at {:#x}", word, pc);
|
||||
From(cpu).Yield(HaltReason::PrefetchAbort, false, false);
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
void ArmScarletNx64::Breakpoint(CPU* cpu, u64 pc, u32 imm) {
|
||||
// As Dynarmic does without a debugger: report it and go on.
|
||||
LOG_CRITICAL(Core_ARM, "BRK #{:#x} at {:#x}", imm, pc);
|
||||
cpu->pc = pc + 4;
|
||||
}
|
||||
|
||||
void ArmScarletNx64::Poll(CPU* cpu) {
|
||||
auto& self = From(cpu);
|
||||
__atomic_store_n(&cpu->poll, 0, __ATOMIC_RELAXED);
|
||||
if (self.m_interrupt.exchange(false))
|
||||
self.Yield(HaltReason::BreakLoop, true, false);
|
||||
}
|
||||
|
||||
void ArmScarletNx64::Miss(CPU* cpu, u64 pc) {
|
||||
auto& process = *From(cpu).m_process;
|
||||
const auto function = process.Lookup(pc);
|
||||
if (!function) {
|
||||
cpu->pc = pc;
|
||||
Undefined(cpu, pc, 0);
|
||||
return;
|
||||
}
|
||||
// The first region was recompiled by this lookup: dispatch through its table from now on.
|
||||
if (snx_recompiled* const module = cpu->disp ? nullptr : process.FindModule(pc))
|
||||
snx_recompiled_bind(module, cpu);
|
||||
function(cpu, pc);
|
||||
}
|
||||
|
||||
void ArmScarletNx64::CodeChanged(CPU* cpu, u64 addr) {
|
||||
constexpr u64 ICacheLineSize = 64;
|
||||
From(cpu).m_process->InvalidateCacheRange(addr & ~(ICacheLineSize - 1), ICacheLineSize);
|
||||
}
|
||||
|
||||
void ArmScarletNx64::Entry(ctx::transfer_t transfer) {
|
||||
auto* const self = static_cast<ArmScarletNx64*>(transfer.data);
|
||||
self->m_host = transfer.fctx;
|
||||
self->Execute();
|
||||
}
|
||||
|
||||
void ArmScarletNx64::Execute() {
|
||||
if (sigsetjmp(m_fault_scope.env, 1) != 0) {
|
||||
LOG_CRITICAL(Core_ARM, "invalid memory access at {:#x}", m_fault_scope.fault_address);
|
||||
Yield(HaltReason::PrefetchAbort, false, false);
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
// Every guest return to below the first frame comes back here.
|
||||
while (true)
|
||||
snx_lookup(&m_cpu, m_cpu.pc)(&m_cpu, m_cpu.pc);
|
||||
}
|
||||
|
||||
void ArmScarletNx64::Yield(HaltReason reason, bool resumable, bool in_svc) {
|
||||
m_halt = reason;
|
||||
m_resumable = resumable;
|
||||
m_suspended_in_svc = in_svc;
|
||||
m_host = ctx::jump_fcontext(m_host, nullptr).fctx;
|
||||
}
|
||||
|
||||
void ArmScarletNx64::ResetGuest() {
|
||||
m_guest = ctx::make_fcontext(m_stack + StackSize, StackSize - GuardSize, &Entry);
|
||||
if (snx_recompiled* const module = m_process->FindModule(m_cpu.pc))
|
||||
snx_recompiled_bind(module, &m_cpu);
|
||||
}
|
||||
|
||||
HaltReason ArmScarletNx64::RunThread(Kernel::KThread* thread) {
|
||||
if (m_interrupt.exchange(false))
|
||||
return HaltReason::BreakLoop;
|
||||
|
||||
bool const resume = m_resumable && m_suspended_thread_id == thread->GetThreadId() && SameContext(m_ctx, m_suspended_ctx, m_suspended_in_svc);
|
||||
LoadCpu();
|
||||
if (!resume)
|
||||
ResetGuest();
|
||||
|
||||
m_resumable = false;
|
||||
m_fault_scope.last_fault = ~u64{};
|
||||
SetScarletNxFaultScope(&m_fault_scope);
|
||||
m_guest = ctx::jump_fcontext(m_guest, this).fctx;
|
||||
SetScarletNxFaultScope(nullptr);
|
||||
|
||||
SaveCpu();
|
||||
if (m_resumable) {
|
||||
m_suspended_thread_id = thread->GetThreadId();
|
||||
m_suspended_ctx = m_ctx;
|
||||
}
|
||||
return m_halt;
|
||||
}
|
||||
|
||||
HaltReason ArmScarletNx64::StepThread(Kernel::KThread* thread) {
|
||||
// Never reached: the debugger selects Dynarmic.
|
||||
LOG_ERROR(Core_ARM, "ScarletNX cannot single step");
|
||||
return HaltReason::BreakLoop;
|
||||
}
|
||||
|
||||
void ArmScarletNx64::LoadCpu() {
|
||||
static_assert(sizeof(m_cpu.v) == sizeof(m_ctx.v));
|
||||
for (std::size_t i = 0; i < m_ctx.r.size(); i++)
|
||||
m_cpu.x[i] = m_ctx.r[i];
|
||||
m_cpu.x[29] = m_ctx.fp;
|
||||
m_cpu.x[30] = m_ctx.lr;
|
||||
m_cpu.x[31] = m_ctx.sp;
|
||||
m_cpu.pc = m_ctx.pc;
|
||||
set_nzcv(&m_cpu, m_ctx.pstate >> 28);
|
||||
std::memcpy(m_cpu.v, m_ctx.v.data(), sizeof(m_cpu.v));
|
||||
m_cpu.fpcr = m_ctx.fpcr;
|
||||
m_cpu.fpsr = m_ctx.fpsr;
|
||||
m_cpu.tpidr = m_ctx.tpidr;
|
||||
m_cpu.tpidrro = m_tpidrro;
|
||||
m_cpu.excl_on = 0;
|
||||
}
|
||||
|
||||
void ArmScarletNx64::SaveCpu() {
|
||||
for (std::size_t i = 0; i < m_ctx.r.size(); i++) {
|
||||
m_ctx.r[i] = m_cpu.x[i];
|
||||
}
|
||||
m_ctx.fp = m_cpu.x[29];
|
||||
m_ctx.lr = m_cpu.x[30];
|
||||
m_ctx.sp = m_cpu.x[31];
|
||||
m_ctx.pc = m_cpu.pc;
|
||||
m_ctx.pstate = get_nzcv(&m_cpu);
|
||||
std::memcpy(m_ctx.v.data(), m_cpu.v, sizeof(m_cpu.v));
|
||||
m_ctx.fpcr = m_cpu.fpcr;
|
||||
m_ctx.fpsr = m_cpu.fpsr;
|
||||
m_ctx.tpidr = m_cpu.tpidr;
|
||||
}
|
||||
|
||||
void ArmScarletNx64::GetContext(Kernel::Svc::ThreadContext& ctx) const {
|
||||
ctx = m_ctx;
|
||||
}
|
||||
|
||||
void ArmScarletNx64::SetContext(const Kernel::Svc::ThreadContext& ctx) {
|
||||
m_ctx = ctx;
|
||||
}
|
||||
|
||||
void ArmScarletNx64::SetTpidrroEl0(u64 value) {
|
||||
m_tpidrro = value;
|
||||
}
|
||||
|
||||
void ArmScarletNx64::GetSvcArguments(std::span<uint64_t, 8> args) const {
|
||||
for (std::size_t i = 0; i < args.size(); i++) {
|
||||
args[i] = m_ctx.r[i];
|
||||
}
|
||||
}
|
||||
|
||||
void ArmScarletNx64::SetSvcArguments(std::span<const uint64_t, 8> args) {
|
||||
for (std::size_t i = 0; i < args.size(); i++) {
|
||||
m_ctx.r[i] = args[i];
|
||||
}
|
||||
}
|
||||
|
||||
u32 ArmScarletNx64::GetSvcNumber() const {
|
||||
return m_svc;
|
||||
}
|
||||
|
||||
void ArmScarletNx64::SignalInterrupt(Kernel::KThread* thread) {
|
||||
// Generated code reads poll on backward branches and calls Poll, which yields.
|
||||
m_interrupt.store(true);
|
||||
__atomic_store_n(&m_cpu.poll, 1, __ATOMIC_RELAXED);
|
||||
}
|
||||
|
||||
void ArmScarletNx64::ClearInstructionCache() {
|
||||
m_process->ClearInstructionCache();
|
||||
}
|
||||
|
||||
void ArmScarletNx64::InvalidateCacheRange(u64 addr, std::size_t size) {
|
||||
m_process->InvalidateCacheRange(addr, size);
|
||||
}
|
||||
|
||||
} // namespace Core
|
||||
@@ -1,100 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
|
||||
#include <boost/context/detail/fcontext.hpp>
|
||||
|
||||
#include "core/arm/arm_interface.h"
|
||||
#include "core/arm/scarletnx/scarletnx_api.h"
|
||||
#include "core/arm/scarletnx/scarletnx_process.h"
|
||||
|
||||
namespace Core {
|
||||
|
||||
/// Runs A64 code recompiled by ScarletNX.
|
||||
///
|
||||
/// A recompiled guest function is a host function that returns when the guest function returns,
|
||||
/// so guest calls nest on the host stack and an SVC cannot return from the generated code. Guest
|
||||
/// code therefore runs on a coroutine of this core, which the SVC and interrupt hooks suspend.
|
||||
/// When the kernel next runs the same thread with the same context, the coroutine resumes;
|
||||
/// otherwise its host frames are dropped and execution restarts at the new pc through dispatch.
|
||||
class ArmScarletNx64 final : public ArmInterface {
|
||||
public:
|
||||
ArmScarletNx64(std::shared_ptr<ScarletNxProcess> process, std::size_t core_index);
|
||||
~ArmScarletNx64() override;
|
||||
|
||||
Architecture GetArchitecture() const override {
|
||||
return Architecture::AArch64;
|
||||
}
|
||||
|
||||
HaltReason RunThread(Kernel::KThread* thread) override;
|
||||
HaltReason StepThread(Kernel::KThread* thread) override;
|
||||
|
||||
void GetContext(Kernel::Svc::ThreadContext& ctx) const override;
|
||||
void SetContext(const Kernel::Svc::ThreadContext& ctx) override;
|
||||
void SetTpidrroEl0(u64 value) override;
|
||||
|
||||
void GetSvcArguments(std::span<uint64_t, 8> args) const override;
|
||||
void SetSvcArguments(std::span<const uint64_t, 8> args) override;
|
||||
u32 GetSvcNumber() const override;
|
||||
|
||||
void SignalInterrupt(Kernel::KThread* thread) override;
|
||||
void ClearInstructionCache() override;
|
||||
void InvalidateCacheRange(u64 addr, std::size_t size) override;
|
||||
|
||||
protected:
|
||||
const Kernel::DebugWatchpoint* HaltedWatchpoint() const override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void RewindBreakpointInstruction() override {}
|
||||
|
||||
private:
|
||||
static ArmScarletNx64& From(CPU* cpu) {
|
||||
return *static_cast<ArmScarletNx64*>(cpu->thread);
|
||||
}
|
||||
static const RtAPI* Runtime();
|
||||
|
||||
// Runtime hooks called by the generated code.
|
||||
static void Svc(CPU* cpu, u32 imm);
|
||||
static void Undefined(CPU* cpu, u64 pc, u32 word);
|
||||
static void Breakpoint(CPU* cpu, u64 pc, u32 imm);
|
||||
static void Poll(CPU* cpu);
|
||||
static void Miss(CPU* cpu, u64 pc);
|
||||
static void CodeChanged(CPU* cpu, u64 addr);
|
||||
|
||||
static void Entry(boost::context::detail::transfer_t transfer);
|
||||
[[noreturn]] void Execute();
|
||||
void Yield(HaltReason reason, bool resumable, bool in_svc);
|
||||
void ResetGuest();
|
||||
void LoadCpu();
|
||||
void SaveCpu();
|
||||
|
||||
std::shared_ptr<ScarletNxProcess> m_process;
|
||||
std::size_t m_core_index{};
|
||||
|
||||
// The context the kernel reads and writes; m_cpu holds it while guest code runs.
|
||||
Kernel::Svc::ThreadContext m_ctx{};
|
||||
u64 m_tpidrro{};
|
||||
CPU m_cpu{};
|
||||
|
||||
HaltReason m_halt{};
|
||||
u32 m_svc{};
|
||||
std::atomic<bool> m_interrupt{};
|
||||
|
||||
// The coroutine, and what it was suspended in, when it can be resumed.
|
||||
boost::context::detail::fcontext_t m_guest{};
|
||||
boost::context::detail::fcontext_t m_host{};
|
||||
u8* m_stack{};
|
||||
bool m_resumable{};
|
||||
bool m_suspended_in_svc{};
|
||||
u64 m_suspended_thread_id{};
|
||||
Kernel::Svc::ThreadContext m_suspended_ctx{};
|
||||
|
||||
ScarletNxFaultScope m_fault_scope{};
|
||||
};
|
||||
|
||||
} // namespace Core
|
||||
@@ -1,10 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
// snx_recompiler.h includes cpu.h and arm.h before its own extern "C" block, so the whole
|
||||
// header needs C linkage for the runtime library's functions to resolve.
|
||||
extern "C" {
|
||||
#include <scarletnx/snx_recompiler.h>
|
||||
}
|
||||
@@ -1,300 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include <algorithm>
|
||||
#include <mutex>
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#include "common/fs/path_util.h"
|
||||
#include "common/logging.h"
|
||||
#include "common/settings.h"
|
||||
#include "core/arm/scarletnx/arm_scarletnx_32.h"
|
||||
#include "core/arm/scarletnx/arm_scarletnx_64.h"
|
||||
#include "core/arm/scarletnx/scarletnx_api.h"
|
||||
#include "core/arm/scarletnx/scarletnx_process.h"
|
||||
#include "core/core.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/device_memory.h"
|
||||
#include "core/hle/kernel/k_process.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/memory.h"
|
||||
|
||||
namespace Core {
|
||||
|
||||
namespace {
|
||||
|
||||
// ScarletNX refuses dispatch tables spanning more than 1 GiB of guest code.
|
||||
constexpr u64 MaxModuleSpan = 1ULL << 30;
|
||||
constexpr u64 A32Limit = 1ULL << 32;
|
||||
|
||||
std::atomic<Timing::CoreTiming*> g_core_timing{};
|
||||
|
||||
// Needs be TLS because SNX expects like, more than 4 threads (host == guest threads)
|
||||
// and well -- quite impervious to "emulated" threads... maybe one day this can be removed
|
||||
thread_local ScarletNxFaultScope* g_fault_scope{};
|
||||
static struct {
|
||||
struct sigaction old_sigsegv;
|
||||
struct sigaction old_sigbus;
|
||||
std::once_flag installed;
|
||||
} g_snx_data;
|
||||
|
||||
bool Overlaps(const ScarletNxProcess::CodeRange& range, u64 addr, u64 size) {
|
||||
return addr < range.addr + range.size && range.addr < addr + size;
|
||||
}
|
||||
|
||||
void ChainSignal(int sig, siginfo_t* info, void* raw_context) {
|
||||
const struct sigaction& old = sig == SIGSEGV ? g_snx_data.old_sigsegv : g_snx_data.old_sigbus;
|
||||
if (old.sa_flags & SA_SIGINFO) {
|
||||
old.sa_sigaction(sig, info, raw_context);
|
||||
} else if (old.sa_handler == SIG_DFL) {
|
||||
// The faulting instruction runs again and takes the default action.
|
||||
signal(sig, SIG_DFL);
|
||||
} else if (old.sa_handler != SIG_IGN) {
|
||||
old.sa_handler(sig);
|
||||
}
|
||||
}
|
||||
|
||||
void FaultHandler(int sig, siginfo_t* info, void* raw_context) {
|
||||
ScarletNxFaultScope* const scope = g_fault_scope;
|
||||
u8* const addr = static_cast<u8*>(info->si_addr);
|
||||
if (!scope || addr < scope->arena || addr >= scope->arena + scope->arena_size) {
|
||||
ChainSignal(sig, info, raw_context);
|
||||
return;
|
||||
}
|
||||
|
||||
// Pages the rasterizer protects fault on access: invalidate them and retry. A second fault at
|
||||
// the same addr means retrying will not help.
|
||||
const u64 guest_address = u64(addr - scope->arena);
|
||||
if (guest_address != scope->last_fault) {
|
||||
scope->last_fault = guest_address;
|
||||
if (scope->memory->InvalidateNCE(guest_address & ~Memory::YUZU_PAGEMASK, Memory::YUZU_PAGESIZE)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
scope->fault_address = guest_address;
|
||||
siglongjmp(scope->env, 1);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void InstallScarletNxFaultHandler() {
|
||||
std::call_once(g_snx_data.installed, [] {
|
||||
struct sigaction action {};
|
||||
action.sa_flags = SA_SIGINFO;
|
||||
action.sa_sigaction = &FaultHandler;
|
||||
sigemptyset(&action.sa_mask);
|
||||
sigaction(SIGSEGV, &action, &g_snx_data.old_sigsegv);
|
||||
sigaction(SIGBUS, &action, &g_snx_data.old_sigbus);
|
||||
});
|
||||
}
|
||||
|
||||
void SetScarletNxFaultScope(ScarletNxFaultScope* scope) {
|
||||
g_fault_scope = scope;
|
||||
}
|
||||
|
||||
u64 ScarletNxTicks() {
|
||||
return g_core_timing.load(std::memory_order_relaxed)->GetClockTicks();
|
||||
}
|
||||
|
||||
std::unique_ptr<ArmInterface> MakeScarletNxInterface(std::shared_ptr<ScarletNxProcess> process, bool is_64bit, std::size_t core_index) {
|
||||
if (is_64bit)
|
||||
return std::make_unique<ArmScarletNx64>(std::move(process), core_index);
|
||||
return std::make_unique<ArmScarletNx32>(std::move(process), core_index);
|
||||
}
|
||||
|
||||
ScarletNxProcess::ScarletNxProcess(System& system, Kernel::KProcess& process)
|
||||
: m_system{system}
|
||||
, m_process{process}
|
||||
, m_arena{system.DeviceMemory().buffer.VirtualBasePointer()}
|
||||
{
|
||||
InstallScarletNxFaultHandler();
|
||||
g_core_timing.store(&system.CoreTiming(), std::memory_order_relaxed);
|
||||
|
||||
m_recompiler = snx_recompiler_new(SNX_RECOMPILER_FLAG_LLVM);
|
||||
ASSERT(m_recompiler && "cannot create the recompiler");
|
||||
|
||||
// Linked modules are kept by a hash of their code, so later launches skip the recompile.
|
||||
const auto cache = Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / "scarletnx";
|
||||
if (snx_recompiler_set_cache(m_recompiler, Common::FS::PathToUTF8String(cache).c_str()) != 0)
|
||||
LOG_WARNING(Core_ARM, "no code cache: {}", snx_recompiler_error(m_recompiler));
|
||||
}
|
||||
|
||||
ScarletNxProcess::~ScarletNxProcess() {
|
||||
for (auto& mod : m_modules)
|
||||
snx_recompiled_free(mod.mod);
|
||||
snx_recompiler_free(m_recompiler);
|
||||
}
|
||||
|
||||
bool ScarletNxProcess::ShouldUse(System& system, const Kernel::KProcess& process) {
|
||||
if (Settings::values.cpu_backend.GetValue() != Settings::CpuBackend::ScarletNx)
|
||||
return false;
|
||||
auto const f = [](auto& s) {
|
||||
LOG_WARNING(Core_ARM, "snx: {}", s);
|
||||
return false;
|
||||
};
|
||||
if (!process.IsApplication())
|
||||
return f("no qlaunch yet");
|
||||
if (!system.Kernel().IsMulticore())
|
||||
return f("single core mode needs cycle counting");
|
||||
if (system.DebuggerEnabled())
|
||||
return f("the debugger needs stepping and watchpoints");
|
||||
/// ScarletNX expects flat memory, so it will only work with fastmem
|
||||
if (!Settings::IsFastmemEnabled() || !system.DeviceMemory().buffer.VirtualBasePointer())
|
||||
return f("guest memory must be mapped by fastmem");
|
||||
if (snx_recompiler_abi() != SNX_ABI)
|
||||
return f("the library was built with a different ABI");
|
||||
if (!snx_recompiler_has(SNX_RECOMPILER_FLAG_LLVM))
|
||||
return f("LLVM cannot target this host");
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<ScarletNxProcess::CodeRange> ScarletNxProcess::GetCodeRanges() const {
|
||||
std::vector<CodeRange> r;
|
||||
const auto& page_table = m_process.GetPageTable().GetBasePageTable();
|
||||
u64 addr = GetInteger(page_table.GetAddressSpaceStart());
|
||||
while (true) {
|
||||
Kernel::KMemoryInfo info;
|
||||
Kernel::Svc::PageInfo page_info;
|
||||
if (page_table.QueryInfo(&info, &page_info, addr).IsError())
|
||||
break;
|
||||
if (True(info.GetPermission() & Kernel::KMemoryPermission::UserExecute)) {
|
||||
if (!r.empty() && r.back().addr + r.back().size == info.GetAddress()) {
|
||||
r.back().size += info.GetSize();
|
||||
} else {
|
||||
r.push_back({info.GetAddress(), info.GetSize()});
|
||||
}
|
||||
}
|
||||
// The block past the addr space ends at 0.
|
||||
if (info.GetEndAddress() <= addr)
|
||||
break;
|
||||
addr = info.GetEndAddress();
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
const ScarletNxProcess::Module* ScarletNxProcess::FindModuleLocked(u64 pc) const {
|
||||
for (const auto& mod : m_modules) {
|
||||
if (mod.retired || pc < mod.lo || pc >= mod.hi)
|
||||
continue;
|
||||
for (const auto& range : mod.ranges)
|
||||
if (pc >= range.addr && pc < range.addr + range.size)
|
||||
return &mod;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
snx_recompiled* ScarletNxProcess::RecompileRegionLocked(u64 pc) {
|
||||
const auto r = GetCodeRanges();
|
||||
const auto it = std::ranges::find_if(r, [pc](const CodeRange& range) {
|
||||
return pc >= range.addr && pc < range.addr + range.size;
|
||||
});
|
||||
if (it == r.end())
|
||||
return nullptr;
|
||||
|
||||
const auto is_covered = [this](const CodeRange& range) {
|
||||
return std::ranges::any_of(m_modules, [&](const Module& mod) {
|
||||
return !mod.retired && std::ranges::any_of(mod.ranges, [&](const CodeRange& cr) {
|
||||
return Overlaps(cr, range.addr, range.size);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// Recompile as many neighbouring regions as one dispatch table can cover.
|
||||
auto first = size_t(it - r.begin());
|
||||
auto last = first;
|
||||
const auto end_of = [&](size_t i) { return r[i].addr + r[i].size; };
|
||||
while (first > 0 && !is_covered(r[first - 1]) && end_of(last) - r[first - 1].addr <= MaxModuleSpan)
|
||||
--first;
|
||||
while (last + 1 < r.size() && !is_covered(r[last + 1])
|
||||
&& end_of(last + 1) - r[first].addr <= MaxModuleSpan)
|
||||
++last;
|
||||
|
||||
Module mod{};
|
||||
mod.ranges.assign(r.begin() + first, r.begin() + last + 1);
|
||||
mod.lo = r[first].addr;
|
||||
mod.hi = end_of(last);
|
||||
|
||||
std::vector<snx_code_range> code;
|
||||
u64 code_size = 0;
|
||||
for (const auto& range : mod.ranges) {
|
||||
code.push_back({range.addr, m_arena + range.addr, range.size});
|
||||
code_size += range.size;
|
||||
}
|
||||
|
||||
LOG_INFO(Core_ARM, "recompiling {} KiB of code at {:#x}-{:#x}", code_size / 1024, mod.lo, mod.hi);
|
||||
mod.mod = snx_recompile_ranges(m_recompiler, code.data(), code.size(), &pc, 1);
|
||||
if (mod.mod) {
|
||||
LOG_INFO(Core_ARM, "recompiled {} functions", snx_recompiled_functions(mod.mod));
|
||||
} else {
|
||||
// Kept, so the region is not recompiled again on every miss.
|
||||
LOG_ERROR(Core_ARM, "recompilation failed: {}", snx_recompiler_error(m_recompiler));
|
||||
}
|
||||
|
||||
m_modules.push_back(std::move(mod));
|
||||
return m_modules.back().mod;
|
||||
}
|
||||
|
||||
ScarletNxProcess::SnxGuestFn ScarletNxProcess::Lookup(u64 pc) {
|
||||
snx_recompiled* mod;
|
||||
{
|
||||
std::scoped_lock lk{m_mutex};
|
||||
const Module* const known = FindModuleLocked(pc);
|
||||
mod = known ? known->mod : RecompileRegionLocked(pc);
|
||||
}
|
||||
if (!mod)
|
||||
return nullptr;
|
||||
// Waits for the mod's JIT when discovery missed the code at pc.
|
||||
return snx_recompiled_lookup(mod, pc);
|
||||
}
|
||||
|
||||
snx_recompiled* ScarletNxProcess::FindModule(u64 pc) {
|
||||
std::scoped_lock lk{m_mutex};
|
||||
const Module* const mod = FindModuleLocked(pc);
|
||||
return mod ? mod->mod : nullptr;
|
||||
}
|
||||
|
||||
snx_recompiled32* ScarletNxProcess::MakeModule32() {
|
||||
std::scoped_lock lk{m_mutex};
|
||||
std::vector<snx_code_range> code;
|
||||
for (const auto& range : GetCodeRanges()) {
|
||||
if (range.addr >= A32Limit) {
|
||||
continue;
|
||||
}
|
||||
code.push_back({range.addr, nullptr, std::min(range.size, A32Limit - range.addr)});
|
||||
}
|
||||
if (code.empty())
|
||||
return nullptr;
|
||||
snx_recompiled32* const mod = snx_recompile32_ranges(m_recompiler, code.data(), code.size());
|
||||
if (!mod)
|
||||
LOG_ERROR(Core_ARM, "cannot prepare A32 code: {}", snx_recompiler_error(m_recompiler));
|
||||
return mod;
|
||||
}
|
||||
|
||||
void ScarletNxProcess::InvalidateCacheRange(u64 addr, u64 size) {
|
||||
std::scoped_lock lk{m_mutex};
|
||||
for (auto& mod : m_modules) {
|
||||
if (mod.retired || !std::ranges::any_of(mod.ranges, [&](const CodeRange& range) {
|
||||
return Overlaps(range, addr, size);
|
||||
}))
|
||||
continue;
|
||||
// Running code diverts out of the retired functions, and the region is recompiled from
|
||||
// the new code when it is next reached.
|
||||
if (mod.mod)
|
||||
snx_recompiled_invalidate(mod.mod, addr, size, nullptr, nullptr);
|
||||
mod.retired = true;
|
||||
}
|
||||
m_code_generation.fetch_add(1, std::memory_order_release);
|
||||
}
|
||||
|
||||
void ScarletNxProcess::ClearInstructionCache() {
|
||||
std::scoped_lock lk{m_mutex};
|
||||
for (auto& mod : m_modules) {
|
||||
if (!mod.retired && mod.mod)
|
||||
snx_recompiled_invalidate(mod.mod, mod.lo, mod.hi - mod.lo, nullptr, nullptr);
|
||||
mod.retired = true;
|
||||
}
|
||||
m_code_generation.fetch_add(1, std::memory_order_release);
|
||||
}
|
||||
|
||||
} // namespace Core
|
||||
@@ -1,104 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <csetjmp>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
#include "common/common_types.h"
|
||||
|
||||
struct CPU;
|
||||
struct snx_recompiler;
|
||||
struct snx_recompiled;
|
||||
struct snx_recompiled32;
|
||||
|
||||
namespace Kernel {
|
||||
class KProcess;
|
||||
}
|
||||
|
||||
namespace Core::Memory {
|
||||
class Memory;
|
||||
}
|
||||
|
||||
namespace Core {
|
||||
|
||||
class ArmInterface;
|
||||
class System;
|
||||
|
||||
class ScarletNxProcess {
|
||||
public:
|
||||
using SnxGuestFn = void (*)(CPU*, u64);
|
||||
|
||||
// DeviceMemory reserves 39 bits of address space for the fastmem arena.
|
||||
static constexpr u64 ArenaSize = 1ULL << 39;
|
||||
|
||||
struct CodeRange {
|
||||
u64 addr;
|
||||
u64 size;
|
||||
};
|
||||
|
||||
ScarletNxProcess(System& system, Kernel::KProcess& process);
|
||||
~ScarletNxProcess();
|
||||
|
||||
static bool ShouldUse(System& system, const Kernel::KProcess& process);
|
||||
SnxGuestFn Lookup(u64 pc);
|
||||
snx_recompiled* FindModule(u64 pc);
|
||||
snx_recompiled32* MakeModule32();
|
||||
|
||||
void InvalidateCacheRange(u64 addr, u64 size);
|
||||
void ClearInstructionCache();
|
||||
|
||||
/// @brief general gate for when we are about to invalidate a given block aka. trigger regen
|
||||
u64 CodeGeneration() const {
|
||||
return m_code_generation.load(std::memory_order_acquire);
|
||||
}
|
||||
|
||||
struct Module {
|
||||
std::vector<CodeRange> ranges;
|
||||
u64 lo;
|
||||
u64 hi;
|
||||
snx_recompiled* mod;
|
||||
bool retired;
|
||||
};
|
||||
|
||||
std::vector<CodeRange> GetCodeRanges() const;
|
||||
const Module* FindModuleLocked(u64 pc) const;
|
||||
snx_recompiled* RecompileRegionLocked(u64 pc);
|
||||
|
||||
std::vector<Module> m_modules;
|
||||
std::atomic<u64> m_code_generation{};
|
||||
|
||||
// TODO: remove parent ref?
|
||||
System& m_system;
|
||||
Kernel::KProcess& m_process;
|
||||
u8* m_arena{};
|
||||
snx_recompiler* m_recompiler{};
|
||||
|
||||
// ScarletNX's recompiler is used by one thread at a time.
|
||||
std::mutex m_mutex;
|
||||
};
|
||||
|
||||
/// Recovers from host faults in guest memory on the thread running guest code: a fault on a
|
||||
/// page the rasterizer protects is resolved and retried, any other jumps to env.
|
||||
struct ScarletNxFaultScope {
|
||||
sigjmp_buf env;
|
||||
Memory::Memory* memory{};
|
||||
u8* arena{};
|
||||
u64 arena_size{};
|
||||
u64 last_fault{~0ull};
|
||||
u64 fault_address{};
|
||||
};
|
||||
|
||||
void InstallScarletNxFaultHandler();
|
||||
void SetScarletNxFaultScope(ScarletNxFaultScope* scope);
|
||||
|
||||
/// CNTPCT_EL0 of the emulated system.
|
||||
u64 ScarletNxTicks();
|
||||
|
||||
std::unique_ptr<ArmInterface> MakeScarletNxInterface(std::shared_ptr<ScarletNxProcess> process, bool is_64bit, std::size_t core_index);
|
||||
|
||||
} // namespace Core
|
||||
@@ -23,9 +23,6 @@
|
||||
#ifdef HAS_NCE
|
||||
#include "core/arm/nce/arm_nce.h"
|
||||
#endif
|
||||
#ifdef HAS_SCARLETNX
|
||||
#include "core/arm/scarletnx/scarletnx_process.h"
|
||||
#endif
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
@@ -1314,13 +1311,6 @@ void KProcess::InitializeInterfaces(KernelCore& kernel) {
|
||||
for (size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++)
|
||||
m_arm_interfaces[i] = std::make_unique<Core::ArmNce>(kernel.System(), true, i);
|
||||
} else
|
||||
#endif
|
||||
#ifdef HAS_SCARLETNX
|
||||
if (Core::ScarletNxProcess::ShouldUse(kernel.System(), *this)) {
|
||||
auto scarletnx = std::make_shared<Core::ScarletNxProcess>(kernel.System(), *this);
|
||||
for (size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++)
|
||||
m_arm_interfaces[i] = Core::MakeScarletNxInterface(scarletnx, this->Is64Bit(), i);
|
||||
} else
|
||||
#endif
|
||||
if (this->Is64Bit()) {
|
||||
for (size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
|
||||
|
||||
+971
-962
File diff suppressed because it is too large
Load Diff
@@ -14,70 +14,6 @@ namespace Service::Account {
|
||||
|
||||
class ProfileManager;
|
||||
|
||||
class Module final {
|
||||
public:
|
||||
class Interface : public ServiceFramework<Interface> {
|
||||
public:
|
||||
explicit Interface(std::shared_ptr<Module> module_,
|
||||
std::shared_ptr<ProfileManager> profile_manager_, Core::System& system_,
|
||||
const char* name);
|
||||
~Interface() override;
|
||||
|
||||
void GetUserCount(HLERequestContext& ctx);
|
||||
void GetUserExistence(HLERequestContext& ctx);
|
||||
void ListAllUsers(HLERequestContext& ctx);
|
||||
void ListOpenUsers(HLERequestContext& ctx);
|
||||
void GetLastOpenedUser(HLERequestContext& ctx);
|
||||
void GetProfile(HLERequestContext& ctx);
|
||||
void InitializeApplicationInfo(HLERequestContext& ctx);
|
||||
void InitializeApplicationInfoRestricted(HLERequestContext& ctx);
|
||||
void GetBaasAccountManagerForApplication(HLERequestContext& ctx);
|
||||
void IsUserRegistrationRequestPermitted(HLERequestContext& ctx);
|
||||
void TrySelectUserWithoutInteractionDeprecated(HLERequestContext& ctx);
|
||||
void TrySelectUserWithoutInteraction(HLERequestContext& ctx);
|
||||
void IsUserAccountSwitchLocked(HLERequestContext& ctx);
|
||||
void InitializeApplicationInfoV2(HLERequestContext& ctx);
|
||||
void BeginUserRegistration(HLERequestContext& ctx);
|
||||
void CompleteUserRegistration(HLERequestContext& ctx);
|
||||
void DeleteUser(HLERequestContext& ctx);
|
||||
void SetUserPosition(HLERequestContext& ctx);
|
||||
void GetProfileEditor(HLERequestContext& ctx);
|
||||
void GetBaasAccountAdministrator(HLERequestContext &ctx);
|
||||
void ListQualifiedUsers(HLERequestContext& ctx);
|
||||
void ListOpenContextStoredUsers(HLERequestContext& ctx);
|
||||
void StoreSaveDataThumbnailApplication(HLERequestContext& ctx);
|
||||
void GetBaasAccountManagerForSystemService(HLERequestContext& ctx);
|
||||
void StoreSaveDataThumbnailSystem(HLERequestContext& ctx);
|
||||
void GetPinCodeLength(HLERequestContext& ctx);
|
||||
|
||||
private:
|
||||
Result InitializeApplicationInfoBase();
|
||||
void StoreSaveDataThumbnail(HLERequestContext& ctx, const Common::UUID& uuid,
|
||||
const u64 tid);
|
||||
|
||||
enum class ApplicationType : u32_le {
|
||||
GameCard = 0,
|
||||
Digital = 1,
|
||||
Unknown = 3,
|
||||
};
|
||||
|
||||
struct ApplicationInfo {
|
||||
Service::Glue::ApplicationLaunchProperty launch_property;
|
||||
ApplicationType application_type;
|
||||
|
||||
constexpr explicit operator bool() const {
|
||||
return launch_property.title_id != 0x0;
|
||||
}
|
||||
};
|
||||
|
||||
ApplicationInfo application_info{};
|
||||
|
||||
protected:
|
||||
std::shared_ptr<Module> module;
|
||||
std::shared_ptr<ProfileManager> profile_manager;
|
||||
};
|
||||
};
|
||||
|
||||
void LoopProcess(Core::System& system);
|
||||
|
||||
} // namespace Service::Account
|
||||
|
||||
@@ -12,17 +12,6 @@
|
||||
namespace Service::Account {
|
||||
IAsyncContext::IAsyncContext(Core::System& system_)
|
||||
: ServiceFramework{system_, "IAsyncContext"}, service_context{system_, "IAsyncContext"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IAsyncContext::GetSystemEvent, "GetSystemEvent"},
|
||||
{1, &IAsyncContext::Cancel, "Cancel"},
|
||||
{2, &IAsyncContext::HasDone, "HasDone"},
|
||||
{3, &IAsyncContext::GetResult, "GetResult"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
|
||||
completion_event = service_context.CreateEvent("IAsyncContext:CompletionEvent");
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,16 @@ protected:
|
||||
|
||||
void MarkComplete();
|
||||
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, &IAsyncContext::GetSystemEvent, "GetSystemEvent"},
|
||||
FunctionInfo{1, &IAsyncContext::Cancel, "Cancel"},
|
||||
FunctionInfo{2, &IAsyncContext::HasDone, "HasDone"},
|
||||
FunctionInfo{3, &IAsyncContext::GetResult, "GetResult"}
|
||||
);
|
||||
|
||||
KernelHelpers::ServiceContext service_context;
|
||||
|
||||
std::atomic<bool> is_complete{false};
|
||||
|
||||
+1330
-8
File diff suppressed because it is too large
Load Diff
@@ -1,135 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "core/core.h"
|
||||
#include "core/hle/service/am/applet_manager.h"
|
||||
#include "core/hle/service/am/service/all_system_applet_proxies_service.h"
|
||||
#include "core/hle/service/am/service/application_proxy.h"
|
||||
#include "core/hle/service/am/service/library_applet_proxy.h"
|
||||
#include "core/hle/service/am/service/system_applet_proxy.h"
|
||||
#include "core/hle/service/am/service/overlay_applet_proxy.h"
|
||||
#include "core/hle/service/am/window_system.h"
|
||||
#include "core/hle/service/cmif_serialization.h"
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
IAllSystemAppletProxiesService::IAllSystemAppletProxiesService(Core::System& system_,
|
||||
WindowSystem& window_system)
|
||||
: ServiceFramework{system_, "appletAE"}, m_window_system{window_system} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{100, D<&IAllSystemAppletProxiesService::OpenSystemAppletProxy>, "OpenSystemAppletProxy"},
|
||||
{110, D<&IAllSystemAppletProxiesService::OpenSystemAppletProxy>, "OpenSystemAppletProxyEx"},
|
||||
{200, D<&IAllSystemAppletProxiesService::OpenLibraryAppletProxyOld>, "OpenLibraryAppletProxyOld"},
|
||||
{201, D<&IAllSystemAppletProxiesService::OpenLibraryAppletProxy>, "OpenLibraryAppletProxy"},
|
||||
{300, D<&IAllSystemAppletProxiesService::OpenOverlayAppletProxy>, "OpenOverlayAppletProxy"},
|
||||
{350, D<&IAllSystemAppletProxiesService::OpenSystemApplicationProxy>, "OpenSystemApplicationProxy"},
|
||||
{400, nullptr, "CreateSelfLibraryAppletCreatorForDevelop"},
|
||||
{410, nullptr, "GetSystemAppletControllerForDebug"},
|
||||
{450, D<&IAllSystemAppletProxiesService::GetSystemProcessCommonFunctions>, "GetSystemProcessCommonFunctions"}, // 19.0.0+
|
||||
{460, D<&IAllSystemAppletProxiesService::GetAppletAlternativeFunctions>, "GetAppletAlternativeFunctions"}, // 20.0.0+
|
||||
{1000, nullptr, "GetDebugFunctions"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
IAllSystemAppletProxiesService::~IAllSystemAppletProxiesService() = default;
|
||||
|
||||
Result IAllSystemAppletProxiesService::OpenSystemAppletProxy(
|
||||
Out<SharedPointer<ISystemAppletProxy>> out_system_applet_proxy, ClientProcessId pid,
|
||||
InCopyHandle<Kernel::KProcess> process_handle) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
|
||||
if (const auto applet = this->GetAppletFromProcessId(pid); applet) {
|
||||
*out_system_applet_proxy = std::make_shared<ISystemAppletProxy>(
|
||||
system, applet, process_handle.Get(), m_window_system);
|
||||
R_SUCCEED();
|
||||
} else {
|
||||
UNIMPLEMENTED();
|
||||
R_THROW(ResultUnknown);
|
||||
}
|
||||
}
|
||||
|
||||
Result IAllSystemAppletProxiesService::OpenLibraryAppletProxy(
|
||||
Out<SharedPointer<ILibraryAppletProxy>> out_library_applet_proxy, ClientProcessId pid,
|
||||
InCopyHandle<Kernel::KProcess> process_handle,
|
||||
InLargeData<AppletAttribute, BufferAttr_HipcMapAlias> attribute) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
|
||||
if (const auto applet = this->GetAppletFromProcessId(pid); applet) {
|
||||
*out_library_applet_proxy = std::make_shared<ILibraryAppletProxy>(
|
||||
system, applet, process_handle.Get(), m_window_system);
|
||||
R_SUCCEED();
|
||||
} else {
|
||||
UNIMPLEMENTED();
|
||||
R_THROW(ResultUnknown);
|
||||
}
|
||||
}
|
||||
|
||||
Result IAllSystemAppletProxiesService::OpenOverlayAppletProxy(
|
||||
Out<SharedPointer<IOverlayAppletProxy>> out_overlay_applet_proxy, ClientProcessId pid,
|
||||
InCopyHandle<Kernel::KProcess> process_handle) {
|
||||
LOG_WARNING(Service_AM, "called");
|
||||
|
||||
if (const auto applet = this->GetAppletFromProcessId(pid); applet) {
|
||||
*out_overlay_applet_proxy = std::make_shared<IOverlayAppletProxy>(
|
||||
system, applet, process_handle.Get(), m_window_system);
|
||||
R_SUCCEED();
|
||||
} else {
|
||||
UNIMPLEMENTED();
|
||||
R_THROW(ResultUnknown);
|
||||
}
|
||||
}
|
||||
|
||||
Result IAllSystemAppletProxiesService::OpenSystemApplicationProxy(
|
||||
Out<SharedPointer<IApplicationProxy>> out_system_application_proxy, ClientProcessId pid,
|
||||
InCopyHandle<Kernel::KProcess> process_handle) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
|
||||
if (const auto applet = this->GetAppletFromProcessId(pid); applet) {
|
||||
*out_system_application_proxy = std::make_shared<IApplicationProxy>(
|
||||
system, applet, process_handle.Get(), m_window_system);
|
||||
R_SUCCEED();
|
||||
} else {
|
||||
UNIMPLEMENTED();
|
||||
R_THROW(ResultUnknown);
|
||||
}
|
||||
}
|
||||
|
||||
Result IAllSystemAppletProxiesService::OpenLibraryAppletProxyOld(
|
||||
Out<SharedPointer<ILibraryAppletProxy>> out_library_applet_proxy, ClientProcessId pid,
|
||||
InCopyHandle<Kernel::KProcess> process_handle) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
|
||||
AppletAttribute attribute{};
|
||||
R_RETURN(
|
||||
this->OpenLibraryAppletProxy(out_library_applet_proxy, pid, process_handle, attribute));
|
||||
}
|
||||
|
||||
Result IAllSystemAppletProxiesService::GetSystemProcessCommonFunctions() {
|
||||
LOG_DEBUG(Service_AM, "(STUBBED) called.");
|
||||
|
||||
// TODO (jarrodnorwell)
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IAllSystemAppletProxiesService::GetAppletAlternativeFunctions() {
|
||||
LOG_DEBUG(Service_AM, "(STUBBED) called.");
|
||||
|
||||
// TODO (maufeat)
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
std::shared_ptr<Applet> IAllSystemAppletProxiesService::GetAppletFromProcessId(
|
||||
ProcessId process_id) {
|
||||
return m_window_system.GetByAppletResourceUserId(process_id.pid);
|
||||
}
|
||||
|
||||
} // namespace Service::AM
|
||||
@@ -1,56 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/cmif_types.h"
|
||||
#include "core/hle/service/service.h"
|
||||
#include "core/hle/service/am/service/overlay_applet_proxy.h"
|
||||
|
||||
namespace Service {
|
||||
|
||||
namespace AM {
|
||||
|
||||
struct Applet;
|
||||
struct AppletAttribute;
|
||||
class IApplicationProxy;
|
||||
class ILibraryAppletProxy;
|
||||
class ISystemAppletProxy;
|
||||
class WindowSystem;
|
||||
|
||||
class IAllSystemAppletProxiesService final
|
||||
: public ServiceFramework<IAllSystemAppletProxiesService> {
|
||||
public:
|
||||
explicit IAllSystemAppletProxiesService(Core::System& system_, WindowSystem& window_system);
|
||||
~IAllSystemAppletProxiesService() override;
|
||||
|
||||
private:
|
||||
Result OpenSystemAppletProxy(Out<SharedPointer<ISystemAppletProxy>> out_system_applet_proxy,
|
||||
ClientProcessId pid,
|
||||
InCopyHandle<Kernel::KProcess> process_handle);
|
||||
Result OpenLibraryAppletProxy(Out<SharedPointer<ILibraryAppletProxy>> out_library_applet_proxy,
|
||||
ClientProcessId pid,
|
||||
InCopyHandle<Kernel::KProcess> process_handle,
|
||||
InLargeData<AppletAttribute, BufferAttr_HipcMapAlias> attribute);
|
||||
Result OpenOverlayAppletProxy(Out<SharedPointer<IOverlayAppletProxy>> out_overlay_applet_proxy,
|
||||
ClientProcessId pid, InCopyHandle<Kernel::KProcess> process_handle);
|
||||
Result OpenLibraryAppletProxyOld(
|
||||
Out<SharedPointer<ILibraryAppletProxy>> out_library_applet_proxy, ClientProcessId pid,
|
||||
InCopyHandle<Kernel::KProcess> process_handle);
|
||||
Result OpenSystemApplicationProxy(
|
||||
Out<SharedPointer<IApplicationProxy>> out_system_application_proxy, ClientProcessId pid,
|
||||
InCopyHandle<Kernel::KProcess> process_handle);
|
||||
Result GetSystemProcessCommonFunctions();
|
||||
Result GetAppletAlternativeFunctions();
|
||||
|
||||
private:
|
||||
std::shared_ptr<Applet> GetAppletFromProcessId(ProcessId pid);
|
||||
|
||||
WindowSystem& m_window_system;
|
||||
};
|
||||
|
||||
} // namespace AM
|
||||
} // namespace Service
|
||||
@@ -1,98 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "core/core.h"
|
||||
#include "core/file_sys/common_funcs.h"
|
||||
#include "core/hle/service/am/applet.h"
|
||||
#include "core/hle/service/am/service/applet_common_functions.h"
|
||||
#include "core/hle/service/cmif_serialization.h"
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
IAppletCommonFunctions::IAppletCommonFunctions(Core::System& system_,
|
||||
std::shared_ptr<Applet> applet_)
|
||||
: ServiceFramework{system_, "IAppletCommonFunctions"}, applet{std::move(applet_)} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "SetTerminateResult"},
|
||||
{10, nullptr, "ReadThemeStorage"},
|
||||
{11, nullptr, "WriteThemeStorage"},
|
||||
{20, nullptr, "PushToAppletBoundChannel"},
|
||||
{21, nullptr, "TryPopFromAppletBoundChannel"},
|
||||
{40, nullptr, "GetDisplayLogicalResolution"},
|
||||
{42, D<&IAppletCommonFunctions::SetDisplayMagnification>, "SetDisplayMagnification"},
|
||||
{50, D<&IAppletCommonFunctions::SetHomeButtonDoubleClickEnabled>, "SetHomeButtonDoubleClickEnabled"},
|
||||
{51, D<&IAppletCommonFunctions::GetHomeButtonDoubleClickEnabled>, "GetHomeButtonDoubleClickEnabled"},
|
||||
{52, nullptr, "IsHomeButtonShortPressedBlocked"},
|
||||
{60, nullptr, "IsVrModeCurtainRequired"},
|
||||
{61, nullptr, "IsSleepRequiredByHighTemperature"},
|
||||
{62, nullptr, "IsSleepRequiredByLowBattery"},
|
||||
{70, D<&IAppletCommonFunctions::SetCpuBoostRequestPriority>, "SetCpuBoostRequestPriority"},
|
||||
{80, nullptr, "SetHandlingCaptureButtonShortPressedMessageEnabledForApplet"},
|
||||
{81, nullptr, "SetHandlingCaptureButtonLongPressedMessageEnabledForApplet"},
|
||||
{90, nullptr, "OpenNamedChannelAsParent"},
|
||||
{91, nullptr, "OpenNamedChannelAsChild"},
|
||||
{100, nullptr, "SetApplicationCoreUsageMode"},
|
||||
{300, D<&IAppletCommonFunctions::GetCurrentApplicationId>, "GetCurrentApplicationId"},
|
||||
{310, nullptr, "IsSystemAppletHomeMenu"}, //19.0.0+
|
||||
{320, D<&IAppletCommonFunctions::SetGpuTimeSliceBoost>, "SetGpuTimeSliceBoost"}, //19.0.0+
|
||||
{321, nullptr, "SetGpuTimeSliceBoostDueToApplication"}, //19.0.0+
|
||||
{350, D<&IAppletCommonFunctions::Unknown350>, "Unknown350"} //20.0.0+
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
IAppletCommonFunctions::~IAppletCommonFunctions() = default;
|
||||
|
||||
Result IAppletCommonFunctions::SetHomeButtonDoubleClickEnabled(
|
||||
bool home_button_double_click_enabled) {
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called, home_button_double_click_enabled={}",
|
||||
home_button_double_click_enabled);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IAppletCommonFunctions::GetHomeButtonDoubleClickEnabled(
|
||||
Out<bool> out_home_button_double_click_enabled) {
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
*out_home_button_double_click_enabled = false;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IAppletCommonFunctions::SetDisplayMagnification(f32 x, f32 y, f32 width, f32 height) {
|
||||
LOG_DEBUG(Service_AM, "(STUBBED) called, x={}, y={}, width={}, height={}", x, y, width,
|
||||
height);
|
||||
std::scoped_lock lk{applet->lock};
|
||||
applet->display_magnification = Common::Rectangle<f32>{x, y, x + width, y + height};
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IAppletCommonFunctions::SetCpuBoostRequestPriority(s32 priority) {
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
std::scoped_lock lk{applet->lock};
|
||||
applet->cpu_boost_request_priority = priority;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IAppletCommonFunctions::GetCurrentApplicationId(Out<u64> out_application_id) {
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
*out_application_id = FileSys::GetBaseTitleID(system.GetApplicationProcessProgramID());
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IAppletCommonFunctions::SetGpuTimeSliceBoost(s64 time_span) {
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called, time_span={}", time_span);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IAppletCommonFunctions::Unknown350(Out<u16> out_unknown) {
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
*out_unknown = 0;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
} // namespace Service::AM
|
||||
@@ -1,33 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/cmif_types.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
struct Applet;
|
||||
|
||||
class IAppletCommonFunctions final : public ServiceFramework<IAppletCommonFunctions> {
|
||||
public:
|
||||
explicit IAppletCommonFunctions(Core::System& system_, std::shared_ptr<Applet> applet_);
|
||||
~IAppletCommonFunctions() override;
|
||||
|
||||
private:
|
||||
Result SetHomeButtonDoubleClickEnabled(bool home_button_double_click_enabled);
|
||||
Result GetHomeButtonDoubleClickEnabled(Out<bool> out_home_button_double_click_enabled);
|
||||
Result SetDisplayMagnification(f32 x, f32 y, f32 width, f32 height);
|
||||
Result SetCpuBoostRequestPriority(s32 priority);
|
||||
Result GetCurrentApplicationId(Out<u64> out_application_id);
|
||||
Result SetGpuTimeSliceBoost(s64 time_span);
|
||||
Result Unknown350(Out<u16> out_unknown);
|
||||
|
||||
const std::shared_ptr<Applet> applet;
|
||||
};
|
||||
|
||||
} // namespace Service::AM
|
||||
@@ -18,42 +18,42 @@
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> IApplicationAccessor::FindRequest(u32 key) {
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, D<&IApplicationAccessor::GetAppletStateChangedEvent>, "GetAppletStateChangedEvent"},
|
||||
FunctionInfo{1, nullptr, "IsCompleted"},
|
||||
FunctionInfo{10, D<&IApplicationAccessor::Start>, "Start"},
|
||||
FunctionInfo{20, D<&IApplicationAccessor::RequestExit>, "RequestExit"},
|
||||
FunctionInfo{25, D<&IApplicationAccessor::Terminate>, "Terminate"},
|
||||
FunctionInfo{30, D<&IApplicationAccessor::GetResult>, "GetResult"},
|
||||
FunctionInfo{101, D<&IApplicationAccessor::RequestForApplicationToGetForeground>, "RequestForApplicationToGetForeground"},
|
||||
FunctionInfo{110, nullptr, "TerminateAllLibraryApplets"},
|
||||
FunctionInfo{111, nullptr, "AreAnyLibraryAppletsLeft"},
|
||||
FunctionInfo{112, D<&IApplicationAccessor::GetCurrentLibraryApplet>, "GetCurrentLibraryApplet"},
|
||||
FunctionInfo{120, nullptr, "GetApplicationId"},
|
||||
FunctionInfo{121, D<&IApplicationAccessor::PushLaunchParameter>, "PushLaunchParameter"},
|
||||
FunctionInfo{122, D<&IApplicationAccessor::GetApplicationControlProperty>, "GetApplicationControlProperty"},
|
||||
FunctionInfo{123, nullptr, "GetApplicationLaunchProperty"},
|
||||
FunctionInfo{124, nullptr, "GetApplicationLaunchRequestInfo"},
|
||||
FunctionInfo{130, D<&IApplicationAccessor::SetUsers>, "SetUsers"},
|
||||
FunctionInfo{131, D<&IApplicationAccessor::CheckRightsEnvironmentAvailable>, "CheckRightsEnvironmentAvailable"},
|
||||
FunctionInfo{132, D<&IApplicationAccessor::GetNsRightsEnvironmentHandle>, "GetNsRightsEnvironmentHandle"},
|
||||
FunctionInfo{140, nullptr, "GetDesirableUids"},
|
||||
FunctionInfo{150, D<&IApplicationAccessor::ReportApplicationExitTimeout>, "ReportApplicationExitTimeout"},
|
||||
FunctionInfo{160, nullptr, "SetApplicationAttribute"},
|
||||
FunctionInfo{170, nullptr, "HasSaveDataAccessPermission"},
|
||||
FunctionInfo{180, nullptr, "PushToFriendInvitationStorageChannel"},
|
||||
FunctionInfo{190, nullptr, "PushToNotificationStorageChannel"},
|
||||
FunctionInfo{200, nullptr, "RequestApplicationSoftReset"},
|
||||
FunctionInfo{201, nullptr, "RestartApplicationTimer"}
|
||||
);
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
|
||||
IApplicationAccessor::IApplicationAccessor(Core::System& system_, std::shared_ptr<Applet> applet,
|
||||
WindowSystem& window_system)
|
||||
: ServiceFramework{system_, "IApplicationAccessor"}, m_window_system(window_system),
|
||||
m_applet(std::move(applet)) {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, D<&IApplicationAccessor::GetAppletStateChangedEvent>, "GetAppletStateChangedEvent"},
|
||||
{1, nullptr, "IsCompleted"},
|
||||
{10, D<&IApplicationAccessor::Start>, "Start"},
|
||||
{20, D<&IApplicationAccessor::RequestExit>, "RequestExit"},
|
||||
{25, D<&IApplicationAccessor::Terminate>, "Terminate"},
|
||||
{30, D<&IApplicationAccessor::GetResult>, "GetResult"},
|
||||
{101, D<&IApplicationAccessor::RequestForApplicationToGetForeground>, "RequestForApplicationToGetForeground"},
|
||||
{110, nullptr, "TerminateAllLibraryApplets"},
|
||||
{111, nullptr, "AreAnyLibraryAppletsLeft"},
|
||||
{112, D<&IApplicationAccessor::GetCurrentLibraryApplet>, "GetCurrentLibraryApplet"},
|
||||
{120, nullptr, "GetApplicationId"},
|
||||
{121, D<&IApplicationAccessor::PushLaunchParameter>, "PushLaunchParameter"},
|
||||
{122, D<&IApplicationAccessor::GetApplicationControlProperty>, "GetApplicationControlProperty"},
|
||||
{123, nullptr, "GetApplicationLaunchProperty"},
|
||||
{124, nullptr, "GetApplicationLaunchRequestInfo"},
|
||||
{130, D<&IApplicationAccessor::SetUsers>, "SetUsers"},
|
||||
{131, D<&IApplicationAccessor::CheckRightsEnvironmentAvailable>, "CheckRightsEnvironmentAvailable"},
|
||||
{132, D<&IApplicationAccessor::GetNsRightsEnvironmentHandle>, "GetNsRightsEnvironmentHandle"},
|
||||
{140, nullptr, "GetDesirableUids"},
|
||||
{150, D<&IApplicationAccessor::ReportApplicationExitTimeout>, "ReportApplicationExitTimeout"},
|
||||
{160, nullptr, "SetApplicationAttribute"},
|
||||
{170, nullptr, "HasSaveDataAccessPermission"},
|
||||
{180, nullptr, "PushToFriendInvitationStorageChannel"},
|
||||
{190, nullptr, "PushToNotificationStorageChannel"},
|
||||
{200, nullptr, "RequestApplicationSoftReset"},
|
||||
{201, nullptr, "RestartApplicationTimer"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
IApplicationAccessor::~IApplicationAccessor() = default;
|
||||
|
||||
@@ -39,6 +39,7 @@ private:
|
||||
Result GetNsRightsEnvironmentHandle(Out<u64> out_handle);
|
||||
Result ReportApplicationExitTimeout();
|
||||
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override;
|
||||
WindowSystem& m_window_system;
|
||||
const std::shared_ptr<Applet> m_applet;
|
||||
};
|
||||
|
||||
@@ -20,6 +20,16 @@
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> IApplicationCreator::FindRequest(u32 key) {
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, D<&IApplicationCreator::CreateApplication>, "CreateApplication"},
|
||||
FunctionInfo{1, nullptr, "PopLaunchRequestedApplication"},
|
||||
FunctionInfo{10, D<&IApplicationCreator::CreateSystemApplication>, "CreateSystemApplication"},
|
||||
FunctionInfo{100, nullptr, "PopFloatingApplicationForDevelopment"}
|
||||
);
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
Result CreateGuestApplication(SharedPointer<IApplicationAccessor>* out_application_accessor, Core::System& system, WindowSystem& window_system, u64 program_id) {
|
||||
@@ -54,16 +64,6 @@ Result CreateGuestApplication(SharedPointer<IApplicationAccessor>* out_applicati
|
||||
|
||||
IApplicationCreator::IApplicationCreator(Core::System& system_, WindowSystem& window_system)
|
||||
: ServiceFramework{system_, "IApplicationCreator"}, m_window_system{window_system} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, D<&IApplicationCreator::CreateApplication>, "CreateApplication"},
|
||||
{1, nullptr, "PopLaunchRequestedApplication"},
|
||||
{10, D<&IApplicationCreator::CreateSystemApplication>, "CreateSystemApplication"},
|
||||
{100, nullptr, "PopFloatingApplicationForDevelopment"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
IApplicationCreator::~IApplicationCreator() = default;
|
||||
|
||||
@@ -24,6 +24,7 @@ private:
|
||||
Result CreateApplication(Out<SharedPointer<IApplicationAccessor>>, u64 application_id);
|
||||
Result CreateSystemApplication(Out<SharedPointer<IApplicationAccessor>>, u64 application_id);
|
||||
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override;
|
||||
WindowSystem& m_window_system;
|
||||
};
|
||||
|
||||
|
||||
@@ -51,84 +51,85 @@ FileSys::PatchManager::Metadata GetApplicationMetadata(Core::System& system, u64
|
||||
|
||||
} // Anonymous namespace
|
||||
|
||||
IApplicationFunctions::IApplicationFunctions(Core::System& system_, std::shared_ptr<Applet> applet)
|
||||
: ServiceFramework{system_, "IApplicationFunctions"}, m_applet{std::move(applet)} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{1, D<&IApplicationFunctions::PopLaunchParameter>, "PopLaunchParameter"},
|
||||
{10, nullptr, "CreateApplicationAndPushAndRequestToStart"},
|
||||
{11, nullptr, "CreateApplicationAndPushAndRequestToStartForQuest"},
|
||||
{12, D<&IApplicationFunctions::CreateApplicationAndRequestToStart>, "CreateApplicationAndRequestToStart"},
|
||||
{13, nullptr, "CreateApplicationAndRequestToStartForQuest"},
|
||||
{14, nullptr, "CreateApplicationWithAttributeAndPushAndRequestToStartForQuest"},
|
||||
{15, nullptr, "CreateApplicationWithAttributeAndRequestToStartForQuest"},
|
||||
{20, D<&IApplicationFunctions::EnsureSaveData>, "EnsureSaveData"},
|
||||
{21, D<&IApplicationFunctions::GetDesiredLanguage>, "GetDesiredLanguage"},
|
||||
{22, D<&IApplicationFunctions::SetTerminateResult>, "SetTerminateResult"},
|
||||
{23, D<&IApplicationFunctions::GetDisplayVersion>, "GetDisplayVersion"},
|
||||
{24, nullptr, "GetLaunchStorageInfoForDebug"},
|
||||
{25, D<&IApplicationFunctions::ExtendSaveData>, "ExtendSaveData"},
|
||||
{26, D<&IApplicationFunctions::GetSaveDataSize>, "GetSaveDataSize"},
|
||||
{27, D<&IApplicationFunctions::CreateCacheStorage>, "CreateCacheStorage"},
|
||||
{28, D<&IApplicationFunctions::GetSaveDataSizeMax>, "GetSaveDataSizeMax"},
|
||||
{29, D<&IApplicationFunctions::GetCacheStorageMax>, "GetCacheStorageMax"},
|
||||
{30, D<&IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed>, "BeginBlockingHomeButtonShortAndLongPressed"},
|
||||
{31, D<&IApplicationFunctions::EndBlockingHomeButtonShortAndLongPressed>, "EndBlockingHomeButtonShortAndLongPressed"},
|
||||
{32, D<&IApplicationFunctions::BeginBlockingHomeButton>, "BeginBlockingHomeButton"},
|
||||
{33, D<&IApplicationFunctions::EndBlockingHomeButton>, "EndBlockingHomeButton"},
|
||||
{34, nullptr, "SelectApplicationLicense"},
|
||||
{35, nullptr, "GetDeviceSaveDataSizeMax"},
|
||||
{36, nullptr, "GetLimitedApplicationLicense"},
|
||||
{37, nullptr, "GetLimitedApplicationLicenseUpgradableEvent"},
|
||||
{40, D<&IApplicationFunctions::NotifyRunning>, "NotifyRunning"},
|
||||
{50, D<&IApplicationFunctions::GetPseudoDeviceId>, "GetPseudoDeviceId"},
|
||||
{60, D<&IApplicationFunctions::SetMediaPlaybackStateForApplication>, "SetMediaPlaybackStateForApplication"},
|
||||
{65, D<&IApplicationFunctions::IsGamePlayRecordingSupported>, "IsGamePlayRecordingSupported"},
|
||||
{66, D<&IApplicationFunctions::InitializeGamePlayRecording>, "InitializeGamePlayRecording"},
|
||||
{67, D<&IApplicationFunctions::SetGamePlayRecordingState>, "SetGamePlayRecordingState"},
|
||||
{68, nullptr, "RequestFlushGamePlayingMovieForDebug"},
|
||||
{70, nullptr, "RequestToShutdown"},
|
||||
{71, nullptr, "RequestToReboot"},
|
||||
{72, nullptr, "RequestToSleep"},
|
||||
{80, nullptr, "ExitAndRequestToShowThanksMessage"},
|
||||
{90, D<&IApplicationFunctions::EnableApplicationCrashReport>, "EnableApplicationCrashReport"},
|
||||
{100, D<&IApplicationFunctions::InitializeApplicationCopyrightFrameBuffer>, "InitializeApplicationCopyrightFrameBuffer"},
|
||||
{101, D<&IApplicationFunctions::SetApplicationCopyrightImage>, "SetApplicationCopyrightImage"},
|
||||
{102, D<&IApplicationFunctions::SetApplicationCopyrightVisibility>, "SetApplicationCopyrightVisibility"},
|
||||
{110, D<&IApplicationFunctions::QueryApplicationPlayStatistics>, "QueryApplicationPlayStatistics"},
|
||||
{111, D<&IApplicationFunctions::QueryApplicationPlayStatisticsByUid>, "QueryApplicationPlayStatisticsByUid"},
|
||||
{120, D<&IApplicationFunctions::ExecuteProgram>, "ExecuteProgram"},
|
||||
{121, D<&IApplicationFunctions::ClearUserChannel>, "ClearUserChannel"},
|
||||
{122, D<&IApplicationFunctions::UnpopToUserChannel>, "UnpopToUserChannel"},
|
||||
{123, D<&IApplicationFunctions::GetPreviousProgramIndex>, "GetPreviousProgramIndex"},
|
||||
{124, nullptr, "EnableApplicationAllThreadDumpOnCrash"},
|
||||
{130, D<&IApplicationFunctions::GetGpuErrorDetectedSystemEvent>, "GetGpuErrorDetectedSystemEvent"},
|
||||
{131, nullptr, "SetDelayTimeToAbortOnGpuError"},
|
||||
{140, D<&IApplicationFunctions::GetFriendInvitationStorageChannelEvent>, "GetFriendInvitationStorageChannelEvent"},
|
||||
{141, D<&IApplicationFunctions::TryPopFromFriendInvitationStorageChannel>, "TryPopFromFriendInvitationStorageChannel"},
|
||||
{150, D<&IApplicationFunctions::GetNotificationStorageChannelEvent>, "GetNotificationStorageChannelEvent"},
|
||||
{151, nullptr, "TryPopFromNotificationStorageChannel"},
|
||||
{160, D<&IApplicationFunctions::GetHealthWarningDisappearedSystemEvent>, "GetHealthWarningDisappearedSystemEvent"},
|
||||
{170, nullptr, "SetHdcpAuthenticationActivated"},
|
||||
{180, nullptr, "GetLaunchRequiredVersion"},
|
||||
{181, nullptr, "UpgradeLaunchRequiredVersion"},
|
||||
{190, nullptr, "SendServerMaintenanceOverlayNotification"},
|
||||
{200, nullptr, "GetLastApplicationExitReason"},
|
||||
{210, D<&IApplicationFunctions::GetUnknownEvent210>, "Unknown210"},
|
||||
{220, nullptr, "Unknown220"}, // [20.0.0+]
|
||||
{300, nullptr, "CreateMovieWriter"}, // [19.0.0+]
|
||||
{310, nullptr, "Unknown310"}, // [20.0.0+]
|
||||
{320, nullptr, "Unknown320"}, // [20.0.0+]
|
||||
{330, D<&IApplicationFunctions::Unknown330>, "Unknown330"}, // [20.0.0+]
|
||||
{500, nullptr, "StartContinuousRecordingFlushForDebug"},
|
||||
{1000, nullptr, "CreateMovieMaker"},
|
||||
{1001, D<&IApplicationFunctions::PrepareForJit>, "PrepareForJit"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> IApplicationFunctions::FindRequest(u32 key) {
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{1, D<&IApplicationFunctions::PopLaunchParameter>, "PopLaunchParameter"},
|
||||
FunctionInfo{10, nullptr, "CreateApplicationAndPushAndRequestToStart"},
|
||||
FunctionInfo{11, nullptr, "CreateApplicationAndPushAndRequestToStartForQuest"},
|
||||
FunctionInfo{12, D<&IApplicationFunctions::CreateApplicationAndRequestToStart>, "CreateApplicationAndRequestToStart"},
|
||||
FunctionInfo{13, nullptr, "CreateApplicationAndRequestToStartForQuest"},
|
||||
FunctionInfo{14, nullptr, "CreateApplicationWithAttributeAndPushAndRequestToStartForQuest"},
|
||||
FunctionInfo{15, nullptr, "CreateApplicationWithAttributeAndRequestToStartForQuest"},
|
||||
FunctionInfo{20, D<&IApplicationFunctions::EnsureSaveData>, "EnsureSaveData"},
|
||||
FunctionInfo{21, D<&IApplicationFunctions::GetDesiredLanguage>, "GetDesiredLanguage"},
|
||||
FunctionInfo{22, D<&IApplicationFunctions::SetTerminateResult>, "SetTerminateResult"},
|
||||
FunctionInfo{23, D<&IApplicationFunctions::GetDisplayVersion>, "GetDisplayVersion"},
|
||||
FunctionInfo{24, nullptr, "GetLaunchStorageInfoForDebug"},
|
||||
FunctionInfo{25, D<&IApplicationFunctions::ExtendSaveData>, "ExtendSaveData"},
|
||||
FunctionInfo{26, D<&IApplicationFunctions::GetSaveDataSize>, "GetSaveDataSize"},
|
||||
FunctionInfo{27, D<&IApplicationFunctions::CreateCacheStorage>, "CreateCacheStorage"},
|
||||
FunctionInfo{28, D<&IApplicationFunctions::GetSaveDataSizeMax>, "GetSaveDataSizeMax"},
|
||||
FunctionInfo{29, D<&IApplicationFunctions::GetCacheStorageMax>, "GetCacheStorageMax"},
|
||||
FunctionInfo{30, D<&IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed>, "BeginBlockingHomeButtonShortAndLongPressed"},
|
||||
FunctionInfo{31, D<&IApplicationFunctions::EndBlockingHomeButtonShortAndLongPressed>, "EndBlockingHomeButtonShortAndLongPressed"},
|
||||
FunctionInfo{32, D<&IApplicationFunctions::BeginBlockingHomeButton>, "BeginBlockingHomeButton"},
|
||||
FunctionInfo{33, D<&IApplicationFunctions::EndBlockingHomeButton>, "EndBlockingHomeButton"},
|
||||
FunctionInfo{34, nullptr, "SelectApplicationLicense"},
|
||||
FunctionInfo{35, nullptr, "GetDeviceSaveDataSizeMax"},
|
||||
FunctionInfo{36, nullptr, "GetLimitedApplicationLicense"},
|
||||
FunctionInfo{37, nullptr, "GetLimitedApplicationLicenseUpgradableEvent"},
|
||||
FunctionInfo{40, D<&IApplicationFunctions::NotifyRunning>, "NotifyRunning"},
|
||||
FunctionInfo{50, D<&IApplicationFunctions::GetPseudoDeviceId>, "GetPseudoDeviceId"},
|
||||
FunctionInfo{60, D<&IApplicationFunctions::SetMediaPlaybackStateForApplication>, "SetMediaPlaybackStateForApplication"},
|
||||
FunctionInfo{65, D<&IApplicationFunctions::IsGamePlayRecordingSupported>, "IsGamePlayRecordingSupported"},
|
||||
FunctionInfo{66, D<&IApplicationFunctions::InitializeGamePlayRecording>, "InitializeGamePlayRecording"},
|
||||
FunctionInfo{67, D<&IApplicationFunctions::SetGamePlayRecordingState>, "SetGamePlayRecordingState"},
|
||||
FunctionInfo{68, nullptr, "RequestFlushGamePlayingMovieForDebug"},
|
||||
FunctionInfo{70, nullptr, "RequestToShutdown"},
|
||||
FunctionInfo{71, nullptr, "RequestToReboot"},
|
||||
FunctionInfo{72, nullptr, "RequestToSleep"},
|
||||
FunctionInfo{80, nullptr, "ExitAndRequestToShowThanksMessage"},
|
||||
FunctionInfo{90, D<&IApplicationFunctions::EnableApplicationCrashReport>, "EnableApplicationCrashReport"},
|
||||
FunctionInfo{100, D<&IApplicationFunctions::InitializeApplicationCopyrightFrameBuffer>, "InitializeApplicationCopyrightFrameBuffer"},
|
||||
FunctionInfo{101, D<&IApplicationFunctions::SetApplicationCopyrightImage>, "SetApplicationCopyrightImage"},
|
||||
FunctionInfo{102, D<&IApplicationFunctions::SetApplicationCopyrightVisibility>, "SetApplicationCopyrightVisibility"},
|
||||
FunctionInfo{110, D<&IApplicationFunctions::QueryApplicationPlayStatistics>, "QueryApplicationPlayStatistics"},
|
||||
FunctionInfo{111, D<&IApplicationFunctions::QueryApplicationPlayStatisticsByUid>, "QueryApplicationPlayStatisticsByUid"},
|
||||
FunctionInfo{120, D<&IApplicationFunctions::ExecuteProgram>, "ExecuteProgram"},
|
||||
FunctionInfo{121, D<&IApplicationFunctions::ClearUserChannel>, "ClearUserChannel"},
|
||||
FunctionInfo{122, D<&IApplicationFunctions::UnpopToUserChannel>, "UnpopToUserChannel"},
|
||||
FunctionInfo{123, D<&IApplicationFunctions::GetPreviousProgramIndex>, "GetPreviousProgramIndex"},
|
||||
FunctionInfo{124, nullptr, "EnableApplicationAllThreadDumpOnCrash"},
|
||||
FunctionInfo{130, D<&IApplicationFunctions::GetGpuErrorDetectedSystemEvent>, "GetGpuErrorDetectedSystemEvent"},
|
||||
FunctionInfo{131, nullptr, "SetDelayTimeToAbortOnGpuError"},
|
||||
FunctionInfo{140, D<&IApplicationFunctions::GetFriendInvitationStorageChannelEvent>, "GetFriendInvitationStorageChannelEvent"},
|
||||
FunctionInfo{141, D<&IApplicationFunctions::TryPopFromFriendInvitationStorageChannel>, "TryPopFromFriendInvitationStorageChannel"},
|
||||
FunctionInfo{150, D<&IApplicationFunctions::GetNotificationStorageChannelEvent>, "GetNotificationStorageChannelEvent"},
|
||||
FunctionInfo{151, nullptr, "TryPopFromNotificationStorageChannel"},
|
||||
FunctionInfo{160, D<&IApplicationFunctions::GetHealthWarningDisappearedSystemEvent>, "GetHealthWarningDisappearedSystemEvent"},
|
||||
FunctionInfo{170, nullptr, "SetHdcpAuthenticationActivated"},
|
||||
FunctionInfo{180, nullptr, "GetLaunchRequiredVersion"},
|
||||
FunctionInfo{181, nullptr, "UpgradeLaunchRequiredVersion"},
|
||||
FunctionInfo{190, nullptr, "SendServerMaintenanceOverlayNotification"},
|
||||
FunctionInfo{200, nullptr, "GetLastApplicationExitReason"},
|
||||
FunctionInfo{210, D<&IApplicationFunctions::GetUnknownEvent210>, "Unknown210"},
|
||||
FunctionInfo{220, nullptr, "Unknown220"}, // [20.0.0+]
|
||||
FunctionInfo{300, nullptr, "CreateMovieWriter"}, // [19.0.0+]
|
||||
FunctionInfo{310, nullptr, "Unknown310"}, // [20.0.0+]
|
||||
FunctionInfo{320, nullptr, "Unknown320"}, // [20.0.0+]
|
||||
FunctionInfo{330, D<&IApplicationFunctions::Unknown330>, "Unknown330"}, // [20.0.0+]
|
||||
FunctionInfo{500, nullptr, "StartContinuousRecordingFlushForDebug"},
|
||||
FunctionInfo{1000, nullptr, "CreateMovieMaker"},
|
||||
FunctionInfo{1001, D<&IApplicationFunctions::PrepareForJit>, "PrepareForJit"}
|
||||
);
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
|
||||
IApplicationFunctions::IApplicationFunctions(Core::System& system_, std::shared_ptr<Applet> applet)
|
||||
: ServiceFramework{system_, "IApplicationFunctions"}
|
||||
, m_applet{std::move(applet)}
|
||||
{}
|
||||
|
||||
IApplicationFunctions::~IApplicationFunctions() = default;
|
||||
|
||||
Result IApplicationFunctions::PopLaunchParameter(Out<SharedPointer<IStorage>> out_storage,
|
||||
|
||||
@@ -84,6 +84,7 @@ private:
|
||||
Result GetUnknownEvent210(OutCopyHandle<Kernel::KReadableEvent> out_event);
|
||||
Result Unknown330(Out<u8> out);
|
||||
Result PrepareForJit();
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override;
|
||||
|
||||
const std::shared_ptr<Applet> m_applet;
|
||||
};
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "core/hle/service/am/service/applet_common_functions.h"
|
||||
#include "core/hle/service/am/service/application_functions.h"
|
||||
#include "core/hle/service/am/service/application_proxy.h"
|
||||
#include "core/hle/service/am/service/audio_controller.h"
|
||||
#include "core/hle/service/am/service/common_state_getter.h"
|
||||
#include "core/hle/service/am/service/debug_functions.h"
|
||||
#include "core/hle/service/am/service/display_controller.h"
|
||||
#include "core/hle/service/am/service/library_applet_creator.h"
|
||||
#include "core/hle/service/am/service/process_winding_controller.h"
|
||||
#include "core/hle/service/am/service/self_controller.h"
|
||||
#include "core/hle/service/am/service/window_controller.h"
|
||||
#include "core/hle/service/cmif_serialization.h"
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
IApplicationProxy::IApplicationProxy(Core::System& system_, std::shared_ptr<Applet> applet,
|
||||
Kernel::KProcess* process, WindowSystem& window_system)
|
||||
: ServiceFramework{system_, "IApplicationProxy"},
|
||||
m_window_system{window_system}, m_process{process}, m_applet{std::move(applet)} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, D<&IApplicationProxy::GetCommonStateGetter>, "GetCommonStateGetter"},
|
||||
{1, D<&IApplicationProxy::GetSelfController>, "GetSelfController"},
|
||||
{2, D<&IApplicationProxy::GetWindowController>, "GetWindowController"},
|
||||
{3, D<&IApplicationProxy::GetAudioController>, "GetAudioController"},
|
||||
{4, D<&IApplicationProxy::GetDisplayController>, "GetDisplayController"},
|
||||
{10, D<&IApplicationProxy::GetProcessWindingController>, "GetProcessWindingController"},
|
||||
{11, D<&IApplicationProxy::GetLibraryAppletCreator>, "GetLibraryAppletCreator"},
|
||||
{20, D<&IApplicationProxy::GetApplicationFunctions>, "GetApplicationFunctions"},
|
||||
{1000, D<&IApplicationProxy::GetDebugFunctions>, "GetDebugFunctions"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
IApplicationProxy::~IApplicationProxy() = default;
|
||||
|
||||
Result IApplicationProxy::GetAudioController(
|
||||
Out<SharedPointer<IAudioController>> out_audio_controller) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_audio_controller = std::make_shared<IAudioController>(system);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IApplicationProxy::GetDisplayController(
|
||||
Out<SharedPointer<IDisplayController>> out_display_controller) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_display_controller = std::make_shared<IDisplayController>(system, m_applet);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IApplicationProxy::GetProcessWindingController(
|
||||
Out<SharedPointer<IProcessWindingController>> out_process_winding_controller) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_process_winding_controller = std::make_shared<IProcessWindingController>(system, m_applet);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IApplicationProxy::GetDebugFunctions(
|
||||
Out<SharedPointer<IDebugFunctions>> out_debug_functions) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_debug_functions = std::make_shared<IDebugFunctions>(system);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IApplicationProxy::GetWindowController(
|
||||
Out<SharedPointer<IWindowController>> out_window_controller) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_window_controller = std::make_shared<IWindowController>(system, m_applet, m_window_system);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IApplicationProxy::GetSelfController(
|
||||
Out<SharedPointer<ISelfController>> out_self_controller) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_self_controller = std::make_shared<ISelfController>(system, m_applet, m_process);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IApplicationProxy::GetCommonStateGetter(
|
||||
Out<SharedPointer<ICommonStateGetter>> out_common_state_getter) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_common_state_getter = std::make_shared<ICommonStateGetter>(system, m_applet);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IApplicationProxy::GetLibraryAppletCreator(
|
||||
Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_library_applet_creator =
|
||||
std::make_shared<ILibraryAppletCreator>(system, m_applet, m_window_system);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IApplicationProxy::GetApplicationFunctions(
|
||||
Out<SharedPointer<IApplicationFunctions>> out_application_functions) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_application_functions = std::make_shared<IApplicationFunctions>(system, m_applet);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
} // namespace Service::AM
|
||||
@@ -1,52 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/cmif_types.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
struct Applet;
|
||||
class IAudioController;
|
||||
class IApplicationFunctions;
|
||||
class ICommonStateGetter;
|
||||
class IDebugFunctions;
|
||||
class IDisplayController;
|
||||
class ILibraryAppletCreator;
|
||||
class IProcessWindingController;
|
||||
class ISelfController;
|
||||
class IWindowController;
|
||||
class WindowSystem;
|
||||
|
||||
class IApplicationProxy final : public ServiceFramework<IApplicationProxy> {
|
||||
public:
|
||||
explicit IApplicationProxy(Core::System& system_, std::shared_ptr<Applet> applet,
|
||||
Kernel::KProcess* process, WindowSystem& window_system);
|
||||
~IApplicationProxy();
|
||||
|
||||
private:
|
||||
Result GetAudioController(Out<SharedPointer<IAudioController>> out_audio_controller);
|
||||
Result GetDisplayController(Out<SharedPointer<IDisplayController>> out_display_controller);
|
||||
Result GetProcessWindingController(
|
||||
Out<SharedPointer<IProcessWindingController>> out_process_winding_controller);
|
||||
Result GetDebugFunctions(Out<SharedPointer<IDebugFunctions>> out_debug_functions);
|
||||
Result GetWindowController(Out<SharedPointer<IWindowController>> out_window_controller);
|
||||
Result GetSelfController(Out<SharedPointer<ISelfController>> out_self_controller);
|
||||
Result GetCommonStateGetter(Out<SharedPointer<ICommonStateGetter>> out_common_state_getter);
|
||||
Result GetLibraryAppletCreator(
|
||||
Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator);
|
||||
Result GetApplicationFunctions(
|
||||
Out<SharedPointer<IApplicationFunctions>> out_application_functions);
|
||||
|
||||
private:
|
||||
WindowSystem& m_window_system;
|
||||
Kernel::KProcess* const m_process;
|
||||
const std::shared_ptr<Applet> m_applet;
|
||||
};
|
||||
|
||||
} // namespace Service::AM
|
||||
@@ -1,47 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "core/core.h"
|
||||
#include "core/hle/service/am/am.h"
|
||||
#include "core/hle/service/am/applet_manager.h"
|
||||
#include "core/hle/service/am/service/application_proxy.h"
|
||||
#include "core/hle/service/am/service/application_proxy_service.h"
|
||||
#include "core/hle/service/am/window_system.h"
|
||||
#include "core/hle/service/cmif_serialization.h"
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
IApplicationProxyService::IApplicationProxyService(Core::System& system_,
|
||||
WindowSystem& window_system)
|
||||
: ServiceFramework{system_, "appletOE"}, m_window_system{window_system} {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, D<&IApplicationProxyService::OpenApplicationProxy>, "OpenApplicationProxy"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
IApplicationProxyService::~IApplicationProxyService() = default;
|
||||
|
||||
Result IApplicationProxyService::OpenApplicationProxy(
|
||||
Out<SharedPointer<IApplicationProxy>> out_application_proxy, ClientProcessId pid,
|
||||
InCopyHandle<Kernel::KProcess> process_handle) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
|
||||
if (const auto applet = this->GetAppletFromProcessId(pid)) {
|
||||
*out_application_proxy = std::make_shared<IApplicationProxy>(
|
||||
system, applet, process_handle.Get(), m_window_system);
|
||||
R_SUCCEED();
|
||||
} else {
|
||||
UNIMPLEMENTED();
|
||||
R_THROW(ResultUnknown);
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<Applet> IApplicationProxyService::GetAppletFromProcessId(ProcessId process_id) {
|
||||
return m_window_system.GetByAppletResourceUserId(process_id.pid);
|
||||
}
|
||||
|
||||
} // namespace Service::AM
|
||||
@@ -1,36 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/cmif_types.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service {
|
||||
|
||||
namespace AM {
|
||||
|
||||
struct Applet;
|
||||
class IApplicationProxy;
|
||||
class WindowSystem;
|
||||
|
||||
class IApplicationProxyService final : public ServiceFramework<IApplicationProxyService> {
|
||||
public:
|
||||
explicit IApplicationProxyService(Core::System& system_, WindowSystem& window_system);
|
||||
~IApplicationProxyService() override;
|
||||
|
||||
private:
|
||||
Result OpenApplicationProxy(Out<SharedPointer<IApplicationProxy>> out_application_proxy,
|
||||
ClientProcessId pid, InCopyHandle<Kernel::KProcess> process_handle);
|
||||
|
||||
private:
|
||||
std::shared_ptr<Applet> GetAppletFromProcessId(ProcessId pid);
|
||||
|
||||
WindowSystem& m_window_system;
|
||||
};
|
||||
|
||||
} // namespace AM
|
||||
} // namespace Service
|
||||
@@ -9,20 +9,20 @@
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> IAudioController::FindRequest(u32 key) {
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, D<&IAudioController::SetExpectedMasterVolume>, "SetExpectedMasterVolume"},
|
||||
FunctionInfo{1, D<&IAudioController::GetMainAppletExpectedMasterVolume>, "GetMainAppletExpectedMasterVolume"},
|
||||
FunctionInfo{2, D<&IAudioController::GetLibraryAppletExpectedMasterVolume>, "GetLibraryAppletExpectedMasterVolume"},
|
||||
FunctionInfo{3, D<&IAudioController::ChangeMainAppletMasterVolume>, "ChangeMainAppletMasterVolume"},
|
||||
FunctionInfo{4, D<&IAudioController::SetTransparentVolumeRate>, "SetTransparentVolumeRate"},
|
||||
FunctionInfo{5, nullptr, "Unknown5", MakeVersionGate({20,0,0})}
|
||||
);
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
|
||||
IAudioController::IAudioController(Core::System& system_)
|
||||
: ServiceFramework{system_, "IAudioController"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, D<&IAudioController::SetExpectedMasterVolume>, "SetExpectedMasterVolume"},
|
||||
{1, D<&IAudioController::GetMainAppletExpectedMasterVolume>, "GetMainAppletExpectedMasterVolume"},
|
||||
{2, D<&IAudioController::GetLibraryAppletExpectedMasterVolume>, "GetLibraryAppletExpectedMasterVolume"},
|
||||
{3, D<&IAudioController::ChangeMainAppletMasterVolume>, "ChangeMainAppletMasterVolume"},
|
||||
{4, D<&IAudioController::SetTransparentVolumeRate>, "SetTransparentVolumeRate"},
|
||||
{5, nullptr, "Unknown5"}, //20.0.0+
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
IAudioController::~IAudioController() = default;
|
||||
|
||||
@@ -23,6 +23,7 @@ private:
|
||||
Result ChangeMainAppletMasterVolume(f32 volume, s64 fade_time_ns);
|
||||
Result SetTransparentVolumeRate(f32 transparent_volume_rate);
|
||||
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override;
|
||||
static constexpr float MinAllowedVolume = 0.0f;
|
||||
static constexpr float MaxAllowedVolume = 1.0f;
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include "core/hle/service/am/am_results.h"
|
||||
#include "core/hle/service/am/applet.h"
|
||||
#include "core/hle/service/am/service/common_state_getter.h"
|
||||
#include "core/hle/service/am/service/lock_accessor.h"
|
||||
#include "core/hle/service/am/service/storage.h"
|
||||
#include "core/hle/service/apm/apm_interface.h"
|
||||
#include "core/hle/service/cmif_serialization.h"
|
||||
@@ -18,77 +17,147 @@
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> ICommonStateGetter::FindRequest(u32 key) {
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, D<&ICommonStateGetter::GetEventHandle>, "GetEventHandle"},
|
||||
FunctionInfo{1, D<&ICommonStateGetter::ReceiveMessage>, "ReceiveMessage"},
|
||||
FunctionInfo{2, nullptr, "GetThisAppletKind"},
|
||||
FunctionInfo{3, nullptr, "AllowToEnterSleep"},
|
||||
FunctionInfo{4, nullptr, "DisallowToEnterSleep"},
|
||||
FunctionInfo{5, D<&ICommonStateGetter::GetOperationMode>, "GetOperationMode"},
|
||||
FunctionInfo{6, D<&ICommonStateGetter::GetPerformanceMode>, "GetPerformanceMode"},
|
||||
FunctionInfo{7, nullptr, "GetCradleStatus"},
|
||||
FunctionInfo{8, D<&ICommonStateGetter::GetBootMode>, "GetBootMode"},
|
||||
FunctionInfo{9, D<&ICommonStateGetter::GetCurrentFocusState>, "GetCurrentFocusState"},
|
||||
FunctionInfo{10, D<&ICommonStateGetter::RequestToAcquireSleepLock>, "RequestToAcquireSleepLock"},
|
||||
FunctionInfo{11, D<&ICommonStateGetter::ReleaseSleepLock>, "ReleaseSleepLock"},
|
||||
FunctionInfo{12, D<&ICommonStateGetter::ReleaseSleepLockTransiently>, "ReleaseSleepLockTransiently"},
|
||||
FunctionInfo{13, D<&ICommonStateGetter::GetAcquiredSleepLockEvent>, "GetAcquiredSleepLockEvent"},
|
||||
FunctionInfo{14, nullptr, "GetWakeupCount", MakeVersionGate({11,0,0})},
|
||||
FunctionInfo{15, nullptr, "Unknown15", MakeVersionGate({19,0,0})},
|
||||
FunctionInfo{20, D<&ICommonStateGetter::PushToGeneralChannel>, "PushToGeneralChannel"},
|
||||
FunctionInfo{30, D<&ICommonStateGetter::GetHomeButtonReaderLockAccessor>, "GetHomeButtonReaderLockAccessor"},
|
||||
FunctionInfo{31, D<&ICommonStateGetter::GetReaderLockAccessorEx>, "GetReaderLockAccessorEx", MakeVersionGate({2,0,0})},
|
||||
FunctionInfo{32, D<&ICommonStateGetter::GetWriterLockAccessorEx>, "GetWriterLockAccessorEx", MakeVersionGate({7,0,0})},
|
||||
FunctionInfo{40, nullptr, "GetCradleFwVersion", MakeVersionGate({2,0,0})},
|
||||
FunctionInfo{50, D<&ICommonStateGetter::IsVrModeEnabled>, "IsVrModeEnabled", MakeVersionGate({3,0,0})},
|
||||
FunctionInfo{51, D<&ICommonStateGetter::SetVrModeEnabled>, "SetVrModeEnabled", MakeVersionGate({3,0,0})},
|
||||
FunctionInfo{52, D<&ICommonStateGetter::SetLcdBacklighOffEnabled>, "SetLcdBacklighOffEnabled", MakeVersionGate({4,0,0})},
|
||||
FunctionInfo{53, D<&ICommonStateGetter::BeginVrModeEx>, "BeginVrModeEx", MakeVersionGate({7,0,0})},
|
||||
FunctionInfo{54, D<&ICommonStateGetter::EndVrModeEx>, "EndVrModeEx", MakeVersionGate({7,0,0})},
|
||||
FunctionInfo{55, D<&ICommonStateGetter::IsInControllerFirmwareUpdateSection>, "IsInControllerFirmwareUpdateSection", MakeVersionGate({3,0,0})},
|
||||
FunctionInfo{59, nullptr, "SetVrPositionForDebug", MakeVersionGate({1,0,0})},
|
||||
FunctionInfo{60, D<&ICommonStateGetter::GetDefaultDisplayResolution>, "GetDefaultDisplayResolution"},
|
||||
FunctionInfo{61, D<&ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent>, "GetDefaultDisplayResolutionChangeEvent"},
|
||||
FunctionInfo{62, D<&ICommonStateGetter::GetHdcpAuthenticationState>, "GetHdcpAuthenticationState"},
|
||||
FunctionInfo{63, D<&ICommonStateGetter::GetHdcpAuthenticationStateChangeEvent>, "GetHdcpAuthenticationStateChangeEvent"},
|
||||
FunctionInfo{64, nullptr, "SetTvPowerStateMatchingMode"},
|
||||
FunctionInfo{65, nullptr, "GetApplicationIdByContentActionName"},
|
||||
FunctionInfo{66, &ICommonStateGetter::SetCpuBoostMode, "SetCpuBoostMode"},
|
||||
FunctionInfo{67, nullptr, "CancelCpuBoostMode"},
|
||||
FunctionInfo{68, D<&ICommonStateGetter::GetBuiltInDisplayType>, "GetBuiltInDisplayType"},
|
||||
FunctionInfo{80, D<&ICommonStateGetter::PerformSystemButtonPressingIfInFocus>, "PerformSystemButtonPressingIfInFocus"},
|
||||
FunctionInfo{90, nullptr, "SetPerformanceConfigurationChangedNotification"},
|
||||
FunctionInfo{91, nullptr, "GetCurrentPerformanceConfiguration"},
|
||||
FunctionInfo{100, D<&ICommonStateGetter::SetHandlingHomeButtonShortPressedEnabled>, "SetHandlingHomeButtonShortPressedEnabled"},
|
||||
FunctionInfo{110, nullptr, "OpenMyGpuErrorHandler"},
|
||||
FunctionInfo{120, D<&ICommonStateGetter::GetAppletLaunchedHistory>, "GetAppletLaunchedHistory", MakeVersionGate({13,0,0})},
|
||||
FunctionInfo{130, D<&ICommonStateGetter::EnableStartupLogoDisappearedMessage>, "EnableStartupLogoDisappearedMessage", MakeVersionGate({21,0,0})},
|
||||
FunctionInfo{200, D<&ICommonStateGetter::GetOperationModeSystemInfo>, "GetOperationModeSystemInfo"},
|
||||
FunctionInfo{300, D<&ICommonStateGetter::GetSettingsPlatformRegion>, "GetSettingsPlatformRegion"},
|
||||
FunctionInfo{400, nullptr, "ActivateMigrationService"},
|
||||
FunctionInfo{401, nullptr, "DeactivateMigrationService"},
|
||||
FunctionInfo{500, nullptr, "DisableSleepTillShutdown"},
|
||||
FunctionInfo{501, nullptr, "SuppressDisablingSleepTemporarily"},
|
||||
FunctionInfo{502, nullptr, "IsSleepEnabled"},
|
||||
FunctionInfo{503, nullptr, "IsDisablingSleepSuppressed"},
|
||||
FunctionInfo{600, nullptr, "SetHidInputMagnificationForApplication", MakeVersionGate({20,0,0})},
|
||||
FunctionInfo{610, D<&ICommonStateGetter::Unknown610>, "Unknown610", MakeVersionGate({21,0,0})},
|
||||
FunctionInfo{611, D<&ICommonStateGetter::Unknown611>, "Unknown611", MakeVersionGate({22,0,0})},
|
||||
FunctionInfo{900, D<&ICommonStateGetter::SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled>, "SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled", MakeVersionGate({11,0,0})},
|
||||
FunctionInfo{910, nullptr, "GetLaunchRequiredTick", MakeVersionGate({17,0,0})},
|
||||
FunctionInfo{1000, D<&ICommonStateGetter::BeginVrMode3d>, "BeginVrMode3d", MakeVersionGate({19,0,0})},
|
||||
FunctionInfo{1001, D<&ICommonStateGetter::EndVrMode3d>, "EndVrMode3d", MakeVersionGate({19,0,0})},
|
||||
FunctionInfo{1002, D<&ICommonStateGetter::IsVrModeEnabled3d>, "IsVrModeEnabled3d", MakeVersionGate({19,0,0})},
|
||||
FunctionInfo{1003, D<&ICommonStateGetter::GetVrLaboGoggleViewport>, "GetVrLaboGoggleViewport", MakeVersionGate({21,0,0})},
|
||||
FunctionInfo{1004, D<&ICommonStateGetter::GetPanelPhysicalSizeForSpecificTitle>, "GetPanelPhysicalSizeForSpecificTitle", MakeVersionGate({21,0,0})},
|
||||
FunctionInfo{1005, D<&ICommonStateGetter::GetPanelResolutionForSpecificTitle>, "GetPanelResolutionForSpecificTitle", MakeVersionGate({21,0,0})}
|
||||
);
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
|
||||
class ILockAccessor final : public ServiceFramework<ILockAccessor> {
|
||||
public:
|
||||
explicit ILockAccessor(Core::System& system_)
|
||||
: ServiceFramework{system_, "ILockAccessor"}, m_context{system_, "ILockAccessor"},
|
||||
m_event{m_context} {
|
||||
m_event.Signal(system.Kernel());
|
||||
}
|
||||
~ILockAccessor() override = default;
|
||||
|
||||
Result TryLock(Out<bool> out_is_locked, OutCopyHandle<Kernel::KReadableEvent> out_handle, bool return_handle) {
|
||||
LOG_INFO(Service_AM, "called, return_handle={}", return_handle);
|
||||
|
||||
{
|
||||
std::scoped_lock lk{m_mutex};
|
||||
if (m_is_locked) {
|
||||
*out_is_locked = false;
|
||||
} else {
|
||||
m_is_locked = true;
|
||||
*out_is_locked = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (return_handle) {
|
||||
*out_handle = m_event.GetHandle();
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result Unlock() {
|
||||
LOG_INFO(Service_AM, "called");
|
||||
|
||||
{
|
||||
std::scoped_lock lk{m_mutex};
|
||||
m_is_locked = false;
|
||||
}
|
||||
|
||||
m_event.Signal(system.Kernel());
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result GetEvent(OutCopyHandle<Kernel::KReadableEvent> out_handle) {
|
||||
LOG_INFO(Service_AM, "called");
|
||||
*out_handle = m_event.GetHandle();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IsLocked(Out<bool> out_is_locked) {
|
||||
LOG_INFO(Service_AM, "called");
|
||||
std::scoped_lock lk{m_mutex};
|
||||
*out_is_locked = m_is_locked;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
private:
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{1, D<&ILockAccessor::TryLock>, "TryLock"},
|
||||
FunctionInfo{2, D<&ILockAccessor::Unlock>, "Unlock"},
|
||||
FunctionInfo{3, D<&ILockAccessor::GetEvent>, "GetEvent"},
|
||||
FunctionInfo{4, D<&ILockAccessor::IsLocked>, "IsLocked"}
|
||||
);
|
||||
KernelHelpers::ServiceContext m_context;
|
||||
Event m_event;
|
||||
std::mutex m_mutex{};
|
||||
bool m_is_locked{};
|
||||
};
|
||||
|
||||
ICommonStateGetter::ICommonStateGetter(Core::System& system_, std::shared_ptr<Applet> applet)
|
||||
: ServiceFramework{system_, "ICommonStateGetter"}, m_applet{std::move(applet)} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, D<&ICommonStateGetter::GetEventHandle>, "GetEventHandle"},
|
||||
{1, D<&ICommonStateGetter::ReceiveMessage>, "ReceiveMessage"},
|
||||
{2, nullptr, "GetThisAppletKind"},
|
||||
{3, nullptr, "AllowToEnterSleep"},
|
||||
{4, nullptr, "DisallowToEnterSleep"},
|
||||
{5, D<&ICommonStateGetter::GetOperationMode>, "GetOperationMode"},
|
||||
{6, D<&ICommonStateGetter::GetPerformanceMode>, "GetPerformanceMode"},
|
||||
{7, nullptr, "GetCradleStatus"},
|
||||
{8, D<&ICommonStateGetter::GetBootMode>, "GetBootMode"},
|
||||
{9, D<&ICommonStateGetter::GetCurrentFocusState>, "GetCurrentFocusState"},
|
||||
{10, D<&ICommonStateGetter::RequestToAcquireSleepLock>, "RequestToAcquireSleepLock"},
|
||||
{11, D<&ICommonStateGetter::ReleaseSleepLock>, "ReleaseSleepLock"},
|
||||
{12, D<&ICommonStateGetter::ReleaseSleepLockTransiently>, "ReleaseSleepLockTransiently"},
|
||||
{13, D<&ICommonStateGetter::GetAcquiredSleepLockEvent>, "GetAcquiredSleepLockEvent"},
|
||||
{14, nullptr, "GetWakeupCount"}, //11.0.0+
|
||||
{15, nullptr, "Unknown15"}, //19.0.0+
|
||||
{20, D<&ICommonStateGetter::PushToGeneralChannel>, "PushToGeneralChannel"},
|
||||
{30, D<&ICommonStateGetter::GetHomeButtonReaderLockAccessor>, "GetHomeButtonReaderLockAccessor"},
|
||||
{31, D<&ICommonStateGetter::GetReaderLockAccessorEx>, "GetReaderLockAccessorEx"}, //2.0.0+
|
||||
{32, D<&ICommonStateGetter::GetWriterLockAccessorEx>, "GetWriterLockAccessorEx"}, //7.0.0+
|
||||
{40, nullptr, "GetCradleFwVersion"}, //2.0.0+
|
||||
{50, D<&ICommonStateGetter::IsVrModeEnabled>, "IsVrModeEnabled"}, //3.0.0+
|
||||
{51, D<&ICommonStateGetter::SetVrModeEnabled>, "SetVrModeEnabled"}, //3.0.0+
|
||||
{52, D<&ICommonStateGetter::SetLcdBacklighOffEnabled>, "SetLcdBacklighOffEnabled"}, //4.0.0+
|
||||
{53, D<&ICommonStateGetter::BeginVrModeEx>, "BeginVrModeEx"}, //7.0.0+
|
||||
{54, D<&ICommonStateGetter::EndVrModeEx>, "EndVrModeEx"}, //7.0.0+
|
||||
{55, D<&ICommonStateGetter::IsInControllerFirmwareUpdateSection>, "IsInControllerFirmwareUpdateSection"}, //3.0.0+
|
||||
{59, nullptr, "SetVrPositionForDebug"}, //1.0.0+
|
||||
{60, D<&ICommonStateGetter::GetDefaultDisplayResolution>, "GetDefaultDisplayResolution"},
|
||||
{61, D<&ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent>, "GetDefaultDisplayResolutionChangeEvent"},
|
||||
{62, D<&ICommonStateGetter::GetHdcpAuthenticationState>, "GetHdcpAuthenticationState"},
|
||||
{63, D<&ICommonStateGetter::GetHdcpAuthenticationStateChangeEvent>, "GetHdcpAuthenticationStateChangeEvent"},
|
||||
{64, nullptr, "SetTvPowerStateMatchingMode"},
|
||||
{65, nullptr, "GetApplicationIdByContentActionName"},
|
||||
{66, &ICommonStateGetter::SetCpuBoostMode, "SetCpuBoostMode"},
|
||||
{67, nullptr, "CancelCpuBoostMode"},
|
||||
{68, D<&ICommonStateGetter::GetBuiltInDisplayType>, "GetBuiltInDisplayType"},
|
||||
{80, D<&ICommonStateGetter::PerformSystemButtonPressingIfInFocus>, "PerformSystemButtonPressingIfInFocus"},
|
||||
{90, nullptr, "SetPerformanceConfigurationChangedNotification"},
|
||||
{91, nullptr, "GetCurrentPerformanceConfiguration"},
|
||||
{100, D<&ICommonStateGetter::SetHandlingHomeButtonShortPressedEnabled>, "SetHandlingHomeButtonShortPressedEnabled"},
|
||||
{110, nullptr, "OpenMyGpuErrorHandler"},
|
||||
{120, D<&ICommonStateGetter::GetAppletLaunchedHistory>, "GetAppletLaunchedHistory"}, //13.0.0+
|
||||
{130, D<&ICommonStateGetter::EnableStartupLogoDisappearedMessage>, "EnableStartupLogoDisappearedMessage"}, //21.0.0+
|
||||
{200, D<&ICommonStateGetter::GetOperationModeSystemInfo>, "GetOperationModeSystemInfo"},
|
||||
{300, D<&ICommonStateGetter::GetSettingsPlatformRegion>, "GetSettingsPlatformRegion"},
|
||||
{400, nullptr, "ActivateMigrationService"},
|
||||
{401, nullptr, "DeactivateMigrationService"},
|
||||
{500, nullptr, "DisableSleepTillShutdown"},
|
||||
{501, nullptr, "SuppressDisablingSleepTemporarily"},
|
||||
{502, nullptr, "IsSleepEnabled"},
|
||||
{503, nullptr, "IsDisablingSleepSuppressed"},
|
||||
{600, nullptr, "SetHidInputMagnificationForApplication"}, //20.0.0+
|
||||
{610, D<&ICommonStateGetter::Unknown610>, "Unknown610"}, //21.0.0+
|
||||
{611, D<&ICommonStateGetter::Unknown611>, "Unknown611"}, //22.0.0+
|
||||
{900, D<&ICommonStateGetter::SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled>, "SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled"}, //11.0.0+
|
||||
{910, nullptr, "GetLaunchRequiredTick"}, //17.0.0+
|
||||
{1000, D<&ICommonStateGetter::BeginVrMode3d>, "BeginVrMode3d"}, //19.0.0+
|
||||
{1001, D<&ICommonStateGetter::EndVrMode3d>, "EndVrMode3d"}, //19.0.0+
|
||||
{1002, D<&ICommonStateGetter::IsVrModeEnabled3d>, "IsVrModeEnabled3d"}, //19.0.0+
|
||||
{1003, D<&ICommonStateGetter::GetVrLaboGoggleViewport>, "GetVrLaboGoggleViewport"}, //21.0.0+
|
||||
{1004, D<&ICommonStateGetter::GetPanelPhysicalSizeForSpecificTitle>, "GetPanelPhysicalSizeForSpecificTitle"}, //21.0.0+
|
||||
{1005, D<&ICommonStateGetter::GetPanelResolutionForSpecificTitle>, "GetPanelResolutionForSpecificTitle"}, //21.0.0+
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
ICommonStateGetter::~ICommonStateGetter() = default;
|
||||
|
||||
@@ -76,6 +76,7 @@ private:
|
||||
|
||||
void SetCpuBoostMode(HLERequestContext& ctx);
|
||||
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override;
|
||||
const std::shared_ptr<Applet> m_applet;
|
||||
};
|
||||
|
||||
|
||||
@@ -9,22 +9,21 @@
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> ICradleFirmwareUpdater::FindRequest(u32 key) {
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, D<&ICradleFirmwareUpdater::StartUpdate>, "StartUpdate"},
|
||||
FunctionInfo{1, D<&ICradleFirmwareUpdater::FinishUpdate>, "FinishUpdate"},
|
||||
FunctionInfo{2, D<&ICradleFirmwareUpdater::GetCradleDeviceInfo>, "GetCradleDeviceInfo"},
|
||||
FunctionInfo{3, D<&ICradleFirmwareUpdater::GetCradleDeviceInfoChangeEvent>, "GetCradleDeviceInfoChangeEvent"},
|
||||
FunctionInfo{4, nullptr, "GetUpdateProgressInfo"},
|
||||
FunctionInfo{5, nullptr, "GetLastInternalResult"}
|
||||
);
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
|
||||
ICradleFirmwareUpdater::ICradleFirmwareUpdater(Core::System& system_)
|
||||
: ServiceFramework{system_, "ICradleFirmwareUpdater"},
|
||||
m_context{system, "ICradleFirmwareUpdater"}, m_cradle_device_info_event{m_context} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, D<&ICradleFirmwareUpdater::StartUpdate>, "StartUpdate"},
|
||||
{1, D<&ICradleFirmwareUpdater::FinishUpdate>, "FinishUpdate"},
|
||||
{2, D<&ICradleFirmwareUpdater::GetCradleDeviceInfo>, "GetCradleDeviceInfo"},
|
||||
{3, D<&ICradleFirmwareUpdater::GetCradleDeviceInfoChangeEvent>, "GetCradleDeviceInfoChangeEvent"},
|
||||
{4, nullptr, "GetUpdateProgressInfo"},
|
||||
{5, nullptr, "GetLastInternalResult"},
|
||||
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
ICradleFirmwareUpdater::~ICradleFirmwareUpdater() = default;
|
||||
|
||||
@@ -33,6 +33,7 @@ private:
|
||||
Result GetCradleDeviceInfoChangeEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
|
||||
|
||||
private:
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override;
|
||||
KernelHelpers::ServiceContext m_context;
|
||||
Event m_cradle_device_info_event;
|
||||
};
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "core/hle/service/am/service/debug_functions.h"
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
IDebugFunctions::IDebugFunctions(Core::System& system_)
|
||||
: ServiceFramework{system_, "IDebugFunctions"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "NotifyMessageToHomeMenuForDebug"},
|
||||
{1, nullptr, "OpenMainApplication"},
|
||||
{10, nullptr, "PerformSystemButtonPressing"},
|
||||
{20, nullptr, "InvalidateTransitionLayer"},
|
||||
{30, nullptr, "RequestLaunchApplicationWithUserAndArgumentForDebug"},
|
||||
{31, nullptr, "RequestLaunchApplicationByApplicationLaunchInfoForDebug"},
|
||||
{40, nullptr, "GetAppletResourceUsageInfo"},
|
||||
{50, nullptr, "AddSystemProgramIdAndAppletIdForDebug"},
|
||||
{51, nullptr, "AddOperationConfirmedLibraryAppletIdForDebug"},
|
||||
{100, nullptr, "SetCpuBoostModeForApplet"},
|
||||
{101, nullptr, "CancelCpuBoostModeForApplet"},
|
||||
{110, nullptr, "PushToAppletBoundChannelForDebug"},
|
||||
{111, nullptr, "TryPopFromAppletBoundChannelForDebug"},
|
||||
{120, nullptr, "AlarmSettingNotificationEnableAppEventReserve"},
|
||||
{121, nullptr, "AlarmSettingNotificationDisableAppEventReserve"},
|
||||
{122, nullptr, "AlarmSettingNotificationPushAppEventNotify"},
|
||||
{130, nullptr, "FriendInvitationSetApplicationParameter"},
|
||||
{131, nullptr, "FriendInvitationClearApplicationParameter"},
|
||||
{132, nullptr, "FriendInvitationPushApplicationParameter"},
|
||||
{140, nullptr, "RestrictPowerOperationForSecureLaunchModeForDebug"},
|
||||
{200, nullptr, "CreateFloatingLibraryAppletAccepterForDebug"},
|
||||
{300, nullptr, "TerminateAllRunningApplicationsForDebug"},
|
||||
{900, nullptr, "GetGrcProcessLaunchedSystemEvent"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
IDebugFunctions::~IDebugFunctions() = default;
|
||||
|
||||
} // namespace Service::AM
|
||||
@@ -1,19 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
class IDebugFunctions final : public ServiceFramework<IDebugFunctions> {
|
||||
public:
|
||||
explicit IDebugFunctions(Core::System& system_);
|
||||
~IDebugFunctions() override;
|
||||
};
|
||||
|
||||
} // namespace Service::AM
|
||||
@@ -12,42 +12,42 @@
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> IDisplayController::FindRequest(u32 key) {
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, nullptr, "GetLastForegroundCaptureImage"},
|
||||
FunctionInfo{1, nullptr, "UpdateLastForegroundCaptureImage"},
|
||||
FunctionInfo{2, nullptr, "GetLastApplicationCaptureImage"},
|
||||
FunctionInfo{3, nullptr, "GetCallerAppletCaptureImage"},
|
||||
FunctionInfo{4, nullptr, "UpdateCallerAppletCaptureImage"},
|
||||
FunctionInfo{5, D<&IDisplayController::GetLastForegroundCaptureImageEx>, "GetLastForegroundCaptureImageEx"},
|
||||
FunctionInfo{6, nullptr, "GetLastApplicationCaptureImageEx"},
|
||||
FunctionInfo{7, D<&IDisplayController::GetCallerAppletCaptureImageEx>, "GetCallerAppletCaptureImageEx"},
|
||||
FunctionInfo{8, D<&IDisplayController::TakeScreenShotOfOwnLayer>, "TakeScreenShotOfOwnLayer"},
|
||||
FunctionInfo{9, nullptr, "CopyBetweenCaptureBuffers"},
|
||||
FunctionInfo{10, nullptr, "AcquireLastApplicationCaptureBuffer"},
|
||||
FunctionInfo{11, nullptr, "ReleaseLastApplicationCaptureBuffer"},
|
||||
FunctionInfo{12, nullptr, "AcquireLastForegroundCaptureBuffer"},
|
||||
FunctionInfo{13, nullptr, "ReleaseLastForegroundCaptureBuffer"},
|
||||
FunctionInfo{14, nullptr, "AcquireCallerAppletCaptureBuffer"},
|
||||
FunctionInfo{15, nullptr, "ReleaseCallerAppletCaptureBuffer"},
|
||||
FunctionInfo{16, nullptr, "AcquireLastApplicationCaptureBufferEx"},
|
||||
FunctionInfo{17, nullptr, "AcquireLastForegroundCaptureBufferEx"},
|
||||
FunctionInfo{18, nullptr, "AcquireCallerAppletCaptureBufferEx"},
|
||||
FunctionInfo{20, D<&IDisplayController::ClearCaptureBuffer>, "ClearCaptureBuffer"},
|
||||
FunctionInfo{21, nullptr, "ClearAppletTransitionBuffer"},
|
||||
FunctionInfo{22, D<&IDisplayController::AcquireLastApplicationCaptureSharedBuffer>, "AcquireLastApplicationCaptureSharedBuffer"},
|
||||
FunctionInfo{23, D<&IDisplayController::ReleaseLastApplicationCaptureSharedBuffer>, "ReleaseLastApplicationCaptureSharedBuffer"},
|
||||
FunctionInfo{24, D<&IDisplayController::AcquireLastForegroundCaptureSharedBuffer>, "AcquireLastForegroundCaptureSharedBuffer"},
|
||||
FunctionInfo{25, D<&IDisplayController::ReleaseLastForegroundCaptureSharedBuffer>, "ReleaseLastForegroundCaptureSharedBuffer"},
|
||||
FunctionInfo{26, D<&IDisplayController::AcquireCallerAppletCaptureSharedBuffer>, "AcquireCallerAppletCaptureSharedBuffer"},
|
||||
FunctionInfo{27, D<&IDisplayController::ReleaseCallerAppletCaptureSharedBuffer>, "ReleaseCallerAppletCaptureSharedBuffer"},
|
||||
FunctionInfo{28, nullptr, "TakeScreenShotOfOwnLayerEx"}
|
||||
);
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
|
||||
IDisplayController::IDisplayController(Core::System& system_, std::shared_ptr<Applet> applet_)
|
||||
: ServiceFramework{system_, "IDisplayController"}, applet(std::move(applet_)) {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetLastForegroundCaptureImage"},
|
||||
{1, nullptr, "UpdateLastForegroundCaptureImage"},
|
||||
{2, nullptr, "GetLastApplicationCaptureImage"},
|
||||
{3, nullptr, "GetCallerAppletCaptureImage"},
|
||||
{4, nullptr, "UpdateCallerAppletCaptureImage"},
|
||||
{5, D<&IDisplayController::GetLastForegroundCaptureImageEx>, "GetLastForegroundCaptureImageEx"},
|
||||
{6, nullptr, "GetLastApplicationCaptureImageEx"},
|
||||
{7, D<&IDisplayController::GetCallerAppletCaptureImageEx>, "GetCallerAppletCaptureImageEx"},
|
||||
{8, D<&IDisplayController::TakeScreenShotOfOwnLayer>, "TakeScreenShotOfOwnLayer"},
|
||||
{9, nullptr, "CopyBetweenCaptureBuffers"},
|
||||
{10, nullptr, "AcquireLastApplicationCaptureBuffer"},
|
||||
{11, nullptr, "ReleaseLastApplicationCaptureBuffer"},
|
||||
{12, nullptr, "AcquireLastForegroundCaptureBuffer"},
|
||||
{13, nullptr, "ReleaseLastForegroundCaptureBuffer"},
|
||||
{14, nullptr, "AcquireCallerAppletCaptureBuffer"},
|
||||
{15, nullptr, "ReleaseCallerAppletCaptureBuffer"},
|
||||
{16, nullptr, "AcquireLastApplicationCaptureBufferEx"},
|
||||
{17, nullptr, "AcquireLastForegroundCaptureBufferEx"},
|
||||
{18, nullptr, "AcquireCallerAppletCaptureBufferEx"},
|
||||
{20, D<&IDisplayController::ClearCaptureBuffer>, "ClearCaptureBuffer"},
|
||||
{21, nullptr, "ClearAppletTransitionBuffer"},
|
||||
{22, D<&IDisplayController::AcquireLastApplicationCaptureSharedBuffer>, "AcquireLastApplicationCaptureSharedBuffer"},
|
||||
{23, D<&IDisplayController::ReleaseLastApplicationCaptureSharedBuffer>, "ReleaseLastApplicationCaptureSharedBuffer"},
|
||||
{24, D<&IDisplayController::AcquireLastForegroundCaptureSharedBuffer>, "AcquireLastForegroundCaptureSharedBuffer"},
|
||||
{25, D<&IDisplayController::ReleaseLastForegroundCaptureSharedBuffer>, "ReleaseLastForegroundCaptureSharedBuffer"},
|
||||
{26, D<&IDisplayController::AcquireCallerAppletCaptureSharedBuffer>, "AcquireCallerAppletCaptureSharedBuffer"},
|
||||
{27, D<&IDisplayController::ReleaseCallerAppletCaptureSharedBuffer>, "ReleaseCallerAppletCaptureSharedBuffer"},
|
||||
{28, nullptr, "TakeScreenShotOfOwnLayerEx"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
IDisplayController::~IDisplayController() = default;
|
||||
|
||||
@@ -35,6 +35,7 @@ private:
|
||||
Out<s32> out_fbshare_layer_index);
|
||||
Result ReleaseLastApplicationCaptureSharedBuffer();
|
||||
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override;
|
||||
const std::shared_ptr<Applet> applet;
|
||||
};
|
||||
|
||||
|
||||
@@ -10,28 +10,28 @@
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> IGlobalStateController::FindRequest(u32 key) {
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, nullptr, "RequestToEnterSleep"},
|
||||
FunctionInfo{1, nullptr, "EnterSleep"},
|
||||
FunctionInfo{2, nullptr, "StartSleepSequence"},
|
||||
FunctionInfo{3, D<&IGlobalStateController::StartShutdownSequence>, "StartShutdownSequence"},
|
||||
FunctionInfo{4, D<&IGlobalStateController::StartRebootSequence>, "StartRebootSequence"},
|
||||
FunctionInfo{9, nullptr, "IsAutoPowerDownRequested"},
|
||||
FunctionInfo{10, D<&IGlobalStateController::LoadAndApplyIdlePolicySettings>, "LoadAndApplyIdlePolicySettings"},
|
||||
FunctionInfo{11, nullptr, "NotifyCecSettingsChanged"},
|
||||
FunctionInfo{12, nullptr, "SetDefaultHomeButtonLongPressTime"},
|
||||
FunctionInfo{13, nullptr, "UpdateDefaultDisplayResolution"},
|
||||
FunctionInfo{14, D<&IGlobalStateController::ShouldSleepOnBoot>, "ShouldSleepOnBoot"},
|
||||
FunctionInfo{15, D<&IGlobalStateController::GetHdcpAuthenticationFailedEvent>, "GetHdcpAuthenticationFailedEvent"},
|
||||
FunctionInfo{30, D<&IGlobalStateController::OpenCradleFirmwareUpdater>, "OpenCradleFirmwareUpdater"}
|
||||
);
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
|
||||
IGlobalStateController::IGlobalStateController(Core::System& system_)
|
||||
: ServiceFramework{system_, "IGlobalStateController"},
|
||||
m_context{system_, "IGlobalStateController"}, m_hdcp_authentication_failed_event{m_context} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "RequestToEnterSleep"},
|
||||
{1, nullptr, "EnterSleep"},
|
||||
{2, nullptr, "StartSleepSequence"},
|
||||
{3, D<&IGlobalStateController::StartShutdownSequence>, "StartShutdownSequence"},
|
||||
{4, D<&IGlobalStateController::StartRebootSequence>, "StartRebootSequence"},
|
||||
{9, nullptr, "IsAutoPowerDownRequested"},
|
||||
{10, D<&IGlobalStateController::LoadAndApplyIdlePolicySettings>, "LoadAndApplyIdlePolicySettings"},
|
||||
{11, nullptr, "NotifyCecSettingsChanged"},
|
||||
{12, nullptr, "SetDefaultHomeButtonLongPressTime"},
|
||||
{13, nullptr, "UpdateDefaultDisplayResolution"},
|
||||
{14, D<&IGlobalStateController::ShouldSleepOnBoot>, "ShouldSleepOnBoot"},
|
||||
{15, D<&IGlobalStateController::GetHdcpAuthenticationFailedEvent>, "GetHdcpAuthenticationFailedEvent"},
|
||||
{30, D<&IGlobalStateController::OpenCradleFirmwareUpdater>, "OpenCradleFirmwareUpdater"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
Result IGlobalStateController::StartShutdownSequence() {
|
||||
|
||||
@@ -26,9 +26,9 @@ private:
|
||||
Result LoadAndApplyIdlePolicySettings();
|
||||
Result ShouldSleepOnBoot(Out<bool> out_should_sleep_on_boot);
|
||||
Result GetHdcpAuthenticationFailedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
|
||||
Result OpenCradleFirmwareUpdater(
|
||||
Out<SharedPointer<ICradleFirmwareUpdater>> out_cradle_firmware_updater);
|
||||
Result OpenCradleFirmwareUpdater(Out<SharedPointer<ICradleFirmwareUpdater>> out_cradle_firmware_updater);
|
||||
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override;
|
||||
KernelHelpers::ServiceContext m_context;
|
||||
Event m_hdcp_authentication_failed_event;
|
||||
};
|
||||
|
||||
@@ -14,31 +14,31 @@
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> IHomeMenuFunctions::FindRequest(u32 key) {
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{10, D<&IHomeMenuFunctions::RequestToGetForeground>, "RequestToGetForeground"},
|
||||
FunctionInfo{11, D<&IHomeMenuFunctions::LockForeground>, "LockForeground"},
|
||||
FunctionInfo{12, D<&IHomeMenuFunctions::UnlockForeground>, "UnlockForeground"},
|
||||
FunctionInfo{20, D<&IHomeMenuFunctions::PopFromGeneralChannel>, "PopFromGeneralChannel"},
|
||||
FunctionInfo{21, D<&IHomeMenuFunctions::GetPopFromGeneralChannelEvent>, "GetPopFromGeneralChannelEvent"},
|
||||
FunctionInfo{30, nullptr, "GetHomeButtonWriterLockAccessor"},
|
||||
FunctionInfo{31, nullptr, "GetWriterLockAccessorEx"},
|
||||
FunctionInfo{40, D<&IHomeMenuFunctions::IsSleepEnabled>, "IsSleepEnabled"},
|
||||
FunctionInfo{41, D<&IHomeMenuFunctions::IsRebootEnabled>, "IsRebootEnabled"},
|
||||
FunctionInfo{50, nullptr, "LaunchSystemApplet"},
|
||||
FunctionInfo{51, nullptr, "LaunchStarter"},
|
||||
FunctionInfo{100, nullptr, "PopRequestLaunchApplicationForDebug"},
|
||||
FunctionInfo{110, D<&IHomeMenuFunctions::IsForceTerminateApplicationDisabledForDebug>, "IsForceTerminateApplicationDisabledForDebug"},
|
||||
FunctionInfo{200, nullptr, "LaunchDevMenu"},
|
||||
FunctionInfo{1000, nullptr, "SetLastApplicationExitReason"}
|
||||
);
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
|
||||
IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_, std::shared_ptr<Applet> applet,
|
||||
WindowSystem& window_system)
|
||||
: ServiceFramework{system_, "IHomeMenuFunctions"}, m_window_system{window_system},
|
||||
m_applet{std::move(applet)}, m_context{system, "IHomeMenuFunctions"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{10, D<&IHomeMenuFunctions::RequestToGetForeground>, "RequestToGetForeground"},
|
||||
{11, D<&IHomeMenuFunctions::LockForeground>, "LockForeground"},
|
||||
{12, D<&IHomeMenuFunctions::UnlockForeground>, "UnlockForeground"},
|
||||
{20, D<&IHomeMenuFunctions::PopFromGeneralChannel>, "PopFromGeneralChannel"},
|
||||
{21, D<&IHomeMenuFunctions::GetPopFromGeneralChannelEvent>, "GetPopFromGeneralChannelEvent"},
|
||||
{30, nullptr, "GetHomeButtonWriterLockAccessor"},
|
||||
{31, nullptr, "GetWriterLockAccessorEx"},
|
||||
{40, D<&IHomeMenuFunctions::IsSleepEnabled>, "IsSleepEnabled"},
|
||||
{41, D<&IHomeMenuFunctions::IsRebootEnabled>, "IsRebootEnabled"},
|
||||
{50, nullptr, "LaunchSystemApplet"},
|
||||
{51, nullptr, "LaunchStarter"},
|
||||
{100, nullptr, "PopRequestLaunchApplicationForDebug"},
|
||||
{110, D<&IHomeMenuFunctions::IsForceTerminateApplicationDisabledForDebug>, "IsForceTerminateApplicationDisabledForDebug"},
|
||||
{200, nullptr, "LaunchDevMenu"},
|
||||
{1000, nullptr, "SetLastApplicationExitReason"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
IHomeMenuFunctions::~IHomeMenuFunctions() = default;
|
||||
|
||||
@@ -34,6 +34,7 @@ private:
|
||||
Result IsForceTerminateApplicationDisabledForDebug(
|
||||
Out<bool> out_is_force_terminate_application_disabled_for_debug);
|
||||
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override;
|
||||
WindowSystem& m_window_system;
|
||||
const std::shared_ptr<Applet> m_applet;
|
||||
KernelHelpers::ServiceContext m_context;
|
||||
|
||||
@@ -17,9 +17,7 @@
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
namespace {
|
||||
|
||||
void EnableSingleUserPlay(const std::shared_ptr<LibraryAppletStorage>& impl) {
|
||||
static void EnableSingleUserPlay(const std::shared_ptr<LibraryAppletStorage>& impl) {
|
||||
constexpr s64 DisplayOptionsOffset = 0x90;
|
||||
constexpr s64 IsSkipEnabledOffset = 1;
|
||||
constexpr s64 ShowSkipButtonOffset = 4;
|
||||
@@ -29,7 +27,7 @@ void EnableSingleUserPlay(const std::shared_ptr<LibraryAppletStorage>& impl) {
|
||||
impl->Write(DisplayOptionsOffset + ShowSkipButtonOffset, &enabled, sizeof(enabled));
|
||||
}
|
||||
|
||||
void ReplaceEmptyUuidWithCurrentUser(const std::shared_ptr<LibraryAppletStorage>& impl) {
|
||||
static void ReplaceEmptyUuidWithCurrentUser(const std::shared_ptr<LibraryAppletStorage>& impl) {
|
||||
Frontend::UiReturnArg return_arg{};
|
||||
impl->Read(0, &return_arg, sizeof(return_arg));
|
||||
|
||||
@@ -47,42 +45,40 @@ void ReplaceEmptyUuidWithCurrentUser(const std::shared_ptr<LibraryAppletStorage>
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> ILibraryAppletAccessor::FindRequest(u32 key) {
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, D<&ILibraryAppletAccessor::GetAppletStateChangedEvent>, "GetAppletStateChangedEvent"},
|
||||
FunctionInfo{1, D<&ILibraryAppletAccessor::IsCompleted>, "IsCompleted"},
|
||||
FunctionInfo{10, D<&ILibraryAppletAccessor::Start>, "Start"},
|
||||
FunctionInfo{20, D<&ILibraryAppletAccessor::RequestExit>, "RequestExit"},
|
||||
FunctionInfo{25, D<&ILibraryAppletAccessor::Terminate>, "Terminate"},
|
||||
FunctionInfo{30, D<&ILibraryAppletAccessor::GetResult>, "GetResult"},
|
||||
FunctionInfo{50, nullptr, "SetOutOfFocusApplicationSuspendingEnabled"},
|
||||
FunctionInfo{60, D<&ILibraryAppletAccessor::PresetLibraryAppletGpuTimeSliceZero>, "PresetLibraryAppletGpuTimeSliceZero", MakeVersionGate({10,0,0})},
|
||||
FunctionInfo{80, nullptr, "RequestForLibraryAppletToGetForeground", MakeVersionGate({19,0,0})},
|
||||
FunctionInfo{81, nullptr, "GetCurrentChildLibraryApplet", MakeVersionGate({19,0,0})},
|
||||
FunctionInfo{90, D<&ILibraryAppletAccessor::Unknown90>, "Unknown90", MakeVersionGate({20,0,0})},
|
||||
FunctionInfo{100, D<&ILibraryAppletAccessor::PushInData>, "PushInData"},
|
||||
FunctionInfo{101, D<&ILibraryAppletAccessor::PopOutData>, "PopOutData"},
|
||||
FunctionInfo{102, nullptr, "PushExtraStorage"},
|
||||
FunctionInfo{103, D<&ILibraryAppletAccessor::PushInteractiveInData>, "PushInteractiveInData"},
|
||||
FunctionInfo{104, D<&ILibraryAppletAccessor::PopInteractiveOutData>, "PopInteractiveOutData"},
|
||||
FunctionInfo{105, D<&ILibraryAppletAccessor::GetPopOutDataEvent>, "GetPopOutDataEvent"},
|
||||
FunctionInfo{106, D<&ILibraryAppletAccessor::GetPopInteractiveOutDataEvent>, "GetPopInteractiveOutDataEvent"},
|
||||
FunctionInfo{110, nullptr, "NeedsToExitProcess"},
|
||||
FunctionInfo{120, D<&ILibraryAppletAccessor::GetLibraryAppletInfo>, "GetLibraryAppletInfo"},
|
||||
FunctionInfo{150, nullptr, "RequestForAppletToGetForeground"},
|
||||
FunctionInfo{160, D<&ILibraryAppletAccessor::GetIndirectLayerConsumerHandle>, "GetIndirectLayerConsumerHandle", MakeVersionGate({2,0,0})},
|
||||
FunctionInfo{170, D<&ILibraryAppletAccessor::Unknown170>, "Unknown170", MakeVersionGate({22,0,0})}
|
||||
);
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
|
||||
ILibraryAppletAccessor::ILibraryAppletAccessor(Core::System& system_,
|
||||
std::shared_ptr<AppletDataBroker> broker,
|
||||
std::shared_ptr<Applet> applet)
|
||||
: ServiceFramework{system_, "ILibraryAppletAccessor"}, m_broker{std::move(broker)},
|
||||
m_applet{std::move(applet)} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, D<&ILibraryAppletAccessor::GetAppletStateChangedEvent>, "GetAppletStateChangedEvent"},
|
||||
{1, D<&ILibraryAppletAccessor::IsCompleted>, "IsCompleted"},
|
||||
{10, D<&ILibraryAppletAccessor::Start>, "Start"},
|
||||
{20, D<&ILibraryAppletAccessor::RequestExit>, "RequestExit"},
|
||||
{25, D<&ILibraryAppletAccessor::Terminate>, "Terminate"},
|
||||
{30, D<&ILibraryAppletAccessor::GetResult>, "GetResult"},
|
||||
{50, nullptr, "SetOutOfFocusApplicationSuspendingEnabled"},
|
||||
{60, D<&ILibraryAppletAccessor::PresetLibraryAppletGpuTimeSliceZero>, "PresetLibraryAppletGpuTimeSliceZero"}, //10.0.0+
|
||||
{80, nullptr, "RequestForLibraryAppletToGetForeground"}, //19.0.0+
|
||||
{81, nullptr, "GetCurrentChildLibraryApplet"}, //19.0.0+
|
||||
{90, D<&ILibraryAppletAccessor::Unknown90>, "Unknown90"}, //20.0.0+
|
||||
{100, D<&ILibraryAppletAccessor::PushInData>, "PushInData"},
|
||||
{101, D<&ILibraryAppletAccessor::PopOutData>, "PopOutData"},
|
||||
{102, nullptr, "PushExtraStorage"},
|
||||
{103, D<&ILibraryAppletAccessor::PushInteractiveInData>, "PushInteractiveInData"},
|
||||
{104, D<&ILibraryAppletAccessor::PopInteractiveOutData>, "PopInteractiveOutData"},
|
||||
{105, D<&ILibraryAppletAccessor::GetPopOutDataEvent>, "GetPopOutDataEvent"},
|
||||
{106, D<&ILibraryAppletAccessor::GetPopInteractiveOutDataEvent>, "GetPopInteractiveOutDataEvent"},
|
||||
{110, nullptr, "NeedsToExitProcess"},
|
||||
{120, D<&ILibraryAppletAccessor::GetLibraryAppletInfo>, "GetLibraryAppletInfo"},
|
||||
{150, nullptr, "RequestForAppletToGetForeground"},
|
||||
{160, D<&ILibraryAppletAccessor::GetIndirectLayerConsumerHandle>, "GetIndirectLayerConsumerHandle"}, //2.0.0+
|
||||
{170, D<&ILibraryAppletAccessor::Unknown170>, "Unknown170"}, //22.0.0+
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
ILibraryAppletAccessor::~ILibraryAppletAccessor() = default;
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/am/service/library_applet_self_accessor.h"
|
||||
#include "core/hle/service/cmif_types.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
@@ -16,6 +15,26 @@ class AppletDataBroker;
|
||||
struct Applet;
|
||||
class IStorage;
|
||||
|
||||
struct LibraryAppletInfo {
|
||||
AppletId applet_id;
|
||||
LibraryAppletMode library_applet_mode;
|
||||
};
|
||||
static_assert(sizeof(LibraryAppletInfo) == 0x8, "LibraryAppletInfo has incorrect size.");
|
||||
|
||||
struct ErrorCode {
|
||||
u32 category;
|
||||
u32 number;
|
||||
};
|
||||
static_assert(sizeof(ErrorCode) == 0x8, "ErrorCode has incorrect size.");
|
||||
|
||||
struct ErrorContext {
|
||||
u8 type;
|
||||
INSERT_PADDING_BYTES_NOINIT(0x7);
|
||||
std::array<u8, 0x1f4> data;
|
||||
Result result;
|
||||
};
|
||||
static_assert(sizeof(ErrorContext) == 0x200, "ErrorContext has incorrect size.");
|
||||
|
||||
class ILibraryAppletAccessor final : public ServiceFramework<ILibraryAppletAccessor> {
|
||||
public:
|
||||
explicit ILibraryAppletAccessor(Core::System& system_, std::shared_ptr<AppletDataBroker> broker,
|
||||
@@ -49,6 +68,7 @@ private:
|
||||
void FrontendExecuteInteractive();
|
||||
void FrontendRequestExit();
|
||||
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override;
|
||||
const std::shared_ptr<AppletDataBroker> m_broker;
|
||||
const std::shared_ptr<Applet> m_applet;
|
||||
};
|
||||
|
||||
@@ -1,287 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "common/settings.h"
|
||||
#include "core/hle/kernel/k_transfer_memory.h"
|
||||
#include "core/hle/service/am/applet_data_broker.h"
|
||||
#include "core/hle/service/am/applet_manager.h"
|
||||
#include "core/hle/service/am/frontend/applets.h"
|
||||
#include "core/hle/service/am/library_applet_storage.h"
|
||||
#include "core/hle/service/am/process_creation.h"
|
||||
#include "core/hle/service/am/service/library_applet_accessor.h"
|
||||
#include "core/hle/service/am/service/library_applet_creator.h"
|
||||
|
||||
#include "core/hle/api_version.h"
|
||||
#include "core/hle/service/am/service/storage.h"
|
||||
#include "core/hle/service/am/window_system.h"
|
||||
#include "core/hle/service/cmif_serialization.h"
|
||||
#include "core/hle/service/sm/sm.h"
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
namespace {
|
||||
|
||||
bool ShouldCreateGuestApplet(AppletId applet_id) {
|
||||
#define X(Name, name) \
|
||||
if (applet_id == AppletId::Name && \
|
||||
Settings::values.name##_applet_mode.GetValue() != Settings::AppletMode::LLE) { \
|
||||
return false; \
|
||||
}
|
||||
|
||||
X(Cabinet, cabinet)
|
||||
X(Controller, controller)
|
||||
X(DataErase, data_erase)
|
||||
X(Error, error)
|
||||
X(NetConnect, net_connect)
|
||||
X(ProfileSelect, player_select)
|
||||
X(SoftwareKeyboard, swkbd)
|
||||
X(MiiEdit, mii_edit)
|
||||
X(Web, web)
|
||||
X(Shop, shop)
|
||||
X(PhotoViewer, photo_viewer)
|
||||
X(OfflineWeb, offline_web)
|
||||
X(LoginShare, login_share)
|
||||
X(WebAuth, wifi_web_auth)
|
||||
X(MyPage, my_page)
|
||||
|
||||
#undef X
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
AppletProgramId AppletIdToProgramId(AppletId applet_id) {
|
||||
switch (applet_id) {
|
||||
case AppletId::OverlayDisplay:
|
||||
return AppletProgramId::OverlayDisplay;
|
||||
case AppletId::QLaunch:
|
||||
return AppletProgramId::QLaunch;
|
||||
case AppletId::Starter:
|
||||
return AppletProgramId::Starter;
|
||||
case AppletId::Auth:
|
||||
return AppletProgramId::Auth;
|
||||
case AppletId::Cabinet:
|
||||
return AppletProgramId::Cabinet;
|
||||
case AppletId::Controller:
|
||||
return AppletProgramId::Controller;
|
||||
case AppletId::DataErase:
|
||||
return AppletProgramId::DataErase;
|
||||
case AppletId::Error:
|
||||
return AppletProgramId::Error;
|
||||
case AppletId::NetConnect:
|
||||
return AppletProgramId::NetConnect;
|
||||
case AppletId::ProfileSelect:
|
||||
return AppletProgramId::ProfileSelect;
|
||||
case AppletId::SoftwareKeyboard:
|
||||
return AppletProgramId::SoftwareKeyboard;
|
||||
case AppletId::MiiEdit:
|
||||
return AppletProgramId::MiiEdit;
|
||||
case AppletId::Web:
|
||||
return AppletProgramId::Web;
|
||||
case AppletId::Shop:
|
||||
return AppletProgramId::Shop;
|
||||
case AppletId::PhotoViewer:
|
||||
return AppletProgramId::PhotoViewer;
|
||||
case AppletId::Settings:
|
||||
return AppletProgramId::Settings;
|
||||
case AppletId::OfflineWeb:
|
||||
return AppletProgramId::OfflineWeb;
|
||||
case AppletId::LoginShare:
|
||||
return AppletProgramId::LoginShare;
|
||||
case AppletId::WebAuth:
|
||||
return AppletProgramId::WebAuth;
|
||||
case AppletId::MyPage:
|
||||
return AppletProgramId::MyPage;
|
||||
default:
|
||||
return static_cast<AppletProgramId>(0);
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system,
|
||||
WindowSystem& window_system,
|
||||
std::shared_ptr<Applet> caller_applet,
|
||||
AppletId applet_id,
|
||||
LibraryAppletMode mode) {
|
||||
const auto program_id = static_cast<u64>(AppletIdToProgramId(applet_id));
|
||||
if (program_id == 0) {
|
||||
// Unknown applet
|
||||
return {};
|
||||
}
|
||||
|
||||
auto process = CreateProcess(system, program_id, 1, HLE::ApiVersion::HOS_VERSION_MAJOR);
|
||||
if (process) {
|
||||
const auto applet = std::make_shared<Applet>(system, std::move(process), false);
|
||||
applet->program_id = program_id;
|
||||
applet->applet_id = applet_id;
|
||||
applet->type = AppletType::LibraryApplet;
|
||||
applet->library_applet_mode = mode;
|
||||
applet->window_visible = mode != LibraryAppletMode::AllForegroundInitiallyHidden;
|
||||
|
||||
auto broker = std::make_shared<AppletDataBroker>(system);
|
||||
applet->caller_applet = caller_applet;
|
||||
applet->caller_applet_broker = broker;
|
||||
{
|
||||
std::scoped_lock lk{caller_applet->lock};
|
||||
caller_applet->child_applets.push_back(applet);
|
||||
}
|
||||
window_system.TrackApplet(applet, false);
|
||||
return std::make_shared<ILibraryAppletAccessor>(system, broker, applet);
|
||||
}
|
||||
// Couldn't initialize the guest process
|
||||
return {};
|
||||
}
|
||||
|
||||
std::shared_ptr<ILibraryAppletAccessor> CreateFrontendApplet(Core::System& system,
|
||||
WindowSystem& window_system,
|
||||
std::shared_ptr<Applet> caller_applet,
|
||||
AppletId applet_id,
|
||||
LibraryAppletMode mode) {
|
||||
const auto program_id = static_cast<u64>(AppletIdToProgramId(applet_id));
|
||||
|
||||
auto process = std::make_unique<Process>(system);
|
||||
auto applet = std::make_shared<Applet>(system, std::move(process), false);
|
||||
applet->program_id = program_id;
|
||||
applet->applet_id = applet_id;
|
||||
applet->type = AppletType::LibraryApplet;
|
||||
applet->library_applet_mode = mode;
|
||||
|
||||
auto storage = std::make_shared<AppletDataBroker>(system);
|
||||
applet->caller_applet = caller_applet;
|
||||
applet->caller_applet_broker = storage;
|
||||
applet->frontend = system.GetFrontendAppletHolder().GetApplet(applet, applet_id, mode);
|
||||
{
|
||||
std::scoped_lock lk{caller_applet->lock};
|
||||
caller_applet->child_applets.push_back(applet);
|
||||
}
|
||||
return std::make_shared<ILibraryAppletAccessor>(system, storage, applet);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ILibraryAppletCreator::ILibraryAppletCreator(Core::System& system_, std::shared_ptr<Applet> applet,
|
||||
WindowSystem& window_system)
|
||||
: ServiceFramework{system_, "ILibraryAppletCreator"},
|
||||
m_window_system{window_system}, m_applet{std::move(applet)} {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, D<&ILibraryAppletCreator::CreateLibraryApplet>, "CreateLibraryApplet"},
|
||||
{1, nullptr, "TerminateAllLibraryApplets"},
|
||||
{2, nullptr, "AreAnyLibraryAppletsLeft"},
|
||||
{3, D<&ILibraryAppletCreator::CreateLibraryAppletEx>, "CreateLibraryAppletEx"},
|
||||
{10, D<&ILibraryAppletCreator::CreateStorage>, "CreateStorage"},
|
||||
{11, D<&ILibraryAppletCreator::CreateTransferMemoryStorage>, "CreateTransferMemoryStorage"},
|
||||
{12, D<&ILibraryAppletCreator::CreateHandleStorage>, "CreateHandleStorage"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
ILibraryAppletCreator::~ILibraryAppletCreator() = default;
|
||||
|
||||
Result ILibraryAppletCreator::CreateLibraryApplet(
|
||||
Out<SharedPointer<ILibraryAppletAccessor>> out_library_applet_accessor, AppletId applet_id,
|
||||
LibraryAppletMode library_applet_mode) {
|
||||
LOG_DEBUG(Service_AM, "called with applet_id={} applet_mode={}", applet_id,
|
||||
library_applet_mode);
|
||||
|
||||
std::shared_ptr<ILibraryAppletAccessor> library_applet;
|
||||
if (ShouldCreateGuestApplet(applet_id)) {
|
||||
library_applet =
|
||||
CreateGuestApplet(system, m_window_system, m_applet, applet_id, library_applet_mode);
|
||||
}
|
||||
if (!library_applet) {
|
||||
library_applet =
|
||||
CreateFrontendApplet(system, m_window_system, m_applet, applet_id, library_applet_mode);
|
||||
}
|
||||
if (!library_applet) {
|
||||
LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", applet_id);
|
||||
R_THROW(ResultUnknown);
|
||||
}
|
||||
|
||||
// Applet is created, can now be launched.
|
||||
m_applet->library_applet_launchable_event.Signal(system.Kernel());
|
||||
*out_library_applet_accessor = library_applet;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILibraryAppletCreator::CreateLibraryAppletEx(
|
||||
Out<SharedPointer<ILibraryAppletAccessor>> out_library_applet_accessor, AppletId applet_id,
|
||||
LibraryAppletMode library_applet_mode, u64 thread_id) {
|
||||
LOG_DEBUG(Service_AM, "called with applet_id={} applet_mode={} thread_id={}", applet_id,
|
||||
library_applet_mode, thread_id);
|
||||
|
||||
std::shared_ptr<ILibraryAppletAccessor> library_applet;
|
||||
if (ShouldCreateGuestApplet(applet_id)) {
|
||||
library_applet =
|
||||
CreateGuestApplet(system, m_window_system, m_applet, applet_id, library_applet_mode);
|
||||
}
|
||||
if (!library_applet) {
|
||||
library_applet =
|
||||
CreateFrontendApplet(system, m_window_system, m_applet, applet_id, library_applet_mode);
|
||||
}
|
||||
if (!library_applet) {
|
||||
LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", applet_id);
|
||||
R_THROW(ResultUnknown);
|
||||
}
|
||||
|
||||
// Applet is created, can now be launched.
|
||||
m_applet->library_applet_launchable_event.Signal(system.Kernel());
|
||||
*out_library_applet_accessor = library_applet;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILibraryAppletCreator::CreateStorage(Out<SharedPointer<IStorage>> out_storage, s64 size) {
|
||||
LOG_DEBUG(Service_AM, "called, size={}", size);
|
||||
|
||||
if (size <= 0) {
|
||||
LOG_ERROR(Service_AM, "size is less than or equal to 0");
|
||||
R_THROW(ResultUnknown);
|
||||
}
|
||||
|
||||
*out_storage = std::make_shared<IStorage>(system, AM::CreateStorage(std::vector<u8>(size)));
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILibraryAppletCreator::CreateTransferMemoryStorage(
|
||||
Out<SharedPointer<IStorage>> out_storage, bool is_writable, s64 size,
|
||||
InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle) {
|
||||
LOG_DEBUG(Service_AM, "called, is_writable={} size={}", is_writable, size);
|
||||
|
||||
if (size <= 0) {
|
||||
LOG_ERROR(Service_AM, "size is less than or equal to 0");
|
||||
R_THROW(ResultUnknown);
|
||||
}
|
||||
|
||||
if (!transfer_memory_handle) {
|
||||
LOG_ERROR(Service_AM, "transfer_memory_handle is null");
|
||||
R_THROW(ResultUnknown);
|
||||
}
|
||||
|
||||
*out_storage = std::make_shared<IStorage>(
|
||||
system, AM::CreateTransferMemoryStorage(system.Kernel(), transfer_memory_handle->GetOwner()->GetMemory(),
|
||||
transfer_memory_handle.Get(), is_writable, size));
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILibraryAppletCreator::CreateHandleStorage(
|
||||
Out<SharedPointer<IStorage>> out_storage, s64 size,
|
||||
InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle) {
|
||||
LOG_DEBUG(Service_AM, "called, size={}", size);
|
||||
|
||||
if (size <= 0) {
|
||||
LOG_ERROR(Service_AM, "size is less than or equal to 0");
|
||||
R_THROW(ResultUnknown);
|
||||
}
|
||||
|
||||
if (!transfer_memory_handle) {
|
||||
LOG_ERROR(Service_AM, "transfer_memory_handle is null");
|
||||
R_THROW(ResultUnknown);
|
||||
}
|
||||
|
||||
*out_storage = std::make_shared<IStorage>(
|
||||
system, AM::CreateHandleStorage(system.Kernel(), transfer_memory_handle->GetOwner()->GetMemory(),
|
||||
transfer_memory_handle.Get(), size));
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
} // namespace Service::AM
|
||||
@@ -1,44 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/am/am_types.h"
|
||||
#include "core/hle/service/cmif_types.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
struct Applet;
|
||||
class ILibraryAppletAccessor;
|
||||
class IStorage;
|
||||
class WindowSystem;
|
||||
|
||||
class ILibraryAppletCreator final : public ServiceFramework<ILibraryAppletCreator> {
|
||||
public:
|
||||
explicit ILibraryAppletCreator(Core::System& system_, std::shared_ptr<Applet> applet,
|
||||
WindowSystem& window_system);
|
||||
~ILibraryAppletCreator() override;
|
||||
|
||||
private:
|
||||
Result CreateLibraryApplet(
|
||||
Out<SharedPointer<ILibraryAppletAccessor>> out_library_applet_accessor, AppletId applet_id,
|
||||
LibraryAppletMode library_applet_mode);
|
||||
Result CreateLibraryAppletEx(
|
||||
Out<SharedPointer<ILibraryAppletAccessor>> out_library_applet_accessor, AppletId applet_id,
|
||||
LibraryAppletMode library_applet_mode, u64 thread_id);
|
||||
Result CreateStorage(Out<SharedPointer<IStorage>> out_storage, s64 size);
|
||||
Result CreateTransferMemoryStorage(
|
||||
Out<SharedPointer<IStorage>> out_storage, bool is_writable, s64 size,
|
||||
InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle);
|
||||
Result CreateHandleStorage(Out<SharedPointer<IStorage>> out_storage, s64 size,
|
||||
InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle);
|
||||
|
||||
WindowSystem& m_window_system;
|
||||
const std::shared_ptr<Applet> m_applet;
|
||||
};
|
||||
|
||||
} // namespace Service::AM
|
||||
@@ -1,137 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "core/hle/service/am/service/applet_common_functions.h"
|
||||
#include "core/hle/service/am/service/audio_controller.h"
|
||||
#include "core/hle/service/am/service/common_state_getter.h"
|
||||
#include "core/hle/service/am/service/debug_functions.h"
|
||||
#include "core/hle/service/am/service/display_controller.h"
|
||||
#include "core/hle/service/am/service/global_state_controller.h"
|
||||
#include "core/hle/service/am/service/home_menu_functions.h"
|
||||
#include "core/hle/service/am/service/library_applet_creator.h"
|
||||
#include "core/hle/service/am/service/library_applet_proxy.h"
|
||||
#include "core/hle/service/am/service/library_applet_self_accessor.h"
|
||||
#include "core/hle/service/am/service/process_winding_controller.h"
|
||||
#include "core/hle/service/am/service/self_controller.h"
|
||||
#include "core/hle/service/am/service/window_controller.h"
|
||||
#include "core/hle/service/cmif_serialization.h"
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
ILibraryAppletProxy::ILibraryAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet,
|
||||
Kernel::KProcess* process, WindowSystem& window_system)
|
||||
: ServiceFramework{system_, "ILibraryAppletProxy"},
|
||||
m_window_system{window_system}, m_process{process}, m_applet{std::move(applet)} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, D<&ILibraryAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"},
|
||||
{1, D<&ILibraryAppletProxy::GetSelfController>, "GetSelfController"},
|
||||
{2, D<&ILibraryAppletProxy::GetWindowController>, "GetWindowController"},
|
||||
{3, D<&ILibraryAppletProxy::GetAudioController>, "GetAudioController"},
|
||||
{4, D<&ILibraryAppletProxy::GetDisplayController>, "GetDisplayController"},
|
||||
{10, D<&ILibraryAppletProxy::GetProcessWindingController>, "GetProcessWindingController"},
|
||||
{11, D<&ILibraryAppletProxy::GetLibraryAppletCreator>, "GetLibraryAppletCreator"},
|
||||
{20, D<&ILibraryAppletProxy::OpenLibraryAppletSelfAccessor>, "OpenLibraryAppletSelfAccessor"},
|
||||
{21, D<&ILibraryAppletProxy::GetAppletCommonFunctions>, "GetAppletCommonFunctions"},
|
||||
{22, D<&ILibraryAppletProxy::GetHomeMenuFunctions>, "GetHomeMenuFunctions"},
|
||||
{23, D<&ILibraryAppletProxy::GetGlobalStateController>, "GetGlobalStateController"},
|
||||
{1000, D<&ILibraryAppletProxy::GetDebugFunctions>, "GetDebugFunctions"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
ILibraryAppletProxy::~ILibraryAppletProxy() = default;
|
||||
|
||||
Result ILibraryAppletProxy::GetAudioController(
|
||||
Out<SharedPointer<IAudioController>> out_audio_controller) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_audio_controller = std::make_shared<IAudioController>(system);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILibraryAppletProxy::GetDisplayController(
|
||||
Out<SharedPointer<IDisplayController>> out_display_controller) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_display_controller = std::make_shared<IDisplayController>(system, m_applet);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILibraryAppletProxy::GetProcessWindingController(
|
||||
Out<SharedPointer<IProcessWindingController>> out_process_winding_controller) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_process_winding_controller = std::make_shared<IProcessWindingController>(system, m_applet);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILibraryAppletProxy::GetDebugFunctions(
|
||||
Out<SharedPointer<IDebugFunctions>> out_debug_functions) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_debug_functions = std::make_shared<IDebugFunctions>(system);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILibraryAppletProxy::GetWindowController(
|
||||
Out<SharedPointer<IWindowController>> out_window_controller) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_window_controller = std::make_shared<IWindowController>(system, m_applet, m_window_system);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILibraryAppletProxy::GetSelfController(
|
||||
Out<SharedPointer<ISelfController>> out_self_controller) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_self_controller = std::make_shared<ISelfController>(system, m_applet, m_process);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILibraryAppletProxy::GetCommonStateGetter(
|
||||
Out<SharedPointer<ICommonStateGetter>> out_common_state_getter) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_common_state_getter = std::make_shared<ICommonStateGetter>(system, m_applet);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILibraryAppletProxy::GetLibraryAppletCreator(
|
||||
Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_library_applet_creator =
|
||||
std::make_shared<ILibraryAppletCreator>(system, m_applet, m_window_system);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILibraryAppletProxy::OpenLibraryAppletSelfAccessor(
|
||||
Out<SharedPointer<ILibraryAppletSelfAccessor>> out_library_applet_self_accessor) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_library_applet_self_accessor =
|
||||
std::make_shared<ILibraryAppletSelfAccessor>(system, m_applet);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILibraryAppletProxy::GetAppletCommonFunctions(
|
||||
Out<SharedPointer<IAppletCommonFunctions>> out_applet_common_functions) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_applet_common_functions = std::make_shared<IAppletCommonFunctions>(system, m_applet);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILibraryAppletProxy::GetHomeMenuFunctions(
|
||||
Out<SharedPointer<IHomeMenuFunctions>> out_home_menu_functions) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_home_menu_functions =
|
||||
std::make_shared<IHomeMenuFunctions>(system, m_applet, m_window_system);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILibraryAppletProxy::GetGlobalStateController(
|
||||
Out<SharedPointer<IGlobalStateController>> out_global_state_controller) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_global_state_controller = std::make_shared<IGlobalStateController>(system);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
} // namespace Service::AM
|
||||
@@ -1,59 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/cmif_types.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
struct Applet;
|
||||
class IAppletCommonFunctions;
|
||||
class IAudioController;
|
||||
class ICommonStateGetter;
|
||||
class IDebugFunctions;
|
||||
class IDisplayController;
|
||||
class IHomeMenuFunctions;
|
||||
class IGlobalStateController;
|
||||
class ILibraryAppletCreator;
|
||||
class ILibraryAppletSelfAccessor;
|
||||
class IProcessWindingController;
|
||||
class ISelfController;
|
||||
class IWindowController;
|
||||
class WindowSystem;
|
||||
|
||||
class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> {
|
||||
public:
|
||||
explicit ILibraryAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet,
|
||||
Kernel::KProcess* process, WindowSystem& window_system);
|
||||
~ILibraryAppletProxy();
|
||||
|
||||
private:
|
||||
Result GetAudioController(Out<SharedPointer<IAudioController>> out_audio_controller);
|
||||
Result GetDisplayController(Out<SharedPointer<IDisplayController>> out_display_controller);
|
||||
Result GetProcessWindingController(
|
||||
Out<SharedPointer<IProcessWindingController>> out_process_winding_controller);
|
||||
Result GetDebugFunctions(Out<SharedPointer<IDebugFunctions>> out_debug_functions);
|
||||
Result GetWindowController(Out<SharedPointer<IWindowController>> out_window_controller);
|
||||
Result GetSelfController(Out<SharedPointer<ISelfController>> out_self_controller);
|
||||
Result GetCommonStateGetter(Out<SharedPointer<ICommonStateGetter>> out_common_state_getter);
|
||||
Result GetLibraryAppletCreator(
|
||||
Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator);
|
||||
Result OpenLibraryAppletSelfAccessor(
|
||||
Out<SharedPointer<ILibraryAppletSelfAccessor>> out_library_applet_self_accessor);
|
||||
Result GetAppletCommonFunctions(
|
||||
Out<SharedPointer<IAppletCommonFunctions>> out_applet_common_functions);
|
||||
Result GetHomeMenuFunctions(Out<SharedPointer<IHomeMenuFunctions>> out_home_menu_functions);
|
||||
Result GetGlobalStateController(
|
||||
Out<SharedPointer<IGlobalStateController>> out_global_state_controller);
|
||||
|
||||
WindowSystem& m_window_system;
|
||||
Kernel::KProcess* const m_process;
|
||||
const std::shared_ptr<Applet> m_applet;
|
||||
};
|
||||
|
||||
} // namespace Service::AM
|
||||
@@ -1,332 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "core/core_timing.h"
|
||||
#include "core/file_sys/control_metadata.h"
|
||||
#include "core/file_sys/patch_manager.h"
|
||||
#include "core/file_sys/registered_cache.h"
|
||||
#include "core/hle/service/acc/profile_manager.h"
|
||||
#include "core/hle/service/am/applet_data_broker.h"
|
||||
#include "core/hle/service/am/applet_manager.h"
|
||||
#include "core/hle/service/am/frontend/applets.h"
|
||||
#include "core/hle/service/am/service/library_applet_self_accessor.h"
|
||||
#include "core/hle/service/am/service/storage.h"
|
||||
#include "core/hle/service/cmif_serialization.h"
|
||||
#include "core/hle/service/filesystem/filesystem.h"
|
||||
#include "core/hle/service/glue/glue_manager.h"
|
||||
#include "core/hle/service/ns/application_manager_interface.h"
|
||||
#include "core/hle/service/ns/service_getter_interface.h"
|
||||
#include "core/hle/service/sm/sm.h"
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
namespace {
|
||||
|
||||
AppletIdentityInfo GetCallerIdentity(Applet& applet) {
|
||||
if (const auto caller_applet = applet.caller_applet.lock(); caller_applet) {
|
||||
// TODO: is this actually the application ID?
|
||||
return {
|
||||
.applet_id = caller_applet->applet_id,
|
||||
.application_id = caller_applet->program_id,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
.applet_id = AppletId::QLaunch,
|
||||
.application_id = 0x0100000000001000ull,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_,
|
||||
std::shared_ptr<Applet> applet)
|
||||
: ServiceFramework{system_, "ILibraryAppletSelfAccessor"}, m_applet{std::move(applet)},
|
||||
m_broker{m_applet->caller_applet_broker} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, D<&ILibraryAppletSelfAccessor::PopInData>, "PopInData"},
|
||||
{1, D<&ILibraryAppletSelfAccessor::PushOutData>, "PushOutData"},
|
||||
{2, D<&ILibraryAppletSelfAccessor::PopInteractiveInData>, "PopInteractiveInData"},
|
||||
{3, D<&ILibraryAppletSelfAccessor::PushInteractiveOutData>, "PushInteractiveOutData"},
|
||||
{5, D<&ILibraryAppletSelfAccessor::GetPopInDataEvent>, "GetPopInDataEvent"},
|
||||
{6, D<&ILibraryAppletSelfAccessor::GetPopInteractiveInDataEvent>, "GetPopInteractiveInDataEvent"},
|
||||
{10, D<&ILibraryAppletSelfAccessor::ExitProcessAndReturn>, "ExitProcessAndReturn"},
|
||||
{11, D<&ILibraryAppletSelfAccessor::GetLibraryAppletInfo>, "GetLibraryAppletInfo"},
|
||||
{12, D<&ILibraryAppletSelfAccessor::GetMainAppletIdentityInfo>, "GetMainAppletIdentityInfo"},
|
||||
{13, D<&ILibraryAppletSelfAccessor::CanUseApplicationCore>, "CanUseApplicationCore"},
|
||||
{14, D<&ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo>, "GetCallerAppletIdentityInfo"},
|
||||
{15, D<&ILibraryAppletSelfAccessor::GetMainAppletApplicationControlProperty>, "GetMainAppletApplicationControlProperty"},
|
||||
{16, D<&ILibraryAppletSelfAccessor::GetMainAppletStorageId>, "GetMainAppletStorageId"},
|
||||
{17, D<&ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfoStack>, "GetCallerAppletIdentityInfoStack"},
|
||||
{18, nullptr, "GetNextReturnDestinationAppletIdentityInfo"},
|
||||
{19, D<&ILibraryAppletSelfAccessor::GetDesirableKeyboardLayout>, "GetDesirableKeyboardLayout"},
|
||||
{20, nullptr, "PopExtraStorage"},
|
||||
{25, nullptr, "GetPopExtraStorageEvent"},
|
||||
{30, D<&ILibraryAppletSelfAccessor::UnpopInData>, "UnpopInData"},
|
||||
{31, nullptr, "UnpopExtraStorage"},
|
||||
{40, nullptr, "GetIndirectLayerProducerHandle"},
|
||||
{50, D<&ILibraryAppletSelfAccessor::ReportVisibleError>, "ReportVisibleError"},
|
||||
{51, D<&ILibraryAppletSelfAccessor::ReportVisibleErrorWithErrorContext>, "ReportVisibleErrorWithErrorContext"},
|
||||
{60, D<&ILibraryAppletSelfAccessor::GetMainAppletApplicationDesiredLanguage>, "GetMainAppletApplicationDesiredLanguage"},
|
||||
{70, D<&ILibraryAppletSelfAccessor::GetCurrentApplicationId>, "GetCurrentApplicationId"},
|
||||
{80, nullptr, "RequestExitToSelf"},
|
||||
{90, nullptr, "CreateApplicationAndPushAndRequestToLaunch"},
|
||||
{100, nullptr, "CreateGameMovieTrimmer"},
|
||||
{101, nullptr, "ReserveResourceForMovieOperation"},
|
||||
{102, nullptr, "UnreserveResourceForMovieOperation"},
|
||||
{110, D<&ILibraryAppletSelfAccessor::GetMainAppletAvailableUsers>, "GetMainAppletAvailableUsers"},
|
||||
{120, nullptr, "GetLaunchStorageInfoForDebug"},
|
||||
{130, nullptr, "GetGpuErrorDetectedSystemEvent"},
|
||||
{140, nullptr, "SetApplicationMemoryReservation"},
|
||||
{150, D<&ILibraryAppletSelfAccessor::ShouldSetGpuTimeSliceManually>, "ShouldSetGpuTimeSliceManually"},
|
||||
{160, D<&ILibraryAppletSelfAccessor::GetLibraryAppletInfoEx>, "GetLibraryAppletInfoEx"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
ILibraryAppletSelfAccessor::~ILibraryAppletSelfAccessor() = default;
|
||||
|
||||
Result ILibraryAppletSelfAccessor::PopInData(Out<SharedPointer<IStorage>> out_storage) {
|
||||
LOG_INFO(Service_AM, "called");
|
||||
R_RETURN(m_broker->GetInData().Pop(system.Kernel(), out_storage));
|
||||
}
|
||||
|
||||
Result ILibraryAppletSelfAccessor::PushOutData(SharedPointer<IStorage> storage) {
|
||||
LOG_INFO(Service_AM, "called");
|
||||
m_broker->GetOutData().Push(system.Kernel(), storage);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILibraryAppletSelfAccessor::PopInteractiveInData(Out<SharedPointer<IStorage>> out_storage) {
|
||||
LOG_INFO(Service_AM, "called");
|
||||
R_RETURN(m_broker->GetInteractiveInData().Pop(system.Kernel(), out_storage));
|
||||
}
|
||||
|
||||
Result ILibraryAppletSelfAccessor::PushInteractiveOutData(SharedPointer<IStorage> storage) {
|
||||
LOG_INFO(Service_AM, "called");
|
||||
m_broker->GetInteractiveOutData().Push(system.Kernel(), storage);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILibraryAppletSelfAccessor::GetPopInDataEvent(
|
||||
OutCopyHandle<Kernel::KReadableEvent> out_event) {
|
||||
LOG_INFO(Service_AM, "called");
|
||||
*out_event = m_broker->GetInData().GetEvent();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILibraryAppletSelfAccessor::GetPopInteractiveInDataEvent(
|
||||
OutCopyHandle<Kernel::KReadableEvent> out_event) {
|
||||
LOG_INFO(Service_AM, "called");
|
||||
*out_event = m_broker->GetInteractiveInData().GetEvent();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILibraryAppletSelfAccessor::GetLibraryAppletInfo(
|
||||
Out<LibraryAppletInfo> out_library_applet_info) {
|
||||
LOG_INFO(Service_AM, "called");
|
||||
*out_library_applet_info = {
|
||||
.applet_id = m_applet->applet_id,
|
||||
.library_applet_mode = m_applet->library_applet_mode,
|
||||
};
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILibraryAppletSelfAccessor::GetMainAppletIdentityInfo(
|
||||
Out<AppletIdentityInfo> out_identity_info) {
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
*out_identity_info = {
|
||||
.applet_id = AppletId::QLaunch,
|
||||
.application_id = 0x0100000000001000ull,
|
||||
};
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILibraryAppletSelfAccessor::CanUseApplicationCore(Out<bool> out_can_use_application_core) {
|
||||
// TODO: This appears to read the NPDM from state and check the core mask of the applet.
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
*out_can_use_application_core = false;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILibraryAppletSelfAccessor::GetMainAppletApplicationControlProperty(
|
||||
OutLargeData<std::array<u8, 0x4000>, BufferAttr_HipcMapAlias> out_nacp) {
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
|
||||
// TODO: this should be the main applet, not the caller applet
|
||||
const auto application = GetCallerIdentity(*m_applet);
|
||||
std::vector<u8> nacp;
|
||||
const auto result =
|
||||
system.GetARPManager().GetControlProperty(&nacp, application.application_id);
|
||||
|
||||
if (R_SUCCEEDED(result)) {
|
||||
std::memcpy(out_nacp->data(), nacp.data(), (std::min)(nacp.size(), out_nacp->size()));
|
||||
}
|
||||
|
||||
R_RETURN(result);
|
||||
}
|
||||
|
||||
Result ILibraryAppletSelfAccessor::GetMainAppletStorageId(Out<FileSys::StorageId> out_storage_id) {
|
||||
LOG_INFO(Service_AM, "(STUBBED) called");
|
||||
*out_storage_id = FileSys::StorageId::NandUser;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILibraryAppletSelfAccessor::ExitProcessAndReturn() {
|
||||
LOG_INFO(Service_AM, "called");
|
||||
|
||||
if (const auto caller_applet = m_applet->caller_applet.lock(); caller_applet) {
|
||||
m_applet->process->Terminate();
|
||||
} else {
|
||||
system.GetUserChannel() = m_applet->user_channel_launch_parameter;
|
||||
system.ExecuteProgram(0);
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo(
|
||||
Out<AppletIdentityInfo> out_identity_info) {
|
||||
LOG_INFO(Service_AM, "called");
|
||||
*out_identity_info = GetCallerIdentity(*m_applet);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfoStack(
|
||||
Out<s32> out_count, OutArray<AppletIdentityInfo, BufferAttr_HipcMapAlias> out_identity_info) {
|
||||
LOG_INFO(Service_AM, "called");
|
||||
|
||||
std::shared_ptr<Applet> applet = m_applet;
|
||||
*out_count = 0;
|
||||
|
||||
do {
|
||||
if (*out_count >= static_cast<s32>(out_identity_info.size())) {
|
||||
break;
|
||||
}
|
||||
out_identity_info[(*out_count)++] = GetCallerIdentity(*applet);
|
||||
} while ((applet = applet->caller_applet.lock()));
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILibraryAppletSelfAccessor::GetDesirableKeyboardLayout(Out<u32> out_desirable_layout) {
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
*out_desirable_layout = 0;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILibraryAppletSelfAccessor::ReportVisibleError(ErrorCode error_code) {
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called, error {}-{}", error_code.category,
|
||||
error_code.number);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILibraryAppletSelfAccessor::ReportVisibleErrorWithErrorContext(
|
||||
ErrorCode error_code, InLargeData<ErrorContext, BufferAttr_HipcMapAlias> error_context) {
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called, error {}-{}", error_code.category,
|
||||
error_code.number);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILibraryAppletSelfAccessor::UnpopInData(SharedPointer<IStorage> storage) {
|
||||
LOG_INFO(Service_AM, "called");
|
||||
m_broker->GetInData().Unpop(system.Kernel(), storage);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILibraryAppletSelfAccessor::GetMainAppletApplicationDesiredLanguage(
|
||||
Out<u64> out_desired_language) {
|
||||
// FIXME: this is copied from IApplicationFunctions::GetDesiredLanguage
|
||||
// FIXME: all of this stuff belongs to ns
|
||||
auto identity = GetCallerIdentity(*m_applet);
|
||||
|
||||
// TODO(bunnei): This should be configurable
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
|
||||
// Get supported languages from NACP, if possible
|
||||
// Default to 0 (all languages supported)
|
||||
u32 supported_languages = 0;
|
||||
|
||||
const auto res = FileSys::PatchManager::GetMetadataFromBaseOrUpdate(system, identity.application_id);
|
||||
|
||||
if (res.first != nullptr) {
|
||||
supported_languages = res.first->GetSupportedLanguages();
|
||||
}
|
||||
|
||||
// Call IApplicationManagerInterface implementation.
|
||||
auto& service_manager = system.ServiceManager();
|
||||
auto ns_am2 = service_manager.GetService<NS::IServiceGetterInterface>("ns:am2");
|
||||
|
||||
std::shared_ptr<NS::IApplicationManagerInterface> app_man;
|
||||
R_TRY(ns_am2->GetApplicationManagerInterface(&app_man));
|
||||
|
||||
// Get desired application language
|
||||
NS::ApplicationLanguage desired_language{};
|
||||
R_TRY(app_man->GetApplicationDesiredLanguage(&desired_language, supported_languages));
|
||||
|
||||
// Convert to settings language code.
|
||||
u64 language_code{};
|
||||
R_TRY(app_man->ConvertApplicationLanguageToLanguageCode(&language_code, desired_language));
|
||||
|
||||
LOG_DEBUG(Service_AM, "got desired_language={:016X}", language_code);
|
||||
|
||||
*out_desired_language = language_code;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILibraryAppletSelfAccessor::GetCurrentApplicationId(Out<u64> out_application_id) {
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
|
||||
// TODO: this should be the main applet, not the caller applet
|
||||
const auto main_applet = GetCallerIdentity(*m_applet);
|
||||
*out_application_id = main_applet.application_id;
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILibraryAppletSelfAccessor::GetMainAppletAvailableUsers(
|
||||
Out<bool> out_can_select_any_user, Out<s32> out_users_count,
|
||||
OutArray<Common::UUID, BufferAttr_HipcMapAlias> out_users) {
|
||||
const Service::Account::ProfileManager manager{};
|
||||
|
||||
*out_can_select_any_user = false;
|
||||
*out_users_count = -1;
|
||||
|
||||
LOG_INFO(Service_AM, "called");
|
||||
|
||||
if (manager.GetUserCount() > 0) {
|
||||
*out_can_select_any_user = true;
|
||||
*out_users_count = static_cast<s32>(manager.GetUserCount());
|
||||
|
||||
const auto users = manager.GetAllUsers();
|
||||
for (size_t i = 0; i < users.size() && i < out_users.size(); i++) {
|
||||
out_users[i] = users[i];
|
||||
}
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILibraryAppletSelfAccessor::ShouldSetGpuTimeSliceManually(
|
||||
Out<bool> out_should_set_gpu_time_slice_manually) {
|
||||
LOG_INFO(Service_AM, "(STUBBED) called");
|
||||
*out_should_set_gpu_time_slice_manually = false;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILibraryAppletSelfAccessor::GetLibraryAppletInfoEx(
|
||||
Out<LibraryAppletInfo> out_library_applet_info) {
|
||||
LOG_INFO(Service_AM, "called");
|
||||
*out_library_applet_info = {
|
||||
.applet_id = m_applet->applet_id,
|
||||
.library_applet_mode = m_applet->library_applet_mode,
|
||||
};
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
} // namespace Service::AM
|
||||
@@ -1,87 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/uuid.h"
|
||||
#include "core/hle/service/am/am_types.h"
|
||||
#include "core/hle/service/cmif_types.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace FileSys {
|
||||
enum class StorageId : u8;
|
||||
}
|
||||
|
||||
namespace Kernel {
|
||||
class KReadableEvent;
|
||||
}
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
class AppletDataBroker;
|
||||
struct Applet;
|
||||
class IStorage;
|
||||
|
||||
struct LibraryAppletInfo {
|
||||
AppletId applet_id;
|
||||
LibraryAppletMode library_applet_mode;
|
||||
};
|
||||
static_assert(sizeof(LibraryAppletInfo) == 0x8, "LibraryAppletInfo has incorrect size.");
|
||||
|
||||
struct ErrorCode {
|
||||
u32 category;
|
||||
u32 number;
|
||||
};
|
||||
static_assert(sizeof(ErrorCode) == 0x8, "ErrorCode has incorrect size.");
|
||||
|
||||
struct ErrorContext {
|
||||
u8 type;
|
||||
INSERT_PADDING_BYTES_NOINIT(0x7);
|
||||
std::array<u8, 0x1f4> data;
|
||||
Result result;
|
||||
};
|
||||
static_assert(sizeof(ErrorContext) == 0x200, "ErrorContext has incorrect size.");
|
||||
|
||||
class ILibraryAppletSelfAccessor final : public ServiceFramework<ILibraryAppletSelfAccessor> {
|
||||
public:
|
||||
explicit ILibraryAppletSelfAccessor(Core::System& system_, std::shared_ptr<Applet> applet);
|
||||
~ILibraryAppletSelfAccessor() override;
|
||||
|
||||
private:
|
||||
Result PopInData(Out<SharedPointer<IStorage>> out_storage);
|
||||
Result PushOutData(SharedPointer<IStorage> storage);
|
||||
Result PopInteractiveInData(Out<SharedPointer<IStorage>> out_storage);
|
||||
Result PushInteractiveOutData(SharedPointer<IStorage> storage);
|
||||
Result GetPopInDataEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
|
||||
Result GetPopInteractiveInDataEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
|
||||
Result GetLibraryAppletInfo(Out<LibraryAppletInfo> out_library_applet_info);
|
||||
Result GetMainAppletIdentityInfo(Out<AppletIdentityInfo> out_identity_info);
|
||||
Result CanUseApplicationCore(Out<bool> out_can_use_application_core);
|
||||
Result GetMainAppletApplicationControlProperty(
|
||||
OutLargeData<std::array<u8, 0x4000>, BufferAttr_HipcMapAlias> out_nacp);
|
||||
Result GetMainAppletStorageId(Out<FileSys::StorageId> out_storage_id);
|
||||
Result ExitProcessAndReturn();
|
||||
Result GetCallerAppletIdentityInfo(Out<AppletIdentityInfo> out_identity_info);
|
||||
Result GetCallerAppletIdentityInfoStack(
|
||||
Out<s32> out_count,
|
||||
OutArray<AppletIdentityInfo, BufferAttr_HipcMapAlias> out_identity_info);
|
||||
Result GetDesirableKeyboardLayout(Out<u32> out_desirable_layout);
|
||||
Result ReportVisibleError(ErrorCode error_code);
|
||||
Result ReportVisibleErrorWithErrorContext(
|
||||
ErrorCode error_code, InLargeData<ErrorContext, BufferAttr_HipcMapAlias> error_context);
|
||||
Result UnpopInData(SharedPointer<IStorage> storage);
|
||||
Result GetMainAppletApplicationDesiredLanguage(Out<u64> out_desired_language);
|
||||
Result GetCurrentApplicationId(Out<u64> out_application_id);
|
||||
Result GetMainAppletAvailableUsers(Out<bool> out_can_select_any_user, Out<s32> out_users_count,
|
||||
OutArray<Common::UUID, BufferAttr_HipcMapAlias> out_users);
|
||||
Result ShouldSetGpuTimeSliceManually(Out<bool> out_should_set_gpu_time_slice_manually);
|
||||
Result GetLibraryAppletInfoEx(Out<LibraryAppletInfo> out_library_applet_info);
|
||||
|
||||
const std::shared_ptr<Applet> m_applet;
|
||||
const std::shared_ptr<AppletDataBroker> m_broker;
|
||||
};
|
||||
|
||||
} // namespace Service::AM
|
||||
@@ -1,78 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "core/hle/service/am/service/lock_accessor.h"
|
||||
#include "core/hle/service/cmif_serialization.h"
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
ILockAccessor::ILockAccessor(Core::System& system_)
|
||||
: ServiceFramework{system_, "ILockAccessor"}, m_context{system_, "ILockAccessor"},
|
||||
m_event{m_context} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{1, D<&ILockAccessor::TryLock>, "TryLock"},
|
||||
{2, D<&ILockAccessor::Unlock>, "Unlock"},
|
||||
{3, D<&ILockAccessor::GetEvent>, "GetEvent"},
|
||||
{4, D<&ILockAccessor::IsLocked>, "IsLocked"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
|
||||
m_event.Signal(system.Kernel());
|
||||
}
|
||||
|
||||
ILockAccessor::~ILockAccessor() = default;
|
||||
|
||||
Result ILockAccessor::TryLock(Out<bool> out_is_locked,
|
||||
OutCopyHandle<Kernel::KReadableEvent> out_handle,
|
||||
bool return_handle) {
|
||||
LOG_INFO(Service_AM, "called, return_handle={}", return_handle);
|
||||
|
||||
{
|
||||
std::scoped_lock lk{m_mutex};
|
||||
if (m_is_locked) {
|
||||
*out_is_locked = false;
|
||||
} else {
|
||||
m_is_locked = true;
|
||||
*out_is_locked = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (return_handle) {
|
||||
*out_handle = m_event.GetHandle();
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILockAccessor::Unlock() {
|
||||
LOG_INFO(Service_AM, "called");
|
||||
|
||||
{
|
||||
std::scoped_lock lk{m_mutex};
|
||||
m_is_locked = false;
|
||||
}
|
||||
|
||||
m_event.Signal(system.Kernel());
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILockAccessor::GetEvent(OutCopyHandle<Kernel::KReadableEvent> out_handle) {
|
||||
LOG_INFO(Service_AM, "called");
|
||||
*out_handle = m_event.GetHandle();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ILockAccessor::IsLocked(Out<bool> out_is_locked) {
|
||||
LOG_INFO(Service_AM, "called");
|
||||
std::scoped_lock lk{m_mutex};
|
||||
*out_is_locked = m_is_locked;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
} // namespace Service::AM
|
||||
@@ -1,35 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/cmif_types.h"
|
||||
#include "core/hle/service/kernel_helpers.h"
|
||||
#include "core/hle/service/os/event.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
class ILockAccessor final : public ServiceFramework<ILockAccessor> {
|
||||
public:
|
||||
explicit ILockAccessor(Core::System& system_);
|
||||
~ILockAccessor() override;
|
||||
|
||||
private:
|
||||
Result TryLock(Out<bool> out_is_locked, OutCopyHandle<Kernel::KReadableEvent> out_handle,
|
||||
bool return_handle);
|
||||
Result Unlock();
|
||||
Result GetEvent(OutCopyHandle<Kernel::KReadableEvent> out_handle);
|
||||
Result IsLocked(Out<bool> out_is_locked);
|
||||
|
||||
private:
|
||||
KernelHelpers::ServiceContext m_context;
|
||||
Event m_event;
|
||||
std::mutex m_mutex{};
|
||||
bool m_is_locked{};
|
||||
};
|
||||
|
||||
} // namespace Service::AM
|
||||
@@ -1,120 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "core/hle/service/am/service/common_state_getter.h"
|
||||
#include "core/hle/service/am/service/display_controller.h"
|
||||
#include "core/hle/service/am/service/global_state_controller.h"
|
||||
#include "core/hle/service/am/service/audio_controller.h"
|
||||
#include "core/hle/service/am/service/applet_common_functions.h"
|
||||
#include "core/hle/service/am/service/overlay_applet_proxy.h"
|
||||
#include "core/hle/service/am/service/library_applet_creator.h"
|
||||
#include "core/hle/service/am/service/process_winding_controller.h"
|
||||
#include "core/hle/service/am/service/self_controller.h"
|
||||
#include "core/hle/service/am/service/window_controller.h"
|
||||
#include "core/hle/service/am/service/debug_functions.h"
|
||||
#include "core/hle/service/cmif_serialization.h"
|
||||
|
||||
namespace Service::AM {
|
||||
IOverlayAppletProxy::IOverlayAppletProxy(Core::System &system_, std::shared_ptr<Applet> applet,
|
||||
Kernel::KProcess *process, WindowSystem &window_system)
|
||||
: ServiceFramework{system_, "IOverlayAppletProxy"},
|
||||
m_window_system{window_system}, m_process{process}, m_applet{std::move(applet)} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, D<&IOverlayAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"},
|
||||
{1, D<&IOverlayAppletProxy::GetSelfController>, "GetSelfController"},
|
||||
{2, D<&IOverlayAppletProxy::GetWindowController>, "GetWindowController"},
|
||||
{3, D<&IOverlayAppletProxy::GetAudioController>, "GetAudioController"},
|
||||
{4, D<&IOverlayAppletProxy::GetDisplayController>, "GetDisplayController"},
|
||||
{10, D<&IOverlayAppletProxy::GetProcessWindingController>, "GetProcessWindingController"},
|
||||
{11, D<&IOverlayAppletProxy::GetLibraryAppletCreator>, "GetLibraryAppletCreator"},
|
||||
{20, D<&IOverlayAppletProxy::GetOverlayFunctions>, "GetOverlayFunctions"},
|
||||
{21, D<&IOverlayAppletProxy::GetAppletCommonFunctions>, "GetAppletCommonFunctions"},
|
||||
{23, D<&IOverlayAppletProxy::GetGlobalStateController>, "GetGlobalStateController"},
|
||||
{1000, D<&IOverlayAppletProxy::GetDebugFunctions>, "GetDebugFunctions"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
IOverlayAppletProxy::~IOverlayAppletProxy() = default;
|
||||
|
||||
Result IOverlayAppletProxy::GetCommonStateGetter(
|
||||
Out<SharedPointer<ICommonStateGetter> > out_common_state_getter) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_common_state_getter = std::make_shared<ICommonStateGetter>(system, m_applet);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IOverlayAppletProxy::GetSelfController(
|
||||
Out<SharedPointer<ISelfController> > out_self_controller) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_self_controller = std::make_shared<ISelfController>(system, m_applet, m_process);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IOverlayAppletProxy::GetWindowController(
|
||||
Out<SharedPointer<IWindowController> > out_window_controller) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_window_controller = std::make_shared<IWindowController>(system, m_applet, m_window_system);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IOverlayAppletProxy::GetAudioController(
|
||||
Out<SharedPointer<IAudioController> > out_audio_controller) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_audio_controller = std::make_shared<IAudioController>(system);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IOverlayAppletProxy::GetDisplayController(
|
||||
Out<SharedPointer<IDisplayController> > out_display_controller) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_display_controller = std::make_shared<IDisplayController>(system, m_applet);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IOverlayAppletProxy::GetProcessWindingController(
|
||||
Out<SharedPointer<IProcessWindingController> > out_process_winding_controller) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_process_winding_controller = std::make_shared<IProcessWindingController>(system, m_applet);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IOverlayAppletProxy::GetLibraryAppletCreator(
|
||||
Out<SharedPointer<ILibraryAppletCreator> > out_library_applet_creator) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_library_applet_creator =
|
||||
std::make_shared<ILibraryAppletCreator>(system, m_applet, m_window_system);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IOverlayAppletProxy::GetOverlayFunctions(
|
||||
Out<SharedPointer<IOverlayFunctions> > out_overlay_functions) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_overlay_functions = std::make_shared<IOverlayFunctions>(system, m_applet);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IOverlayAppletProxy::GetAppletCommonFunctions(
|
||||
Out<SharedPointer<IAppletCommonFunctions> > out_applet_common_functions) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_applet_common_functions = std::make_shared<IAppletCommonFunctions>(system, m_applet);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IOverlayAppletProxy::GetGlobalStateController(
|
||||
Out<SharedPointer<IGlobalStateController> > out_global_state_controller) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_global_state_controller = std::make_shared<IGlobalStateController>(system);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IOverlayAppletProxy::GetDebugFunctions(
|
||||
Out<SharedPointer<IDebugFunctions> > out_debug_functions) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_debug_functions = std::make_shared<IDebugFunctions>(system);
|
||||
R_SUCCEED();
|
||||
}
|
||||
} // namespace Service::AM
|
||||
@@ -1,55 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/cmif_types.h"
|
||||
#include "core/hle/service/service.h"
|
||||
#include "core/hle/service/am/service/overlay_functions.h"
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
struct Applet;
|
||||
class IAppletCommonFunctions;
|
||||
class IAudioController;
|
||||
class ICommonStateGetter;
|
||||
class IDebugFunctions;
|
||||
class IDisplayController;
|
||||
class IHomeMenuFunctions;
|
||||
class IGlobalStateController;
|
||||
class ILibraryAppletCreator;
|
||||
class ILibraryAppletSelfAccessor;
|
||||
class IProcessWindingController;
|
||||
class ISelfController;
|
||||
class IWindowController;
|
||||
class WindowSystem;
|
||||
|
||||
class IOverlayAppletProxy final : public ServiceFramework<IOverlayAppletProxy> {
|
||||
public:
|
||||
explicit IOverlayAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet,
|
||||
Kernel::KProcess* process, WindowSystem& window_system);
|
||||
~IOverlayAppletProxy();
|
||||
|
||||
private:
|
||||
Result GetCommonStateGetter(Out<SharedPointer<ICommonStateGetter>> out_common_state_getter);
|
||||
Result GetSelfController(Out<SharedPointer<ISelfController>> out_self_controller);
|
||||
Result GetWindowController(Out<SharedPointer<IWindowController>> out_window_controller);
|
||||
Result GetAudioController(Out<SharedPointer<IAudioController>> out_audio_controller);
|
||||
Result GetDisplayController(Out<SharedPointer<IDisplayController>> out_display_controller);
|
||||
Result GetProcessWindingController(
|
||||
Out<SharedPointer<IProcessWindingController>> out_process_winding_controller);
|
||||
Result GetLibraryAppletCreator(
|
||||
Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator);
|
||||
Result GetOverlayFunctions(Out<SharedPointer<IOverlayFunctions>> out_overlay_functions);
|
||||
Result GetAppletCommonFunctions(
|
||||
Out<SharedPointer<IAppletCommonFunctions>> out_applet_common_functions);
|
||||
Result GetGlobalStateController(
|
||||
Out<SharedPointer<IGlobalStateController>> out_global_state_controller);
|
||||
Result GetDebugFunctions(Out<SharedPointer<IDebugFunctions>> out_debug_functions);
|
||||
|
||||
WindowSystem& m_window_system;
|
||||
Kernel::KProcess* const m_process;
|
||||
const std::shared_ptr<Applet> m_applet;
|
||||
};
|
||||
|
||||
} // namespace Service::AM
|
||||
@@ -8,34 +8,34 @@
|
||||
#include "core/hle/service/am/window_system.h"
|
||||
|
||||
namespace Service::AM {
|
||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> IOverlayFunctions::FindRequest(u32 key) {
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, D<&IOverlayFunctions::BeginToWatchShortHomeButtonMessage>, "BeginToWatchShortHomeButtonMessage"},
|
||||
FunctionInfo{1, D<&IOverlayFunctions::EndToWatchShortHomeButtonMessage>, "EndToWatchShortHomeButtonMessage"},
|
||||
FunctionInfo{2, D<&IOverlayFunctions::GetApplicationIdForLogo>, "GetApplicationIdForLogo"},
|
||||
FunctionInfo{3, nullptr, "SetGpuTimeSliceBoost"},
|
||||
FunctionInfo{4, D<&IOverlayFunctions::SetAutoSleepTimeAndDimmingTimeEnabled>, "SetAutoSleepTimeAndDimmingTimeEnabled"},
|
||||
FunctionInfo{5, nullptr, "TerminateApplicationAndSetReason"},
|
||||
FunctionInfo{6, nullptr, "SetScreenShotPermissionGlobally"},
|
||||
FunctionInfo{10, nullptr, "StartShutdownSequenceForOverlay"},
|
||||
FunctionInfo{11, nullptr, "StartRebootSequenceForOverlay"},
|
||||
FunctionInfo{20, D<&IOverlayFunctions::SetHandlingHomeButtonShortPressedEnabled>, "SetHandlingHomeButtonShortPressedEnabled"},
|
||||
FunctionInfo{21, D<&IOverlayFunctions::SetHandlingTouchScreenInputEnabled>, "SetHandlingTouchScreenInputEnabled"},
|
||||
FunctionInfo{30, nullptr, "SetHealthWarningShowingState"},
|
||||
FunctionInfo{31, D<&IOverlayFunctions::IsHealthWarningRequired>, "IsHealthWarningRequired"},
|
||||
FunctionInfo{40, nullptr, "GetApplicationNintendoLogo"},
|
||||
FunctionInfo{41, nullptr, "GetApplicationStartupMovie"},
|
||||
FunctionInfo{50, nullptr, "SetGpuTimeSliceBoostForApplication"},
|
||||
FunctionInfo{60, nullptr, "Unknown60"},
|
||||
FunctionInfo{70, D<&IOverlayFunctions::Unknown70>, "Unknown70"},
|
||||
FunctionInfo{90, nullptr, "SetRequiresGpuResourceUse"},
|
||||
FunctionInfo{101, nullptr, "BeginToObserveHidInputForDevelop"}
|
||||
);
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
|
||||
IOverlayFunctions::IOverlayFunctions(Core::System &system_, std::shared_ptr<Applet> applet)
|
||||
: ServiceFramework{system_, "IOverlayFunctions"}, m_applet{std::move(applet)} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, D<&IOverlayFunctions::BeginToWatchShortHomeButtonMessage>, "BeginToWatchShortHomeButtonMessage"},
|
||||
{1, D<&IOverlayFunctions::EndToWatchShortHomeButtonMessage>, "EndToWatchShortHomeButtonMessage"},
|
||||
{2, D<&IOverlayFunctions::GetApplicationIdForLogo>, "GetApplicationIdForLogo"},
|
||||
{3, nullptr, "SetGpuTimeSliceBoost"},
|
||||
{4, D<&IOverlayFunctions::SetAutoSleepTimeAndDimmingTimeEnabled>, "SetAutoSleepTimeAndDimmingTimeEnabled"},
|
||||
{5, nullptr, "TerminateApplicationAndSetReason"},
|
||||
{6, nullptr, "SetScreenShotPermissionGlobally"},
|
||||
{10, nullptr, "StartShutdownSequenceForOverlay"},
|
||||
{11, nullptr, "StartRebootSequenceForOverlay"},
|
||||
{20, D<&IOverlayFunctions::SetHandlingHomeButtonShortPressedEnabled>, "SetHandlingHomeButtonShortPressedEnabled"},
|
||||
{21, D<&IOverlayFunctions::SetHandlingTouchScreenInputEnabled>, "SetHandlingTouchScreenInputEnabled"},
|
||||
{30, nullptr, "SetHealthWarningShowingState"},
|
||||
{31, D<&IOverlayFunctions::IsHealthWarningRequired>, "IsHealthWarningRequired"},
|
||||
{40, nullptr, "GetApplicationNintendoLogo"},
|
||||
{41, nullptr, "GetApplicationStartupMovie"},
|
||||
{50, nullptr, "SetGpuTimeSliceBoostForApplication"},
|
||||
{60, nullptr, "Unknown60"},
|
||||
{70, D<&IOverlayFunctions::Unknown70>, "Unknown70"},
|
||||
{90, nullptr, "SetRequiresGpuResourceUse"},
|
||||
{101, nullptr, "BeginToObserveHidInputForDevelop"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
IOverlayFunctions::~IOverlayFunctions() = default;
|
||||
|
||||
@@ -6,24 +6,25 @@
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service::AM {
|
||||
struct Applet;
|
||||
struct Applet;
|
||||
|
||||
class IOverlayFunctions final : public ServiceFramework<IOverlayFunctions> {
|
||||
public:
|
||||
explicit IOverlayFunctions(Core::System &system_, std::shared_ptr<Applet> applet);
|
||||
~IOverlayFunctions() override;
|
||||
class IOverlayFunctions final : public ServiceFramework<IOverlayFunctions> {
|
||||
public:
|
||||
explicit IOverlayFunctions(Core::System &system_, std::shared_ptr<Applet> applet);
|
||||
~IOverlayFunctions() override;
|
||||
|
||||
private:
|
||||
Result BeginToWatchShortHomeButtonMessage();
|
||||
Result EndToWatchShortHomeButtonMessage();
|
||||
Result GetApplicationIdForLogo(Out<u64> out_application_id);
|
||||
Result SetAutoSleepTimeAndDimmingTimeEnabled(bool enabled);
|
||||
Result IsHealthWarningRequired(Out<bool> is_required);
|
||||
Result SetHandlingHomeButtonShortPressedEnabled(bool enabled);
|
||||
Result SetHandlingTouchScreenInputEnabled(bool enabled);
|
||||
Result Unknown70();
|
||||
private:
|
||||
Result BeginToWatchShortHomeButtonMessage();
|
||||
Result EndToWatchShortHomeButtonMessage();
|
||||
Result GetApplicationIdForLogo(Out<u64> out_application_id);
|
||||
Result SetAutoSleepTimeAndDimmingTimeEnabled(bool enabled);
|
||||
Result IsHealthWarningRequired(Out<bool> is_required);
|
||||
Result SetHandlingHomeButtonShortPressedEnabled(bool enabled);
|
||||
Result SetHandlingTouchScreenInputEnabled(bool enabled);
|
||||
Result Unknown70();
|
||||
|
||||
private:
|
||||
const std::shared_ptr<Applet> m_applet;
|
||||
};
|
||||
private:
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override;
|
||||
const std::shared_ptr<Applet> m_applet;
|
||||
};
|
||||
} // namespace Service::AM
|
||||
|
||||
@@ -13,23 +13,23 @@
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> IProcessWindingController::FindRequest(u32 key) {
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, D<&IProcessWindingController::GetLaunchReason>, "GetLaunchReason"},
|
||||
FunctionInfo{11, D<&IProcessWindingController::OpenCallingLibraryApplet>, "OpenCallingLibraryApplet"},
|
||||
FunctionInfo{21, D<&IProcessWindingController::PushContext>, "PushContext"},
|
||||
FunctionInfo{22, D<&IProcessWindingController::PopContext>, "PopContext"},
|
||||
FunctionInfo{23, D<&IProcessWindingController::CancelWindingReservation>, "CancelWindingReservation"},
|
||||
FunctionInfo{30, D<&IProcessWindingController::WindAndDoReserved>, "WindAndDoReserved"},
|
||||
FunctionInfo{40, D<&IProcessWindingController::ReserveToStartAndWaitAndUnwindThis>, "ReserveToStartAndWaitAndUnwindThis"},
|
||||
FunctionInfo{41, D<&IProcessWindingController::ReserveToStartAndWait>, "ReserveToStartAndWait"}
|
||||
);
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
|
||||
IProcessWindingController::IProcessWindingController(Core::System& system_,
|
||||
std::shared_ptr<Applet> applet)
|
||||
: ServiceFramework{system_, "IProcessWindingController"}, m_applet{std::move(applet)} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, D<&IProcessWindingController::GetLaunchReason>, "GetLaunchReason"},
|
||||
{11, D<&IProcessWindingController::OpenCallingLibraryApplet>, "OpenCallingLibraryApplet"},
|
||||
{21, D<&IProcessWindingController::PushContext>, "PushContext"},
|
||||
{22, D<&IProcessWindingController::PopContext>, "PopContext"},
|
||||
{23, D<&IProcessWindingController::CancelWindingReservation>, "CancelWindingReservation"},
|
||||
{30, D<&IProcessWindingController::WindAndDoReserved>, "WindAndDoReserved"},
|
||||
{40, D<&IProcessWindingController::ReserveToStartAndWaitAndUnwindThis>, "ReserveToStartAndWaitAndUnwindThis"},
|
||||
{41, D<&IProcessWindingController::ReserveToStartAndWait>, "ReserveToStartAndWait"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
IProcessWindingController::~IProcessWindingController() = default;
|
||||
|
||||
@@ -33,6 +33,7 @@ private:
|
||||
SharedPointer<ILibraryAppletAccessor> reserved_applet_accessor);
|
||||
Result ReserveToStartAndWait(SharedPointer<ILibraryAppletAccessor> reserved_applet_accessor);
|
||||
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override;
|
||||
const std::shared_ptr<Applet> m_applet;
|
||||
};
|
||||
|
||||
|
||||
@@ -17,67 +17,66 @@
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> ISelfController::FindRequest(u32 key) {
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, D<&ISelfController::Exit>, "Exit"},
|
||||
FunctionInfo{1, D<&ISelfController::LockExit>, "LockExit"},
|
||||
FunctionInfo{2, D<&ISelfController::UnlockExit>, "UnlockExit"},
|
||||
FunctionInfo{3, D<&ISelfController::EnterFatalSection>, "EnterFatalSection"},
|
||||
FunctionInfo{4, D<&ISelfController::LeaveFatalSection>, "LeaveFatalSection"},
|
||||
FunctionInfo{9, D<&ISelfController::GetLibraryAppletLaunchableEvent>, "GetLibraryAppletLaunchableEvent"},
|
||||
FunctionInfo{10, D<&ISelfController::SetScreenShotPermission>, "SetScreenShotPermission"},
|
||||
FunctionInfo{11, D<&ISelfController::SetOperationModeChangedNotification>, "SetOperationModeChangedNotification"},
|
||||
FunctionInfo{12, D<&ISelfController::SetPerformanceModeChangedNotification>, "SetPerformanceModeChangedNotification"},
|
||||
FunctionInfo{13, D<&ISelfController::SetFocusHandlingMode>, "SetFocusHandlingMode"},
|
||||
FunctionInfo{14, D<&ISelfController::SetRestartMessageEnabled>, "SetRestartMessageEnabled"},
|
||||
FunctionInfo{15, D<&ISelfController::SetScreenShotAppletIdentityInfo>, "SetScreenShotAppletIdentityInfo"},
|
||||
FunctionInfo{16, D<&ISelfController::SetOutOfFocusSuspendingEnabled>, "SetOutOfFocusSuspendingEnabled"},
|
||||
FunctionInfo{17, nullptr, "SetControllerFirmwareUpdateSection"},
|
||||
FunctionInfo{18, nullptr, "SetRequiresCaptureButtonShortPressedMessage"},
|
||||
FunctionInfo{19, D<&ISelfController::SetAlbumImageOrientation>, "SetAlbumImageOrientation"},
|
||||
FunctionInfo{20, nullptr, "SetDesirableKeyboardLayout"},
|
||||
FunctionInfo{21, nullptr, "GetScreenShotProgramId"},
|
||||
FunctionInfo{40, D<&ISelfController::CreateManagedDisplayLayer>, "CreateManagedDisplayLayer"},
|
||||
FunctionInfo{41, D<&ISelfController::IsSystemBufferSharingEnabled>, "IsSystemBufferSharingEnabled"},
|
||||
FunctionInfo{42, D<&ISelfController::GetSystemSharedLayerHandle>, "GetSystemSharedLayerHandle"},
|
||||
FunctionInfo{43, D<&ISelfController::GetSystemSharedBufferHandle>, "GetSystemSharedBufferHandle"},
|
||||
FunctionInfo{44, D<&ISelfController::CreateManagedDisplaySeparableLayer>, "CreateManagedDisplaySeparableLayer"},
|
||||
FunctionInfo{45, nullptr, "SetManagedDisplayLayerSeparationMode"},
|
||||
FunctionInfo{46, nullptr, "SetRecordingLayerCompositionEnabled"},
|
||||
FunctionInfo{50, D<&ISelfController::SetHandlesRequestToDisplay>, "SetHandlesRequestToDisplay"},
|
||||
FunctionInfo{51, D<&ISelfController::ApproveToDisplay>, "ApproveToDisplay"},
|
||||
FunctionInfo{60, D<&ISelfController::OverrideAutoSleepTimeAndDimmingTime>, "OverrideAutoSleepTimeAndDimmingTime"},
|
||||
FunctionInfo{61, D<&ISelfController::SetMediaPlaybackState>, "SetMediaPlaybackState"},
|
||||
FunctionInfo{62, D<&ISelfController::SetIdleTimeDetectionExtension>, "SetIdleTimeDetectionExtension"},
|
||||
FunctionInfo{63, D<&ISelfController::GetIdleTimeDetectionExtension>, "GetIdleTimeDetectionExtension"},
|
||||
FunctionInfo{64, nullptr, "SetInputDetectionSourceSet"},
|
||||
FunctionInfo{65, D<&ISelfController::ReportUserIsActive>, "ReportUserIsActive"},
|
||||
FunctionInfo{66, nullptr, "GetCurrentIlluminance"},
|
||||
FunctionInfo{67, D<&ISelfController::IsIlluminanceAvailable>, "IsIlluminanceAvailable"},
|
||||
FunctionInfo{68, D<&ISelfController::SetAutoSleepDisabled>, "SetAutoSleepDisabled"},
|
||||
FunctionInfo{69, D<&ISelfController::IsAutoSleepDisabled>, "IsAutoSleepDisabled"},
|
||||
FunctionInfo{70, nullptr, "ReportMultimediaError"},
|
||||
FunctionInfo{71, nullptr, "GetCurrentIlluminanceEx"},
|
||||
FunctionInfo{72, D<&ISelfController::SetInputDetectionPolicy>, "SetInputDetectionPolicy"},
|
||||
FunctionInfo{80, nullptr, "SetWirelessPriorityMode"},
|
||||
FunctionInfo{90, D<&ISelfController::GetAccumulatedSuspendedTickValue>, "GetAccumulatedSuspendedTickValue"},
|
||||
FunctionInfo{91, D<&ISelfController::GetAccumulatedSuspendedTickChangedEvent>, "GetAccumulatedSuspendedTickChangedEvent"},
|
||||
FunctionInfo{100, D<&ISelfController::SetAlbumImageTakenNotificationEnabled>, "SetAlbumImageTakenNotificationEnabled"},
|
||||
FunctionInfo{110, nullptr, "SetApplicationAlbumUserData"},
|
||||
FunctionInfo{120, D<&ISelfController::SaveCurrentScreenshot>, "SaveCurrentScreenshot"},
|
||||
FunctionInfo{130, D<&ISelfController::SetRecordVolumeMuted>, "SetRecordVolumeMuted"},
|
||||
FunctionInfo{230, D<&ISelfController::Unknown230>, "Unknown230"},
|
||||
FunctionInfo{240, D<&ISelfController::Unknown240>, "Unknown240"},
|
||||
FunctionInfo{1000, nullptr, "GetDebugStorageChannel"}
|
||||
);
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
|
||||
ISelfController::ISelfController(Core::System& system_, std::shared_ptr<Applet> applet,
|
||||
Kernel::KProcess* process)
|
||||
: ServiceFramework{system_, "ISelfController"}, m_process{process}, m_applet{
|
||||
std::move(applet)} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, D<&ISelfController::Exit>, "Exit"},
|
||||
{1, D<&ISelfController::LockExit>, "LockExit"},
|
||||
{2, D<&ISelfController::UnlockExit>, "UnlockExit"},
|
||||
{3, D<&ISelfController::EnterFatalSection>, "EnterFatalSection"},
|
||||
{4, D<&ISelfController::LeaveFatalSection>, "LeaveFatalSection"},
|
||||
{9, D<&ISelfController::GetLibraryAppletLaunchableEvent>, "GetLibraryAppletLaunchableEvent"},
|
||||
{10, D<&ISelfController::SetScreenShotPermission>, "SetScreenShotPermission"},
|
||||
{11, D<&ISelfController::SetOperationModeChangedNotification>, "SetOperationModeChangedNotification"},
|
||||
{12, D<&ISelfController::SetPerformanceModeChangedNotification>, "SetPerformanceModeChangedNotification"},
|
||||
{13, D<&ISelfController::SetFocusHandlingMode>, "SetFocusHandlingMode"},
|
||||
{14, D<&ISelfController::SetRestartMessageEnabled>, "SetRestartMessageEnabled"},
|
||||
{15, D<&ISelfController::SetScreenShotAppletIdentityInfo>, "SetScreenShotAppletIdentityInfo"},
|
||||
{16, D<&ISelfController::SetOutOfFocusSuspendingEnabled>, "SetOutOfFocusSuspendingEnabled"},
|
||||
{17, nullptr, "SetControllerFirmwareUpdateSection"},
|
||||
{18, nullptr, "SetRequiresCaptureButtonShortPressedMessage"},
|
||||
{19, D<&ISelfController::SetAlbumImageOrientation>, "SetAlbumImageOrientation"},
|
||||
{20, nullptr, "SetDesirableKeyboardLayout"},
|
||||
{21, nullptr, "GetScreenShotProgramId"},
|
||||
{40, D<&ISelfController::CreateManagedDisplayLayer>, "CreateManagedDisplayLayer"},
|
||||
{41, D<&ISelfController::IsSystemBufferSharingEnabled>, "IsSystemBufferSharingEnabled"},
|
||||
{42, D<&ISelfController::GetSystemSharedLayerHandle>, "GetSystemSharedLayerHandle"},
|
||||
{43, D<&ISelfController::GetSystemSharedBufferHandle>, "GetSystemSharedBufferHandle"},
|
||||
{44, D<&ISelfController::CreateManagedDisplaySeparableLayer>, "CreateManagedDisplaySeparableLayer"},
|
||||
{45, nullptr, "SetManagedDisplayLayerSeparationMode"},
|
||||
{46, nullptr, "SetRecordingLayerCompositionEnabled"},
|
||||
{50, D<&ISelfController::SetHandlesRequestToDisplay>, "SetHandlesRequestToDisplay"},
|
||||
{51, D<&ISelfController::ApproveToDisplay>, "ApproveToDisplay"},
|
||||
{60, D<&ISelfController::OverrideAutoSleepTimeAndDimmingTime>, "OverrideAutoSleepTimeAndDimmingTime"},
|
||||
{61, D<&ISelfController::SetMediaPlaybackState>, "SetMediaPlaybackState"},
|
||||
{62, D<&ISelfController::SetIdleTimeDetectionExtension>, "SetIdleTimeDetectionExtension"},
|
||||
{63, D<&ISelfController::GetIdleTimeDetectionExtension>, "GetIdleTimeDetectionExtension"},
|
||||
{64, nullptr, "SetInputDetectionSourceSet"},
|
||||
{65, D<&ISelfController::ReportUserIsActive>, "ReportUserIsActive"},
|
||||
{66, nullptr, "GetCurrentIlluminance"},
|
||||
{67, D<&ISelfController::IsIlluminanceAvailable>, "IsIlluminanceAvailable"},
|
||||
{68, D<&ISelfController::SetAutoSleepDisabled>, "SetAutoSleepDisabled"},
|
||||
{69, D<&ISelfController::IsAutoSleepDisabled>, "IsAutoSleepDisabled"},
|
||||
{70, nullptr, "ReportMultimediaError"},
|
||||
{71, nullptr, "GetCurrentIlluminanceEx"},
|
||||
{72, D<&ISelfController::SetInputDetectionPolicy>, "SetInputDetectionPolicy"},
|
||||
{80, nullptr, "SetWirelessPriorityMode"},
|
||||
{90, D<&ISelfController::GetAccumulatedSuspendedTickValue>, "GetAccumulatedSuspendedTickValue"},
|
||||
{91, D<&ISelfController::GetAccumulatedSuspendedTickChangedEvent>, "GetAccumulatedSuspendedTickChangedEvent"},
|
||||
{100, D<&ISelfController::SetAlbumImageTakenNotificationEnabled>, "SetAlbumImageTakenNotificationEnabled"},
|
||||
{110, nullptr, "SetApplicationAlbumUserData"},
|
||||
{120, D<&ISelfController::SaveCurrentScreenshot>, "SaveCurrentScreenshot"},
|
||||
{130, D<&ISelfController::SetRecordVolumeMuted>, "SetRecordVolumeMuted"},
|
||||
{230, D<&ISelfController::Unknown230>, "Unknown230"},
|
||||
{240, D<&ISelfController::Unknown240>, "Unknown240"},
|
||||
{1000, nullptr, "GetDebugStorageChannel"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
|
||||
std::scoped_lock lk{m_applet->lock};
|
||||
m_applet->display_layer_manager.Initialize(system, m_process, m_applet->applet_id,
|
||||
m_applet->library_applet_mode);
|
||||
|
||||
@@ -70,6 +70,7 @@ private:
|
||||
Result Unknown230(u32 in_val, Out<u16> out_val);
|
||||
Result Unknown240(u32 in_val);
|
||||
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override;
|
||||
Kernel::KProcess* const m_process;
|
||||
const std::shared_ptr<Applet> m_applet;
|
||||
};
|
||||
|
||||
@@ -4,22 +4,86 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "core/hle/kernel/k_transfer_memory.h"
|
||||
#include "core/hle/service/am/am_results.h"
|
||||
#include "core/hle/service/am/library_applet_storage.h"
|
||||
#include "core/hle/service/am/service/storage.h"
|
||||
#include "core/hle/service/am/service/storage_accessor.h"
|
||||
#include "core/hle/service/cmif_serialization.h"
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
class IStorageAccessor final : public ServiceFramework<IStorageAccessor> {
|
||||
public:
|
||||
explicit IStorageAccessor(Core::System& system_, std::shared_ptr<LibraryAppletStorage> impl) : ServiceFramework{system_, "IStorageAccessor"}, m_impl{std::move(impl)} {}
|
||||
~IStorageAccessor() override = default;
|
||||
|
||||
Result GetSize(Out<s64> out_size) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_size = m_impl->GetSize();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result Write(InBuffer<BufferAttr_HipcAutoSelect> buffer, s64 offset) {
|
||||
LOG_DEBUG(Service_AM, "called, offset={} size={}", offset, buffer.size());
|
||||
R_RETURN(m_impl->Write(offset, buffer.data(), buffer.size()));
|
||||
}
|
||||
|
||||
Result Read(OutBuffer<BufferAttr_HipcAutoSelect> out_buffer, s64 offset) {
|
||||
LOG_DEBUG(Service_AM, "called, offset={} size={}", offset, out_buffer.size());
|
||||
R_RETURN(m_impl->Read(offset, out_buffer.data(), out_buffer.size()));
|
||||
}
|
||||
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, D<&IStorageAccessor::GetSize>, "GetSize"},
|
||||
FunctionInfo{10, D<&IStorageAccessor::Write>, "Write"},
|
||||
FunctionInfo{11, D<&IStorageAccessor::Read>, "Read"}
|
||||
);
|
||||
|
||||
const std::shared_ptr<LibraryAppletStorage> m_impl;
|
||||
};
|
||||
|
||||
class ITransferStorageAccessor final : public ServiceFramework<ITransferStorageAccessor> {
|
||||
public:
|
||||
explicit ITransferStorageAccessor(Core::System& system_, std::shared_ptr<LibraryAppletStorage> impl) : ServiceFramework{system_, "ITransferStorageAccessor"}, m_impl{std::move(impl)} {}
|
||||
~ITransferStorageAccessor() override = default;
|
||||
|
||||
Result GetSize(Out<s64> out_size) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_size = m_impl->GetSize();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result GetHandle(Out<s64> out_size, OutCopyHandle<Kernel::KTransferMemory> out_handle) {
|
||||
LOG_INFO(Service_AM, "called");
|
||||
*out_size = m_impl->GetSize();
|
||||
*out_handle = m_impl->GetHandle();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, D<&ITransferStorageAccessor::GetSize>, "GetSize"},
|
||||
FunctionInfo{1, D<&ITransferStorageAccessor::GetHandle>, "GetHandle"}
|
||||
);
|
||||
|
||||
const std::shared_ptr<LibraryAppletStorage> m_impl;
|
||||
};
|
||||
|
||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> IStorage::FindRequest(u32 key) {
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, D<&IStorage::Open>, "Open"},
|
||||
FunctionInfo{1, D<&IStorage::OpenTransferStorage>, "OpenTransferStorage"}
|
||||
);
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
|
||||
IStorage::IStorage(Core::System& system_, std::shared_ptr<LibraryAppletStorage> impl)
|
||||
: ServiceFramework{system_, "IStorage"}, m_impl{std::move(impl)} {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, D<&IStorage::Open>, "Open"},
|
||||
{1, D<&IStorage::OpenTransferStorage>, "OpenTransferStorage"},
|
||||
};
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
IStorage::IStorage(Core::System& system_, std::vector<u8>&& data)
|
||||
|
||||
@@ -32,6 +32,7 @@ private:
|
||||
Result OpenTransferStorage(
|
||||
Out<SharedPointer<ITransferStorageAccessor>> out_transfer_storage_accessor);
|
||||
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override;
|
||||
const std::shared_ptr<LibraryAppletStorage> m_impl;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "core/hle/kernel/k_transfer_memory.h"
|
||||
#include "core/hle/service/am/library_applet_storage.h"
|
||||
#include "core/hle/service/am/service/storage_accessor.h"
|
||||
#include "core/hle/service/cmif_serialization.h"
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
IStorageAccessor::IStorageAccessor(Core::System& system_,
|
||||
std::shared_ptr<LibraryAppletStorage> impl)
|
||||
: ServiceFramework{system_, "IStorageAccessor"}, m_impl{std::move(impl)} {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, D<&IStorageAccessor::GetSize>, "GetSize"},
|
||||
{10, D<&IStorageAccessor::Write>, "Write"},
|
||||
{11, D<&IStorageAccessor::Read>, "Read"},
|
||||
};
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
IStorageAccessor::~IStorageAccessor() = default;
|
||||
|
||||
Result IStorageAccessor::GetSize(Out<s64> out_size) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_size = m_impl->GetSize();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IStorageAccessor::Write(InBuffer<BufferAttr_HipcAutoSelect> buffer, s64 offset) {
|
||||
LOG_DEBUG(Service_AM, "called, offset={} size={}", offset, buffer.size());
|
||||
R_RETURN(m_impl->Write(offset, buffer.data(), buffer.size()));
|
||||
}
|
||||
|
||||
Result IStorageAccessor::Read(OutBuffer<BufferAttr_HipcAutoSelect> out_buffer, s64 offset) {
|
||||
LOG_DEBUG(Service_AM, "called, offset={} size={}", offset, out_buffer.size());
|
||||
R_RETURN(m_impl->Read(offset, out_buffer.data(), out_buffer.size()));
|
||||
}
|
||||
|
||||
ITransferStorageAccessor::ITransferStorageAccessor(Core::System& system_,
|
||||
std::shared_ptr<LibraryAppletStorage> impl)
|
||||
: ServiceFramework{system_, "ITransferStorageAccessor"}, m_impl{std::move(impl)} {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, D<&ITransferStorageAccessor::GetSize>, "GetSize"},
|
||||
{1, D<&ITransferStorageAccessor::GetHandle>, "GetHandle"},
|
||||
};
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
ITransferStorageAccessor::~ITransferStorageAccessor() = default;
|
||||
|
||||
Result ITransferStorageAccessor::GetSize(Out<s64> out_size) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_size = m_impl->GetSize();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ITransferStorageAccessor::GetHandle(Out<s64> out_size,
|
||||
OutCopyHandle<Kernel::KTransferMemory> out_handle) {
|
||||
LOG_INFO(Service_AM, "called");
|
||||
*out_size = m_impl->GetSize();
|
||||
*out_handle = m_impl->GetHandle();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
} // namespace Service::AM
|
||||
@@ -1,41 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/am/library_applet_storage.h"
|
||||
#include "core/hle/service/cmif_types.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
class IStorageAccessor final : public ServiceFramework<IStorageAccessor> {
|
||||
public:
|
||||
explicit IStorageAccessor(Core::System& system_, std::shared_ptr<LibraryAppletStorage> impl);
|
||||
~IStorageAccessor() override;
|
||||
|
||||
private:
|
||||
Result GetSize(Out<s64> out_size);
|
||||
Result Write(InBuffer<BufferAttr_HipcAutoSelect> buffer, s64 offset);
|
||||
Result Read(OutBuffer<BufferAttr_HipcAutoSelect> out_buffer, s64 offset);
|
||||
|
||||
const std::shared_ptr<LibraryAppletStorage> m_impl;
|
||||
};
|
||||
|
||||
class ITransferStorageAccessor final : public ServiceFramework<ITransferStorageAccessor> {
|
||||
public:
|
||||
explicit ITransferStorageAccessor(Core::System& system_,
|
||||
std::shared_ptr<LibraryAppletStorage> impl);
|
||||
~ITransferStorageAccessor() override;
|
||||
|
||||
private:
|
||||
Result GetSize(Out<s64> out_size);
|
||||
Result GetHandle(Out<s64> out_size, OutCopyHandle<Kernel::KTransferMemory> out_handle);
|
||||
|
||||
const std::shared_ptr<LibraryAppletStorage> m_impl;
|
||||
};
|
||||
|
||||
} // namespace Service::AM
|
||||
@@ -1,136 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "core/hle/service/am/service/applet_common_functions.h"
|
||||
#include "core/hle/service/am/service/application_creator.h"
|
||||
#include "core/hle/service/am/service/audio_controller.h"
|
||||
#include "core/hle/service/am/service/common_state_getter.h"
|
||||
#include "core/hle/service/am/service/debug_functions.h"
|
||||
#include "core/hle/service/am/service/display_controller.h"
|
||||
#include "core/hle/service/am/service/global_state_controller.h"
|
||||
#include "core/hle/service/am/service/home_menu_functions.h"
|
||||
#include "core/hle/service/am/service/library_applet_creator.h"
|
||||
#include "core/hle/service/am/service/process_winding_controller.h"
|
||||
#include "core/hle/service/am/service/self_controller.h"
|
||||
#include "core/hle/service/am/service/system_applet_proxy.h"
|
||||
#include "core/hle/service/am/service/window_controller.h"
|
||||
#include "core/hle/service/cmif_serialization.h"
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
ISystemAppletProxy::ISystemAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet,
|
||||
Kernel::KProcess* process, WindowSystem& window_system)
|
||||
: ServiceFramework{system_, "ISystemAppletProxy"},
|
||||
m_window_system{window_system}, m_process{process}, m_applet{std::move(applet)} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, D<&ISystemAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"},
|
||||
{1, D<&ISystemAppletProxy::GetSelfController>, "GetSelfController"},
|
||||
{2, D<&ISystemAppletProxy::GetWindowController>, "GetWindowController"},
|
||||
{3, D<&ISystemAppletProxy::GetAudioController>, "GetAudioController"},
|
||||
{4, D<&ISystemAppletProxy::GetDisplayController>, "GetDisplayController"},
|
||||
{10, D<&ISystemAppletProxy::GetProcessWindingController>, "GetProcessWindingController"},
|
||||
{11, D<&ISystemAppletProxy::GetLibraryAppletCreator>, "GetLibraryAppletCreator"},
|
||||
{20, D<&ISystemAppletProxy::GetHomeMenuFunctions>, "GetHomeMenuFunctions"},
|
||||
{21, D<&ISystemAppletProxy::GetGlobalStateController>, "GetGlobalStateController"},
|
||||
{22, D<&ISystemAppletProxy::GetApplicationCreator>, "GetApplicationCreator"},
|
||||
{23, D<&ISystemAppletProxy::GetAppletCommonFunctions>, "GetAppletCommonFunctions"},
|
||||
{1000, D<&ISystemAppletProxy::GetDebugFunctions>, "GetDebugFunctions"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
ISystemAppletProxy::~ISystemAppletProxy() = default;
|
||||
|
||||
Result ISystemAppletProxy::GetAudioController(
|
||||
Out<SharedPointer<IAudioController>> out_audio_controller) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_audio_controller = std::make_shared<IAudioController>(system);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ISystemAppletProxy::GetDisplayController(
|
||||
Out<SharedPointer<IDisplayController>> out_display_controller) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_display_controller = std::make_shared<IDisplayController>(system, m_applet);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ISystemAppletProxy::GetProcessWindingController(
|
||||
Out<SharedPointer<IProcessWindingController>> out_process_winding_controller) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_process_winding_controller = std::make_shared<IProcessWindingController>(system, m_applet);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ISystemAppletProxy::GetDebugFunctions(
|
||||
Out<SharedPointer<IDebugFunctions>> out_debug_functions) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_debug_functions = std::make_shared<IDebugFunctions>(system);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ISystemAppletProxy::GetWindowController(
|
||||
Out<SharedPointer<IWindowController>> out_window_controller) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_window_controller = std::make_shared<IWindowController>(system, m_applet, m_window_system);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ISystemAppletProxy::GetSelfController(
|
||||
Out<SharedPointer<ISelfController>> out_self_controller) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_self_controller = std::make_shared<ISelfController>(system, m_applet, m_process);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ISystemAppletProxy::GetCommonStateGetter(
|
||||
Out<SharedPointer<ICommonStateGetter>> out_common_state_getter) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_common_state_getter = std::make_shared<ICommonStateGetter>(system, m_applet);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ISystemAppletProxy::GetLibraryAppletCreator(
|
||||
Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_library_applet_creator =
|
||||
std::make_shared<ILibraryAppletCreator>(system, m_applet, m_window_system);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ISystemAppletProxy::GetApplicationCreator(
|
||||
Out<SharedPointer<IApplicationCreator>> out_application_creator) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_application_creator = std::make_shared<IApplicationCreator>(system, m_window_system);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ISystemAppletProxy::GetAppletCommonFunctions(
|
||||
Out<SharedPointer<IAppletCommonFunctions>> out_applet_common_functions) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_applet_common_functions = std::make_shared<IAppletCommonFunctions>(system, m_applet);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ISystemAppletProxy::GetHomeMenuFunctions(
|
||||
Out<SharedPointer<IHomeMenuFunctions>> out_home_menu_functions) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_home_menu_functions =
|
||||
std::make_shared<IHomeMenuFunctions>(system, m_applet, m_window_system);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ISystemAppletProxy::GetGlobalStateController(
|
||||
Out<SharedPointer<IGlobalStateController>> out_global_state_controller) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_global_state_controller = std::make_shared<IGlobalStateController>(system);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
} // namespace Service::AM
|
||||
@@ -1,58 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/cmif_types.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
struct Applet;
|
||||
class IAppletCommonFunctions;
|
||||
class IApplicationCreator;
|
||||
class IAudioController;
|
||||
class ICommonStateGetter;
|
||||
class IDebugFunctions;
|
||||
class IDisplayController;
|
||||
class IHomeMenuFunctions;
|
||||
class IGlobalStateController;
|
||||
class ILibraryAppletCreator;
|
||||
class IProcessWindingController;
|
||||
class ISelfController;
|
||||
class IWindowController;
|
||||
class WindowSystem;
|
||||
|
||||
class ISystemAppletProxy final : public ServiceFramework<ISystemAppletProxy> {
|
||||
public:
|
||||
explicit ISystemAppletProxy(Core::System& system, std::shared_ptr<Applet> applet,
|
||||
Kernel::KProcess* process, WindowSystem& window_system);
|
||||
~ISystemAppletProxy();
|
||||
|
||||
private:
|
||||
Result GetCommonStateGetter(Out<SharedPointer<ICommonStateGetter>> out_common_state_getter);
|
||||
Result GetSelfController(Out<SharedPointer<ISelfController>> out_self_controller);
|
||||
Result GetWindowController(Out<SharedPointer<IWindowController>> out_window_controller);
|
||||
Result GetAudioController(Out<SharedPointer<IAudioController>> out_audio_controller);
|
||||
Result GetDisplayController(Out<SharedPointer<IDisplayController>> out_display_controller);
|
||||
Result GetProcessWindingController(
|
||||
Out<SharedPointer<IProcessWindingController>> out_process_winding_controller);
|
||||
Result GetDebugFunctions(Out<SharedPointer<IDebugFunctions>> out_debug_functions);
|
||||
Result GetLibraryAppletCreator(
|
||||
Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator);
|
||||
Result GetApplicationCreator(Out<SharedPointer<IApplicationCreator>> out_application_creator);
|
||||
Result GetAppletCommonFunctions(
|
||||
Out<SharedPointer<IAppletCommonFunctions>> out_applet_common_functions);
|
||||
Result GetHomeMenuFunctions(Out<SharedPointer<IHomeMenuFunctions>> out_home_menu_functions);
|
||||
Result GetGlobalStateController(
|
||||
Out<SharedPointer<IGlobalStateController>> out_global_state_controller);
|
||||
|
||||
WindowSystem& m_window_system;
|
||||
Kernel::KProcess* const m_process;
|
||||
const std::shared_ptr<Applet> m_applet;
|
||||
};
|
||||
|
||||
} // namespace Service::AM
|
||||
@@ -12,24 +12,24 @@
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> IWindowController::FindRequest(u32 key) {
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, nullptr, "CreateWindow"},
|
||||
FunctionInfo{1, D<&IWindowController::GetAppletResourceUserId>, "GetAppletResourceUserId"},
|
||||
FunctionInfo{2, D<&IWindowController::GetAppletResourceUserIdOfCallerApplet>, "GetAppletResourceUserIdOfCallerApplet"},
|
||||
FunctionInfo{10, D<&IWindowController::AcquireForegroundRights>, "AcquireForegroundRights"},
|
||||
FunctionInfo{11, D<&IWindowController::ReleaseForegroundRights>, "ReleaseForegroundRights"},
|
||||
FunctionInfo{12, D<&IWindowController::RejectToChangeIntoBackground>, "RejectToChangeIntoBackground"},
|
||||
FunctionInfo{20, D<&IWindowController::SetAppletWindowVisibility>, "SetAppletWindowVisibility"},
|
||||
FunctionInfo{21, D<&IWindowController::SetAppletGpuTimeSlice>, "SetAppletGpuTimeSlice"}
|
||||
);
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
|
||||
IWindowController::IWindowController(Core::System& system_, std::shared_ptr<Applet> applet,
|
||||
WindowSystem& window_system)
|
||||
: ServiceFramework{system_, "IWindowController"},
|
||||
m_window_system{window_system}, m_applet{std::move(applet)} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "CreateWindow"},
|
||||
{1, D<&IWindowController::GetAppletResourceUserId>, "GetAppletResourceUserId"},
|
||||
{2, D<&IWindowController::GetAppletResourceUserIdOfCallerApplet>, "GetAppletResourceUserIdOfCallerApplet"},
|
||||
{10, D<&IWindowController::AcquireForegroundRights>, "AcquireForegroundRights"},
|
||||
{11, D<&IWindowController::ReleaseForegroundRights>, "ReleaseForegroundRights"},
|
||||
{12, D<&IWindowController::RejectToChangeIntoBackground>, "RejectToChangeIntoBackground"},
|
||||
{20, D<&IWindowController::SetAppletWindowVisibility>, "SetAppletWindowVisibility"},
|
||||
{21, D<&IWindowController::SetAppletGpuTimeSlice>, "SetAppletGpuTimeSlice"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
IWindowController::~IWindowController() = default;
|
||||
|
||||
@@ -29,6 +29,7 @@ private:
|
||||
Result SetAppletWindowVisibility(bool visible);
|
||||
Result SetAppletGpuTimeSlice(s64 time_slice);
|
||||
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override;
|
||||
WindowSystem& m_window_system;
|
||||
const std::shared_ptr<Applet> m_applet;
|
||||
};
|
||||
|
||||
@@ -28,6 +28,34 @@
|
||||
|
||||
namespace Service::AOC {
|
||||
|
||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> IAddOnContentManager::FindRequest(u32 key) {
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, nullptr, "CountAddOnContentByApplicationId"},
|
||||
FunctionInfo{1, nullptr, "ListAddOnContentByApplicationId"},
|
||||
FunctionInfo{2, D<&IAddOnContentManager::CountAddOnContent>, "CountAddOnContent"},
|
||||
FunctionInfo{3, D<&IAddOnContentManager::ListAddOnContent>, "ListAddOnContent"},
|
||||
FunctionInfo{4, nullptr, "GetAddOnContentBaseIdByApplicationId"},
|
||||
FunctionInfo{5, D<&IAddOnContentManager::GetAddOnContentBaseId>, "GetAddOnContentBaseId"},
|
||||
FunctionInfo{6, nullptr, "PrepareAddOnContentByApplicationId"},
|
||||
FunctionInfo{7, D<&IAddOnContentManager::PrepareAddOnContent>, "PrepareAddOnContent"},
|
||||
FunctionInfo{8, D<&IAddOnContentManager::GetAddOnContentListChangedEvent>, "GetAddOnContentListChangedEvent"},
|
||||
FunctionInfo{9, nullptr, "GetAddOnContentLostErrorCode"},
|
||||
FunctionInfo{10, D<&IAddOnContentManager::GetAddOnContentListChangedEventWithProcessId>, "GetAddOnContentListChangedEventWithProcessId"},
|
||||
FunctionInfo{11, D<&IAddOnContentManager::NotifyMountAddOnContent>, "NotifyMountAddOnContent"},
|
||||
FunctionInfo{12, D<&IAddOnContentManager::NotifyUnmountAddOnContent>, "NotifyUnmountAddOnContent"},
|
||||
FunctionInfo{13, nullptr, "IsAddOnContentMountedForDebug"},
|
||||
FunctionInfo{50, D<&IAddOnContentManager::CheckAddOnContentMountStatus>, "CheckAddOnContentMountStatus"},
|
||||
FunctionInfo{100, D<&IAddOnContentManager::CreateEcPurchasedEventManager>, "CreateEcPurchasedEventManager"},
|
||||
FunctionInfo{101, D<&IAddOnContentManager::CreatePermanentEcPurchasedEventManager>, "CreatePermanentEcPurchasedEventManager"},
|
||||
FunctionInfo{110, nullptr, "CreateContentsServiceManager"},
|
||||
FunctionInfo{200, nullptr, "SetRequiredAddOnContentsOnContentsAvailabilityTransition"},
|
||||
FunctionInfo{300, nullptr, "SetupHostAddOnContent"},
|
||||
FunctionInfo{301, nullptr, "GetRegisteredAddOnContentPath"},
|
||||
FunctionInfo{302, nullptr, "UpdateCachedList"}
|
||||
);
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
|
||||
static bool CheckAOCTitleIDMatchesBase(u64 title_id, u64 base) {
|
||||
return FileSys::GetBaseTitleID(title_id) == base;
|
||||
}
|
||||
@@ -57,35 +85,6 @@ static std::vector<u64> AccumulateAOCTitleIDs(Core::System& system) {
|
||||
IAddOnContentManager::IAddOnContentManager(Core::System& system_)
|
||||
: ServiceFramework{system_, "aoc:u"}, add_on_content{AccumulateAOCTitleIDs(system)},
|
||||
service_context{system_, "aoc:u"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "CountAddOnContentByApplicationId"},
|
||||
{1, nullptr, "ListAddOnContentByApplicationId"},
|
||||
{2, D<&IAddOnContentManager::CountAddOnContent>, "CountAddOnContent"},
|
||||
{3, D<&IAddOnContentManager::ListAddOnContent>, "ListAddOnContent"},
|
||||
{4, nullptr, "GetAddOnContentBaseIdByApplicationId"},
|
||||
{5, D<&IAddOnContentManager::GetAddOnContentBaseId>, "GetAddOnContentBaseId"},
|
||||
{6, nullptr, "PrepareAddOnContentByApplicationId"},
|
||||
{7, D<&IAddOnContentManager::PrepareAddOnContent>, "PrepareAddOnContent"},
|
||||
{8, D<&IAddOnContentManager::GetAddOnContentListChangedEvent>, "GetAddOnContentListChangedEvent"},
|
||||
{9, nullptr, "GetAddOnContentLostErrorCode"},
|
||||
{10, D<&IAddOnContentManager::GetAddOnContentListChangedEventWithProcessId>, "GetAddOnContentListChangedEventWithProcessId"},
|
||||
{11, D<&IAddOnContentManager::NotifyMountAddOnContent>, "NotifyMountAddOnContent"},
|
||||
{12, D<&IAddOnContentManager::NotifyUnmountAddOnContent>, "NotifyUnmountAddOnContent"},
|
||||
{13, nullptr, "IsAddOnContentMountedForDebug"},
|
||||
{50, D<&IAddOnContentManager::CheckAddOnContentMountStatus>, "CheckAddOnContentMountStatus"},
|
||||
{100, D<&IAddOnContentManager::CreateEcPurchasedEventManager>, "CreateEcPurchasedEventManager"},
|
||||
{101, D<&IAddOnContentManager::CreatePermanentEcPurchasedEventManager>, "CreatePermanentEcPurchasedEventManager"},
|
||||
{110, nullptr, "CreateContentsServiceManager"},
|
||||
{200, nullptr, "SetRequiredAddOnContentsOnContentsAvailabilityTransition"},
|
||||
{300, nullptr, "SetupHostAddOnContent"},
|
||||
{301, nullptr, "GetRegisteredAddOnContentPath"},
|
||||
{302, nullptr, "UpdateCachedList"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
|
||||
aoc_change_event = service_context.CreateEvent("GetAddOnContentListChanged:Event");
|
||||
}
|
||||
|
||||
|
||||
@@ -43,9 +43,9 @@ public:
|
||||
OutInterface<IPurchaseEventManager> out_interface);
|
||||
|
||||
private:
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override;
|
||||
std::vector<u64> add_on_content;
|
||||
KernelHelpers::ServiceContext service_context;
|
||||
|
||||
Kernel::KEvent* aoc_change_event;
|
||||
};
|
||||
|
||||
|
||||
@@ -11,21 +11,20 @@ namespace Service::AOC {
|
||||
|
||||
constexpr Result ResultNoPurchasedProductInfoAvailable{ErrorModule::NIMShop, 400};
|
||||
|
||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> IPurchaseEventManager::FindRequest(u32 key) {
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, D<&IPurchaseEventManager::SetDefaultDeliveryTarget>, "SetDefaultDeliveryTarget"},
|
||||
FunctionInfo{1, D<&IPurchaseEventManager::SetDeliveryTarget>, "SetDeliveryTarget"},
|
||||
FunctionInfo{2, D<&IPurchaseEventManager::GetPurchasedEvent>, "GetPurchasedEvent"},
|
||||
FunctionInfo{3, D<&IPurchaseEventManager::PopPurchasedProductInfo>, "PopPurchasedProductInfo"},
|
||||
FunctionInfo{4, D<&IPurchaseEventManager::PopPurchasedProductInfoWithUid>, "PopPurchasedProductInfoWithUid"}
|
||||
);
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
|
||||
IPurchaseEventManager::IPurchaseEventManager(Core::System& system_)
|
||||
: ServiceFramework{system_, "IPurchaseEventManager"}, service_context{system,
|
||||
"IPurchaseEventManager"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, D<&IPurchaseEventManager::SetDefaultDeliveryTarget>, "SetDefaultDeliveryTarget"},
|
||||
{1, D<&IPurchaseEventManager::SetDeliveryTarget>, "SetDeliveryTarget"},
|
||||
{2, D<&IPurchaseEventManager::GetPurchasedEvent>, "GetPurchasedEvent"},
|
||||
{3, D<&IPurchaseEventManager::PopPurchasedProductInfo>, "PopPurchasedProductInfo"},
|
||||
{4, D<&IPurchaseEventManager::PopPurchasedProductInfoWithUid>, "PopPurchasedProductInfoWithUid"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
|
||||
: ServiceFramework{system_, "IPurchaseEventManager"}
|
||||
, service_context{system, "IPurchaseEventManager"} {
|
||||
purchased_event = service_context.CreateEvent("IPurchaseEventManager:PurchasedEvent");
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@ public:
|
||||
Result PopPurchasedProductInfo();
|
||||
Result PopPurchasedProductInfoWithUid();
|
||||
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override;
|
||||
|
||||
private:
|
||||
KernelHelpers::ServiceContext service_context;
|
||||
Kernel::KEvent* purchased_event;
|
||||
|
||||
@@ -14,15 +14,7 @@ namespace Service::APM {
|
||||
|
||||
class ISession final : public ServiceFramework<ISession> {
|
||||
public:
|
||||
explicit ISession(Core::System& system_, Controller& controller_)
|
||||
: ServiceFramework{system_, "ISession"}, controller{controller_} {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &ISession::SetPerformanceConfiguration, "SetPerformanceConfiguration"},
|
||||
{1, &ISession::GetPerformanceConfiguration, "GetPerformanceConfiguration"},
|
||||
{2, &ISession::SetCpuOverclockEnabled, "SetCpuOverclockEnabled"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
explicit ISession(Core::System& system_, Controller& controller_) : ServiceFramework{system_, "ISession"}, controller{controller_} {}
|
||||
|
||||
private:
|
||||
void SetPerformanceConfiguration(HLERequestContext& ctx) {
|
||||
@@ -61,18 +53,20 @@ private:
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, &ISession::SetPerformanceConfiguration, "SetPerformanceConfiguration"},
|
||||
FunctionInfo{1, &ISession::GetPerformanceConfiguration, "GetPerformanceConfiguration"},
|
||||
FunctionInfo{2, &ISession::SetCpuOverclockEnabled, "SetCpuOverclockEnabled"}
|
||||
);
|
||||
Controller& controller;
|
||||
};
|
||||
|
||||
APM::APM(Core::System& system_, std::shared_ptr<Module> apm_, Controller& controller_,
|
||||
const char* name)
|
||||
: ServiceFramework{system_, name}, apm(std::move(apm_)), controller{controller_} {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &APM::OpenSession, "OpenSession"},
|
||||
{1, &APM::GetPerformanceMode, "GetPerformanceMode"},
|
||||
{6, &APM::IsCpuOverclockEnabled, "IsCpuOverclockEnabled"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
APM::~APM() = default;
|
||||
@@ -102,20 +96,6 @@ void APM::IsCpuOverclockEnabled(HLERequestContext& ctx) {
|
||||
|
||||
APM_Sys::APM_Sys(Core::System& system_, Controller& controller_)
|
||||
: ServiceFramework{system_, "apm:sys"}, controller{controller_} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "RequestPerformanceMode"},
|
||||
{1, &APM_Sys::GetPerformanceEvent, "GetPerformanceEvent"},
|
||||
{2, nullptr, "GetThrottlingState"},
|
||||
{3, nullptr, "GetLastThrottlingState"},
|
||||
{4, nullptr, "ClearLastThrottlingState"},
|
||||
{5, nullptr, "LoadAndApplySettings"},
|
||||
{6, &APM_Sys::SetCpuBoostMode, "SetCpuBoostMode"},
|
||||
{7, &APM_Sys::GetCurrentPerformanceConfiguration, "GetCurrentPerformanceConfiguration"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
APM_Sys::~APM_Sys() = default;
|
||||
|
||||
@@ -24,6 +24,14 @@ private:
|
||||
void GetPerformanceMode(HLERequestContext& ctx);
|
||||
void IsCpuOverclockEnabled(HLERequestContext& ctx);
|
||||
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, &APM::OpenSession, "OpenSession"},
|
||||
FunctionInfo{1, &APM::GetPerformanceMode, "GetPerformanceMode"},
|
||||
FunctionInfo{6, &APM::IsCpuOverclockEnabled, "IsCpuOverclockEnabled"}
|
||||
);
|
||||
std::shared_ptr<Module> apm;
|
||||
Controller& controller;
|
||||
};
|
||||
@@ -39,6 +47,19 @@ private:
|
||||
void GetPerformanceEvent(HLERequestContext& ctx);
|
||||
void GetCurrentPerformanceConfiguration(HLERequestContext& ctx);
|
||||
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, nullptr, "RequestPerformanceMode"},
|
||||
FunctionInfo{1, &APM_Sys::GetPerformanceEvent, "GetPerformanceEvent"},
|
||||
FunctionInfo{2, nullptr, "GetThrottlingState"},
|
||||
FunctionInfo{3, nullptr, "GetLastThrottlingState"},
|
||||
FunctionInfo{4, nullptr, "ClearLastThrottlingState"},
|
||||
FunctionInfo{5, nullptr, "LoadAndApplySettings"},
|
||||
FunctionInfo{6, &APM_Sys::SetCpuBoostMode, "SetCpuBoostMode"},
|
||||
FunctionInfo{7, &APM_Sys::GetCurrentPerformanceConfiguration, "GetCurrentPerformanceConfiguration"}
|
||||
);
|
||||
Controller& controller;
|
||||
};
|
||||
|
||||
|
||||
@@ -21,164 +21,164 @@ namespace Service::Audio {
|
||||
class IAudioOutManagerForApplet final : public ServiceFramework<IAudioOutManagerForApplet> {
|
||||
public:
|
||||
explicit IAudioOutManagerForApplet(Core::System& system_)
|
||||
: ServiceFramework{system_, "audout:a"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "RequestSuspend"},
|
||||
{1, nullptr, "RequestResume"},
|
||||
{2, nullptr, "GetProcessMasterVolume"},
|
||||
{3, nullptr, "SetProcessMasterVolume"},
|
||||
{4, nullptr, "GetProcessRecordVolume"},
|
||||
{5, nullptr, "SetProcessRecordVolume"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
: ServiceFramework{system_, "audout:a"} {}
|
||||
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, nullptr, "RequestSuspend"},
|
||||
FunctionInfo{1, nullptr, "RequestResume"},
|
||||
FunctionInfo{2, nullptr, "GetProcessMasterVolume"},
|
||||
FunctionInfo{3, nullptr, "SetProcessMasterVolume"},
|
||||
FunctionInfo{4, nullptr, "GetProcessRecordVolume"},
|
||||
FunctionInfo{5, nullptr, "SetProcessRecordVolume"}
|
||||
);
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
};
|
||||
|
||||
class IAudioSnoopManager final : public ServiceFramework<IAudioSnoopManager> {
|
||||
public:
|
||||
explicit IAudioSnoopManager(Core::System& system_)
|
||||
: ServiceFramework{system_, "auddev"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetDspStatistics"},
|
||||
{1, nullptr, "GetAppletStateSummaries"},
|
||||
{2, nullptr, "SetDspStatisticsParameter"},
|
||||
{3, nullptr, "GetDspStatisticsParameter"},
|
||||
{6, nullptr, "GetDspUsage"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
: ServiceFramework{system_, "auddev"} {}
|
||||
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, nullptr, "GetDspStatistics"},
|
||||
FunctionInfo{1, nullptr, "GetAppletStateSummaries"},
|
||||
FunctionInfo{2, nullptr, "SetDspStatisticsParameter"},
|
||||
FunctionInfo{3, nullptr, "GetDspStatisticsParameter"},
|
||||
FunctionInfo{6, nullptr, "GetDspUsage"}
|
||||
);
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
};
|
||||
|
||||
class IAudioInManagerForApplet final : public ServiceFramework<IAudioInManagerForApplet> {
|
||||
public:
|
||||
explicit IAudioInManagerForApplet(Core::System& system_)
|
||||
: ServiceFramework{system_, "audin:a"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "RequestSuspend"},
|
||||
{1, nullptr, "RequestResume"},
|
||||
{2, nullptr, "GetProcessMasterVolume"},
|
||||
{3, nullptr, "SetProcessMasterVolume"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
: ServiceFramework{system_, "audin:a"} {}
|
||||
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, nullptr, "RequestSuspend"},
|
||||
FunctionInfo{1, nullptr, "RequestResume"},
|
||||
FunctionInfo{2, nullptr, "GetProcessMasterVolume"},
|
||||
FunctionInfo{3, nullptr, "SetProcessMasterVolume"}
|
||||
);
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
};
|
||||
|
||||
class IAudioRendererManagerForApplet final : public ServiceFramework<IAudioRendererManagerForApplet> {
|
||||
public:
|
||||
explicit IAudioRendererManagerForApplet(Core::System& system_)
|
||||
: ServiceFramework{system_, "audren:a"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "RequestSuspend"},
|
||||
{1, nullptr, "RequestResume"},
|
||||
{2, nullptr, "GetProcessMasterVolume"},
|
||||
{3, nullptr, "SetProcessMasterVolume"},
|
||||
{4, nullptr, "RegisterAppletResourceUserId"},
|
||||
{5, nullptr, "UnregisterAppletResourceUserId"},
|
||||
{6, nullptr, "GetProcessRecordVolume"},
|
||||
{7, nullptr, "SetProcessRecordVolume"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
: ServiceFramework{system_, "audren:a"} {}
|
||||
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, nullptr, "RequestSuspend"},
|
||||
FunctionInfo{1, nullptr, "RequestResume"},
|
||||
FunctionInfo{2, nullptr, "GetProcessMasterVolume"},
|
||||
FunctionInfo{3, nullptr, "SetProcessMasterVolume"},
|
||||
FunctionInfo{4, nullptr, "RegisterAppletResourceUserId"},
|
||||
FunctionInfo{5, nullptr, "UnregisterAppletResourceUserId"},
|
||||
FunctionInfo{6, nullptr, "GetProcessRecordVolume"},
|
||||
FunctionInfo{7, nullptr, "SetProcessRecordVolume"}
|
||||
);
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
};
|
||||
|
||||
class IAudioOutManagerForDebugger final : public ServiceFramework<IAudioOutManagerForDebugger> {
|
||||
public:
|
||||
explicit IAudioOutManagerForDebugger(Core::System& system_)
|
||||
: ServiceFramework{system_, "audout:d"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "RequestSuspend"},
|
||||
{1, nullptr, "RequestResume"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
: ServiceFramework{system_, "audout:d"} {}
|
||||
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, nullptr, "RequestSuspend"},
|
||||
FunctionInfo{1, nullptr, "RequestResume"}
|
||||
);
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
};
|
||||
|
||||
class IAudioInManagerForDebugger final : public ServiceFramework<IAudioInManagerForDebugger> {
|
||||
public:
|
||||
explicit IAudioInManagerForDebugger(Core::System& system_)
|
||||
: ServiceFramework{system_, "audin:d"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "RequestSuspend"},
|
||||
{1, nullptr, "RequestResume"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
: ServiceFramework{system_, "audin:d"} {}
|
||||
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, nullptr, "RequestSuspend"},
|
||||
FunctionInfo{1, nullptr, "RequestResume"}
|
||||
);
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
};
|
||||
|
||||
class IFinalOutputRecorderManagerForDebugger final : public ServiceFramework<IFinalOutputRecorderManagerForDebugger> {
|
||||
public:
|
||||
explicit IFinalOutputRecorderManagerForDebugger(Core::System& system_)
|
||||
: ServiceFramework{system_, "audrec:d"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "RequestSuspend"},
|
||||
{1, nullptr, "RequestResume"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
: ServiceFramework{system_, "audrec:d"} {}
|
||||
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, nullptr, "RequestSuspend"},
|
||||
FunctionInfo{1, nullptr, "RequestResume"}
|
||||
);
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
};
|
||||
|
||||
class IAudioRendererManagerForDebugger final : public ServiceFramework<IAudioRendererManagerForDebugger> {
|
||||
public:
|
||||
explicit IAudioRendererManagerForDebugger(Core::System& system_)
|
||||
: ServiceFramework{system_, "audren:d"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "RequestSuspend"},
|
||||
{1, nullptr, "RequestResume"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
: ServiceFramework{system_, "audren:d"} {}
|
||||
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, nullptr, "RequestSuspend"},
|
||||
FunctionInfo{1, nullptr, "RequestResume"}
|
||||
);
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
};
|
||||
|
||||
class IAudioSystemManagerForApplet final : public ServiceFramework<IAudioSystemManagerForApplet> {
|
||||
public:
|
||||
explicit IAudioSystemManagerForApplet(Core::System& system_)
|
||||
: ServiceFramework{system_, "aud:a"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "RegisterAppletResourceUserId"},
|
||||
{1, nullptr, "UnregisterAppletResourceUserId"},
|
||||
{2, nullptr, "RequestSuspendAudio"},
|
||||
{3, nullptr, "RequestResumeAudio"},
|
||||
{4, nullptr, "GetAudioOutputProcessMasterVolume"},
|
||||
{5, nullptr, "SetAudioOutputProcessMasterVolume"},
|
||||
{6, nullptr, "GetAudioInputProcessMasterVolume"},
|
||||
{7, nullptr, "SetAudioInputProcessMasterVolume"},
|
||||
{8, nullptr, "GetAudioOutputProcessRecordVolume"},
|
||||
{9, nullptr, "SetAudioOutputProcessRecordVolume"},
|
||||
{10, nullptr, "GetAppletStateSummaries"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
: ServiceFramework{system_, "aud:a"} {}
|
||||
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, nullptr, "RegisterAppletResourceUserId"},
|
||||
FunctionInfo{1, nullptr, "UnregisterAppletResourceUserId"},
|
||||
FunctionInfo{2, nullptr, "RequestSuspendAudio"},
|
||||
FunctionInfo{3, nullptr, "RequestResumeAudio"},
|
||||
FunctionInfo{4, nullptr, "GetAudioOutputProcessMasterVolume"},
|
||||
FunctionInfo{5, nullptr, "SetAudioOutputProcessMasterVolume"},
|
||||
FunctionInfo{6, nullptr, "GetAudioInputProcessMasterVolume"},
|
||||
FunctionInfo{7, nullptr, "SetAudioInputProcessMasterVolume"},
|
||||
FunctionInfo{8, nullptr, "GetAudioOutputProcessRecordVolume"},
|
||||
FunctionInfo{9, nullptr, "SetAudioOutputProcessRecordVolume"},
|
||||
FunctionInfo{10, nullptr, "GetAppletStateSummaries"}
|
||||
);
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
};
|
||||
|
||||
class IAudioSystemManagerForDebugger final : public ServiceFramework<IAudioSystemManagerForDebugger> {
|
||||
public:
|
||||
explicit IAudioSystemManagerForDebugger(Core::System& system_)
|
||||
: ServiceFramework{system_, "aud:d"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "RequestSuspendAudioForDebug"},
|
||||
{1, nullptr, "RequestResumeAudioForDebug"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
: ServiceFramework{system_, "aud:d"} {}
|
||||
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, nullptr, "RequestSuspendAudioForDebug"},
|
||||
FunctionInfo{1, nullptr, "RequestResumeAudioForDebug"}
|
||||
);
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -17,77 +17,75 @@
|
||||
|
||||
namespace Service::Audio {
|
||||
|
||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> IAudioController::FindRequest(u32 key) {
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, D<&IAudioController::GetTargetVolume>, "GetTargetVolume"},
|
||||
FunctionInfo{1, D<&IAudioController::SetTargetVolume>, "SetTargetVolume"},
|
||||
FunctionInfo{2, D<&IAudioController::GetTargetVolumeMin>, "GetTargetVolumeMin"},
|
||||
FunctionInfo{3, D<&IAudioController::GetTargetVolumeMax>, "GetTargetVolumeMax"},
|
||||
FunctionInfo{4, D<&IAudioController::IsTargetMute>, "IsTargetMute"},
|
||||
FunctionInfo{5, D<&IAudioController::SetTargetMute>, "SetTargetMute"},
|
||||
FunctionInfo{6, nullptr, "IsTargetConnected", MakeVersionGate({20,0,0})},
|
||||
FunctionInfo{7, nullptr, "SetDefaultTarget"},
|
||||
FunctionInfo{8, nullptr, "GetDefaultTarget"},
|
||||
FunctionInfo{9, D<&IAudioController::GetAudioOutputMode>, "GetAudioOutputMode"},
|
||||
FunctionInfo{10, D<&IAudioController::SetAudioOutputMode>, "SetAudioOutputMode"},
|
||||
FunctionInfo{11, nullptr, "SetForceMutePolicy"},
|
||||
FunctionInfo{12, D<&IAudioController::GetForceMutePolicy>, "GetForceMutePolicy"},
|
||||
FunctionInfo{13, D<&IAudioController::GetOutputModeSetting>, "GetOutputModeSetting"},
|
||||
FunctionInfo{14, D<&IAudioController::SetOutputModeSetting>, "SetOutputModeSetting"},
|
||||
FunctionInfo{15, nullptr, "SetOutputTarget"},
|
||||
FunctionInfo{16, nullptr, "SetInputTargetForceEnabled"},
|
||||
FunctionInfo{17, D<&IAudioController::SetHeadphoneOutputLevelMode>, "SetHeadphoneOutputLevelMode"},
|
||||
FunctionInfo{18, D<&IAudioController::GetHeadphoneOutputLevelMode>, "GetHeadphoneOutputLevelMode"},
|
||||
FunctionInfo{19, nullptr, "AcquireAudioVolumeUpdateEventForPlayReport"},
|
||||
FunctionInfo{20, nullptr, "AcquireAudioOutputDeviceUpdateEventForPlayReport"},
|
||||
FunctionInfo{21, nullptr, "GetAudioOutputTargetForPlayReport"},
|
||||
FunctionInfo{22, D<&IAudioController::NotifyHeadphoneVolumeWarningDisplayedEvent>, "NotifyHeadphoneVolumeWarningDisplayedEvent"},
|
||||
FunctionInfo{23, nullptr, "SetSystemOutputMasterVolume"},
|
||||
FunctionInfo{24, nullptr, "GetSystemOutputMasterVolume"},
|
||||
FunctionInfo{25, nullptr, "GetAudioVolumeDataForPlayReport"},
|
||||
FunctionInfo{26, nullptr, "UpdateHeadphoneSettings"},
|
||||
FunctionInfo{27, nullptr, "SetVolumeMappingTableForDev"},
|
||||
FunctionInfo{28, nullptr, "GetAudioOutputChannelCountForPlayReport"},
|
||||
FunctionInfo{29, nullptr, "BindAudioOutputChannelCountUpdateEventForPlayReport"},
|
||||
FunctionInfo{30, D<&IAudioController::SetSpeakerAutoMuteEnabled>, "SetSpeakerAutoMuteEnabled"},
|
||||
FunctionInfo{31, D<&IAudioController::IsSpeakerAutoMuteEnabled>, "IsSpeakerAutoMuteEnabled"},
|
||||
FunctionInfo{32, D<&IAudioController::GetActiveOutputTarget>, "GetActiveOutputTarget"},
|
||||
FunctionInfo{33, nullptr, "GetTargetDeviceInfo"},
|
||||
FunctionInfo{34, D<&IAudioController::AcquireTargetNotification>, "AcquireTargetNotification"},
|
||||
FunctionInfo{35, nullptr, "SetHearingProtectionSafeguardTimerRemainingTimeForDebug"},
|
||||
FunctionInfo{36, nullptr, "GetHearingProtectionSafeguardTimerRemainingTimeForDebug"},
|
||||
FunctionInfo{37, nullptr, "SetHearingProtectionSafeguardEnabled"},
|
||||
FunctionInfo{38, nullptr, "IsHearingProtectionSafeguardEnabled"},
|
||||
FunctionInfo{39, nullptr, "IsHearingProtectionSafeguardMonitoringOutputForDebug"},
|
||||
FunctionInfo{40, nullptr, "GetSystemInformationForDebug"},
|
||||
FunctionInfo{41, nullptr, "SetVolumeButtonLongPressTime"},
|
||||
FunctionInfo{42, nullptr, "SetNativeVolumeForDebug"},
|
||||
FunctionInfo{43, nullptr, "Unknown43", MakeVersionGate({21,0,0})},
|
||||
FunctionInfo{5000, D<&IAudioController::Unknown5000>, "Unknown5000", MakeVersionGate({19,0,0})},
|
||||
FunctionInfo{10000, nullptr, "NotifyAudioOutputTargetForPlayReport"},
|
||||
FunctionInfo{10001, nullptr, "NotifyAudioOutputChannelCountForPlayReport"},
|
||||
FunctionInfo{10002, nullptr, "NotifyUnsupportedUsbOutputDeviceAttachedForPlayReport"},
|
||||
FunctionInfo{10100, nullptr, "GetAudioVolumeDataForPlayReport"},
|
||||
FunctionInfo{10101, nullptr, "BindAudioVolumeUpdateEventForPlayReport"},
|
||||
FunctionInfo{10102, nullptr, "BindAudioOutputTargetUpdateEventForPlayReport"},
|
||||
FunctionInfo{10103, nullptr, "GetAudioOutputTargetForPlayReport"},
|
||||
FunctionInfo{10104, nullptr, "GetAudioOutputChannelCountForPlayReport"},
|
||||
FunctionInfo{10105, nullptr, "BindAudioOutputChannelCountUpdateEventForPlayReport", MakeVersionGate({14,0,0}, {19,0,1})},
|
||||
FunctionInfo{10106, nullptr, "GetDefaultAudioOutputTargetForPlayReport", MakeVersionGate({14,0,0}, {19,0,1})},
|
||||
FunctionInfo{10200, nullptr, "Unknown10200", MakeVersionGate({20,0,0})},
|
||||
FunctionInfo{50000, nullptr, "SetAnalogInputBoostGainForPrototyping", MakeVersionGate({15,0,0}, {18,1,0})},
|
||||
FunctionInfo{50001, nullptr, "OverrideDefaultTargetForDebug", MakeVersionGate({19,0,0}, {19,0,1})},
|
||||
FunctionInfo{50003, nullptr, "SetForceOverrideExternalDeviceNameForDebug", MakeVersionGate({19,0,0})},
|
||||
FunctionInfo{50004, nullptr, "ClearForceOverrideExternalDeviceNameForDebug", MakeVersionGate({19,0,0})}
|
||||
);
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
|
||||
IAudioController::IAudioController(Core::System& system_)
|
||||
: ServiceFramework{system_, "audctl"}, service_context{system, "audctl"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, D<&IAudioController::GetTargetVolume>, "GetTargetVolume"},
|
||||
{1, D<&IAudioController::SetTargetVolume>, "SetTargetVolume"},
|
||||
{2, D<&IAudioController::GetTargetVolumeMin>, "GetTargetVolumeMin"},
|
||||
{3, D<&IAudioController::GetTargetVolumeMax>, "GetTargetVolumeMax"},
|
||||
{4, D<&IAudioController::IsTargetMute>, "IsTargetMute"},
|
||||
{5, D<&IAudioController::SetTargetMute>, "SetTargetMute"},
|
||||
{6, nullptr, "IsTargetConnected"}, //20.0.0+
|
||||
{7, nullptr, "SetDefaultTarget"},
|
||||
{8, nullptr, "GetDefaultTarget"},
|
||||
{9, D<&IAudioController::GetAudioOutputMode>, "GetAudioOutputMode"},
|
||||
{10, D<&IAudioController::SetAudioOutputMode>, "SetAudioOutputMode"},
|
||||
{11, nullptr, "SetForceMutePolicy"},
|
||||
{12, D<&IAudioController::GetForceMutePolicy>, "GetForceMutePolicy"},
|
||||
{13, D<&IAudioController::GetOutputModeSetting>, "GetOutputModeSetting"},
|
||||
{14, D<&IAudioController::SetOutputModeSetting>, "SetOutputModeSetting"},
|
||||
{15, nullptr, "SetOutputTarget"},
|
||||
{16, nullptr, "SetInputTargetForceEnabled"},
|
||||
{17, D<&IAudioController::SetHeadphoneOutputLevelMode>, "SetHeadphoneOutputLevelMode"},
|
||||
{18, D<&IAudioController::GetHeadphoneOutputLevelMode>, "GetHeadphoneOutputLevelMode"},
|
||||
{19, nullptr, "AcquireAudioVolumeUpdateEventForPlayReport"},
|
||||
{20, nullptr, "AcquireAudioOutputDeviceUpdateEventForPlayReport"},
|
||||
{21, nullptr, "GetAudioOutputTargetForPlayReport"},
|
||||
{22, D<&IAudioController::NotifyHeadphoneVolumeWarningDisplayedEvent>, "NotifyHeadphoneVolumeWarningDisplayedEvent"},
|
||||
{23, nullptr, "SetSystemOutputMasterVolume"},
|
||||
{24, nullptr, "GetSystemOutputMasterVolume"},
|
||||
{25, nullptr, "GetAudioVolumeDataForPlayReport"},
|
||||
{26, nullptr, "UpdateHeadphoneSettings"},
|
||||
{27, nullptr, "SetVolumeMappingTableForDev"},
|
||||
{28, nullptr, "GetAudioOutputChannelCountForPlayReport"},
|
||||
{29, nullptr, "BindAudioOutputChannelCountUpdateEventForPlayReport"},
|
||||
{30, D<&IAudioController::SetSpeakerAutoMuteEnabled>, "SetSpeakerAutoMuteEnabled"},
|
||||
{31, D<&IAudioController::IsSpeakerAutoMuteEnabled>, "IsSpeakerAutoMuteEnabled"},
|
||||
{32, D<&IAudioController::GetActiveOutputTarget>, "GetActiveOutputTarget"},
|
||||
{33, nullptr, "GetTargetDeviceInfo"},
|
||||
{34, D<&IAudioController::AcquireTargetNotification>, "AcquireTargetNotification"},
|
||||
{35, nullptr, "SetHearingProtectionSafeguardTimerRemainingTimeForDebug"},
|
||||
{36, nullptr, "GetHearingProtectionSafeguardTimerRemainingTimeForDebug"},
|
||||
{37, nullptr, "SetHearingProtectionSafeguardEnabled"},
|
||||
{38, nullptr, "IsHearingProtectionSafeguardEnabled"},
|
||||
{39, nullptr, "IsHearingProtectionSafeguardMonitoringOutputForDebug"},
|
||||
{40, nullptr, "GetSystemInformationForDebug"},
|
||||
{41, nullptr, "SetVolumeButtonLongPressTime"},
|
||||
{42, nullptr, "SetNativeVolumeForDebug"},
|
||||
{43, nullptr, "Unknown43"}, //21.0.0+
|
||||
{5000, D<&IAudioController::Unknown5000>, "Unknown5000"}, //19.0.0+
|
||||
{10000, nullptr, "NotifyAudioOutputTargetForPlayReport"},
|
||||
{10001, nullptr, "NotifyAudioOutputChannelCountForPlayReport"},
|
||||
{10002, nullptr, "NotifyUnsupportedUsbOutputDeviceAttachedForPlayReport"},
|
||||
{10100, nullptr, "GetAudioVolumeDataForPlayReport"},
|
||||
{10101, nullptr, "BindAudioVolumeUpdateEventForPlayReport"},
|
||||
{10102, nullptr, "BindAudioOutputTargetUpdateEventForPlayReport"},
|
||||
{10103, nullptr, "GetAudioOutputTargetForPlayReport"},
|
||||
{10104, nullptr, "GetAudioOutputChannelCountForPlayReport"},
|
||||
{10105, nullptr, "BindAudioOutputChannelCountUpdateEventForPlayReport"}, //14.0.0-19.0.1
|
||||
{10106, nullptr, "GetDefaultAudioOutputTargetForPlayReport"}, //14.0.0-19.0.1
|
||||
{10200, nullptr, "Unknown10200"}, //20.0.0+
|
||||
{50000, nullptr, "SetAnalogInputBoostGainForPrototyping"}, //15.0.0-18.1.0
|
||||
{50001, nullptr, "OverrideDefaultTargetForDebug"}, //19.0.0-19.0.1
|
||||
{50003, nullptr, "SetForceOverrideExternalDeviceNameForDebug"}, //19.0.0+
|
||||
{50004, nullptr, "ClearForceOverrideExternalDeviceNameForDebug"} //19.0.0+
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
|
||||
m_set_sys =
|
||||
system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true);
|
||||
m_set_sys = system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true);
|
||||
notification_event = service_context.CreateEvent("IAudioController:NotificationEvent");
|
||||
|
||||
// Probably shouldn't do this in constructor?
|
||||
|
||||
@@ -59,8 +59,8 @@ private:
|
||||
Result AcquireTargetNotification(OutCopyHandle<Kernel::KReadableEvent> out_notification_event);
|
||||
Result Unknown5000(Out<SharedPointer<IAudioController>> out_audio_controller);
|
||||
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override;
|
||||
KernelHelpers::ServiceContext service_context;
|
||||
|
||||
Kernel::KEvent* notification_event;
|
||||
std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys;
|
||||
std::array<s32, 6> m_target_volumes{{15, 15, 15, 15, 15, 15}};
|
||||
|
||||
@@ -12,36 +12,38 @@
|
||||
namespace Service::Audio {
|
||||
using namespace AudioCore::Renderer;
|
||||
|
||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> IAudioDevice::FindRequest(u32 key) {
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, D<&IAudioDevice::ListAudioDeviceName>, "ListAudioDeviceName"},
|
||||
FunctionInfo{1, D<&IAudioDevice::SetAudioDeviceOutputVolume>, "SetAudioDeviceOutputVolume"},
|
||||
FunctionInfo{2, D<&IAudioDevice::GetAudioDeviceOutputVolume>, "GetAudioDeviceOutputVolume"},
|
||||
FunctionInfo{3, D<&IAudioDevice::GetActiveAudioDeviceName>, "GetActiveAudioDeviceName"},
|
||||
FunctionInfo{4, D<&IAudioDevice::QueryAudioDeviceSystemEvent>, "QueryAudioDeviceSystemEvent"},
|
||||
FunctionInfo{5, D<&IAudioDevice::GetActiveChannelCount>, "GetActiveChannelCount"},
|
||||
FunctionInfo{6, D<&IAudioDevice::ListAudioDeviceNameAuto>, "ListAudioDeviceNameAuto"},
|
||||
FunctionInfo{7, D<&IAudioDevice::SetAudioDeviceOutputVolumeAuto>, "SetAudioDeviceOutputVolumeAuto"},
|
||||
FunctionInfo{8, D<&IAudioDevice::GetAudioDeviceOutputVolumeAuto>, "GetAudioDeviceOutputVolumeAuto"},
|
||||
FunctionInfo{10, D<&IAudioDevice::GetActiveAudioDeviceNameAuto>, "GetActiveAudioDeviceNameAuto"},
|
||||
FunctionInfo{11, D<&IAudioDevice::QueryAudioDeviceInputEvent>, "QueryAudioDeviceInputEvent"},
|
||||
FunctionInfo{12, D<&IAudioDevice::QueryAudioDeviceOutputEvent>, "QueryAudioDeviceOutputEvent"},
|
||||
FunctionInfo{13, D<&IAudioDevice::GetActiveAudioDeviceName>, "GetActiveAudioOutputDeviceName"},
|
||||
FunctionInfo{14, D<&IAudioDevice::ListAudioOutputDeviceName>, "ListAudioOutputDeviceName"},
|
||||
FunctionInfo{15, nullptr, "AcquireAudioInputDeviceNotification", MakeVersionGate({17,0,0})},
|
||||
FunctionInfo{16, nullptr, "ReleaseAudioInputDeviceNotification", MakeVersionGate({17,0,0})},
|
||||
FunctionInfo{17, nullptr, "AcquireAudioOutputDeviceNotification", MakeVersionGate({17,0,0})},
|
||||
FunctionInfo{18, nullptr, "ReleaseAudioOutputDeviceNotification", MakeVersionGate({17,0,0})},
|
||||
FunctionInfo{19, D<&IAudioDevice::SetAudioDeviceOutputVolumeAutoTuneEnabled>, "SetAudioDeviceOutputVolumeAutoTuneEnabled", MakeVersionGate({18,0,0})},
|
||||
FunctionInfo{20, D<&IAudioDevice::IsAudioDeviceOutputVolumeAutoTuneEnabled>, "IsAudioDeviceOutputVolumeAutoTuneEnabled", MakeVersionGate({18,0,0})},
|
||||
FunctionInfo{21, nullptr, "IsActiveOutputDeviceEstimatedLowLatency", MakeVersionGate({21,0,0})}
|
||||
);
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
|
||||
IAudioDevice::IAudioDevice(Core::System& system_, u64 applet_resource_user_id, u32 revision,
|
||||
u32 device_num)
|
||||
: ServiceFramework{system_, "IAudioDevice"}, service_context{system_, "IAudioDevice"},
|
||||
impl{std::make_unique<AudioDevice>(system_, applet_resource_user_id, revision)},
|
||||
event{service_context.CreateEvent(fmt::format("IAudioDeviceEvent-{}", device_num))} {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, D<&IAudioDevice::ListAudioDeviceName>, "ListAudioDeviceName"},
|
||||
{1, D<&IAudioDevice::SetAudioDeviceOutputVolume>, "SetAudioDeviceOutputVolume"},
|
||||
{2, D<&IAudioDevice::GetAudioDeviceOutputVolume>, "GetAudioDeviceOutputVolume"},
|
||||
{3, D<&IAudioDevice::GetActiveAudioDeviceName>, "GetActiveAudioDeviceName"},
|
||||
{4, D<&IAudioDevice::QueryAudioDeviceSystemEvent>, "QueryAudioDeviceSystemEvent"},
|
||||
{5, D<&IAudioDevice::GetActiveChannelCount>, "GetActiveChannelCount"},
|
||||
{6, D<&IAudioDevice::ListAudioDeviceNameAuto>, "ListAudioDeviceNameAuto"},
|
||||
{7, D<&IAudioDevice::SetAudioDeviceOutputVolumeAuto>, "SetAudioDeviceOutputVolumeAuto"},
|
||||
{8, D<&IAudioDevice::GetAudioDeviceOutputVolumeAuto>, "GetAudioDeviceOutputVolumeAuto"},
|
||||
{10, D<&IAudioDevice::GetActiveAudioDeviceNameAuto>, "GetActiveAudioDeviceNameAuto"},
|
||||
{11, D<&IAudioDevice::QueryAudioDeviceInputEvent>, "QueryAudioDeviceInputEvent"},
|
||||
{12, D<&IAudioDevice::QueryAudioDeviceOutputEvent>, "QueryAudioDeviceOutputEvent"},
|
||||
{13, D<&IAudioDevice::GetActiveAudioDeviceName>, "GetActiveAudioOutputDeviceName"},
|
||||
{14, D<&IAudioDevice::ListAudioOutputDeviceName>, "ListAudioOutputDeviceName"},
|
||||
{15, nullptr, "AcquireAudioInputDeviceNotification"}, //17.0.0+
|
||||
{16, nullptr, "ReleaseAudioInputDeviceNotification"}, //17.0.0+
|
||||
{17, nullptr, "AcquireAudioOutputDeviceNotification"}, //17.0.0+
|
||||
{18, nullptr, "ReleaseAudioOutputDeviceNotification"}, //17.0.0+
|
||||
{19, D<&IAudioDevice::SetAudioDeviceOutputVolumeAutoTuneEnabled>, "SetAudioDeviceOutputVolumeAutoTuneEnabled"}, //18.0.0+
|
||||
{20, D<&IAudioDevice::IsAudioDeviceOutputVolumeAutoTuneEnabled>, "IsAudioDeviceOutputVolumeAutoTuneEnabled"}, //18.0.0+
|
||||
{21, nullptr, "IsActiveOutputDeviceEstimatedLowLatency"} //21.0.0+
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
|
||||
event->Signal(system.Kernel());
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ private:
|
||||
Result SetAudioDeviceOutputVolumeAutoTuneEnabled(bool enabled);
|
||||
Result IsAudioDeviceOutputVolumeAutoTuneEnabled(Out<bool> out_enabled);
|
||||
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override;
|
||||
KernelHelpers::ServiceContext service_context;
|
||||
std::unique_ptr<AudioCore::Renderer::AudioDevice> impl;
|
||||
Kernel::KEvent* event;
|
||||
|
||||
@@ -11,35 +11,33 @@
|
||||
namespace Service::Audio {
|
||||
using namespace AudioCore::AudioIn;
|
||||
|
||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> IAudioIn::FindRequest(u32 key) {
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, D<&IAudioIn::GetAudioInState>, "GetAudioInState"},
|
||||
FunctionInfo{1, D<&IAudioIn::Start>, "Start"},
|
||||
FunctionInfo{2, D<&IAudioIn::Stop>, "Stop"},
|
||||
FunctionInfo{3, D<&IAudioIn::AppendAudioInBuffer>, "AppendAudioInBuffer"},
|
||||
FunctionInfo{4, D<&IAudioIn::RegisterBufferEvent>, "RegisterBufferEvent"},
|
||||
FunctionInfo{5, D<&IAudioIn::GetReleasedAudioInBuffers>, "GetReleasedAudioInBuffers"},
|
||||
FunctionInfo{6, D<&IAudioIn::ContainsAudioInBuffer>, "ContainsAudioInBuffer"},
|
||||
FunctionInfo{7, D<&IAudioIn::AppendAudioInBuffer>, "AppendUacInBuffer"},
|
||||
FunctionInfo{8, D<&IAudioIn::AppendAudioInBufferAuto>, "AppendAudioInBufferAuto"},
|
||||
FunctionInfo{9, D<&IAudioIn::GetReleasedAudioInBuffersAuto>, "GetReleasedAudioInBuffersAuto"},
|
||||
FunctionInfo{10, D<&IAudioIn::AppendAudioInBufferAuto>, "AppendUacInBufferAuto"},
|
||||
FunctionInfo{11, D<&IAudioIn::GetAudioInBufferCount>, "GetAudioInBufferCount"},
|
||||
FunctionInfo{12, D<&IAudioIn::SetDeviceGain>, "SetDeviceGain"},
|
||||
FunctionInfo{13, D<&IAudioIn::GetDeviceGain>, "GetDeviceGain"},
|
||||
FunctionInfo{14, D<&IAudioIn::FlushAudioInBuffers>, "FlushAudioInBuffers"}
|
||||
);
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
|
||||
IAudioIn::IAudioIn(Core::System& system_, Manager& manager, size_t session_id,
|
||||
const std::string& device_name, const AudioInParameter& in_params,
|
||||
Kernel::KProcess* handle, u64 applet_resource_user_id)
|
||||
: ServiceFramework{system_, "IAudioIn"}, process{handle}, service_context{system_, "IAudioIn"},
|
||||
event{service_context.CreateEvent("AudioInEvent")}, impl{std::make_shared<In>(system_,
|
||||
manager, event,
|
||||
session_id)} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, D<&IAudioIn::GetAudioInState>, "GetAudioInState"},
|
||||
{1, D<&IAudioIn::Start>, "Start"},
|
||||
{2, D<&IAudioIn::Stop>, "Stop"},
|
||||
{3, D<&IAudioIn::AppendAudioInBuffer>, "AppendAudioInBuffer"},
|
||||
{4, D<&IAudioIn::RegisterBufferEvent>, "RegisterBufferEvent"},
|
||||
{5, D<&IAudioIn::GetReleasedAudioInBuffers>, "GetReleasedAudioInBuffers"},
|
||||
{6, D<&IAudioIn::ContainsAudioInBuffer>, "ContainsAudioInBuffer"},
|
||||
{7, D<&IAudioIn::AppendAudioInBuffer>, "AppendUacInBuffer"},
|
||||
{8, D<&IAudioIn::AppendAudioInBufferAuto>, "AppendAudioInBufferAuto"},
|
||||
{9, D<&IAudioIn::GetReleasedAudioInBuffersAuto>, "GetReleasedAudioInBuffersAuto"},
|
||||
{10, D<&IAudioIn::AppendAudioInBufferAuto>, "AppendUacInBufferAuto"},
|
||||
{11, D<&IAudioIn::GetAudioInBufferCount>, "GetAudioInBufferCount"},
|
||||
{12, D<&IAudioIn::SetDeviceGain>, "SetDeviceGain"},
|
||||
{13, D<&IAudioIn::GetDeviceGain>, "GetDeviceGain"},
|
||||
{14, D<&IAudioIn::FlushAudioInBuffers>, "FlushAudioInBuffers"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
|
||||
: ServiceFramework{system_, "IAudioIn"}, process{handle}, service_context{system_, "IAudioIn"}
|
||||
, event{service_context.CreateEvent("AudioInEvent")}, impl{std::make_shared<In>(system_, manager, event, session_id)}
|
||||
{
|
||||
process->Open(system.Kernel());
|
||||
|
||||
if (impl->GetSystem()
|
||||
|
||||
@@ -46,6 +46,7 @@ public:
|
||||
Result FlushAudioInBuffers(Out<bool> out_flushed);
|
||||
|
||||
private:
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override;
|
||||
Kernel::KProcess* process;
|
||||
KernelHelpers::ServiceContext service_context;
|
||||
Kernel::KEvent* event;
|
||||
|
||||
@@ -12,23 +12,23 @@
|
||||
namespace Service::Audio {
|
||||
using namespace AudioCore::AudioIn;
|
||||
|
||||
IAudioInManager::IAudioInManager(Core::System& system_)
|
||||
: ServiceFramework{system_, "audin:u"}, impl{std::make_unique<AudioCore::AudioIn::Manager>(
|
||||
system_)} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, D<&IAudioInManager::ListAudioIns>, "ListAudioIns"},
|
||||
{1, D<&IAudioInManager::OpenAudioIn>, "OpenAudioIn"},
|
||||
{2, D<&IAudioInManager::ListAudioIns>, "ListAudioInsAuto"},
|
||||
{3, D<&IAudioInManager::OpenAudioIn>, "OpenAudioInAuto"},
|
||||
{4, D<&IAudioInManager::ListAudioInsAutoFiltered>, "ListAudioInsAutoFiltered"},
|
||||
{5, D<&IAudioInManager::OpenAudioInProtocolSpecified>, "OpenAudioInProtocolSpecified"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> IAudioInManager::FindRequest(u32 key) {
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, D<&IAudioInManager::ListAudioIns>, "ListAudioIns"},
|
||||
FunctionInfo{1, D<&IAudioInManager::OpenAudioIn>, "OpenAudioIn"},
|
||||
FunctionInfo{2, D<&IAudioInManager::ListAudioIns>, "ListAudioInsAuto"},
|
||||
FunctionInfo{3, D<&IAudioInManager::OpenAudioIn>, "OpenAudioInAuto"},
|
||||
FunctionInfo{4, D<&IAudioInManager::ListAudioInsAutoFiltered>, "ListAudioInsAutoFiltered"},
|
||||
FunctionInfo{5, D<&IAudioInManager::OpenAudioInProtocolSpecified>, "OpenAudioInProtocolSpecified"}
|
||||
);
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
|
||||
IAudioInManager::IAudioInManager(Core::System& system_)
|
||||
: ServiceFramework{system_, "audin:u"}
|
||||
, impl{std::make_unique<AudioCore::AudioIn::Manager>(system_)}
|
||||
{}
|
||||
|
||||
IAudioInManager::~IAudioInManager() = default;
|
||||
|
||||
Result IAudioInManager::ListAudioIns(
|
||||
|
||||
@@ -54,6 +54,7 @@ private:
|
||||
AudioCore::AudioIn::AudioInParameter parameter,
|
||||
InCopyHandle<Kernel::KProcess> process_handle, ClientAppletResourceUserId aruid);
|
||||
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override;
|
||||
std::unique_ptr<AudioCore::AudioIn::Manager> impl;
|
||||
};
|
||||
|
||||
|
||||
@@ -15,6 +15,26 @@
|
||||
namespace Service::Audio {
|
||||
using namespace AudioCore::AudioOut;
|
||||
|
||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> IAudioOut::FindRequest(u32 key) {
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, D<&IAudioOut::GetAudioOutState>, "GetAudioOutState"},
|
||||
FunctionInfo{1, D<&IAudioOut::Start>, "Start"},
|
||||
FunctionInfo{2, D<&IAudioOut::Stop>, "Stop"},
|
||||
FunctionInfo{3, D<&IAudioOut::AppendAudioOutBuffer>, "AppendAudioOutBuffer"},
|
||||
FunctionInfo{4, D<&IAudioOut::RegisterBufferEvent>, "RegisterBufferEvent"},
|
||||
FunctionInfo{5, D<&IAudioOut::GetReleasedAudioOutBuffers>, "GetReleasedAudioOutBuffers"},
|
||||
FunctionInfo{6, D<&IAudioOut::ContainsAudioOutBuffer>, "ContainsAudioOutBuffer"},
|
||||
FunctionInfo{7, D<&IAudioOut::AppendAudioOutBufferAuto>, "AppendAudioOutBufferAuto"},
|
||||
FunctionInfo{8, D<&IAudioOut::GetReleasedAudioOutBuffersAuto>, "GetReleasedAudioOutBuffersAuto"},
|
||||
FunctionInfo{9, D<&IAudioOut::GetAudioOutBufferCount>, "GetAudioOutBufferCount"},
|
||||
FunctionInfo{10, D<&IAudioOut::GetAudioOutPlayedSampleCount>, "GetAudioOutPlayedSampleCount"},
|
||||
FunctionInfo{11, D<&IAudioOut::FlushAudioOutBuffers>, "FlushAudioOutBuffers"},
|
||||
FunctionInfo{12, D<&IAudioOut::SetAudioOutVolume>, "SetAudioOutVolume"},
|
||||
FunctionInfo{13, D<&IAudioOut::GetAudioOutVolume>, "GetAudioOutVolume"}
|
||||
);
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
|
||||
IAudioOut::IAudioOut(Core::System& system_, Manager& manager, size_t session_id,
|
||||
const std::string& device_name, const AudioOutParameter& in_params,
|
||||
Kernel::KProcess* handle, u64 applet_resource_user_id)
|
||||
@@ -22,26 +42,6 @@ IAudioOut::IAudioOut(Core::System& system_, Manager& manager, size_t session_id,
|
||||
event{service_context.CreateEvent("AudioOutEvent")}, process{handle},
|
||||
impl{std::make_shared<AudioCore::AudioOut::Out>(system_, manager, event, session_id)} {
|
||||
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, D<&IAudioOut::GetAudioOutState>, "GetAudioOutState"},
|
||||
{1, D<&IAudioOut::Start>, "Start"},
|
||||
{2, D<&IAudioOut::Stop>, "Stop"},
|
||||
{3, D<&IAudioOut::AppendAudioOutBuffer>, "AppendAudioOutBuffer"},
|
||||
{4, D<&IAudioOut::RegisterBufferEvent>, "RegisterBufferEvent"},
|
||||
{5, D<&IAudioOut::GetReleasedAudioOutBuffers>, "GetReleasedAudioOutBuffers"},
|
||||
{6, D<&IAudioOut::ContainsAudioOutBuffer>, "ContainsAudioOutBuffer"},
|
||||
{7, D<&IAudioOut::AppendAudioOutBufferAuto>, "AppendAudioOutBufferAuto"},
|
||||
{8, D<&IAudioOut::GetReleasedAudioOutBuffersAuto>, "GetReleasedAudioOutBuffersAuto"},
|
||||
{9, D<&IAudioOut::GetAudioOutBufferCount>, "GetAudioOutBufferCount"},
|
||||
{10, D<&IAudioOut::GetAudioOutPlayedSampleCount>, "GetAudioOutPlayedSampleCount"},
|
||||
{11, D<&IAudioOut::FlushAudioOutBuffers>, "FlushAudioOutBuffers"},
|
||||
{12, D<&IAudioOut::SetAudioOutVolume>, "SetAudioOutVolume"},
|
||||
{13, D<&IAudioOut::GetAudioOutVolume>, "GetAudioOutVolume"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
|
||||
process->Open(system.Kernel());
|
||||
}
|
||||
|
||||
|
||||
@@ -52,6 +52,8 @@ public:
|
||||
Result GetAudioOutVolume(Out<f32> out_volume);
|
||||
|
||||
private:
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override;
|
||||
|
||||
KernelHelpers::ServiceContext service_context;
|
||||
Kernel::KEvent* event;
|
||||
Kernel::KProcess* process;
|
||||
|
||||
@@ -13,20 +13,20 @@
|
||||
namespace Service::Audio {
|
||||
using namespace AudioCore::AudioOut;
|
||||
|
||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> IAudioOutManager::FindRequest(u32 key) {
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, D<&IAudioOutManager::ListAudioOuts>, "ListAudioOuts"},
|
||||
FunctionInfo{1, D<&IAudioOutManager::OpenAudioOut>, "OpenAudioOut"},
|
||||
FunctionInfo{2, D<&IAudioOutManager::ListAudioOutsAuto>, "ListAudioOutsAuto"},
|
||||
FunctionInfo{3, D<&IAudioOutManager::OpenAudioOutAuto>, "OpenAudioOutAuto"}
|
||||
);
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
|
||||
IAudioOutManager::IAudioOutManager(Core::System& system_)
|
||||
: ServiceFramework{system_, "audout:u"}
|
||||
, impl(system_)
|
||||
{
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, D<&IAudioOutManager::ListAudioOuts>, "ListAudioOuts"},
|
||||
{1, D<&IAudioOutManager::OpenAudioOut>, "OpenAudioOut"},
|
||||
{2, D<&IAudioOutManager::ListAudioOutsAuto>, "ListAudioOutsAuto"},
|
||||
{3, D<&IAudioOutManager::OpenAudioOutAuto>, "OpenAudioOutAuto"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
IAudioOutManager::~IAudioOutManager() = default;
|
||||
|
||||
@@ -43,6 +43,7 @@ private:
|
||||
AudioCore::AudioOut::AudioOutParameter parameter,
|
||||
InCopyHandle<Kernel::KProcess> process_handle, ClientAppletResourceUserId aruid);
|
||||
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override;
|
||||
std::optional<AudioCore::AudioOut::Manager> impl;
|
||||
};
|
||||
|
||||
|
||||
@@ -10,38 +10,37 @@
|
||||
namespace Service::Audio {
|
||||
using namespace AudioCore::Renderer;
|
||||
|
||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> IAudioRenderer::FindRequest(u32 key) {
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, D<&IAudioRenderer::GetSampleRate>, "GetSampleRate"},
|
||||
FunctionInfo{1, D<&IAudioRenderer::GetSampleCount>, "GetSampleCount"},
|
||||
FunctionInfo{2, D<&IAudioRenderer::GetMixBufferCount>, "GetMixBufferCount"},
|
||||
FunctionInfo{3, D<&IAudioRenderer::GetState>, "GetState"},
|
||||
FunctionInfo{4, D<&IAudioRenderer::RequestUpdate>, "RequestUpdate"},
|
||||
FunctionInfo{5, D<&IAudioRenderer::Start>, "Start"},
|
||||
FunctionInfo{6, D<&IAudioRenderer::Stop>, "Stop"},
|
||||
FunctionInfo{7, D<&IAudioRenderer::QuerySystemEvent>, "QuerySystemEvent"},
|
||||
FunctionInfo{8, D<&IAudioRenderer::SetRenderingTimeLimit>, "SetRenderingTimeLimit"},
|
||||
FunctionInfo{9, D<&IAudioRenderer::GetRenderingTimeLimit>, "GetRenderingTimeLimit"},
|
||||
FunctionInfo{10, D<&IAudioRenderer::RequestUpdateAuto>, "RequestUpdateAuto", MakeVersionGate({3,0,0})},
|
||||
FunctionInfo{11, nullptr, "ExecuteAudioRendererRendering", MakeVersionGate({3,0,0})},
|
||||
FunctionInfo{12, D<&IAudioRenderer::SetVoiceDropParameter>, "SetVoiceDropParameter", MakeVersionGate({15,0,0})},
|
||||
FunctionInfo{13, D<&IAudioRenderer::GetVoiceDropParameter>, "GetVoiceDropParameter", MakeVersionGate({15,0,0})}
|
||||
);
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
|
||||
IAudioRenderer::IAudioRenderer(Core::System& system_, Manager& manager_,
|
||||
AudioCore::AudioRendererParameterInternal& params,
|
||||
Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size,
|
||||
Kernel::KProcess* process_handle_, u64 applet_resource_user_id,
|
||||
s32 session_id)
|
||||
: ServiceFramework{system_, "IAudioRenderer"}, service_context{system_, "IAudioRenderer"},
|
||||
rendered_event{service_context.CreateEvent("IAudioRendererEvent")}, manager{manager_},
|
||||
impl{std::make_unique<Renderer>(system_, manager, rendered_event)}, process_handle{
|
||||
process_handle_} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, D<&IAudioRenderer::GetSampleRate>, "GetSampleRate"},
|
||||
{1, D<&IAudioRenderer::GetSampleCount>, "GetSampleCount"},
|
||||
{2, D<&IAudioRenderer::GetMixBufferCount>, "GetMixBufferCount"},
|
||||
{3, D<&IAudioRenderer::GetState>, "GetState"},
|
||||
{4, D<&IAudioRenderer::RequestUpdate>, "RequestUpdate"},
|
||||
{5, D<&IAudioRenderer::Start>, "Start"},
|
||||
{6, D<&IAudioRenderer::Stop>, "Stop"},
|
||||
{7, D<&IAudioRenderer::QuerySystemEvent>, "QuerySystemEvent"},
|
||||
{8, D<&IAudioRenderer::SetRenderingTimeLimit>, "SetRenderingTimeLimit"},
|
||||
{9, D<&IAudioRenderer::GetRenderingTimeLimit>, "GetRenderingTimeLimit"},
|
||||
{10, D<&IAudioRenderer::RequestUpdateAuto>, "RequestUpdateAuto"}, //3.0.0+
|
||||
{11, nullptr, "ExecuteAudioRendererRendering"}, //3.0.0+
|
||||
{12, D<&IAudioRenderer::SetVoiceDropParameter>, "SetVoiceDropParameter"}, //15.0.0+
|
||||
{13, D<&IAudioRenderer::GetVoiceDropParameter>, "GetVoiceDropParameter"}, //15.0.0+
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
|
||||
: ServiceFramework{system_, "IAudioRenderer"}, service_context{system_, "IAudioRenderer"}
|
||||
, rendered_event{service_context.CreateEvent("IAudioRendererEvent")}, manager{manager_}
|
||||
, impl{std::make_unique<Renderer>(system_, manager, rendered_event)}
|
||||
, process_handle{process_handle_} {
|
||||
process_handle->Open(system_.Kernel());
|
||||
impl->Initialize(params, transfer_memory, transfer_memory_size, process_handle,
|
||||
applet_resource_user_id, session_id);
|
||||
impl->Initialize(params, transfer_memory, transfer_memory_size, process_handle, applet_resource_user_id, session_id);
|
||||
}
|
||||
|
||||
IAudioRenderer::~IAudioRenderer() {
|
||||
|
||||
@@ -45,6 +45,7 @@ private:
|
||||
Result SetVoiceDropParameter(f32 voice_drop_parameter);
|
||||
Result GetVoiceDropParameter(Out<f32> out_voice_drop_parameter);
|
||||
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override;
|
||||
KernelHelpers::ServiceContext service_context;
|
||||
Kernel::KEvent* rendered_event;
|
||||
AudioCore::Renderer::Manager& manager;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user