diff --git a/Source/Core/Core/HW/DVDInterface.cpp b/Source/Core/Core/HW/DVDInterface.cpp index ba5a730c1b..ac6b22c0d8 100644 --- a/Source/Core/Core/HW/DVDInterface.cpp +++ b/Source/Core/Core/HW/DVDInterface.cpp @@ -472,10 +472,20 @@ static void InsertDiscCallback(u64 userdata, s64 cyclesLate) delete _FileName; } -void ChangeDisc(const std::string& newFileName) +// Can only be called by the host thread +void ChangeDiscAsHost(const std::string& newFileName) { - // WARNING: Can only run on Host Thread bool was_unpaused = Core::PauseAndLock(true); + + // The host thread is now temporarily the CPU thread + ChangeDiscAsCPU(newFileName); + + Core::PauseAndLock(false, was_unpaused); +} + +// Can only be called by the CPU thread +void ChangeDiscAsCPU(const std::string& newFileName) +{ std::string* _FileName = new std::string(newFileName); CoreTiming::ScheduleEvent(0, s_eject_disc); CoreTiming::ScheduleEvent(500000000, s_insert_disc, (u64)_FileName); @@ -492,7 +502,6 @@ void ChangeDisc(const std::string& newFileName) } Movie::g_discChange = fileName.substr(sizeofpath); } - Core::PauseAndLock(false, was_unpaused); } void SetLidOpen(bool open) diff --git a/Source/Core/Core/HW/DVDInterface.h b/Source/Core/Core/HW/DVDInterface.h index a67fd39baf..640afe1d84 100644 --- a/Source/Core/Core/HW/DVDInterface.h +++ b/Source/Core/Core/HW/DVDInterface.h @@ -108,7 +108,8 @@ bool VolumeIsValid(); // Disc detection and swapping void SetDiscInside(bool _DiscInside); bool IsDiscInside(); -void ChangeDisc(const std::string& fileName); // [NOT THREADSAFE] Host only +void ChangeDiscAsHost(const std::string& path); // Can only be called by the host thread +void ChangeDiscAsCPU(const std::string& path); // Can only be called by the CPU thread // DVD Access Functions bool ChangePartition(u64 offset); diff --git a/Source/Core/Core/Movie.cpp b/Source/Core/Core/Movie.cpp index 1f4fface23..7be05a5bfa 100644 --- a/Source/Core/Core/Movie.cpp +++ b/Source/Core/Core/Movie.cpp @@ -1210,17 +1210,15 @@ void PlayController(GCPadStatus* PadStatus, int controllerID) PadStatus->button |= PAD_TRIGGER_R; if (s_padState.disc) { - // This implementation assumes the disc change will only happen once. Trying to change more than - // that will cause - // it to load the last disc every time. As far as i know though, there are no 3+ disc games, so - // this should be fine. - CPU::Break(); + // This implementation assumes the disc change will only happen once. Trying + // to change more than that will cause it to load the last disc every time. + // As far as I know, there are no 3+ disc games, so this should be fine. bool found = false; std::string path; - for (size_t i = 0; i < SConfig::GetInstance().m_ISOFolder.size(); ++i) + for (const std::string& iso_folder : SConfig::GetInstance().m_ISOFolder) { - path = SConfig::GetInstance().m_ISOFolder[i]; - if (File::Exists(path + '/' + g_discChange)) + path = iso_folder + '/' + g_discChange; + if (File::Exists(path)) { found = true; break; @@ -1228,18 +1226,11 @@ void PlayController(GCPadStatus* PadStatus, int controllerID) } if (found) { - path += '/' + g_discChange; - - Core::QueueHostJob([=] { - if (!Movie::IsPlayingInput()) - return; - - DVDInterface::ChangeDisc(path); - CPU::EnableStepping(false); - }); + DVDInterface::ChangeDiscAsCPU(path); } else { + CPU::Break(); PanicAlertT("Change the disc to %s", g_discChange.c_str()); } } diff --git a/Source/Core/DolphinWX/Frame.cpp b/Source/Core/DolphinWX/Frame.cpp index 608a6fe507..4260644e46 100644 --- a/Source/Core/DolphinWX/Frame.cpp +++ b/Source/Core/DolphinWX/Frame.cpp @@ -132,7 +132,7 @@ void CRenderFrame::OnDropFiles(wxDropFilesEvent& event) } else { - DVDInterface::ChangeDisc(filepath); + DVDInterface::ChangeDiscAsHost(filepath); } } diff --git a/Source/Core/DolphinWX/FrameTools.cpp b/Source/Core/DolphinWX/FrameTools.cpp index 6b07736d7a..a33c9fa87f 100644 --- a/Source/Core/DolphinWX/FrameTools.cpp +++ b/Source/Core/DolphinWX/FrameTools.cpp @@ -691,7 +691,7 @@ void CFrame::DoOpen(bool Boot) } else { - DVDInterface::ChangeDisc(WxStrToStr(path)); + DVDInterface::ChangeDiscAsHost(WxStrToStr(path)); } } diff --git a/Source/Core/DolphinWX/GameListCtrl.cpp b/Source/Core/DolphinWX/GameListCtrl.cpp index 9a16a610c8..2eda206cce 100644 --- a/Source/Core/DolphinWX/GameListCtrl.cpp +++ b/Source/Core/DolphinWX/GameListCtrl.cpp @@ -1331,7 +1331,7 @@ void CGameListCtrl::OnChangeDisc(wxCommandEvent& WXUNUSED(event)) const GameListItem* iso = GetSelectedISO(); if (!iso || !Core::IsRunning()) return; - DVDInterface::ChangeDisc(WxStrToStr(iso->GetFileName())); + DVDInterface::ChangeDiscAsHost(WxStrToStr(iso->GetFileName())); } void CGameListCtrl::OnSize(wxSizeEvent& event)