x86UNIXOpenAL.client.cpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #if 0
  23. #include "platformX86UNIX/platformX86UNIX.h"
  24. #include "console/console.h"
  25. #include <dlfcn.h>
  26. #include <al/altypes.h>
  27. #include <al/alctypes.h>
  28. #define INITGUID
  29. #include <al/eaxtypes.h>
  30. // Define the OpenAL and Extension Stub functions
  31. #define AL_FUNCTION(fn_return, fn_name, fn_args, fn_value) fn_return stub_##fn_name fn_args{ fn_value }
  32. #include <al/al_func.h>
  33. #include <al/alc_func.h>
  34. #include <al/eax_func.h>
  35. #undef AL_FUNCTION
  36. // Declare the OpenAL and Extension Function pointers
  37. // And initialize them to the stub functions
  38. #define AL_FUNCTION(fn_return,fn_name,fn_args, fn_value) fn_return (*fn_name)fn_args = stub_##fn_name;
  39. #include <al/al_func.h>
  40. #include <al/alc_func.h>
  41. #include <al/eax_func.h>
  42. #undef AL_FUNCTION
  43. // Declarations for the "emulated" functions (al functions that don't
  44. // exist in the loki openal implementation)
  45. ALboolean emu_alGetBoolean(ALenum param);
  46. ALint emu_alGetInteger(ALenum param);
  47. ALfloat emu_alGetFloat(ALenum param);
  48. ALdouble emu_alGetDouble(ALenum param);
  49. void emu_alListeneri( ALenum param, ALint value );
  50. void emu_alGetListener3f(ALenum pname,ALfloat *v1,ALfloat *v2,ALfloat *v3);
  51. ALCdevice* emu_alcGetContextsDevice(ALCcontext *context);
  52. static void *dlHandle = NULL;
  53. static char* dlError = "no error";
  54. /*! Get an "emulated" function address and bind it to the function pointer
  55. */
  56. static bool bindEmulatedFunction(void *&fnAddress, const char *name)
  57. {
  58. fnAddress = NULL;
  59. if (dStrcmp(name, "alGetBoolean")==0)
  60. fnAddress = (void*)&emu_alGetBoolean;
  61. else if (dStrcmp(name, "alGetInteger")==0)
  62. fnAddress = (void*)&emu_alGetInteger;
  63. else if (dStrcmp(name, "alGetFloat")==0)
  64. fnAddress = (void*)&emu_alGetFloat;
  65. else if (dStrcmp(name, "alGetDouble")==0)
  66. fnAddress = (void*)&emu_alGetDouble;
  67. else if (dStrcmp(name, "alListeneri")==0)
  68. fnAddress = (void*)&emu_alListeneri;
  69. else if (dStrcmp(name, "alGetListener3f")==0)
  70. fnAddress = (void*)&emu_alGetListener3f;
  71. else if (dStrcmp(name, "alcGetContextsDevice")==0)
  72. fnAddress = (void*)&emu_alcGetContextsDevice;
  73. return fnAddress != NULL;
  74. }
  75. /*! Get a function address from the OpenAL DLL and bind it to the
  76. * function pointer
  77. */
  78. static bool bindFunction( void *&fnAddress, const char *name )
  79. {
  80. fnAddress = dlsym(dlHandle, name);
  81. if( !fnAddress )
  82. if (bindEmulatedFunction(fnAddress, name))
  83. Con::warnf(ConsoleLogEntry::General, " Missing OpenAL function '%s', using emulated function", name);
  84. else
  85. Con::errorf(ConsoleLogEntry::General, " Missing OpenAL function '%s'", name);
  86. return (fnAddress != NULL);
  87. }
  88. /*! Get a function address for an OpenAL extension function and bind it
  89. * to it's function pointer
  90. */
  91. static bool bindExtensionFunction( void *&fnAddress, const char *name )
  92. {
  93. fnAddress = alGetProcAddress( (ALubyte*)name );
  94. if( !fnAddress )
  95. Con::errorf(ConsoleLogEntry::General, " Missing OpenAL Extension function '%s'", name);
  96. return (fnAddress != NULL);
  97. }
  98. /*! Bind the functions in the OpenAL DLL to the al interface functions
  99. */
  100. static bool bindOpenALFunctions()
  101. {
  102. bool result = true;
  103. #define AL_FUNCTION(fn_return, fn_name, fn_args, fn_value) result &= bindFunction( *(void**)&fn_name, #fn_name);
  104. #include <al/al_func.h>
  105. #include <al/alc_func.h>
  106. #undef AL_FUNCTION
  107. return result;
  108. }
  109. /*! Bind the stub functions to the al interface functions
  110. */
  111. static void unbindOpenALFunctions()
  112. {
  113. #define AL_FUNCTION(fn_return, fn_name, fn_args, fn_value) fn_name = stub_##fn_name;
  114. #include <al/al_func.h>
  115. #include <al/alc_func.h>
  116. #include <al/eax_func.h>
  117. #undef AL_FUNCTION
  118. }
  119. /*! Bind the EAX Extension functions to the EAX interface functions
  120. */
  121. static bool bindEAXFunctions()
  122. {
  123. bool result = true;
  124. #define AL_FUNCTION(fn_return, fn_name, fn_args, fn_value) result &= bindExtensionFunction( *(void**)&fn_name, #fn_name);
  125. #include <al/eax_func.h>
  126. #undef AL_FUNCTION
  127. return result;
  128. }
  129. // Definitions for the emulated functions
  130. ALboolean emu_alGetBoolean(ALenum param)
  131. {
  132. ALboolean alboolean;
  133. alGetBooleanv(param, &alboolean);
  134. return alboolean;
  135. }
  136. ALint emu_alGetInteger(ALenum param)
  137. {
  138. ALint alint;
  139. alGetIntegerv(param, &alint);
  140. return alint;
  141. }
  142. ALfloat emu_alGetFloat(ALenum param)
  143. {
  144. ALfloat alfloat;
  145. alGetFloatv(param, &alfloat);
  146. return alfloat;
  147. }
  148. ALdouble emu_alGetDouble(ALenum param)
  149. {
  150. ALdouble aldouble;
  151. alGetDoublev(param, &aldouble);
  152. return aldouble;
  153. }
  154. void emu_alGetListener3f(ALenum pname,ALfloat *v0,ALfloat *v1,ALfloat *v2)
  155. {
  156. ALfloat ptArray[10];
  157. ptArray[0] = *v0;
  158. ptArray[1] = *v1;
  159. ptArray[2] = *v2;
  160. alGetListenerfv(pname, ptArray);
  161. *v0 = ptArray[0];
  162. *v1 = ptArray[1];
  163. *v2 = ptArray[2];
  164. }
  165. void emu_alListeneri( ALenum param, ALint value )
  166. {
  167. alListenerf(param, static_cast<ALfloat>(value));
  168. }
  169. ALCdevice* emu_alcGetContextsDevice(ALCcontext *context)
  170. {
  171. // this function isn't emulated
  172. AssertFatal(false, "alcGetContextsDevice is not available");
  173. return NULL;
  174. }
  175. namespace Audio
  176. {
  177. /*! Shutdown and Unload the OpenAL DLL
  178. */
  179. void OpenALDLLShutdown()
  180. {
  181. if (dlHandle != NULL)
  182. {
  183. dlclose(dlHandle);
  184. // FreeBSD didn't like that const dlerror() was returning.
  185. if ((dlError = (char *)dlerror()) != NULL)
  186. Con::errorf(ConsoleLogEntry::General, " Error unloading OpenAL Library: %s", dlError);
  187. }
  188. dlHandle = NULL;
  189. unbindOpenALFunctions();
  190. }
  191. /*! Dynamically Loads the OpenAL DLL if present and binds all the functions.
  192. * If there is no DLL or an unexpected error occurs binding functions the
  193. * stub functions are automatically bound.
  194. */
  195. bool OpenALDLLInit()
  196. {
  197. OpenALDLLShutdown();
  198. const char* libName = "libopenal.so";
  199. // these are relative to the current working directory
  200. const char* searchPath[] = {
  201. "lib",
  202. "tplib", // superceeded by "lib", here for backass compatibility
  203. "", // i.e.: current working directory
  204. NULL // this must be last
  205. };
  206. char openalPath[4096];
  207. for (int i = 0; searchPath[i] != NULL; ++i)
  208. {
  209. dSprintf(openalPath, sizeof(openalPath), "%s/%s/%s",
  210. Platform::getWorkingDirectory(),
  211. searchPath[i],
  212. libName);
  213. Con::printf(" Searching for OpenAl at location : %s", openalPath);
  214. dlHandle = dlopen(openalPath, RTLD_NOW);
  215. if (dlHandle != NULL)
  216. {
  217. // found it
  218. Con::printf(" Loading OpenAL: %s", openalPath);
  219. break;
  220. }
  221. }
  222. if (dlHandle == NULL)
  223. {
  224. // couldn't find it in our searchPath, try the system path
  225. dlHandle = dlopen(libName, RTLD_NOW);
  226. if (dlHandle != NULL)
  227. Con::printf(" Loading OpenAL from system (dlopen) path");
  228. }
  229. if (dlHandle != NULL)
  230. {
  231. // if the DLL loaded bind the OpenAL function pointers
  232. if(bindOpenALFunctions())
  233. {
  234. // if EAX is available bind it's function pointers
  235. if (alIsExtensionPresent((ALubyte*)"EAX" ))
  236. bindEAXFunctions();
  237. return(true);
  238. }
  239. // an error occured, shutdown
  240. OpenALDLLShutdown();
  241. }
  242. else
  243. {
  244. Con::errorf(ConsoleLogEntry::General, " Error loading OpenAL Library: %s", dlerror());
  245. }
  246. return(false);
  247. }
  248. } // end namespace Audio
  249. #endif //0