Merge pull request #3582 from JosJuice/disc-inside-cleanup

DVDInterface: Cleanup for setting/getting whether a disc is inside
This commit is contained in:
JosJuice 2017-03-13 14:26:15 +01:00 committed by GitHub
commit c48ee87f0a
4 changed files with 38 additions and 54 deletions

View File

@ -50,7 +50,7 @@ bool CBoot::DVDRead(u64 dvd_offset, u32 output_address, u32 length, bool decrypt
void CBoot::Load_FST(bool _bIsWii) void CBoot::Load_FST(bool _bIsWii)
{ {
if (!DVDInterface::VolumeIsValid()) if (!DVDInterface::IsDiscInside())
return; return;
const DiscIO::IVolume& volume = DVDInterface::GetVolume(); const DiscIO::IVolume& volume = DVDInterface::GetVolume();
@ -267,8 +267,7 @@ bool CBoot::BootUp()
case SConfig::BOOT_ISO: case SConfig::BOOT_ISO:
{ {
DVDInterface::SetVolumeName(_StartupPara.m_strFilename); DVDInterface::SetVolumeName(_StartupPara.m_strFilename);
DVDInterface::SetDiscInside(DVDInterface::VolumeIsValid()); if (!DVDInterface::IsDiscInside())
if (!DVDInterface::VolumeIsValid())
return false; return false;
const DiscIO::IVolume& pVolume = DVDInterface::GetVolume(); const DiscIO::IVolume& pVolume = DVDInterface::GetVolume();
@ -337,7 +336,7 @@ bool CBoot::BootUp()
{ {
BS2Success = EmulatedBS2(dolWii); BS2Success = EmulatedBS2(dolWii);
} }
else if ((!DVDInterface::VolumeIsValid() || else if ((!DVDInterface::IsDiscInside() ||
DVDInterface::GetVolume().GetVolumeType() != DiscIO::Platform::WII_DISC) && DVDInterface::GetVolume().GetVolumeType() != DiscIO::Platform::WII_DISC) &&
!_StartupPara.m_strDefaultISO.empty()) !_StartupPara.m_strDefaultISO.empty())
{ {
@ -353,8 +352,6 @@ bool CBoot::BootUp()
BS2Success = EmulatedBS2(dolWii); BS2Success = EmulatedBS2(dolWii);
} }
DVDInterface::SetDiscInside(DVDInterface::VolumeIsValid());
if (!BS2Success) if (!BS2Success)
{ {
// Set up MSR and the BAT SPR registers. // Set up MSR and the BAT SPR registers.
@ -414,8 +411,6 @@ bool CBoot::BootUp()
DVDInterface::SetVolumeDirectory(_StartupPara.m_strFilename, _StartupPara.bWii); DVDInterface::SetVolumeDirectory(_StartupPara.m_strFilename, _StartupPara.bWii);
} }
DVDInterface::SetDiscInside(DVDInterface::VolumeIsValid());
// Poor man's bootup // Poor man's bootup
if (_StartupPara.bWii) if (_StartupPara.bWii)
{ {
@ -450,13 +445,11 @@ bool CBoot::BootUp()
else if (!_StartupPara.m_strDefaultISO.empty()) else if (!_StartupPara.m_strDefaultISO.empty())
DVDInterface::SetVolumeName(_StartupPara.m_strDefaultISO); DVDInterface::SetVolumeName(_StartupPara.m_strDefaultISO);
DVDInterface::SetDiscInside(DVDInterface::VolumeIsValid());
break; break;
// Bootstrap 2 (AKA: Initial Program Loader, "BIOS") // Bootstrap 2 (AKA: Initial Program Loader, "BIOS")
case SConfig::BOOT_BS2: case SConfig::BOOT_BS2:
{ {
DVDInterface::SetDiscInside(DVDInterface::VolumeIsValid());
if (Load_BS2(_StartupPara.m_strBootROM)) if (Load_BS2(_StartupPara.m_strBootROM))
{ {
if (LoadMapFromFilename()) if (LoadMapFromFilename())

View File

@ -67,7 +67,7 @@ bool CBoot::EmulatedBS2_GC(bool skipAppLoader)
// to 0x80000000 according to YAGCD 4.2. // to 0x80000000 according to YAGCD 4.2.
// It's possible to boot DOL and ELF files without a disc inserted // It's possible to boot DOL and ELF files without a disc inserted
if (DVDInterface::VolumeIsValid()) if (DVDInterface::IsDiscInside())
DVDRead(/*offset*/ 0x00000000, /*address*/ 0x00000000, 0x20, false); // write disc info DVDRead(/*offset*/ 0x00000000, /*address*/ 0x00000000, 0x20, false); // write disc info
PowerPC::HostWrite_U32(0x0D15EA5E, PowerPC::HostWrite_U32(0x0D15EA5E,
@ -100,7 +100,7 @@ bool CBoot::EmulatedBS2_GC(bool skipAppLoader)
HLE::Patch(0x81300000, "OSReport"); // HLE OSReport for Apploader HLE::Patch(0x81300000, "OSReport"); // HLE OSReport for Apploader
if (!DVDInterface::VolumeIsValid()) if (!DVDInterface::IsDiscInside())
return false; return false;
// Load Apploader to Memory - The apploader is hardcoded to begin at 0x2440 on the disc, // Load Apploader to Memory - The apploader is hardcoded to begin at 0x2440 on the disc,
@ -255,7 +255,7 @@ bool CBoot::SetupWiiMemory(u64 ios_title_id)
*/ */
// When booting a WAD or the system menu, there will probably not be a disc inserted // When booting a WAD or the system menu, there will probably not be a disc inserted
if (DVDInterface::VolumeIsValid()) if (DVDInterface::IsDiscInside())
DVDRead(0x00000000, 0x00000000, 0x20, false); // Game Code DVDRead(0x00000000, 0x00000000, 0x20, false); // Game Code
Memory::Write_U32(0x0D15EA5E, 0x00000020); // Another magic word Memory::Write_U32(0x0D15EA5E, 0x00000020); // Another magic word
@ -306,7 +306,7 @@ bool CBoot::SetupWiiMemory(u64 ios_title_id)
bool CBoot::EmulatedBS2_Wii() bool CBoot::EmulatedBS2_Wii()
{ {
INFO_LOG(BOOT, "Faking Wii BS2..."); INFO_LOG(BOOT, "Faking Wii BS2...");
if (!DVDInterface::VolumeIsValid()) if (!DVDInterface::IsDiscInside())
return false; return false;
if (DVDInterface::GetVolume().GetVolumeType() != DiscIO::Platform::WII_DISC) if (DVDInterface::GetVolume().GetVolumeType() != DiscIO::Platform::WII_DISC)

View File

@ -244,7 +244,6 @@ static u32 s_pending_samples;
// Disc drive state // Disc drive state
static u32 s_error_code = 0; static u32 s_error_code = 0;
static bool s_disc_inside = false;
// Disc drive timing // Disc drive timing
static u64 s_read_buffer_start_time; static u64 s_read_buffer_start_time;
@ -264,7 +263,7 @@ static void EjectDiscCallback(u64 userdata, s64 cyclesLate);
static void InsertDiscCallback(u64 userdata, s64 cyclesLate); static void InsertDiscCallback(u64 userdata, s64 cyclesLate);
static void FinishExecutingCommandCallback(u64 userdata, s64 cycles_late); static void FinishExecutingCommandCallback(u64 userdata, s64 cycles_late);
void SetLidOpen(bool _bOpen); void SetLidOpen();
void UpdateInterrupts(); void UpdateInterrupts();
void GenerateDIInterrupt(DIInterruptType _DVDInterrupt); void GenerateDIInterrupt(DIInterruptType _DVDInterrupt);
@ -282,6 +281,8 @@ u64 CalculateRawDiscReadTime(u64 offset, u64 length);
void DoState(PointerWrap& p) void DoState(PointerWrap& p)
{ {
bool disc_inside = IsDiscInside();
p.DoPOD(s_DISR); p.DoPOD(s_DISR);
p.DoPOD(s_DICVR); p.DoPOD(s_DICVR);
p.DoArray(s_DICMDBUF); p.DoArray(s_DICMDBUF);
@ -301,7 +302,7 @@ void DoState(PointerWrap& p)
p.Do(s_pending_samples); p.Do(s_pending_samples);
p.Do(s_error_code); p.Do(s_error_code);
p.Do(s_disc_inside); p.Do(disc_inside);
p.Do(s_read_buffer_start_time); p.Do(s_read_buffer_start_time);
p.Do(s_read_buffer_end_time); p.Do(s_read_buffer_end_time);
@ -313,13 +314,13 @@ void DoState(PointerWrap& p)
DVDThread::DoState(p); DVDThread::DoState(p);
// s_inserted_volume isn't savestated (because it points to // s_inserted_volume isn't savestated (because it points to
// files on the local system). Instead, we check that // files on the local system). Instead, we check that the
// s_disc_inside matches the status of s_inserted_volume. // savestated disc_inside matches our IsDiscInside(). This
// This won't catch cases of having the wrong disc inserted, though. // won't catch cases of having the wrong disc inserted, though.
// TODO: Check the game ID, disc number, revision? // TODO: Check the game ID, disc number, revision?
if (s_disc_inside != (s_inserted_volume != nullptr)) if (disc_inside != IsDiscInside())
{ {
if (s_disc_inside) if (disc_inside)
PanicAlertT("An inserted disc was expected but not found."); PanicAlertT("An inserted disc was expected but not found.");
else else
s_inserted_volume.reset(); s_inserted_volume.reset();
@ -418,11 +419,12 @@ static void DTKStreamingCallback(const std::vector<u8>& audio_data, s64 cycles_l
void Init() void Init()
{ {
_assert_(!IsDiscInside());
DVDThread::Start(); DVDThread::Start();
Reset(); Reset();
s_DICVR.Hex = 1; // Disc Channel relies on cover being open when no disc is inserted s_DICVR.Hex = 1; // Disc Channel relies on cover being open when no disc is inserted
s_disc_inside = false;
s_eject_disc = CoreTiming::RegisterEvent("EjectDisc", EjectDiscCallback); s_eject_disc = CoreTiming::RegisterEvent("EjectDisc", EjectDiscCallback);
s_insert_disc = CoreTiming::RegisterEvent("InsertDisc", InsertDiscCallback); s_insert_disc = CoreTiming::RegisterEvent("InsertDisc", InsertDiscCallback);
@ -476,6 +478,7 @@ void Shutdown()
const DiscIO::IVolume& GetVolume() const DiscIO::IVolume& GetVolume()
{ {
_assert_(IsDiscInside());
return *s_inserted_volume; return *s_inserted_volume;
} }
@ -483,7 +486,8 @@ bool SetVolumeName(const std::string& disc_path)
{ {
DVDThread::WaitUntilIdle(); DVDThread::WaitUntilIdle();
s_inserted_volume = DiscIO::CreateVolumeFromFilename(disc_path); s_inserted_volume = DiscIO::CreateVolumeFromFilename(disc_path);
return VolumeIsValid(); SetLidOpen();
return IsDiscInside();
} }
bool SetVolumeDirectory(const std::string& full_path, bool is_wii, bool SetVolumeDirectory(const std::string& full_path, bool is_wii,
@ -492,25 +496,13 @@ bool SetVolumeDirectory(const std::string& full_path, bool is_wii,
DVDThread::WaitUntilIdle(); DVDThread::WaitUntilIdle();
s_inserted_volume = s_inserted_volume =
DiscIO::CreateVolumeFromDirectory(full_path, is_wii, apploader_path, DOL_path); DiscIO::CreateVolumeFromDirectory(full_path, is_wii, apploader_path, DOL_path);
return VolumeIsValid(); SetLidOpen();
} return IsDiscInside();
bool VolumeIsValid()
{
return s_inserted_volume != nullptr;
}
void SetDiscInside(bool disc_inside)
{
if (s_disc_inside != disc_inside)
SetLidOpen(!disc_inside);
s_disc_inside = disc_inside;
} }
bool IsDiscInside() bool IsDiscInside()
{ {
return s_disc_inside; return s_inserted_volume != nullptr;
} }
// Take care of all logic of "swapping discs" // Take care of all logic of "swapping discs"
@ -521,7 +513,7 @@ static void EjectDiscCallback(u64 userdata, s64 cyclesLate)
{ {
DVDThread::WaitUntilIdle(); DVDThread::WaitUntilIdle();
s_inserted_volume.reset(); s_inserted_volume.reset();
SetDiscInside(false); SetLidOpen();
} }
static void InsertDiscCallback(u64 userdata, s64 cyclesLate) static void InsertDiscCallback(u64 userdata, s64 cyclesLate)
@ -534,7 +526,6 @@ static void InsertDiscCallback(u64 userdata, s64 cyclesLate)
SetVolumeName(old_path); SetVolumeName(old_path);
PanicAlertT("The disc that was about to be inserted couldn't be found."); PanicAlertT("The disc that was about to be inserted couldn't be found.");
} }
SetDiscInside(VolumeIsValid());
s_disc_path_to_insert.clear(); s_disc_path_to_insert.clear();
} }
@ -566,10 +557,11 @@ void ChangeDiscAsCPU(const std::string& new_path)
Movie::SignalDiscChange(new_path); Movie::SignalDiscChange(new_path);
} }
void SetLidOpen(bool open) void SetLidOpen()
{ {
s_DICVR.CVR = open ? 1 : 0; u32 old_value = s_DICVR.CVR;
s_DICVR.CVR = IsDiscInside() ? 0 : 1;
if (s_DICVR.CVR != old_value)
GenerateDIInterrupt(INT_CVRINT); GenerateDIInterrupt(INT_CVRINT);
} }
@ -699,7 +691,7 @@ void WriteImmediate(u32 value, u32 output_address, bool reply_to_ios)
bool ExecuteReadCommand(u64 DVD_offset, u32 output_address, u32 DVD_length, u32 output_length, bool ExecuteReadCommand(u64 DVD_offset, u32 output_address, u32 DVD_length, u32 output_length,
bool decrypt, ReplyType reply_type, DIInterruptType* interrupt_type) bool decrypt, ReplyType reply_type, DIInterruptType* interrupt_type)
{ {
if (!s_disc_inside) if (!IsDiscInside())
{ {
// Disc read fails // Disc read fails
s_error_code = ERROR_NO_DISK | ERROR_COVER_H; s_error_code = ERROR_NO_DISK | ERROR_COVER_H;
@ -814,8 +806,8 @@ void ExecuteCommand(u32 command_0, u32 command_1, u32 command_2, u32 output_addr
// Probably only used by Wii // Probably only used by Wii
case DVDLowGetCoverStatus: case DVDLowGetCoverStatus:
WriteImmediate(s_disc_inside ? 2 : 1, output_address, reply_to_ios); WriteImmediate(IsDiscInside() ? 2 : 1, output_address, reply_to_ios);
INFO_LOG(DVDINTERFACE, "DVDLowGetCoverStatus: Disc %sInserted", s_disc_inside ? "" : "Not "); INFO_LOG(DVDINTERFACE, "DVDLowGetCoverStatus: Disc %sInserted", IsDiscInside() ? "" : "Not ");
break; break;
// Probably only used by Wii // Probably only used by Wii

View File

@ -108,23 +108,22 @@ void DoState(PointerWrap& p);
void RegisterMMIO(MMIO::Mapping* mmio, u32 base); void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
// Direct disc access // Disc access (don't call GetVolume unless you know that IsDiscInside() == true)
const DiscIO::IVolume& GetVolume(); const DiscIO::IVolume& GetVolume();
bool SetVolumeName(const std::string& disc_path); bool SetVolumeName(const std::string& disc_path);
bool SetVolumeDirectory(const std::string& disc_path, bool is_wii, bool SetVolumeDirectory(const std::string& disc_path, bool is_wii,
const std::string& apploader_path = "", const std::string& DOL_path = ""); const std::string& apploader_path = "", const std::string& DOL_path = "");
bool VolumeIsValid();
// Disc detection and swapping
void SetDiscInside(bool _DiscInside);
bool IsDiscInside(); bool IsDiscInside();
void ChangeDiscAsHost(const std::string& new_path); // Can only be called by the host thread void ChangeDiscAsHost(const std::string& new_path); // Can only be called by the host thread
void ChangeDiscAsCPU(const std::string& new_path); // Can only be called by the CPU thread void ChangeDiscAsCPU(const std::string& new_path); // Can only be called by the CPU thread
// DVD Access Functions // Direct access to DI for IOS HLE (simpler to implement than how real IOS accesses DI,
// and lets us skip encrypting/decrypting in some cases)
bool ChangePartition(u64 offset); bool ChangePartition(u64 offset);
void ExecuteCommand(u32 command_0, u32 command_1, u32 command_2, u32 output_address, void ExecuteCommand(u32 command_0, u32 command_1, u32 command_2, u32 output_address,
u32 output_length, bool reply_to_ios); u32 output_length, bool reply_to_ios);
// Used by DVDThread
void FinishExecutingCommand(ReplyType reply_type, DIInterruptType interrupt_type, s64 cycles_late, void FinishExecutingCommand(ReplyType reply_type, DIInterruptType interrupt_type, s64 cycles_late,
const std::vector<u8>& data = std::vector<u8>()); const std::vector<u8>& data = std::vector<u8>());