mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-26 23:55:40 +00:00
Qt: Fix 'Edit Memory Cards' using disc-specific cards
This commit is contained in:
parent
e382f2b64a
commit
c482dfd27a
|
@ -40,7 +40,7 @@ namespace {
|
||||||
|
|
||||||
enum : u32
|
enum : u32
|
||||||
{
|
{
|
||||||
GAME_LIST_CACHE_SIGNATURE = 0x45434C47,
|
GAME_LIST_CACHE_SIGNATURE = 0x45434C48,
|
||||||
GAME_LIST_CACHE_VERSION = 34,
|
GAME_LIST_CACHE_VERSION = 34,
|
||||||
|
|
||||||
PLAYED_TIME_SERIAL_LENGTH = 32,
|
PLAYED_TIME_SERIAL_LENGTH = 32,
|
||||||
|
@ -232,6 +232,19 @@ bool GameList::GetDiscListEntry(const std::string& path, Entry* entry)
|
||||||
entry->max_blocks = dentry->max_blocks;
|
entry->max_blocks = dentry->max_blocks;
|
||||||
entry->supported_controllers = dentry->supported_controllers;
|
entry->supported_controllers = dentry->supported_controllers;
|
||||||
entry->compatibility = dentry->compatibility;
|
entry->compatibility = dentry->compatibility;
|
||||||
|
|
||||||
|
if (!cdi->HasSubImages())
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < dentry->disc_set_serials.size(); i++)
|
||||||
|
{
|
||||||
|
if (dentry->disc_set_serials[i] == entry->serial)
|
||||||
|
{
|
||||||
|
entry->disc_set_name = dentry->disc_set_name;
|
||||||
|
entry->disc_set_index = static_cast<s8>(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -318,12 +331,13 @@ bool GameList::LoadEntriesFromCache(ByteStream* stream)
|
||||||
|
|
||||||
if (!stream->ReadU8(&type) || !stream->ReadU8(®ion) || !stream->ReadSizePrefixedString(&path) ||
|
if (!stream->ReadU8(&type) || !stream->ReadU8(®ion) || !stream->ReadSizePrefixedString(&path) ||
|
||||||
!stream->ReadSizePrefixedString(&ge.serial) || !stream->ReadSizePrefixedString(&ge.title) ||
|
!stream->ReadSizePrefixedString(&ge.serial) || !stream->ReadSizePrefixedString(&ge.title) ||
|
||||||
!stream->ReadSizePrefixedString(&ge.genre) || !stream->ReadSizePrefixedString(&ge.publisher) ||
|
!stream->ReadSizePrefixedString(&ge.disc_set_name) || !stream->ReadSizePrefixedString(&ge.genre) ||
|
||||||
!stream->ReadSizePrefixedString(&ge.developer) || !stream->ReadU64(&ge.hash) ||
|
!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.hash) || !stream->ReadU64(&ge.total_size) ||
|
||||||
!stream->ReadU64(&ge.release_date) || !stream->ReadU16(&ge.supported_controllers) ||
|
!stream->ReadU64(reinterpret_cast<u64*>(&ge.last_modified_time)) || !stream->ReadU64(&ge.release_date) ||
|
||||||
!stream->ReadU8(&ge.min_players) || !stream->ReadU8(&ge.max_players) || !stream->ReadU8(&ge.min_blocks) ||
|
!stream->ReadU16(&ge.supported_controllers) || !stream->ReadU8(&ge.min_players) ||
|
||||||
!stream->ReadU8(&ge.max_blocks) || !stream->ReadU8(&compatibility_rating) ||
|
!stream->ReadU8(&ge.max_players) || !stream->ReadU8(&ge.min_blocks) || !stream->ReadU8(&ge.max_blocks) ||
|
||||||
|
!stream->ReadS8(&ge.disc_set_index) || !stream->ReadU8(&compatibility_rating) ||
|
||||||
region >= static_cast<u8>(DiscRegion::Count) || type >= static_cast<u8>(EntryType::Count) ||
|
region >= static_cast<u8>(DiscRegion::Count) || type >= static_cast<u8>(EntryType::Count) ||
|
||||||
compatibility_rating >= static_cast<u8>(GameDatabase::CompatibilityRating::Count))
|
compatibility_rating >= static_cast<u8>(GameDatabase::CompatibilityRating::Count))
|
||||||
{
|
{
|
||||||
|
@ -354,6 +368,7 @@ bool GameList::WriteEntryToCache(const Entry* entry)
|
||||||
result &= s_cache_write_stream->WriteSizePrefixedString(entry->path);
|
result &= s_cache_write_stream->WriteSizePrefixedString(entry->path);
|
||||||
result &= s_cache_write_stream->WriteSizePrefixedString(entry->serial);
|
result &= s_cache_write_stream->WriteSizePrefixedString(entry->serial);
|
||||||
result &= s_cache_write_stream->WriteSizePrefixedString(entry->title);
|
result &= s_cache_write_stream->WriteSizePrefixedString(entry->title);
|
||||||
|
result &= s_cache_write_stream->WriteSizePrefixedString(entry->disc_set_name);
|
||||||
result &= s_cache_write_stream->WriteSizePrefixedString(entry->genre);
|
result &= s_cache_write_stream->WriteSizePrefixedString(entry->genre);
|
||||||
result &= s_cache_write_stream->WriteSizePrefixedString(entry->publisher);
|
result &= s_cache_write_stream->WriteSizePrefixedString(entry->publisher);
|
||||||
result &= s_cache_write_stream->WriteSizePrefixedString(entry->developer);
|
result &= s_cache_write_stream->WriteSizePrefixedString(entry->developer);
|
||||||
|
@ -366,6 +381,7 @@ bool GameList::WriteEntryToCache(const Entry* entry)
|
||||||
result &= s_cache_write_stream->WriteU8(entry->max_players);
|
result &= s_cache_write_stream->WriteU8(entry->max_players);
|
||||||
result &= s_cache_write_stream->WriteU8(entry->min_blocks);
|
result &= s_cache_write_stream->WriteU8(entry->min_blocks);
|
||||||
result &= s_cache_write_stream->WriteU8(entry->max_blocks);
|
result &= s_cache_write_stream->WriteU8(entry->max_blocks);
|
||||||
|
result &= s_cache_write_stream->WriteS8(entry->disc_set_index);
|
||||||
result &= s_cache_write_stream->WriteU8(static_cast<u8>(entry->compatibility));
|
result &= s_cache_write_stream->WriteU8(static_cast<u8>(entry->compatibility));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -581,7 +597,7 @@ const GameList::Entry* GameList::GetEntryForPath(const char* path)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const GameList::Entry* GameList::GetEntryBySerial(const std::string_view& serial)
|
const GameList::Entry* GameList::GetEntryBySerial(std::string_view serial)
|
||||||
{
|
{
|
||||||
for (const Entry& entry : s_entries)
|
for (const Entry& entry : s_entries)
|
||||||
{
|
{
|
||||||
|
@ -595,7 +611,7 @@ const GameList::Entry* GameList::GetEntryBySerial(const std::string_view& serial
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const GameList::Entry* GameList::GetEntryBySerialAndHash(const std::string_view& serial, u64 hash)
|
const GameList::Entry* GameList::GetEntryBySerialAndHash(std::string_view serial, u64 hash)
|
||||||
{
|
{
|
||||||
for (const Entry& entry : s_entries)
|
for (const Entry& entry : s_entries)
|
||||||
{
|
{
|
||||||
|
@ -606,6 +622,19 @@ const GameList::Entry* GameList::GetEntryBySerialAndHash(const std::string_view&
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<const GameList::Entry*> GameList::GetDiscSetMembers(std::string_view disc_set_name)
|
||||||
|
{
|
||||||
|
std::vector<const Entry*> ret;
|
||||||
|
for (const Entry& entry : s_entries)
|
||||||
|
{
|
||||||
|
if (/*!entry.disc_set_member || */ disc_set_name != entry.disc_set_name)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ret.push_back(&entry);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
u32 GameList::GetEntryCount()
|
u32 GameList::GetEntryCount()
|
||||||
{
|
{
|
||||||
return static_cast<u32>(s_entries.size());
|
return static_cast<u32>(s_entries.size());
|
||||||
|
|
|
@ -39,6 +39,7 @@ struct Entry
|
||||||
std::string path;
|
std::string path;
|
||||||
std::string serial;
|
std::string serial;
|
||||||
std::string title;
|
std::string title;
|
||||||
|
std::string disc_set_name;
|
||||||
std::string genre;
|
std::string genre;
|
||||||
std::string publisher;
|
std::string publisher;
|
||||||
std::string developer;
|
std::string developer;
|
||||||
|
@ -54,6 +55,7 @@ struct Entry
|
||||||
u8 max_players = 1;
|
u8 max_players = 1;
|
||||||
u8 min_blocks = 0;
|
u8 min_blocks = 0;
|
||||||
u8 max_blocks = 0;
|
u8 max_blocks = 0;
|
||||||
|
s8 disc_set_index = -1;
|
||||||
|
|
||||||
GameDatabase::CompatibilityRating compatibility = GameDatabase::CompatibilityRating::Unknown;
|
GameDatabase::CompatibilityRating compatibility = GameDatabase::CompatibilityRating::Unknown;
|
||||||
|
|
||||||
|
@ -75,8 +77,9 @@ bool PopulateEntryFromPath(const std::string& path, Entry* entry);
|
||||||
std::unique_lock<std::recursive_mutex> GetLock();
|
std::unique_lock<std::recursive_mutex> GetLock();
|
||||||
const Entry* GetEntryByIndex(u32 index);
|
const Entry* GetEntryByIndex(u32 index);
|
||||||
const Entry* GetEntryForPath(const char* path);
|
const Entry* GetEntryForPath(const char* path);
|
||||||
const Entry* GetEntryBySerial(const std::string_view& serial);
|
const Entry* GetEntryBySerial(std::string_view serial);
|
||||||
const Entry* GetEntryBySerialAndHash(const std::string_view& serial, u64 hash);
|
const Entry* GetEntryBySerialAndHash(std::string_view serial, u64 hash);
|
||||||
|
std::vector<const Entry*> GetDiscSetMembers(std::string_view disc_set_name);
|
||||||
u32 GetEntryCount();
|
u32 GetEntryCount();
|
||||||
|
|
||||||
bool IsGameListLoaded();
|
bool IsGameListLoaded();
|
||||||
|
|
|
@ -229,6 +229,9 @@ u32 MemoryCardImage::GetFreeBlockCount(const DataArray& data)
|
||||||
|
|
||||||
std::vector<MemoryCardImage::FileInfo> MemoryCardImage::EnumerateFiles(const DataArray& data, bool include_deleted)
|
std::vector<MemoryCardImage::FileInfo> MemoryCardImage::EnumerateFiles(const DataArray& data, bool include_deleted)
|
||||||
{
|
{
|
||||||
|
// For getting the icon, we only consider binary transparency. Some games set the alpha to 0.
|
||||||
|
static constexpr auto icon_to_rgba8 = [](u16 col) { return (col == 0) ? 0u : VRAMRGBA5551ToRGBA8888(col | 0x8000); };
|
||||||
|
|
||||||
std::vector<FileInfo> files;
|
std::vector<FileInfo> files;
|
||||||
|
|
||||||
for (u32 dir_frame = 1; dir_frame < FRAMES_PER_BLOCK; dir_frame++)
|
for (u32 dir_frame = 1; dir_frame < FRAMES_PER_BLOCK; dir_frame++)
|
||||||
|
@ -295,8 +298,8 @@ std::vector<MemoryCardImage::FileInfo> MemoryCardImage::EnumerateFiles(const Dat
|
||||||
u32* pixels_ptr = fi.icon_frames[icon_frame].pixels;
|
u32* pixels_ptr = fi.icon_frames[icon_frame].pixels;
|
||||||
for (u32 i = 0; i < ICON_WIDTH * ICON_HEIGHT; i += 2)
|
for (u32 i = 0; i < ICON_WIDTH * ICON_HEIGHT; i += 2)
|
||||||
{
|
{
|
||||||
*(pixels_ptr++) = VRAMRGBA5551ToRGBA8888(tf->icon_palette[*indices_ptr & 0xF]);
|
*(pixels_ptr++) = icon_to_rgba8(tf->icon_palette[*indices_ptr & 0xF]);
|
||||||
*(pixels_ptr++) = VRAMRGBA5551ToRGBA8888(tf->icon_palette[*indices_ptr >> 4]);
|
*(pixels_ptr++) = icon_to_rgba8(tf->icon_palette[*indices_ptr >> 4]);
|
||||||
indices_ptr++;
|
indices_ptr++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -822,17 +822,25 @@ void MainWindow::populateGameListContextMenu(const GameList::Entry* entry, QWidg
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MemoryCardType::PerGame:
|
case MemoryCardType::PerGame:
|
||||||
paths[i] = QString::fromStdString(g_settings.GetGameMemoryCardPath(entry->serial.c_str(), i));
|
paths[i] = QString::fromStdString(g_settings.GetGameMemoryCardPath(entry->serial, i));
|
||||||
break;
|
break;
|
||||||
case MemoryCardType::PerGameTitle:
|
case MemoryCardType::PerGameTitle:
|
||||||
|
{
|
||||||
paths[i] = QString::fromStdString(
|
paths[i] = QString::fromStdString(
|
||||||
g_settings.GetGameMemoryCardPath(MemoryCard::SanitizeGameTitleForFileName(entry->title).c_str(), i));
|
g_settings.GetGameMemoryCardPath(MemoryCard::SanitizeGameTitleForFileName(entry->title), i));
|
||||||
break;
|
if (!entry->disc_set_name.empty() && g_settings.memory_card_use_playlist_title && !QFile::exists(paths[i]))
|
||||||
|
{
|
||||||
|
paths[i] = QString::fromStdString(
|
||||||
|
g_settings.GetGameMemoryCardPath(MemoryCard::SanitizeGameTitleForFileName(entry->disc_set_name), i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case MemoryCardType::PerGameFileTitle:
|
case MemoryCardType::PerGameFileTitle:
|
||||||
{
|
{
|
||||||
const std::string display_name(FileSystem::GetDisplayNameFromPath(entry->path));
|
const std::string display_name(FileSystem::GetDisplayNameFromPath(entry->path));
|
||||||
paths[i] = QString::fromStdString(g_settings.GetGameMemoryCardPath(
|
paths[i] = QString::fromStdString(g_settings.GetGameMemoryCardPath(
|
||||||
MemoryCard::SanitizeGameTitleForFileName(Path::GetFileTitle(display_name)).c_str(), i));
|
MemoryCard::SanitizeGameTitleForFileName(Path::GetFileTitle(display_name)), i));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in a new issue