Issue #26: runtime master volume (-/= keys, persisted)
The game audio plays hot with no in-game control -- testers couldn't hear voice chat without the Windows mixer (playtest night). The -/= keys now step the OpenAL listener gain (the master scale every source inherits) in 5% steps, clamped 0..150%, edge-detected in the per-frame poll with a foreground guard; the value persists to content\volume.cfg and reloads at boot (BT_AUDIO_VOLUME env still wins when set; default stays 0.6). README updated. Verified: volume.cfg 0.25 -> boot log "master gain=0.25"; key stepping needs a live focused session (awaiting live verification). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
44f7c39ee1
commit
4e0fcbf328
@@ -383,9 +383,22 @@ void
|
||||
ALCcontext *context = alcCreateContext(device,NULL);
|
||||
alcMakeContextCurrent(context);
|
||||
// Master volume: AL_GAIN on the listener scales EVERY source. Default 0.6
|
||||
// (the raw samples are hot); override with BT_AUDIO_VOLUME=<0.0..1.0+>.
|
||||
// (the raw samples are hot). Priority: BT_AUDIO_VOLUME env >
|
||||
// content\volume.cfg (written by the runtime -/+ keys, issue #26) > 0.6.
|
||||
float masterVol = 0.6f;
|
||||
{
|
||||
FILE *cfg = fopen("volume.cfg", "rt");
|
||||
if (cfg != NULL)
|
||||
{
|
||||
float f = -1.0f;
|
||||
if (fscanf(cfg, "%f", &f) == 1 && f >= 0.0f && f <= 1.5f)
|
||||
masterVol = f;
|
||||
fclose(cfg);
|
||||
}
|
||||
}
|
||||
if (const char *v = getenv("BT_AUDIO_VOLUME")) { float f = (float)atof(v); if (f >= 0.0f) masterVol = f; }
|
||||
extern float gBTMasterVolume;
|
||||
gBTMasterVolume = masterVol;
|
||||
alListenerf(AL_GAIN, masterVol);
|
||||
if (getenv("BT_AUDIO_LOG")) DEBUG_STREAM << "[audio] OpenAL device OPENED + context current; master gain=" << masterVol << "\n" << std::flush;
|
||||
// (task #50, AUDIO_FIDELITY F9/F11) EFX bridge: the authored lowpass
|
||||
@@ -1442,3 +1455,31 @@ void L4AudioRenderer::ReleaseSourceSet(SourceSet &sourceSet)
|
||||
#if defined(TRACE_AUDIO_RENDERER_DORMANT_SOURCES)
|
||||
BitTrace Audio_Renderer_Dormant_Sources("Audio Renderer Dormant Sources");
|
||||
#endif
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// Master-volume runtime control (issue #26, 2026-07-23). The pod had a
|
||||
// physical volume knob on the operator side; desktop players had NO way to
|
||||
// duck the (hot) game audio under voice chat short of the Windows mixer.
|
||||
// The -/= keys step the OpenAL listener gain (the master scale for every
|
||||
// source); the value persists in content\volume.cfg (CWD) and reloads at
|
||||
// the next boot (BT_AUDIO_VOLUME env still wins when set).
|
||||
//#############################################################################
|
||||
//
|
||||
float gBTMasterVolume = 0.6f;
|
||||
|
||||
void BTAudioMasterVolumeStep(int direction)
|
||||
{
|
||||
gBTMasterVolume += (direction > 0) ? 0.05f : -0.05f;
|
||||
if (gBTMasterVolume < 0.0f) gBTMasterVolume = 0.0f;
|
||||
if (gBTMasterVolume > 1.5f) gBTMasterVolume = 1.5f;
|
||||
alListenerf(AL_GAIN, gBTMasterVolume);
|
||||
FILE *cfg = fopen("volume.cfg", "wt");
|
||||
if (cfg != NULL)
|
||||
{
|
||||
fprintf(cfg, "%.2f\n", gBTMasterVolume);
|
||||
fclose(cfg);
|
||||
}
|
||||
DEBUG_STREAM << "[audio] master volume "
|
||||
<< (int)(gBTMasterVolume * 100.0f + 0.5f) << "%" << std::endl << std::flush;
|
||||
}
|
||||
|
||||
@@ -2746,6 +2746,24 @@ void
|
||||
// task #12: Generator1-4 actions assign the selected weapon
|
||||
// to Generator A..D; Reconnect toggles Manual/Auto.
|
||||
gBTGenSelKey = gBTInput.genSel;
|
||||
// issue #26: -/= step the master volume (edge-detected;
|
||||
// VK_OEM_MINUS/VK_OEM_PLUS, focus-guarded like all polls).
|
||||
{
|
||||
extern void BTAudioMasterVolumeStep(int direction);
|
||||
static int sVolDn = 0, sVolUp = 0;
|
||||
unsigned long fgpid = 0;
|
||||
if (GetForegroundWindow() != 0)
|
||||
GetWindowThreadProcessId(GetForegroundWindow(), &fgpid);
|
||||
int focused_vol = (fgpid == GetCurrentProcessId());
|
||||
int dn = focused_vol
|
||||
&& (GetAsyncKeyState(VK_OEM_MINUS) & 0x8000) != 0;
|
||||
int up = focused_vol
|
||||
&& (GetAsyncKeyState(VK_OEM_PLUS) & 0x8000) != 0;
|
||||
if (dn && !sVolDn) BTAudioMasterVolumeStep(-1);
|
||||
if (up && !sVolUp) BTAudioMasterVolumeStep(+1);
|
||||
sVolDn = dn;
|
||||
sVolUp = up;
|
||||
}
|
||||
// task #13: the Valve action cycles the coolant valve.
|
||||
gBTValveKey = gBTInput.valve;
|
||||
// Gitea #7: the Flush action HELD = the coolant MFD's
|
||||
|
||||
@@ -41,6 +41,7 @@ CONTROLS (keyboard):
|
||||
1 or Space ........... main trigger 2 ............. middle thumb
|
||||
3 or Ctrl ............ upper thumb (missiles) 4 ............ pinky
|
||||
V view | B look-behind | M control mode | N schematic | J/K/L MFD pages
|
||||
- / = ................ game volume down/up (saved between sessions)
|
||||
G (hold) + fire key .. regroup a weapon onto that trigger -- or hold a
|
||||
weapon panel's red PROGRAM button with the mouse and tap a fire key;
|
||||
the joystick diagram on the panel shows the binding live.
|
||||
|
||||
Reference in New Issue
Block a user