mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-10 08:09:26 +01:00
GCMemcard: Read file comments according to logical data offsets instead of physical data offsets.
This commit is contained in:
parent
770605bc80
commit
58f21830bd
@ -639,43 +639,33 @@ std::optional<std::vector<u8>> GCMemcard::GetSaveDataBytes(u8 save_index, size_t
|
|||||||
return std::make_optional(std::move(result));
|
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)
|
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
|
const auto data = GetSaveDataBytes(index, address, DENTRY_STRLEN * 2);
|
||||||
{
|
if (!data || data->size() != DENTRY_STRLEN * 2)
|
||||||
if (!m_valid || index >= DIRLEN)
|
return std::nullopt;
|
||||||
return "";
|
|
||||||
|
|
||||||
u32 Comment1 = GetActiveDirectory().m_dir_entries[index].m_comments_address;
|
const auto string_decoder = IsShiftJIS() ? SHIFTJISToUTF8 : CP1252ToUTF8;
|
||||||
u32 DataBlock = GetActiveDirectory().m_dir_entries[index].m_first_block - MC_FST_BLOCKS;
|
const auto strip_null = [](const std::string& s) {
|
||||||
if ((DataBlock > m_size_blocks) || (Comment1 == 0xFFFFFFFF))
|
auto offset = s.find('\0');
|
||||||
{
|
if (offset == std::string::npos)
|
||||||
return "";
|
offset = s.length();
|
||||||
}
|
return s.substr(0, offset);
|
||||||
return std::string((const char*)m_data_blocks[DataBlock].m_block.data() + Comment1,
|
};
|
||||||
DENTRY_STRLEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string GCMemcard::GetSaveComment2(u8 index) const
|
const u8* address_1 = data->data();
|
||||||
{
|
const u8* address_2 = address_1 + DENTRY_STRLEN;
|
||||||
if (!m_valid || index >= DIRLEN)
|
const std::string encoded_1(reinterpret_cast<const char*>(address_1), DENTRY_STRLEN);
|
||||||
return "";
|
const std::string encoded_2(reinterpret_cast<const char*>(address_2), DENTRY_STRLEN);
|
||||||
|
return std::make_pair(strip_null(string_decoder(encoded_1)),
|
||||||
u32 Comment1 = GetActiveDirectory().m_dir_entries[index].m_comments_address;
|
strip_null(string_decoder(encoded_2)));
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<DEntry> GCMemcard::GetDEntry(u8 index) const
|
std::optional<DEntry> GCMemcard::GetDEntry(u8 index) const
|
||||||
|
@ -118,7 +118,7 @@ constexpr u32 MC_FST_BLOCKS = 0x05;
|
|||||||
// maximum number of saves that can be stored on a single memory card
|
// maximum number of saves that can be stored on a single memory card
|
||||||
constexpr u8 DIRLEN = 0x7F;
|
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;
|
constexpr u32 DENTRY_STRLEN = 0x20;
|
||||||
|
|
||||||
// size of a single entry in the Directory in bytes
|
// size of a single entry in the Directory in bytes
|
||||||
@ -456,9 +456,10 @@ public:
|
|||||||
GetSaveDataBytes(u8 save_index, size_t offset = 0,
|
GetSaveDataBytes(u8 save_index, size_t offset = 0,
|
||||||
size_t length = std::numeric_limits<size_t>::max()) const;
|
size_t length = std::numeric_limits<size_t>::max()) const;
|
||||||
|
|
||||||
u32 DEntry_CommentsAddress(u8 index) const;
|
// Returns, if available, the two strings shown on the save file in the GC BIOS, in UTF8.
|
||||||
std::string GetSaveComment1(u8 index) const;
|
// The first is the big line on top, usually the game title, and the second is the smaller line
|
||||||
std::string GetSaveComment2(u8 index) const;
|
// 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.
|
// Fetches a DEntry from the given file index.
|
||||||
std::optional<DEntry> GetDEntry(u8 index) const;
|
std::optional<DEntry> GetDEntry(u8 index) const;
|
||||||
|
@ -186,14 +186,6 @@ void GCMemcardManager::UpdateSlotTable(int slot)
|
|||||||
return item;
|
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();
|
const u8 num_files = memcard->GetNumFiles();
|
||||||
m_slot_active_icons[slot].reserve(num_files);
|
m_slot_active_icons[slot].reserve(num_files);
|
||||||
for (int i = 0; i < num_files; i++)
|
for (int i = 0; i < num_files; i++)
|
||||||
@ -201,12 +193,16 @@ void GCMemcardManager::UpdateSlotTable(int slot)
|
|||||||
int file_index = memcard->GetFileIndex(i);
|
int file_index = memcard->GetFileIndex(i);
|
||||||
table->setRowCount(i + 1);
|
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 blocks = QStringLiteral("%1").arg(memcard->DEntry_BlockCount(file_index));
|
||||||
QString block_count = QStringLiteral("%1").arg(memcard->DEntry_FirstBlock(file_index));
|
QString block_count = QStringLiteral("%1").arg(memcard->DEntry_FirstBlock(file_index));
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user