diff --git a/UnleashedRecomp/gpu/video.cpp b/UnleashedRecomp/gpu/video.cpp index a9edd0b..c196c98 100644 --- a/UnleashedRecomp/gpu/video.cpp +++ b/UnleashedRecomp/gpu/video.cpp @@ -299,6 +299,10 @@ static std::unique_ptr g_device; static RenderDeviceCapabilities g_capabilities; +// Track the currently active graphics API for display purposes +static EGraphicsAPI g_currentGraphicsAPI = EGraphicsAPI::Auto; +static bool g_currentAPIChosenByAuto = false; + static constexpr size_t NUM_FRAMES = 2; static constexpr size_t NUM_QUERIES = 2; @@ -1673,6 +1677,12 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver, bool graphicsApiRetry) #ifdef UNLEASHED_RECOMP_D3D12 g_vulkan = DetectWine() || Config::GraphicsAPI == EGraphicsAPI::Vulkan; + + // Track if the Graphics API was chosen by Auto or manually selected + g_currentAPIChosenByAuto = (Config::GraphicsAPI == EGraphicsAPI::Auto); +#else + // For Vulkan-only builds, check if Auto was selected + g_currentAPIChosenByAuto = (Config::GraphicsAPI == EGraphicsAPI::Auto); #endif // Attempt to create the possible backends using a vector of function pointers. Whichever succeeds first will be the chosen API. @@ -1765,6 +1775,12 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver, bool graphicsApiRetry) } g_vulkan = (interfaceFunction == CreateVulkanInterfaceWrapper); + + // Track which graphics API is actually being used for display purposes + g_currentGraphicsAPI = g_vulkan ? EGraphicsAPI::Vulkan : EGraphicsAPI::D3D12; +#else + // For Vulkan-only builds + g_currentGraphicsAPI = EGraphicsAPI::Vulkan; #endif // Enable triangle strip workaround if we are on AMD, as there is a bug where // restart indices cause triangles to be culled incorrectly. Converting them to degenerate triangles fixes it. @@ -3062,6 +3078,16 @@ void Video::ComputeViewportDimensions() AspectRatioPatches::ComputeOffsets(); } +EGraphicsAPI Video::GetCurrentGraphicsAPI() +{ + return g_currentGraphicsAPI; +} + +bool Video::IsCurrentAPIChosenByAuto() +{ + return g_currentAPIChosenByAuto; +} + static RenderFormat ConvertFormat(uint32_t format) { switch (format) diff --git a/UnleashedRecomp/gpu/video.h b/UnleashedRecomp/gpu/video.h index 6c24d30..115e7a4 100644 --- a/UnleashedRecomp/gpu/video.h +++ b/UnleashedRecomp/gpu/video.h @@ -5,6 +5,7 @@ //#define PSO_CACHING_CLEANUP #include +#include #define D3DCLEAR_TARGET 0x1 #define D3DCLEAR_ZBUFFER 0x10 @@ -24,6 +25,8 @@ struct Video static void StartPipelinePrecompilation(); static void WaitForGPU(); static void ComputeViewportDimensions(); + static EGraphicsAPI GetCurrentGraphicsAPI(); + static bool IsCurrentAPIChosenByAuto(); }; struct GuestSamplerState diff --git a/UnleashedRecomp/locale/config_locale.cpp b/UnleashedRecomp/locale/config_locale.cpp index 1242e4e..a05e439 100644 --- a/UnleashedRecomp/locale/config_locale.cpp +++ b/UnleashedRecomp/locale/config_locale.cpp @@ -526,6 +526,82 @@ CONFIG_DEFINE_LOCALE(Monitor) { ELanguage::Italian, { "Schermo", "Cambia lo schermo su cui visualizzare il gioco." } } }; +// Japanese Notes: This localization should include furigana. +CONFIG_DEFINE_LOCALE(GraphicsAPI) +{ + { ELanguage::English, { "Graphics API", "Change the graphics API used for rendering. \n\nWARNING: Changing graphics api requires game restart" } }, + { ELanguage::Japanese, { "グラフィックAPI", "レンダリングに[使用:しよう]するグラフィックAPIを[変更:へんこう]します。\n\n[警告:けいこく]: グラフィックAPIの[変更:へんこう]にはゲームの[再起動:さいきどう]が[必要:ひつよう]です" } }, + { ELanguage::German, { "Grafik-API", "Ändere die Grafik-API für das Rendering. \n\nWARNUNG: Das Ändern der Grafik-API erfordert einen Neustart des Spiels" } }, + { ELanguage::French, { "API graphique", "Modifie l'API graphique utilisée pour le rendu. \n\nATTENTION : Changer l'API graphique nécessite un redémarrage du jeu" } }, + { ELanguage::Spanish, { "API de gráficos", "Cambia la API de gráficos utilizada para el renderizado. \n\nADVERTENCIA: Cambiar la API de gráficos requiere reiniciar el juego" } }, + { ELanguage::Italian, { "API grafica", "Modifica l'API grafica utilizzata per il rendering. \n\nATTENZIONE: Cambiare l'API grafica richiede il riavvio del gioco" } } +}; + +// Japanese Notes: This localization should include furigana in its description. +CONFIG_DEFINE_ENUM_LOCALE(EGraphicsAPI) +{ + { + ELanguage::English, + { + { EGraphicsAPI::Auto, { "AUTO", "Automatically selects the best available graphics API for your system." } }, +#ifdef UNLEASHED_RECOMP_D3D12 + { EGraphicsAPI::D3D12, { "DX12", "use Microsoft's DirectX 12 API for graphics rendering." } }, +#endif + { EGraphicsAPI::Vulkan, { "VULKAN", "use Khronos Group's Vulkan API for graphics rendering." } } + } + }, + { + ELanguage::Japanese, + { + { EGraphicsAPI::Auto, { "自動", "[自動:じどう]: [最適:さいてき]なグラフィックAPIを\u200B[自動的:じどうてき]に\u200B[選択:せんたく]します" } }, +#ifdef UNLEASHED_RECOMP_D3D12 + { EGraphicsAPI::D3D12, { "DX12", "Microsoft の DirectX 12 API を\u200B[使用:しよう]してレンダリングします" } }, +#endif + { EGraphicsAPI::Vulkan, { "VULKAN", "Khronos Group の Vulkan API を\u200B[使用:しよう]してレンダリングします" } } + } + }, + { + ELanguage::German, + { + { EGraphicsAPI::Auto, { "AUTO", "Wählt automatisch die beste verfügbare Grafik-API aus." } }, +#ifdef UNLEASHED_RECOMP_D3D12 + { EGraphicsAPI::D3D12, { "DX12", "Verwendet Microsofts DirectX 12 API für das Rendering." } }, +#endif + { EGraphicsAPI::Vulkan, { "VULKAN", "Verwendet die Khronos Group's Vulkan API für das Rendering." } } + } + }, + { + ELanguage::French, + { + { EGraphicsAPI::Auto, { "AUTO", "sélectionne automatiquement la meilleure API graphique disponible." } }, +#ifdef UNLEASHED_RECOMP_D3D12 + { EGraphicsAPI::D3D12, { "DX12", "utilise l'API DirectX 12 de Microsoft pour le rendu." } }, +#endif + { EGraphicsAPI::Vulkan, { "VULKAN", "utilise l'API Vulkan du Khronos Group pour le rendu." } } + } + }, + { + ELanguage::Spanish, + { + { EGraphicsAPI::Auto, { "AUTO", "selecciona automáticamente la mejor API de gráficos disponible." } }, +#ifdef UNLEASHED_RECOMP_D3D12 + { EGraphicsAPI::D3D12, { "DX12", "utiliza la API DirectX 12 de Microsoft para el renderizado." } }, +#endif + { EGraphicsAPI::Vulkan, { "VULKAN", "utiliza la API Vulkan del Khronos Group para el renderizado." } } + } + }, + { + ELanguage::Italian, + { + { EGraphicsAPI::Auto, { "AUTO", "seleziona automaticamente la migliore API grafica disponibile." } }, +#ifdef UNLEASHED_RECOMP_D3D12 + { EGraphicsAPI::D3D12, { "DX12", "utilizza l'API DirectX 12 di Microsoft per il rendering." } }, +#endif + { EGraphicsAPI::Vulkan, { "VULKAN", "utilizza l'API Vulkan del Khronos Group per il rendering." } } + } + } +}; + // Japanese Notes: This localization should include furigana. CONFIG_DEFINE_LOCALE(AspectRatio) { diff --git a/UnleashedRecomp/ui/options_menu.cpp b/UnleashedRecomp/ui/options_menu.cpp index 33ac5c6..7601f48 100644 --- a/UnleashedRecomp/ui/options_menu.cpp +++ b/UnleashedRecomp/ui/options_menu.cpp @@ -1271,6 +1271,7 @@ static void DrawConfigOptions() DrawConfigOption(rowCount++, yOffset, &Config::AspectRatio, true); DrawConfigOption(rowCount++, yOffset, &Config::ResolutionScale, true, nullptr, 0.25f, 1.0f, 2.0f); DrawConfigOption(rowCount++, yOffset, &Config::Fullscreen, true); + DrawConfigOption(rowCount++, yOffset, &Config::GraphicsAPI, true); DrawConfigOption(rowCount++, yOffset, &Config::VSync, true); DrawConfigOption(rowCount++, yOffset, &Config::FPS, true, nullptr, FPS_MIN, 120, FPS_MAX); DrawConfigOption(rowCount++, yOffset, &Config::Brightness, true); diff --git a/UnleashedRecomp/user/config.cpp b/UnleashedRecomp/user/config.cpp index bd622b7..f1218ce 100644 --- a/UnleashedRecomp/user/config.cpp +++ b/UnleashedRecomp/user/config.cpp @@ -2,6 +2,7 @@ #include #include #include +#include std::vector g_configDefinitions; @@ -407,6 +408,12 @@ CONFIG_DEFINE_ENUM_TEMPLATE(EUIAlignmentMode) extern CONFIG_ENUM_LOCALE(type) g_##type##_locale; \ ConfigDef Config::name{section, #name, &g_##name##_locale, defaultValue, &g_##type##_template, &g_##type##_locale}; +#undef CONFIG_DEFINE_ENUM_LOCALISED_HIDDEN +#define CONFIG_DEFINE_ENUM_LOCALISED_HIDDEN(section, type, name, defaultValue) \ + extern CONFIG_LOCALE g_##name##_locale; \ + extern CONFIG_ENUM_LOCALE(type) g_##type##_locale; \ + ConfigDef Config::name{section, #name, &g_##name##_locale, defaultValue, &g_##type##_template, &g_##type##_locale}; + #include "config_def.h" // CONFIG_DEFINE @@ -594,6 +601,58 @@ std::string ConfigDef::GetValueLocalised(ELanguage language) const return ToString(false); } +template +bool ConfigDef::ShouldShowCurrentAPI() const +{ + if constexpr (std::is_same_v) + { + return Value == EGraphicsAPI::Auto && + Config::GraphicsAPI.Value == EGraphicsAPI::Auto && + Video::IsCurrentAPIChosenByAuto(); + } + return false; +} + +template +std::string ConfigDef::GetCurrentAPIName(const ELanguage* languages, CONFIG_ENUM_LOCALE(T)* locale) const +{ + if constexpr (std::is_same_v) + { + EGraphicsAPI currentAPI = Video::GetCurrentGraphicsAPI(); + if (currentAPI == EGraphicsAPI::Auto) return ""; + + for (auto langToFind : {languages[0], languages[1]}) + { + auto langFindResult = locale->find(langToFind); + if (langFindResult != locale->end()) + { + auto apiFindResult = langFindResult->second.find(currentAPI); + if (apiFindResult != langFindResult->second.end()) + { + return std::get<0>(apiFindResult->second); + } + } + if (langToFind == ELanguage::English) break; + } + } + return ""; +} + +template +std::string ConfigDef::GetCurrentAPIText(ELanguage language, const std::string& apiName) const +{ + switch (language) + { + case ELanguage::English: return " Currently using: " + apiName; + case ELanguage::Japanese: return " [現在:げんざい][使用中:しようちゅう]: " + apiName; + case ELanguage::German: return " Derzeit verwendet: " + apiName; + case ELanguage::French: return " Actuellement utilisé : " + apiName; + case ELanguage::Spanish: return " Actualmente usando: " + apiName; + case ELanguage::Italian: return " Attualmente in uso: " + apiName; + default: return " Currently using: " + apiName; + } +} + template std::string ConfigDef::GetValueDescription(ELanguage language) const { @@ -620,7 +679,24 @@ std::string ConfigDef::GetValueDescription(ELanguage language) cons { auto valueFindResult = languageFindResult->second.find(Value); if (valueFindResult != languageFindResult->second.end()) - return std::get<1>(valueFindResult->second); + { + std::string description = std::get<1>(valueFindResult->second); + + // Special case for EGraphicsAPI::Auto - append current API info + if constexpr (std::is_same_v) + { + if (ShouldShowCurrentAPI()) + { + std::string currentAPIText = GetCurrentAPIName(languages, locale); + if (!currentAPIText.empty()) + { + description += GetCurrentAPIText(language, currentAPIText); + } + } + } + + return description; + } } if (languageToFind == ELanguage::English) diff --git a/UnleashedRecomp/user/config.h b/UnleashedRecomp/user/config.h index 9e87d12..af35627 100644 --- a/UnleashedRecomp/user/config.h +++ b/UnleashedRecomp/user/config.h @@ -200,6 +200,13 @@ public: void GetLocaleStrings(std::vector& localeStrings) const override; void SnapToNearestAccessibleValue(bool searchUp) override; +private: + // Graphics API dynamic text + bool ShouldShowCurrentAPI() const; + std::string GetCurrentAPIName(const ELanguage* languages, CONFIG_ENUM_LOCALE(T)* locale) const; + std::string GetCurrentAPIText(ELanguage language, const std::string& apiName) const; + +public: operator T() const { return Value; @@ -219,6 +226,7 @@ public: #define CONFIG_DEFINE_LOCALISED(section, type, name, defaultValue) CONFIG_DECLARE(type, name) #define CONFIG_DEFINE_ENUM(section, type, name, defaultValue) CONFIG_DECLARE(type, name) #define CONFIG_DEFINE_ENUM_LOCALISED(section, type, name, defaultValue) CONFIG_DECLARE(type, name) +#define CONFIG_DEFINE_ENUM_LOCALISED_HIDDEN(section, type, name, defaultValue) CONFIG_DECLARE_HIDDEN(type, name) class Config { diff --git a/UnleashedRecomp/user/config_def.h b/UnleashedRecomp/user/config_def.h index 80eb29c..ca63dda 100644 --- a/UnleashedRecomp/user/config_def.h +++ b/UnleashedRecomp/user/config_def.h @@ -47,7 +47,12 @@ CONFIG_DEFINE_LOCALISED("Audio", bool, MusicAttenuation, false); CONFIG_DEFINE_LOCALISED("Audio", bool, BattleTheme, true); CONFIG_DEFINE("Video", std::string, GraphicsDevice, ""); -CONFIG_DEFINE_ENUM("Video", EGraphicsAPI, GraphicsAPI, EGraphicsAPI::Auto); +#ifdef UNLEASHED_RECOMP_D3D12 +CONFIG_DEFINE_ENUM_LOCALISED("Video", EGraphicsAPI, GraphicsAPI, EGraphicsAPI::Auto); +#else +// Hide Graphics API setting for Vulkan-only builds +CONFIG_DEFINE_ENUM_LOCALISED_HIDDEN("Video", EGraphicsAPI, GraphicsAPI, EGraphicsAPI::Vulkan); +#endif CONFIG_DEFINE("Video", int32_t, WindowX, WINDOWPOS_CENTRED); CONFIG_DEFINE("Video", int32_t, WindowY, WINDOWPOS_CENTRED); CONFIG_DEFINE_LOCALISED("Video", int32_t, WindowSize, -1);