From 6b811df6d0fc8342826b81d1ec27c1954e11c7bf Mon Sep 17 00:00:00 2001 From: Stenzek Date: Tue, 27 May 2025 17:05:09 +1000 Subject: [PATCH] CDROM: Add "Switch to Next Disc on Stop" option. NOTE: THIS WILL NOT WORK FOR ALL GAMES. Plenty of games don't stop the CD-ROM drive when they're expecting a disc change, leaving us with no way of knowing when it's needed. --- src/core/cdrom.cpp | 10 +++++++++- src/core/fullscreen_ui.cpp | 6 ++++++ src/core/settings.cpp | 2 ++ src/core/settings.h | 1 + src/duckstation-qt/consolesettingswidget.cpp | 6 ++++++ src/duckstation-qt/consolesettingswidget.ui | 13 ++++++++++--- 6 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/core/cdrom.cpp b/src/core/cdrom.cpp index 2add9abb0..4840cb58f 100644 --- a/src/core/cdrom.cpp +++ b/src/core/cdrom.cpp @@ -2590,10 +2590,18 @@ void CDROM::ExecuteCommandSecondResponse(void*, TickCount ticks, TickCount ticks case Command::ReadTOC: case Command::Pause: case Command::MotorOn: - case Command::Stop: DoStatSecondResponse(); break; + case Command::Stop: + { + DoStatSecondResponse(); + + if (g_settings.cdrom_auto_disc_change) + Host::RunOnCPUThread([]() { System::SwitchToNextDisc(false); }); + } + break; + default: break; } diff --git a/src/core/fullscreen_ui.cpp b/src/core/fullscreen_ui.cpp index 61a3dcde1..11990cd1d 100644 --- a/src/core/fullscreen_ui.cpp +++ b/src/core/fullscreen_ui.cpp @@ -4539,6 +4539,10 @@ void FullscreenUI::DrawConsoleSettingsPage() bsi, FSUI_ICONVSTR(ICON_FA_VEST_PATCHES, "Apply Image Patches"), FSUI_VSTR("Automatically applies patches to disc images when they are present, currently only PPF is supported."), "CDROM", "LoadImagePatches", false); + DrawToggleSetting(bsi, FSUI_ICONVSTR(ICON_FA_LIST_OL, "Switch to Next Disc on Stop"), + FSUI_VSTR("Automatically switches to the next disc in the game when the game stops the CD-ROM " + "motor. Does not work for all games."), + "CDROM", "AutoDiscChange", false); EndMenuButtons(); } @@ -9166,6 +9170,7 @@ TRANSLATE_NOOP("FullscreenUI", "Automatically applies patches to disc images whe TRANSLATE_NOOP("FullscreenUI", "Automatically resizes the window to match the internal resolution."); TRANSLATE_NOOP("FullscreenUI", "Automatically saves the emulator state when powering down or exiting. You can then resume directly from where you left off next time."); TRANSLATE_NOOP("FullscreenUI", "Automatically switches to fullscreen mode when the program is started."); +TRANSLATE_NOOP("FullscreenUI", "Automatically switches to the next disc in the game when the game stops the CD-ROM motor. Does not work for all games."); TRANSLATE_NOOP("FullscreenUI", "Avoids calls to C++ code, significantly speeding up the recompiler."); TRANSLATE_NOOP("FullscreenUI", "BIOS Directory"); TRANSLATE_NOOP("FullscreenUI", "BIOS Selection"); @@ -9728,6 +9733,7 @@ TRANSLATE_NOOP("FullscreenUI", "Stores the current settings to a controller pres TRANSLATE_NOOP("FullscreenUI", "Stretch Mode"); TRANSLATE_NOOP("FullscreenUI", "Summary"); TRANSLATE_NOOP("FullscreenUI", "Support for controllers that use the XInput protocol. XInput should only be used if you are using a XInput wrapper library."); +TRANSLATE_NOOP("FullscreenUI", "Switch to Next Disc on Stop"); TRANSLATE_NOOP("FullscreenUI", "Switches back to 4:3 display aspect ratio when displaying 24-bit content, usually FMVs."); TRANSLATE_NOOP("FullscreenUI", "Switches between full screen and windowed when the window is double-clicked."); TRANSLATE_NOOP("FullscreenUI", "Sync To Host Refresh Rate"); diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 1c48e9fe7..2ba4b790d 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -362,6 +362,7 @@ void Settings::Load(const SettingsInterface& si, const SettingsInterface& contro cdrom_load_image_to_ram = si.GetBoolValue("CDROM", "LoadImageToRAM", false); cdrom_load_image_patches = si.GetBoolValue("CDROM", "LoadImagePatches", false); cdrom_mute_cd_audio = si.GetBoolValue("CDROM", "MuteCDAudio", false); + cdrom_auto_disc_change = si.GetBoolValue("CDROM", "AutoDiscChange", false); cdrom_read_speedup = Truncate8(std::min(si.GetUIntValue("CDROM", "ReadSpeedup", 1u), std::numeric_limits::max())); cdrom_seek_speedup = @@ -679,6 +680,7 @@ void Settings::Save(SettingsInterface& si, bool ignore_base) const si.SetBoolValue("CDROM", "LoadImageToRAM", cdrom_load_image_to_ram); si.SetBoolValue("CDROM", "LoadImagePatches", cdrom_load_image_patches); si.SetBoolValue("CDROM", "MuteCDAudio", cdrom_mute_cd_audio); + si.SetBoolValue("CDROM", "AutoDiscChange", cdrom_auto_disc_change); si.SetUIntValue("CDROM", "ReadSpeedup", cdrom_read_speedup); si.SetUIntValue("CDROM", "SeekSpeedup", cdrom_seek_speedup); si.SetUIntValue("CDROM", "MaxReadSpeedupCycles", cdrom_max_seek_speedup_cycles); diff --git a/src/core/settings.h b/src/core/settings.h index c65f3b517..148ac64d2 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -308,6 +308,7 @@ struct Settings : public GPUSettings bool cdrom_load_image_to_ram : 1 = false; bool cdrom_load_image_patches : 1 = false; bool cdrom_mute_cd_audio : 1 = false; + bool cdrom_auto_disc_change : 1 = false; u16 rewind_save_slots = 10; u8 runahead_frames = 0; diff --git a/src/duckstation-qt/consolesettingswidget.cpp b/src/duckstation-qt/consolesettingswidget.cpp index 9183984b6..ce84eada6 100644 --- a/src/duckstation-qt/consolesettingswidget.cpp +++ b/src/duckstation-qt/consolesettingswidget.cpp @@ -65,6 +65,7 @@ ConsoleSettingsWidget::ConsoleSettingsWidget(SettingsWindow* dialog, QWidget* pa SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.recompilerICache, "CPU", "RecompilerICache", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.cdromLoadImageToRAM, "CDROM", "LoadImageToRAM", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.cdromLoadImagePatches, "CDROM", "LoadImagePatches", false); + SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.cdromAutoDiscChange, "CDROM", "AutoDiscChange", false); if (!m_dialog->isPerGameSettings()) { @@ -73,6 +74,7 @@ ConsoleSettingsWidget::ConsoleSettingsWidget(SettingsWindow* dialog, QWidget* pa } else { + m_ui.cdromIgnoreDriveSubcode->setEnabled(false); } @@ -131,6 +133,10 @@ ConsoleSettingsWidget::ConsoleSettingsWidget(SettingsWindow* dialog, QWidget* pa dialog->registerWidgetHelp(m_ui.cdromLoadImagePatches, tr("Apply Image Patches"), tr("Unchecked"), tr("Automatically applies patches to disc images when they are present in the same " "directory. Currently only PPF patches are supported with this option.")); + dialog->registerWidgetHelp( + m_ui.cdromAutoDiscChange, tr("Switch to Next Disc on Stop"), tr("Unchecked"), + tr("Automatically switches to the next disc in the game when the game stops the CD-ROM motor. No switch will occur " + "if the last disc in the game is already selected. Does not work for all games.")); dialog->registerWidgetHelp( m_ui.cdromIgnoreDriveSubcode, tr("Ignore Drive Subcode"), tr("Unchecked"), tr("Ignores the subchannel provided by the drive when using physical discs, instead always generating subchannel " diff --git a/src/duckstation-qt/consolesettingswidget.ui b/src/duckstation-qt/consolesettingswidget.ui index e8e2b95fb..b65e6c92f 100644 --- a/src/duckstation-qt/consolesettingswidget.ui +++ b/src/duckstation-qt/consolesettingswidget.ui @@ -167,11 +167,11 @@ - + CD-ROM Emulation - + @@ -323,13 +323,20 @@ - + Ignore Drive Subcode + + + + Switch to Next Disc on Stop + + +