mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-09-25 18:55:57 +00:00
Compare commits
48 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 411dc2054b | |||
| f0190a1643 | |||
| f232a351cb | |||
| a1fd05e855 | |||
| 33a6f339a2 | |||
| 1f784d5541 | |||
| 9375aeaacf | |||
| 9e59b4132a | |||
| bebc19da32 | |||
| 99bf8cf51a | |||
| dbeb73ee01 | |||
| cb73a4dcc7 | |||
| 278f411dad | |||
| 3d37a816c6 | |||
| a25e32676f | |||
| 38df54edfe | |||
| 3266c20e3f | |||
| 9cd24e85c2 | |||
| 74b5e10dc5 | |||
| a277b62fe4 | |||
| 908b1e9a37 | |||
| 847e91c3a8 | |||
| 2d1eb0dab9 | |||
| 9a30172e45 | |||
| 07f40d5cac | |||
| 3c38afad74 | |||
| 0ce29be608 | |||
| 1203082a8f | |||
| 14235dc0d0 | |||
| 6374f7f51f | |||
| 73e004de6e | |||
| f7b8ade40e | |||
| 8c1194474e | |||
| 90aafeedc1 | |||
| 4fe5f62c38 | |||
| c3f1e6562b | |||
| ac35358b3f | |||
| 7bf95be2c2 | |||
| 4ce45b3b37 | |||
| fd34024f0e | |||
| d76f8f91c4 | |||
| a7061eb4c8 | |||
| fa4e7c6992 | |||
| b77308ced6 | |||
| defddec47f | |||
| c5405250d1 | |||
| 10c07d700c | |||
| 505b157647 |
@@ -1,13 +0,0 @@
|
||||
diff --git a/libs/cobalt/include/boost/cobalt/concepts.hpp b/libs/cobalt/include/boost/cobalt/concepts.hpp
|
||||
index d49f2ec..a9bdb80 100644
|
||||
--- a/libs/cobalt/include/boost/cobalt/concepts.hpp
|
||||
+++ b/libs/cobalt/include/boost/cobalt/concepts.hpp
|
||||
@@ -62,7 +62,7 @@ struct enable_awaitables
|
||||
template <typename T>
|
||||
concept with_get_executor = requires (T& t)
|
||||
{
|
||||
- {t.get_executor()} -> asio::execution::executor;
|
||||
+ t.get_executor();
|
||||
};
|
||||
|
||||
|
||||
+3
-7
@@ -417,12 +417,9 @@ AddJsonPackage(boost)
|
||||
set(BOOST_NO_HEADERS ${Boost_ADDED})
|
||||
|
||||
if (Boost_ADDED)
|
||||
if (MSVC OR ANDROID)
|
||||
add_compile_definitions(YUZU_BOOST_v1)
|
||||
endif()
|
||||
|
||||
add_compile_definitions(YUZU_BOOST_v1)
|
||||
if (NOT MSVC OR CXX_CLANG)
|
||||
# boost sucks
|
||||
# solaris sucks
|
||||
if (SOLARIS)
|
||||
add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:-pthreads>)
|
||||
endif()
|
||||
@@ -431,8 +428,7 @@ if (Boost_ADDED)
|
||||
target_compile_options(boost_icl INTERFACE $<$<COMPILE_LANGUAGE:C,CXX>:-Wno-shadow>)
|
||||
target_compile_options(boost_asio INTERFACE
|
||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-conversion>
|
||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-implicit-fallthrough>
|
||||
)
|
||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-implicit-fallthrough>)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
+6
-9
@@ -6,22 +6,19 @@
|
||||
"version": "v0.19.0"
|
||||
},
|
||||
"boost": {
|
||||
"artifact": "%VERSION%-cmake.tar.xz",
|
||||
"artifact": "boost-%VERSION%.tar.zst",
|
||||
"find_args": "CONFIG OPTIONAL_COMPONENTS headers context system fiber filesystem",
|
||||
"hash": "6ae6e94664fe7f2fb01976b59b276ac5df8085c7503fa829d810fbfe495960cfec44fa2c36e2cb23480bc19c956ed199d4952b02639a00a6c07625d4e7130c2d",
|
||||
"hash": "681d97be4386767662e230b2e7c9754d45e709cc5db4e747c23c27d1f5b0e87770bdf19b0bc44dcb0e8349324887bbb8fffb432098f4d0ce74a5043021a90afc",
|
||||
"min_version": "1.57",
|
||||
"package": "Boost",
|
||||
"patches": [
|
||||
"0001-clang-cl.patch"
|
||||
],
|
||||
"repo": "boostorg/boost",
|
||||
"version": "boost-1.90.0"
|
||||
"repo": "eden-emulator/ext-boost",
|
||||
"version": "1.92.0"
|
||||
},
|
||||
"boost_headers": {
|
||||
"bundled": true,
|
||||
"hash": "4ef845775e2277a8104ded6ddf749aa262ce52cf8438042869a048f9a0156dd772fbbcfa74efa1378fecef339b7286f6fe4b4feb5c45d49966b35d08e3e83507",
|
||||
"hash": "c5fa2cd72f6e6666b7963b97bc359c75284b8fb540c30f3629a028b85270c9bc66c8a051383964f2bd4c1e005a4691593d15696e7ef39ea87cf6cff9e5691fb2",
|
||||
"repo": "boostorg/headers",
|
||||
"version": "boost-1.90.0"
|
||||
"version": "boost-1.91.0"
|
||||
},
|
||||
"catch2": {
|
||||
"hash": "7eea385d79d88a5690cde131fe7ccda97d5c54ea09d6f515000d7bf07c828809d61c1ac99912c1ee507cf933f61c1c47ecdcc45df7850ffa82714034b0fccf35",
|
||||
|
||||
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,42 @@ 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"}
|
||||
{}
|
||||
|
||||
// Define here your functions and methods, please order them.
|
||||
// Use FindRequestTipc for TIPC handlers.
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
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"}
|
||||
);
|
||||
}
|
||||
};
|
||||
```
|
||||
+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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -611,6 +640,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 +928,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>
|
||||
|
||||
@@ -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>
|
||||
@@ -1020,9 +1020,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 +1066,8 @@
|
||||
|
||||
<string name="renderer_none">無</string>
|
||||
|
||||
<!-- Renderer Accuracy -->
|
||||
<string name="renderer_accuracy_low">效能</string>
|
||||
<string name="renderer_accuracy_high">準確</string>
|
||||
|
||||
<!-- DMA Accuracy -->
|
||||
|
||||
@@ -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
|
||||
@@ -110,7 +109,6 @@ add_library(
|
||||
socket_types.h
|
||||
sparse_large_vector.cpp
|
||||
sparse_large_vector.h
|
||||
spin_lock.h
|
||||
stb.cpp
|
||||
stb.h
|
||||
steady_clock.cpp
|
||||
|
||||
@@ -244,7 +244,8 @@ WallClock::WallClock(bool invariant_, u64 rdtsc_frequency_) noexcept
|
||||
, ns_rdtsc_factor{invariant_ ? GetFixedPoint64Factor(NsRatio::den, rdtsc_frequency_) : 0}
|
||||
, us_rdtsc_factor{invariant_ ? GetFixedPoint64Factor(UsRatio::den, rdtsc_frequency_) : 0}
|
||||
, ms_rdtsc_factor{invariant_ ? GetFixedPoint64Factor(MsRatio::den, rdtsc_frequency_) : 0}
|
||||
, rdtsc_ns_factor{invariant_ ? GetFixedPoint64Factor(rdtsc_frequency_, NsRatio::den) : 1}
|
||||
, rdtsc_ns_integer{invariant_ ? rdtsc_frequency_ / NsRatio::den : 1}
|
||||
, rdtsc_ns_factor{invariant_ ? GetFixedPoint64Factor(rdtsc_frequency_ % NsRatio::den, NsRatio::den) : 0}
|
||||
, cntpct_rdtsc_factor{invariant_ ? GetFixedPoint64Factor(CNTFRQ, rdtsc_frequency_) : 0}
|
||||
, gputick_rdtsc_factor{invariant_ ? GetFixedPoint64Factor(GPUTickFreq, rdtsc_frequency_) : 0}
|
||||
, invariant{invariant_}
|
||||
@@ -291,7 +292,7 @@ bool WallClock::IsNative() const {
|
||||
}
|
||||
|
||||
u64 WallClock::NsToTicks(std::chrono::nanoseconds ns) const {
|
||||
return invariant ? MultiplyHigh(ns.count(), rdtsc_ns_factor) : ns.count();
|
||||
return ns.count() * rdtsc_ns_integer + MultiplyHigh(ns.count(), rdtsc_ns_factor);
|
||||
}
|
||||
#elif defined(HAS_NCE)
|
||||
namespace {
|
||||
@@ -416,7 +417,7 @@ u64 WallClock::NsToTicks(std::chrono::nanoseconds ns) const {
|
||||
const WallClock g_wall_clock = [] {
|
||||
#if defined(ARCHITECTURE_x86_64)
|
||||
auto const& caps = Common::g_cpu_caps;
|
||||
return WallClock(caps.invariant_tsc && caps.tsc_frequency >= std::nano::den, caps.tsc_frequency);
|
||||
return WallClock(caps.invariant_tsc && caps.tsc_frequency > std::nano::den, caps.tsc_frequency);
|
||||
#elif defined(HAS_NCE)
|
||||
return WallClock(false, 1);
|
||||
#else
|
||||
|
||||
@@ -96,6 +96,7 @@ public:
|
||||
u64 ns_rdtsc_factor;
|
||||
u64 us_rdtsc_factor;
|
||||
u64 ms_rdtsc_factor;
|
||||
u64 rdtsc_ns_integer;
|
||||
u64 rdtsc_ns_factor;
|
||||
u64 cntpct_rdtsc_factor;
|
||||
u64 gputick_rdtsc_factor;
|
||||
|
||||
+18
-20
@@ -17,35 +17,33 @@
|
||||
|
||||
namespace Common {
|
||||
|
||||
// glibc, mlibc, musl, and newlib all define their own variants of strerror_r
|
||||
// We don't need to use the preprocessor, we can just select depending on return type
|
||||
template<typename T> std::string HandleStrerrorR(T r, char *err_str);
|
||||
template<> std::string HandleStrerrorR(char* r, char *) { return std::string{r}; }
|
||||
template<> std::string HandleStrerrorR(const char* r, char *) { return std::string{r}; }
|
||||
template<> std::string HandleStrerrorR(int r, char *err_str) {
|
||||
return std::string{r != 0
|
||||
? "(strerror_r failed to format error)"
|
||||
: err_str};
|
||||
}
|
||||
|
||||
std::string NativeErrorToString(int e) {
|
||||
#ifdef _WIN32
|
||||
LPSTR err_str;
|
||||
|
||||
DWORD res = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
nullptr, e, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
reinterpret_cast<LPSTR>(&err_str), 1, nullptr);
|
||||
if (!res) {
|
||||
return "(FormatMessageA failed to format error)";
|
||||
LPSTR(&err_str), 1, nullptr);
|
||||
if (res) {
|
||||
std::string ret(err_str);
|
||||
LocalFree(err_str);
|
||||
return ret;
|
||||
}
|
||||
std::string ret(err_str);
|
||||
LocalFree(err_str);
|
||||
return ret;
|
||||
return "(FormatMessageA failed to format error)";
|
||||
#else
|
||||
char err_str[255];
|
||||
#if defined(__ANDROID__) || \
|
||||
(defined(__GLIBC__) && (_GNU_SOURCE || (_POSIX_C_SOURCE < 200112L && _XOPEN_SOURCE < 600)))
|
||||
// Thread safe (GNU-specific)
|
||||
const char* str = strerror_r(e, err_str, sizeof(err_str));
|
||||
return std::string(str);
|
||||
#else
|
||||
// Thread safe (XSI-compliant)
|
||||
int second_err = strerror_r(e, err_str, sizeof(err_str));
|
||||
if (second_err != 0) {
|
||||
return "(strerror_r failed to format error)";
|
||||
}
|
||||
return std::string(err_str);
|
||||
#endif // GLIBC etc.
|
||||
return HandleStrerrorR(strerror_r(e, err_str, sizeof(err_str)), err_str);
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
|
||||
+66
-13
@@ -5,6 +5,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include "common/container/unordered_map.h"
|
||||
@@ -480,28 +481,80 @@ std::string SanitizePath(std::string_view path_, DirectorySeparator directory_se
|
||||
[type2](char c1, char c2) { return c1 == type2 && c2 == type2; }),
|
||||
path.end());
|
||||
|
||||
const bool absolute = !path.empty() && path[0] == type2;
|
||||
std::vector<std::string_view> parts;
|
||||
std::string root;
|
||||
std::string_view components{path};
|
||||
bool drive_relative = false;
|
||||
|
||||
for (const auto part : SplitPathComponents(path))
|
||||
{
|
||||
if (part.empty() || part == ".")
|
||||
continue;
|
||||
if (part == ".." && !parts.empty() && parts.back() != "..")
|
||||
parts.pop_back();
|
||||
else if (part != "..") parts.push_back(part);
|
||||
#ifdef _WIN32
|
||||
const bool network = path.size() > 1 && path[0] == type2 && path[1] == type2;
|
||||
const bool drive =
|
||||
path.size() > 1 && std::isalpha(static_cast<unsigned char>(path[0])) && path[1] == ':';
|
||||
|
||||
if (network) {
|
||||
root.assign(2, type2);
|
||||
components.remove_prefix(2);
|
||||
} else if (drive) {
|
||||
root.assign(path.data(), 2);
|
||||
components.remove_prefix(2);
|
||||
if (!components.empty() && components.front() == type2) {
|
||||
root += type2;
|
||||
components.remove_prefix(1);
|
||||
} else {
|
||||
drive_relative = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (root.empty() && !components.empty() && components.front() == type2) {
|
||||
root += type2;
|
||||
components.remove_prefix(1);
|
||||
}
|
||||
|
||||
std::string resolved = absolute ? std::string(1, type2) : std::string{};
|
||||
for (std::size_t i = 0; i < parts.size(); ++i)
|
||||
{
|
||||
if (i != 0)
|
||||
const auto path_parts = SplitPathComponents(components);
|
||||
std::size_t root_component_count = 0;
|
||||
#ifdef _WIN32
|
||||
if (network) {
|
||||
root_component_count = 2;
|
||||
|
||||
const auto is_unc = [](std::string_view part) {
|
||||
return part.size() == 3 && (part[0] == 'U' || part[0] == 'u') &&
|
||||
(part[1] == 'N' || part[1] == 'n') && (part[2] == 'C' || part[2] == 'c');
|
||||
};
|
||||
if (path_parts.size() >= 2 && path_parts[0] == "?" && is_unc(path_parts[1])) {
|
||||
root_component_count = 4;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
std::vector<std::string_view> parts;
|
||||
for (std::size_t i = 0; i < path_parts.size(); ++i) {
|
||||
const auto part = path_parts[i];
|
||||
if (i < root_component_count) {
|
||||
parts.push_back(part);
|
||||
} else if (part.empty() || part == ".") {
|
||||
continue;
|
||||
} else if (part == "..") {
|
||||
if (parts.size() > root_component_count) {
|
||||
parts.pop_back();
|
||||
}
|
||||
} else {
|
||||
parts.push_back(part);
|
||||
}
|
||||
}
|
||||
|
||||
const std::size_t root_length = root.size();
|
||||
std::string resolved = std::move(root);
|
||||
for (std::size_t i = 0; i < parts.size(); ++i) {
|
||||
if (i != 0 || (!resolved.empty() && resolved.back() != type2 && !drive_relative))
|
||||
resolved += type2;
|
||||
resolved.append(parts[i].data(), parts[i].size());
|
||||
}
|
||||
|
||||
path = std::move(resolved);
|
||||
|
||||
if (!path.empty() && path.size() == root_length) {
|
||||
return path;
|
||||
}
|
||||
return std::string(RemoveTrailingSlash(path));
|
||||
}
|
||||
|
||||
|
||||
@@ -347,8 +347,9 @@ enum class DirectorySeparator {
|
||||
// i.e. "C:\Users\Yuzu\Documents\save.bin" becomes {"C:", "Users", "Yuzu", "Documents", "save.bin" }
|
||||
[[nodiscard]] std::vector<std::string> SplitPathComponentsCopy(std::string_view filename);
|
||||
|
||||
// Removes trailing slash, makes all '\\' into '/', and removes duplicate '/'. Makes '/' into '\\'
|
||||
// depending if directory_separator is BackwardSlash or PlatformDefault and running on windows
|
||||
// Normalizes directory separators, removes duplicate and non-root trailing separators, and resolves
|
||||
// '.' and '..' components without traversing above the path root. Windows drive and UNC roots are
|
||||
// preserved.
|
||||
[[nodiscard]] std::string SanitizePath(
|
||||
std::string_view path,
|
||||
DirectorySeparator directory_separator = DirectorySeparator::ForwardSlash);
|
||||
|
||||
@@ -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
|
||||
@@ -96,15 +96,15 @@ struct PageTable {
|
||||
}
|
||||
|
||||
/// Write page info atomically
|
||||
constexpr void Store(bool marked, PageType type, u16 block, uintptr_t pointer) noexcept {
|
||||
inline void Store(bool marked, PageType type, u16 block, uintptr_t pointer) noexcept {
|
||||
data_raw.store(std::bit_cast<u64>(Data{marked, type, block, pointer}));
|
||||
}
|
||||
|
||||
constexpr void MarkRasterizerCached() noexcept {
|
||||
inline void MarkRasterizerCached() noexcept {
|
||||
data_raw.fetch_or(0b111);
|
||||
}
|
||||
|
||||
constexpr void MarkDebug(u64 ptr, u16 block) noexcept {
|
||||
inline void MarkDebug(u64 ptr, u16 block) noexcept {
|
||||
Store(true, PageType::DebugMemory, block, ptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -96,6 +96,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) {
|
||||
|
||||
@@ -35,10 +35,12 @@ const u64 HostPageMask = ~(HostPageSize - 1);
|
||||
|
||||
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>
|
||||
requires std::is_trivially_copyable_v<T>
|
||||
// MSVC doesn't regard structs with atomics as trivially copyable
|
||||
// requires std::is_trivially_copyable_v<T>
|
||||
class SparseLargeVector final {
|
||||
public:
|
||||
constexpr SparseLargeVector() = default;
|
||||
@@ -113,7 +115,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);
|
||||
}
|
||||
|
||||
@@ -123,11 +125,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,6 +189,14 @@ private:
|
||||
committed_pages[page_index >> 6].fetch_or(1ULL << (page_index & 63), std::memory_order_release);
|
||||
}
|
||||
|
||||
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{};
|
||||
T* base_ptr{};
|
||||
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <intrin.h>
|
||||
#elif defined(ARCHITECTURE_x86_64)
|
||||
#include <xmmintrin.h>
|
||||
#endif
|
||||
#include <atomic>
|
||||
|
||||
namespace Common {
|
||||
|
||||
/// @brief A lock similar to mutex that forces a thread to spin wait instead calling the
|
||||
/// supervisor. Should be used on short sequences of code.
|
||||
struct SpinLock {
|
||||
SpinLock() noexcept = default;
|
||||
SpinLock(const SpinLock&) noexcept = delete;
|
||||
SpinLock& operator=(const SpinLock&) noexcept = delete;
|
||||
SpinLock(SpinLock&&) noexcept = delete;
|
||||
SpinLock& operator=(SpinLock&&) noexcept = delete;
|
||||
|
||||
inline void lock() noexcept {
|
||||
while (lck.test_and_set(std::memory_order_acquire)) {
|
||||
#if defined(ARCHITECTURE_x86_64)
|
||||
_mm_pause();
|
||||
#elif defined(ARCHITECTURE_arm64) && defined(_MSC_VER)
|
||||
__yield();
|
||||
#elif defined(ARCHITECTURE_arm64)
|
||||
asm("yield");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
inline void unlock() noexcept {
|
||||
lck.clear(std::memory_order_release);
|
||||
}
|
||||
|
||||
[[nodiscard]] inline bool try_lock() noexcept {
|
||||
return !lck.test_and_set(std::memory_order_acquire);
|
||||
}
|
||||
|
||||
std::atomic_flag lck = ATOMIC_FLAG_INIT;
|
||||
};
|
||||
|
||||
} // namespace Common
|
||||
+2
-2
@@ -208,9 +208,9 @@ UUID UUID::MakeRandomRFC4122V4() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
UUID UUID::MakeRFC4122V5(std::span<u8, 20> sha1) {
|
||||
UUID UUID::MakeRFC4122V5(std::span<u8, 16> sha1) {
|
||||
UUID uuid{};
|
||||
std::memcpy(&uuid.uuid, sha1.data(), sizeof(UUID));
|
||||
std::memcpy(&uuid.uuid, sha1.data(), sha1.size());
|
||||
uuid.uuid[8] = 0x80 | (uuid.uuid[8] & 0x3F);
|
||||
uuid.uuid[6] = 0x50 | (uuid.uuid[6] & 0xF);
|
||||
return uuid;
|
||||
|
||||
+1
-1
@@ -104,7 +104,7 @@ struct UUID {
|
||||
/// @returns A random UUID that is RFC 4122 Version 4 compliant.
|
||||
[[nodiscard]] static UUID MakeRandomRFC4122V4();
|
||||
|
||||
[[nodiscard]] static UUID MakeRFC4122V5(std::span<u8, 20> sha1);
|
||||
[[nodiscard]] static UUID MakeRFC4122V5(std::span<u8, 16> sha1);
|
||||
|
||||
friend constexpr bool operator==(const UUID& lhs, const UUID& rhs) = default;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
@@ -796,6 +798,8 @@ add_library(core STATIC
|
||||
hle/service/ns/application_manager_interface.h
|
||||
hle/service/ns/application_version_interface.cpp
|
||||
hle/service/ns/application_version_interface.h
|
||||
hle/service/ns/async_result.cpp
|
||||
hle/service/ns/async_result.h
|
||||
hle/service/ns/content_management_interface.cpp
|
||||
hle/service/ns/content_management_interface.h
|
||||
hle/service/ns/develop_interface.cpp
|
||||
@@ -1201,6 +1205,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)
|
||||
@@ -1215,7 +1222,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)
|
||||
|
||||
@@ -22,21 +22,15 @@ DynarmicCallbacks32::DynarmicCallbacks32(ArmDynarmic32& parent, Kernel::KProcess
|
||||
, m_check_memory_access{m_debugger_enabled || !Settings::values.cpuopt_ignore_memory_aborts.GetValue()}
|
||||
{}
|
||||
|
||||
u8 DynarmicCallbacks32::MemoryRead8(u32 vaddr) {
|
||||
CheckMemoryAccess(vaddr, 1, Kernel::DebugWatchpointType::Read);
|
||||
return m_memory.Read8(vaddr);
|
||||
}
|
||||
u16 DynarmicCallbacks32::MemoryRead16(u32 vaddr) {
|
||||
CheckMemoryAccess(vaddr, 2, Kernel::DebugWatchpointType::Read);
|
||||
return m_memory.Read16(vaddr);
|
||||
}
|
||||
u32 DynarmicCallbacks32::MemoryRead32(u32 vaddr) {
|
||||
CheckMemoryAccess(vaddr, 4, Kernel::DebugWatchpointType::Read);
|
||||
return m_memory.Read32(vaddr);
|
||||
}
|
||||
u64 DynarmicCallbacks32::MemoryRead64(u32 vaddr) {
|
||||
CheckMemoryAccess(vaddr, 8, Kernel::DebugWatchpointType::Read);
|
||||
return m_memory.Read64(vaddr);
|
||||
u64 DynarmicCallbacks32::MemoryRead(u32 vaddr, size_t size) {
|
||||
CheckMemoryAccess(vaddr, size, Kernel::DebugWatchpointType::Read);
|
||||
switch (size) {
|
||||
case sizeof(u64): return m_memory.Read64(vaddr);
|
||||
case sizeof(u32): return m_memory.Read32(vaddr);
|
||||
case sizeof(u16): return m_memory.Read16(vaddr);
|
||||
case sizeof(u8): return m_memory.Read8(vaddr);
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<u32> DynarmicCallbacks32::MemoryReadCode(u32 vaddr) {
|
||||
@@ -50,27 +44,17 @@ std::optional<u32> DynarmicCallbacks32::MemoryReadCode(u32 vaddr) {
|
||||
return cached_code_page.inst[(vaddr & Core::Memory::YUZU_PAGEMASK) / sizeof(u32)];
|
||||
}
|
||||
|
||||
void DynarmicCallbacks32::MemoryWrite8(u32 vaddr, u8 value) {
|
||||
if (CheckMemoryAccess(vaddr, 1, Kernel::DebugWatchpointType::Write)) {
|
||||
m_memory.Write8(vaddr, value);
|
||||
void DynarmicCallbacks32::MemoryWrite(Dynarmic::A32::VAddr vaddr, u64 value, size_t size) {
|
||||
if (CheckMemoryAccess(vaddr, size, Kernel::DebugWatchpointType::Write)) {
|
||||
switch (size) {
|
||||
case sizeof(u64): return m_memory.Write64(vaddr, value);
|
||||
case sizeof(u32): return m_memory.Write32(vaddr, u32(value));
|
||||
case sizeof(u16): return m_memory.Write16(vaddr, u16(value));
|
||||
case sizeof(u8): return m_memory.Write8(vaddr, u8(value));
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
}
|
||||
}
|
||||
void DynarmicCallbacks32::MemoryWrite16(u32 vaddr, u16 value) {
|
||||
if (CheckMemoryAccess(vaddr, 2, Kernel::DebugWatchpointType::Write)) {
|
||||
m_memory.Write16(vaddr, value);
|
||||
}
|
||||
}
|
||||
void DynarmicCallbacks32::MemoryWrite32(u32 vaddr, u32 value) {
|
||||
if (CheckMemoryAccess(vaddr, 4, Kernel::DebugWatchpointType::Write)) {
|
||||
m_memory.Write32(vaddr, value);
|
||||
}
|
||||
}
|
||||
void DynarmicCallbacks32::MemoryWrite64(u32 vaddr, u64 value) {
|
||||
if (CheckMemoryAccess(vaddr, 8, Kernel::DebugWatchpointType::Write)) {
|
||||
m_memory.Write64(vaddr, value);
|
||||
}
|
||||
}
|
||||
|
||||
bool DynarmicCallbacks32::MemoryWriteExclusive8(u32 vaddr, u8 value, u8 expected) {
|
||||
return CheckMemoryAccess(vaddr, 1, Kernel::DebugWatchpointType::Write) &&
|
||||
m_memory.WriteExclusive8(vaddr, value, expected);
|
||||
@@ -177,7 +161,7 @@ void ArmDynarmic32::MakeJit(Common::PageTable* page_table) {
|
||||
config.page_table = reinterpret_cast<std::array<std::uint8_t*, NumPageTableEntries>*>(
|
||||
const_cast<Common::PageTable::PageEntryData*>(page_table->entries.data()));
|
||||
config.page_table_pointer_mask = Common::PageTable::ATTRIBUTE_MASK;
|
||||
config.page_table_marked_bit = 0;
|
||||
config.page_table_marked_bit = uint8_t(0);
|
||||
config.absolute_offset_page_table = true;
|
||||
config.detect_misaligned_access_via_page_table = 16 | 32 | 64 | 128;
|
||||
config.only_detect_misalignment_via_page_table_on_page_boundary = true;
|
||||
@@ -193,7 +177,7 @@ void ArmDynarmic32::MakeJit(Common::PageTable* page_table) {
|
||||
Kernel::Board::Nintendo::Nx::KSystemControl::Init::GetIntendedMemorySize()) < (1ULL << 39)) {
|
||||
// Systems like FreeBSD allocate memory really low by default, and since we pack our page table entries,
|
||||
// we have to manually sign extend when our actual pointer is negative.
|
||||
config.page_table_sign_extension = Common::PageTable::SIGN_BIT;
|
||||
config.page_table_sign_extension = std::uint8_t(Common::PageTable::SIGN_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,18 +30,12 @@ class System;
|
||||
class DynarmicCallbacks32 : public Dynarmic::A32::UserCallbacks {
|
||||
public:
|
||||
explicit DynarmicCallbacks32(ArmDynarmic32& parent, Kernel::KProcess* process);
|
||||
u8 MemoryRead8(u32 vaddr) override;
|
||||
u16 MemoryRead16(u32 vaddr) override;
|
||||
u32 MemoryRead32(u32 vaddr) override;
|
||||
u64 MemoryRead64(u32 vaddr) override;
|
||||
u64 MemoryRead(u32 vaddr, size_t size) override;
|
||||
std::optional<u32> MemoryReadCode(u32 vaddr) override;
|
||||
void InstructionSynchronizationBarrierRaised() override {
|
||||
last_code_addr = u64(-1); //reset back, force refetch
|
||||
}
|
||||
void MemoryWrite8(u32 vaddr, u8 value) override;
|
||||
void MemoryWrite16(u32 vaddr, u16 value) override;
|
||||
void MemoryWrite32(u32 vaddr, u32 value) override;
|
||||
void MemoryWrite64(u32 vaddr, u64 value) override;
|
||||
void MemoryWrite(Dynarmic::A32::VAddr vaddr, u64 value, size_t size) override;
|
||||
bool MemoryWriteExclusive8(u32 vaddr, u8 value, u8 expected) override;
|
||||
bool MemoryWriteExclusive16(u32 vaddr, u16 value, u16 expected) override;
|
||||
bool MemoryWriteExclusive32(u32 vaddr, u32 value, u32 expected) override;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "core/arm/dynarmic/dynarmic_exclusive_monitor.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/hle/kernel/k_process.h"
|
||||
#include "dynarmic/interface/A64/config.h"
|
||||
|
||||
namespace Core {
|
||||
|
||||
@@ -21,21 +22,15 @@ DynarmicCallbacks64::DynarmicCallbacks64(ArmDynarmic64& parent, Kernel::KProcess
|
||||
, m_check_memory_access{m_debugger_enabled || !Settings::values.cpuopt_ignore_memory_aborts.GetValue()}
|
||||
{}
|
||||
|
||||
u8 DynarmicCallbacks64::MemoryRead8(u64 vaddr) {
|
||||
CheckMemoryAccess(vaddr, 1, Kernel::DebugWatchpointType::Read);
|
||||
return m_memory.Read8(vaddr);
|
||||
}
|
||||
u16 DynarmicCallbacks64::MemoryRead16(u64 vaddr) {
|
||||
CheckMemoryAccess(vaddr, 2, Kernel::DebugWatchpointType::Read);
|
||||
return m_memory.Read16(vaddr);
|
||||
}
|
||||
u32 DynarmicCallbacks64::MemoryRead32(u64 vaddr) {
|
||||
CheckMemoryAccess(vaddr, 4, Kernel::DebugWatchpointType::Read);
|
||||
return m_memory.Read32(vaddr);
|
||||
}
|
||||
u64 DynarmicCallbacks64::MemoryRead64(u64 vaddr) {
|
||||
CheckMemoryAccess(vaddr, 8, Kernel::DebugWatchpointType::Read);
|
||||
return m_memory.Read64(vaddr);
|
||||
u64 DynarmicCallbacks64::MemoryRead(u64 vaddr, size_t size) {
|
||||
CheckMemoryAccess(vaddr, size, Kernel::DebugWatchpointType::Read);
|
||||
switch (size) {
|
||||
case sizeof(u64): return m_memory.Read64(vaddr);
|
||||
case sizeof(u32): return m_memory.Read32(vaddr);
|
||||
case sizeof(u16): return m_memory.Read16(vaddr);
|
||||
case sizeof(u8): return m_memory.Read8(vaddr);
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
}
|
||||
Dynarmic::A64::Vector DynarmicCallbacks64::MemoryRead128(u64 vaddr) {
|
||||
CheckMemoryAccess(vaddr, 16, Kernel::DebugWatchpointType::Read);
|
||||
@@ -53,24 +48,15 @@ std::optional<u32> DynarmicCallbacks64::MemoryReadCode(u64 vaddr) {
|
||||
return cached_code_page.inst[(vaddr & Core::Memory::YUZU_PAGEMASK) / sizeof(u32)];
|
||||
}
|
||||
|
||||
void DynarmicCallbacks64::MemoryWrite8(u64 vaddr, u8 value) {
|
||||
if (CheckMemoryAccess(vaddr, 1, Kernel::DebugWatchpointType::Write)) {
|
||||
m_memory.Write8(vaddr, value);
|
||||
}
|
||||
}
|
||||
void DynarmicCallbacks64::MemoryWrite16(u64 vaddr, u16 value) {
|
||||
if (CheckMemoryAccess(vaddr, 2, Kernel::DebugWatchpointType::Write)) {
|
||||
m_memory.Write16(vaddr, value);
|
||||
}
|
||||
}
|
||||
void DynarmicCallbacks64::MemoryWrite32(u64 vaddr, u32 value) {
|
||||
if (CheckMemoryAccess(vaddr, 4, Kernel::DebugWatchpointType::Write)) {
|
||||
m_memory.Write32(vaddr, value);
|
||||
}
|
||||
}
|
||||
void DynarmicCallbacks64::MemoryWrite64(u64 vaddr, u64 value) {
|
||||
if (CheckMemoryAccess(vaddr, 8, Kernel::DebugWatchpointType::Write)) {
|
||||
m_memory.Write64(vaddr, value);
|
||||
void DynarmicCallbacks64::MemoryWrite(Dynarmic::A64::VAddr vaddr, u64 value, std::size_t size) {
|
||||
if (CheckMemoryAccess(vaddr, size, Kernel::DebugWatchpointType::Write)) {
|
||||
switch (size) {
|
||||
case sizeof(u64): return m_memory.Write64(vaddr, u64(value));
|
||||
case sizeof(u32): return m_memory.Write32(vaddr, u32(value));
|
||||
case sizeof(u16): return m_memory.Write16(vaddr, u16(value));
|
||||
case sizeof(u8): return m_memory.Write8(vaddr, u8(value));
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
}
|
||||
}
|
||||
void DynarmicCallbacks64::MemoryWrite128(u64 vaddr, Dynarmic::A64::Vector value) {
|
||||
@@ -216,7 +202,7 @@ void ArmDynarmic64::MakeJit(Common::PageTable* page_table, std::size_t address_s
|
||||
const_cast<Common::PageTable::PageEntryData*>(page_table->entries.data()));
|
||||
config.page_table_address_space_bits = std::uint32_t(address_space_bits);
|
||||
config.page_table_pointer_mask = Common::PageTable::ATTRIBUTE_MASK;
|
||||
config.page_table_marked_bit = 0;
|
||||
config.page_table_marked_bit = uint8_t(0);
|
||||
config.silently_mirror_page_table = false;
|
||||
config.absolute_offset_page_table = true;
|
||||
config.detect_misaligned_access_via_page_table = 16 | 32 | 64 | 128;
|
||||
@@ -235,7 +221,7 @@ void ArmDynarmic64::MakeJit(Common::PageTable* page_table, std::size_t address_s
|
||||
Kernel::Board::Nintendo::Nx::KSystemControl::Init::GetIntendedMemorySize()) < (1ULL << 39)) {
|
||||
// Systems like FreeBSD allocate memory really low by default, and since we pack our page table entries,
|
||||
// we have to manually sign extend when our actual pointer is negative.
|
||||
config.page_table_sign_extension = Common::PageTable::SIGN_BIT;
|
||||
config.page_table_sign_extension = std::uint8_t(Common::PageTable::SIGN_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "common/hash.h"
|
||||
#include "core/arm/arm_interface.h"
|
||||
#include "core/arm/dynarmic/dynarmic_exclusive_monitor.h"
|
||||
#include "dynarmic/interface/A64/config.h"
|
||||
|
||||
namespace Core::Memory {
|
||||
class Memory;
|
||||
@@ -36,19 +37,13 @@ class DynarmicCallbacks64 : public Dynarmic::A64::UserCallbacks {
|
||||
public:
|
||||
explicit DynarmicCallbacks64(ArmDynarmic64& parent, Kernel::KProcess* process);
|
||||
|
||||
u8 MemoryRead8(u64 vaddr) override;
|
||||
u16 MemoryRead16(u64 vaddr) override;
|
||||
u32 MemoryRead32(u64 vaddr) override;
|
||||
u64 MemoryRead64(u64 vaddr) override;
|
||||
u64 MemoryRead(u64 vaddr, size_t size) override;
|
||||
Dynarmic::A64::Vector MemoryRead128(u64 vaddr) override;
|
||||
std::optional<u32> MemoryReadCode(u64 vaddr) override;
|
||||
void InstructionSynchronizationBarrierRaised() override {
|
||||
last_code_addr = u64(-1); //reset back, force refetch
|
||||
}
|
||||
void MemoryWrite8(u64 vaddr, u8 value) override;
|
||||
void MemoryWrite16(u64 vaddr, u16 value) override;
|
||||
void MemoryWrite32(u64 vaddr, u32 value) override;
|
||||
void MemoryWrite64(u64 vaddr, u64 value) override;
|
||||
void MemoryWrite(Dynarmic::A64::VAddr vaddr, u64 value, std::size_t size) override;
|
||||
void MemoryWrite128(u64 vaddr, Dynarmic::A64::Vector value) override;
|
||||
bool MemoryWriteExclusive8(u64 vaddr, std::uint8_t value, std::uint8_t expected) override;
|
||||
bool MemoryWriteExclusive16(u64 vaddr, std::uint16_t value, std::uint16_t expected) override;
|
||||
|
||||
@@ -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()) {
|
||||
@@ -100,8 +103,7 @@ VirtualFile PatchIPS(const VirtualFile& in, const VirtualFile& ips) {
|
||||
|
||||
|
||||
struct IPSwitchRecord {
|
||||
std::array<uint8_t, 256 - sizeof(size_t)> data;
|
||||
size_t count;
|
||||
std::vector<uint8_t> data;
|
||||
};
|
||||
struct IPSwitchCompiler::IPSwitchPatch {
|
||||
::Common::unordered_map<u32, IPSwitchRecord> records;
|
||||
@@ -122,22 +124,23 @@ static IPSwitchRecord EscapeStringSequences(std::string_view sv) {
|
||||
IPSwitchRecord r{};
|
||||
for (auto it = sv.cbegin(); it < sv.cend(); ) {
|
||||
if (*it == '\\' && it + 1 < sv.cend()) {
|
||||
switch (it[1]) {
|
||||
case 'a': r.data[r.count] = '\a'; break;
|
||||
case 'b': r.data[r.count] = '\b'; break;
|
||||
case 'e': r.data[r.count] = '\e'; break;
|
||||
case 'f': r.data[r.count] = '\f'; break;
|
||||
case 'n': r.data[r.count] = '\n'; break;
|
||||
case 'r': r.data[r.count] = '\r'; break;
|
||||
case 't': r.data[r.count] = '\t'; break;
|
||||
case 'v': r.data[r.count] = '\v'; break;
|
||||
case '?': r.data[r.count] = '\?'; break;
|
||||
default: r.data[r.count] = it[1]; break;
|
||||
}
|
||||
++r.count;
|
||||
r.data.push_back([it]() {
|
||||
switch (it[1]) {
|
||||
case 'a': return '\a';
|
||||
case 'b': return '\b';
|
||||
case 'e': return '\e';
|
||||
case 'f': return '\f';
|
||||
case 'n': return '\n';
|
||||
case 'r': return '\r';
|
||||
case 't': return '\t';
|
||||
case 'v': return '\v';
|
||||
case '?': return '\?';
|
||||
default: return it[1];
|
||||
}
|
||||
}());
|
||||
it += 2;
|
||||
} else {
|
||||
++r.count;
|
||||
r.data.push_back(*it);
|
||||
++it;
|
||||
}
|
||||
}
|
||||
@@ -223,8 +226,8 @@ void IPSwitchCompiler::Parse(std::span<u8 const> bytes) {
|
||||
if (start <= line.cend() && end <= line.cend()) {
|
||||
// Actually IPS wants ordering from {lsb, ..., msb} -- so LE and BE are inverted, fun!
|
||||
auto const hs = Common::HexStringToVector({start, end}, is_little_endian);
|
||||
r.data.resize(hs.size());
|
||||
std::memcpy(r.data.data(), hs.data(), hs.size());
|
||||
r.count = hs.size();
|
||||
LOG_INFO(Loader, "[H] value @ {:#08X}", offset);
|
||||
patches.back().records.insert_or_assign(u32(offset), std::move(r));
|
||||
} else {
|
||||
@@ -293,7 +296,7 @@ VirtualFile IPSwitchCompiler::Apply(const VirtualFile& in) const {
|
||||
if (patch.enabled) {
|
||||
for (const auto& record : patch.records) {
|
||||
if (record.first < in_data.size()) {
|
||||
auto replace_size = record.second.count;
|
||||
auto replace_size = record.second.data.size();
|
||||
if (record.first + replace_size > in_data.size())
|
||||
replace_size = in_data.size() - record.first;
|
||||
std::memcpy(in_data.data() + record.first, record.second.data.data(), replace_size);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/hex_util.h"
|
||||
#include "common/logging.h"
|
||||
#include "common/settings.h"
|
||||
@@ -156,12 +157,15 @@ std::string GetUpdateVersionStringFromSlot(const ContentProvider* provider, u64
|
||||
NACP nacp{nacp_file};
|
||||
return nacp.GetVersionString();
|
||||
}
|
||||
YUZU_NO_INLINE std::optional<u64> GetParentApplicationId(const ContentProvider* provider, u64 title_id) {
|
||||
return provider == nullptr ? std::nullopt : provider->GetParentApplicationId(title_id);
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
PatchManager::PatchManager(u64 title_id_,
|
||||
const Service::FileSystem::FileSystemController& fs_controller_,
|
||||
const ContentProvider& content_provider_)
|
||||
: title_id{title_id_}, fs_controller{fs_controller_}, content_provider{content_provider_} {}
|
||||
: title_id{title_id_}, parent_title_id{GetParentApplicationId(std::addressof(content_provider_), title_id_)}, fs_controller{fs_controller_}, content_provider{content_provider_} {}
|
||||
|
||||
PatchManager::~PatchManager() = default;
|
||||
|
||||
@@ -169,13 +173,35 @@ u64 PatchManager::GetTitleID() const {
|
||||
return title_id;
|
||||
}
|
||||
|
||||
VirtualDir PatchManager::GetModificationLoadRoot(bool sdmc) const {
|
||||
const auto get_root = [&](u64 id) {
|
||||
return sdmc ? fs_controller.GetSDMCModificationLoadRoot(id) : fs_controller.GetModificationLoadRoot(id);
|
||||
};
|
||||
auto root = get_root(title_id);
|
||||
if (!parent_title_id) {
|
||||
return root;
|
||||
}
|
||||
std::vector<VirtualDir> roots{std::move(root), get_root(*parent_title_id)};
|
||||
std::erase(roots, nullptr);
|
||||
return LayeredVfsDirectory::MakeLayeredDirectory(std::move(roots));
|
||||
}
|
||||
|
||||
std::vector<std::string> PatchManager::GetDisabledAddons() const {
|
||||
auto disabled = Settings::values.disabled_addons[title_id];
|
||||
if (parent_title_id) {
|
||||
const auto& shared = Settings::values.disabled_addons[*parent_title_id];
|
||||
disabled.insert(disabled.end(), shared.begin(), shared.end());
|
||||
}
|
||||
return disabled;
|
||||
}
|
||||
|
||||
VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const {
|
||||
LOG_INFO(Loader, "Patching ExeFS for title_id={:016X}", title_id);
|
||||
|
||||
if (exefs == nullptr)
|
||||
return exefs;
|
||||
|
||||
const auto& disabled = Settings::values.disabled_addons[title_id];
|
||||
const auto disabled = GetDisabledAddons();
|
||||
|
||||
bool update_disabled = true;
|
||||
std::optional<u32> enabled_version;
|
||||
@@ -303,8 +329,8 @@ VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const {
|
||||
}
|
||||
|
||||
// LayeredExeFS
|
||||
const auto load_dir = fs_controller.GetModificationLoadRoot(title_id);
|
||||
const auto sdmc_load_dir = fs_controller.GetSDMCModificationLoadRoot(title_id);
|
||||
const auto load_dir = GetModificationLoadRoot();
|
||||
const auto sdmc_load_dir = GetModificationLoadRoot(true);
|
||||
|
||||
std::vector<VirtualDir> patch_dirs = {sdmc_load_dir};
|
||||
if (load_dir != nullptr) {
|
||||
@@ -346,7 +372,7 @@ VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const {
|
||||
}
|
||||
|
||||
std::vector<VirtualFile> PatchManager::CollectPatches(const std::vector<VirtualDir>& patch_dirs, const std::string& build_id) const {
|
||||
const auto& disabled = Settings::values.disabled_addons[title_id];
|
||||
const auto disabled = GetDisabledAddons();
|
||||
const auto nso_build_id = fmt::format("{:0<64}", build_id);
|
||||
|
||||
std::vector<VirtualFile> out;
|
||||
@@ -405,7 +431,7 @@ std::vector<u8> PatchManager::PatchNSO(const std::vector<u8>& nso, const std::st
|
||||
|
||||
LOG_INFO(Loader, "Patching NSO for name={}, build_id={}", name, build_id);
|
||||
|
||||
const auto load_dir = fs_controller.GetModificationLoadRoot(title_id);
|
||||
const auto load_dir = GetModificationLoadRoot();
|
||||
if (load_dir == nullptr) {
|
||||
LOG_ERROR(Loader, "Cannot load mods for invalid title_id={:016X}", title_id);
|
||||
return nso;
|
||||
@@ -448,7 +474,7 @@ bool PatchManager::HasNSOPatch(const BuildID& build_id_, std::string_view name)
|
||||
|
||||
LOG_INFO(Loader, "Querying NSO patch existence for build_id={}, name={}", build_id, name);
|
||||
|
||||
const auto load_dir = fs_controller.GetModificationLoadRoot(title_id);
|
||||
const auto load_dir = GetModificationLoadRoot();
|
||||
if (load_dir == nullptr) {
|
||||
LOG_ERROR(Loader, "Cannot load mods for invalid title_id={:016X}", title_id);
|
||||
return false;
|
||||
@@ -462,13 +488,13 @@ bool PatchManager::HasNSOPatch(const BuildID& build_id_, std::string_view name)
|
||||
}
|
||||
|
||||
std::vector<Core::Memory::CheatEntry> PatchManager::CreateCheatList(const BuildID& build_id_) const {
|
||||
const auto load_dir = fs_controller.GetModificationLoadRoot(title_id);
|
||||
const auto load_dir = GetModificationLoadRoot();
|
||||
if (load_dir == nullptr) {
|
||||
LOG_ERROR(Loader, "Cannot load mods for invalid title_id={:016X}", title_id);
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto& disabled = Settings::values.disabled_addons[title_id];
|
||||
const auto disabled = GetDisabledAddons();
|
||||
auto patch_dirs = load_dir->GetSubdirectories();
|
||||
std::sort(patch_dirs.begin(), patch_dirs.end(), [](auto const& l, auto const& r) { return l->GetName() < r->GetName(); });
|
||||
|
||||
@@ -502,17 +528,16 @@ std::vector<Core::Memory::CheatEntry> PatchManager::CreateCheatList(const BuildI
|
||||
return out;
|
||||
}
|
||||
|
||||
static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType type,
|
||||
const Service::FileSystem::FileSystemController& fs_controller) {
|
||||
const auto load_dir = fs_controller.GetModificationLoadRoot(title_id);
|
||||
const auto sdmc_load_dir = fs_controller.GetSDMCModificationLoadRoot(title_id);
|
||||
void PatchManager::ApplyLayeredFS(VirtualFile& romfs, ContentRecordType type) const {
|
||||
const auto load_dir = GetModificationLoadRoot();
|
||||
const auto sdmc_load_dir = GetModificationLoadRoot(true);
|
||||
if ((type != ContentRecordType::Program && type != ContentRecordType::Data &&
|
||||
type != ContentRecordType::HtmlDocument) ||
|
||||
(load_dir == nullptr && sdmc_load_dir == nullptr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& disabled = Settings::values.disabled_addons[title_id];
|
||||
const auto disabled = GetDisabledAddons();
|
||||
std::vector<VirtualDir> patch_dirs = load_dir->GetSubdirectories();
|
||||
if (std::find(disabled.cbegin(), disabled.cend(), "SDMC") == disabled.cend()) {
|
||||
patch_dirs.push_back(sdmc_load_dir);
|
||||
@@ -591,7 +616,7 @@ VirtualFile PatchManager::PatchRomFS(const NCA* base_nca, VirtualFile base_romfs
|
||||
|
||||
// Game Updates
|
||||
const auto update_tid = GetUpdateTitleID(title_id);
|
||||
const auto& disabled = Settings::values.disabled_addons[title_id];
|
||||
const auto disabled = GetDisabledAddons();
|
||||
|
||||
bool update_disabled = true;
|
||||
std::optional<u32> enabled_version;
|
||||
@@ -698,7 +723,7 @@ VirtualFile PatchManager::PatchRomFS(const NCA* base_nca, VirtualFile base_romfs
|
||||
|
||||
// LayeredFS
|
||||
if (apply_layeredfs) {
|
||||
ApplyLayeredFS(romfs, title_id, type, fs_controller);
|
||||
ApplyLayeredFS(romfs, type);
|
||||
}
|
||||
|
||||
return romfs;
|
||||
@@ -1072,15 +1097,22 @@ std::vector<Patch> PatchManager::GetPatches(VirtualFile update_raw) const {
|
||||
std::optional<u32> PatchManager::GetGameVersion() const {
|
||||
const auto update_tid = GetUpdateTitleID(title_id);
|
||||
if (content_provider.HasEntry(update_tid, ContentRecordType::Program)) {
|
||||
return content_provider.GetEntryVersion(update_tid);
|
||||
const auto version = content_provider.GetEntryVersion(update_tid);
|
||||
return version || !parent_title_id ? version : content_provider.GetEntryVersion(GetUpdateTitleID(*parent_title_id));
|
||||
}
|
||||
|
||||
return content_provider.GetEntryVersion(title_id);
|
||||
const auto version = content_provider.GetEntryVersion(title_id);
|
||||
return version || !parent_title_id ? version : content_provider.GetEntryVersion(*parent_title_id);
|
||||
}
|
||||
|
||||
PatchManager::Metadata PatchManager::GetControlMetadata() const {
|
||||
const auto base_control_nca = content_provider.GetEntry(title_id, ContentRecordType::Control);
|
||||
if (base_control_nca == nullptr) {
|
||||
if (parent_title_id) {
|
||||
const auto control_id = content_provider.HasEntry(*parent_title_id, ContentRecordType::Control) ? *parent_title_id : GetUpdateTitleID(*parent_title_id);
|
||||
const PatchManager parent{control_id, fs_controller, content_provider};
|
||||
return parent.GetControlMetadata();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
@@ -109,10 +109,14 @@ public:
|
||||
[[nodiscard]] static PatchManager::Metadata GetMetadataFromBaseOrUpdate(Core::System& system, u64 application_id) noexcept;
|
||||
|
||||
private:
|
||||
[[nodiscard]] VirtualDir GetModificationLoadRoot(bool sdmc = false) const;
|
||||
[[nodiscard]] std::vector<std::string> GetDisabledAddons() const;
|
||||
void ApplyLayeredFS(VirtualFile& romfs, ContentRecordType type) const;
|
||||
[[nodiscard]] std::vector<VirtualFile> CollectPatches(const std::vector<VirtualDir>& patch_dirs,
|
||||
const std::string& build_id) const;
|
||||
|
||||
u64 title_id;
|
||||
std::optional<u64> parent_title_id;
|
||||
const Service::FileSystem::FileSystemController& fs_controller;
|
||||
const ContentProvider& content_provider;
|
||||
};
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <random>
|
||||
#include <regex>
|
||||
#include <openssl/evp.h>
|
||||
@@ -348,6 +349,22 @@ std::vector<ContentProviderEntry> ContentProvider::ListEntries() const {
|
||||
return ListEntriesFilter(std::nullopt, std::nullopt, std::nullopt);
|
||||
}
|
||||
|
||||
std::optional<u64> ContentProvider::GetParentApplicationId(u64 program_id) const {
|
||||
const auto application_id = GetBaseTitleID(program_id);
|
||||
const auto program_index = program_id - application_id;
|
||||
if (program_index == 0 || program_index > std::numeric_limits<u8>::max()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
if (!ListEntriesFilter(TitleType::Application, ContentRecordType::Meta, program_id).empty()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
if ((!ListEntriesFilter(TitleType::Application, ContentRecordType::Meta, application_id).empty() && HasEntry(program_id, ContentRecordType::Program))
|
||||
|| (!ListEntriesFilter(TitleType::Update, ContentRecordType::Meta, GetUpdateTitleID(application_id)).empty() && HasEntry(GetUpdateTitleID(program_id), ContentRecordType::Program))) {
|
||||
return application_id;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
PlaceholderCache::PlaceholderCache(VirtualDir dir_) : dir(std::move(dir_)) {}
|
||||
|
||||
bool PlaceholderCache::Create(const NcaID& id, u64 size) const {
|
||||
|
||||
@@ -100,6 +100,8 @@ public:
|
||||
std::optional<TitleType> title_type = {}, std::optional<ContentRecordType> record_type = {},
|
||||
std::optional<u64> title_id = {}) const = 0;
|
||||
|
||||
[[nodiscard]] std::optional<u64> GetParentApplicationId(u64 program_id) const;
|
||||
|
||||
protected:
|
||||
// A single instance of KeyManager to be used by GetEntry()
|
||||
Core::Crypto::KeyManager& keys = Core::Crypto::KeyManager::Instance();
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// 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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "hid_core/frontend/emulated_controller.h"
|
||||
#include "hid_core/hid_core.h"
|
||||
#include "hid_core/hid_types.h"
|
||||
#include <array>
|
||||
|
||||
namespace Core::Frontend {
|
||||
|
||||
@@ -29,23 +30,39 @@ void DefaultControllerApplet::ReconfigureControllers(ReconfigureCallback callbac
|
||||
|
||||
const std::size_t min_supported_players =
|
||||
parameters.enable_single_mode ? 1 : parameters.min_players;
|
||||
using Core::HID::NpadStyleIndex;
|
||||
const std::size_t max_supported_players = parameters.enable_single_mode ? 1 : parameters.max_players;
|
||||
std::size_t num_selected_players = 0;
|
||||
std::array<bool, HID::HIDCore::available_controllers> keep_connected{};
|
||||
|
||||
// Disconnect Handheld first.
|
||||
// reserve existing AND valid players before filling slots. include Handheld, but not other
|
||||
for (std::size_t index = 0; index < hid_core.available_controllers - 1; ++index) {
|
||||
const auto* controller = hid_core.GetEmulatedControllerByIndex(index);
|
||||
if (!parameters.keep_controllers_connected || !controller->IsConnected() || num_selected_players >= max_supported_players) continue;
|
||||
|
||||
const auto style = controller->GetNpadStyleIndex();
|
||||
keep_connected[index] =
|
||||
(style == NpadStyleIndex::Fullkey && parameters.allow_pro_controller) ||
|
||||
(style == NpadStyleIndex::JoyconDual && parameters.allow_dual_joycons) ||
|
||||
(style == NpadStyleIndex::JoyconLeft && parameters.allow_left_joycon) ||
|
||||
(style == NpadStyleIndex::JoyconRight && parameters.allow_right_joycon) ||
|
||||
(style == NpadStyleIndex::Handheld && parameters.enable_single_mode && parameters.allow_handheld && !Settings::IsDockedMode()) ||
|
||||
(style == NpadStyleIndex::GameCube && parameters.allow_gamecube_controller);
|
||||
num_selected_players += keep_connected[index];
|
||||
}
|
||||
auto* handheld = hid_core.GetEmulatedController(Core::HID::NpadIdType::Handheld);
|
||||
handheld->Disconnect();
|
||||
if (!keep_connected[hid_core.available_controllers - 2]) handheld->Disconnect();
|
||||
|
||||
// Deduce the best configuration based on the input parameters.
|
||||
for (std::size_t index = 0; index < hid_core.available_controllers - 2; ++index) {
|
||||
auto* controller = hid_core.GetEmulatedControllerByIndex(index);
|
||||
|
||||
// First, disconnect all controllers regardless of the value of keep_controllers_connected.
|
||||
// This makes it easy to connect the desired controllers.
|
||||
if (keep_connected[index]) continue;
|
||||
controller->Disconnect();
|
||||
|
||||
// Only connect the minimum number of required players.
|
||||
if (index >= min_supported_players) {
|
||||
continue;
|
||||
}
|
||||
// only add players still needed to reach the minimum
|
||||
if (num_selected_players >= min_supported_players) continue;
|
||||
++num_selected_players;
|
||||
|
||||
// Connect controllers based on the following priority list from highest to lowest priority:
|
||||
// Pro Controller -> Dual Joycons -> Left Joycon/Right Joycon -> Handheld
|
||||
|
||||
@@ -465,6 +465,10 @@ void KScheduler::ScheduleImplFiber(KernelCore& kernel) {
|
||||
// Check if we need scheduling. If we do, then we can't complete the switch and should
|
||||
// retry.
|
||||
if (m_state.needs_scheduling.load(std::memory_order_seq_cst)) {
|
||||
// Some libc++ lazily init mutex
|
||||
[[maybe_unused]] auto const can_lock = highest_priority_thread->m_context_guard.try_lock();
|
||||
DEBUG_ASSERT(!can_lock);
|
||||
|
||||
// Our switch failed.
|
||||
// We should unlock the thread context, and then retry.
|
||||
highest_priority_thread->m_context_guard.unlock();
|
||||
@@ -496,6 +500,10 @@ void KScheduler::Unload(KernelCore& kernel, KThread* thread) {
|
||||
|
||||
// Check if the thread is terminated by checking the DPC flags.
|
||||
if ((thread->GetStackParameters().dpc_flags & static_cast<u32>(DpcFlag::Terminated)) == 0) {
|
||||
// Some libc++ lazily init mutex
|
||||
[[maybe_unused]] auto const can_lock = thread->m_context_guard.try_lock();
|
||||
DEBUG_ASSERT(!can_lock);
|
||||
|
||||
// The thread isn't terminated, so we want to unlock it.
|
||||
thread->m_context_guard.unlock();
|
||||
}
|
||||
|
||||
@@ -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 2020 yuzu Emulator Project
|
||||
@@ -12,7 +12,6 @@
|
||||
#include "common/atomic_ops.h"
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
#include "common/spin_lock.h"
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
@@ -30,7 +29,7 @@ public:
|
||||
};
|
||||
|
||||
public:
|
||||
constexpr KSlabHeapImpl() = default;
|
||||
KSlabHeapImpl() = default;
|
||||
|
||||
void Initialize() {
|
||||
ASSERT(m_head == nullptr);
|
||||
@@ -68,7 +67,7 @@ public:
|
||||
|
||||
private:
|
||||
std::atomic<Node*> m_head{};
|
||||
Common::SpinLock m_lock;
|
||||
std::mutex m_lock;
|
||||
};
|
||||
|
||||
} // namespace impl
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
#include "common/intrusive_red_black_tree.h"
|
||||
#include "common/scratch_buffer.h"
|
||||
#include "common/spin_lock.h"
|
||||
#include "core/arm/arm_interface.h"
|
||||
#include "core/hle/kernel/k_affinity_mask.h"
|
||||
#include "core/hle/kernel/k_light_lock.h"
|
||||
@@ -920,7 +919,7 @@ private:
|
||||
bool m_resource_limit_release_hint{};
|
||||
bool m_is_kernel_address_key{};
|
||||
StackParameters m_stack_parameters{};
|
||||
Common::SpinLock m_context_guard{};
|
||||
std::mutex m_context_guard{};
|
||||
|
||||
// For emulation
|
||||
std::shared_ptr<Common::Fiber> m_host_context{};
|
||||
|
||||
+591
-629
File diff suppressed because it is too large
Load Diff
@@ -23,6 +23,12 @@ constexpr std::size_t profile_username_size{32};
|
||||
using ProfileUsername = std::array<u8, profile_username_size>;
|
||||
using UserIDArray = std::array<Common::UUID, MAX_USERS>;
|
||||
|
||||
// This is nn::account::Uid
|
||||
struct Uid {
|
||||
std::array<u8, 0x10> unk0;
|
||||
};
|
||||
static_assert(sizeof(Uid) == 0x10);
|
||||
|
||||
/// Contains extra data related to a user.
|
||||
/// TODO: RE this structure
|
||||
struct UserData {
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "core/hle/service/am/frontend/applet_web_browser.h"
|
||||
#include "core/hle/service/am/frontend/applets.h"
|
||||
#include "core/hle/service/am/service/storage.h"
|
||||
#include "core/hle/service/am/window_system.h"
|
||||
#include "core/hle/service/sm/sm.h"
|
||||
|
||||
namespace Service::AM::Frontend {
|
||||
@@ -72,10 +73,16 @@ void FrontendApplet::PushInteractiveOutData(std::shared_ptr<IStorage> storage) {
|
||||
|
||||
void FrontendApplet::Exit() {
|
||||
auto applet_ = applet.lock();
|
||||
|
||||
std::scoped_lock lk{applet_->lock};
|
||||
applet_->is_completed = true;
|
||||
applet_->state_changed_event.Signal(system.Kernel());
|
||||
{
|
||||
std::scoped_lock lk{applet_->lock};
|
||||
applet_->is_completed = true;
|
||||
applet_->state_changed_event.Signal(system.Kernel());
|
||||
}
|
||||
if (auto caller_applet = applet_->caller_applet.lock()) {
|
||||
std::scoped_lock lk{caller_applet->lock};
|
||||
std::erase(caller_applet->child_applets, applet_);
|
||||
}
|
||||
if (auto* window_system = system.GetAppletManager().GetWindowSystem()) window_system->RequestUpdate();
|
||||
}
|
||||
|
||||
FrontendAppletSet::FrontendAppletSet() = default;
|
||||
|
||||
@@ -92,6 +92,13 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void RequestFocusStateChangedNotification(Kernel::KernelCore& kernel) {
|
||||
if (m_focus_state_changed_notification_enabled) {
|
||||
m_has_focus_state_changed = true;
|
||||
this->SignalSystemEventIfNeeded(kernel);
|
||||
}
|
||||
}
|
||||
|
||||
void OnOperationAndPerformanceModeChanged(Kernel::KernelCore& kernel);
|
||||
|
||||
public:
|
||||
|
||||
@@ -347,21 +347,22 @@ Result IApplicationFunctions::NotifyRunning(Out<bool> out_became_running) {
|
||||
|
||||
Result IApplicationFunctions::GetPseudoDeviceId(Out<Common::UUID> out_pseudo_device_id) {
|
||||
LOG_WARNING(Service_AM, "(stubbed)");
|
||||
R_UNLESS(out_pseudo_device_id, ResultUnknown);
|
||||
R_UNLESS(out_pseudo_device_id != nullptr, ResultUnknown);
|
||||
|
||||
// This should be hashed with the device specific hash
|
||||
// for now this will do
|
||||
const auto res = FileSys::PatchManager::GetMetadataFromBaseOrUpdate(system, m_applet->program_id);
|
||||
u8 hash[EVP_MAX_MD_SIZE];
|
||||
R_UNLESS(res.first != nullptr, ResultUnknown);
|
||||
std::array<u8, EVP_MAX_MD_SIZE> hash;
|
||||
unsigned int hash_len = 0;
|
||||
auto const seed = res.first->raw.seed_for_pseudo_device_id;
|
||||
EVP_MD_CTX *ctx = EVP_MD_CTX_new();
|
||||
auto const algorithm = EVP_sha1();
|
||||
EVP_DigestInit_ex(ctx, algorithm, nullptr);
|
||||
EVP_DigestUpdate(ctx, &seed, sizeof(seed));
|
||||
EVP_DigestFinal_ex(ctx, hash, &hash_len);
|
||||
EVP_DigestFinal_ex(ctx, hash.data(), &hash_len);
|
||||
EVP_MD_CTX_free(ctx);
|
||||
*out_pseudo_device_id = Common::UUID::MakeRFC4122V5(std::span<u8, 20>{hash, std::size(hash)});
|
||||
*out_pseudo_device_id = Common::UUID::MakeRFC4122V5(std::span<u8, 16>{hash.begin(), hash.begin() + 16});
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
|
||||
@@ -164,14 +164,14 @@ Result ILibraryAppletAccessor::PushInData(SharedPointer<IStorage> storage) {
|
||||
Result ILibraryAppletAccessor::PopOutData(Out<SharedPointer<IStorage>> out_storage) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
|
||||
if (auto caller_applet = m_applet->caller_applet.lock(); caller_applet) {
|
||||
caller_applet->lifecycle_manager.GetSystemEvent().Signal(system.Kernel());
|
||||
caller_applet->lifecycle_manager.RequestResumeNotification();
|
||||
caller_applet->lifecycle_manager.GetSystemEvent().Clear(system.Kernel());
|
||||
caller_applet->lifecycle_manager.UpdateRequestedFocusState();
|
||||
}
|
||||
|
||||
R_TRY(m_broker->GetOutData().Pop(system.Kernel(), out_storage.Get()));
|
||||
if (auto caller_applet = m_applet->caller_applet.lock(); caller_applet) {
|
||||
std::scoped_lock lk{caller_applet->lock};
|
||||
const bool focus_state_changed = caller_applet->lifecycle_manager.UpdateRequestedFocusState();
|
||||
const bool is_front_app = m_applet->frontend && caller_applet->lifecycle_manager.IsApplication();
|
||||
if (focus_state_changed) caller_applet->lifecycle_manager.SignalSystemEventIfNeeded(system.Kernel());
|
||||
else if (is_front_app) caller_applet->lifecycle_manager.RequestFocusStateChangedNotification(system.Kernel());
|
||||
}
|
||||
|
||||
if (m_applet->applet_id == AppletId::ProfileSelect && *out_storage) {
|
||||
auto impl = (*out_storage)->GetImpl();
|
||||
|
||||
@@ -122,7 +122,10 @@ std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system,
|
||||
auto broker = std::make_shared<AppletDataBroker>(system);
|
||||
applet->caller_applet = caller_applet;
|
||||
applet->caller_applet_broker = broker;
|
||||
caller_applet->child_applets.push_back(applet);
|
||||
{
|
||||
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);
|
||||
}
|
||||
@@ -148,10 +151,10 @@ std::shared_ptr<ILibraryAppletAccessor> CreateFrontendApplet(Core::System& syste
|
||||
applet->caller_applet = caller_applet;
|
||||
applet->caller_applet_broker = storage;
|
||||
applet->frontend = system.GetFrontendAppletHolder().GetApplet(applet, applet_id, mode);
|
||||
caller_applet->child_applets.push_back(applet);
|
||||
|
||||
window_system.TrackApplet(applet, false);
|
||||
|
||||
{
|
||||
std::scoped_lock lk{caller_applet->lock};
|
||||
caller_applet->child_applets.push_back(applet);
|
||||
}
|
||||
return std::make_shared<ILibraryAppletAccessor>(system, storage, applet);
|
||||
}
|
||||
|
||||
|
||||
@@ -517,7 +517,7 @@ void WindowSystem::UpdateAppletStateLocked(Applet* applet, bool is_foreground, b
|
||||
// Layer ordering. Composition sorts back-to-front. Now with enums for calrity.
|
||||
s32 z_index = Background;
|
||||
if (is_overlay) {
|
||||
z_index = Overlay;
|
||||
z_index = this->IsOverlayOpenLocked(*applet) ? Overlay : Background;
|
||||
} else if (inherited_foreground) {
|
||||
z_index = is_obscured ? Foreground : ForegroundVisible;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// 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
|
||||
|
||||
@@ -13,11 +16,11 @@ IPurchaseEventManager::IPurchaseEventManager(Core::System& system_)
|
||||
"IPurchaseEventManager"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, D<&IPurchaseEventManager::SetDefaultDeliveryTarget>, "SetDefaultDeliveryTarget"},
|
||||
{1, D<&IPurchaseEventManager::SetDeliveryTarget>, "SetDeliveryTarget"},
|
||||
{2, D<&IPurchaseEventManager::GetPurchasedEvent>, "GetPurchasedEvent"},
|
||||
{3, D<&IPurchaseEventManager::PopPurchasedProductInfo>, "PopPurchasedProductInfo"},
|
||||
{4, D<&IPurchaseEventManager::PopPurchasedProductInfoWithUid>, "PopPurchasedProductInfoWithUid"},
|
||||
FunctionInfo{0, D<&IPurchaseEventManager::SetDefaultDeliveryTarget>, "SetDefaultDeliveryTarget"},
|
||||
FunctionInfo{1, D<&IPurchaseEventManager::SetDeliveryTarget>, "SetDeliveryTarget"},
|
||||
FunctionInfo{2, D<&IPurchaseEventManager::GetPurchasedEvent>, "GetPurchasedEvent"},
|
||||
FunctionInfo{3, D<&IPurchaseEventManager::PopPurchasedProductInfo>, "PopPurchasedProductInfo"},
|
||||
FunctionInfo{4, D<&IPurchaseEventManager::PopPurchasedProductInfoWithUid>, "PopPurchasedProductInfoWithUid"}
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -17,9 +17,9 @@ public:
|
||||
explicit ISession(Core::System& system_, Controller& controller_)
|
||||
: ServiceFramework{system_, "ISession"}, controller{controller_} {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &ISession::SetPerformanceConfiguration, "SetPerformanceConfiguration"},
|
||||
{1, &ISession::GetPerformanceConfiguration, "GetPerformanceConfiguration"},
|
||||
{2, &ISession::SetCpuOverclockEnabled, "SetCpuOverclockEnabled"},
|
||||
FunctionInfo{0, &ISession::SetPerformanceConfiguration, "SetPerformanceConfiguration"},
|
||||
FunctionInfo{1, &ISession::GetPerformanceConfiguration, "GetPerformanceConfiguration"},
|
||||
FunctionInfo{2, &ISession::SetCpuOverclockEnabled, "SetCpuOverclockEnabled"}
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
@@ -21,164 +21,154 @@ namespace Service::Audio {
|
||||
class IAudioOutManagerForApplet final : public ServiceFramework<IAudioOutManagerForApplet> {
|
||||
public:
|
||||
explicit IAudioOutManagerForApplet(Core::System& system_)
|
||||
: ServiceFramework{system_, "audout:a"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "RequestSuspend"},
|
||||
{1, nullptr, "RequestResume"},
|
||||
{2, nullptr, "GetProcessMasterVolume"},
|
||||
{3, nullptr, "SetProcessMasterVolume"},
|
||||
{4, nullptr, "GetProcessRecordVolume"},
|
||||
{5, nullptr, "SetProcessRecordVolume"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
: ServiceFramework{system_, "audout:a"} {}
|
||||
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{0, nullptr, "RequestSuspend"},
|
||||
FunctionInfo{1, nullptr, "RequestResume"},
|
||||
FunctionInfo{2, nullptr, "GetProcessMasterVolume"},
|
||||
FunctionInfo{3, nullptr, "SetProcessMasterVolume"},
|
||||
FunctionInfo{4, nullptr, "GetProcessRecordVolume"},
|
||||
FunctionInfo{5, nullptr, "SetProcessRecordVolume"}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
class IAudioSnoopManager final : public ServiceFramework<IAudioSnoopManager> {
|
||||
public:
|
||||
explicit IAudioSnoopManager(Core::System& system_)
|
||||
: ServiceFramework{system_, "auddev"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetDspStatistics"},
|
||||
{1, nullptr, "GetAppletStateSummaries"},
|
||||
{2, nullptr, "SetDspStatisticsParameter"},
|
||||
{3, nullptr, "GetDspStatisticsParameter"},
|
||||
{6, nullptr, "GetDspUsage"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
: ServiceFramework{system_, "auddev"} {}
|
||||
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{0, nullptr, "GetDspStatistics"},
|
||||
FunctionInfo{1, nullptr, "GetAppletStateSummaries"},
|
||||
FunctionInfo{2, nullptr, "SetDspStatisticsParameter"},
|
||||
FunctionInfo{3, nullptr, "GetDspStatisticsParameter"},
|
||||
FunctionInfo{6, nullptr, "GetDspUsage"}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
class IAudioInManagerForApplet final : public ServiceFramework<IAudioInManagerForApplet> {
|
||||
public:
|
||||
explicit IAudioInManagerForApplet(Core::System& system_)
|
||||
: ServiceFramework{system_, "audin:a"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "RequestSuspend"},
|
||||
{1, nullptr, "RequestResume"},
|
||||
{2, nullptr, "GetProcessMasterVolume"},
|
||||
{3, nullptr, "SetProcessMasterVolume"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
: ServiceFramework{system_, "audin:a"} {}
|
||||
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{0, nullptr, "RequestSuspend"},
|
||||
FunctionInfo{1, nullptr, "RequestResume"},
|
||||
FunctionInfo{2, nullptr, "GetProcessMasterVolume"},
|
||||
FunctionInfo{3, nullptr, "SetProcessMasterVolume"}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
class IAudioRendererManagerForApplet final : public ServiceFramework<IAudioRendererManagerForApplet> {
|
||||
public:
|
||||
explicit IAudioRendererManagerForApplet(Core::System& system_)
|
||||
: ServiceFramework{system_, "audren:a"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "RequestSuspend"},
|
||||
{1, nullptr, "RequestResume"},
|
||||
{2, nullptr, "GetProcessMasterVolume"},
|
||||
{3, nullptr, "SetProcessMasterVolume"},
|
||||
{4, nullptr, "RegisterAppletResourceUserId"},
|
||||
{5, nullptr, "UnregisterAppletResourceUserId"},
|
||||
{6, nullptr, "GetProcessRecordVolume"},
|
||||
{7, nullptr, "SetProcessRecordVolume"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
: ServiceFramework{system_, "audren:a"} {}
|
||||
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{0, nullptr, "RequestSuspend"},
|
||||
FunctionInfo{1, nullptr, "RequestResume"},
|
||||
FunctionInfo{2, nullptr, "GetProcessMasterVolume"},
|
||||
FunctionInfo{3, nullptr, "SetProcessMasterVolume"},
|
||||
FunctionInfo{4, nullptr, "RegisterAppletResourceUserId"},
|
||||
FunctionInfo{5, nullptr, "UnregisterAppletResourceUserId"},
|
||||
FunctionInfo{6, nullptr, "GetProcessRecordVolume"},
|
||||
FunctionInfo{7, nullptr, "SetProcessRecordVolume"}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
class IAudioOutManagerForDebugger final : public ServiceFramework<IAudioOutManagerForDebugger> {
|
||||
public:
|
||||
explicit IAudioOutManagerForDebugger(Core::System& system_)
|
||||
: ServiceFramework{system_, "audout:d"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "RequestSuspend"},
|
||||
{1, nullptr, "RequestResume"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
: ServiceFramework{system_, "audout:d"} {}
|
||||
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{0, nullptr, "RequestSuspend"},
|
||||
FunctionInfo{1, nullptr, "RequestResume"}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
class IAudioInManagerForDebugger final : public ServiceFramework<IAudioInManagerForDebugger> {
|
||||
public:
|
||||
explicit IAudioInManagerForDebugger(Core::System& system_)
|
||||
: ServiceFramework{system_, "audin:d"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "RequestSuspend"},
|
||||
{1, nullptr, "RequestResume"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
: ServiceFramework{system_, "audin:d"} {}
|
||||
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{0, nullptr, "RequestSuspend"},
|
||||
FunctionInfo{1, nullptr, "RequestResume"}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
class IFinalOutputRecorderManagerForDebugger final : public ServiceFramework<IFinalOutputRecorderManagerForDebugger> {
|
||||
public:
|
||||
explicit IFinalOutputRecorderManagerForDebugger(Core::System& system_)
|
||||
: ServiceFramework{system_, "audrec:d"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "RequestSuspend"},
|
||||
{1, nullptr, "RequestResume"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
: ServiceFramework{system_, "audrec:d"} {}
|
||||
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{0, nullptr, "RequestSuspend"},
|
||||
FunctionInfo{1, nullptr, "RequestResume"}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
class IAudioRendererManagerForDebugger final : public ServiceFramework<IAudioRendererManagerForDebugger> {
|
||||
public:
|
||||
explicit IAudioRendererManagerForDebugger(Core::System& system_)
|
||||
: ServiceFramework{system_, "audren:d"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "RequestSuspend"},
|
||||
{1, nullptr, "RequestResume"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
: ServiceFramework{system_, "audren:d"} {}
|
||||
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{0, nullptr, "RequestSuspend"},
|
||||
FunctionInfo{1, nullptr, "RequestResume"}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
class IAudioSystemManagerForApplet final : public ServiceFramework<IAudioSystemManagerForApplet> {
|
||||
public:
|
||||
explicit IAudioSystemManagerForApplet(Core::System& system_)
|
||||
: ServiceFramework{system_, "aud:a"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "RegisterAppletResourceUserId"},
|
||||
{1, nullptr, "UnregisterAppletResourceUserId"},
|
||||
{2, nullptr, "RequestSuspendAudio"},
|
||||
{3, nullptr, "RequestResumeAudio"},
|
||||
{4, nullptr, "GetAudioOutputProcessMasterVolume"},
|
||||
{5, nullptr, "SetAudioOutputProcessMasterVolume"},
|
||||
{6, nullptr, "GetAudioInputProcessMasterVolume"},
|
||||
{7, nullptr, "SetAudioInputProcessMasterVolume"},
|
||||
{8, nullptr, "GetAudioOutputProcessRecordVolume"},
|
||||
{9, nullptr, "SetAudioOutputProcessRecordVolume"},
|
||||
{10, nullptr, "GetAppletStateSummaries"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
: ServiceFramework{system_, "aud:a"} {}
|
||||
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{0, nullptr, "RegisterAppletResourceUserId"},
|
||||
FunctionInfo{1, nullptr, "UnregisterAppletResourceUserId"},
|
||||
FunctionInfo{2, nullptr, "RequestSuspendAudio"},
|
||||
FunctionInfo{3, nullptr, "RequestResumeAudio"},
|
||||
FunctionInfo{4, nullptr, "GetAudioOutputProcessMasterVolume"},
|
||||
FunctionInfo{5, nullptr, "SetAudioOutputProcessMasterVolume"},
|
||||
FunctionInfo{6, nullptr, "GetAudioInputProcessMasterVolume"},
|
||||
FunctionInfo{7, nullptr, "SetAudioInputProcessMasterVolume"},
|
||||
FunctionInfo{8, nullptr, "GetAudioOutputProcessRecordVolume"},
|
||||
FunctionInfo{9, nullptr, "SetAudioOutputProcessRecordVolume"},
|
||||
FunctionInfo{10, nullptr, "GetAppletStateSummaries"}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
class IAudioSystemManagerForDebugger final : public ServiceFramework<IAudioSystemManagerForDebugger> {
|
||||
public:
|
||||
explicit IAudioSystemManagerForDebugger(Core::System& system_)
|
||||
: ServiceFramework{system_, "aud:d"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "RequestSuspendAudioForDebug"},
|
||||
{1, nullptr, "RequestResumeAudioForDebug"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
: ServiceFramework{system_, "aud:d"} {}
|
||||
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{0, nullptr, "RequestSuspendAudioForDebug"},
|
||||
FunctionInfo{1, nullptr, "RequestResumeAudioForDebug"}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -191,7 +181,7 @@ void LoopProcess(Core::System& system) {
|
||||
server_manager->RegisterNamedService("audout:d", std::make_shared<IAudioOutManagerForDebugger>(system), 30);
|
||||
server_manager->RegisterNamedService("audin:d", std::make_shared<IAudioInManagerForDebugger>(system), 30);
|
||||
server_manager->RegisterNamedService("audrec:d", std::make_shared<IFinalOutputRecorderManagerForDebugger>(system), 30);
|
||||
server_manager->RegisterNamedService("audren:d", std::make_shared<IAudioInManager>(system), 30);
|
||||
server_manager->RegisterNamedService("audren:d", std::make_shared<IAudioRendererManagerForDebugger>(system), 30);
|
||||
|
||||
server_manager->RegisterNamedService("audin:u", std::make_shared<IAudioInManager>(system), 30);
|
||||
server_manager->RegisterNamedService("audin:a", std::make_shared<IAudioInManagerForApplet>(system), 30);
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// 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
|
||||
|
||||
@@ -8,25 +11,23 @@ namespace Service::Audio {
|
||||
class IFinalOutputRecorder final : public ServiceFramework<IFinalOutputRecorder> {
|
||||
public:
|
||||
explicit IFinalOutputRecorder(Core::System& system_)
|
||||
: ServiceFramework{system_, "IFinalOutputRecorder"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetFinalOutputRecorderState"},
|
||||
{1, nullptr, "Start"},
|
||||
{2, nullptr, "Stop"},
|
||||
{3, nullptr, "AppendFinalOutputRecorderBuffer"},
|
||||
{4, nullptr, "RegisterBufferEvent"},
|
||||
{5, nullptr, "GetReleasedFinalOutputRecorderBuffers"},
|
||||
{6, nullptr, "ContainsFinalOutputRecorderBuffer"},
|
||||
{7, nullptr, "GetFinalOutputRecorderBufferEndTime"},
|
||||
{8, nullptr, "AppendFinalOutputRecorderBufferAuto"},
|
||||
{9, nullptr, "GetReleasedFinalOutputRecorderBufferAuto"},
|
||||
{10, nullptr, "FlushFinalOutputRecorderBuffers"},
|
||||
{11, nullptr, "AttachWorkBuffer"},
|
||||
};
|
||||
// clang-format on
|
||||
: ServiceFramework{system_, "IFinalOutputRecorder"} {}
|
||||
|
||||
RegisterHandlers(functions);
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{0, nullptr, "GetFinalOutputRecorderState"},
|
||||
FunctionInfo{1, nullptr, "Start"},
|
||||
FunctionInfo{2, nullptr, "Stop"},
|
||||
FunctionInfo{3, nullptr, "AppendFinalOutputRecorderBuffer"},
|
||||
FunctionInfo{4, nullptr, "RegisterBufferEvent"},
|
||||
FunctionInfo{5, nullptr, "GetReleasedFinalOutputRecorderBuffers"},
|
||||
FunctionInfo{6, nullptr, "ContainsFinalOutputRecorderBuffer"},
|
||||
FunctionInfo{7, nullptr, "GetFinalOutputRecorderBufferEndTime"},
|
||||
FunctionInfo{8, nullptr, "AppendFinalOutputRecorderBufferAuto"},
|
||||
FunctionInfo{9, nullptr, "GetReleasedFinalOutputRecorderBufferAuto"},
|
||||
FunctionInfo{10, nullptr, "FlushFinalOutputRecorderBuffers"},
|
||||
FunctionInfo{11, nullptr, "AttachWorkBuffer"}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -32,32 +32,32 @@ IBcatService::IBcatService(Core::System& system_, BcatBackend& backend_, u64 pro
|
||||
}} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{10100, D<&IBcatService::RequestSyncDeliveryCache>, "RequestSyncDeliveryCache"},
|
||||
{10101, D<&IBcatService::RequestSyncDeliveryCacheWithDirectoryName>, "RequestSyncDeliveryCacheWithDirectoryName"},
|
||||
{10200, nullptr, "CancelSyncDeliveryCacheRequest"},
|
||||
{20100, nullptr, "RequestSyncDeliveryCacheWithApplicationId"},
|
||||
{20101, nullptr, "RequestSyncDeliveryCacheWithApplicationIdAndDirectoryName"},
|
||||
{20300, nullptr, "GetDeliveryCacheStorageUpdateNotifier"},
|
||||
{20301, nullptr, "RequestSuspendDeliveryTask"},
|
||||
{20400, nullptr, "RegisterSystemApplicationDeliveryTask"},
|
||||
{20401, nullptr, "UnregisterSystemApplicationDeliveryTask"},
|
||||
{20410, nullptr, "SetSystemApplicationDeliveryTaskTimer"},
|
||||
{30100, D<&IBcatService::SetPassphrase>, "SetPassphrase"},
|
||||
{30101, nullptr, "Unknown30101"}, //2.0.0-2.3.0
|
||||
{30102, nullptr, "Unknown30102"}, //2.0.0-2.3.0
|
||||
{30200, nullptr, "RegisterBackgroundDeliveryTask"},
|
||||
{30201, nullptr, "UnregisterBackgroundDeliveryTask"},
|
||||
{30202, nullptr, "BlockDeliveryTask"},
|
||||
{30203, nullptr, "UnblockDeliveryTask"},
|
||||
{30210, nullptr, "SetDeliveryTaskTimer"},
|
||||
{30300, D<&IBcatService::RegisterSystemApplicationDeliveryTasks>, "RegisterSystemApplicationDeliveryTasks"},
|
||||
{90100, nullptr, "GetDeliveryTaskList"},
|
||||
{90101, nullptr, "GetDeliveryTaskListForSystem"}, //11.0.0+
|
||||
{90200, nullptr, "GetDeliveryList"},
|
||||
{90201, D<&IBcatService::ClearDeliveryCacheStorage>, "ClearDeliveryCacheStorage"},
|
||||
{90202, nullptr, "ClearDeliveryTaskSubscriptionStatus"},
|
||||
{90300, nullptr, "GetPushNotificationLog"},
|
||||
{90301, nullptr, "GetDeliveryCacheStorageUsage"}, //11.0.0+
|
||||
FunctionInfo{10100, D<&IBcatService::RequestSyncDeliveryCache>, "RequestSyncDeliveryCache"},
|
||||
FunctionInfo{10101, D<&IBcatService::RequestSyncDeliveryCacheWithDirectoryName>, "RequestSyncDeliveryCacheWithDirectoryName"},
|
||||
FunctionInfo{10200, nullptr, "CancelSyncDeliveryCacheRequest"},
|
||||
FunctionInfo{20100, nullptr, "RequestSyncDeliveryCacheWithApplicationId"},
|
||||
FunctionInfo{20101, nullptr, "RequestSyncDeliveryCacheWithApplicationIdAndDirectoryName"},
|
||||
FunctionInfo{20300, nullptr, "GetDeliveryCacheStorageUpdateNotifier"},
|
||||
FunctionInfo{20301, nullptr, "RequestSuspendDeliveryTask"},
|
||||
FunctionInfo{20400, nullptr, "RegisterSystemApplicationDeliveryTask"},
|
||||
FunctionInfo{20401, nullptr, "UnregisterSystemApplicationDeliveryTask"},
|
||||
FunctionInfo{20410, nullptr, "SetSystemApplicationDeliveryTaskTimer"},
|
||||
FunctionInfo{30100, D<&IBcatService::SetPassphrase>, "SetPassphrase"},
|
||||
FunctionInfo{30101, nullptr, "Unknown30101"}, //2.0.0-2.3.0
|
||||
FunctionInfo{30102, nullptr, "Unknown30102"}, //2.0.0-2.3.0
|
||||
FunctionInfo{30200, nullptr, "RegisterBackgroundDeliveryTask"},
|
||||
FunctionInfo{30201, nullptr, "UnregisterBackgroundDeliveryTask"},
|
||||
FunctionInfo{30202, nullptr, "BlockDeliveryTask"},
|
||||
FunctionInfo{30203, nullptr, "UnblockDeliveryTask"},
|
||||
FunctionInfo{30210, nullptr, "SetDeliveryTaskTimer"},
|
||||
FunctionInfo{30300, D<&IBcatService::RegisterSystemApplicationDeliveryTasks>, "RegisterSystemApplicationDeliveryTasks"},
|
||||
FunctionInfo{90100, nullptr, "GetDeliveryTaskList"},
|
||||
FunctionInfo{90101, nullptr, "GetDeliveryTaskListForSystem"}, //11.0.0+
|
||||
FunctionInfo{90200, nullptr, "GetDeliveryList"},
|
||||
FunctionInfo{90201, D<&IBcatService::ClearDeliveryCacheStorage>, "ClearDeliveryCacheStorage"},
|
||||
FunctionInfo{90202, nullptr, "ClearDeliveryTaskSubscriptionStatus"},
|
||||
FunctionInfo{90300, nullptr, "GetPushNotificationLog"},
|
||||
FunctionInfo{90301, nullptr, "GetDeliveryCacheStorageUsage"}, //11.0.0+
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
|
||||
@@ -14,103 +14,95 @@ namespace Service::BPC {
|
||||
|
||||
class BPC final : public ServiceFramework<BPC> {
|
||||
public:
|
||||
explicit BPC(Core::System& system_) : ServiceFramework{system_, "bpc"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "ShutdownSystem"},
|
||||
{1, nullptr, "RebootSystem"},
|
||||
{2, nullptr, "GetWakeupReason"},
|
||||
{3, nullptr, "GetShutdownReason"},
|
||||
{4, nullptr, "GetAcOk"},
|
||||
{5, nullptr, "GetBoardPowerControlEvent"},
|
||||
{6, nullptr, "GetSleepButtonState"},
|
||||
{7, nullptr, "GetPowerEvent"},
|
||||
{8, nullptr, "CreateWakeupTimer"},
|
||||
{9, nullptr, "CancelWakeupTimer"},
|
||||
{10, nullptr, "EnableWakeupTimerOnDevice"},
|
||||
{11, nullptr, "CreateWakeupTimerEx"},
|
||||
{12, nullptr, "GetLastEnabledWakeupTimerType"},
|
||||
{13, nullptr, "CleanAllWakeupTimers"},
|
||||
{14, nullptr, "GetPowerButton"},
|
||||
{15, nullptr, "SetEnableWakeupTimer"},
|
||||
};
|
||||
// clang-format on
|
||||
explicit BPC(Core::System& system_) : ServiceFramework{system_, "bpc"} {}
|
||||
|
||||
RegisterHandlers(functions);
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{0, nullptr, "ShutdownSystem"},
|
||||
FunctionInfo{1, nullptr, "RebootSystem"},
|
||||
FunctionInfo{2, nullptr, "GetWakeupReason"},
|
||||
FunctionInfo{3, nullptr, "GetShutdownReason"},
|
||||
FunctionInfo{4, nullptr, "GetAcOk"},
|
||||
FunctionInfo{5, nullptr, "GetBoardPowerControlEvent"},
|
||||
FunctionInfo{6, nullptr, "GetSleepButtonState"},
|
||||
FunctionInfo{7, nullptr, "GetPowerEvent"},
|
||||
FunctionInfo{8, nullptr, "CreateWakeupTimer"},
|
||||
FunctionInfo{9, nullptr, "CancelWakeupTimer"},
|
||||
FunctionInfo{10, nullptr, "EnableWakeupTimerOnDevice"},
|
||||
FunctionInfo{11, nullptr, "CreateWakeupTimerEx"},
|
||||
FunctionInfo{12, nullptr, "GetLastEnabledWakeupTimerType"},
|
||||
FunctionInfo{13, nullptr, "CleanAllWakeupTimers"},
|
||||
FunctionInfo{14, nullptr, "GetPowerButton"},
|
||||
FunctionInfo{15, nullptr, "SetEnableWakeupTimer"}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
class BPC_R final : public ServiceFramework<BPC_R> {
|
||||
public:
|
||||
explicit BPC_R(Core::System& system_) : ServiceFramework{system_, "bpc:r"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetRtcTime"},
|
||||
{1, nullptr, "SetRtcTime"},
|
||||
{2, nullptr, "GetRtcResetDetected"},
|
||||
{3, nullptr, "ClearRtcResetDetected"},
|
||||
{4, nullptr, "SetUpRtcResetOnShutdown"},
|
||||
};
|
||||
// clang-format on
|
||||
explicit BPC_R(Core::System& system_) : ServiceFramework{system_, "bpc:r"} {}
|
||||
|
||||
RegisterHandlers(functions);
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{0, nullptr, "GetRtcTime"},
|
||||
FunctionInfo{1, nullptr, "SetRtcTime"},
|
||||
FunctionInfo{2, nullptr, "GetRtcResetDetected"},
|
||||
FunctionInfo{3, nullptr, "ClearRtcResetDetected"},
|
||||
FunctionInfo{4, nullptr, "SetUpRtcResetOnShutdown"}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
class BPC_C final : public ServiceFramework<BPC_C> {
|
||||
public:
|
||||
explicit BPC_C(Core::System& system_) : ServiceFramework{system_, "bpc:c"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "ShutdownSystem"},
|
||||
{1, nullptr, "RebootSystem"},
|
||||
{2, nullptr, "GetWakeupReason"},
|
||||
{3, nullptr, "GetShutdownReason"},
|
||||
{4, nullptr, "GetAcOk"},
|
||||
{5, nullptr, "GetPowerEvent"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
explicit BPC_C(Core::System& system_) : ServiceFramework{system_, "bpc:c"} {}
|
||||
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{0, nullptr, "ShutdownSystem"},
|
||||
FunctionInfo{1, nullptr, "RebootSystem"},
|
||||
FunctionInfo{2, nullptr, "GetWakeupReason"},
|
||||
FunctionInfo{3, nullptr, "GetShutdownReason"},
|
||||
FunctionInfo{4, nullptr, "GetAcOk"},
|
||||
FunctionInfo{5, nullptr, "GetPowerEvent"}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
class BPC_B final : public ServiceFramework<BPC_B> {
|
||||
public:
|
||||
explicit BPC_B(Core::System& system_) : ServiceFramework{system_, "bpc:b"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetSleepButtonState"},
|
||||
{1, nullptr, "GetPowerButtonEvent"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
explicit BPC_B(Core::System& system_) : ServiceFramework{system_, "bpc:b"} {}
|
||||
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{0, nullptr, "GetSleepButtonState"},
|
||||
FunctionInfo{1, nullptr, "GetPowerButtonEvent"}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
class BPC_W final : public ServiceFramework<BPC_W> {
|
||||
public:
|
||||
explicit BPC_W(Core::System& system_) : ServiceFramework{system_, "bpc:w"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "CreateWakeupTimer"},
|
||||
{1, nullptr, "CancelWakeupTimer"},
|
||||
{2, nullptr, "EnableWakeupTimerOnDevice"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
explicit BPC_W(Core::System& system_) : ServiceFramework{system_, "bpc:w"} {}
|
||||
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{0, nullptr, "CreateWakeupTimer"},
|
||||
FunctionInfo{1, nullptr, "CancelWakeupTimer"},
|
||||
FunctionInfo{2, nullptr, "EnableWakeupTimerOnDevice"}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
class BPC_AMS final : public ServiceFramework<BPC_AMS> {
|
||||
public:
|
||||
explicit BPC_AMS(Core::System& system_) : ServiceFramework{system_, "bpc:ams"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{65000, nullptr, "RebootToFatalError"},
|
||||
{65001, nullptr, "SetRebootPayload"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
explicit BPC_AMS(Core::System& system_) : ServiceFramework{system_, "bpc:ams"} {}
|
||||
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{65000, nullptr, "RebootToFatalError"},
|
||||
FunctionInfo{65001, nullptr, "SetRebootPayload"}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -20,26 +20,26 @@ namespace Service::BtDrv {
|
||||
class IBluetoothUser final : public ServiceFramework<IBluetoothUser> {
|
||||
public:
|
||||
explicit IBluetoothUser(Core::System& system_)
|
||||
: ServiceFramework{system_, "bt"}, service_context{system_, "bt"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "LeClientReadCharacteristic"},
|
||||
{1, nullptr, "LeClientReadDescriptor"},
|
||||
{2, nullptr, "LeClientWriteCharacteristic"},
|
||||
{3, nullptr, "LeClientWriteDescriptor"},
|
||||
{4, nullptr, "LeClientRegisterNotification"},
|
||||
{5, nullptr, "LeClientDeregisterNotification"},
|
||||
{6, nullptr, "SetLeResponse"},
|
||||
{7, nullptr, "LeSendIndication"},
|
||||
{8, nullptr, "GetLeEventInfo"},
|
||||
{9, C<&IBluetoothUser::RegisterBleEvent>, "RegisterBleEvent"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
|
||||
: ServiceFramework{system_, "bt"}
|
||||
, service_context{system_, "bt"} {
|
||||
register_event = service_context.CreateEvent("BT:RegisterEvent");
|
||||
}
|
||||
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{0, nullptr, "LeClientReadCharacteristic"},
|
||||
FunctionInfo{1, nullptr, "LeClientReadDescriptor"},
|
||||
FunctionInfo{2, nullptr, "LeClientWriteCharacteristic"},
|
||||
FunctionInfo{3, nullptr, "LeClientWriteDescriptor"},
|
||||
FunctionInfo{4, nullptr, "LeClientRegisterNotification"},
|
||||
FunctionInfo{5, nullptr, "LeClientDeregisterNotification"},
|
||||
FunctionInfo{6, nullptr, "SetLeResponse"},
|
||||
FunctionInfo{7, nullptr, "LeSendIndication"},
|
||||
FunctionInfo{8, nullptr, "GetLeEventInfo"},
|
||||
FunctionInfo{9, C<&IBluetoothUser::RegisterBleEvent>, "RegisterBleEvent"}
|
||||
);
|
||||
}
|
||||
|
||||
~IBluetoothUser() override {
|
||||
service_context.CloseEvent(register_event);
|
||||
}
|
||||
@@ -59,144 +59,142 @@ private:
|
||||
|
||||
class IBluetoothDriver final : public ServiceFramework<IBluetoothDriver> {
|
||||
public:
|
||||
explicit IBluetoothDriver(Core::System& system_) : ServiceFramework{system_, "btdrv"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "InitializeBluetoothDriver"},
|
||||
{1, nullptr, "InitializeBluetooth"},
|
||||
{2, nullptr, "EnableBluetooth"},
|
||||
{3, nullptr, "DisableBluetooth"},
|
||||
{4, nullptr, "FinalizeBluetooth"},
|
||||
{5, nullptr, "GetAdapterProperties"},
|
||||
{6, nullptr, "GetAdapterProperty"},
|
||||
{7, nullptr, "SetAdapterProperty"},
|
||||
{8, nullptr, "StartInquiry"},
|
||||
{9, nullptr, "StopInquiry"},
|
||||
{10, nullptr, "CreateBond"},
|
||||
{11, nullptr, "RemoveBond"},
|
||||
{12, nullptr, "CancelBond"},
|
||||
{13, nullptr, "RespondToPinRequest"},
|
||||
{14, nullptr, "RespondToSspRequest"},
|
||||
{15, nullptr, "GetEventInfo"},
|
||||
{16, nullptr, "InitializeHid"},
|
||||
{17, nullptr, "OpenHidConnection"},
|
||||
{18, nullptr, "CloseHidConnection"},
|
||||
{19, nullptr, "WriteHidData"},
|
||||
{20, nullptr, "WriteHidData2"},
|
||||
{21, nullptr, "SetHidReport"},
|
||||
{22, nullptr, "GetHidReport"},
|
||||
{23, nullptr, "TriggerConnection"},
|
||||
{24, nullptr, "AddPairedDeviceInfo"},
|
||||
{25, nullptr, "GetPairedDeviceInfo"},
|
||||
{26, nullptr, "FinalizeHid"},
|
||||
{27, nullptr, "GetHidEventInfo"},
|
||||
{28, nullptr, "SetTsi"},
|
||||
{29, nullptr, "EnableBurstMode"},
|
||||
{30, nullptr, "SetZeroRetransmission"},
|
||||
{31, nullptr, "EnableMcMode"},
|
||||
{32, nullptr, "EnableLlrScan"},
|
||||
{33, nullptr, "DisableLlrScan"},
|
||||
{34, C<&IBluetoothDriver::EnableRadio>, "EnableRadio"},
|
||||
{35, nullptr, "SetVisibility"},
|
||||
{36, nullptr, "EnableTbfcScan"},
|
||||
{37, nullptr, "RegisterHidReportEvent"},
|
||||
{38, nullptr, "GetHidReportEventInfo"},
|
||||
{39, nullptr, "GetLatestPlr"},
|
||||
{40, nullptr, "GetPendingConnections"},
|
||||
{41, nullptr, "GetChannelMap"},
|
||||
{42, nullptr, "EnableTxPowerBoostSetting"},
|
||||
{43, nullptr, "IsTxPowerBoostSettingEnabled"},
|
||||
{44, nullptr, "EnableAfhSetting"},
|
||||
{45, nullptr, "IsAfhSettingEnabled"},
|
||||
{46, nullptr, "InitializeBle"},
|
||||
{47, nullptr, "EnableBle"},
|
||||
{48, nullptr, "DisableBle"},
|
||||
{49, nullptr, "FinalizeBle"},
|
||||
{50, nullptr, "SetBleVisibility"},
|
||||
{51, nullptr, "SetBleConnectionParameter"},
|
||||
{52, nullptr, "SetBleDefaultConnectionParameter"},
|
||||
{53, nullptr, "SetBleAdvertiseData"},
|
||||
{54, nullptr, "SetBleAdvertiseParameter"},
|
||||
{55, nullptr, "StartBleScan"},
|
||||
{56, nullptr, "StopBleScan"},
|
||||
{57, nullptr, "AddBleScanFilterCondition"},
|
||||
{58, nullptr, "DeleteBleScanFilterCondition"},
|
||||
{59, nullptr, "DeleteBleScanFilter"},
|
||||
{60, nullptr, "ClearBleScanFilters"},
|
||||
{61, nullptr, "EnableBleScanFilter"},
|
||||
{62, nullptr, "RegisterGattClient"},
|
||||
{63, nullptr, "UnregisterGattClient"},
|
||||
{64, nullptr, "UnregisterAllGattClients"},
|
||||
{65, nullptr, "ConnectGattServer"},
|
||||
{66, nullptr, "CancelConnectGattServer"},
|
||||
{67, nullptr, "DisconnectGattServer"},
|
||||
{68, nullptr, "GetGattAttribute"},
|
||||
{69, nullptr, "GetGattService"},
|
||||
{70, nullptr, "ConfigureAttMtu"},
|
||||
{71, nullptr, "RegisterGattServer"},
|
||||
{72, nullptr, "UnregisterGattServer"},
|
||||
{73, nullptr, "ConnectGattClient"},
|
||||
{74, nullptr, "DisconnectGattClient"},
|
||||
{75, nullptr, "AddGattService"},
|
||||
{76, nullptr, "EnableGattService"},
|
||||
{77, nullptr, "AddGattCharacteristic"},
|
||||
{78, nullptr, "AddGattDescriptor"},
|
||||
{79, nullptr, "GetBleManagedEventInfo"},
|
||||
{80, nullptr, "GetGattFirstCharacteristic"},
|
||||
{81, nullptr, "GetGattNextCharacteristic"},
|
||||
{82, nullptr, "GetGattFirstDescriptor"},
|
||||
{83, nullptr, "GetGattNextDescriptor"},
|
||||
{84, nullptr, "RegisterGattManagedDataPath"},
|
||||
{85, nullptr, "UnregisterGattManagedDataPath"},
|
||||
{86, nullptr, "RegisterGattHidDataPath"},
|
||||
{87, nullptr, "UnregisterGattHidDataPath"},
|
||||
{88, nullptr, "RegisterGattDataPath"},
|
||||
{89, nullptr, "UnregisterGattDataPath"},
|
||||
{90, nullptr, "ReadGattCharacteristic"},
|
||||
{91, nullptr, "ReadGattDescriptor"},
|
||||
{92, nullptr, "WriteGattCharacteristic"},
|
||||
{93, nullptr, "WriteGattDescriptor"},
|
||||
{94, nullptr, "RegisterGattNotification"},
|
||||
{95, nullptr, "UnregisterGattNotification"},
|
||||
{96, nullptr, "GetLeHidEventInfo"},
|
||||
{97, nullptr, "RegisterBleHidEvent"},
|
||||
{98, nullptr, "SetBleScanParameter"},
|
||||
{99, nullptr, "MoveToSecondaryPiconet"},
|
||||
{100, nullptr, "IsBluetoothEnabled"},
|
||||
{128, nullptr, "AcquireAudioEvent"},
|
||||
{129, nullptr, "GetAudioEventInfo"},
|
||||
{130, nullptr, "OpenAudioConnection"},
|
||||
{131, nullptr, "CloseAudioConnection"},
|
||||
{132, nullptr, "OpenAudioOut"},
|
||||
{133, nullptr, "CloseAudioOut"},
|
||||
{134, nullptr, "AcquireAudioOutStateChangedEvent"},
|
||||
{135, nullptr, "StartAudioOut"},
|
||||
{136, nullptr, "StopAudioOut"},
|
||||
{137, nullptr, "GetAudioOutState"},
|
||||
{138, nullptr, "GetAudioOutFeedingCodec"},
|
||||
{139, nullptr, "GetAudioOutFeedingParameter"},
|
||||
{140, nullptr, "AcquireAudioOutBufferAvailableEvent"},
|
||||
{141, nullptr, "SendAudioData"},
|
||||
{142, nullptr, "AcquireAudioControlInputStateChangedEvent"},
|
||||
{143, nullptr, "GetAudioControlInputState"},
|
||||
{144, nullptr, "AcquireAudioConnectionStateChangedEvent"},
|
||||
{145, nullptr, "GetConnectedAudioDevice"},
|
||||
{146, nullptr, "CloseAudioControlInput"},
|
||||
{147, nullptr, "RegisterAudioControlNotification"},
|
||||
{148, nullptr, "SendAudioControlPassthroughCommand"},
|
||||
{149, nullptr, "SendAudioControlSetAbsoluteVolumeCommand"},
|
||||
{150, nullptr, "AcquireAudioSinkVolumeLocallyChangedEvent"},
|
||||
{151, nullptr, "AcquireAudioSinkVolumeUpdateRequestCompletedEvent"},
|
||||
{152, nullptr, "GetAudioSinkVolume"},
|
||||
{153, nullptr, "RequestUpdateAudioSinkVolume"},
|
||||
{154, nullptr, "IsAudioSinkVolumeSupported"},
|
||||
{256, nullptr, "IsManufacturingMode"},
|
||||
{257, nullptr, "EmulateBluetoothCrash"},
|
||||
{258, nullptr, "GetBleChannelMap"},
|
||||
};
|
||||
// clang-format on
|
||||
explicit IBluetoothDriver(Core::System& system_) : ServiceFramework{system_, "btdrv"} {}
|
||||
|
||||
RegisterHandlers(functions);
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{0, nullptr, "InitializeBluetoothDriver"},
|
||||
FunctionInfo{1, nullptr, "InitializeBluetooth"},
|
||||
FunctionInfo{2, nullptr, "EnableBluetooth"},
|
||||
FunctionInfo{3, nullptr, "DisableBluetooth"},
|
||||
FunctionInfo{4, nullptr, "FinalizeBluetooth"},
|
||||
FunctionInfo{5, nullptr, "GetAdapterProperties"},
|
||||
FunctionInfo{6, nullptr, "GetAdapterProperty"},
|
||||
FunctionInfo{7, nullptr, "SetAdapterProperty"},
|
||||
FunctionInfo{8, nullptr, "StartInquiry"},
|
||||
FunctionInfo{9, nullptr, "StopInquiry"},
|
||||
FunctionInfo{10, nullptr, "CreateBond"},
|
||||
FunctionInfo{11, nullptr, "RemoveBond"},
|
||||
FunctionInfo{12, nullptr, "CancelBond"},
|
||||
FunctionInfo{13, nullptr, "RespondToPinRequest"},
|
||||
FunctionInfo{14, nullptr, "RespondToSspRequest"},
|
||||
FunctionInfo{15, nullptr, "GetEventInfo"},
|
||||
FunctionInfo{16, nullptr, "InitializeHid"},
|
||||
FunctionInfo{17, nullptr, "OpenHidConnection"},
|
||||
FunctionInfo{18, nullptr, "CloseHidConnection"},
|
||||
FunctionInfo{19, nullptr, "WriteHidData"},
|
||||
FunctionInfo{20, nullptr, "WriteHidData2"},
|
||||
FunctionInfo{21, nullptr, "SetHidReport"},
|
||||
FunctionInfo{22, nullptr, "GetHidReport"},
|
||||
FunctionInfo{23, nullptr, "TriggerConnection"},
|
||||
FunctionInfo{24, nullptr, "AddPairedDeviceInfo"},
|
||||
FunctionInfo{25, nullptr, "GetPairedDeviceInfo"},
|
||||
FunctionInfo{26, nullptr, "FinalizeHid"},
|
||||
FunctionInfo{27, nullptr, "GetHidEventInfo"},
|
||||
FunctionInfo{28, nullptr, "SetTsi"},
|
||||
FunctionInfo{29, nullptr, "EnableBurstMode"},
|
||||
FunctionInfo{30, nullptr, "SetZeroRetransmission"},
|
||||
FunctionInfo{31, nullptr, "EnableMcMode"},
|
||||
FunctionInfo{32, nullptr, "EnableLlrScan"},
|
||||
FunctionInfo{33, nullptr, "DisableLlrScan"},
|
||||
FunctionInfo{34, C<&IBluetoothDriver::EnableRadio>, "EnableRadio"},
|
||||
FunctionInfo{35, nullptr, "SetVisibility"},
|
||||
FunctionInfo{36, nullptr, "EnableTbfcScan"},
|
||||
FunctionInfo{37, nullptr, "RegisterHidReportEvent"},
|
||||
FunctionInfo{38, nullptr, "GetHidReportEventInfo"},
|
||||
FunctionInfo{39, nullptr, "GetLatestPlr"},
|
||||
FunctionInfo{40, nullptr, "GetPendingConnections"},
|
||||
FunctionInfo{41, nullptr, "GetChannelMap"},
|
||||
FunctionInfo{42, nullptr, "EnableTxPowerBoostSetting"},
|
||||
FunctionInfo{43, nullptr, "IsTxPowerBoostSettingEnabled"},
|
||||
FunctionInfo{44, nullptr, "EnableAfhSetting"},
|
||||
FunctionInfo{45, nullptr, "IsAfhSettingEnabled"},
|
||||
FunctionInfo{46, nullptr, "InitializeBle"},
|
||||
FunctionInfo{47, nullptr, "EnableBle"},
|
||||
FunctionInfo{48, nullptr, "DisableBle"},
|
||||
FunctionInfo{49, nullptr, "FinalizeBle"},
|
||||
FunctionInfo{50, nullptr, "SetBleVisibility"},
|
||||
FunctionInfo{51, nullptr, "SetBleConnectionParameter"},
|
||||
FunctionInfo{52, nullptr, "SetBleDefaultConnectionParameter"},
|
||||
FunctionInfo{53, nullptr, "SetBleAdvertiseData"},
|
||||
FunctionInfo{54, nullptr, "SetBleAdvertiseParameter"},
|
||||
FunctionInfo{55, nullptr, "StartBleScan"},
|
||||
FunctionInfo{56, nullptr, "StopBleScan"},
|
||||
FunctionInfo{57, nullptr, "AddBleScanFilterCondition"},
|
||||
FunctionInfo{58, nullptr, "DeleteBleScanFilterCondition"},
|
||||
FunctionInfo{59, nullptr, "DeleteBleScanFilter"},
|
||||
FunctionInfo{60, nullptr, "ClearBleScanFilters"},
|
||||
FunctionInfo{61, nullptr, "EnableBleScanFilter"},
|
||||
FunctionInfo{62, nullptr, "RegisterGattClient"},
|
||||
FunctionInfo{63, nullptr, "UnregisterGattClient"},
|
||||
FunctionInfo{64, nullptr, "UnregisterAllGattClients"},
|
||||
FunctionInfo{65, nullptr, "ConnectGattServer"},
|
||||
FunctionInfo{66, nullptr, "CancelConnectGattServer"},
|
||||
FunctionInfo{67, nullptr, "DisconnectGattServer"},
|
||||
FunctionInfo{68, nullptr, "GetGattAttribute"},
|
||||
FunctionInfo{69, nullptr, "GetGattService"},
|
||||
FunctionInfo{70, nullptr, "ConfigureAttMtu"},
|
||||
FunctionInfo{71, nullptr, "RegisterGattServer"},
|
||||
FunctionInfo{72, nullptr, "UnregisterGattServer"},
|
||||
FunctionInfo{73, nullptr, "ConnectGattClient"},
|
||||
FunctionInfo{74, nullptr, "DisconnectGattClient"},
|
||||
FunctionInfo{75, nullptr, "AddGattService"},
|
||||
FunctionInfo{76, nullptr, "EnableGattService"},
|
||||
FunctionInfo{77, nullptr, "AddGattCharacteristic"},
|
||||
FunctionInfo{78, nullptr, "AddGattDescriptor"},
|
||||
FunctionInfo{79, nullptr, "GetBleManagedEventInfo"},
|
||||
FunctionInfo{80, nullptr, "GetGattFirstCharacteristic"},
|
||||
FunctionInfo{81, nullptr, "GetGattNextCharacteristic"},
|
||||
FunctionInfo{82, nullptr, "GetGattFirstDescriptor"},
|
||||
FunctionInfo{83, nullptr, "GetGattNextDescriptor"},
|
||||
FunctionInfo{84, nullptr, "RegisterGattManagedDataPath"},
|
||||
FunctionInfo{85, nullptr, "UnregisterGattManagedDataPath"},
|
||||
FunctionInfo{86, nullptr, "RegisterGattHidDataPath"},
|
||||
FunctionInfo{87, nullptr, "UnregisterGattHidDataPath"},
|
||||
FunctionInfo{88, nullptr, "RegisterGattDataPath"},
|
||||
FunctionInfo{89, nullptr, "UnregisterGattDataPath"},
|
||||
FunctionInfo{90, nullptr, "ReadGattCharacteristic"},
|
||||
FunctionInfo{91, nullptr, "ReadGattDescriptor"},
|
||||
FunctionInfo{92, nullptr, "WriteGattCharacteristic"},
|
||||
FunctionInfo{93, nullptr, "WriteGattDescriptor"},
|
||||
FunctionInfo{94, nullptr, "RegisterGattNotification"},
|
||||
FunctionInfo{95, nullptr, "UnregisterGattNotification"},
|
||||
FunctionInfo{96, nullptr, "GetLeHidEventInfo"},
|
||||
FunctionInfo{97, nullptr, "RegisterBleHidEvent"},
|
||||
FunctionInfo{98, nullptr, "SetBleScanParameter"},
|
||||
FunctionInfo{99, nullptr, "MoveToSecondaryPiconet"},
|
||||
FunctionInfo{100, nullptr, "IsBluetoothEnabled"},
|
||||
FunctionInfo{128, nullptr, "AcquireAudioEvent"},
|
||||
FunctionInfo{129, nullptr, "GetAudioEventInfo"},
|
||||
FunctionInfo{130, nullptr, "OpenAudioConnection"},
|
||||
FunctionInfo{131, nullptr, "CloseAudioConnection"},
|
||||
FunctionInfo{132, nullptr, "OpenAudioOut"},
|
||||
FunctionInfo{133, nullptr, "CloseAudioOut"},
|
||||
FunctionInfo{134, nullptr, "AcquireAudioOutStateChangedEvent"},
|
||||
FunctionInfo{135, nullptr, "StartAudioOut"},
|
||||
FunctionInfo{136, nullptr, "StopAudioOut"},
|
||||
FunctionInfo{137, nullptr, "GetAudioOutState"},
|
||||
FunctionInfo{138, nullptr, "GetAudioOutFeedingCodec"},
|
||||
FunctionInfo{139, nullptr, "GetAudioOutFeedingParameter"},
|
||||
FunctionInfo{140, nullptr, "AcquireAudioOutBufferAvailableEvent"},
|
||||
FunctionInfo{141, nullptr, "SendAudioData"},
|
||||
FunctionInfo{142, nullptr, "AcquireAudioControlInputStateChangedEvent"},
|
||||
FunctionInfo{143, nullptr, "GetAudioControlInputState"},
|
||||
FunctionInfo{144, nullptr, "AcquireAudioConnectionStateChangedEvent"},
|
||||
FunctionInfo{145, nullptr, "GetConnectedAudioDevice"},
|
||||
FunctionInfo{146, nullptr, "CloseAudioControlInput"},
|
||||
FunctionInfo{147, nullptr, "RegisterAudioControlNotification"},
|
||||
FunctionInfo{148, nullptr, "SendAudioControlPassthroughCommand"},
|
||||
FunctionInfo{149, nullptr, "SendAudioControlSetAbsoluteVolumeCommand"},
|
||||
FunctionInfo{150, nullptr, "AcquireAudioSinkVolumeLocallyChangedEvent"},
|
||||
FunctionInfo{151, nullptr, "AcquireAudioSinkVolumeUpdateRequestCompletedEvent"},
|
||||
FunctionInfo{152, nullptr, "GetAudioSinkVolume"},
|
||||
FunctionInfo{153, nullptr, "RequestUpdateAudioSinkVolume"},
|
||||
FunctionInfo{154, nullptr, "IsAudioSinkVolumeSupported"},
|
||||
FunctionInfo{256, nullptr, "IsManufacturingMode"},
|
||||
FunctionInfo{257, nullptr, "EmulateBluetoothCrash"},
|
||||
FunctionInfo{258, nullptr, "GetBleChannelMap"}
|
||||
);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -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 2018 yuzu Emulator Project
|
||||
@@ -17,100 +17,98 @@ namespace Service::BTM {
|
||||
|
||||
class IBtm final : public ServiceFramework<IBtm> {
|
||||
public:
|
||||
explicit IBtm(Core::System& system_) : ServiceFramework{system_, "btm"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetState"},
|
||||
{1, nullptr, "GetHostDeviceProperty"},
|
||||
{2, nullptr, "AcquireDeviceConditionEvent"},
|
||||
{3, nullptr, "GetDeviceCondition"},
|
||||
{4, nullptr, "SetBurstMode"},
|
||||
{5, nullptr, "SetSlotMode"},
|
||||
{6, nullptr, "SetBluetoothMode"},
|
||||
{7, nullptr, "SetWlanMode"},
|
||||
{8, nullptr, "AcquireDeviceInfoEvent"},
|
||||
{9, nullptr, "GetDeviceInfo"},
|
||||
{10, nullptr, "AddDeviceInfo"},
|
||||
{11, nullptr, "RemoveDeviceInfo"},
|
||||
{12, nullptr, "IncreaseDeviceInfoOrder"},
|
||||
{13, nullptr, "LlrNotify"},
|
||||
{14, nullptr, "EnableRadio"},
|
||||
{15, nullptr, "DisableRadio"},
|
||||
{16, nullptr, "HidDisconnect"},
|
||||
{17, nullptr, "HidSetRetransmissionMode"},
|
||||
{18, nullptr, "AcquireAwakeReqEvent"},
|
||||
{19, nullptr, "AcquireLlrStateEvent"},
|
||||
{20, nullptr, "IsLlrStarted"},
|
||||
{21, nullptr, "EnableSlotSaving"},
|
||||
{22, nullptr, "ProtectDeviceInfo"},
|
||||
{23, nullptr, "AcquireBleScanEvent"},
|
||||
{24, nullptr, "GetBleScanParameterGeneral"},
|
||||
{25, nullptr, "GetBleScanParameterSmartDevice"},
|
||||
{26, nullptr, "StartBleScanForGeneral"},
|
||||
{27, nullptr, "StopBleScanForGeneral"},
|
||||
{28, nullptr, "GetBleScanResultsForGeneral"},
|
||||
{29, nullptr, "StartBleScanForPairedDevice"},
|
||||
{30, nullptr, "StopBleScanForPairedDevice"},
|
||||
{31, nullptr, "StartBleScanForSmartDevice"},
|
||||
{32, nullptr, "StopBleScanForSmartDevice"},
|
||||
{33, nullptr, "GetBleScanResultsForSmartDevice"},
|
||||
{34, nullptr, "AcquireBleConnectionEvent"},
|
||||
{35, nullptr, "BleConnect"},
|
||||
{36, nullptr, "BleOverrideConnection"},
|
||||
{37, nullptr, "BleDisconnect"},
|
||||
{38, nullptr, "BleGetConnectionState"},
|
||||
{39, nullptr, "BleGetGattClientConditionList"},
|
||||
{40, nullptr, "AcquireBlePairingEvent"},
|
||||
{41, nullptr, "BlePairDevice"},
|
||||
{42, nullptr, "BleUnpairDeviceOnBoth"},
|
||||
{43, nullptr, "BleUnpairDevice"},
|
||||
{44, nullptr, "BleGetPairedAddresses"},
|
||||
{45, nullptr, "AcquireBleServiceDiscoveryEvent"},
|
||||
{46, nullptr, "GetGattServices"},
|
||||
{47, nullptr, "GetGattService"},
|
||||
{48, nullptr, "GetGattIncludedServices"},
|
||||
{49, nullptr, "GetBelongingService"},
|
||||
{50, nullptr, "GetGattCharacteristics"},
|
||||
{51, nullptr, "GetGattDescriptors"},
|
||||
{52, nullptr, "AcquireBleMtuConfigEvent"},
|
||||
{53, nullptr, "ConfigureBleMtu"},
|
||||
{54, nullptr, "GetBleMtu"},
|
||||
{55, nullptr, "RegisterBleGattDataPath"},
|
||||
{56, nullptr, "UnregisterBleGattDataPath"},
|
||||
{57, nullptr, "RegisterAppletResourceUserId"},
|
||||
{58, nullptr, "UnregisterAppletResourceUserId"},
|
||||
{59, nullptr, "SetAppletResourceUserId"},
|
||||
{60, nullptr, "AcquireBleConnectionParameterUpdateEvent"}, //8.0.0+
|
||||
{61, nullptr, "SetCeLength"}, //8.0.0+
|
||||
{62, nullptr, "EnsureSlotExpansion"}, //9.0.0+
|
||||
{63, nullptr, "IsSlotExpansionEnsured"}, //9.0.0+
|
||||
{64, nullptr, "CancelConnectionTrigger"}, //10.0.0+
|
||||
{65, nullptr, "GetConnectionCapacity"}, //13.0.0+
|
||||
{66, nullptr, "GetWlanMode"}, //13.0.0+
|
||||
{67, nullptr, "IsSlotSavingEnabled"}, //13.0.0+
|
||||
{68, nullptr, "IsSlotSavingForPairingEnabled"}, //13.0.0+
|
||||
{69, nullptr, "AcquireAudioDeviceConnectionEvent"}, //13.0.0+
|
||||
{70, nullptr, "GetConnectedAudioDevices"}, //13.0.0+
|
||||
{71, nullptr, "SetAudioSourceVolume"}, //13.0.0+
|
||||
{72, nullptr, "GetAudioSourceVolume"}, //13.0.0+
|
||||
{73, nullptr, "RequestAudioDeviceConnectionRejection"}, //13.0.0+
|
||||
{74, nullptr, "CancelAudioDeviceConnectionRejection"}, //13.0.0+
|
||||
{75, nullptr, "GetPairedAudioDevices"}, //13.0.0+
|
||||
{76, nullptr, "SetWlanModeWithOption"}, //13.1.0+
|
||||
{100, nullptr, "AcquireConnectionDisallowedEvent"}, //13.0.0+
|
||||
{101, nullptr, "GetUsecaseViolationFactor"}, //13.0.0+
|
||||
{110, nullptr, "GetShortenedDeviceInfo"}, //13.0.0+
|
||||
{111, nullptr, "AcquirePairingCountUpdateEvent"},//13.0.0+
|
||||
{112, nullptr, "Unknown112"}, //14.0.0-14.1.2
|
||||
{113, nullptr, "Unknown113"}, //14.0.0-14.1.2
|
||||
{114, nullptr, "IsFirstAudioControlConnection"}, //14.0.0+
|
||||
{115, nullptr, "GetShortenedDeviceCondition"}, //14.0.0+
|
||||
{116, nullptr, "SetAudioSinkVolume"}, //15.0.0+
|
||||
{117, nullptr, "GetAudioSinkVolume"}, //15.0.0+
|
||||
};
|
||||
// clang-format on
|
||||
explicit IBtm(Core::System& system_) : ServiceFramework{system_, "btm"} {}
|
||||
|
||||
RegisterHandlers(functions);
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{0, nullptr, "GetState"},
|
||||
FunctionInfo{1, nullptr, "GetHostDeviceProperty"},
|
||||
FunctionInfo{2, nullptr, "AcquireDeviceConditionEvent"},
|
||||
FunctionInfo{3, nullptr, "GetDeviceCondition"},
|
||||
FunctionInfo{4, nullptr, "SetBurstMode"},
|
||||
FunctionInfo{5, nullptr, "SetSlotMode"},
|
||||
FunctionInfo{6, nullptr, "SetBluetoothMode"},
|
||||
FunctionInfo{7, nullptr, "SetWlanMode"},
|
||||
FunctionInfo{8, nullptr, "AcquireDeviceInfoEvent"},
|
||||
FunctionInfo{9, nullptr, "GetDeviceInfo"},
|
||||
FunctionInfo{10, nullptr, "AddDeviceInfo"},
|
||||
FunctionInfo{11, nullptr, "RemoveDeviceInfo"},
|
||||
FunctionInfo{12, nullptr, "IncreaseDeviceInfoOrder"},
|
||||
FunctionInfo{13, nullptr, "LlrNotify"},
|
||||
FunctionInfo{14, nullptr, "EnableRadio"},
|
||||
FunctionInfo{15, nullptr, "DisableRadio"},
|
||||
FunctionInfo{16, nullptr, "HidDisconnect"},
|
||||
FunctionInfo{17, nullptr, "HidSetRetransmissionMode"},
|
||||
FunctionInfo{18, nullptr, "AcquireAwakeReqEvent"},
|
||||
FunctionInfo{19, nullptr, "AcquireLlrStateEvent"},
|
||||
FunctionInfo{20, nullptr, "IsLlrStarted"},
|
||||
FunctionInfo{21, nullptr, "EnableSlotSaving"},
|
||||
FunctionInfo{22, nullptr, "ProtectDeviceInfo"},
|
||||
FunctionInfo{23, nullptr, "AcquireBleScanEvent"},
|
||||
FunctionInfo{24, nullptr, "GetBleScanParameterGeneral"},
|
||||
FunctionInfo{25, nullptr, "GetBleScanParameterSmartDevice"},
|
||||
FunctionInfo{26, nullptr, "StartBleScanForGeneral"},
|
||||
FunctionInfo{27, nullptr, "StopBleScanForGeneral"},
|
||||
FunctionInfo{28, nullptr, "GetBleScanResultsForGeneral"},
|
||||
FunctionInfo{29, nullptr, "StartBleScanForPairedDevice"},
|
||||
FunctionInfo{30, nullptr, "StopBleScanForPairedDevice"},
|
||||
FunctionInfo{31, nullptr, "StartBleScanForSmartDevice"},
|
||||
FunctionInfo{32, nullptr, "StopBleScanForSmartDevice"},
|
||||
FunctionInfo{33, nullptr, "GetBleScanResultsForSmartDevice"},
|
||||
FunctionInfo{34, nullptr, "AcquireBleConnectionEvent"},
|
||||
FunctionInfo{35, nullptr, "BleConnect"},
|
||||
FunctionInfo{36, nullptr, "BleOverrideConnection"},
|
||||
FunctionInfo{37, nullptr, "BleDisconnect"},
|
||||
FunctionInfo{38, nullptr, "BleGetConnectionState"},
|
||||
FunctionInfo{39, nullptr, "BleGetGattClientConditionList"},
|
||||
FunctionInfo{40, nullptr, "AcquireBlePairingEvent"},
|
||||
FunctionInfo{41, nullptr, "BlePairDevice"},
|
||||
FunctionInfo{42, nullptr, "BleUnpairDeviceOnBoth"},
|
||||
FunctionInfo{43, nullptr, "BleUnpairDevice"},
|
||||
FunctionInfo{44, nullptr, "BleGetPairedAddresses"},
|
||||
FunctionInfo{45, nullptr, "AcquireBleServiceDiscoveryEvent"},
|
||||
FunctionInfo{46, nullptr, "GetGattServices"},
|
||||
FunctionInfo{47, nullptr, "GetGattService"},
|
||||
FunctionInfo{48, nullptr, "GetGattIncludedServices"},
|
||||
FunctionInfo{49, nullptr, "GetBelongingService"},
|
||||
FunctionInfo{50, nullptr, "GetGattCharacteristics"},
|
||||
FunctionInfo{51, nullptr, "GetGattDescriptors"},
|
||||
FunctionInfo{52, nullptr, "AcquireBleMtuConfigEvent"},
|
||||
FunctionInfo{53, nullptr, "ConfigureBleMtu"},
|
||||
FunctionInfo{54, nullptr, "GetBleMtu"},
|
||||
FunctionInfo{55, nullptr, "RegisterBleGattDataPath"},
|
||||
FunctionInfo{56, nullptr, "UnregisterBleGattDataPath"},
|
||||
FunctionInfo{57, nullptr, "RegisterAppletResourceUserId"},
|
||||
FunctionInfo{58, nullptr, "UnregisterAppletResourceUserId"},
|
||||
FunctionInfo{59, nullptr, "SetAppletResourceUserId"},
|
||||
FunctionInfo{60, nullptr, "AcquireBleConnectionParameterUpdateEvent"}, //8.0.0+
|
||||
FunctionInfo{61, nullptr, "SetCeLength"}, //8.0.0+
|
||||
FunctionInfo{62, nullptr, "EnsureSlotExpansion"}, //9.0.0+
|
||||
FunctionInfo{63, nullptr, "IsSlotExpansionEnsured"}, //9.0.0+
|
||||
FunctionInfo{64, nullptr, "CancelConnectionTrigger"}, //10.0.0+
|
||||
FunctionInfo{65, nullptr, "GetConnectionCapacity"}, //13.0.0+
|
||||
FunctionInfo{66, nullptr, "GetWlanMode"}, //13.0.0+
|
||||
FunctionInfo{67, nullptr, "IsSlotSavingEnabled"}, //13.0.0+
|
||||
FunctionInfo{68, nullptr, "IsSlotSavingForPairingEnabled"}, //13.0.0+
|
||||
FunctionInfo{69, nullptr, "AcquireAudioDeviceConnectionEvent"}, //13.0.0+
|
||||
FunctionInfo{70, nullptr, "GetConnectedAudioDevices"}, //13.0.0+
|
||||
FunctionInfo{71, nullptr, "SetAudioSourceVolume"}, //13.0.0+
|
||||
FunctionInfo{72, nullptr, "GetAudioSourceVolume"}, //13.0.0+
|
||||
FunctionInfo{73, nullptr, "RequestAudioDeviceConnectionRejection"}, //13.0.0+
|
||||
FunctionInfo{74, nullptr, "CancelAudioDeviceConnectionRejection"}, //13.0.0+
|
||||
FunctionInfo{75, nullptr, "GetPairedAudioDevices"}, //13.0.0+
|
||||
FunctionInfo{76, nullptr, "SetWlanModeWithOption"}, //13.1.0+
|
||||
FunctionInfo{100, nullptr, "AcquireConnectionDisallowedEvent"}, //13.0.0+
|
||||
FunctionInfo{101, nullptr, "GetUsecaseViolationFactor"}, //13.0.0+
|
||||
FunctionInfo{110, nullptr, "GetShortenedDeviceInfo"}, //13.0.0+
|
||||
FunctionInfo{111, nullptr, "AcquirePairingCountUpdateEvent"},//13.0.0+
|
||||
FunctionInfo{112, nullptr, "Unknown112"}, //14.0.0-14.1.2
|
||||
FunctionInfo{113, nullptr, "Unknown113"}, //14.0.0-14.1.2
|
||||
FunctionInfo{114, nullptr, "IsFirstAudioControlConnection"}, //14.0.0+
|
||||
FunctionInfo{115, nullptr, "GetShortenedDeviceCondition"}, //14.0.0+
|
||||
FunctionInfo{116, nullptr, "SetAudioSinkVolume"}, //15.0.0+
|
||||
FunctionInfo{117, nullptr, "GetAudioSinkVolume"} //15.0.0+
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -20,15 +20,14 @@ namespace Service::Capture {
|
||||
|
||||
class IDecoderControlService final : public ServiceFramework<IDecoderControlService> {
|
||||
public:
|
||||
explicit IDecoderControlService(Core::System& system_) : ServiceFramework{system_, "grc:d"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{3001, nullptr, "DecodeJpeg"},
|
||||
{4001, nullptr, "ShrinkJpeg"},
|
||||
{4002, nullptr, "ShrinkJpegEx"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
explicit IDecoderControlService(Core::System& system_) : ServiceFramework{system_, "grc:d"} {}
|
||||
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{3001, nullptr, "DecodeJpeg"},
|
||||
FunctionInfo{4001, nullptr, "ShrinkJpeg"},
|
||||
FunctionInfo{4002, nullptr, "ShrinkJpegEx"}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -17,30 +17,28 @@ namespace Service::ERPT {
|
||||
|
||||
class ErrorReportContext final : public ServiceFramework<ErrorReportContext> {
|
||||
public:
|
||||
explicit ErrorReportContext(Core::System& system_) : ServiceFramework{system_, "erpt:c"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, C<&ErrorReportContext::SubmitContext>, "SubmitContext"},
|
||||
{1, C<&ErrorReportContext::CreateReportV0>, "CreateReportV0"},
|
||||
{2, nullptr, "SetInitialLaunchSettingsCompletionTime"},
|
||||
{3, nullptr, "ClearInitialLaunchSettingsCompletionTime"},
|
||||
{4, nullptr, "UpdatePowerOnTime"},
|
||||
{5, D<&ErrorReportContext::UpdateAwakeTime>, "UpdateAwakeTime"},
|
||||
{6, nullptr, "SubmitMultipleCategoryContext"},
|
||||
{7, nullptr, "UpdateApplicationLaunchTime"},
|
||||
{8, nullptr, "ClearApplicationLaunchTime"},
|
||||
{9, nullptr, "SubmitAttachment"},
|
||||
{10, nullptr, "CreateReportWithAttachments"},
|
||||
{11, C<&ErrorReportContext::CreateReportV1>, "CreateReportV1"},
|
||||
{12, C<&ErrorReportContext::CreateReport>, "CreateReport"},
|
||||
{20, nullptr, "RegisterRunningApplet"},
|
||||
{21, nullptr, "UnregisterRunningApplet"},
|
||||
{22, nullptr, "UpdateAppletSuspendedDuration"},
|
||||
{30, nullptr, "InvalidateForcedShutdownDetection"},
|
||||
};
|
||||
// clang-format on
|
||||
explicit ErrorReportContext(Core::System& system_) : ServiceFramework{system_, "erpt:c"} {}
|
||||
|
||||
RegisterHandlers(functions);
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{0, C<&ErrorReportContext::SubmitContext>, "SubmitContext"},
|
||||
FunctionInfo{1, C<&ErrorReportContext::CreateReportV0>, "CreateReportV0"},
|
||||
FunctionInfo{2, nullptr, "SetInitialLaunchSettingsCompletionTime"},
|
||||
FunctionInfo{3, nullptr, "ClearInitialLaunchSettingsCompletionTime"},
|
||||
FunctionInfo{4, nullptr, "UpdatePowerOnTime"},
|
||||
FunctionInfo{5, D<&ErrorReportContext::UpdateAwakeTime>, "UpdateAwakeTime"},
|
||||
FunctionInfo{6, nullptr, "SubmitMultipleCategoryContext"},
|
||||
FunctionInfo{7, nullptr, "UpdateApplicationLaunchTime"},
|
||||
FunctionInfo{8, nullptr, "ClearApplicationLaunchTime"},
|
||||
FunctionInfo{9, nullptr, "SubmitAttachment"},
|
||||
FunctionInfo{10, nullptr, "CreateReportWithAttachments"},
|
||||
FunctionInfo{11, C<&ErrorReportContext::CreateReportV1>, "CreateReportV1"},
|
||||
FunctionInfo{12, C<&ErrorReportContext::CreateReport>, "CreateReport"},
|
||||
FunctionInfo{20, nullptr, "RegisterRunningApplet"},
|
||||
FunctionInfo{21, nullptr, "UnregisterRunningApplet"},
|
||||
FunctionInfo{22, nullptr, "UpdateAppletSuspendedDuration"},
|
||||
FunctionInfo{30, nullptr, "InvalidateForcedShutdownDetection"}
|
||||
);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -89,16 +87,14 @@ private:
|
||||
|
||||
class ErrorReportSession final : public ServiceFramework<ErrorReportSession> {
|
||||
public:
|
||||
explicit ErrorReportSession(Core::System& system_) : ServiceFramework{system_, "erpt:r"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "OpenReport"},
|
||||
{1, nullptr, "OpenManager"},
|
||||
{2, nullptr, "OpenAttachment"},
|
||||
};
|
||||
// clang-format on
|
||||
explicit ErrorReportSession(Core::System& system_) : ServiceFramework{system_, "erpt:r"} {}
|
||||
|
||||
RegisterHandlers(functions);
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{0, nullptr, "OpenReport"},
|
||||
FunctionInfo{1, nullptr, "OpenManager"},
|
||||
FunctionInfo{2, nullptr, "OpenAttachment"}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+168
-171
@@ -19,110 +19,109 @@ constexpr Result ERROR_INVALID_RIGHTS_ID{ErrorModule::ETicket, 3};
|
||||
class ETicket final : public ServiceFramework<ETicket> {
|
||||
public:
|
||||
explicit ETicket(Core::System& system_) : ServiceFramework{system_, "es"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{1, &ETicket::ImportTicket, "ImportTicket"},
|
||||
{2, nullptr, "ImportTicketCertificateSet"},
|
||||
{3, nullptr, "DeleteTicket"},
|
||||
{4, nullptr, "DeletePersonalizedTicket"},
|
||||
{5, nullptr, "DeleteAllCommonTicket"},
|
||||
{6, nullptr, "DeleteAllPersonalizedTicket"},
|
||||
{7, nullptr, "DeleteAllPersonalizedTicketEx"},
|
||||
{8, &ETicket::GetTitleKey, "GetTitleKey"},
|
||||
{9, &ETicket::CountCommonTicket, "CountCommonTicket"},
|
||||
{10, &ETicket::CountPersonalizedTicket, "CountPersonalizedTicket"},
|
||||
{11, &ETicket::ListCommonTicketRightsIds, "ListCommonTicketRightsIds"},
|
||||
{12, &ETicket::ListPersonalizedTicketRightsIds, "ListPersonalizedTicketRightsIds"},
|
||||
{13, nullptr, "ListMissingPersonalizedTicket"},
|
||||
{14, &ETicket::GetCommonTicketSize, "GetCommonTicketSize"},
|
||||
{15, &ETicket::GetPersonalizedTicketSize, "GetPersonalizedTicketSize"},
|
||||
{16, &ETicket::GetCommonTicketData, "GetCommonTicketData"},
|
||||
{17, &ETicket::GetPersonalizedTicketData, "GetPersonalizedTicketData"},
|
||||
{18, nullptr, "OwnTicket"},
|
||||
{19, nullptr, "GetTicketInfo"},
|
||||
{20, nullptr, "ListLightTicketInfo"},
|
||||
{21, nullptr, "SignData"},
|
||||
{22, nullptr, "GetCommonTicketAndCertificateSize"},
|
||||
{23, nullptr, "GetCommonTicketAndCertificateData"},
|
||||
{24, nullptr, "ImportPrepurchaseRecord"},
|
||||
{25, nullptr, "DeletePrepurchaseRecord"},
|
||||
{26, nullptr, "DeleteAllPrepurchaseRecord"},
|
||||
{27, nullptr, "CountPrepurchaseRecord"},
|
||||
{28, nullptr, "ListPrepurchaseRecordRightsIds"},
|
||||
{29, nullptr, "ListPrepurchaseRecordInfo"},
|
||||
{30, nullptr, "CountTicket"},
|
||||
{31, nullptr, "ListTicketRightsIds"},
|
||||
{32, nullptr, "CountPrepurchaseRecordEx"},
|
||||
{33, nullptr, "ListPrepurchaseRecordRightsIdsEx"},
|
||||
{34, nullptr, "GetEncryptedTicketSize"},
|
||||
{35, nullptr, "GetEncryptedTicketData"},
|
||||
{36, nullptr, "DeleteAllInactiveELicenseRequiredPersonalizedTicket"},
|
||||
{37, nullptr, "OwnTicket2"},
|
||||
{38, nullptr, "OwnTicket3"},
|
||||
{39, nullptr, "DeleteAllInactivePersonalizedTicket"},
|
||||
{40, nullptr, "DeletePrepurchaseRecordByNintendoAccountId"},
|
||||
{101, nullptr, "Unknown101"}, //18.0.0+
|
||||
{102, nullptr, "Unknown102"}, //18.0.0+
|
||||
{103, nullptr, "Unknown103"}, //18.0.0+
|
||||
{104, nullptr, "Unknown104"}, //18.0.0+
|
||||
{105, nullptr, "Unknown105"}, //20.0.0+
|
||||
{201, nullptr, "Unknown201"}, //18.0.0+
|
||||
{202, nullptr, "Unknown202"}, //18.0.0+
|
||||
{203, nullptr, "Unknown203"}, //18.0.0+
|
||||
{204, nullptr, "Unknown204"}, //18.0.0+
|
||||
{205, nullptr, "Unknown205"}, //18.0.0+
|
||||
{501, nullptr, "Unknown501"},
|
||||
{502, nullptr, "Unknown502"},
|
||||
{503, nullptr, "GetTitleKey"},
|
||||
{504, nullptr, "Unknown504"},
|
||||
{508, nullptr, "Unknown508"},
|
||||
{509, nullptr, "Unknown509"},
|
||||
{510, nullptr, "Unknown510"},
|
||||
{511, nullptr, "Unknown511"},
|
||||
{1001, nullptr, "Unknown1001"},
|
||||
{1002, nullptr, "Unknown1001"},
|
||||
{1003, nullptr, "Unknown1003"},
|
||||
{1004, nullptr, "Unknown1004"},
|
||||
{1005, nullptr, "Unknown1005"},
|
||||
{1006, nullptr, "Unknown1006"},
|
||||
{1007, nullptr, "Unknown1007"},
|
||||
{1009, nullptr, "Unknown1009"},
|
||||
{1010, nullptr, "Unknown1010"},
|
||||
{1011, nullptr, "Unknown1011"},
|
||||
{1012, nullptr, "Unknown1012"},
|
||||
{1013, nullptr, "Unknown1013"},
|
||||
{1014, nullptr, "Unknown1014"},
|
||||
{1015, nullptr, "Unknown1015"},
|
||||
{1016, nullptr, "Unknown1016"},
|
||||
{1017, nullptr, "Unknown1017"},
|
||||
{1018, nullptr, "Unknown1018"},
|
||||
{1019, nullptr, "Unknown1019"},
|
||||
{1020, nullptr, "Unknown1020"},
|
||||
{1021, nullptr, "Unknown1021"},
|
||||
{1501, nullptr, "Unknown1501"},
|
||||
{1502, nullptr, "Unknown1502"},
|
||||
{1503, nullptr, "Unknown1503"},
|
||||
{1504, nullptr, "Unknown1504"},
|
||||
{1505, nullptr, "Unknown1505"},
|
||||
{1506, nullptr, "Unknown1506"},
|
||||
{2000, nullptr, "Unknown2000"},
|
||||
{2001, nullptr, "Unknown2001"},
|
||||
{2002, nullptr, "Unknown2002"},
|
||||
{2003, nullptr, "Unknown2003"},
|
||||
{2100, nullptr, "Unknown2100"},
|
||||
{2501, nullptr, "Unknown2501"},
|
||||
{2502, nullptr, "Unknown2502"},
|
||||
{2601, nullptr, "Unknown2601"},
|
||||
{3001, nullptr, "Unknown3001"},
|
||||
{3002, nullptr, "Unknown3002"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
|
||||
keys.PopulateTickets();
|
||||
keys.SynthesizeTickets();
|
||||
}
|
||||
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{1, &ETicket::ImportTicket, "ImportTicket"},
|
||||
FunctionInfo{2, nullptr, "ImportTicketCertificateSet"},
|
||||
FunctionInfo{3, nullptr, "DeleteTicket"},
|
||||
FunctionInfo{4, nullptr, "DeletePersonalizedTicket"},
|
||||
FunctionInfo{5, nullptr, "DeleteAllCommonTicket"},
|
||||
FunctionInfo{6, nullptr, "DeleteAllPersonalizedTicket"},
|
||||
FunctionInfo{7, nullptr, "DeleteAllPersonalizedTicketEx"},
|
||||
FunctionInfo{8, &ETicket::GetTitleKey, "GetTitleKey"},
|
||||
FunctionInfo{9, &ETicket::CountCommonTicket, "CountCommonTicket"},
|
||||
FunctionInfo{10, &ETicket::CountPersonalizedTicket, "CountPersonalizedTicket"},
|
||||
FunctionInfo{11, &ETicket::ListCommonTicketRightsIds, "ListCommonTicketRightsIds"},
|
||||
FunctionInfo{12, &ETicket::ListPersonalizedTicketRightsIds, "ListPersonalizedTicketRightsIds"},
|
||||
FunctionInfo{13, nullptr, "ListMissingPersonalizedTicket"},
|
||||
FunctionInfo{14, &ETicket::GetCommonTicketSize, "GetCommonTicketSize"},
|
||||
FunctionInfo{15, &ETicket::GetPersonalizedTicketSize, "GetPersonalizedTicketSize"},
|
||||
FunctionInfo{16, &ETicket::GetCommonTicketData, "GetCommonTicketData"},
|
||||
FunctionInfo{17, &ETicket::GetPersonalizedTicketData, "GetPersonalizedTicketData"},
|
||||
FunctionInfo{18, nullptr, "OwnTicket"},
|
||||
FunctionInfo{19, nullptr, "GetTicketInfo"},
|
||||
FunctionInfo{20, nullptr, "ListLightTicketInfo"},
|
||||
FunctionInfo{21, nullptr, "SignData"},
|
||||
FunctionInfo{22, nullptr, "GetCommonTicketAndCertificateSize"},
|
||||
FunctionInfo{23, nullptr, "GetCommonTicketAndCertificateData"},
|
||||
FunctionInfo{24, nullptr, "ImportPrepurchaseRecord"},
|
||||
FunctionInfo{25, nullptr, "DeletePrepurchaseRecord"},
|
||||
FunctionInfo{26, nullptr, "DeleteAllPrepurchaseRecord"},
|
||||
FunctionInfo{27, nullptr, "CountPrepurchaseRecord"},
|
||||
FunctionInfo{28, nullptr, "ListPrepurchaseRecordRightsIds"},
|
||||
FunctionInfo{29, nullptr, "ListPrepurchaseRecordInfo"},
|
||||
FunctionInfo{30, nullptr, "CountTicket"},
|
||||
FunctionInfo{31, nullptr, "ListTicketRightsIds"},
|
||||
FunctionInfo{32, nullptr, "CountPrepurchaseRecordEx"},
|
||||
FunctionInfo{33, nullptr, "ListPrepurchaseRecordRightsIdsEx"},
|
||||
FunctionInfo{34, nullptr, "GetEncryptedTicketSize"},
|
||||
FunctionInfo{35, nullptr, "GetEncryptedTicketData"},
|
||||
FunctionInfo{36, nullptr, "DeleteAllInactiveELicenseRequiredPersonalizedTicket"},
|
||||
FunctionInfo{37, nullptr, "OwnTicket2"},
|
||||
FunctionInfo{38, nullptr, "OwnTicket3"},
|
||||
FunctionInfo{39, nullptr, "DeleteAllInactivePersonalizedTicket"},
|
||||
FunctionInfo{40, nullptr, "DeletePrepurchaseRecordByNintendoAccountId"},
|
||||
FunctionInfo{101, nullptr, "Unknown101"}, //18.0.0+
|
||||
FunctionInfo{102, nullptr, "Unknown102"}, //18.0.0+
|
||||
FunctionInfo{103, nullptr, "Unknown103"}, //18.0.0+
|
||||
FunctionInfo{104, nullptr, "Unknown104"}, //18.0.0+
|
||||
FunctionInfo{105, nullptr, "Unknown105"}, //20.0.0+
|
||||
FunctionInfo{201, nullptr, "Unknown201"}, //18.0.0+
|
||||
FunctionInfo{202, nullptr, "Unknown202"}, //18.0.0+
|
||||
FunctionInfo{203, nullptr, "Unknown203"}, //18.0.0+
|
||||
FunctionInfo{204, nullptr, "Unknown204"}, //18.0.0+
|
||||
FunctionInfo{205, nullptr, "Unknown205"}, //18.0.0+
|
||||
FunctionInfo{501, nullptr, "Unknown501"},
|
||||
FunctionInfo{502, nullptr, "Unknown502"},
|
||||
FunctionInfo{503, nullptr, "GetTitleKey"},
|
||||
FunctionInfo{504, nullptr, "Unknown504"},
|
||||
FunctionInfo{508, nullptr, "Unknown508"},
|
||||
FunctionInfo{509, nullptr, "Unknown509"},
|
||||
FunctionInfo{510, nullptr, "Unknown510"},
|
||||
FunctionInfo{511, nullptr, "Unknown511"},
|
||||
FunctionInfo{1001, nullptr, "Unknown1001"},
|
||||
FunctionInfo{1002, nullptr, "Unknown1001"},
|
||||
FunctionInfo{1003, nullptr, "Unknown1003"},
|
||||
FunctionInfo{1004, nullptr, "Unknown1004"},
|
||||
FunctionInfo{1005, nullptr, "Unknown1005"},
|
||||
FunctionInfo{1006, nullptr, "Unknown1006"},
|
||||
FunctionInfo{1007, nullptr, "Unknown1007"},
|
||||
FunctionInfo{1009, nullptr, "Unknown1009"},
|
||||
FunctionInfo{1010, nullptr, "Unknown1010"},
|
||||
FunctionInfo{1011, nullptr, "Unknown1011"},
|
||||
FunctionInfo{1012, nullptr, "Unknown1012"},
|
||||
FunctionInfo{1013, nullptr, "Unknown1013"},
|
||||
FunctionInfo{1014, nullptr, "Unknown1014"},
|
||||
FunctionInfo{1015, nullptr, "Unknown1015"},
|
||||
FunctionInfo{1016, nullptr, "Unknown1016"},
|
||||
FunctionInfo{1017, nullptr, "Unknown1017"},
|
||||
FunctionInfo{1018, nullptr, "Unknown1018"},
|
||||
FunctionInfo{1019, nullptr, "Unknown1019"},
|
||||
FunctionInfo{1020, nullptr, "Unknown1020"},
|
||||
FunctionInfo{1021, nullptr, "Unknown1021"},
|
||||
FunctionInfo{1501, nullptr, "Unknown1501"},
|
||||
FunctionInfo{1502, nullptr, "Unknown1502"},
|
||||
FunctionInfo{1503, nullptr, "Unknown1503"},
|
||||
FunctionInfo{1504, nullptr, "Unknown1504"},
|
||||
FunctionInfo{1505, nullptr, "Unknown1505"},
|
||||
FunctionInfo{1506, nullptr, "Unknown1506"},
|
||||
FunctionInfo{2000, nullptr, "Unknown2000"},
|
||||
FunctionInfo{2001, nullptr, "Unknown2001"},
|
||||
FunctionInfo{2002, nullptr, "Unknown2002"},
|
||||
FunctionInfo{2003, nullptr, "Unknown2003"},
|
||||
FunctionInfo{2100, nullptr, "Unknown2100"},
|
||||
FunctionInfo{2501, nullptr, "Unknown2501"},
|
||||
FunctionInfo{2502, nullptr, "Unknown2502"},
|
||||
FunctionInfo{2601, nullptr, "Unknown2601"},
|
||||
FunctionInfo{3001, nullptr, "Unknown3001"},
|
||||
FunctionInfo{3002, nullptr, "Unknown3002"}
|
||||
);
|
||||
}
|
||||
|
||||
private:
|
||||
bool CheckRightsId(HLERequestContext& ctx, const u128& rights_id) {
|
||||
if (rights_id == u128{}) {
|
||||
@@ -323,83 +322,81 @@ private:
|
||||
class NDRM_LU final : public ServiceFramework<NDRM_LU> {
|
||||
public:
|
||||
explicit NDRM_LU(Core::System& system_)
|
||||
: ServiceFramework{system_, "ndrm:lu"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{1, nullptr, "Cmd1"},
|
||||
{2, nullptr, "Cmd2"},
|
||||
{3, nullptr, "Cmd3"},
|
||||
{1000, nullptr, "Cmd1000"},
|
||||
{8000, nullptr, "Cmd8000"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
: ServiceFramework{system_, "ndrm:lu"} {}
|
||||
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{1, nullptr, "Cmd1"},
|
||||
FunctionInfo{2, nullptr, "Cmd2"},
|
||||
FunctionInfo{3, nullptr, "Cmd3"},
|
||||
FunctionInfo{1000, nullptr, "Cmd1000"},
|
||||
FunctionInfo{8000, nullptr, "Cmd8000"}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
class NDRM_LA final : public ServiceFramework<NDRM_LA> {
|
||||
public:
|
||||
explicit NDRM_LA(Core::System& system_)
|
||||
: ServiceFramework{system_, "ndrm:la"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{1, nullptr, "Cmd1"},
|
||||
{2, nullptr, "Cmd2"},
|
||||
{3, nullptr, "Cmd3"},
|
||||
{4, nullptr, "Cmd4"},
|
||||
{5, nullptr, "Cmd5"},
|
||||
{6, nullptr, "Cmd6"},
|
||||
{7, nullptr, "Cmd7"},
|
||||
{8, nullptr, "Cmd8"},
|
||||
{9, nullptr, "Cmd9"},
|
||||
{10, nullptr, "Cmd10"},
|
||||
{11, nullptr, "Cmd11"},
|
||||
{12, nullptr, "Cmd12"},
|
||||
{13, nullptr, "Cmd13"},
|
||||
{14, nullptr, "Cmd14"},
|
||||
{15, nullptr, "Cmd15"},
|
||||
{16, nullptr, "Cmd16"},
|
||||
{17, nullptr, "Cmd17"},
|
||||
{18, nullptr, "Cmd18"},
|
||||
{19, nullptr, "Cmd19"},
|
||||
{20, nullptr, "Cmd20"},
|
||||
{21, nullptr, "Cmd21"},
|
||||
{22, nullptr, "Cmd22"},
|
||||
{23, nullptr, "Cmd23"},
|
||||
{24, nullptr, "Cmd24"},
|
||||
{25, nullptr, "Cmd25"},
|
||||
{26, nullptr, "Cmd26"},
|
||||
{27, nullptr, "Cmd27"},
|
||||
{28, nullptr, "Cmd28"},
|
||||
{29, nullptr, "Cmd29"},
|
||||
{30, nullptr, "Cmd30"},
|
||||
{31, nullptr, "Cmd31"},
|
||||
{32, nullptr, "Cmd32"},
|
||||
{33, nullptr, "Cmd33"},
|
||||
{34, nullptr, "Cmd34"},
|
||||
{35, nullptr, "Cmd35"},
|
||||
{36, nullptr, "Cmd36"},
|
||||
{37, nullptr, "Cmd37"},
|
||||
{38, nullptr, "Cmd38"},
|
||||
{39, nullptr, "Cmd39"},
|
||||
{40, nullptr, "Cmd40"},
|
||||
{42, nullptr, "Cmd42"},
|
||||
{43, nullptr, "Cmd43"},
|
||||
{44, nullptr, "Cmd44"},
|
||||
{45, nullptr, "Cmd45"},
|
||||
{46, nullptr, "Cmd46"},
|
||||
{47, nullptr, "Cmd47"},
|
||||
{48, nullptr, "Cmd48"},
|
||||
{49, nullptr, "Cmd49"},
|
||||
{50, nullptr, "Cmd50"},
|
||||
{51, nullptr, "Cmd51"},
|
||||
{8000, nullptr, "Cmd8000"},
|
||||
{8001, nullptr, "Cmd8001"},
|
||||
{8002, nullptr, "Cmd8002"},
|
||||
{8003, nullptr, "Cmd8003"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
: ServiceFramework{system_, "ndrm:la"} {}
|
||||
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{1, nullptr, "Cmd1"},
|
||||
FunctionInfo{2, nullptr, "Cmd2"},
|
||||
FunctionInfo{3, nullptr, "Cmd3"},
|
||||
FunctionInfo{4, nullptr, "Cmd4"},
|
||||
FunctionInfo{5, nullptr, "Cmd5"},
|
||||
FunctionInfo{6, nullptr, "Cmd6"},
|
||||
FunctionInfo{7, nullptr, "Cmd7"},
|
||||
FunctionInfo{8, nullptr, "Cmd8"},
|
||||
FunctionInfo{9, nullptr, "Cmd9"},
|
||||
FunctionInfo{10, nullptr, "Cmd10"},
|
||||
FunctionInfo{11, nullptr, "Cmd11"},
|
||||
FunctionInfo{12, nullptr, "Cmd12"},
|
||||
FunctionInfo{13, nullptr, "Cmd13"},
|
||||
FunctionInfo{14, nullptr, "Cmd14"},
|
||||
FunctionInfo{15, nullptr, "Cmd15"},
|
||||
FunctionInfo{16, nullptr, "Cmd16"},
|
||||
FunctionInfo{17, nullptr, "Cmd17"},
|
||||
FunctionInfo{18, nullptr, "Cmd18"},
|
||||
FunctionInfo{19, nullptr, "Cmd19"},
|
||||
FunctionInfo{20, nullptr, "Cmd20"},
|
||||
FunctionInfo{21, nullptr, "Cmd21"},
|
||||
FunctionInfo{22, nullptr, "Cmd22"},
|
||||
FunctionInfo{23, nullptr, "Cmd23"},
|
||||
FunctionInfo{24, nullptr, "Cmd24"},
|
||||
FunctionInfo{25, nullptr, "Cmd25"},
|
||||
FunctionInfo{26, nullptr, "Cmd26"},
|
||||
FunctionInfo{27, nullptr, "Cmd27"},
|
||||
FunctionInfo{28, nullptr, "Cmd28"},
|
||||
FunctionInfo{29, nullptr, "Cmd29"},
|
||||
FunctionInfo{30, nullptr, "Cmd30"},
|
||||
FunctionInfo{31, nullptr, "Cmd31"},
|
||||
FunctionInfo{32, nullptr, "Cmd32"},
|
||||
FunctionInfo{33, nullptr, "Cmd33"},
|
||||
FunctionInfo{34, nullptr, "Cmd34"},
|
||||
FunctionInfo{35, nullptr, "Cmd35"},
|
||||
FunctionInfo{36, nullptr, "Cmd36"},
|
||||
FunctionInfo{37, nullptr, "Cmd37"},
|
||||
FunctionInfo{38, nullptr, "Cmd38"},
|
||||
FunctionInfo{39, nullptr, "Cmd39"},
|
||||
FunctionInfo{40, nullptr, "Cmd40"},
|
||||
FunctionInfo{42, nullptr, "Cmd42"},
|
||||
FunctionInfo{43, nullptr, "Cmd43"},
|
||||
FunctionInfo{44, nullptr, "Cmd44"},
|
||||
FunctionInfo{45, nullptr, "Cmd45"},
|
||||
FunctionInfo{46, nullptr, "Cmd46"},
|
||||
FunctionInfo{47, nullptr, "Cmd47"},
|
||||
FunctionInfo{48, nullptr, "Cmd48"},
|
||||
FunctionInfo{49, nullptr, "Cmd49"},
|
||||
FunctionInfo{50, nullptr, "Cmd50"},
|
||||
FunctionInfo{51, nullptr, "Cmd51"},
|
||||
FunctionInfo{8000, nullptr, "Cmd8000"},
|
||||
FunctionInfo{8001, nullptr, "Cmd8001"},
|
||||
FunctionInfo{8002, nullptr, "Cmd8002"},
|
||||
FunctionInfo{8003, nullptr, "Cmd8003"}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// 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
|
||||
|
||||
@@ -11,36 +14,32 @@ namespace Service::EUPLD {
|
||||
|
||||
class ErrorUploadContext final : public ServiceFramework<ErrorUploadContext> {
|
||||
public:
|
||||
explicit ErrorUploadContext(Core::System& system_) : ServiceFramework{system_, "eupld:c"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "SetUrl"},
|
||||
{1, nullptr, "ImportCrt"},
|
||||
{2, nullptr, "ImportPki"},
|
||||
{3, nullptr, "SetAutoUpload"},
|
||||
{4, nullptr, "GetAutoUpload"},
|
||||
};
|
||||
// clang-format on
|
||||
explicit ErrorUploadContext(Core::System& system_) : ServiceFramework{system_, "eupld:c"} {}
|
||||
|
||||
RegisterHandlers(functions);
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{0, nullptr, "SetUrl"},
|
||||
FunctionInfo{1, nullptr, "ImportCrt"},
|
||||
FunctionInfo{2, nullptr, "ImportPki"},
|
||||
FunctionInfo{3, nullptr, "SetAutoUpload"},
|
||||
FunctionInfo{4, nullptr, "GetAutoUpload"}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
class ErrorUploadRequest final : public ServiceFramework<ErrorUploadRequest> {
|
||||
public:
|
||||
explicit ErrorUploadRequest(Core::System& system_) : ServiceFramework{system_, "eupld:r"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "Initialize"},
|
||||
{1, nullptr, "UploadAll"},
|
||||
{2, nullptr, "UploadSelected"},
|
||||
{3, nullptr, "GetUploadStatus"},
|
||||
{4, nullptr, "CancelUpload"},
|
||||
{5, nullptr, "GetResult"},
|
||||
};
|
||||
// clang-format on
|
||||
explicit ErrorUploadRequest(Core::System& system_) : ServiceFramework{system_, "eupld:r"} {}
|
||||
|
||||
RegisterHandlers(functions);
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{0, nullptr, "Initialize"},
|
||||
FunctionInfo{1, nullptr, "UploadAll"},
|
||||
FunctionInfo{2, nullptr, "UploadSelected"},
|
||||
FunctionInfo{3, nullptr, "GetUploadStatus"},
|
||||
FunctionInfo{4, nullptr, "CancelUpload"},
|
||||
FunctionInfo{5, nullptr, "GetResult"}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -16,30 +16,26 @@ namespace Service::FGM {
|
||||
|
||||
class IRequest final : public ServiceFramework<IRequest> {
|
||||
public:
|
||||
explicit IRequest(Core::System& system_) : ServiceFramework{system_, "IRequest"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "Initialize"},
|
||||
{1, nullptr, "Set"},
|
||||
{2, nullptr, "Get"},
|
||||
{3, nullptr, "Cancel"},
|
||||
};
|
||||
// clang-format on
|
||||
explicit IRequest(Core::System& system_) : ServiceFramework{system_, "IRequest"} {}
|
||||
|
||||
RegisterHandlers(functions);
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{0, nullptr, "Initialize"},
|
||||
FunctionInfo{1, nullptr, "Set"},
|
||||
FunctionInfo{2, nullptr, "Get"},
|
||||
FunctionInfo{3, nullptr, "Cancel"}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
class FGM final : public ServiceFramework<FGM> {
|
||||
public:
|
||||
explicit FGM(Core::System& system_, const char* name) : ServiceFramework{system_, name} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &FGM::Initialize, "Initialize"},
|
||||
};
|
||||
// clang-format on
|
||||
explicit FGM(Core::System& system_, const char* name) : ServiceFramework{system_, name} {}
|
||||
|
||||
RegisterHandlers(functions);
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{0, &FGM::Initialize, "Initialize"}
|
||||
);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -54,16 +50,14 @@ private:
|
||||
|
||||
class FGM_DBG final : public ServiceFramework<FGM_DBG> {
|
||||
public:
|
||||
explicit FGM_DBG(Core::System& system_) : ServiceFramework{system_, "fgm:dbg"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "Initialize"},
|
||||
{1, nullptr, "Read"},
|
||||
{2, nullptr, "Cancel"},
|
||||
};
|
||||
// clang-format on
|
||||
explicit FGM_DBG(Core::System& system_) : ServiceFramework{system_, "fgm:dbg"} {}
|
||||
|
||||
RegisterHandlers(functions);
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{0, nullptr, "Initialize"},
|
||||
FunctionInfo{1, nullptr, "Read"},
|
||||
FunctionInfo{2, nullptr, "Cancel"}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -154,6 +154,9 @@ FSP_SRV::FSP_SRV(Core::System& system_)
|
||||
{720, nullptr, "AbandonAccessFailure"},
|
||||
{800, nullptr, "GetAndClearFileSystemProxyErrorInfo"},
|
||||
{810, nullptr, "RegisterProgramIndexMapInfo"},
|
||||
{820, nullptr, "GetContentStorageInfoIndex"},
|
||||
{830, nullptr, "EncryptStreamPlaySaveData"},
|
||||
{831, nullptr, "DecryptStreamPlaySaveData"},
|
||||
{1000, nullptr, "SetBisRootForHost"},
|
||||
{1001, nullptr, "SetSaveDataSize"},
|
||||
{1002, nullptr, "SetSaveDataRootPath"},
|
||||
|
||||
@@ -22,128 +22,126 @@ class IFriendService final : public ServiceFramework<IFriendService> {
|
||||
public:
|
||||
explicit IFriendService(Core::System& system_)
|
||||
: ServiceFramework{system_, "IFriendService"}, service_context{system, "IFriendService"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IFriendService::GetCompletionEvent, "GetCompletionEvent"},
|
||||
{1, &IFriendService::Cancel, "Cancel"},
|
||||
{10100, nullptr, "GetFriendListIds"},
|
||||
{10101, &IFriendService::GetFriendList, "GetFriendList"},
|
||||
{10102, nullptr, "UpdateFriendInfo"},
|
||||
{10110, nullptr, "GetFriendProfileImage"},
|
||||
{10111, nullptr, "GetFriendProfileImageWithImageSize"}, // 18.0.0+
|
||||
{10120, &IFriendService::CheckFriendListAvailability, "CheckFriendListAvailability"},
|
||||
{10121, nullptr, "EnsureFriendListAvailable"},
|
||||
{10200, nullptr, "SendFriendRequestForApplication"},
|
||||
{10211, nullptr, "AddFacedFriendRequestForApplication"},
|
||||
{10400, &IFriendService::GetBlockedUserListIds, "GetBlockedUserListIds"},
|
||||
{10420, &IFriendService::CheckBlockedUserListAvailability, "CheckBlockedUserListAvailability"},
|
||||
{10421, nullptr, "EnsureBlockedUserListAvailable"},
|
||||
{10500, nullptr, "GetProfileList"},
|
||||
{10501, nullptr, "GetProfileListV2"}, // 18.0.0+
|
||||
{10600, nullptr, "DeclareOpenOnlinePlaySession"},
|
||||
{10601, &IFriendService::DeclareCloseOnlinePlaySession, "DeclareCloseOnlinePlaySession"},
|
||||
{10610, &IFriendService::UpdateUserPresence, "UpdateUserPresence"},
|
||||
{10700, &IFriendService::GetPlayHistoryRegistrationKey, "GetPlayHistoryRegistrationKey"},
|
||||
{10701, nullptr, "GetPlayHistoryRegistrationKeyWithNetworkServiceAccountId"},
|
||||
{10702, nullptr, "AddPlayHistory"},
|
||||
{11000, nullptr, "GetProfileImageUrl"},
|
||||
{11001, nullptr, "GetProfileImageUrlV2"}, // 18.0.0+
|
||||
{20100, &IFriendService::GetFriendCount, "GetFriendCount"},
|
||||
{20101, &IFriendService::GetNewlyFriendCount, "GetNewlyFriendCount"},
|
||||
{20102, nullptr, "GetFriendDetailedInfo"},
|
||||
{20103, nullptr, "SyncFriendList"},
|
||||
{20104, &IFriendService::RequestSyncFriendList, "RequestSyncFriendList"},
|
||||
{20105, &IFriendService::GetFriendListForViewer, "GetFriendListForViewerV1"},
|
||||
{20106, nullptr, "UpdateFriendInfoForViewerV1"},
|
||||
{20107, nullptr, "GetFriendDetailedInfoV2"}, // 20.0.0+
|
||||
{20108, &IFriendService::GetFriendListForViewer, "GetFriendListForViewerV2"}, // 22.0.0+
|
||||
{20109, nullptr, "UpdateFriendInfoForViewerV2"}, // 22.0.0+
|
||||
{20110, nullptr, "LoadFriendSettingV1"},
|
||||
{20111, nullptr, "LoadFriendSettingV2"}, // 22.0.0+
|
||||
{20200, &IFriendService::GetReceivedFriendRequestCount, "GetReceivedFriendRequestCount"},
|
||||
{20201, nullptr, "GetFriendRequestListV1"},
|
||||
{20202, nullptr, "GetFriendRequestListV2"}, // 20.0.0+
|
||||
{20203, nullptr, "GetFriendRequestReceivedNotificationCount"}, // 22.0.0+
|
||||
{20300, nullptr, "GetFriendCandidateList"},
|
||||
{20301, nullptr, "GetNintendoNetworkIdInfo"},
|
||||
{20302, nullptr, "GetSnsAccountLinkage"}, // 5.0.0-19.0.1
|
||||
{20303, nullptr, "GetSnsAccountProfile"}, // 5.0.0-19.0.1
|
||||
{20304, nullptr, "GetSnsAccountFriendList"}, // 5.0.0-19.0.1
|
||||
{20400, nullptr, "GetBlockedUserListV1"},
|
||||
{20401, nullptr, "SyncBlockedUserList"},
|
||||
{20402, nullptr, "GetBlockedUserListV2"}, // 20.0.0+
|
||||
{20500, nullptr, "GetProfileExtraListV1"},
|
||||
{20501, nullptr, "GetRelationship"},
|
||||
{20502, nullptr, "GetProfileExtraListV2"}, // 19.0.0+
|
||||
{20600, &IFriendService::GetUserPresenceView, "GetUserPresenceViewV1"},
|
||||
{20601, &IFriendService::GetUserPresenceView, "GetUserPresenceViewV2"}, // 19.0.0+
|
||||
{20700, nullptr, "GetPlayHistoryListV1"},
|
||||
{20701, &IFriendService::GetPlayHistoryStatistics, "GetPlayHistoryStatistics"},
|
||||
{20702, nullptr, "GetPlayHistoryListV2"}, // 19.0.0+
|
||||
{20800, &IFriendService::LoadUserSetting, "LoadUserSettingV1"},
|
||||
{20801, nullptr, "SyncUserSetting"},
|
||||
{20802, &IFriendService::LoadUserSetting, "LoadUserSettingV2"}, // 19.0.0+
|
||||
{20900, &IFriendService::RequestListSummaryOverlayNotification, "RequestListSummaryOverlayNotification"},
|
||||
{21000, nullptr, "GetExternalApplicationCatalog"},
|
||||
{22000, nullptr, "GetReceivedFriendInvitationListV1"},
|
||||
{22001, nullptr, "GetReceivedFriendInvitationDetailedInfoV1"},
|
||||
{22002, nullptr, "GetReceivedFriendInvitationListV2"}, // 19.0.0+
|
||||
{22003, nullptr, "GetReceivedFriendInvitationDetailedInfoV2"}, // 19.0.0+
|
||||
{22010, &IFriendService::GetReceivedFriendInvitationCountCache, "GetReceivedFriendInvitationCountCache"},
|
||||
{30100, nullptr, "DropFriendNewlyFlags"},
|
||||
{30101, nullptr, "DeleteFriend"},
|
||||
{30110, nullptr, "DropFriendNewlyFlag"},
|
||||
{30120, nullptr, "ChangeFriendFavoriteFlag"},
|
||||
{30121, nullptr, "ChangeFriendOnlineNotificationFlag"},
|
||||
{30130, nullptr, "SetFriendNote"}, // 22.0.0+
|
||||
{30131, nullptr, "RequestUploadPendingNote"}, // 22.0.0+
|
||||
{30190, nullptr, "RequestSyncLocalUpdates"}, // 22.0.0+
|
||||
{30200, nullptr, "SendFriendRequest"},
|
||||
{30201, nullptr, "SendFriendRequestWithApplicationInfoV1"},
|
||||
{30202, nullptr, "CancelFriendRequest"},
|
||||
{30203, nullptr, "AcceptFriendRequest"},
|
||||
{30204, nullptr, "RejectFriendRequest"},
|
||||
{30205, nullptr, "ReadFriendRequest"},
|
||||
{30210, nullptr, "GetFacedFriendRequestRegistrationKey"},
|
||||
{30211, nullptr, "AddFacedFriendRequest"},
|
||||
{30212, nullptr, "CancelFacedFriendRequest"},
|
||||
{30213, nullptr, "GetFacedFriendRequestProfileImage"},
|
||||
{30214, nullptr, "GetFacedFriendRequestProfileImageFromPath"},
|
||||
{30215, nullptr, "SendFriendRequestWithExternalApplicationCatalogId"},
|
||||
{30216, nullptr, "ResendFacedFriendRequest"},
|
||||
{30217, nullptr, "SendFriendRequestWithNintendoNetworkIdInfo"},
|
||||
{30218, nullptr, "SendFriendRequestWithApplicationInfoV2"}, // 20.0.0+
|
||||
{30300, nullptr, "GetSnsAccountLinkPageUrl"}, // 5.0.0-19.0.1
|
||||
{30301, nullptr, "UnlinkSnsAccount"}, // 5.0.0-19.0.1
|
||||
{30400, nullptr, "BlockUser"},
|
||||
{30401, nullptr, "BlockUserWithApplicationInfoV1"},
|
||||
{30402, nullptr, "UnblockUser"},
|
||||
{30403, nullptr, "BlockUserWithApplicationInfoV2"}, // 20.0.0+
|
||||
{30500, nullptr, "GetProfileExtraFromFriendCodeV1"},
|
||||
{30501, nullptr, "GetProfileExtraFromFriendCodeV2"}, // 19.0.0+
|
||||
{30700, nullptr, "DeletePlayHistory"},
|
||||
{30701, nullptr, "AddPlayHistoryWithApplication"}, // 19.0.0+
|
||||
{30810, nullptr, "ChangePresencePermission"},
|
||||
{30811, nullptr, "ChangeFriendRequestReception"},
|
||||
{30812, nullptr, "ChangePlayLogPermission"},
|
||||
{30820, nullptr, "IssueFriendCode"},
|
||||
{30830, nullptr, "ClearPlayLog"},
|
||||
{30900, nullptr, "SendFriendInvitationV1"},
|
||||
{30901, nullptr, "SendFriendInvitationV2"}, // 19.0.0+
|
||||
{30910, nullptr, "ReadFriendInvitation"},
|
||||
{30911, nullptr, "ReadAllFriendInvitations"},
|
||||
{31000, nullptr, "OpenUser"}, // 19.0.0+
|
||||
{40100, nullptr, "DeleteFriendListCache"},
|
||||
{40400, nullptr, "DeleteBlockedUserListCache"},
|
||||
{49900, nullptr, "DeleteNetworkServiceAccountCache"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
|
||||
completion_event = service_context.CreateEvent("IFriendService:CompletionEvent");
|
||||
}
|
||||
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{0, &IFriendService::GetCompletionEvent, "GetCompletionEvent"},
|
||||
FunctionInfo{1, &IFriendService::Cancel, "Cancel"},
|
||||
FunctionInfo{10100, nullptr, "GetFriendListIds"},
|
||||
FunctionInfo{10101, &IFriendService::GetFriendList, "GetFriendList"},
|
||||
FunctionInfo{10102, nullptr, "UpdateFriendInfo"},
|
||||
FunctionInfo{10110, nullptr, "GetFriendProfileImage"},
|
||||
FunctionInfo{10111, nullptr, "GetFriendProfileImageWithImageSize"}, // 18.0.0+
|
||||
FunctionInfo{10120, &IFriendService::CheckFriendListAvailability, "CheckFriendListAvailability"},
|
||||
FunctionInfo{10121, nullptr, "EnsureFriendListAvailable"},
|
||||
FunctionInfo{10200, nullptr, "SendFriendRequestForApplication"},
|
||||
FunctionInfo{10211, nullptr, "AddFacedFriendRequestForApplication"},
|
||||
FunctionInfo{10400, &IFriendService::GetBlockedUserListIds, "GetBlockedUserListIds"},
|
||||
FunctionInfo{10420, &IFriendService::CheckBlockedUserListAvailability, "CheckBlockedUserListAvailability"},
|
||||
FunctionInfo{10421, nullptr, "EnsureBlockedUserListAvailable"},
|
||||
FunctionInfo{10500, nullptr, "GetProfileList"},
|
||||
FunctionInfo{10501, nullptr, "GetProfileListV2"}, // 18.0.0+
|
||||
FunctionInfo{10600, nullptr, "DeclareOpenOnlinePlaySession"},
|
||||
FunctionInfo{10601, &IFriendService::DeclareCloseOnlinePlaySession, "DeclareCloseOnlinePlaySession"},
|
||||
FunctionInfo{10610, &IFriendService::UpdateUserPresence, "UpdateUserPresence"},
|
||||
FunctionInfo{10700, &IFriendService::GetPlayHistoryRegistrationKey, "GetPlayHistoryRegistrationKey"},
|
||||
FunctionInfo{10701, nullptr, "GetPlayHistoryRegistrationKeyWithNetworkServiceAccountId"},
|
||||
FunctionInfo{10702, nullptr, "AddPlayHistory"},
|
||||
FunctionInfo{11000, nullptr, "GetProfileImageUrl"},
|
||||
FunctionInfo{11001, nullptr, "GetProfileImageUrlV2"}, // 18.0.0+
|
||||
FunctionInfo{20100, &IFriendService::GetFriendCount, "GetFriendCount"},
|
||||
FunctionInfo{20101, &IFriendService::GetNewlyFriendCount, "GetNewlyFriendCount"},
|
||||
FunctionInfo{20102, nullptr, "GetFriendDetailedInfo"},
|
||||
FunctionInfo{20103, nullptr, "SyncFriendList"},
|
||||
FunctionInfo{20104, &IFriendService::RequestSyncFriendList, "RequestSyncFriendList"},
|
||||
FunctionInfo{20105, &IFriendService::GetFriendListForViewer, "GetFriendListForViewerV1"},
|
||||
FunctionInfo{20106, nullptr, "UpdateFriendInfoForViewerV1"},
|
||||
FunctionInfo{20107, nullptr, "GetFriendDetailedInfoV2"}, // 20.0.0+
|
||||
FunctionInfo{20108, &IFriendService::GetFriendListForViewer, "GetFriendListForViewerV2"}, // 22.0.0+
|
||||
FunctionInfo{20109, nullptr, "UpdateFriendInfoForViewerV2"}, // 22.0.0+
|
||||
FunctionInfo{20110, nullptr, "LoadFriendSettingV1"},
|
||||
FunctionInfo{20111, nullptr, "LoadFriendSettingV2"}, // 22.0.0+
|
||||
FunctionInfo{20200, &IFriendService::GetReceivedFriendRequestCount, "GetReceivedFriendRequestCount"},
|
||||
FunctionInfo{20201, nullptr, "GetFriendRequestListV1"},
|
||||
FunctionInfo{20202, nullptr, "GetFriendRequestListV2"}, // 20.0.0+
|
||||
FunctionInfo{20203, nullptr, "GetFriendRequestReceivedNotificationCount"}, // 22.0.0+
|
||||
FunctionInfo{20300, nullptr, "GetFriendCandidateList"},
|
||||
FunctionInfo{20301, nullptr, "GetNintendoNetworkIdInfo"},
|
||||
FunctionInfo{20302, nullptr, "GetSnsAccountLinkage"}, // 5.0.0-19.0.1
|
||||
FunctionInfo{20303, nullptr, "GetSnsAccountProfile"}, // 5.0.0-19.0.1
|
||||
FunctionInfo{20304, nullptr, "GetSnsAccountFriendList"}, // 5.0.0-19.0.1
|
||||
FunctionInfo{20400, nullptr, "GetBlockedUserListV1"},
|
||||
FunctionInfo{20401, nullptr, "SyncBlockedUserList"},
|
||||
FunctionInfo{20402, nullptr, "GetBlockedUserListV2"}, // 20.0.0+
|
||||
FunctionInfo{20500, nullptr, "GetProfileExtraListV1"},
|
||||
FunctionInfo{20501, nullptr, "GetRelationship"},
|
||||
FunctionInfo{20502, nullptr, "GetProfileExtraListV2"}, // 19.0.0+
|
||||
FunctionInfo{20600, &IFriendService::GetUserPresenceView, "GetUserPresenceViewV1"},
|
||||
FunctionInfo{20601, &IFriendService::GetUserPresenceView, "GetUserPresenceViewV2"}, // 19.0.0+
|
||||
FunctionInfo{20700, nullptr, "GetPlayHistoryListV1"},
|
||||
FunctionInfo{20701, &IFriendService::GetPlayHistoryStatistics, "GetPlayHistoryStatistics"},
|
||||
FunctionInfo{20702, nullptr, "GetPlayHistoryListV2"}, // 19.0.0+
|
||||
FunctionInfo{20800, &IFriendService::LoadUserSetting, "LoadUserSettingV1"},
|
||||
FunctionInfo{20801, nullptr, "SyncUserSetting"},
|
||||
FunctionInfo{20802, &IFriendService::LoadUserSetting, "LoadUserSettingV2"}, // 19.0.0+
|
||||
FunctionInfo{20900, &IFriendService::RequestListSummaryOverlayNotification, "RequestListSummaryOverlayNotification"},
|
||||
FunctionInfo{21000, nullptr, "GetExternalApplicationCatalog"},
|
||||
FunctionInfo{22000, nullptr, "GetReceivedFriendInvitationListV1"},
|
||||
FunctionInfo{22001, nullptr, "GetReceivedFriendInvitationDetailedInfoV1"},
|
||||
FunctionInfo{22002, nullptr, "GetReceivedFriendInvitationListV2"}, // 19.0.0+
|
||||
FunctionInfo{22003, nullptr, "GetReceivedFriendInvitationDetailedInfoV2"}, // 19.0.0+
|
||||
FunctionInfo{22010, &IFriendService::GetReceivedFriendInvitationCountCache, "GetReceivedFriendInvitationCountCache"},
|
||||
FunctionInfo{30100, nullptr, "DropFriendNewlyFlags"},
|
||||
FunctionInfo{30101, nullptr, "DeleteFriend"},
|
||||
FunctionInfo{30110, nullptr, "DropFriendNewlyFlag"},
|
||||
FunctionInfo{30120, nullptr, "ChangeFriendFavoriteFlag"},
|
||||
FunctionInfo{30121, nullptr, "ChangeFriendOnlineNotificationFlag"},
|
||||
FunctionInfo{30130, nullptr, "SetFriendNote"}, // 22.0.0+
|
||||
FunctionInfo{30131, nullptr, "RequestUploadPendingNote"}, // 22.0.0+
|
||||
FunctionInfo{30190, nullptr, "RequestSyncLocalUpdates"}, // 22.0.0+
|
||||
FunctionInfo{30200, nullptr, "SendFriendRequest"},
|
||||
FunctionInfo{30201, nullptr, "SendFriendRequestWithApplicationInfoV1"},
|
||||
FunctionInfo{30202, nullptr, "CancelFriendRequest"},
|
||||
FunctionInfo{30203, nullptr, "AcceptFriendRequest"},
|
||||
FunctionInfo{30204, nullptr, "RejectFriendRequest"},
|
||||
FunctionInfo{30205, nullptr, "ReadFriendRequest"},
|
||||
FunctionInfo{30210, nullptr, "GetFacedFriendRequestRegistrationKey"},
|
||||
FunctionInfo{30211, nullptr, "AddFacedFriendRequest"},
|
||||
FunctionInfo{30212, nullptr, "CancelFacedFriendRequest"},
|
||||
FunctionInfo{30213, nullptr, "GetFacedFriendRequestProfileImage"},
|
||||
FunctionInfo{30214, nullptr, "GetFacedFriendRequestProfileImageFromPath"},
|
||||
FunctionInfo{30215, nullptr, "SendFriendRequestWithExternalApplicationCatalogId"},
|
||||
FunctionInfo{30216, nullptr, "ResendFacedFriendRequest"},
|
||||
FunctionInfo{30217, nullptr, "SendFriendRequestWithNintendoNetworkIdInfo"},
|
||||
FunctionInfo{30218, nullptr, "SendFriendRequestWithApplicationInfoV2"}, // 20.0.0+
|
||||
FunctionInfo{30300, nullptr, "GetSnsAccountLinkPageUrl"}, // 5.0.0-19.0.1
|
||||
FunctionInfo{30301, nullptr, "UnlinkSnsAccount"}, // 5.0.0-19.0.1
|
||||
FunctionInfo{30400, nullptr, "BlockUser"},
|
||||
FunctionInfo{30401, nullptr, "BlockUserWithApplicationInfoV1"},
|
||||
FunctionInfo{30402, nullptr, "UnblockUser"},
|
||||
FunctionInfo{30403, nullptr, "BlockUserWithApplicationInfoV2"}, // 20.0.0+
|
||||
FunctionInfo{30500, nullptr, "GetProfileExtraFromFriendCodeV1"},
|
||||
FunctionInfo{30501, nullptr, "GetProfileExtraFromFriendCodeV2"}, // 19.0.0+
|
||||
FunctionInfo{30700, nullptr, "DeletePlayHistory"},
|
||||
FunctionInfo{30701, nullptr, "AddPlayHistoryWithApplication"}, // 19.0.0+
|
||||
FunctionInfo{30810, nullptr, "ChangePresencePermission"},
|
||||
FunctionInfo{30811, nullptr, "ChangeFriendRequestReception"},
|
||||
FunctionInfo{30812, nullptr, "ChangePlayLogPermission"},
|
||||
FunctionInfo{30820, nullptr, "IssueFriendCode"},
|
||||
FunctionInfo{30830, nullptr, "ClearPlayLog"},
|
||||
FunctionInfo{30900, nullptr, "SendFriendInvitationV1"},
|
||||
FunctionInfo{30901, nullptr, "SendFriendInvitationV2"}, // 19.0.0+
|
||||
FunctionInfo{30910, nullptr, "ReadFriendInvitation"},
|
||||
FunctionInfo{30911, nullptr, "ReadAllFriendInvitations"},
|
||||
FunctionInfo{31000, nullptr, "OpenUser"}, // 19.0.0+
|
||||
FunctionInfo{40100, nullptr, "DeleteFriendListCache"},
|
||||
FunctionInfo{40400, nullptr, "DeleteBlockedUserListCache"},
|
||||
FunctionInfo{49900, nullptr, "DeleteNetworkServiceAccountCache"}
|
||||
);
|
||||
}
|
||||
|
||||
~IFriendService() override {
|
||||
service_context.CloseEvent(completion_event);
|
||||
}
|
||||
@@ -375,21 +373,19 @@ private:
|
||||
class INotificationService final : public ServiceFramework<INotificationService> {
|
||||
public:
|
||||
explicit INotificationService(Core::System& system_, Common::UUID uuid_)
|
||||
: ServiceFramework{system_, "INotificationService"}, uuid{uuid_},
|
||||
service_context{system_, "INotificationService"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &INotificationService::GetEvent, "GetEvent"},
|
||||
{1, &INotificationService::Clear, "Clear"},
|
||||
{2, &INotificationService::Pop, "Pop"}
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
|
||||
: ServiceFramework{system_, "INotificationService"}, uuid{uuid_}
|
||||
, service_context{system_, "INotificationService"} {
|
||||
notification_event = service_context.CreateEvent("INotificationService:NotifyEvent");
|
||||
}
|
||||
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{0, &INotificationService::GetEvent, "GetEvent"},
|
||||
FunctionInfo{1, &INotificationService::Clear, "Clear"},
|
||||
FunctionInfo{2, &INotificationService::Pop, "Pop"}
|
||||
);
|
||||
}
|
||||
|
||||
~INotificationService() override {
|
||||
service_context.CloseEvent(notification_event);
|
||||
}
|
||||
@@ -501,12 +497,13 @@ class IServiceForApplication final : public ServiceFramework<IServiceForApplicat
|
||||
public:
|
||||
explicit IServiceForApplication(Core::System& system_)
|
||||
: ServiceFramework{system_, "nd:app"}
|
||||
{
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetReceivableNeighborInfoCountMax"},
|
||||
{10, nullptr, "IsNeighborDetectionEnabled"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
{}
|
||||
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{0, nullptr, "GetReceivableNeighborInfoCountMax"},
|
||||
FunctionInfo{10, nullptr, "IsNeighborDetectionEnabled"}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -514,47 +511,48 @@ class IServiceForSystem final : public ServiceFramework<IServiceForSystem> {
|
||||
public:
|
||||
explicit IServiceForSystem(Core::System& system_)
|
||||
: ServiceFramework{system_, "nd:sys"}
|
||||
{
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetReceivableNeighborInfoCountMax"},
|
||||
{10, nullptr, "IsNeighborDetectionEnabled"},
|
||||
{200, nullptr, "SetSystemData"},
|
||||
{201, nullptr, "ClearSystemData"},
|
||||
{203, nullptr, "GetReceivableNeighborInfoCountForSystem"},
|
||||
{204, nullptr, "ReceiveNeighborInfoForSystem"},
|
||||
{205, nullptr, "SetSender"},
|
||||
{206, nullptr, "GetSender"},
|
||||
{207, nullptr, "CreateScannerForSystem"},
|
||||
{208, nullptr, "CreateReceiveEventHolderForSystem"},
|
||||
{223, nullptr, "EnableNeighborDetection"},
|
||||
{224, nullptr, "DisableNeighborDetection"},
|
||||
{226, nullptr, "EnablePowerSave"},
|
||||
{227, nullptr, "DisablePowerSave"},
|
||||
{228, nullptr, "IsPowerSaveEnabled"},
|
||||
{232, nullptr, "ClearBlockedUsers"},
|
||||
{233, nullptr, "GetBlockedUserCount"},
|
||||
{234, nullptr, "BlockUserByLocalUserId"},
|
||||
{235, nullptr, "BlockUserByNetworkUserId"},
|
||||
{236, nullptr, "UnblockUserByLocalUserId"},
|
||||
{237, nullptr, "UnblockUserByNetworkUserId"},
|
||||
{240, nullptr, "DeleteApplication"},
|
||||
{250, nullptr, "InitializeApplicationInfo"},
|
||||
{260, nullptr, "CreateAccountSystemSaveDataAccessSuppressor"},
|
||||
{300, nullptr, "AddReceivedNeighborInfoForSystemForDebug"},
|
||||
{301, nullptr, "GetSendDataForDebug"},
|
||||
{302, nullptr, "ClearReceiveCounterForDebug"},
|
||||
{303, nullptr, "GetNextReceiveCounterForDebug"},
|
||||
{304, nullptr, "ListBlockedUsersForDebug"},
|
||||
{305, nullptr, "RefreshSendDataIdForDebug"},
|
||||
{306, nullptr, "ReloadFwdbgSettingsForDebug"},
|
||||
{307, nullptr, "EnableApplicationForDebug"},
|
||||
{308, nullptr, "GetNextReceiveCountersForDebug"},
|
||||
{309, nullptr, "ListApplicationInfoForDebug"},
|
||||
{310, nullptr, "SetApplicationDataForDebug"},
|
||||
{400, nullptr, "GetNetworkUserId"},
|
||||
{401, nullptr, "DeleteNetworkUserId"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
{}
|
||||
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{0, nullptr, "GetReceivableNeighborInfoCountMax"},
|
||||
FunctionInfo{10, nullptr, "IsNeighborDetectionEnabled"},
|
||||
FunctionInfo{200, nullptr, "SetSystemData"},
|
||||
FunctionInfo{201, nullptr, "ClearSystemData"},
|
||||
FunctionInfo{203, nullptr, "GetReceivableNeighborInfoCountForSystem"},
|
||||
FunctionInfo{204, nullptr, "ReceiveNeighborInfoForSystem"},
|
||||
FunctionInfo{205, nullptr, "SetSender"},
|
||||
FunctionInfo{206, nullptr, "GetSender"},
|
||||
FunctionInfo{207, nullptr, "CreateScannerForSystem"},
|
||||
FunctionInfo{208, nullptr, "CreateReceiveEventHolderForSystem"},
|
||||
FunctionInfo{223, nullptr, "EnableNeighborDetection"},
|
||||
FunctionInfo{224, nullptr, "DisableNeighborDetection"},
|
||||
FunctionInfo{226, nullptr, "EnablePowerSave"},
|
||||
FunctionInfo{227, nullptr, "DisablePowerSave"},
|
||||
FunctionInfo{228, nullptr, "IsPowerSaveEnabled"},
|
||||
FunctionInfo{232, nullptr, "ClearBlockedUsers"},
|
||||
FunctionInfo{233, nullptr, "GetBlockedUserCount"},
|
||||
FunctionInfo{234, nullptr, "BlockUserByLocalUserId"},
|
||||
FunctionInfo{235, nullptr, "BlockUserByNetworkUserId"},
|
||||
FunctionInfo{236, nullptr, "UnblockUserByLocalUserId"},
|
||||
FunctionInfo{237, nullptr, "UnblockUserByNetworkUserId"},
|
||||
FunctionInfo{240, nullptr, "DeleteApplication"},
|
||||
FunctionInfo{250, nullptr, "InitializeApplicationInfo"},
|
||||
FunctionInfo{260, nullptr, "CreateAccountSystemSaveDataAccessSuppressor"},
|
||||
FunctionInfo{300, nullptr, "AddReceivedNeighborInfoForSystemForDebug"},
|
||||
FunctionInfo{301, nullptr, "GetSendDataForDebug"},
|
||||
FunctionInfo{302, nullptr, "ClearReceiveCounterForDebug"},
|
||||
FunctionInfo{303, nullptr, "GetNextReceiveCounterForDebug"},
|
||||
FunctionInfo{304, nullptr, "ListBlockedUsersForDebug"},
|
||||
FunctionInfo{305, nullptr, "RefreshSendDataIdForDebug"},
|
||||
FunctionInfo{306, nullptr, "ReloadFwdbgSettingsForDebug"},
|
||||
FunctionInfo{307, nullptr, "EnableApplicationForDebug"},
|
||||
FunctionInfo{308, nullptr, "GetNextReceiveCountersForDebug"},
|
||||
FunctionInfo{309, nullptr, "ListApplicationInfoForDebug"},
|
||||
FunctionInfo{310, nullptr, "SetApplicationDataForDebug"},
|
||||
FunctionInfo{400, nullptr, "GetNetworkUserId"},
|
||||
FunctionInfo{401, nullptr, "DeleteNetworkUserId"}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -164,16 +164,14 @@ public:
|
||||
using IssuerFn = std::function<Result(u64, ApplicationLaunchProperty, std::vector<u8>)>;
|
||||
|
||||
explicit IRegistrar(Core::System& system_, IssuerFn&& issuer)
|
||||
: ServiceFramework{system_, "IRegistrar"}, issue_process_id{std::move(issuer)} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IRegistrar::Issue, "Issue"},
|
||||
{1, &IRegistrar::SetApplicationLaunchProperty, "SetApplicationLaunchProperty"},
|
||||
{2, &IRegistrar::SetApplicationControlProperty, "SetApplicationControlProperty"},
|
||||
};
|
||||
// clang-format on
|
||||
: ServiceFramework{system_, "IRegistrar"}, issue_process_id{std::move(issuer)} {}
|
||||
|
||||
RegisterHandlers(functions);
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{0, &IRegistrar::Issue, "Issue"},
|
||||
FunctionInfo{1, &IRegistrar::SetApplicationLaunchProperty, "SetApplicationLaunchProperty"},
|
||||
FunctionInfo{2, &IRegistrar::SetApplicationControlProperty, "SetApplicationControlProperty"}
|
||||
);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -248,9 +246,9 @@ ARP_W::ARP_W(Core::System& system_, ARPManager& manager_)
|
||||
: ServiceFramework{system_, "arp:w"}, manager{manager_} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &ARP_W::AcquireRegistrar, "AcquireRegistrar"},
|
||||
{1, &ARP_W::UnregisterApplicationInstance , "UnregisterApplicationInstance "},
|
||||
{2, nullptr, "AcquireUpdater"},
|
||||
FunctionInfo{0, &ARP_W::AcquireRegistrar, "AcquireRegistrar"},
|
||||
FunctionInfo{1, &ARP_W::UnregisterApplicationInstance , "UnregisterApplicationInstance "},
|
||||
FunctionInfo{2, nullptr, "AcquireUpdater"}
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -12,14 +12,12 @@ namespace Service::Glue {
|
||||
// This is nn::err::context::IContextRegistrar
|
||||
class IContextRegistrar : public ServiceFramework<IContextRegistrar> {
|
||||
public:
|
||||
IContextRegistrar(Core::System& system_) : ServiceFramework{system_, "IContextRegistrar"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IContextRegistrar::Complete, "Complete"},
|
||||
};
|
||||
// clang-format on
|
||||
IContextRegistrar(Core::System& system_) : ServiceFramework{system_, "IContextRegistrar"} {}
|
||||
|
||||
RegisterHandlers(functions);
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{0, &IContextRegistrar::Complete, "Complete"}
|
||||
);
|
||||
}
|
||||
|
||||
~IContextRegistrar() override = default;
|
||||
|
||||
@@ -178,18 +178,15 @@ class INotificationSystemEventAccessor final
|
||||
: public ServiceFramework<INotificationSystemEventAccessor> {
|
||||
public:
|
||||
explicit INotificationSystemEventAccessor(Core::System& system_)
|
||||
: ServiceFramework{system_, "INotificationSystemEventAccessor"},
|
||||
service_context{system_, "INotificationSystemEventAccessor"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, D<&INotificationSystemEventAccessor::GetSystemEvent>, "GetSystemEvent"},
|
||||
};
|
||||
// clang-format on
|
||||
: ServiceFramework{system_, "INotificationSystemEventAccessor"}
|
||||
, service_context{system_, "INotificationSystemEventAccessor"} {
|
||||
notification_event = service_context.CreateEvent("INotificationSystemEventAccessor:NotificationEvent");
|
||||
}
|
||||
|
||||
RegisterHandlers(functions);
|
||||
|
||||
notification_event =
|
||||
service_context.CreateEvent("INotificationSystemEventAccessor:NotificationEvent");
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{0, D<&INotificationSystemEventAccessor::GetSystemEvent>, "GetSystemEvent"}
|
||||
);
|
||||
}
|
||||
|
||||
~INotificationSystemEventAccessor() {
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -31,25 +34,25 @@ StaticService::StaticService(Core::System& system_,
|
||||
m_time_zone_binary{time->m_time_zone_binary} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, D<&StaticService::GetStandardUserSystemClock>, "GetStandardUserSystemClock"},
|
||||
{1, D<&StaticService::GetStandardNetworkSystemClock>, "GetStandardNetworkSystemClock"},
|
||||
{2, D<&StaticService::GetStandardSteadyClock>, "GetStandardSteadyClock"},
|
||||
{3, D<&StaticService::GetTimeZoneService>, "GetTimeZoneService"},
|
||||
{4, D<&StaticService::GetStandardLocalSystemClock>, "GetStandardLocalSystemClock"},
|
||||
{5, D<&StaticService::GetEphemeralNetworkSystemClock>, "GetEphemeralNetworkSystemClock"},
|
||||
{20, D<&StaticService::GetSharedMemoryNativeHandle>, "GetSharedMemoryNativeHandle"},
|
||||
{50, D<&StaticService::SetStandardSteadyClockInternalOffset>, "SetStandardSteadyClockInternalOffset"},
|
||||
{51, D<&StaticService::GetStandardSteadyClockRtcValue>, "GetStandardSteadyClockRtcValue"},
|
||||
{100, D<&StaticService::IsStandardUserSystemClockAutomaticCorrectionEnabled>, "IsStandardUserSystemClockAutomaticCorrectionEnabled"},
|
||||
{101, D<&StaticService::SetStandardUserSystemClockAutomaticCorrectionEnabled>, "SetStandardUserSystemClockAutomaticCorrectionEnabled"},
|
||||
{102, D<&StaticService::GetStandardUserSystemClockInitialYear>, "GetStandardUserSystemClockInitialYear"},
|
||||
{200, D<&StaticService::IsStandardNetworkSystemClockAccuracySufficient>, "IsStandardNetworkSystemClockAccuracySufficient"},
|
||||
{201, D<&StaticService::GetStandardUserSystemClockAutomaticCorrectionUpdatedTime>, "GetStandardUserSystemClockAutomaticCorrectionUpdatedTime"},
|
||||
{300, D<&StaticService::CalculateMonotonicSystemClockBaseTimePoint>, "CalculateMonotonicSystemClockBaseTimePoint"},
|
||||
{400, D<&StaticService::GetClockSnapshot>, "GetClockSnapshot"},
|
||||
{401, D<&StaticService::GetClockSnapshotFromSystemClockContext>, "GetClockSnapshotFromSystemClockContext"},
|
||||
{500, D<&StaticService::CalculateStandardUserSystemClockDifferenceByUser>, "CalculateStandardUserSystemClockDifferenceByUser"},
|
||||
{501, D<&StaticService::CalculateSpanBetween>, "CalculateSpanBetween"},
|
||||
FunctionInfo{0, D<&StaticService::GetStandardUserSystemClock>, "GetStandardUserSystemClock"},
|
||||
FunctionInfo{1, D<&StaticService::GetStandardNetworkSystemClock>, "GetStandardNetworkSystemClock"},
|
||||
FunctionInfo{2, D<&StaticService::GetStandardSteadyClock>, "GetStandardSteadyClock"},
|
||||
FunctionInfo{3, D<&StaticService::GetTimeZoneService>, "GetTimeZoneService"},
|
||||
FunctionInfo{4, D<&StaticService::GetStandardLocalSystemClock>, "GetStandardLocalSystemClock"},
|
||||
FunctionInfo{5, D<&StaticService::GetEphemeralNetworkSystemClock>, "GetEphemeralNetworkSystemClock"},
|
||||
FunctionInfo{20, D<&StaticService::GetSharedMemoryNativeHandle>, "GetSharedMemoryNativeHandle"},
|
||||
FunctionInfo{50, D<&StaticService::SetStandardSteadyClockInternalOffset>, "SetStandardSteadyClockInternalOffset"},
|
||||
FunctionInfo{51, D<&StaticService::GetStandardSteadyClockRtcValue>, "GetStandardSteadyClockRtcValue"},
|
||||
FunctionInfo{100, D<&StaticService::IsStandardUserSystemClockAutomaticCorrectionEnabled>, "IsStandardUserSystemClockAutomaticCorrectionEnabled"},
|
||||
FunctionInfo{101, D<&StaticService::SetStandardUserSystemClockAutomaticCorrectionEnabled>, "SetStandardUserSystemClockAutomaticCorrectionEnabled"},
|
||||
FunctionInfo{102, D<&StaticService::GetStandardUserSystemClockInitialYear>, "GetStandardUserSystemClockInitialYear"},
|
||||
FunctionInfo{200, D<&StaticService::IsStandardNetworkSystemClockAccuracySufficient>, "IsStandardNetworkSystemClockAccuracySufficient"},
|
||||
FunctionInfo{201, D<&StaticService::GetStandardUserSystemClockAutomaticCorrectionUpdatedTime>, "GetStandardUserSystemClockAutomaticCorrectionUpdatedTime"},
|
||||
FunctionInfo{300, D<&StaticService::CalculateMonotonicSystemClockBaseTimePoint>, "CalculateMonotonicSystemClockBaseTimePoint"},
|
||||
FunctionInfo{400, D<&StaticService::GetClockSnapshot>, "GetClockSnapshot"},
|
||||
FunctionInfo{401, D<&StaticService::GetClockSnapshotFromSystemClockContext>, "GetClockSnapshotFromSystemClockContext"},
|
||||
FunctionInfo{500, D<&StaticService::CalculateStandardUserSystemClockDifferenceByUser>, "CalculateStandardUserSystemClockDifferenceByUser"},
|
||||
FunctionInfo{501, D<&StaticService::CalculateSpanBetween>, "CalculateSpanBetween"}
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ public:
|
||||
: ServiceFramework{system_, "gpio"}
|
||||
{
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "Cmd0"},
|
||||
FunctionInfo{0, nullptr, "Cmd0"}
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
@@ -14,32 +14,29 @@ namespace Service::GRC {
|
||||
|
||||
class GRC final : public ServiceFramework<GRC> {
|
||||
public:
|
||||
explicit GRC(Core::System& system_) : ServiceFramework{system_, "grc:c"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{1, nullptr, "OpenContinuousRecorder"},
|
||||
{2, nullptr, "OpenGameMovieTrimmer"},
|
||||
{3, nullptr, "OpenOffscreenRecorder"},
|
||||
{101, nullptr, "CreateMovieMaker"},
|
||||
{9903, nullptr, "SetOffscreenRecordingMarker"}
|
||||
};
|
||||
// clang-format on
|
||||
explicit GRC(Core::System& system_) : ServiceFramework{system_, "grc:c"} {}
|
||||
|
||||
RegisterHandlers(functions);
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{1, nullptr, "OpenContinuousRecorder"},
|
||||
FunctionInfo{2, nullptr, "OpenGameMovieTrimmer"},
|
||||
FunctionInfo{3, nullptr, "OpenOffscreenRecorder"},
|
||||
FunctionInfo{101, nullptr, "CreateMovieMaker"},
|
||||
FunctionInfo{9903, nullptr, "SetOffscreenRecordingMarker"}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
class GRC_D final : public ServiceFramework<GRC_D> {
|
||||
public:
|
||||
explicit GRC_D(Core::System& system_) : ServiceFramework{system_, "grc:d"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{1, nullptr, "Initialize"},
|
||||
{2, nullptr, "Transfer"},
|
||||
{3, nullptr, "Cmd3"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
explicit GRC_D(Core::System& system_) : ServiceFramework{system_, "grc:d"} {}
|
||||
|
||||
FunctionInfoBase const* FindRequest(u32 key) override {
|
||||
return HandlerTableGenerateWithFind(key,
|
||||
FunctionInfo{1, nullptr, "Initialize"},
|
||||
FunctionInfo{2, nullptr, "Transfer"},
|
||||
FunctionInfo{3, nullptr, "Cmd3"}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ IActiveVibrationDeviceList::IActiveVibrationDeviceList(Core::System& system_,
|
||||
: ServiceFramework{system_, "IActiveVibrationDeviceList"}, resource_manager(resource) {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, C<&IActiveVibrationDeviceList::ActivateVibrationDevice>, "ActivateVibrationDevice"},
|
||||
FunctionInfo{0, C<&IActiveVibrationDeviceList::ActivateVibrationDevice>, "ActivateVibrationDevice"}
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user