mirror of https://github.com/PCSX2/pcsx2.git
GameDatabase: Add ability to override GS fixes
This commit is contained in:
parent
d35db63d73
commit
96269db93e
|
@ -141,8 +141,8 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
|
|||
// HW Renderer Fixes
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.halfScreenFix, "EmuCore/GS", "UserHacks_Half_Bottom_Override", -1, -1);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.skipDrawRangeStart, "EmuCore/GS", "UserHacks_SkipDraw", 0);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.skipDrawRangeCount, "EmuCore/GS", "UserHacks_SkipDraw_Offset", 0);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.skipDrawStart, "EmuCore/GS", "UserHacks_SkipDraw_Offset", 0);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.skipDrawEnd, "EmuCore/GS", "UserHacks_SkipDraw", 0);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.hwAutoFlush, "EmuCore/GS", "UserHacks_AutoFlush", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.frameBufferConversion, "EmuCore/GS", "UserHacks_CPU_FB_Conversion", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableDepthEmulation, "EmuCore/GS", "UserHacks_DisableDepthSupport", false);
|
||||
|
|
|
@ -586,7 +586,7 @@
|
|||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="enableHWFixes">
|
||||
<property name="text">
|
||||
<string>Enable Hardware Renderer Fixes</string>
|
||||
<string>Manual Hardware Renderer Fixes</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -661,10 +661,10 @@
|
|||
<item row="1" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QSpinBox" name="skipDrawRangeStart"/>
|
||||
<widget class="QSpinBox" name="skipDrawStart"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="skipDrawRangeCount"/>
|
||||
<widget class="QSpinBox" name="skipDrawEnd"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
|
|
|
@ -442,7 +442,7 @@ struct Pcsx2Config
|
|||
WrapGSMem : 1,
|
||||
Mipmap : 1,
|
||||
AA1 : 1,
|
||||
UserHacks : 1,
|
||||
ManualUserHacks : 1,
|
||||
UserHacks_AlignSpriteX : 1,
|
||||
UserHacks_AutoFlush : 1,
|
||||
UserHacks_CPUFBConversion : 1,
|
||||
|
@ -510,8 +510,8 @@ struct Pcsx2Config
|
|||
int SWExtraThreads{2};
|
||||
int SWExtraThreadsHeight{4};
|
||||
int TVShader{0};
|
||||
int SkipDraw{0};
|
||||
int SkipDrawOffset{0};
|
||||
int SkipDrawStart{0};
|
||||
int SkipDrawEnd{0};
|
||||
|
||||
int UserHacks_HalfBottomOverride{-1};
|
||||
int UserHacks_HalfPixelOffset{0};
|
||||
|
|
|
@ -310,8 +310,6 @@ bool GSopen(const Pcsx2Config::GSOptions& config, GSRendererType renderer, u8* b
|
|||
|
||||
GSConfig = config;
|
||||
GSConfig.Renderer = renderer;
|
||||
GSConfig.MaskUserHacks();
|
||||
GSConfig.MaskUpscalingHacks();
|
||||
|
||||
if (!Host::AcquireHostDisplay(GetAPIForRenderer(renderer)))
|
||||
{
|
||||
|
@ -724,8 +722,6 @@ void GSUpdateConfig(const Pcsx2Config::GSOptions& new_config)
|
|||
Pcsx2Config::GSOptions old_config(std::move(GSConfig));
|
||||
GSConfig = new_config;
|
||||
GSConfig.Renderer = (GSConfig.Renderer == GSRendererType::Auto) ? GSUtil::GetPreferredRenderer() : GSConfig.Renderer;
|
||||
GSConfig.MaskUserHacks();
|
||||
GSConfig.MaskUpscalingHacks();
|
||||
if (!s_gs)
|
||||
return;
|
||||
|
||||
|
|
|
@ -1053,7 +1053,7 @@ bool GSState::IsBadFrame()
|
|||
return false;
|
||||
}
|
||||
|
||||
if (m_skip == 0 && GSConfig.SkipDraw > 0)
|
||||
if (m_skip == 0 && GSConfig.SkipDrawEnd > 0)
|
||||
{
|
||||
if (fi.TME)
|
||||
{
|
||||
|
@ -1061,8 +1061,8 @@ bool GSState::IsBadFrame()
|
|||
// General, often problematic post processing
|
||||
if (GSLocalMemory::m_psm[fi.TPSM].depth || GSUtil::HasSharedBits(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM))
|
||||
{
|
||||
m_skip_offset = GSConfig.SkipDrawOffset;
|
||||
m_skip = std::max(GSConfig.SkipDraw, m_skip_offset);
|
||||
m_skip_offset = GSConfig.SkipDrawStart;
|
||||
m_skip = GSConfig.SkipDrawEnd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -328,7 +328,7 @@ HacksTab::HacksTab(wxWindow* parent)
|
|||
PaddedBoxSizer<wxBoxSizer> tab_box(wxVERTICAL);
|
||||
|
||||
auto hw_prereq = [this]{ return m_is_hardware; };
|
||||
auto* hacks_check_box = m_ui.addCheckBox(tab_box.inner, "Enable HW Hacks", "UserHacks", -1, hw_prereq);
|
||||
auto* hacks_check_box = m_ui.addCheckBox(tab_box.inner, "Manual HW Hacks", "UserHacks", -1, hw_prereq);
|
||||
auto hacks_prereq = [this, hacks_check_box]{ return m_is_hardware && hacks_check_box->GetValue(); };
|
||||
auto upscale_hacks_prereq = [this, hacks_check_box]{ return !m_is_native_res && hacks_check_box->GetValue(); };
|
||||
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "GameDatabase.h"
|
||||
#include "Config.h"
|
||||
#include "Host.h"
|
||||
#include "Patch.h"
|
||||
|
||||
#include "common/FileSystem.h"
|
||||
#include "common/Path.h"
|
||||
|
@ -31,6 +31,20 @@
|
|||
#include "fmt/ranges.h"
|
||||
#include <fstream>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
|
||||
namespace GameDatabaseSchema
|
||||
{
|
||||
static const char* getHWFixName(GSHWFixId id);
|
||||
static std::optional<GSHWFixId> parseHWFixName(const std::string_view& name);
|
||||
static bool isUserHackHWFix(GSHWFixId id);
|
||||
} // namespace GameDatabaseSchema
|
||||
|
||||
namespace GameDatabase
|
||||
{
|
||||
static void parseAndInsert(const std::string_view& serial, const c4::yml::NodeRef& node);
|
||||
static void initDatabase();
|
||||
} // namespace GameDatabase
|
||||
|
||||
static constexpr char GAMEDB_YAML_FILE_NAME[] = "GameIndex.yaml";
|
||||
|
||||
|
@ -85,7 +99,7 @@ const char* GameDatabaseSchema::GameEntry::compatAsString() const
|
|||
}
|
||||
}
|
||||
|
||||
void parseAndInsert(const std::string_view& serial, const c4::yml::NodeRef& node)
|
||||
void GameDatabase::parseAndInsert(const std::string_view& serial, const c4::yml::NodeRef& node)
|
||||
{
|
||||
GameDatabaseSchema::GameEntry gameEntry;
|
||||
if (node.has_child("name"))
|
||||
|
@ -195,6 +209,25 @@ void parseAndInsert(const std::string_view& serial, const c4::yml::NodeRef& node
|
|||
}
|
||||
}
|
||||
|
||||
if (node.has_child("gsHWFixes"))
|
||||
{
|
||||
for (const ryml::NodeRef& n : node["gsHWFixes"].children())
|
||||
{
|
||||
const std::string_view id_name(n.key().data(), n.key().size());
|
||||
std::optional<GameDatabaseSchema::GSHWFixId> id = GameDatabaseSchema::parseHWFixName(id_name);
|
||||
std::optional<s32> value = n.has_val() ? StringUtil::FromChars<s32>(std::string_view(n.val().data(), n.val().size())) : 1;
|
||||
if (!id.has_value() || !value.has_value())
|
||||
{
|
||||
Console.Error("[GameDB] Invalid GS HW Fix: '%*s' specified for serial '%*s'. Dropping!",
|
||||
static_cast<int>(id_name.size()), id_name.data(),
|
||||
static_cast<int>(serial.size()), serial.data());
|
||||
continue;
|
||||
}
|
||||
|
||||
gameEntry.gsHWFixes.emplace_back(id.value(), value.value());
|
||||
}
|
||||
}
|
||||
|
||||
// Memory Card Filters - Store as a vector to allow flexibility in the future
|
||||
// - currently they are used as a '\n' delimited string in the app
|
||||
if (node.has_child("memcardFilters") && node["memcardFilters"].has_children())
|
||||
|
@ -231,16 +264,188 @@ void parseAndInsert(const std::string_view& serial, const c4::yml::NodeRef& node
|
|||
s_game_db.emplace(std::move(serial), std::move(gameEntry));
|
||||
}
|
||||
|
||||
static std::ifstream getFileStream(std::string path)
|
||||
static const char* s_gs_hw_fix_names[] = {
|
||||
"autoFlush",
|
||||
"conservativeFramebuffer",
|
||||
"cpuFramebufferConversion",
|
||||
"disableDepthSupport",
|
||||
"wrapGSMem",
|
||||
"preloadFrameData",
|
||||
"fastTextureInvalidation",
|
||||
"textureInsideRT",
|
||||
"alignSprite",
|
||||
"mergeSprite",
|
||||
"wildArmsHack",
|
||||
"mipmap",
|
||||
"trilinearFiltering",
|
||||
"skipDrawStart",
|
||||
"skipDrawEnd",
|
||||
"halfBottomOverride",
|
||||
"halfPixelOffset",
|
||||
"roundSprite",
|
||||
"texturePreloading",
|
||||
};
|
||||
static_assert(std::size(s_gs_hw_fix_names) == static_cast<u32>(GameDatabaseSchema::GSHWFixId::Count), "HW fix name lookup is correct size");
|
||||
|
||||
const char* GameDatabaseSchema::getHWFixName(GSHWFixId id)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return std::ifstream(StringUtil::UTF8StringToWideString(path));
|
||||
#else
|
||||
return std::ifstream(path.c_str());
|
||||
#endif
|
||||
return s_gs_hw_fix_names[static_cast<u32>(id)];
|
||||
}
|
||||
|
||||
static void initDatabase()
|
||||
static std::optional<GameDatabaseSchema::GSHWFixId> GameDatabaseSchema::parseHWFixName(const std::string_view& name)
|
||||
{
|
||||
for (u32 i = 0; i < std::size(s_gs_hw_fix_names); i++)
|
||||
{
|
||||
if (name.compare(s_gs_hw_fix_names[i]) == 0)
|
||||
return static_cast<GameDatabaseSchema::GSHWFixId>(i);
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool GameDatabaseSchema::isUserHackHWFix(GSHWFixId id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case GSHWFixId::Mipmap:
|
||||
case GSHWFixId::TexturePreloading:
|
||||
case GSHWFixId::ConservativeFramebuffer:
|
||||
return false;
|
||||
|
||||
#ifdef PCSX2_CORE
|
||||
// Trifiltering isn't a hack in Qt.
|
||||
case GSHWFixId::TrilinearFiltering:
|
||||
return false;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
u32 GameDatabaseSchema::GameEntry::applyGSHardwareFixes(Pcsx2Config::GSOptions& config) const
|
||||
{
|
||||
// Only apply GS HW fixes if the user hasn't manually enabled HW fixes.
|
||||
const bool apply_auto_fixes = !config.ManualUserHacks;
|
||||
if (!apply_auto_fixes)
|
||||
Console.Warning("[GameDB] Hardware fixes are enabled, not using automatic fixes.");
|
||||
|
||||
u32 num_applied_fixes = 0;
|
||||
for (const auto& [id, value] : gsHWFixes)
|
||||
{
|
||||
if (isUserHackHWFix(id) && !apply_auto_fixes)
|
||||
{
|
||||
PatchesCon->Warning("[GameDB] Skipping GS Hardware Fix: %s to [mode=%d]", getHWFixName(id), value);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case GSHWFixId::AutoFlush:
|
||||
config.UserHacks_AutoFlush = (value > 0);
|
||||
break;
|
||||
|
||||
case GSHWFixId::ConservativeFramebuffer:
|
||||
config.ConservativeFramebuffer = (value > 0);
|
||||
break;
|
||||
|
||||
case GSHWFixId::CPUFramebufferConversion:
|
||||
config.UserHacks_CPUFBConversion = (value > 0);
|
||||
break;
|
||||
|
||||
case GSHWFixId::DisableDepthSupport:
|
||||
config.UserHacks_DisableDepthSupport = (value > 0);
|
||||
break;
|
||||
|
||||
case GSHWFixId::WrapGSMem:
|
||||
config.WrapGSMem = (value > 0);
|
||||
break;
|
||||
|
||||
case GSHWFixId::PreloadFrameData:
|
||||
config.PreloadFrameWithGSData = (value > 0);
|
||||
break;
|
||||
|
||||
case GSHWFixId::FastTextureInvalidation:
|
||||
config.UserHacks_DisablePartialInvalidation = (value > 0);
|
||||
break;
|
||||
|
||||
case GSHWFixId::TextureInsideRT:
|
||||
config.UserHacks_TextureInsideRt = (value > 0);
|
||||
break;
|
||||
|
||||
case GSHWFixId::AlignSprite:
|
||||
config.UserHacks_AlignSpriteX = (value > 0);
|
||||
break;
|
||||
|
||||
case GSHWFixId::MergeSprite:
|
||||
config.UserHacks_MergePPSprite = (value > 0);
|
||||
break;
|
||||
|
||||
case GSHWFixId::WildArmsHack:
|
||||
config.UserHacks_WildHack = (value > 0);
|
||||
break;
|
||||
|
||||
case GSHWFixId::Mipmap:
|
||||
{
|
||||
if (value >= 0 && value <= static_cast<int>(HWMipmapLevel::Full))
|
||||
{
|
||||
if (config.HWMipmap == HWMipmapLevel::Automatic)
|
||||
config.HWMipmap = static_cast<HWMipmapLevel>(value);
|
||||
else if (config.HWMipmap == HWMipmapLevel::Off)
|
||||
Console.Warning("[GameDB] Game requires mipmapping but it has been force disabled.");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GSHWFixId::TrilinearFiltering:
|
||||
{
|
||||
if (value >= 0 && value <= static_cast<int>(TriFiltering::Forced))
|
||||
config.UserHacks_TriFilter = static_cast<TriFiltering>(value);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSHWFixId::SkipDrawStart:
|
||||
config.SkipDrawStart = value;
|
||||
break;
|
||||
|
||||
case GSHWFixId::SkipDrawEnd:
|
||||
config.SkipDrawEnd = value;
|
||||
break;
|
||||
|
||||
case GSHWFixId::HalfBottomOverride:
|
||||
config.UserHacks_HalfBottomOverride = value;
|
||||
break;
|
||||
|
||||
case GSHWFixId::HalfPixelOffset:
|
||||
config.UserHacks_HalfPixelOffset = value;
|
||||
break;
|
||||
|
||||
case GSHWFixId::RoundSprite:
|
||||
config.UserHacks_RoundSprite = value;
|
||||
break;
|
||||
|
||||
case GSHWFixId::TexturePreloading:
|
||||
{
|
||||
if (value >= 0 && value <= static_cast<int>(TexturePreloadingLevel::Full))
|
||||
config.TexturePreloading = std::min(config.TexturePreloading, static_cast<TexturePreloadingLevel>(value));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
PatchesCon->WriteLn("[GameDB] Enabled GS Hardware Fix: %s to [mode=%d]", getHWFixName(id), value);
|
||||
num_applied_fixes++;
|
||||
}
|
||||
|
||||
// fixup skipdraw range just in case the db has a bad range (but the linter should catch this)
|
||||
config.SkipDrawEnd = std::max(config.SkipDrawStart, config.SkipDrawEnd);
|
||||
|
||||
return num_applied_fixes;
|
||||
}
|
||||
|
||||
void GameDatabase::initDatabase()
|
||||
{
|
||||
ryml::Callbacks rymlCallbacks = ryml::get_callbacks();
|
||||
rymlCallbacks.m_error = [](const char* msg, size_t msg_len, ryml::Location loc, void*) {
|
||||
|
@ -291,8 +496,6 @@ static void initDatabase()
|
|||
ryml::reset_callbacks();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GameDatabase::ensureLoaded()
|
||||
{
|
||||
std::call_once(s_load_once_flag, []() {
|
||||
|
|
|
@ -15,16 +15,18 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "Config.h"
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
enum GamefixId;
|
||||
enum SpeedhackId;
|
||||
|
||||
class GameDatabaseSchema
|
||||
namespace GameDatabaseSchema
|
||||
{
|
||||
public:
|
||||
enum class Compatibility
|
||||
{
|
||||
Unknown = 0,
|
||||
|
@ -54,6 +56,34 @@ public:
|
|||
Full
|
||||
};
|
||||
|
||||
enum class GSHWFixId : u32
|
||||
{
|
||||
// boolean settings
|
||||
AutoFlush,
|
||||
ConservativeFramebuffer,
|
||||
CPUFramebufferConversion,
|
||||
DisableDepthSupport,
|
||||
WrapGSMem,
|
||||
PreloadFrameData,
|
||||
FastTextureInvalidation,
|
||||
TextureInsideRT,
|
||||
AlignSprite,
|
||||
MergeSprite,
|
||||
WildArmsHack,
|
||||
|
||||
// integer settings
|
||||
Mipmap,
|
||||
TrilinearFiltering,
|
||||
SkipDrawStart,
|
||||
SkipDrawEnd,
|
||||
HalfBottomOverride,
|
||||
HalfPixelOffset,
|
||||
RoundSprite,
|
||||
TexturePreloading,
|
||||
|
||||
Count
|
||||
};
|
||||
|
||||
using Patch = std::vector<std::string>;
|
||||
|
||||
struct GameEntry
|
||||
|
@ -67,6 +97,7 @@ public:
|
|||
ClampMode vuClampMode = ClampMode::Undefined;
|
||||
std::vector<GamefixId> gameFixes;
|
||||
std::vector<std::pair<SpeedhackId, int>> speedHacks;
|
||||
std::vector<std::pair<GSHWFixId, s32>> gsHWFixes;
|
||||
std::vector<std::string> memcardFilters;
|
||||
std::unordered_map<std::string, Patch> patches;
|
||||
|
||||
|
@ -74,6 +105,9 @@ public:
|
|||
std::string memcardFiltersAsString() const;
|
||||
const Patch* findPatch(const std::string_view& crc) const;
|
||||
const char* compatAsString() const;
|
||||
|
||||
/// Applies GS hardware fixes to an existing config. Returns the number of applied fixes.
|
||||
u32 applyGSHardwareFixes(Pcsx2Config::GSOptions& config) const;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -314,7 +314,7 @@ Pcsx2Config::GSOptions::GSOptions()
|
|||
Mipmap = true;
|
||||
AA1 = true;
|
||||
|
||||
UserHacks = false;
|
||||
ManualUserHacks = false;
|
||||
UserHacks_AlignSpriteX = false;
|
||||
UserHacks_AutoFlush = false;
|
||||
UserHacks_CPUFBConversion = false;
|
||||
|
@ -385,8 +385,8 @@ bool Pcsx2Config::GSOptions::OptionsAreEqual(const GSOptions& right) const
|
|||
OpEqu(SWExtraThreads) &&
|
||||
OpEqu(SWExtraThreadsHeight) &&
|
||||
OpEqu(TVShader) &&
|
||||
OpEqu(SkipDraw) &&
|
||||
OpEqu(SkipDrawOffset) &&
|
||||
OpEqu(SkipDrawEnd) &&
|
||||
OpEqu(SkipDrawStart) &&
|
||||
|
||||
OpEqu(UserHacks_HalfBottomOverride) &&
|
||||
OpEqu(UserHacks_HalfPixelOffset) &&
|
||||
|
@ -513,7 +513,7 @@ void Pcsx2Config::GSOptions::ReloadIniSettings()
|
|||
GSSettingBoolEx(WrapGSMem, "wrap_gs_mem");
|
||||
GSSettingBoolEx(Mipmap, "mipmap");
|
||||
GSSettingBoolEx(AA1, "aa1");
|
||||
GSSettingBoolEx(UserHacks, "UserHacks");
|
||||
GSSettingBoolEx(ManualUserHacks, "UserHacks");
|
||||
GSSettingBoolEx(UserHacks_AlignSpriteX, "UserHacks_align_sprite_X");
|
||||
GSSettingBoolEx(UserHacks_AutoFlush, "UserHacks_AutoFlush");
|
||||
GSSettingBoolEx(UserHacks_CPUFBConversion, "UserHacks_CPU_FB_Conversion");
|
||||
|
@ -555,8 +555,9 @@ void Pcsx2Config::GSOptions::ReloadIniSettings()
|
|||
GSSettingIntEx(SWExtraThreads, "extrathreads");
|
||||
GSSettingIntEx(SWExtraThreadsHeight, "extrathreads_height");
|
||||
GSSettingIntEx(TVShader, "TVShader");
|
||||
GSSettingIntEx(SkipDraw, "UserHacks_SkipDraw");
|
||||
GSSettingIntEx(SkipDrawOffset, "UserHacks_SkipDraw_Offset");
|
||||
GSSettingIntEx(SkipDrawStart, "UserHacks_SkipDraw_Offset");
|
||||
GSSettingIntEx(SkipDrawEnd, "UserHacks_SkipDraw");
|
||||
SkipDrawEnd = std::max(SkipDrawStart, SkipDrawEnd);
|
||||
|
||||
GSSettingIntEx(UserHacks_HalfBottomOverride, "UserHacks_Half_Bottom_Override");
|
||||
GSSettingIntEx(UserHacks_HalfPixelOffset, "UserHacks_HalfPixelOffset");
|
||||
|
@ -588,7 +589,7 @@ void Pcsx2Config::GSOptions::ReloadIniSettings()
|
|||
|
||||
void Pcsx2Config::GSOptions::MaskUserHacks()
|
||||
{
|
||||
if (UserHacks)
|
||||
if (ManualUserHacks)
|
||||
return;
|
||||
|
||||
UserHacks_AlignSpriteX = false;
|
||||
|
@ -605,8 +606,8 @@ void Pcsx2Config::GSOptions::MaskUserHacks()
|
|||
UserHacks_TextureInsideRt = false;
|
||||
UserHacks_TCOffsetX = 0;
|
||||
UserHacks_TCOffsetY = 0;
|
||||
SkipDraw = 0;
|
||||
SkipDrawOffset = 0;
|
||||
SkipDrawStart = 0;
|
||||
SkipDrawEnd = 0;
|
||||
|
||||
// in wx, we put trilinear filtering behind user hacks, but not in qt.
|
||||
#ifndef PCSX2_CORE
|
||||
|
@ -616,7 +617,7 @@ void Pcsx2Config::GSOptions::MaskUserHacks()
|
|||
|
||||
void Pcsx2Config::GSOptions::MaskUpscalingHacks()
|
||||
{
|
||||
if (UpscaleMultiplier == 1 || UserHacks)
|
||||
if (UpscaleMultiplier == 1 || ManualUserHacks)
|
||||
return;
|
||||
|
||||
UserHacks_AlignSpriteX = false;
|
||||
|
|
|
@ -218,6 +218,10 @@ void VMManager::LoadSettings()
|
|||
InputManager::ReloadSources(*si);
|
||||
InputManager::ReloadBindings(*si);
|
||||
|
||||
// Remove any user-specified hacks in the config (we don't want stale/conflicting values when it's globally disabled).
|
||||
EmuConfig.GS.MaskUserHacks();
|
||||
EmuConfig.GS.MaskUpscalingHacks();
|
||||
|
||||
if (HasValidVM())
|
||||
ApplyGameFixes();
|
||||
}
|
||||
|
@ -295,6 +299,8 @@ void VMManager::ApplyGameFixes()
|
|||
if (id == Fix_GoemonTlbMiss && true)
|
||||
vtlb_Alloc_Ppmap();
|
||||
}
|
||||
|
||||
s_active_game_fixes += game->applyGSHardwareFixes(EmuConfig.GS);
|
||||
}
|
||||
|
||||
std::string VMManager::GetGameSettingsPath(u32 game_crc)
|
||||
|
|
|
@ -333,6 +333,8 @@ static int loadGameSettings(Pcsx2Config& dest, const GameDatabaseSchema::GameEnt
|
|||
vtlb_Alloc_Ppmap();
|
||||
}
|
||||
|
||||
gf += game.applyGSHardwareFixes(dest.GS);
|
||||
|
||||
return gf;
|
||||
}
|
||||
|
||||
|
@ -404,6 +406,10 @@ static void _ApplySettings(const Pcsx2Config& src, Pcsx2Config& fixup)
|
|||
fixup.GS.VsyncEnable = VsyncMode::Off;
|
||||
}
|
||||
|
||||
// Remove any user-specified hacks in the config (we don't want stale/conflicting values when it's globally disabled).
|
||||
fixup.GS.MaskUserHacks();
|
||||
fixup.GS.MaskUpscalingHacks();
|
||||
|
||||
wxString gamePatch;
|
||||
wxString gameFixes;
|
||||
wxString gameCheats;
|
||||
|
|
Loading…
Reference in New Issue