diff --git a/Source/Core/Core/Config/MainSettings.cpp b/Source/Core/Core/Config/MainSettings.cpp index be901fe289..4662728c6d 100644 --- a/Source/Core/Core/Config/MainSettings.cpp +++ b/Source/Core/Core/Config/MainSettings.cpp @@ -44,6 +44,8 @@ const Info MAIN_MAX_FALLBACK{{System::Main, "Core", "MaxFallback"}, 100}; const Info MAIN_TIMING_VARIANCE{{System::Main, "Core", "TimingVariance"}, 40}; const Info MAIN_CPU_THREAD{{System::Main, "Core", "CPUThread"}, true}; const Info MAIN_SYNC_ON_SKIP_IDLE{{System::Main, "Core", "SyncOnSkipIdle"}, true}; +const Info MAIN_GC_EMPTY_DRIVE_IS_CLOSED{{System::Main, "Core", "GCEmptyDriveIsClosed"}, + false}; const Info MAIN_DEFAULT_ISO{{System::Main, "Core", "DefaultISO"}, ""}; const Info MAIN_ENABLE_CHEATS{{System::Main, "Core", "EnableCheats"}, false}; const Info MAIN_GC_LANGUAGE{{System::Main, "Core", "SelectedLanguage"}, 0}; diff --git a/Source/Core/Core/Config/MainSettings.h b/Source/Core/Core/Config/MainSettings.h index 0d591ee5db..0924cbca00 100644 --- a/Source/Core/Core/Config/MainSettings.h +++ b/Source/Core/Core/Config/MainSettings.h @@ -63,6 +63,7 @@ extern const Info MAIN_MAX_FALLBACK; extern const Info MAIN_TIMING_VARIANCE; extern const Info MAIN_CPU_THREAD; extern const Info MAIN_SYNC_ON_SKIP_IDLE; +extern const Info MAIN_GC_EMPTY_DRIVE_IS_CLOSED; extern const Info MAIN_DEFAULT_ISO; extern const Info MAIN_ENABLE_CHEATS; extern const Info MAIN_GC_LANGUAGE; diff --git a/Source/Core/Core/HW/DVD/DVDInterface.cpp b/Source/Core/Core/HW/DVD/DVDInterface.cpp index a17ee5bd37..4da99552b8 100644 --- a/Source/Core/Core/HW/DVD/DVDInterface.cpp +++ b/Source/Core/Core/HW/DVD/DVDInterface.cpp @@ -257,7 +257,7 @@ void DVDInterface::Init() m_system.GetDVDThread().Start(); m_DISR.Hex = 0; - m_DICVR.Hex = 1; // Disc Channel relies on cover being open when no disc is inserted + m_DICVR.Hex = ShouldLidBeOpen() ? 1 : 0; m_DICMDBUF[0] = 0; m_DICMDBUF[1] = 0; m_DICMDBUF[2] = 0; @@ -304,7 +304,7 @@ void DVDInterface::ResetDrive(bool spinup) // On the Wii, this can only happen if something other than a DVD is inserted into the disc // drive (for instance, an audio CD) and only after it attempts to read it. Otherwise, it will // report the cover as opened. - SetDriveState(DriveState::CoverOpened); + SetDriveState(ShouldLidBeOpen() ? DriveState::CoverOpened : DriveState::NoMediumPresent); } else if (!spinup) { @@ -494,10 +494,19 @@ bool DVDInterface::AutoChangeDisc() return true; } +bool DVDInterface::ShouldLidBeOpen() +{ + // Disc Channel relies on cover being open when no disc is inserted. + // The Wii also has no physical cover. (TODO: How does the Wii Mini behave?) + // Therefore, the behaviour is only customisable for the GameCube. + return (!IsDiscInside() && + (SConfig::GetInstance().bWii || !Config::Get(Config::MAIN_GC_EMPTY_DRIVE_IS_CLOSED))); +} + void DVDInterface::SetLidOpen() { const u32 old_value = m_DICVR.CVR; - m_DICVR.CVR = IsDiscInside() ? 0 : 1; + m_DICVR.CVR = ShouldLidBeOpen() ? 1 : 0; if (m_DICVR.CVR != old_value) GenerateDIInterrupt(DIInterruptType::CVRINT); } diff --git a/Source/Core/Core/HW/DVD/DVDInterface.h b/Source/Core/Core/HW/DVD/DVDInterface.h index f01558cc1e..a764b1faef 100644 --- a/Source/Core/Core/HW/DVD/DVDInterface.h +++ b/Source/Core/Core/HW/DVD/DVDInterface.h @@ -182,6 +182,7 @@ private: const std::vector& audio_data); u32 AdvanceDTK(u32 maximum_blocks, u32* blocks_to_process); + bool ShouldLidBeOpen(); void SetLidOpen(); void UpdateInterrupts(); void GenerateDIInterrupt(DIInterruptType dvd_interrupt); diff --git a/Source/Core/DolphinQt/Settings/GameCubePane.cpp b/Source/Core/DolphinQt/Settings/GameCubePane.cpp index 78be23d5f2..d4ad682bf4 100644 --- a/Source/Core/DolphinQt/Settings/GameCubePane.cpp +++ b/Source/Core/DolphinQt/Settings/GameCubePane.cpp @@ -65,6 +65,9 @@ void GameCubePane::CreateWidgets() QVBoxLayout* layout = new QVBoxLayout(this); + m_empty_drive_is_closed = new QCheckBox( + tr("Report disc drive as closed when empty (shows GameCube logo sequence)"), this); + // IPL Settings QGroupBox* ipl_box = new QGroupBox(tr("IPL Settings"), this); QVBoxLayout* ipl_box_layout = new QVBoxLayout(ipl_box); @@ -236,6 +239,7 @@ void GameCubePane::CreateWidgets() layout->addWidget(ipl_box); layout->addWidget(device_box); + layout->addWidget(m_empty_drive_is_closed); #ifdef HAS_LIBMGBA layout->addWidget(gba_box); #endif @@ -247,6 +251,8 @@ void GameCubePane::CreateWidgets() void GameCubePane::ConnectWidgets() { + connect(m_empty_drive_is_closed, &QCheckBox::stateChanged, this, &GameCubePane::SaveSettings); + // IPL Settings connect(m_skip_main_menu, &QCheckBox::stateChanged, this, &GameCubePane::SaveSettings); connect(m_language_combo, qOverload(&QComboBox::currentIndexChanged), this, @@ -701,6 +707,9 @@ void GameCubePane::BrowseGBASaves() void GameCubePane::LoadSettings() { + SignalBlocking(m_empty_drive_is_closed) + ->setChecked(Config::Get(Config::MAIN_GC_EMPTY_DRIVE_IS_CLOSED)); + // IPL Settings SignalBlocking(m_skip_main_menu)->setChecked(Config::Get(Config::MAIN_SKIP_IPL)); SignalBlocking(m_language_combo) @@ -762,6 +771,9 @@ void GameCubePane::SaveSettings() { Config::ConfigChangeCallbackGuard config_guard; + Config::SetBaseOrCurrent(Config::MAIN_GC_EMPTY_DRIVE_IS_CLOSED, + m_empty_drive_is_closed->isChecked()); + // IPL Settings Config::SetBaseOrCurrent(Config::MAIN_SKIP_IPL, m_skip_main_menu->isChecked()); Config::SetBaseOrCurrent(Config::MAIN_GC_LANGUAGE, m_language_combo->currentData().toInt()); diff --git a/Source/Core/DolphinQt/Settings/GameCubePane.h b/Source/Core/DolphinQt/Settings/GameCubePane.h index 35862e2f57..bbad7d7b15 100644 --- a/Source/Core/DolphinQt/Settings/GameCubePane.h +++ b/Source/Core/DolphinQt/Settings/GameCubePane.h @@ -52,6 +52,7 @@ private: void SaveRomPathChanged(); void BrowseGBASaves(); + QCheckBox* m_empty_drive_is_closed; QCheckBox* m_skip_main_menu; QComboBox* m_language_combo;