Compare commits

..

2 Commits

Author SHA1 Message Date
lizzie 15e3acac93 fix span shit 2026-08-30 08:02:39 +02:00
lizzie 71d8796040 [audio_core] remove dangling Core::System& references
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2026-08-30 08:02:39 +02:00
171 changed files with 1047 additions and 1185 deletions
@@ -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> {
+1
View File
@@ -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)
+11
View File
@@ -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",
-2
View File
@@ -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
View File
@@ -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
+11 -27
View File
@@ -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);
} }
``` ```
@@ -324,13 +308,13 @@ bool UseOptimizedPath() {
```cpp ```cpp
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;
} }
// Experimental implementation // Experimental implementation
ExperimentalImplementation(); ExperimentalImplementation();
} }
+26
View File
@@ -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
``` ```
+3
View File
@@ -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"
@@ -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)
@@ -28,4 +29,4 @@ enum class ShortSetting(override val key: String) : AbstractShortSetting {
override fun getValueAsString(needsGlobal: Boolean): String = getShort(needsGlobal).toString() override fun getValueAsString(needsGlobal: Boolean): String = getShort(needsGlobal).toString()
override fun reset() = NativeConfig.setShort(key, defaultValue) override fun reset() = NativeConfig.setShort(key, defaultValue)
} }
@@ -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"),
@@ -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)
}
@@ -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,
@@ -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();
+2 -2
View File
@@ -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>
+1 -1
View File
@@ -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);
+12 -15
View File
@@ -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");
+10 -11
View File
@@ -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
+3 -3
View File
@@ -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);
+6 -3
View File
@@ -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.
+10 -15
View File
@@ -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
+8 -15
View File
@@ -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
+8 -3
View File
@@ -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_);
} }
+5 -4
View File
@@ -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
+18 -22
View File
@@ -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{};
}; };
+24 -20
View File
@@ -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
+5 -2
View File
@@ -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
+24 -20
View File
@@ -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
+5 -2
View File
@@ -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
+18 -23
View File
@@ -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
+5 -2
View File
@@ -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
+1 -1
View File
@@ -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);
+2 -3
View File
@@ -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
-16
View File
@@ -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>;
}
-16
View File
@@ -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>;
}
-33
View File
@@ -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
+3 -3
View File
@@ -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) {
+2 -2
View File
@@ -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
View File
@@ -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 {
+15 -27
View File
@@ -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{
.timestamp = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - logging_instance->time_origin), .message = buffer,
.log_class = log_class, .message_len = (std::min)(result.size, sizeof(buffer) - 1),
.log_level = log_level, .timestamp = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - logging_instance->time_origin),
.filename = TrimSourcePath(filename), .log_class = log_class,
.function = function, .log_level = log_level,
.line_num = line_num, .filename = TrimSourcePath(filename),
}; .function = function,
if (result.size <= sizeof(buffer) - 1) { .line_num = line_num,
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
+2 -2
View File
@@ -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);
+3 -3
View File
@@ -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;
} }
+2 -2
View File
@@ -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();
+3 -4
View File
@@ -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>
+1 -1
View File
@@ -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>
+2 -2
View File
@@ -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:
+240 -193
View File
@@ -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"},
return IPSFileType::IPS; {"\\f", "\f"},
if (std::memcmp(magic.data(), "IPS32", 5) == 0) {"\\n", "\n"},
return IPSFileType::IPS32; {"\\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;
}
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::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))
};
if (sline.size() > 0) {
auto p = sline.cbegin();
// skip space off line
for (; p < sline.cend() && std::isspace(*p); ++p)
;
// now make a nominal preprocessed line: remove comments
char quote = '\0';
auto const sline_start = p;
for (; p < sline.cend(); ) {
// we dont check for "//", IPS checks for '/' only...
if ((!quote && p[0] == '/')
|| (!quote && p[0] == '#')) {
break;
} else if (p[0] == '\"' || p[0] == '\'') {
quote = (p[0] == quote) ? '\0' : p[0];
++p;
} else if (p + 1 < sline.cend() && p[0] == '\\') {
p += 2;
} else {
++p;
}
}
// now we have the preprocessed string ;)
std::string_view pp_str(sline_start, p);
if (pp_str.size() > 0 && !parse_line(pp_str)) {
break;
}
} }
} }
return in;
}
void IPSwitchCompiler::ParseFlag(const std::string& line) {
if (StartsWith(line, "@flag offset_shift ")) {
// Offset Shift Flag
offset_shift = std::strtoll(line.substr(19).c_str(), nullptr, 0);
} else if (StartsWith(line, "@little-endian")) {
// Set values to read as little endian
is_little_endian = true;
} else if (StartsWith(line, "@big-endian")) {
// Set values to read as big endian
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;
}
}
if (!StartsWith(line, "//") && comment_index != std::string::npos) {
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 {
// hex replacement
const auto value =
patch_line.substr(9, patch_line.find_first_of(" /\r\n", 9) - 9);
replace = Common::HexStringToVector(value, is_little_endian);
}
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)
for (const auto& record : patch.records) { continue;
if (record.first < in_data.size()) {
auto replace_size = record.second.count; for (const auto& record : patch.records) {
if (record.first + replace_size > in_data.size()) if (record.first >= in_data.size())
replace_size = in_data.size() - record.first; continue;
std::memcpy(in_data.data() + record.first, record.second.data.data(), replace_size); auto replace_size = record.second.size();
} else { if (record.first + replace_size > in_data.size())
LOG_WARNING(Loader, "record offs={:x},size={:x}", record.first, record.second.data.size()); replace_size = in_data.size() - record.first;
} for (std::size_t i = 0; i < replace_size; ++i)
} in_data[i + record.first] = record.second[i];
} }
} }
return std::make_shared<VectorVfsFile>(std::move(in_data), in->GetName(), in->GetContainingDirectory());
return std::make_shared<VectorVfsFile>(std::move(in_data), in->GetName(),
in->GetContainingDirectory());
} }
} // namespace FileSys } // namespace FileSys
+9 -5
View File
@@ -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
+9 -2
View File
@@ -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;
} }
+1 -1
View File
@@ -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;
+6 -6
View File
@@ -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;
}; };
+3 -3
View File
@@ -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()) {
+2 -2
View File
@@ -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
+3 -4
View File
@@ -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;
+1 -1
View File
@@ -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"
+47 -3
View File
@@ -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();
} }
@@ -129,9 +129,9 @@ Result DisplayLayerManager::IsSystemBufferSharingEnabled() {
(void)m_display_service->GetContainer()->SetLayerStackMask(m_system_shared_layer_id, (void)m_display_service->GetContainer()->SetLayerStackMask(m_system_shared_layer_id,
this->GetLayerStackMask()); this->GetLayerStackMask());
m_manager_display_service->SetLayerBlending(m_blending_enabled, m_system_shared_layer_id); m_manager_display_service->SetLayerBlending(m_blending_enabled, m_system_shared_layer_id);
s32 initial_z = 1; s32 initial_z = Foreground;
if (m_applet_id == AppletId::OverlayDisplay) { if (m_applet_id == AppletId::OverlayDisplay) {
initial_z = -1; initial_z = Overlay;
(void)m_display_service->GetContainer()->SetLayerIsOverlay(m_system_shared_layer_id, true); (void)m_display_service->GetContainer()->SetLayerIsOverlay(m_system_shared_layer_id, true);
} }
m_manager_display_service->SetLayerZIndex(initial_z, m_system_shared_layer_id); m_manager_display_service->SetLayerZIndex(initial_z, m_system_shared_layer_id);
@@ -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
+1 -1
View File
@@ -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);
+1 -1
View File
@@ -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{};
}; };
+2 -2
View File
@@ -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;
}; };
+2 -2
View File
@@ -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};
+2 -2
View File
@@ -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};
}; };
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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"
+2 -2
View File
@@ -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
+2 -2
View File
@@ -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
+3 -3
View File
@@ -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
+3 -3
View File
@@ -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.
+3 -3
View File
@@ -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;
+91 -91
View File
@@ -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 {};
} }
+10 -10
View File
@@ -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;
+3 -3
View File
@@ -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"));
+2 -2
View File
@@ -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);
+2 -2
View File
@@ -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;
+3 -3
View File
@@ -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;
+1
View File
@@ -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)
+1
View File
@@ -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)

Some files were not shown because too many files have changed in this diff Show More