aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKleidis <kleidis1@protonmail.com>2025-12-17 03:59:27 +0100
committercrueter <crueter@eden-emu.dev>2025-12-17 03:59:27 +0100
commitb9530ae80f9994f4a10143f8336f2b9bee4416fc (patch)
tree6d3da866cb878c7fda927ca68bb4d6467f6b76f6 /src
parent5130185d122781a125f43602cfe521a905a5b1a0 (diff)
[core] Add overridable game setting functionality (#2963)
Adds a place to override specific game settings for specific vendors Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2963 Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com> Reviewed-by: Maufeat <sahyno1996@gmail.com> Co-authored-by: Kleidis <kleidis1@protonmail.com> Co-committed-by: Kleidis <kleidis1@protonmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/core/CMakeLists.txt2
-rw-r--r--src/core/core.cpp46
-rw-r--r--src/core/game_settings.cpp140
-rw-r--r--src/core/game_settings.h60
4 files changed, 205 insertions, 43 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 6a8b9b93b3..a961eff8bf 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -17,6 +17,8 @@ add_library(core STATIC
constants.h
core.cpp
core.h
+ game_settings.cpp
+ game_settings.h
core_timing.cpp
core_timing.h
cpu_manager.cpp
diff --git a/src/core/core.cpp b/src/core/core.cpp
index edc2df4851..bf97184f8f 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -6,6 +6,7 @@
#include <memory>
#include <utility>
+#include "game_settings.h"
#include "audio_core/audio_core.h"
#include "common/fs/fs.h"
#include "common/logging/log.h"
@@ -292,48 +293,6 @@ struct System::Impl {
return SystemResultStatus::Success;
}
-
- void LoadOverrides(u64 programId) const {
- std::string vendor = gpu_core->Renderer().GetDeviceVendor();
- LOG_INFO(Core, "GPU Vendor: {}", vendor);
-
- // Reset all per-game flags
- Settings::values.use_squashed_iterated_blend = false;
-
- // Insert PC overrides here
-
- #ifdef ANDROID
- // Example on how to set a setting based on the program ID and vendor
- if (programId == 0x010028600EBDA000 && vendor == "Mali") { // Mario 3d World
- // Settings::values.example = true;
- }
-
- // Example array of program IDs
- const std::array<u64, 10> example_array = {
- //0xprogramId
- 0x0004000000033400, // Game 1
- 0x0004000000033500 // Game 2
- // And so on
- };
-
- for (auto id : example_array) {
- if (programId == id) {
- // Settings::values.example = true;
- break;
- }
- }
-
- #endif
-
- // Ninja Gaiden Ragebound
- constexpr u64 ngr = 0x0100781020710000ULL;
-
- if (programId == ngr) {
- LOG_INFO(Core, "Enabling game specifc override: use_squashed_iterated_blend");
- Settings::values.use_squashed_iterated_blend = true;
- }
- }
-
SystemResultStatus Load(System& system, Frontend::EmuWindow& emu_window,
const std::string& filepath,
Service::AM::FrontendAppletParameters& params) {
@@ -419,7 +378,8 @@ struct System::Impl {
LOG_ERROR(Core, "Failed to find program id for ROM");
}
- LoadOverrides(program_id);
+
+ GameSettings::LoadOverrides(program_id, gpu_core->Renderer());
if (auto room_member = Network::GetRoomMember().lock()) {
Network::GameInfo game_info;
game_info.name = name;
diff --git a/src/core/game_settings.cpp b/src/core/game_settings.cpp
new file mode 100644
index 0000000000..da1530e026
--- /dev/null
+++ b/src/core/game_settings.cpp
@@ -0,0 +1,140 @@
+// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "core/game_settings.h"
+
+#include <algorithm>
+#include <cctype>
+
+#include "common/logging/log.h"
+#include "common/settings.h"
+#include "video_core/renderer_base.h"
+
+#if defined(__APPLE__)
+#include <TargetConditionals.h>
+#endif
+
+namespace Core::GameSettings {
+
+static GPUVendor GetGPU(const std::string& gpu_vendor_string) {
+ struct Entry { const char* name; GPUVendor vendor; };
+ static constexpr Entry GpuVendor[] = {
+ // NVIDIA
+ {"NVIDIA", GPUVendor::Nvidia},
+ {"Nouveau", GPUVendor::Nvidia},
+ {"NVK", GPUVendor::Nvidia},
+ {"Tegra", GPUVendor::Nvidia},
+ // AMD
+ {"AMD", GPUVendor::AMD},
+ {"RadeonSI", GPUVendor::AMD},
+ {"RADV", GPUVendor::AMD},
+ {"AMDVLK", GPUVendor::AMD},
+ {"R600", GPUVendor::AMD},
+ // Intel
+ {"Intel", GPUVendor::Intel},
+ {"ANV", GPUVendor::Intel},
+ {"i965", GPUVendor::Intel},
+ {"i915", GPUVendor::Intel},
+ {"OpenSWR", GPUVendor::Intel},
+ // Apple
+ {"Apple", GPUVendor::Apple},
+ {"MoltenVK", GPUVendor::Apple},
+ // Qualcomm / Adreno
+ {"Qualcomm", GPUVendor::Qualcomm},
+ {"Turnip", GPUVendor::Qualcomm},
+ // ARM / Mali
+ {"Mali", GPUVendor::ARM},
+ {"PanVK", GPUVendor::ARM},
+ // Imagination / PowerVR
+ {"PowerVR", GPUVendor::Imagination},
+ {"PVR", GPUVendor::Imagination},
+ // Microsoft / WARP / D3D12 GL
+ {"D3D12", GPUVendor::Microsoft},
+ {"Microsoft", GPUVendor::Microsoft},
+ {"WARP", GPUVendor::Microsoft},
+ };
+
+ for (const auto& entry : GpuVendor) {
+ if (gpu_vendor_string == entry.name) {
+ return entry.vendor;
+ }
+ }
+
+ // legacy (shouldn't be needed anymore, but just in case)
+ std::string gpu = gpu_vendor_string;
+ std::transform(gpu.begin(), gpu.end(), gpu.begin(), [](unsigned char c){ return (char)std::tolower(c); });
+ if (gpu.find("geforce") != std::string::npos) {
+ return GPUVendor::Nvidia;
+ }
+ if (gpu.find("radeon") != std::string::npos || gpu.find("ati") != std::string::npos) {
+ return GPUVendor::AMD;
+ }
+
+ return GPUVendor::Unknown;
+}
+
+static OS DetectOS() {
+#if defined(_WIN32)
+ return OS::Windows;
+#elif defined(__FIREOS__)
+ return OS::FireOS;
+#elif defined(__ANDROID__)
+ return OS::Android;
+#elif defined(__OHOS__)
+ return OS::HarmonyOS;
+#elif defined(__HAIKU__)
+ return OS::HaikuOS;
+#elif defined(__DragonFly__)
+ return OS::DragonFlyBSD;
+#elif defined(__NetBSD__)
+ return OS::NetBSD;
+#elif defined(__OpenBSD__)
+ return OS::OpenBSD;
+#elif defined(_AIX)
+ return OS::AIX;
+#elif defined(__managarm__)
+ return OS::Managarm;
+#elif defined(__redox__)
+ return OS::RedoxOS;
+#elif defined(__APPLE__) && defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
+ return OS::IOS;
+#elif defined(__APPLE__)
+ return OS::MacOS;
+#elif defined(__FreeBSD__)
+ return OS::FreeBSD;
+#elif defined(__sun) && defined(__SVR4)
+ return OS::Solaris;
+#elif defined(__linux__)
+ return OS::Linux;
+#else
+ return OS::Unknown;
+#endif
+}
+
+EnvironmentInfo DetectEnvironment(const VideoCore::RendererBase& renderer) {
+ EnvironmentInfo env{};
+ env.os = DetectOS();
+ env.vendor_string = renderer.GetDeviceVendor();
+ env.vendor = GetGPU(env.vendor_string);
+ return env;
+}
+
+void LoadOverrides(std::uint64_t program_id, const VideoCore::RendererBase& renderer) {
+ const auto env = DetectEnvironment(renderer);
+
+ switch (static_cast<TitleID>(program_id)) {
+ case TitleID::NinjaGaidenRagebound:
+ Settings::values.use_squashed_iterated_blend = true;
+ break;
+ default:
+ break;
+ }
+
+ LOG_INFO(Core, "Applied game settings for title ID {:016X} on OS {}, GPU vendor {} ({})",
+ program_id,
+ static_cast<int>(env.os),
+ static_cast<int>(env.vendor),
+ env.vendor_string);
+}
+
+} // namespace Core::GameSettings
diff --git a/src/core/game_settings.h b/src/core/game_settings.h
new file mode 100644
index 0000000000..327a1a4e2c
--- /dev/null
+++ b/src/core/game_settings.h
@@ -0,0 +1,60 @@
+// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include <array>
+#include <cstdint>
+#include <string>
+
+namespace VideoCore { class RendererBase; }
+
+namespace Core::GameSettings {
+
+enum class OS {
+ Windows,
+ Linux,
+ MacOS,
+ IOS,
+ Android,
+ FireOS,
+ HarmonyOS,
+ FreeBSD,
+ DragonFlyBSD,
+ NetBSD,
+ OpenBSD,
+ HaikuOS,
+ AIX,
+ Managarm,
+ RedoxOS,
+ Solaris,
+ Unknown,
+};
+
+enum class GPUVendor {
+ Nvidia,
+ AMD,
+ Intel,
+ Apple,
+ Qualcomm,
+ ARM,
+ Imagination,
+ Microsoft,
+ Unknown,
+};
+
+enum class TitleID : std::uint64_t {
+ NinjaGaidenRagebound = 0x0100781020710000ULL
+};
+
+struct EnvironmentInfo {
+ OS os{OS::Unknown};
+ GPUVendor vendor{GPUVendor::Unknown};
+ std::string vendor_string; // raw string from driver
+};
+
+EnvironmentInfo DetectEnvironment(const VideoCore::RendererBase& renderer);
+
+void LoadOverrides(std::uint64_t program_id, const VideoCore::RendererBase& renderer);
+
+} // namespace Core::GameSettings