System: Hash executable for game code when system.cnf missing
This commit is contained in:
parent
ac4dd11fa0
commit
6bbb1128b6
|
@ -32,6 +32,7 @@
|
||||||
#include "spu.h"
|
#include "spu.h"
|
||||||
#include "texture_replacements.h"
|
#include "texture_replacements.h"
|
||||||
#include "timers.h"
|
#include "timers.h"
|
||||||
|
#include "xxhash.h"
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
@ -385,39 +386,57 @@ std::string_view GetTitleForPath(const char* path)
|
||||||
return path_view.substr(0, path_view.find_last_of('.'));
|
return path_view.substr(0, path_view.find_last_of('.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GetGameCodeForPath(const char* image_path)
|
std::string GetGameCodeForPath(const char* image_path, bool fallback_to_hash)
|
||||||
{
|
{
|
||||||
std::unique_ptr<CDImage> cdi = CDImage::Open(image_path);
|
std::unique_ptr<CDImage> cdi = CDImage::Open(image_path);
|
||||||
if (!cdi)
|
if (!cdi)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
return GetGameCodeForImage(cdi.get());
|
return GetGameCodeForImage(cdi.get(), fallback_to_hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GetGameCodeForImage(CDImage* cdi)
|
std::string GetGameCodeForImage(CDImage* cdi, bool fallback_to_hash)
|
||||||
{
|
{
|
||||||
std::string code(GetExecutableNameForImage(cdi));
|
std::string code(GetExecutableNameForImage(cdi));
|
||||||
if (code.empty())
|
if (!code.empty())
|
||||||
return {};
|
|
||||||
|
|
||||||
// SCES_123.45 -> SCES-12345
|
|
||||||
for (std::string::size_type pos = 0; pos < code.size();)
|
|
||||||
{
|
{
|
||||||
if (code[pos] == '.')
|
// SCES_123.45 -> SCES-12345
|
||||||
|
for (std::string::size_type pos = 0; pos < code.size();)
|
||||||
{
|
{
|
||||||
code.erase(pos, 1);
|
if (code[pos] == '.')
|
||||||
continue;
|
{
|
||||||
|
code.erase(pos, 1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code[pos] == '_')
|
||||||
|
code[pos] = '-';
|
||||||
|
else
|
||||||
|
code[pos] = static_cast<char>(std::toupper(code[pos]));
|
||||||
|
|
||||||
|
pos++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code[pos] == '_')
|
return code;
|
||||||
code[pos] = '-';
|
|
||||||
else
|
|
||||||
code[pos] = static_cast<char>(std::toupper(code[pos]));
|
|
||||||
|
|
||||||
pos++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return code;
|
if (!fallback_to_hash)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
std::string exe_name;
|
||||||
|
std::vector<u8> exe_buffer;
|
||||||
|
if (!ReadExecutableFromImage(cdi, &exe_name, &exe_buffer))
|
||||||
|
return {};
|
||||||
|
|
||||||
|
XXH64_state_t* state = XXH64_createState();
|
||||||
|
XXH64_reset(state, 0x4242D00C);
|
||||||
|
XXH64_update(state, exe_name.c_str(), exe_name.size());
|
||||||
|
XXH64_update(state, exe_buffer.data(), exe_buffer.size());
|
||||||
|
const u64 hash = XXH64_digest(state);
|
||||||
|
XXH64_freeState(state);
|
||||||
|
|
||||||
|
Log_InfoPrintf("Hash for '%s' - %" PRIX64, exe_name.c_str(), hash);
|
||||||
|
return StringUtil::StdStringFromFormat("HASH-%" PRIX64, hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string GetExecutableNameForImage(CDImage* cdi, ISOReader& iso, bool strip_subdirectories)
|
static std::string GetExecutableNameForImage(CDImage* cdi, ISOReader& iso, bool strip_subdirectories)
|
||||||
|
@ -601,7 +620,7 @@ DiscRegion GetRegionForImage(CDImage* cdi)
|
||||||
if (system_area_region != DiscRegion::Other)
|
if (system_area_region != DiscRegion::Other)
|
||||||
return system_area_region;
|
return system_area_region;
|
||||||
|
|
||||||
std::string code = GetGameCodeForImage(cdi);
|
std::string code = GetGameCodeForImage(cdi, false);
|
||||||
if (code.empty())
|
if (code.empty())
|
||||||
return DiscRegion::Other;
|
return DiscRegion::Other;
|
||||||
|
|
||||||
|
|
|
@ -78,8 +78,8 @@ ConsoleRegion GetConsoleRegionForDiscRegion(DiscRegion region);
|
||||||
std::string GetExecutableNameForImage(CDImage* cdi);
|
std::string GetExecutableNameForImage(CDImage* cdi);
|
||||||
bool ReadExecutableFromImage(CDImage* cdi, std::string* out_executable_name, std::vector<u8>* out_executable_data);
|
bool ReadExecutableFromImage(CDImage* cdi, std::string* out_executable_name, std::vector<u8>* out_executable_data);
|
||||||
|
|
||||||
std::string GetGameCodeForImage(CDImage* cdi);
|
std::string GetGameCodeForImage(CDImage* cdi, bool fallback_to_hash);
|
||||||
std::string GetGameCodeForPath(const char* image_path);
|
std::string GetGameCodeForPath(const char* image_path, bool fallback_to_hash);
|
||||||
DiscRegion GetRegionForCode(std::string_view code);
|
DiscRegion GetRegionForCode(std::string_view code);
|
||||||
DiscRegion GetRegionFromSystemArea(CDImage* cdi);
|
DiscRegion GetRegionFromSystemArea(CDImage* cdi);
|
||||||
DiscRegion GetRegionForImage(CDImage* cdi);
|
DiscRegion GetRegionForImage(CDImage* cdi);
|
||||||
|
|
|
@ -415,7 +415,7 @@ bool CommonHostInterface::ParseCommandLineParameters(int argc, char* argv[],
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// find the game id, and get its save state path
|
// find the game id, and get its save state path
|
||||||
std::string game_code = System::GetGameCodeForPath(boot_filename.c_str());
|
std::string game_code = System::GetGameCodeForPath(boot_filename.c_str(), true);
|
||||||
if (game_code.empty())
|
if (game_code.empty())
|
||||||
{
|
{
|
||||||
Log_WarningPrintf("Could not identify game code for '%s', cannot load save state %d.", boot_filename.c_str(),
|
Log_WarningPrintf("Could not identify game code for '%s', cannot load save state %d.", boot_filename.c_str(),
|
||||||
|
@ -2867,7 +2867,7 @@ void CommonHostInterface::GetGameInfo(const char* path, CDImage* image, std::str
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (image)
|
if (image)
|
||||||
*code = System::GetGameCodeForImage(image);
|
*code = System::GetGameCodeForImage(image, true);
|
||||||
|
|
||||||
const GameListDatabaseEntry* db_entry = (!code->empty()) ? m_game_list->GetDatabaseEntryForCode(*code) : nullptr;
|
const GameListDatabaseEntry* db_entry = (!code->empty()) ? m_game_list->GetDatabaseEntryForCode(*code) : nullptr;
|
||||||
if (db_entry)
|
if (db_entry)
|
||||||
|
|
|
@ -181,7 +181,7 @@ bool GameList::GetM3UListEntry(const char* path, GameListEntry* entry)
|
||||||
|
|
||||||
if (entry->compatibility_rating == GameListCompatibilityRating::Unknown)
|
if (entry->compatibility_rating == GameListCompatibilityRating::Unknown)
|
||||||
{
|
{
|
||||||
std::string code = System::GetGameCodeForImage(entry_image.get());
|
std::string code = System::GetGameCodeForImage(entry_image.get(), true);
|
||||||
const GameListCompatibilityEntry* compatibility_entry = GetCompatibilityEntryForCode(entry->code);
|
const GameListCompatibilityEntry* compatibility_entry = GetCompatibilityEntryForCode(entry->code);
|
||||||
if (compatibility_entry)
|
if (compatibility_entry)
|
||||||
entry->compatibility_rating = compatibility_entry->compatibility_rating;
|
entry->compatibility_rating = compatibility_entry->compatibility_rating;
|
||||||
|
@ -206,7 +206,7 @@ bool GameList::GetGameListEntry(const std::string& path, GameListEntry* entry)
|
||||||
if (!cdi)
|
if (!cdi)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::string code = System::GetGameCodeForImage(cdi.get());
|
std::string code = System::GetGameCodeForImage(cdi.get(), true);
|
||||||
DiscRegion region = System::GetRegionFromSystemArea(cdi.get());
|
DiscRegion region = System::GetRegionFromSystemArea(cdi.get());
|
||||||
if (region == DiscRegion::Other)
|
if (region == DiscRegion::Other)
|
||||||
region = System::GetRegionForCode(code);
|
region = System::GetRegionForCode(code);
|
||||||
|
|
Loading…
Reference in New Issue