mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2025-01-19 16:00:56 +00:00
Add work around for lost OpenAL output devices.
The Intel display driver for Windows 10 destroys the DisplayPort audio device when the resolution changes. It's recreated at an unspecified later time. This is a work around to recover from that: * Check every frame if OpenAL is still connected. * If not, wait for 2.5 seconds, after that inject a 'snd_restart' into the command buffer. Samples send to the OpenAL backend while disconnected are skipped. This fixes #483.
This commit is contained in:
parent
9f00655e8e
commit
29d607c550
3 changed files with 86 additions and 0 deletions
|
@ -120,6 +120,20 @@ extern LPALDELETEFILTERS qalDeleteFilters;
|
||||||
*/
|
*/
|
||||||
void QAL_SoundInfo(void);
|
void QAL_SoundInfo(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checks if the output device is still connected. Returns true
|
||||||
|
* if it is, false otherwise. Should be called every frame, if
|
||||||
|
* disconnected a 'snd_restart' is injected after waiting for 50
|
||||||
|
* frame.
|
||||||
|
*
|
||||||
|
* This is mostly a work around for broken Sound driver. For
|
||||||
|
* example the _good_ Intel display driver for Windows 10
|
||||||
|
* destroys the DisplayPort sound device when the display
|
||||||
|
* resolution changes and recreates it after an unspecified
|
||||||
|
* amount of time...
|
||||||
|
*/
|
||||||
|
qboolean QAL_RecoverLostDevice();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Loads the OpenAL shared lib, creates
|
* Loads the OpenAL shared lib, creates
|
||||||
* a context and device handle.
|
* a context and device handle.
|
||||||
|
|
|
@ -620,6 +620,15 @@ AL_Update(void)
|
||||||
|
|
||||||
paintedtime = cls.realtime;
|
paintedtime = cls.realtime;
|
||||||
|
|
||||||
|
/* Do nothing if we aren't connected to a output device.
|
||||||
|
This is called after increasing paintedtime, because
|
||||||
|
the sound for the current frame needs to be skipped.
|
||||||
|
Otherwise sound and game will become asynchronous and
|
||||||
|
the paint buffer may overflow. */
|
||||||
|
if (!QAL_RecoverLostDevice()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* set listener (player) parameters */
|
/* set listener (player) parameters */
|
||||||
AL_CopyVector(listener_forward, orientation);
|
AL_CopyVector(listener_forward, orientation);
|
||||||
AL_CopyVector(listener_up, orientation + 3);
|
AL_CopyVector(listener_up, orientation + 3);
|
||||||
|
|
|
@ -44,6 +44,7 @@ static ALCcontext *context;
|
||||||
static ALCdevice *device;
|
static ALCdevice *device;
|
||||||
static cvar_t *al_device;
|
static cvar_t *al_device;
|
||||||
static cvar_t *al_driver;
|
static cvar_t *al_driver;
|
||||||
|
static qboolean hasAlcExtDisconnect;
|
||||||
static void *handle;
|
static void *handle;
|
||||||
|
|
||||||
/* Function pointers for OpenAL management */
|
/* Function pointers for OpenAL management */
|
||||||
|
@ -199,6 +200,61 @@ void QAL_SoundInfo()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checks if the output device is still connected. Returns true
|
||||||
|
* if it is, false otherwise. Should be called every frame, if
|
||||||
|
* disconnected a 'snd_restart' is injected after waiting for 2.5
|
||||||
|
* seconds.
|
||||||
|
*
|
||||||
|
* This is mostly a work around for broken Sound driver. For
|
||||||
|
* example the _good_ Intel display driver for Windows 10
|
||||||
|
* destroys the DisplayPort sound device when the display
|
||||||
|
* resolution changes and recreates it after an unspecified
|
||||||
|
* amount of time...
|
||||||
|
*/
|
||||||
|
qboolean
|
||||||
|
QAL_RecoverLostDevice()
|
||||||
|
{
|
||||||
|
static int discoCount = 0;
|
||||||
|
|
||||||
|
if (!hasAlcExtDisconnect)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (discoCount == 0)
|
||||||
|
{
|
||||||
|
ALCint connected;
|
||||||
|
qalcGetIntegerv(device, ALC_CONNECTED, 1, &connected);
|
||||||
|
|
||||||
|
if (!connected)
|
||||||
|
{
|
||||||
|
discoCount++;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Wait for about 2.5 seconds
|
||||||
|
before trying to reconnect. */
|
||||||
|
if (discoCount < (int)(Cvar_VariableValue("cl_maxfps") * 2.5))
|
||||||
|
{
|
||||||
|
discoCount++;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Cbuf_AddText("snd_restart\n");
|
||||||
|
discoCount = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Shuts OpenAL down, frees all context and
|
* Shuts OpenAL down, frees all context and
|
||||||
* device handles and unloads the shared lib.
|
* device handles and unloads the shared lib.
|
||||||
|
@ -510,6 +566,13 @@ QAL_Init()
|
||||||
QAL_SoundInfo();
|
QAL_SoundInfo();
|
||||||
Com_Printf("\n");
|
Com_Printf("\n");
|
||||||
|
|
||||||
|
/* Check extensions */
|
||||||
|
if (qalcIsExtensionPresent(device, "ALC_EXT_disconnect") != AL_FALSE)
|
||||||
|
{
|
||||||
|
hasAlcExtDisconnect = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue