summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorAdmiral H. Curtiss <pikachu025@gmail.com>2022-10-30 02:40:54 +0100
committerAdmiral H. Curtiss <pikachu025@gmail.com>2022-11-22 10:54:11 +0100
commit4b0312ecf8f22514bc92e5bb30d618c6d53db93c (patch)
tree5ed70a140a75cf3f2e8296e89867de87f569de20 /Source/Core
parentc517e92719c352eebcdf250c2a4cdec4e657eaaf (diff)
GCMemcardDirectory: Decode and strip strings for GCI filenames.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/HW/GCMemcard/GCMemcard.cpp16
-rw-r--r--Source/Core/Core/HW/GCMemcard/GCMemcard.h5
-rw-r--r--Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.cpp32
-rw-r--r--Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.h3
-rw-r--r--Source/Core/Core/NetPlayServer.cpp7
5 files changed, 43 insertions, 20 deletions
diff --git a/Source/Core/Core/HW/GCMemcard/GCMemcard.cpp b/Source/Core/Core/HW/GCMemcard/GCMemcard.cpp
index 15173e0e48..d603e1075e 100644
--- a/Source/Core/Core/HW/GCMemcard/GCMemcard.cpp
+++ b/Source/Core/Core/HW/GCMemcard/GCMemcard.cpp
@@ -304,7 +304,7 @@ void GCMemcard::UpdateBat(const BlockAlloc& bat)
bool GCMemcard::IsShiftJIS() const
{
- return m_header_block.m_data.m_encoding != 0;
+ return m_header_block.IsShiftJIS();
}
bool GCMemcard::Save()
@@ -1274,15 +1274,6 @@ DEntry::DEntry()
memset(reinterpret_cast<u8*>(this), 0xFF, DENTRY_SIZE);
}
-std::string DEntry::GCI_FileName() const
-{
- std::string filename =
- std::string(reinterpret_cast<const char*>(m_makercode.data()), m_makercode.size()) + '-' +
- std::string(reinterpret_cast<const char*>(m_gamecode.data()), m_gamecode.size()) + '-' +
- reinterpret_cast<const char*>(m_filename.data()) + ".gci";
- return Common::EscapeFileName(filename);
-}
-
void Header::FixChecksums()
{
std::tie(m_checksum, m_checksum_inv) = CalculateChecksums();
@@ -1324,6 +1315,11 @@ GCMemcardErrorCode Header::CheckForErrors(u16 card_size_mbits) const
return error_code;
}
+bool Header::IsShiftJIS() const
+{
+ return m_data.m_encoding != 0;
+}
+
Directory::Directory()
{
memset(reinterpret_cast<u8*>(this), 0xFF, BLOCK_SIZE);
diff --git a/Source/Core/Core/HW/GCMemcard/GCMemcard.h b/Source/Core/Core/HW/GCMemcard/GCMemcard.h
index ed4c36ba20..80a2b3eea4 100644
--- a/Source/Core/Core/HW/GCMemcard/GCMemcard.h
+++ b/Source/Core/Core/HW/GCMemcard/GCMemcard.h
@@ -231,6 +231,8 @@ struct Header
std::pair<u16, u16> CalculateChecksums() const;
GCMemcardErrorCode CheckForErrors(u16 card_size_mbits) const;
+
+ bool IsShiftJIS() const;
};
static_assert(sizeof(Header) == BLOCK_SIZE);
static_assert(std::is_trivially_copyable_v<Header>);
@@ -239,9 +241,6 @@ struct DEntry
{
DEntry();
- // TODO: This probably shouldn't be here at all?
- std::string GCI_FileName() const;
-
static constexpr std::array<u8, 4> UNINITIALIZED_GAMECODE{{0xFF, 0xFF, 0xFF, 0xFF}};
// 4 bytes at 0x00: Gamecode
diff --git a/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.cpp b/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.cpp
index 3f02ef16b1..f7b318a6eb 100644
--- a/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.cpp
+++ b/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.cpp
@@ -9,6 +9,7 @@
#include <memory>
#include <mutex>
#include <string>
+#include <string_view>
#include <vector>
#include <fmt/format.h>
@@ -39,6 +40,28 @@
static const char* MC_HDR = "MC_SYSTEM_AREA";
+static std::string GenerateDefaultGCIFilename(const Memcard::DEntry& entry,
+ bool card_encoding_is_shift_jis)
+{
+ const auto string_decoder = card_encoding_is_shift_jis ? SHIFTJISToUTF8 : CP1252ToUTF8;
+ const auto strip_null = [](const std::string_view& s) {
+ auto offset = s.find('\0');
+ if (offset == std::string_view::npos)
+ return s;
+ return s.substr(0, offset);
+ };
+
+ const std::string_view makercode(reinterpret_cast<const char*>(entry.m_makercode.data()),
+ entry.m_makercode.size());
+ const std::string_view gamecode(reinterpret_cast<const char*>(entry.m_gamecode.data()),
+ entry.m_gamecode.size());
+ const std::string_view filename(reinterpret_cast<const char*>(entry.m_filename.data()),
+ entry.m_filename.size());
+ return Common::EscapeFileName(fmt::format("{}-{}-{}.gci", strip_null(string_decoder(makercode)),
+ strip_null(string_decoder(gamecode)),
+ strip_null(string_decoder(filename))));
+}
+
bool GCMemcardDirectory::LoadGCI(Memcard::GCIFile gci)
{
// check if any already loaded file has the same internal name as the new file
@@ -102,7 +125,8 @@ bool GCMemcardDirectory::LoadGCI(Memcard::GCIFile gci)
// This is only used by NetPlay but it made sense to put it here to keep the relevant code together
std::vector<std::string> GCMemcardDirectory::GetFileNamesForGameID(const std::string& directory,
- const std::string& game_id)
+ const std::string& game_id,
+ bool card_encoding_is_shift_jis)
{
std::vector<std::string> filenames;
@@ -123,7 +147,8 @@ std::vector<std::string> GCMemcardDirectory::GetFileNamesForGameID(const std::st
if (!gci_file.ReadBytes(&gci.m_gci_header, Memcard::DENTRY_SIZE))
continue;
- const std::string gci_filename = gci.m_gci_header.GCI_FileName();
+ const std::string gci_filename =
+ GenerateDefaultGCIFilename(gci.m_gci_header, card_encoding_is_shift_jis);
if (std::find(loaded_saves.begin(), loaded_saves.end(), gci_filename) != loaded_saves.end())
continue;
@@ -614,7 +639,8 @@ void GCMemcardDirectory::FlushToFile()
}
if (save.m_filename.empty())
{
- std::string default_save_name = m_save_directory + save.m_gci_header.GCI_FileName();
+ std::string default_save_name =
+ m_save_directory + GenerateDefaultGCIFilename(save.m_gci_header, m_hdr.IsShiftJIS());
// Check to see if another file is using the same name
// This seems unlikely except in the case of file corruption
diff --git a/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.h b/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.h
index 5b02700a61..b61ad360b6 100644
--- a/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.h
+++ b/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.h
@@ -32,7 +32,8 @@ public:
GCMemcardDirectory& operator=(GCMemcardDirectory&&) = delete;
static std::vector<std::string> GetFileNamesForGameID(const std::string& directory,
- const std::string& game_id);
+ const std::string& game_id,
+ bool card_encoding_is_shift_jis);
void FlushToFile();
void FlushThread();
s32 Read(u32 src_address, s32 length, u8* dest_address) override;
diff --git a/Source/Core/Core/NetPlayServer.cpp b/Source/Core/Core/NetPlayServer.cpp
index 18076ada29..9c0ba0a53d 100644
--- a/Source/Core/Core/NetPlayServer.cpp
+++ b/Source/Core/Core/NetPlayServer.cpp
@@ -1686,7 +1686,8 @@ bool NetPlayServer::SyncSaveData(const SaveSyncInfo& sync_info)
return true;
const auto game_region = sync_info.game->GetRegion();
- const std::string region = Config::GetDirectoryForRegion(Config::ToGameCubeRegion(game_region));
+ const auto gamecube_region = Config::ToGameCubeRegion(game_region);
+ const std::string region = Config::GetDirectoryForRegion(gamecube_region);
for (ExpansionInterface::Slot slot : ExpansionInterface::MEMCARD_SLOTS)
{
@@ -1733,8 +1734,8 @@ bool NetPlayServer::SyncSaveData(const SaveSyncInfo& sync_info)
if (File::IsDirectory(path))
{
- std::vector<std::string> files =
- GCMemcardDirectory::GetFileNamesForGameID(path + DIR_SEP, sync_info.game->GetGameID());
+ std::vector<std::string> files = GCMemcardDirectory::GetFileNamesForGameID(
+ path + DIR_SEP, sync_info.game->GetGameID(), gamecube_region == DiscIO::Region::NTSC_J);
pac << static_cast<u8>(files.size());