summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Common/Src/ChunkFile.h11
-rw-r--r--Source/Core/Core/Src/CoreTiming.cpp2
-rw-r--r--Source/Core/Core/Src/HW/HW.cpp12
-rw-r--r--Source/Core/Core/Src/HW/Memmap.cpp3
-rw-r--r--Source/Core/Core/Src/State.cpp33
5 files changed, 55 insertions, 6 deletions
diff --git a/Source/Core/Common/Src/ChunkFile.h b/Source/Core/Common/Src/ChunkFile.h
index 03216deaf1..b0662d2517 100644
--- a/Source/Core/Common/Src/ChunkFile.h
+++ b/Source/Core/Common/Src/ChunkFile.h
@@ -170,6 +170,17 @@ public:
// TODO
PanicAlert("Do(linked list<>) does not yet work.");
}
+
+ void DoMarker(const char* prevName, u32 arbitraryNumber=0x42)
+ {
+ u32 cookie = arbitraryNumber;
+ Do(cookie);
+ if(mode == PointerWrap::MODE_READ && cookie != arbitraryNumber)
+ {
+ PanicAlertT("Error: After \"%s\", found %d (0x%X) instead of save marker %d (0x%X). Aborting savestate load...", prevName, cookie, cookie, arbitraryNumber, arbitraryNumber);
+ mode = PointerWrap::MODE_MEASURE;
+ }
+ }
};
diff --git a/Source/Core/Core/Src/CoreTiming.cpp b/Source/Core/Core/Src/CoreTiming.cpp
index 9aacea5847..979add358b 100644
--- a/Source/Core/Core/Src/CoreTiming.cpp
+++ b/Source/Core/Core/Src/CoreTiming.cpp
@@ -163,6 +163,7 @@ void DoState(PointerWrap &p)
p.Do(fakeDecStartTicks);
p.Do(fakeTBStartValue);
p.Do(fakeTBStartTicks);
+ p.DoMarker("CoreTimingData");
// OK, here we're gonna need to specialize depending on the mode.
// Should do something generic to serialize linked lists.
switch (p.GetMode()) {
@@ -209,6 +210,7 @@ void DoState(PointerWrap &p)
break;
}
}
+ p.DoMarker("CoreTimingEvents");
}
u64 GetTicks()
diff --git a/Source/Core/Core/Src/HW/HW.cpp b/Source/Core/Core/Src/HW/HW.cpp
index ec8aa7063f..a078955815 100644
--- a/Source/Core/Core/Src/HW/HW.cpp
+++ b/Source/Core/Core/Src/HW/HW.cpp
@@ -89,18 +89,30 @@ namespace HW
void DoState(PointerWrap &p)
{
Memory::DoState(p);
+ p.DoMarker("Memory");
VideoInterface::DoState(p);
+ p.DoMarker("VideoInterface");
SerialInterface::DoState(p);
+ p.DoMarker("SerialInterface");
ProcessorInterface::DoState(p);
+ p.DoMarker("ProcessorInterface");
DSP::DoState(p);
+ p.DoMarker("DSP");
DVDInterface::DoState(p);
+ p.DoMarker("DVDInterface");
GPFifo::DoState(p);
+ p.DoMarker("GPFifo");
ExpansionInterface::DoState(p);
+ p.DoMarker("ExpansionInterface");
AudioInterface::DoState(p);
+ p.DoMarker("AudioInterface");
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii)
{
WII_IPCInterface::DoState(p);
+ p.DoMarker("WII_IPCInterface");
WII_IPC_HLE_Interface::DoState(p);
+ p.DoMarker("WII_IPC_HLE_Interface");
}
+ p.DoMarker("WIIHW");
}
}
diff --git a/Source/Core/Core/Src/HW/Memmap.cpp b/Source/Core/Core/Src/HW/Memmap.cpp
index 980b080761..f26ac76a14 100644
--- a/Source/Core/Core/Src/HW/Memmap.cpp
+++ b/Source/Core/Core/Src/HW/Memmap.cpp
@@ -373,10 +373,13 @@ void DoState(PointerWrap &p)
p.DoArray(m_pPhysicalRAM, RAM_SIZE);
// p.DoArray(m_pVirtualEFB, EFB_SIZE);
p.DoArray(m_pVirtualL1Cache, L1_CACHE_SIZE);
+ p.DoMarker("Memory RAM");
if (bFakeVMEM)
p.DoArray(m_pVirtualFakeVMEM, FAKEVMEM_SIZE);
+ p.DoMarker("Memory FakeVMEM");
if (wii)
p.DoArray(m_pEXRAM, EXRAM_SIZE);
+ p.DoMarker("Memory EXRAM");
}
void Shutdown()
diff --git a/Source/Core/Core/Src/State.cpp b/Source/Core/Core/Src/State.cpp
index 7cfcba66d5..e8dcddcb62 100644
--- a/Source/Core/Core/Src/State.cpp
+++ b/Source/Core/Core/Src/State.cpp
@@ -64,6 +64,7 @@ static std::string g_current_filename, g_last_filename;
// Temporary undo state buffer
static std::vector<u8> g_undo_load_buffer;
static std::vector<u8> g_current_buffer;
+static int g_loadDepth = 0;
static std::thread g_save_thread;
@@ -74,7 +75,7 @@ static u64 lastCheckedStates[NUM_HOOKS];
static u8 hook;
// Don't forget to increase this after doing changes on the savestate system
-static const int STATE_VERSION = 6;
+static const int STATE_VERSION = 7;
struct StateHeader
{
@@ -121,18 +122,26 @@ void DoState(PointerWrap &p)
}
}
+ p.DoMarker("Version");
+
// Begin with video backend, so that it gets a chance to clear it's caches and writeback modified things to RAM
// Pause the video thread in multi-threaded mode
g_video_backend->RunLoop(false);
g_video_backend->DoState(p);
+ p.DoMarker("video_backend");
if (Core::g_CoreStartupParameter.bWii)
Wiimote::DoState(p.GetPPtr(), p.GetMode());
+ p.DoMarker("Wiimote");
PowerPC::DoState(p);
+ p.DoMarker("PowerPC");
HW::DoState(p);
+ p.DoMarker("HW");
CoreTiming::DoState(p);
+ p.DoMarker("CoreTiming");
Movie::DoState(p, version<6);
+ p.DoMarker("Movie");
// Resume the video thread
g_video_backend->RunLoop(true);
@@ -353,6 +362,8 @@ void LoadFileStateCallback(u64 userdata, int cyclesLate)
// Stop the core while we load the state
CCPU::EnableStepping(true);
+ g_loadDepth++;
+
Flush();
// Save temp buffer for undo load state
@@ -371,20 +382,30 @@ void LoadFileStateCallback(u64 userdata, int cyclesLate)
DoState(p);
if (p.GetMode() == PointerWrap::MODE_READ)
+ {
Core::DisplayMessage(StringFromFormat("Loaded state from %s", g_current_filename.c_str()).c_str(), 2000);
+ if (File::Exists(g_current_filename + ".dtm"))
+ Movie::LoadInput((g_current_filename + ".dtm").c_str());
+ else if (!Movie::IsJustStartingRecordingInputFromSaveState())
+ Movie::EndPlayInput(false);
+ }
else
+ {
+ // failed to load
Core::DisplayMessage("Unable to Load : Can't load state from other revisions !", 4000);
-
- if (File::Exists(g_current_filename + ".dtm"))
- Movie::LoadInput((g_current_filename + ".dtm").c_str());
- else if (!Movie::IsJustStartingRecordingInputFromSaveState())
- Movie::EndPlayInput(false);
+
+ // since we're probably in an inconsistent state now (and might crash or whatever), undo.
+ if(g_loadDepth < 2)
+ UndoLoadState();
+ }
}
ResetCounters();
g_op_in_progress = false;
+ g_loadDepth--;
+
// resume dat core
CCPU::EnableStepping(false);
}