summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorAdmiral H. Curtiss <pikachu025@gmail.com>2019-10-19 16:06:02 +0200
committerAdmiral H. Curtiss <pikachu025@gmail.com>2019-11-17 01:42:26 +0100
commit58f21830bd6ebec3874a1c811a0a329e24ffb84d (patch)
tree3725ef85874b09c37c2cf46242a597f3f4a89e68 /Source/Core
parent770605bc800c525b96d53482579a3ed6cbd14168 (diff)
GCMemcard: Read file comments according to logical data offsets instead of physical data offsets.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/HW/GCMemcard/GCMemcard.cpp54
-rw-r--r--Source/Core/Core/HW/GCMemcard/GCMemcard.h9
-rw-r--r--Source/Core/DolphinQt/GCMemcardManager.cpp22
3 files changed, 36 insertions, 49 deletions
diff --git a/Source/Core/Core/HW/GCMemcard/GCMemcard.cpp b/Source/Core/Core/HW/GCMemcard/GCMemcard.cpp
index 33c6c58858..07dcb01b69 100644
--- a/Source/Core/Core/HW/GCMemcard/GCMemcard.cpp
+++ b/Source/Core/Core/HW/GCMemcard/GCMemcard.cpp
@@ -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
diff --git a/Source/Core/Core/HW/GCMemcard/GCMemcard.h b/Source/Core/Core/HW/GCMemcard/GCMemcard.h
index d8c7b79486..24db3194ea 100644
--- a/Source/Core/Core/HW/GCMemcard/GCMemcard.h
+++ b/Source/Core/Core/HW/GCMemcard/GCMemcard.h
@@ -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;
diff --git a/Source/Core/DolphinQt/GCMemcardManager.cpp b/Source/Core/DolphinQt/GCMemcardManager.cpp
index 84dc10d02b..17d5d162e3 100644
--- a/Source/Core/DolphinQt/GCMemcardManager.cpp
+++ b/Source/Core/DolphinQt/GCMemcardManager.cpp
@@ -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));