duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

biossettingswidget.cpp (6215B)


      1 // SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin <stenzek@gmail.com>
      2 // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
      3 
      4 #include "biossettingswidget.h"
      5 #include "qthost.h"
      6 #include "qtutils.h"
      7 #include "settingswindow.h"
      8 #include "settingwidgetbinder.h"
      9 
     10 #include "core/bios.h"
     11 #include "core/settings.h"
     12 
     13 #include <QtWidgets/QFileDialog>
     14 #include <algorithm>
     15 
     16 BIOSSettingsWidget::BIOSSettingsWidget(SettingsWindow* dialog, QWidget* parent) : QWidget(parent), m_dialog(dialog)
     17 {
     18   SettingsInterface* sif = dialog->getSettingsInterface();
     19 
     20   m_ui.setupUi(this);
     21 
     22   SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.enableTTYLogging, "BIOS", "TTYLogging", false);
     23   SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.fastBoot, "BIOS", "PatchFastBoot", false);
     24 
     25   dialog->registerWidgetHelp(m_ui.fastBoot, tr("Fast Boot"), tr("Unchecked"),
     26                              tr("Patches the BIOS to skip the console's boot animation. Does not work with all games, "
     27                                 "but usually safe to enable."));
     28   dialog->registerWidgetHelp(m_ui.enableTTYLogging, tr("Enable TTY Logging"), tr("Unchecked"),
     29                              tr("Logs BIOS calls to printf(). Not all games contain debugging messages."));
     30 
     31   connect(m_ui.imageNTSCJ, QOverload<int>::of(&QComboBox::currentIndexChanged), [this](int index) {
     32     if (m_dialog->isPerGameSettings() && index == 0)
     33     {
     34       m_dialog->removeSettingValue("BIOS", "PathNTSCJ");
     35     }
     36     else
     37     {
     38       m_dialog->setStringSettingValue("BIOS", "PathNTSCJ",
     39                                       m_ui.imageNTSCJ->itemData(index).toString().toStdString().c_str());
     40     }
     41   });
     42   connect(m_ui.imageNTSCU, QOverload<int>::of(&QComboBox::currentIndexChanged), [this](int index) {
     43     if (m_dialog->isPerGameSettings() && index == 0)
     44     {
     45       m_dialog->removeSettingValue("BIOS", "PathNTSCU");
     46     }
     47     else
     48     {
     49       m_dialog->setStringSettingValue("BIOS", "PathNTSCU",
     50                                       m_ui.imageNTSCU->itemData(index).toString().toStdString().c_str());
     51     }
     52   });
     53   connect(m_ui.imagePAL, QOverload<int>::of(&QComboBox::currentIndexChanged), [this](int index) {
     54     if (m_dialog->isPerGameSettings() && index == 0)
     55     {
     56       m_dialog->removeSettingValue("BIOS", "PathPAL");
     57     }
     58     else
     59     {
     60       m_dialog->setStringSettingValue("BIOS", "PathPAL",
     61                                       m_ui.imagePAL->itemData(index).toString().toStdString().c_str());
     62     }
     63   });
     64 
     65   connect(m_ui.refresh, &QPushButton::clicked, this, &BIOSSettingsWidget::refreshList);
     66 
     67   if (!m_dialog->isPerGameSettings())
     68   {
     69     SettingWidgetBinder::BindWidgetToFolderSetting(
     70       sif, m_ui.searchDirectory, m_ui.browseSearchDirectory, tr("Select BIOS Directory"), m_ui.openSearchDirectory,
     71       nullptr, "BIOS", "SearchDirectory", Path::Combine(EmuFolders::DataRoot, "bios"));
     72     connect(m_ui.searchDirectory, &QLineEdit::textChanged, this, &BIOSSettingsWidget::refreshList);
     73   }
     74   else
     75   {
     76     m_ui.mainLayout->removeWidget(m_ui.directoryGroupBox);
     77     delete m_ui.directoryGroupBox;
     78     m_ui.directoryGroupBox = nullptr;
     79     m_ui.directoryGroupBoxLabel = nullptr;
     80     m_ui.directoryGroupBoxLayout = nullptr;
     81     m_ui.directoryGroupBoxHorizontalLayout = nullptr;
     82     m_ui.searchDirectory = nullptr;
     83     m_ui.browseSearchDirectory = nullptr;
     84   }
     85 
     86   refreshList();
     87 }
     88 
     89 BIOSSettingsWidget::~BIOSSettingsWidget() = default;
     90 
     91 void BIOSSettingsWidget::refreshList()
     92 {
     93   auto images = BIOS::FindBIOSImagesInDirectory(EmuFolders::Bios.c_str());
     94   populateDropDownForRegion(ConsoleRegion::NTSC_J, m_ui.imageNTSCJ, images, m_dialog->isPerGameSettings());
     95   populateDropDownForRegion(ConsoleRegion::NTSC_U, m_ui.imageNTSCU, images, m_dialog->isPerGameSettings());
     96   populateDropDownForRegion(ConsoleRegion::PAL, m_ui.imagePAL, images, m_dialog->isPerGameSettings());
     97 
     98   setDropDownValue(m_ui.imageNTSCJ, m_dialog->getStringValue("BIOS", "PathNTSCJ", std::nullopt),
     99                    m_dialog->isPerGameSettings());
    100   setDropDownValue(m_ui.imageNTSCU, m_dialog->getStringValue("BIOS", "PathNTSCU", std::nullopt),
    101                    m_dialog->isPerGameSettings());
    102   setDropDownValue(m_ui.imagePAL, m_dialog->getStringValue("BIOS", "PathPAL", std::nullopt),
    103                    m_dialog->isPerGameSettings());
    104 }
    105 
    106 void BIOSSettingsWidget::populateDropDownForRegion(ConsoleRegion region, QComboBox* cb,
    107                                                    std::vector<std::pair<std::string, const BIOS::ImageInfo*>>& images,
    108                                                    bool per_game)
    109 {
    110   QSignalBlocker sb(cb);
    111   cb->clear();
    112 
    113   if (per_game)
    114     cb->addItem(QIcon(QStringLiteral(":/icons/system-search.png")), tr("Use Global Setting"));
    115 
    116   cb->addItem(QIcon(QStringLiteral(":/icons/system-search.png")), tr("Auto-Detect"));
    117 
    118   std::sort(images.begin(), images.end(), [region](const auto& left, const auto& right) {
    119     const bool left_region_match = (left.second && left.second->region == region);
    120     const bool right_region_match = (right.second && right.second->region == region);
    121     if (left_region_match && !right_region_match)
    122       return true;
    123     else if (right_region_match && !left_region_match)
    124       return false;
    125 
    126     return left.first < right.first;
    127   });
    128 
    129   for (const auto& [name, info] : images)
    130   {
    131     QString name_str(QString::fromStdString(name));
    132     cb->addItem(QtUtils::GetIconForRegion(info ? info->region : ConsoleRegion::Count),
    133                 QStringLiteral("%1 (%2)")
    134                   .arg(info ? QString(info->description) : qApp->translate("BIOSSettingsWidget", "Unknown"))
    135                   .arg(name_str),
    136                 QVariant(name_str));
    137   }
    138 }
    139 
    140 void BIOSSettingsWidget::setDropDownValue(QComboBox* cb, const std::optional<std::string>& name, bool per_game)
    141 {
    142   QSignalBlocker sb(cb);
    143 
    144   if (!name.has_value() || name->empty())
    145   {
    146     cb->setCurrentIndex((per_game && name.has_value()) ? 1 : 0);
    147     return;
    148   }
    149 
    150   QString qname(QString::fromStdString(name.value()));
    151   for (int i = 1; i < cb->count(); i++)
    152   {
    153     if (cb->itemData(i) == qname)
    154     {
    155       cb->setCurrentIndex(i);
    156       return;
    157     }
    158   }
    159 
    160   cb->addItem(qname, QVariant(qname));
    161   cb->setCurrentIndex(cb->count() - 1);
    162 }