diff --git a/Source/Android/jni/MainAndroid.cpp b/Source/Android/jni/MainAndroid.cpp index 91d0dd7d9f..5f8f71a08b 100644 --- a/Source/Android/jni/MainAndroid.cpp +++ b/Source/Android/jni/MainAndroid.cpp @@ -315,7 +315,7 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SaveState(JN jboolean wait) { HostThreadLock guard; - State::Save(slot, wait); + State::Save(Core::System::GetInstance(), slot, wait); } JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SaveStateAs(JNIEnv* env, jclass, @@ -323,21 +323,21 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SaveStateAs( jboolean wait) { HostThreadLock guard; - State::SaveAs(GetJString(env, path), wait); + State::SaveAs(Core::System::GetInstance(), GetJString(env, path), wait); } JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_LoadState(JNIEnv*, jclass, jint slot) { HostThreadLock guard; - State::Load(slot); + State::Load(Core::System::GetInstance(), slot); } JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_LoadStateAs(JNIEnv* env, jclass, jstring path) { HostThreadLock guard; - State::LoadAs(GetJString(env, path)); + State::LoadAs(Core::System::GetInstance(), GetJString(env, path)); } JNIEXPORT jlong JNICALL diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index 7efee6563d..565ff0d2eb 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -389,7 +389,7 @@ static void CpuThread(Core::System& system, const std::optional& sa if (savestate_path) { - ::State::LoadAs(*savestate_path); + ::State::LoadAs(system, *savestate_path); if (delete_savestate) File::Delete(*savestate_path); } diff --git a/Source/Core/Core/HW/HW.cpp b/Source/Core/Core/HW/HW.cpp index 20aed37a17..524feab884 100644 --- a/Source/Core/Core/HW/HW.cpp +++ b/Source/Core/Core/HW/HW.cpp @@ -35,7 +35,7 @@ void Init(Core::System& system, const Sram* override_sram) system.GetCoreTiming().Init(); system.GetSystemTimers().PreInit(); - State::Init(); + State::Init(system); // Init the whole Hardware system.GetAudioInterface().Init(); diff --git a/Source/Core/Core/Movie.cpp b/Source/Core/Core/Movie.cpp index e576afc1b7..a21a5afb33 100644 --- a/Source/Core/Core/Movie.cpp +++ b/Source/Core/Core/Movie.cpp @@ -541,7 +541,7 @@ bool MovieManager::BeginRecordingInput(const ControllerTypeArray& controllers, if (File::Exists(save_path)) File::Delete(save_path); - State::SaveAs(save_path); + State::SaveAs(m_system, save_path); m_recording_from_save_state = true; std::thread md5thread(&MovieManager::GetMD5, this); diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp index 83c7655203..4e7d061d36 100644 --- a/Source/Core/Core/State.cpp +++ b/Source/Core/Core/State.cpp @@ -138,10 +138,8 @@ void EnableCompression(bool compression) s_use_compression = compression; } -static void DoState(PointerWrap& p) +static void DoState(Core::System& system, PointerWrap& p) { - auto& system = Core::System::GetInstance(); - bool is_wii = system.IsWii() || system.IsMIOS(); const bool is_wii_currently = is_wii; p.Do(is_wii); @@ -202,7 +200,7 @@ static void DoState(PointerWrap& p) p.DoMarker("Gecko"); } -void LoadFromBuffer(std::vector& buffer) +void LoadFromBuffer(Core::System& system, std::vector& buffer) { if (NetPlay::IsNetPlayRunning()) { @@ -222,25 +220,25 @@ void LoadFromBuffer(std::vector& buffer) [&] { u8* ptr = buffer.data(); PointerWrap p(&ptr, buffer.size(), PointerWrap::Mode::Read); - DoState(p); + DoState(system, p); }, true); } -void SaveToBuffer(std::vector& buffer) +void SaveToBuffer(Core::System& system, std::vector& buffer) { Core::RunOnCPUThread( [&] { u8* ptr = nullptr; PointerWrap p_measure(&ptr, 0, PointerWrap::Mode::Measure); - DoState(p_measure); + DoState(system, p_measure); const size_t buffer_size = reinterpret_cast(ptr); buffer.resize(buffer_size); ptr = buffer.data(); PointerWrap p(&ptr, buffer_size, PointerWrap::Mode::Write); - DoState(p); + DoState(system, p); }, true); } @@ -382,7 +380,7 @@ static void WriteHeadersToFile(size_t uncompressed_size, File::IOFile& f) // If StateExtendedHeader is amended to include more than the base, add WriteBytes() calls here. } -static void CompressAndDumpState(CompressAndDumpState_args& save_args) +static void CompressAndDumpState(Core::System& system, CompressAndDumpState_args& save_args) { const u8* const buffer_data = save_args.buffer_vector.data(); const size_t buffer_size = save_args.buffer_vector.size(); @@ -442,7 +440,7 @@ static void CompressAndDumpState(CompressAndDumpState_args& save_args) } } - auto& movie = Core::System::GetInstance().GetMovie(); + auto& movie = system.GetMovie(); if ((movie.IsMovieActive()) && !movie.IsJustStartingRecordingInputFromSaveState()) movie.SaveRecording(dtmname); else if (!movie.IsMovieActive()) @@ -468,7 +466,7 @@ static void CompressAndDumpState(CompressAndDumpState_args& save_args) Host_UpdateMainFrame(); } -void SaveAs(const std::string& filename, bool wait) +void SaveAs(Core::System& system, const std::string& filename, bool wait) { std::unique_lock lk(s_load_or_save_in_progress_mutex, std::try_to_lock); if (!lk) @@ -484,7 +482,7 @@ void SaveAs(const std::string& filename, bool wait) // Measure the size of the buffer. u8* ptr = nullptr; PointerWrap p_measure(&ptr, 0, PointerWrap::Mode::Measure); - DoState(p_measure); + DoState(system, p_measure); const size_t buffer_size = reinterpret_cast(ptr); // Then actually do the write. @@ -492,7 +490,7 @@ void SaveAs(const std::string& filename, bool wait) current_buffer.resize(buffer_size); ptr = current_buffer.data(); PointerWrap p(&ptr, buffer_size, PointerWrap::Mode::Write); - DoState(p); + DoState(system, p); if (p.IsWriteMode()) { @@ -849,7 +847,7 @@ static void LoadFileStateData(const std::string& filename, std::vector& ret_ ret_data.swap(buffer); } -void LoadAs(const std::string& filename) +void LoadAs(Core::System& system, const std::string& filename) { if (!Core::IsRunning()) return; @@ -875,11 +873,11 @@ void LoadAs(const std::string& filename) Core::RunOnCPUThread( [&] { // Save temp buffer for undo load state - auto& movie = Core::System::GetInstance().GetMovie(); + auto& movie = system.GetMovie(); if (!movie.IsJustStartingRecordingInputFromSaveState()) { std::lock_guard lk2(s_undo_load_buffer_mutex); - SaveToBuffer(s_undo_load_buffer); + SaveToBuffer(system, s_undo_load_buffer); const std::string dtmpath = File::GetUserPath(D_STATESAVES_IDX) + "undo.dtm"; if (movie.IsMovieActive()) movie.SaveRecording(dtmpath); @@ -899,7 +897,7 @@ void LoadAs(const std::string& filename) { u8* ptr = buffer.data(); PointerWrap p(&ptr, buffer.size(), PointerWrap::Mode::Read); - DoState(p); + DoState(system, p); loaded = true; loadedSuccessfully = p.IsReadMode(); } @@ -923,7 +921,7 @@ void LoadAs(const std::string& filename) Core::DisplayMessage("The savestate could not be loaded", OSD::Duration::NORMAL); // since we could be in an inconsistent state now (and might crash or whatever), undo. - UndoLoadState(); + UndoLoadState(system); } } @@ -938,10 +936,10 @@ void SetOnAfterLoadCallback(AfterLoadCallbackFunc callback) s_on_after_load_callback = std::move(callback); } -void Init() +void Init(Core::System& system) { - s_save_thread.Reset("Savestate Worker", [](CompressAndDumpState_args args) { - CompressAndDumpState(args); + s_save_thread.Reset("Savestate Worker", [&system](CompressAndDumpState_args args) { + CompressAndDumpState(system, args); { std::lock_guard lk(s_state_writes_in_queue_mutex); @@ -973,17 +971,17 @@ static std::string MakeStateFilename(int number) SConfig::GetInstance().GetGameID(), number); } -void Save(int slot, bool wait) +void Save(Core::System& system, int slot, bool wait) { - SaveAs(MakeStateFilename(slot), wait); + SaveAs(system, MakeStateFilename(slot), wait); } -void Load(int slot) +void Load(Core::System& system, int slot) { - LoadAs(MakeStateFilename(slot)); + LoadAs(system, MakeStateFilename(slot)); } -void LoadLastSaved(int i) +void LoadLastSaved(Core::System& system, int i) { if (i <= 0) { @@ -999,38 +997,38 @@ void LoadLastSaved(int i) } std::stable_sort(used_slots.begin(), used_slots.end(), CompareTimestamp); - Load((used_slots.end() - i)->slot); + Load(system, (used_slots.end() - i)->slot); } // must wait for state to be written because it must know if all slots are taken -void SaveFirstSaved() +void SaveFirstSaved(Core::System& system) { std::vector used_slots = GetUsedSlotsWithTimestamp(); if (used_slots.size() < NUM_STATES) { // save to an empty slot - Save(GetEmptySlot(used_slots), true); + Save(system, GetEmptySlot(used_slots), true); return; } // overwrite the oldest state std::stable_sort(used_slots.begin(), used_slots.end(), CompareTimestamp); - Save(used_slots.front().slot, true); + Save(system, used_slots.front().slot, true); } // Load the last state before loading the state -void UndoLoadState() +void UndoLoadState(Core::System& system) { std::lock_guard lk(s_undo_load_buffer_mutex); if (!s_undo_load_buffer.empty()) { - auto& movie = Core::System::GetInstance().GetMovie(); + auto& movie = system.GetMovie(); if (movie.IsMovieActive()) { const std::string dtmpath = File::GetUserPath(D_STATESAVES_IDX) + "undo.dtm"; if (File::Exists(dtmpath)) { - LoadFromBuffer(s_undo_load_buffer); + LoadFromBuffer(system, s_undo_load_buffer); movie.LoadInput(dtmpath); } else @@ -1040,7 +1038,7 @@ void UndoLoadState() } else { - LoadFromBuffer(s_undo_load_buffer); + LoadFromBuffer(system, s_undo_load_buffer); } } else @@ -1050,9 +1048,9 @@ void UndoLoadState() } // Load the state that the last save state overwritten on -void UndoSaveState() +void UndoSaveState(Core::System& system) { - LoadAs(File::GetUserPath(D_STATESAVES_IDX) + "lastState.sav"); + LoadAs(system, File::GetUserPath(D_STATESAVES_IDX) + "lastState.sav"); } } // namespace State diff --git a/Source/Core/Core/State.h b/Source/Core/Core/State.h index 7d592b2d88..626a0ecca4 100644 --- a/Source/Core/Core/State.h +++ b/Source/Core/Core/State.h @@ -13,6 +13,11 @@ #include "Common/CommonTypes.h" +namespace Core +{ +class System; +} + namespace State { // number of states @@ -75,7 +80,7 @@ struct StateExtendedHeader // and WriteHeadersToFile() }; -void Init(); +void Init(Core::System& system); void Shutdown(); @@ -95,19 +100,19 @@ u64 GetUnixTimeOfSlot(int slot); // If we're in the main CPU thread then they run immediately instead // because some things (like Lua) need them to run immediately. // Slots from 0-99. -void Save(int slot, bool wait = false); -void Load(int slot); +void Save(Core::System& system, int slot, bool wait = false); +void Load(Core::System& system, int slot); -void SaveAs(const std::string& filename, bool wait = false); -void LoadAs(const std::string& filename); +void SaveAs(Core::System& system, const std::string& filename, bool wait = false); +void LoadAs(Core::System& system, const std::string& filename); -void SaveToBuffer(std::vector& buffer); -void LoadFromBuffer(std::vector& buffer); +void SaveToBuffer(Core::System& system, std::vector& buffer); +void LoadFromBuffer(Core::System& system, std::vector& buffer); -void LoadLastSaved(int i = 1); -void SaveFirstSaved(); -void UndoSaveState(); -void UndoLoadState(); +void LoadLastSaved(Core::System& system, int i = 1); +void SaveFirstSaved(Core::System& system); +void UndoSaveState(Core::System& system); +void UndoLoadState(Core::System& system); // for calling back into UI code without introducing a dependency on it in core using AfterLoadCallbackFunc = std::function; diff --git a/Source/Core/DolphinNoGUI/PlatformMacos.mm b/Source/Core/DolphinNoGUI/PlatformMacos.mm index 0bdfd44356..142f38bb5e 100644 --- a/Source/Core/DolphinNoGUI/PlatformMacos.mm +++ b/Source/Core/DolphinNoGUI/PlatformMacos.mm @@ -55,27 +55,27 @@ - (void)loadLastSaved { - State::LoadLastSaved(); + State::LoadLastSaved(Core::System::GetInstance()); } - (void)undoLoadState { - State::UndoLoadState(); + State::UndoLoadState(Core::System::GetInstance()); } - (void)undoSaveState { - State::UndoSaveState(); + State::UndoSaveState(Core::System::GetInstance()); } - (void)loadState:(id)sender { - State::Load([sender tag]); + State::Load(Core::System::GetInstance(), [sender tag]); } - (void)saveState:(id)sender { - State::Save([sender tag]); + State::Save(Core::System::GetInstance(), [sender tag]); } @end diff --git a/Source/Core/DolphinNoGUI/PlatformX11.cpp b/Source/Core/DolphinNoGUI/PlatformX11.cpp index 16cfaa3683..707a533069 100644 --- a/Source/Core/DolphinNoGUI/PlatformX11.cpp +++ b/Source/Core/DolphinNoGUI/PlatformX11.cpp @@ -225,20 +225,20 @@ void PlatformX11::ProcessEvents() { int slot_number = key - XK_F1 + 1; if (event.xkey.state & ShiftMask) - State::Save(slot_number); + State::Save(Core::System::GetInstance(), slot_number); else - State::Load(slot_number); + State::Load(Core::System::GetInstance(), slot_number); } else if (key == XK_F9) Core::SaveScreenShot(); else if (key == XK_F11) - State::LoadLastSaved(); + State::LoadLastSaved(Core::System::GetInstance()); else if (key == XK_F12) { if (event.xkey.state & ShiftMask) - State::UndoLoadState(); + State::UndoLoadState(Core::System::GetInstance()); else - State::UndoSaveState(); + State::UndoSaveState(Core::System::GetInstance()); } break; case FocusIn: diff --git a/Source/Core/DolphinQt/MainWindow.cpp b/Source/Core/DolphinQt/MainWindow.cpp index 7e7086e5af..576759bd52 100644 --- a/Source/Core/DolphinQt/MainWindow.cpp +++ b/Source/Core/DolphinQt/MainWindow.cpp @@ -1414,7 +1414,7 @@ void MainWindow::StateLoad() this, tr("Select a File"), dialog_path, tr("All Save States (*.sav *.s##);; All Files (*)")); Config::SetBase(Config::MAIN_CURRENT_STATE_PATH, QFileInfo(path).dir().path().toStdString()); if (!path.isEmpty()) - State::LoadAs(path.toStdString()); + State::LoadAs(Core::System::GetInstance(), path.toStdString()); } void MainWindow::StateSave() @@ -1426,47 +1426,47 @@ void MainWindow::StateSave() this, tr("Select a File"), dialog_path, tr("All Save States (*.sav *.s##);; All Files (*)")); Config::SetBase(Config::MAIN_CURRENT_STATE_PATH, QFileInfo(path).dir().path().toStdString()); if (!path.isEmpty()) - State::SaveAs(path.toStdString()); + State::SaveAs(Core::System::GetInstance(), path.toStdString()); } void MainWindow::StateLoadSlot() { - State::Load(m_state_slot); + State::Load(Core::System::GetInstance(), m_state_slot); } void MainWindow::StateSaveSlot() { - State::Save(m_state_slot); + State::Save(Core::System::GetInstance(), m_state_slot); } void MainWindow::StateLoadSlotAt(int slot) { - State::Load(slot); + State::Load(Core::System::GetInstance(), slot); } void MainWindow::StateLoadLastSavedAt(int slot) { - State::LoadLastSaved(slot); + State::LoadLastSaved(Core::System::GetInstance(), slot); } void MainWindow::StateSaveSlotAt(int slot) { - State::Save(slot); + State::Save(Core::System::GetInstance(), slot); } void MainWindow::StateLoadUndo() { - State::UndoLoadState(); + State::UndoLoadState(Core::System::GetInstance()); } void MainWindow::StateSaveUndo() { - State::UndoSaveState(); + State::UndoSaveState(Core::System::GetInstance()); } void MainWindow::StateSaveOldest() { - State::SaveFirstSaved(); + State::SaveFirstSaved(Core::System::GetInstance()); } void MainWindow::SetStateSlot(int slot) diff --git a/Source/Core/DolphinQt/RenderWidget.cpp b/Source/Core/DolphinQt/RenderWidget.cpp index ac07dfcf27..5518aa41fc 100644 --- a/Source/Core/DolphinQt/RenderWidget.cpp +++ b/Source/Core/DolphinQt/RenderWidget.cpp @@ -22,6 +22,7 @@ #include "Core/Config/MainSettings.h" #include "Core/Core.h" #include "Core/State.h" +#include "Core/System.h" #include "DolphinQt/Host.h" #include "DolphinQt/QtUtils/ModalMessageBox.h" @@ -129,7 +130,7 @@ void RenderWidget::dropEvent(QDropEvent* event) return; } - State::LoadAs(path.toStdString()); + State::LoadAs(Core::System::GetInstance(), path.toStdString()); } void RenderWidget::OnHideCursorChanged()