[Project64] Make saving states more cross platform

This commit is contained in:
zilmar 2016-04-20 19:18:13 +10:00
parent 1e222705e4
commit 112ea9d8da
3 changed files with 79 additions and 85 deletions

View File

@ -318,7 +318,7 @@ bool CSystemTimer::SaveAllowed(void)
return true;
}
void CSystemTimer::SaveData(void * file) const
void CSystemTimer::SaveData(zipFile & file) const
{
uint32_t TimerDetailsSize = sizeof(TIMER_DETAILS);
uint32_t Entries = sizeof(m_TimerDetatils) / sizeof(m_TimerDetatils[0]);
@ -330,6 +330,19 @@ void CSystemTimer::SaveData(void * file) const
zipWriteInFileInZip(file, (void *)&m_Current, sizeof(m_Current));
}
void CSystemTimer::SaveData(CFile & file) const
{
uint32_t TimerDetailsSize = sizeof(TIMER_DETAILS);
uint32_t Entries = sizeof(m_TimerDetatils) / sizeof(m_TimerDetatils[0]);
file.Write(&TimerDetailsSize, sizeof(TimerDetailsSize));
file.Write(&Entries, sizeof(Entries));
file.Write((void *)&m_TimerDetatils, sizeof(m_TimerDetatils));
file.Write((void *)&m_LastUpdate, sizeof(m_LastUpdate));
file.Write(&m_NextTimer, sizeof(m_NextTimer));
file.Write((void *)&m_Current, sizeof(m_Current));
}
void CSystemTimer::LoadData(void * file)
{
uint32_t TimerDetailsSize, Entries;

View File

@ -12,6 +12,7 @@
#include <Common/LogClass.h>
#include <Project64-core/N64System/N64Types.h>
#include <Project64-core/3rdParty/Zip.h>
class CSystemTimer
{
@ -50,7 +51,8 @@ public:
void UpdateCompareTimer();
bool SaveAllowed();
void SaveData(void * file) const;
void SaveData(zipFile & file) const;
void SaveData(CFile & file) const;
void LoadData(void * file);
void RecordDifference(CLog &LogFile, const CSystemTimer& rSystemTimer);

View File

@ -1399,52 +1399,33 @@ bool CN64System::SaveState()
// if (!m_SystemTimer.SaveAllowed()) { return false; }
if ((m_Reg.STATUS_REGISTER & STATUS_EXL) != 0) { return false; }
//Get the file Name
stdstr FileName, ExtraInfoFileName, CurrentSaveName = g_Settings->LoadStringVal(GameRunning_InstantSaveFile);
if (CurrentSaveName.empty())
CPath SaveFile(g_Settings->LoadStringVal(GameRunning_InstantSaveFile));
int Slot = 0;
if (((const std::string &)SaveFile).empty())
{
int Slot = g_Settings->LoadDword(Game_CurrentSaveState);
if (Slot != 0)
{
CurrentSaveName.Format("%s.pj%d", g_Settings->LoadStringVal(Game_GoodName).c_str(), Slot);
}
else
{
CurrentSaveName.Format("%s.pj", g_Settings->LoadStringVal(Game_GoodName).c_str());
}
FileName.Format("%s%s", g_Settings->LoadStringVal(Directory_InstantSave).c_str(), CurrentSaveName.c_str());
stdstr_f ZipFileName("%s.zip", FileName.c_str());
//Make sure the target dir exists
CreateDirectory(g_Settings->LoadStringVal(Directory_InstantSave).c_str(), NULL);
//delete any old save
DeleteFile(FileName.c_str());
DeleteFile(ZipFileName.c_str());
ExtraInfoFileName.Format("%s.dat", CurrentSaveName.c_str());
//If ziping save add .zip on the end
if (g_Settings->LoadDword(Setting_AutoZipInstantSave))
{
FileName = ZipFileName;
}
Slot = g_Settings->LoadDword(Game_CurrentSaveState);
SaveFile = CPath(g_Settings->LoadStringVal(Directory_InstantSave).c_str(), "");
SaveFile.SetName(g_Settings->LoadStringVal(Game_GoodName).c_str());
g_Settings->SaveDword(Game_LastSaveSlot, g_Settings->LoadDword(Game_CurrentSaveState));
}
else
SaveFile.SetExtension(stdstr_f("pj%s", Slot != 0 ? stdstr_f("%d", Slot).c_str() : "").c_str());
CPath ExtraInfo(SaveFile);
ExtraInfo.SetExtension(".dat");
CPath ZipFile(SaveFile);
ZipFile.SetNameExtension(stdstr_f("%s.zip", ZipFile.GetNameExtension().c_str()).c_str());
//Make sure the target dir exists
if (!SaveFile.DirectoryExists())
{
char drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT];
_splitpath(CurrentSaveName.c_str(), drive, dir, fname, ext);
FileName.Format("%s.pj", CurrentSaveName.c_str());
CurrentSaveName.Format("%s.pj", fname);
ExtraInfoFileName.Format("%s.dat", fname);
//If ziping save add .zip on the end
if (g_Settings->LoadDword(Setting_AutoZipInstantSave))
{
FileName.Format("%s.zip", FileName.c_str());
}
SaveFile.DirectoryCreate();
}
if (FileName.empty()) { return true; }
//delete any old save
ExtraInfo.Delete();
SaveFile.Delete();
ZipFile.Delete();
//Open the file
if (g_Settings->LoadDword(Game_FuncLookupMode) == FuncFind_ChangeMemory)
@ -1461,10 +1442,8 @@ bool CN64System::SaveState()
uint32_t NextViTimer = m_SystemTimer.GetTimer(CSystemTimer::ViTimer);
if (g_Settings->LoadDword(Setting_AutoZipInstantSave))
{
zipFile file;
file = zipOpen(FileName.c_str(), 0);
zipOpenNewFileInZip(file, CurrentSaveName.c_str(), NULL, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION);
zipFile file = zipOpen(ZipFile, 0);
zipOpenNewFileInZip(file, SaveFile.GetNameExtension().c_str(), NULL, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION);
zipWriteInFileInZip(file, &SaveID_0, sizeof(SaveID_0));
zipWriteInFileInZip(file, &RdramSize, sizeof(uint32_t));
zipWriteInFileInZip(file, g_Rom->GetRomAddress(), 0x40);
@ -1492,7 +1471,7 @@ bool CN64System::SaveState()
zipWriteInFileInZip(file, m_MMU_VM.Imem(), 0x1000);
zipCloseFileInZip(file);
zipOpenNewFileInZip(file, ExtraInfoFileName.c_str(), NULL, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION);
zipOpenNewFileInZip(file, ExtraInfo.GetNameExtension().c_str(), NULL, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION);
zipWriteInFileInZip(file, &SaveID_1, sizeof(SaveID_1));
m_SystemTimer.SaveData(file);
zipCloseFileInZip(file);
@ -1501,9 +1480,8 @@ bool CN64System::SaveState()
}
else
{
HANDLE hSaveFile = CreateFile(FileName.c_str(), GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL);
if (hSaveFile == INVALID_HANDLE_VALUE)
CFile hSaveFile(SaveFile, CFileBase::modeWrite | CFileBase::modeCreate);
if (!hSaveFile.IsOpen())
{
g_Notify->DisplayError(GS(MSG_FAIL_OPEN_SAVE));
m_Reg.MI_INTR_REG = MiInterReg;
@ -1511,44 +1489,45 @@ bool CN64System::SaveState()
}
//Write info to file
SetFilePointer(hSaveFile, 0, NULL, FILE_BEGIN);
DWORD dwWritten;
WriteFile(hSaveFile, &SaveID_0, sizeof(uint32_t), &dwWritten, NULL);
WriteFile(hSaveFile, &RdramSize, sizeof(uint32_t), &dwWritten, NULL);
WriteFile(hSaveFile, g_Rom->GetRomAddress(), 0x40, &dwWritten, NULL);
WriteFile(hSaveFile, &NextViTimer, sizeof(uint32_t), &dwWritten, NULL);
WriteFile(hSaveFile, &m_Reg.m_PROGRAM_COUNTER, sizeof(m_Reg.m_PROGRAM_COUNTER), &dwWritten, NULL);
WriteFile(hSaveFile, m_Reg.m_GPR, sizeof(int64_t) * 32, &dwWritten, NULL);
WriteFile(hSaveFile, m_Reg.m_FPR, sizeof(int64_t) * 32, &dwWritten, NULL);
WriteFile(hSaveFile, m_Reg.m_CP0, sizeof(uint32_t) * 32, &dwWritten, NULL);
WriteFile(hSaveFile, m_Reg.m_FPCR, sizeof(uint32_t) * 32, &dwWritten, NULL);
WriteFile(hSaveFile, &m_Reg.m_HI, sizeof(int64_t), &dwWritten, NULL);
WriteFile(hSaveFile, &m_Reg.m_LO, sizeof(int64_t), &dwWritten, NULL);
WriteFile(hSaveFile, m_Reg.m_RDRAM_Registers, sizeof(uint32_t) * 10, &dwWritten, NULL);
WriteFile(hSaveFile, m_Reg.m_SigProcessor_Interface, sizeof(uint32_t) * 10, &dwWritten, NULL);
WriteFile(hSaveFile, m_Reg.m_Display_ControlReg, sizeof(uint32_t) * 10, &dwWritten, NULL);
WriteFile(hSaveFile, m_Reg.m_Mips_Interface, sizeof(uint32_t) * 4, &dwWritten, NULL);
WriteFile(hSaveFile, m_Reg.m_Video_Interface, sizeof(uint32_t) * 14, &dwWritten, NULL);
WriteFile(hSaveFile, m_Reg.m_Audio_Interface, sizeof(uint32_t) * 6, &dwWritten, NULL);
WriteFile(hSaveFile, m_Reg.m_Peripheral_Interface, sizeof(uint32_t) * 13, &dwWritten, NULL);
WriteFile(hSaveFile, m_Reg.m_RDRAM_Interface, sizeof(uint32_t) * 8, &dwWritten, NULL);
WriteFile(hSaveFile, m_Reg.m_SerialInterface, sizeof(uint32_t) * 4, &dwWritten, NULL);
WriteFile(hSaveFile, &g_TLB->TlbEntry(0), sizeof(CTLB::TLB_ENTRY) * 32, &dwWritten, NULL);
WriteFile(hSaveFile, g_MMU->PifRam(), 0x40, &dwWritten, NULL);
WriteFile(hSaveFile, g_MMU->Rdram(), RdramSize, &dwWritten, NULL);
WriteFile(hSaveFile, g_MMU->Dmem(), 0x1000, &dwWritten, NULL);
WriteFile(hSaveFile, g_MMU->Imem(), 0x1000, &dwWritten, NULL);
hSaveFile.SeekToBegin();
hSaveFile.Write(&SaveID_0, sizeof(uint32_t));
hSaveFile.Write(&RdramSize, sizeof(uint32_t));
hSaveFile.Write(g_Rom->GetRomAddress(), 0x40);
hSaveFile.Write(&NextViTimer, sizeof(uint32_t));
hSaveFile.Write(&m_Reg.m_PROGRAM_COUNTER, sizeof(m_Reg.m_PROGRAM_COUNTER));
hSaveFile.Write(m_Reg.m_GPR, sizeof(int64_t) * 32);
hSaveFile.Write(m_Reg.m_FPR, sizeof(int64_t) * 32);
hSaveFile.Write(m_Reg.m_CP0, sizeof(uint32_t) * 32);
hSaveFile.Write(m_Reg.m_FPCR, sizeof(uint32_t) * 32);
hSaveFile.Write(&m_Reg.m_HI, sizeof(int64_t));
hSaveFile.Write(&m_Reg.m_LO, sizeof(int64_t));
hSaveFile.Write(m_Reg.m_RDRAM_Registers, sizeof(uint32_t) * 10);
hSaveFile.Write(m_Reg.m_SigProcessor_Interface, sizeof(uint32_t) * 10);
hSaveFile.Write(m_Reg.m_Display_ControlReg, sizeof(uint32_t) * 10);
hSaveFile.Write(m_Reg.m_Mips_Interface, sizeof(uint32_t) * 4);
hSaveFile.Write(m_Reg.m_Video_Interface, sizeof(uint32_t) * 14);
hSaveFile.Write(m_Reg.m_Audio_Interface, sizeof(uint32_t) * 6);
hSaveFile.Write(m_Reg.m_Peripheral_Interface, sizeof(uint32_t) * 13);
hSaveFile.Write(m_Reg.m_RDRAM_Interface, sizeof(uint32_t) * 8);
hSaveFile.Write(m_Reg.m_SerialInterface, sizeof(uint32_t) * 4);
hSaveFile.Write(&g_TLB->TlbEntry(0), sizeof(CTLB::TLB_ENTRY) * 32);
hSaveFile.Write(g_MMU->PifRam(), 0x40);
hSaveFile.Write(g_MMU->Rdram(), RdramSize);
hSaveFile.Write(g_MMU->Dmem(), 0x1000);
hSaveFile.Write(g_MMU->Imem(), 0x1000);
hSaveFile.Close();
CloseHandle(hSaveFile);
CFile hExtraInfo(ExtraInfo, CFileBase::modeWrite | CFileBase::modeCreate);
if (hExtraInfo.IsOpen())
{
m_SystemTimer.SaveData(hExtraInfo);
hExtraInfo.Close();
}
}
m_Reg.MI_INTR_REG = MiInterReg;
g_Settings->SaveString(GameRunning_InstantSaveFile, "");
std::string SaveMessage = g_Lang->GetString(MSG_SAVED_STATE);
CPath SavedFileName(FileName);
g_Notify->DisplayMessage(5, stdstr_f("%s %s", SaveMessage.c_str(), stdstr(SavedFileName.GetNameExtension()).c_str()).c_str());
//Notify().RefreshMenu();
g_Notify->DisplayMessage(5, stdstr_f("%s %s", g_Lang->GetString(MSG_SAVED_STATE).c_str(), stdstr(SaveFile.GetNameExtension()).c_str()).c_str());
WriteTrace(TraceN64System, TraceDebug, "Done");
return true;
}