Skip to content

Commit cbc55d4

Browse files
committed
Memory Cards: Actually implement the optimizations and the bugs that come with it on non-windows platforms
1 parent 4d600dc commit cbc55d4

File tree

5 files changed

+44
-67
lines changed

5 files changed

+44
-67
lines changed

common/Darwin/DarwinMisc.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -296,11 +296,11 @@ void* HostSys::CreateMappingFromFile(FILE* file)
296296
return reinterpret_cast<void*>(static_cast<uintptr_t>(fileno(file)));
297297
}
298298

299-
void* HostSys::MapMapping(void* handle, const PageProtectionMode& mode)
299+
void* HostSys::MapMapping(void* handle, size_t size, const PageProtectionMode& mode)
300300
{
301301
const u32 mmap_prot = (mode.CanWrite() ? (PROT_READ | PROT_WRITE) : (PROT_READ)) | (mode.CanExecute() ? PROT_EXEC : 0);
302302

303-
return mmap(nullptr, 0, mmap_prot, MAP_PRIVATE | MAP_ANON, static_cast<int>(reinterpret_cast<intptr_t>(handle)), 0);
303+
return mmap(nullptr, size, mmap_prot, MAP_PRIVATE | MAP_ANON, static_cast<int>(reinterpret_cast<intptr_t>(handle)), 0);
304304
}
305305

306306
void HostSys::DestroyMapping(void* handle)

common/HostSys.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ namespace HostSys
103103
extern void* CreateSharedMemory(const char* name, size_t size);
104104

105105
extern void* CreateMappingFromFile(FILE* file);
106-
extern void* MapMapping(void* handle, const PageProtectionMode& mode);
106+
extern void* MapMapping(void* handle, size_t size, const PageProtectionMode& mode);
107107
extern void DestroyMapping(void* handle);
108108

109109
extern void DestroySharedMemory(void* ptr);

common/Linux/LnxHostSys.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,9 @@ void* HostSys::CreateMappingFromFile(FILE* file)
120120
return reinterpret_cast<void*>(static_cast<intptr_t>(fileno(file)));
121121
}
122122

123-
void* HostSys::MapMapping(void* handle, const PageProtectionMode& mode)
123+
void* HostSys::MapMapping(void* handle, size_t size, const PageProtectionMode& mode)
124124
{
125-
return HostSys::MapSharedMemory(handle, 0, nullptr, 0, mode);
125+
return HostSys::MapSharedMemory(handle, 0, nullptr, size, mode);
126126
}
127127

128128
void HostSys::DestroyMapping(void* handle)

common/Windows/WinHostSys.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ void* HostSys::CreateMappingFromFile(FILE* fd)
7979
0, 0, nullptr));
8080
}
8181

82-
void* HostSys::MapMapping(void* handle, const PageProtectionMode& mode)
82+
void* HostSys::MapMapping(void* handle, size_t size, const PageProtectionMode& mode)
8383
{
8484
return MapViewOfFile(static_cast<HANDLE>(handle), FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
8585
}

pcsx2/SIO/Memcard/MemoryCardFile.cpp

Lines changed: 38 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,8 @@ class FileMemoryCard
168168
bool m_ispsx[8] = {};
169169
u32 m_chkaddr = 0;
170170

171+
std::chrono::time_point<std::chrono::system_clock> m_lastSaveTime = std::chrono::system_clock::now();
172+
171173
public:
172174
FileMemoryCard();
173175
~FileMemoryCard();
@@ -323,10 +325,22 @@ void FileMemoryCard::Open()
323325
"Close any other instances of PCSX2, or restart your computer.\n"),
324326
fname));
325327
}
326-
else // Load checksum
328+
else // Load memory map and checksum
327329
{
328330
m_fileSize[slot] = FileSystem::FSize64(m_file[slot]);
329331

332+
m_mapping_handles[slot] = HostSys::CreateMappingFromFile(m_file[slot]);
333+
if (!m_mapping_handles[slot])
334+
{
335+
Console.Warning("CreateMappingFromFile failed!");
336+
}
337+
338+
m_mappings[slot] = static_cast<u8*>(HostSys::MapMapping(m_mapping_handles[slot], m_fileSize[slot], PageAccess_ReadWrite()));
339+
if (!m_mappings[slot])
340+
{
341+
Console.Warning("MapSharedMemory failed! %d. %s", errno, strerror(errno));
342+
}
343+
330344
Console.WriteLnFmt(Color_Green, "McdSlot {} [File]: {} [{} MB, {}]", slot, Path::GetFileName(fname),
331345
(m_fileSize[slot] + (MCD_SIZE + 1)) / MC2_MBSIZE,
332346
FileMcd_IsMemoryCardFormatted(m_file[slot]) ? "Formatted" : "UNFORMATTED");
@@ -335,22 +349,9 @@ void FileMemoryCard::Open()
335349
m_ispsx[slot] = m_fileSize[slot] == 0x20000;
336350
m_chkaddr = 0x210;
337351

338-
if (!m_ispsx[slot] && FileSystem::FSeek64(m_file[slot], m_chkaddr, SEEK_SET) == 0)
352+
if (!m_ispsx[slot])
339353
{
340-
const size_t read_result = std::fread(&m_chksum[slot], sizeof(m_chksum[slot]), 1, m_file[slot]);
341-
if (read_result == 0)
342-
Host::ReportErrorAsync("Memory Card Read Failed", "Error reading memory card.");
343-
}
344-
345-
m_mapping_handles[slot] = HostSys::CreateMappingFromFile(m_file[slot]);
346-
if (!m_mapping_handles[slot])
347-
{
348-
Console.Warning("CreateMappingFromFile failed!");
349-
}
350-
m_mappings[slot] = static_cast<u8*>(HostSys::MapMapping(m_mapping_handles[slot], PageAccess_ReadWrite()));
351-
if (!m_mappings[slot])
352-
{
353-
Console.Warning("MapSharedMemory failed!");
354+
std::memcpy(&m_chksum[slot], m_mappings[slot] + m_chkaddr, sizeof(m_chksum[slot]));
354355
}
355356
}
356357
}
@@ -364,8 +365,8 @@ void FileMemoryCard::Close()
364365
continue;
365366

366367
// Store checksum
367-
if (!m_ispsx[slot] && FileSystem::FSeek64(m_file[slot], m_chkaddr, SEEK_SET) == 0)
368-
std::fwrite(&m_chksum[slot], sizeof(m_chksum[slot]), 1, m_file[slot]);
368+
if (!m_ispsx[slot])
369+
std::memcpy(m_mappings[slot] + m_chkaddr, &m_chksum[slot], sizeof(m_chksum[slot]));
369370

370371
std::fclose(m_file[slot]);
371372
m_file[slot] = nullptr;
@@ -377,15 +378,15 @@ void FileMemoryCard::Close()
377378
FileSystem::DeleteFilePath(name_in.c_str());
378379
}
379380

380-
m_filenames[slot] = {};
381-
m_fileSize[slot] = -1;
382-
383381
if (m_mappings[slot])
384382
{
385-
HostSys::UnmapSharedMemory(m_mappings[slot], 0);
383+
HostSys::UnmapSharedMemory(m_mappings[slot], m_fileSize[slot]);
386384
HostSys::DestroyMapping(m_mapping_handles[slot]);
387385
m_mappings[slot] = nullptr;
388386
}
387+
388+
m_filenames[slot] = {};
389+
m_fileSize[slot] = -1;
389390
}
390391
}
391392

@@ -453,23 +454,20 @@ s32 FileMemoryCard::Read(uint slot, u8* dest, u32 adr, int size)
453454
return 1;
454455
}
455456

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

462462
std::memcpy(dest, m_mappings[slot] + adr, size);
463463
return 1;
464-
#else
465-
if (!Seek(mcfp, adr))
466-
return 0;
467-
return std::fread(dest, size, 1, mcfp) == 1;
468-
#endif
469464
}
470465

471466
s32 FileMemoryCard::Save(uint slot, const u8* src, u32 adr, int size)
472467
{
468+
if (adr + size > static_cast<u32>(m_fileSize[slot]))
469+
return 0;
470+
473471
std::FILE* mcfp = m_file[slot];
474472

475473
if (!mcfp)
@@ -487,14 +485,10 @@ s32 FileMemoryCard::Save(uint slot, const u8* src, u32 adr, int size)
487485
}
488486
else
489487
{
490-
if (!Seek(mcfp, adr))
491-
return 0;
492488
if (static_cast<int>(m_currentdata.size()) < size)
493489
m_currentdata.resize(size);
494490

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

499493
for (int i = 0; i < size; i++)
500494
{
@@ -516,26 +510,18 @@ s32 FileMemoryCard::Save(uint slot, const u8* src, u32 adr, int size)
516510
}
517511
}
518512

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

522-
if (std::fwrite(m_currentdata.data(), size, 1, mcfp) == 1)
515+
std::chrono::duration<float> elapsed = std::chrono::system_clock::now() - m_lastSaveTime;
516+
if (elapsed > std::chrono::seconds(5))
523517
{
524-
static auto last = std::chrono::time_point<std::chrono::system_clock>();
525-
526-
std::chrono::duration<float> elapsed = std::chrono::system_clock::now() - last;
527-
if (elapsed > std::chrono::seconds(5))
528-
{
529-
Host::AddIconOSDMessage(fmt::format("MemoryCardSave{}", slot), ICON_PF_MEMORY_CARD,
530-
fmt::format(TRANSLATE_FS("MemoryCard", "Memory Card '{}' was saved to storage."),
531-
Path::GetFileName(m_filenames[slot])),
532-
Host::OSD_INFO_DURATION);
533-
last = std::chrono::system_clock::now();
534-
}
535-
return 1;
518+
Host::AddIconOSDMessage(fmt::format("MemoryCardSave{}", slot), ICON_PF_MEMORY_CARD,
519+
fmt::format(TRANSLATE_FS("MemoryCard", "Memory Card '{}' was saved to storage."),
520+
Path::GetFileName(m_filenames[slot])),
521+
Host::OSD_INFO_DURATION);
522+
m_lastSaveTime = std::chrono::system_clock::now();
536523
}
537-
538-
return 0;
524+
return 1;
539525
}
540526

541527
s32 FileMemoryCard::EraseBlock(uint slot, u32 adr)
@@ -549,15 +535,10 @@ s32 FileMemoryCard::EraseBlock(uint slot, u32 adr)
549535

550536
if (!Seek(mcfp, adr))
551537
return 0;
552-
#ifdef _WIN32
538+
553539
std::memset(m_mappings[slot] + adr, 0xff, MC2_ERASE_SIZE);
554540

555541
return 1;
556-
#else
557-
std::array<u8, MC2_ERASE_SIZE> buffer;
558-
std::memset(buffer.data(), 0xff, buffer.size());
559-
return std::fwrite(buffer.data(), buffer.size(), 1, mcfp) == 1;
560-
#endif
561542
}
562543

563544
u64 FileMemoryCard::GetCRC(uint slot)
@@ -570,9 +551,6 @@ u64 FileMemoryCard::GetCRC(uint slot)
570551

571552
if (m_ispsx[slot])
572553
{
573-
if (!Seek(mcfp, 0))
574-
return 0;
575-
576554
const s64 mcfpsize = m_fileSize[slot];
577555
if (mcfpsize < 0)
578556
return 0;
@@ -584,8 +562,7 @@ u64 FileMemoryCard::GetCRC(uint slot)
584562
const uint filesize = static_cast<uint>(mcfpsize) / sizeof(buffer);
585563
for (uint i = filesize; i; --i)
586564
{
587-
if (std::fread(buffer, sizeof(buffer), 1, mcfp) != 1)
588-
return 0;
565+
std::memcpy(buffer, m_mappings[slot], sizeof(buffer));
589566

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

0 commit comments

Comments
 (0)