diff --git a/bin/GameIndex.yaml b/bin/resources/GameIndex.yaml similarity index 100% rename from bin/GameIndex.yaml rename to bin/resources/GameIndex.yaml diff --git a/pcsx2/CMakeLists.txt b/pcsx2/CMakeLists.txt index 95b60e9f1f..c457dbddd2 100644 --- a/pcsx2/CMakeLists.txt +++ b/pcsx2/CMakeLists.txt @@ -900,7 +900,6 @@ set(pcsx2GuiSources gui/AppConfig.cpp gui/AppCoreThread.cpp gui/AppEventSources.cpp - gui/AppGameDatabase.cpp gui/AppHost.cpp gui/AppUserMode.cpp gui/AppInit.cpp @@ -977,7 +976,6 @@ set(pcsx2GuiHeaders gui/AppCoreThread.h gui/AppEventListeners.h gui/AppForwardDefs.h - gui/AppGameDatabase.h gui/App.h gui/ApplyState.h gui/AppSaveStates.h @@ -1498,9 +1496,7 @@ if (APPLE) ) target_sources(PCSX2 PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/gui/Resources/PCSX2.icns") - target_sources(PCSX2 PRIVATE "${CMAKE_SOURCE_DIR}/bin/GameIndex.yaml") set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/gui/Resources/PCSX2.icns" PROPERTIES MACOSX_PACKAGE_LOCATION Resources) - set_source_files_properties("${CMAKE_SOURCE_DIR}/bin/GameIndex.yaml" PROPERTIES MACOSX_PACKAGE_LOCATION Resources) # Add in shaders and other resources. file(GLOB resource_files "${CMAKE_SOURCE_DIR}/bin/resources/*") @@ -1559,5 +1555,5 @@ source_group(System/Ps2/USB REGULAR_EXPRESSION USB/*) source_group(Resources/GUI FILES ${pcsx2GuiResources}) source_group(Resources/PAD FILES ${pcsx2PADResources}) source_group(Resources/Recording FILES ${pcsx2RecordingVirtualPadResources}) -source_group(Resources FILES ../bin/GameIndex.yaml gui/Resources/PCSX2.icns) +source_group(Resources FILES gui/Resources/PCSX2.icns) source_group(Resources REGULAR_EXPRESSION ${CMAKE_CURRENT_BINARY_DIR}/*) diff --git a/pcsx2/GameDatabase.cpp b/pcsx2/GameDatabase.cpp index c24927579e..18a329b1b1 100644 --- a/pcsx2/GameDatabase.cpp +++ b/pcsx2/GameDatabase.cpp @@ -16,54 +16,83 @@ #include "PrecompiledHeader.h" #include "GameDatabase.h" +#include "Config.h" +#include "Host.h" + +#include "common/FileSystem.h" +#include "common/Path.h" +#include "common/StringUtil.h" +#include "common/Timer.h" #include "fmt/core.h" #include "fmt/ranges.h" #include "yaml-cpp/yaml.h" #include #include +#include +#include -std::string strToLower(std::string str) +static constexpr char GAMEDB_YAML_FILE_NAME[] = "GameIndex.yaml"; + +static std::unordered_map s_game_db; +static std::once_flag s_load_once_flag; + +static std::string strToLower(std::string str) { std::transform(str.begin(), str.end(), str.begin(), - [](unsigned char c) { return std::tolower(c); }); + [](unsigned char c) { return std::tolower(c); }); return str; } -bool compareStrNoCase(const std::string str1, const std::string str2) -{ - return std::equal(str1.begin(), str1.end(), str2.begin(), - [](char a, char b) { - return tolower(a) == tolower(b); - }); -} - -std::string GameDatabaseSchema::GameEntry::memcardFiltersAsString() const +std::string GameDatabaseSchema::GameEntry::MemcardFiltersAsString() const { return fmt::to_string(fmt::join(memcardFilters, "/")); } -bool GameDatabaseSchema::GameEntry::findPatch(const std::string crc, Patch& patch) const +const GameDatabaseSchema::Patch* GameDatabaseSchema::GameEntry::FindPatch(const std::string& crc) const { - std::string crcLower = strToLower(crc); + const std::string crcLower(strToLower(crc)); Console.WriteLn(fmt::format("[GameDB] Searching for patch with CRC '{}'", crc)); - if (patches.count(crcLower) == 1) + + auto it = patches.find(crcLower); + if (it != patches.end()) { Console.WriteLn(fmt::format("[GameDB] Found patch with CRC '{}'", crc)); - patch = patches.at(crcLower); - return true; + return &it->second; } - else if (patches.count("default") == 1) + + it = patches.find("default"); + if (it != patches.end()) { Console.WriteLn("[GameDB] Found and falling back to default patch"); - patch = patches.at("default"); - return true; + return &it->second; } Console.WriteLn("[GameDB] No CRC-specific patch or default patch found"); - return false; + return nullptr; } -std::vector YamlGameDatabaseImpl::convertMultiLineStringToVector(const std::string multiLineString) +const char* GameDatabaseSchema::compatToString(Compatibility compat) +{ + switch (compat) + { + case GameDatabaseSchema::Compatibility::Perfect: + return "Perfect"; + case GameDatabaseSchema::Compatibility::Playable: + return "Playable"; + case GameDatabaseSchema::Compatibility::InGame: + return "In-Game"; + case GameDatabaseSchema::Compatibility::Menu: + return "Menu"; + case GameDatabaseSchema::Compatibility::Intro: + return "Intro"; + case GameDatabaseSchema::Compatibility::Nothing: + return "Nothing"; + default: + return "Unknown"; + } +} + +static std::vector convertMultiLineStringToVector(const std::string& multiLineString) { std::vector lines; std::istringstream stream(multiLineString); @@ -77,7 +106,7 @@ std::vector YamlGameDatabaseImpl::convertMultiLineStringToVector(co return lines; } -GameDatabaseSchema::GameEntry YamlGameDatabaseImpl::entryFromYaml(const std::string serial, const YAML::Node& node) +static bool parseAndInsert(std::string serial, const YAML::Node& node) { GameDatabaseSchema::GameEntry gameEntry; try @@ -161,60 +190,38 @@ GameDatabaseSchema::GameEntry YamlGameDatabaseImpl::entryFromYaml(const std::str } YAML::Node patchNode = entry.second; - GameDatabaseSchema::Patch patchCol; - - patchCol.author = patchNode["author"].as(""); - patchCol.patchLines = convertMultiLineStringToVector(patchNode["content"].as("")); - gameEntry.patches[crc] = patchCol; + gameEntry.patches[crc] = convertMultiLineStringToVector(patchNode["content"].as("")); } } + + s_game_db.emplace(std::move(serial), std::move(gameEntry)); + return true; } catch (const YAML::RepresentationException& e) { Console.Error(fmt::format("[GameDB] Invalid GameDB syntax detected on serial: '{}'. Error Details - {}", serial, e.msg)); - gameEntry.isValid = false; } catch (const std::exception& e) { Console.Error(fmt::format("[GameDB] Unexpected error occurred when reading serial: '{}'. Error Details - {}", serial, e.what())); - gameEntry.isValid = false; - } - return gameEntry; -} - -GameDatabaseSchema::GameEntry YamlGameDatabaseImpl::findGame(const std::string serial) -{ - std::string serialLower = strToLower(serial); - Console.WriteLn(fmt::format("[GameDB] Searching for '{}' in GameDB", serialLower)); - if (gameDb.count(serialLower) == 1) - { - Console.WriteLn(fmt::format("[GameDB] Found '{}' in GameDB", serialLower)); - return gameDb[serialLower]; } - Console.Error(fmt::format("[GameDB] Could not find '{}' in GameDB", serialLower)); - GameDatabaseSchema::GameEntry entry; - entry.isValid = false; - return entry; + return false; } -int YamlGameDatabaseImpl::numGames() -{ - return gameDb.size(); -} - -bool YamlGameDatabaseImpl::initDatabase(std::ifstream& stream) +static bool LoadYamlFile() { try { - if (!stream) + std::optional file_data(Host::ReadResourceFileToString(GAMEDB_YAML_FILE_NAME)); + if (!file_data.has_value()) { Console.Error("[GameDB] Unable to open GameDB file."); return false; } // yaml-cpp has memory leak issues if you persist and modify a YAML::Node // convert to a map and throw it away instead! - YAML::Node data = YAML::Load(stream); + YAML::Node data = YAML::Load(file_data.value()); for (const auto& entry : data) { // we don't want to throw away the entire GameDB file if a single entry is made incorrectly, @@ -225,13 +232,13 @@ bool YamlGameDatabaseImpl::initDatabase(std::ifstream& stream) // this is because the application may pass a lowercase CRC or serial along // // However, YAML's keys are as expected case-sensitive, so we have to explicitly do our own duplicate checking - std::string serial = strToLower(entry.first.as()); - if (gameDb.count(serial) == 1) + std::string serial(strToLower(entry.first.as())); + if (s_game_db.count(serial) == 1) { Console.Error(fmt::format("[GameDB] Duplicate serial '{}' found in GameDB. Skipping, Serials are case-insensitive!", serial)); continue; } - gameDb[serial] = entryFromYaml(serial, entry.second); + parseAndInsert(std::move(serial), entry.second); } catch (const YAML::RepresentationException& e) { @@ -247,3 +254,36 @@ bool YamlGameDatabaseImpl::initDatabase(std::ifstream& stream) return true; } + +void GameDatabase::EnsureLoaded() +{ + std::call_once(s_load_once_flag, []() { + Common::Timer timer; + + if (!LoadYamlFile()) + { + Console.Error("GameDB: Failed to load YAML file"); + return; + } + + Console.WriteLn("[GameDB] %zu games on record (loaded in %.2fms)", s_game_db.size(), timer.GetTimeMilliseconds()); + }); +} + +const GameDatabaseSchema::GameEntry* GameDatabase::FindGame(const std::string& serial) +{ + EnsureLoaded(); + + const std::string serialLower(strToLower(serial)); + Console.WriteLn("[GameDB] Searching for '%s' in GameDB", serialLower.c_str()); + + auto iter = s_game_db.find(serialLower); + if (iter == s_game_db.end()) + { + Console.Error("[GameDB] Could not find '%s' in GameDB", serialLower.c_str()); + return nullptr; + } + + Console.WriteLn("[GameDB] Found '%s' in GameDB", serialLower.c_str()); + return &iter->second; +} diff --git a/pcsx2/GameDatabase.h b/pcsx2/GameDatabase.h index 5c58d6a5ed..f09f5daaca 100644 --- a/pcsx2/GameDatabase.h +++ b/pcsx2/GameDatabase.h @@ -15,8 +15,6 @@ #pragma once -#include "yaml-cpp/yaml.h" - #include #include #include @@ -56,15 +54,10 @@ public: Full }; - struct Patch - { - std::string author; - std::vector patchLines; - }; + using Patch = std::vector; struct GameEntry { - bool isValid = true; std::string name; std::string region; Compatibility compat = Compatibility::Unknown; @@ -78,33 +71,16 @@ public: std::unordered_map patches; // Returns the list of memory card serials as a `/` delimited string - std::string memcardFiltersAsString() const; - bool findPatch(const std::string crc, Patch& patch) const; + std::string MemcardFiltersAsString() const; + const Patch* FindPatch(const std::string& crc) const; }; + + static const char* compatToString(GameDatabaseSchema::Compatibility compat); }; -class IGameDatabase +namespace GameDatabase { -public: - virtual bool initDatabase(std::ifstream& stream) = 0; - virtual GameDatabaseSchema::GameEntry findGame(const std::string serial) = 0; - virtual int numGames() = 0; -}; + void EnsureLoaded(); -class YamlGameDatabaseImpl : public IGameDatabase -{ -public: - bool initDatabase(std::ifstream& stream) override; - GameDatabaseSchema::GameEntry findGame(const std::string serial) override; - int numGames() override; - -private: - std::unordered_map gameDb; - GameDatabaseSchema::GameEntry entryFromYaml(const std::string serial, const YAML::Node& node); - - std::vector convertMultiLineStringToVector(const std::string multiLineString); -}; - -extern IGameDatabase* AppHost_GetGameDatabase(); -extern std::string strToLower(std::string str); -extern bool compareStrNoCase(const std::string str1, const std::string str2); + const GameDatabaseSchema::GameEntry* FindGame(const std::string& serial); +}; // namespace GameDatabase diff --git a/pcsx2/Patch.cpp b/pcsx2/Patch.cpp index a6268f5237..ec01c813bc 100644 --- a/pcsx2/Patch.cpp +++ b/pcsx2/Patch.cpp @@ -17,6 +17,7 @@ #define _PC_ // disables MIPS opcode macros. +#include "common/StringUtil.h" #include "IopCommon.h" #include "Patch.h" #include "Config.h" @@ -129,19 +130,13 @@ static void inifile_command(const wxString& cmd) // This routine loads patches from the game database (but not the config/game fixes/hacks) // Returns number of patches loaded -int LoadPatchesFromGamesDB(const wxString& crc, const GameDatabaseSchema::GameEntry& game) +int LoadPatchesFromGamesDB(const std::string& crc, const GameDatabaseSchema::GameEntry& game) { - if (game.isValid) + const GameDatabaseSchema::Patch* patch = game.FindPatch(crc); + if (patch) { - GameDatabaseSchema::Patch patch; - bool patchFound = game.findPatch(std::string(crc.ToUTF8()), patch); - if (patchFound && patch.patchLines.size() > 0) - { - for (auto line : patch.patchLines) - { - inifile_command(fromUTF8(line)); - } - } + for (const std::string& line : *patch) + inifile_command(StringUtil::UTF8StringToWxString(line)); } return Patch.size(); @@ -209,20 +204,19 @@ static int _LoadPatchFiles(const wxDirName& folderName, wxString& fileSpec, cons // Returns number of patches loaded // Note: does not reset previously loaded patches (use ForgetLoadedPatches() for that) // Note: only load patches from the root folder of the zip -int LoadPatchesFromZip(wxString gameCRC, const wxString& patchesArchiveFilename) +int LoadPatchesFromZip(const wxString& gameCRC, const wxString& patchesArchiveFilename, wxInputStream* stream) { - gameCRC.MakeUpper(); + wxString upperGameCRC(gameCRC.Upper()); int before = Patch.size(); std::unique_ptr entry; - wxFFileInputStream in(patchesArchiveFilename); - wxZipInputStream zip(in); + wxZipInputStream zip(stream); while (entry.reset(zip.GetNextEntry()), entry.get() != NULL) { wxString name = entry->GetName(); name.MakeUpper(); - if (name.Find(gameCRC) == 0 && name.Find(L".PNACH") + 6u == name.Length()) + if (name.Find(upperGameCRC) == 0 && name.Find(L".PNACH") + 6u == name.Length()) { PatchesCon->WriteLn(Color_Green, L"Loading patch '%s' from archive '%s'", WX_STR(entry->GetName()), WX_STR(patchesArchiveFilename)); @@ -240,7 +234,7 @@ int LoadPatchesFromZip(wxString gameCRC, const wxString& patchesArchiveFilename) // This routine loads patches from *.pnach files // Returns number of patches loaded // Note: does not reset previously loaded patches (use ForgetLoadedPatches() for that) -int LoadPatchesFromDir(wxString name, const wxDirName& folderName, const wxString& friendlyName) +int LoadPatchesFromDir(const wxString& name, const wxDirName& folderName, const wxString& friendlyName) { int loaded = 0; int numberFoundPatchFiles; @@ -250,7 +244,7 @@ int LoadPatchesFromDir(wxString name, const wxDirName& folderName, const wxStrin if (folderName.ToString().IsSameAs(EmuFolders::Cheats.ToString()) && numberFoundPatchFiles == 0) { - wxString pathName = Path::Combine(folderName, name.MakeUpper() + L".pnach"); + wxString pathName = Path::Combine(folderName, name.Upper() + L".pnach"); PatchesCon->WriteLn(Color_Gray, L"Not found %s file: %s", WX_STR(friendlyName), WX_STR(pathName)); } diff --git a/pcsx2/Patch.h b/pcsx2/Patch.h index 8c072fadd7..59044a8d68 100644 --- a/pcsx2/Patch.h +++ b/pcsx2/Patch.h @@ -37,7 +37,9 @@ #include "common/Pcsx2Defs.h" #include "SysForwardDefs.h" -#include "gui/AppGameDatabase.h" +#include "GameDatabase.h" + +class wxInputStream; enum patch_cpu_type { NO_CPU, @@ -106,9 +108,9 @@ 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 wxString& crc, const GameDatabaseSchema::GameEntry& game); -extern int LoadPatchesFromDir(wxString name, const wxDirName& folderName, const wxString& friendlyName); -extern int LoadPatchesFromZip(wxString gameCRC, const wxString& cheatsArchiveFilename); +extern int LoadPatchesFromGamesDB(const std::string& crc, const GameDatabaseSchema::GameEntry& game); +extern int LoadPatchesFromDir(const wxString& name, const wxDirName& folderName, const wxString& friendlyName); +extern int LoadPatchesFromZip(const wxString& gameCRC, const wxString& patchesArchiveFilename, wxInputStream* stream); // Patches the emulation memory by applying all the loaded patches with a specific place value. // Note: unless you know better, there's no need to check whether or not different patch sources diff --git a/pcsx2/Recording/InputRecording.cpp b/pcsx2/Recording/InputRecording.cpp index 18ed6a6c03..ff46105c71 100644 --- a/pcsx2/Recording/InputRecording.cpp +++ b/pcsx2/Recording/InputRecording.cpp @@ -15,18 +15,21 @@ #include "PrecompiledHeader.h" -#include "gui/AppSaveStates.h" +#include "common/StringUtil.h" #include "Counters.h" +#include "SaveState.h" #ifndef DISABLE_RECORDING -#include "gui/AppGameDatabase.h" +#include "GameDatabase.h" #include "DebugTools/Debug.h" #include "InputRecording.h" #include "InputRecordingControls.h" #include "Utilities/InputRecordingLogger.h" +#include "gui/AppSaveStates.h" + #include #endif @@ -448,21 +451,18 @@ void InputRecording::GoToFirstFrame(wxWindow* parent) wxString InputRecording::resolveGameName() { // Code loosely taken from AppCoreThread::_ApplySettings to resolve the Game Name - wxString gameName; - const wxString gameKey(SysGetDiscID()); - if (!gameKey.IsEmpty()) + std::string gameName; + const std::string gameKey(StringUtil::wxStringToUTF8String(SysGetDiscID())); + if (!gameKey.empty()) { - if (IGameDatabase* gameDB = AppHost_GetGameDatabase()) + const GameDatabaseSchema::GameEntry* game = GameDatabase::FindGame(gameKey); + if (game) { - GameDatabaseSchema::GameEntry game = gameDB->findGame(std::string(gameKey.ToUTF8())); - if (game.isValid) - { - gameName = fromUTF8(game.name); - gameName += L" (" + fromUTF8(game.region) + L")"; - } + gameName = game->name; + gameName += " (" + game->region + ")"; } } - return !gameName.IsEmpty() ? gameName : (wxString)Path::GetFilename(g_Conf->CurrentIso); + return !gameName.empty() ? StringUtil::UTF8StringToWxString(gameName) : Path::GetFilename(g_Conf->CurrentIso); } #endif diff --git a/pcsx2/gui/App.h b/pcsx2/gui/App.h index c54fa9f6ac..ea4b5625e9 100644 --- a/pcsx2/gui/App.h +++ b/pcsx2/gui/App.h @@ -279,7 +279,6 @@ public: std::unique_ptr IconBundle; std::unique_ptr Bitmap_Logo; std::unique_ptr ScreenshotBitmap; - std::unique_ptr GameDB; pxAppResources(); virtual ~pxAppResources(); @@ -592,7 +591,6 @@ public: wxImageList& GetImgList_Toolbars(); const AppImageIds& GetImgId() const; - AppGameDatabase* GetGameDatabase(); // -------------------------------------------------------------------------- // Overrides of wxApp virtuals: diff --git a/pcsx2/gui/AppCoreThread.cpp b/pcsx2/gui/AppCoreThread.cpp index 3f0df893fc..bc8c798929 100644 --- a/pcsx2/gui/AppCoreThread.cpp +++ b/pcsx2/gui/AppCoreThread.cpp @@ -16,9 +16,10 @@ #include "PrecompiledHeader.h" #include "App.h" #include "AppSaveStates.h" -#include "AppGameDatabase.h" +#include "GameDatabase.h" #include +#include #include "fmt/core.h" #include "common/StringUtil.h" @@ -264,9 +265,6 @@ void AppCoreThread::OnPauseDebug() // Returns number of gamefixes set static int loadGameSettings(Pcsx2Config& dest, const GameDatabaseSchema::GameEntry& game) { - if (!game.isValid) - return 0; - int gf = 0; if (game.eeRoundMode != GameDatabaseSchema::RoundMode::Undefined) @@ -450,33 +448,29 @@ static void _ApplySettings(const Pcsx2Config& src, Pcsx2Config& fixup) if (!curGameKey.IsEmpty()) { - if (IGameDatabase* GameDB = AppHost_GetGameDatabase()) + const GameDatabaseSchema::GameEntry* game = GameDatabase::FindGame(StringUtil::wxStringToUTF8String(curGameKey)); + if (game) { - GameDatabaseSchema::GameEntry game = GameDB->findGame(std::string(curGameKey.ToUTF8())); - if (game.isValid) - { - GameInfo::gameName = fromUTF8(game.name); - GameInfo::gameName += L" (" + fromUTF8(game.region) + L")"; - gameCompat = L" [Status = " + compatToStringWX(game.compat) + L"]"; - gameMemCardFilter = fromUTF8(game.memcardFiltersAsString()); - } - else - { - // Set correct title for loading standalone/homebrew ELFs - GameInfo::gameName = LastELF.AfterLast('\\'); - } + GameInfo::gameName = StringUtil::UTF8StringToWxString(StringUtil::StdStringFromFormat("%s (%s)", game->name.c_str(), game->region.c_str())); + gameCompat.Printf(" [Status = %s]", GameDatabaseSchema::compatToString(game->compat)); + gameMemCardFilter = StringUtil::UTF8StringToWxString(game->MemcardFiltersAsString()); if (fixup.EnablePatches) { - if (int patches = LoadPatchesFromGamesDB(GameInfo::gameCRC, game)) + if (int patches = LoadPatchesFromGamesDB(GameInfo::gameCRC.ToStdString(), *game)) { gamePatch.Printf(L" [%d Patches]", patches); PatchesCon->WriteLn(Color_Green, "(GameDB) Patches Loaded: %d", patches); } - if (int fixes = loadGameSettings(fixup, game)) + if (int fixes = loadGameSettings(fixup, *game)) gameFixes.Printf(L" [%d Fixes]", fixes); } } + else + { + // Set correct title for loading standalone/homebrew ELFs + GameInfo::gameName = LastELF.AfterLast('\\'); + } } if (!gameMemCardFilter.IsEmpty()) @@ -516,9 +510,12 @@ static void _ApplySettings(const Pcsx2Config& src, Pcsx2Config& fixup) { // No ws cheat files found at the cheats_ws folder, try the ws cheats zip file. wxString cheats_ws_archive = Path::Combine(PathDefs::GetProgramDataDir(), wxFileName(L"cheats_ws.zip")); - int numberDbfCheatsLoaded = LoadPatchesFromZip(GameInfo::gameCRC, cheats_ws_archive); - PatchesCon->WriteLn(Color_Green, "(Wide Screen Cheats DB) Patches Loaded: %d", numberDbfCheatsLoaded); - gameWsHacks.Printf(L" [%d widescreen hacks]", numberDbfCheatsLoaded); + if (wxFile::Exists(cheats_ws_archive)) + { + int numberDbfCheatsLoaded = LoadPatchesFromZip(GameInfo::gameCRC, cheats_ws_archive, new wxFFileInputStream(cheats_ws_archive)); + PatchesCon->WriteLn(Color_Green, "(Wide Screen Cheats DB) Patches Loaded: %d", numberDbfCheatsLoaded); + gameWsHacks.Printf(L" [%d widescreen hacks]", numberDbfCheatsLoaded); + } } } diff --git a/pcsx2/gui/AppForwardDefs.h b/pcsx2/gui/AppForwardDefs.h index 70838de29a..551955d193 100644 --- a/pcsx2/gui/AppForwardDefs.h +++ b/pcsx2/gui/AppForwardDefs.h @@ -33,7 +33,6 @@ class PipeRedirectionBase; class AppCoreThread; class Pcsx2AppMethodEvent; class pxAppResources; -class AppGameDatabase; class IScopedCoreThread; struct KeyAcceleratorCode; diff --git a/pcsx2/gui/AppGameDatabase.cpp b/pcsx2/gui/AppGameDatabase.cpp deleted file mode 100644 index b0aa707737..0000000000 --- a/pcsx2/gui/AppGameDatabase.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* PCSX2 - PS2 Emulator for PCs - * Copyright (C) 2002-2020 PCSX2 Dev Team - * - * PCSX2 is free software: you can redistribute it and/or modify it under the terms - * of the GNU Lesser General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with PCSX2. - * If not, see . - */ - -#include "PrecompiledHeader.h" - -#include "App.h" -#include "AppGameDatabase.h" - -#include -#include "fmt/core.h" -#include - -std::ifstream AppGameDatabase::getFileAsStream(const wxString& file) -{ -// TODO - config - refactor with std::filesystem/ghc::filesystem -#ifdef _WIN32 - return std::ifstream(file.wc_str()); -#else - return std::ifstream(file.c_str()); -#endif -} - -AppGameDatabase& AppGameDatabase::LoadFromFile(const wxString& _file) -{ - // TODO - config - refactor with std::filesystem/ghc::filesystem - - wxString file(_file); - if (wxFileName(file).IsRelative()) - { - // InstallFolder is the preferred base directory for the DB file, but the registry can point to previous - // installs if uninstall wasn't done properly. - // Since the games DB file is considered part of pcsx2.exe itself, look for it at the exe folder - // regardless of any other settings. - - // Note 1: Portable setup didn't suffer from this as install folder pointed already to the exe folder in portable. - // Note 2: Other folders are either configurable (memcards, etc) or create their content automatically (inis) - // So the games DB was really the only one that suffers from residues of prior installs. - - //wxDirName dir = InstallFolder; - wxDirName dir = (wxDirName)wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath(); - file = (dir + file).GetFullPath(); - } - - - if (!wxFileExists(file)) - { - Console.Error(L"[GameDB] Database Not Found! [%s]", WX_STR(file)); - return *this; - } - - const u64 qpc_Start = GetCPUTicks(); - - std::ifstream fileStream = getFileAsStream(file); - if (!this->initDatabase(fileStream)) - { - Console.Error(L"[GameDB] Database could not be loaded successfully"); - return *this; - } - - const u64 qpc_end = GetCPUTicks(); - - Console.WriteLn(fmt::format("[GameDB] {} games on record (loaded in {}ms)", this->numGames(), - (u32)(((qpc_end - qpc_Start) * 1000) / GetTickFrequency()))); - - return *this; -} - -AppGameDatabase* Pcsx2App::GetGameDatabase() -{ - pxAppResources& res(GetResourceCache()); - - ScopedLock lock(m_mtx_LoadingGameDB); - if (!res.GameDB) - { - res.GameDB = std::make_unique(); - res.GameDB->LoadFromFile(); - } - return res.GameDB.get(); -} - -IGameDatabase* AppHost_GetGameDatabase() -{ - return wxGetApp().GetGameDatabase(); -} diff --git a/pcsx2/gui/AppGameDatabase.h b/pcsx2/gui/AppGameDatabase.h deleted file mode 100644 index 78b37d0a0c..0000000000 --- a/pcsx2/gui/AppGameDatabase.h +++ /dev/null @@ -1,60 +0,0 @@ -/* PCSX2 - PS2 Emulator for PCs - * Copyright (C) 2002-2020 PCSX2 Dev Team - * - * PCSX2 is free software: you can redistribute it and/or modify it under the terms - * of the GNU Lesser General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with PCSX2. - * If not, see . - */ - -#pragma once - -#include "GameDatabase.h" - -#include "AppConfig.h" - -class AppGameDatabase : public YamlGameDatabaseImpl -{ -public: - AppGameDatabase() {} - virtual ~AppGameDatabase() - { - try - { - Console.WriteLn("(GameDB) Unloading..."); - } - DESTRUCTOR_CATCHALL - } - - AppGameDatabase& LoadFromFile(const wxString& file = Path::Combine(PathDefs::GetProgramDataDir(), wxFileName(L"GameIndex.yaml"))); - -private: - std::ifstream getFileAsStream(const wxString& file); -}; - -static wxString compatToStringWX(GameDatabaseSchema::Compatibility compat) -{ - switch (compat) - { - case GameDatabaseSchema::Compatibility::Perfect: - return L"Perfect"; - case GameDatabaseSchema::Compatibility::Playable: - return L"Playable"; - case GameDatabaseSchema::Compatibility::InGame: - return L"In-Game"; - case GameDatabaseSchema::Compatibility::Menu: - return L"Menu"; - case GameDatabaseSchema::Compatibility::Intro: - return L"Intro"; - case GameDatabaseSchema::Compatibility::Nothing: - return L"Nothing"; - default: - return L"Unknown"; - } -} diff --git a/pcsx2/gui/AppInit.cpp b/pcsx2/gui/AppInit.cpp index f856444bfc..ff5fffe568 100644 --- a/pcsx2/gui/AppInit.cpp +++ b/pcsx2/gui/AppInit.cpp @@ -352,47 +352,6 @@ bool Pcsx2App::OnCmdLineParsed(wxCmdLineParser& parser) typedef void (wxEvtHandler::*pxInvokeAppMethodEventFunction)(Pcsx2AppMethodEvent&); typedef void (wxEvtHandler::*pxStuckThreadEventHandler)(pxMessageBoxEvent&); -// -------------------------------------------------------------------------------------- -// GameDatabaseLoaderThread -// -------------------------------------------------------------------------------------- -class GameDatabaseLoaderThread : public pxThread, EventListener_AppStatus -{ - typedef pxThread _parent; - -public: - GameDatabaseLoaderThread() - : pxThread(L"GameDatabaseLoader") - { - } - - virtual ~GameDatabaseLoaderThread() - { - try - { - _parent::Cancel(); - } - DESTRUCTOR_CATCHALL - } - -protected: - void ExecuteTaskInThread() - { - Sleep(2); - wxGetApp().GetGameDatabase(); - } - - void OnCleanupInThread() - { - _parent::OnCleanupInThread(); - wxGetApp().DeleteThread(this); - } - - void AppStatusEvent_OnExit() - { - Block(); - } -}; - bool Pcsx2App::OnInit() { EnableAllLogging(); @@ -464,8 +423,6 @@ bool Pcsx2App::OnInit() OpenMainFrame(); - (new GameDatabaseLoaderThread())->Start(); - // By default no IRX injection EmuConfig.CurrentIRX.clear(); diff --git a/pcsx2/gui/AppMain.cpp b/pcsx2/gui/AppMain.cpp index e6fe698a66..7657bd256a 100644 --- a/pcsx2/gui/AppMain.cpp +++ b/pcsx2/gui/AppMain.cpp @@ -20,7 +20,6 @@ #include "GS.h" #include "Host.h" #include "AppSaveStates.h" -#include "AppGameDatabase.h" #include "AppAccelerators.h" #include "PAD/Gamepad.h" diff --git a/pcsx2/gui/AppRes.cpp b/pcsx2/gui/AppRes.cpp index 4c741e0734..87259607ea 100644 --- a/pcsx2/gui/AppRes.cpp +++ b/pcsx2/gui/AppRes.cpp @@ -15,7 +15,6 @@ #include "PrecompiledHeader.h" #include "MainFrame.h" -#include "AppGameDatabase.h" #include #include diff --git a/pcsx2/pcsx2.vcxproj b/pcsx2/pcsx2.vcxproj index edd96db5b9..6600f4ddf5 100644 --- a/pcsx2/pcsx2.vcxproj +++ b/pcsx2/pcsx2.vcxproj @@ -307,7 +307,6 @@ - @@ -746,7 +745,6 @@ - diff --git a/pcsx2/pcsx2.vcxproj.filters b/pcsx2/pcsx2.vcxproj.filters index eea503422a..9eddddb008 100644 --- a/pcsx2/pcsx2.vcxproj.filters +++ b/pcsx2/pcsx2.vcxproj.filters @@ -884,9 +884,6 @@ AppHost - - AppHost - AppHost\Dialogs @@ -2008,9 +2005,6 @@ System\Ps2\IPU - - AppHost - AppHost