Config: Make SpeedHack a scoped enum

And get rid of the redundant "SpeedHack" suffix on all values.
This commit is contained in:
Stenzek 2023-07-07 20:24:15 +10:00 committed by Connor McLaughlin
parent b53e9856b8
commit 48cfe9ca73
6 changed files with 233 additions and 220 deletions

File diff suppressed because it is too large Load Diff

View File

@ -170,15 +170,12 @@ enum GamefixId
// TODO - config - not a fan of the excessive use of enums and macros to make them work // TODO - config - not a fan of the excessive use of enums and macros to make them work
// a proper object would likely make more sense (if possible). // a proper object would likely make more sense (if possible).
enum SpeedhackId enum class SpeedHack
{ {
SpeedhackId_FIRST = 0, MVUFlag,
InstantVU1,
Speedhack_mvuFlag = SpeedhackId_FIRST, MTVU,
Speedhack_InstantVU1, MaxCount,
Speedhack_MTVU,
SpeedhackId_COUNT
}; };
enum class VsyncMode enum class VsyncMode
@ -374,7 +371,6 @@ typename std::underlying_type<Enumeration>::type enum_cast(Enumeration E)
} }
ImplementEnumOperators(GamefixId); ImplementEnumOperators(GamefixId);
ImplementEnumOperators(SpeedhackId);
//------------ DEFAULT sseMXCSR VALUES --------------- //------------ DEFAULT sseMXCSR VALUES ---------------
#define DEFAULT_sseMXCSR 0xffc0 //FPU rounding > DaZ, FtZ, "chop" #define DEFAULT_sseMXCSR 0xffc0 //FPU rounding > DaZ, FtZ, "chop"
@ -1068,6 +1064,10 @@ struct Pcsx2Config
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
struct SpeedhackOptions struct SpeedhackOptions
{ {
static constexpr s8 MIN_EE_CYCLE_RATE = -3;
static constexpr s8 MAX_EE_CYCLE_RATE = 3;
static constexpr u8 MAX_EE_CYCLE_SKIP = 3;
BITFIELD32() BITFIELD32()
bool bool
fastCDVD : 1, // enables fast CDVD access fastCDVD : 1, // enables fast CDVD access
@ -1085,17 +1085,13 @@ struct Pcsx2Config
void LoadSave(SettingsWrapper& conf); void LoadSave(SettingsWrapper& conf);
SpeedhackOptions& DisableAll(); SpeedhackOptions& DisableAll();
void Set(SpeedhackId id, bool enabled = true); void Set(SpeedHack id, int value);
bool operator==(const SpeedhackOptions& right) const bool operator==(const SpeedhackOptions& right) const;
{ bool operator!=(const SpeedhackOptions& right) const;
return OpEqu(bitset) && OpEqu(EECycleRate) && OpEqu(EECycleSkip);
}
bool operator!=(const SpeedhackOptions& right) const static const char* GetSpeedHackName(SpeedHack id);
{ static std::optional<SpeedHack> ParseSpeedHackName(const std::string_view& name);
return !this->operator==(right);
}
}; };
struct DebugOptions struct DebugOptions

View File

@ -303,17 +303,17 @@
"speedHacks": { "speedHacks": {
"type": "object", "type": "object",
"properties": { "properties": {
"mvuFlagSpeedHack": { "mvuFlag": {
"type": "integer", "type": "integer",
"minimum": 0, "minimum": 0,
"maximum": 1 "maximum": 1
}, },
"InstantVU1SpeedHack": { "instantVU1": {
"type": "integer", "type": "integer",
"minimum": 0, "minimum": 0,
"maximum": 1 "maximum": 1
}, },
"MTVUSpeedHack": { "mtvu": {
"type": "integer", "type": "integer",
"minimum": 0, "minimum": 0,
"maximum": 1 "maximum": 1

View File

@ -200,33 +200,25 @@ void GameDatabase::parseAndInsert(const std::string_view& serial, const c4::yml:
} }
} }
// Validate speed hacks, invalid ones will be dropped!
if (node.has_child("speedHacks") && node["speedHacks"].has_children()) if (node.has_child("speedHacks") && node["speedHacks"].has_children())
{ {
for (const auto& n : node["speedHacks"].children()) for (const auto& n : node["speedHacks"].children())
{ {
bool speedHackValidated = false; const std::string_view id_view = std::string_view(n.key().str, n.key().len);
auto speedHack = std::string(n.key().str, n.key().len); const std::string_view value_view = std::string_view(n.val().str, n.val().len);
const std::optional<SpeedHack> id = Pcsx2Config::SpeedhackOptions::ParseSpeedHackName(id_view);
const std::optional<int> value = StringUtil::FromChars<int>(value_view);
// Same deal with SpeedHacks if (id.has_value() && value.has_value() &&
if (StringUtil::EndsWith(speedHack, "SpeedHack")) std::none_of(gameEntry.speedHacks.begin(), gameEntry.speedHacks.end(),
[&id](const auto& it) { return it.first == id.value(); }))
{ {
speedHack.erase(speedHack.size() - 9); gameEntry.speedHacks.emplace_back(id.value(), value.value());
for (SpeedhackId id = SpeedhackId_FIRST; id < pxEnumEnd; ++id)
{
if (speedHack.compare(EnumToString(id)) == 0 &&
std::none_of(gameEntry.speedHacks.begin(), gameEntry.speedHacks.end(), [id](const auto& it) { return it.first == id; }))
{
gameEntry.speedHacks.emplace_back(id, std::atoi(n.val().str));
speedHackValidated = true;
break;
}
}
} }
else
if (!speedHackValidated)
{ {
Console.Error(fmt::format("[GameDB] Invalid speedhack: '{}', specified for serial: '{}'. Dropping!", speedHack.c_str(), serial)); Console.Error(fmt::format("[GameDB] Invalid speedhack: '{}={}', specified for serial: '{}'. Dropping!",
id_view, value_view, serial));
} }
} }
} }
@ -507,16 +499,17 @@ void GameDatabaseSchema::GameEntry::applyGameFixes(Pcsx2Config& config, bool app
// TODO - config - this could be simplified with maps instead of bitfields and enums // TODO - config - this could be simplified with maps instead of bitfields and enums
for (const auto& it : speedHacks) for (const auto& it : speedHacks)
{ {
const bool mode = it.second != 0;
if (!applyAuto) if (!applyAuto)
{ {
Console.Warning("[GameDB] Skipping setting Speedhack '%s' to [mode=%d]", EnumToString(it.first), mode); Console.Warning("[GameDB] Skipping setting Speedhack '%s' to [mode=%d]",
Pcsx2Config::SpeedhackOptions::GetSpeedHackName(it.first), it.second);
continue; continue;
} }
// Legacy note - speedhacks are setup in the GameDB as integer values, but // Legacy note - speedhacks are setup in the GameDB as integer values, but
// are effectively booleans like the gamefixes // are effectively booleans like the gamefixes
config.Speedhacks.Set(it.first, mode); config.Speedhacks.Set(it.first, it.second);
Console.WriteLn("(GameDB) Setting Speedhack '%s' to [mode=%d]", EnumToString(it.first), mode); Console.WriteLn("(GameDB) Setting Speedhack '%s' to [mode=%d]",
Pcsx2Config::SpeedhackOptions::GetSpeedHackName(it.first), it.second);
} }
// TODO - config - this could be simplified with maps instead of bitfields and enums // TODO - config - this could be simplified with maps instead of bitfields and enums

View File

@ -24,7 +24,6 @@
#include <vector> #include <vector>
enum GamefixId; enum GamefixId;
enum SpeedhackId;
namespace GameDatabaseSchema namespace GameDatabaseSchema
{ {
@ -113,7 +112,7 @@ namespace GameDatabaseSchema
ClampMode vu0ClampMode = ClampMode::Undefined; ClampMode vu0ClampMode = ClampMode::Undefined;
ClampMode vu1ClampMode = ClampMode::Undefined; ClampMode vu1ClampMode = ClampMode::Undefined;
std::vector<GamefixId> gameFixes; std::vector<GamefixId> gameFixes;
std::vector<std::pair<SpeedhackId, int>> speedHacks; std::vector<std::pair<SpeedHack, int>> speedHacks;
std::vector<std::pair<GSHWFixId, s32>> gsHWFixes; std::vector<std::pair<GSHWFixId, s32>> gsHWFixes;
std::vector<std::string> memcardFilters; std::vector<std::string> memcardFilters;
std::unordered_map<u32, std::string> patches; std::unordered_map<u32, std::string> patches;

View File

@ -177,36 +177,58 @@ void TraceLogFilters::LoadSave(SettingsWrapper& wrap)
SettingsWrapEntry(IOP.bitset); SettingsWrapEntry(IOP.bitset);
} }
const char* const tbl_SpeedhackNames[] = static constexpr const char* s_speed_hack_names[] = {
{
"mvuFlag", "mvuFlag",
"InstantVU1", "instantVU1",
"MTVU" "mtvu",
}; };
const char* EnumToString(SpeedhackId id) const char* Pcsx2Config::SpeedhackOptions::GetSpeedHackName(SpeedHack id)
{ {
return tbl_SpeedhackNames[id]; pxAssert(static_cast<u32>(id) < std::size(s_speed_hack_names));
return s_speed_hack_names[static_cast<u32>(id)];
} }
void Pcsx2Config::SpeedhackOptions::Set(SpeedhackId id, bool enabled) std::optional<SpeedHack> Pcsx2Config::SpeedhackOptions::ParseSpeedHackName(const std::string_view& name)
{ {
pxAssert(EnumIsValid(id)); for (u32 i = 0; i < std::size(s_speed_hack_names); i++)
{
if (name == s_speed_hack_names[i])
return static_cast<SpeedHack>(i);
}
return std::nullopt;
}
void Pcsx2Config::SpeedhackOptions::Set(SpeedHack id, int value)
{
pxAssert(static_cast<u32>(id) < std::size(s_speed_hack_names));
switch (id) switch (id)
{ {
case Speedhack_mvuFlag: case SpeedHack::MVUFlag:
vuFlagHack = enabled; vuFlagHack = (value != 0);
break; break;
case Speedhack_InstantVU1: case SpeedHack::InstantVU1:
vu1Instant = enabled; vu1Instant = (value != 0);
break; break;
case Speedhack_MTVU: case SpeedHack::MTVU:
vuThread = enabled; vuThread = (value != 0);
break; break;
jNO_DEFAULT; jNO_DEFAULT
} }
} }
bool Pcsx2Config::SpeedhackOptions::operator==(const SpeedhackOptions& right) const
{
return OpEqu(bitset) && OpEqu(EECycleRate) && OpEqu(EECycleSkip);
}
bool Pcsx2Config::SpeedhackOptions::operator!=(const SpeedhackOptions& right) const
{
return !operator==(right);
}
Pcsx2Config::SpeedhackOptions::SpeedhackOptions() Pcsx2Config::SpeedhackOptions::SpeedhackOptions()
{ {
DisableAll(); DisableAll();
@ -239,6 +261,9 @@ void Pcsx2Config::SpeedhackOptions::LoadSave(SettingsWrapper& wrap)
SettingsWrapBitBool(vuFlagHack); SettingsWrapBitBool(vuFlagHack);
SettingsWrapBitBool(vuThread); SettingsWrapBitBool(vuThread);
SettingsWrapBitBool(vu1Instant); SettingsWrapBitBool(vu1Instant);
EECycleRate = std::clamp(EECycleRate, MIN_EE_CYCLE_RATE, MAX_EE_CYCLE_RATE);
EECycleSkip = std::min(EECycleSkip, MAX_EE_CYCLE_SKIP);
} }
void Pcsx2Config::ProfilerOptions::LoadSave(SettingsWrapper& wrap) void Pcsx2Config::ProfilerOptions::LoadSave(SettingsWrapper& wrap)