mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-09-26 19:11:00 +00:00
Compare commits
40 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a43d439c98 | |||
| 7e45cb2855 | |||
| 560be57685 | |||
| 3050a2027b | |||
| 0150bfc66d | |||
| b0b8050eda | |||
| ea0a011d2c | |||
| 444e396e11 | |||
| 61c4ad6d89 | |||
| 4123e4870f | |||
| 37a43fdb99 | |||
| 5e35e8a9fe | |||
| 441c902329 | |||
| 83a92be045 | |||
| 61b3183d30 | |||
| 22b7e1e24c | |||
| 5e7ba8fc9c | |||
| e1d9c2295d | |||
| 1797b5839c | |||
| 705206f331 | |||
| caaabb503d | |||
| 0f6a782cfa | |||
| 740db2fd2a | |||
| 1148431277 | |||
| 3497ef2022 | |||
| 37fe911952 | |||
| f273423b2b | |||
| 87d2f03c39 | |||
| bebc19da32 | |||
| 99bf8cf51a | |||
| dbeb73ee01 | |||
| cb73a4dcc7 | |||
| 278f411dad | |||
| 3d37a816c6 | |||
| a25e32676f | |||
| 38df54edfe | |||
| 3266c20e3f | |||
| 9cd24e85c2 | |||
| 74b5e10dc5 | |||
| a277b62fe4 |
Vendored
+628
-583
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+548
-503
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+550
-508
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
Vendored
+573
-527
File diff suppressed because it is too large
Load Diff
Vendored
+547
-502
File diff suppressed because it is too large
Load Diff
@@ -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.
|
||||
|
||||
|
||||
+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.
|
||||
+33
-21
@@ -1,32 +1,44 @@
|
||||
# User Handbook - Command Line
|
||||
|
||||
There are two main applications, an SDL-based app (`eden-cli`) and a Qt based app (`eden`); both accept command line arguments.
|
||||
|
||||
## eden
|
||||
There are two main applications, an SDL-based app (`eden-cli`) and a Qt based app (`eden`); both accept the same command line arguments.
|
||||
|
||||
- `./eden <path>`: Running with a single argument and nothing else, will make the emulator look for the given file and load it, this behavior is similar to `eden-cli`; allows dragging and dropping games into the application.
|
||||
- `-g <path>`: Alternate way to specify what to load, overrides. However let it be noted that arguments that use `-` will be treated as options/ignored, if your game, for some reason, starts with `-`, in order to safely handle it you may need to specify it as an argument.
|
||||
- `-f`: Use fullscreen.
|
||||
- `-u <number>`: Select the index of the user to load as.
|
||||
- `-input-profile <name>`: Specifies input profile name to use (for player #0 only).
|
||||
- `--debug/-d`: Enter debug mode, allow gdb stub at port `1234`
|
||||
- `--config/-c`: Specify alternate configuration file.
|
||||
- `--fullscreen/-f`: Use fullscreen.
|
||||
- `--help/-h`: Display help.
|
||||
- `--game/-g <path>`: Alternate way to specify what to load, overrides. However let it be noted that arguments that use `-` will be treated as options/ignored, if your game, for some reason, starts with `-`, in order to safely handle it you may need to specify it as an argument.
|
||||
- `--multiplayer/-m`: Specify multiplayer options.
|
||||
- `--program/-p`: Specify the program arguments to pass (optional).
|
||||
- `--user/-u <number>`: Specify the user index.
|
||||
- `--version/-v`: Display version and quit.
|
||||
- `--input-profile/-i <name>`: Specifies input profile name to use (for player #0 only).
|
||||
- `--null-render/-n`: Forces the usage of the "Null" render backend irrespective of settings.
|
||||
- `--filter/-x`: Sets the debug log filter irrespective of settings.
|
||||
- `--singlecore/-s`: Forces single-core regardless of settings.
|
||||
|
||||
Only the Qt frontend supports the following arguments:
|
||||
|
||||
- `-qlaunch`: Launch QLaunch.
|
||||
- `-hlaunch`: Launch homebrew launcher `nx-hbloader`.
|
||||
- Requires a copy of Atmosphere to be extracted onto `sdmc`.
|
||||
- This is a shorthand for `<eden folder>/sdmc/atmosphere/hbl.nsp`.
|
||||
- `-setup`: Launch setup applet.
|
||||
|
||||
## eden-cli
|
||||
`eden` (provided with `--room`), and `eden-room` supports the following options as well:
|
||||
|
||||
- `--debug/-d`: Enter debug mode, allow gdb stub at port `1234`
|
||||
- `--config/-c`: Specify alternate configuration file.
|
||||
- `--fullscreen/-f`: Set fullscreen.
|
||||
- `--help/-h`: Display help.
|
||||
- `--game/-g`: Specify the game to run.
|
||||
- `--multiplayer/-m`: Specify multiplayer options.
|
||||
- `--program/-p`: Specify the program arguments to pass (optional).
|
||||
- `--user/-u`: Specify the user index.
|
||||
- `--version/-v`: Display version and quit.
|
||||
- `--input-profile/-i`: Specifies input profile name to use (for player #0 only).
|
||||
- `--null-render/-n`: Forces the usage of the "Null" render backend irrespective of settings.
|
||||
- `--filter/-x`: Sets the debug log filter irrespective of settings.
|
||||
- `--singlecore/-s`: Forces single-core regardless of settings.
|
||||
- `-n/--room-name`: The name of the room.
|
||||
- `-d/--room-description`: The room description.
|
||||
- `-s/--bind-address`: The bind address for the room.
|
||||
- `-p/--port`: The port used for the room.
|
||||
- `-m/--max-members`: The maximum number of players for this room.
|
||||
- `-w/--password`: The password for the room.
|
||||
- `-g/--preferred-game`: The preferred game for this room.
|
||||
- `-i/--preferred-game-id`: The preferred game-id for this room.
|
||||
- `-u/--username`: The username used for announce.
|
||||
- `-t/--token`: The token used for announce.
|
||||
- `-a/--web-api-url`: yuzu Web API url.
|
||||
- `-b/--ban-list-file`: The file for storing the room ban list.
|
||||
- `-l/--log-file`: The file for storing the room log.
|
||||
- `-h/--help`: Display this help and exit.
|
||||
- `-v/--version`: Output version information and exit.
|
||||
|
||||
-1
@@ -30,7 +30,6 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
|
||||
RENDERER_REACTIVE_FLUSHING("use_reactive_flushing"),
|
||||
ENABLE_BUFFER_HISTORY("enable_buffer_history"),
|
||||
USE_OPTIMIZED_VERTEX_BUFFERS("use_optimized_vertex_buffers"),
|
||||
ENABLE_GPU_BUFFER_READBACK("enable_gpu_buffer_readback"),
|
||||
SYNC_MEMORY_OPERATIONS("sync_memory_operations"),
|
||||
BUFFER_REORDER_DISABLE("disable_buffer_reorder"),
|
||||
RENDERER_DEBUG("debug"),
|
||||
|
||||
-7
@@ -908,13 +908,6 @@ abstract class SettingsItem(
|
||||
descriptionId = R.string.enable_buffer_history_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.ENABLE_GPU_BUFFER_READBACK,
|
||||
titleId = R.string.enable_gpu_buffer_readback,
|
||||
descriptionId = R.string.enable_gpu_buffer_readback_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.USE_OPTIMIZED_VERTEX_BUFFERS,
|
||||
|
||||
-1
@@ -549,7 +549,6 @@ class SettingsFragmentPresenter(
|
||||
add(BooleanSetting.RENDERER_FORCE_MAX_CLOCK.key)
|
||||
add(BooleanSetting.RENDERER_REACTIVE_FLUSHING.key)
|
||||
add(BooleanSetting.ENABLE_BUFFER_HISTORY.key)
|
||||
add(BooleanSetting.ENABLE_GPU_BUFFER_READBACK.key)
|
||||
add(BooleanSetting.USE_OPTIMIZED_VERTEX_BUFFERS.key)
|
||||
|
||||
add(HeaderSetting(R.string.hacks))
|
||||
|
||||
@@ -788,7 +788,7 @@ int Java_org_yuzu_yuzu_1emu_NativeLibrary_installFileToNand(JNIEnv* env, jobject
|
||||
jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_doesUpdateMatchProgram(JNIEnv* env, jobject jobj,
|
||||
jstring jprogramId,
|
||||
jstring jupdatePath) {
|
||||
u64 program_id = EmulationSession::GetProgramId(env, jprogramId);
|
||||
const u64 program_id = FileSys::GetBaseTitleID(EmulationSession::GetProgramId(env, jprogramId));
|
||||
std::string updatePath = Common::Android::GetJString(env, jupdatePath);
|
||||
std::shared_ptr<FileSys::NSP> nsp = std::make_shared<FileSys::NSP>(
|
||||
EmulationSession::GetInstance().System().GetFilesystem()->OpenFile(
|
||||
@@ -796,7 +796,7 @@ jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_doesUpdateMatchProgram(JNIEnv* en
|
||||
for (const auto& item : nsp->GetNCAs()) {
|
||||
for (const auto& nca_details : item.second) {
|
||||
if (nca_details.second->GetName().ends_with(".cnmt.nca")) {
|
||||
auto update_id = nca_details.second->GetTitleId() & ~0xFFFULL;
|
||||
const auto update_id = FileSys::GetBaseTitleID(nca_details.second->GetTitleId());
|
||||
if (update_id == program_id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -580,8 +580,6 @@
|
||||
<string name="renderer_reactive_flushing_description">يحسن دقة العرض في بعض الألعاب على حساب الأداء.</string>
|
||||
<string name="enable_buffer_history">تمكين سجل التخزين المؤقت</string>
|
||||
<string name="enable_buffer_history_description">يُتيح هذا الخيار الوصول إلى حالات التخزين المؤقت السابقة. وقد يُحسّن جودة العرض وثبات الأداء في بعض الألعاب.</string>
|
||||
<string name="enable_gpu_buffer_readback">تفعيل قراءة مخزن وحدة معالجة الرسومات</string>
|
||||
<string name="enable_gpu_buffer_readback_description">يحافظ هذا النظام على بيانات المخزن المؤقت المُعدّلة بواسطة وحدة معالجة الرسومات عن طريق قراءتها مرة أخرى قبل التحميل. تتطلب بعض الألعاب ذلك لعرض بعض التأثيرات بشكل صحيح. قد يُسبب ذلك مشاكل إذا لم يتمكن الجهاز من التعامل مع عبء العمل الإضافي.</string>
|
||||
<string name="use_optimized_vertex_buffers">مخازن الرؤوس المُحسّنة</string>
|
||||
<string name="use_optimized_vertex_buffers_description">يُتيح ربطًا مُحسَّنًا لمخازن الرؤوس لتحسين الأداء. يتطلب برامج تشغيل Mesa 26.0+ Turnip/ برامج تشغيل QCOM. قد يتعطل على برامج تشغيل Turnip القديمة (25.3 وما دون).</string>
|
||||
|
||||
@@ -1099,7 +1097,6 @@
|
||||
<string name="gpu_fence_behavior_immediate">فوري</string>
|
||||
<string name="gpu_fence_behavior_balanced">متوازن</string>
|
||||
<string name="gpu_fence_behavior_accurate">دقيق</string>
|
||||
<string name="gpu_fence_behavior_strict">صارم</string>
|
||||
|
||||
<string name="vram_usage_conservative">محافظ</string>
|
||||
<string name="vram_usage_aggressive">عدواني</string>
|
||||
|
||||
@@ -967,7 +967,6 @@ Wirklich fortfahren?</string>
|
||||
<string name="gpu_fence_behavior_immediate">Direkt</string>
|
||||
<string name="gpu_fence_behavior_balanced">Ausgewogen</string>
|
||||
<string name="gpu_fence_behavior_accurate">Genau</string>
|
||||
<string name="gpu_fence_behavior_strict">Strikt</string>
|
||||
|
||||
<string name="vram_usage_conservative">Konservativ</string>
|
||||
<string name="vram_usage_aggressive">Aggressiv</string>
|
||||
|
||||
@@ -289,6 +289,7 @@
|
||||
<string name="gpu_driver_fetcher">Obtenedor de controladores de la GPU</string>
|
||||
<string name="gpu_driver_manager">Gestor de controladores de la GPU</string>
|
||||
<string name="install_gpu_driver_description">Instale los controladores alternativos para obtener un posible mejor rendimiento o precisión</string>
|
||||
<string name="post_processing_add">Añadir efecto</string>
|
||||
<string name="post_processing_open_list">Abrir lista</string>
|
||||
<string name="post_processing_close_list">Cerrar lista</string>
|
||||
<string name="post_processing_reset">Restablecer a predeterminado</string>
|
||||
@@ -523,8 +524,6 @@
|
||||
<string name="renderer_reactive_flushing_description">Mejora la precisión de renderizado en algunos juegos, pero reduce el rendimiento.</string>
|
||||
<string name="enable_buffer_history">Activar el historial del búfer</string>
|
||||
<string name="enable_buffer_history_description">Permite el acceso al estado del búfer anterior. Esta opción puede mejorar la calidad de renderizado y la consistencia en el rendimiento de algunos juegos.</string>
|
||||
<string name="enable_gpu_buffer_readback">Activar la lectura del buffer de la GPU</string>
|
||||
<string name="enable_gpu_buffer_readback_description">Conserva los datos del búfer modificados por la GPU leyéndolos antes de subirlos.\nAlgunos juegos requieren esto para renderizar correctamente ciertos efectos.\nPuede causar problemas si el hardware no puede soportar la carga de trabajo adicional.</string>
|
||||
<string name="use_optimized_vertex_buffers">Búferes de vértices optimizados</string>
|
||||
<string name="use_optimized_vertex_buffers_description">Permite la optimización del enlace del búfer de vértices para un mejor rendimiento. Requiere controladores Mesa 26.0+ Turnip/ controladores QCOM. Fallará con controladores Turnip más antiguos (versión 25.3 o inferior).</string>
|
||||
|
||||
@@ -1037,7 +1036,6 @@
|
||||
<string name="gpu_fence_behavior_immediate">Inmediato</string>
|
||||
<string name="gpu_fence_behavior_balanced">Equilibrado</string>
|
||||
<string name="gpu_fence_behavior_accurate">Preciso</string>
|
||||
<string name="gpu_fence_behavior_strict">Estricto</string>
|
||||
|
||||
<string name="vram_usage_conservative">Conservador</string>
|
||||
<string name="vram_usage_aggressive">Agresivo</string>
|
||||
|
||||
@@ -318,6 +318,13 @@
|
||||
<string name="frame_gen_target_rate">Целевая частота кадров</string>
|
||||
<string name="frame_gen_target_rate_description">Выберите значение под ваш дисплей. Множитель подстроится сам, чтобы его держать, и откатит изменения, если игра начнёт тормозить.</string>
|
||||
<string name="frame_gen_target_rate_off">Использовать фиксированный множитель</string>
|
||||
<string name="frame_gen_on">Вкл.</string>
|
||||
<string name="frame_gen_off">Выкл.</string>
|
||||
<string name="frame_gen_fixed">Фикс.</string>
|
||||
<string name="frame_gen_flow_auto">Авто</string>
|
||||
<string name="frame_gen_quick_description">Включите или выключите генерацию кадров и выберите множитель кадров.</string>
|
||||
<string name="frame_gen_target_rate_quick_description">Генерация кадров с заданной частотой кадров. Множитель регулируется автоматически.</string>
|
||||
<string name="frame_gen_flow_scale_quick_description">Разрешение, используемое для оценки движения между кадрами. Меньшие значения экономят время ГПУ.</string>
|
||||
<string name="frame_gen_queue_target">Целевой размер очереди кадров</string>
|
||||
<string name="frame_gen_queue_target_description">Сколько готовых кадров может ожидать перед выводом на экран. Более длинные очереди сглаживают скачки ГПУ ценой задержки ввода.</string>
|
||||
<string name="frame_gen_queue_target_0">Минимальная задержка (Без буферизации)</string>
|
||||
@@ -328,12 +335,14 @@
|
||||
<string name="frame_gen_flow_scale">Разрешение оценки движения</string>
|
||||
<string name="frame_gen_flow_scale_description">Разрешение прохода оптического потока в долях от выходного разрешения. Его понижение — самый дешёвый способ вернуть производительность.</string>
|
||||
<string name="frame_gen_unsupported">Генерация кадров недоступна</string>
|
||||
<string name="frame_gen_unsupported_description">В этом ГПУ драйвере отсутствует поддержка модели памяти Vulkan или половинной точности (float16), которая требуется шейдерам Lossless Scaling.</string>
|
||||
<string name="lossless_scaling_setup_description">Опционально. Укажите свой Lossless.dll для включения генерации кадров позже.</string>
|
||||
<string name="lossless_scaling_install">Установить Lossless.dll</string>
|
||||
<string name="lossless_scaling_install_description">Для генерации кадров требуется ваша собственная легальная копия Lossless.dll из Lossless Scaling</string>
|
||||
<string name="lossless_scaling_replace_description">Выбрать другой файл Lossless.dll</string>
|
||||
<string name="frame_generation_support">Генерация кадров</string>
|
||||
<string name="frame_generation_supported">Поддерживается</string>
|
||||
<string name="frame_generation_unsupported">Не поддерживается (нет модели памяти Vulkan или float16)</string>
|
||||
<string name="lossless_scaling_description">Предоставьте свою копию Lossless.dll для включения генерации кадров</string>
|
||||
<string name="lossless_scaling_installed">Установлена</string>
|
||||
<string name="lossless_scaling_not_installed">Не установлена</string>
|
||||
@@ -560,8 +569,6 @@
|
||||
<string name="renderer_reactive_flushing_description">Повышение точности рендеринга в некоторых играх за счет снижения производительности.</string>
|
||||
<string name="enable_buffer_history">Включить историю буфера</string>
|
||||
<string name="enable_buffer_history_description">Позволяет обращаться к предыдущим состояниям буфера. Эта опция может повысить качество рендеринга и стабильность производительности в некоторых играх.</string>
|
||||
<string name="enable_gpu_buffer_readback">Включить обратное чтение буфера ГПУ</string>
|
||||
<string name="enable_gpu_buffer_readback_description">Сохраняет измененные ГПУ данные буфера путем чтения их обратно перед выгрузками. Некоторые игры требуют этого, чтобы рендерить определенные эффекты правильно. Может вызывать проблемы если оборудование не может обработать дополнительную рабочую нагрузку.</string>
|
||||
<string name="use_optimized_vertex_buffers">Оптимизированные вершинные буферы</string>
|
||||
<string name="use_optimized_vertex_buffers_description">Включает оптимизированную привязку вершинного буфера для повышения производительности. Требует Mesa Turnip 26.0+ / QCOM. Приводит к вылету на старых версиях драйверов Turnip (25.3 и ниже).</string>
|
||||
|
||||
@@ -1079,7 +1086,6 @@
|
||||
<string name="gpu_fence_behavior_immediate">Мгновенный</string>
|
||||
<string name="gpu_fence_behavior_balanced">Сбалансированный</string>
|
||||
<string name="gpu_fence_behavior_accurate">Точный</string>
|
||||
<string name="gpu_fence_behavior_strict">Строгий</string>
|
||||
|
||||
<string name="vram_usage_conservative">Консервативный</string>
|
||||
<string name="vram_usage_aggressive">Агрессивный</string>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
|
||||
|
||||
<string name="app_disclaimer">本软件可以运行用于 Nintendo Switch 游戏机的游戏。不包含任何游戏或密钥。<br /><br />在您开始之前, 请定位您设备存储上的 <![CDATA[<b> prod.keys </b>]]> 文件。<br /><br /><![CDATA[<a href=\"https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/QuickStart.md\">了解更多</a>]]></string>
|
||||
<string name="notice_notification_channel_name">错误与注意事项</string>
|
||||
<string name="notice_notification_channel_description">当发生错误时显示通知。</string>
|
||||
<string name="notification_permission_not_granted">未授予通知权限!</string>
|
||||
@@ -290,6 +291,25 @@
|
||||
<string name="gpu_driver_fetcher">GPU驱动获取器</string>
|
||||
<string name="gpu_driver_manager">GPU 驱动管理器</string>
|
||||
<string name="install_gpu_driver_description">安装替代的驱动程序以获得更好的性能和精度</string>
|
||||
<string name="post_processing">后处理效果</string>
|
||||
<string name="post_processing_description">在渲染完成后应用 ReShade FX 效果</string>
|
||||
<string name="post_processing_per_game_description">配置此游戏的效果链</string>
|
||||
<string name="post_processing_add">添加效果</string>
|
||||
<string name="post_processing_remove">移除</string>
|
||||
<string name="post_processing_open_list">打开列表</string>
|
||||
<string name="post_processing_close_list">关闭列表</string>
|
||||
<string name="post_processing_remove_all">移除效果</string>
|
||||
<string name="post_processing_preset_locked">预设已激活。在开始游戏前可以在后处理效果中编辑它。</string>
|
||||
<string name="post_processing_preset_modified">数值已从原始预设被更改。</string>
|
||||
<string name="post_processing_presets">预设</string>
|
||||
<string name="post_processing_preset_new">新建预设</string>
|
||||
<string name="post_processing_preset_new_description">把您加载的效果及当前数值保存为一个预设,以便今后选用。</string>
|
||||
<string name="post_processing_preset_name_invalid">请给预设起一个不含等号的名称。</string>
|
||||
<string name="post_processing_preset_none">无预设</string>
|
||||
<string name="post_processing_preset_delete">删除预设</string>
|
||||
<string name="post_processing_preset_reset">重置预设值</string>
|
||||
<string name="post_processing_reset">重置为默认值</string>
|
||||
<string name="post_processing_empty">找不到效果。请在此文件中放置 .fx 文件:</string>
|
||||
<string name="frame_gen">帧生成</string>
|
||||
<string name="frame_gen_per_game_description">配置针对此游戏的帧生成设定</string>
|
||||
<string name="frame_gen_description">设定要在使用无损缩放渲染的帧之间应用的插帧。启用后强制采用FIFO呈现模式 。</string>
|
||||
@@ -304,6 +324,13 @@
|
||||
<string name="frame_gen_target_rate_60">60 FPS</string>
|
||||
<string name="frame_gen_target_rate_90">90 FPS</string>
|
||||
<string name="frame_gen_target_rate_120">120 FPS</string>
|
||||
<string name="frame_gen_on">开</string>
|
||||
<string name="frame_gen_off">关</string>
|
||||
<string name="frame_gen_fixed">固定</string>
|
||||
<string name="frame_gen_flow_auto">自动</string>
|
||||
<string name="frame_gen_quick_description">打开或关闭帧生成并选择帧生成倍数。</string>
|
||||
<string name="frame_gen_target_rate_quick_description">生成帧到目标帧率。倍率会自动调整。</string>
|
||||
<string name="frame_gen_flow_scale_quick_description">用来估算帧间运动的分辨率。较低的值可以节省 GPU 时间。</string>
|
||||
<string name="frame_gen_queue_target">帧队列目标</string>
|
||||
<string name="frame_gen_queue_target_description">在显示之前有多少已完成渲染的帧正在等待。较大的队列可以缓解 GPU 突发的压力,但会增加输入延迟。</string>
|
||||
<string name="frame_gen_queue_target_0">最低延迟 (无缓冲)</string>
|
||||
@@ -314,12 +341,14 @@
|
||||
<string name="frame_gen_flow_scale">运动预估分辨率</string>
|
||||
<string name="frame_gen_flow_scale_description">光流通道的分辨率,以输出的比例表示。降低它是提升性能最经济的做法。</string>
|
||||
<string name="frame_gen_unsupported">帧生成不可用</string>
|
||||
<string name="frame_gen_unsupported_description">这个 GPU 驱动缺少 Lossless Scaling 着色器所需的 Vulkan 内存模型或半精度 (float16) 支持。</string>
|
||||
<string name="lossless_scaling_setup_description">作为可选项。请提供您自己的 Lossless.dll 以便在之后可以启用帧生成。</string>
|
||||
<string name="lossless_scaling_install">安装 Lossless.dll</string>
|
||||
<string name="lossless_scaling_install_description">帧生成需要您自己从 Lossless Scaling 获得合法的 Lossless.dll 副本</string>
|
||||
<string name="lossless_scaling_replace_description">选择其它 Lossless.dll 副本</string>
|
||||
<string name="frame_generation_support">帧生成</string>
|
||||
<string name="frame_generation_supported">支持</string>
|
||||
<string name="frame_generation_unsupported">不支持 (无 Vulkan 内存模型或 float16)</string>
|
||||
<string name="lossless_scaling">无损缩放</string>
|
||||
<string name="lossless_scaling_description">提供您自己的 Lossless.dll 文件以启用帧生成</string>
|
||||
<string name="lossless_scaling_installed">已安装</string>
|
||||
@@ -541,8 +570,6 @@
|
||||
<string name="renderer_reactive_flushing_description">通过牺牲性能来提升某些游戏的渲染精度。</string>
|
||||
<string name="enable_buffer_history">启用缓冲区历史</string>
|
||||
<string name="enable_buffer_history_description">启用对先前缓冲区状态的访问。此选项可在某些游戏中提升渲染质量并保持性能的一致性。</string>
|
||||
<string name="enable_gpu_buffer_readback">启用 GPU 缓冲区回读</string>
|
||||
<string name="enable_gpu_buffer_readback_description">在上传前回读经由 GPU 修改过的缓冲区数据,以将其保留。一些游戏会用到这项设定以正确渲染某些效果。如果硬件无法处理额外的工作负载,则可能会导致问题。</string>
|
||||
<string name="use_optimized_vertex_buffers">优化顶点缓冲区</string>
|
||||
<string name="use_optimized_vertex_buffers_description">启用经过优化的顶点缓冲区绑定以提升性能。需要 Mesa 26.0 及以上版本的 Turnip 或 QCOM 驱动程序。若使用较旧版本的 Turnip 驱动 (25.3 及以下版本) 则会导致崩溃。</string>
|
||||
|
||||
@@ -611,6 +638,11 @@
|
||||
<string name="log">日志记录</string>
|
||||
<string name="flush_by_line">按行刷新调试日志</string>
|
||||
<string name="flush_by_line_description">在每行写入时刷新调试日志,使在崩溃或冻结时调试更容易。</string>
|
||||
<string name="extended_logging">开启扩展日志</string>
|
||||
<string name="extended_logging_description">将最大日志文件大小从 100 MiB 提升至 1GiB。</string>
|
||||
<string name="log_filter">日志筛选器</string>
|
||||
<string name="log_filter_description">控制 Eden 的日志类别。例如: *:Info Service.LM:Debug</string>
|
||||
|
||||
<!-- GPU Logging strings -->
|
||||
<string name="gpu_logging_header">GPU 日志</string>
|
||||
<string name="gpu_log_level">日志等级</string>
|
||||
@@ -894,6 +926,8 @@
|
||||
<string name="loader_error_file_not_found">ROM 文件不存在</string>
|
||||
|
||||
<string name="loader_requires_firmware">游戏需要固件</string>
|
||||
<string name="loader_requires_firmware_description"><![CDATA[这个游戏可能需要固件才能正常运行,但您还没有安装任何固件。请在启动前安装固件,或者按 “确定” 继续启动。]]></string>
|
||||
|
||||
<!-- Intent Launch strings -->
|
||||
<string name="searching_for_game">正在搜索游戏...</string>
|
||||
<string name="game_not_found_for_title_id">未找到标题ID的游戏: %1$s</string>
|
||||
@@ -1053,7 +1087,6 @@
|
||||
<string name="gpu_fence_behavior_immediate">即时</string>
|
||||
<string name="gpu_fence_behavior_balanced">均衡</string>
|
||||
<string name="gpu_fence_behavior_accurate">精确</string>
|
||||
<string name="gpu_fence_behavior_strict">严格</string>
|
||||
|
||||
<string name="vram_usage_conservative">保守式</string>
|
||||
<string name="vram_usage_aggressive">主动式</string>
|
||||
|
||||
@@ -229,7 +229,7 @@
|
||||
<string name="add_directory_success">遊戲目錄新增成功</string>
|
||||
<string name="enable_update_checks">檢查更新</string>
|
||||
<string name="enable_update_checks_description">在Eden啟動時檢查有無新版本並選擇是否要下載與安裝更新</string>
|
||||
<string name="update_available">偵測到新版本</string>
|
||||
<string name="update_available">發現新版本</string>
|
||||
<string name="update_available_description">有更新可供安裝:%1$s\n\n您要進行更新嗎?</string>
|
||||
<string name="downloading_update">下載更新中</string>
|
||||
<string name="update_download_failed">更新下載失敗</string>
|
||||
@@ -561,8 +561,6 @@
|
||||
<string name="renderer_reactive_flushing_description">犧牲效能,以改善部分遊戲的轉譯準確度</string>
|
||||
<string name="enable_buffer_history">啟用緩衝區歷史</string>
|
||||
<string name="enable_buffer_history_description">允許存取先前的緩衝區狀態。此選項可能會改善部分遊戲的渲染品質與效能穩定性</string>
|
||||
<string name="enable_gpu_buffer_readback">啟用 GPU 緩衝區讀回</string>
|
||||
<string name="enable_gpu_buffer_readback_description">透過在上傳之前先將 GPU 修改過的緩衝區資料讀回來保存資料,部分遊戲需要啟用此功能才能正常渲染遊戲特效。如果硬體無法負荷可能會導致錯誤</string>
|
||||
<string name="use_optimized_vertex_buffers">最佳化頂點緩衝區</string>
|
||||
<string name="use_optimized_vertex_buffers_description">啟用最佳化的頂點緩衝區綁定。需要安裝 Mesa 26.0+ Turnip drivers/Qualcomm drivers。使用舊版 Turnip drivers 會導致當機 (25.3版和更低的版本)</string>
|
||||
|
||||
@@ -1020,9 +1018,40 @@
|
||||
<string name="memory_6gb">6GB (不穩定)</string>
|
||||
<string name="memory_8gb">8GB (不穩定)</string>
|
||||
|
||||
<!-- CPU clock levels -->
|
||||
<string name="clock_normal">正常</string>
|
||||
<string name="clock_boost">加速</string>
|
||||
<string name="clock_fast">超頻</string>
|
||||
|
||||
<!-- GPU clock levels -->
|
||||
<string name="fast_gpu_normal">正常</string>
|
||||
<string name="fast_gpu_medium">加速</string>
|
||||
<string name="fast_gpu_high">超頻</string>
|
||||
|
||||
<!-- GPU swizzle texture size -->
|
||||
<string name="gpu_texturesizeswizzle_verysmall">極小 (16MB)</string>
|
||||
<string name="gpu_texturesizeswizzle_small">小(32MB)</string>
|
||||
<string name="gpu_texturesizeswizzle_normal">正常(128MB)</string>
|
||||
<string name="gpu_texturesizeswizzle_large">大(256MB)</string>
|
||||
<string name="gpu_texturesizeswizzle_verylarge">極大(512MB)</string>
|
||||
|
||||
<!-- GPU swizzle streams -->
|
||||
<string name="gpu_swizzle_verylow">極小(4MB)</string>
|
||||
<string name="gpu_swizzle_low">小(8MB)</string>
|
||||
<string name="gpu_swizzle_normal">正常(16MB)</string>
|
||||
<string name="gpu_swizzle_medium">中(32MB)</string>
|
||||
<string name="gpu_swizzle_high">大(64MB)</string>
|
||||
|
||||
<!-- GPU swizzle chunks -->
|
||||
<string name="gpu_swizzlechunk_verylow">極小(32)</string>
|
||||
<string name="gpu_swizzlechunk_low">小(64)</string>
|
||||
<string name="gpu_swizzlechunk_normal">正常(128)</string>
|
||||
<string name="gpu_swizzlechunk_medium">中(256)</string>
|
||||
<string name="gpu_swizzlechunk_high">大(512)</string>
|
||||
|
||||
<!-- Temperature Units -->
|
||||
<string name="temperature_celsius">攝氏度</string>
|
||||
<string name="temperature_fahrenheit">華氏度</string>
|
||||
<string name="temperature_celsius">攝氏</string>
|
||||
<string name="temperature_fahrenheit">華氏</string>
|
||||
|
||||
<!-- Memory Sizes -->
|
||||
<string name="memory_byte_shorthand">B</string>
|
||||
@@ -1035,6 +1064,8 @@
|
||||
|
||||
<string name="renderer_none">無</string>
|
||||
|
||||
<!-- Renderer Accuracy -->
|
||||
<string name="renderer_accuracy_low">效能</string>
|
||||
<string name="renderer_accuracy_high">準確</string>
|
||||
|
||||
<!-- DMA Accuracy -->
|
||||
|
||||
@@ -558,7 +558,6 @@
|
||||
<item>@string/gpu_fence_behavior_immediate</item>
|
||||
<item>@string/gpu_fence_behavior_balanced</item>
|
||||
<item>@string/gpu_fence_behavior_accurate</item>
|
||||
<item>@string/gpu_fence_behavior_strict</item>
|
||||
</string-array>
|
||||
<integer-array name="gpuFenceBehaviorValues">
|
||||
<item>0</item>
|
||||
|
||||
@@ -586,8 +586,6 @@
|
||||
<string name="renderer_reactive_flushing_description">Improves rendering accuracy in some games at the cost of performance.</string>
|
||||
<string name="enable_buffer_history">Enable buffer history</string>
|
||||
<string name="enable_buffer_history_description">Enables access to previous buffer states. This option may improve rendering quality and performance consistency in some games.</string>
|
||||
<string name="enable_gpu_buffer_readback">Enable GPU Buffer Readback</string>
|
||||
<string name="enable_gpu_buffer_readback_description">Preserves GPU-modified buffer data by reading it back before uploads. Some games require this to render certain effects properly. May cause issues if the hardware cannot handle the additional workload.</string>
|
||||
<string name="use_optimized_vertex_buffers">Optimized Vertex Buffers</string>
|
||||
<string name="use_optimized_vertex_buffers_description">Enables optimized vertex buffer binding for improved performance. Requires Mesa 26.0+ Turnip drivers/ QCOM drivers. Will crash on older Turnip drivers (25.3 and below).</string>
|
||||
|
||||
@@ -1138,7 +1136,6 @@
|
||||
<string name="gpu_fence_behavior_immediate">Immediate</string>
|
||||
<string name="gpu_fence_behavior_balanced">Balanced</string>
|
||||
<string name="gpu_fence_behavior_accurate">Accurate</string>
|
||||
<string name="gpu_fence_behavior_strict">Strict</string>
|
||||
|
||||
<!-- ASTC Decoding Method Choices -->
|
||||
<string name="accelerate_astc_cpu" translatable="false">CPU</string>
|
||||
|
||||
@@ -76,7 +76,6 @@ add_library(
|
||||
logging.h
|
||||
lz4_compression.cpp
|
||||
lz4_compression.h
|
||||
make_unique_for_overwrite.h
|
||||
math_util.h
|
||||
memory_detect.cpp
|
||||
memory_detect.h
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
|
||||
namespace Common {
|
||||
|
||||
template <class T>
|
||||
requires(!std::is_array_v<T>)
|
||||
std::unique_ptr<T> make_unique_for_overwrite() {
|
||||
return std::unique_ptr<T>(new T);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
requires std::is_unbounded_array_v<T>
|
||||
std::unique_ptr<T> make_unique_for_overwrite(std::size_t n) {
|
||||
return std::unique_ptr<T>(new std::remove_extent_t<T>[n]);
|
||||
}
|
||||
|
||||
template <class T, class... Args>
|
||||
requires std::is_bounded_array_v<T>
|
||||
void make_unique_for_overwrite(Args&&...) = delete;
|
||||
|
||||
} // namespace Common
|
||||
@@ -8,8 +8,7 @@
|
||||
|
||||
#include <iterator>
|
||||
#include <cstring>
|
||||
|
||||
#include "common/make_unique_for_overwrite.h"
|
||||
#include <memory>
|
||||
|
||||
namespace Common {
|
||||
|
||||
@@ -38,8 +37,9 @@ public:
|
||||
ScratchBuffer() = default;
|
||||
|
||||
explicit ScratchBuffer(size_type initial_capacity)
|
||||
: last_requested_size{initial_capacity}, buffer_capacity{initial_capacity},
|
||||
buffer{Common::make_unique_for_overwrite<T[]>(initial_capacity)} {}
|
||||
: last_requested_size{initial_capacity}
|
||||
, buffer_capacity{initial_capacity}
|
||||
, buffer{std::make_unique_for_overwrite<T[]>(initial_capacity)} {}
|
||||
|
||||
~ScratchBuffer() = default;
|
||||
ScratchBuffer(const ScratchBuffer&) = delete;
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
/// The previously held data will remain intact.
|
||||
void resize(size_type size) {
|
||||
if (size > buffer_capacity) {
|
||||
auto new_buffer = Common::make_unique_for_overwrite<T[]>(size);
|
||||
auto new_buffer = std::make_unique_for_overwrite<T[]>(size);
|
||||
std::memcpy(new_buffer.get(), buffer.get(), buffer_capacity * sizeof(T));
|
||||
buffer = std::move(new_buffer);
|
||||
buffer_capacity = size;
|
||||
@@ -77,7 +77,7 @@ public:
|
||||
void resize_destructive(size_type size) {
|
||||
if (size > buffer_capacity) {
|
||||
buffer_capacity = size;
|
||||
buffer = Common::make_unique_for_overwrite<T[]>(buffer_capacity);
|
||||
buffer = std::make_unique_for_overwrite<T[]>(buffer_capacity);
|
||||
}
|
||||
last_requested_size = size;
|
||||
}
|
||||
|
||||
@@ -178,10 +178,6 @@ bool IsGPUFenceBehaviorAccurate() {
|
||||
return values.gpu_fence_behavior.GetValue() == GpuFenceBehavior::Accurate;
|
||||
}
|
||||
|
||||
bool IsGPUFenceBehaviorStrict() {
|
||||
return values.gpu_fence_behavior.GetValue() == GpuFenceBehavior::Strict;
|
||||
}
|
||||
|
||||
bool IsFastmemEnabled() {
|
||||
if (values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Debugging)
|
||||
return bool(values.cpuopt_fastmem);
|
||||
|
||||
@@ -525,7 +525,7 @@ struct Values {
|
||||
SwitchableSetting<GpuFenceBehavior, true> gpu_fence_behavior{linkage,
|
||||
GpuFenceBehavior::Default,
|
||||
GpuFenceBehavior::Default,
|
||||
GpuFenceBehavior::Strict,
|
||||
GpuFenceBehavior::Accurate,
|
||||
"gpu_fence_behavior",
|
||||
Category::RendererAdvanced,
|
||||
Specialization::Default,
|
||||
@@ -655,13 +655,6 @@ struct Values {
|
||||
|
||||
SwitchableSetting<bool> rescale_hack{linkage, false, "rescale_hack",
|
||||
Category::RendererHacks};
|
||||
SwitchableSetting<bool> enable_gpu_buffer_readback{linkage,
|
||||
false,
|
||||
"enable_gpu_buffer_readback",
|
||||
Category::RendererAdvanced,
|
||||
Specialization::Default,
|
||||
true,
|
||||
true};
|
||||
|
||||
SwitchableSetting<bool> use_asynchronous_shaders{linkage, false, "use_asynchronous_shaders",
|
||||
Category::RendererHacks};
|
||||
@@ -979,7 +972,6 @@ bool IsDMALevelSafe();
|
||||
bool IsGPUFenceBehaviorDefault();
|
||||
bool IsGPUFenceBehaviorBalanced();
|
||||
bool IsGPUFenceBehaviorAccurate();
|
||||
bool IsGPUFenceBehaviorStrict();
|
||||
|
||||
bool IsFastmemEnabled();
|
||||
void SetNceEnabled(bool is_64bit);
|
||||
|
||||
@@ -137,7 +137,7 @@ ENUM(VramUsageMode, Conservative, Aggressive);
|
||||
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, Strict);
|
||||
ENUM(GpuFenceBehavior, Default, Immediate, Balanced, Accurate);
|
||||
ENUM(CpuBackend, Dynarmic, Nce);
|
||||
ENUM(CpuAccuracy, Auto, Accurate, Unsafe, Paranoid, Debugging);
|
||||
ENUM(CpuClock, Normal, Boost, Overclock)
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <algorithm>
|
||||
#include <windows.h>
|
||||
#include <mutex>
|
||||
#else
|
||||
@@ -20,32 +21,36 @@ namespace Common {
|
||||
|
||||
#ifdef _WIN32
|
||||
static std::vector<std::pair<u64, u64>> vector_regions {};
|
||||
static std::mutex vector_regions_mutex {};
|
||||
|
||||
// Workaround for handling non-commited memory accessed by Dynarmic; usually result of an error
|
||||
static LONG WINAPI FakePageFaultHandler(PEXCEPTION_POINTERS info) {
|
||||
DWORD code = info->ExceptionRecord->ExceptionCode;
|
||||
u64 exception_addr = reinterpret_cast<u64>(info->ExceptionRecord->ExceptionAddress);
|
||||
u64 exception_addr = reinterpret_cast<u64>(info->ExceptionRecord->ExceptionInformation[1]);
|
||||
|
||||
if (code != EXCEPTION_ACCESS_VIOLATION) {
|
||||
if (code != EXCEPTION_ACCESS_VIOLATION || info->ExceptionRecord->ExceptionInformation[0] == 1) {
|
||||
// Not our problem
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
u64 addr = 0, addr2 = 0;
|
||||
|
||||
for (auto region: vector_regions) {
|
||||
auto addr_shifted = exception_addr >> HostPageBits;
|
||||
if (region.first <= addr_shifted && addr_shifted <= region.second) {
|
||||
addr = addr_shifted;
|
||||
}
|
||||
{
|
||||
std::lock_guard lock(vector_regions_mutex);
|
||||
for (auto region: vector_regions) {
|
||||
auto addr_shifted = exception_addr >> HostPageBits;
|
||||
if (region.first <= addr_shifted && addr_shifted <= region.second) {
|
||||
addr = addr_shifted;
|
||||
}
|
||||
|
||||
// Page-boundary accesses
|
||||
if (auto addr_ = (exception_addr + 0x40) >> HostPageBits; addr_ != addr_shifted && region.first <= addr_ && addr_ <= region.second) {
|
||||
addr2 = addr_;
|
||||
}
|
||||
// Page-boundary accesses
|
||||
if (auto addr_ = (exception_addr + 0x40) >> HostPageBits; addr_ != addr_shifted && region.first <= addr_ && addr_ <= region.second) {
|
||||
addr2 = addr_;
|
||||
}
|
||||
|
||||
if (addr != 0 || addr2 != 0) {
|
||||
break;
|
||||
if (addr != 0 || addr2 != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,8 +82,16 @@ bool CommitVectorPage(uintptr_t addr, bool write) noexcept {
|
||||
auto res = VirtualQuery(reinterpret_cast<void*>(addr), &info, sizeof(info));
|
||||
if (res == 0) {
|
||||
LOG_CRITICAL(HW_Memory, "Failed to query large buffer region at {:#x} with error {}, will try committing anyway", addr, GetLastError());
|
||||
} else if (info.State == MEM_COMMIT) {
|
||||
DWORD old_protect {};
|
||||
auto perm = write ? PAGE_READWRITE : PAGE_READONLY;
|
||||
if (!VirtualProtect(reinterpret_cast<void*>(addr), HostPageSize, perm, &old_protect)) {
|
||||
LOG_ERROR(HW_Memory, "Failed to change permissions of large buffer region at {:#x}, error {}", addr, GetLastError());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} else if (info.State != MEM_RESERVE) {
|
||||
LOG_ERROR(HW_Memory, "Tried to commit an unreserved large buffer region at {:#x} that is not mapped or is already committed (state {:#x})", addr, info.State);
|
||||
LOG_ERROR(HW_Memory, "Tried to commit an unreserved large buffer region at {:#x} that is not mapped (state {:#x})", addr, info.State);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -96,6 +109,21 @@ bool CommitVectorPage(uintptr_t addr, bool write) noexcept {
|
||||
#ifndef MAP_NOCORE
|
||||
#define MAP_NOCORE 0
|
||||
#endif
|
||||
#ifndef MADV_FREE
|
||||
#define MADV_FREE MADV_DONTNEED
|
||||
#endif
|
||||
|
||||
void DecommitVectorPage(uintptr_t base) noexcept {
|
||||
#if defined(_WIN32)
|
||||
VirtualFree(reinterpret_cast<LPVOID>(base), HostPageSize, MEM_DECOMMIT);
|
||||
#elif defined(__linux__)
|
||||
// Linux's MADV_DONTNEED zeros out pages for us
|
||||
madvise(reinterpret_cast<void*>(base), HostPageSize, MADV_DONTNEED);
|
||||
#else
|
||||
madvise(reinterpret_cast<void*>(base), HostPageSize, MADV_FREE);
|
||||
std::memset(reinterpret_cast<void*>(base), 0, HostPageSize);
|
||||
#endif
|
||||
}
|
||||
|
||||
void* AllocateMemoryPages(std::size_t size) noexcept {
|
||||
if (auto page = HostPageSize; size % page != 0) {
|
||||
@@ -108,7 +136,8 @@ void* AllocateMemoryPages(std::size_t size) noexcept {
|
||||
void* base = VirtualAlloc(nullptr, size, MEM_RESERVE, PAGE_READWRITE);
|
||||
|
||||
if (base != nullptr) {
|
||||
vector_regions.emplace_back(reinterpret_cast<u64>(base), reinterpret_cast<u64>(base) + size);
|
||||
std::lock_guard lock(vector_regions_mutex);
|
||||
vector_regions.emplace_back(reinterpret_cast<u64>(base) >> HostPageBits, (reinterpret_cast<u64>(base) + size) >> HostPageBits);
|
||||
|
||||
static std::once_flag flag;
|
||||
std::call_once(flag, []() { AddVectoredExceptionHandler(1, FakePageFaultHandler); });
|
||||
@@ -134,6 +163,8 @@ void FreeMemoryPages(void* base, [[maybe_unused]] std::size_t size) noexcept {
|
||||
if (!base)
|
||||
return;
|
||||
#ifdef _WIN32
|
||||
std::lock_guard lock(vector_regions_mutex);
|
||||
std::erase_if(vector_regions, [base](const auto& r) {return r.first == reinterpret_cast<u64>(base); });
|
||||
ASSERT(VirtualFree(base, 0, MEM_RELEASE));
|
||||
#else
|
||||
ASSERT(munmap(base, size) == 0);
|
||||
|
||||
@@ -28,13 +28,14 @@ constexpr u64 HostPageBits = 12;
|
||||
constexpr u64 HostPageMask = ~(HostPageSize - 1);
|
||||
bool CommitVectorPage(uintptr_t addr, bool write) noexcept;
|
||||
#else
|
||||
const u64 HostPageSize = sysconf(_SC_PAGESIZE);
|
||||
const u64 HostPageBits = std::countr_zero(HostPageSize);
|
||||
const u64 HostPageMask = ~(HostPageSize - 1);
|
||||
inline const u64 HostPageSize = sysconf(_SC_PAGESIZE);
|
||||
inline const u64 HostPageBits = std::countr_zero(HostPageSize);
|
||||
inline const u64 HostPageMask = ~(HostPageSize - 1);
|
||||
#endif
|
||||
|
||||
void* AllocateMemoryPages(std::size_t size) noexcept;
|
||||
void FreeMemoryPages(void* base, std::size_t size) noexcept;
|
||||
void DecommitVectorPage(uintptr_t base) noexcept;
|
||||
|
||||
/// A large page-aligned buffer that has optimized memory usage for zero-writes.
|
||||
template <typename T>
|
||||
@@ -80,8 +81,8 @@ public:
|
||||
UNREACHABLE_MSG("Out of bounds RW access on SparseLargeVector @ {}", index);
|
||||
}
|
||||
|
||||
if (!IsCommittedPage(index)) {
|
||||
CommitPage(index);
|
||||
if (!IsCommittedPage(index) && !CommitPage(index)) {
|
||||
UNREACHABLE_MSG("Cannot access SparseLargeVector index {} with RW permission", index);
|
||||
}
|
||||
return base_ptr[index];
|
||||
}
|
||||
@@ -102,9 +103,8 @@ public:
|
||||
LOG_CRITICAL(Common_Memory, "Out of bounds write on SparseLargeVector @ {}", index);
|
||||
return;
|
||||
}
|
||||
if (!IsCommittedPage(index))
|
||||
CommitPage(index);
|
||||
base_ptr[index] = value;
|
||||
if (IsCommittedPage(index) || CommitPage(index))
|
||||
base_ptr[index] = value;
|
||||
}
|
||||
|
||||
void ZeroRegion(std::size_t start, std::size_t end_) noexcept {
|
||||
@@ -114,7 +114,7 @@ public:
|
||||
const u64 end_page = AlignUp(base, HostPageSize);
|
||||
const u64 first_size = (std::min)(end_page, end) - base;
|
||||
|
||||
if (IsCommittedPage(start / sizeof(T))) {
|
||||
if (IsCommittedPage(start)) {
|
||||
std::memset(reinterpret_cast<void*>(base), 0, first_size);
|
||||
}
|
||||
|
||||
@@ -124,11 +124,16 @@ public:
|
||||
base = end_page;
|
||||
|
||||
for (u64 page = base; page < end; page += HostPageSize) {
|
||||
if (!IsCommittedPage((page - reinterpret_cast<u64>(base_ptr)) / sizeof(T))) {
|
||||
auto index = (page - reinterpret_cast<u64>(base_ptr)) / sizeof(T);
|
||||
if (!IsCommittedPage(index)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::memset(reinterpret_cast<void*>(page), 0, (std::min)( HostPageSize, end - page));
|
||||
if (end - page >= HostPageSize) {
|
||||
DecommitPage(index);
|
||||
} else {
|
||||
std::memset(reinterpret_cast<void*>(page), 0, end - page);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,16 +176,30 @@ private:
|
||||
return (val >> (page & 63)) & 1;
|
||||
}
|
||||
|
||||
constexpr void CommitPage(std::size_t index) noexcept {
|
||||
constexpr bool CommitPage(std::size_t index) noexcept {
|
||||
auto page_index = (index * sizeof(T)) >> HostPageBits;
|
||||
auto page = reinterpret_cast<uintptr_t>(base_ptr + index) & HostPageMask;
|
||||
#if defined(_WIN32)
|
||||
CommitVectorPage(page, true);
|
||||
if (!CommitVectorPage(page, true)) {
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
mprotect(reinterpret_cast<void*>(page), HostPageSize, PROT_READ | PROT_WRITE);
|
||||
if (mprotect(reinterpret_cast<void*>(page), HostPageSize, PROT_READ | PROT_WRITE) != 0) {
|
||||
LOG_ERROR(Common_Memory, "Failed to commit large buffer region at index {}, error {}", index, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
committed_pages[page_index >> 6].fetch_or(1ULL << (page_index & 63), std::memory_order_release);
|
||||
return true;
|
||||
}
|
||||
|
||||
constexpr void DecommitPage(std::size_t index) noexcept {
|
||||
auto page_index = (index * sizeof(T)) >> HostPageBits;
|
||||
auto page = reinterpret_cast<uintptr_t>(base_ptr + index) & HostPageMask;
|
||||
|
||||
committed_pages[page_index >> 6].fetch_and(~(1ULL << (page_index & 63)), std::memory_order_release);
|
||||
DecommitVectorPage(page);
|
||||
}
|
||||
|
||||
std::size_t alloc_size{};
|
||||
|
||||
+6
-43
@@ -23,6 +23,8 @@ add_library(core STATIC
|
||||
core_timing.h
|
||||
cpu_manager.cpp
|
||||
cpu_manager.h
|
||||
launch_params.cpp
|
||||
launch_params.h
|
||||
crypto/aes_util.cpp
|
||||
crypto/aes_util.h
|
||||
crypto/ctr_encryption_layer.cpp
|
||||
@@ -442,8 +444,6 @@ 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
|
||||
@@ -452,10 +452,6 @@ add_library(core STATIC
|
||||
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
|
||||
@@ -472,18 +468,8 @@ 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
|
||||
@@ -492,8 +478,6 @@ add_library(core STATIC
|
||||
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
|
||||
@@ -578,16 +562,6 @@ 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
|
||||
@@ -616,10 +590,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
|
||||
@@ -911,8 +881,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
|
||||
@@ -942,14 +910,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
|
||||
@@ -969,8 +931,6 @@ add_library(core STATIC
|
||||
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
|
||||
@@ -1203,6 +1163,9 @@ endif()
|
||||
|
||||
target_include_directories(core PRIVATE ${OPUS_INCLUDE_DIRS})
|
||||
target_link_libraries(core PUBLIC common PRIVATE audio_core hid_core network video_core nx_tzdb tz)
|
||||
if (MSVC)
|
||||
target_link_libraries(core PRIVATE getopt)
|
||||
endif()
|
||||
|
||||
if (BOOST_NO_HEADERS)
|
||||
target_link_libraries(core PUBLIC Boost::container Boost::heap Boost::asio Boost::process Boost::crc)
|
||||
@@ -1217,7 +1180,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)
|
||||
|
||||
@@ -35,19 +35,22 @@ static IPSFileType IdentifyMagic(std::span<const u8> magic) {
|
||||
}
|
||||
|
||||
static bool IsEOF(IPSFileType type, std::span<const u8> magic) {
|
||||
return (type == IPSFileType::IPS && magic.size() > 3 && std::memcmp(magic.data(), "EOF", 3) == 0)
|
||||
|| (type == IPSFileType::IPS32 && magic.size() > 4 && std::memcmp(magic.data(), "EEOF", 4) == 0);
|
||||
return (type == IPSFileType::IPS && magic.size() >= 3 && std::memcmp(magic.data(), "EOF", 3) == 0)
|
||||
|| (type == IPSFileType::IPS32 && magic.size() >= 4 && std::memcmp(magic.data(), "EEOF", 4) == 0);
|
||||
}
|
||||
|
||||
VirtualFile PatchIPS(const VirtualFile& in, const VirtualFile& ips) {
|
||||
if (in == nullptr || ips == nullptr)
|
||||
return nullptr;
|
||||
|
||||
auto in_data = in->ReadAllBytes();
|
||||
auto const type = IdentifyMagic(in_data);
|
||||
const auto type = IdentifyMagic(ips->ReadBytes(0x5));
|
||||
if (type == IPSFileType::Error)
|
||||
return nullptr;
|
||||
|
||||
auto in_data = in->ReadAllBytes();
|
||||
if (in_data.size() == 0)
|
||||
return nullptr;
|
||||
|
||||
std::vector<u8> temp(type == IPSFileType::IPS ? 3 : 4);
|
||||
u64 offset = 5; // After header
|
||||
while (ips->Read(temp.data(), temp.size(), offset) == temp.size()) {
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include "common/logging.h"
|
||||
#include "common/uuid.h"
|
||||
#include "core/core.h"
|
||||
#include "core/file_sys/registered_cache.h"
|
||||
#include "core/file_sys/savedata_factory.h"
|
||||
#include "core/file_sys/vfs/vfs.h"
|
||||
|
||||
@@ -62,24 +61,17 @@ SaveDataFactory::SaveDataFactory(Core::System& system_, ProgramId program_id_,
|
||||
|
||||
SaveDataFactory::~SaveDataFactory() = default;
|
||||
|
||||
std::string SaveDataFactory::GetSaveDataPath(SaveDataSpaceId space, SaveDataType type, u64 title_id, u128 user_id, u64 save_id) const {
|
||||
if (type == SaveDataType::Account || type == SaveDataType::Device) {
|
||||
const auto requested_id = title_id != 0 ? title_id : program_id;
|
||||
const auto parent_id = system.GetContentProvider().GetParentApplicationId(requested_id);
|
||||
title_id = parent_id.value_or(requested_id);
|
||||
}
|
||||
return GetFullPath(program_id, dir, space, type, title_id, user_id, save_id);
|
||||
}
|
||||
|
||||
VirtualDir SaveDataFactory::Create(SaveDataSpaceId space, const SaveDataAttribute& meta) const {
|
||||
const auto save_directory = GetSaveDataPath(space, meta.type, meta.program_id, meta.user_id, meta.system_save_data_id);
|
||||
const auto save_directory = GetFullPath(program_id, dir, space, meta.type, meta.program_id,
|
||||
meta.user_id, meta.system_save_data_id);
|
||||
|
||||
return dir->CreateDirectoryRelative(save_directory);
|
||||
}
|
||||
|
||||
VirtualDir SaveDataFactory::Open(SaveDataSpaceId space, const SaveDataAttribute& meta) const {
|
||||
|
||||
const auto save_directory = GetSaveDataPath(space, meta.type, meta.program_id, meta.user_id, meta.system_save_data_id);
|
||||
const auto save_directory = GetFullPath(program_id, dir, space, meta.type, meta.program_id,
|
||||
meta.user_id, meta.system_save_data_id);
|
||||
|
||||
auto out = dir->GetDirectoryRelative(save_directory);
|
||||
|
||||
@@ -162,7 +154,8 @@ std::string SaveDataFactory::GetUserGameSaveDataRoot(u128 user_id, bool future)
|
||||
|
||||
SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id,
|
||||
u128 user_id) const {
|
||||
const auto path = GetSaveDataPath(SaveDataSpaceId::User, type, title_id, user_id, 0);
|
||||
const auto path =
|
||||
GetFullPath(program_id, dir, SaveDataSpaceId::User, type, title_id, user_id, 0);
|
||||
const auto relative_dir = GetOrCreateDirectoryRelative(dir, path);
|
||||
|
||||
const auto size_file = relative_dir->GetFile(GetSaveDataSizeFileName());
|
||||
@@ -180,7 +173,8 @@ SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id,
|
||||
|
||||
void SaveDataFactory::WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id,
|
||||
SaveDataSize new_value) const {
|
||||
const auto path = GetSaveDataPath(SaveDataSpaceId::User, type, title_id, user_id, 0);
|
||||
const auto path =
|
||||
GetFullPath(program_id, dir, SaveDataSpaceId::User, type, title_id, user_id, 0);
|
||||
const auto relative_dir = GetOrCreateDirectoryRelative(dir, path);
|
||||
|
||||
const auto size_file = relative_dir->CreateFile(GetSaveDataSizeFileName());
|
||||
|
||||
@@ -50,7 +50,6 @@ public:
|
||||
void SetAutoCreate(bool state);
|
||||
|
||||
private:
|
||||
std::string GetSaveDataPath(SaveDataSpaceId space, SaveDataType type, u64 title_id, u128 user_id, u64 save_id) const;
|
||||
Core::System& system;
|
||||
ProgramId program_id;
|
||||
VirtualDir dir;
|
||||
|
||||
@@ -109,8 +109,7 @@ VirtualFile RealVfsFilesystem::OpenFileFromEntry(std::string_view path_, std::op
|
||||
auto reference = std::make_unique<FileReference>();
|
||||
this->InsertReferenceIntoListLocked(*reference);
|
||||
|
||||
auto file = std::shared_ptr<RealVfsFile>(
|
||||
new RealVfsFile(*this, std::move(reference), path, perms, size, std::move(parent_path)));
|
||||
auto file = std::make_shared<RealVfsFile>(*this, std::move(reference), path, perms, size, std::move(parent_path));
|
||||
cache[path] = file;
|
||||
|
||||
return file;
|
||||
@@ -177,7 +176,7 @@ bool RealVfsFilesystem::DeleteFile(std::string_view path_) {
|
||||
|
||||
VirtualDir RealVfsFilesystem::OpenDirectory(std::string_view path_, OpenMode perms) {
|
||||
const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault);
|
||||
return std::shared_ptr<RealVfsDirectory>(new RealVfsDirectory(*this, path, perms));
|
||||
return std::make_shared<RealVfsDirectory>(*this, path, perms);
|
||||
}
|
||||
|
||||
VirtualDir RealVfsFilesystem::CreateDirectory(std::string_view path_, OpenMode perms) {
|
||||
@@ -185,7 +184,7 @@ VirtualDir RealVfsFilesystem::CreateDirectory(std::string_view path_, OpenMode p
|
||||
if (!FS::CreateDirs(path)) {
|
||||
return nullptr;
|
||||
}
|
||||
return std::shared_ptr<RealVfsDirectory>(new RealVfsDirectory(*this, path, perms));
|
||||
return std::make_shared<RealVfsDirectory>(*this, path, perms);
|
||||
}
|
||||
|
||||
VirtualDir RealVfsFilesystem::CopyDirectory(std::string_view old_path_,
|
||||
|
||||
@@ -82,6 +82,9 @@ class RealVfsFile : public VfsFile {
|
||||
friend class RealVfsFilesystem;
|
||||
|
||||
public:
|
||||
RealVfsFile(RealVfsFilesystem& base, std::unique_ptr<FileReference> reference,
|
||||
const std::string& path, OpenMode perms = OpenMode::Read,
|
||||
std::optional<u64> size = {}, std::optional<std::string> parent_path = {});
|
||||
~RealVfsFile() override;
|
||||
|
||||
std::string GetName() const override;
|
||||
@@ -95,9 +98,6 @@ public:
|
||||
bool Rename(std::string_view name) override;
|
||||
|
||||
private:
|
||||
RealVfsFile(RealVfsFilesystem& base, std::unique_ptr<FileReference> reference,
|
||||
const std::string& path, OpenMode perms = OpenMode::Read,
|
||||
std::optional<u64> size = {}, std::optional<std::string> parent_path = {});
|
||||
|
||||
RealVfsFilesystem& base;
|
||||
std::unique_ptr<FileReference> reference;
|
||||
@@ -113,6 +113,8 @@ class RealVfsDirectory : public VfsDirectory {
|
||||
friend class RealVfsFilesystem;
|
||||
|
||||
public:
|
||||
RealVfsDirectory(RealVfsFilesystem& base, const std::string& path,
|
||||
OpenMode perms = OpenMode::Read);
|
||||
~RealVfsDirectory() override;
|
||||
|
||||
VirtualFile GetFileRelative(std::string_view relative_path) const override;
|
||||
@@ -138,9 +140,6 @@ public:
|
||||
std::map<std::string, VfsEntryType, std::less<>> GetEntries() const override;
|
||||
|
||||
private:
|
||||
RealVfsDirectory(RealVfsFilesystem& base, const std::string& path,
|
||||
OpenMode perms = OpenMode::Read);
|
||||
|
||||
template <typename T, typename R>
|
||||
std::vector<std::shared_ptr<R>> IterateEntries() const;
|
||||
|
||||
|
||||
+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");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -30,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};
|
||||
|
||||
+1218
-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
|
||||
@@ -12,39 +12,39 @@
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> IAppletCommonFunctions::FindRequest(u32 key) {
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, nullptr, "SetTerminateResult"},
|
||||
FunctionInfo{10, nullptr, "ReadThemeStorage"},
|
||||
FunctionInfo{11, nullptr, "WriteThemeStorage"},
|
||||
FunctionInfo{20, nullptr, "PushToAppletBoundChannel"},
|
||||
FunctionInfo{21, nullptr, "TryPopFromAppletBoundChannel"},
|
||||
FunctionInfo{40, nullptr, "GetDisplayLogicalResolution"},
|
||||
FunctionInfo{42, D<&IAppletCommonFunctions::SetDisplayMagnification>, "SetDisplayMagnification"},
|
||||
FunctionInfo{50, D<&IAppletCommonFunctions::SetHomeButtonDoubleClickEnabled>, "SetHomeButtonDoubleClickEnabled"},
|
||||
FunctionInfo{51, D<&IAppletCommonFunctions::GetHomeButtonDoubleClickEnabled>, "GetHomeButtonDoubleClickEnabled"},
|
||||
FunctionInfo{52, nullptr, "IsHomeButtonShortPressedBlocked"},
|
||||
FunctionInfo{60, nullptr, "IsVrModeCurtainRequired"},
|
||||
FunctionInfo{61, nullptr, "IsSleepRequiredByHighTemperature"},
|
||||
FunctionInfo{62, nullptr, "IsSleepRequiredByLowBattery"},
|
||||
FunctionInfo{70, D<&IAppletCommonFunctions::SetCpuBoostRequestPriority>, "SetCpuBoostRequestPriority"},
|
||||
FunctionInfo{80, nullptr, "SetHandlingCaptureButtonShortPressedMessageEnabledForApplet"},
|
||||
FunctionInfo{81, nullptr, "SetHandlingCaptureButtonLongPressedMessageEnabledForApplet"},
|
||||
FunctionInfo{90, nullptr, "OpenNamedChannelAsParent"},
|
||||
FunctionInfo{91, nullptr, "OpenNamedChannelAsChild"},
|
||||
FunctionInfo{100, nullptr, "SetApplicationCoreUsageMode"},
|
||||
FunctionInfo{300, D<&IAppletCommonFunctions::GetCurrentApplicationId>, "GetCurrentApplicationId"},
|
||||
FunctionInfo{310, nullptr, "IsSystemAppletHomeMenu"}, //19.0.0+
|
||||
FunctionInfo{320, D<&IAppletCommonFunctions::SetGpuTimeSliceBoost>, "SetGpuTimeSliceBoost"}, //19.0.0+
|
||||
FunctionInfo{321, nullptr, "SetGpuTimeSliceBoostDueToApplication"}, //19.0.0+
|
||||
FunctionInfo{350, D<&IAppletCommonFunctions::Unknown350>, "Unknown350"} //20.0.0+
|
||||
);
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@@ -27,6 +27,7 @@ private:
|
||||
Result SetGpuTimeSliceBoost(s64 time_span);
|
||||
Result Unknown350(Out<u16> out_unknown);
|
||||
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override;
|
||||
const std::shared_ptr<Applet> applet;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// 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
|
||||
|
||||
@@ -36,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;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
@@ -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,106 +0,0 @@
|
||||
// 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,49 +0,0 @@
|
||||
// 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,44 +0,0 @@
|
||||
// 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,33 +0,0 @@
|
||||
// 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
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
@@ -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"} //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;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// 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
|
||||
|
||||
@@ -20,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"}, //11.0.0+
|
||||
FunctionInfo{15, nullptr, "Unknown15"}, //19.0.0+
|
||||
FunctionInfo{20, D<&ICommonStateGetter::PushToGeneralChannel>, "PushToGeneralChannel"},
|
||||
FunctionInfo{30, D<&ICommonStateGetter::GetHomeButtonReaderLockAccessor>, "GetHomeButtonReaderLockAccessor"},
|
||||
FunctionInfo{31, D<&ICommonStateGetter::GetReaderLockAccessorEx>, "GetReaderLockAccessorEx"}, //2.0.0+
|
||||
FunctionInfo{32, D<&ICommonStateGetter::GetWriterLockAccessorEx>, "GetWriterLockAccessorEx"}, //7.0.0+
|
||||
FunctionInfo{40, nullptr, "GetCradleFwVersion"}, //2.0.0+
|
||||
FunctionInfo{50, D<&ICommonStateGetter::IsVrModeEnabled>, "IsVrModeEnabled"}, //3.0.0+
|
||||
FunctionInfo{51, D<&ICommonStateGetter::SetVrModeEnabled>, "SetVrModeEnabled"}, //3.0.0+
|
||||
FunctionInfo{52, D<&ICommonStateGetter::SetLcdBacklighOffEnabled>, "SetLcdBacklighOffEnabled"}, //4.0.0+
|
||||
FunctionInfo{53, D<&ICommonStateGetter::BeginVrModeEx>, "BeginVrModeEx"}, //7.0.0+
|
||||
FunctionInfo{54, D<&ICommonStateGetter::EndVrModeEx>, "EndVrModeEx"}, //7.0.0+
|
||||
FunctionInfo{55, D<&ICommonStateGetter::IsInControllerFirmwareUpdateSection>, "IsInControllerFirmwareUpdateSection"}, //3.0.0+
|
||||
FunctionInfo{59, nullptr, "SetVrPositionForDebug"}, //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"}, //13.0.0+
|
||||
FunctionInfo{130, D<&ICommonStateGetter::EnableStartupLogoDisappearedMessage>, "EnableStartupLogoDisappearedMessage"}, //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"}, //20.0.0+
|
||||
FunctionInfo{610, D<&ICommonStateGetter::Unknown610>, "Unknown610"}, //21.0.0+
|
||||
FunctionInfo{611, D<&ICommonStateGetter::Unknown611>, "Unknown611"}, //22.0.0+
|
||||
FunctionInfo{900, D<&ICommonStateGetter::SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled>, "SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled"}, //11.0.0+
|
||||
FunctionInfo{910, nullptr, "GetLaunchRequiredTick"}, //17.0.0+
|
||||
FunctionInfo{1000, D<&ICommonStateGetter::BeginVrMode3d>, "BeginVrMode3d"}, //19.0.0+
|
||||
FunctionInfo{1001, D<&ICommonStateGetter::EndVrMode3d>, "EndVrMode3d"}, //19.0.0+
|
||||
FunctionInfo{1002, D<&ICommonStateGetter::IsVrModeEnabled3d>, "IsVrModeEnabled3d"}, //19.0.0+
|
||||
FunctionInfo{1003, D<&ICommonStateGetter::GetVrLaboGoggleViewport>, "GetVrLaboGoggleViewport"}, //21.0.0+
|
||||
FunctionInfo{1004, D<&ICommonStateGetter::GetPanelPhysicalSizeForSpecificTitle>, "GetPanelPhysicalSizeForSpecificTitle"}, //21.0.0+
|
||||
FunctionInfo{1005, D<&ICommonStateGetter::GetPanelResolutionForSpecificTitle>, "GetPanelResolutionForSpecificTitle"} //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;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// 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
|
||||
|
||||
@@ -6,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;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// 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
|
||||
|
||||
@@ -30,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,3 +1,6 @@
|
||||
// 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
|
||||
|
||||
@@ -7,35 +10,6 @@ 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;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// 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
|
||||
|
||||
@@ -11,6 +14,35 @@ class IDebugFunctions final : public ServiceFramework<IDebugFunctions> {
|
||||
public:
|
||||
explicit IDebugFunctions(Core::System& system_);
|
||||
~IDebugFunctions() override;
|
||||
|
||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key, functions);
|
||||
}
|
||||
static constexpr auto functions = CreateStaticMap(
|
||||
FunctionInfo{0, nullptr, "NotifyMessageToHomeMenuForDebug"},
|
||||
FunctionInfo{1, nullptr, "OpenMainApplication"},
|
||||
FunctionInfo{10, nullptr, "PerformSystemButtonPressing"},
|
||||
FunctionInfo{20, nullptr, "InvalidateTransitionLayer"},
|
||||
FunctionInfo{30, nullptr, "RequestLaunchApplicationWithUserAndArgumentForDebug"},
|
||||
FunctionInfo{31, nullptr, "RequestLaunchApplicationByApplicationLaunchInfoForDebug"},
|
||||
FunctionInfo{40, nullptr, "GetAppletResourceUsageInfo"},
|
||||
FunctionInfo{50, nullptr, "AddSystemProgramIdAndAppletIdForDebug"},
|
||||
FunctionInfo{51, nullptr, "AddOperationConfirmedLibraryAppletIdForDebug"},
|
||||
FunctionInfo{100, nullptr, "SetCpuBoostModeForApplet"},
|
||||
FunctionInfo{101, nullptr, "CancelCpuBoostModeForApplet"},
|
||||
FunctionInfo{110, nullptr, "PushToAppletBoundChannelForDebug"},
|
||||
FunctionInfo{111, nullptr, "TryPopFromAppletBoundChannelForDebug"},
|
||||
FunctionInfo{120, nullptr, "AlarmSettingNotificationEnableAppEventReserve"},
|
||||
FunctionInfo{121, nullptr, "AlarmSettingNotificationDisableAppEventReserve"},
|
||||
FunctionInfo{122, nullptr, "AlarmSettingNotificationPushAppEventNotify"},
|
||||
FunctionInfo{130, nullptr, "FriendInvitationSetApplicationParameter"},
|
||||
FunctionInfo{131, nullptr, "FriendInvitationClearApplicationParameter"},
|
||||
FunctionInfo{132, nullptr, "FriendInvitationPushApplicationParameter"},
|
||||
FunctionInfo{140, nullptr, "RestrictPowerOperationForSecureLaunchModeForDebug"},
|
||||
FunctionInfo{200, nullptr, "CreateFloatingLibraryAppletAccepterForDebug"},
|
||||
FunctionInfo{300, nullptr, "TerminateAllRunningApplicationsForDebug"},
|
||||
FunctionInfo{900, nullptr, "GetGrcProcessLaunchedSystemEvent"}
|
||||
);
|
||||
};
|
||||
|
||||
} // 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;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// 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
|
||||
|
||||
@@ -7,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() {
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// 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
|
||||
|
||||
@@ -23,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"}, //10.0.0+
|
||||
FunctionInfo{80, nullptr, "RequestForLibraryAppletToGetForeground"}, //19.0.0+
|
||||
FunctionInfo{81, nullptr, "GetCurrentChildLibraryApplet"}, //19.0.0+
|
||||
FunctionInfo{90, D<&ILibraryAppletAccessor::Unknown90>, "Unknown90"}, //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"}, //2.0.0+
|
||||
FunctionInfo{170, D<&ILibraryAppletAccessor::Unknown170>, "Unknown170"} //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 2025 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,134 +0,0 @@
|
||||
// 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,56 +0,0 @@
|
||||
// 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,32 +0,0 @@
|
||||
// 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
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user