Skip to content

Commit

Permalink
Memory Cards: Actually implement the optimizations and the bugs that …
Browse files Browse the repository at this point in the history
…come with it on non-windows platforms
  • Loading branch information
F0bes committed Jan 14, 2025
1 parent 4d3c43d commit 60b8da1
Showing 1 changed file with 35 additions and 56 deletions.
91 changes: 35 additions & 56 deletions pcsx2/SIO/Memcard/MemoryCardFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ class FileMemoryCard
bool m_ispsx[8] = {};
u32 m_chkaddr = 0;

std::chrono::time_point<std::chrono::system_clock> m_lastSaveTime = std::chrono::system_clock::now();

public:
FileMemoryCard();
~FileMemoryCard();
Expand Down Expand Up @@ -323,35 +325,34 @@ void FileMemoryCard::Open()
"Close any other instances of PCSX2, or restart your computer.\n"),
fname));
}
else // Load checksum
else // Load memory map and checksum
{
m_fileSize[slot] = FileSystem::FSize64(m_file[slot]);

Console.WriteLnFmt(Color_Green, "McdSlot {} [File]: {} [{} MB, {}]", slot, Path::GetFileName(fname),
(m_fileSize[slot] + (MCD_SIZE + 1)) / MC2_MBSIZE,
FileMcd_IsMemoryCardFormatted(m_file[slot]) ? "Formatted" : "UNFORMATTED");

m_filenames[slot] = std::move(fname);
m_ispsx[slot] = m_fileSize[slot] == 0x20000;
m_chkaddr = 0x210;

if (!m_ispsx[slot] && FileSystem::FSeek64(m_file[slot], m_chkaddr, SEEK_SET) == 0)
{
const size_t read_result = std::fread(&m_chksum[slot], sizeof(m_chksum[slot]), 1, m_file[slot]);
if (read_result == 0)
Host::ReportErrorAsync("Memory Card Read Failed", "Error reading memory card.");
}

m_mapping_handles[slot] = HostSys::CreateMappingFromFile(m_file[slot]);
if (!m_mapping_handles[slot])
{
Console.Warning("CreateMappingFromFile failed!");
}

m_mappings[slot] = static_cast<u8*>(HostSys::MapMapping(m_mapping_handles[slot], PageAccess_ReadWrite()));
if (!m_mappings[slot])
{
Console.Warning("MapSharedMemory failed!");
}

Console.WriteLnFmt(Color_Green, "McdSlot {} [File]: {} [{} MB, {}]", slot, Path::GetFileName(fname),
(m_fileSize[slot] + (MCD_SIZE + 1)) / MC2_MBSIZE,
FileMcd_IsMemoryCardFormatted(m_file[slot]) ? "Formatted" : "UNFORMATTED");

m_filenames[slot] = std::move(fname);
m_ispsx[slot] = m_fileSize[slot] == 0x20000;
m_chkaddr = 0x210;

if (!m_ispsx[slot])
{
std::memcpy(&m_chksum[slot], m_mappings[slot] + m_chkaddr, sizeof(m_chksum[slot]));
}
}
}
}
Expand All @@ -364,8 +365,8 @@ void FileMemoryCard::Close()
continue;

// Store checksum
if (!m_ispsx[slot] && FileSystem::FSeek64(m_file[slot], m_chkaddr, SEEK_SET) == 0)
std::fwrite(&m_chksum[slot], sizeof(m_chksum[slot]), 1, m_file[slot]);
if (!m_ispsx[slot] && m_chkaddr < m_fileSize[slot])
std::memcpy(m_mappings[slot] + m_chkaddr, &m_chksum[slot], sizeof(m_chksum[slot]));

std::fclose(m_file[slot]);
m_file[slot] = nullptr;
Expand Down Expand Up @@ -453,23 +454,20 @@ s32 FileMemoryCard::Read(uint slot, u8* dest, u32 adr, int size)
return 1;
}

#ifdef _WIN32
if (adr + size > static_cast<u32>(m_fileSize[slot]))
{
Console.Warning("(FileMcd) Warning: read past end of file. (%d) [%08X]", slot, adr);
}

std::memcpy(dest, m_mappings[slot] + adr, size);
return 1;
#else
if (!Seek(mcfp, adr))
return 0;
return std::fread(dest, size, 1, mcfp) == 1;
#endif
}

s32 FileMemoryCard::Save(uint slot, const u8* src, u32 adr, int size)
{
if (adr + size > static_cast<u32>(m_fileSize[slot]))
return 0;

std::FILE* mcfp = m_file[slot];

if (!mcfp)
Expand All @@ -487,14 +485,12 @@ s32 FileMemoryCard::Save(uint slot, const u8* src, u32 adr, int size)
}
else
{
if (!Seek(mcfp, adr))
if (adr + size > static_cast<u32>(m_fileSize[slot]))
return 0;
if (static_cast<int>(m_currentdata.size()) < size)
m_currentdata.resize(size);

const size_t read_result = std::fread(m_currentdata.data(), size, 1, mcfp);
if (read_result == 0)
Host::ReportErrorAsync("Memory Card Read Failed", "Error reading memory card.");
std::memcpy(m_currentdata.data(), m_mappings[slot] + adr, size);

for (int i = 0; i < size; i++)
{
Expand All @@ -516,26 +512,18 @@ s32 FileMemoryCard::Save(uint slot, const u8* src, u32 adr, int size)
}
}

if (!Seek(mcfp, adr))
return 0;
std::memcpy(m_mappings[slot] + adr, src, size);

if (std::fwrite(m_currentdata.data(), size, 1, mcfp) == 1)
std::chrono::duration<float> elapsed = std::chrono::system_clock::now() - m_lastSaveTime;
if (elapsed > std::chrono::seconds(5))
{
static auto last = std::chrono::time_point<std::chrono::system_clock>();

std::chrono::duration<float> elapsed = std::chrono::system_clock::now() - last;
if (elapsed > std::chrono::seconds(5))
{
Host::AddIconOSDMessage(fmt::format("MemoryCardSave{}", slot), ICON_PF_MEMORY_CARD,
fmt::format(TRANSLATE_FS("MemoryCard", "Memory Card '{}' was saved to storage."),
Path::GetFileName(m_filenames[slot])),
Host::OSD_INFO_DURATION);
last = std::chrono::system_clock::now();
}
return 1;
Host::AddIconOSDMessage(fmt::format("MemoryCardSave{}", slot), ICON_PF_MEMORY_CARD,
fmt::format(TRANSLATE_FS("MemoryCard", "Memory Card '{}' was saved to storage."),
Path::GetFileName(m_filenames[slot])),
Host::OSD_INFO_DURATION);
m_lastSaveTime = std::chrono::system_clock::now();
}

return 0;
return 1;
}

s32 FileMemoryCard::EraseBlock(uint slot, u32 adr)
Expand All @@ -549,15 +537,10 @@ s32 FileMemoryCard::EraseBlock(uint slot, u32 adr)

if (!Seek(mcfp, adr))
return 0;
#ifdef _WIN32

std::memset(m_mappings[slot] + adr, 0xff, MC2_ERASE_SIZE);

return 1;
#else
std::array<u8, MC2_ERASE_SIZE> buffer;
std::memset(buffer.data(), 0xff, buffer.size());
return std::fwrite(buffer.data(), buffer.size(), 1, mcfp) == 1;
#endif
}

u64 FileMemoryCard::GetCRC(uint slot)
Expand All @@ -570,9 +553,6 @@ u64 FileMemoryCard::GetCRC(uint slot)

if (m_ispsx[slot])
{
if (!Seek(mcfp, 0))
return 0;

const s64 mcfpsize = m_fileSize[slot];
if (mcfpsize < 0)
return 0;
Expand All @@ -584,8 +564,7 @@ u64 FileMemoryCard::GetCRC(uint slot)
const uint filesize = static_cast<uint>(mcfpsize) / sizeof(buffer);
for (uint i = filesize; i; --i)
{
if (std::fread(buffer, sizeof(buffer), 1, mcfp) != 1)
return 0;
std::memcpy(buffer, m_mappings[slot], sizeof(buffer));

for (uint t = 0; t < std::size(buffer); ++t)
retval ^= buffer[t];
Expand Down

0 comments on commit 60b8da1

Please sign in to comment.