Initial commit
This commit is contained in:
269
Torque/SDK/engine/platformX86UNIX/x86UNIXOpenAL.cc
Normal file
269
Torque/SDK/engine/platformX86UNIX/x86UNIXOpenAL.cc
Normal file
@@ -0,0 +1,269 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#include "platformX86UNIX/platformX86UNIX.h"
|
||||
#include "console/console.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include <al/altypes.h>
|
||||
#include <al/alctypes.h>
|
||||
#define INITGUID
|
||||
#include <al/eaxtypes.h>
|
||||
|
||||
|
||||
// Define the OpenAL and Extension Stub functions
|
||||
#define AL_FUNCTION(fn_return, fn_name, fn_args, fn_value) fn_return stub_##fn_name fn_args{ fn_value }
|
||||
#include <al/al_func.h>
|
||||
#include <al/alc_func.h>
|
||||
#include <al/eax_func.h>
|
||||
#undef AL_FUNCTION
|
||||
|
||||
|
||||
// Declare the OpenAL and Extension Function pointers
|
||||
// And initialize them to the stub functions
|
||||
#define AL_FUNCTION(fn_return,fn_name,fn_args, fn_value) fn_return (*fn_name)fn_args = stub_##fn_name;
|
||||
#include <al/al_func.h>
|
||||
#include <al/alc_func.h>
|
||||
#include <al/eax_func.h>
|
||||
#undef AL_FUNCTION
|
||||
|
||||
// Declarations for the "emulated" functions (al functions that don't
|
||||
// exist in the loki openal implementation)
|
||||
ALboolean emu_alGetBoolean(ALenum param);
|
||||
ALint emu_alGetInteger(ALenum param);
|
||||
ALfloat emu_alGetFloat(ALenum param);
|
||||
ALdouble emu_alGetDouble(ALenum param);
|
||||
void emu_alListeneri( ALenum param, ALint value );
|
||||
void emu_alGetListener3f(ALenum pname,ALfloat *v1,ALfloat *v2,ALfloat *v3);
|
||||
ALCdevice* emu_alcGetContextsDevice(ALCcontext *context);
|
||||
|
||||
static void *dlHandle = NULL;
|
||||
static char* dlError = "no error";
|
||||
|
||||
/*! Get an "emulated" function address and bind it to the function pointer
|
||||
*/
|
||||
static bool bindEmulatedFunction(void *&fnAddress, const char *name)
|
||||
{
|
||||
fnAddress = NULL;
|
||||
|
||||
if (dStrcmp(name, "alGetBoolean")==0)
|
||||
fnAddress = (void*)&emu_alGetBoolean;
|
||||
else if (dStrcmp(name, "alGetInteger")==0)
|
||||
fnAddress = (void*)&emu_alGetInteger;
|
||||
else if (dStrcmp(name, "alGetFloat")==0)
|
||||
fnAddress = (void*)&emu_alGetFloat;
|
||||
else if (dStrcmp(name, "alGetDouble")==0)
|
||||
fnAddress = (void*)&emu_alGetDouble;
|
||||
else if (dStrcmp(name, "alListeneri")==0)
|
||||
fnAddress = (void*)&emu_alListeneri;
|
||||
else if (dStrcmp(name, "alGetListener3f")==0)
|
||||
fnAddress = (void*)&emu_alGetListener3f;
|
||||
else if (dStrcmp(name, "alcGetContextsDevice")==0)
|
||||
fnAddress = (void*)&emu_alcGetContextsDevice;
|
||||
|
||||
return fnAddress != NULL;
|
||||
}
|
||||
|
||||
/*! Get a function address from the OpenAL DLL and bind it to the
|
||||
* function pointer
|
||||
*/
|
||||
static bool bindFunction( void *&fnAddress, const char *name )
|
||||
{
|
||||
fnAddress = dlsym(dlHandle, name);
|
||||
if( !fnAddress )
|
||||
if (bindEmulatedFunction(fnAddress, name))
|
||||
Con::warnf(ConsoleLogEntry::General, " Missing OpenAL function '%s', using emulated function", name);
|
||||
else
|
||||
Con::errorf(ConsoleLogEntry::General, " Missing OpenAL function '%s'", name);
|
||||
return (fnAddress != NULL);
|
||||
}
|
||||
|
||||
/*! Get a function address for an OpenAL extension function and bind it
|
||||
* to it's function pointer
|
||||
*/
|
||||
static bool bindExtensionFunction( void *&fnAddress, const char *name )
|
||||
{
|
||||
fnAddress = alGetProcAddress( (ALubyte*)name );
|
||||
if( !fnAddress )
|
||||
Con::errorf(ConsoleLogEntry::General, " Missing OpenAL Extension function '%s'", name);
|
||||
return (fnAddress != NULL);
|
||||
}
|
||||
|
||||
/*! Bind the functions in the OpenAL DLL to the al interface functions
|
||||
*/
|
||||
static bool bindOpenALFunctions()
|
||||
{
|
||||
bool result = true;
|
||||
#define AL_FUNCTION(fn_return, fn_name, fn_args, fn_value) result &= bindFunction( *(void**)&fn_name, #fn_name);
|
||||
#include <al/al_func.h>
|
||||
#include <al/alc_func.h>
|
||||
#undef AL_FUNCTION
|
||||
return result;
|
||||
}
|
||||
|
||||
/*! Bind the stub functions to the al interface functions
|
||||
*/
|
||||
static void unbindOpenALFunctions()
|
||||
{
|
||||
#define AL_FUNCTION(fn_return, fn_name, fn_args, fn_value) fn_name = stub_##fn_name;
|
||||
#include <al/al_func.h>
|
||||
#include <al/alc_func.h>
|
||||
#include <al/eax_func.h>
|
||||
#undef AL_FUNCTION
|
||||
}
|
||||
|
||||
/*! Bind the EAX Extension functions to the EAX interface functions
|
||||
*/
|
||||
static bool bindEAXFunctions()
|
||||
{
|
||||
bool result = true;
|
||||
#define AL_FUNCTION(fn_return, fn_name, fn_args, fn_value) result &= bindExtensionFunction( *(void**)&fn_name, #fn_name);
|
||||
#include <al/eax_func.h>
|
||||
#undef AL_FUNCTION
|
||||
return result;
|
||||
}
|
||||
|
||||
// Definitions for the emulated functions
|
||||
ALboolean emu_alGetBoolean(ALenum param)
|
||||
{
|
||||
ALboolean alboolean;
|
||||
alGetBooleanv(param, &alboolean);
|
||||
return alboolean;
|
||||
}
|
||||
|
||||
ALint emu_alGetInteger(ALenum param)
|
||||
{
|
||||
ALint alint;
|
||||
alGetIntegerv(param, &alint);
|
||||
return alint;
|
||||
}
|
||||
|
||||
ALfloat emu_alGetFloat(ALenum param)
|
||||
{
|
||||
ALfloat alfloat;
|
||||
alGetFloatv(param, &alfloat);
|
||||
return alfloat;
|
||||
}
|
||||
|
||||
ALdouble emu_alGetDouble(ALenum param)
|
||||
{
|
||||
ALdouble aldouble;
|
||||
alGetDoublev(param, &aldouble);
|
||||
return aldouble;
|
||||
}
|
||||
|
||||
void emu_alGetListener3f(ALenum pname,ALfloat *v0,ALfloat *v1,ALfloat *v2)
|
||||
{
|
||||
ALfloat ptArray[10];
|
||||
ptArray[0] = *v0;
|
||||
ptArray[1] = *v1;
|
||||
ptArray[2] = *v2;
|
||||
alGetListenerfv(pname, ptArray);
|
||||
*v0 = ptArray[0];
|
||||
*v1 = ptArray[1];
|
||||
*v2 = ptArray[2];
|
||||
}
|
||||
|
||||
void emu_alListeneri( ALenum param, ALint value )
|
||||
{
|
||||
alListenerf(param, static_cast<ALfloat>(value));
|
||||
}
|
||||
|
||||
ALCdevice* emu_alcGetContextsDevice(ALCcontext *context)
|
||||
{
|
||||
// this function isn't emulated
|
||||
AssertFatal(false, "alcGetContextsDevice is not available");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
namespace Audio
|
||||
{
|
||||
|
||||
/*! Shutdown and Unload the OpenAL DLL
|
||||
*/
|
||||
void OpenALDLLShutdown()
|
||||
{
|
||||
if (dlHandle != NULL)
|
||||
{
|
||||
dlclose(dlHandle);
|
||||
// FreeBSD didn't like that const dlerror() was returning.
|
||||
if ((dlError = (char *)dlerror()) != NULL)
|
||||
Con::errorf(ConsoleLogEntry::General, " Error unloading OpenAL Library: %s", dlError);
|
||||
}
|
||||
dlHandle = NULL;
|
||||
|
||||
unbindOpenALFunctions();
|
||||
}
|
||||
|
||||
/*! Dynamically Loads the OpenAL DLL if present and binds all the functions.
|
||||
* If there is no DLL or an unexpected error occurs binding functions the
|
||||
* stub functions are automatically bound.
|
||||
*/
|
||||
bool OpenALDLLInit()
|
||||
{
|
||||
OpenALDLLShutdown();
|
||||
|
||||
const char* libName = "libopenal.so";
|
||||
|
||||
// these are relative to the current working directory
|
||||
const char* searchPath[] = {
|
||||
"lib",
|
||||
"tplib", // superceeded by "lib", here for backass compatibility
|
||||
"", // i.e.: current working directory
|
||||
NULL // this must be last
|
||||
};
|
||||
|
||||
char openalPath[4096];
|
||||
for (int i = 0; searchPath[i] != NULL; ++i)
|
||||
{
|
||||
dSprintf(openalPath, sizeof(openalPath), "%s/%s/%s",
|
||||
Platform::getWorkingDirectory(),
|
||||
searchPath[i],
|
||||
libName);
|
||||
|
||||
Con::printf(" Searching for OpenAl at location : %s", openalPath);
|
||||
dlHandle = dlopen(openalPath, RTLD_NOW);
|
||||
if (dlHandle != NULL)
|
||||
{
|
||||
// found it
|
||||
Con::printf(" Loading OpenAL: %s", openalPath);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dlHandle == NULL)
|
||||
{
|
||||
// couldn't find it in our searchPath, try the system path
|
||||
dlHandle = dlopen(libName, RTLD_NOW);
|
||||
if (dlHandle != NULL)
|
||||
Con::printf(" Loading OpenAL from system (dlopen) path");
|
||||
}
|
||||
|
||||
if (dlHandle != NULL)
|
||||
{
|
||||
// if the DLL loaded bind the OpenAL function pointers
|
||||
if(bindOpenALFunctions())
|
||||
{
|
||||
// if EAX is available bind it's function pointers
|
||||
if (alIsExtensionPresent((ALubyte*)"EAX" ))
|
||||
bindEAXFunctions();
|
||||
return(true);
|
||||
}
|
||||
|
||||
// an error occured, shutdown
|
||||
OpenALDLLShutdown();
|
||||
}
|
||||
else
|
||||
{
|
||||
Con::errorf(ConsoleLogEntry::General, " Error loading OpenAL Library: %s", dlerror());
|
||||
}
|
||||
return(false);
|
||||
}
|
||||
|
||||
} // end namespace Audio
|
||||
|
||||
Reference in New Issue
Block a user