BIOS: Automatically detect images, improve selection UI

This commit is contained in:
Connor McLaughlin
2020-09-22 23:08:07 +10:00
parent 3385346b7f
commit 7d01bedf07
23 changed files with 512 additions and 179 deletions

View File

@ -15,6 +15,9 @@ set(SRCS
autoupdaterdialog.cpp
autoupdaterdialog.h
autoupdaterdialog.ui
biossettingswidget.cpp
biossettingswidget.h
biossettingswidget.ui
consolesettingswidget.cpp
consolesettingswidget.h
consolesettingswidget.ui

View File

@ -0,0 +1,123 @@
#include "biossettingswidget.h"
#include "core/bios.h"
#include "qthostinterface.h"
#include "settingsdialog.h"
#include "settingwidgetbinder.h"
#include <QtWidgets/QFileDialog>
#include <algorithm>
static void populateDropDownForRegion(ConsoleRegion region, QComboBox* cb,
std::vector<std::pair<std::string, const BIOS::ImageInfo*>>& images)
{
cb->addItem(QIcon(QStringLiteral(":/icons/system-search.png")),
QT_TRANSLATE_NOOP("BIOSSettingsWidget", "Auto-Detect"));
std::sort(images.begin(), images.end(), [region](const auto& left, const auto& right) {
const bool left_region_match = (left.second && left.second->region == region);
const bool right_region_match = (right.second && right.second->region == region);
if (left_region_match && !right_region_match)
return true;
else if (right_region_match && left_region_match)
return false;
return left.first < right.first;
});
for (const auto& [name, info] : images)
{
QIcon icon;
if (info)
{
switch (info->region)
{
case ConsoleRegion::NTSC_J:
icon = QIcon(QStringLiteral(":/icons/flag-jp.png"));
break;
case ConsoleRegion::PAL:
icon = QIcon(QStringLiteral(":/icons/flag-eu.png"));
break;
case ConsoleRegion::NTSC_U:
icon = QIcon(QStringLiteral(":/icons/flag-uc.png"));
break;
default:
icon = QIcon(QStringLiteral(":/icons/applications-other.png"));
break;
}
}
else
{
icon = QIcon(QStringLiteral(":/icons/applications-other.png"));
}
QString name_str(QString::fromStdString(name));
cb->addItem(icon,
QStringLiteral("%1 (%2)")
.arg(info ? QString(info->description) : qApp->translate("BIOSSettingsWidget", "Unknown"))
.arg(name_str),
QVariant(name_str));
}
}
static void setDropDownValue(QComboBox* cb, const std::string& name)
{
QSignalBlocker sb(cb);
if (name.empty())
{
cb->setCurrentIndex(0);
return;
}
QString qname(QString::fromStdString(name));
for (int i = 1; i < cb->count(); i++)
{
if (cb->itemData(i) == qname)
{
cb->setCurrentIndex(i);
return;
}
}
cb->addItem(qname, QVariant(qname));
cb->setCurrentIndex(cb->count() - 1);
}
BIOSSettingsWidget::BIOSSettingsWidget(QtHostInterface* host_interface, QWidget* parent, SettingsDialog* dialog)
: QWidget(parent), m_host_interface(host_interface)
{
m_ui.setupUi(this);
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.enableTTYOutput, "BIOS", "PatchTTYEnable");
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.fastBoot, "BIOS", "PatchFastBoot");
dialog->registerWidgetHelp(m_ui.fastBoot, tr("Fast Boot"), tr("Unchecked"),
tr("Patches the BIOS to skip the console's boot animation. Does not work with all games, "
"but usually safe to enabled."));
auto images = m_host_interface->FindBIOSImagesInUserDirectory();
populateDropDownForRegion(ConsoleRegion::NTSC_J, m_ui.imageNTSCJ, images);
populateDropDownForRegion(ConsoleRegion::NTSC_U, m_ui.imageNTSCU, images);
populateDropDownForRegion(ConsoleRegion::PAL, m_ui.imagePAL, images);
setDropDownValue(m_ui.imageNTSCJ, m_host_interface->GetStringSettingValue("BIOS", "PathNTSCJ", ""));
setDropDownValue(m_ui.imageNTSCU, m_host_interface->GetStringSettingValue("BIOS", "PathNTSCU", ""));
setDropDownValue(m_ui.imagePAL, m_host_interface->GetStringSettingValue("BIOS", "PathPAL", ""));
connect(m_ui.imageNTSCJ, QOverload<int>::of(&QComboBox::currentIndexChanged), [this](int index) {
m_host_interface->SetStringSettingValue("BIOS", "PathNTSCJ",
m_ui.imageNTSCJ->itemData(index).toString().toStdString().c_str());
m_host_interface->applySettings();
});
connect(m_ui.imageNTSCU, QOverload<int>::of(&QComboBox::currentIndexChanged), [this](int index) {
m_host_interface->SetStringSettingValue("BIOS", "PathNTSCU",
m_ui.imageNTSCU->itemData(index).toString().toStdString().c_str());
m_host_interface->applySettings();
});
connect(m_ui.imagePAL, QOverload<int>::of(&QComboBox::currentIndexChanged), [this](int index) {
m_host_interface->SetStringSettingValue("BIOS", "PathPAL",
m_ui.imagePAL->itemData(index).toString().toStdString().c_str());
m_host_interface->applySettings();
});
}
BIOSSettingsWidget::~BIOSSettingsWidget() = default;

View File

@ -0,0 +1,22 @@
#pragma once
#include "core/types.h"
#include <QtWidgets/QWidget>
#include "ui_biossettingswidget.h"
class QtHostInterface;
class SettingsDialog;
class BIOSSettingsWidget : public QWidget
{
Q_OBJECT
public:
explicit BIOSSettingsWidget(QtHostInterface* host_interface, QWidget* parent, SettingsDialog* dialog);
~BIOSSettingsWidget();
private:
Ui::BIOSSettingsWidget m_ui;
QtHostInterface* m_host_interface;
};

View File

@ -0,0 +1,129 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>BIOSSettingsWidget</class>
<widget class="QWidget" name="BIOSSettingsWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>472</width>
<height>259</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>BIOS Selection</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>NTSC-J (Japan):</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="imageNTSCJ">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>NTSC-U/C (US/Canada):</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="imageNTSCU">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>PAL (Europe, Australia):</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="imagePAL">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Options and Patches</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QCheckBox" name="fastBoot">
<property name="text">
<string>Fast Boot</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="enableTTYOutput">
<property name="text">
<string>Enable TTY Output</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -1,9 +1,6 @@
#include "consolesettingswidget.h"
#include "settingsdialog.h"
#include "settingwidgetbinder.h"
#include <QtWidgets/QFileDialog>
static constexpr char BIOS_IMAGE_FILTER[] = "Binary Images (*.bin);;All Files (*.*)";
ConsoleSettingsWidget::ConsoleSettingsWidget(QtHostInterface* host_interface, QWidget* parent, SettingsDialog* dialog)
: QWidget(parent), m_host_interface(host_interface)
@ -25,9 +22,6 @@ ConsoleSettingsWidget::ConsoleSettingsWidget(QtHostInterface* host_interface, QW
SettingWidgetBinder::BindWidgetToEnumSetting(m_host_interface, m_ui.region, "Console", "Region",
&Settings::ParseConsoleRegionName, &Settings::GetConsoleRegionName,
Settings::DEFAULT_CONSOLE_REGION);
SettingWidgetBinder::BindWidgetToStringSetting(m_host_interface, m_ui.biosPath, "BIOS", "Path");
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.enableTTYOutput, "BIOS", "PatchTTYEnable");
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.fastBoot, "BIOS", "PatchFastBoot");
SettingWidgetBinder::BindWidgetToEnumSetting(m_host_interface, m_ui.cpuExecutionMode, "CPU", "ExecutionMode",
&Settings::ParseCPUExecutionMode, &Settings::GetCPUExecutionModeName,
Settings::DEFAULT_CPU_EXECUTION_MODE);
@ -36,12 +30,6 @@ ConsoleSettingsWidget::ConsoleSettingsWidget(QtHostInterface* host_interface, QW
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.cdromLoadImageToRAM, "CDROM", "LoadImageToRAM",
false);
connect(m_ui.biosPathBrowse, &QPushButton::pressed, this, &ConsoleSettingsWidget::onBrowseBIOSPathButtonClicked);
dialog->registerWidgetHelp(m_ui.fastBoot, tr("Fast Boot"), tr("Unchecked"),
tr("Patches the BIOS to skip the console's boot animation. Does not work with all games, "
"but usually safe to enabled."));
dialog->registerWidgetHelp(
m_ui.cdromLoadImageToRAM, tr("Preload Image to RAM"), tr("Unchecked"),
tr("Loads the game image into RAM. Useful for network paths that may become unreliable during gameplay. In some "
@ -49,16 +37,3 @@ ConsoleSettingsWidget::ConsoleSettingsWidget(QtHostInterface* host_interface, QW
}
ConsoleSettingsWidget::~ConsoleSettingsWidget() = default;
void ConsoleSettingsWidget::onBrowseBIOSPathButtonClicked()
{
QString path = QDir::toNativeSeparators(
QFileDialog::getOpenFileName(this, tr("Select BIOS Image"), QString(), tr(BIOS_IMAGE_FILTER)));
if (path.isEmpty())
return;
m_ui.biosPath->setText(path);
m_host_interface->SetStringSettingValue("BIOS", "Path", path.toUtf8().constData());
m_host_interface->applySettings();
}

View File

@ -15,9 +15,6 @@ public:
explicit ConsoleSettingsWidget(QtHostInterface* host_interface, QWidget* parent, SettingsDialog* dialog);
~ConsoleSettingsWidget();
private Q_SLOTS:
void onBrowseBIOSPathButtonClicked();
private:
Ui::ConsoleSettingsWidget m_ui;

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>502</width>
<height>358</height>
<height>255</height>
</rect>
</property>
<property name="windowTitle">
@ -42,41 +42,6 @@
<item row="0" column="1">
<widget class="QComboBox" name="region"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>BIOS Image Path:</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QCheckBox" name="fastBoot">
<property name="text">
<string>Fast Boot</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QCheckBox" name="enableTTYOutput">
<property name="text">
<string>Enable TTY Output</string>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="biosPath"/>
</item>
<item>
<widget class="QPushButton" name="biosPathBrowse">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
@ -145,7 +110,7 @@
</layout>
</widget>
<resources>
<include location="resources/icons.qrc"/>
<include location="resources/resources.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -39,6 +39,7 @@
<ClCompile Include="advancedsettingswidget.cpp" />
<ClCompile Include="audiosettingswidget.cpp" />
<ClCompile Include="autoupdaterdialog.cpp" />
<ClCompile Include="biossettingswidget.cpp" />
<ClCompile Include="consolesettingswidget.cpp" />
<ClCompile Include="enhancementsettingswidget.cpp" />
<ClCompile Include="gamelistmodel.cpp" />
@ -68,6 +69,7 @@
<ItemGroup>
<QtMoc Include="aboutdialog.h" />
<QtMoc Include="audiosettingswidget.h" />
<QtMoc Include="biossettingswidget.h" />
<QtMoc Include="controllersettingswidget.h" />
<QtMoc Include="enhancementsettingswidget.h" />
<QtMoc Include="memorycardsettingswidget.h" />
@ -124,6 +126,9 @@
<QtUi Include="audiosettingswidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="biossettingswidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="consolesettingswidget.ui">
<FileType>Document</FileType>
</QtUi>
@ -171,6 +176,7 @@
<ClCompile Include="$(IntDir)moc_audiosettingswidget.cpp" />
<ClCompile Include="$(IntDir)moc_autoupdaterdialog.cpp" />
<ClCompile Include="$(IntDir)moc_advancedsettingswidget.cpp" />
<ClCompile Include="$(IntDir)moc_biossettingswidget.cpp" />
<ClCompile Include="$(IntDir)moc_consolesettingswidget.cpp" />
<ClCompile Include="$(IntDir)moc_controllersettingswidget.cpp" />
<ClCompile Include="$(IntDir)moc_enhancementsettingswidget.cpp" />

View File

@ -646,6 +646,8 @@ void MainWindow::connectSignals()
connect(m_ui.actionSettings, &QAction::triggered, [this]() { doSettings(SettingsDialog::Category::Count); });
connect(m_ui.actionGeneralSettings, &QAction::triggered,
[this]() { doSettings(SettingsDialog::Category::GeneralSettings); });
connect(m_ui.actionBIOSSettings, &QAction::triggered,
[this]() { doSettings(SettingsDialog::Category::BIOSSettings); });
connect(m_ui.actionConsoleSettings, &QAction::triggered,
[this]() { doSettings(SettingsDialog::Category::ConsoleSettings); });
connect(m_ui.actionGameListSettings, &QAction::triggered,

View File

@ -115,6 +115,7 @@
<addaction name="actionFullscreen"/>
<addaction name="separator"/>
<addaction name="actionGeneralSettings"/>
<addaction name="actionBIOSSettings"/>
<addaction name="actionConsoleSettings"/>
<addaction name="actionGameListSettings"/>
<addaction name="actionHotkeySettings"/>
@ -322,6 +323,15 @@
<string>E&amp;xit</string>
</property>
</action>
<action name="actionBIOSSettings">
<property name="icon">
<iconset>
<normaloff>:/icons/media-flash-2.png</normaloff>:/icons/media-flash-2.png</iconset>
</property>
<property name="text">
<string>B&amp;IOS Settings...</string>
</property>
</action>
<action name="actionConsoleSettings">
<property name="icon">
<iconset>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -59,6 +59,8 @@
<file>icons/list-remove@2x.png</file>
<file>icons/media-flash.png</file>
<file>icons/media-flash@2x.png</file>
<file>icons/media-flash-2.png</file>
<file>icons/media-flash-2@2x.png</file>
<file>icons/media-flash-24.png</file>
<file>icons/media-flash-24@2x.png</file>
<file>icons/media-optical.png</file>

View File

@ -1,6 +1,7 @@
#include "settingsdialog.h"
#include "advancedsettingswidget.h"
#include "audiosettingswidget.h"
#include "biossettingswidget.h"
#include "consolesettingswidget.h"
#include "controllersettingswidget.h"
#include "displaysettingswidget.h"
@ -24,6 +25,7 @@ SettingsDialog::SettingsDialog(QtHostInterface* host_interface, QWidget* parent
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
m_general_settings = new GeneralSettingsWidget(host_interface, m_ui.settingsContainer, this);
m_bios_settings = new BIOSSettingsWidget(host_interface, m_ui.settingsContainer, this);
m_console_settings = new ConsoleSettingsWidget(host_interface, m_ui.settingsContainer, this);
m_game_list_settings = new GameListSettingsWidget(host_interface, m_ui.settingsContainer);
m_hotkey_settings = new HotkeySettingsWidget(host_interface, m_ui.settingsContainer);
@ -36,6 +38,7 @@ SettingsDialog::SettingsDialog(QtHostInterface* host_interface, QWidget* parent
m_advanced_settings = new AdvancedSettingsWidget(host_interface, m_ui.settingsContainer, this);
m_ui.settingsContainer->insertWidget(static_cast<int>(Category::GeneralSettings), m_general_settings);
m_ui.settingsContainer->insertWidget(static_cast<int>(Category::BIOSSettings), m_bios_settings);
m_ui.settingsContainer->insertWidget(static_cast<int>(Category::ConsoleSettings), m_console_settings);
m_ui.settingsContainer->insertWidget(static_cast<int>(Category::GameListSettings), m_game_list_settings);
m_ui.settingsContainer->insertWidget(static_cast<int>(Category::HotkeySettings), m_hotkey_settings);

View File

@ -8,6 +8,7 @@
class QtHostInterface;
class GeneralSettingsWidget;
class BIOSSettingsWidget;
class GameListSettingsWidget;
class HotkeySettingsWidget;
class ConsoleSettingsWidget;
@ -27,6 +28,7 @@ public:
enum class Category
{
GeneralSettings,
BIOSSettings,
ConsoleSettings,
GameListSettings,
HotkeySettings,
@ -44,6 +46,7 @@ public:
~SettingsDialog();
GeneralSettingsWidget* getGeneralSettingsWidget() const { return m_general_settings; }
BIOSSettingsWidget* getBIOSSettingsWidget() const { return m_bios_settings; }
ConsoleSettingsWidget* getConsoleSettingsWidget() const { return m_console_settings; }
GameListSettingsWidget* getGameListSettingsWidget() const { return m_game_list_settings; }
HotkeySettingsWidget* getHotkeySettingsWidget() const { return m_hotkey_settings; }
@ -72,6 +75,7 @@ private:
QtHostInterface* m_host_interface;
GeneralSettingsWidget* m_general_settings = nullptr;
BIOSSettingsWidget* m_bios_settings = nullptr;
ConsoleSettingsWidget* m_console_settings = nullptr;
GameListSettingsWidget* m_game_list_settings = nullptr;
HotkeySettingsWidget* m_hotkey_settings = nullptr;
@ -79,7 +83,7 @@ private:
MemoryCardSettingsWidget* m_memory_card_settings = nullptr;
DisplaySettingsWidget* m_display_settings = nullptr;
EnhancementSettingsWidget* m_enhancement_settings = nullptr;
PostProcessingSettingsWidget *m_post_processing_settings = nullptr;
PostProcessingSettingsWidget* m_post_processing_settings = nullptr;
AudioSettingsWidget* m_audio_settings = nullptr;
AdvancedSettingsWidget* m_advanced_settings = nullptr;

View File

@ -67,6 +67,15 @@
<normaloff>:/icons/applications-system.png</normaloff>:/icons/applications-system.png</iconset>
</property>
</item>
<item>
<property name="text">
<string>BIOS Settings</string>
</property>
<property name="icon">
<iconset resource="resources/resources.qrc">
<normaloff>:/icons/media-flash-2.png</normaloff>:/icons/media-flash-2.png</iconset>
</property>
</item>
<item>
<property name="text">
<string>Console Settings</string>