mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-09-01 02:51:41 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 15e3acac93 | |||
| 71d8796040 |
@@ -0,0 +1,26 @@
|
|||||||
|
From b3622608433c183ba868a1dc8dd9cf285eb3b916 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dario Petrillo <dario.pk1@gmail.com>
|
||||||
|
Date: Thu, 27 Nov 2025 23:12:38 +0100
|
||||||
|
Subject: [PATCH] avoid extra memset when clearing an empty table
|
||||||
|
|
||||||
|
---
|
||||||
|
include/ankerl/unordered_dense.h | 6 ++++--
|
||||||
|
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/include/ankerl/unordered_dense.h b/include/ankerl/unordered_dense.h
|
||||||
|
index 0835342..4938212 100644
|
||||||
|
--- a/include/ankerl/unordered_dense.h
|
||||||
|
+++ b/include/ankerl/unordered_dense.h
|
||||||
|
@@ -1490,8 +1490,10 @@ class table : public std::conditional_t<is_map_v<T>, base_table_type_map<T>, bas
|
||||||
|
// modifiers //////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void clear() {
|
||||||
|
- m_values.clear();
|
||||||
|
- clear_buckets();
|
||||||
|
+ if (!empty()) {
|
||||||
|
+ m_values.clear();
|
||||||
|
+ clear_buckets();
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
auto insert(value_type const& value) -> std::pair<iterator, bool> {
|
||||||
@@ -540,6 +540,7 @@ add_subdirectory(externals)
|
|||||||
# pass targets from externals
|
# pass targets from externals
|
||||||
# TODO(crueter): CPMUtil Propagate func?
|
# TODO(crueter): CPMUtil Propagate func?
|
||||||
find_package(enet)
|
find_package(enet)
|
||||||
|
find_package(unordered_dense REQUIRED)
|
||||||
|
|
||||||
if (ARCHITECTURE_x86 OR ARCHITECTURE_x86_64)
|
if (ARCHITECTURE_x86 OR ARCHITECTURE_x86_64)
|
||||||
find_package(xbyak)
|
find_package(xbyak)
|
||||||
|
|||||||
@@ -301,6 +301,17 @@
|
|||||||
"repo": "eden-emu/tzdb_to_nx",
|
"repo": "eden-emu/tzdb_to_nx",
|
||||||
"version": "230326"
|
"version": "230326"
|
||||||
},
|
},
|
||||||
|
"unordered-dense": {
|
||||||
|
"bundled": true,
|
||||||
|
"find_args": "CONFIG",
|
||||||
|
"hash": "d2106f6640f6bfb81755e4b8bfb64982e46ec4a507cacdb38f940123212ccf35a20b43c70c6f01d7bfb8c246d1a16f7845d8052971949cea9def1475e3fa02c8",
|
||||||
|
"package": "unordered_dense",
|
||||||
|
"patches": [
|
||||||
|
"0001-avoid-memset-when-clearing-an-empty-table.patch"
|
||||||
|
],
|
||||||
|
"repo": "martinus/unordered_dense",
|
||||||
|
"version": "7b55cab841"
|
||||||
|
},
|
||||||
"vulkan-headers": {
|
"vulkan-headers": {
|
||||||
"hash": "d2846ea228415772645eea4b52a9efd33e6a563043dd3de059e798be6391a8f0ca089f455ae420ff22574939ed0f48ed7c6ff3d5a9987d5231dbf3b3f89b484b",
|
"hash": "d2846ea228415772645eea4b52a9efd33e6a563043dd3de059e798be6391a8f0ca089f455ae420ff22574939ed0f48ed7c6ff3d5a9987d5231dbf3b3f89b484b",
|
||||||
"min_version": "1.4.317",
|
"min_version": "1.4.317",
|
||||||
|
|||||||
Vendored
-2
@@ -509,8 +509,6 @@ QWidget#contentRichDialog QLabel#label_title_rich {
|
|||||||
}
|
}
|
||||||
|
|
||||||
QWidget#contentDialog QLabel#label_dialog {
|
QWidget#contentDialog QLabel#label_dialog {
|
||||||
background: #2E2E2E;
|
|
||||||
|
|
||||||
padding: 20px 65px;
|
padding: 20px 65px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-4
@@ -80,6 +80,7 @@ Certain other dependencies will be fetched by CPM regardless. System packages *c
|
|||||||
* [httplib](https://github.com/yhirose/cpp-httplib) - if `ENABLE_UPDATE_CHECKER` or `ENABLE_WEB_SERVICE` are on
|
* [httplib](https://github.com/yhirose/cpp-httplib) - if `ENABLE_UPDATE_CHECKER` or `ENABLE_WEB_SERVICE` are on
|
||||||
* This package is known to be broken on the AUR.
|
* This package is known to be broken on the AUR.
|
||||||
* [cpp-jwt](https://github.com/arun11299/cpp-jwt) 1.4+ - if `ENABLE_WEB_SERVICE` is on
|
* [cpp-jwt](https://github.com/arun11299/cpp-jwt) 1.4+ - if `ENABLE_WEB_SERVICE` is on
|
||||||
|
* [unordered-dense](https://github.com/martinus/unordered_dense)
|
||||||
|
|
||||||
On amd64:
|
On amd64:
|
||||||
|
|
||||||
@@ -118,7 +119,7 @@ Now, install all deps:
|
|||||||
sudo emerge -a \
|
sudo emerge -a \
|
||||||
app-arch/lz4 app-arch/zstd app-arch/unzip \
|
app-arch/lz4 app-arch/zstd app-arch/unzip \
|
||||||
dev-libs/libfmt dev-libs/libusb dev-libs/mcl dev-libs/sirit \
|
dev-libs/libfmt dev-libs/libusb dev-libs/mcl dev-libs/sirit \
|
||||||
dev-libs/boost dev-libs/openssl dev-libs/discord-rpc \
|
dev-libs/unordered_dense dev-libs/boost dev-libs/openssl dev-libs/discord-rpc \
|
||||||
dev-util/spirv-tools dev-util/spirv-headers dev-util/vulkan-headers \
|
dev-util/spirv-tools dev-util/spirv-headers dev-util/vulkan-headers \
|
||||||
dev-util/vulkan-utility-libraries dev-util/glslang \
|
dev-util/vulkan-utility-libraries dev-util/glslang \
|
||||||
media-gfx/renderdoc media-libs/libva media-libs/opus media-video/ffmpeg \
|
media-gfx/renderdoc media-libs/libva media-libs/opus media-video/ffmpeg \
|
||||||
@@ -259,7 +260,7 @@ brew install molten-vk
|
|||||||
<details>
|
<details>
|
||||||
<summary>FreeBSD</summary>
|
<summary>FreeBSD</summary>
|
||||||
|
|
||||||
As root run: `pkg install devel/cmake sdl3 devel/boost-libs devel/catch2 devel/libfmt devel/nlohmann-json devel/ninja devel/nasm devel/autoconf devel/pkgconf devel/qt6-base devel/qt6-charts devel/simpleini net/enet multimedia/ffnvcodec-headers multimedia/ffmpeg audio/opus archivers/liblz4 lang/gcc12 graphics/glslang graphics/vulkan-utility-libraries graphics/spirv-tools www/cpp-httplib vulkan-headers quazip-qt6`
|
As root run: `pkg install devel/cmake sdl3 devel/boost-libs devel/catch2 devel/libfmt devel/nlohmann-json devel/ninja devel/nasm devel/autoconf devel/pkgconf devel/qt6-base devel/qt6-charts devel/simpleini net/enet multimedia/ffnvcodec-headers multimedia/ffmpeg audio/opus archivers/liblz4 lang/gcc12 graphics/glslang graphics/vulkan-utility-libraries graphics/spirv-tools www/cpp-httplib devel/unordered-dense vulkan-headers quazip-qt6`
|
||||||
|
|
||||||
If using FreeBSD 12 or prior, use `devel/pkg-config` instead.
|
If using FreeBSD 12 or prior, use `devel/pkg-config` instead.
|
||||||
|
|
||||||
@@ -293,7 +294,7 @@ pkg_add cmake nasm git boost unzip--iconv autoconf-2.72p0 bash ffmpeg glslang gm
|
|||||||
<summary>DragonFlyBSD</summary>
|
<summary>DragonFlyBSD</summary>
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
pkg install gcc14 git cmake unzip nasm autoconf bash pkgconf ffmpeg glslang gmake jq nlohmann-json enet spirv-tools sdl3 vulkan-utility-libraries vulkan-headers catch2 libfmt openssl liblz4 boost-libs cpp-httplib qt6-base qt6-charts quazip-qt6 libva-vdpau-driver libva-utils libva-intel-driver
|
pkg install gcc14 git cmake unzip nasm autoconf bash pkgconf ffmpeg glslang gmake jq nlohmann-json enet spirv-tools sdl3 vulkan-utility-libraries vulkan-headers catch2 libfmt openssl liblz4 boost-libs cpp-httplib qt6-base qt6-charts quazip-qt6 unordered-dense libva-vdpau-driver libva-utils libva-intel-driver
|
||||||
```
|
```
|
||||||
|
|
||||||
[Caveats](./Caveats.md#dragonflybsd).
|
[Caveats](./Caveats.md#dragonflybsd).
|
||||||
@@ -327,7 +328,7 @@ sudo pkgin install git cmake autoconf build-essential libusb-1 nasm gcc13
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
BASE="git make autoconf libtool automake-wrapper jq patch"
|
BASE="git make autoconf libtool automake-wrapper jq patch"
|
||||||
MINGW="qt6-base qt6-charts qt6-tools qt6-translations qt6-svg cmake toolchain clang python-pip openssl vulkan-memory-allocator vulkan-devel glslang boost fmt lz4 nlohmann-json zlib zstd enet opus libusb openssl SDL3"
|
MINGW="qt6-base qt6-charts qt6-tools qt6-translations qt6-svg cmake toolchain clang python-pip openssl vulkan-memory-allocator vulkan-devel glslang boost fmt lz4 nlohmann-json zlib zstd enet opus libusb unordered_dense openssl SDL3"
|
||||||
# Either x86_64 or clang-aarch64 (Windows on ARM)
|
# Either x86_64 or clang-aarch64 (Windows on ARM)
|
||||||
packages="$BASE"
|
packages="$BASE"
|
||||||
for pkg in $MINGW; do
|
for pkg in $MINGW; do
|
||||||
|
|||||||
+8
-24
@@ -43,7 +43,6 @@ This guide will walk you through adding a new boolean toggle setting to Eden's c
|
|||||||
Firstly add your desired toggle:
|
Firstly add your desired toggle:
|
||||||
|
|
||||||
Example: `src/common/setting.h`
|
Example: `src/common/setting.h`
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
SwitchableSetting<bool> your_setting_name{linkage, false, "your_setting_name", Category::RendererExtensions};
|
SwitchableSetting<bool> your_setting_name{linkage, false, "your_setting_name", Category::RendererExtensions};
|
||||||
```
|
```
|
||||||
@@ -68,7 +67,6 @@ Common Categories:
|
|||||||
Add the toggle to the Qt UI, where you wish for it to appear and place it there.
|
Add the toggle to the Qt UI, where you wish for it to appear and place it there.
|
||||||
|
|
||||||
Example: `src/qt_common/config/shared_translation.cpp`
|
Example: `src/qt_common/config/shared_translation.cpp`
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
INSERT(Settings,
|
INSERT(Settings,
|
||||||
your_setting_name,
|
your_setting_name,
|
||||||
@@ -93,7 +91,6 @@ INSERT(Settings,
|
|||||||
Add where it should be in the settings.
|
Add where it should be in the settings.
|
||||||
|
|
||||||
Example: `src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt`
|
Example: `src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt`
|
||||||
|
|
||||||
```kts
|
```kts
|
||||||
RENDERER_YOUR_SETTING_NAME("your_setting_name"),
|
RENDERER_YOUR_SETTING_NAME("your_setting_name"),
|
||||||
```
|
```
|
||||||
@@ -109,7 +106,6 @@ RENDERER_YOUR_SETTING_NAME("your_setting_name"),
|
|||||||
Add the toggle to the Kotlin (Android) UI
|
Add the toggle to the Kotlin (Android) UI
|
||||||
|
|
||||||
Example: `src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt`
|
Example: `src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt`
|
||||||
|
|
||||||
```kts
|
```kts
|
||||||
put(
|
put(
|
||||||
SwitchSetting(
|
SwitchSetting(
|
||||||
@@ -127,7 +123,6 @@ put(
|
|||||||
Add your setting within the right category.
|
Add your setting within the right category.
|
||||||
|
|
||||||
Example: `src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt`
|
Example: `src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt`
|
||||||
|
|
||||||
```kts
|
```kts
|
||||||
add(BooleanSetting.RENDERER_YOUR_SETTING_NAME.key)
|
add(BooleanSetting.RENDERER_YOUR_SETTING_NAME.key)
|
||||||
```
|
```
|
||||||
@@ -142,7 +137,6 @@ add(BooleanSetting.RENDERER_YOUR_SETTING_NAME.key)
|
|||||||
Add your setting and description in the appropriate place.
|
Add your setting and description in the appropriate place.
|
||||||
|
|
||||||
Example: `src/android/app/src/main/res/values/strings.xml`
|
Example: `src/android/app/src/main/res/values/strings.xml`
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<string name="your_setting_name">Your Setting Display Name</string>
|
<string name="your_setting_name">Your Setting Display Name</string>
|
||||||
<string name="your_setting_name_description">Detailed description of what this setting does. Explain any caveats, requirements, or warnings here.</string>
|
<string name="your_setting_name_description">Detailed description of what this setting does. Explain any caveats, requirements, or warnings here.</string>
|
||||||
@@ -156,7 +150,6 @@ Now the UI part is done find a place in the code for the toggle,
|
|||||||
And use it to your heart's desire!
|
And use it to your heart's desire!
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
const bool your_value = Settings::values.your_setting_name.GetValue();
|
const bool your_value = Settings::values.your_setting_name.GetValue();
|
||||||
|
|
||||||
@@ -203,31 +196,25 @@ Common advantages recap:
|
|||||||
|
|
||||||
#### Accessing Debug Knobs (dev side)
|
#### Accessing Debug Knobs (dev side)
|
||||||
|
|
||||||
Use the `Settings::GetDebugKnobAt(u8 i)` function to check if a specific bit is set:
|
Use the `Settings::getDebugKnobAt(u8 i)` function to check if a specific bit is set:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
//cpp side
|
//cpp side
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
|
|
||||||
//To use it as a general purpose uint var:
|
|
||||||
unsigned int debug_knobs = Settings::values.debug_knobs.GetValue();
|
|
||||||
|
|
||||||
// Check if bit 0 is set
|
// Check if bit 0 is set
|
||||||
bool feature_enabled = Settings::GetDebugKnobAt(0);
|
bool feature_enabled = Settings::getDebugKnobAt(0);
|
||||||
|
|
||||||
// Check if bit 15 is set
|
// Check if bit 15 is set
|
||||||
bool another_feature = Settings::GetDebugKnobAt(15);
|
bool another_feature = Settings::getDebugKnobAt(15);
|
||||||
```
|
```
|
||||||
|
|
||||||
```kts
|
```kts
|
||||||
//kotlin side
|
//kotlin side
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.Settings
|
import org.yuzu.yuzu_emu.features.settings.model.Settings
|
||||||
|
|
||||||
//To use it as a general purpose uint var
|
|
||||||
val debug_knobs: Int = UShortSetting.DEBUG_KNOBS.getInt()
|
|
||||||
|
|
||||||
// Check if bit x is set
|
// Check if bit x is set
|
||||||
bool feature_enabled = Settings.GetDebugKnobAt(x); //x as integer from 0 to 15
|
bool feature_enabled = Settings.getDebugKnobAt(x); //x as integer from 0 to 15
|
||||||
```
|
```
|
||||||
|
|
||||||
The function returns `true` if the specified bit (0-15) is set in the `debug_knobs` value, `false` otherwise.
|
The function returns `true` if the specified bit (0-15) is set in the `debug_knobs` value, `false` otherwise.
|
||||||
@@ -260,7 +247,6 @@ There are two main confusions when talking about knobs:
|
|||||||
Sometimes when an user reports: knobs 1 and 2 gets better performance, dev may get confuse whether he means the knobs 1 and 2 literally, or the 1st and 2nd knobs (knobs 0 and 1).
|
Sometimes when an user reports: knobs 1 and 2 gets better performance, dev may get confuse whether he means the knobs 1 and 2 literally, or the 1st and 2nd knobs (knobs 0 and 1).
|
||||||
|
|
||||||
Debug knobs are **zero-based**, which means:
|
Debug knobs are **zero-based**, which means:
|
||||||
|
|
||||||
* The first knob is the knob(0) (or knob0 henceforth), and the last one is the 15 (knob15, likewise)
|
* The first knob is the knob(0) (or knob0 henceforth), and the last one is the 15 (knob15, likewise)
|
||||||
* You can talk: "knob0 is enabled/disabled", "In this video i was using only knobs 0 and 2", etc.
|
* You can talk: "knob0 is enabled/disabled", "In this video i was using only knobs 0 and 2", etc.
|
||||||
|
|
||||||
@@ -273,7 +259,6 @@ Whenever you're instructing tests or reporting results, be precise about whether
|
|||||||
|
|
||||||
ALWAYS use the word in PLURAL (knobs), without mentioning which one, to refer to the setting, aka multiple knobs at once:
|
ALWAYS use the word in PLURAL (knobs), without mentioning which one, to refer to the setting, aka multiple knobs at once:
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
- **knobs=0**: no knobs enabled
|
- **knobs=0**: no knobs enabled
|
||||||
- **knobs=1**: knob0 enabled, others disabled
|
- **knobs=1**: knob0 enabled, others disabled
|
||||||
- **knobs=2**: knob1 enabled, others disabled
|
- **knobs=2**: knob1 enabled, others disabled
|
||||||
@@ -285,7 +270,6 @@ Examples:
|
|||||||
|
|
||||||
Use the word in SINGULAR (knob), or in plural but referring which ones, when meaning multiple knobs at once:
|
Use the word in SINGULAR (knob), or in plural but referring which ones, when meaning multiple knobs at once:
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
- **knob0**: knob 0 enabled, others disabled
|
- **knob0**: knob 0 enabled, others disabled
|
||||||
- **knob1**: knob 1 enabled, others disabled
|
- **knob1**: knob 1 enabled, others disabled
|
||||||
- **knobs 0 and 1**: knobs 0 and 1 enabled, others disabled
|
- **knobs 0 and 1**: knobs 0 and 1 enabled, others disabled
|
||||||
@@ -298,12 +282,12 @@ Examples:
|
|||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
void SomeFunction() {
|
void SomeFunction() {
|
||||||
if (Settings::GetDebugKnobAt(0)) {
|
if (Settings::getDebugKnobAt(0)) {
|
||||||
LOG_DEBUG(Common, "Debug feature 0 is enabled");
|
LOG_DEBUG(Common, "Debug feature 0 is enabled");
|
||||||
// Additional debug code here
|
// Additional debug code here
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Settings::GetDebugKnobAt(1)) {
|
if (Settings::getDebugKnobAt(1)) {
|
||||||
LOG_DEBUG(Common, "Debug feature 1 is enabled");
|
LOG_DEBUG(Common, "Debug feature 1 is enabled");
|
||||||
// Different debug behavior
|
// Different debug behavior
|
||||||
}
|
}
|
||||||
@@ -315,7 +299,7 @@ void SomeFunction() {
|
|||||||
```cpp
|
```cpp
|
||||||
bool UseOptimizedPath() {
|
bool UseOptimizedPath() {
|
||||||
// Skip optimization if debug bit 2 is set for testing
|
// Skip optimization if debug bit 2 is set for testing
|
||||||
return !Settings::GetDebugKnobAt(2);
|
return !Settings::getDebugKnobAt(2);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -325,7 +309,7 @@ bool UseOptimizedPath() {
|
|||||||
void ExperimentalFeature() {
|
void ExperimentalFeature() {
|
||||||
static constexpr u8 EXPERIMENTAL_FEATURE_BIT = 3;
|
static constexpr u8 EXPERIMENTAL_FEATURE_BIT = 3;
|
||||||
|
|
||||||
if (!Settings::GetDebugKnobAt(EXPERIMENTAL_FEATURE_BIT)) {
|
if (!Settings::getDebugKnobAt(EXPERIMENTAL_FEATURE_BIT)) {
|
||||||
// Fallback to stable implementation
|
// Fallback to stable implementation
|
||||||
StableImplementation();
|
StableImplementation();
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -308,6 +308,32 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### unordered_dense
|
||||||
|
|
||||||
|
```
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2022 Martin Leitner-Ankerl
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
```
|
||||||
|
|
||||||
### xbyak
|
### xbyak
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
Vendored
+3
@@ -58,6 +58,9 @@ if (WIN32 AND NOT TARGET LLVM::Demangle)
|
|||||||
add_library(LLVM::Demangle ALIAS demangle)
|
add_library(LLVM::Demangle ALIAS demangle)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# unordered_dense
|
||||||
|
AddJsonPackage(unordered-dense)
|
||||||
|
|
||||||
# httplib
|
# httplib
|
||||||
if (IOS)
|
if (IOS)
|
||||||
set(HTTPLIB_USE_BROTLI_IF_AVAILABLE OFF)
|
set(HTTPLIB_USE_BROTLI_IF_AVAILABLE OFF)
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ object NativeLibrary {
|
|||||||
|
|
||||||
external fun refreshThreadPolicies()
|
external fun refreshThreadPolicies()
|
||||||
|
|
||||||
external fun GetDebugKnobAt(index: Int): Boolean
|
external fun getDebugKnobAt(index: Int): Boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the current speed limit to the configured turbo speed.
|
* Set the current speed limit to the configured turbo speed.
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ object Settings {
|
|||||||
fun getPlayerString(player: Int): String =
|
fun getPlayerString(player: Int): String =
|
||||||
YuzuApplication.appContext.getString(R.string.preferences_player, player)
|
YuzuApplication.appContext.getString(R.string.preferences_player, player)
|
||||||
|
|
||||||
fun GetDebugKnobAt(index: Int): Boolean {
|
fun getDebugKnobAt(index: Int): Boolean {
|
||||||
return org.yuzu.yuzu_emu.NativeLibrary.GetDebugKnobAt(index)
|
return org.yuzu.yuzu_emu.NativeLibrary.getDebugKnobAt(index)
|
||||||
}
|
}
|
||||||
|
|
||||||
const val PREF_FIRST_APP_LAUNCH = "FirstApplicationLaunch"
|
const val PREF_FIRST_APP_LAUNCH = "FirstApplicationLaunch"
|
||||||
|
|||||||
+2
-1
@@ -11,7 +11,8 @@ import org.yuzu.yuzu_emu.utils.NativeConfig
|
|||||||
enum class ShortSetting(override val key: String) : AbstractShortSetting {
|
enum class ShortSetting(override val key: String) : AbstractShortSetting {
|
||||||
RENDERER_SPEED_LIMIT("speed_limit"),
|
RENDERER_SPEED_LIMIT("speed_limit"),
|
||||||
RENDERER_TURBO_SPEED_LIMIT("turbo_speed_limit"),
|
RENDERER_TURBO_SPEED_LIMIT("turbo_speed_limit"),
|
||||||
RENDERER_SLOW_SPEED_LIMIT("slow_speed_limit")
|
RENDERER_SLOW_SPEED_LIMIT("slow_speed_limit"),
|
||||||
|
DEBUG_KNOBS("debug_knobs")
|
||||||
;
|
;
|
||||||
|
|
||||||
override fun getShort(needsGlobal: Boolean): Short = NativeConfig.getShort(key, needsGlobal)
|
override fun getShort(needsGlobal: Boolean): Short = NativeConfig.getShort(key, needsGlobal)
|
||||||
|
|||||||
-1
@@ -11,7 +11,6 @@ import org.yuzu.yuzu_emu.utils.NativeConfig
|
|||||||
enum class StringSetting(override val key: String) : AbstractStringSetting {
|
enum class StringSetting(override val key: String) : AbstractStringSetting {
|
||||||
DRIVER_PATH("driver_path"),
|
DRIVER_PATH("driver_path"),
|
||||||
DEVICE_NAME("device_name"),
|
DEVICE_NAME("device_name"),
|
||||||
LOG_FILTER("log_filter"),
|
|
||||||
PROGRAM_ARGS("program_args"),
|
PROGRAM_ARGS("program_args"),
|
||||||
|
|
||||||
WEB_TOKEN("eden_token"),
|
WEB_TOKEN("eden_token"),
|
||||||
|
|||||||
-27
@@ -1,27 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.features.settings.model
|
|
||||||
|
|
||||||
import org.yuzu.yuzu_emu.utils.NativeConfig
|
|
||||||
|
|
||||||
enum class UShortSetting(override val key: String) : AbstractIntSetting {
|
|
||||||
DEBUG_KNOBS("debug_knobs")
|
|
||||||
;
|
|
||||||
|
|
||||||
override fun getInt(needsGlobal: Boolean): Int =
|
|
||||||
NativeConfig.getUnsignedShort(key, needsGlobal)
|
|
||||||
|
|
||||||
override fun setInt(value: Int) {
|
|
||||||
if (NativeConfig.isPerGameConfigLoaded()) {
|
|
||||||
global = false
|
|
||||||
}
|
|
||||||
NativeConfig.setUnsignedShort(key, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
override val defaultValue: Int by lazy { NativeConfig.getDefaultToString(key).toInt() }
|
|
||||||
|
|
||||||
override fun getValueAsString(needsGlobal: Boolean): String = getInt(needsGlobal).toString()
|
|
||||||
|
|
||||||
override fun reset() = NativeConfig.setUnsignedShort(key, defaultValue)
|
|
||||||
}
|
|
||||||
+1
-9
@@ -20,7 +20,6 @@ import org.yuzu.yuzu_emu.features.settings.model.IntSetting
|
|||||||
import org.yuzu.yuzu_emu.features.settings.model.LongSetting
|
import org.yuzu.yuzu_emu.features.settings.model.LongSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.ShortSetting
|
import org.yuzu.yuzu_emu.features.settings.model.ShortSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.StringSetting
|
import org.yuzu.yuzu_emu.features.settings.model.StringSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.UShortSetting
|
|
||||||
import org.yuzu.yuzu_emu.network.NetDataValidators
|
import org.yuzu.yuzu_emu.network.NetDataValidators
|
||||||
import org.yuzu.yuzu_emu.utils.LosslessScalingHelper
|
import org.yuzu.yuzu_emu.utils.LosslessScalingHelper
|
||||||
import org.yuzu.yuzu_emu.utils.NativeConfig
|
import org.yuzu.yuzu_emu.utils.NativeConfig
|
||||||
@@ -1033,16 +1032,9 @@ abstract class SettingsItem(
|
|||||||
descriptionId = R.string.use_auto_stub_description
|
descriptionId = R.string.use_auto_stub_description
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
put(
|
|
||||||
StringInputSetting(
|
|
||||||
StringSetting.LOG_FILTER,
|
|
||||||
titleId = R.string.log_filter,
|
|
||||||
descriptionId = R.string.log_filter_description
|
|
||||||
)
|
|
||||||
)
|
|
||||||
put(
|
put(
|
||||||
SpinBoxSetting(
|
SpinBoxSetting(
|
||||||
UShortSetting.DEBUG_KNOBS,
|
ShortSetting.DEBUG_KNOBS,
|
||||||
titleId = R.string.debug_knobs,
|
titleId = R.string.debug_knobs,
|
||||||
descriptionId = R.string.debug_knobs_description,
|
descriptionId = R.string.debug_knobs_description,
|
||||||
valueHint = R.string.debug_knobs_hint,
|
valueHint = R.string.debug_knobs_hint,
|
||||||
|
|||||||
+1
-3
@@ -25,7 +25,6 @@ import org.yuzu.yuzu_emu.features.settings.model.Settings
|
|||||||
import org.yuzu.yuzu_emu.features.settings.model.Settings.MenuTag
|
import org.yuzu.yuzu_emu.features.settings.model.Settings.MenuTag
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.ShortSetting
|
import org.yuzu.yuzu_emu.features.settings.model.ShortSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.StringSetting
|
import org.yuzu.yuzu_emu.features.settings.model.StringSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.UShortSetting
|
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.view.*
|
import org.yuzu.yuzu_emu.features.settings.model.view.*
|
||||||
import org.yuzu.yuzu_emu.utils.InputHandler
|
import org.yuzu.yuzu_emu.utils.InputHandler
|
||||||
import org.yuzu.yuzu_emu.utils.LosslessScalingHelper
|
import org.yuzu.yuzu_emu.utils.LosslessScalingHelper
|
||||||
@@ -1323,12 +1322,11 @@ class SettingsFragmentPresenter(
|
|||||||
add(HeaderSetting(R.string.log))
|
add(HeaderSetting(R.string.log))
|
||||||
|
|
||||||
add(BooleanSetting.DEBUG_FLUSH_BY_LINE.key)
|
add(BooleanSetting.DEBUG_FLUSH_BY_LINE.key)
|
||||||
add(StringSetting.LOG_FILTER.key)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
add(HeaderSetting(R.string.general))
|
add(HeaderSetting(R.string.general))
|
||||||
|
|
||||||
add(UShortSetting.DEBUG_KNOBS.key)
|
add(ShortSetting.DEBUG_KNOBS.key)
|
||||||
add(StringSetting.PROGRAM_ARGS.key)
|
add(StringSetting.PROGRAM_ARGS.key)
|
||||||
|
|
||||||
if (!NativeConfig.isPerGameConfigLoaded()) {
|
if (!NativeConfig.isPerGameConfigLoaded()) {
|
||||||
|
|||||||
@@ -80,12 +80,6 @@ object NativeConfig {
|
|||||||
@Synchronized
|
@Synchronized
|
||||||
external fun setShort(key: String, value: Short)
|
external fun setShort(key: String, value: Short)
|
||||||
|
|
||||||
@Synchronized
|
|
||||||
external fun getUnsignedShort(key: String, needsGlobal: Boolean): Int
|
|
||||||
|
|
||||||
@Synchronized
|
|
||||||
external fun setUnsignedShort(key: String, value: Int)
|
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
external fun getInt(key: String, needsGlobal: Boolean): Int
|
external fun getInt(key: String, needsGlobal: Boolean): Int
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ struct RomMetadata {
|
|||||||
std::vector<u8> icon;
|
std::vector<u8> icon;
|
||||||
bool isHomebrew;
|
bool isHomebrew;
|
||||||
};
|
};
|
||||||
static ::Common::unordered_map<std::string, RomMetadata> m_rom_metadata_cache;
|
static ankerl::unordered_dense::map<std::string, RomMetadata> m_rom_metadata_cache;
|
||||||
|
|
||||||
static RomMetadata CacheRomMetadata(const std::string& path) {
|
static RomMetadata CacheRomMetadata(const std::string& path) {
|
||||||
auto& instance = EmulationSession::GetInstance();
|
auto& instance = EmulationSession::GetInstance();
|
||||||
|
|||||||
@@ -1300,8 +1300,8 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_refreshThreadPolicies(JNIEnv* env, jo
|
|||||||
Common::RefreshThreadPolicies();
|
Common::RefreshThreadPolicies();
|
||||||
}
|
}
|
||||||
|
|
||||||
jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_GetDebugKnobAt(JNIEnv* env, jobject jobj, jint index) {
|
jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_getDebugKnobAt(JNIEnv* env, jobject jobj, jint index) {
|
||||||
return static_cast<jboolean>(Settings::GetDebugKnobAt(static_cast<u8>(index)));
|
return static_cast<jboolean>(Settings::getDebugKnobAt(static_cast<u8>(index)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Java_org_yuzu_yuzu_1emu_NativeLibrary_setTurboSpeedLimit(JNIEnv *env, jobject jobj, jboolean enabled) {
|
void Java_org_yuzu_yuzu_1emu_NativeLibrary_setTurboSpeedLimit(JNIEnv *env, jobject jobj, jboolean enabled) {
|
||||||
|
|||||||
@@ -130,25 +130,6 @@ void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setShort(JNIEnv* env, jobject ob
|
|||||||
setting->SetValue(value);
|
setting->SetValue(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
jint Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getUnsignedShort(JNIEnv* env, jobject obj,
|
|
||||||
jstring jkey,
|
|
||||||
jboolean needGlobal) {
|
|
||||||
auto setting = getSetting<u16>(env, jkey);
|
|
||||||
if (setting == nullptr) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return static_cast<jint>(setting->GetValue(static_cast<bool>(needGlobal)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setUnsignedShort(JNIEnv* env, jobject obj,
|
|
||||||
jstring jkey, jint value) {
|
|
||||||
auto setting = getSetting<u16>(env, jkey);
|
|
||||||
if (setting == nullptr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setting->SetValue(static_cast<u16>(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
jint Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getInt(JNIEnv* env, jobject obj, jstring jkey,
|
jint Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getInt(JNIEnv* env, jobject obj, jstring jkey,
|
||||||
jboolean needGlobal) {
|
jboolean needGlobal) {
|
||||||
auto setting = getSetting<int>(env, jkey);
|
auto setting = getSetting<int>(env, jkey);
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
#include "input_common/drivers/virtual_gamepad.h"
|
#include "input_common/drivers/virtual_gamepad.h"
|
||||||
#include "native.h"
|
#include "native.h"
|
||||||
|
|
||||||
::Common::unordered_map<std::string, std::unique_ptr<AndroidConfig>> map_profiles;
|
ankerl::unordered_dense::map<std::string, std::unique_ptr<AndroidConfig>> map_profiles;
|
||||||
|
|
||||||
bool IsHandheldOnly() {
|
bool IsHandheldOnly() {
|
||||||
const auto npad_style_set =
|
const auto npad_style_set =
|
||||||
|
|||||||
@@ -636,8 +636,6 @@
|
|||||||
<string name="log">Logging</string>
|
<string name="log">Logging</string>
|
||||||
<string name="flush_by_line">Flush debug logs by line</string>
|
<string name="flush_by_line">Flush debug logs by line</string>
|
||||||
<string name="flush_by_line_description">Flushes debugging logs on each line written, making debugging easier in cases of crashing or freezing.</string>
|
<string name="flush_by_line_description">Flushes debugging logs on each line written, making debugging easier in cases of crashing or freezing.</string>
|
||||||
<string name="log_filter">Log filter</string>
|
|
||||||
<string name="log_filter_description">Controls Eden\'s log categories. Example: *:Info Service.LM:Debug</string>
|
|
||||||
|
|
||||||
<!-- GPU Logging strings -->
|
<!-- GPU Logging strings -->
|
||||||
<string name="gpu_logging_header">GPU Logging</string>
|
<string name="gpu_logging_header">GPU Logging</string>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
namespace AudioCore {
|
namespace AudioCore {
|
||||||
|
|
||||||
AudioCore::AudioCore(Core::System& system) {
|
AudioCore::AudioCore(Core::System& system) {
|
||||||
audio_manager.emplace();
|
audio_manager.emplace(system);
|
||||||
CreateSinks();
|
CreateSinks();
|
||||||
// Must be created after the sinks
|
// Must be created after the sinks
|
||||||
adsp.emplace(system, *output_sink);
|
adsp.emplace(system, *output_sink);
|
||||||
|
|||||||
@@ -15,12 +15,12 @@
|
|||||||
|
|
||||||
namespace AudioCore::AudioIn {
|
namespace AudioCore::AudioIn {
|
||||||
|
|
||||||
Manager::Manager(Core::System& system_) : system{system_} {
|
Manager::Manager(Core::System& system) {
|
||||||
std::iota(session_ids.begin(), session_ids.end(), 0);
|
std::iota(session_ids.begin(), session_ids.end(), 0);
|
||||||
num_free_sessions = MaxInSessions;
|
num_free_sessions = MaxInSessions;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result Manager::AcquireSessionId(size_t& session_id) {
|
Result Manager::AcquireSessionId(Core::System& system, size_t& session_id) {
|
||||||
if (num_free_sessions == 0) {
|
if (num_free_sessions == 0) {
|
||||||
LOG_ERROR(Service_Audio, "All 4 AudioIn sessions are in use, cannot create any more");
|
LOG_ERROR(Service_Audio, "All 4 AudioIn sessions are in use, cannot create any more");
|
||||||
return Service::Audio::ResultOutOfSessions;
|
return Service::Audio::ResultOutOfSessions;
|
||||||
@@ -31,7 +31,7 @@ Result Manager::AcquireSessionId(size_t& session_id) {
|
|||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::ReleaseSessionId(const size_t session_id) {
|
void Manager::ReleaseSessionId(Core::System& system, const size_t session_id) {
|
||||||
std::scoped_lock l{mutex};
|
std::scoped_lock l{mutex};
|
||||||
LOG_DEBUG(Service_Audio, "Freeing AudioIn session {}", session_id);
|
LOG_DEBUG(Service_Audio, "Freeing AudioIn session {}", session_id);
|
||||||
session_ids[free_session_id] = session_id;
|
session_ids[free_session_id] = session_id;
|
||||||
@@ -41,21 +41,20 @@ void Manager::ReleaseSessionId(const size_t session_id) {
|
|||||||
applet_resource_user_ids[session_id] = 0;
|
applet_resource_user_ids[session_id] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result Manager::LinkToManager() {
|
Result Manager::LinkToManager(Core::System& system) {
|
||||||
std::scoped_lock l{mutex};
|
std::scoped_lock l{mutex};
|
||||||
if (!linked_to_manager) {
|
if (!linked_to_manager) {
|
||||||
system.AudioCore().GetAudioManager().SetInManager(std::bind(&Manager::BufferReleaseAndRegister, this));
|
system.AudioCore().GetAudioManager().SetInManager(&Manager::BufferReleaseAndRegister);
|
||||||
linked_to_manager = true;
|
linked_to_manager = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::Start() {
|
void Manager::Start(Core::System& system) {
|
||||||
if (sessions_started) {
|
if (sessions_started) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::scoped_lock l{mutex};
|
std::scoped_lock l{mutex};
|
||||||
for (auto& session : sessions) {
|
for (auto& session : sessions) {
|
||||||
if (session) {
|
if (session) {
|
||||||
@@ -66,21 +65,19 @@ void Manager::Start() {
|
|||||||
sessions_started = true;
|
sessions_started = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::BufferReleaseAndRegister() {
|
void Manager::BufferReleaseAndRegister(void *data, Core::System& system) noexcept {
|
||||||
std::scoped_lock l{mutex};
|
Manager* this_ = (Manager*)data;
|
||||||
for (auto& session : sessions) {
|
std::scoped_lock l{this_->mutex};
|
||||||
|
for (auto& session : this_->sessions) {
|
||||||
if (session != nullptr) {
|
if (session != nullptr) {
|
||||||
session->ReleaseAndRegisterBuffers();
|
session->ReleaseAndRegisterBuffers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 Manager::GetDeviceNames(std::span<Renderer::AudioDevice::AudioDeviceName> names,
|
u32 Manager::GetDeviceNames(Core::System& system, std::span<Renderer::AudioDevice::AudioDeviceName> names, [[maybe_unused]] const bool filter) {
|
||||||
[[maybe_unused]] const bool filter) {
|
|
||||||
std::scoped_lock l{mutex};
|
std::scoped_lock l{mutex};
|
||||||
|
LinkToManager(system);
|
||||||
LinkToManager();
|
|
||||||
|
|
||||||
auto input_devices{Sink::GetDeviceListForSink(Settings::values.sink_id.GetValue(), true)};
|
auto input_devices{Sink::GetDeviceListForSink(Settings::values.sink_id.GetValue(), true)};
|
||||||
if (!input_devices.empty() && !names.empty()) {
|
if (!input_devices.empty() && !names.empty()) {
|
||||||
names[0] = Renderer::AudioDevice::AudioDeviceName("Uac");
|
names[0] = Renderer::AudioDevice::AudioDeviceName("Uac");
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -30,31 +33,29 @@ public:
|
|||||||
* @param session_id - Output session_id.
|
* @param session_id - Output session_id.
|
||||||
* @return Result code.
|
* @return Result code.
|
||||||
*/
|
*/
|
||||||
Result AcquireSessionId(size_t& session_id);
|
Result AcquireSessionId(Core::System& system, size_t& session_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Release a session id on close.
|
* Release a session id on close.
|
||||||
*
|
*
|
||||||
* @param session_id - Session id to free.
|
* @param session_id - Session id to free.
|
||||||
*/
|
*/
|
||||||
void ReleaseSessionId(size_t session_id);
|
void ReleaseSessionId(Core::System& system, const size_t session_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Link the audio in manager to the main audio manager.
|
* Link the audio in manager to the main audio manager.
|
||||||
*
|
*
|
||||||
* @return Result code.
|
* @return Result code.
|
||||||
*/
|
*/
|
||||||
Result LinkToManager();
|
Result LinkToManager(Core::System& system);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start the audio in manager.
|
* Start the audio in manager.
|
||||||
*/
|
*/
|
||||||
void Start();
|
void Start(Core::System& system);
|
||||||
|
|
||||||
/**
|
/// @brief Callback function, called by the audio manager when the audio in event is signalled.
|
||||||
* Callback function, called by the audio manager when the audio in event is signalled.
|
static void BufferReleaseAndRegister(void *data, Core::System& system) noexcept;
|
||||||
*/
|
|
||||||
void BufferReleaseAndRegister();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of audio in device names.
|
* Get a list of audio in device names.
|
||||||
@@ -64,10 +65,8 @@ public:
|
|||||||
*
|
*
|
||||||
* @return Number of names written.
|
* @return Number of names written.
|
||||||
*/
|
*/
|
||||||
u32 GetDeviceNames(std::span<Renderer::AudioDevice::AudioDeviceName> names, bool filter);
|
u32 GetDeviceNames(Core::System& system, std::span<Renderer::AudioDevice::AudioDeviceName> names, bool filter);
|
||||||
|
|
||||||
/// Core system
|
|
||||||
Core::System& system;
|
|
||||||
/// Array of session ids
|
/// Array of session ids
|
||||||
std::array<size_t, MaxInSessions> session_ids{};
|
std::array<size_t, MaxInSessions> session_ids{};
|
||||||
/// Array of resource user ids
|
/// Array of resource user ids
|
||||||
|
|||||||
@@ -11,8 +11,8 @@
|
|||||||
|
|
||||||
namespace AudioCore {
|
namespace AudioCore {
|
||||||
|
|
||||||
AudioManager::AudioManager() {
|
AudioManager::AudioManager(Core::System& system) {
|
||||||
thread = std::jthread([this](std::stop_token stop_token) {
|
thread = std::jthread([&](std::stop_token stop_token) {
|
||||||
Common::SetCurrentThreadName("AudioManager");
|
Common::SetCurrentThreadName("AudioManager");
|
||||||
std::unique_lock l{events.GetAudioEventLock()};
|
std::unique_lock l{events.GetAudioEventLock()};
|
||||||
events.ClearEvents();
|
events.ClearEvents();
|
||||||
@@ -25,7 +25,7 @@ AudioManager::AudioManager() {
|
|||||||
const auto event_type = Event::Type(i);
|
const auto event_type = Event::Type(i);
|
||||||
if (events.CheckAudioEventSet(event_type) || timed_out) {
|
if (events.CheckAudioEventSet(event_type) || timed_out) {
|
||||||
if (buffer_events[i]) {
|
if (buffer_events[i]) {
|
||||||
buffer_events[i]();
|
buffer_events[i](this, system);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
events.SetAudioEvent(event_type, false);
|
events.SetAudioEvent(event_type, false);
|
||||||
|
|||||||
@@ -16,6 +16,10 @@
|
|||||||
|
|
||||||
#include "audio_core/audio_event.h"
|
#include "audio_core/audio_event.h"
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
|
||||||
union Result;
|
union Result;
|
||||||
|
|
||||||
namespace AudioCore {
|
namespace AudioCore {
|
||||||
@@ -34,10 +38,9 @@ namespace AudioCore {
|
|||||||
* This is only used by audio in and audio out.
|
* This is only used by audio in and audio out.
|
||||||
*/
|
*/
|
||||||
class AudioManager {
|
class AudioManager {
|
||||||
using BufferEventFunc = std::function<void()>;
|
using BufferEventFunc = void (*)(void *data, Core::System& system) noexcept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit AudioManager();
|
explicit AudioManager(Core::System& system);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shutdown the audio manager.
|
* Shutdown the audio manager.
|
||||||
|
|||||||
@@ -14,12 +14,12 @@
|
|||||||
|
|
||||||
namespace AudioCore::AudioOut {
|
namespace AudioCore::AudioOut {
|
||||||
|
|
||||||
Manager::Manager(Core::System& system_) : system{system_} {
|
Manager::Manager(Core::System& system) {
|
||||||
std::iota(session_ids.begin(), session_ids.end(), 0);
|
std::iota(session_ids.begin(), session_ids.end(), 0);
|
||||||
num_free_sessions = MaxOutSessions;
|
num_free_sessions = MaxOutSessions;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result Manager::AcquireSessionId(size_t& session_id) {
|
Result Manager::AcquireSessionId(Core::System& system, size_t& session_id) {
|
||||||
if (num_free_sessions == 0) {
|
if (num_free_sessions == 0) {
|
||||||
LOG_ERROR(Service_Audio, "All 12 Audio Out sessions are in use, cannot create any more");
|
LOG_ERROR(Service_Audio, "All 12 Audio Out sessions are in use, cannot create any more");
|
||||||
return Service::Audio::ResultOutOfSessions;
|
return Service::Audio::ResultOutOfSessions;
|
||||||
@@ -30,7 +30,7 @@ Result Manager::AcquireSessionId(size_t& session_id) {
|
|||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::ReleaseSessionId(const size_t session_id) {
|
void Manager::ReleaseSessionId(Core::System& system, const size_t session_id) {
|
||||||
std::scoped_lock l{mutex};
|
std::scoped_lock l{mutex};
|
||||||
LOG_DEBUG(Service_Audio, "Freeing AudioOut session {}", session_id);
|
LOG_DEBUG(Service_Audio, "Freeing AudioOut session {}", session_id);
|
||||||
session_ids[free_session_id] = session_id;
|
session_ids[free_session_id] = session_id;
|
||||||
@@ -40,17 +40,17 @@ void Manager::ReleaseSessionId(const size_t session_id) {
|
|||||||
applet_resource_user_ids[session_id] = 0;
|
applet_resource_user_ids[session_id] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result Manager::LinkToManager() {
|
Result Manager::LinkToManager(Core::System& system) {
|
||||||
std::scoped_lock l{mutex};
|
std::scoped_lock l{mutex};
|
||||||
if (!linked_to_manager) {
|
if (!linked_to_manager) {
|
||||||
system.AudioCore().GetAudioManager().SetOutManager(std::bind(&Manager::BufferReleaseAndRegister, this));
|
system.AudioCore().GetAudioManager().SetOutManager(&Manager::BufferReleaseAndRegister);
|
||||||
linked_to_manager = true;
|
linked_to_manager = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::Start() {
|
void Manager::Start(Core::System& system) {
|
||||||
if (sessions_started) {
|
if (sessions_started) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -65,19 +65,14 @@ void Manager::Start() {
|
|||||||
sessions_started = true;
|
sessions_started = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::BufferReleaseAndRegister() {
|
void Manager::BufferReleaseAndRegister(void *data, Core::System& system) noexcept {
|
||||||
std::scoped_lock l{mutex};
|
Manager* this_ = (Manager*)data;
|
||||||
for (auto& session : sessions) {
|
std::scoped_lock l{this_->mutex};
|
||||||
|
for (auto& session : this_->sessions) {
|
||||||
if (session != nullptr) {
|
if (session != nullptr) {
|
||||||
session->ReleaseAndRegisterBuffers();
|
session->ReleaseAndRegisterBuffers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 Manager::GetAudioOutDeviceNames(
|
|
||||||
std::vector<Renderer::AudioDevice::AudioDeviceName>& names) const {
|
|
||||||
names.emplace_back("DeviceOut");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace AudioCore::AudioOut
|
} // namespace AudioCore::AudioOut
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -29,42 +32,32 @@ public:
|
|||||||
* @param session_id - Output session_id.
|
* @param session_id - Output session_id.
|
||||||
* @return Result code.
|
* @return Result code.
|
||||||
*/
|
*/
|
||||||
Result AcquireSessionId(size_t& session_id);
|
Result AcquireSessionId(Core::System& system, size_t& session_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Release a session id on close.
|
* Release a session id on close.
|
||||||
*
|
*
|
||||||
* @param session_id - Session id to free.
|
* @param session_id - Session id to free.
|
||||||
*/
|
*/
|
||||||
void ReleaseSessionId(size_t session_id);
|
void ReleaseSessionId(Core::System& system, const size_t session_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Link this manager to the main audio manager.
|
* Link this manager to the main audio manager.
|
||||||
*
|
*
|
||||||
* @return Result code.
|
* @return Result code.
|
||||||
*/
|
*/
|
||||||
Result LinkToManager();
|
Result LinkToManager(Core::System& system);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start the audio out manager.
|
* Start the audio out manager.
|
||||||
*/
|
*/
|
||||||
void Start();
|
void Start(Core::System& system);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback function, called by the audio manager when the audio out event is signalled.
|
* Callback function, called by the audio manager when the audio out event is signalled.
|
||||||
*/
|
*/
|
||||||
void BufferReleaseAndRegister();
|
static void BufferReleaseAndRegister(void* data, Core::System& system) noexcept;
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a list of audio out device names.
|
|
||||||
*
|
|
||||||
* @param names - Output container to write names to.
|
|
||||||
* @return Number of names written.
|
|
||||||
*/
|
|
||||||
u32 GetAudioOutDeviceNames(std::vector<Renderer::AudioDevice::AudioDeviceName>& names) const;
|
|
||||||
|
|
||||||
/// Core system
|
|
||||||
Core::System& system;
|
|
||||||
/// Array of session ids
|
/// Array of session ids
|
||||||
std::array<size_t, MaxOutSessions> session_ids{};
|
std::array<size_t, MaxOutSessions> session_ids{};
|
||||||
/// Array of resource user ids
|
/// Array of resource user ids
|
||||||
|
|||||||
@@ -1,15 +1,20 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include "audio_core/audio_render_manager.h"
|
#include "audio_core/audio_render_manager.h"
|
||||||
#include "audio_core/common/audio_renderer_parameter.h"
|
#include "audio_core/common/audio_renderer_parameter.h"
|
||||||
|
#include "audio_core/renderer/system_manager.h"
|
||||||
#include "audio_core/common/feature_support.h"
|
#include "audio_core/common/feature_support.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
|
|
||||||
namespace AudioCore::Renderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
Manager::Manager(Core::System& system_)
|
Manager::Manager(Core::System& system_)
|
||||||
: system{system_}, system_manager{std::make_unique<SystemManager>(system)} {
|
: system_manager{std::make_unique<SystemManager>(system_)}
|
||||||
|
{
|
||||||
std::iota(session_ids.begin(), session_ids.end(), 0);
|
std::iota(session_ids.begin(), session_ids.end(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,11 +64,11 @@ u32 Manager::GetSessionCount() const {
|
|||||||
return session_count;
|
return session_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Manager::AddSystem(System& system_) {
|
bool Manager::AddSystem(Renderer::System& system_) {
|
||||||
return system_manager->Add(system_);
|
return system_manager->Add(system_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Manager::RemoveSystem(System& system_) {
|
bool Manager::RemoveSystem(Renderer::System& system_) {
|
||||||
return system_manager->Remove(system_);
|
return system_manager->Remove(system_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -71,7 +74,7 @@ public:
|
|||||||
* @param system - The system to add.
|
* @param system - The system to add.
|
||||||
* @return True if the system was successfully added, otherwise false.
|
* @return True if the system was successfully added, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool AddSystem(System& system);
|
bool AddSystem(Renderer::System& system);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a renderer system from the manager.
|
* Remove a renderer system from the manager.
|
||||||
@@ -79,7 +82,7 @@ public:
|
|||||||
* @param system - The system to remove.
|
* @param system - The system to remove.
|
||||||
* @return True if the system was successfully removed, otherwise false.
|
* @return True if the system was successfully removed, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool RemoveSystem(System& system);
|
bool RemoveSystem(Renderer::System& system);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free a session id when the system wants to shut down.
|
* Free a session id when the system wants to shut down.
|
||||||
@@ -89,8 +92,6 @@ public:
|
|||||||
void ReleaseSessionId(s32 session_id);
|
void ReleaseSessionId(s32 session_id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Core system
|
|
||||||
Core::System& system;
|
|
||||||
/// Session ids, -1 when in use
|
/// Session ids, -1 when in use
|
||||||
std::array<s32, MaxRendererSessions> session_ids{};
|
std::array<s32, MaxRendererSessions> session_ids{};
|
||||||
/// Number of active renderers
|
/// Number of active renderers
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -16,8 +19,9 @@ namespace AudioCore {
|
|||||||
*/
|
*/
|
||||||
class WorkbufferAllocator {
|
class WorkbufferAllocator {
|
||||||
public:
|
public:
|
||||||
explicit WorkbufferAllocator(std::span<u8> buffer_, u64 size_)
|
explicit WorkbufferAllocator(std::span<u8> buffer_)
|
||||||
: buffer{reinterpret_cast<u64>(buffer_.data())}, size{size_} {}
|
: buffer{buffer_}
|
||||||
|
{}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate the given count of T elements, aligned to alignment.
|
* Allocate the given count of T elements, aligned to alignment.
|
||||||
@@ -29,36 +33,31 @@ public:
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
std::span<T> Allocate(u64 count, u64 alignment) {
|
std::span<T> Allocate(u64 count, u64 alignment) {
|
||||||
u64 out{0};
|
u64 out{0};
|
||||||
u64 byte_size{count * sizeof(T)};
|
u64 byte_size = count * sizeof(T);
|
||||||
|
|
||||||
if (byte_size > 0) {
|
if (byte_size > 0) {
|
||||||
auto current{buffer + offset};
|
auto current{uintptr_t(buffer.data()) + offset};
|
||||||
auto aligned_buffer{Common::AlignUp(current, alignment)};
|
auto aligned_buffer{Common::AlignUp(current, alignment)};
|
||||||
if (aligned_buffer + byte_size <= buffer + size) {
|
if (aligned_buffer + byte_size <= uintptr_t(buffer.data()) + buffer.size()) {
|
||||||
out = aligned_buffer;
|
out = aligned_buffer;
|
||||||
offset = byte_size - buffer + aligned_buffer;
|
offset = byte_size - uintptr_t(buffer.data()) + aligned_buffer;
|
||||||
} else {
|
} else {
|
||||||
LOG_ERROR(
|
LOG_ERROR(
|
||||||
Service_Audio,
|
Service_Audio,
|
||||||
"Allocated buffer was too small to hold new alloc.\nAllocator size={:08X}, "
|
"Allocated buffer was too small to hold new alloc.\nAllocator size={:08X}, "
|
||||||
"offset={:08X}.\nAttempting to allocate {:08X} with alignment={:02X}",
|
"offset={:08X}.\nAttempting to allocate {:08X} with alignment={:02X}",
|
||||||
size, offset, byte_size, alignment);
|
buffer.size(), offset, byte_size, alignment);
|
||||||
count = 0;
|
count = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::span<T>(reinterpret_cast<T*>(out), count);
|
return std::span<T>(reinterpret_cast<T*>(out), count);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// @brief Align the current offset to the given alignment.
|
||||||
* Align the current offset to the given alignment.
|
/// @param alignment - The required starting alignment.
|
||||||
*
|
|
||||||
* @param alignment - The required starting alignment.
|
|
||||||
*/
|
|
||||||
void Align(u64 alignment) {
|
void Align(u64 alignment) {
|
||||||
auto current{buffer + offset};
|
auto current{uintptr_t(buffer.data()) + offset};
|
||||||
auto aligned_buffer{Common::AlignUp(current, alignment)};
|
auto aligned_buffer{Common::AlignUp(current, alignment)};
|
||||||
offset = 0 - buffer + aligned_buffer;
|
offset = 0 - uintptr_t(buffer.data()) + aligned_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -76,7 +75,7 @@ public:
|
|||||||
* @return The size of the current buffer.
|
* @return The size of the current buffer.
|
||||||
*/
|
*/
|
||||||
u64 GetSize() const {
|
u64 GetSize() const {
|
||||||
return size;
|
return buffer.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -85,14 +84,11 @@ public:
|
|||||||
* @return The remaining size left in the buffer.
|
* @return The remaining size left in the buffer.
|
||||||
*/
|
*/
|
||||||
u64 GetRemainingSize() const {
|
u64 GetRemainingSize() const {
|
||||||
return size - offset;
|
return buffer.size() - offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// The buffer into which we are allocating.
|
const std::span<u8> buffer;
|
||||||
u64 buffer;
|
|
||||||
/// Size of the buffer we're allocating to.
|
|
||||||
u64 size;
|
|
||||||
/// Current offset into the buffer, an error will be thrown if it exceeds size.
|
/// Current offset into the buffer, an error will be thrown if it exceeds size.
|
||||||
u64 offset{};
|
u64 offset{};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -8,42 +11,43 @@
|
|||||||
namespace AudioCore::AudioIn {
|
namespace AudioCore::AudioIn {
|
||||||
|
|
||||||
In::In(Core::System& system_, Manager& manager_, Kernel::KEvent* event_, size_t session_id_)
|
In::In(Core::System& system_, Manager& manager_, Kernel::KEvent* event_, size_t session_id_)
|
||||||
: manager{manager_}, parent_mutex{manager.mutex}, event{event_}, system{system_, event,
|
: manager{manager_}, parent_mutex{manager.mutex}, event{event_}
|
||||||
session_id_} {}
|
, audio_system{system_, event, session_id_}
|
||||||
|
{}
|
||||||
|
|
||||||
void In::Free() {
|
void In::Free(Core::System& system) {
|
||||||
std::scoped_lock l{parent_mutex};
|
std::scoped_lock l{parent_mutex};
|
||||||
manager.ReleaseSessionId(system.GetSessionId());
|
manager.ReleaseSessionId(system, audio_system.GetSessionId());
|
||||||
}
|
}
|
||||||
|
|
||||||
System& In::GetSystem() {
|
System& In::GetSystem() {
|
||||||
return system;
|
return audio_system;
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioIn::State In::GetState() {
|
AudioIn::State In::GetState() {
|
||||||
std::scoped_lock l{parent_mutex};
|
std::scoped_lock l{parent_mutex};
|
||||||
return system.GetState();
|
return audio_system.GetState();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result In::StartSystem() {
|
Result In::StartSystem() {
|
||||||
std::scoped_lock l{parent_mutex};
|
std::scoped_lock l{parent_mutex};
|
||||||
return system.Start();
|
return audio_system.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void In::StartSession() {
|
void In::StartSession() {
|
||||||
std::scoped_lock l{parent_mutex};
|
std::scoped_lock l{parent_mutex};
|
||||||
system.StartSession();
|
audio_system.StartSession();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result In::StopSystem() {
|
Result In::StopSystem() {
|
||||||
std::scoped_lock l{parent_mutex};
|
std::scoped_lock l{parent_mutex};
|
||||||
return system.Stop();
|
return audio_system.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result In::AppendBuffer(const AudioInBuffer& buffer, u64 tag) {
|
Result In::AppendBuffer(const AudioInBuffer& buffer, u64 tag) {
|
||||||
std::scoped_lock l{parent_mutex};
|
std::scoped_lock l{parent_mutex};
|
||||||
|
|
||||||
if (system.AppendBuffer(buffer, tag)) {
|
if (audio_system.AppendBuffer(buffer, tag)) {
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
return Service::Audio::ResultBufferCountReached;
|
return Service::Audio::ResultBufferCountReached;
|
||||||
@@ -51,20 +55,20 @@ Result In::AppendBuffer(const AudioInBuffer& buffer, u64 tag) {
|
|||||||
|
|
||||||
void In::ReleaseAndRegisterBuffers() {
|
void In::ReleaseAndRegisterBuffers() {
|
||||||
std::scoped_lock l{parent_mutex};
|
std::scoped_lock l{parent_mutex};
|
||||||
if (system.GetState() == State::Started) {
|
if (audio_system.GetState() == State::Started) {
|
||||||
system.ReleaseBuffers();
|
audio_system.ReleaseBuffers();
|
||||||
system.RegisterBuffers();
|
audio_system.RegisterBuffers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool In::FlushAudioInBuffers() {
|
bool In::FlushAudioInBuffers() {
|
||||||
std::scoped_lock l{parent_mutex};
|
std::scoped_lock l{parent_mutex};
|
||||||
return system.FlushAudioInBuffers();
|
return audio_system.FlushAudioInBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 In::GetReleasedBuffers(std::span<u64> tags) {
|
u32 In::GetReleasedBuffers(std::span<u64> tags) {
|
||||||
std::scoped_lock l{parent_mutex};
|
std::scoped_lock l{parent_mutex};
|
||||||
return system.GetReleasedBuffers(tags);
|
return audio_system.GetReleasedBuffers(tags);
|
||||||
}
|
}
|
||||||
|
|
||||||
Kernel::KReadableEvent& In::GetBufferEvent() {
|
Kernel::KReadableEvent& In::GetBufferEvent() {
|
||||||
@@ -74,27 +78,27 @@ Kernel::KReadableEvent& In::GetBufferEvent() {
|
|||||||
|
|
||||||
f32 In::GetVolume() const {
|
f32 In::GetVolume() const {
|
||||||
std::scoped_lock l{parent_mutex};
|
std::scoped_lock l{parent_mutex};
|
||||||
return system.GetVolume();
|
return audio_system.GetVolume();
|
||||||
}
|
}
|
||||||
|
|
||||||
void In::SetVolume(f32 volume) {
|
void In::SetVolume(f32 volume) {
|
||||||
std::scoped_lock l{parent_mutex};
|
std::scoped_lock l{parent_mutex};
|
||||||
system.SetVolume(volume);
|
audio_system.SetVolume(volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool In::ContainsAudioBuffer(u64 tag) const {
|
bool In::ContainsAudioBuffer(u64 tag) const {
|
||||||
std::scoped_lock l{parent_mutex};
|
std::scoped_lock l{parent_mutex};
|
||||||
return system.ContainsAudioBuffer(tag);
|
return audio_system.ContainsAudioBuffer(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 In::GetBufferCount() const {
|
u32 In::GetBufferCount() const {
|
||||||
std::scoped_lock l{parent_mutex};
|
std::scoped_lock l{parent_mutex};
|
||||||
return system.GetBufferCount();
|
return audio_system.GetBufferCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 In::GetPlayedSampleCount() const {
|
u64 In::GetPlayedSampleCount() const {
|
||||||
std::scoped_lock l{parent_mutex};
|
std::scoped_lock l{parent_mutex};
|
||||||
return system.GetPlayedSampleCount();
|
return audio_system.GetPlayedSampleCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioIn
|
} // namespace AudioCore::AudioIn
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -30,7 +33,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Free this audio in from the audio in manager.
|
* Free this audio in from the audio in manager.
|
||||||
*/
|
*/
|
||||||
void Free();
|
void Free(Core::System& system);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get this audio in's system.
|
* Get this audio in's system.
|
||||||
@@ -141,7 +144,7 @@ private:
|
|||||||
/// Buffer event, signalled when buffers are ready to be released
|
/// Buffer event, signalled when buffers are ready to be released
|
||||||
Kernel::KEvent* event;
|
Kernel::KEvent* event;
|
||||||
/// Main audio in system
|
/// Main audio in system
|
||||||
System system;
|
System audio_system;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioIn
|
} // namespace AudioCore::AudioIn
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -8,42 +11,43 @@
|
|||||||
namespace AudioCore::AudioOut {
|
namespace AudioCore::AudioOut {
|
||||||
|
|
||||||
Out::Out(Core::System& system_, Manager& manager_, Kernel::KEvent* event_, size_t session_id_)
|
Out::Out(Core::System& system_, Manager& manager_, Kernel::KEvent* event_, size_t session_id_)
|
||||||
: manager{manager_}, parent_mutex{manager.mutex}, event{event_}, system{system_, event,
|
: manager{manager_}, parent_mutex{manager.mutex}, event{event_}
|
||||||
session_id_} {}
|
, audio_system{system_, event, session_id_}
|
||||||
|
{}
|
||||||
|
|
||||||
void Out::Free() {
|
void Out::Free(Core::System& system) {
|
||||||
std::scoped_lock l{parent_mutex};
|
std::scoped_lock l{parent_mutex};
|
||||||
manager.ReleaseSessionId(system.GetSessionId());
|
manager.ReleaseSessionId(system, audio_system.GetSessionId());
|
||||||
}
|
}
|
||||||
|
|
||||||
System& Out::GetSystem() {
|
System& Out::GetSystem() {
|
||||||
return system;
|
return audio_system;
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioOut::State Out::GetState() {
|
AudioOut::State Out::GetState() {
|
||||||
std::scoped_lock l{parent_mutex};
|
std::scoped_lock l{parent_mutex};
|
||||||
return system.GetState();
|
return audio_system.GetState();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result Out::StartSystem() {
|
Result Out::StartSystem() {
|
||||||
std::scoped_lock l{parent_mutex};
|
std::scoped_lock l{parent_mutex};
|
||||||
return system.Start();
|
return audio_system.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Out::StartSession() {
|
void Out::StartSession() {
|
||||||
std::scoped_lock l{parent_mutex};
|
std::scoped_lock l{parent_mutex};
|
||||||
system.StartSession();
|
audio_system.StartSession();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result Out::StopSystem() {
|
Result Out::StopSystem() {
|
||||||
std::scoped_lock l{parent_mutex};
|
std::scoped_lock l{parent_mutex};
|
||||||
return system.Stop();
|
return audio_system.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result Out::AppendBuffer(const AudioOutBuffer& buffer, const u64 tag) {
|
Result Out::AppendBuffer(const AudioOutBuffer& buffer, const u64 tag) {
|
||||||
std::scoped_lock l{parent_mutex};
|
std::scoped_lock l{parent_mutex};
|
||||||
|
|
||||||
if (system.AppendBuffer(buffer, tag)) {
|
if (audio_system.AppendBuffer(buffer, tag)) {
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
return Service::Audio::ResultBufferCountReached;
|
return Service::Audio::ResultBufferCountReached;
|
||||||
@@ -51,20 +55,20 @@ Result Out::AppendBuffer(const AudioOutBuffer& buffer, const u64 tag) {
|
|||||||
|
|
||||||
void Out::ReleaseAndRegisterBuffers() {
|
void Out::ReleaseAndRegisterBuffers() {
|
||||||
std::scoped_lock l{parent_mutex};
|
std::scoped_lock l{parent_mutex};
|
||||||
if (system.GetState() == State::Started) {
|
if (audio_system.GetState() == State::Started) {
|
||||||
system.ReleaseBuffers();
|
audio_system.ReleaseBuffers();
|
||||||
system.RegisterBuffers();
|
audio_system.RegisterBuffers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Out::FlushAudioOutBuffers() {
|
bool Out::FlushAudioOutBuffers() {
|
||||||
std::scoped_lock l{parent_mutex};
|
std::scoped_lock l{parent_mutex};
|
||||||
return system.FlushAudioOutBuffers();
|
return audio_system.FlushAudioOutBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 Out::GetReleasedBuffers(std::span<u64> tags) {
|
u32 Out::GetReleasedBuffers(std::span<u64> tags) {
|
||||||
std::scoped_lock l{parent_mutex};
|
std::scoped_lock l{parent_mutex};
|
||||||
return system.GetReleasedBuffers(tags);
|
return audio_system.GetReleasedBuffers(tags);
|
||||||
}
|
}
|
||||||
|
|
||||||
Kernel::KReadableEvent& Out::GetBufferEvent() {
|
Kernel::KReadableEvent& Out::GetBufferEvent() {
|
||||||
@@ -74,27 +78,27 @@ Kernel::KReadableEvent& Out::GetBufferEvent() {
|
|||||||
|
|
||||||
f32 Out::GetVolume() const {
|
f32 Out::GetVolume() const {
|
||||||
std::scoped_lock l{parent_mutex};
|
std::scoped_lock l{parent_mutex};
|
||||||
return system.GetVolume();
|
return audio_system.GetVolume();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Out::SetVolume(const f32 volume) {
|
void Out::SetVolume(const f32 volume) {
|
||||||
std::scoped_lock l{parent_mutex};
|
std::scoped_lock l{parent_mutex};
|
||||||
system.SetVolume(volume);
|
audio_system.SetVolume(volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Out::ContainsAudioBuffer(const u64 tag) const {
|
bool Out::ContainsAudioBuffer(const u64 tag) const {
|
||||||
std::scoped_lock l{parent_mutex};
|
std::scoped_lock l{parent_mutex};
|
||||||
return system.ContainsAudioBuffer(tag);
|
return audio_system.ContainsAudioBuffer(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 Out::GetBufferCount() const {
|
u32 Out::GetBufferCount() const {
|
||||||
std::scoped_lock l{parent_mutex};
|
std::scoped_lock l{parent_mutex};
|
||||||
return system.GetBufferCount();
|
return audio_system.GetBufferCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 Out::GetPlayedSampleCount() const {
|
u64 Out::GetPlayedSampleCount() const {
|
||||||
std::scoped_lock l{parent_mutex};
|
std::scoped_lock l{parent_mutex};
|
||||||
return system.GetPlayedSampleCount();
|
return audio_system.GetPlayedSampleCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::AudioOut
|
} // namespace AudioCore::AudioOut
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -30,7 +33,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Free this audio out from the audio out manager.
|
* Free this audio out from the audio out manager.
|
||||||
*/
|
*/
|
||||||
void Free();
|
void Free(Core::System& system);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get this audio out's system.
|
* Get this audio out's system.
|
||||||
@@ -141,7 +144,7 @@ private:
|
|||||||
/// Buffer event, signalled when buffers are ready to be released
|
/// Buffer event, signalled when buffers are ready to be released
|
||||||
Kernel::KEvent* event;
|
Kernel::KEvent* event;
|
||||||
/// Main audio out system
|
/// Main audio out system
|
||||||
System system;
|
System audio_system;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioOut
|
} // namespace AudioCore::AudioOut
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -13,56 +16,48 @@
|
|||||||
namespace AudioCore::Renderer {
|
namespace AudioCore::Renderer {
|
||||||
|
|
||||||
Renderer::Renderer(Core::System& system_, Manager& manager_, Kernel::KEvent* rendered_event)
|
Renderer::Renderer(Core::System& system_, Manager& manager_, Kernel::KEvent* rendered_event)
|
||||||
: core{system_}, manager{manager_}, system{system_, rendered_event} {}
|
: system{system_}, manager{manager_}
|
||||||
|
, audio_system{system_, rendered_event}
|
||||||
|
{}
|
||||||
|
|
||||||
Result Renderer::Initialize(const AudioRendererParameterInternal& params,
|
Result Renderer::Initialize(const AudioRendererParameterInternal& params, Kernel::KTransferMemory* transfer_memory, const u64 transfer_memory_size, Kernel::KProcess* process_handle, const u64 applet_resource_user_id, const s32 session_id) {
|
||||||
Kernel::KTransferMemory* transfer_memory,
|
|
||||||
const u64 transfer_memory_size, Kernel::KProcess* process_handle,
|
|
||||||
const u64 applet_resource_user_id, const s32 session_id) {
|
|
||||||
if (params.execution_mode == ExecutionMode::Auto) {
|
if (params.execution_mode == ExecutionMode::Auto) {
|
||||||
if (!manager.AddSystem(system)) {
|
if (!manager.AddSystem(audio_system)) {
|
||||||
LOG_ERROR(Service_Audio,
|
LOG_ERROR(Service_Audio, "Both Audio Render sessions are in use, cannot create any more");
|
||||||
"Both Audio Render sessions are in use, cannot create any more");
|
|
||||||
return Service::Audio::ResultOutOfSessions;
|
return Service::Audio::ResultOutOfSessions;
|
||||||
}
|
}
|
||||||
system_registered = true;
|
system_registered = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
initialized = true;
|
initialized = true;
|
||||||
system.Initialize(params, transfer_memory, transfer_memory_size, process_handle,
|
audio_system.Initialize(params, transfer_memory, transfer_memory_size, process_handle, applet_resource_user_id, session_id);
|
||||||
applet_resource_user_id, session_id);
|
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::Finalize() {
|
void Renderer::Finalize() {
|
||||||
auto session_id{system.GetSessionId()};
|
auto const session_id{audio_system.GetSessionId()};
|
||||||
|
audio_system.Finalize();
|
||||||
system.Finalize();
|
|
||||||
|
|
||||||
if (system_registered) {
|
if (system_registered) {
|
||||||
manager.RemoveSystem(system);
|
manager.RemoveSystem(audio_system);
|
||||||
system_registered = false;
|
system_registered = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
manager.ReleaseSessionId(session_id);
|
manager.ReleaseSessionId(session_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
System& Renderer::GetSystem() {
|
System& Renderer::GetSystem() {
|
||||||
return system;
|
return audio_system;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::Start() {
|
void Renderer::Start() {
|
||||||
system.Start();
|
audio_system.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::Stop() {
|
void Renderer::Stop() {
|
||||||
system.Stop();
|
audio_system.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result Renderer::RequestUpdate(std::span<const u8> input, std::span<u8> performance,
|
Result Renderer::RequestUpdate(std::span<const u8> input, std::span<u8> performance, std::span<u8> output) {
|
||||||
std::span<u8> output) {
|
return audio_system.Update(input, performance, output);
|
||||||
return system.Update(input, performance, output);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::Renderer
|
} // namespace AudioCore::Renderer
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -84,7 +87,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
/// System core
|
/// System core
|
||||||
Core::System& core;
|
Core::System& system;
|
||||||
/// Manager this renderer is registered with
|
/// Manager this renderer is registered with
|
||||||
Manager& manager;
|
Manager& manager;
|
||||||
/// Is the audio renderer initialized?
|
/// Is the audio renderer initialized?
|
||||||
@@ -92,7 +95,7 @@ private:
|
|||||||
/// Is the system registered with the manager?
|
/// Is the system registered with the manager?
|
||||||
bool system_registered{};
|
bool system_registered{};
|
||||||
/// Audio render system, main driver of audio rendering
|
/// Audio render system, main driver of audio rendering
|
||||||
System system;
|
System audio_system;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Renderer
|
} // namespace Renderer
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
|
|||||||
PoolMapper pool_mapper(process_handle, false);
|
PoolMapper pool_mapper(process_handle, false);
|
||||||
pool_mapper.InitializeSystemPool(memory_pool_info, workbuffer.get(), workbuffer_size);
|
pool_mapper.InitializeSystemPool(memory_pool_info, workbuffer.get(), workbuffer_size);
|
||||||
|
|
||||||
WorkbufferAllocator allocator({workbuffer.get(), workbuffer_size}, workbuffer_size);
|
WorkbufferAllocator allocator({workbuffer.get(), workbuffer_size});
|
||||||
|
|
||||||
samples_workbuffer =
|
samples_workbuffer =
|
||||||
allocator.Allocate<s32>((voice_channels + mix_buffer_count) * sample_count, 0x10);
|
allocator.Allocate<s32>((voice_channels + mix_buffer_count) * sample_count, 0x10);
|
||||||
|
|||||||
@@ -147,8 +147,7 @@ add_library(
|
|||||||
cpu_features.cpp
|
cpu_features.cpp
|
||||||
cpu_features.h
|
cpu_features.h
|
||||||
httplib.h
|
httplib.h
|
||||||
net/net.h net/net.cpp
|
net/net.h net/net.cpp)
|
||||||
container/unordered_map.h container/unordered_set.h)
|
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
target_sources(common PRIVATE windows/timer_resolution.cpp
|
target_sources(common PRIVATE windows/timer_resolution.cpp
|
||||||
@@ -242,7 +241,7 @@ if (lz4_ADDED)
|
|||||||
target_include_directories(common PRIVATE ${lz4_SOURCE_DIR}/lib)
|
target_include_directories(common PRIVATE ${lz4_SOURCE_DIR}/lib)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_link_libraries(common PUBLIC fmt::fmt stb::headers Threads::Threads)
|
target_link_libraries(common PUBLIC fmt::fmt stb::headers Threads::Threads unordered_dense::unordered_dense)
|
||||||
target_link_libraries(common PRIVATE lz4::lz4 zstd::zstd)
|
target_link_libraries(common PRIVATE lz4::lz4 zstd::zstd)
|
||||||
|
|
||||||
# Please refer to src/common/demangle.cpp
|
# Please refer to src/common/demangle.cpp
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "common/container_hash.h"
|
|
||||||
|
|
||||||
#include <boost/unordered/unordered_flat_map.hpp>
|
|
||||||
|
|
||||||
namespace Common {
|
|
||||||
|
|
||||||
template <class Key, class T, class Hash = std::hash<Key>, class Pred = std::equal_to<Key>,
|
|
||||||
class Allocator = std::allocator<std::pair<const Key, T>>>
|
|
||||||
using unordered_map = boost::unordered::unordered_flat_map<Key, T, Hash, Pred, Allocator>;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "common/container_hash.h"
|
|
||||||
|
|
||||||
#include <boost/unordered/unordered_flat_set.hpp>
|
|
||||||
|
|
||||||
namespace Common {
|
|
||||||
|
|
||||||
template <class Key, class Hash = std::hash<Key>, class Pred = std::equal_to<Key>,
|
|
||||||
class Allocator = std::allocator<Key>>
|
|
||||||
using unordered_set = boost::unordered::unordered_flat_set<Key, Hash, Pred, Allocator>;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -10,11 +10,8 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
#include <climits>
|
#include <climits>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <functional>
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <tuple>
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
@@ -72,17 +69,10 @@ struct HashCombineImpl<64> {
|
|||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires std::is_unsigned_v<T>
|
|
||||||
inline void HashCombine(std::size_t& seed, const T& v) {
|
inline void HashCombine(std::size_t& seed, const T& v) {
|
||||||
seed = detail::HashCombineImpl<sizeof(std::size_t) * CHAR_BIT>::fn(seed, detail::HashValue(v));
|
seed = detail::HashCombineImpl<sizeof(std::size_t) * CHAR_BIT>::fn(seed, detail::HashValue(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
requires (!std::is_unsigned_v<T>)
|
|
||||||
inline void HashCombine(std::size_t& seed, const T& v) {
|
|
||||||
seed = detail::HashCombineImpl<sizeof(std::size_t) * CHAR_BIT>::fn(seed, std::hash<T>{}(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename It>
|
template <typename It>
|
||||||
inline std::size_t HashRange(It first, It last) {
|
inline std::size_t HashRange(It first, It last) {
|
||||||
std::size_t seed = 0;
|
std::size_t seed = 0;
|
||||||
@@ -105,26 +95,3 @@ std::size_t HashValue(const std::vector<T, Allocator>& v) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Common
|
} // namespace Common
|
||||||
|
|
||||||
namespace std {
|
|
||||||
|
|
||||||
template <typename... Args>
|
|
||||||
struct hash<std::tuple<Args...>> {
|
|
||||||
std::size_t operator()(const std::tuple<Args...>& t) const noexcept {
|
|
||||||
std::size_t seed = 0;
|
|
||||||
std::apply([&seed](const Args&... args) { (Common::HashCombine(seed, args), ...); }, t);
|
|
||||||
return seed;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class A, class B>
|
|
||||||
struct hash<std::pair<A, B>> {
|
|
||||||
std::size_t operator()(const std::pair<A, B>& p) const noexcept {
|
|
||||||
std::size_t seed = 0;
|
|
||||||
Common::HashCombine(seed, p.first);
|
|
||||||
Common::HashCombine(seed, p.second);
|
|
||||||
return seed;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace std
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include "common/container/unordered_map.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/fs/fs.h"
|
#include "common/fs/fs.h"
|
||||||
@@ -196,8 +196,8 @@ private:
|
|||||||
SetLegacyPathImpl(legacy_path, new_path);
|
SetLegacyPathImpl(legacy_path, new_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
::Common::unordered_map<EdenPath, fs::path> eden_paths;
|
ankerl::unordered_dense::map<EdenPath, fs::path> eden_paths;
|
||||||
::Common::unordered_map<EmuPath, fs::path> legacy_paths;
|
ankerl::unordered_dense::map<EmuPath, fs::path> legacy_paths;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool ValidatePath(const fs::path& path) {
|
bool ValidatePath(const fs::path& path) {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include "common/container/unordered_map.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
#include <boost/icl/separate_interval_set.hpp>
|
#include <boost/icl/separate_interval_set.hpp>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include "common/dynamic_library.h"
|
#include "common/dynamic_library.h"
|
||||||
@@ -391,7 +391,7 @@ private:
|
|||||||
|
|
||||||
std::mutex placeholder_mutex; ///< Mutex for placeholders
|
std::mutex placeholder_mutex; ///< Mutex for placeholders
|
||||||
boost::icl::separate_interval_set<size_t> placeholders; ///< Mapped placeholders
|
boost::icl::separate_interval_set<size_t> placeholders; ///< Mapped placeholders
|
||||||
::Common::unordered_map<size_t, size_t> placeholder_host_pointers; ///< Placeholder backing offset
|
ankerl::unordered_dense::map<size_t, size_t> placeholder_host_pointers; ///< Placeholder backing offset
|
||||||
};
|
};
|
||||||
|
|
||||||
#elif defined(__OPENORBIS__) || defined(__managarm__)
|
#elif defined(__OPENORBIS__) || defined(__managarm__)
|
||||||
|
|||||||
+2
-2
@@ -9,7 +9,7 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "common/container/unordered_map.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "common/logging.h"
|
#include "common/logging.h"
|
||||||
@@ -412,7 +412,7 @@ public:
|
|||||||
namespace Impl {
|
namespace Impl {
|
||||||
|
|
||||||
template <typename InputDeviceType>
|
template <typename InputDeviceType>
|
||||||
using FactoryListType = ::Common::unordered_map<std::string, std::shared_ptr<Factory<InputDeviceType>>>;
|
using FactoryListType = ankerl::unordered_dense::map<std::string, std::shared_ptr<Factory<InputDeviceType>>>;
|
||||||
|
|
||||||
template <typename InputDeviceType>
|
template <typename InputDeviceType>
|
||||||
struct FactoryList {
|
struct FactoryList {
|
||||||
|
|||||||
+8
-20
@@ -329,7 +329,7 @@ struct LogcatBackend : public Backend {
|
|||||||
}
|
}
|
||||||
}();
|
}();
|
||||||
auto const df = GetDirectFormatArgs(entry);
|
auto const df = GetDirectFormatArgs(entry);
|
||||||
__android_log_print(android_log_priority, "YuzuNative", "%s %s:%u:%s: %s", df.class_name, entry.filename, entry.line_num, entry.function, entry.message);
|
__android_log_print(android_log_priority, "YuzuNative", CCB_PRINTF_FMT, df.time_seconds, df.time_fractional, df.class_name, df.level_name, entry.filename, entry.line_num, entry.function, entry.message);
|
||||||
}
|
}
|
||||||
void Flush() noexcept override {}
|
void Flush() noexcept override {}
|
||||||
};
|
};
|
||||||
@@ -428,33 +428,21 @@ void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename, u
|
|||||||
auto const flush = ::Settings::values.log_flush_line.GetValue();
|
auto const flush = ::Settings::values.log_flush_line.GetValue();
|
||||||
char buffer[BUFSIZ];
|
char buffer[BUFSIZ];
|
||||||
auto result = fmt::vformat_to_n(buffer, sizeof(buffer) - 1, format, args);
|
auto result = fmt::vformat_to_n(buffer, sizeof(buffer) - 1, format, args);
|
||||||
Entry e{
|
buffer[(std::min)(result.size, sizeof(buffer) - 1)] = '\0';
|
||||||
.message = nullptr,
|
logging_instance->ForEachBackend([=](Backend& backend) {
|
||||||
.message_len = 0,
|
backend.Write(Entry{
|
||||||
|
.message = buffer,
|
||||||
|
.message_len = (std::min)(result.size, sizeof(buffer) - 1),
|
||||||
.timestamp = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - logging_instance->time_origin),
|
.timestamp = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - logging_instance->time_origin),
|
||||||
.log_class = log_class,
|
.log_class = log_class,
|
||||||
.log_level = log_level,
|
.log_level = log_level,
|
||||||
.filename = TrimSourcePath(filename),
|
.filename = TrimSourcePath(filename),
|
||||||
.function = function,
|
.function = function,
|
||||||
.line_num = line_num,
|
.line_num = line_num,
|
||||||
};
|
|
||||||
if (result.size <= sizeof(buffer) - 1) {
|
|
||||||
buffer[(std::min)(result.size, sizeof(buffer) - 1)] = '\0';
|
|
||||||
e.message = buffer;
|
|
||||||
e.message_len = (std::min)(result.size, sizeof(buffer) - 1);
|
|
||||||
logging_instance->ForEachBackend([=](Backend& backend) {
|
|
||||||
backend.Write(e);
|
|
||||||
if (flush) backend.Flush();
|
|
||||||
});
|
});
|
||||||
} else {
|
if (flush)
|
||||||
std::string s = fmt::vformat(format, args);
|
backend.Flush();
|
||||||
e.message = s.c_str();
|
|
||||||
e.message_len = s.size();
|
|
||||||
logging_instance->ForEachBackend([=](Backend& backend) {
|
|
||||||
backend.Write(e);
|
|
||||||
if (flush) backend.Flush();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} // namespace Common::Log
|
} // namespace Common::Log
|
||||||
|
|||||||
@@ -8,14 +8,14 @@
|
|||||||
|
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "common/container/unordered_map.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
|
|
||||||
/// A string-based key-value container supporting serializing to and deserializing from a string
|
/// A string-based key-value container supporting serializing to and deserializing from a string
|
||||||
class ParamPackage {
|
class ParamPackage {
|
||||||
public:
|
public:
|
||||||
using DataType = ::Common::unordered_map<std::string, std::string>;
|
using DataType = ankerl::unordered_dense::map<std::string, std::string>;
|
||||||
|
|
||||||
ParamPackage() = default;
|
ParamPackage() = default;
|
||||||
explicit ParamPackage(const std::string& serialized);
|
explicit ParamPackage(const std::string& serialized);
|
||||||
|
|||||||
@@ -126,9 +126,9 @@ void LogSettings() {
|
|||||||
setting->UsingGlobal() ? '-' : 'C', TranslateCategory(category),
|
setting->UsingGlobal() ? '-' : 'C', TranslateCategory(category),
|
||||||
setting->GetLabel());
|
setting->GetLabel());
|
||||||
if (is_default)
|
if (is_default)
|
||||||
settings_list.push_back(fmt::format("{}: {}", name, setting->Canonicalize()));
|
settings_list.push_back(fmt::format("{}: {}\n", name, setting->Canonicalize()));
|
||||||
else
|
else
|
||||||
settings_list.push_front(fmt::format("{}: {}", name, setting->Canonicalize()));
|
settings_list.push_front(fmt::format("{}: {}\n", name, setting->Canonicalize()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -146,7 +146,7 @@ void LogSettings() {
|
|||||||
#undef LOG_PATH
|
#undef LOG_PATH
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetDebugKnobAt(u8 i) {
|
bool getDebugKnobAt(u8 i) {
|
||||||
return (values.debug_knobs.GetValue() & (1 << (i & 0xF))) != 0;
|
return (values.debug_knobs.GetValue() & (1 << (i & 0xF))) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -904,7 +904,7 @@ struct Values {
|
|||||||
0,
|
0,
|
||||||
65535,
|
65535,
|
||||||
"debug_knobs",
|
"debug_knobs",
|
||||||
Category::System,
|
Category::Debugging,
|
||||||
Specialization::Countable,
|
Specialization::Countable,
|
||||||
true,
|
true,
|
||||||
true};
|
true};
|
||||||
@@ -947,7 +947,7 @@ constexpr u32 MAX_FRAME_GEN_MULTIPLIER = 4;
|
|||||||
|
|
||||||
[[nodiscard]] size_t FrameGenMaxGenerations();
|
[[nodiscard]] size_t FrameGenMaxGenerations();
|
||||||
|
|
||||||
bool GetDebugKnobAt(u8 i);
|
bool getDebugKnobAt(u8 i);
|
||||||
|
|
||||||
void UpdateGPUAccuracy();
|
void UpdateGPUAccuracy();
|
||||||
bool IsGPULevelHigh();
|
bool IsGPULevelHigh();
|
||||||
|
|||||||
@@ -22,11 +22,10 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// You must ensure this matches with src/common/x64/xbyak.h on root dir
|
// You must ensure this matches with src/common/x64/xbyak.h on root dir
|
||||||
#include "common/container/unordered_map.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
#include "common/container/unordered_set.h"
|
|
||||||
#include <boost/unordered_map.hpp>
|
#include <boost/unordered_map.hpp>
|
||||||
#define XBYAK_STD_UNORDERED_SET ::Common::unordered_set
|
#define XBYAK_STD_UNORDERED_SET ankerl::unordered_dense::set
|
||||||
#define XBYAK_STD_UNORDERED_MAP ::Common::unordered_map
|
#define XBYAK_STD_UNORDERED_MAP ankerl::unordered_dense::map
|
||||||
#define XBYAK_STD_UNORDERED_MULTIMAP boost::unordered_multimap
|
#define XBYAK_STD_UNORDERED_MULTIMAP boost::unordered_multimap
|
||||||
#include <xbyak/xbyak.h>
|
#include <xbyak/xbyak.h>
|
||||||
#include <xbyak/xbyak_util.h>
|
#include <xbyak/xbyak_util.h>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "common/container/unordered_map.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
|
|
||||||
#include <dynarmic/interface/A64/a64.h>
|
#include <dynarmic/interface/A64/a64.h>
|
||||||
#include <dynarmic/interface/code_page.h>
|
#include <dynarmic/interface/code_page.h>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <span>
|
#include <span>
|
||||||
#include "common/container/unordered_map.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <oaknut/code_block.hpp>
|
#include <oaknut/code_block.hpp>
|
||||||
#include <oaknut/oaknut.hpp>
|
#include <oaknut/oaknut.hpp>
|
||||||
@@ -46,7 +46,7 @@ enum class PatchMode : u32 {
|
|||||||
|
|
||||||
using ModuleTextAddress = u64;
|
using ModuleTextAddress = u64;
|
||||||
using PatchTextAddress = u64;
|
using PatchTextAddress = u64;
|
||||||
using EntryTrampolines = ::Common::unordered_map<ModuleTextAddress, PatchTextAddress>;
|
using EntryTrampolines = ankerl::unordered_dense::map<ModuleTextAddress, PatchTextAddress>;
|
||||||
|
|
||||||
class Patcher {
|
class Patcher {
|
||||||
public:
|
public:
|
||||||
|
|||||||
+233
-186
@@ -3,12 +3,10 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <map>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <span>
|
|
||||||
#include <cctype>
|
|
||||||
#include "common/container/unordered_map.h"
|
|
||||||
|
|
||||||
#include "common/hex_util.h"
|
#include "common/hex_util.h"
|
||||||
#include "common/logging.h"
|
#include "common/logging.h"
|
||||||
@@ -24,30 +22,61 @@ enum class IPSFileType {
|
|||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
|
|
||||||
static IPSFileType IdentifyMagic(std::span<const u8> magic) {
|
constexpr std::array<std::pair<const char*, const char*>, 11> ESCAPE_CHARACTER_MAP{{
|
||||||
if (magic.size() >= 5) {
|
{"\\a", "\a"},
|
||||||
if (std::memcmp(magic.data(), "PATCH", 5) == 0)
|
{"\\b", "\b"},
|
||||||
|
{"\\f", "\f"},
|
||||||
|
{"\\n", "\n"},
|
||||||
|
{"\\r", "\r"},
|
||||||
|
{"\\t", "\t"},
|
||||||
|
{"\\v", "\v"},
|
||||||
|
{"\\\\", "\\"},
|
||||||
|
{"\\\'", "\'"},
|
||||||
|
{"\\\"", "\""},
|
||||||
|
{"\\\?", "\?"},
|
||||||
|
}};
|
||||||
|
|
||||||
|
static IPSFileType IdentifyMagic(const std::vector<u8>& magic) {
|
||||||
|
if (magic.size() != 5) {
|
||||||
|
return IPSFileType::Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr std::array<u8, 5> patch_magic{{'P', 'A', 'T', 'C', 'H'}};
|
||||||
|
if (std::equal(magic.begin(), magic.end(), patch_magic.begin())) {
|
||||||
return IPSFileType::IPS;
|
return IPSFileType::IPS;
|
||||||
if (std::memcmp(magic.data(), "IPS32", 5) == 0)
|
}
|
||||||
|
|
||||||
|
static constexpr std::array<u8, 5> ips32_magic{{'I', 'P', 'S', '3', '2'}};
|
||||||
|
if (std::equal(magic.begin(), magic.end(), ips32_magic.begin())) {
|
||||||
return IPSFileType::IPS32;
|
return IPSFileType::IPS32;
|
||||||
}
|
}
|
||||||
|
|
||||||
return IPSFileType::Error;
|
return IPSFileType::Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsEOF(IPSFileType type, std::span<const u8> magic) {
|
static bool IsEOF(IPSFileType type, const std::vector<u8>& data) {
|
||||||
return (type == IPSFileType::IPS && magic.size() > 3 && std::memcmp(magic.data(), "EOF", 3) == 0)
|
static constexpr std::array<u8, 3> eof{{'E', 'O', 'F'}};
|
||||||
|| (type == IPSFileType::IPS32 && magic.size() > 4 && std::memcmp(magic.data(), "EEOF", 4) == 0);
|
if (type == IPSFileType::IPS && std::equal(data.begin(), data.end(), eof.begin())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr std::array<u8, 4> eeof{{'E', 'E', 'O', 'F'}};
|
||||||
|
return type == IPSFileType::IPS32 && std::equal(data.begin(), data.end(), eeof.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtualFile PatchIPS(const VirtualFile& in, const VirtualFile& ips) {
|
VirtualFile PatchIPS(const VirtualFile& in, const VirtualFile& ips) {
|
||||||
if (in == nullptr || ips == nullptr)
|
if (in == nullptr || ips == nullptr)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
auto in_data = in->ReadAllBytes();
|
const auto type = IdentifyMagic(ips->ReadBytes(0x5));
|
||||||
auto const type = IdentifyMagic(in_data);
|
|
||||||
if (type == IPSFileType::Error)
|
if (type == IPSFileType::Error)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
auto in_data = in->ReadAllBytes();
|
||||||
|
if (in_data.size() == 0) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<u8> temp(type == IPSFileType::IPS ? 3 : 4);
|
std::vector<u8> temp(type == IPSFileType::IPS ? 3 : 4);
|
||||||
u64 offset = 5; // After header
|
u64 offset = 5; // After header
|
||||||
while (ips->Read(temp.data(), temp.size(), offset) == temp.size()) {
|
while (ips->Read(temp.data(), temp.size(), offset) == temp.size()) {
|
||||||
@@ -56,9 +85,12 @@ VirtualFile PatchIPS(const VirtualFile& in, const VirtualFile& ips) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 real_offset = (type == IPSFileType::IPS32)
|
u32 real_offset{};
|
||||||
? ((temp[0] << 24) | (temp[1] << 16) | (temp[2] << 8) | temp[3])
|
if (type == IPSFileType::IPS32)
|
||||||
: ((temp[0] << 16) | (temp[1] << 8) | temp[2]);
|
real_offset = (temp[0] << 24) | (temp[1] << 16) | (temp[2] << 8) | temp[3];
|
||||||
|
else
|
||||||
|
real_offset = (temp[0] << 16) | (temp[1] << 8) | temp[2];
|
||||||
|
|
||||||
if (real_offset > in_data.size()) {
|
if (real_offset > in_data.size()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -81,35 +113,34 @@ VirtualFile PatchIPS(const VirtualFile& in, const VirtualFile& ips) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (real_offset + rle_size > in_data.size())
|
if (real_offset + rle_size > in_data.size())
|
||||||
rle_size = u16(in_data.size() - real_offset);
|
rle_size = static_cast<u16>(in_data.size() - real_offset);
|
||||||
std::memset(in_data.data() + real_offset, *data, rle_size);
|
std::memset(in_data.data() + real_offset, *data, rle_size);
|
||||||
} else { // Standard Patch
|
} else { // Standard Patch
|
||||||
auto read = data_size;
|
auto read = data_size;
|
||||||
if (real_offset + read > in_data.size())
|
if (real_offset + read > in_data.size())
|
||||||
read = u16(in_data.size() - real_offset);
|
read = static_cast<u16>(in_data.size() - real_offset);
|
||||||
if (ips->Read(in_data.data() + real_offset, read, offset) != data_size)
|
if (ips->Read(in_data.data() + real_offset, read, offset) != data_size)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
offset += data_size;
|
offset += data_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (IsEOF(type, temp)) {
|
|
||||||
return std::make_shared<VectorVfsFile>(std::move(in_data), in->GetName(), in->GetContainingDirectory());
|
if (!IsEOF(type, temp)) {
|
||||||
}
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_shared<VectorVfsFile>(std::move(in_data), in->GetName(),
|
||||||
|
in->GetContainingDirectory());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct IPSwitchRecord {
|
|
||||||
std::array<uint8_t, 256 - sizeof(size_t)> data;
|
|
||||||
size_t count;
|
|
||||||
};
|
|
||||||
struct IPSwitchCompiler::IPSwitchPatch {
|
struct IPSwitchCompiler::IPSwitchPatch {
|
||||||
::Common::unordered_map<u32, IPSwitchRecord> records;
|
std::string name;
|
||||||
bool enabled;
|
bool enabled;
|
||||||
|
std::map<u32, std::vector<u8>> records;
|
||||||
};
|
};
|
||||||
|
|
||||||
IPSwitchCompiler::IPSwitchCompiler(VirtualFile patch_text_) : patch_text(std::move(patch_text_)) {
|
IPSwitchCompiler::IPSwitchCompiler(VirtualFile patch_text_) : patch_text(std::move(patch_text_)) {
|
||||||
Parse(patch_text->ReadAllBytes());
|
Parse();
|
||||||
}
|
}
|
||||||
|
|
||||||
IPSwitchCompiler::~IPSwitchCompiler() = default;
|
IPSwitchCompiler::~IPSwitchCompiler() = default;
|
||||||
@@ -118,185 +149,201 @@ std::array<u8, 32> IPSwitchCompiler::GetBuildID() const {
|
|||||||
return nso_build_id;
|
return nso_build_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static IPSwitchRecord EscapeStringSequences(std::string_view sv) {
|
bool IPSwitchCompiler::IsValid() const {
|
||||||
IPSwitchRecord r{};
|
return valid;
|
||||||
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;
|
|
||||||
it += 2;
|
|
||||||
} else {
|
|
||||||
++r.count;
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void IPSwitchCompiler::Parse(std::span<u8 const> bytes) {
|
static bool StartsWith(std::string_view base, std::string_view check) {
|
||||||
LOG_INFO(Loader, "IPSwitchCompiler: '{}'", patch_text->GetName());
|
return base.size() >= check.size() && base.substr(0, check.size()) == check;
|
||||||
bool is_little_endian = true;
|
}
|
||||||
s64 offset_shift = 0;
|
|
||||||
//bool print_values = false;
|
|
||||||
auto const parse_line = [&](std::string_view const line) {
|
|
||||||
// Keep in mind lines have trimmed spaces (at the end & start)!
|
|
||||||
LOG_INFO(Loader, "<{}>", line);
|
|
||||||
// IPSwitch is case insensitive
|
|
||||||
// Yes this is how the logic goes for the main reference parsers!
|
|
||||||
if (line.size() > 2 && line[0] == '@') {
|
|
||||||
switch (line[1]) {
|
|
||||||
// yes, @nsobid too -- NSO Build ID Specifier
|
|
||||||
case 'n':
|
|
||||||
case 'N':
|
|
||||||
nso_build_id = Common::HexStringToArray<0x20>(fmt::format("{:0<64}", line.substr(8)));
|
|
||||||
break;
|
|
||||||
// @stop
|
|
||||||
case 's':
|
|
||||||
case 'S':
|
|
||||||
return false;
|
|
||||||
// @enabled
|
|
||||||
case 'e':
|
|
||||||
case 'E':
|
|
||||||
patches.push_back({{}, true});
|
|
||||||
break;
|
|
||||||
// @disabled
|
|
||||||
case 'd':
|
|
||||||
case 'D':
|
|
||||||
patches.push_back({{}, false});
|
|
||||||
break;
|
|
||||||
// @flag
|
|
||||||
case 'f':
|
|
||||||
case 'F': {
|
|
||||||
if (line.starts_with("@flag offset_shift")) {
|
|
||||||
offset_shift = std::strtoll(line.data() + 19, nullptr, 0); // Offset Shift Flag
|
|
||||||
} else if (line.starts_with("@flag print_values")) {
|
|
||||||
//print_values = true; // Force printing of applied values
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'l':
|
|
||||||
case 'L':
|
|
||||||
is_little_endian = true;
|
|
||||||
break;
|
|
||||||
// IPS parsers dont support big endian no more, we do due to backcompat
|
|
||||||
case 'b':
|
|
||||||
case 'B':
|
|
||||||
is_little_endian = false;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG_WARNING(Loader, "Unknown flag {}", line);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
size_t offset = size_t(std::strtoul(line.data(), nullptr, 16));
|
|
||||||
offset += size_t(offset_shift);
|
|
||||||
if (auto const first_quote = line.find_first_of("\"\'"); first_quote != std::string::npos) {
|
|
||||||
// string replacement
|
|
||||||
char quote = line[first_quote];
|
|
||||||
auto const start = line.cbegin() + first_quote + 1;
|
|
||||||
auto end = start;
|
|
||||||
for (; end < line.cend() && *end != quote; )
|
|
||||||
end += (*end == '\\') ? 2 : 1;
|
|
||||||
if (start <= line.cend() && end <= line.cend()) {
|
|
||||||
LOG_INFO(Loader, "[S] value @ {:#08X} ", offset);
|
|
||||||
patches.back().records.insert_or_assign(u32(offset), EscapeStringSequences({start, end}));
|
|
||||||
} else {
|
|
||||||
LOG_WARNING(Loader, "invalid string");
|
|
||||||
}
|
|
||||||
} else if (auto const first_space = line.find_last_of(" /\t\r\n"); first_space != std::string::npos) {
|
|
||||||
IPSwitchRecord r{}; // hex replacement
|
|
||||||
auto const start = line.cbegin() + first_space + 1;
|
|
||||||
auto const end = line.cend();
|
|
||||||
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);
|
|
||||||
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 {
|
|
||||||
LOG_WARNING(Loader, "invalid line");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
LOG_WARNING(Loader, "unhandled line!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true; //continue
|
|
||||||
};
|
|
||||||
|
|
||||||
for (auto it = bytes.begin(); it < bytes.end(); ) {
|
static std::string EscapeStringSequences(std::string in) {
|
||||||
auto const start = it;
|
for (const auto& seq : ESCAPE_CHARACTER_MAP) {
|
||||||
auto end = start;
|
for (auto index = in.find(seq.first); index != std::string::npos;
|
||||||
for (; end < bytes.end() && *end != '\n' && *end != '\r'; ++end)
|
index = in.find(seq.first, index)) {
|
||||||
;
|
in.replace(index, std::strlen(seq.first), seq.second);
|
||||||
it = end + 1; //prepare for next line
|
index += std::strlen(seq.second);
|
||||||
std::string_view const sline{
|
}
|
||||||
reinterpret_cast<const char*>(bytes.data() + std::distance(bytes.begin(), start)),
|
}
|
||||||
size_t(std::distance(start, end))
|
|
||||||
};
|
return in;
|
||||||
if (sline.size() > 0) {
|
}
|
||||||
auto p = sline.cbegin();
|
|
||||||
// skip space off line
|
void IPSwitchCompiler::ParseFlag(const std::string& line) {
|
||||||
for (; p < sline.cend() && std::isspace(*p); ++p)
|
if (StartsWith(line, "@flag offset_shift ")) {
|
||||||
;
|
// Offset Shift Flag
|
||||||
// now make a nominal preprocessed line: remove comments
|
offset_shift = std::strtoll(line.substr(19).c_str(), nullptr, 0);
|
||||||
char quote = '\0';
|
} else if (StartsWith(line, "@little-endian")) {
|
||||||
auto const sline_start = p;
|
// Set values to read as little endian
|
||||||
for (; p < sline.cend(); ) {
|
is_little_endian = true;
|
||||||
// we dont check for "//", IPS checks for '/' only...
|
} else if (StartsWith(line, "@big-endian")) {
|
||||||
if ((!quote && p[0] == '/')
|
// Set values to read as big endian
|
||||||
|| (!quote && p[0] == '#')) {
|
is_little_endian = false;
|
||||||
|
} else if (StartsWith(line, "@flag print_values")) {
|
||||||
|
// Force printing of applied values
|
||||||
|
print_values = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IPSwitchCompiler::Parse() {
|
||||||
|
const auto bytes = patch_text->ReadAllBytes();
|
||||||
|
std::stringstream s;
|
||||||
|
s.write(reinterpret_cast<const char*>(bytes.data()), bytes.size());
|
||||||
|
|
||||||
|
std::vector<std::string> lines;
|
||||||
|
std::string stream_line;
|
||||||
|
while (std::getline(s, stream_line)) {
|
||||||
|
// Remove a trailing \r
|
||||||
|
if (!stream_line.empty() && stream_line.back() == '\r')
|
||||||
|
stream_line.pop_back();
|
||||||
|
lines.push_back(std::move(stream_line));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < lines.size(); ++i) {
|
||||||
|
auto line = lines[i];
|
||||||
|
|
||||||
|
// Remove midline comments
|
||||||
|
std::size_t comment_index = std::string::npos;
|
||||||
|
bool within_string = false;
|
||||||
|
for (std::size_t k = 0; k < line.size(); ++k) {
|
||||||
|
if (line[k] == '\"' && (k > 0 && line[k - 1] != '\\')) {
|
||||||
|
within_string = !within_string;
|
||||||
|
} else if (line[k] == '\\' && (k < line.size() - 1 && line[k + 1] == '\\')) {
|
||||||
|
comment_index = k;
|
||||||
break;
|
break;
|
||||||
} else if (p[0] == '\"' || p[0] == '\'') {
|
}
|
||||||
quote = (p[0] == quote) ? '\0' : p[0];
|
}
|
||||||
++p;
|
|
||||||
} else if (p + 1 < sline.cend() && p[0] == '\\') {
|
if (!StartsWith(line, "//") && comment_index != std::string::npos) {
|
||||||
p += 2;
|
last_comment = line.substr(comment_index + 2);
|
||||||
|
line = line.substr(0, comment_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StartsWith(line, "@stop")) {
|
||||||
|
// Force stop
|
||||||
|
break;
|
||||||
|
} else if (StartsWith(line, "@nsobid-")) {
|
||||||
|
// NSO Build ID Specifier
|
||||||
|
const auto raw_build_id = fmt::format("{:0<64}", line.substr(8));
|
||||||
|
nso_build_id = Common::HexStringToArray<0x20>(raw_build_id);
|
||||||
|
} else if (StartsWith(line, "#")) {
|
||||||
|
// Mandatory Comment
|
||||||
|
LOG_INFO(Loader, "[IPSwitchCompiler ('{}')] Forced output comment: {}",
|
||||||
|
patch_text->GetName(), line.substr(1));
|
||||||
|
} else if (StartsWith(line, "//")) {
|
||||||
|
// Normal Comment
|
||||||
|
last_comment = line.substr(2);
|
||||||
|
if (last_comment.find_first_not_of(' ') == std::string::npos)
|
||||||
|
continue;
|
||||||
|
if (last_comment.find_first_not_of(' ') != 0)
|
||||||
|
last_comment = last_comment.substr(last_comment.find_first_not_of(' '));
|
||||||
|
} else if (StartsWith(line, "@enabled") || StartsWith(line, "@disabled")) {
|
||||||
|
// Start of patch
|
||||||
|
const auto enabled = StartsWith(line, "@enabled");
|
||||||
|
if (i == 0)
|
||||||
|
return;
|
||||||
|
LOG_INFO(Loader, "[IPSwitchCompiler ('{}')] Parsing patch '{}' ({})",
|
||||||
|
patch_text->GetName(), last_comment, line.substr(1));
|
||||||
|
|
||||||
|
IPSwitchPatch patch{last_comment, enabled, {}};
|
||||||
|
|
||||||
|
// Read rest of patch
|
||||||
|
while (true) {
|
||||||
|
if (i + 1 >= lines.size()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& patch_line = lines[++i];
|
||||||
|
|
||||||
|
// Patch line may contain comments
|
||||||
|
if (StartsWith(patch_line, "//") || StartsWith(patch_line, "#")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start of new patch
|
||||||
|
if (StartsWith(patch_line, "@enabled") || StartsWith(patch_line, "@disabled")) {
|
||||||
|
--i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for a flag
|
||||||
|
if (StartsWith(patch_line, "@")) {
|
||||||
|
ParseFlag(patch_line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 11 - 8 hex digit offset + space + minimum two digit overwrite val
|
||||||
|
if (patch_line.length() < 11)
|
||||||
|
break;
|
||||||
|
auto offset = std::strtoul(patch_line.substr(0, 8).c_str(), nullptr, 16);
|
||||||
|
offset += static_cast<unsigned long>(offset_shift);
|
||||||
|
|
||||||
|
std::vector<u8> replace;
|
||||||
|
// 9 - first char of replacement val
|
||||||
|
if (patch_line[9] == '\"') {
|
||||||
|
// string replacement
|
||||||
|
auto end_index = patch_line.find('\"', 10);
|
||||||
|
if (end_index == std::string::npos || end_index < 10)
|
||||||
|
return;
|
||||||
|
while (patch_line[end_index - 1] == '\\') {
|
||||||
|
end_index = patch_line.find('\"', end_index + 1);
|
||||||
|
if (end_index == std::string::npos || end_index < 10)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto value = patch_line.substr(10, end_index - 10);
|
||||||
|
value = EscapeStringSequences(value);
|
||||||
|
replace.reserve(value.size());
|
||||||
|
std::copy(value.begin(), value.end(), std::back_inserter(replace));
|
||||||
} else {
|
} else {
|
||||||
++p;
|
// hex replacement
|
||||||
}
|
const auto value =
|
||||||
}
|
patch_line.substr(9, patch_line.find_first_of(" /\r\n", 9) - 9);
|
||||||
// now we have the preprocessed string ;)
|
replace = Common::HexStringToVector(value, is_little_endian);
|
||||||
std::string_view pp_str(sline_start, p);
|
}
|
||||||
if (pp_str.size() > 0 && !parse_line(pp_str)) {
|
|
||||||
break;
|
if (print_values) {
|
||||||
}
|
LOG_INFO(Loader,
|
||||||
|
"[IPSwitchCompiler ('{}')] - Patching value at offset {:#08x} "
|
||||||
|
"with byte string '{}'",
|
||||||
|
patch_text->GetName(), offset, Common::HexToString(replace));
|
||||||
|
}
|
||||||
|
|
||||||
|
patch.records.insert_or_assign(static_cast<u32>(offset), std::move(replace));
|
||||||
|
}
|
||||||
|
|
||||||
|
patches.push_back(std::move(patch));
|
||||||
|
} else if (StartsWith(line, "@")) {
|
||||||
|
ParseFlag(line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
valid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtualFile IPSwitchCompiler::Apply(const VirtualFile& in) const {
|
VirtualFile IPSwitchCompiler::Apply(const VirtualFile& in) const {
|
||||||
if (in == nullptr)
|
if (in == nullptr || !valid)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
auto in_data = in->ReadAllBytes();
|
auto in_data = in->ReadAllBytes();
|
||||||
|
|
||||||
for (const auto& patch : patches) {
|
for (const auto& patch : patches) {
|
||||||
if (patch.enabled) {
|
if (!patch.enabled)
|
||||||
|
continue;
|
||||||
|
|
||||||
for (const auto& record : patch.records) {
|
for (const auto& record : patch.records) {
|
||||||
if (record.first < in_data.size()) {
|
if (record.first >= in_data.size())
|
||||||
auto replace_size = record.second.count;
|
continue;
|
||||||
|
auto replace_size = record.second.size();
|
||||||
if (record.first + replace_size > in_data.size())
|
if (record.first + replace_size > in_data.size())
|
||||||
replace_size = in_data.size() - record.first;
|
replace_size = in_data.size() - record.first;
|
||||||
std::memcpy(in_data.data() + record.first, record.second.data.data(), replace_size);
|
for (std::size_t i = 0; i < replace_size; ++i)
|
||||||
} else {
|
in_data[i + record.first] = record.second[i];
|
||||||
LOG_WARNING(Loader, "record offs={:x},size={:x}", record.first, record.second.data.size());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
return std::make_shared<VectorVfsFile>(std::move(in_data), in->GetName(),
|
||||||
return std::make_shared<VectorVfsFile>(std::move(in_data), in->GetName(), in->GetContainingDirectory());
|
in->GetContainingDirectory());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace FileSys
|
} // namespace FileSys
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <span>
|
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "core/file_sys/vfs/vfs.h"
|
#include "core/file_sys/vfs/vfs.h"
|
||||||
@@ -23,17 +20,24 @@ public:
|
|||||||
~IPSwitchCompiler();
|
~IPSwitchCompiler();
|
||||||
|
|
||||||
std::array<u8, 0x20> GetBuildID() const;
|
std::array<u8, 0x20> GetBuildID() const;
|
||||||
|
bool IsValid() const;
|
||||||
VirtualFile Apply(const VirtualFile& in) const;
|
VirtualFile Apply(const VirtualFile& in) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct IPSwitchPatch;
|
struct IPSwitchPatch;
|
||||||
|
|
||||||
void ParseFlag(const std::string& flag);
|
void ParseFlag(const std::string& flag);
|
||||||
void Parse(std::span<u8 const> bytes);
|
void Parse();
|
||||||
|
|
||||||
|
bool valid = false;
|
||||||
|
|
||||||
VirtualFile patch_text;
|
VirtualFile patch_text;
|
||||||
std::vector<IPSwitchPatch> patches;
|
std::vector<IPSwitchPatch> patches;
|
||||||
std::array<u8, 0x20> nso_build_id{};
|
std::array<u8, 0x20> nso_build_id{};
|
||||||
|
bool is_little_endian = false;
|
||||||
|
s64 offset_shift = 0;
|
||||||
|
bool print_values = false;
|
||||||
|
std::string last_comment = "";
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace FileSys
|
} // namespace FileSys
|
||||||
|
|||||||
@@ -345,7 +345,8 @@ VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const {
|
|||||||
return exefs;
|
return exefs;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<VirtualFile> PatchManager::CollectPatches(const std::vector<VirtualDir>& patch_dirs, const std::string& build_id) 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 = Settings::values.disabled_addons[title_id];
|
||||||
const auto nso_build_id = fmt::format("{:0<64}", build_id);
|
const auto nso_build_id = fmt::format("{:0<64}", build_id);
|
||||||
|
|
||||||
@@ -360,11 +361,16 @@ std::vector<VirtualFile> PatchManager::CollectPatches(const std::vector<VirtualD
|
|||||||
for (const auto& file : exefs_dir->GetFiles()) {
|
for (const auto& file : exefs_dir->GetFiles()) {
|
||||||
if (file->GetExtension() == "ips") {
|
if (file->GetExtension() == "ips") {
|
||||||
auto name = file->GetName();
|
auto name = file->GetName();
|
||||||
const auto this_build_id = fmt::format("{:0<64}", name.substr(0, name.find('.')));
|
|
||||||
|
const auto this_build_id =
|
||||||
|
fmt::format("{:0<64}", name.substr(0, name.find('.')));
|
||||||
if (nso_build_id == this_build_id)
|
if (nso_build_id == this_build_id)
|
||||||
out.push_back(file);
|
out.push_back(file);
|
||||||
} else if (file->GetExtension() == "pchtxt") {
|
} else if (file->GetExtension() == "pchtxt") {
|
||||||
IPSwitchCompiler compiler{file};
|
IPSwitchCompiler compiler{file};
|
||||||
|
if (!compiler.IsValid())
|
||||||
|
continue;
|
||||||
|
|
||||||
const auto this_build_id = Common::HexToString(compiler.GetBuildID());
|
const auto this_build_id = Common::HexToString(compiler.GetBuildID());
|
||||||
if (nso_build_id == this_build_id)
|
if (nso_build_id == this_build_id)
|
||||||
out.push_back(file);
|
out.push_back(file);
|
||||||
@@ -372,6 +378,7 @@ std::vector<VirtualFile> PatchManager::CollectPatches(const std::vector<VirtualD
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -566,7 +566,7 @@ VirtualFile RegisteredCache::GetFileAtID(NcaID id) const {
|
|||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::optional<NcaID> CheckMapForContentRecord(const ::Common::unordered_map<u64, CNMT>& map, u64 title_id, ContentRecordType type) {
|
static std::optional<NcaID> CheckMapForContentRecord(const ankerl::unordered_dense::map<u64, CNMT>& map, u64 title_id, ContentRecordType type) {
|
||||||
auto cmnt_iter = map.find(title_id);
|
auto cmnt_iter = map.find(title_id);
|
||||||
u8 id_offset = 0;
|
u8 id_offset = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "common/container/unordered_map.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
#include <boost/container/flat_map.hpp>
|
#include <boost/container/flat_map.hpp>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "core/crypto/key_manager.h"
|
#include "core/crypto/key_manager.h"
|
||||||
@@ -209,11 +209,11 @@ private:
|
|||||||
ContentProviderParsingFunction parser;
|
ContentProviderParsingFunction parser;
|
||||||
|
|
||||||
// maps tid -> NcaID of meta
|
// maps tid -> NcaID of meta
|
||||||
::Common::unordered_map<u64, NcaID> meta_id;
|
ankerl::unordered_dense::map<u64, NcaID> meta_id;
|
||||||
// maps tid -> meta
|
// maps tid -> meta
|
||||||
::Common::unordered_map<u64, CNMT> meta;
|
ankerl::unordered_dense::map<u64, CNMT> meta;
|
||||||
// maps tid -> meta for CNMT in yuzu_meta
|
// maps tid -> meta for CNMT in yuzu_meta
|
||||||
::Common::unordered_map<u64, CNMT> yuzu_meta;
|
ankerl::unordered_dense::map<u64, CNMT> yuzu_meta;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class ContentProviderUnionSlot {
|
enum class ContentProviderUnionSlot {
|
||||||
@@ -313,8 +313,8 @@ private:
|
|||||||
void ProcessXCI(const VirtualFile& file);
|
void ProcessXCI(const VirtualFile& file);
|
||||||
|
|
||||||
std::vector<VirtualDir> load_dirs;
|
std::vector<VirtualDir> load_dirs;
|
||||||
::Common::unordered_map<std::tuple<u64, ContentRecordType, TitleType>, VirtualFile> entries;
|
ankerl::unordered_dense::map<std::tuple<u64, ContentRecordType, TitleType>, VirtualFile> entries;
|
||||||
::Common::unordered_map<u64, u32> versions;
|
ankerl::unordered_dense::map<u64, u32> versions;
|
||||||
std::vector<ExternalUpdateEntry> multi_version_entries;
|
std::vector<ExternalUpdateEntry> multi_version_entries;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include "common/container/unordered_set.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include "core/file_sys/vfs/vfs_layered.h"
|
#include "core/file_sys/vfs/vfs_layered.h"
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ std::string LayeredVfsDirectory::GetFullPath() const {
|
|||||||
|
|
||||||
std::vector<VirtualFile> LayeredVfsDirectory::GetFiles() const {
|
std::vector<VirtualFile> LayeredVfsDirectory::GetFiles() const {
|
||||||
std::vector<VirtualFile> out;
|
std::vector<VirtualFile> out;
|
||||||
::Common::unordered_set<std::string> out_names;
|
ankerl::unordered_dense::set<std::string> out_names;
|
||||||
|
|
||||||
for (const auto& layer : dirs) {
|
for (const auto& layer : dirs) {
|
||||||
for (auto& file : layer->GetFiles()) {
|
for (auto& file : layer->GetFiles()) {
|
||||||
@@ -79,7 +79,7 @@ std::vector<VirtualFile> LayeredVfsDirectory::GetFiles() const {
|
|||||||
|
|
||||||
std::vector<VirtualDir> LayeredVfsDirectory::GetSubdirectories() const {
|
std::vector<VirtualDir> LayeredVfsDirectory::GetSubdirectories() const {
|
||||||
std::vector<VirtualDir> out;
|
std::vector<VirtualDir> out;
|
||||||
::Common::unordered_set<std::string> out_names;
|
ankerl::unordered_dense::set<std::string> out_names;
|
||||||
|
|
||||||
for (const auto& layer : dirs) {
|
for (const auto& layer : dirs) {
|
||||||
for (const auto& sd : layer->GetSubdirectories()) {
|
for (const auto& sd : layer->GetSubdirectories()) {
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ private:
|
|||||||
std::array<DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS> m_watchpoints{};
|
std::array<DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS> m_watchpoints{};
|
||||||
std::map<KProcessAddress, u64> m_debug_page_refcounts{};
|
std::map<KProcessAddress, u64> m_debug_page_refcounts{};
|
||||||
#ifdef HAS_NCE
|
#ifdef HAS_NCE
|
||||||
::Common::unordered_map<u64, u64> m_post_handlers{};
|
ankerl::unordered_dense::map<u64, u64> m_post_handlers{};
|
||||||
#endif
|
#endif
|
||||||
std::unique_ptr<Core::ExclusiveMonitor> m_exclusive_monitor;
|
std::unique_ptr<Core::ExclusiveMonitor> m_exclusive_monitor;
|
||||||
Core::Memory::Memory m_memory;
|
Core::Memory::Memory m_memory;
|
||||||
@@ -494,7 +494,7 @@ public:
|
|||||||
static void Switch(KernelCore& kernel, KProcess* cur_process, KProcess* next_process);
|
static void Switch(KernelCore& kernel, KProcess* cur_process, KProcess* next_process);
|
||||||
|
|
||||||
#ifdef HAS_NCE
|
#ifdef HAS_NCE
|
||||||
::Common::unordered_map<u64, u64>& GetPostHandlers() noexcept {
|
ankerl::unordered_dense::map<u64, u64>& GetPostHandlers() noexcept {
|
||||||
return m_post_handlers;
|
return m_post_handlers;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -10,8 +10,7 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include "common/container/unordered_map.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
#include "common/container/unordered_set.h"
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
@@ -793,8 +792,8 @@ struct KernelCore::Impl {
|
|||||||
|
|
||||||
std::optional<KObjectNameGlobalData> object_name_global_data;
|
std::optional<KObjectNameGlobalData> object_name_global_data;
|
||||||
|
|
||||||
::Common::unordered_set<KAutoObject*> registered_objects;
|
ankerl::unordered_dense::set<KAutoObject*> registered_objects;
|
||||||
::Common::unordered_set<KAutoObject*> registered_in_use_objects;
|
ankerl::unordered_dense::set<KAutoObject*> registered_in_use_objects;
|
||||||
|
|
||||||
std::mutex server_lock;
|
std::mutex server_lock;
|
||||||
std::vector<std::unique_ptr<Service::ServerManager>> server_managers;
|
std::vector<std::unique_ptr<Service::ServerManager>> server_managers;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
#include <list>
|
#include <list>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "common/container/unordered_map.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "common/polyfill_thread.h"
|
#include "common/polyfill_thread.h"
|
||||||
|
|||||||
@@ -17,12 +17,56 @@
|
|||||||
|
|
||||||
namespace Kernel::Svc {
|
namespace Kernel::Svc {
|
||||||
|
|
||||||
|
constexpr auto MAX_MSG_TIME = std::chrono::milliseconds(250);
|
||||||
|
const auto MAX_MSG_SIZE = 0x1000;
|
||||||
|
|
||||||
/// Used to output a message on a debug hardware unit - does nothing on a retail unit
|
/// Used to output a message on a debug hardware unit - does nothing on a retail unit
|
||||||
Result OutputDebugString(Core::System& system, u64 address, u64 len) {
|
Result OutputDebugString(Core::System& system, u64 address, u64 len) {
|
||||||
|
static struct DebugFlusher {
|
||||||
|
std::string msg_buffer;
|
||||||
|
std::mutex msg_mutex;
|
||||||
|
std::condition_variable msg_cv;
|
||||||
|
std::chrono::steady_clock::time_point last_msg_time;
|
||||||
|
std::optional<std::jthread> thread;
|
||||||
|
} flusher_data;
|
||||||
R_SUCCEED_IF(len == 0);
|
R_SUCCEED_IF(len == 0);
|
||||||
std::string msg_buffer(len, 0);
|
// Only start the thread the very first time this function is called
|
||||||
GetCurrentMemory(system.Kernel()).ReadBlock(address, msg_buffer.data(), len);
|
if (!flusher_data.thread) {
|
||||||
LOG_INFO(Debug_Emulated, "{}", msg_buffer);
|
flusher_data.thread.emplace([](std::stop_token stop_token) {
|
||||||
|
while (!stop_token.stop_requested()) {
|
||||||
|
std::unique_lock lock(flusher_data.msg_mutex);
|
||||||
|
flusher_data.msg_cv.wait(lock, [&stop_token] {
|
||||||
|
return !flusher_data.msg_buffer.empty() || stop_token.stop_requested();
|
||||||
|
});
|
||||||
|
if (stop_token.stop_requested() && flusher_data.msg_buffer.empty())
|
||||||
|
break;
|
||||||
|
auto timeout = flusher_data.last_msg_time + MAX_MSG_TIME;
|
||||||
|
bool woke_early = flusher_data.msg_cv.wait_until(lock, timeout, [&stop_token] {
|
||||||
|
return flusher_data.msg_buffer.size() >= MAX_MSG_SIZE || stop_token.stop_requested();
|
||||||
|
});
|
||||||
|
if (!woke_early || flusher_data.msg_buffer.size() >= MAX_MSG_SIZE || stop_token.stop_requested()) {
|
||||||
|
if (!flusher_data.msg_buffer.empty()) {
|
||||||
|
// Remove trailing newline as LOG_INFO adds that anyways
|
||||||
|
if (flusher_data.msg_buffer.back() == '\n')
|
||||||
|
flusher_data.msg_buffer.pop_back();
|
||||||
|
|
||||||
|
LOG_INFO(Debug_Emulated, "\n{}", flusher_data.msg_buffer);
|
||||||
|
flusher_data.msg_buffer.clear();
|
||||||
|
}
|
||||||
|
if (stop_token.stop_requested()) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
flusher_data.msg_cv.notify_all();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::lock_guard lock(flusher_data.msg_mutex);
|
||||||
|
const auto old_size = flusher_data.msg_buffer.size();
|
||||||
|
flusher_data.msg_buffer.resize(old_size + len);
|
||||||
|
GetCurrentMemory(system.Kernel()).ReadBlock(address, flusher_data.msg_buffer.data() + old_size, len);
|
||||||
|
flusher_data.last_msg_time = std::chrono::steady_clock::now();
|
||||||
|
}
|
||||||
|
flusher_data.msg_cv.notify_one();
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include "common/container/unordered_map.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "common/common_funcs.h"
|
#include "common/common_funcs.h"
|
||||||
@@ -176,6 +176,6 @@ struct WebCommonReturnValue {
|
|||||||
};
|
};
|
||||||
static_assert(sizeof(WebCommonReturnValue) == 0x1010, "WebCommonReturnValue has incorrect size.");
|
static_assert(sizeof(WebCommonReturnValue) == 0x1010, "WebCommonReturnValue has incorrect size.");
|
||||||
|
|
||||||
using WebArgInputTLVMap = ::Common::unordered_map<WebArgInputTLVType, std::vector<u8>>;
|
using WebArgInputTLVMap = ankerl::unordered_dense::map<WebArgInputTLVType, std::vector<u8>>;
|
||||||
|
|
||||||
} // namespace Service::AM::Frontend
|
} // namespace Service::AM::Frontend
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ IAudioIn::IAudioIn(Core::System& system_, Manager& manager, size_t session_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
IAudioIn::~IAudioIn() {
|
IAudioIn::~IAudioIn() {
|
||||||
impl->Free();
|
impl->Free(system);
|
||||||
service_context.CloseEvent(event);
|
service_context.CloseEvent(event);
|
||||||
process->Close(system.Kernel());
|
process->Close(system.Kernel());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -65,7 +68,7 @@ Result IAudioInManager::OpenAudioInAuto(
|
|||||||
Result IAudioInManager::ListAudioInsAutoFiltered(
|
Result IAudioInManager::ListAudioInsAutoFiltered(
|
||||||
OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_audio_ins, Out<u32> out_count) {
|
OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_audio_ins, Out<u32> out_count) {
|
||||||
LOG_DEBUG(Service_Audio, "called");
|
LOG_DEBUG(Service_Audio, "called");
|
||||||
*out_count = impl->GetDeviceNames(out_audio_ins, true);
|
*out_count = impl->GetDeviceNames(system, out_audio_ins, true);
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,8 +93,8 @@ Result IAudioInManager::OpenAudioInProtocolSpecified(
|
|||||||
|
|
||||||
size_t new_session_id{};
|
size_t new_session_id{};
|
||||||
|
|
||||||
R_TRY(impl->LinkToManager());
|
R_TRY(impl->LinkToManager(system));
|
||||||
R_TRY(impl->AcquireSessionId(new_session_id));
|
R_TRY(impl->AcquireSessionId(system, new_session_id));
|
||||||
|
|
||||||
LOG_DEBUG(Service_Audio, "Opening new AudioIn, session_id={}, free sessions={}", new_session_id,
|
LOG_DEBUG(Service_Audio, "Opening new AudioIn, session_id={}, free sessions={}", new_session_id,
|
||||||
impl->num_free_sessions);
|
impl->num_free_sessions);
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ IAudioOut::IAudioOut(Core::System& system_, Manager& manager, size_t session_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
IAudioOut::~IAudioOut() {
|
IAudioOut::~IAudioOut() {
|
||||||
impl->Free();
|
impl->Free(system);
|
||||||
service_context.CloseEvent(event);
|
service_context.CloseEvent(event);
|
||||||
process->Close(system.Kernel());
|
process->Close(system.Kernel());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,8 +77,8 @@ Result IAudioOutManager::OpenAudioOutAuto(
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t new_session_id{};
|
size_t new_session_id{};
|
||||||
R_TRY(impl->LinkToManager());
|
R_TRY(impl->LinkToManager(system));
|
||||||
R_TRY(impl->AcquireSessionId(new_session_id));
|
R_TRY(impl->AcquireSessionId(system, new_session_id));
|
||||||
|
|
||||||
const auto device_name = Common::StringFromBuffer(name[0].name);
|
const auto device_name = Common::StringFromBuffer(name[0].name);
|
||||||
LOG_DEBUG(Service_Audio, "Opening new AudioOut, sessionid={}, free sessions={}", new_session_id,
|
LOG_DEBUG(Service_Audio, "Opening new AudioOut, sessionid={}, free sessions={}", new_session_id,
|
||||||
|
|||||||
@@ -40,8 +40,8 @@ std::vector<u8> default_logo_small;
|
|||||||
std::vector<u8> default_logo_large;
|
std::vector<u8> default_logo_large;
|
||||||
bool default_logos_loaded = false;
|
bool default_logos_loaded = false;
|
||||||
|
|
||||||
::Common::unordered_map<std::string, std::vector<u8>> news_images_small;
|
ankerl::unordered_dense::map<std::string, std::vector<u8>> news_images_small;
|
||||||
::Common::unordered_map<std::string, std::vector<u8>> news_images_large;
|
ankerl::unordered_dense::map<std::string, std::vector<u8>> news_images_large;
|
||||||
std::mutex images_mutex;
|
std::mutex images_mutex;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
#include <optional>
|
#include <optional>
|
||||||
#include <span>
|
#include <span>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "common/container/unordered_map.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
@@ -93,7 +93,7 @@ private:
|
|||||||
static s64 Now();
|
static s64 Now();
|
||||||
|
|
||||||
mutable std::mutex mtx;
|
mutable std::mutex mtx;
|
||||||
::Common::unordered_map<std::string, StoredNews> items;
|
ankerl::unordered_dense::map<std::string, StoredNews> items;
|
||||||
size_t open_counter{};
|
size_t open_counter{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/container/unordered_map.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
|
|
||||||
#include "common/fs/fs.h"
|
#include "common/fs/fs.h"
|
||||||
#include "core/hle/result.h"
|
#include "core/hle/result.h"
|
||||||
@@ -88,7 +88,7 @@ private:
|
|||||||
AlbumFileDateTime ConvertToAlbumDateTime(u64 posix_time) const;
|
AlbumFileDateTime ConvertToAlbumDateTime(u64 posix_time) const;
|
||||||
|
|
||||||
bool is_mounted{};
|
bool is_mounted{};
|
||||||
::Common::unordered_map<AlbumFileId, std::filesystem::path> album_files;
|
ankerl::unordered_dense::map<AlbumFileId, std::filesystem::path> album_files;
|
||||||
|
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
#include <random>
|
#include <random>
|
||||||
#include <span>
|
#include <span>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include "common/container/unordered_map.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
|
|
||||||
#include "common/logging.h"
|
#include "common/logging.h"
|
||||||
#include "common/socket_types.h"
|
#include "common/socket_types.h"
|
||||||
@@ -119,7 +119,7 @@ protected:
|
|||||||
std::array<LanStation, StationCountMax> stations;
|
std::array<LanStation, StationCountMax> stations;
|
||||||
std::array<NodeLatestUpdate, NodeCountMax> node_changes{};
|
std::array<NodeLatestUpdate, NodeCountMax> node_changes{};
|
||||||
std::array<u8, NodeCountMax> node_last_states{};
|
std::array<u8, NodeCountMax> node_last_states{};
|
||||||
::Common::unordered_map<MacAddress, NetworkInfo, MACAddressHash> scan_results{};
|
ankerl::unordered_dense::map<MacAddress, NetworkInfo, MACAddressHash> scan_results{};
|
||||||
NodeInfo node_info{};
|
NodeInfo node_info{};
|
||||||
NetworkInfo network_info{};
|
NetworkInfo network_info{};
|
||||||
State state{State::None};
|
State state{State::None};
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include "common/container/unordered_map.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
#include <boost/container_hash/hash.hpp>
|
#include <boost/container_hash/hash.hpp>
|
||||||
#include "common/logging.h"
|
#include "common/logging.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
@@ -331,7 +331,7 @@ private:
|
|||||||
};
|
};
|
||||||
static_assert(sizeof(LogPacketHeader) == 0x18, "LogPacketHeader is an invalid size");
|
static_assert(sizeof(LogPacketHeader) == 0x18, "LogPacketHeader is an invalid size");
|
||||||
|
|
||||||
::Common::unordered_map<LogPacketHeaderEntry, std::vector<u8>> entries{};
|
ankerl::unordered_dense::map<LogPacketHeaderEntry, std::vector<u8>> entries{};
|
||||||
LogDestination destination{LogDestination::All};
|
LogDestination destination{LogDestination::All};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include "common/container/unordered_map.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
#include <common/settings.h>
|
#include <common/settings.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "common/container/unordered_map.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
|
|
||||||
#include "core/device_memory_manager.h"
|
#include "core/device_memory_manager.h"
|
||||||
#include "core/hle/service/nvdrv/nvdata.h"
|
#include "core/hle/service/nvdrv/nvdata.h"
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include "common/container/unordered_map.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "common/bit_field.h"
|
#include "common/bit_field.h"
|
||||||
@@ -161,7 +161,7 @@ private:
|
|||||||
std::list<std::shared_ptr<Handle>> unmap_queue{};
|
std::list<std::shared_ptr<Handle>> unmap_queue{};
|
||||||
std::mutex unmap_queue_lock{}; //!< Protects access to `unmap_queue`
|
std::mutex unmap_queue_lock{}; //!< Protects access to `unmap_queue`
|
||||||
|
|
||||||
::Common::unordered_map<Handle::Id, std::shared_ptr<Handle>>
|
ankerl::unordered_dense::map<Handle::Id, std::shared_ptr<Handle>>
|
||||||
handles{}; //!< Main owning map of handles
|
handles{}; //!< Main owning map of handles
|
||||||
std::mutex handles_lock; //!< Protects access to `handles`
|
std::mutex handles_lock; //!< Protects access to `handles`
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include "common/container/unordered_set.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "common/address_space.h"
|
#include "common/address_space.h"
|
||||||
@@ -113,7 +113,7 @@ private:
|
|||||||
};
|
};
|
||||||
static_assert(sizeof(IoctlRemapEntry) == 20, "IoctlRemapEntry is incorrect size");
|
static_assert(sizeof(IoctlRemapEntry) == 20, "IoctlRemapEntry is incorrect size");
|
||||||
|
|
||||||
::Common::unordered_set<s64_le> map_buffer_offsets{};
|
ankerl::unordered_dense::set<s64_le> map_buffer_offsets{};
|
||||||
|
|
||||||
struct IoctlMapBufferEx {
|
struct IoctlMapBufferEx {
|
||||||
MappingFlags flags{}; // bit0: fixed_offset, bit2: cacheable
|
MappingFlags flags{}; // bit0: fixed_offset, bit2: cacheable
|
||||||
|
|||||||
@@ -217,7 +217,7 @@ private:
|
|||||||
NvCore::SyncpointManager& syncpoint_manager;
|
NvCore::SyncpointManager& syncpoint_manager;
|
||||||
NvCore::NvMap& nvmap;
|
NvCore::NvMap& nvmap;
|
||||||
std::shared_ptr<Tegra::Control::ChannelState> channel_state;
|
std::shared_ptr<Tegra::Control::ChannelState> channel_state;
|
||||||
::Common::unordered_map<DeviceFD, NvCore::SessionId> sessions;
|
ankerl::unordered_dense::map<DeviceFD, NvCore::SessionId> sessions;
|
||||||
u32 channel_syncpoint;
|
u32 channel_syncpoint;
|
||||||
std::mutex channel_mutex;
|
std::mutex channel_mutex;
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include "common/container/unordered_map.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
@@ -138,7 +138,7 @@ protected:
|
|||||||
NvCore::NvMap& nvmap;
|
NvCore::NvMap& nvmap;
|
||||||
NvCore::ChannelType channel_type;
|
NvCore::ChannelType channel_type;
|
||||||
std::array<u32, MaxSyncPoints> device_syncpoints{};
|
std::array<u32, MaxSyncPoints> device_syncpoints{};
|
||||||
::Common::unordered_map<DeviceFD, NvCore::SessionId> sessions;
|
ankerl::unordered_dense::map<DeviceFD, NvCore::SessionId> sessions;
|
||||||
};
|
};
|
||||||
}; // namespace Devices
|
}; // namespace Devices
|
||||||
} // namespace Service::Nvidia
|
} // namespace Service::Nvidia
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "common/container/unordered_map.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "common/common_funcs.h"
|
#include "common/common_funcs.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
@@ -118,7 +118,7 @@ private:
|
|||||||
|
|
||||||
NvCore::Container& container;
|
NvCore::Container& container;
|
||||||
NvCore::NvMap& file;
|
NvCore::NvMap& file;
|
||||||
::Common::unordered_map<DeviceFD, NvCore::SessionId> sessions;
|
ankerl::unordered_dense::map<DeviceFD, NvCore::SessionId> sessions;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Service::Nvidia::Devices
|
} // namespace Service::Nvidia::Devices
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <span>
|
#include <span>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "common/container/unordered_map.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "core/hle/service/kernel_helpers.h"
|
#include "core/hle/service/kernel_helpers.h"
|
||||||
@@ -103,7 +103,7 @@ private:
|
|||||||
/// Id to use for the next open file descriptor.
|
/// Id to use for the next open file descriptor.
|
||||||
DeviceFD next_fd = 1;
|
DeviceFD next_fd = 1;
|
||||||
|
|
||||||
using FilesContainerType = ::Common::unordered_map<DeviceFD, std::shared_ptr<Devices::nvdevice>>;
|
using FilesContainerType = ankerl::unordered_dense::map<DeviceFD, std::shared_ptr<Devices::nvdevice>>;
|
||||||
/// Mapping of file descriptors to the devices they reference.
|
/// Mapping of file descriptors to the devices they reference.
|
||||||
FilesContainerType open_files;
|
FilesContainerType open_files;
|
||||||
|
|
||||||
@@ -111,7 +111,7 @@ private:
|
|||||||
|
|
||||||
EventInterface events_interface;
|
EventInterface events_interface;
|
||||||
|
|
||||||
::Common::unordered_map<std::string, std::function<FilesContainerType::iterator(DeviceFD)>> builders;
|
ankerl::unordered_dense::map<std::string, std::function<FilesContainerType::iterator(DeviceFD)>> builders;
|
||||||
};
|
};
|
||||||
|
|
||||||
void LoopProcess(Core::System& system);
|
void LoopProcess(Core::System& system);
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include "common/container/unordered_map.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "core/hle/service/nvnflinger/binder.h"
|
#include "core/hle/service/nvnflinger/binder.h"
|
||||||
@@ -39,8 +39,8 @@ private:
|
|||||||
|
|
||||||
mutable std::mutex lock;
|
mutable std::mutex lock;
|
||||||
s32 last_id = 0;
|
s32 last_id = 0;
|
||||||
::Common::unordered_map<s32, std::shared_ptr<android::IBinder>> binders;
|
ankerl::unordered_dense::map<s32, std::shared_ptr<android::IBinder>> binders;
|
||||||
::Common::unordered_map<s32, RefCounts> refcounts;
|
ankerl::unordered_dense::map<s32, RefCounts> refcounts;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Service::Nvnflinger
|
} // namespace Service::Nvnflinger
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/container/unordered_map.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
|
|
||||||
#include "common/uuid.h"
|
#include "common/uuid.h"
|
||||||
#include "core/hle/service/cmif_types.h"
|
#include "core/hle/service/cmif_types.h"
|
||||||
@@ -56,10 +56,10 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
::Common::unordered_map<AppKey, bool, AppKeyHash> app_auto_transfer_{};
|
ankerl::unordered_dense::map<AppKey, bool, AppKeyHash> app_auto_transfer_{};
|
||||||
::Common::unordered_map<Common::UUID, bool> global_auto_upload_{};
|
ankerl::unordered_dense::map<Common::UUID, bool> global_auto_upload_{};
|
||||||
::Common::unordered_map<Common::UUID, bool> global_auto_download_{};
|
ankerl::unordered_dense::map<Common::UUID, bool> global_auto_download_{};
|
||||||
::Common::unordered_map<AppKey, u8, AppKeyHash> autonomy_task_status_{};
|
ankerl::unordered_dense::map<AppKey, u8, AppKeyHash> autonomy_task_status_{};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Service::OLSC
|
} // namespace Service::OLSC
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include "common/container/unordered_map.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "core/hle/service/hle_ipc.h"
|
#include "core/hle/service/hle_ipc.h"
|
||||||
|
|
||||||
@@ -99,8 +99,8 @@ private:
|
|||||||
void ReportUnimplementedFunction(HLERequestContext& ctx, const FunctionInfoBase* info);
|
void ReportUnimplementedFunction(HLERequestContext& ctx, const FunctionInfoBase* info);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
::Common::unordered_map<u32, FunctionInfoBase> handlers;
|
ankerl::unordered_dense::map<u32, FunctionInfoBase> handlers;
|
||||||
::Common::unordered_map<u32, FunctionInfoBase> handlers_tipc;
|
ankerl::unordered_dense::map<u32, FunctionInfoBase> handlers_tipc;
|
||||||
/// Used to gain exclusive access to the service members, e.g. from CoreTiming thread.
|
/// Used to gain exclusive access to the service members, e.g. from CoreTiming thread.
|
||||||
std::mutex lock_service;
|
std::mutex lock_service;
|
||||||
/// System context that the service operates under.
|
/// System context that the service operates under.
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "common/container/unordered_map.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
#include <concepts>
|
#include <concepts>
|
||||||
|
|
||||||
#include "core/hle/kernel/k_port.h"
|
#include "core/hle/kernel/k_port.h"
|
||||||
@@ -100,8 +100,8 @@ private:
|
|||||||
|
|
||||||
/// Map of registered services, retrieved using GetServicePort.
|
/// Map of registered services, retrieved using GetServicePort.
|
||||||
mutable std::mutex lock;
|
mutable std::mutex lock;
|
||||||
::Common::unordered_map<std::string, SessionRequestHandlerFactory> registered_services;
|
ankerl::unordered_dense::map<std::string, SessionRequestHandlerFactory> registered_services;
|
||||||
::Common::unordered_map<std::string, Kernel::KClientPort*> service_ports;
|
ankerl::unordered_dense::map<std::string, Kernel::KClientPort*> service_ports;
|
||||||
|
|
||||||
/// Kernel context
|
/// Kernel context
|
||||||
Kernel::KernelCore& kernel;
|
Kernel::KernelCore& kernel;
|
||||||
|
|||||||
@@ -54,11 +54,11 @@ void PutValue(std::span<u8> buffer, const T& t) {
|
|||||||
|
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
||||||
void BSD_USA::PollWork::Execute(BSD_USA* bsd) {
|
void BSD::PollWork::Execute(BSD* bsd) {
|
||||||
std::tie(ret, bsd_errno) = bsd->PollImpl(write_buffer, read_buffer, nfds, timeout);
|
std::tie(ret, bsd_errno) = bsd->PollImpl(write_buffer, read_buffer, nfds, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::PollWork::Response(HLERequestContext& ctx) {
|
void BSD::PollWork::Response(HLERequestContext& ctx) {
|
||||||
if (write_buffer.size() > 0) {
|
if (write_buffer.size() > 0) {
|
||||||
ctx.WriteBuffer(write_buffer);
|
ctx.WriteBuffer(write_buffer);
|
||||||
}
|
}
|
||||||
@@ -69,11 +69,11 @@ void BSD_USA::PollWork::Response(HLERequestContext& ctx) {
|
|||||||
rb.PushEnum(bsd_errno);
|
rb.PushEnum(bsd_errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::AcceptWork::Execute(BSD_USA* bsd) {
|
void BSD::AcceptWork::Execute(BSD* bsd) {
|
||||||
std::tie(ret, bsd_errno) = bsd->AcceptImpl(fd, write_buffer);
|
std::tie(ret, bsd_errno) = bsd->AcceptImpl(fd, write_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::AcceptWork::Response(HLERequestContext& ctx) {
|
void BSD::AcceptWork::Response(HLERequestContext& ctx) {
|
||||||
if (write_buffer.size() > 0) {
|
if (write_buffer.size() > 0) {
|
||||||
ctx.WriteBuffer(write_buffer);
|
ctx.WriteBuffer(write_buffer);
|
||||||
}
|
}
|
||||||
@@ -85,22 +85,22 @@ void BSD_USA::AcceptWork::Response(HLERequestContext& ctx) {
|
|||||||
rb.Push<u32>(static_cast<u32>(write_buffer.size()));
|
rb.Push<u32>(static_cast<u32>(write_buffer.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::ConnectWork::Execute(BSD_USA* bsd) {
|
void BSD::ConnectWork::Execute(BSD* bsd) {
|
||||||
bsd_errno = bsd->ConnectImpl(fd, addr);
|
bsd_errno = bsd->ConnectImpl(fd, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::ConnectWork::Response(HLERequestContext& ctx) {
|
void BSD::ConnectWork::Response(HLERequestContext& ctx) {
|
||||||
IPC::ResponseBuilder rb{ctx, 4};
|
IPC::ResponseBuilder rb{ctx, 4};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
rb.Push<s32>(bsd_errno == Errno::SUCCESS ? 0 : -1);
|
rb.Push<s32>(bsd_errno == Errno::SUCCESS ? 0 : -1);
|
||||||
rb.PushEnum(bsd_errno);
|
rb.PushEnum(bsd_errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::RecvWork::Execute(BSD_USA* bsd) {
|
void BSD::RecvWork::Execute(BSD* bsd) {
|
||||||
std::tie(ret, bsd_errno) = bsd->RecvImpl(fd, flags, message);
|
std::tie(ret, bsd_errno) = bsd->RecvImpl(fd, flags, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::RecvWork::Response(HLERequestContext& ctx) {
|
void BSD::RecvWork::Response(HLERequestContext& ctx) {
|
||||||
ctx.WriteBuffer(message);
|
ctx.WriteBuffer(message);
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 4};
|
IPC::ResponseBuilder rb{ctx, 4};
|
||||||
@@ -109,11 +109,11 @@ void BSD_USA::RecvWork::Response(HLERequestContext& ctx) {
|
|||||||
rb.PushEnum(bsd_errno);
|
rb.PushEnum(bsd_errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::RecvFromWork::Execute(BSD_USA* bsd) {
|
void BSD::RecvFromWork::Execute(BSD* bsd) {
|
||||||
std::tie(ret, bsd_errno) = bsd->RecvFromImpl(fd, flags, message, addr);
|
std::tie(ret, bsd_errno) = bsd->RecvFromImpl(fd, flags, message, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::RecvFromWork::Response(HLERequestContext& ctx) {
|
void BSD::RecvFromWork::Response(HLERequestContext& ctx) {
|
||||||
ctx.WriteBuffer(message, 0);
|
ctx.WriteBuffer(message, 0);
|
||||||
if (!addr.empty()) {
|
if (!addr.empty()) {
|
||||||
ctx.WriteBuffer(addr, 1);
|
ctx.WriteBuffer(addr, 1);
|
||||||
@@ -126,29 +126,29 @@ void BSD_USA::RecvFromWork::Response(HLERequestContext& ctx) {
|
|||||||
rb.Push<u32>(static_cast<u32>(addr.size()));
|
rb.Push<u32>(static_cast<u32>(addr.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::SendWork::Execute(BSD_USA* bsd) {
|
void BSD::SendWork::Execute(BSD* bsd) {
|
||||||
std::tie(ret, bsd_errno) = bsd->SendImpl(fd, flags, message);
|
std::tie(ret, bsd_errno) = bsd->SendImpl(fd, flags, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::SendWork::Response(HLERequestContext& ctx) {
|
void BSD::SendWork::Response(HLERequestContext& ctx) {
|
||||||
IPC::ResponseBuilder rb{ctx, 4};
|
IPC::ResponseBuilder rb{ctx, 4};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
rb.Push<s32>(ret);
|
rb.Push<s32>(ret);
|
||||||
rb.PushEnum(bsd_errno);
|
rb.PushEnum(bsd_errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::SendToWork::Execute(BSD_USA* bsd) {
|
void BSD::SendToWork::Execute(BSD* bsd) {
|
||||||
std::tie(ret, bsd_errno) = bsd->SendToImpl(fd, flags, message, addr);
|
std::tie(ret, bsd_errno) = bsd->SendToImpl(fd, flags, message, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::SendToWork::Response(HLERequestContext& ctx) {
|
void BSD::SendToWork::Response(HLERequestContext& ctx) {
|
||||||
IPC::ResponseBuilder rb{ctx, 4};
|
IPC::ResponseBuilder rb{ctx, 4};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
rb.Push<s32>(ret);
|
rb.Push<s32>(ret);
|
||||||
rb.PushEnum(bsd_errno);
|
rb.PushEnum(bsd_errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::RegisterClient(HLERequestContext& ctx) {
|
void BSD::RegisterClient(HLERequestContext& ctx) {
|
||||||
LOG_WARNING(Service, "(STUBBED) called");
|
LOG_WARNING(Service, "(STUBBED) called");
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 3};
|
IPC::ResponseBuilder rb{ctx, 3};
|
||||||
@@ -157,7 +157,7 @@ void BSD_USA::RegisterClient(HLERequestContext& ctx) {
|
|||||||
rb.Push<s32>(0); // bsd errno
|
rb.Push<s32>(0); // bsd errno
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::StartMonitoring(HLERequestContext& ctx) {
|
void BSD::StartMonitoring(HLERequestContext& ctx) {
|
||||||
LOG_WARNING(Service, "(STUBBED) called");
|
LOG_WARNING(Service, "(STUBBED) called");
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
@@ -165,7 +165,7 @@ void BSD_USA::StartMonitoring(HLERequestContext& ctx) {
|
|||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::Socket(HLERequestContext& ctx) {
|
void BSD::Socket(HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
const u32 domain = rp.Pop<u32>();
|
const u32 domain = rp.Pop<u32>();
|
||||||
const u32 type = rp.Pop<u32>();
|
const u32 type = rp.Pop<u32>();
|
||||||
@@ -181,7 +181,7 @@ void BSD_USA::Socket(HLERequestContext& ctx) {
|
|||||||
rb.PushEnum(bsd_errno);
|
rb.PushEnum(bsd_errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::SocketExempt(HLERequestContext& ctx) {
|
void BSD::SocketExempt(HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
const u32 domain = rp.Pop<u32>();
|
const u32 domain = rp.Pop<u32>();
|
||||||
const u32 type = rp.Pop<u32>();
|
const u32 type = rp.Pop<u32>();
|
||||||
@@ -200,7 +200,7 @@ void BSD_USA::SocketExempt(HLERequestContext& ctx) {
|
|||||||
rb.PushEnum(bsd_errno);
|
rb.PushEnum(bsd_errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::Select(HLERequestContext& ctx) {
|
void BSD::Select(HLERequestContext& ctx) {
|
||||||
LOG_DEBUG(Service, "(STUBBED) called");
|
LOG_DEBUG(Service, "(STUBBED) called");
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 4};
|
IPC::ResponseBuilder rb{ctx, 4};
|
||||||
@@ -210,7 +210,7 @@ void BSD_USA::Select(HLERequestContext& ctx) {
|
|||||||
rb.Push<u32>(0); // bsd errno
|
rb.Push<u32>(0); // bsd errno
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::Poll(HLERequestContext& ctx) {
|
void BSD::Poll(HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
const s32 nfds = rp.Pop<s32>();
|
const s32 nfds = rp.Pop<s32>();
|
||||||
const s32 timeout = rp.Pop<s32>();
|
const s32 timeout = rp.Pop<s32>();
|
||||||
@@ -225,7 +225,7 @@ void BSD_USA::Poll(HLERequestContext& ctx) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::Accept(HLERequestContext& ctx) {
|
void BSD::Accept(HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
const s32 fd = rp.Pop<s32>();
|
const s32 fd = rp.Pop<s32>();
|
||||||
|
|
||||||
@@ -237,7 +237,7 @@ void BSD_USA::Accept(HLERequestContext& ctx) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::Bind(HLERequestContext& ctx) {
|
void BSD::Bind(HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
const s32 fd = rp.Pop<s32>();
|
const s32 fd = rp.Pop<s32>();
|
||||||
|
|
||||||
@@ -245,7 +245,7 @@ void BSD_USA::Bind(HLERequestContext& ctx) {
|
|||||||
BuildErrnoResponse(ctx, BindImpl(fd, ctx.ReadBuffer()));
|
BuildErrnoResponse(ctx, BindImpl(fd, ctx.ReadBuffer()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::Connect(HLERequestContext& ctx) {
|
void BSD::Connect(HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
const s32 fd = rp.Pop<s32>();
|
const s32 fd = rp.Pop<s32>();
|
||||||
|
|
||||||
@@ -257,7 +257,7 @@ void BSD_USA::Connect(HLERequestContext& ctx) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::GetPeerName(HLERequestContext& ctx) {
|
void BSD::GetPeerName(HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
const s32 fd = rp.Pop<s32>();
|
const s32 fd = rp.Pop<s32>();
|
||||||
|
|
||||||
@@ -275,7 +275,7 @@ void BSD_USA::GetPeerName(HLERequestContext& ctx) {
|
|||||||
rb.Push<u32>(static_cast<u32>(write_buffer.size()));
|
rb.Push<u32>(static_cast<u32>(write_buffer.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::GetSockName(HLERequestContext& ctx) {
|
void BSD::GetSockName(HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
const s32 fd = rp.Pop<s32>();
|
const s32 fd = rp.Pop<s32>();
|
||||||
|
|
||||||
@@ -293,7 +293,7 @@ void BSD_USA::GetSockName(HLERequestContext& ctx) {
|
|||||||
rb.Push<u32>(static_cast<u32>(write_buffer.size()));
|
rb.Push<u32>(static_cast<u32>(write_buffer.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::GetSockOpt(HLERequestContext& ctx) {
|
void BSD::GetSockOpt(HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
const s32 fd = rp.Pop<s32>();
|
const s32 fd = rp.Pop<s32>();
|
||||||
const u32 level = rp.Pop<u32>();
|
const u32 level = rp.Pop<u32>();
|
||||||
@@ -315,7 +315,7 @@ void BSD_USA::GetSockOpt(HLERequestContext& ctx) {
|
|||||||
rb.Push<u32>(static_cast<u32>(optval.size()));
|
rb.Push<u32>(static_cast<u32>(optval.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::Listen(HLERequestContext& ctx) {
|
void BSD::Listen(HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
const s32 fd = rp.Pop<s32>();
|
const s32 fd = rp.Pop<s32>();
|
||||||
const s32 backlog = rp.Pop<s32>();
|
const s32 backlog = rp.Pop<s32>();
|
||||||
@@ -325,7 +325,7 @@ void BSD_USA::Listen(HLERequestContext& ctx) {
|
|||||||
BuildErrnoResponse(ctx, ListenImpl(fd, backlog));
|
BuildErrnoResponse(ctx, ListenImpl(fd, backlog));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::Fcntl(HLERequestContext& ctx) {
|
void BSD::Fcntl(HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
const s32 fd = rp.Pop<s32>();
|
const s32 fd = rp.Pop<s32>();
|
||||||
const s32 cmd = rp.Pop<s32>();
|
const s32 cmd = rp.Pop<s32>();
|
||||||
@@ -341,7 +341,7 @@ void BSD_USA::Fcntl(HLERequestContext& ctx) {
|
|||||||
rb.PushEnum(bsd_errno);
|
rb.PushEnum(bsd_errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::SetSockOpt(HLERequestContext& ctx) {
|
void BSD::SetSockOpt(HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
|
|
||||||
const s32 fd = rp.Pop<s32>();
|
const s32 fd = rp.Pop<s32>();
|
||||||
@@ -355,7 +355,7 @@ void BSD_USA::SetSockOpt(HLERequestContext& ctx) {
|
|||||||
BuildErrnoResponse(ctx, SetSockOptImpl(fd, level, optname, optval));
|
BuildErrnoResponse(ctx, SetSockOptImpl(fd, level, optname, optval));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::Shutdown(HLERequestContext& ctx) {
|
void BSD::Shutdown(HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
|
|
||||||
const s32 fd = rp.Pop<s32>();
|
const s32 fd = rp.Pop<s32>();
|
||||||
@@ -366,7 +366,7 @@ void BSD_USA::Shutdown(HLERequestContext& ctx) {
|
|||||||
BuildErrnoResponse(ctx, ShutdownImpl(fd, how));
|
BuildErrnoResponse(ctx, ShutdownImpl(fd, how));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::Recv(HLERequestContext& ctx) {
|
void BSD::Recv(HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
|
|
||||||
const s32 fd = rp.Pop<s32>();
|
const s32 fd = rp.Pop<s32>();
|
||||||
@@ -381,7 +381,7 @@ void BSD_USA::Recv(HLERequestContext& ctx) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::RecvFrom(HLERequestContext& ctx) {
|
void BSD::RecvFrom(HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
|
|
||||||
const s32 fd = rp.Pop<s32>();
|
const s32 fd = rp.Pop<s32>();
|
||||||
@@ -398,7 +398,7 @@ void BSD_USA::RecvFrom(HLERequestContext& ctx) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::Send(HLERequestContext& ctx) {
|
void BSD::Send(HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
|
|
||||||
const s32 fd = rp.Pop<s32>();
|
const s32 fd = rp.Pop<s32>();
|
||||||
@@ -413,7 +413,7 @@ void BSD_USA::Send(HLERequestContext& ctx) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::SendTo(HLERequestContext& ctx) {
|
void BSD::SendTo(HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
const s32 fd = rp.Pop<s32>();
|
const s32 fd = rp.Pop<s32>();
|
||||||
const u32 flags = rp.Pop<u32>();
|
const u32 flags = rp.Pop<u32>();
|
||||||
@@ -429,7 +429,7 @@ void BSD_USA::SendTo(HLERequestContext& ctx) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::Write(HLERequestContext& ctx) {
|
void BSD::Write(HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
const s32 fd = rp.Pop<s32>();
|
const s32 fd = rp.Pop<s32>();
|
||||||
|
|
||||||
@@ -442,7 +442,7 @@ void BSD_USA::Write(HLERequestContext& ctx) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::Read(HLERequestContext& ctx) {
|
void BSD::Read(HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
const s32 fd = rp.Pop<s32>();
|
const s32 fd = rp.Pop<s32>();
|
||||||
|
|
||||||
@@ -454,7 +454,7 @@ void BSD_USA::Read(HLERequestContext& ctx) {
|
|||||||
rb.Push<u32>(0); // bsd errno
|
rb.Push<u32>(0); // bsd errno
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::Close(HLERequestContext& ctx) {
|
void BSD::Close(HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
const s32 fd = rp.Pop<s32>();
|
const s32 fd = rp.Pop<s32>();
|
||||||
|
|
||||||
@@ -464,7 +464,7 @@ void BSD_USA::Close(HLERequestContext& ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Only bsd:s is able to dup()
|
/// @brief Only bsd:s is able to dup()
|
||||||
void BSD_USA::DuplicateSocket(HLERequestContext& ctx) {
|
void BSD::DuplicateSocket(HLERequestContext& ctx) {
|
||||||
struct InputParameters {
|
struct InputParameters {
|
||||||
s32 fd;
|
s32 fd;
|
||||||
u64 reserved;
|
u64 reserved;
|
||||||
@@ -505,7 +505,7 @@ void BSD_USA::DuplicateSocket(HLERequestContext& ctx) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::EventFd(HLERequestContext& ctx) {
|
void BSD::EventFd(HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
const u64 initval = rp.Pop<u64>();
|
const u64 initval = rp.Pop<u64>();
|
||||||
const u32 flags = rp.Pop<u32>();
|
const u32 flags = rp.Pop<u32>();
|
||||||
@@ -516,12 +516,12 @@ void BSD_USA::EventFd(HLERequestContext& ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename Work>
|
template <typename Work>
|
||||||
void BSD_USA::ExecuteWork(HLERequestContext& ctx, Work work) {
|
void BSD::ExecuteWork(HLERequestContext& ctx, Work work) {
|
||||||
work.Execute(this);
|
work.Execute(this);
|
||||||
work.Response(ctx);
|
work.Response(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<s32, Errno> BSD_USA::SocketImpl(Domain domain, Type type, Protocol protocol) {
|
std::pair<s32, Errno> BSD::SocketImpl(Domain domain, Type type, Protocol protocol) {
|
||||||
// user bsd:u has restrictions on SOCK_SEQPACKET and SOCK_RAW
|
// user bsd:u has restrictions on SOCK_SEQPACKET and SOCK_RAW
|
||||||
if (is_user && (type == Type::SEQPACKET || type == Type::RAW)) {
|
if (is_user && (type == Type::SEQPACKET || type == Type::RAW)) {
|
||||||
if (type == Type::RAW && domain == Domain::INET && protocol == Protocol::ICMP) {
|
if (type == Type::RAW && domain == Domain::INET && protocol == Protocol::ICMP) {
|
||||||
@@ -565,7 +565,7 @@ std::pair<s32, Errno> BSD_USA::SocketImpl(Domain domain, Type type, Protocol pro
|
|||||||
return {fd, Errno::SUCCESS};
|
return {fd, Errno::SUCCESS};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<s32, Errno> BSD_USA::PollImpl(std::vector<u8>& write_buffer, std::span<const u8> read_buffer,
|
std::pair<s32, Errno> BSD::PollImpl(std::vector<u8>& write_buffer, std::span<const u8> read_buffer,
|
||||||
s32 nfds, s32 timeout) {
|
s32 nfds, s32 timeout) {
|
||||||
if (nfds <= 0) {
|
if (nfds <= 0) {
|
||||||
// When no entries are provided, -1 is returned with errno zero
|
// When no entries are provided, -1 is returned with errno zero
|
||||||
@@ -632,7 +632,7 @@ std::pair<s32, Errno> BSD_USA::PollImpl(std::vector<u8>& write_buffer, std::span
|
|||||||
return Translate(result);
|
return Translate(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<s32, Errno> BSD_USA::AcceptImpl(s32 fd, std::vector<u8>& write_buffer) {
|
std::pair<s32, Errno> BSD::AcceptImpl(s32 fd, std::vector<u8>& write_buffer) {
|
||||||
if (!IsFileDescriptorValid(fd)) {
|
if (!IsFileDescriptorValid(fd)) {
|
||||||
return {-1, Errno::BADF};
|
return {-1, Errno::BADF};
|
||||||
}
|
}
|
||||||
@@ -660,7 +660,7 @@ std::pair<s32, Errno> BSD_USA::AcceptImpl(s32 fd, std::vector<u8>& write_buffer)
|
|||||||
return {new_fd, Errno::SUCCESS};
|
return {new_fd, Errno::SUCCESS};
|
||||||
}
|
}
|
||||||
|
|
||||||
Errno BSD_USA::BindImpl(s32 fd, std::span<const u8> addr) {
|
Errno BSD::BindImpl(s32 fd, std::span<const u8> addr) {
|
||||||
if (!IsFileDescriptorValid(fd)) {
|
if (!IsFileDescriptorValid(fd)) {
|
||||||
return Errno::BADF;
|
return Errno::BADF;
|
||||||
}
|
}
|
||||||
@@ -675,7 +675,7 @@ Errno BSD_USA::BindImpl(s32 fd, std::span<const u8> addr) {
|
|||||||
return Translate(file_descriptors[fd]->socket->Bind(Translate(addr_in)));
|
return Translate(file_descriptors[fd]->socket->Bind(Translate(addr_in)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Errno BSD_USA::ConnectImpl(s32 fd, std::span<const u8> addr) {
|
Errno BSD::ConnectImpl(s32 fd, std::span<const u8> addr) {
|
||||||
if (!IsFileDescriptorValid(fd)) {
|
if (!IsFileDescriptorValid(fd)) {
|
||||||
return Errno::BADF;
|
return Errno::BADF;
|
||||||
}
|
}
|
||||||
@@ -698,7 +698,7 @@ Errno BSD_USA::ConnectImpl(s32 fd, std::span<const u8> addr) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Errno BSD_USA::GetPeerNameImpl(s32 fd, std::vector<u8>& write_buffer) {
|
Errno BSD::GetPeerNameImpl(s32 fd, std::vector<u8>& write_buffer) {
|
||||||
if (!IsFileDescriptorValid(fd)) {
|
if (!IsFileDescriptorValid(fd)) {
|
||||||
return Errno::BADF;
|
return Errno::BADF;
|
||||||
}
|
}
|
||||||
@@ -720,7 +720,7 @@ Errno BSD_USA::GetPeerNameImpl(s32 fd, std::vector<u8>& write_buffer) {
|
|||||||
return Translate(bsd_errno);
|
return Translate(bsd_errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
Errno BSD_USA::GetSockNameImpl(s32 fd, std::vector<u8>& write_buffer) {
|
Errno BSD::GetSockNameImpl(s32 fd, std::vector<u8>& write_buffer) {
|
||||||
if (!IsFileDescriptorValid(fd)) {
|
if (!IsFileDescriptorValid(fd)) {
|
||||||
return Errno::BADF;
|
return Errno::BADF;
|
||||||
}
|
}
|
||||||
@@ -742,7 +742,7 @@ Errno BSD_USA::GetSockNameImpl(s32 fd, std::vector<u8>& write_buffer) {
|
|||||||
return Translate(bsd_errno);
|
return Translate(bsd_errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
Errno BSD_USA::ListenImpl(s32 fd, s32 backlog) {
|
Errno BSD::ListenImpl(s32 fd, s32 backlog) {
|
||||||
if (!IsFileDescriptorValid(fd)) {
|
if (!IsFileDescriptorValid(fd)) {
|
||||||
return Errno::BADF;
|
return Errno::BADF;
|
||||||
}
|
}
|
||||||
@@ -753,7 +753,7 @@ Errno BSD_USA::ListenImpl(s32 fd, s32 backlog) {
|
|||||||
return Translate(file_descriptors[fd]->socket->Listen(backlog));
|
return Translate(file_descriptors[fd]->socket->Listen(backlog));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<s32, Errno> BSD_USA::FcntlImpl(s32 fd, FcntlCmd cmd, s32 arg) {
|
std::pair<s32, Errno> BSD::FcntlImpl(s32 fd, FcntlCmd cmd, s32 arg) {
|
||||||
if (!IsFileDescriptorValid(fd)) {
|
if (!IsFileDescriptorValid(fd)) {
|
||||||
return {-1, Errno::BADF};
|
return {-1, Errno::BADF};
|
||||||
}
|
}
|
||||||
@@ -783,7 +783,7 @@ std::pair<s32, Errno> BSD_USA::FcntlImpl(s32 fd, FcntlCmd cmd, s32 arg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Errno BSD_USA::GetSockOptImpl(s32 fd, u32 level, OptName optname, std::vector<u8>& optval) {
|
Errno BSD::GetSockOptImpl(s32 fd, u32 level, OptName optname, std::vector<u8>& optval) {
|
||||||
if (!IsFileDescriptorValid(fd)) {
|
if (!IsFileDescriptorValid(fd)) {
|
||||||
return Errno::BADF;
|
return Errno::BADF;
|
||||||
}
|
}
|
||||||
@@ -818,7 +818,7 @@ Errno BSD_USA::GetSockOptImpl(s32 fd, u32 level, OptName optname, std::vector<u8
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Errno BSD_USA::SetSockOptImpl(s32 fd, u32 level, OptName optname, std::span<const u8> optval) {
|
Errno BSD::SetSockOptImpl(s32 fd, u32 level, OptName optname, std::span<const u8> optval) {
|
||||||
if (!IsFileDescriptorValid(fd)) {
|
if (!IsFileDescriptorValid(fd)) {
|
||||||
return Errno::BADF;
|
return Errno::BADF;
|
||||||
}
|
}
|
||||||
@@ -872,7 +872,7 @@ Errno BSD_USA::SetSockOptImpl(s32 fd, u32 level, OptName optname, std::span<cons
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Errno BSD_USA::ShutdownImpl(s32 fd, s32 how) {
|
Errno BSD::ShutdownImpl(s32 fd, s32 how) {
|
||||||
if (!IsFileDescriptorValid(fd)) {
|
if (!IsFileDescriptorValid(fd)) {
|
||||||
return Errno::BADF;
|
return Errno::BADF;
|
||||||
}
|
}
|
||||||
@@ -884,7 +884,7 @@ Errno BSD_USA::ShutdownImpl(s32 fd, s32 how) {
|
|||||||
return Translate(file_descriptors[fd]->socket->Shutdown(host_how));
|
return Translate(file_descriptors[fd]->socket->Shutdown(host_how));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<s32, Errno> BSD_USA::RecvImpl(s32 fd, u32 flags, std::vector<u8>& message) {
|
std::pair<s32, Errno> BSD::RecvImpl(s32 fd, u32 flags, std::vector<u8>& message) {
|
||||||
if (!IsFileDescriptorValid(fd)) {
|
if (!IsFileDescriptorValid(fd)) {
|
||||||
return {-1, Errno::BADF};
|
return {-1, Errno::BADF};
|
||||||
}
|
}
|
||||||
@@ -911,7 +911,7 @@ std::pair<s32, Errno> BSD_USA::RecvImpl(s32 fd, u32 flags, std::vector<u8>& mess
|
|||||||
return {ret, bsd_errno};
|
return {ret, bsd_errno};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<s32, Errno> BSD_USA::RecvFromImpl(s32 fd, u32 flags, std::vector<u8>& message,
|
std::pair<s32, Errno> BSD::RecvFromImpl(s32 fd, u32 flags, std::vector<u8>& message,
|
||||||
std::vector<u8>& addr) {
|
std::vector<u8>& addr) {
|
||||||
if (!IsFileDescriptorValid(fd)) {
|
if (!IsFileDescriptorValid(fd)) {
|
||||||
return {-1, Errno::BADF};
|
return {-1, Errno::BADF};
|
||||||
@@ -958,7 +958,7 @@ std::pair<s32, Errno> BSD_USA::RecvFromImpl(s32 fd, u32 flags, std::vector<u8>&
|
|||||||
return {ret, bsd_errno};
|
return {ret, bsd_errno};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<s32, Errno> BSD_USA::SendImpl(s32 fd, u32 flags, std::span<const u8> message) {
|
std::pair<s32, Errno> BSD::SendImpl(s32 fd, u32 flags, std::span<const u8> message) {
|
||||||
if (!IsFileDescriptorValid(fd)) {
|
if (!IsFileDescriptorValid(fd)) {
|
||||||
return {-1, Errno::BADF};
|
return {-1, Errno::BADF};
|
||||||
}
|
}
|
||||||
@@ -969,7 +969,7 @@ std::pair<s32, Errno> BSD_USA::SendImpl(s32 fd, u32 flags, std::span<const u8> m
|
|||||||
return Translate(file_descriptors[fd]->socket->Send(message, flags));
|
return Translate(file_descriptors[fd]->socket->Send(message, flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<s32, Errno> BSD_USA::SendToImpl(s32 fd, u32 flags, std::span<const u8> message,
|
std::pair<s32, Errno> BSD::SendToImpl(s32 fd, u32 flags, std::span<const u8> message,
|
||||||
std::span<const u8> addr) {
|
std::span<const u8> addr) {
|
||||||
if (!IsFileDescriptorValid(fd)) {
|
if (!IsFileDescriptorValid(fd)) {
|
||||||
return {-1, Errno::BADF};
|
return {-1, Errno::BADF};
|
||||||
@@ -991,7 +991,7 @@ std::pair<s32, Errno> BSD_USA::SendToImpl(s32 fd, u32 flags, std::span<const u8>
|
|||||||
return Translate(file_descriptors[fd]->socket->SendTo(flags, message, p_addr_in));
|
return Translate(file_descriptors[fd]->socket->SendTo(flags, message, p_addr_in));
|
||||||
}
|
}
|
||||||
|
|
||||||
Errno BSD_USA::CloseImpl(s32 fd) {
|
Errno BSD::CloseImpl(s32 fd) {
|
||||||
if (!IsFileDescriptorValid(fd)) {
|
if (!IsFileDescriptorValid(fd)) {
|
||||||
return Errno::BADF;
|
return Errno::BADF;
|
||||||
}
|
}
|
||||||
@@ -1011,7 +1011,7 @@ Errno BSD_USA::CloseImpl(s32 fd) {
|
|||||||
return bsd_errno;
|
return bsd_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::variant<s32, Errno> BSD_USA::DuplicateSocketImpl(s32 fd) {
|
std::variant<s32, Errno> BSD::DuplicateSocketImpl(s32 fd) {
|
||||||
if (!IsFileDescriptorValid(fd)) {
|
if (!IsFileDescriptorValid(fd)) {
|
||||||
return Errno::BADF;
|
return Errno::BADF;
|
||||||
}
|
}
|
||||||
@@ -1030,7 +1030,7 @@ std::variant<s32, Errno> BSD_USA::DuplicateSocketImpl(s32 fd) {
|
|||||||
return new_fd;
|
return new_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::shared_ptr<Network::SocketBase>> BSD_USA::GetSocket(s32 fd) {
|
std::optional<std::shared_ptr<Network::SocketBase>> BSD::GetSocket(s32 fd) {
|
||||||
if (!IsFileDescriptorValid(fd)) {
|
if (!IsFileDescriptorValid(fd)) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
@@ -1041,7 +1041,7 @@ std::optional<std::shared_ptr<Network::SocketBase>> BSD_USA::GetSocket(s32 fd) {
|
|||||||
return file_descriptors[fd]->socket;
|
return file_descriptors[fd]->socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 BSD_USA::FindFreeFileDescriptorHandle() noexcept {
|
s32 BSD::FindFreeFileDescriptorHandle() noexcept {
|
||||||
for (s32 fd = 0; fd < static_cast<s32>(file_descriptors.size()); ++fd) {
|
for (s32 fd = 0; fd < static_cast<s32>(file_descriptors.size()); ++fd) {
|
||||||
if (!file_descriptors[fd]) {
|
if (!file_descriptors[fd]) {
|
||||||
return fd;
|
return fd;
|
||||||
@@ -1050,7 +1050,7 @@ s32 BSD_USA::FindFreeFileDescriptorHandle() noexcept {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BSD_USA::IsFileDescriptorValid(s32 fd) const noexcept {
|
bool BSD::IsFileDescriptorValid(s32 fd) const noexcept {
|
||||||
if (fd > static_cast<s32>(MAX_FD) || fd < 0) {
|
if (fd > static_cast<s32>(MAX_FD) || fd < 0) {
|
||||||
LOG_ERROR(Service, "Invalid file descriptor handle={}", fd);
|
LOG_ERROR(Service, "Invalid file descriptor handle={}", fd);
|
||||||
return false;
|
return false;
|
||||||
@@ -1062,7 +1062,7 @@ bool BSD_USA::IsFileDescriptorValid(s32 fd) const noexcept {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::BuildErrnoResponse(HLERequestContext& ctx, Errno bsd_errno) const noexcept {
|
void BSD::BuildErrnoResponse(HLERequestContext& ctx, Errno bsd_errno) const noexcept {
|
||||||
IPC::ResponseBuilder rb{ctx, 4};
|
IPC::ResponseBuilder rb{ctx, 4};
|
||||||
|
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
@@ -1070,7 +1070,7 @@ void BSD_USA::BuildErrnoResponse(HLERequestContext& ctx, Errno bsd_errno) const
|
|||||||
rb.PushEnum(bsd_errno);
|
rb.PushEnum(bsd_errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSD_USA::OnProxyPacketReceived(const Network::ProxyPacket& packet) {
|
void BSD::OnProxyPacketReceived(const Network::ProxyPacket& packet) {
|
||||||
for (auto& optional_descriptor : file_descriptors) {
|
for (auto& optional_descriptor : file_descriptors) {
|
||||||
if (!optional_descriptor.has_value()) {
|
if (!optional_descriptor.has_value()) {
|
||||||
continue;
|
continue;
|
||||||
@@ -1080,43 +1080,43 @@ void BSD_USA::OnProxyPacketReceived(const Network::ProxyPacket& packet) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BSD_USA::BSD_USA(Core::System& system_, const char* name, bool is_user_)
|
BSD::BSD(Core::System& system_, const char* name, bool is_user_)
|
||||||
: ServiceFramework{system_, name}
|
: ServiceFramework{system_, name}
|
||||||
, is_user{is_user_} {
|
, is_user{is_user_} {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, &BSD_USA::RegisterClient, "RegisterClient"},
|
{0, &BSD::RegisterClient, "RegisterClient"},
|
||||||
{1, &BSD_USA::StartMonitoring, "StartMonitoring"},
|
{1, &BSD::StartMonitoring, "StartMonitoring"},
|
||||||
{2, &BSD_USA::Socket, "Socket"},
|
{2, &BSD::Socket, "Socket"},
|
||||||
{3, &BSD_USA::SocketExempt, "SocketExempt"},
|
{3, &BSD::SocketExempt, "SocketExempt"},
|
||||||
{4, nullptr, "Open"},
|
{4, nullptr, "Open"},
|
||||||
{5, &BSD_USA::Select, "Select"},
|
{5, &BSD::Select, "Select"},
|
||||||
{6, &BSD_USA::Poll, "Poll"},
|
{6, &BSD::Poll, "Poll"},
|
||||||
{7, nullptr, "Sysctl"},
|
{7, nullptr, "Sysctl"},
|
||||||
{8, &BSD_USA::Recv, "Recv"},
|
{8, &BSD::Recv, "Recv"},
|
||||||
{9, &BSD_USA::RecvFrom, "RecvFrom"},
|
{9, &BSD::RecvFrom, "RecvFrom"},
|
||||||
{10, &BSD_USA::Send, "Send"},
|
{10, &BSD::Send, "Send"},
|
||||||
{11, &BSD_USA::SendTo, "SendTo"},
|
{11, &BSD::SendTo, "SendTo"},
|
||||||
{12, &BSD_USA::Accept, "Accept"},
|
{12, &BSD::Accept, "Accept"},
|
||||||
{13, &BSD_USA::Bind, "Bind"},
|
{13, &BSD::Bind, "Bind"},
|
||||||
{14, &BSD_USA::Connect, "Connect"},
|
{14, &BSD::Connect, "Connect"},
|
||||||
{15, &BSD_USA::GetPeerName, "GetPeerName"},
|
{15, &BSD::GetPeerName, "GetPeerName"},
|
||||||
{16, &BSD_USA::GetSockName, "GetSockName"},
|
{16, &BSD::GetSockName, "GetSockName"},
|
||||||
{17, &BSD_USA::GetSockOpt, "GetSockOpt"},
|
{17, &BSD::GetSockOpt, "GetSockOpt"},
|
||||||
{18, &BSD_USA::Listen, "Listen"},
|
{18, &BSD::Listen, "Listen"},
|
||||||
{19, nullptr, "Ioctl"},
|
{19, nullptr, "Ioctl"},
|
||||||
{20, &BSD_USA::Fcntl, "Fcntl"},
|
{20, &BSD::Fcntl, "Fcntl"},
|
||||||
{21, &BSD_USA::SetSockOpt, "SetSockOpt"},
|
{21, &BSD::SetSockOpt, "SetSockOpt"},
|
||||||
{22, &BSD_USA::Shutdown, "Shutdown"},
|
{22, &BSD::Shutdown, "Shutdown"},
|
||||||
{23, nullptr, "ShutdownAllSockets"},
|
{23, nullptr, "ShutdownAllSockets"},
|
||||||
{24, &BSD_USA::Write, "Write"},
|
{24, &BSD::Write, "Write"},
|
||||||
{25, &BSD_USA::Read, "Read"},
|
{25, &BSD::Read, "Read"},
|
||||||
{26, &BSD_USA::Close, "Close"},
|
{26, &BSD::Close, "Close"},
|
||||||
{27, &BSD_USA::DuplicateSocket, "DuplicateSocket"},
|
{27, &BSD::DuplicateSocket, "DuplicateSocket"},
|
||||||
{28, nullptr, "GetResourceStatistics"},
|
{28, nullptr, "GetResourceStatistics"},
|
||||||
{29, nullptr, "RecvMMsg"}, //3.0.0+
|
{29, nullptr, "RecvMMsg"}, //3.0.0+
|
||||||
{30, nullptr, "SendMMsg"}, //3.0.0+
|
{30, nullptr, "SendMMsg"}, //3.0.0+
|
||||||
{31, &BSD_USA::EventFd, "EventFd"}, //7.0.0+
|
{31, &BSD::EventFd, "EventFd"}, //7.0.0+
|
||||||
{32, nullptr, "RegisterResourceStatisticsName"}, //7.0.0+
|
{32, nullptr, "RegisterResourceStatisticsName"}, //7.0.0+
|
||||||
{33, nullptr, "RegisterClientShared"}, //10.0.0+
|
{33, nullptr, "RegisterClientShared"}, //10.0.0+
|
||||||
{34, nullptr, "GetSocketStatistics"}, //15.0.0+
|
{34, nullptr, "GetSocketStatistics"}, //15.0.0+
|
||||||
@@ -1144,13 +1144,13 @@ BSD_USA::BSD_USA(Core::System& system_, const char* name, bool is_user_)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BSD_USA::~BSD_USA() {
|
BSD::~BSD() {
|
||||||
if (auto room_member = Network::GetRoomMember().lock()) {
|
if (auto room_member = Network::GetRoomMember().lock()) {
|
||||||
room_member->Unbind(proxy_packet_received);
|
room_member->Unbind(proxy_packet_received);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_lock<std::mutex> BSD_USA::LockService() noexcept {
|
std::unique_lock<std::mutex> BSD::LockService() noexcept {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,10 +27,10 @@ class Socket;
|
|||||||
|
|
||||||
namespace Service::Sockets {
|
namespace Service::Sockets {
|
||||||
|
|
||||||
class BSD_USA final : public ServiceFramework<BSD_USA> {
|
class BSD final : public ServiceFramework<BSD> {
|
||||||
public:
|
public:
|
||||||
explicit BSD_USA(Core::System& system_, const char* name, bool is_user);
|
explicit BSD(Core::System& system_, const char* name, bool is_user);
|
||||||
~BSD_USA() override;
|
~BSD() override;
|
||||||
|
|
||||||
// These methods are called from SSL; the first two are also called from
|
// These methods are called from SSL; the first two are also called from
|
||||||
// this class for the corresponding IPC methods.
|
// this class for the corresponding IPC methods.
|
||||||
@@ -50,7 +50,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct PollWork {
|
struct PollWork {
|
||||||
void Execute(BSD_USA* bsd);
|
void Execute(BSD* bsd);
|
||||||
void Response(HLERequestContext& ctx);
|
void Response(HLERequestContext& ctx);
|
||||||
|
|
||||||
s32 nfds;
|
s32 nfds;
|
||||||
@@ -62,7 +62,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct AcceptWork {
|
struct AcceptWork {
|
||||||
void Execute(BSD_USA* bsd);
|
void Execute(BSD* bsd);
|
||||||
void Response(HLERequestContext& ctx);
|
void Response(HLERequestContext& ctx);
|
||||||
|
|
||||||
s32 fd;
|
s32 fd;
|
||||||
@@ -72,7 +72,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct ConnectWork {
|
struct ConnectWork {
|
||||||
void Execute(BSD_USA* bsd);
|
void Execute(BSD* bsd);
|
||||||
void Response(HLERequestContext& ctx);
|
void Response(HLERequestContext& ctx);
|
||||||
|
|
||||||
s32 fd;
|
s32 fd;
|
||||||
@@ -81,7 +81,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct RecvWork {
|
struct RecvWork {
|
||||||
void Execute(BSD_USA* bsd);
|
void Execute(BSD* bsd);
|
||||||
void Response(HLERequestContext& ctx);
|
void Response(HLERequestContext& ctx);
|
||||||
|
|
||||||
s32 fd;
|
s32 fd;
|
||||||
@@ -92,7 +92,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct RecvFromWork {
|
struct RecvFromWork {
|
||||||
void Execute(BSD_USA* bsd);
|
void Execute(BSD* bsd);
|
||||||
void Response(HLERequestContext& ctx);
|
void Response(HLERequestContext& ctx);
|
||||||
|
|
||||||
s32 fd;
|
s32 fd;
|
||||||
@@ -104,7 +104,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct SendWork {
|
struct SendWork {
|
||||||
void Execute(BSD_USA* bsd);
|
void Execute(BSD* bsd);
|
||||||
void Response(HLERequestContext& ctx);
|
void Response(HLERequestContext& ctx);
|
||||||
|
|
||||||
s32 fd;
|
s32 fd;
|
||||||
@@ -115,7 +115,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct SendToWork {
|
struct SendToWork {
|
||||||
void Execute(BSD_USA* bsd);
|
void Execute(BSD* bsd);
|
||||||
void Response(HLERequestContext& ctx);
|
void Response(HLERequestContext& ctx);
|
||||||
|
|
||||||
s32 fd;
|
s32 fd;
|
||||||
|
|||||||
@@ -66,9 +66,9 @@ void LoopProcess(Core::System& system) {
|
|||||||
|
|
||||||
server_manager->RegisterNamedService("ethc:c", std::make_shared<ETHC_C>(system));
|
server_manager->RegisterNamedService("ethc:c", std::make_shared<ETHC_C>(system));
|
||||||
server_manager->RegisterNamedService("ethc:i", std::make_shared<ETHC_I>(system));
|
server_manager->RegisterNamedService("ethc:i", std::make_shared<ETHC_I>(system));
|
||||||
server_manager->RegisterNamedService("bsd:s", std::make_shared<BSD_USA>(system, "bsd:s", false));
|
server_manager->RegisterNamedService("bsd:s", std::make_shared<BSD>(system, "bsd:s", false));
|
||||||
server_manager->RegisterNamedService("bsd:u", std::make_shared<BSD_USA>(system, "bsd:u", true));
|
server_manager->RegisterNamedService("bsd:u", std::make_shared<BSD>(system, "bsd:u", true));
|
||||||
server_manager->RegisterNamedService("bsd:a", std::make_shared<BSD_USA>(system, "bsd:a", true));
|
server_manager->RegisterNamedService("bsd:a", std::make_shared<BSD>(system, "bsd:a", true));
|
||||||
server_manager->RegisterNamedService("bsd:nu", std::make_shared<BSD_NU>(system));
|
server_manager->RegisterNamedService("bsd:nu", std::make_shared<BSD_NU>(system));
|
||||||
server_manager->RegisterNamedService("bsdcfg", std::make_shared<BSDCFG>(system, "bsdcfg"));
|
server_manager->RegisterNamedService("bsdcfg", std::make_shared<BSDCFG>(system, "bsdcfg"));
|
||||||
server_manager->RegisterNamedService("ifcfg", std::make_shared<BSDCFG>(system, "ifcfg"));
|
server_manager->RegisterNamedService("ifcfg", std::make_shared<BSDCFG>(system, "ifcfg"));
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ public:
|
|||||||
LOG_ERROR(Service_SSL,
|
LOG_ERROR(Service_SSL,
|
||||||
"do_not_close_socket was changed after setting socket; is this right?");
|
"do_not_close_socket was changed after setting socket; is this right?");
|
||||||
} else {
|
} else {
|
||||||
auto bsd = system.ServiceManager().GetService<Service::Sockets::BSD_USA>("bsd:u");
|
auto bsd = system.ServiceManager().GetService<Service::Sockets::BSD>("bsd:u");
|
||||||
if (bsd) {
|
if (bsd) {
|
||||||
auto err = bsd->CloseImpl(fd);
|
auto err = bsd->CloseImpl(fd);
|
||||||
if (err != Service::Sockets::Errno::SUCCESS) {
|
if (err != Service::Sockets::Errno::SUCCESS) {
|
||||||
@@ -157,7 +157,7 @@ private:
|
|||||||
Result SetSocketDescriptorImpl(s32* out_fd, s32 fd) {
|
Result SetSocketDescriptorImpl(s32* out_fd, s32 fd) {
|
||||||
LOG_DEBUG(Service_SSL, "called, fd={}", fd);
|
LOG_DEBUG(Service_SSL, "called, fd={}", fd);
|
||||||
ASSERT(!did_handshake);
|
ASSERT(!did_handshake);
|
||||||
auto bsd = system.ServiceManager().GetService<Service::Sockets::BSD_USA>("bsd:u");
|
auto bsd = system.ServiceManager().GetService<Service::Sockets::BSD>("bsd:u");
|
||||||
ASSERT_OR_EXECUTE(bsd, { return ResultInternalError; });
|
ASSERT_OR_EXECUTE(bsd, { return ResultInternalError; });
|
||||||
|
|
||||||
auto const res_v = bsd->DuplicateSocketImpl(fd);
|
auto const res_v = bsd->DuplicateSocketImpl(fd);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "common/container/unordered_map.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/polyfill_thread.h"
|
#include "common/polyfill_thread.h"
|
||||||
@@ -49,7 +49,7 @@ private:
|
|||||||
private:
|
private:
|
||||||
Core::System& m_system;
|
Core::System& m_system;
|
||||||
Container& m_container;
|
Container& m_container;
|
||||||
::Common::unordered_map<u64, VsyncManager> m_vsync_managers;
|
ankerl::unordered_dense::map<u64, VsyncManager> m_vsync_managers;
|
||||||
std::shared_ptr<Core::Timing::EventType> m_event;
|
std::shared_ptr<Core::Timing::EventType> m_event;
|
||||||
Common::Event m_signal;
|
Common::Event m_signal;
|
||||||
std::jthread m_thread;
|
std::jthread m_thread;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "common/container/unordered_map.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
@@ -21,8 +21,8 @@
|
|||||||
namespace Core::LaunchTimestampCache {
|
namespace Core::LaunchTimestampCache {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using CacheMap = ::Common::unordered_map<u64, s64>;
|
using CacheMap = ankerl::unordered_dense::map<u64, s64>;
|
||||||
using CountMap = ::Common::unordered_map<u64, u64>;
|
using CountMap = ankerl::unordered_dense::map<u64, u64>;
|
||||||
|
|
||||||
std::mutex g_mutex;
|
std::mutex g_mutex;
|
||||||
CacheMap g_cache;
|
CacheMap g_cache;
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ if (NOT Boost_FOUND)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_package(fmt 8 CONFIG)
|
find_package(fmt 8 CONFIG)
|
||||||
|
find_package(unordered_dense REQUIRED)
|
||||||
|
|
||||||
if ("arm64" IN_LIST ARCHITECTURE OR DYNARMIC_TESTS)
|
if ("arm64" IN_LIST ARCHITECTURE OR DYNARMIC_TESTS)
|
||||||
find_package(oaknut 2.0.1 CONFIG)
|
find_package(oaknut 2.0.1 CONFIG)
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ if (NOT @BUILD_SHARED_LIBS@)
|
|||||||
find_dependency(Boost 1.57)
|
find_dependency(Boost 1.57)
|
||||||
find_dependency(fmt 9)
|
find_dependency(fmt 9)
|
||||||
find_dependency(mcl 0.1.12 EXACT)
|
find_dependency(mcl 0.1.12 EXACT)
|
||||||
|
find_dependency(unordered_dense)
|
||||||
|
|
||||||
if ("arm64" IN_LIST ARCHITECTURE)
|
if ("arm64" IN_LIST ARCHITECTURE)
|
||||||
find_dependency(oaknut 2.0.1)
|
find_dependency(oaknut 2.0.1)
|
||||||
|
|||||||
@@ -387,6 +387,7 @@ set_target_properties(dynarmic PROPERTIES
|
|||||||
|
|
||||||
target_compile_options(dynarmic PRIVATE ${DYNARMIC_CXX_FLAGS})
|
target_compile_options(dynarmic PRIVATE ${DYNARMIC_CXX_FLAGS})
|
||||||
|
|
||||||
|
target_link_libraries(dynarmic PRIVATE unordered_dense::unordered_dense)
|
||||||
target_link_libraries(dynarmic PUBLIC fmt::fmt common)
|
target_link_libraries(dynarmic PUBLIC fmt::fmt common)
|
||||||
|
|
||||||
if (BOOST_NO_HEADERS)
|
if (BOOST_NO_HEADERS)
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ CodePtr AddressSpace::GetOrEmit(IR::LocationDescriptor descriptor) {
|
|||||||
return block_info.entry_point;
|
return block_info.entry_point;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddressSpace::InvalidateBasicBlocks(const ::Common::unordered_set<IR::LocationDescriptor>& descriptors) {
|
void AddressSpace::InvalidateBasicBlocks(const ankerl::unordered_dense::set<IR::LocationDescriptor>& descriptors) {
|
||||||
UnprotectCodeMemory();
|
UnprotectCodeMemory();
|
||||||
|
|
||||||
for (const auto& descriptor : descriptors) {
|
for (const auto& descriptor : descriptors) {
|
||||||
|
|||||||
@@ -14,8 +14,7 @@
|
|||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include <oaknut/code_block.hpp>
|
#include <oaknut/code_block.hpp>
|
||||||
#include <oaknut/oaknut.hpp>
|
#include <oaknut/oaknut.hpp>
|
||||||
#include "common/container/unordered_map.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
#include "common/container/unordered_set.h"
|
|
||||||
|
|
||||||
#include "dynarmic/backend/arm64/emit_arm64.h"
|
#include "dynarmic/backend/arm64/emit_arm64.h"
|
||||||
#include "dynarmic/backend/arm64/fastmem.h"
|
#include "dynarmic/backend/arm64/fastmem.h"
|
||||||
@@ -42,7 +41,7 @@ public:
|
|||||||
|
|
||||||
CodePtr GetOrEmit(IR::LocationDescriptor descriptor);
|
CodePtr GetOrEmit(IR::LocationDescriptor descriptor);
|
||||||
|
|
||||||
void InvalidateBasicBlocks(const ::Common::unordered_set<IR::LocationDescriptor>& descriptors);
|
void InvalidateBasicBlocks(const ankerl::unordered_dense::set<IR::LocationDescriptor>& descriptors);
|
||||||
|
|
||||||
void ClearCache();
|
void ClearCache();
|
||||||
protected:
|
protected:
|
||||||
@@ -77,9 +76,9 @@ protected:
|
|||||||
// A IR::LocationDescriptor will have one current CodePtr.
|
// A IR::LocationDescriptor will have one current CodePtr.
|
||||||
// However, there can be multiple other CodePtrs which are older, previously invalidated blocks.
|
// However, there can be multiple other CodePtrs which are older, previously invalidated blocks.
|
||||||
std::map<CodePtr, IR::LocationDescriptor> reverse_block_entries;
|
std::map<CodePtr, IR::LocationDescriptor> reverse_block_entries;
|
||||||
::Common::unordered_map<IR::LocationDescriptor, CodePtr> block_entries;
|
ankerl::unordered_dense::map<IR::LocationDescriptor, CodePtr> block_entries;
|
||||||
::Common::unordered_map<CodePtr, EmittedBlockInfo> block_infos;
|
ankerl::unordered_dense::map<CodePtr, EmittedBlockInfo> block_infos;
|
||||||
::Common::unordered_map<IR::LocationDescriptor, ::Common::unordered_set<CodePtr>> block_references;
|
ankerl::unordered_dense::map<IR::LocationDescriptor, ankerl::unordered_dense::set<CodePtr>> block_references;
|
||||||
|
|
||||||
ExceptionHandler exception_handler;
|
ExceptionHandler exception_handler;
|
||||||
FastmemManager fastmem_manager;
|
FastmemManager fastmem_manager;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/container/unordered_map.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
|
|
||||||
#include "dynarmic/backend/arm64/fastmem.h"
|
#include "dynarmic/backend/arm64/fastmem.h"
|
||||||
#include "dynarmic/interface/A32/coprocessor.h"
|
#include "dynarmic/interface/A32/coprocessor.h"
|
||||||
@@ -105,8 +105,8 @@ struct EmittedBlockInfo {
|
|||||||
CodePtr entry_point;
|
CodePtr entry_point;
|
||||||
std::size_t size;
|
std::size_t size;
|
||||||
std::vector<Relocation> relocations;
|
std::vector<Relocation> relocations;
|
||||||
::Common::unordered_map<IR::LocationDescriptor, std::vector<BlockRelocation>> block_relocations;
|
ankerl::unordered_dense::map<IR::LocationDescriptor, std::vector<BlockRelocation>> block_relocations;
|
||||||
::Common::unordered_map<std::ptrdiff_t, FastmemPatchInfo> fastmem_patch_info;
|
ankerl::unordered_dense::map<std::ptrdiff_t, FastmemPatchInfo> fastmem_patch_info;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct EmitConfig {
|
struct EmitConfig {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include "common/container/unordered_set.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
|
|
||||||
#include "dynarmic/mcl/bit.hpp"
|
#include "dynarmic/mcl/bit.hpp"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
@@ -59,7 +59,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
ExceptionHandler& exception_handler;
|
ExceptionHandler& exception_handler;
|
||||||
::Common::unordered_set<DoNotFastmemMarker, DoNotFastmemMarkerHash> do_not_fastmem;
|
ankerl::unordered_dense::set<DoNotFastmemMarker, DoNotFastmemMarkerHash> do_not_fastmem;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Dynarmic::Backend::Arm64
|
} // namespace Dynarmic::Backend::Arm64
|
||||||
|
|||||||
@@ -18,8 +18,7 @@
|
|||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "dynarmic/mcl/is_instance_of_template.hpp"
|
#include "dynarmic/mcl/is_instance_of_template.hpp"
|
||||||
#include <oaknut/oaknut.hpp>
|
#include <oaknut/oaknut.hpp>
|
||||||
#include "common/container/unordered_map.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
#include "common/container/unordered_set.h"
|
|
||||||
|
|
||||||
#include "dynarmic/backend/arm64/stack_layout.h"
|
#include "dynarmic/backend/arm64/stack_layout.h"
|
||||||
#include "dynarmic/ir/cond.h"
|
#include "dynarmic/ir/cond.h"
|
||||||
@@ -337,7 +336,7 @@ private:
|
|||||||
std::array<HostLocInfo, SpillCount> spills;
|
std::array<HostLocInfo, SpillCount> spills;
|
||||||
|
|
||||||
mutable std::size_t alloc_candidate_index = 0;
|
mutable std::size_t alloc_candidate_index = 0;
|
||||||
::Common::unordered_set<const IR::Inst*> defined_insts;
|
ankerl::unordered_dense::set<const IR::Inst*> defined_insts;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|||||||
@@ -11,13 +11,13 @@
|
|||||||
#include <boost/icl/interval_map.hpp>
|
#include <boost/icl/interval_map.hpp>
|
||||||
#include <boost/icl/interval_set.hpp>
|
#include <boost/icl/interval_set.hpp>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/container/unordered_set.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
|
|
||||||
namespace Dynarmic::Backend {
|
namespace Dynarmic::Backend {
|
||||||
|
|
||||||
template<typename P>
|
template<typename P>
|
||||||
void BlockRangeInformation<P>::AddRange(boost::icl::discrete_interval<P> range, IR::LocationDescriptor location) {
|
void BlockRangeInformation<P>::AddRange(boost::icl::discrete_interval<P> range, IR::LocationDescriptor location) {
|
||||||
block_ranges.add(std::make_pair(range, ::Common::unordered_set<IR::LocationDescriptor>{location}));
|
block_ranges.add(std::make_pair(range, ankerl::unordered_dense::set<IR::LocationDescriptor>{location}));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename P>
|
template<typename P>
|
||||||
@@ -26,8 +26,8 @@ void BlockRangeInformation<P>::ClearCache() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename P>
|
template<typename P>
|
||||||
::Common::unordered_set<IR::LocationDescriptor> BlockRangeInformation<P>::InvalidateRanges(const boost::icl::interval_set<P>& ranges) {
|
ankerl::unordered_dense::set<IR::LocationDescriptor> BlockRangeInformation<P>::InvalidateRanges(const boost::icl::interval_set<P>& ranges) {
|
||||||
::Common::unordered_set<IR::LocationDescriptor> erase_locations;
|
ankerl::unordered_dense::set<IR::LocationDescriptor> erase_locations;
|
||||||
for (auto invalidate_interval : ranges) {
|
for (auto invalidate_interval : ranges) {
|
||||||
auto pair = block_ranges.equal_range(invalidate_interval);
|
auto pair = block_ranges.equal_range(invalidate_interval);
|
||||||
for (auto it = pair.first; it != pair.second; ++it)
|
for (auto it = pair.first; it != pair.second; ++it)
|
||||||
|
|||||||
@@ -12,8 +12,7 @@
|
|||||||
|
|
||||||
#include <boost/icl/interval_map.hpp>
|
#include <boost/icl/interval_map.hpp>
|
||||||
#include <boost/icl/interval_set.hpp>
|
#include <boost/icl/interval_set.hpp>
|
||||||
#include "common/container/unordered_map.h"
|
#include <ankerl/unordered_dense.h>
|
||||||
#include "common/container/unordered_set.h"
|
|
||||||
|
|
||||||
#include "dynarmic/ir/location_descriptor.h"
|
#include "dynarmic/ir/location_descriptor.h"
|
||||||
|
|
||||||
@@ -24,8 +23,8 @@ class BlockRangeInformation {
|
|||||||
public:
|
public:
|
||||||
void AddRange(boost::icl::discrete_interval<P> range, IR::LocationDescriptor location);
|
void AddRange(boost::icl::discrete_interval<P> range, IR::LocationDescriptor location);
|
||||||
void ClearCache();
|
void ClearCache();
|
||||||
::Common::unordered_set<IR::LocationDescriptor> InvalidateRanges(const boost::icl::interval_set<P>& ranges);
|
ankerl::unordered_dense::set<IR::LocationDescriptor> InvalidateRanges(const boost::icl::interval_set<P>& ranges);
|
||||||
boost::icl::interval_map<P, ::Common::unordered_set<IR::LocationDescriptor>> block_ranges;
|
boost::icl::interval_map<P, ankerl::unordered_dense::set<IR::LocationDescriptor>> block_ranges;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Dynarmic::Backend
|
} // namespace Dynarmic::Backend
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user