diff --git a/Source/Project64-core/N64System/Mips/SystemTiming.cpp b/Source/Project64-core/N64System/Mips/SystemTiming.cpp index 736e9518b..5e99786eb 100644 --- a/Source/Project64-core/N64System/Mips/SystemTiming.cpp +++ b/Source/Project64-core/N64System/Mips/SystemTiming.cpp @@ -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; diff --git a/Source/Project64-core/N64System/Mips/SystemTiming.h b/Source/Project64-core/N64System/Mips/SystemTiming.h index 85969a2cc..0c1d8975f 100644 --- a/Source/Project64-core/N64System/Mips/SystemTiming.h +++ b/Source/Project64-core/N64System/Mips/SystemTiming.h @@ -12,6 +12,7 @@ #include #include +#include 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); diff --git a/Source/Project64-core/N64System/N64Class.cpp b/Source/Project64-core/N64System/N64Class.cpp index ab71fbf0f..8b36b1c18 100644 --- a/Source/Project64-core/N64System/N64Class.cpp +++ b/Source/Project64-core/N64System/N64Class.cpp @@ -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; }