diff options
| author | 2023-05-08 18:12:28 -0300 | |
|---|---|---|
| committer | 2023-05-17 00:04:55 +0100 | |
| commit | 35ff516fc23f5bc90d30e9a5827ae492ca9e550a (patch) | |
| tree | fb96da5feaa79af02c5581f5ede691ff0e0d0953 | |
| parent | 7933acbabceba8fd826f6505bfeb3ae8baff0a5c (diff) | |
| download | sst-35ff516fc23f5bc90d30e9a5827ae492ca9e550a.tar.gz sst-35ff516fc23f5bc90d30e9a5827ae492ca9e550a.zip | |
Add snd_mute_losefocus backport
| -rw-r--r-- | compile.bat | 4 | ||||
| -rw-r--r-- | src/nomute.c | 108 | 
2 files changed, 111 insertions, 1 deletions
| diff --git a/compile.bat b/compile.bat index f48453e..c275cb0 100644 --- a/compile.bat +++ b/compile.bat @@ -73,6 +73,7 @@ setlocal DisableDelayedExpansion  :+ hook.c
  :+ kv.c
  :+ l4dwarp.c
 +:+ nomute.c
  :+ nosleep.c
  :+ portalcolours.c
  :+ rinput.c
 @@ -102,7 +103,8 @@ if "%dbg%"=="1" (  	set clibs=-lmsvcrt -lvcruntime -lucrt
  )
  %CC% -shared -flto %ldflags% -Wl,/IMPLIB:.build/sst.lib,/Brepro,/nodefaultlib ^
 --L.build %clibs% -lkernel32 -luser32 -ladvapi32 -lshlwapi -ld3d9 -ltier0 -lvstdlib -o sst.dll%objs% .build/dll.res || exit /b
 +-L.build %clibs% -lkernel32 -luser32 -ladvapi32 -lshlwapi -ld3d9 -ldsound ^
 +-ltier0 -lvstdlib -o sst.dll%objs% .build/dll.res || exit /b
  :: get rid of another useless file (can we just not create this???)
  del .build\sst.lib
 diff --git a/src/nomute.c b/src/nomute.c new file mode 100644 index 0000000..861062a --- /dev/null +++ b/src/nomute.c @@ -0,0 +1,108 @@ +/* + * Copyright © 2023 Willian Henrique <wsimanbrazil@yahoo.com.br> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +// TODO(linux): this is currently only built on Windows, but a linux +// implementation would be also useful for some games e.g. L4D2 + +#include "con_.h" +#include "errmsg.h" +#include "feature.h" +#include "hook.h" +#include "intdefs.h" +#include "mem.h" +#include "os.h" +#include "sst.h" +#include "x86.h" +#include "x86util.h" + +// these have to come after Windows.h (via os.h) and in this order +#include <mmeapi.h> +#include <dsound.h> + +FEATURE("inactive window audio control") + +DEF_CVAR_UNREG(snd_mute_losefocus, +		"Keep playing audio while tabbed out (SST reimplementation)", 1, +		CON_ARCHIVE | CON_HIDDEN) + +static IDirectSoundVtbl *ds_vt = 0; +static typeof(ds_vt->CreateSoundBuffer) orig_CreateSoundBuffer; +static con_cmdcbv1 snd_restart_cb = 0; + +// early init (via VDF) happens before config is loaded, and audio is set up +// after that, so we don't want to run snd_restart the first time the cvar is +// set, unless we were loaded later with plugin_load, in which case audio is +// already up and running and we'll want to restart it every time +bool skiprestart; +static void losefocuscb(struct con_var *v) { +	if (!skiprestart) snd_restart_cb(); +	skiprestart = false; +} + +static long __stdcall hook_CreateSoundBuffer(IDirectSound *this, +		const DSBUFFERDESC *desc, IDirectSoundBuffer **buff, IUnknown *unk) { +	if (!con_getvari(snd_mute_losefocus)) { +		((DSBUFFERDESC *)desc)->dwFlags |= DSBCAPS_GLOBALFOCUS; +	} +	return orig_CreateSoundBuffer(this, desc, buff, unk); +} + +PREINIT { +	if (con_findvar("snd_mute_losefocus")) return false; +	con_reg(snd_mute_losefocus); +	return true; +} + +INIT { +	skiprestart = sst_earlyloaded; // see above +	IDirectSound *ds_obj = 0; +	if (DirectSoundCreate(NULL, &ds_obj, NULL) != DS_OK) { +		errmsg_errorx("couldn't create IDirectSound instance"); +		return false; +	} + +	ds_vt = ds_obj->lpVtbl; +	if (!os_mprot(&ds_vt->CreateSoundBuffer, sizeof(void *), PAGE_READWRITE)) { +		errmsg_errorx("couldn't make virtual table writable"); +		return false; +	} + +	ds_obj->lpVtbl->Release(ds_obj); + +	orig_CreateSoundBuffer = ds_vt->CreateSoundBuffer; +	ds_vt->CreateSoundBuffer = &hook_CreateSoundBuffer; +	snd_mute_losefocus->base.flags &= ~CON_HIDDEN; + +	struct con_cmd *snd_restart = con_findcmd("snd_restart"); +	if (snd_restart) { +		snd_restart_cb = con_getcmdcbv1(snd_restart); +		snd_mute_losefocus->cb = &losefocuscb; +	} +	else { +		errmsg_warnx("couldn't find snd_restart"); +		errmsg_note("changing snd_mute_losefocus will require changing other " +				"audio settings or restarting the game with SST autoloaded in " +				"order to have an effect"); +	} + +	return true; +} + +END { +	ds_vt->CreateSoundBuffer = orig_CreateSoundBuffer; +} + +// vi: sw=4 ts=4 noet tw=80 cc=80 | 
