mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'sleek-sound-options' into 'master'
Sound options polish Closes #289 See merge request KartKrew/Kart!1719
This commit is contained in:
commit
6563ab9261
7 changed files with 349 additions and 87 deletions
|
|
@ -318,8 +318,12 @@ consvar_t cv_controlperkey = Player("controlperkey", "One").values({{1, "One"},
|
|||
// actual general (maximum) sound & music volume, saved into the config
|
||||
// Volume scale is 0-100 in new mixer. 100 is treated as -0dB or 100% gain. No more weirdness to work around SDL_mixer
|
||||
// problems
|
||||
consvar_t cv_digmusicvolume = Player("musicvolume", "80").min_max(0, 100);
|
||||
consvar_t cv_soundvolume = Player("soundvolume", "80").min_max(0, 100);
|
||||
void MasterVolume_OnChange(void);
|
||||
void DigMusicVolume_OnChange(void);
|
||||
void SoundVolume_OnChange(void);
|
||||
consvar_t cv_mastervolume = Player("volume", "80").min_max(0, 100).onchange_noinit(MasterVolume_OnChange);
|
||||
consvar_t cv_digmusicvolume = Player("musicvolume", "80").min_max(0, 100).onchange_noinit(DigMusicVolume_OnChange);
|
||||
consvar_t cv_soundvolume = Player("soundvolume", "80").min_max(0, 100).onchange_noinit(SoundVolume_OnChange);
|
||||
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
void DRPC_UpdatePresence(void);
|
||||
|
|
@ -402,10 +406,14 @@ extern CV_PossibleValue_t perfstats_cons_t[];
|
|||
consvar_t cv_perfstats = Player("perfstats", "Off").dont_save().values(perfstats_cons_t);
|
||||
|
||||
// Window focus sound sytem toggles
|
||||
void PlayMusicIfUnfocused_OnChange(void);
|
||||
void PlaySoundIfUnfocused_OnChange(void);
|
||||
consvar_t cv_playmusicifunfocused = Player("playmusicifunfocused", "No").yes_no().onchange_noinit(PlayMusicIfUnfocused_OnChange);
|
||||
consvar_t cv_playsoundifunfocused = Player("playsoundsifunfocused", "No").yes_no().onchange_noinit(PlaySoundIfUnfocused_OnChange);
|
||||
void BGAudio_OnChange(void);
|
||||
void BGAudio_OnChange(void);
|
||||
consvar_t cv_bgaudio = Player("bgaudio", "Nothing").onchange_noinit(BGAudio_OnChange).values({
|
||||
{0, "Nothing"},
|
||||
{1, "Music"},
|
||||
{2, "Sounds"},
|
||||
{3, "Music&Sounds"},
|
||||
});
|
||||
|
||||
// Pause game upon window losing focus
|
||||
consvar_t cv_pauseifunfocused = Player("pauseifunfocused", "Yes").yes_no();
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ target_sources(SRB2SDL2 PRIVATE
|
|||
options-profiles-edit-controls.c
|
||||
options-server-1.c
|
||||
options-server-advanced.c
|
||||
options-sound.c
|
||||
options-sound.cpp
|
||||
options-video-1.c
|
||||
options-video-gl.c
|
||||
options-video-modes.c
|
||||
|
|
|
|||
|
|
@ -1,66 +0,0 @@
|
|||
/// \file menus/options-sound.c
|
||||
/// \brief Sound Options
|
||||
|
||||
#include "../k_menu.h"
|
||||
#include "../s_sound.h" // sounds consvars
|
||||
#include "../g_game.h" // cv_chatnotifications
|
||||
|
||||
menuitem_t OPTIONS_Sound[] =
|
||||
{
|
||||
|
||||
{IT_STRING | IT_CVAR, "SFX", "Enable or disable sound effect playback.",
|
||||
NULL, {.cvar = &cv_gamesounds}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER, "SFX Volume", "Adjust the volume of sound effects.",
|
||||
NULL, {.cvar = &cv_soundvolume}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CVAR, "Music", "Enable or disable music playback.",
|
||||
NULL, {.cvar = &cv_gamedigimusic}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER, "Music Volume", "Adjust the volume of music playback.",
|
||||
NULL, {.cvar = &cv_digmusicvolume}, 0, 0},
|
||||
|
||||
{IT_SPACE | IT_NOTHING, NULL, NULL,
|
||||
NULL, {NULL}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CVAR, "Reverse L/R Channels", "Reverse left & right channels for Stereo playback.",
|
||||
NULL, {.cvar = &stereoreverse}, 0, 0},
|
||||
|
||||
{IT_SPACE | IT_NOTHING, NULL, NULL,
|
||||
NULL, {NULL}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CVAR, "Chat Notifications", "Set when to play notification sounds when chat messages are received.",
|
||||
NULL, {.cvar = &cv_chatnotifications}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CVAR, "Character Voices", "Set how often to play character voices in game.",
|
||||
NULL, {.cvar = &cv_kartvoices}, 0, 0},
|
||||
|
||||
{IT_SPACE | IT_NOTHING, NULL, NULL,
|
||||
NULL, {NULL}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CVAR, "Play Music While Unfocused", "Keeps playing music even if the game is not the active window.",
|
||||
NULL, {.cvar = &cv_playmusicifunfocused}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CVAR, "Play SFX While Unfocused", "Keeps playing sound effects even if the game is not the active window.",
|
||||
NULL, {.cvar = &cv_playsoundifunfocused}, 0, 0},
|
||||
|
||||
// @TODO: Sound test (there's currently no space on this menu, might be better to throw it in extras?)
|
||||
};
|
||||
|
||||
menu_t OPTIONS_SoundDef = {
|
||||
sizeof (OPTIONS_Sound) / sizeof (menuitem_t),
|
||||
&OPTIONS_MainDef,
|
||||
0,
|
||||
OPTIONS_Sound,
|
||||
48, 80,
|
||||
SKINCOLOR_THUNDER, 0,
|
||||
MBF_DRAWBGWHILEPLAYING,
|
||||
NULL,
|
||||
2, 5,
|
||||
M_DrawGenericOptions,
|
||||
M_DrawOptionsCogs,
|
||||
M_OptionsTick,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
280
src/menus/options-sound.cpp
Normal file
280
src/menus/options-sound.cpp
Normal file
|
|
@ -0,0 +1,280 @@
|
|||
/// \file menus/options-sound.c
|
||||
/// \brief Sound Options
|
||||
|
||||
#include <array>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "../v_draw.hpp"
|
||||
|
||||
#include "../doomstat.h"
|
||||
#include "../console.h"
|
||||
#include "../k_menu.h"
|
||||
#include "../m_cond.h"
|
||||
#include "../s_sound.h" // sounds consvars
|
||||
#include "../g_game.h" // cv_chatnotifications
|
||||
|
||||
extern "C" consvar_t cv_mastervolume;
|
||||
|
||||
using srb2::Draw;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
bool basic_options()
|
||||
{
|
||||
// M_GameTrulyStarted
|
||||
return gamedata && gamestartchallenge < MAXUNLOCKABLES && !netgame && gamedata->gonerlevel <= GDGONER_PROFILE;
|
||||
}
|
||||
|
||||
int flip_delay = 0;
|
||||
|
||||
struct Slider
|
||||
{
|
||||
enum Id
|
||||
{
|
||||
kMasterVolume,
|
||||
kMusicVolume,
|
||||
kSfxVolume,
|
||||
kNumSliders
|
||||
};
|
||||
|
||||
Slider(bool(*toggle)(bool), consvar_t& volume) : toggle_(toggle), volume_(volume) {}
|
||||
|
||||
bool(*toggle_)(bool);
|
||||
consvar_t& volume_;
|
||||
|
||||
int shake_ = 0;
|
||||
|
||||
void draw(int x, int y, bool shaded, bool selected)
|
||||
{
|
||||
constexpr int kWidth = 111;
|
||||
|
||||
Draw h(320 - x - kWidth, y);
|
||||
|
||||
if (selected)
|
||||
{
|
||||
int ofs = skullAnimCounter / 5;
|
||||
Draw arrows = h.font(Draw::Font::kConsole).align(Draw::Align::kLeft).flags(highlightflags);
|
||||
|
||||
arrows.x(-10 - ofs).text("\x1C");
|
||||
arrows.x(kWidth + 2 + ofs).text("\x1D");
|
||||
|
||||
if (!basic_options())
|
||||
{
|
||||
h.xy(kWidth + 9, -3).small_button(Draw::Button::z, false);
|
||||
}
|
||||
}
|
||||
|
||||
h = h.y(1);
|
||||
h.size(kWidth, 7).fill(31);
|
||||
|
||||
Draw s = shaded ? h.xy(1, 5).size(10, 1) : h.xy(1, 2).size(10, 4);
|
||||
int color = toggle_(false) ? aquamap[0] : 15;
|
||||
|
||||
int n = volume_.value / 10;
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
s.fill(color);
|
||||
s = s.x(11);
|
||||
}
|
||||
|
||||
s.width(volume_.value % 10).fill(color);
|
||||
|
||||
n = std::atoi(volume_.defaultvalue);
|
||||
h.x(1 + shake_ + n + (n / 10)).size(1, 7).fill(35);
|
||||
|
||||
if (!toggle_(false))
|
||||
{
|
||||
h
|
||||
.x(kWidth / 2)
|
||||
.font(Draw::Font::kConsole)
|
||||
.align(Draw::Align::kCenter)
|
||||
.flags(V_40TRANS)
|
||||
.text("S I L E N T");
|
||||
}
|
||||
}
|
||||
|
||||
void input(INT32 c)
|
||||
{
|
||||
if (c == -1 && &volume_ == &cv_mastervolume)
|
||||
{
|
||||
// Master volume does not necessarily change when
|
||||
// music or sound volumes change separately. So
|
||||
// cv_mastervolume could still have its default
|
||||
// value, and M_ChangeCvarDirect would do
|
||||
// nothing.
|
||||
CV_Set(&cv_digmusicvolume, cv_mastervolume.defaultvalue);
|
||||
CV_Set(&cv_soundvolume, cv_mastervolume.defaultvalue);
|
||||
}
|
||||
else
|
||||
{
|
||||
M_ChangeCvarDirect(c, &volume_);
|
||||
}
|
||||
|
||||
shake_ = !shake_;
|
||||
flip_delay = 2;
|
||||
}
|
||||
};
|
||||
|
||||
std::array<Slider, Slider::kNumSliders> sliders{{
|
||||
{
|
||||
[](bool toggle) -> bool
|
||||
{
|
||||
bool n = !S_MusicDisabled() || !S_SoundDisabled();
|
||||
|
||||
if (toggle)
|
||||
{
|
||||
n = !n;
|
||||
CV_SetValue(&cv_gamedigimusic, n);
|
||||
CV_SetValue(&cv_gamesounds, n);
|
||||
}
|
||||
|
||||
return n;
|
||||
},
|
||||
cv_mastervolume,
|
||||
},
|
||||
{
|
||||
[](bool toggle) -> bool
|
||||
{
|
||||
if (toggle)
|
||||
{
|
||||
CV_AddValue(&cv_gamedigimusic, 1);
|
||||
}
|
||||
|
||||
return !S_MusicDisabled();
|
||||
},
|
||||
cv_digmusicvolume,
|
||||
},
|
||||
{
|
||||
[](bool toggle) -> bool
|
||||
{
|
||||
if (toggle)
|
||||
{
|
||||
CV_AddValue(&cv_gamesounds, 1);
|
||||
}
|
||||
|
||||
return !S_SoundDisabled();
|
||||
},
|
||||
cv_soundvolume,
|
||||
},
|
||||
}};
|
||||
|
||||
void slider_routine(INT32 c)
|
||||
{
|
||||
sliders.at(currentMenu->menuitems[itemOn].mvar2).input(c);
|
||||
}
|
||||
|
||||
void restartaudio_routine(INT32)
|
||||
{
|
||||
COM_ImmedExecute("restartaudio");
|
||||
}
|
||||
|
||||
void draw_routine()
|
||||
{
|
||||
int x = currentMenu->x - (menutransition.tics * 48);
|
||||
int y = currentMenu->y;
|
||||
|
||||
M_DrawGenericOptions();
|
||||
|
||||
for (int i = 0; i < currentMenu->numitems; ++i)
|
||||
{
|
||||
const menuitem_t& it = currentMenu->menuitems[i];
|
||||
|
||||
if ((it.status & IT_TYPE) == IT_ARROWS)
|
||||
{
|
||||
sliders.at(it.mvar2).draw(
|
||||
x,
|
||||
y,
|
||||
it.mvar2 == Slider::kMasterVolume,
|
||||
i == itemOn
|
||||
);
|
||||
}
|
||||
|
||||
y += 8;
|
||||
}
|
||||
}
|
||||
|
||||
void tick_routine(void)
|
||||
{
|
||||
M_OptionsTick();
|
||||
|
||||
if (flip_delay && !--flip_delay)
|
||||
{
|
||||
for (Slider& slider : sliders)
|
||||
{
|
||||
slider.shake_ = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean input_routine(INT32)
|
||||
{
|
||||
UINT8 pid = 0; // todo: Add ability for any splitscreen player to bring up the menu.
|
||||
|
||||
const menuitem_t& it = currentMenu->menuitems[itemOn];
|
||||
|
||||
if (M_MenuButtonPressed(pid, MBT_Z) && (it.status & IT_TYPE) == IT_ARROWS && !basic_options())
|
||||
{
|
||||
sliders.at(it.mvar2).toggle_(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}; // namespace
|
||||
|
||||
menuitem_t OPTIONS_Sound[] =
|
||||
{
|
||||
|
||||
{IT_STRING | IT_ARROWS | IT_CV_SLIDER, "Volume", "Adjust the volume of game audio.",
|
||||
NULL, {.routine = slider_routine}, 0, Slider::kMasterVolume},
|
||||
|
||||
{IT_STRING | IT_ARROWS | IT_CV_SLIDER, "SFX Volume", "Adjust the volume of sound effects.",
|
||||
NULL, {.routine = slider_routine}, 0, Slider::kSfxVolume},
|
||||
|
||||
{IT_STRING | IT_ARROWS | IT_CV_SLIDER, "Music Volume", "Adjust the volume of music playback.",
|
||||
NULL, {.routine = slider_routine}, 0, Slider::kMusicVolume},
|
||||
|
||||
{IT_SPACE | IT_NOTHING, NULL, NULL,
|
||||
NULL, {NULL}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CVAR, "Chat Notifications", "Set when to play notification sounds when chat messages are received.",
|
||||
NULL, {.cvar = &cv_chatnotifications}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CVAR, "Character Voices", "Set how often to play character voices in game.",
|
||||
NULL, {.cvar = &cv_kartvoices}, 0, 0},
|
||||
|
||||
{IT_SPACE | IT_NOTHING, NULL, NULL,
|
||||
NULL, {NULL}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CVAR, "Reverse L/R Channels", "Reverse left & right channels for Stereo playback.",
|
||||
NULL, {.cvar = &stereoreverse}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CVAR, "Hear Tabbed-out", "Keep playing game audio when the window is out of focus (FOCUS LOST).",
|
||||
NULL, {.cvar = &cv_bgaudio}, 0, 0},
|
||||
|
||||
{IT_SPACE | IT_NOTHING, NULL, NULL,
|
||||
NULL, {NULL}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CALL, "\x85" "Restart Audio", "Reboot the game's audio system.",
|
||||
NULL, {.routine = restartaudio_routine}, 0, 0},
|
||||
};
|
||||
|
||||
menu_t OPTIONS_SoundDef = {
|
||||
sizeof (OPTIONS_Sound) / sizeof (menuitem_t),
|
||||
&OPTIONS_MainDef,
|
||||
0,
|
||||
OPTIONS_Sound,
|
||||
48, 80,
|
||||
SKINCOLOR_THUNDER, 0,
|
||||
MBF_DRAWBGWHILEPLAYING,
|
||||
NULL,
|
||||
2, 5,
|
||||
draw_routine,
|
||||
M_DrawOptionsCogs,
|
||||
tick_routine,
|
||||
NULL,
|
||||
NULL,
|
||||
input_routine,
|
||||
};
|
||||
|
|
@ -37,6 +37,8 @@
|
|||
#include "v_video.h" // V_ThinStringWidth
|
||||
#include "music.h"
|
||||
|
||||
extern consvar_t cv_mastervolume;
|
||||
|
||||
static boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *vol, INT32 *sep, INT32 *pitch, sfxinfo_t *sfxinfo);
|
||||
|
||||
static void Command_Tunes_f(void);
|
||||
|
|
@ -246,7 +248,7 @@ boolean S_SoundDisabled(void)
|
|||
{
|
||||
return (
|
||||
sound_disabled ||
|
||||
( window_notinfocus && ! cv_playsoundifunfocused.value )
|
||||
( window_notinfocus && ! (cv_bgaudio.value & 2) )
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -2166,7 +2168,7 @@ boolean S_MusicDisabled(void)
|
|||
boolean S_MusicNotInFocus(void)
|
||||
{
|
||||
return (
|
||||
( window_notinfocus && ! cv_playmusicifunfocused.value )
|
||||
( window_notinfocus && ! (cv_bgaudio.value & 1) )
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -2519,24 +2521,63 @@ void GameDigiMusic_OnChange(void)
|
|||
}
|
||||
}
|
||||
|
||||
void PlayMusicIfUnfocused_OnChange(void);
|
||||
void PlayMusicIfUnfocused_OnChange(void)
|
||||
void MasterVolume_OnChange(void);
|
||||
void MasterVolume_OnChange(void)
|
||||
{
|
||||
INT32 adj = cv_mastervolume.value - max(cv_digmusicvolume.value, cv_soundvolume.value);
|
||||
|
||||
if (adj < 0)
|
||||
{
|
||||
INT32 under = min(cv_digmusicvolume.value, cv_soundvolume.value) + adj;
|
||||
|
||||
if (under < 0)
|
||||
{
|
||||
// Ensure balance between music/sound volume does
|
||||
// not change at lower bound. (This is already
|
||||
// guaranteed at upper bound.)
|
||||
adj -= under;
|
||||
CV_StealthSetValue(&cv_mastervolume, cv_mastervolume.value - under);
|
||||
}
|
||||
}
|
||||
|
||||
CV_SetValue(&cv_digmusicvolume, cv_digmusicvolume.value + adj);
|
||||
CV_SetValue(&cv_soundvolume, cv_soundvolume.value + adj);
|
||||
}
|
||||
|
||||
void DigMusicVolume_OnChange(void);
|
||||
void DigMusicVolume_OnChange(void)
|
||||
{
|
||||
if (!cv_gamedigimusic.value)
|
||||
{
|
||||
CV_SetValue(&cv_gamedigimusic, 1);
|
||||
}
|
||||
CV_StealthSetValue(&cv_mastervolume, max(cv_digmusicvolume.value, cv_soundvolume.value));
|
||||
}
|
||||
|
||||
void SoundVolume_OnChange(void);
|
||||
void SoundVolume_OnChange(void)
|
||||
{
|
||||
if (!cv_gamesounds.value)
|
||||
{
|
||||
CV_SetValue(&cv_gamesounds, 1);
|
||||
}
|
||||
CV_StealthSetValue(&cv_mastervolume, max(cv_digmusicvolume.value, cv_soundvolume.value));
|
||||
}
|
||||
|
||||
void BGAudio_OnChange(void);
|
||||
void BGAudio_OnChange(void)
|
||||
{
|
||||
if (window_notinfocus)
|
||||
{
|
||||
if (cv_playmusicifunfocused.value)
|
||||
if (cv_bgaudio.value & 1)
|
||||
I_SetMusicVolume(0);
|
||||
else
|
||||
S_SetMusicVolume();
|
||||
}
|
||||
}
|
||||
|
||||
void PlaySoundIfUnfocused_OnChange(void);
|
||||
void PlaySoundIfUnfocused_OnChange(void)
|
||||
{
|
||||
if (!cv_gamesounds.value)
|
||||
return;
|
||||
|
||||
if (window_notinfocus && !cv_playsoundifunfocused.value)
|
||||
if (window_notinfocus && !(cv_bgaudio.value & 2))
|
||||
S_StopSounds();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,8 +41,7 @@ extern consvar_t cv_numChannels;
|
|||
extern consvar_t cv_gamedigimusic;
|
||||
|
||||
extern consvar_t cv_gamesounds;
|
||||
extern consvar_t cv_playmusicifunfocused;
|
||||
extern consvar_t cv_playsoundifunfocused;
|
||||
extern consvar_t cv_bgaudio;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
|
|
|||
|
|
@ -538,9 +538,9 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
|
|||
{
|
||||
// Tell game we lost focus, pause music
|
||||
window_notinfocus = true;
|
||||
if (!cv_playmusicifunfocused.value)
|
||||
if (!(cv_bgaudio.value & 1))
|
||||
I_SetMusicVolume(0);
|
||||
if (!cv_playsoundifunfocused.value)
|
||||
if (!(cv_bgaudio.value & 2))
|
||||
S_StopSounds();
|
||||
|
||||
if (!disable_mouse)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue