Qt: Add options to mute inactive or non-P1 multiplayer windows (fixes #857)

This commit is contained in:
Vicki Pfau 2021-06-24 20:20:34 -07:00
parent 14419282f4
commit c785340ea9
7 changed files with 139 additions and 33 deletions

View File

@ -3,6 +3,7 @@ Features:
- Presets for Game Boy palettes - Presets for Game Boy palettes
- Add Super Game Boy palettes for original Game Boy games - Add Super Game Boy palettes for original Game Boy games
- Tool for converting scanned pictures of e-Reader cards to raw dotcode data - Tool for converting scanned pictures of e-Reader cards to raw dotcode data
- Options for muting when inactive, minimized, or for different players in multiplayer
- Cheat code support in homebrew ports - Cheat code support in homebrew ports
- Support for combo "Super Game Boy Color" SGB + GBC ROM hacks - Support for combo "Super Game Boy Color" SGB + GBC ROM hacks
- Support for 64 kiB SRAM saves used in some bootlegs - Support for 64 kiB SRAM saves used in some bootlegs

View File

@ -524,6 +524,21 @@ void CoreController::forceFastForward(bool enable) {
emit fastForwardChanged(enable || m_fastForward); emit fastForwardChanged(enable || m_fastForward);
} }
void CoreController::overrideMute(bool override) {
m_mute = override;
Interrupter interrupter(this);
mCore* core = m_threadContext.core;
if (m_mute) {
core->opts.mute = true;
} else {
int fakeBool = 0;
mCoreConfigGetIntValue(&core->config, "mute", &fakeBool);
core->opts.mute = fakeBool;
}
core->reloadConfigOption(core, NULL, NULL);
}
void CoreController::loadState(int slot) { void CoreController::loadState(int slot) {
if (slot > 0 && slot != m_stateSlot) { if (slot > 0 && slot != m_stateSlot) {
m_stateSlot = slot; m_stateSlot = slot;
@ -1074,7 +1089,7 @@ void CoreController::updateFastForward() {
m_threadContext.core->opts.volume = m_fastForwardVolume; m_threadContext.core->opts.volume = m_fastForwardVolume;
} }
if (m_fastForwardMute >= 0) { if (m_fastForwardMute >= 0) {
m_threadContext.core->opts.mute = m_fastForwardMute; m_threadContext.core->opts.mute = m_fastForwardMute || m_mute;
} }
// If we aren't holding the fast forward button // If we aren't holding the fast forward button

View File

@ -140,6 +140,8 @@ public slots:
void setFastForward(bool); void setFastForward(bool);
void forceFastForward(bool); void forceFastForward(bool);
void overrideMute(bool);
void loadState(int slot = 0); void loadState(int slot = 0);
void loadState(const QString& path, int flags = -1); void loadState(const QString& path, int flags = -1);
void loadState(QIODevice* iodev, int flags = -1); void loadState(QIODevice* iodev, int flags = -1);
@ -276,6 +278,8 @@ private:
float m_fastForwardHeldRatio = -1.f; float m_fastForwardHeldRatio = -1.f;
float m_fpsTarget; float m_fpsTarget;
bool m_mute;
InputController* m_inputController = nullptr; InputController* m_inputController = nullptr;
LogController* m_log = nullptr; LogController* m_log = nullptr;
MultiplayerController* m_multiplayer = nullptr; MultiplayerController* m_multiplayer = nullptr;

View File

@ -534,6 +534,14 @@ void SettingsView::updateConfig() {
emit languageChanged(); emit languageChanged();
} }
if (m_ui.multiplayerAudioAll->isChecked()) {
m_controller->setQtOption("multiplayerAudio", "all");
} else if (m_ui.multiplayerAudio1->isChecked()) {
m_controller->setQtOption("multiplayerAudio", "p1");
} else if (m_ui.multiplayerAudioActive->isChecked()) {
m_controller->setQtOption("multiplayerAudio", "active");
}
int hwaccelVideo = m_controller->getOption("hwaccelVideo").toInt(); int hwaccelVideo = m_controller->getOption("hwaccelVideo").toInt();
saveSetting("hwaccelVideo", m_ui.hwaccelVideo->currentIndex()); saveSetting("hwaccelVideo", m_ui.hwaccelVideo->currentIndex());
if (hwaccelVideo != m_ui.hwaccelVideo->currentIndex()) { if (hwaccelVideo != m_ui.hwaccelVideo->currentIndex()) {
@ -762,6 +770,15 @@ void SettingsView::reloadConfig() {
m_ui.videoScaleSize->setText(tr("(%1×%2)").arg(GBA_VIDEO_HORIZONTAL_PIXELS * value).arg(GBA_VIDEO_VERTICAL_PIXELS * value)); m_ui.videoScaleSize->setText(tr("(%1×%2)").arg(GBA_VIDEO_HORIZONTAL_PIXELS * value).arg(GBA_VIDEO_VERTICAL_PIXELS * value));
}); });
loadSetting("videoScale", m_ui.videoScale, 1); loadSetting("videoScale", m_ui.videoScale, 1);
QString multiplayerAudio = m_controller->getQtOption("multiplayerAudio").toString();
if (multiplayerAudio == QLatin1String("p1")) {
m_ui.multiplayerAudio1->setChecked(true);
} else if (multiplayerAudio == QLatin1String("active")) {
m_ui.multiplayerAudioActive->setChecked(true);
} else {
m_ui.multiplayerAudioAll->setChecked(true);
}
} }
void SettingsView::addPage(const QString& name, QWidget* view, Page index) { void SettingsView::addPage(const QString& name, QWidget* view, Page index) {

View File

@ -313,21 +313,61 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="5" column="0" colspan="2"> <item row="5" column="0">
<widget class="QLabel" name="label_43">
<property name="text">
<string>Audio in multiplayer:</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QRadioButton" name="multiplayerAudioAll">
<property name="text">
<string>All windows</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">multiplayerAudio</string>
</attribute>
</widget>
</item>
<item row="6" column="1">
<widget class="QRadioButton" name="multiplayerAudio1">
<property name="text">
<string>Player 1 window only</string>
</property>
<attribute name="buttonGroup">
<string notr="true">multiplayerAudio</string>
</attribute>
</widget>
</item>
<item row="7" column="1">
<widget class="QRadioButton" name="multiplayerAudioActive">
<property name="text">
<string>Currently active player window</string>
</property>
<attribute name="buttonGroup">
<string notr="true">multiplayerAudio</string>
</attribute>
</widget>
</item>
<item row="8" column="0" colspan="2">
<widget class="Line" name="line_4"> <widget class="Line" name="line_4">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="0"> <item row="9" column="0">
<widget class="QLabel" name="label_10"> <widget class="QLabel" name="label_10">
<property name="text"> <property name="text">
<string>Display driver:</string> <string>Display driver:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="1"> <item row="9" column="1">
<widget class="QComboBox" name="displayDriver"> <widget class="QComboBox" name="displayDriver">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
@ -337,14 +377,14 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="0"> <item row="10" column="0">
<widget class="QLabel" name="label_9"> <widget class="QLabel" name="label_9">
<property name="text"> <property name="text">
<string>Frameskip:</string> <string>Frameskip:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="1"> <item row="10" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_16"> <layout class="QHBoxLayout" name="horizontalLayout_16">
<item> <item>
<widget class="QLabel" name="label_12"> <widget class="QLabel" name="label_12">
@ -365,14 +405,14 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="8" column="0"> <item row="11" column="0">
<widget class="QLabel" name="label_3"> <widget class="QLabel" name="label_3">
<property name="text"> <property name="text">
<string>FPS target:</string> <string>FPS target:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="8" column="1"> <item row="11" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<item> <item>
<widget class="QDoubleSpinBox" name="fpsTarget"> <widget class="QDoubleSpinBox" name="fpsTarget">
@ -399,28 +439,28 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="9" column="1"> <item row="12" column="1">
<widget class="QPushButton" name="nativeGB"> <widget class="QPushButton" name="nativeGB">
<property name="text"> <property name="text">
<string>Native (59.7275)</string> <string>Native (59.7275)</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="10" column="0" colspan="2"> <item row="13" column="0" colspan="2">
<widget class="Line" name="line_5"> <widget class="Line" name="line_5">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
</widget> </widget>
</item> </item>
<item row="11" column="0"> <item row="14" column="0">
<widget class="QLabel" name="label_2"> <widget class="QLabel" name="label_2">
<property name="text"> <property name="text">
<string>Sync:</string> <string>Sync:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="11" column="1"> <item row="14" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_10"> <layout class="QHBoxLayout" name="horizontalLayout_10">
<item> <item>
<widget class="QCheckBox" name="videoSync"> <widget class="QCheckBox" name="videoSync">
@ -438,28 +478,28 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="12" column="1"> <item row="15" column="1">
<widget class="QCheckBox" name="lockAspectRatio"> <widget class="QCheckBox" name="lockAspectRatio">
<property name="text"> <property name="text">
<string>Lock aspect ratio</string> <string>Lock aspect ratio</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="13" column="1"> <item row="16" column="1">
<widget class="QCheckBox" name="lockIntegerScaling"> <widget class="QCheckBox" name="lockIntegerScaling">
<property name="text"> <property name="text">
<string>Force integer scaling</string> <string>Force integer scaling</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="14" column="1"> <item row="17" column="1">
<widget class="QCheckBox" name="interframeBlending"> <widget class="QCheckBox" name="interframeBlending">
<property name="text"> <property name="text">
<string>Interframe blending</string> <string>Interframe blending</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="15" column="1"> <item row="18" column="1">
<widget class="QCheckBox" name="resampleVideo"> <widget class="QCheckBox" name="resampleVideo">
<property name="text"> <property name="text">
<string>Bilinear filtering</string> <string>Bilinear filtering</string>
@ -2174,5 +2214,6 @@
</connections> </connections>
<buttongroups> <buttongroups>
<buttongroup name="gbColors"/> <buttongroup name="gbColors"/>
<buttongroup name="multiplayerAudio"/>
</buttongroups> </buttongroups>
</ui> </ui>

View File

@ -217,6 +217,11 @@ void Window::resizeFrame(const QSize& size) {
} }
} }
void Window::updateMultiplayerActive(bool active) {
m_multiActive = active;
updateMute();
}
void Window::setConfig(ConfigController* config) { void Window::setConfig(ConfigController* config) {
m_config = config; m_config = config;
} }
@ -249,6 +254,7 @@ void Window::reloadConfig() {
if (m_audioProcessor) { if (m_audioProcessor) {
m_audioProcessor->configure(m_config); m_audioProcessor->configure(m_config);
} }
updateMute();
m_display->resizeContext(); m_display->resizeContext();
} }
@ -664,12 +670,8 @@ void Window::showEvent(QShowEvent* event) {
} }
if (m_config->getOption("muteOnMinimize").toInt()) { if (m_config->getOption("muteOnMinimize").toInt()) {
CoreController::Interrupter interrupter(m_controller); m_inactiveMute = false;
mCore* core = m_controller->thread()->core; updateMute();
int fakeBool = 0;
mCoreConfigGetIntValue(&core->config, "mute", &fakeBool);
core->opts.mute = fakeBool;
core->reloadConfigOption(core, NULL, NULL);
} }
} }
return; return;
@ -710,10 +712,8 @@ void Window::hideEvent(QHideEvent* event) {
m_controller->setPaused(true); m_controller->setPaused(true);
} }
if (m_config->getOption("muteOnMinimize").toInt()) { if (m_config->getOption("muteOnMinimize").toInt()) {
CoreController::Interrupter interrupter(m_controller); m_inactiveMute = true;
mCore* core = m_controller->thread()->core; updateMute();
core->opts.mute = true;
core->reloadConfigOption(core, NULL, NULL);
} }
} }
@ -736,6 +736,13 @@ void Window::closeEvent(QCloseEvent* event) {
} }
void Window::focusInEvent(QFocusEvent*) { void Window::focusInEvent(QFocusEvent*) {
for (Window* window : GBAApp::app()->windows()) {
if (window != this) {
window->updateMultiplayerActive(false);
} else {
updateMultiplayerActive(true);
}
}
m_display->forceDraw(); m_display->forceDraw();
} }
@ -1861,16 +1868,12 @@ void Window::focusCheck() {
} }
} }
if (m_config->getOption("muteOnFocusLost").toInt()) { if (m_config->getOption("muteOnFocusLost").toInt()) {
CoreController::Interrupter interrupter(m_controller);
mCore* core = m_controller->thread()->core;
if (QGuiApplication::focusWindow()) { if (QGuiApplication::focusWindow()) {
int fakeBool = 0; m_inactiveMute = false;
mCoreConfigGetIntValue(&core->config, "mute", &fakeBool);
core->opts.mute = fakeBool;
} else { } else {
core->opts.mute = true; m_inactiveMute = true;
} }
core->reloadConfigOption(core, NULL, NULL); updateMute();
} }
} }
@ -2009,6 +2012,26 @@ void Window::attachDisplay() {
m_display->startDrawing(m_controller); m_display->startDrawing(m_controller);
} }
void Window::updateMute() {
if (!m_controller) {
return;
}
bool mute = m_inactiveMute;
if (!mute) {
QString multiplayerAudio = m_config->getQtOption("multiplayerAudio").toString();
if (multiplayerAudio == QLatin1String("p1")) {
MultiplayerController* multiplayer = m_controller->multiplayerController();
mute = multiplayer && multiplayer->attached() > 1 && multiplayer->playerId(m_controller.get());
} else if (multiplayerAudio == QLatin1String("active")) {
mute = !m_multiActive;
}
}
m_controller->overrideMute(mute);
}
void Window::setLogo() { void Window::setLogo() {
m_screenWidget->setPixmap(m_logo); m_screenWidget->setPixmap(m_logo);
m_screenWidget->setDimensions(m_logo.width(), m_logo.height()); m_screenWidget->setDimensions(m_logo.width(), m_logo.height());

View File

@ -64,6 +64,7 @@ public:
void resizeFrame(const QSize& size); void resizeFrame(const QSize& size);
void updateMultiplayerStatus(bool canOpenAnother) { m_multiWindow->setEnabled(canOpenAnother); } void updateMultiplayerStatus(bool canOpenAnother) { m_multiWindow->setEnabled(canOpenAnother); }
void updateMultiplayerActive(bool active);
signals: signals:
void startDrawing(); void startDrawing();
@ -145,6 +146,7 @@ private slots:
void focusCheck(); void focusCheck();
void updateFrame(); void updateFrame();
void updateMute();
void setLogo(); void setLogo();
@ -226,6 +228,9 @@ private:
bool m_hitUnimplementedBiosCall; bool m_hitUnimplementedBiosCall;
bool m_inactiveMute = false;
bool m_multiActive = true;
std::unique_ptr<OverrideView> m_overrideView; std::unique_ptr<OverrideView> m_overrideView;
std::unique_ptr<SensorView> m_sensorView; std::unique_ptr<SensorView> m_sensorView;
std::unique_ptr<DolphinConnector> m_dolphinView; std::unique_ptr<DolphinConnector> m_dolphinView;