mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-22 13:55:38 +00:00
GameDatabase: Parse discSetName/discSetSerials
This commit is contained in:
parent
7a1af36e8d
commit
2419008242
|
@ -29,7 +29,7 @@ namespace GameDatabase {
|
||||||
enum : u32
|
enum : u32
|
||||||
{
|
{
|
||||||
GAME_DATABASE_CACHE_SIGNATURE = 0x45434C48,
|
GAME_DATABASE_CACHE_SIGNATURE = 0x45434C48,
|
||||||
GAME_DATABASE_CACHE_VERSION = 3,
|
GAME_DATABASE_CACHE_VERSION = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
static Entry* GetMutableEntry(const std::string_view& serial);
|
static Entry* GetMutableEntry(const std::string_view& serial);
|
||||||
|
@ -427,9 +427,9 @@ void GameDatabase::Entry::ApplySettings(Settings& settings, bool display_osd_mes
|
||||||
settings.cpu_fastmem_mode = CPUFastmemMode::LUT;
|
settings.cpu_fastmem_mode = CPUFastmemMode::LUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BIT_FOR(ctype) (static_cast<u32>(1) << static_cast<u32>(ctype))
|
#define BIT_FOR(ctype) (static_cast<u16>(1) << static_cast<u32>(ctype))
|
||||||
|
|
||||||
if (supported_controllers != 0 && supported_controllers != static_cast<u32>(-1))
|
if (supported_controllers != 0 && supported_controllers != static_cast<u16>(-1))
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i < NUM_CONTROLLER_AND_CARD_PORTS; i++)
|
for (u32 i = 0; i < NUM_CONTROLLER_AND_CARD_PORTS; i++)
|
||||||
{
|
{
|
||||||
|
@ -558,13 +558,14 @@ bool GameDatabase::LoadFromCache()
|
||||||
constexpr u32 num_bytes = (static_cast<u32>(Trait::Count) + 7) / 8;
|
constexpr u32 num_bytes = (static_cast<u32>(Trait::Count) + 7) / 8;
|
||||||
std::array<u8, num_bytes> bits;
|
std::array<u8, num_bytes> bits;
|
||||||
u8 compatibility;
|
u8 compatibility;
|
||||||
|
u32 num_disc_set_serials;
|
||||||
|
|
||||||
if (!stream->ReadSizePrefixedString(&entry.serial) || !stream->ReadSizePrefixedString(&entry.title) ||
|
if (!stream->ReadSizePrefixedString(&entry.serial) || !stream->ReadSizePrefixedString(&entry.title) ||
|
||||||
!stream->ReadSizePrefixedString(&entry.genre) || !stream->ReadSizePrefixedString(&entry.developer) ||
|
!stream->ReadSizePrefixedString(&entry.genre) || !stream->ReadSizePrefixedString(&entry.developer) ||
|
||||||
!stream->ReadSizePrefixedString(&entry.publisher) || !stream->ReadU64(&entry.release_date) ||
|
!stream->ReadSizePrefixedString(&entry.publisher) || !stream->ReadU64(&entry.release_date) ||
|
||||||
!stream->ReadU8(&entry.min_players) || !stream->ReadU8(&entry.max_players) ||
|
!stream->ReadU8(&entry.min_players) || !stream->ReadU8(&entry.max_players) ||
|
||||||
!stream->ReadU8(&entry.min_blocks) || !stream->ReadU8(&entry.max_blocks) ||
|
!stream->ReadU8(&entry.min_blocks) || !stream->ReadU8(&entry.max_blocks) ||
|
||||||
!stream->ReadU32(&entry.supported_controllers) || !stream->ReadU8(&compatibility) ||
|
!stream->ReadU16(&entry.supported_controllers) || !stream->ReadU8(&compatibility) ||
|
||||||
compatibility >= static_cast<u8>(GameDatabase::CompatibilityRating::Count) ||
|
compatibility >= static_cast<u8>(GameDatabase::CompatibilityRating::Count) ||
|
||||||
!stream->Read2(bits.data(), num_bytes) ||
|
!stream->Read2(bits.data(), num_bytes) ||
|
||||||
!ReadOptionalFromStream(stream.get(), &entry.display_active_start_offset) ||
|
!ReadOptionalFromStream(stream.get(), &entry.display_active_start_offset) ||
|
||||||
|
@ -576,12 +577,26 @@ bool GameDatabase::LoadFromCache()
|
||||||
!ReadOptionalFromStream(stream.get(), &entry.gpu_fifo_size) ||
|
!ReadOptionalFromStream(stream.get(), &entry.gpu_fifo_size) ||
|
||||||
!ReadOptionalFromStream(stream.get(), &entry.gpu_max_run_ahead) ||
|
!ReadOptionalFromStream(stream.get(), &entry.gpu_max_run_ahead) ||
|
||||||
!ReadOptionalFromStream(stream.get(), &entry.gpu_pgxp_tolerance) ||
|
!ReadOptionalFromStream(stream.get(), &entry.gpu_pgxp_tolerance) ||
|
||||||
!ReadOptionalFromStream(stream.get(), &entry.gpu_pgxp_depth_threshold))
|
!ReadOptionalFromStream(stream.get(), &entry.gpu_pgxp_depth_threshold) ||
|
||||||
|
!stream->ReadSizePrefixedString(&entry.disc_set_name) || !stream->ReadU32(&num_disc_set_serials))
|
||||||
{
|
{
|
||||||
Log_DevPrintf("Cache entry is corrupted.");
|
Log_DevPrintf("Cache entry is corrupted.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (num_disc_set_serials > 0)
|
||||||
|
{
|
||||||
|
entry.disc_set_serials.reserve(num_disc_set_serials);
|
||||||
|
for (u32 j = 0; j < num_disc_set_serials; j++)
|
||||||
|
{
|
||||||
|
if (!stream->ReadSizePrefixedString(&entry.disc_set_serials.emplace_back()))
|
||||||
|
{
|
||||||
|
Log_DevPrintf("Cache entry is corrupted.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
entry.compatibility = static_cast<GameDatabase::CompatibilityRating>(compatibility);
|
entry.compatibility = static_cast<GameDatabase::CompatibilityRating>(compatibility);
|
||||||
entry.traits.reset();
|
entry.traits.reset();
|
||||||
for (u32 j = 0; j < static_cast<int>(Trait::Count); j++)
|
for (u32 j = 0; j < static_cast<int>(Trait::Count); j++)
|
||||||
|
@ -640,7 +655,7 @@ bool GameDatabase::SaveToCache()
|
||||||
result = result && stream->WriteU8(entry.max_players);
|
result = result && stream->WriteU8(entry.max_players);
|
||||||
result = result && stream->WriteU8(entry.min_blocks);
|
result = result && stream->WriteU8(entry.min_blocks);
|
||||||
result = result && stream->WriteU8(entry.max_blocks);
|
result = result && stream->WriteU8(entry.max_blocks);
|
||||||
result = result && stream->WriteU32(entry.supported_controllers);
|
result = result && stream->WriteU16(entry.supported_controllers);
|
||||||
result = result && stream->WriteU8(static_cast<u8>(entry.compatibility));
|
result = result && stream->WriteU8(static_cast<u8>(entry.compatibility));
|
||||||
|
|
||||||
constexpr u32 num_bytes = (static_cast<u32>(Trait::Count) + 7) / 8;
|
constexpr u32 num_bytes = (static_cast<u32>(Trait::Count) + 7) / 8;
|
||||||
|
@ -664,6 +679,11 @@ bool GameDatabase::SaveToCache()
|
||||||
result = result && WriteOptionalToStream(stream.get(), entry.gpu_max_run_ahead);
|
result = result && WriteOptionalToStream(stream.get(), entry.gpu_max_run_ahead);
|
||||||
result = result && WriteOptionalToStream(stream.get(), entry.gpu_pgxp_tolerance);
|
result = result && WriteOptionalToStream(stream.get(), entry.gpu_pgxp_tolerance);
|
||||||
result = result && WriteOptionalToStream(stream.get(), entry.gpu_pgxp_depth_threshold);
|
result = result && WriteOptionalToStream(stream.get(), entry.gpu_pgxp_depth_threshold);
|
||||||
|
|
||||||
|
result = result && stream->WriteSizePrefixedString(entry.disc_set_name);
|
||||||
|
result = result && stream->WriteU32(static_cast<u32>(entry.disc_set_serials.size()));
|
||||||
|
for (const std::string& serial : entry.disc_set_serials)
|
||||||
|
result = result && stream->WriteSizePrefixedString(serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& it : s_code_lookup)
|
for (const auto& it : s_code_lookup)
|
||||||
|
@ -852,7 +872,7 @@ bool GameDatabase::ParseJsonEntry(Entry* entry, const rapidjson::Value& value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
entry->supported_controllers = ~0u;
|
entry->supported_controllers = static_cast<u16>(~0u);
|
||||||
const auto controllers = value.FindMember("controllers");
|
const auto controllers = value.FindMember("controllers");
|
||||||
if (controllers != value.MemberEnd())
|
if (controllers != value.MemberEnd())
|
||||||
{
|
{
|
||||||
|
@ -880,7 +900,7 @@ bool GameDatabase::ParseJsonEntry(Entry* entry, const rapidjson::Value& value)
|
||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry->supported_controllers |= (1u << static_cast<u32>(ctype.value()));
|
entry->supported_controllers |= (1u << static_cast<u16>(ctype.value()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -937,6 +957,32 @@ bool GameDatabase::ParseJsonEntry(Entry* entry, const rapidjson::Value& value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GetStringFromObject(value, "discSetName", &entry->disc_set_name);
|
||||||
|
const auto disc_set_serials = value.FindMember("discSetSerials");
|
||||||
|
if (disc_set_serials != value.MemberEnd())
|
||||||
|
{
|
||||||
|
if (disc_set_serials->value.IsArray())
|
||||||
|
{
|
||||||
|
const auto disc_set_serials_array = disc_set_serials->value.GetArray();
|
||||||
|
entry->disc_set_serials.reserve(disc_set_serials_array.Size());
|
||||||
|
for (const rapidjson::Value& serial : disc_set_serials_array)
|
||||||
|
{
|
||||||
|
if (serial.IsString())
|
||||||
|
{
|
||||||
|
entry->disc_set_serials.emplace_back(serial.GetString(), serial.GetStringLength());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log_WarningPrintf("discSetSerial is not a string");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log_WarningPrintf("discSetSerials is not an array");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ struct Entry
|
||||||
u8 max_players;
|
u8 max_players;
|
||||||
u8 min_blocks;
|
u8 min_blocks;
|
||||||
u8 max_blocks;
|
u8 max_blocks;
|
||||||
u32 supported_controllers;
|
u16 supported_controllers;
|
||||||
CompatibilityRating compatibility;
|
CompatibilityRating compatibility;
|
||||||
|
|
||||||
std::bitset<static_cast<int>(Trait::Count)> traits{};
|
std::bitset<static_cast<int>(Trait::Count)> traits{};
|
||||||
|
@ -80,6 +80,9 @@ struct Entry
|
||||||
std::optional<float> gpu_pgxp_tolerance;
|
std::optional<float> gpu_pgxp_tolerance;
|
||||||
std::optional<float> gpu_pgxp_depth_threshold;
|
std::optional<float> gpu_pgxp_depth_threshold;
|
||||||
|
|
||||||
|
std::string disc_set_name;
|
||||||
|
std::vector<std::string> disc_set_serials;
|
||||||
|
|
||||||
ALWAYS_INLINE bool HasTrait(Trait trait) const { return traits[static_cast<int>(trait)]; }
|
ALWAYS_INLINE bool HasTrait(Trait trait) const { return traits[static_cast<int>(trait)]; }
|
||||||
|
|
||||||
void ApplySettings(Settings& settings, bool display_osd_messages) const;
|
void ApplySettings(Settings& settings, bool display_osd_messages) const;
|
||||||
|
|
|
@ -41,7 +41,7 @@ namespace GameList {
|
||||||
enum : u32
|
enum : u32
|
||||||
{
|
{
|
||||||
GAME_LIST_CACHE_SIGNATURE = 0x45434C47,
|
GAME_LIST_CACHE_SIGNATURE = 0x45434C47,
|
||||||
GAME_LIST_CACHE_VERSION = 33,
|
GAME_LIST_CACHE_VERSION = 34,
|
||||||
|
|
||||||
PLAYED_TIME_SERIAL_LENGTH = 32,
|
PLAYED_TIME_SERIAL_LENGTH = 32,
|
||||||
PLAYED_TIME_LAST_TIME_LENGTH = 20, // uint64
|
PLAYED_TIME_LAST_TIME_LENGTH = 20, // uint64
|
||||||
|
@ -244,7 +244,7 @@ bool GameList::GetDiscListEntry(const std::string& path, Entry* entry)
|
||||||
entry->max_players = 0;
|
entry->max_players = 0;
|
||||||
entry->min_blocks = 0;
|
entry->min_blocks = 0;
|
||||||
entry->max_blocks = 0;
|
entry->max_blocks = 0;
|
||||||
entry->supported_controllers = ~0u;
|
entry->supported_controllers = static_cast<u16>(~0u);
|
||||||
}
|
}
|
||||||
|
|
||||||
// region detection
|
// region detection
|
||||||
|
@ -319,7 +319,7 @@ bool GameList::LoadEntriesFromCache(ByteStream* stream)
|
||||||
!stream->ReadSizePrefixedString(&ge.genre) || !stream->ReadSizePrefixedString(&ge.publisher) ||
|
!stream->ReadSizePrefixedString(&ge.genre) || !stream->ReadSizePrefixedString(&ge.publisher) ||
|
||||||
!stream->ReadSizePrefixedString(&ge.developer) || !stream->ReadU64(&ge.hash) ||
|
!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.total_size) || !stream->ReadU64(reinterpret_cast<u64*>(&ge.last_modified_time)) ||
|
||||||
!stream->ReadU64(&ge.release_date) || !stream->ReadU32(&ge.supported_controllers) ||
|
!stream->ReadU64(&ge.release_date) || !stream->ReadU16(&ge.supported_controllers) ||
|
||||||
!stream->ReadU8(&ge.min_players) || !stream->ReadU8(&ge.max_players) || !stream->ReadU8(&ge.min_blocks) ||
|
!stream->ReadU8(&ge.min_players) || !stream->ReadU8(&ge.max_players) || !stream->ReadU8(&ge.min_blocks) ||
|
||||||
!stream->ReadU8(&ge.max_blocks) || !stream->ReadU8(&compatibility_rating) ||
|
!stream->ReadU8(&ge.max_blocks) || !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) ||
|
||||||
|
@ -359,7 +359,7 @@ bool GameList::WriteEntryToCache(const Entry* entry)
|
||||||
result &= s_cache_write_stream->WriteU64(entry->total_size);
|
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->last_modified_time);
|
||||||
result &= s_cache_write_stream->WriteU64(entry->release_date);
|
result &= s_cache_write_stream->WriteU64(entry->release_date);
|
||||||
result &= s_cache_write_stream->WriteU32(entry->supported_controllers);
|
result &= s_cache_write_stream->WriteU16(entry->supported_controllers);
|
||||||
result &= s_cache_write_stream->WriteU8(entry->min_players);
|
result &= s_cache_write_stream->WriteU8(entry->min_players);
|
||||||
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);
|
||||||
|
|
|
@ -48,7 +48,7 @@ struct Entry
|
||||||
std::time_t total_played_time = 0;
|
std::time_t total_played_time = 0;
|
||||||
|
|
||||||
u64 release_date = 0;
|
u64 release_date = 0;
|
||||||
u32 supported_controllers = ~static_cast<u32>(0);
|
u16 supported_controllers = static_cast<u16>(~0u);
|
||||||
u8 min_players = 1;
|
u8 min_players = 1;
|
||||||
u8 max_players = 1;
|
u8 max_players = 1;
|
||||||
u8 min_blocks = 0;
|
u8 min_blocks = 0;
|
||||||
|
|
|
@ -105,11 +105,11 @@ void GameSummaryWidget::populateUi(const std::string& path, const std::string& s
|
||||||
m_ui.releaseInfo->setText(tr("Unknown"));
|
m_ui.releaseInfo->setText(tr("Unknown"));
|
||||||
|
|
||||||
QString controllers;
|
QString controllers;
|
||||||
if (entry->supported_controllers != 0 && entry->supported_controllers != static_cast<u32>(-1))
|
if (entry->supported_controllers != 0 && entry->supported_controllers != static_cast<u16>(-1))
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i < static_cast<u32>(ControllerType::Count); i++)
|
for (u32 i = 0; i < static_cast<u32>(ControllerType::Count); i++)
|
||||||
{
|
{
|
||||||
if ((entry->supported_controllers & (1u << i)) != 0)
|
if ((entry->supported_controllers & static_cast<u16>(1u << i)) != 0)
|
||||||
{
|
{
|
||||||
if (!controllers.isEmpty())
|
if (!controllers.isEmpty())
|
||||||
controllers.append(", ");
|
controllers.append(", ");
|
||||||
|
|
Loading…
Reference in a new issue