mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-18 19:45:47 -04:00
System: Store game hash as well as serial
This commit is contained in:
@ -470,7 +470,7 @@ void Achievements::Initialize()
|
||||
s_logged_in = (!s_username.empty() && !s_api_token.empty());
|
||||
|
||||
if (System::IsValid())
|
||||
GameChanged(System::GetRunningPath(), nullptr);
|
||||
GameChanged(System::GetDiscPath(), nullptr);
|
||||
}
|
||||
|
||||
void Achievements::UpdateSettings(const Settings& old_config)
|
||||
@ -2142,7 +2142,7 @@ void Achievements::RAIntegration::RACallbackRebuildMenu()
|
||||
|
||||
void Achievements::RAIntegration::RACallbackEstimateTitle(char* buf)
|
||||
{
|
||||
StringUtil::Strlcpy(buf, System::GetRunningTitle(), 256);
|
||||
StringUtil::Strlcpy(buf, System::GetGameTitle(), 256);
|
||||
}
|
||||
|
||||
void Achievements::RAIntegration::RACallbackResetEmulator()
|
||||
|
@ -570,8 +570,8 @@ void CommonHost::UpdateDiscordPresence(bool rich_presence_only)
|
||||
SmallString details_string;
|
||||
if (!System::IsShutdown())
|
||||
{
|
||||
details_string.AppendFormattedString("%s (%s)", System::GetRunningTitle().c_str(),
|
||||
System::GetRunningSerial().c_str());
|
||||
details_string.AppendFormattedString("%s (%s)", System::GetGameTitle().c_str(),
|
||||
System::GetGameSerial().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -635,7 +635,7 @@ static void HotkeyLoadStateSlot(bool global, s32 slot)
|
||||
if (!System::IsValid())
|
||||
return;
|
||||
|
||||
if (!global && System::GetRunningSerial().empty())
|
||||
if (!global && System::GetGameSerial().empty())
|
||||
{
|
||||
Host::AddKeyedOSDMessage("LoadState", TRANSLATABLE("OSDMessage", "Cannot load state for game without serial."),
|
||||
5.0f);
|
||||
@ -643,7 +643,7 @@ static void HotkeyLoadStateSlot(bool global, s32 slot)
|
||||
}
|
||||
|
||||
std::string path(global ? System::GetGlobalSaveStateFileName(slot) :
|
||||
System::GetGameSaveStateFileName(System::GetRunningSerial(), slot));
|
||||
System::GetGameSaveStateFileName(System::GetGameSerial(), slot));
|
||||
if (!FileSystem::FileExists(path.c_str()))
|
||||
{
|
||||
Host::AddKeyedOSDMessage("LoadState",
|
||||
@ -659,7 +659,7 @@ static void HotkeySaveStateSlot(bool global, s32 slot)
|
||||
if (!System::IsValid())
|
||||
return;
|
||||
|
||||
if (!global && System::GetRunningSerial().empty())
|
||||
if (!global && System::GetGameSerial().empty())
|
||||
{
|
||||
Host::AddKeyedOSDMessage("LoadState", TRANSLATABLE("OSDMessage", "Cannot save state for game without serial."),
|
||||
5.0f);
|
||||
@ -667,7 +667,7 @@ static void HotkeySaveStateSlot(bool global, s32 slot)
|
||||
}
|
||||
|
||||
std::string path(global ? System::GetGlobalSaveStateFileName(slot) :
|
||||
System::GetGameSaveStateFileName(System::GetRunningSerial(), slot));
|
||||
System::GetGameSaveStateFileName(System::GetGameSerial(), slot));
|
||||
System::SaveState(path.c_str(), g_settings.create_save_state_backups);
|
||||
}
|
||||
|
||||
|
@ -654,8 +654,8 @@ void FullscreenUI::OnRunningGameChanged()
|
||||
if (!IsInitialized())
|
||||
return;
|
||||
|
||||
const std::string& path = System::GetRunningPath();
|
||||
const std::string& serial = System::GetRunningSerial();
|
||||
const std::string& path = System::GetDiscPath();
|
||||
const std::string& serial = System::GetGameSerial();
|
||||
if (!serial.empty())
|
||||
s_current_game_subtitle = fmt::format("{0} - {1}", serial, Path::GetFileName(path));
|
||||
else
|
||||
@ -963,7 +963,7 @@ void FullscreenUI::DoChangeDiscFromFile()
|
||||
};
|
||||
|
||||
OpenFileSelector(ICON_FA_COMPACT_DISC " Select Disc Image", false, std::move(callback), GetDiscImageFilters(),
|
||||
std::string(Path::GetDirectory(System::GetRunningPath())));
|
||||
std::string(Path::GetDirectory(System::GetDiscPath())));
|
||||
}
|
||||
|
||||
void FullscreenUI::DoChangeDisc()
|
||||
@ -1010,7 +1010,7 @@ void FullscreenUI::DoCheatsMenu()
|
||||
{
|
||||
if (!System::LoadCheatListFromDatabase() || ((cl = System::GetCheatList()) == nullptr))
|
||||
{
|
||||
Host::AddKeyedOSDMessage("load_cheat_list", fmt::format("No cheats found for {}.", System::GetRunningTitle()),
|
||||
Host::AddKeyedOSDMessage("load_cheat_list", fmt::format("No cheats found for {}.", System::GetGameTitle()),
|
||||
10.0f);
|
||||
ReturnToMainWindow();
|
||||
return;
|
||||
@ -2325,14 +2325,14 @@ void FullscreenUI::SwitchToGameSettingsForSerial(const std::string_view& serial)
|
||||
|
||||
void FullscreenUI::SwitchToGameSettings()
|
||||
{
|
||||
if (System::GetRunningSerial().empty())
|
||||
if (System::GetGameSerial().empty())
|
||||
return;
|
||||
|
||||
auto lock = GameList::GetLock();
|
||||
const GameList::Entry* entry = GameList::GetEntryForPath(System::GetRunningPath().c_str());
|
||||
const GameList::Entry* entry = GameList::GetEntryForPath(System::GetDiscPath().c_str());
|
||||
if (!entry)
|
||||
{
|
||||
SwitchToGameSettingsForSerial(System::GetRunningSerial());
|
||||
SwitchToGameSettingsForSerial(System::GetGameSerial());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -4561,12 +4561,12 @@ void FullscreenUI::DrawPauseMenu(MainWindowType type)
|
||||
|
||||
// title info
|
||||
{
|
||||
const std::string& title = System::GetRunningTitle();
|
||||
const std::string& serial = System::GetRunningSerial();
|
||||
const std::string& title = System::GetGameTitle();
|
||||
const std::string& serial = System::GetGameSerial();
|
||||
|
||||
if (!serial.empty())
|
||||
buffer.Format("%s - ", serial.c_str());
|
||||
buffer.AppendString(Path::GetFileName(System::GetRunningPath()));
|
||||
buffer.AppendString(Path::GetFileName(System::GetDiscPath()));
|
||||
|
||||
const ImVec2 title_size(
|
||||
g_large_font->CalcTextSizeA(g_large_font->FontSize, std::numeric_limits<float>::max(), -1.0f, title.c_str()));
|
||||
@ -4624,7 +4624,7 @@ void FullscreenUI::DrawPauseMenu(MainWindowType type)
|
||||
DrawShadowedText(dl, g_large_font, time_pos, IM_COL32(255, 255, 255, 255), buffer.GetCharArray(),
|
||||
buffer.GetCharArray() + buffer.GetLength());
|
||||
|
||||
const std::string& serial = System::GetRunningSerial();
|
||||
const std::string& serial = System::GetGameSerial();
|
||||
if (!serial.empty())
|
||||
{
|
||||
const std::time_t cached_played_time = GameList::GetCachedPlayedTimeForSerial(serial);
|
||||
@ -4674,7 +4674,7 @@ void FullscreenUI::DrawPauseMenu(MainWindowType type)
|
||||
case PauseSubMenu::None:
|
||||
{
|
||||
// NOTE: Menu close must come first, because otherwise VM destruction options will race.
|
||||
const bool has_game = System::IsValid() && !System::GetRunningSerial().empty();
|
||||
const bool has_game = System::IsValid() && !System::GetGameSerial().empty();
|
||||
|
||||
if (ActiveButton(ICON_FA_PLAY " Resume Game", false) || WantsToCloseMenu())
|
||||
ClosePauseMenu();
|
||||
@ -4698,7 +4698,7 @@ void FullscreenUI::DrawPauseMenu(MainWindowType type)
|
||||
}
|
||||
|
||||
if (ActiveButton(ICON_FA_FROWN_OPEN " Cheat List", false,
|
||||
!System::GetRunningSerial().empty() && !Achievements::ChallengeModeActive()))
|
||||
!System::GetGameSerial().empty() && !Achievements::ChallengeModeActive()))
|
||||
{
|
||||
s_current_main_window = MainWindowType::None;
|
||||
DoCheatsMenu();
|
||||
@ -4944,7 +4944,7 @@ bool FullscreenUI::OpenSaveStateSelector(bool is_loading)
|
||||
s_save_state_selector_game_path = {};
|
||||
s_save_state_selector_loading = is_loading;
|
||||
s_save_state_selector_resuming = false;
|
||||
if (PopulateSaveStateListEntries(System::GetRunningTitle().c_str(), System::GetRunningSerial().c_str()) > 0)
|
||||
if (PopulateSaveStateListEntries(System::GetGameTitle().c_str(), System::GetGameSerial().c_str()) > 0)
|
||||
{
|
||||
s_save_state_selector_open = true;
|
||||
return true;
|
||||
@ -5380,7 +5380,7 @@ void FullscreenUI::DoSaveState(s32 slot, bool global)
|
||||
return;
|
||||
|
||||
std::string filename(global ? System::GetGlobalSaveStateFileName(slot) :
|
||||
System::GetGameSaveStateFileName(System::GetRunningSerial(), slot));
|
||||
System::GetGameSaveStateFileName(System::GetGameSerial(), slot));
|
||||
System::SaveState(filename.c_str(), g_settings.create_save_state_backups);
|
||||
});
|
||||
}
|
||||
@ -6172,7 +6172,7 @@ GPUTexture* FullscreenUI::GetCoverForCurrentGame()
|
||||
{
|
||||
auto lock = GameList::GetLock();
|
||||
|
||||
const GameList::Entry* entry = GameList::GetEntryForPath(System::GetRunningPath().c_str());
|
||||
const GameList::Entry* entry = GameList::GetEntryForPath(System::GetDiscPath().c_str());
|
||||
if (!entry)
|
||||
return s_fallback_disc_texture.get();
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
|
||||
// SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin <stenzek@gmail.com>
|
||||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
#include "game_list.h"
|
||||
@ -18,13 +18,14 @@
|
||||
#include "core/psf_loader.h"
|
||||
#include "core/settings.h"
|
||||
#include "core/system.h"
|
||||
#include "tinyxml2.h"
|
||||
#include "util/cd_image.h"
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cctype>
|
||||
#include <ctime>
|
||||
#include <string_view>
|
||||
#include <tinyxml2.h>
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
Log_SetChannel(GameList);
|
||||
@ -37,7 +38,7 @@ namespace GameList {
|
||||
enum : u32
|
||||
{
|
||||
GAME_LIST_CACHE_SIGNATURE = 0x45434C47,
|
||||
GAME_LIST_CACHE_VERSION = 32,
|
||||
GAME_LIST_CACHE_VERSION = 33,
|
||||
|
||||
PLAYED_TIME_SERIAL_LENGTH = 32,
|
||||
PLAYED_TIME_LAST_TIME_LENGTH = 20, // uint64
|
||||
@ -55,6 +56,8 @@ struct PlayedTimeEntry
|
||||
using CacheMap = UnorderedStringMap<Entry>;
|
||||
using PlayedTimeMap = UnorderedStringMap<PlayedTimeEntry>;
|
||||
|
||||
static_assert(std::is_same_v<decltype(Entry::hash), System::GameHash>);
|
||||
|
||||
static bool GetExeListEntry(const std::string& path, Entry* entry);
|
||||
static bool GetPsfListEntry(const std::string& path, Entry* entry);
|
||||
static bool GetDiscListEntry(const std::string& path, Entry* entry);
|
||||
@ -204,8 +207,11 @@ bool GameList::GetDiscListEntry(const std::string& path, Entry* entry)
|
||||
entry->type = EntryType::Disc;
|
||||
entry->compatibility = GameDatabase::CompatibilityRating::Unknown;
|
||||
|
||||
std::string id;
|
||||
System::GetGameDetailsFromImage(cdi.get(), &id, &entry->hash);
|
||||
|
||||
// try the database first
|
||||
const GameDatabase::Entry* dentry = GameDatabase::GetEntryForDisc(cdi.get());
|
||||
const GameDatabase::Entry* dentry = GameDatabase::GetEntryForId(id);
|
||||
if (dentry)
|
||||
{
|
||||
// pull from database
|
||||
@ -227,7 +233,7 @@ bool GameList::GetDiscListEntry(const std::string& path, Entry* entry)
|
||||
const std::string display_name(FileSystem::GetDisplayNameFromPath(path));
|
||||
|
||||
// no game code, so use the filename title
|
||||
entry->serial = System::GetGameIdFromImage(cdi.get(), true);
|
||||
entry->serial = std::move(id);
|
||||
entry->title = Path::GetFileTitle(display_name);
|
||||
entry->compatibility = GameDatabase::CompatibilityRating::Unknown;
|
||||
entry->release_date = 0;
|
||||
@ -239,9 +245,7 @@ bool GameList::GetDiscListEntry(const std::string& path, Entry* entry)
|
||||
}
|
||||
|
||||
// region detection
|
||||
entry->region = System::GetRegionFromSystemArea(cdi.get());
|
||||
if (entry->region == DiscRegion::Other)
|
||||
entry->region = System::GetRegionForSerial(entry->serial);
|
||||
entry->region = System::GetRegionForImage(cdi.get());
|
||||
|
||||
if (cdi->HasSubImages())
|
||||
{
|
||||
@ -310,12 +314,12 @@ bool GameList::LoadEntriesFromCache(ByteStream* stream)
|
||||
if (!stream->ReadU8(&type) || !stream->ReadU8(®ion) || !stream->ReadSizePrefixedString(&path) ||
|
||||
!stream->ReadSizePrefixedString(&ge.serial) || !stream->ReadSizePrefixedString(&ge.title) ||
|
||||
!stream->ReadSizePrefixedString(&ge.genre) || !stream->ReadSizePrefixedString(&ge.publisher) ||
|
||||
!stream->ReadSizePrefixedString(&ge.developer) || !stream->ReadU64(&ge.total_size) ||
|
||||
!stream->ReadU64(reinterpret_cast<u64*>(&ge.last_modified_time)) || !stream->ReadU64(&ge.release_date) ||
|
||||
!stream->ReadU32(&ge.supported_controllers) || !stream->ReadU8(&ge.min_players) ||
|
||||
!stream->ReadU8(&ge.max_players) || !stream->ReadU8(&ge.min_blocks) || !stream->ReadU8(&ge.max_blocks) ||
|
||||
!stream->ReadU8(&compatibility_rating) || region >= static_cast<u8>(DiscRegion::Count) ||
|
||||
type >= static_cast<u8>(EntryType::Count) ||
|
||||
!stream->ReadSizePrefixedString(&ge.developer) || !stream->ReadU64(&ge.hash) ||
|
||||
!stream->ReadU64(&ge.total_size) || !stream->ReadU64(reinterpret_cast<u64*>(&ge.last_modified_time)) ||
|
||||
!stream->ReadU64(&ge.release_date) || !stream->ReadU32(&ge.supported_controllers) ||
|
||||
!stream->ReadU8(&ge.min_players) || !stream->ReadU8(&ge.max_players) || !stream->ReadU8(&ge.min_blocks) ||
|
||||
!stream->ReadU8(&ge.max_blocks) || !stream->ReadU8(&compatibility_rating) ||
|
||||
region >= static_cast<u8>(DiscRegion::Count) || type >= static_cast<u8>(EntryType::Count) ||
|
||||
compatibility_rating >= static_cast<u8>(GameDatabase::CompatibilityRating::Count))
|
||||
{
|
||||
Log_WarningPrintf("Game list cache entry is corrupted");
|
||||
@ -348,6 +352,7 @@ bool GameList::WriteEntryToCache(const Entry* entry)
|
||||
result &= s_cache_write_stream->WriteSizePrefixedString(entry->genre);
|
||||
result &= s_cache_write_stream->WriteSizePrefixedString(entry->publisher);
|
||||
result &= s_cache_write_stream->WriteSizePrefixedString(entry->developer);
|
||||
result &= s_cache_write_stream->WriteU64(entry->hash);
|
||||
result &= s_cache_write_stream->WriteU64(entry->total_size);
|
||||
result &= s_cache_write_stream->WriteU64(entry->last_modified_time);
|
||||
result &= s_cache_write_stream->WriteU64(entry->release_date);
|
||||
|
@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
|
||||
// SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin <stenzek@gmail.com>
|
||||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
#pragma once
|
||||
@ -37,6 +37,7 @@ struct Entry
|
||||
std::string genre;
|
||||
std::string publisher;
|
||||
std::string developer;
|
||||
u64 hash = 0;
|
||||
u64 total_size = 0;
|
||||
std::time_t last_modified_time = 0;
|
||||
std::time_t last_played_time = 0;
|
||||
|
@ -621,11 +621,11 @@ void SaveStateSelectorUI::RefreshList()
|
||||
if (System::IsShutdown())
|
||||
return;
|
||||
|
||||
if (!System::GetRunningSerial().empty())
|
||||
if (!System::GetGameSerial().empty())
|
||||
{
|
||||
for (s32 i = 1; i <= System::PER_GAME_SAVE_STATE_SLOTS; i++)
|
||||
{
|
||||
std::string path(System::GetGameSaveStateFileName(System::GetRunningSerial(), i));
|
||||
std::string path(System::GetGameSaveStateFileName(System::GetGameSerial(), i));
|
||||
std::optional<ExtendedSaveStateInfo> ssi = System::GetExtendedSaveStateInfo(path.c_str());
|
||||
|
||||
ListEntry li;
|
||||
|
Reference in New Issue
Block a user