mirror of https://github.com/PCSX2/pcsx2.git
Patch: Store gamedb patches as single string
This commit is contained in:
parent
29cea58471
commit
5fa9427323
|
@ -57,23 +57,22 @@ std::string GameDatabaseSchema::GameEntry::memcardFiltersAsString() const
|
|||
return fmt::to_string(fmt::join(memcardFilters, "/"));
|
||||
}
|
||||
|
||||
const GameDatabaseSchema::Patch* GameDatabaseSchema::GameEntry::findPatch(const std::string_view& crc) const
|
||||
const std::string* GameDatabaseSchema::GameEntry::findPatch(u32 crc) const
|
||||
{
|
||||
std::string crcLower = StringUtil::toLower(crc);
|
||||
Console.WriteLn(fmt::format("[GameDB] Searching for patch with CRC '{}'", crc));
|
||||
Console.WriteLn(fmt::format("[GameDB] Searching for patch with CRC '{:08X}'", crc));
|
||||
|
||||
auto it = patches.find(crcLower);
|
||||
auto it = patches.find(crc);
|
||||
if (it != patches.end())
|
||||
{
|
||||
Console.WriteLn(fmt::format("[GameDB] Found patch with CRC '{}'", crc));
|
||||
return &patches.at(crcLower);
|
||||
Console.WriteLn(fmt::format("[GameDB] Found patch with CRC '{:08X}'", crc));
|
||||
return &it->second;
|
||||
}
|
||||
|
||||
it = patches.find("default");
|
||||
it = patches.find(0);
|
||||
if (it != patches.end())
|
||||
{
|
||||
Console.WriteLn("[GameDB] Found and falling back to default patch");
|
||||
return &patches.at("default");
|
||||
return &it->second;
|
||||
}
|
||||
Console.WriteLn("[GameDB] No CRC-specific patch or default patch found");
|
||||
return nullptr;
|
||||
|
@ -245,20 +244,24 @@ void GameDatabase::parseAndInsert(const std::string_view& serial, const c4::yml:
|
|||
{
|
||||
for (const ryml::NodeRef& n : node["patches"].children())
|
||||
{
|
||||
auto crc = StringUtil::toLower(std::string(n.key().str, n.key().len));
|
||||
if (gameEntry.patches.count(crc) == 1)
|
||||
// use a crc of 0 for default patches
|
||||
const std::string_view crc_str(n.key().str, n.key().len);
|
||||
const std::optional<u32> crc = (StringUtil::compareNoCase(crc_str, "default")) ? std::optional<u32>(0) : StringUtil::FromChars<u32>(crc_str, 16);
|
||||
if (!crc.has_value())
|
||||
{
|
||||
Console.Error(fmt::format("[GameDB] Duplicate CRC '{}' found for serial: '{}'. Skipping, CRCs are case-insensitive!", crc, serial));
|
||||
Console.Error(fmt::format("[GameDB] Invalid CRC '{}' found for serial: '{}'. Skipping!", crc_str, serial));
|
||||
continue;
|
||||
}
|
||||
GameDatabaseSchema::Patch patch;
|
||||
if (n.has_child("content"))
|
||||
if (gameEntry.patches.find(crc.value()) != gameEntry.patches.end())
|
||||
{
|
||||
std::string patchLines;
|
||||
n["content"] >> patchLines;
|
||||
patch = StringUtil::splitOnNewLine(patchLines);
|
||||
Console.Error(fmt::format("[GameDB] Duplicate CRC '{}' found for serial: '{}'. Skipping, CRCs are case-insensitive!", crc_str, serial));
|
||||
continue;
|
||||
}
|
||||
gameEntry.patches[crc] = patch;
|
||||
|
||||
std::string patch;
|
||||
if (n.has_child("content"))
|
||||
n["content"] >> patch;
|
||||
gameEntry.patches.emplace(crc.value(), std::move(patch));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -86,8 +86,6 @@ namespace GameDatabaseSchema
|
|||
Count
|
||||
};
|
||||
|
||||
using Patch = std::vector<std::string>;
|
||||
|
||||
struct GameEntry
|
||||
{
|
||||
std::string name;
|
||||
|
@ -101,11 +99,11 @@ namespace GameDatabaseSchema
|
|||
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;
|
||||
std::unordered_map<u32, std::string> patches;
|
||||
|
||||
// Returns the list of memory card serials as a `/` delimited string
|
||||
std::string memcardFiltersAsString() const;
|
||||
const Patch* findPatch(const std::string_view& crc) const;
|
||||
const std::string* findPatch(u32 crc) const;
|
||||
const char* compatAsString() const;
|
||||
|
||||
/// Applies Core game fixes to an existing config. Returns the number of applied fixes.
|
||||
|
|
|
@ -120,23 +120,11 @@ static void inifile_command(const std::string& cmd)
|
|||
/*int code = */ PatchTableExecute(key, value, commands_patch);
|
||||
}
|
||||
|
||||
// This routine loads patches from the game database (but not the config/game fixes/hacks)
|
||||
// Returns number of patches loaded
|
||||
int LoadPatchesFromGamesDB(const std::string& crc, const GameDatabaseSchema::GameEntry& game)
|
||||
int LoadPatchesFromString(const std::string& patches)
|
||||
{
|
||||
const GameDatabaseSchema::Patch* patch = game.findPatch(crc);
|
||||
if (patch)
|
||||
{
|
||||
for (const std::string& line : *patch)
|
||||
inifile_command(line);
|
||||
}
|
||||
const size_t before = Patch.size();
|
||||
|
||||
return Patch.size();
|
||||
}
|
||||
|
||||
static void inifile_processString(const std::string& inStr)
|
||||
{
|
||||
std::istringstream ss(inStr);
|
||||
std::istringstream ss(patches);
|
||||
std::string line;
|
||||
while (std::getline(ss, line))
|
||||
{
|
||||
|
@ -144,6 +132,8 @@ static void inifile_processString(const std::string& inStr)
|
|||
if (!line.empty())
|
||||
inifile_command(line);
|
||||
}
|
||||
|
||||
return static_cast<int>(Patch.size() - before);
|
||||
}
|
||||
|
||||
void ForgetLoadedPatches()
|
||||
|
@ -162,18 +152,13 @@ int LoadPatchesFromZip(const std::string& crc, const u8* zip_data, size_t zip_da
|
|||
if (!zf)
|
||||
return 0;
|
||||
|
||||
const int before = Patch.size();
|
||||
|
||||
const std::string pnach_filename(crc + ".pnach");
|
||||
std::optional<std::string> pnach_data(ReadFileInZipToString(zf.get(), pnach_filename.c_str()));
|
||||
if (!pnach_data.has_value())
|
||||
return 0;
|
||||
|
||||
PatchesCon->WriteLn(Color_Green, "Loading patch '%s' from archive.", pnach_filename.c_str());
|
||||
|
||||
inifile_processString(pnach_data.value());
|
||||
|
||||
return Patch.size() - before;
|
||||
return LoadPatchesFromString(pnach_data.value());
|
||||
}
|
||||
|
||||
|
||||
|
@ -198,7 +183,7 @@ int LoadPatchesFromDir(const std::string& crc, const wxDirName& folder, const ch
|
|||
friendly_name, folder.ToUTF8().data(), crc.c_str());
|
||||
}
|
||||
|
||||
const size_t before_all = Patch.size();
|
||||
int total_loaded = 0;
|
||||
|
||||
for (const FILESYSTEM_FIND_DATA& fd : files)
|
||||
{
|
||||
|
@ -209,17 +194,13 @@ int LoadPatchesFromDir(const std::string& crc, const wxDirName& folder, const ch
|
|||
if (!pnach_data.has_value())
|
||||
continue;
|
||||
|
||||
const size_t before = Patch.size();
|
||||
inifile_processString(pnach_data.value());
|
||||
const size_t loaded = Patch.size() - before;
|
||||
|
||||
PatchesCon->WriteLn((loaded ? Color_Green : Color_Gray), "Loaded %zu %s from '%.*s'.",
|
||||
const int loaded = LoadPatchesFromString(pnach_data.value());
|
||||
PatchesCon->WriteLn((loaded ? Color_Green : Color_Gray), "Loaded %d %s from '%.*s'.",
|
||||
loaded, friendly_name, static_cast<int>(name.size()), name.data());
|
||||
}
|
||||
|
||||
const size_t loaded = Patch.size() - before_all;
|
||||
PatchesCon->WriteLn((loaded ? Color_Green : Color_Gray), "Overall %zu %s loaded", loaded, friendly_name);
|
||||
return loaded;
|
||||
PatchesCon->WriteLn((total_loaded ? Color_Green : Color_Gray), "Overall %d %s loaded", total_loaded, friendly_name);
|
||||
return total_loaded;
|
||||
}
|
||||
|
||||
// PatchFunc Functions.
|
||||
|
|
|
@ -107,7 +107,7 @@ namespace PatchFunc
|
|||
// The following LoadPatchesFrom* functions:
|
||||
// - do not reset/unload previously loaded patches (use ForgetLoadedPatches() for that)
|
||||
// - do not actually patch the emulation memory (that happens at ApplyLoadedPatches(...) )
|
||||
extern int LoadPatchesFromGamesDB(const std::string& crc, const GameDatabaseSchema::GameEntry& game);
|
||||
extern int LoadPatchesFromString(const std::string& patches);
|
||||
extern int LoadPatchesFromDir(const std::string& crc, const wxDirName& folder, const char* friendly_name, bool show_error_when_missing);
|
||||
extern int LoadPatchesFromZip(const std::string& crc, const u8* zip_data, size_t zip_data_size);
|
||||
|
||||
|
|
|
@ -337,7 +337,8 @@ static void LoadPatches(const std::string& crc_string, bool show_messages, bool
|
|||
if (EmuConfig.EnablePatches)
|
||||
{
|
||||
const GameDatabaseSchema::GameEntry* game = GameDatabase::findGame(s_game_serial);
|
||||
if (game && (patch_count = LoadPatchesFromGamesDB(crc_string, *game)) > 0)
|
||||
const std::string* patches = game ? game->findPatch(s_game_crc) : nullptr;
|
||||
if (patches && (patch_count = LoadPatchesFromString(*patches)) > 0)
|
||||
{
|
||||
PatchesCon->WriteLn(Color_Green, "(GameDB) Patches Loaded: %d", patch_count);
|
||||
message.Write("%u game patches", patch_count);
|
||||
|
|
|
@ -391,10 +391,12 @@ static void _ApplySettings(const Pcsx2Config& src, Pcsx2Config& fixup)
|
|||
|
||||
if (fixup.EnablePatches)
|
||||
{
|
||||
if (int patches = LoadPatchesFromGamesDB(GameInfo::gameCRC.ToStdString(), *game))
|
||||
const std::string* patches = ingame ? game->findPatch(ElfCRC) : 0;
|
||||
int numPatches;
|
||||
if (patches && (numPatches = LoadPatchesFromString(*patches)) > 0)
|
||||
{
|
||||
gamePatch.Printf(L" [%d Patches]", patches);
|
||||
PatchesCon->WriteLn(Color_Green, "(GameDB) Patches Loaded: %d", patches);
|
||||
gamePatch.Printf(L" [%d Patches]", numPatches);
|
||||
PatchesCon->WriteLn(Color_Green, "(GameDB) Patches Loaded: %d", numPatches);
|
||||
}
|
||||
}
|
||||
if (int fixes = loadGameSettings(fixup, *game))
|
||||
|
|
Loading…
Reference in New Issue