From d25aed2da98cfc4e2208bb46cd24776d5e6b6020 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 7 Mar 2025 00:36:09 +0600 Subject: [PATCH] Add global mute option --- src/86box.c | 1 + src/config.c | 5 ++++ src/include/86box/86box.h | 1 + src/qt/icons/sound_mute.ico | Bin 0 -> 9622 bytes src/qt/qt_machinestatus.cpp | 45 +++++++++++++++++++++++++++++++----- src/qt/qt_machinestatus.hpp | 6 +++++ src/qt/qt_mainwindow.cpp | 1 + src/qt_resources.qrc | 1 + src/sound/openal.c | 2 +- src/sound/xaudio2.c | 2 +- 10 files changed, 56 insertions(+), 8 deletions(-) create mode 100644 src/qt/icons/sound_mute.ico diff --git a/src/86box.c b/src/86box.c index 6b64cd2ec..aa3afb085 100644 --- a/src/86box.c +++ b/src/86box.c @@ -213,6 +213,7 @@ int do_auto_pause = 0; /* (C) Auto-pa int hook_enabled = 1; /* (C) Keyboard hook is enabled */ int test_mode = 0; /* (C) Test mode */ char uuid[MAX_UUID_LEN] = { '\0' }; /* (C) UUID or machine identifier */ +int sound_muted = 0; /* (C) Is sound muted? */ int other_ide_present = 0; /* IDE controllers from non-IDE cards are present */ diff --git a/src/config.c b/src/config.c index 6c34c4790..07e770822 100644 --- a/src/config.c +++ b/src/config.c @@ -168,6 +168,7 @@ load_general(void) kbd_req_capture = ini_section_get_int(cat, "kbd_req_capture", 0); hide_status_bar = ini_section_get_int(cat, "hide_status_bar", 0); hide_tool_bar = ini_section_get_int(cat, "hide_tool_bar", 0); + sound_muted = ini_section_get_int(cat, "sound_muted", 0); confirm_reset = ini_section_get_int(cat, "confirm_reset", 1); confirm_exit = ini_section_get_int(cat, "confirm_exit", 1); @@ -1846,6 +1847,10 @@ save_general(void) const char *va_name; + ini_section_set_int(cat, "sound_muted", sound_muted); + if (sound_muted == 0) + ini_section_delete_var(cat, "sound_muted"); + ini_section_set_int(cat, "vid_resize", vid_resize); if (vid_resize == 0) ini_section_delete_var(cat, "vid_resize"); diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index e4e5ecae1..79bb84009 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -158,6 +158,7 @@ extern int other_scsi_present; /* SCSI controllers from non-SCSI ca extern int hard_reset_pending; extern int fixed_size_x; extern int fixed_size_y; +extern int sound_muted; /* (C) Is sound muted? */ extern int do_auto_pause; /* (C) Auto-pause the emulator on focus loss */ extern int auto_paused; extern double mouse_sensitivity; /* (C) Mouse sensitivity scale */ diff --git a/src/qt/icons/sound_mute.ico b/src/qt/icons/sound_mute.ico new file mode 100644 index 0000000000000000000000000000000000000000..89a8407354ce0ef805689d75763cd17fd58ce52b GIT binary patch literal 9622 zcmZQzU}Run5D);-3Je)63=D1z3=AS75dID}28MMk3=9$y5PkV}|7)cl>6Qq^_YQ}#ChW|*I z0W610CsYqqFUSory)YdhK6W!u^@7yH^n=)7eGCw{VCskI1t|cjK5*c`e+CAGeuzBC z3=oFv2m1vg$H1^;!2%RMsu>`CAPh1SWCO$u{CXLX!U3eO;Xh10$b@Ilo`LOy*$ZagjB$-(r%)WGz@#L;P(K4coE24)5lA6Xe*HcStU#;X{&Bsg8*mS$l1pZx#- zzsCRn|ML9*|7*(s|6c|E|6kSk|9`0C|NpC2|NkEv3Zbut{{R1K_y7N2L;wH(wg3PB zzxDtB|NH;{Kd77$VSto3jNsCSfnfq0J{w7r1Gyg^lVkvrVx+PMl>cBDkr$BE;$%YN z1C$5h`jOPa#XxRG635Aes)LyaQU@{vM8hzc4^;;f!=xeZg5_~!^FV6BW`G!=BndJL zgrR&)3e_x-Ji2)xF_@WP8mDum{~9yW(JIg zsmDcw%!HN8Fg-A{VD5s^FnJgsq!)_8VFhJ_DVTjQv(e3jnFUjaWG2ik7!5WLnLsxa zW(LemB(q@JaGC{D0MZXL6Q&nt7Dx`J1{)0$!-ZjH!pwk~iA6nL_aUoCHxpS7jZL(f zFh9fGiDnLnONv<_^&m`+9*{nY@c$q7|NnoG|NsAR|Ns9>&;S4LcK-jr<^KQwI`aSj zwLt#=)c|>DeHH(I)$0BKuZG6||FwGm|DU1p|NpJu|Nnpd{r~?#^!@)}0IIhn7#J7~ zklM!yoD?|`T{9@0&@s9ia`;d)5oHpjeG1}(%NLM5Ip%`&AeDKbvJ)MH>;Pe~Js|bO zVz9ZOfQPiZK`cxRlY{t&Xgi?(Z2%jHW(JD;Knfu8MEe1Y*~s>Q%^}wgsM#QYVw#EO zR%rVlOzDJbJnC62tpxc2(4B31b8%!h2#_oQY8_?}Qn0GWe~LE<0`5(9-RtUZTl^PsyQ#)sGiu>;kuAoCy?Bo4wLzasq2z(Ab)85kgT zf!v0$2V@=$gUp3saFBrsm_4vCftZ2t4@fUqAp^v}FnNeM5W5g;uu5=zf>}@kW(T@I zAYlSl1l9vH8>Svz9-WV*4jPA;@d49=#cZ&}SO~CNu!zHjVD`eo4917q0au8dL9`vX z+z+#p5RKajh_Hg$0W%Aq9;h5a_e0fT#0yNE2%2a+VD2ZvOqddw*)SR=KIG{Cf8_uF z|G@tL{{!a#{~H+p|95=&|6jw0|9@Em{{Lz-_#j6ty=Z}YWVm6zt;c$|2H)B|G)LW|NoEw`~Uy`U!ZIc#-Mf>XpGVUsU6k; z8n~oiNP*%A9n-^hsGaC#9EcAt3qkU(Zpe9g5~fKFm+%WR$n39fN4L-EHt}7LJVkPVDrEdxCyWt{B>2b><3|FHz2cN=7H2;!FcT^E9_xz zfVdqw4q$eG>_NsLaS#THVdQ_Xov<*0*$Jaz;xId5G|Ybxd59ZO{R*-Vf;m##%u>co} z1z>Yv>R@)E(jaA+7`=TBvlE?0w+rS5OcRM0ftd-j3uY#a52IoJf~kk8gYjWBx;mIR zE*j)gV*L+_N054$9WXaQ#mJ&y?t=LfW+sdeqhWT!)Wg)l_(+zcr31JOOdKu%W5CQH z6b>*qpxX`852In~(D~@%Nb(r%eVD&tG)yndZWxVh2FyP=Xqf+DG!A8mJO;BHM#Joa z*$ty{8bpBv%r2PSg!~UvPl$$@15=03i7+*|+yIluX9lHmFgsvwfbl5^dszI#Xo60J z*$E3fnB7R?1kFHGK(yU3eMokJ^&;_MN@z~Q?1a%Yw-CDpVE<#68WkOCA@Cn%AmRYy z|L+GM{(s%@;s4c^g8!@94E~3<3;bKv-tafn(ec-+1B_Qg9hg_GTEG+<8X~`H6=)qp zXefj(y}xSJs#RA*>#zS>^&d1Y5&Cb{|Ns9(|9}0z>i_TmSO5S2|N8&`|KCBiI06Fz D@pane literal 0 HcmV?d00001 diff --git a/src/qt/qt_machinestatus.cpp b/src/qt/qt_machinestatus.cpp index dee90f11c..3c3f4019f 100644 --- a/src/qt/qt_machinestatus.cpp +++ b/src/qt/qt_machinestatus.cpp @@ -39,6 +39,7 @@ extern "C" { #include <86box/network.h> #include <86box/ui.h> #include <86box/machine_status.h> +#include <86box/config.h> }; #include @@ -89,7 +90,7 @@ struct Pixmaps { PixmapSetEmptyActive mo; PixmapSetActive hd; PixmapSetEmptyActive net; - QPixmap sound; + QPixmap sound, soundMuted; }; struct StateActive { @@ -215,6 +216,7 @@ struct MachineStatus::States { pixmaps.hd.load("/hard_disk%1.ico"); pixmaps.net.load("/network%1.ico"); pixmaps.sound = ProgSettings::loadIcon("/sound.ico").pixmap(pixmap_size); + pixmaps.soundMuted = ProgSettings::loadIcon("/sound_mute.ico").pixmap(pixmap_size); cartridge[0].pixmaps = &pixmaps.cartridge; cartridge[1].pixmaps = &pixmaps.cartridge; @@ -256,12 +258,19 @@ MachineStatus::MachineStatus(QObject *parent) , refreshTimer(new QTimer(this)) { d = std::make_unique(this); + muteUnmuteAction = nullptr; connect(refreshTimer, &QTimer::timeout, this, &MachineStatus::refreshIcons); refreshTimer->start(75); } MachineStatus::~MachineStatus() = default; +void +MachineStatus::setSoundGainAction(QAction* action) +{ + soundGainAction = action; +} + bool MachineStatus::hasCassette() { @@ -494,6 +503,28 @@ MachineStatus::refresh(QStatusBar *sbar) } sbar->removeWidget(d->sound.get()); + if (!muteUnmuteAction) { + muteUnmuteAction = new QAction; + connect(muteUnmuteAction, &QAction::triggered, this, [this]() { + sound_muted ^= 1; + config_save(); + if (d->sound) + d->sound->setPixmap(sound_muted ? d->pixmaps.soundMuted : d->pixmaps.sound); + + muteUnmuteAction->setText(sound_muted ? tr("&Unmute") : tr("&Mute")); + }); + } + + if (!soundMenu) { + soundMenu = new QMenu((QWidget*)parent()); + + soundMenu->addAction(muteUnmuteAction); + soundMenu->addSeparator(); + soundMenu->addAction(soundGainAction); + + muteUnmuteAction->setParent(soundMenu); + } + if (cassette_enable) { d->cassette.label = std::make_unique(); d->cassette.setEmpty(QString(cassette_fname).isEmpty()); @@ -662,12 +693,14 @@ MachineStatus::refresh(QStatusBar *sbar) } d->sound = std::make_unique(); - d->sound->setPixmap(d->pixmaps.sound); - - connect(d->sound.get(), &ClickableLabel::doubleClicked, d->sound.get(), [](QPoint pos) { - SoundGain gain(main_window); - gain.exec(); + d->sound->setPixmap(sound_muted ? d->pixmaps.soundMuted : d->pixmaps.sound); + if (muteUnmuteAction) + muteUnmuteAction->setText(sound_muted ? tr("&Unmute") : tr("&Mute")); + + connect(d->sound.get(), &ClickableLabel::clicked, this, [this](QPoint pos) { + this->soundMenu->popup(pos - QPoint(0, this->soundMenu->sizeHint().height())); }); + d->sound->setToolTip(tr("Sound")); sbar->addWidget(d->sound.get()); d->text = std::make_unique(); diff --git a/src/qt/qt_machinestatus.hpp b/src/qt/qt_machinestatus.hpp index fc0e33e91..90b420763 100644 --- a/src/qt/qt_machinestatus.hpp +++ b/src/qt/qt_machinestatus.hpp @@ -1,6 +1,8 @@ #ifndef QT_MACHINESTATUS_HPP #define QT_MACHINESTATUS_HPP +#include +#include #include #include #include @@ -71,6 +73,7 @@ public: QString getMessage(); void clearActivity(); + void setSoundGainAction(QAction* action); public slots: void refresh(QStatusBar *sbar); void message(const QString &msg); @@ -82,6 +85,9 @@ private: struct States; std::unique_ptr d; QTimer *refreshTimer; + QAction *soundGainAction; + QAction *muteUnmuteAction; + QMenu *soundMenu; }; #endif // QT_MACHINESTATUS_HPP diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 552fd0310..61f5f6fe1 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -178,6 +178,7 @@ MainWindow::MainWindow(QWidget *parent) extern MainWindow *main_window; main_window = this; ui->setupUi(this); + status->setSoundGainAction(ui->actionSound_gain); ui->stackedWidget->setMouseTracking(true); statusBar()->setVisible(!hide_status_bar); statusBar()->setStyleSheet("QStatusBar::item {border: None; } QStatusBar QLabel { margin-right: 2px; margin-bottom: 1px; }"); diff --git a/src/qt_resources.qrc b/src/qt_resources.qrc index 1f6341786..6ca323b89 100644 --- a/src/qt_resources.qrc +++ b/src/qt_resources.qrc @@ -43,6 +43,7 @@ qt/icons/other_removable_devices.ico qt/icons/ports.ico qt/icons/sound.ico + qt/icons/sound_mute.ico qt/icons/storage_controllers.ico qt/icons/zip.ico qt/icons/zip_active.ico diff --git a/src/sound/openal.c b/src/sound/openal.c index a41199b23..90f626362 100644 --- a/src/sound/openal.c +++ b/src/sound/openal.c @@ -278,7 +278,7 @@ givealbuffer_common(const void *buf, const uint8_t src, const int size, const in alGetSourcei(source[src], AL_BUFFERS_PROCESSED, &processed); if (processed >= 1) { - const double gain = pow(10.0, (double) sound_gain / 20.0); + const double gain = sound_muted ? 0.0 : pow(10.0, (double) sound_gain / 20.0); alListenerf(AL_GAIN, (float) gain); alSourceUnqueueBuffers(source[src], 1, &buffer); diff --git a/src/sound/xaudio2.c b/src/sound/xaudio2.c index 9b341f574..2aee97efc 100644 --- a/src/sound/xaudio2.c +++ b/src/sound/xaudio2.c @@ -245,7 +245,7 @@ givealbuffer_common(const void *buf, IXAudio2SourceVoice *sourcevoice, const siz if (!initialized) return; - (void) IXAudio2MasteringVoice_SetVolume(mastervoice, pow(10.0, (double) sound_gain / 20.0), + (void) IXAudio2MasteringVoice_SetVolume(mastervoice, sound_muted ? 0.0 : pow(10.0, (double) sound_gain / 20.0), XAUDIO2_COMMIT_NOW); XAUDIO2_BUFFER buffer = { 0 }; buffer.Flags = 0;