GCMemcard: Read file comments according to logical data offsets instead of physical data offsets.

This commit is contained in:
Admiral H. Curtiss 2019-10-19 16:06:02 +02:00
parent 770605bc80
commit 58f21830bd
3 changed files with 35 additions and 48 deletions

View File

@ -639,43 +639,33 @@ std::optional<std::vector<u8>> GCMemcard::GetSaveDataBytes(u8 save_index, size_t
return std::make_optional(std::move(result));
}
u32 GCMemcard::DEntry_CommentsAddress(u8 index) const
std::optional<std::pair<std::string, std::string>> GCMemcard::GetSaveComments(u8 index) const
{
if (!m_valid || index >= DIRLEN)
return 0xFFFF;
return std::nullopt;
return GetActiveDirectory().m_dir_entries[index].m_comments_address;
}
const u32 address = GetActiveDirectory().m_dir_entries[index].m_comments_address;
if (address == 0xFFFFFFFF)
return std::nullopt;
std::string GCMemcard::GetSaveComment1(u8 index) const
{
if (!m_valid || index >= DIRLEN)
return "";
const auto data = GetSaveDataBytes(index, address, DENTRY_STRLEN * 2);
if (!data || data->size() != DENTRY_STRLEN * 2)
return std::nullopt;
u32 Comment1 = GetActiveDirectory().m_dir_entries[index].m_comments_address;
u32 DataBlock = GetActiveDirectory().m_dir_entries[index].m_first_block - MC_FST_BLOCKS;
if ((DataBlock > m_size_blocks) || (Comment1 == 0xFFFFFFFF))
{
return "";
}
return std::string((const char*)m_data_blocks[DataBlock].m_block.data() + Comment1,
DENTRY_STRLEN);
}
const auto string_decoder = IsShiftJIS() ? SHIFTJISToUTF8 : CP1252ToUTF8;
const auto strip_null = [](const std::string& s) {
auto offset = s.find('\0');
if (offset == std::string::npos)
offset = s.length();
return s.substr(0, offset);
};
std::string GCMemcard::GetSaveComment2(u8 index) const
{
if (!m_valid || index >= DIRLEN)
return "";
u32 Comment1 = GetActiveDirectory().m_dir_entries[index].m_comments_address;
u32 Comment2 = Comment1 + DENTRY_STRLEN;
u32 DataBlock = GetActiveDirectory().m_dir_entries[index].m_first_block - MC_FST_BLOCKS;
if ((DataBlock > m_size_blocks) || (Comment1 == 0xFFFFFFFF))
{
return "";
}
return std::string((const char*)m_data_blocks[DataBlock].m_block.data() + Comment2,
DENTRY_STRLEN);
const u8* address_1 = data->data();
const u8* address_2 = address_1 + DENTRY_STRLEN;
const std::string encoded_1(reinterpret_cast<const char*>(address_1), DENTRY_STRLEN);
const std::string encoded_2(reinterpret_cast<const char*>(address_2), DENTRY_STRLEN);
return std::make_pair(strip_null(string_decoder(encoded_1)),
strip_null(string_decoder(encoded_2)));
}
std::optional<DEntry> GCMemcard::GetDEntry(u8 index) const

View File

@ -118,7 +118,7 @@ constexpr u32 MC_FST_BLOCKS = 0x05;
// maximum number of saves that can be stored on a single memory card
constexpr u8 DIRLEN = 0x7F;
// maximum size of memory card file comment in bytes
// maximum size of a single memory card file comment in bytes
constexpr u32 DENTRY_STRLEN = 0x20;
// size of a single entry in the Directory in bytes
@ -456,9 +456,10 @@ public:
GetSaveDataBytes(u8 save_index, size_t offset = 0,
size_t length = std::numeric_limits<size_t>::max()) const;
u32 DEntry_CommentsAddress(u8 index) const;
std::string GetSaveComment1(u8 index) const;
std::string GetSaveComment2(u8 index) const;
// Returns, if available, the two strings shown on the save file in the GC BIOS, in UTF8.
// The first is the big line on top, usually the game title, and the second is the smaller line
// next to the block size, often a progress indicator or subtitle.
std::optional<std::pair<std::string, std::string>> GetSaveComments(u8 index) const;
// Fetches a DEntry from the given file index.
std::optional<DEntry> GetDEntry(u8 index) const;

View File

@ -186,14 +186,6 @@ void GCMemcardManager::UpdateSlotTable(int slot)
return item;
};
const auto strip_garbage = [](const std::string& s) {
auto offset = s.find('\0');
if (offset == std::string::npos)
offset = s.length();
return s.substr(0, offset);
};
const u8 num_files = memcard->GetNumFiles();
m_slot_active_icons[slot].reserve(num_files);
for (int i = 0; i < num_files; i++)
@ -201,12 +193,16 @@ void GCMemcardManager::UpdateSlotTable(int slot)
int file_index = memcard->GetFileIndex(i);
table->setRowCount(i + 1);
auto const string_decoder = memcard->IsShiftJIS() ? SHIFTJISToUTF8 : CP1252ToUTF8;
const auto file_comments = memcard->GetSaveComments(file_index);
QString title;
QString comment;
if (file_comments)
{
title = QString::fromStdString(file_comments->first);
comment = QString::fromStdString(file_comments->second);
}
QString title =
QString::fromStdString(strip_garbage(string_decoder(memcard->GetSaveComment1(file_index))));
QString comment =
QString::fromStdString(strip_garbage(string_decoder(memcard->GetSaveComment2(file_index))));
QString blocks = QStringLiteral("%1").arg(memcard->DEntry_BlockCount(file_index));
QString block_count = QStringLiteral("%1").arg(memcard->DEntry_FirstBlock(file_index));