From 5ac8a26814bb43c5e91ab77af9a2e546b0ef50e4 Mon Sep 17 00:00:00 2001
From: James R <justsomejames2@gmail.com>
Date: Mon, 11 Mar 2019 14:57:11 -0700
Subject: [PATCH] Miscellaneous window de-focus options

Music pausing is now optional.
Sounds may be paused--on by default.
The game itself being paused in off-line mode is now optional.

(showfocuslost now loads from config.)
---
 src/d_netcmd.c    |  2 ++
 src/g_game.c      |  2 ++
 src/g_game.h      |  2 ++
 src/m_menu.c      | 42 +++++++++++++-------------------
 src/m_menu.h      |  1 +
 src/p_user.c      |  2 +-
 src/s_sound.c     | 62 +++++++++++++++++++++++++++++++++++++++++------
 src/s_sound.h     |  6 +++++
 src/sdl/i_video.c |  9 ++++++-
 9 files changed, 94 insertions(+), 34 deletions(-)

diff --git a/src/d_netcmd.c b/src/d_netcmd.c
index 4fb309600..bbe6b28d2 100644
--- a/src/d_netcmd.c
+++ b/src/d_netcmd.c
@@ -736,6 +736,8 @@ void D_RegisterClientCommands(void)
 	CV_RegisterVar(&cv_chasefreelook);
 	CV_RegisterVar(&cv_chasefreelook2);
 	CV_RegisterVar(&cv_tutorialprompt);
+	CV_RegisterVar(&cv_showfocuslost);
+	CV_RegisterVar(&cv_pauseifunfocused);
 
 	// g_input.c
 	CV_RegisterVar(&cv_sideaxis);
diff --git a/src/g_game.c b/src/g_game.c
index 6c31ce9e3..92b8de96e 100644
--- a/src/g_game.c
+++ b/src/g_game.c
@@ -361,6 +361,8 @@ consvar_t cv_chatbacktint = {"chatbacktint", "On", CV_SAVE, CV_OnOff, NULL, 0, N
 static CV_PossibleValue_t consolechat_cons_t[] = {{0, "Window"}, {1, "Console"}, {2, "Window (Hidden)"}, {0, NULL}};
 consvar_t cv_consolechat = {"chatmode", "Window", CV_SAVE, consolechat_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
 
+// Pause game upon window losing focus
+consvar_t cv_pauseifunfocused = {"pauseifunfocused", "Yes", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
 
 consvar_t cv_crosshair = {"crosshair", "Cross", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
 consvar_t cv_crosshair2 = {"crosshair2", "Cross", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
diff --git a/src/g_game.h b/src/g_game.h
index df1301dd7..198cbc396 100644
--- a/src/g_game.h
+++ b/src/g_game.h
@@ -59,6 +59,8 @@ extern boolean pausebreakkey;
 
 extern boolean promptactive;
 
+extern consvar_t cv_pauseifunfocused;
+
 // used in game menu
 extern consvar_t cv_tutorialprompt;
 extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatbacktint, cv_chatspamprotection, cv_compactscoreboard;
diff --git a/src/m_menu.c b/src/m_menu.c
index 8d3dad741..13e5bfc4f 100644
--- a/src/m_menu.c
+++ b/src/m_menu.c
@@ -1326,22 +1326,25 @@ static menuitem_t OP_OpenGLColorMenu[] =
 
 static menuitem_t OP_SoundOptionsMenu[] =
 {
-	{IT_HEADER, NULL, "Game Audio", NULL, 0}, // 0 // ScrollMenu offsets
-	{IT_STRING | IT_CVAR,  NULL,  "Sound Effects", &cv_gamesounds, 13}, // 6
-	{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Sound Volume", &cv_soundvolume, 23}, // 11
+	{IT_HEADER, NULL, "Game Audio", NULL, 0},
+	{IT_STRING | IT_CVAR,  NULL,  "Sound Effects", &cv_gamesounds, 6},
+	{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Sound Volume", &cv_soundvolume, 11},
 
-	{IT_STRING | IT_CVAR,  NULL,  "Digital Music", &cv_gamedigimusic, 43}, // 21
-	{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Digital Music Volume", &cv_digmusicvolume,  53}, // 26
+	{IT_STRING | IT_CVAR,  NULL,  "Digital Music", &cv_gamedigimusic, 21},
+	{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Digital Music Volume", &cv_digmusicvolume,  26},
 
-	{IT_STRING | IT_CVAR,  NULL,  "MIDI Music", &cv_gamemidimusic, 73}, // 36
-	{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "MIDI Music Volume", &cv_midimusicvolume, 83}, // 41
+	{IT_STRING | IT_CVAR,  NULL,  "MIDI Music", &cv_gamemidimusic, 36},
+	{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "MIDI Music Volume", &cv_midimusicvolume, 41},
 
-	{IT_HEADER, NULL, "Accessibility", NULL, 103}, // 50
-	{IT_STRING | IT_CVAR, NULL, "Closed Captioning", &cv_closedcaptioning, 115}, // 56
-	{IT_STRING | IT_CVAR, NULL, "Reset Music Upon Dying", &cv_resetmusic, 125}, // 62
+	{IT_HEADER, NULL, "Accessibility", NULL, 50},
+	{IT_STRING | IT_CVAR, NULL, "Closed Captioning", &cv_closedcaptioning, 56},
+	{IT_STRING | IT_CVAR, NULL, "Reset Music Upon Dying", &cv_resetmusic, 61},
+
+	{IT_STRING | IT_CVAR, NULL, "Play Music While Unfocused", &cv_playmusicifunfocused, 71},
+	{IT_STRING | IT_CVAR, NULL, "Play SFX While Unfocused", &cv_playsoundifunfocused, 76},
 
 #ifdef HAVE_MIXERX
-	{IT_STRING | IT_SUBMENU, NULL, "Advanced Settings...", &OP_SoundAdvancedDef, 143},
+	{IT_STRING | IT_SUBMENU, NULL, "Advanced Settings...", &OP_SoundAdvancedDef, 86},
 #endif
 };
 
@@ -1964,18 +1967,9 @@ menu_t OP_ColorOptionsDef =
 	0,
 	NULL
 };
-menu_t OP_SoundOptionsDef =
-{
-	MN_OP_MAIN + (MN_OP_SOUND << 6),
-	"M_SOUND",
-	sizeof (OP_SoundOptionsMenu)/sizeof (menuitem_t),
-	&OP_MainDef,
-	OP_SoundOptionsMenu,
-	M_DrawGenericMenu,
-	30, 30,
-	0,
-	NULL
-};
+menu_t OP_SoundOptionsDef = DEFAULTSCROLLMENUSTYLE(
+		MN_OP_MAIN + (MN_OP_SOUND << 6),
+		"M_SOUND", OP_SoundOptionsMenu, &OP_MainDef, 30, 30);
 #ifdef HAVE_MIXERX
 menu_t OP_SoundAdvancedDef = DEFAULTMENUSTYLE(MN_OP_MAIN + (MN_OP_SOUND << 6), "M_SOUND", OP_SoundAdvancedMenu, &OP_SoundOptionsDef, 30, 30);
 #endif
@@ -3550,8 +3544,6 @@ void M_Init(void)
 {
 	int i;
 
-	CV_RegisterVar(&cv_showfocuslost);
-
 	CV_RegisterVar(&cv_nextmap);
 	CV_RegisterVar(&cv_newgametype);
 	CV_RegisterVar(&cv_chooseskin);
diff --git a/src/m_menu.h b/src/m_menu.h
index 05962d2b1..d568a1b53 100644
--- a/src/m_menu.h
+++ b/src/m_menu.h
@@ -374,6 +374,7 @@ typedef struct
 
 extern description_t description[MAXSKINS];
 
+extern consvar_t cv_showfocuslost;
 extern consvar_t cv_newgametype, cv_nextmap, cv_chooseskin, cv_serversort;
 extern CV_PossibleValue_t gametype_cons_t[];
 
diff --git a/src/p_user.c b/src/p_user.c
index 3f4d08222..c65d7b6cc 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -191,7 +191,7 @@ boolean P_AutoPause(void)
 	if (netgame || modeattacking || gamestate == GS_TITLESCREEN)
 		return false;
 
-	return (menuactive || window_notinfocus);
+	return (menuactive || ( window_notinfocus && cv_pauseifunfocused.value ));
 }
 
 //
diff --git a/src/s_sound.c b/src/s_sound.c
index 1a719d972..e68a25ec9 100644
--- a/src/s_sound.c
+++ b/src/s_sound.c
@@ -60,6 +60,9 @@ static void GameMIDIMusic_OnChange(void);
 static void GameSounds_OnChange(void);
 static void GameDigiMusic_OnChange(void);
 
+static void PlayMusicIfUnfocused_OnChange(void);
+static void PlaySoundIfUnfocused_OnChange(void);
+
 static void ModFilter_OnChange(void);
 
 static lumpnum_t S_GetMusicLumpNum(const char *mname);
@@ -117,6 +120,9 @@ consvar_t cv_gamedigimusic = {"digimusic", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_O
 consvar_t cv_gamemidimusic = {"midimusic", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameMIDIMusic_OnChange, 0, NULL, NULL, 0, 0, NULL};
 consvar_t cv_gamesounds = {"sounds", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameSounds_OnChange, 0, NULL, NULL, 0, 0, NULL};
 
+consvar_t cv_playmusicifunfocused = {"playmusicifunfocused",  "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, PlayMusicIfUnfocused_OnChange, 0, NULL, NULL, 0, 0, NULL};
+consvar_t cv_playsoundifunfocused = {"playsoundsifunfocused", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, PlaySoundIfUnfocused_OnChange, 0, NULL, NULL, 0, 0, NULL};
+
 #ifdef HAVE_OPENMPT
 static CV_PossibleValue_t interpolationfilter_cons_t[] = {{0, "Default"}, {1, "None"}, {2, "Linear"}, {4, "Cubic"}, {8, "Windowed sinc"}, {0, NULL}};
 consvar_t cv_modfilter = {"modfilter", "0", CV_SAVE|CV_CALL, interpolationfilter_cons_t, ModFilter_OnChange, 0, NULL, NULL, 0, 0, NULL};
@@ -290,6 +296,9 @@ void S_RegisterSoundStuff(void)
 	CV_RegisterVar(&cv_miditimiditypath);
 #endif
 
+	CV_RegisterVar(&cv_playmusicifunfocused);
+	CV_RegisterVar(&cv_playsoundifunfocused);
+
 	COM_AddCommand("tunes", Command_Tunes_f);
 	COM_AddCommand("restartaudio", Command_RestartAudio_f);
 
@@ -2018,6 +2027,24 @@ void S_ResumeAudio(void)
 	S_AdjustMusicStackTics();
 }
 
+void S_DisableSound(void)
+{
+	if (sound_started && !sound_disabled)
+	{
+		sound_disabled = true;
+		S_StopSounds();
+	}
+}
+
+void S_EnableSound(void)
+{
+	if (sound_started && sound_disabled)
+	{
+		sound_disabled = false;
+		S_InitSfxChannels(cv_soundvolume.value);
+	}
+}
+
 void S_SetMusicVolume(INT32 digvolume, INT32 seqvolume)
 {
 	if (digvolume < 0)
@@ -2207,15 +2234,11 @@ void GameSounds_OnChange(void)
 
 	if (sound_disabled)
 	{
-		sound_disabled = false;
-		S_InitSfxChannels(cv_soundvolume.value);
-		S_StartSound(NULL, sfx_strpst);
+		if (!( cv_playsoundifunfocused.value && window_notinfocus ))
+			S_EnableSound();
 	}
 	else
-	{
-		sound_disabled = true;
-		S_StopSounds();
-	}
+		S_DisableSound();
 }
 
 void GameDigiMusic_OnChange(void)
@@ -2308,3 +2331,28 @@ void ModFilter_OnChange(void)
 		openmpt_module_set_render_param(openmpt_mhandle, OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH, cv_modfilter.value);
 }
 #endif
+
+static void PlayMusicIfUnfocused_OnChange(void)
+{
+	if (window_notinfocus)
+	{
+		if (cv_playmusicifunfocused.value)
+			S_PauseAudio();
+		else
+			S_ResumeAudio();
+	}
+}
+
+static void PlaySoundIfUnfocused_OnChange(void)
+{
+	if (!cv_gamesounds.value)
+		return;
+
+	if (window_notinfocus)
+	{
+		if (cv_playsoundifunfocused.value)
+			S_DisableSound();
+		else
+			S_EnableSound();
+	}
+}
diff --git a/src/s_sound.h b/src/s_sound.h
index 48128527c..f4a986585 100644
--- a/src/s_sound.h
+++ b/src/s_sound.h
@@ -44,6 +44,8 @@ extern consvar_t cv_resetmusicbyheader;
 extern consvar_t cv_gamedigimusic;
 extern consvar_t cv_gamemidimusic;
 extern consvar_t cv_gamesounds;
+extern consvar_t cv_playmusicifunfocused;
+extern consvar_t cv_playsoundifunfocused;
 
 #ifdef HAVE_OPENMPT
 extern consvar_t cv_modfilter;
@@ -244,6 +246,10 @@ void S_StopMusic(void);
 void S_PauseAudio(void);
 void S_ResumeAudio(void);
 
+// Enable and disable sound effects
+void S_EnableSound(void);
+void S_DisableSound(void);
+
 //
 // Music Fading
 //
diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c
index b90b5c868..f760e79bd 100644
--- a/src/sdl/i_video.c
+++ b/src/sdl/i_video.c
@@ -580,7 +580,11 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
 		// Tell game we got focus back, resume music if necessary
 		window_notinfocus = false;
 		if (!paused)
+		{
 			S_ResumeAudio(); //resume it
+			if (cv_gamesounds.value)
+				S_EnableSound();
+		}
 
 		if (!firsttimeonmouse)
 		{
@@ -595,7 +599,10 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
 	{
 		// Tell game we lost focus, pause music
 		window_notinfocus = true;
-		S_PauseAudio();
+		if (!cv_playmusicifunfocused.value)
+			S_PauseAudio();
+		if (!cv_playsoundifunfocused.value)
+			S_DisableSound();
 
 		if (!disable_mouse)
 		{