Dynamic object loader for OpenAL

git-svn-id: https://svn.eduke32.com/eduke32@636 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
terminx 2008-03-08 06:51:53 +00:00
parent 0701fad3db
commit bc0f8369e6
7 changed files with 272 additions and 58 deletions

View file

@ -54,14 +54,14 @@ ifeq ($(PLATFORM),LINUX)
EOBJ=eobj
NASMFLAGS+= -f elf
ifeq ($(USE_OPENAL),1)
LIBS+= -lopenal -lvorbisfile -lvorbis -logg
LIBS+= -lvorbisfile -lvorbis -logg
endif
else
ifeq ($(PLATFORM),WINDOWS)
OBJ=obj_win
EOBJ=eobj_win
ifeq ($(USE_OPENAL),1)
LIBS+= -L$(ALROOT)/lib -lOpenAL32 -lvorbisfile -lvorbis -logg
LIBS+= -L$(ALROOT)/lib -lvorbisfile -lvorbis -logg
endif
else
OBJ=obj

View file

@ -1211,7 +1211,7 @@ int AL_DefineMusic(char *ID,char *name)
}
map[sel].musicfn1=makename(map[sel].musicfn1,name/*,ID*/);
initprintf("%s | %3d %2d %2d | %s\n",ID,sel,ep,lev,map[sel].musicfn1);
// initprintf("%s | %3d %2d %2d | %s\n",ID,sel,ep,lev,map[sel].musicfn1);
// playmusicMAP(ID,sel);
return 0;
}

View file

@ -377,8 +377,11 @@ void MV_PlayVoice(VoiceNode *voice)
flags = DisableInterrupts();
LL_SortedInsertion(&VoiceList, voice, prev, next, VoiceNode, priority);
#ifdef USE_OPENAL
if(!voice->bufsnd)voice->bufsnd=(char *)Bcalloc(0x8000*4,sizeof(char));
if(!voice->bufsnd)initprintf("Attention. It gonna crash! Thank you."); // FIXME: change the msg
if (!openal_disabled)
{
if(!voice->bufsnd)voice->bufsnd=(char *)Bcalloc(0x8000*4,sizeof(char));
if(!voice->bufsnd)initprintf("Attention. It gonna crash! Thank you."); // FIXME: change the msg
}
#endif
RestoreInterrupts(flags);
}
@ -396,7 +399,10 @@ void MV_StopVoice(VoiceNode *voice)
flags = DisableInterrupts();
#ifdef USE_OPENAL
if(!voice->bufsnd)Bfree(voice->bufsnd);
if (!openal_disabled)
{
if(!voice->bufsnd)Bfree(voice->bufsnd);
}
#endif
// move the voice from the play list to the free list
LL_Remove(voice, next, prev);
@ -2869,7 +2875,23 @@ int MV_Init(int soundcard, int MixRate, int Voices, int numchannels, int sampleb
// Initialize the sound card
#ifdef USE_OPENAL
AL_Init();
if (AL_Init())
{
int i;
// no AL support so shitcan the ogg definitions
for (i=(MAXLEVELS*(MAXVOLUMES+1))-1;i>=0;i--) // +1 volume for "intro", "briefing" music
{
if (map[i].musicfn1 != NULL)
Bfree(map[i].musicfn1);
}
for (i=MAXSOUNDS-1;i>=0;i--)
{
if (g_sounds[i].filename1 != NULL)
Bfree(g_sounds[i].filename1);
}
}
#endif
#if defined(_WIN32)
status = DSOUND_Init(soundcard, MixRate, numchannels, samplebits, TotalBufferSize);
@ -2972,7 +2994,8 @@ int MV_Shutdown(void)
// Shutdown the sound card
#ifdef USE_OPENAL
AL_Shutdown();
if (!openal_disabled)
AL_Shutdown();
#endif
#if defined(_WIN32)
DSOUND_Shutdown();

View file

@ -191,7 +191,8 @@ void MUSIC_SetVolume
volume = max(0, volume);
volume = min(volume, 255);
#ifdef USE_OPENAL
AL_SetMusicVolume(volume);
if (!openal_disabled)
AL_SetMusicVolume(volume);
#endif
if (MUSIC_SoundDevice != -1)
{
@ -299,7 +300,8 @@ void MUSIC_Continue
{
#ifdef USE_OPENAL
AL_Continue();
if (!openal_disabled)
AL_Continue();
#endif
MIDI_ContinueSong();
}
@ -318,7 +320,8 @@ void MUSIC_Pause
{
#ifdef USE_OPENAL
AL_Pause();
if (!openal_disabled)
AL_Pause();
#endif
MIDI_PauseSong();
}
@ -337,7 +340,8 @@ int MUSIC_StopSong
{
#ifdef USE_OPENAL
AL_stop();
if (!openal_disabled)
AL_stop();
#endif
MUSIC_StopFade();
MIDI_StopSong();
@ -362,8 +366,9 @@ int MUSIC_PlaySong
int status;
#ifdef USE_OPENAL
AL_PlaySong((char *)song,loopflag);
if(AL_isntALmusic())
if (!openal_disabled)
AL_PlaySong((char *)song,loopflag);
if(openal_disabled || AL_isntALmusic())
#endif
{
MUSIC_StopSong();

View file

@ -1,10 +1,11 @@
#ifdef _WIN32
#include "dsound.h"
#endif
#include "baselayer.h"
#include "compat.h"
#include "winlayer.h"
#include <al/al.h>
#include <al/alc.h>
#include <AL/al.h>
#include <AL/alc.h>
#include <vorbis/vorbisfile.h>
#include "_multivc.h"
@ -14,6 +15,7 @@ ALCcontext * context=NULL;
char *ALdoing="";
int AL_Error;
int bufsize;
int openal_disabled = 0;
typedef struct SD
{
@ -29,6 +31,160 @@ typedef struct SD
sounddef1 sounds1[2];
#ifdef _WIN32
// Windows
static HANDLE hALDLL;
#else
#include <dlfcn.h>
static void *alhandle = NULL;
#endif
char *aldriver = NULL;
void (AL_APIENTRY * balGetSourcei)( ALuint sid, ALenum param, ALint* value );
void (AL_APIENTRY * balSourcef)( ALuint sid, ALenum param, ALfloat value );
void (AL_APIENTRY * balSourcePlay)( ALuint sid );
void (AL_APIENTRY * balSourcePause)( ALuint sid );
ALCenum (ALC_APIENTRY * balcGetError)( ALCdevice *device );
ALenum (AL_APIENTRY * balGetError)( void );
void (AL_APIENTRY * balBufferData)( ALuint bid, ALenum format, const ALvoid* data, ALsizei size, ALsizei freq );
void (AL_APIENTRY * balGenBuffers)( ALsizei n, ALuint* buffers );
void (AL_APIENTRY * balGenSources)( ALsizei n, ALuint* sources );
void (AL_APIENTRY * balSourcei)( ALuint sid, ALenum param, ALint value );
void (AL_APIENTRY * balSourceQueueBuffers)( ALuint sid, ALsizei numEntries, const ALuint *bids );
void (AL_APIENTRY * balSourceStop)( ALuint sid );
void (AL_APIENTRY * balSourceUnqueueBuffers)( ALuint sid, ALsizei numEntries, ALuint *bids );
void (AL_APIENTRY * bbalDeleteSources)( ALsizei n, const ALuint* sources );
ALCboolean (ALC_APIENTRY * balcMakeContextCurrent)( ALCcontext *context );
void (AL_APIENTRY * balDeleteSources)( ALsizei n, const ALuint* sources );
void (AL_APIENTRY * balDeleteBuffers)( ALsizei n, const ALuint* buffers );
void (ALC_APIENTRY * balcDestroyContext)( ALCcontext *context );
ALCboolean (ALC_APIENTRY * balcCloseDevice)( ALCdevice *device );
ALCdevice *(ALC_APIENTRY * balcOpenDevice)( const ALCchar *devicename );
ALCcontext *(ALC_APIENTRY * balcCreateContext)( ALCdevice *device, const ALCint* attrlist );
const ALchar* (AL_APIENTRY * balGetString)( ALenum param );
static void * algetproc_(const char *s, int *err, int fatal)
{
void *t;
#if defined _WIN32
t = (void*)GetProcAddress(hALDLL,s);
#else
t = (void*)dlsym(alhandle,s);
#endif
if (!t && fatal)
{
initprintf("Failed to find %s in %s\n", s, aldriver);
*err = 1;
}
return t;
}
#define ALGETPROC(s) algetproc_(s,&err,1)
#define ALGETPROCSOFT(s) algetproc_(s,&err,0)
int unloadaldriver(void)
{
#ifdef _WIN32
if (!hALDLL) return 0;
#endif
free(aldriver);
aldriver = NULL;
#ifdef _WIN32
FreeLibrary(hALDLL);
hALDLL = NULL;
#else
if (alhandle) dlclose(alhandle);
alhandle = NULL;
#endif
balGetSourcei = NULL;
balSourcef = NULL;
balSourcePlay = NULL;
balSourcePause = NULL;
balcGetError = NULL;
balGetError = NULL;
balBufferData = NULL;
balGenBuffers = NULL;
balGenSources = NULL;
balSourcei = NULL;
balSourceQueueBuffers = NULL;
balSourceStop = NULL;
balSourceUnqueueBuffers = NULL;
bbalDeleteSources = NULL;
balcMakeContextCurrent = NULL;
balDeleteSources = NULL;
balDeleteBuffers = NULL;
balcDestroyContext = NULL;
balcCloseDevice = NULL;
balcOpenDevice = NULL;
balcCreateContext = NULL;
balGetString = NULL;
return 0;
}
int loadaldriver(void)
{
void *t;
int err=0;
char *driver;
#ifdef _WIN32
if (hALDLL) return 0;
#endif
// if (!driver)
{
#ifdef _WIN32
driver = "OpenAL32.DLL";
#elif defined __APPLE__
driver = "/System/Library/Frameworks/OpenGL.framework/OpenGL"; // FIXME: like I know anything about Apple. Hah.
#else
driver = "libopenal.so";
#endif
}
initprintf("Loading %s\n",driver);
#if defined _WIN32
hALDLL = LoadLibrary(driver);
if (!hALDLL) return -1;
#else
alhandle = dlopen(driver, RTLD_NOW|RTLD_GLOBAL);
if (!alhandle) return -1;
#endif
aldriver = strdup(driver);
balGetSourcei = ALGETPROC("alGetSourcei");
balSourcef = ALGETPROC("alSourcef");
balSourcePlay = ALGETPROC("alSourcePlay");
balSourcePause = ALGETPROC("alSourcePause");
balcGetError = ALGETPROC("alcGetError");
balGetError = ALGETPROC("alGetError");
balBufferData = ALGETPROC("alBufferData");
balGenBuffers = ALGETPROC("alGenBuffers");
balGenSources = ALGETPROC("alGenSources");
balSourcei = ALGETPROC("alSourcei");
balSourceQueueBuffers = ALGETPROC("alSourceQueueBuffers");
balSourceStop = ALGETPROC("alSourceStop");
balSourceUnqueueBuffers = ALGETPROC("alSourceUnqueueBuffers");
balDeleteSources = ALGETPROC("alDeleteSources");
balcMakeContextCurrent = ALGETPROC("alcMakeContextCurrent");
balDeleteSources = ALGETPROC("alDeleteSources");
balDeleteBuffers = ALGETPROC("alDeleteBuffers");
balcDestroyContext = ALGETPROC("alcDestroyContext");
balcCloseDevice = ALGETPROC("alcCloseDevice");
balcOpenDevice = ALGETPROC("alcOpenDevice");
balcCreateContext = ALGETPROC("alcCreateContext");
balGetString = ALGETPROC("alGetString");
if (err) unloadaldriver();
return err;
}
char *ALC_ErrorString(int code)
{
switch(code)
@ -93,50 +249,66 @@ char *AL_ErrorString(int code)
}
void check(int show)
{
AL_Error=alcGetError(device);
AL_Error=balcGetError(device);
if(AL_Error!=ALC_NO_ERROR&&show)initprintf("%s(%s)\n",ALC_ErrorString(AL_Error),ALdoing);
AL_Error=alGetError();
AL_Error=balGetError();
if(AL_Error!= AL_NO_ERROR&&show)initprintf("%s(%s)\n", AL_ErrorString(AL_Error),ALdoing);
}
extern ov_callbacks cb;
void AL_Init()
int AL_Init()
{
if (loadaldriver())
{
initprintf("Failed loading OpenAL driver.\n");
openal_disabled = 1;
return 1;
}
ALdoing="Init";
// device=alcOpenDevice(ud.config.HardwareAL?"Generic Hardware":"Generic Software");
device=alcOpenDevice("Generic Hardware");check(1);
if(device){context=alcCreateContext(device,NULL);check(1);}
device=balcOpenDevice(NULL);
check(1);
if(device)
{
context=balcCreateContext(device,NULL);
check(1);
}
if(context)
{
alcMakeContextCurrent(context);check(1);
balcMakeContextCurrent(context);check(1);
initprintf("OpenAL Information:\n"
" Version: %s\n"
" Vendor: %s\n\n",alGetString(AL_VERSION),alGetString(AL_VENDOR));
" Vendor: %s\n\n",balGetString(AL_VERSION),balGetString(AL_VENDOR));
} else initprintf("OpenAL initialisation failed. Try http://www.openal.org/\n");
ALdoing="Open";
alGenBuffers(16, sounds1[1].buffers);
balGenBuffers(16, sounds1[1].buffers);
check(1);
alGenSources(1,&sounds1[1].source);
balGenSources(1,&sounds1[1].source);
check(1);
return 0;
}
void AL_Shutdown()
{
ALdoing="Delete source";
alDeleteSources(1,&sounds1[1].source);
balDeleteSources(1,&sounds1[1].source);
check(1);
ALdoing="Delete buffers";
alDeleteBuffers(16, sounds1[1].buffers);
balDeleteBuffers(16, sounds1[1].buffers);
check(1);
ALdoing="Shut";
alcMakeContextCurrent(NULL);
balcMakeContextCurrent(NULL);
check(1);
alcDestroyContext(context);
balcDestroyContext(context);
check(1);
alcCloseDevice(device);
balcCloseDevice(device);
unloadaldriver();
}
#define BUFFER_SIZE (4096 * 4*8*8)
@ -152,21 +324,21 @@ void open1(char *ptr,int sizef,char loop);
void AL_Pause() {if(music.def.size)alSourcePause(music.source);}
void AL_Continue() {if(music.def.size)alSourcePlay(music.source);}
void AL_Pause() {if(music.def.size)balSourcePause(music.source);}
void AL_Continue() {if(music.def.size)balSourcePlay(music.source);}
void AL_Update() {if(music.def.size&&!update(0))AL_stop();}
int AL_isntALmusic() {return !music.def.size;}
void AL_SetMusicVolume(int volume)
{
AL_MusicVolume=volume;
if(music.def.size)alSourcef(music.source,AL_GAIN,volume/(255.));
if(music.def.size)balSourcef(music.source,AL_GAIN,volume/(255.));
}
int isplaying()
{
ALenum state;
alGetSourcei(music.source,AL_SOURCE_STATE,&state);
balGetSourcei(music.source,AL_SOURCE_STATE,&state);
return state==AL_PLAYING;
}
@ -177,7 +349,7 @@ int update()
ALuint buffer;
ALdoing="update";
alGetSourcei(music.source,AL_BUFFERS_PROCESSED,&processed);
balGetSourcei(music.source,AL_BUFFERS_PROCESSED,&processed);
check(1);
if(processed)
switch(music.type)
@ -185,12 +357,12 @@ int update()
case 1:
while(processed--)
{
alSourceUnqueueBuffers(music.source,1,&buffer);
balSourceUnqueueBuffers(music.source,1,&buffer);
check(1);
active=stream(buffer);
if(active)
{
alSourceQueueBuffers(music.source,1,&buffer);
balSourceQueueBuffers(music.source,1,&buffer);
check(1);
}
}
@ -205,17 +377,17 @@ void AL_stop()
if(!music.def.size)return;
alSourceStop(music.source);
alGetSourcei(music.source,AL_BUFFERS_QUEUED,&queued);
balSourceStop(music.source);
balGetSourcei(music.source,AL_BUFFERS_QUEUED,&queued);
ALdoing="release";
while(queued--)
{
alSourceUnqueueBuffers(music.source,1,&buffer);
balSourceUnqueueBuffers(music.source,1,&buffer);
check(1);
}
alDeleteSources(1,&music.source);check(1);
alDeleteBuffers(2, music.buffers);check(1);
balDeleteSources(1,&music.source);check(1);
balDeleteBuffers(2, music.buffers);check(1);
if(music.type==1)ov_clear(&music.def.oggStream);
Bmemset(&music,0,sizeof(sounddef1));
@ -235,7 +407,7 @@ int stream(ALuint buffer)
}
if(!size)return 0;
ALdoing="stream";
alBufferData(buffer,music.format,pcm,size,music.rate);
balBufferData(buffer,music.format,pcm,size,music.rate);
check(1);
return 1;
}
@ -278,15 +450,15 @@ void AL_PlaySong(char *ptr,int loop)
}
ALdoing="Open";
alGenBuffers(2, music.buffers);check(1);
alGenSources(1,&music.source);check(1);
alSourcei(music.source,AL_SOURCE_RELATIVE,AL_TRUE);
balGenBuffers(2, music.buffers);check(1);
balGenSources(1,&music.source);check(1);
balSourcei(music.source,AL_SOURCE_RELATIVE,AL_TRUE);
switch(music.type)
{
case 1: stream(music.buffers[0]);
if(!stream(music.buffers[1]))bf=1;
alSourceQueueBuffers(music.source,bf,music.buffers);
balSourceQueueBuffers(music.source,bf,music.buffers);
break;
}

View file

@ -3,7 +3,7 @@
#include <vorbis/vorbisfile.h>
void AL_Init();
int AL_Init();
void AL_Shutdown();
void AL_Update();
char *AL_ErrorString(int code);
@ -23,4 +23,6 @@ typedef struct sounddef
unsigned size;
OggVorbis_File oggStream;
}sounddef;
int openal_disabled;
#endif

View file

@ -32,6 +32,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "util_lib.h"
#include "osd.h"
#ifdef USE_OPENAL
#include "openal.h"
#endif
#define LOUDESTVOLUME 150
int backflag,numenvsnds;
@ -389,10 +393,12 @@ int xyzsound(int num,int i,int x,int y,int z)
voice = FX_PlayLoopedVOC(g_sounds[num].ptr, start, start + g_sounds[num].soundsiz,
pitch,sndist>>6,sndist>>6,0,g_sounds[num].pr,num);
#ifdef USE_OPENAL
else
else if (!openal_disabled)
{
if (*g_sounds[num].ptr == 'O')
voice = FX_PlayLoopedOGG(g_sounds[num].ptr, start, start + g_sounds[num].soundsiz,
pitch,sndist>>6,sndist>>6,0,g_sounds[num].pr,num);
}
#endif
else
voice = FX_PlayLoopedWAV(g_sounds[num].ptr, start, start + g_sounds[num].soundsiz,
@ -403,9 +409,11 @@ int xyzsound(int num,int i,int x,int y,int z)
if (*g_sounds[num].ptr == 'C')
voice = FX_PlayVOC3D(g_sounds[ num ].ptr,pitch,sndang>>6,sndist>>6, g_sounds[num].pr, num);
#ifdef USE_OPENAL
else
else if (!openal_disabled)
{
if (*g_sounds[num].ptr == 'O')
voice = FX_PlayOGG3D(g_sounds[ num ].ptr,pitch,sndang>>6,sndist>>6, g_sounds[num].pr, num);
}
#endif
else
voice = FX_PlayWAV3D(g_sounds[ num ].ptr,pitch,sndang>>6,sndist>>6, g_sounds[num].pr, num);
@ -470,12 +478,14 @@ void sound(int num)
pitch,LOUDESTVOLUME,LOUDESTVOLUME,LOUDESTVOLUME,g_sounds[num].pr,num);
}
#ifdef USE_OPENAL
else
if (*g_sounds[num].ptr == 'O')
else if (!openal_disabled)
{
start = (int)*(unsigned short *)(g_sounds[num].ptr + 0x14);
voice = FX_PlayLoopedOGG(g_sounds[num].ptr, start, start + g_sounds[num].soundsiz,
pitch,LOUDESTVOLUME,LOUDESTVOLUME,LOUDESTVOLUME,g_sounds[num].pr,num);
if (*g_sounds[num].ptr == 'O')
{
start = (int)*(unsigned short *)(g_sounds[num].ptr + 0x14);
voice = FX_PlayLoopedOGG(g_sounds[num].ptr, start, start + g_sounds[num].soundsiz,
pitch,LOUDESTVOLUME,LOUDESTVOLUME,LOUDESTVOLUME,g_sounds[num].pr,num);
}
}
#endif
else
@ -490,9 +500,11 @@ void sound(int num)
if (*g_sounds[num].ptr == 'C')
voice = FX_PlayVOC3D(g_sounds[ num ].ptr, pitch,0,255-LOUDESTVOLUME,g_sounds[num].pr, num);
#ifdef USE_OPENAL
else
else if (!openal_disabled)
{
if (*g_sounds[num].ptr == 'O')
voice = FX_PlayOGG3D(g_sounds[ num ].ptr, pitch,0,255-LOUDESTVOLUME,g_sounds[num].pr, num);
}
#endif
else
voice = FX_PlayWAV3D(g_sounds[ num ].ptr, pitch,0,255-LOUDESTVOLUME,g_sounds[num].pr, num);