After the previous attempt by Nick Burns was more or less abandoned, I decided to try making an acceptable version myself. This is the current result.
I used the original version Nick had and got rid a lot of the macro abuse. It still uses macros to declare/define and load the functions, but it isn't nearly as bad as it was. I know AJ isn't very thrilled with macro use, but I believe the current method is a nice balance between flexibility and clarity. Note that this IS NOT FINISHED. It should be good enough to work, however. The main reason for this is to get some testing to make sure it works as expected on other machines (especially OSX). The things I still need to work on are: a) Skip building the DLL if OpenAL headers aren't found on the system durring ./configure (any autotools experts want to help?) b) Properly handle the autotools stuff (any autotools experts want to help?) c) Fix up extension handling to use al[c]GetProcAddress instead of dlsym (for the sake of being proper; I don't believe this would pose a problem currently) The OpenAL lib is dynamicly loaded, so the lib doesn't need to be present when building. If the lib is not present when the DLL is loaded however, then the DLL will fail to load. Because of this, it might be a good idea to include OpenAL headers with Wine, so they will always be available to build the DLL with (the headers are LGPL licensed, AFAIK). Won't have to worry about skipping building or configure checking that way. On my Linux machine, the OpenAL 1.1 SDK demos work*. I'm curious about how they work for other people on other machines, and for other apps. * Not quite true. EnumerateWin32.exe doesn't wait for a key press before exiting, and OpenALDemo.exe won't wait for key presses when trying to pick a test (it loops endlessly on the "main menu"). These problems are not related to OpenAL. PlayStaticWin32.exe and PlayStreamWin32.exe both work perfectly, and EnumerateWin32.exe does do what it's supposed to, with the exception of the wait-for-key-before-exit problem. Note that if you're using the Sample Implementation, you must get a recent (as in today/yesterday) SVN checkout of it. It was missing a couple somewhat obscure 1.1 functions I sent in a patch for and got applied. After patching, you'll need to run autoconf (or autogen if you use that script) to generate a new configure. Reconfigure, then rebuild Wine. PS. I did get permission from Nick before posting this as I used his "un-licensed" patch as a starting point. It's all okay with him. PPS. I know not everyone likes the idea of this thunk, because the native implementations aren't "up to par" with the Windows version that backends on DSound. However, the only way they'll get better is with use (they've already got several patches from me because of this thunk, with more pending, and more in planning), and if worse comes to worse, you can use a DLL override to use the Windows native OpenAL. Creative is planning on releasing hardware OpenAL Linux drivers for some of their cards later this year, and this would be the best way to take advantage of them.
From 4b95f0f33ac155a84c42c73b2d00547e3983e133 Mon Sep 17 00:00:00 2001 From: Chris Robinson <[EMAIL PROTECTED]> Date: Sun, 13 May 2007 21:19:57 -0700 Subject: [PATCH] Add OpenAL32 DLL thunk --- Makefile.in | 2 + configure.ac | 15 ++ dlls/Makefile.in | 1 + dlls/openal32/Makefile.in | 14 ++ dlls/openal32/openal.c | 418 +++++++++++++++++++++++++++++++++++++++++++ dlls/openal32/openal32.spec | 97 ++++++++++ include/config.h.in | 6 + 7 files changed, 553 insertions(+), 0 deletions(-) create mode 100644 dlls/openal32/Makefile.in create mode 100644 dlls/openal32/openal.c create mode 100644 dlls/openal32/openal32.spec diff --git a/Makefile.in b/Makefile.in index 30e0581..7d834b7 100644 --- a/Makefile.in +++ b/Makefile.in @@ -322,6 +322,7 @@ ALL_MAKEFILES = \ dlls/oledlg/Makefile \ dlls/olepro32/Makefile \ dlls/olesvr32/Makefile \ + dlls/openal32/Makefile \ dlls/opengl32/Makefile \ dlls/powrprof/Makefile \ dlls/psapi/Makefile \ @@ -668,6 +669,7 @@ dlls/olecli32/Makefile: dlls/olecli32/Makefile.in dlls/Makedll.rules dlls/oledlg/Makefile: dlls/oledlg/Makefile.in dlls/Makedll.rules dlls/olepro32/Makefile: dlls/olepro32/Makefile.in dlls/Makedll.rules dlls/olesvr32/Makefile: dlls/olesvr32/Makefile.in dlls/Makedll.rules +dlls/openal32/Makefile: dlls/openal32/Makefile.in dlls/Makedll.rules dlls/opengl32/Makefile: dlls/opengl32/Makefile.in dlls/Makedll.rules dlls/powrprof/Makefile: dlls/powrprof/Makefile.in dlls/Makedll.rules dlls/psapi/Makefile: dlls/psapi/Makefile.in dlls/Makedll.rules diff --git a/configure.ac b/configure.ac index 52323c7..d87fe69 100644 --- a/configure.ac +++ b/configure.ac @@ -157,6 +157,8 @@ AC_SUBST(QUARTZFILES,"") dnl **** Check for header files **** AC_CHECK_HEADERS(\ + OpenAL/al.h \ + AL/al.h \ AudioUnit/AudioUnit.h \ Carbon/Carbon.h \ CoreAudio/CoreAudio.h \ @@ -839,6 +841,14 @@ then AC_CHECK_LIB(capi20,capi20_register,[AC_DEFINE(HAVE_CAPI4LINUX,1,[Define if you have capi4linux libs and headers])]) fi +dnl **** Check for OpenAL support **** +dnl **** Mac OSX OpenAL support checked below **** + +if test "$ac_cv_header_AL_al_h" = "yes" + then + dnl OpenAL framework +fi + dnl **** Check for gcc specific options **** AC_SUBST(EXTRACFLAGS,"") @@ -991,6 +1001,10 @@ case $host_os in dnl CoreServices needed by AudioUnit AC_SUBST(COREAUDIO,"-framework CoreAudio -framework AudioUnit -framework CoreServices -framework AudioToolbox -framework CoreMIDI") fi + if test "$ac_cv_header_OpenAL_al_h" = "yes" + then + dnl OpenAL framework + fi case $host_cpu in *powerpc*) LDDLLFLAGS="$LDDLLFLAGS -read_only_relocs warning" dnl FIXME @@ -1652,6 +1666,7 @@ AC_CONFIG_FILES([dlls/olecli32/Makefile]) AC_CONFIG_FILES([dlls/oledlg/Makefile]) AC_CONFIG_FILES([dlls/olepro32/Makefile]) AC_CONFIG_FILES([dlls/olesvr32/Makefile]) +AC_CONFIG_FILES([dlls/openal32/Makefile]) AC_CONFIG_FILES([dlls/opengl32/Makefile]) AC_CONFIG_FILES([dlls/powrprof/Makefile]) AC_CONFIG_FILES([dlls/psapi/Makefile]) diff --git a/dlls/Makefile.in b/dlls/Makefile.in index f9707e7..6741978 100644 --- a/dlls/Makefile.in +++ b/dlls/Makefile.in @@ -138,6 +138,7 @@ BASEDIRS = \ oledlg \ olepro32 \ olesvr32 \ + openal32 \ powrprof \ psapi \ pstorec \ diff --git a/dlls/openal32/Makefile.in b/dlls/openal32/Makefile.in new file mode 100644 index 0000000..a30042b --- /dev/null +++ b/dlls/openal32/Makefile.in @@ -0,0 +1,14 @@ +TOPSRCDIR = @top_srcdir@ +TOPOBJDIR = ../.. +SRCDIR = @srcdir@ +VPATH = @srcdir@ +MODULE = openal32.dll +IMPORTS = kernel32 ntdll +EXTRALIBS = -ldl + +C_SRCS = \ + openal.c + [EMAIL PROTECTED]@ + [EMAIL PROTECTED]@ # everything below this line is overwritten by make depend diff --git a/dlls/openal32/openal.c b/dlls/openal32/openal.c new file mode 100644 index 0000000..e324833 --- /dev/null +++ b/dlls/openal32/openal.c @@ -0,0 +1,418 @@ +/* + * OpenAL32.dll thunk. Wraps Win32 OpenAL function calls around a native + * implementation. + * + * Copyright 2007 Nick Burns ([EMAIL PROTECTED]) + * Copyright 2007 Chris Robinson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" + +#if !defined(HAVE_OPENAL_AL_H) && !defined(HAVE_AL_AL_H) + +#error You need OpenAL installed to build this DLL! + +#else + +#include <stdarg.h> +#include <assert.h> +#include <dlfcn.h> + +#include "windef.h" +#include "winbase.h" +#include "wine/debug.h" + +#if defined(HAVE_OPENAL_AL_H) + #include <OpenAL/al.h> + #include <OpenAL/alc.h> +#elif defined(HAVE_AL_AL_H) + #include <AL/al.h> + #include <AL/alc.h> +#endif + +WINE_DEFAULT_DEBUG_CHANNEL(openal); + + +static HMODULE openal32_handle; +static void *openal_dl; + +#ifdef __APPLE__ +#define OPENAL_LIBNAME "libopenal.dynlib" +#else +#define OPENAL_LIBNAME "libopenal.so" +#endif + +/* Make the thunking functions */ + +/* NOTE: If you add a function here, you *must* also make sure to load it in + * load_procs! + */ + +#define MAKE_PROC(ret, name, params, args) \ +typedef ret (AL_APIENTRY * t_##name)params; \ +static t_##name p_##name = NULL; \ +ret CDECL wine_##name params \ +{ \ + TRACE(#name " == %p\n", p_##name); \ + assert(p_##name); \ + return p_##name args; \ +} + +/* OpenAL ALC 1.0 functions */ +MAKE_PROC(ALCcontext* , alcCreateContext, ( ALCdevice *device, const ALCint* attrlist ), ( device, attrlist )) +MAKE_PROC(ALCboolean , alcMakeContextCurrent, ( ALCcontext *context ), ( context )) +MAKE_PROC(ALvoid , alcProcessContext, ( ALCcontext *context ), ( context )) +MAKE_PROC(ALvoid , alcSuspendContext, ( ALCcontext *context ), ( context )) +MAKE_PROC(ALvoid , alcDestroyContext, ( ALCcontext *context ), ( context )) +MAKE_PROC(ALCcontext* , alcGetCurrentContext, ( ALCvoid ), ( )) +MAKE_PROC(ALCdevice* , alcGetContextsDevice, ( ALCcontext *context ), ( context )) +MAKE_PROC(ALCdevice* , alcOpenDevice, ( const ALCchar *devicename ), ( devicename )) +MAKE_PROC(ALCboolean , alcCloseDevice, ( ALCdevice *device ), ( device )) +MAKE_PROC(ALCenum , alcGetError, ( ALCdevice *device ), ( device )) +MAKE_PROC(ALCboolean , alcIsExtensionPresent, ( ALCdevice *device, const ALCchar *extname ), ( device, extname )) +MAKE_PROC(ALCenum , alcGetEnumValue, ( ALCdevice *device, const ALCchar *enumname ), ( device, enumname )) +MAKE_PROC(const ALCchar*, alcGetString, ( ALCdevice *device, ALCenum param ), ( device, param )) +MAKE_PROC(ALvoid , alcGetIntegerv, ( ALCdevice *device, ALCenum param, ALCsizei size, ALCint *dest ), ( device, param, size, dest )) + +/* OpenAL 1.0 functions */ +MAKE_PROC(ALvoid , alEnable, ( ALenum capability ), ( capability )) +MAKE_PROC(ALvoid , alDisable, ( ALenum capability ), ( capability )) +MAKE_PROC(ALboolean , alIsEnabled, ( ALenum capability ), ( capability )) +MAKE_PROC(const ALchar*, alGetString, ( ALenum param ), ( param )) +MAKE_PROC(ALvoid , alGetBooleanv, ( ALenum param, ALboolean* data ), ( param, data )) +MAKE_PROC(ALvoid , alGetIntegerv, ( ALenum param, ALint* data ), ( param, data )) +MAKE_PROC(ALvoid , alGetFloatv, ( ALenum param, ALfloat* data ), ( param, data )) +MAKE_PROC(ALvoid , alGetDoublev, ( ALenum param, ALdouble* data ), ( param, data )) +MAKE_PROC(ALboolean , alGetBoolean, ( ALenum param ), ( param )) +MAKE_PROC(ALint , alGetInteger, ( ALenum param ), ( param )) +MAKE_PROC(ALfloat , alGetFloat, ( ALenum param ), ( param )) +MAKE_PROC(ALdouble , alGetDouble, ( ALenum param ), ( param )) +MAKE_PROC(ALenum , alGetError, ( ALvoid ), ( )) +MAKE_PROC(ALboolean , alIsExtensionPresent, (const ALchar* extname ), (extname )) +MAKE_PROC(ALenum , alGetEnumValue, ( const ALchar* ename ), ( ename )) +MAKE_PROC(ALvoid , alListenerf, ( ALenum param, ALfloat value ), ( param, value )) +MAKE_PROC(ALvoid , alListener3f, ( ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ), ( param, value1, value2, value3 )) +MAKE_PROC(ALvoid , alListenerfv, ( ALenum param, const ALfloat* values ), ( param, values )) +MAKE_PROC(ALvoid , alListeneri, ( ALenum param, ALint value ), ( param, value )) +MAKE_PROC(ALvoid , alGetListenerf, ( ALenum param, ALfloat* value ), ( param, value )) +MAKE_PROC(ALvoid , alGetListener3f, ( ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3 ), ( param, value1, value2, value3 )) +MAKE_PROC(ALvoid , alGetListenerfv, ( ALenum param, ALfloat* values ), ( param, values )) +MAKE_PROC(ALvoid , alGetListeneri, ( ALenum param, ALint* value ), ( param, value )) +MAKE_PROC(ALvoid , alGetListeneriv, ( ALenum param, ALint* values ), ( param, values )) +MAKE_PROC(ALvoid , alGenSources, ( ALsizei n, ALuint* sources ), ( n, sources )) +MAKE_PROC(ALvoid , alDeleteSources, ( ALsizei n, const ALuint* sources ), ( n, sources )) +MAKE_PROC(ALboolean , alIsSource, ( ALuint sid ), ( sid )) +MAKE_PROC(ALvoid , alSourcef, ( ALuint sid, ALenum param, ALfloat value), ( sid, param, value)) +MAKE_PROC(ALvoid , alSource3f, ( ALuint sid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ), ( sid, param, value1, value2, value3 )) +MAKE_PROC(ALvoid , alSourcefv, ( ALuint sid, ALenum param, const ALfloat* values ), ( sid, param, values )) +MAKE_PROC(ALvoid , alSourcei, ( ALuint sid, ALenum param, ALint value), ( sid, param, value)) +MAKE_PROC(ALvoid , alGetSourcef, ( ALuint sid, ALenum param, ALfloat* value ), ( sid, param, value )) +MAKE_PROC(ALvoid , alGetSource3f, ( ALuint sid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3), ( sid, param, value1, value2, value3)) +MAKE_PROC(ALvoid , alGetSourcefv, ( ALuint sid, ALenum param, ALfloat* values ), ( sid, param, values )) +MAKE_PROC(ALvoid , alGetSourcei, ( ALuint sid, ALenum param, ALint* value ), ( sid, param, value )) +MAKE_PROC(ALvoid , alGetSourceiv, ( ALuint sid, ALenum param, ALint* values ), ( sid, param, values )) +MAKE_PROC(ALvoid , alSourcePlayv, ( ALsizei ns, const ALuint *sids ), ( ns, sids )) +MAKE_PROC(ALvoid , alSourceStopv, ( ALsizei ns, const ALuint *sids ), ( ns, sids )) +MAKE_PROC(ALvoid , alSourceRewindv, ( ALsizei ns, const ALuint *sids ), ( ns, sids )) +MAKE_PROC(ALvoid , alSourcePausev, ( ALsizei ns, const ALuint *sids ), ( ns, sids )) +MAKE_PROC(ALvoid , alSourcePlay, ( ALuint sid ), ( sid )) +MAKE_PROC(ALvoid , alSourceStop, ( ALuint sid ), ( sid )) +MAKE_PROC(ALvoid , alSourceRewind, ( ALuint sid ), ( sid )) +MAKE_PROC(ALvoid , alSourcePause, ( ALuint sid ), ( sid )) +MAKE_PROC(ALvoid , alSourceQueueBuffers, ( ALuint sid, ALsizei numEntries, const ALuint *bids ), ( sid, numEntries, bids )) +MAKE_PROC(ALvoid , alSourceUnqueueBuffers, ( ALuint sid, ALsizei numEntries, ALuint *bids ), ( sid, numEntries, bids )) +MAKE_PROC(ALvoid , alGenBuffers, ( ALsizei n, ALuint* buffers ), ( n, buffers )) +MAKE_PROC(ALvoid , alDeleteBuffers, ( ALsizei n, const ALuint* buffers ), ( n, buffers )) +MAKE_PROC(ALboolean , alIsBuffer, ( ALuint bid ), ( bid )) +MAKE_PROC(ALvoid , alBufferData, ( ALuint bid, ALenum format, const ALvoid* data, ALsizei size, ALsizei freq ), ( bid, format, data, size, freq )) +MAKE_PROC(ALvoid , alGetBufferf, ( ALuint bid, ALenum param, ALfloat* value ), ( bid, param, value )) +MAKE_PROC(ALvoid , alGetBufferfv, ( ALuint bid, ALenum param, ALfloat* values ), ( bid, param, values )) +MAKE_PROC(ALvoid , alGetBufferi, ( ALuint bid, ALenum param, ALint* value ), ( bid, param, value )) +MAKE_PROC(ALvoid , alGetBufferiv, ( ALuint bid, ALenum param, ALint* values ), ( bid, param, values )) +MAKE_PROC(ALvoid , alDopplerFactor, ( ALfloat value ), ( value )) +MAKE_PROC(ALvoid , alDopplerVelocity, ( ALfloat value ), ( value )) +MAKE_PROC(ALvoid , alDistanceModel, ( ALenum distanceModel ), ( distanceModel )) + +/* OpenAL ALC 1.1 functions */ +MAKE_PROC(ALCdevice*, alcCaptureOpenDevice, ( const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize ), ( devicename, frequency, format, buffersize )) +MAKE_PROC(ALCboolean, alcCaptureCloseDevice, ( ALCdevice *device ), ( device )) +MAKE_PROC(ALvoid , alcCaptureStart, ( ALCdevice *device ), ( device )) +MAKE_PROC(ALvoid , alcCaptureStop, ( ALCdevice *device ), ( device )) +MAKE_PROC(ALvoid , alcCaptureSamples, ( ALCdevice *device, ALCvoid *buffer, ALCsizei samples ), ( device, buffer, samples )) + +/* OpenAL 1.1 functions */ +MAKE_PROC(ALvoid, alListener3i, ( ALenum param, ALint value1, ALint value2, ALint value3 ), ( param, value1, value2, value3 )) +MAKE_PROC(ALvoid, alListeneriv, ( ALenum param, const ALint* values ), ( param, values )) +MAKE_PROC(ALvoid, alGetListener3i, ( ALenum param, ALint *value1, ALint *value2, ALint *value3 ), ( param, value1, value2, value3 )) +MAKE_PROC(ALvoid, alSource3i, ( ALuint sid, ALenum param, ALint value1, ALint value2, ALint value3 ), ( sid, param, value1, value2, value3 )) +MAKE_PROC(ALvoid, alSourceiv, ( ALuint sid, ALenum param, const ALint* values ), ( sid, param, values )) +MAKE_PROC(ALvoid, alGetSource3i, ( ALuint sid, ALenum param, ALint* value1, ALint* value2, ALint* value3), ( sid, param, value1, value2, value3)) +MAKE_PROC(ALvoid, alBufferf, ( ALuint bid, ALenum param, ALfloat value), ( bid, param, value)) +MAKE_PROC(ALvoid, alBuffer3f, ( ALuint bid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ), ( bid, param, value1, value2, value3 )) +MAKE_PROC(ALvoid, alBufferfv, ( ALuint bid, ALenum param, const ALfloat* values ), ( bid, param, values )) +MAKE_PROC(ALvoid, alBufferi, ( ALuint bid, ALenum param, ALint value), ( bid, param, value)) +MAKE_PROC(ALvoid, alBuffer3i, ( ALuint bid, ALenum param, ALint value1, ALint value2, ALint value3 ), ( bid, param, value1, value2, value3 )) +MAKE_PROC(ALvoid, alBufferiv, ( ALuint bid, ALenum param, const ALint* values ), ( bid, param, values )) +MAKE_PROC(ALvoid, alGetBuffer3f, ( ALuint bid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3), ( bid, param, value1, value2, value3)) +MAKE_PROC(ALvoid, alGetBuffer3i, ( ALuint bid, ALenum param, ALint* value1, ALint* value2, ALint* value3), ( bid, param, value1, value2, value3)) +MAKE_PROC(ALvoid, alSpeedOfSound, ( ALfloat value ), ( value )) + +/* ALC_LOKI_audio_channel */ +MAKE_PROC(ALCfloat, alcGetAudioChannel_LOKI, ( ALCuint channel ), ( channel )) +MAKE_PROC(ALCvoid , alcSetAudioChannel_LOKI, ( ALCuint channel, ALCfloat volume ), ( channel, volume )) + +/* AL_LOKI_buffer_data_callback */ +MAKE_PROC(ALvoid, alBufferDataWithCallback_LOKI, ( ALuint bid, ALint (*callback)(ALuint,ALuint,ALvoid*,ALenum,ALuint) ), ( bid, callback )) + +/* ALC_EXT_MAC_OSX */ +MAKE_PROC(ALvoid , alcMacOSXRenderingQualityProcPtr, ( const ALint value ), ( value )) +MAKE_PROC(ALvoid , alMacOSXRenderChannelCountProcPtr, ( const ALint value ), ( value )) +MAKE_PROC(ALvoid , alcMacOSXMixerMaxiumumBussesProcPtr, ( const ALint value ), ( value )) +MAKE_PROC(ALvoid , alcMacOSXMixerOutputRateProcPtr, ( const ALdouble value ), ( value )) +MAKE_PROC(ALint , alcMacOSXGetRenderingQualityProcPtr, ( ALCvoid ), ( )) +MAKE_PROC(ALint , alMacOSXGetRenderChannelCountProcPtr, ( ALvoid ), ( )) +MAKE_PROC(ALint , alcMacOSXGetMixerMaxiumumBussesProcPtr, ( ALCvoid ), ( )) +MAKE_PROC(ALdouble, alcMacOSXGetMixerOutputRateProcPtr, ( ALCvoid ), ( )) + +/* ALC_EXT_ASA */ +MAKE_PROC(ALenum, alcASAGetSourceProcPtr, ( const ALuint property, ALuint source, ALvoid *data, ALuint* dataSize ), ( property, source, data, dataSize )) +MAKE_PROC(ALenum, alcASASetSourceProcPtr, ( const ALuint property, ALuint source, ALvoid *data, ALuint dataSize ), ( property, source, data, dataSize )) +MAKE_PROC(ALenum, alcASAGetListenerProcPtr, ( const ALuint property, ALvoid *data,ALuint* dataSize ), ( property, data, dataSize )) +MAKE_PROC(ALenum, alcASASetListenerProcPtr, ( const ALuint property, ALvoid *data,ALuint dataSize ), ( property, data, dataSize )) + +/* AL_EXT_STATIC_BUFFER */ +MAKE_PROC(ALvoid, alBufferDataStatic, ( const ALint bid, ALenum format, ALvoid* data, ALsizei size, ALsizei freq ), ( bid, format, data, size, freq )) + +#undef MAKE_PROC + +/* These are handled seperately */ +typedef void* (AL_APIENTRY * t_alcGetProcAddress)(ALCdevice *device, const ALCchar *funcname); +static t_alcGetProcAddress p_alcGetProcAddress = NULL; +void* CDECL wine_alcGetProcAddress(ALCdevice *device, const ALCchar *funcname) +{ + void *ret = NULL; + + /* Check to make sure the native implementation has the function before + * returning the thunk + */ + TRACE("alcGetProcAddress == %p\n", p_alcGetProcAddress); + assert(p_alcGetProcAddress); + if(p_alcGetProcAddress(device, funcname)) + ret = GetProcAddress(openal32_handle, funcname); + + TRACE("funcname == %s, ret == %p\n", funcname, ret); + return ret; +} + +typedef void* (AL_APIENTRY * t_alGetProcAddress)(const ALchar *funcname); +static t_alGetProcAddress p_alGetProcAddress = NULL; +void* CDECL wine_alGetProcAddress(const ALchar* funcname) +{ + void *ret = NULL; + + TRACE("alGetProcAddress == %p\n", p_alGetProcAddress); + assert(p_alGetProcAddress); + if(p_alGetProcAddress(funcname)) + ret = GetProcAddress(openal32_handle, funcname); + + TRACE("funcname == %s, ret == %p\n", funcname, ret); + return ret; +} + + +static BOOL load_procs(void) +{ + char *err; + + openal_dl = dlopen(OPENAL_LIBNAME, RTLD_LAZY); + if(!openal_dl) + { + ERR("Could not load " OPENAL_LIBNAME ": %s\n", dlerror()); + return FALSE; + } + + /* Clear error status */ + dlerror(); + +/* OpenAL 1.1 is required (since that is what's exported). Unix (Linux, + * FreeBSD, etc), Windows, and OSX all support this version. + */ +#define LOAD_SYM(sym) \ +p_##sym = dlsym(openal_dl, #sym); \ +if((err=dlerror()) != NULL) { \ + ERR("Could not load required function " #sym ": %s\n", err); \ + dlclose(openal_dl); \ + openal_dl = NULL; \ + return FALSE; \ +} + +LOAD_SYM(alcCreateContext); +LOAD_SYM(alcMakeContextCurrent); +LOAD_SYM(alcProcessContext); +LOAD_SYM(alcSuspendContext); +LOAD_SYM(alcDestroyContext); +LOAD_SYM(alcGetCurrentContext); +LOAD_SYM(alcGetContextsDevice); +LOAD_SYM(alcOpenDevice); +LOAD_SYM(alcCloseDevice); +LOAD_SYM(alcGetError); +LOAD_SYM(alcIsExtensionPresent); +LOAD_SYM(alcGetProcAddress); +LOAD_SYM(alcGetEnumValue); +LOAD_SYM(alcGetString); +LOAD_SYM(alcGetIntegerv); + +LOAD_SYM(alEnable); +LOAD_SYM(alDisable); +LOAD_SYM(alIsEnabled); +LOAD_SYM(alGetString); +LOAD_SYM(alGetBooleanv); +LOAD_SYM(alGetIntegerv); +LOAD_SYM(alGetFloatv); +LOAD_SYM(alGetDoublev); +LOAD_SYM(alGetBoolean); +LOAD_SYM(alGetInteger); +LOAD_SYM(alGetFloat); +LOAD_SYM(alGetDouble); +LOAD_SYM(alGetError); +LOAD_SYM(alIsExtensionPresent); +LOAD_SYM(alGetProcAddress); +LOAD_SYM(alGetEnumValue); +LOAD_SYM(alListenerf); +LOAD_SYM(alListener3f); +LOAD_SYM(alListenerfv); +LOAD_SYM(alListeneri); +LOAD_SYM(alGetListenerf); +LOAD_SYM(alGetListener3f); +LOAD_SYM(alGetListenerfv); +LOAD_SYM(alGetListeneri); +LOAD_SYM(alGetListeneriv); +LOAD_SYM(alGenSources); +LOAD_SYM(alDeleteSources); +LOAD_SYM(alIsSource); +LOAD_SYM(alSourcef); +LOAD_SYM(alSource3f); +LOAD_SYM(alSourcefv); +LOAD_SYM(alSourcei); +LOAD_SYM(alGetSourcef); +LOAD_SYM(alGetSource3f); +LOAD_SYM(alGetSourcefv); +LOAD_SYM(alGetSourcei); +LOAD_SYM(alGetSourceiv); +LOAD_SYM(alSourcePlayv); +LOAD_SYM(alSourceStopv); +LOAD_SYM(alSourceRewindv); +LOAD_SYM(alSourcePausev); +LOAD_SYM(alSourcePlay); +LOAD_SYM(alSourceStop); +LOAD_SYM(alSourceRewind); +LOAD_SYM(alSourcePause); +LOAD_SYM(alSourceQueueBuffers); +LOAD_SYM(alSourceUnqueueBuffers); +LOAD_SYM(alGenBuffers); +LOAD_SYM(alDeleteBuffers); +LOAD_SYM(alIsBuffer); +LOAD_SYM(alBufferData); +LOAD_SYM(alGetBufferf); +LOAD_SYM(alGetBufferfv); +LOAD_SYM(alGetBufferi); +LOAD_SYM(alGetBufferiv); +LOAD_SYM(alDopplerFactor); +LOAD_SYM(alDopplerVelocity); +LOAD_SYM(alDistanceModel); + +LOAD_SYM(alcCaptureOpenDevice); +LOAD_SYM(alcCaptureCloseDevice); +LOAD_SYM(alcCaptureStart); +LOAD_SYM(alcCaptureStop); +LOAD_SYM(alcCaptureSamples); + +LOAD_SYM(alListener3i); +LOAD_SYM(alListeneriv); +LOAD_SYM(alGetListener3i); +LOAD_SYM(alSource3i); +LOAD_SYM(alSourceiv); +LOAD_SYM(alGetSource3i); +LOAD_SYM(alBufferf); +LOAD_SYM(alBuffer3f); +LOAD_SYM(alBufferfv); +LOAD_SYM(alBufferi); +LOAD_SYM(alBuffer3i); +LOAD_SYM(alBufferiv); +LOAD_SYM(alGetBuffer3f); +LOAD_SYM(alGetBuffer3i); +LOAD_SYM(alSpeedOfSound); + +/* Extensions are optional */ +#undef LOAD_SYM +#define LOAD_SYM(sym) \ +p_##sym = dlsym(openal_dl, #sym); \ +if((err=dlerror()) != NULL) \ + WARN("Could not load function " #sym ": %s\n", err) + +LOAD_SYM(alcGetAudioChannel_LOKI); +LOAD_SYM(alcSetAudioChannel_LOKI); + +LOAD_SYM(alBufferDataWithCallback_LOKI); + +LOAD_SYM(alcMacOSXRenderingQualityProcPtr); +LOAD_SYM(alMacOSXRenderChannelCountProcPtr); +LOAD_SYM(alcMacOSXMixerMaxiumumBussesProcPtr); +LOAD_SYM(alcMacOSXMixerOutputRateProcPtr); +LOAD_SYM(alcMacOSXGetRenderingQualityProcPtr); +LOAD_SYM(alMacOSXGetRenderChannelCountProcPtr); +LOAD_SYM(alcMacOSXGetMixerMaxiumumBussesProcPtr); +LOAD_SYM(alcMacOSXGetMixerOutputRateProcPtr); + +LOAD_SYM(alcASAGetSourceProcPtr); +LOAD_SYM(alcASASetSourceProcPtr); +LOAD_SYM(alcASAGetListenerProcPtr); +LOAD_SYM(alcASASetListenerProcPtr); + +LOAD_SYM(alBufferDataStatic); + +#undef LOAD_SYM + + return TRUE; +} + + +/*********************************************************************** + * OpenAL initialisation routine + */ +BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) +{ + BOOL ret = TRUE; + + switch(reason) + { + case DLL_PROCESS_ATTACH: + ret = load_procs(); + if(ret != FALSE) + openal32_handle = hinst; + break; + case DLL_PROCESS_DETACH: + if(openal_dl) + dlclose(openal_dl); + break; + } + + return ret; +} + + +#endif /* defined(HAVE_OPENAL_AL_H) || defined(HAVE_AL_AL_H) */ diff --git a/dlls/openal32/openal32.spec b/dlls/openal32/openal32.spec new file mode 100644 index 0000000..df76e3a --- /dev/null +++ b/dlls/openal32/openal32.spec @@ -0,0 +1,97 @@ +#OpenAL ALC_1_0 +@ cdecl alcCreateContext(ptr ptr ) wine_alcCreateContext +@ cdecl alcMakeContextCurrent(ptr) wine_alcMakeContextCurrent +@ cdecl alcProcessContext(ptr) wine_alcProcessContext +@ cdecl alcSuspendContext(ptr) wine_alcSuspendContext +@ cdecl alcDestroyContext(ptr) wine_alcDestroyContext +@ cdecl alcGetCurrentContext( ) wine_alcGetCurrentContext +@ cdecl alcGetContextsDevice(ptr) wine_alcGetContextsDevice +@ cdecl alcOpenDevice(str) wine_alcOpenDevice +@ cdecl alcCloseDevice(ptr) wine_alcCloseDevice +@ cdecl alcGetError(ptr) wine_alcGetError +@ cdecl alcIsExtensionPresent(ptr str) wine_alcIsExtensionPresent +@ cdecl alcGetProcAddress(ptr str) wine_alcGetProcAddress +@ cdecl alcGetEnumValue(ptr str) wine_alcGetEnumValue +@ cdecl alcGetString(ptr long ) wine_alcGetString +@ cdecl alcGetIntegerv(ptr long long ptr) wine_alcGetIntegerv +#OpenAL AL_1_0 +@ cdecl alEnable(long ) wine_alEnable +@ cdecl alDisable(long ) wine_alDisable +@ cdecl alIsEnabled(long ) wine_alIsEnabled +@ cdecl alGetString(long ) wine_alGetString +@ cdecl alGetBooleanv(long ptr ) wine_alGetBooleanv +@ cdecl alGetIntegerv(long ptr ) wine_alGetIntegerv +@ cdecl alGetFloatv(long ptr ) wine_alGetFloatv +@ cdecl alGetDoublev(long ptr ) wine_alGetDoublev +@ cdecl alGetBoolean(long ) wine_alGetBoolean +@ cdecl alGetInteger(long ) wine_alGetInteger +@ cdecl alGetFloat(long ) wine_alGetFloat +@ cdecl alGetDouble(long ) wine_alGetDouble +@ cdecl alGetError( ) wine_alGetError +@ cdecl alIsExtensionPresent(str ) wine_alIsExtensionPresent +@ cdecl alGetProcAddress(str ) wine_alGetProcAddress +@ cdecl alGetEnumValue(str ) wine_alGetEnumValue +@ cdecl alListenerf(long long ) wine_alListenerf +@ cdecl alListener3f(long long long long ) wine_alListener3f +@ cdecl alListenerfv(long ptr ) wine_alListenerfv +@ cdecl alListeneri(long long ) wine_alListeneri +@ cdecl alGetListenerf(long ptr ) wine_alGetListenerf +@ cdecl alGetListener3f(long ptr ptr ptr) wine_alGetListener3f +@ cdecl alGetListenerfv(long ptr ) wine_alGetListenerfv +@ cdecl alGetListeneri(long ptr ) wine_alGetListeneri +@ cdecl alGetListeneriv(long ptr ) wine_alGetListeneriv +@ cdecl alGenSources(long ptr ) wine_alGenSources +@ cdecl alDeleteSources(long ptr ) wine_alDeleteSources +@ cdecl alIsSource(long ) wine_alIsSource +@ cdecl alSourcef(long long long ) wine_alSourcef +@ cdecl alSource3f(long long long long long ) wine_alSource3f +@ cdecl alSourcefv(long long ptr ) wine_alSourcefv +@ cdecl alSourcei(long long long ) wine_alSourcei +@ cdecl alGetSourcef(long long ptr ) wine_alGetSourcef +@ cdecl alGetSource3f(long long ptr ptr ptr ) wine_alGetSource3f +@ cdecl alGetSourcefv(long long ptr ) wine_alGetSourcefv +@ cdecl alGetSourcei(long long ptr ) wine_alGetSourcei +@ cdecl alGetSourceiv(long long ptr ) wine_alGetSourceiv +@ cdecl alSourcePlayv(long ptr) wine_alSourcePlayv +@ cdecl alSourceStopv(long ptr) wine_alSourceStopv +@ cdecl alSourceRewindv(long ptr) wine_alSourceRewindv +@ cdecl alSourcePausev(long ptr) wine_alSourcePausev +@ cdecl alSourcePlay(long ) wine_alSourcePlay +@ cdecl alSourceStop(long ) wine_alSourceStop +@ cdecl alSourceRewind(long ) wine_alSourceRewind +@ cdecl alSourcePause(long ) wine_alSourcePause +@ cdecl alSourceQueueBuffers(long long ptr) wine_alSourceQueueBuffers +@ cdecl alSourceUnqueueBuffers(long long ptr) wine_alSourceUnqueueBuffers +@ cdecl alGenBuffers(long ptr ) wine_alGenBuffers +@ cdecl alDeleteBuffers(long ptr ) wine_alDeleteBuffers +@ cdecl alIsBuffer(long ) wine_alIsBuffer +@ cdecl alBufferData(long long ptr long long ) wine_alBufferData +@ cdecl alGetBufferf(long long ptr ) wine_alGetBufferf +@ cdecl alGetBufferfv(long long ptr ) wine_alGetBufferfv +@ cdecl alGetBufferi(long long ptr ) wine_alGetBufferi +@ cdecl alGetBufferiv(long long ptr ) wine_alGetBufferiv +@ cdecl alDopplerFactor(long ) wine_alDopplerFactor +@ cdecl alDopplerVelocity(long ) wine_alDopplerVelocity +@ cdecl alDistanceModel(long ) wine_alDistanceModel +#OpenAL ALC_1_1 +@ cdecl alcCaptureOpenDevice(str long long long ) wine_alcCaptureOpenDevice +@ cdecl alcCaptureCloseDevice(ptr) wine_alcCaptureCloseDevice +@ cdecl alcCaptureStart(ptr) wine_alcCaptureStart +@ cdecl alcCaptureStop(ptr) wine_alcCaptureStop +@ cdecl alcCaptureSamples(ptr ptr long ) wine_alcCaptureSamples +#OpenAL AL_1_1 +@ cdecl alListener3i(long long long long ) wine_alListener3i +@ cdecl alListeneriv(long ptr ) wine_alListeneriv +@ cdecl alGetListener3i(long ptr ptr ptr) wine_alGetListener3i +@ cdecl alSource3i(long long long long long ) wine_alSource3i +@ cdecl alSourceiv(long long ptr ) wine_alSourceiv +@ cdecl alGetSource3i(long long ptr ptr ptr ) wine_alGetSource3i +@ cdecl alBufferf(long long long ) wine_alBufferf +@ cdecl alBuffer3f(long long long long long ) wine_alBuffer3f +@ cdecl alBufferfv(long long ptr ) wine_alBufferfv +@ cdecl alBufferi(long long long ) wine_alBufferi +@ cdecl alBuffer3i(long long long long long ) wine_alBuffer3i +@ cdecl alBufferiv(long long ptr ) wine_alBufferiv +@ cdecl alGetBuffer3f(long long ptr ptr ptr ) wine_alGetBuffer3f +@ cdecl alGetBuffer3i(long long ptr ptr ptr ) wine_alGetBuffer3i +@ cdecl alSpeedOfSound(long ) wine_alSpeedOfSound diff --git a/include/config.h.in b/include/config.h.in index 331e5cc..11fd094 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -11,6 +11,9 @@ /* Define to 1 if you have the <alsa/asoundlib.h> header file. */ #undef HAVE_ALSA_ASOUNDLIB_H +/* Define to 1 if you have the <AL/al.h> header file. */ +#undef HAVE_AL_AL_H + /* Define to 1 if you have the <arpa/inet.h> header file. */ #undef HAVE_ARPA_INET_H @@ -468,6 +471,9 @@ /* Define to 1 if the system has the type `off_t'. */ #undef HAVE_OFF_T +/* Define to 1 if you have the <OpenAL/al.h> header file. */ +#undef HAVE_OPENAL_AL_H + /* Define if OpenGL is present on the system */ #undef HAVE_OPENGL -- 1.5.0.7