Skip to content

Commit

Permalink
- cleanup of sound system startup and menu handling:
Browse files Browse the repository at this point in the history
* added global functions that check whether FMod and OpenAL are present, without initializing the sound backend.
* make sound init code more fault tolerant. It will now try to switch between FMod and OpenAL if the currently active one cannot be found but the other one can.
* added 'ifoption' checks for sound backend to menu code.
* only show sound backends which are present and hide the options for the ones which are not.
  • Loading branch information
Christoph Oelckers committed Apr 26, 2015
1 parent 8e70a9b commit aecff68
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 30 deletions.
21 changes: 19 additions & 2 deletions src/menu/menudef.cpp
Expand Up @@ -49,6 +49,7 @@
#include "i_music.h"
#include "m_joy.h"
#include "gi.h"
#include "i_sound.h"

#include "optionmenuitems.h"

Expand Down Expand Up @@ -170,6 +171,14 @@ static bool CheckSkipOptionBlock(FScanner &sc)
filter = true;
#endif
}
else if (sc.Compare("OpenAL"))
{
filter |= IsOpenALPresent();
}
else if (sc.Compare("FModEx"))
{
filter |= IsFModExPresent();
}
}
while (sc.CheckString(","));
sc.MustGetStringName(")");
Expand Down Expand Up @@ -591,7 +600,11 @@ static void ParseOptionSettings(FScanner &sc)
while (!sc.CheckString("}"))
{
sc.MustGetString();
if (sc.Compare("ifgame"))
if (sc.Compare("else"))
{
SkipSubBlock(sc);
}
else if (sc.Compare("ifgame"))
{
if (!CheckSkipGameBlock(sc))
{
Expand Down Expand Up @@ -628,7 +641,11 @@ static void ParseOptionMenuBody(FScanner &sc, FOptionMenuDescriptor *desc)
while (!sc.CheckString("}"))
{
sc.MustGetString();
if (sc.Compare("ifgame"))
if (sc.Compare("else"))
{
SkipSubBlock(sc);
}
else if (sc.Compare("ifgame"))
{
if (!CheckSkipGameBlock(sc))
{
Expand Down
54 changes: 46 additions & 8 deletions src/sound/fmodsound.cpp
Expand Up @@ -671,14 +671,8 @@ bool FMODSoundRenderer::Init()

Printf("I_InitSound: Initializing FMOD\n");

HMODULE a = GetModuleHandle("fmodex.dll");

// Create a System object and initialize.
__try
{
result = FMOD::System_Create(&Sys);
}
__except(CheckException(GetExceptionCode()))
// This is just for safety. Normally this should never be called if FMod Ex cannot be found.
if (!IsFModExPresent())
{
Sys = NULL;
Printf(TEXTCOLOR_ORANGE"Failed to load fmodex"
Expand All @@ -688,6 +682,9 @@ bool FMODSoundRenderer::Init()
".dll\n");
return false;
}

// Create a System object and initialize.
result = FMOD::System_Create(&Sys);
if (result != FMOD_OK)
{
Sys = NULL;
Expand Down Expand Up @@ -3177,3 +3174,44 @@ FMOD_RESULT FMODSoundRenderer::SetSystemReverbProperties(const REVERB_PROPERTIES
}

#endif // NO_FMOD


//==========================================================================
//
// IsFModExPresent
//
// Check if FMod can be used
//
//==========================================================================

bool IsFModExPresent()
{
#ifdef NO_FMOD
return false;
#elif !defined _WIN32
return true; // on non-Windows we cannot delay load the library so it has to be present.
#else
static bool cached_result;
static bool done = false;

if (!done)
{
done = true;

FMOD::System *Sys;
FMOD_RESULT result;
__try
{
result = FMOD::System_Create(&Sys);
}
__except (CheckException(GetExceptionCode()))
{
// FMod could not be delay loaded
return false;
}
if (result == FMOD_OK) Sys->release();
cached_result = true;
}
return cached_result;
#endif
}
57 changes: 47 additions & 10 deletions src/sound/i_sound.cpp
Expand Up @@ -83,13 +83,15 @@ CVAR (Int, snd_buffersize, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR (String, snd_output, "default", CVAR_ARCHIVE|CVAR_GLOBALCONFIG)

#ifndef NO_FMOD
CVAR (String, snd_backend, "fmod", CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
#define DEF_BACKEND "fmod"
#elif !defined(NO_OPENAL)
CVAR (String, snd_backend, "openal", CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
#define DEF_BACKEND "openal"
#else
CVAR (String, snd_backend, "null", CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
#define DEF_BACKEND "null"
#endif

CVAR(String, snd_backend, DEF_BACKEND, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)

// killough 2/21/98: optionally use varying pitched sounds
CVAR (Bool, snd_pitched, false, CVAR_ARCHIVE)

Expand Down Expand Up @@ -256,23 +258,58 @@ void I_InitSound ()
nosound = !!Args->CheckParm ("-nosound");
nosfx = !!Args->CheckParm ("-nosfx");

GSnd = NULL;
if (nosound)
{
GSnd = new NullSoundRenderer;
I_InitMusic ();
return;
}

if(stricmp(snd_backend, "null") == 0)
// This has been extended to allow falling back from FMod to OpenAL and vice versa if the currently active sound system cannot be found.
if (stricmp(snd_backend, "null") == 0)
{
GSnd = new NullSoundRenderer;
#ifndef NO_FMOD
}
else if(stricmp(snd_backend, "fmod") == 0)
GSnd = new FMODSoundRenderer;
#endif
#ifndef NO_OPENAL
{
#ifndef NO_FMOD
if (IsFModExPresent())
{
GSnd = new FMODSoundRenderer;
}
#endif
#ifndef NO_OPENAL
if ((!GSnd || !GSnd->IsValid()) && IsOpenALPresent())
{
Printf (TEXTCOLOR_RED"FMod Ex Sound init failed. Trying OpenAL.\n");
GSnd = new OpenALSoundRenderer;
snd_backend = "openal";
}
#endif
}
else if(stricmp(snd_backend, "openal") == 0)
GSnd = new OpenALSoundRenderer;
#endif
{
#ifndef NO_OPENAL
if (IsOpenALPresent())
{
GSnd = new OpenALSoundRenderer;
}
#endif
#ifndef NO_FMOD
if ((!GSnd || !GSnd->IsValid()) && IsFModExPresent())
{
Printf (TEXTCOLOR_RED"OpenAL Sound init failed. Trying FMod Ex.\n");
GSnd = new FMODSoundRenderer;
snd_backend = "fmod";
}
#endif
}
else
{
Printf (TEXTCOLOR_RED"%s: Unknown sound system specified\n", *snd_backend);
snd_backend = "null";
}
if (!GSnd || !GSnd->IsValid ())
{
I_CloseSound();
Expand Down
3 changes: 3 additions & 0 deletions src/sound/i_sound.h
Expand Up @@ -175,4 +175,7 @@ FISoundChannel *S_GetChannel(void *syschan);

extern ReverbContainer *DefaultEnvironments[26];

bool IsFModExPresent();
bool IsOpenALPresent();

#endif
39 changes: 33 additions & 6 deletions src/sound/oalsound.cpp
Expand Up @@ -59,14 +59,44 @@ CVAR (String, snd_aldevice, "Default", CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR (Bool, snd_efx, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)


bool IsOpenALPresent()
{
#ifdef NO_OPENAL
return false;
#elif !defined _WIN32
return true; // on non-Windows we cannot delay load the library so it has to be present.
#else
static bool cached_result;
static bool done = false;

if (!done)
{
done = true;

__try
{
// just call one function from the API to force loading the DLL
alcGetError(NULL);
}
__except (CheckException(GetExceptionCode()))
{
// FMod could not be delay loaded
return false;
}
cached_result = true;
}
return cached_result;
#endif
}

void I_BuildALDeviceList(FOptionValues *opt)
{
opt->mValues.Resize(1);
opt->mValues[0].TextValue = "Default";
opt->mValues[0].Text = "Default";

#ifndef NO_OPENAL
__try
if (IsOpenALPresent())
{
const ALCchar *names = (alcIsExtensionPresent(NULL, "ALC_ENUMERATE_ALL_EXT") ?
alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER) :
Expand All @@ -82,9 +112,6 @@ void I_BuildALDeviceList(FOptionValues *opt)
names += strlen(names) + 1;
}
}
__except (CheckException(GetExceptionCode()))
{
}
#endif
}

Expand Down Expand Up @@ -601,7 +628,7 @@ static float GetRolloff(const FRolloffInfo *rolloff, float distance)
ALCdevice *OpenALSoundRenderer::InitDevice()
{
ALCdevice *device = NULL;
__try
if (IsOpenALPresent())
{
if(strcmp(snd_aldevice, "Default") != 0)
{
Expand All @@ -619,7 +646,7 @@ ALCdevice *OpenALSoundRenderer::InitDevice()
}
}
}
__except(CheckException(GetExceptionCode()))
else
{
Printf(TEXTCOLOR_ORANGE"Failed to load openal32.dll\n");
}
Expand Down
44 changes: 40 additions & 4 deletions wadsrc/static/menudef.txt
Expand Up @@ -1450,11 +1450,22 @@ OptionString Resamplers

OptionString SoundBackends
{
"fmod", "FMOD"
"fmod", "FMOD Ex"
"openal", "OpenAL"
"null", "No Sound"
}

OptionString SoundBackendsFModOnly
{
"fmod", "FMOD Ex"
"null", "No Sound"
}

OptionString SoundBackendsOpenALOnly
{
"openal", "OpenAL"
"null", "No Sound"
}

OptionMenu FMODSoundItems
{
Expand Down Expand Up @@ -1507,9 +1518,34 @@ OptionMenu SoundOptions
Option "Randomize pitches", "snd_pitched", "OnOff"
Slider "Sound channels", "snd_channels", 8, 256, 8, 0
StaticText " "
Option "Sound backend", "snd_backend", "SoundBackends"
Submenu "FMOD options", "FMODSoundItems"
Submenu "OpenAL options", "OpenALSoundItems"

ifoption(fmodex)
{
ifoption(openal)
{
Option "Sound backend", "snd_backend", "SoundBackends"
}
else
{
Option "Sound backend", "snd_backend", "SoundBackendsFModOnly"
}
}
else
{
ifoption(openal)
{
Option "Sound backend", "snd_backend", "SoundBackendsOpenALOnly"
}
}

ifoption(fmodex)
{
Submenu "FMOD options", "FMODSoundItems"
}
ifoption(openal)
{
Submenu "OpenAL options", "OpenALSoundItems"
}
StaticText " "
Command "Restart sound", "snd_reset"

Expand Down

0 comments on commit aecff68

Please sign in to comment.