When loading incompatible savestate, display which version created it
This commit is contained in:
parent
01cb364c7a
commit
85073675a5
|
@ -3,6 +3,7 @@
|
|||
// Refer to the license.txt file included.
|
||||
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <lzo/lzo1x.h>
|
||||
|
||||
|
@ -64,7 +65,42 @@ static Common::Event g_compressAndDumpStateSyncEvent;
|
|||
static std::thread g_save_thread;
|
||||
|
||||
// Don't forget to increase this after doing changes on the savestate system
|
||||
static const u32 STATE_VERSION = 42; // Last changed in PR2193
|
||||
static const u32 STATE_VERSION = 43; // Last changed in PR 2232
|
||||
|
||||
// Maps savestate versions to Dolphin versions.
|
||||
// Versions after 42 don't need to be added to this list,
|
||||
// beacuse they save the exact Dolphin version to savestates.
|
||||
static const std::map<u32, std::pair<std::string, std::string>> s_old_versions =
|
||||
{
|
||||
// The 16 -> 17 change modified the size of StateHeader,
|
||||
// so version older than that can't even be decompressed anymore
|
||||
{ 17, { "3.5-1311", "3.5-1364" } },
|
||||
{ 18, { "3.5-1366", "3.5-1371" } },
|
||||
{ 19, { "3.5-1372", "3.5-1408" } },
|
||||
{ 20, { "3.5-1409", "4.0-704" } },
|
||||
{ 21, { "4.0-705", "4.0-889" } },
|
||||
{ 22, { "4.0-905", "4.0-1871" } },
|
||||
{ 23, { "4.0-1873", "4.0-1900" } },
|
||||
{ 24, { "4.0-1902", "4.0-1919" } },
|
||||
{ 25, { "4.0-1921", "4.0-1936" } },
|
||||
{ 26, { "4.0-1939", "4.0-1959" } },
|
||||
{ 27, { "4.0-1961", "4.0-2018" } },
|
||||
{ 28, { "4.0-2020", "4.0-2291" } },
|
||||
{ 29, { "4.0-2293", "4.0-2360" } },
|
||||
{ 30, { "4.0-2362", "4.0-2628" } },
|
||||
{ 31, { "4.0-2632", "4.0-3331" } },
|
||||
{ 32, { "4.0-3334", "4.0-3340" } },
|
||||
{ 33, { "4.0-3342", "4.0-3373" } },
|
||||
{ 34, { "4.0-3376", "4.0-3402" } },
|
||||
{ 35, { "4.0-3409", "4.0-3603" } },
|
||||
{ 36, { "4.0-3610", "4.0-4480" } },
|
||||
{ 37, { "4.0-4484", "4.0-4943" } },
|
||||
{ 38, { "4.0-4963", "4.0-5267" } },
|
||||
{ 39, { "4.0-5279", "4.0-5525" } },
|
||||
{ 40, { "4.0-5531", "4.0-5809" } },
|
||||
{ 41, { "4.0-5811", "4.0-5923" } },
|
||||
{ 42, { "4.0-5925", "4.0-5946" } }
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -80,7 +116,7 @@ void EnableCompression(bool compression)
|
|||
g_use_compression = compression;
|
||||
}
|
||||
|
||||
static void DoState(PointerWrap &p)
|
||||
static std::string DoState(PointerWrap& p)
|
||||
{
|
||||
u32 version = STATE_VERSION;
|
||||
{
|
||||
|
@ -90,18 +126,38 @@ static void DoState(PointerWrap &p)
|
|||
version = cookie - COOKIE_BASE;
|
||||
}
|
||||
|
||||
std::string version_created_by = scm_rev_str;
|
||||
if (version > 42)
|
||||
p.Do(version_created_by);
|
||||
else
|
||||
version_created_by.clear();
|
||||
|
||||
if (version != STATE_VERSION)
|
||||
{
|
||||
// if the version doesn't match, fail.
|
||||
// this will trigger a message like "Can't load state from other revisions"
|
||||
if (version_created_by.empty() && s_old_versions.count(version))
|
||||
{
|
||||
// The savestate is from an old version that doesn't
|
||||
// save the Dolphin version number to savestates, but
|
||||
// by looking up the savestate version number, it is possible
|
||||
// to know approximately which Dolphin version was used.
|
||||
|
||||
std::pair<std::string, std::string> version_range = s_old_versions.find(version)->second;
|
||||
std::string oldest_version = version_range.first;
|
||||
std::string newest_version = version_range.second;
|
||||
|
||||
version_created_by = "Dolphin " + oldest_version + " - " + newest_version;
|
||||
}
|
||||
|
||||
// because the version doesn't match, fail.
|
||||
// this will trigger an OSD message like "Can't load state from other revisions"
|
||||
// we could use the version numbers to maintain some level of backward compatibility, but currently don't.
|
||||
p.SetMode(PointerWrap::MODE_MEASURE);
|
||||
return;
|
||||
return version_created_by;
|
||||
}
|
||||
|
||||
p.DoMarker("Version");
|
||||
|
||||
// Begin with video backend, so that it gets a chance to clear it's caches and writeback modified things to RAM
|
||||
// Begin with video backend, so that it gets a chance to clear its caches and writeback modified things to RAM
|
||||
g_video_backend->DoState(p);
|
||||
p.DoMarker("video_backend");
|
||||
|
||||
|
@ -117,9 +173,12 @@ static void DoState(PointerWrap &p)
|
|||
p.DoMarker("CoreTiming");
|
||||
Movie::DoState(p);
|
||||
p.DoMarker("Movie");
|
||||
|
||||
#if defined(HAVE_LIBAV) || defined (WIN32)
|
||||
AVIDump::DoState();
|
||||
#endif
|
||||
|
||||
return version_created_by;
|
||||
}
|
||||
|
||||
void LoadFromBuffer(std::vector<u8>& buffer)
|
||||
|
@ -340,7 +399,7 @@ void SaveAs(const std::string& filename, bool wait)
|
|||
else
|
||||
{
|
||||
// someone aborted the save by changing the mode?
|
||||
Core::DisplayMessage("Unable to Save : Internal DoState Error", 4000);
|
||||
Core::DisplayMessage("Unable to save: Internal DoState Error", 4000);
|
||||
}
|
||||
|
||||
// Resume the core and disable stepping
|
||||
|
@ -450,6 +509,7 @@ void LoadAs(const std::string& filename)
|
|||
|
||||
bool loaded = false;
|
||||
bool loadedSuccessfully = false;
|
||||
std::string version_created_by;
|
||||
|
||||
// brackets here are so buffer gets freed ASAP
|
||||
{
|
||||
|
@ -460,7 +520,7 @@ void LoadAs(const std::string& filename)
|
|||
{
|
||||
u8 *ptr = &buffer[0];
|
||||
PointerWrap p(&ptr, PointerWrap::MODE_READ);
|
||||
DoState(p);
|
||||
version_created_by = DoState(p);
|
||||
loaded = true;
|
||||
loadedSuccessfully = (p.GetMode() == PointerWrap::MODE_READ);
|
||||
}
|
||||
|
@ -479,7 +539,9 @@ void LoadAs(const std::string& filename)
|
|||
else
|
||||
{
|
||||
// failed to load
|
||||
Core::DisplayMessage("Unable to Load : Can't load state from other revisions !", 4000);
|
||||
Core::DisplayMessage("Unable to load: Can't load state from other versions!", 4000);
|
||||
if (!version_created_by.empty())
|
||||
Core::DisplayMessage("The savestate was created using " + version_created_by, 4000);
|
||||
|
||||
// since we could be in an inconsistent state now (and might crash or whatever), undo.
|
||||
if (g_loadDepth < 2)
|
||||
|
|
Loading…
Reference in New Issue