Skip to content
Permalink
Browse files

GCMemcard: Read file comments according to logical data offsets inste…

…ad of physical data offsets.
  • Loading branch information
AdmiralCurtiss committed Oct 19, 2019
1 parent 770605b commit 58f21830bd6ebec3874a1c811a0a329e24ffb84d
@@ -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 GetActiveDirectory().m_dir_entries[index].m_comments_address;
}

std::string GCMemcard::GetSaveComment1(u8 index) const
{
if (!m_valid || index >= DIRLEN)
return "";
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 u32 address = GetActiveDirectory().m_dir_entries[index].m_comments_address;
if (address == 0xFFFFFFFF)
return std::nullopt;

std::string GCMemcard::GetSaveComment2(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 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 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);
};

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
@@ -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 @@ class GCMemcard
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;
@@ -186,27 +186,23 @@ 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++)
{
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));

0 comments on commit 58f2183

Please sign in to comment.
You can’t perform that action at this time.