Skip to content

Commit

Permalink
Merge pull request #4242 from JosJuice/change-disc-savestate
Browse files Browse the repository at this point in the history
DVDInterface: Make changing discs savestate-safe
  • Loading branch information
degasus committed Sep 27, 2016
2 parents cb75952 + d44b2de commit 0cb09ee
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 9 deletions.
39 changes: 31 additions & 8 deletions Source/Core/Core/HW/DVDInterface.cpp
Expand Up @@ -244,6 +244,8 @@ static CoreTiming::EventType* s_dtk;
static u64 s_last_read_offset;
static u64 s_last_read_time;

static std::string s_disc_path_to_insert;

static CoreTiming::EventType* s_eject_disc;
static CoreTiming::EventType* s_insert_disc;

Expand Down Expand Up @@ -289,9 +291,24 @@ void DoState(PointerWrap& p)
p.Do(s_last_read_offset);
p.Do(s_last_read_time);

p.Do(s_disc_path_to_insert);

p.Do(s_stop_at_track_end);

DVDThread::DoState(p);

// s_inserted_volume isn't savestated (because it points to
// files on the local system). Instead, we check that
// s_disc_inside matches the status of s_inserted_volume.
// This won't catch cases of having the wrong disc inserted, though.
// TODO: Check the game ID, disc number, revision?
if (s_disc_inside != (s_inserted_volume != nullptr))
{
if (s_disc_inside)
PanicAlertT("An inserted disc was expected but not found.");
else
s_inserted_volume.reset();
}
}

static u32 ProcessDTKSamples(short* tempPCM, u32 num_samples)
Expand Down Expand Up @@ -389,6 +406,8 @@ void Init()
s_last_read_offset = 0;
s_last_read_time = 0;

s_disc_path_to_insert.clear();

s_eject_disc = CoreTiming::RegisterEvent("EjectDisc", EjectDiscCallback);
s_insert_disc = CoreTiming::RegisterEvent("InsertDisc", InsertDiscCallback);

Expand Down Expand Up @@ -458,16 +477,16 @@ static void EjectDiscCallback(u64 userdata, s64 cyclesLate)
static void InsertDiscCallback(u64 userdata, s64 cyclesLate)
{
const std::string& old_path = SConfig::GetInstance().m_strFilename;
std::string* new_path = reinterpret_cast<std::string*>(userdata);

if (!SetVolumeName(*new_path))
if (!SetVolumeName(s_disc_path_to_insert))
{
// Put back the old one
SetVolumeName(old_path);
PanicAlertT("Invalid file");
PanicAlertT("The disc that was about to be inserted couldn't be found.");
}
SetDiscInside(VolumeIsValid());
delete new_path;

s_disc_path_to_insert.clear();
}

// Can only be called by the host thread
Expand All @@ -484,11 +503,15 @@ void ChangeDiscAsHost(const std::string& new_path)
// Can only be called by the CPU thread
void ChangeDiscAsCPU(const std::string& new_path)
{
// TODO: This is bad. Pointers in CoreTiming userdata require
// manual memory management and aren't savestate-safe.
u64 new_path_pointer = reinterpret_cast<u64>(new std::string(new_path));
if (!s_disc_path_to_insert.empty())
{
PanicAlertT("A disc is already about to be inserted.");
return;
}

s_disc_path_to_insert = new_path;
CoreTiming::ScheduleEvent(0, s_eject_disc);
CoreTiming::ScheduleEvent(SystemTimers::GetTicksPerSecond(), s_insert_disc, new_path_pointer);
CoreTiming::ScheduleEvent(SystemTimers::GetTicksPerSecond(), s_insert_disc);

Movie::SignalDiscChange(new_path);
}
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/Core/State.cpp
Expand Up @@ -70,7 +70,7 @@ 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 = 59; // Last changed in PR 3490
static const u32 STATE_VERSION = 60; // Last changed in PR 4242

// Maps savestate versions to Dolphin versions.
// Versions after 42 don't need to be added to this list,
Expand Down

0 comments on commit 0cb09ee

Please sign in to comment.