2021-09-19 16:20:57 +02:00
|
|
|
#include <array>
|
2018-08-07 16:58:16 +02:00
|
|
|
#include <fstream>
|
|
|
|
#include <sstream>
|
|
|
|
#include <iostream>
|
2019-08-17 11:46:56 +02:00
|
|
|
#include <regex>
|
2021-09-19 16:20:57 +02:00
|
|
|
#include <utility>
|
2018-08-07 16:58:16 +02:00
|
|
|
|
2018-08-07 14:13:57 +02:00
|
|
|
#include "config.h"
|
|
|
|
|
2018-08-07 16:58:16 +02:00
|
|
|
#include "../log/log.h"
|
|
|
|
|
|
|
|
#include "../util_env.h"
|
|
|
|
|
2018-08-07 14:13:57 +02:00
|
|
|
namespace dxvk {
|
|
|
|
|
2019-08-17 11:46:56 +02:00
|
|
|
const static std::vector<std::pair<const char*, Config>> g_appDefaults = {{
|
2019-01-19 17:45:26 +01:00
|
|
|
/* Assassin's Creed Syndicate: amdags issues */
|
2019-08-24 18:38:41 +01:00
|
|
|
{ R"(\\ACS\.exe$)", {{
|
2018-09-09 13:46:57 +02:00
|
|
|
{ "dxgi.customVendorId", "10de" },
|
2018-09-12 14:10:49 +02:00
|
|
|
}} },
|
2019-03-30 21:05:39 +01:00
|
|
|
/* Dissidia Final Fantasy NT Free Edition */
|
2019-08-24 18:38:41 +01:00
|
|
|
{ R"(\\dffnt\.exe$)", {{
|
2019-03-30 21:05:39 +01:00
|
|
|
{ "dxgi.deferSurfaceCreation", "True" },
|
|
|
|
}} },
|
2019-01-19 17:45:26 +01:00
|
|
|
/* Elite Dangerous: Compiles weird shaders *
|
|
|
|
* when running on AMD hardware */
|
2019-08-24 18:38:41 +01:00
|
|
|
{ R"(\\EliteDangerous64\.exe$)", {{
|
2018-11-06 17:03:01 +01:00
|
|
|
{ "dxgi.customVendorId", "10de" },
|
|
|
|
}} },
|
2018-10-25 17:49:42 +02:00
|
|
|
/* The Vanishing of Ethan Carter Redux */
|
2019-08-24 18:38:41 +01:00
|
|
|
{ R"(\\EthanCarter-Win64-Shipping\.exe$)", {{
|
2018-10-25 17:49:42 +02:00
|
|
|
{ "dxgi.customVendorId", "10de" },
|
|
|
|
}} },
|
2019-01-19 17:45:26 +01:00
|
|
|
/* The Evil Within: Submits command lists *
|
|
|
|
* multiple times */
|
2019-08-24 18:38:41 +01:00
|
|
|
{ R"(\\EvilWithin(Demo)?\.exe$)", {{
|
2018-11-20 10:51:09 +01:00
|
|
|
{ "d3d11.dcSingleUseMode", "False" },
|
2022-03-03 23:42:11 +01:00
|
|
|
{ "d3d11.cachedDynamicResources", "vi" },
|
2018-10-09 16:29:50 +02:00
|
|
|
}} },
|
2019-02-18 18:02:39 +01:00
|
|
|
/* Far Cry 3: Assumes clear(0.5) on an UNORM *
|
|
|
|
* format to result in 128 on AMD and 127 on *
|
2019-06-12 12:32:30 +02:00
|
|
|
* Nvidia. We assume that the Vulkan drivers *
|
|
|
|
* match the clear behaviour of D3D11. */
|
2019-08-24 18:38:41 +01:00
|
|
|
{ R"(\\(farcry3|fc3_blooddragon)_d3d11\.exe$)", {{
|
2019-06-12 12:32:30 +02:00
|
|
|
{ "dxgi.nvapiHack", "False" },
|
2019-02-18 18:02:39 +01:00
|
|
|
}} },
|
|
|
|
/* Far Cry 4: Same as Far Cry 3 */
|
2019-08-24 18:38:41 +01:00
|
|
|
{ R"(\\FarCry4\.exe$)", {{
|
2019-06-12 12:32:30 +02:00
|
|
|
{ "dxgi.nvapiHack", "False" },
|
2019-02-18 18:02:39 +01:00
|
|
|
}} },
|
2019-01-19 17:45:26 +01:00
|
|
|
/* Frostpunk: Renders one frame with D3D9 *
|
|
|
|
* after creating the DXGI swap chain */
|
2019-08-24 18:38:41 +01:00
|
|
|
{ R"(\\Frostpunk\.exe$)", {{
|
2018-08-07 16:58:16 +02:00
|
|
|
{ "dxgi.deferSurfaceCreation", "True" },
|
|
|
|
}} },
|
2019-03-29 08:48:52 +01:00
|
|
|
/* Nioh: See Frostpunk, apparently? */
|
2019-08-24 18:38:41 +01:00
|
|
|
{ R"(\\nioh\.exe$)", {{
|
2019-03-29 08:48:52 +01:00
|
|
|
{ "dxgi.deferSurfaceCreation", "True" },
|
|
|
|
}} },
|
2019-01-19 17:45:26 +01:00
|
|
|
/* Quantum Break: Mever initializes shared *
|
2022-02-14 04:21:09 +01:00
|
|
|
* memory in one of its compute shaders. *
|
|
|
|
* Also loves using MAP_WRITE on the same *
|
|
|
|
* set of resources multiple times per frame. */
|
2019-08-24 18:38:41 +01:00
|
|
|
{ R"(\\QuantumBreak\.exe$)", {{
|
2018-11-23 16:12:09 +01:00
|
|
|
{ "d3d11.zeroInitWorkgroupMemory", "True" },
|
2022-02-14 04:21:09 +01:00
|
|
|
{ "d3d11.maxImplicitDiscardSize", "-1" },
|
2018-11-23 16:12:09 +01:00
|
|
|
}} },
|
2019-01-19 17:45:26 +01:00
|
|
|
/* Anno 2205: Random crashes with state cache */
|
2019-08-24 18:38:41 +01:00
|
|
|
{ R"(\\anno2205\.exe$)", {{
|
2018-11-24 20:04:21 +01:00
|
|
|
{ "dxvk.enableStateCache", "False" },
|
|
|
|
}} },
|
2022-03-03 17:33:14 +01:00
|
|
|
/* Anno 1800: Poor performance without this */
|
|
|
|
{ R"(\\Anno1800\.exe$)", {{
|
|
|
|
{ "d3d11.cachedDynamicResources", "c" },
|
|
|
|
}} },
|
2019-09-20 16:20:26 +02:00
|
|
|
/* Fifa '19+: Binds typed buffer SRV to shader *
|
2019-01-19 17:45:26 +01:00
|
|
|
* that expects raw/structured buffer SRV */
|
2019-09-20 00:48:17 +02:00
|
|
|
{ R"(\\FIFA(19|[2-9][0-9])(_demo)?\.exe$)", {{
|
2019-01-08 21:01:57 +01:00
|
|
|
{ "dxvk.useRawSsbo", "True" },
|
|
|
|
}} },
|
2020-06-11 22:05:41 +02:00
|
|
|
/* Resident Evil 2/3: Ignore WaW hazards */
|
|
|
|
{ R"(\\re(2|3|3demo)\.exe$)", {{
|
2019-02-08 01:38:03 +01:00
|
|
|
{ "d3d11.relaxedBarriers", "True" },
|
|
|
|
}} },
|
2019-03-11 18:35:39 +01:00
|
|
|
/* Devil May Cry 5 */
|
2019-08-24 18:38:41 +01:00
|
|
|
{ R"(\\DevilMayCry5\.exe$)", {{
|
2019-03-11 18:35:39 +01:00
|
|
|
{ "d3d11.relaxedBarriers", "True" },
|
|
|
|
}} },
|
2019-01-10 11:57:39 +01:00
|
|
|
/* Call of Duty WW2 */
|
2019-08-24 18:38:41 +01:00
|
|
|
{ R"(\\s2_sp64_ship\.exe$)", {{
|
2019-01-10 11:57:39 +01:00
|
|
|
{ "dxgi.nvapiHack", "False" },
|
|
|
|
}} },
|
|
|
|
/* Need for Speed 2015 */
|
2019-08-24 18:38:41 +01:00
|
|
|
{ R"(\\NFS16\.exe$)", {{
|
2019-01-10 11:57:39 +01:00
|
|
|
{ "dxgi.nvapiHack", "False" },
|
|
|
|
}} },
|
2019-01-26 18:38:58 +01:00
|
|
|
/* Mass Effect Andromeda */
|
2019-08-24 18:38:41 +01:00
|
|
|
{ R"(\\MassEffectAndromeda\.exe$)", {{
|
2019-01-26 18:38:58 +01:00
|
|
|
{ "dxgi.nvapiHack", "False" },
|
|
|
|
}} },
|
2019-05-17 11:40:35 +02:00
|
|
|
/* Mirror`s Edge Catalyst: Crashes on AMD */
|
2019-08-24 18:38:41 +01:00
|
|
|
{ R"(\\MirrorsEdgeCatalyst(Trial)?\.exe$)", {{
|
2019-05-17 11:40:35 +02:00
|
|
|
{ "dxgi.customVendorId", "10de" },
|
2019-05-07 22:19:03 +03:00
|
|
|
}} },
|
2019-03-14 16:33:35 +01:00
|
|
|
/* Star Wars Battlefront (2015) */
|
2019-08-24 18:38:41 +01:00
|
|
|
{ R"(\\starwarsbattlefront(trial)?\.exe$)", {{
|
2019-03-14 16:33:35 +01:00
|
|
|
{ "dxgi.nvapiHack", "False" },
|
|
|
|
}} },
|
2019-04-05 20:26:57 +02:00
|
|
|
/* Dark Souls Remastered */
|
2019-08-24 18:38:41 +01:00
|
|
|
{ R"(\\DarkSoulsRemastered\.exe$)", {{
|
2019-04-05 20:26:57 +02:00
|
|
|
{ "d3d11.constantBufferRangeCheck", "True" },
|
|
|
|
}} },
|
|
|
|
/* Grim Dawn */
|
2019-08-24 18:38:41 +01:00
|
|
|
{ R"(\\Grim Dawn\.exe$)", {{
|
2019-04-05 20:26:57 +02:00
|
|
|
{ "d3d11.constantBufferRangeCheck", "True" },
|
|
|
|
}} },
|
2019-04-25 09:42:45 -07:00
|
|
|
/* NieR:Automata */
|
2019-08-24 18:38:41 +01:00
|
|
|
{ R"(\\NieRAutomata\.exe$)", {{
|
2019-04-25 09:42:45 -07:00
|
|
|
{ "d3d11.constantBufferRangeCheck", "True" },
|
|
|
|
}} },
|
2021-06-09 03:48:07 +02:00
|
|
|
/* NieR Replicant */
|
|
|
|
{ R"(\\NieR Replicant ver\.1\.22474487139\.exe)", {{
|
2022-02-14 09:20:41 +01:00
|
|
|
{ "dxgi.syncInterval", "1" },
|
|
|
|
{ "dxgi.maxFrameRate", "60" },
|
2022-02-28 22:44:10 +01:00
|
|
|
{ "d3d11.cachedDynamicResources", "vi" },
|
2021-06-09 03:48:07 +02:00
|
|
|
}} },
|
2019-08-10 11:18:26 +02:00
|
|
|
/* SteamVR performance test */
|
2019-08-24 18:38:41 +01:00
|
|
|
{ R"(\\vr\.exe$)", {{
|
2019-08-10 11:18:26 +02:00
|
|
|
{ "d3d11.dcSingleUseMode", "False" },
|
|
|
|
}} },
|
2021-01-27 14:04:29 +01:00
|
|
|
/* Hitman 2 and 3 - requires AGS library */
|
|
|
|
{ R"(\\HITMAN(2|3)\.exe$)", {{
|
2019-09-26 19:27:19 +02:00
|
|
|
{ "dxgi.customVendorId", "10de" },
|
|
|
|
}} },
|
2019-10-04 18:35:36 +02:00
|
|
|
/* Modern Warfare Remastered */
|
|
|
|
{ R"(\\h1_[ms]p64_ship\.exe$)", {{
|
|
|
|
{ "dxgi.customVendorId", "10de" },
|
|
|
|
}} },
|
2019-10-20 13:27:12 +02:00
|
|
|
/* Titan Quest */
|
|
|
|
{ R"(\\TQ\.exe$)", {{
|
|
|
|
{ "d3d11.constantBufferRangeCheck", "True" },
|
|
|
|
}} },
|
2019-10-27 05:47:58 +03:00
|
|
|
/* Saints Row IV */
|
|
|
|
{ R"(\\SaintsRowIV\.exe$)", {{
|
|
|
|
{ "d3d11.constantBufferRangeCheck", "True" },
|
|
|
|
}} },
|
|
|
|
/* Saints Row: The Third */
|
|
|
|
{ R"(\\SaintsRowTheThird_DX11\.exe$)", {{
|
|
|
|
{ "d3d11.constantBufferRangeCheck", "True" },
|
|
|
|
}} },
|
2021-08-27 13:10:24 +02:00
|
|
|
/* Crysis 3 - slower if it notices AMD card *
|
|
|
|
* Apitrace mode helps massively in cpu bound *
|
|
|
|
* game parts */
|
2019-12-11 23:01:27 +01:00
|
|
|
{ R"(\\Crysis3\.exe$)", {{
|
|
|
|
{ "dxgi.customVendorId", "10de" },
|
2022-02-28 22:44:10 +01:00
|
|
|
{ "d3d11.cachedDynamicResources", "a" },
|
2019-12-11 23:01:27 +01:00
|
|
|
}} },
|
2021-10-18 18:08:43 +02:00
|
|
|
/* Crysis 3 Remastered *
|
|
|
|
* Apitrace mode helps massively in cpu bound *
|
|
|
|
* game parts */
|
|
|
|
{ R"(\\Crysis3Remastered\.exe$)", {{
|
2022-02-28 22:44:10 +01:00
|
|
|
{ "d3d11.cachedDynamicResources", "a" },
|
2021-10-18 18:08:43 +02:00
|
|
|
}} },
|
2020-01-17 18:16:29 +01:00
|
|
|
/* Atelier series - games try to render video *
|
|
|
|
* with a D3D9 swap chain over the DXGI swap *
|
|
|
|
* chain, which breaks D3D11 presentation */
|
|
|
|
{ R"(\\Atelier_(Ayesha|Escha_and_Logy|Shallie)(_EN)?\.exe$)", {{
|
|
|
|
{ "d3d9.deferSurfaceCreation", "True" },
|
|
|
|
}} },
|
2022-03-13 05:38:06 +01:00
|
|
|
/* Atelier Firis */
|
|
|
|
{ R"(\\A18\.exe$)", {{
|
|
|
|
{ "d3d9.deferSurfaceCreation", "True" },
|
|
|
|
}} },
|
2020-01-17 18:16:29 +01:00
|
|
|
/* Atelier Rorona/Totori/Meruru */
|
|
|
|
{ R"(\\A(11R|12V|13V)_x64_Release(_en)?\.exe$)", {{
|
|
|
|
{ "d3d9.deferSurfaceCreation", "True" },
|
|
|
|
}} },
|
|
|
|
/* Just how many of these games are there? */
|
2021-01-26 12:06:20 +01:00
|
|
|
{ R"(\\Atelier_(Lulua|Lydie_and_Suelle|Ryza(_2)?)\.exe$)", {{
|
2019-12-16 14:40:50 +01:00
|
|
|
{ "d3d9.deferSurfaceCreation", "True" },
|
|
|
|
}} },
|
2021-04-22 15:37:40 +02:00
|
|
|
/* ... */
|
|
|
|
{ R"(\\Atelier_(Lydie_and_Suelle|Firis|Sophie)_DX\.exe$)", {{
|
|
|
|
{ "d3d9.deferSurfaceCreation", "True" },
|
|
|
|
}} },
|
2020-08-02 20:36:15 -04:00
|
|
|
/* Fairy Tail */
|
|
|
|
{ R"(\\FAIRY_TAIL\.exe$)", {{
|
|
|
|
{ "d3d9.deferSurfaceCreation", "True" },
|
|
|
|
}} },
|
2021-04-26 09:23:12 -07:00
|
|
|
/* Nights of Azure */
|
|
|
|
{ R"(\\CNN\.exe$)", {{
|
|
|
|
{ "d3d9.deferSurfaceCreation", "True" },
|
|
|
|
}} },
|
2019-12-16 17:13:37 -08:00
|
|
|
/* Star Wars Battlefront II: amdags issues */
|
|
|
|
{ R"(\\starwarsbattlefrontii\.exe$)", {{
|
|
|
|
{ "dxgi.customVendorId", "10de" },
|
|
|
|
}} },
|
2021-01-16 15:23:52 +01:00
|
|
|
/* F1 games - do not synchronize TGSM access *
|
2020-02-07 23:27:11 +01:00
|
|
|
* in a compute shader, causing artifacts */
|
2021-01-16 15:23:52 +01:00
|
|
|
{ R"(\\F1_20(1[89]|[2-9][0-9])\.exe$)", {{
|
2020-02-07 23:27:11 +01:00
|
|
|
{ "d3d11.forceTgsmBarriers", "True" },
|
|
|
|
}} },
|
2020-04-18 13:52:38 +02:00
|
|
|
/* Blue Reflection */
|
|
|
|
{ R"(\\BLUE_REFLECTION\.exe$)", {{
|
|
|
|
{ "d3d11.constantBufferRangeCheck", "True" },
|
2020-04-18 21:14:34 +02:00
|
|
|
}} },
|
|
|
|
/* Secret World Legends */
|
|
|
|
{ R"(\\SecretWorldLegendsDX11\.exe$)", {{
|
|
|
|
{ "d3d11.constantBufferRangeCheck", "True" },
|
2020-04-18 13:52:38 +02:00
|
|
|
}} },
|
2020-08-12 23:39:53 +02:00
|
|
|
/* Darksiders Warmastered - apparently reads *
|
|
|
|
* from write-only mapped buffers */
|
|
|
|
{ R"(\\darksiders1\.exe$)", {{
|
2022-02-28 22:44:10 +01:00
|
|
|
{ "d3d11.cachedDynamicResources", "a" },
|
2020-08-12 23:39:53 +02:00
|
|
|
}} },
|
2020-08-13 18:52:45 +02:00
|
|
|
/* Monster Hunter World */
|
|
|
|
{ R"(\\MonsterHunterWorld\.exe$)", {{
|
2022-02-28 22:44:10 +01:00
|
|
|
{ "d3d11.cachedDynamicResources", "a" },
|
2021-01-28 20:09:10 +01:00
|
|
|
}} },
|
2021-04-16 11:49:43 +10:00
|
|
|
/* Kingdome Come: Deliverance */
|
|
|
|
{ R"(\\KingdomCome\.exe$)", {{
|
2022-02-28 22:44:10 +01:00
|
|
|
{ "d3d11.cachedDynamicResources", "a" },
|
2021-04-16 11:49:43 +10:00
|
|
|
}} },
|
2021-08-14 02:24:14 -07:00
|
|
|
/* Homefront: The Revolution */
|
|
|
|
{ R"(\\Homefront2_Release\.exe$)", {{
|
2022-02-28 22:44:10 +01:00
|
|
|
{ "d3d11.cachedDynamicResources", "a" },
|
2021-08-14 02:24:14 -07:00
|
|
|
}} },
|
2021-04-16 11:49:43 +10:00
|
|
|
/* Sniper Ghost Warrior Contracts */
|
|
|
|
{ R"(\\SGWContracts\.exe$)", {{
|
2022-02-28 22:44:10 +01:00
|
|
|
{ "d3d11.cachedDynamicResources", "a" },
|
2021-04-16 11:49:43 +10:00
|
|
|
}} },
|
2021-01-28 20:09:10 +01:00
|
|
|
/* Shadow of the Tomb Raider - invariant *
|
|
|
|
* position breaks character rendering on NV */
|
|
|
|
{ R"(\\SOTTR\.exe$)", {{
|
|
|
|
{ "d3d11.invariantPosition", "False" },
|
2021-01-28 20:32:38 +01:00
|
|
|
{ "d3d11.floatControls", "False" },
|
2020-08-13 18:52:45 +02:00
|
|
|
}} },
|
2021-02-06 07:48:52 +00:00
|
|
|
/* Nioh 2 */
|
|
|
|
{ R"(\\nioh2\.exe$)", {{
|
|
|
|
{ "dxgi.deferSurfaceCreation", "True" },
|
|
|
|
}} },
|
2021-02-14 02:12:15 +01:00
|
|
|
/* DIRT 5 - uses amd_ags_x64.dll when it *
|
|
|
|
* detects an AMD GPU */
|
|
|
|
{ R"(\\DIRT5\.exe$)", {{
|
|
|
|
{ "dxgi.customVendorId", "10de" },
|
|
|
|
}} },
|
2021-05-11 23:35:33 +01:00
|
|
|
/* Crazy Machines 3 - crashes on long device *
|
|
|
|
* descriptions */
|
|
|
|
{ R"(\\cm3\.exe$)", {{
|
|
|
|
{ "dxgi.customDeviceDesc", "DXVK Adapter" },
|
|
|
|
}} },
|
2021-07-02 04:42:02 +02:00
|
|
|
/* World of Final Fantasy: Broken and useless *
|
|
|
|
* use of 4x MSAA throughout the renderer */
|
|
|
|
{ R"(\\WOFF\.exe$)", {{
|
|
|
|
{ "d3d11.disableMsaa", "True" },
|
|
|
|
}} },
|
2021-11-02 00:17:35 +01:00
|
|
|
/* Final Fantasy XIV - Stuttering on NV */
|
|
|
|
{ R"(\\ffxiv_dx11\.exe$)", {{
|
|
|
|
{ "dxvk.shrinkNvidiaHvvHeap", "True" },
|
2022-02-28 23:33:01 +01:00
|
|
|
{ "d3d11.cachedDynamicResources", "vi" },
|
2021-11-02 00:17:35 +01:00
|
|
|
}} },
|
2022-01-14 15:21:49 +01:00
|
|
|
/* God of War - relies on NVAPI/AMDAGS for *
|
|
|
|
* barrier stuff, needs nvapi for DLSS */
|
2022-01-14 13:16:06 +01:00
|
|
|
{ R"(\\GoW\.exe$)", {{
|
|
|
|
{ "d3d11.ignoreGraphicsBarriers", "True" },
|
|
|
|
{ "d3d11.relaxedBarriers", "True" },
|
2022-01-14 15:21:49 +01:00
|
|
|
{ "dxgi.nvapiHack", "False" },
|
2022-03-24 03:01:29 +01:00
|
|
|
{ "dxgi.maxFrameLatency", "1" },
|
2022-01-14 13:16:06 +01:00
|
|
|
}} },
|
2022-02-11 18:15:46 +01:00
|
|
|
/* AoE 2 DE - runs poorly for some users */
|
|
|
|
{ R"(\\AoE2DE_s\.exe$)", {{
|
2022-02-28 22:44:10 +01:00
|
|
|
{ "d3d11.cachedDynamicResources", "a" },
|
2022-02-11 18:15:46 +01:00
|
|
|
}} },
|
2022-02-22 05:30:19 +01:00
|
|
|
/* Total War: Warhammer III */
|
|
|
|
{ R"(\\Warhammer3\.exe$)", {{
|
|
|
|
{ "d3d11.maxDynamicImageBufferSize", "4096" },
|
|
|
|
}} },
|
2022-03-19 20:11:47 +01:00
|
|
|
/* Assassin's Creed 3 and 4 */
|
|
|
|
{ R"(\\ac(3|4bf)[sm]p\.exe$)", {{
|
|
|
|
{ "d3d11.cachedDynamicResources", "a" },
|
|
|
|
}} },
|
2019-12-16 03:28:01 +00:00
|
|
|
|
|
|
|
/**********************************************/
|
|
|
|
/* D3D9 GAMES */
|
|
|
|
/**********************************************/
|
|
|
|
|
|
|
|
/* A Hat in Time */
|
|
|
|
{ R"(\\HatinTimeGame\.exe$)", {{
|
2020-01-28 18:27:25 +01:00
|
|
|
{ "d3d9.strictPow", "False" },
|
2019-12-16 03:28:01 +00:00
|
|
|
{ "d3d9.lenientClear", "True" },
|
|
|
|
}} },
|
2020-07-25 02:31:46 +02:00
|
|
|
/* Anarchy Online */
|
|
|
|
{ R"(\\anarchyonline\.exe$)", {{
|
|
|
|
{ "d3d9.memoryTrackTest", "True" },
|
|
|
|
}} },
|
2020-06-28 16:07:54 +02:00
|
|
|
/* Borderlands 2 and The Pre Sequel! */
|
|
|
|
{ R"(\\Borderlands(2|PreSequel)\.exe$)", {{
|
2019-12-16 03:28:01 +00:00
|
|
|
{ "d3d9.lenientClear", "True" },
|
2020-06-28 16:07:54 +02:00
|
|
|
{ "d3d9.supportDFFormats", "False" },
|
2019-12-16 03:28:01 +00:00
|
|
|
}} },
|
|
|
|
/* Borderlands */
|
|
|
|
{ R"(\\Borderlands\.exe$)", {{
|
|
|
|
{ "d3d9.lenientClear", "True" },
|
|
|
|
}} },
|
|
|
|
/* Gothic 3 */
|
2020-01-25 12:04:24 +01:00
|
|
|
{ R"(\\Gothic(3|3Final| III Forsaken Gods)\.exe$)", {{
|
2020-01-24 13:45:13 +01:00
|
|
|
{ "d3d9.supportDFFormats", "False" },
|
2019-12-16 03:28:01 +00:00
|
|
|
}} },
|
|
|
|
/* Risen */
|
2020-01-25 12:05:47 +01:00
|
|
|
{ R"(\\Risen[23]?\.exe$)", {{
|
2019-12-16 03:28:01 +00:00
|
|
|
{ "d3d9.invariantPosition", "True" },
|
|
|
|
}} },
|
|
|
|
/* Sonic Adventure 2 */
|
|
|
|
{ R"(\\Sonic Adventure 2\\(launcher|sonic2app)\.exe$)", {{
|
|
|
|
{ "d3d9.floatEmulation", "False" },
|
|
|
|
}} },
|
|
|
|
/* The Sims 2,
|
|
|
|
Body Shop,
|
|
|
|
The Sims Life Stories,
|
|
|
|
The Sims Pet Stories,
|
|
|
|
and The Sims Castaway Stories */
|
|
|
|
{ R"(\\(Sims2.*|TS2BodyShop|SimsLS|SimsPS|SimsCS)\.exe$)", {{
|
|
|
|
{ "d3d9.customVendorId", "10de" },
|
|
|
|
{ "d3d9.customDeviceId", "0091" },
|
|
|
|
{ "d3d9.customDeviceDesc", "GeForce 7800 GTX" },
|
|
|
|
{ "d3d9.disableA8RT", "True" },
|
|
|
|
{ "d3d9.supportX4R4G4B4", "False" },
|
|
|
|
{ "d3d9.maxAvailableMemory", "2048" },
|
|
|
|
{ "d3d9.memoryTrackTest", "True" },
|
|
|
|
}} },
|
|
|
|
/* Dead Space uses the a NULL render target instead
|
|
|
|
of a 1x1 one if DF24 is NOT supported */
|
|
|
|
{ R"(\\Dead Space\.exe$)", {{
|
|
|
|
{ "d3d9.supportDFFormats", "False" },
|
|
|
|
}} },
|
|
|
|
/* Halo 2 */
|
|
|
|
{ R"(\\halo2\.exe$)", {{
|
|
|
|
{ "d3d9.invariantPosition", "True" },
|
|
|
|
}} },
|
|
|
|
/* Halo CE/HaloPC */
|
|
|
|
{ R"(\\halo(ce)?\.exe$)", {{
|
2020-05-17 19:58:15 +02:00
|
|
|
{ "d3d9.invariantPosition", "True" },
|
2019-12-16 03:28:01 +00:00
|
|
|
// Game enables minor decal layering fixes
|
|
|
|
// specifically when it detects AMD.
|
|
|
|
// Avoids chip being detected as unsupported
|
|
|
|
// when on intel. Avoids possible path towards
|
|
|
|
// invalid texture addressing methods.
|
|
|
|
{ "d3d9.customVendorId", "1002" },
|
|
|
|
// Avoids card not recognized error.
|
|
|
|
// Keeps game's rendering methods consistent
|
|
|
|
// for optimal compatibility.
|
|
|
|
{ "d3d9.customDeviceId", "4172" },
|
2020-01-01 20:58:42 +00:00
|
|
|
// The game uses incorrect sampler types in
|
|
|
|
// the shaders for glass rendering which
|
|
|
|
// breaks it on native + us if we don't
|
|
|
|
// spec-constantly chose the sampler type
|
|
|
|
// automagically.
|
|
|
|
{ "d3d9.forceSamplerTypeSpecConstants", "True" },
|
2019-12-16 03:28:01 +00:00
|
|
|
}} },
|
|
|
|
/* Counter Strike: Global Offensive
|
|
|
|
Needs NVAPI to avoid a forced AO + Smoke
|
|
|
|
exploit so we must force AMD vendor ID. */
|
|
|
|
{ R"(\\csgo\.exe$)", {{
|
|
|
|
{ "d3d9.customVendorId", "1002" },
|
|
|
|
}} },
|
|
|
|
/* Vampire - The Masquerade Bloodlines */
|
|
|
|
{ R"(\\vampire\.exe$)", {{
|
|
|
|
{ "d3d9.deferSurfaceCreation", "True" },
|
|
|
|
{ "d3d9.memoryTrackTest", "True" },
|
|
|
|
{ "d3d9.maxAvailableMemory", "1024" },
|
|
|
|
}} },
|
|
|
|
/* Senran Kagura Shinovi Versus */
|
|
|
|
{ R"(\\SKShinoviVersus\.exe$)", {{
|
|
|
|
{ "d3d9.forceAspectRatio", "16:9" },
|
|
|
|
}} },
|
|
|
|
/* Metal Slug X */
|
|
|
|
{ R"(\\mslugx\.exe$)", {{
|
|
|
|
{ "d3d9.supportD32", "False" },
|
|
|
|
}} },
|
2020-01-22 16:20:42 +00:00
|
|
|
/* Skyrim (NVAPI) */
|
|
|
|
{ R"(\\TESV\.exe$)", {{
|
|
|
|
{ "d3d9.customVendorId", "1002" },
|
|
|
|
}} },
|
2020-01-24 05:44:20 +00:00
|
|
|
/* RTHDRIBL Demo
|
|
|
|
Uses DONOTWAIT after GetRenderTargetData
|
|
|
|
then goes into an infinite loop if it gets
|
|
|
|
D3DERR_WASSTILLDRAWING.
|
|
|
|
This is a better solution than penalizing
|
|
|
|
other apps that use this properly. */
|
|
|
|
{ R"(\\rthdribl\.exe$)", {{
|
|
|
|
{ "d3d9.allowDoNotWait", "False" },
|
|
|
|
}} },
|
2020-02-13 20:00:22 -05:00
|
|
|
/* Hyperdimension Neptunia U: Action Unleashed */
|
|
|
|
{ R"(\\Neptunia\.exe$)", {{
|
|
|
|
{ "d3d9.forceAspectRatio", "16:9" },
|
|
|
|
}} },
|
2020-02-18 17:01:41 +00:00
|
|
|
/* D&D - The Temple Of Elemental Evil */
|
|
|
|
{ R"(\\ToEE\.exe$)", {{
|
|
|
|
{ "d3d9.allowDiscard", "False" },
|
|
|
|
}} },
|
2020-02-11 13:26:35 +01:00
|
|
|
/* ZUSI 3 - Aerosoft Edition */
|
|
|
|
{ R"(\\ZusiSim\.exe$)", {{
|
|
|
|
{ "d3d9.noExplicitFrontBuffer", "True" },
|
|
|
|
}} },
|
2020-03-28 11:52:05 +01:00
|
|
|
/* GTA IV (NVAPI) */
|
2021-07-20 20:07:06 +02:00
|
|
|
/* Also thinks we're always on Intel *
|
|
|
|
* and will report/use bad amounts of VRAM. */
|
2020-03-28 11:52:05 +01:00
|
|
|
{ R"(\\GTAIV\.exe$)", {{
|
|
|
|
{ "d3d9.customVendorId", "1002" },
|
2021-07-20 20:07:06 +02:00
|
|
|
{ "dxgi.emulateUMA", "True" },
|
2020-03-28 11:52:05 +01:00
|
|
|
}} },
|
2020-04-08 23:23:21 +01:00
|
|
|
/* Battlefield 2 (bad z-pass) */
|
|
|
|
{ R"(\\BF2\.exe$)", {{
|
|
|
|
{ "d3d9.longMad", "True" },
|
2020-04-09 14:00:26 +01:00
|
|
|
{ "d3d9.invariantPosition", "True" },
|
2020-04-08 23:23:21 +01:00
|
|
|
}} },
|
2020-06-05 02:36:17 +01:00
|
|
|
/* SpellForce 2 Series */
|
|
|
|
{ R"(\\SpellForce2.*\.exe$)", {{
|
2020-05-27 17:14:12 +01:00
|
|
|
{ "d3d9.forceSamplerTypeSpecConstants", "True" },
|
|
|
|
}} },
|
2020-11-26 12:16:33 +00:00
|
|
|
/* Everquest 2 */
|
2020-11-27 06:27:01 +00:00
|
|
|
{ R"(\\EverQuest2.*\.exe$)", {{
|
2020-11-26 12:16:33 +00:00
|
|
|
{ "d3d9.alphaTestWiggleRoom", "True" },
|
|
|
|
}} },
|
2020-12-14 17:40:39 +01:00
|
|
|
/* Tomb Raider: Legend */
|
|
|
|
{ R"(\\trl\.exe$)", {{
|
|
|
|
{ "d3d9.apitraceMode", "True" },
|
|
|
|
}} },
|
2020-12-24 13:41:42 +01:00
|
|
|
/* Everquest */
|
|
|
|
{ R"(\\eqgame\.exe$)", {{
|
|
|
|
{ "d3d9.apitraceMode", "True" },
|
|
|
|
}} },
|
2021-01-30 04:36:26 +00:00
|
|
|
/* Dark Messiah of Might & Magic */
|
|
|
|
{ R"(\\mm\.exe$)", {{
|
|
|
|
{ "d3d9.deferSurfaceCreation", "True" },
|
|
|
|
{ "d3d9.memoryTrackTest", "True" },
|
|
|
|
}} },
|
2021-02-25 15:09:00 +00:00
|
|
|
/* Mafia 2 */
|
|
|
|
{ R"(\\mafia2\.exe$)", {{
|
|
|
|
{ "d3d9.customVendorId", "10de" },
|
|
|
|
{ "d3d9.customDeviceId", "0402" },
|
|
|
|
}} },
|
2021-02-27 20:31:13 +00:00
|
|
|
/* Warhammer: Online */
|
|
|
|
{ R"(\\WAR(-64)?\.exe$)", {{
|
2021-02-28 09:54:33 +00:00
|
|
|
{ "d3d9.customVendorId", "1002" },
|
2021-02-27 20:31:13 +00:00
|
|
|
}} },
|
2021-04-04 13:32:59 +02:00
|
|
|
/* Dragon Nest */
|
|
|
|
{ R"(\\DragonNest_x64\.exe$)", {{
|
|
|
|
{ "d3d9.memoryTrackTest ", "True" },
|
|
|
|
}} },
|
2021-04-22 12:54:26 +02:00
|
|
|
/* Dal Segno */
|
|
|
|
{ R"(\\DST\.exe$)", {{
|
|
|
|
{ "d3d9.deferSurfaceCreation", "True" },
|
|
|
|
}} },
|
2021-04-30 18:49:39 +01:00
|
|
|
/* Kohan II */
|
|
|
|
{ R"(\\k2\.exe$)", {{
|
|
|
|
{ "d3d9.memoryTrackTest", "True" },
|
|
|
|
}} },
|
2021-06-10 01:38:58 -06:00
|
|
|
/* Ninja Gaiden Sigma 1/2 */
|
|
|
|
{ R"(\\NINJA GAIDEN SIGMA(2)?\.exe$)", {{
|
|
|
|
{ "d3d9.deferSurfaceCreation", "True" },
|
|
|
|
}} },
|
2021-06-15 11:49:03 +02:00
|
|
|
/* Demon Stone breaks at frame rates > 60fps */
|
|
|
|
{ R"(\\Demonstone\.exe$)", {{
|
|
|
|
{ "d3d9.maxFrameRate", "60" },
|
|
|
|
}} },
|
2021-06-19 18:26:56 +02:00
|
|
|
/* Far Cry 1 has worse water rendering when it detects AMD GPUs */
|
|
|
|
{ R"(\\FarCry\.exe$)", {{
|
|
|
|
{ "d3d9.customVendorId", "10de" },
|
|
|
|
}} },
|
2021-06-28 18:30:03 +02:00
|
|
|
/* Earth Defense Force 5 */
|
|
|
|
{ R"(\\EDF5\.exe$)", {{
|
|
|
|
{ "dxgi.tearFree", "False" },
|
|
|
|
{ "dxgi.syncInterval", "1" },
|
|
|
|
}} },
|
2021-08-24 17:22:38 +02:00
|
|
|
/* Sine Mora EX */
|
|
|
|
{ R"(\\SineMoraEX\.exe$)", {{
|
|
|
|
{ "d3d9.maxFrameRate", "60" },
|
|
|
|
}} },
|
2021-08-20 19:04:47 +02:00
|
|
|
/* Fantasy Grounds */
|
|
|
|
{ R"(\\FantasyGrounds\.exe$)", {{
|
|
|
|
{ "d3d9.noExplicitFrontBuffer", "True" },
|
|
|
|
}} },
|
2021-11-12 15:26:22 +01:00
|
|
|
/* Red Orchestra 2 */
|
|
|
|
{ R"(\\ROGame\.exe$)", {{
|
|
|
|
{ "d3d9.floatEmulation", "Strict" },
|
|
|
|
}} },
|
|
|
|
/* Dark Souls II */
|
|
|
|
{ R"(\\DarkSoulsII\.exe$)", {{
|
|
|
|
{ "d3d9.floatEmulation", "Strict" },
|
|
|
|
}} },
|
|
|
|
/* Dogfight 1942 */
|
|
|
|
{ R"(\\Dogfight1942\.exe$)", {{
|
|
|
|
{ "d3d9.floatEmulation", "Strict" },
|
|
|
|
}} },
|
|
|
|
/* Bayonetta */
|
|
|
|
{ R"(\\Bayonetta\.exe$)", {{
|
|
|
|
{ "d3d9.floatEmulation", "Strict" },
|
|
|
|
}} },
|
|
|
|
/* Rayman Origins */
|
|
|
|
{ R"(\\Rayman Origins\.exe$)", {{
|
|
|
|
{ "d3d9.floatEmulation", "Strict" },
|
|
|
|
}} },
|
|
|
|
/* Guilty Gear Xrd -Relevator- */
|
|
|
|
{ R"(\\GuiltyGearXrd\.exe$)", {{
|
|
|
|
{ "d3d9.floatEmulation", "Strict" },
|
|
|
|
}} },
|
|
|
|
/* Richard Burns Rally */
|
|
|
|
{ R"(\\RichardBurnsRally_SSE\.exe$)", {{
|
|
|
|
{ "d3d9.floatEmulation", "Strict" },
|
|
|
|
}} },
|
2021-12-09 13:23:50 -05:00
|
|
|
/* BlazBlue Centralfiction */
|
|
|
|
{ R"(\\BBCF\.exe$)", {{
|
|
|
|
{ "d3d9.floatEmulation", "Strict" },
|
|
|
|
}} },
|
2021-12-31 19:21:28 +01:00
|
|
|
/* James Cameron's Avatar needs invariantPosition to fix black flickering vegetation */
|
|
|
|
{ R"(\\Avatar\.exe$)", {{
|
|
|
|
{ "d3d9.invariantPosition", "True" },
|
|
|
|
}} },
|
2022-01-28 23:05:06 +01:00
|
|
|
/* Resident Evil games */
|
|
|
|
{ R"(\\(rerev|rerev2|re0hd|bhd|re5dx9|BH6)\.exe$)", {{
|
|
|
|
{ "d3d9.allowDirectBufferMapping", "False" },
|
|
|
|
}} },
|
2018-08-07 16:58:16 +02:00
|
|
|
}};
|
|
|
|
|
|
|
|
|
|
|
|
static bool isWhitespace(char ch) {
|
|
|
|
return ch == ' ' || ch == '\x9' || ch == '\r';
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static bool isValidKeyChar(char ch) {
|
|
|
|
return (ch >= '0' && ch <= '9')
|
|
|
|
|| (ch >= 'A' && ch <= 'Z')
|
|
|
|
|| (ch >= 'a' && ch <= 'z')
|
|
|
|
|| (ch == '.' || ch == '_');
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static size_t skipWhitespace(const std::string& line, size_t n) {
|
|
|
|
while (n < line.size() && isWhitespace(line[n]))
|
|
|
|
n += 1;
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-04-26 19:17:32 +02:00
|
|
|
struct ConfigContext {
|
|
|
|
bool active;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static void parseUserConfigLine(Config& config, ConfigContext& ctx, const std::string& line) {
|
2018-08-07 16:58:16 +02:00
|
|
|
std::stringstream key;
|
|
|
|
std::stringstream value;
|
|
|
|
|
|
|
|
// Extract the key
|
|
|
|
size_t n = skipWhitespace(line, 0);
|
2019-04-26 19:17:32 +02:00
|
|
|
|
|
|
|
if (n < line.size() && line[n] == '[') {
|
|
|
|
n += 1;
|
|
|
|
|
|
|
|
size_t e = line.size() - 1;
|
|
|
|
while (e > n && line[e] != ']')
|
|
|
|
e -= 1;
|
|
|
|
|
|
|
|
while (n < e)
|
|
|
|
key << line[n++];
|
|
|
|
|
|
|
|
ctx.active = key.str() == env::getExeName();
|
|
|
|
} else {
|
|
|
|
while (n < line.size() && isValidKeyChar(line[n]))
|
|
|
|
key << line[n++];
|
|
|
|
|
|
|
|
// Check whether the next char is a '='
|
|
|
|
n = skipWhitespace(line, n);
|
|
|
|
if (n >= line.size() || line[n] != '=')
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Extract the value
|
2020-04-10 21:15:36 +02:00
|
|
|
bool insideString = false;
|
2019-04-26 19:17:32 +02:00
|
|
|
n = skipWhitespace(line, n + 1);
|
2020-04-10 21:15:36 +02:00
|
|
|
|
|
|
|
while (n < line.size()) {
|
|
|
|
if (!insideString && isWhitespace(line[n]))
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (line[n] == '"') {
|
|
|
|
insideString = !insideString;
|
|
|
|
n++;
|
|
|
|
} else
|
|
|
|
value << line[n++];
|
|
|
|
}
|
2019-04-26 19:17:32 +02:00
|
|
|
|
|
|
|
if (ctx.active)
|
|
|
|
config.setOption(key.str(), value.str());
|
|
|
|
}
|
2018-08-07 16:58:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-08-07 14:13:57 +02:00
|
|
|
Config::Config() { }
|
|
|
|
Config::~Config() { }
|
|
|
|
|
|
|
|
|
|
|
|
Config::Config(OptionMap&& options)
|
|
|
|
: m_options(std::move(options)) { }
|
|
|
|
|
|
|
|
|
|
|
|
void Config::merge(const Config& other) {
|
|
|
|
for (auto& pair : other.m_options)
|
|
|
|
m_options.insert(pair);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Config::setOption(const std::string& key, const std::string& value) {
|
|
|
|
m_options.insert_or_assign(key, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::string Config::getOptionValue(const char* option) const {
|
|
|
|
auto iter = m_options.find(option);
|
|
|
|
|
|
|
|
return iter != m_options.end()
|
|
|
|
? iter->second : std::string();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Config::parseOptionValue(
|
|
|
|
const std::string& value,
|
|
|
|
std::string& result) {
|
|
|
|
result = value;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Config::parseOptionValue(
|
|
|
|
const std::string& value,
|
|
|
|
bool& result) {
|
2021-09-19 16:20:57 +02:00
|
|
|
static const std::array<std::pair<const char*, bool>, 2> s_lookup = {{
|
|
|
|
{ "true", true },
|
|
|
|
{ "false", false },
|
|
|
|
}};
|
|
|
|
|
|
|
|
return parseStringOption(value,
|
|
|
|
s_lookup.begin(), s_lookup.end(), result);
|
2018-08-07 14:13:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Config::parseOptionValue(
|
|
|
|
const std::string& value,
|
|
|
|
int32_t& result) {
|
|
|
|
if (value.size() == 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Parse sign, don't allow '+'
|
|
|
|
int32_t sign = 1;
|
|
|
|
size_t start = 0;
|
|
|
|
|
|
|
|
if (value[0] == '-') {
|
|
|
|
sign = -1;
|
|
|
|
start = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Parse absolute number
|
|
|
|
int32_t intval = 0;
|
|
|
|
|
|
|
|
for (size_t i = start; i < value.size(); i++) {
|
|
|
|
if (value[i] < '0' || value[i] > '9')
|
|
|
|
return false;
|
|
|
|
|
|
|
|
intval *= 10;
|
|
|
|
intval += value[i] - '0';
|
|
|
|
}
|
|
|
|
|
|
|
|
// Apply sign and return
|
|
|
|
result = sign * intval;
|
|
|
|
return true;
|
|
|
|
}
|
2019-01-08 20:57:38 +01:00
|
|
|
|
|
|
|
|
|
|
|
bool Config::parseOptionValue(
|
|
|
|
const std::string& value,
|
|
|
|
Tristate& result) {
|
2021-09-19 16:20:57 +02:00
|
|
|
static const std::array<std::pair<const char*, Tristate>, 3> s_lookup = {{
|
|
|
|
{ "true", Tristate::True },
|
|
|
|
{ "false", Tristate::False },
|
|
|
|
{ "auto", Tristate::Auto },
|
|
|
|
}};
|
|
|
|
|
|
|
|
return parseStringOption(value,
|
|
|
|
s_lookup.begin(), s_lookup.end(), result);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename I, typename V>
|
|
|
|
bool Config::parseStringOption(
|
|
|
|
std::string str,
|
|
|
|
I begin,
|
|
|
|
I end,
|
|
|
|
V& value) {
|
2021-11-12 15:13:11 +01:00
|
|
|
str = Config::toLower(str);
|
2021-09-19 16:20:57 +02:00
|
|
|
|
|
|
|
for (auto i = begin; i != end; i++) {
|
|
|
|
if (str == i->first) {
|
|
|
|
value = i->second;
|
|
|
|
return true;
|
|
|
|
}
|
2019-01-08 20:57:38 +01:00
|
|
|
}
|
2021-09-19 16:20:57 +02:00
|
|
|
|
|
|
|
return false;
|
2019-01-08 20:57:38 +01:00
|
|
|
}
|
2018-08-07 14:13:57 +02:00
|
|
|
|
2018-08-07 16:58:16 +02:00
|
|
|
|
|
|
|
Config Config::getAppConfig(const std::string& appName) {
|
2019-08-17 11:46:56 +02:00
|
|
|
auto appConfig = std::find_if(g_appDefaults.begin(), g_appDefaults.end(),
|
|
|
|
[&appName] (const std::pair<const char*, Config>& pair) {
|
|
|
|
std::regex expr(pair.first, std::regex::extended | std::regex::icase);
|
|
|
|
return std::regex_search(appName, expr);
|
|
|
|
});
|
|
|
|
|
2018-09-09 13:46:57 +02:00
|
|
|
if (appConfig != g_appDefaults.end()) {
|
|
|
|
// Inform the user that we loaded a default config
|
2019-08-17 11:46:56 +02:00
|
|
|
Logger::info(str::format("Found built-in config:"));
|
2018-08-07 16:58:16 +02:00
|
|
|
return appConfig->second;
|
2018-09-09 13:46:57 +02:00
|
|
|
}
|
|
|
|
|
2018-08-07 16:58:16 +02:00
|
|
|
return Config();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Config Config::getUserConfig() {
|
|
|
|
Config config;
|
|
|
|
|
|
|
|
// Load either $DXVK_CONFIG_FILE or $PWD/dxvk.conf
|
2018-11-15 17:12:09 -05:00
|
|
|
std::string filePath = env::getEnvVar("DXVK_CONFIG_FILE");
|
2018-08-07 16:58:16 +02:00
|
|
|
|
|
|
|
if (filePath == "")
|
|
|
|
filePath = "dxvk.conf";
|
|
|
|
|
|
|
|
// Open the file if it exists
|
2020-09-10 12:02:53 +09:00
|
|
|
std::ifstream stream(str::tows(filePath.c_str()).c_str());
|
2018-08-07 16:58:16 +02:00
|
|
|
|
|
|
|
if (!stream)
|
|
|
|
return config;
|
2018-08-17 19:42:32 +02:00
|
|
|
|
|
|
|
// Inform the user that we loaded a file, might
|
|
|
|
// help when debugging configuration issues
|
|
|
|
Logger::info(str::format("Found config file: ", filePath));
|
2018-08-07 16:58:16 +02:00
|
|
|
|
2019-04-26 19:17:32 +02:00
|
|
|
// Initialize parser context
|
|
|
|
ConfigContext ctx;
|
|
|
|
ctx.active = true;
|
|
|
|
|
2018-08-07 16:58:16 +02:00
|
|
|
// Parse the file line by line
|
|
|
|
std::string line;
|
|
|
|
|
|
|
|
while (std::getline(stream, line))
|
2019-04-26 19:17:32 +02:00
|
|
|
parseUserConfigLine(config, ctx, line);
|
2018-08-07 16:58:16 +02:00
|
|
|
|
|
|
|
return config;
|
|
|
|
}
|
|
|
|
|
2018-09-09 13:46:57 +02:00
|
|
|
|
|
|
|
void Config::logOptions() const {
|
|
|
|
if (!m_options.empty()) {
|
|
|
|
Logger::info("Effective configuration:");
|
|
|
|
|
|
|
|
for (auto& pair : m_options)
|
|
|
|
Logger::info(str::format(" ", pair.first, " = ", pair.second));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-12 15:13:11 +01:00
|
|
|
std::string Config::toLower(std::string str) {
|
|
|
|
std::transform(str.begin(), str.end(), str.begin(),
|
|
|
|
[] (unsigned char c) { return (c >= 'A' && c <= 'Z') ? (c + 'a' - 'A') : c; });
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2018-09-08 12:46:21 +02:00
|
|
|
}
|