Compare commits

..

10 commits

Author SHA1 Message Date
245906e147 fix license
All checks were successful
eden-license / license-header (pull_request) Successful in 21s
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2025-09-29 19:08:44 +02:00
20663c774d [dynarmic] get rid of mcl intrusive list
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2025-09-29 19:08:44 +02:00
324ace3cd6
[macos] associate .XCI/NSP file extensions (#2617)
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: #2617
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-09-29 18:43:13 +02:00
33f93ad003
[macos, qt] workaround upstream rendering bug (#2616)
See https://bugreports.qt.io/browse/QTBUG-138942

Signed-off-by: lizzie <lizzie@eden-emu.dev>

Reviewed-on: #2616
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-09-29 18:42:51 +02:00
9f423a24b8
[linux] fix aarch64 builds (again) + fix with slightly outdated qt (#2612)
Fixes issues building on aarch64 linux with a slightly outdated system qt; also fixes linker selection process

Signed-off-by: lizzie <lizzie@eden-emu.dev>

Reviewed-on: #2612
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-09-29 18:42:28 +02:00
50ceb9a43a
[.ci] install-msvc: fix installation on MSVC (#2611)
* changed from Build Tools to Community (congrats Microsoft very cool)
* add spining to show it didnt stopped installing

Signed-off-by: Caio Oliveira <caiooliveirafarias0@gmail.com>

Reviewed-on: #2611
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Co-committed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
2025-09-29 18:42:04 +02:00
ecb811ad04
[qt] move addons row to rightmost side (#2610)
This is because the rightmost row is "extended" to the rest of the table, and add-ons have long names, play time doesn't need that much space.

Signed-off-by: lizzie <lizzie@eden-emu.dev>

Reviewed-on: #2610
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-09-29 18:41:28 +02:00
bf302d7917
[common] No need to specify min/max for settings; fix crash when OOB value is given for some settings (#2609)
This fixes issues when migrating settings that refer to invalid filters/scales. For example if we had 5 filters, but we set filter=6, the program would crash.
This also makes so specifying min/max manually isn't needed (but can still be set for cases like NCE).

Signed-off-by: lizzie <lizzie@eden-emu.dev>

Reviewed-on: #2609
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-09-29 18:40:29 +02:00
d19a7c3782
[service] unstub process winding (#2590)
It's used on FW19+ and FW20+ but since all 20+ applets stuck on HID, you still can't boot into applets.
Should fix: Bioshock Infinite on FW19

Reviewed-on: #2590
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: unknown <sahyno1996@gmail.com>
Co-committed-by: unknown <sahyno1996@gmail.com>
2025-09-28 18:43:01 +02:00
c725641f13
[video_core] Fix fast buffers without performance loss (#2605)
Fixes games that have some elements flickering on the screen, such as Kirby Star Allies and others, without impacting performance.

Reviewed-on: #2605
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-09-28 07:29:19 +02:00
18 changed files with 243 additions and 208 deletions

View file

@ -10,7 +10,7 @@ if (-not ([bool](net session 2>$null))) {
} }
$VSVer = "17" $VSVer = "17"
$ExeFile = "vs_BuildTools.exe" $ExeFile = "vs_community.exe"
$Uri = "https://aka.ms/vs/$VSVer/release/$ExeFile" $Uri = "https://aka.ms/vs/$VSVer/release/$ExeFile"
$Destination = "./$ExeFile" $Destination = "./$ExeFile"
@ -19,21 +19,39 @@ $WebClient = New-Object System.Net.WebClient
$WebClient.DownloadFile($Uri, $Destination) $WebClient.DownloadFile($Uri, $Destination)
Write-Host "Finished downloading $ExeFile" Write-Host "Finished downloading $ExeFile"
$VSROOT = "C:/VSBuildTools/$VSVer"
$Arguments = @( $Arguments = @(
"--installPath `"$VSROOT`"", # set custom installation path "--quiet", # Suppress installer UI
"--quiet", # suppress UI "--wait", # Wait for installation to complete
"--wait", # wait for installation to complete "--norestart", # Prevent automatic restart
"--norestart", # prevent automatic restart "--force", # Force installation even if components are already installed
"--add Microsoft.VisualStudio.Workload.VCTools", # add C++ build tools workload "--add Microsoft.VisualStudio.Workload.NativeDesktop", # Desktop development with C++
"--add Microsoft.VisualStudio.Component.VC.Tools.x86.x64", # add core x86/x64 C++ tools "--add Microsoft.VisualStudio.Component.VC.Tools.x86.x64", # Core C++ compiler/tools for x86/x64
"--add Microsoft.VisualStudio.Component.Windows10SDK.19041" # add specific Windows SDK "--add Microsoft.VisualStudio.Component.Windows11SDK.26100",# Windows 11 SDK (26100)
"--add Microsoft.VisualStudio.Component.Windows10SDK.19041",# Windows 10 SDK (19041)
"--add Microsoft.VisualStudio.Component.VC.Llvm.Clang", # LLVM Clang compiler
"--add Microsoft.VisualStudio.Component.VC.Llvm.ClangToolset", # LLVM Clang integration toolset
"--add Microsoft.VisualStudio.Component.Windows11SDK.22621",# Windows 11 SDK (22621)
"--add Microsoft.VisualStudio.Component.VC.CMake.Project", # CMake project support
"--add Microsoft.VisualStudio.ComponentGroup.VC.Tools.142.x86.x64", # VC++ 14.2 toolset
"--add Microsoft.VisualStudio.ComponentGroup.NativeDesktop.Llvm.Clang" # LLVM Clang for native desktop
) )
Write-Host "Installing Visual Studio Build Tools" Write-Host "Installing Visual Studio Build Tools"
$InstallProcess = Start-Process -FilePath $Destination -NoNewWindow -PassThru -Wait -ArgumentList $Arguments $InstallProcess = Start-Process -FilePath $Destination -NoNewWindow -PassThru -ArgumentList $Arguments
$ExitCode = $InstallProcess.ExitCode
# Spinner while installing
$Spinner = "|/-\"
$i = 0
while (-not $InstallProcess.HasExited) {
Write-Host -NoNewline ("`rInstalling... " + $Spinner[$i % $Spinner.Length])
Start-Sleep -Milliseconds 250
$i++
}
# Clear spinner line
Write-Host "`rSetup completed! "
$ExitCode = $InstallProcess.ExitCode
if ($ExitCode -ne 0) { if ($ExitCode -ne 0) {
Write-Host "Error installing Visual Studio Build Tools (Error: $ExitCode)" Write-Host "Error installing Visual Studio Build Tools (Error: $ExitCode)"
Exit $ExitCode Exit $ExitCode

View file

@ -895,13 +895,13 @@ if (MSVC AND CXX_CLANG)
endif() endif()
if (YUZU_USE_FASTER_LD) if (YUZU_USE_FASTER_LD)
# fallback if everything fails (bfd)
set(LINKER bfd)
# clang should always use lld # clang should always use lld
find_program(LLD lld) find_program(LLD lld)
if (LLD) if (LLD)
set(LINKER lld) set(LINKER lld)
endif() endif()
# GNU appears to work better with mold # GNU appears to work better with mold
# TODO: mold has been slow lately, see if better options exist (search for gold?) # TODO: mold has been slow lately, see if better options exist (search for gold?)
if (CXX_GCC) if (CXX_GCC)
@ -910,7 +910,6 @@ if (YUZU_USE_FASTER_LD)
set(LINKER mold) set(LINKER mold)
endif() endif()
endif() endif()
message(NOTICE "Selecting ${LINKER} as linker") message(NOTICE "Selecting ${LINKER} as linker")
add_link_options("-fuse-ld=${LINKER}") add_link_options("-fuse-ld=${LINKER}")
endif() endif()

View file

@ -4,8 +4,8 @@ To build Eden, you MUST have a C++ compiler.
* On Linux, this is usually [GCC](https://gcc.gnu.org/) 11+ or [Clang](https://clang.llvm.org/) v14+ * On Linux, this is usually [GCC](https://gcc.gnu.org/) 11+ or [Clang](https://clang.llvm.org/) v14+
- GCC 12 also requires Clang 14+ - GCC 12 also requires Clang 14+
* On Windows, this is either: * On Windows, this is either:
- **[MSVC](https://visualstudio.microsoft.com/downloads/)**, - **[MSVC](https://visualstudio.microsoft.com/downloads/)** (you should select *Community* option),
* *A convenience script to install the **minimal** version (Visual Build Tools) is provided in `.ci/windows/install-msvc.ps1`* * *A convenience script to install the Visual Community Studio 2022 with necessary tools is provided in `.ci/windows/install-msvc.ps1`*
- clang-cl - can be downloaded from the MSVC installer, - clang-cl - can be downloaded from the MSVC installer,
- or **[MSYS2](https://www.msys2.org)** - or **[MSYS2](https://www.msys2.org)**
* On macOS, this is Apple Clang * On macOS, this is Apple Clang
@ -211,4 +211,4 @@ Then install the libraries: `sudo pkg install qt6 boost glslang libzip library/l
## All Done ## All Done
You may now return to the **[root build guide](Build.md)**. You may now return to the **[root build guide](Build.md)**.

View file

@ -178,7 +178,7 @@ struct Values {
SwitchableSetting<std::string> audio_input_device_id{ SwitchableSetting<std::string> audio_input_device_id{
linkage, "auto", "input_device", Category::Audio, Specialization::RuntimeList}; linkage, "auto", "input_device", Category::Audio, Specialization::RuntimeList};
SwitchableSetting<AudioMode, true> sound_index{ SwitchableSetting<AudioMode, true> sound_index{
linkage, AudioMode::Stereo, AudioMode::Mono, AudioMode::Surround, linkage, AudioMode::Stereo,
"sound_index", Category::SystemAudio, Specialization::Default, true, "sound_index", Category::SystemAudio, Specialization::Default, true,
true}; true};
SwitchableSetting<u8, true> volume{linkage, SwitchableSetting<u8, true> volume{linkage,
@ -199,8 +199,6 @@ struct Values {
SwitchableSetting<bool> use_multi_core{linkage, true, "use_multi_core", Category::Core}; SwitchableSetting<bool> use_multi_core{linkage, true, "use_multi_core", Category::Core};
SwitchableSetting<MemoryLayout, true> memory_layout_mode{linkage, SwitchableSetting<MemoryLayout, true> memory_layout_mode{linkage,
MemoryLayout::Memory_4Gb, MemoryLayout::Memory_4Gb,
MemoryLayout::Memory_4Gb,
MemoryLayout::Memory_12Gb,
"memory_layout_mode", "memory_layout_mode",
Category::Core, Category::Core,
Specialization::Default, Specialization::Default,
@ -240,9 +238,8 @@ struct Values {
#endif #endif
"cpu_backend", "cpu_backend",
Category::Cpu}; Category::Cpu};
SwitchableSetting<CpuAccuracy, true> cpu_accuracy{linkage, CpuAccuracy::Auto, SwitchableSetting<CpuAccuracy, true> cpu_accuracy{linkage, CpuAccuracy::Auto,
CpuAccuracy::Auto, CpuAccuracy::Paranoid, "cpu_accuracy", Category::Cpu};
"cpu_accuracy", Category::Cpu};
SwitchableSetting<bool> use_fast_cpu_time{linkage, SwitchableSetting<bool> use_fast_cpu_time{linkage,
false, false,
@ -324,10 +321,10 @@ struct Values {
// Renderer // Renderer
SwitchableSetting<RendererBackend, true> renderer_backend{ SwitchableSetting<RendererBackend, true> renderer_backend{
linkage, RendererBackend::Vulkan, RendererBackend::OpenGL, RendererBackend::Null, linkage, RendererBackend::Vulkan,
"backend", Category::Renderer}; "backend", Category::Renderer};
SwitchableSetting<ShaderBackend, true> shader_backend{ SwitchableSetting<ShaderBackend, true> shader_backend{
linkage, ShaderBackend::SpirV, ShaderBackend::Glsl, ShaderBackend::SpirV, linkage, ShaderBackend::SpirV,
"shader_backend", Category::Renderer, Specialization::RuntimeList}; "shader_backend", Category::Renderer, Specialization::RuntimeList};
SwitchableSetting<int> vulkan_device{linkage, 0, "vulkan_device", Category::Renderer, SwitchableSetting<int> vulkan_device{linkage, 0, "vulkan_device", Category::Renderer,
Specialization::RuntimeList}; Specialization::RuntimeList};
@ -342,8 +339,6 @@ struct Values {
Category::Renderer}; Category::Renderer};
SwitchableSetting<SpirvOptimizeMode, true> optimize_spirv_output{linkage, SwitchableSetting<SpirvOptimizeMode, true> optimize_spirv_output{linkage,
SpirvOptimizeMode::Never, SpirvOptimizeMode::Never,
SpirvOptimizeMode::Never,
SpirvOptimizeMode::Always,
"optimize_spirv_output", "optimize_spirv_output",
Category::Renderer}; Category::Renderer};
SwitchableSetting<bool> use_asynchronous_gpu_emulation{ SwitchableSetting<bool> use_asynchronous_gpu_emulation{
@ -354,12 +349,10 @@ struct Values {
#else #else
AstcDecodeMode::Gpu, AstcDecodeMode::Gpu,
#endif #endif
AstcDecodeMode::Cpu,
AstcDecodeMode::CpuAsynchronous,
"accelerate_astc", "accelerate_astc",
Category::Renderer}; Category::Renderer};
SwitchableSetting<VSyncMode, true> vsync_mode{ SwitchableSetting<VSyncMode, true> vsync_mode{
linkage, VSyncMode::Fifo, VSyncMode::Immediate, VSyncMode::FifoRelaxed, linkage, VSyncMode::Fifo,
"use_vsync", Category::Renderer, Specialization::RuntimeList, true, "use_vsync", Category::Renderer, Specialization::RuntimeList, true,
true}; true};
SwitchableSetting<NvdecEmulation> nvdec_emulation{linkage, NvdecEmulation::Gpu, SwitchableSetting<NvdecEmulation> nvdec_emulation{linkage, NvdecEmulation::Gpu,
@ -372,8 +365,6 @@ struct Values {
#else #else
FullscreenMode::Exclusive, FullscreenMode::Exclusive,
#endif #endif
FullscreenMode::Borderless,
FullscreenMode::Exclusive,
"fullscreen_mode", "fullscreen_mode",
Category::Renderer, Category::Renderer,
Specialization::Default, Specialization::Default,
@ -381,8 +372,6 @@ struct Values {
true}; true};
SwitchableSetting<AspectRatio, true> aspect_ratio{linkage, SwitchableSetting<AspectRatio, true> aspect_ratio{linkage,
AspectRatio::R16_9, AspectRatio::R16_9,
AspectRatio::R16_9,
AspectRatio::Stretch,
"aspect_ratio", "aspect_ratio",
Category::Renderer, Category::Renderer,
Specialization::Default, Specialization::Default,
@ -430,8 +419,6 @@ struct Values {
#else #else
GpuAccuracy::High, GpuAccuracy::High,
#endif #endif
GpuAccuracy::Normal,
GpuAccuracy::Extreme,
"gpu_accuracy", "gpu_accuracy",
Category::RendererAdvanced, Category::RendererAdvanced,
Specialization::Default, Specialization::Default,
@ -442,8 +429,6 @@ struct Values {
SwitchableSetting<DmaAccuracy, true> dma_accuracy{linkage, SwitchableSetting<DmaAccuracy, true> dma_accuracy{linkage,
DmaAccuracy::Default, DmaAccuracy::Default,
DmaAccuracy::Default,
DmaAccuracy::Safe,
"dma_accuracy", "dma_accuracy",
Category::RendererAdvanced, Category::RendererAdvanced,
Specialization::Default, Specialization::Default,
@ -456,20 +441,14 @@ struct Values {
#else #else
AnisotropyMode::Automatic, AnisotropyMode::Automatic,
#endif #endif
AnisotropyMode::Automatic,
AnisotropyMode::X16,
"max_anisotropy", "max_anisotropy",
Category::RendererAdvanced}; Category::RendererAdvanced};
SwitchableSetting<AstcRecompression, true> astc_recompression{linkage, SwitchableSetting<AstcRecompression, true> astc_recompression{linkage,
AstcRecompression::Uncompressed, AstcRecompression::Uncompressed,
AstcRecompression::Uncompressed,
AstcRecompression::Bc3,
"astc_recompression", "astc_recompression",
Category::RendererAdvanced}; Category::RendererAdvanced};
SwitchableSetting<VramUsageMode, true> vram_usage_mode{linkage, SwitchableSetting<VramUsageMode, true> vram_usage_mode{linkage,
VramUsageMode::Conservative, VramUsageMode::Conservative,
VramUsageMode::Conservative,
VramUsageMode::Aggressive,
"vram_usage_mode", "vram_usage_mode",
Category::RendererAdvanced}; Category::RendererAdvanced};
SwitchableSetting<bool> skip_cpu_inner_invalidation{linkage, SwitchableSetting<bool> skip_cpu_inner_invalidation{linkage,
@ -595,14 +574,10 @@ struct Values {
// System // System
SwitchableSetting<Language, true> language_index{linkage, SwitchableSetting<Language, true> language_index{linkage,
Language::EnglishAmerican, Language::EnglishAmerican,
Language::Japanese,
Language::Serbian,
"language_index", "language_index",
Category::System}; Category::System};
SwitchableSetting<Region, true> region_index{linkage, Region::Usa, Region::Japan, SwitchableSetting<Region, true> region_index{linkage, Region::Usa, "region_index", Category::System};
Region::Taiwan, "region_index", Category::System}; SwitchableSetting<TimeZone, true> time_zone_index{linkage, TimeZone::Auto,
SwitchableSetting<TimeZone, true> time_zone_index{linkage, TimeZone::Auto,
TimeZone::Auto, TimeZone::Zulu,
"time_zone_index", Category::System}; "time_zone_index", Category::System};
// Measured in seconds since epoch // Measured in seconds since epoch
SwitchableSetting<bool> custom_rtc_enabled{ SwitchableSetting<bool> custom_rtc_enabled{

View file

@ -10,6 +10,7 @@
#pragma once #pragma once
#include <string> #include <string>
#include <string_view>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "common/common_types.h" #include "common/common_types.h"
@ -18,8 +19,10 @@ namespace Settings {
template <typename T> template <typename T>
struct EnumMetadata { struct EnumMetadata {
static std::vector<std::pair<std::string, T>> Canonicalizations(); static std::vector<std::pair<std::string_view, T>> Canonicalizations();
static u32 Index(); static u32 Index();
static constexpr T GetFirst();
static constexpr T GetLast();
}; };
#define PAIR_45(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_46(N, __VA_ARGS__)) #define PAIR_45(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_46(N, __VA_ARGS__))
@ -69,138 +72,101 @@ struct EnumMetadata {
#define PAIR_1(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_2(N, __VA_ARGS__)) #define PAIR_1(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_2(N, __VA_ARGS__))
#define PAIR(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_1(N, __VA_ARGS__)) #define PAIR(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_1(N, __VA_ARGS__))
#define ENUM(NAME, ...) \ #define PP_HEAD(A, ...) A
enum class NAME : u32 { __VA_ARGS__ }; \
template <> \ #define ENUM(NAME, ...) \
inline std::vector<std::pair<std::string, NAME>> EnumMetadata<NAME>::Canonicalizations() { \ enum class NAME : u32 { __VA_ARGS__ }; \
return {PAIR(NAME, __VA_ARGS__)}; \ template<> inline std::vector<std::pair<std::string_view, NAME>> EnumMetadata<NAME>::Canonicalizations() { \
} \ return {PAIR(NAME, __VA_ARGS__)}; \
template <> \ } \
inline u32 EnumMetadata<NAME>::Index() { \ template<> inline u32 EnumMetadata<NAME>::Index() { \
return __COUNTER__; \ return __COUNTER__; \
} \
template<> inline constexpr NAME EnumMetadata<NAME>::GetFirst() { \
return NAME::PP_HEAD(__VA_ARGS__); \
} \
template<> inline constexpr NAME EnumMetadata<NAME>::GetLast() { \
return (std::vector<std::pair<std::string_view, NAME>>{PAIR(NAME, __VA_ARGS__)}).back().second; \
} }
// AudioEngine must be specified discretely due to having existing but slightly different // AudioEngine must be specified discretely due to having existing but slightly different
// canonicalizations // canonicalizations
// TODO (lat9nq): Remove explicit definition of AudioEngine/sink_id // TODO (lat9nq): Remove explicit definition of AudioEngine/sink_id
enum class AudioEngine : u32 { enum class AudioEngine : u32 { Auto, Cubeb, Sdl2, Null, Oboe, };
Auto, template<>
Cubeb, inline std::vector<std::pair<std::string_view, AudioEngine>> EnumMetadata<AudioEngine>::Canonicalizations() {
Sdl2,
Null,
Oboe,
};
template <>
inline std::vector<std::pair<std::string, AudioEngine>>
EnumMetadata<AudioEngine>::Canonicalizations() {
return { return {
{"auto", AudioEngine::Auto}, {"cubeb", AudioEngine::Cubeb}, {"sdl2", AudioEngine::Sdl2}, {"auto", AudioEngine::Auto}, {"cubeb", AudioEngine::Cubeb}, {"sdl2", AudioEngine::Sdl2},
{"null", AudioEngine::Null}, {"oboe", AudioEngine::Oboe}, {"null", AudioEngine::Null}, {"oboe", AudioEngine::Oboe},
}; };
} }
/// @brief This is just a sufficiently large number that is more than the number of other enums declared here
template <> template<>
inline u32 EnumMetadata<AudioEngine>::Index() { inline u32 EnumMetadata<AudioEngine>::Index() {
// This is just a sufficiently large number that is more than the number of other enums declared
// here
return 100; return 100;
} }
template<>
inline constexpr AudioEngine EnumMetadata<AudioEngine>::GetFirst() {
return AudioEngine::Auto;
}
template<>
inline constexpr AudioEngine EnumMetadata<AudioEngine>::GetLast() {
return AudioEngine::Oboe;
}
ENUM(AudioMode, Mono, Stereo, Surround); ENUM(AudioMode, Mono, Stereo, Surround);
static_assert(EnumMetadata<AudioMode>::GetFirst() == AudioMode::Mono);
static_assert(EnumMetadata<AudioMode>::GetLast() == AudioMode::Surround);
ENUM(Language, Japanese, EnglishAmerican, French, German, Italian, Spanish, Chinese, Korean, Dutch, ENUM(Language, Japanese, EnglishAmerican, French, German, Italian, Spanish, Chinese, Korean, Dutch,
Portuguese, Russian, Taiwanese, EnglishBritish, FrenchCanadian, SpanishLatin, Portuguese, Russian, Taiwanese, EnglishBritish, FrenchCanadian, SpanishLatin,
ChineseSimplified, ChineseTraditional, PortugueseBrazilian, Serbian); ChineseSimplified, ChineseTraditional, PortugueseBrazilian, Serbian);
ENUM(Region, Japan, Usa, Europe, Australia, China, Korea, Taiwan); ENUM(Region, Japan, Usa, Europe, Australia, China, Korea, Taiwan);
ENUM(TimeZone, Auto, Default, Cet, Cst6Cdt, Cuba, Eet, Egypt, Eire, Est, Est5Edt, Gb, GbEire, Gmt, ENUM(TimeZone, Auto, Default, Cet, Cst6Cdt, Cuba, Eet, Egypt, Eire, Est, Est5Edt, Gb, GbEire, Gmt,
GmtPlusZero, GmtMinusZero, GmtZero, Greenwich, Hongkong, Hst, Iceland, Iran, Israel, Jamaica, GmtPlusZero, GmtMinusZero, GmtZero, Greenwich, Hongkong, Hst, Iceland, Iran, Israel, Jamaica,
Japan, Kwajalein, Libya, Met, Mst, Mst7Mdt, Navajo, Nz, NzChat, Poland, Portugal, Prc, Pst8Pdt, Japan, Kwajalein, Libya, Met, Mst, Mst7Mdt, Navajo, Nz, NzChat, Poland, Portugal, Prc, Pst8Pdt,
Roc, Rok, Singapore, Turkey, Uct, Universal, Utc, WSu, Wet, Zulu); Roc, Rok, Singapore, Turkey, Uct, Universal, Utc, WSu, Wet, Zulu);
ENUM(AnisotropyMode, Automatic, Default, X2, X4, X8, X16); ENUM(AnisotropyMode, Automatic, Default, X2, X4, X8, X16);
ENUM(AstcDecodeMode, Cpu, Gpu, CpuAsynchronous); ENUM(AstcDecodeMode, Cpu, Gpu, CpuAsynchronous);
ENUM(AstcRecompression, Uncompressed, Bc1, Bc3); ENUM(AstcRecompression, Uncompressed, Bc1, Bc3);
ENUM(VSyncMode, Immediate, Mailbox, Fifo, FifoRelaxed); ENUM(VSyncMode, Immediate, Mailbox, Fifo, FifoRelaxed);
ENUM(VramUsageMode, Conservative, Aggressive); ENUM(VramUsageMode, Conservative, Aggressive);
ENUM(RendererBackend, OpenGL, Vulkan, Null); ENUM(RendererBackend, OpenGL, Vulkan, Null);
ENUM(ShaderBackend, Glsl, Glasm, SpirV); ENUM(ShaderBackend, Glsl, Glasm, SpirV);
ENUM(GpuAccuracy, Normal, High, Extreme); ENUM(GpuAccuracy, Normal, High, Extreme);
ENUM(DmaAccuracy, Default, Unsafe, Safe); ENUM(DmaAccuracy, Default, Unsafe, Safe);
ENUM(CpuBackend, Dynarmic, Nce); ENUM(CpuBackend, Dynarmic, Nce);
ENUM(CpuAccuracy, Auto, Accurate, Unsafe, Paranoid); ENUM(CpuAccuracy, Auto, Accurate, Unsafe, Paranoid);
ENUM(CpuClock, Boost, Fast) ENUM(CpuClock, Boost, Fast)
ENUM(MemoryLayout, Memory_4Gb, Memory_6Gb, Memory_8Gb, Memory_10Gb, Memory_12Gb); ENUM(MemoryLayout, Memory_4Gb, Memory_6Gb, Memory_8Gb, Memory_10Gb, Memory_12Gb);
ENUM(ConfirmStop, Ask_Always, Ask_Based_On_Game, Ask_Never); ENUM(ConfirmStop, Ask_Always, Ask_Based_On_Game, Ask_Never);
ENUM(FullscreenMode, Borderless, Exclusive); ENUM(FullscreenMode, Borderless, Exclusive);
ENUM(NvdecEmulation, Off, Cpu, Gpu); ENUM(NvdecEmulation, Off, Cpu, Gpu);
ENUM(ResolutionSetup, Res1_4X, Res1_2X, Res3_4X, Res1X, Res3_2X, Res2X, Res3X, Res4X, Res5X, Res6X, Res7X, Res8X);
ENUM(ResolutionSetup,
Res1_4X,
Res1_2X,
Res3_4X,
Res1X,
Res3_2X,
Res2X,
Res3X,
Res4X,
Res5X,
Res6X,
Res7X,
Res8X);
ENUM(ScalingFilter, NearestNeighbor, Bilinear, Bicubic, Spline1, Gaussian, Lanczos, ScaleForce, Fsr, Area, MaxEnum); ENUM(ScalingFilter, NearestNeighbor, Bilinear, Bicubic, Spline1, Gaussian, Lanczos, ScaleForce, Fsr, Area, MaxEnum);
ENUM(AntiAliasing, None, Fxaa, Smaa, MaxEnum); ENUM(AntiAliasing, None, Fxaa, Smaa, MaxEnum);
ENUM(AspectRatio, R16_9, R4_3, R21_9, R16_10, Stretch); ENUM(AspectRatio, R16_9, R4_3, R21_9, R16_10, Stretch);
ENUM(ConsoleMode, Handheld, Docked); ENUM(ConsoleMode, Handheld, Docked);
ENUM(AppletMode, HLE, LLE); ENUM(AppletMode, HLE, LLE);
ENUM(SpirvOptimizeMode, Never, OnLoad, Always); ENUM(SpirvOptimizeMode, Never, OnLoad, Always);
ENUM(GpuOverclock, Low, Medium, High) ENUM(GpuOverclock, Low, Medium, High)
ENUM(TemperatureUnits, Celsius, Fahrenheit) ENUM(TemperatureUnits, Celsius, Fahrenheit)
template <typename Type> template <typename Type>
inline std::string CanonicalizeEnum(Type id) { inline std::string_view CanonicalizeEnum(Type id) {
const auto group = EnumMetadata<Type>::Canonicalizations(); const auto group = EnumMetadata<Type>::Canonicalizations();
for (auto& [name, value] : group) { for (auto& [name, value] : group)
if (value == id) { if (value == id)
return name; return name;
}
}
return "unknown"; return "unknown";
} }
template <typename Type> template <typename Type>
inline Type ToEnum(const std::string& canonicalization) { inline Type ToEnum(const std::string& canonicalization) {
const auto group = EnumMetadata<Type>::Canonicalizations(); const auto group = EnumMetadata<Type>::Canonicalizations();
for (auto& [name, value] : group) { for (auto& [name, value] : group)
if (name == canonicalization) { if (name == canonicalization)
return value; return value;
}
}
return {}; return {};
} }
} // namespace Settings } // namespace Settings

View file

@ -72,10 +72,17 @@ public:
u32 specialization_ = Specialization::Default, bool save_ = true, u32 specialization_ = Specialization::Default, bool save_ = true,
bool runtime_modifiable_ = false, BasicSetting* other_setting_ = nullptr) bool runtime_modifiable_ = false, BasicSetting* other_setting_ = nullptr)
requires(ranged) requires(ranged)
: BasicSetting(linkage, name, category_, save_, runtime_modifiable_, specialization_, : BasicSetting(linkage, name, category_, save_, runtime_modifiable_, specialization_, other_setting_),
other_setting_),
value{default_val}, default_value{default_val}, maximum{max_val}, minimum{min_val} {} value{default_val}, default_value{default_val}, maximum{max_val}, minimum{min_val} {}
explicit Setting(Linkage& linkage, const Type& default_val,
const std::string& name, Category category_,
u32 specialization_ = Specialization::Default, bool save_ = true,
bool runtime_modifiable_ = false, BasicSetting* other_setting_ = nullptr)
requires(ranged && std::is_enum_v<Type>)
: BasicSetting(linkage, name, category_, save_, runtime_modifiable_, specialization_, other_setting_),
value{default_val}, default_value{default_val}, maximum{EnumMetadata<Type>::GetLast()}, minimum{EnumMetadata<Type>::GetFirst()} {}
/** /**
* Returns a reference to the setting's value. * Returns a reference to the setting's value.
* *
@ -119,9 +126,6 @@ protected:
return value_.has_value() ? std::to_string(*value_) : "none"; return value_.has_value() ? std::to_string(*value_) : "none";
} else if constexpr (std::is_same_v<Type, bool>) { } else if constexpr (std::is_same_v<Type, bool>) {
return value_ ? "true" : "false"; return value_ ? "true" : "false";
} else if constexpr (std::is_same_v<Type, AudioEngine>) {
// Compatibility with old AudioEngine setting being a string
return CanonicalizeEnum(value_);
} else if constexpr (std::is_floating_point_v<Type>) { } else if constexpr (std::is_floating_point_v<Type>) {
return fmt::format("{:f}", value_); return fmt::format("{:f}", value_);
} else if constexpr (std::is_enum_v<Type>) { } else if constexpr (std::is_enum_v<Type>) {
@ -207,7 +211,7 @@ public:
[[nodiscard]] std::string Canonicalize() const override final { [[nodiscard]] std::string Canonicalize() const override final {
if constexpr (std::is_enum_v<Type>) { if constexpr (std::is_enum_v<Type>) {
return CanonicalizeEnum(this->GetValue()); return std::string{CanonicalizeEnum(this->GetValue())};
} else { } else {
return ToString(this->GetValue()); return ToString(this->GetValue());
} }
@ -288,41 +292,32 @@ public:
* @param other_setting_ A second Setting to associate to this one in metadata * @param other_setting_ A second Setting to associate to this one in metadata
*/ */
template <typename T = BasicSetting> template <typename T = BasicSetting>
explicit SwitchableSetting(Linkage& linkage, const Type& default_val, const std::string& name, explicit SwitchableSetting(Linkage& linkage, const Type& default_val, const std::string& name, Category category_, u32 specialization_ = Specialization::Default, bool save_ = true, bool runtime_modifiable_ = false, T* other_setting_ = nullptr) requires(!ranged)
Category category_, u32 specialization_ = Specialization::Default, : Setting<Type, false>{ linkage, default_val, name, category_, specialization_, save_, runtime_modifiable_, other_setting_} {
bool save_ = true, bool runtime_modifiable_ = false,
typename std::enable_if<!ranged, T*>::type other_setting_ = nullptr)
: Setting<Type, false>{
linkage, default_val, name, category_, specialization_,
save_, runtime_modifiable_, other_setting_} {
linkage.restore_functions.emplace_back([this]() { this->SetGlobal(true); }); linkage.restore_functions.emplace_back([this]() { this->SetGlobal(true); });
} }
virtual ~SwitchableSetting() = default; virtual ~SwitchableSetting() = default;
/** /// @brief Sets a default value, minimum value, maximum value, and label.
* Sets a default value, minimum value, maximum value, and label. /// @param linkage Setting registry
* /// @param default_val Initial value of the setting, and default value of the setting
* @param linkage Setting registry /// @param min_val Sets the minimum allowed value of the setting
* @param default_val Initial value of the setting, and default value of the setting /// @param max_val Sets the maximum allowed value of the setting
* @param min_val Sets the minimum allowed value of the setting /// @param name Label for the setting
* @param max_val Sets the maximum allowed value of the setting /// @param category_ Category of the setting AKA INI group
* @param name Label for the setting /// @param specialization_ Suggestion for how frontend implementations represent this in a config
* @param category_ Category of the setting AKA INI group /// @param save_ Suggests that this should or should not be saved to a frontend config file
* @param specialization_ Suggestion for how frontend implementations represent this in a config /// @param runtime_modifiable_ Suggests whether this is modifiable while a guest is loaded
* @param save_ Suggests that this should or should not be saved to a frontend config file /// @param other_setting_ A second Setting to associate to this one in metadata
* @param runtime_modifiable_ Suggests whether this is modifiable while a guest is loaded
* @param other_setting_ A second Setting to associate to this one in metadata
*/
template <typename T = BasicSetting> template <typename T = BasicSetting>
explicit SwitchableSetting(Linkage& linkage, const Type& default_val, const Type& min_val, explicit SwitchableSetting(Linkage& linkage, const Type& default_val, const Type& min_val, const Type& max_val, const std::string& name, Category category_, u32 specialization_ = Specialization::Default, bool save_ = true, bool runtime_modifiable_ = false, T* other_setting_ = nullptr) requires(ranged)
const Type& max_val, const std::string& name, Category category_, : Setting<Type, true>{linkage, default_val, min_val, max_val, name, category_, specialization_, save_, runtime_modifiable_, other_setting_} {
u32 specialization_ = Specialization::Default, bool save_ = true, linkage.restore_functions.emplace_back([this]() { this->SetGlobal(true); });
bool runtime_modifiable_ = false, }
typename std::enable_if<ranged, T*>::type other_setting_ = nullptr)
: Setting<Type, true>{linkage, default_val, min_val, template <typename T = BasicSetting>
max_val, name, category_, explicit SwitchableSetting(Linkage& linkage, const Type& default_val, const std::string& name, Category category_, u32 specialization_ = Specialization::Default, bool save_ = true, bool runtime_modifiable_ = false, T* other_setting_ = nullptr) requires(ranged)
specialization_, save_, runtime_modifiable_, : Setting<Type, true>{linkage, default_val, EnumMetadata<Type>::GetFirst(), EnumMetadata<Type>::GetLast(), name, category_, specialization_, save_, runtime_modifiable_, other_setting_} {
other_setting_} {
linkage.restore_functions.emplace_back([this]() { this->SetGlobal(true); }); linkage.restore_functions.emplace_back([this]() { this->SetGlobal(true); });
} }

View file

@ -8,6 +8,7 @@
#include <deque> #include <deque>
#include <mutex> #include <mutex>
#include <stack>
#include "common/math_util.h" #include "common/math_util.h"
#include "core/hle/service/apm/apm_controller.h" #include "core/hle/service/apm/apm_controller.h"
@ -23,6 +24,7 @@
#include "core/hle/service/am/hid_registration.h" #include "core/hle/service/am/hid_registration.h"
#include "core/hle/service/am/lifecycle_manager.h" #include "core/hle/service/am/lifecycle_manager.h"
#include "core/hle/service/am/process_holder.h" #include "core/hle/service/am/process_holder.h"
#include "core/hle/service/am/service/storage.h"
namespace Service::AM { namespace Service::AM {
@ -97,6 +99,9 @@ struct Applet {
std::deque<std::vector<u8>> preselected_user_launch_parameter{}; std::deque<std::vector<u8>> preselected_user_launch_parameter{};
std::deque<std::vector<u8>> friend_invitation_storage_channel{}; std::deque<std::vector<u8>> friend_invitation_storage_channel{};
// Context Stack
std::stack<SharedPointer<IStorage>> context_stack{};
// Caller applet // Caller applet
std::weak_ptr<Applet> caller_applet{}; std::weak_ptr<Applet> caller_applet{};
std::shared_ptr<AppletDataBroker> caller_applet_broker{}; std::shared_ptr<AppletDataBroker> caller_applet_broker{};

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 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
@ -15,12 +18,12 @@ IProcessWindingController::IProcessWindingController(Core::System& system_,
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, D<&IProcessWindingController::GetLaunchReason>, "GetLaunchReason"}, {0, D<&IProcessWindingController::GetLaunchReason>, "GetLaunchReason"},
{11, D<&IProcessWindingController::OpenCallingLibraryApplet>, "OpenCallingLibraryApplet"}, {11, D<&IProcessWindingController::OpenCallingLibraryApplet>, "OpenCallingLibraryApplet"},
{21, nullptr, "PushContext"}, {21, D<&IProcessWindingController::PushContext>, "PushContext"},
{22, nullptr, "PopContext"}, {22, D<&IProcessWindingController::PopContext>, "PopContext"},
{23, nullptr, "CancelWindingReservation"}, {23, D<&IProcessWindingController::CancelWindingReservation>, "CancelWindingReservation"},
{30, nullptr, "WindAndDoReserved"}, {30, D<&IProcessWindingController::WindAndDoReserved>, "WindAndDoReserved"},
{40, nullptr, "ReserveToStartAndWaitAndUnwindThis"}, {40, D<&IProcessWindingController::ReserveToStartAndWaitAndUnwindThis>, "ReserveToStartAndWaitAndUnwindThis"},
{41, nullptr, "ReserveToStartAndWait"}, {41, D<&IProcessWindingController::ReserveToStartAndWait>, "ReserveToStartAndWait"},
}; };
// clang-format on // clang-format on
@ -51,4 +54,43 @@ Result IProcessWindingController::OpenCallingLibraryApplet(
R_SUCCEED(); R_SUCCEED();
} }
Result IProcessWindingController::PushContext(SharedPointer<IStorage> context) {
LOG_INFO(Service_AM, "called");
m_applet->context_stack.push(context);
R_SUCCEED();
}
Result IProcessWindingController::PopContext(Out<SharedPointer<IStorage>> out_context) {
LOG_INFO(Service_AM, "called");
if (m_applet->context_stack.empty()) {
LOG_ERROR(Service_AM, "Context stack is empty");
R_THROW(ResultUnknown);
}
*out_context = m_applet->context_stack.top();
m_applet->context_stack.pop();
R_SUCCEED();
}
Result IProcessWindingController::CancelWindingReservation() {
LOG_WARNING(Service_AM, "STUBBED");
R_SUCCEED();
}
Result IProcessWindingController::WindAndDoReserved() {
LOG_WARNING(Service_AM, "STUBBED");
R_SUCCEED();
}
Result IProcessWindingController::ReserveToStartAndWaitAndUnwindThis() {
LOG_WARNING(Service_AM, "STUBBED");
R_SUCCEED();
}
Result IProcessWindingController::ReserveToStartAndWait() {
LOG_WARNING(Service_AM, "STUBBED");
R_SUCCEED();
}
} // namespace Service::AM } // namespace Service::AM

View file

@ -1,8 +1,12 @@
// SPDX-FileCopyrightText: Copyright 2025 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
#pragma once #pragma once
#include "core/hle/service/am/service/storage.h"
#include "core/hle/service/am/am_types.h" #include "core/hle/service/am/am_types.h"
#include "core/hle/service/cmif_types.h" #include "core/hle/service/cmif_types.h"
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
@ -21,6 +25,12 @@ private:
Result GetLaunchReason(Out<AppletProcessLaunchReason> out_launch_reason); Result GetLaunchReason(Out<AppletProcessLaunchReason> out_launch_reason);
Result OpenCallingLibraryApplet( Result OpenCallingLibraryApplet(
Out<SharedPointer<ILibraryAppletAccessor>> out_calling_library_applet); Out<SharedPointer<ILibraryAppletAccessor>> out_calling_library_applet);
Result PushContext(SharedPointer<IStorage> in_context);
Result PopContext(Out<SharedPointer<IStorage>> out_context);
Result CancelWindingReservation();
Result WindAndDoReserved();
Result ReserveToStartAndWaitAndUnwindThis();
Result ReserveToStartAndWait();
const std::shared_ptr<Applet> m_applet; const std::shared_ptr<Applet> m_applet;
}; };

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 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
@ -67,6 +70,7 @@ ISelfController::ISelfController(Core::System& system_, std::shared_ptr<Applet>
{110, nullptr, "SetApplicationAlbumUserData"}, {110, nullptr, "SetApplicationAlbumUserData"},
{120, D<&ISelfController::SaveCurrentScreenshot>, "SaveCurrentScreenshot"}, {120, D<&ISelfController::SaveCurrentScreenshot>, "SaveCurrentScreenshot"},
{130, D<&ISelfController::SetRecordVolumeMuted>, "SetRecordVolumeMuted"}, {130, D<&ISelfController::SetRecordVolumeMuted>, "SetRecordVolumeMuted"},
{230, D<&ISelfController::Unknown230>, "Unknown230"},
{1000, nullptr, "GetDebugStorageChannel"}, {1000, nullptr, "GetDebugStorageChannel"},
}; };
// clang-format on // clang-format on
@ -404,4 +408,12 @@ Result ISelfController::SetRecordVolumeMuted(bool muted) {
R_SUCCEED(); R_SUCCEED();
} }
Result ISelfController::Unknown230(u32 in_val, Out<u16> out_val) {
LOG_WARNING(Service_AM, "(STUBBED) called, in_val={}", in_val);
*out_val = 0;
R_SUCCEED();
}
} // namespace Service::AM } // namespace Service::AM

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 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
@ -63,6 +66,7 @@ private:
Result SetAlbumImageTakenNotificationEnabled(bool enabled); Result SetAlbumImageTakenNotificationEnabled(bool enabled);
Result SaveCurrentScreenshot(Capture::AlbumReportOption album_report_option); Result SaveCurrentScreenshot(Capture::AlbumReportOption album_report_option);
Result SetRecordVolumeMuted(bool muted); Result SetRecordVolumeMuted(bool muted);
Result Unknown230(u32 in_val, Out<u16> out_val);
Kernel::KProcess* const m_process; Kernel::KProcess* const m_process;
const std::shared_ptr<Applet> m_applet; const std::shared_ptr<Applet> m_applet;

View file

@ -135,6 +135,8 @@ target_include_directories(dynarmic_tests PRIVATE . ../src)
target_compile_options(dynarmic_tests PRIVATE ${DYNARMIC_CXX_FLAGS}) target_compile_options(dynarmic_tests PRIVATE ${DYNARMIC_CXX_FLAGS})
target_compile_definitions(dynarmic_tests PRIVATE FMT_USE_USER_DEFINED_LITERALS=1) target_compile_definitions(dynarmic_tests PRIVATE FMT_USE_USER_DEFINED_LITERALS=1)
target_compile_options(dynarmic_tests PRIVATE -mavx2) if ("x86_64" IN_LIST ARCHITECTURE)
target_compile_options(dynarmic_tests PRIVATE -mavx2)
endif()
add_test(dynarmic_tests dynarmic_tests --durations yes) add_test(dynarmic_tests dynarmic_tests --durations yes)

View file

@ -785,18 +785,13 @@ void BufferCache<P>::BindHostGraphicsUniformBuffers(size_t stage) {
} }
template <class P> template <class P>
void BufferCache<P>::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32 binding_index, void BufferCache<P>::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32 binding_index, bool needs_bind) {
bool needs_bind) { ++channel_state->uniform_cache_shots[0];
const Binding& binding = channel_state->uniform_buffers[stage][index]; const Binding& binding = channel_state->uniform_buffers[stage][index];
const DAddr device_addr = binding.device_addr; const DAddr device_addr = binding.device_addr;
const u32 size = (std::min)(binding.size, (*channel_state->uniform_buffer_sizes)[stage][index]); const u32 size = (std::min)(binding.size, (*channel_state->uniform_buffer_sizes)[stage][index]);
Buffer& buffer = slot_buffers[binding.buffer_id]; Buffer& buffer = slot_buffers[binding.buffer_id];
TouchBuffer(buffer, binding.buffer_id); TouchBuffer(buffer, binding.buffer_id);
const bool sync_buffer = SynchronizeBuffer(buffer, device_addr, size);
if (sync_buffer) {
++channel_state->uniform_cache_hits[0];
}
++channel_state->uniform_cache_shots[0];
const bool use_fast_buffer = binding.buffer_id != NULL_BUFFER_ID && const bool use_fast_buffer = binding.buffer_id != NULL_BUFFER_ID &&
size <= channel_state->uniform_buffer_skip_cache_size && size <= channel_state->uniform_buffer_skip_cache_size &&
!memory_tracker.IsRegionGpuModified(device_addr, size); !memory_tracker.IsRegionGpuModified(device_addr, size);
@ -827,7 +822,10 @@ void BufferCache<P>::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32
device_memory.ReadBlockUnsafe(device_addr, span.data(), size); device_memory.ReadBlockUnsafe(device_addr, span.data(), size);
return; return;
} }
// Classic cached path
if (SynchronizeBuffer(buffer, device_addr, size)) {
++channel_state->uniform_cache_hits[0];
}
// Skip binding if it's not needed and if the bound buffer is not the fast version // Skip binding if it's not needed and if the bound buffer is not the fast version
// This exists to avoid instances where the fast buffer is bound and a GPU write happens // This exists to avoid instances where the fast buffer is bound and a GPU write happens
needs_bind |= HasFastUniformBufferBound(stage, binding_index); needs_bind |= HasFastUniformBufferBound(stage, binding_index);

View file

@ -45,9 +45,31 @@ SPDX-License-Identifier: GPL-2.0-or-later
<true/> <true/>
<key>NSHumanReadableCopyright</key> <key>NSHumanReadableCopyright</key>
<string></string> <string></string>
<!-- Fixed -->
<key>LSApplicationCategoryType</key>
<string>public.app-category.games</string>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>nsp</string>
<string>xci</string>
<string>nro</string>
</array>
<key>CFBundleTypeName</key>
<string>Switch File</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSHandlerRank</key>
<string>Default</string>
</dict>
</array>
<key>NSPrincipalClass</key> <key>NSPrincipalClass</key>
<string>NSApplication</string> <string>NSApplication</string>
<key>NSHighResolutionCapable</key> <key>NSHighResolutionCapable</key>
<string>True</string> <string>True</string>
<key>UIDesignRequiresCompatibility</key>
<true/> <!-- https://bugreports.qt.io/browse/QTBUG-138942 -->
</dict> </dict>
</plist> </plist>

View file

@ -270,10 +270,8 @@ void ConfigureAudio::UpdateAudioDevices(int sink_index) {
void ConfigureAudio::InitializeAudioSinkComboBox() { void ConfigureAudio::InitializeAudioSinkComboBox() {
sink_combo_box->clear(); sink_combo_box->clear();
sink_combo_box->addItem(QString::fromUtf8(AudioCore::Sink::auto_device_name)); sink_combo_box->addItem(QString::fromUtf8(AudioCore::Sink::auto_device_name));
for (const auto& id : AudioCore::Sink::GetSinkIDs())
for (const auto& id : AudioCore::Sink::GetSinkIDs()) { sink_combo_box->addItem(QString::fromStdString(std::string{Settings::CanonicalizeEnum(id)}));
sink_combo_box->addItem(QString::fromStdString(Settings::CanonicalizeEnum(id)));
}
} }
void ConfigureAudio::RetranslateUI() { void ConfigureAudio::RetranslateUI() {

View file

@ -13,6 +13,7 @@
#include <QString> #include <QString>
#include <QStringLiteral> #include <QStringLiteral>
#include <QWidget> #include <QWidget>
#include <QObject>
#include <qobjectdefs.h> #include <qobjectdefs.h>
#include "qt_common/shared_translation.h" #include "qt_common/shared_translation.h"

View file

@ -58,11 +58,11 @@ class GameList : public QWidget {
public: public:
enum { enum {
COLUMN_NAME, COLUMN_NAME,
COLUMN_COMPATIBILITY,
COLUMN_ADD_ONS,
COLUMN_FILE_TYPE, COLUMN_FILE_TYPE,
COLUMN_SIZE, COLUMN_SIZE,
COLUMN_PLAY_TIME, COLUMN_PLAY_TIME,
COLUMN_ADD_ONS,
COLUMN_COMPATIBILITY,
COLUMN_COUNT, // Number of columns COLUMN_COUNT, // Number of columns
}; };

View file

@ -204,36 +204,24 @@ QList<QStandardItem*> MakeGameListEntry(const std::string& path,
const PlayTime::PlayTimeManager& play_time_manager, const PlayTime::PlayTimeManager& play_time_manager,
const FileSys::PatchManager& patch) const FileSys::PatchManager& patch)
{ {
const auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id); auto const it = FindMatchingCompatibilityEntry(compatibility_list, program_id);
// The game list uses 99 as compatibility number for untested games
QString compatibility = it != compatibility_list.end() ? it->second.first : QStringLiteral("99");
// The game list uses this as compatibility number for untested games auto const file_type = loader.GetFileType();
QString compatibility{QStringLiteral("99")}; auto const file_type_string = QString::fromStdString(Loader::GetFileTypeString(file_type));
if (it != compatibility_list.end()) {
compatibility = it->second.first;
}
const auto file_type = loader.GetFileType(); QString patch_versions = GetGameListCachedObject(fmt::format("{:016X}", patch.GetTitleID()), "pv.txt", [&patch, &loader] {
const auto file_type_string = QString::fromStdString(Loader::GetFileTypeString(file_type)); return FormatPatchNameVersions(patch, loader, loader.IsRomFSUpdatable());
});
QList<QStandardItem*> list{ return QList<QStandardItem*>{
new GameListItemPath(FormatGameName(path), icon, QString::fromStdString(name), new GameListItemPath(FormatGameName(path), icon, QString::fromStdString(name), file_type_string, program_id),
file_type_string, program_id),
new GameListItemCompat(compatibility),
new GameListItem(file_type_string), new GameListItem(file_type_string),
new GameListItemSize(size), new GameListItemSize(size),
new GameListItemPlayTime(play_time_manager.GetPlayTime(program_id)), new GameListItemPlayTime(play_time_manager.GetPlayTime(program_id)),
new GameListItem(patch_versions),
new GameListItemCompat(compatibility),
}; };
QString patch_versions;
patch_versions = GetGameListCachedObject(
fmt::format("{:016X}", patch.GetTitleID()), "pv.txt", [&patch, &loader] {
return FormatPatchNameVersions(patch, loader, loader.IsRomFSUpdatable());
});
list.insert(2, new GameListItem(patch_versions));
return list;
} }
} // Anonymous namespace } // Anonymous namespace