mirror of https://github.com/PCSX2/pcsx2.git
Memory Cards: Actually implement the optimizations and the bugs that come with it on non-windows platforms
This commit is contained in:
parent
3ee09ae035
commit
43148d465d
|
@ -360,11 +360,11 @@ void* HostSys::CreateMappingFromFile(FILE* file)
|
|||
return reinterpret_cast<void*>(static_cast<uintptr_t>(fileno(file)));
|
||||
}
|
||||
|
||||
void* HostSys::MapMapping(void* handle, const PageProtectionMode& mode)
|
||||
void* HostSys::MapMapping(void* handle, size_t size, const PageProtectionMode& mode)
|
||||
{
|
||||
const u32 mmap_prot = (mode.CanWrite() ? (PROT_READ | PROT_WRITE) : (PROT_READ)) | (mode.CanExecute() ? PROT_EXEC : 0);
|
||||
|
||||
return mmap(nullptr, 0, mmap_prot, MAP_PRIVATE | MAP_ANON, static_cast<int>(reinterpret_cast<intptr_t>(handle)), 0);
|
||||
return mmap(nullptr, size, mmap_prot, MAP_PRIVATE | MAP_ANON, static_cast<int>(reinterpret_cast<intptr_t>(handle)), 0);
|
||||
}
|
||||
|
||||
void HostSys::DestroyMapping(void* handle)
|
||||
|
|
|
@ -104,7 +104,7 @@ namespace HostSys
|
|||
extern void* CreateSharedMemory(const char* name, size_t size);
|
||||
|
||||
extern void* CreateMappingFromFile(FILE* file);
|
||||
extern void* MapMapping(void* handle, const PageProtectionMode& mode);
|
||||
extern void* MapMapping(void* handle, size_t size, const PageProtectionMode& mode);
|
||||
extern void DestroyMapping(void* handle);
|
||||
|
||||
extern void DestroySharedMemory(void* ptr);
|
||||
|
|
|
@ -120,9 +120,9 @@ void* HostSys::CreateMappingFromFile(FILE* file)
|
|||
return reinterpret_cast<void*>(static_cast<intptr_t>(fileno(file)));
|
||||
}
|
||||
|
||||
void* HostSys::MapMapping(void* handle, const PageProtectionMode& mode)
|
||||
void* HostSys::MapMapping(void* handle, size_t size, const PageProtectionMode& mode)
|
||||
{
|
||||
return HostSys::MapSharedMemory(handle, 0, nullptr, 0, mode);
|
||||
return HostSys::MapSharedMemory(handle, 0, nullptr, size, mode);
|
||||
}
|
||||
|
||||
void HostSys::DestroyMapping(void* handle)
|
||||
|
|
|
@ -78,7 +78,7 @@ void* HostSys::CreateMappingFromFile(FILE* fd)
|
|||
0, 0, nullptr));
|
||||
}
|
||||
|
||||
void* HostSys::MapMapping(void* handle, const PageProtectionMode& mode)
|
||||
void* HostSys::MapMapping(void* handle, size_t size, const PageProtectionMode& mode)
|
||||
{
|
||||
return MapViewOfFile(static_cast<HANDLE>(handle), FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
|
||||
}
|
||||
|
|
|
@ -168,6 +168,8 @@ protected:
|
|||
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();
|
||||
|
@ -323,10 +325,22 @@ 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]);
|
||||
|
||||
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], m_fileSize[slot], PageAccess_ReadWrite()));
|
||||
if (!m_mappings[slot])
|
||||
{
|
||||
Console.Warning("MapSharedMemory failed! %d. %s", errno, strerror(errno));
|
||||
}
|
||||
|
||||
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");
|
||||
|
@ -335,22 +349,9 @@ void FileMemoryCard::Open()
|
|||
m_ispsx[slot] = m_fileSize[slot] == 0x20000;
|
||||
m_chkaddr = 0x210;
|
||||
|
||||
if (!m_ispsx[slot] && FileSystem::FSeek64(m_file[slot], m_chkaddr, SEEK_SET) == 0)
|
||||
if (!m_ispsx[slot])
|
||||
{
|
||||
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!");
|
||||
std::memcpy(&m_chksum[slot], m_mappings[slot] + m_chkaddr, sizeof(m_chksum[slot]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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])
|
||||
std::memcpy(m_mappings[slot] + m_chkaddr, &m_chksum[slot], sizeof(m_chksum[slot]));
|
||||
|
||||
std::fclose(m_file[slot]);
|
||||
m_file[slot] = nullptr;
|
||||
|
@ -377,15 +378,15 @@ void FileMemoryCard::Close()
|
|||
FileSystem::DeleteFilePath(name_in.c_str());
|
||||
}
|
||||
|
||||
m_filenames[slot] = {};
|
||||
m_fileSize[slot] = -1;
|
||||
|
||||
if (m_mappings[slot])
|
||||
{
|
||||
HostSys::UnmapSharedMemory(m_mappings[slot], 0);
|
||||
HostSys::UnmapSharedMemory(m_mappings[slot], m_fileSize[slot]);
|
||||
HostSys::DestroyMapping(m_mapping_handles[slot]);
|
||||
m_mappings[slot] = nullptr;
|
||||
}
|
||||
|
||||
m_filenames[slot] = {};
|
||||
m_fileSize[slot] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -453,7 +454,6 @@ 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);
|
||||
|
@ -461,15 +461,13 @@ s32 FileMemoryCard::Read(uint slot, u8* dest, u32 adr, int size)
|
|||
|
||||
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)
|
||||
|
@ -487,14 +485,10 @@ s32 FileMemoryCard::Save(uint slot, const u8* src, u32 adr, int size)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!Seek(mcfp, adr))
|
||||
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++)
|
||||
{
|
||||
|
@ -516,26 +510,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)
|
||||
|
@ -549,15 +535,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)
|
||||
|
@ -570,9 +551,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;
|
||||
|
@ -584,8 +562,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];
|
||||
|
|
Loading…
Reference in New Issue