OpenAL sound code (default now instead of SDL_mixer), some misc fixes
git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@141 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
+10
-6
@@ -33,15 +33,19 @@ SDL-image
|
||||
Homepage: http://www.libsdl.org/projects/SDL_image/
|
||||
Download: http://www.libsdl.org/projects/SDL_image/release/
|
||||
|
||||
SDL-mixer
|
||||
A sound mixing library used with SDL.
|
||||
Homepage: http://www.libsdl.org/projects/SDL_mixer/
|
||||
Download: http://www.libsdl.org/projects/SDL_mixer/release/
|
||||
|
||||
SDL-sound
|
||||
A sound loader library used with SDL.
|
||||
An audio format decoder library.
|
||||
Homepage: http://www.icculus.org/SDL_sound/
|
||||
Download: http://www.icculus.org/SDL_sound/downloads/
|
||||
Win32 users maybe need to get few updated dll's from: http://www.cc.jyu.fi/~mimakole/sc2/sdl_sound_dlls.zip
|
||||
If compiling this yourself, be sure ogg vorbis and libmikmod (or libmodplug) support is compiled in.
|
||||
|
||||
OpenAL
|
||||
A cross-platform spatialized audio library.
|
||||
Homepage: http://www.openal.org
|
||||
Linux download via CVS: http://opensource.creative.com
|
||||
Win32 SDK download: http://ftp://opensource.creative.com/pub/sdk/OpenALSDK.exe
|
||||
|
||||
|
||||
If you find these aren't enough, or if you know the names
|
||||
of the corresponding RPM etc. packages, please report to
|
||||
|
||||
@@ -67,6 +67,25 @@ Glitches (don't crash the game, medium priority):
|
||||
crash anymore. This means the memory will not be freed until after the
|
||||
complete battle (not just one fight). There's no permanent memory leak
|
||||
though.
|
||||
- OpenAL sound code problems:
|
||||
- On Linux, volume control (AL_GAIN) doesn't work for streams.
|
||||
This prevents also music fade in/out from working.
|
||||
Most probably this is a Linux OpenAL implementation bug itself, and
|
||||
authors have been informed.
|
||||
- Occasional clipping/popping/etc artifacts
|
||||
- Maybe caused by buggy soundcard drivers also
|
||||
- Some unimplemented functions (for oscilloscope and dialogue seeking)
|
||||
- Occasionally some speech oggs don't play
|
||||
- When mod music is looping, there's some volume fade at the end of tune,
|
||||
then it starts playing again. Should this happen? (modplug only?)
|
||||
- Stock SDL_sound package for VC is outdated and win32 users have to get
|
||||
few new .dll's to ensure proper operation
|
||||
- Perhaps we should integrate mikmod to our code and use vorbis libs
|
||||
directly to avoid depending on SDL_sound at all?
|
||||
- If OpenAL causes too many problems, reverting to SDL_mixer is easy as
|
||||
all code is preserved related to that, etc.. but SDL_mixer is pretty
|
||||
sucky for various reasons so I'd like to avoid that.
|
||||
|
||||
|
||||
Implementation bugs (low priority):
|
||||
- The main thread is still created by a direct all to the SDL function,
|
||||
@@ -137,7 +156,3 @@ Questions:
|
||||
which we can free when no more memory is available, to allow an emergency
|
||||
save.
|
||||
- How about an ISO image for a self-contained linux CD which boots into SC2?
|
||||
- SDL_mixer really doesn't seem to meet our needs.. should we
|
||||
a) write our own mixing routines
|
||||
b) look for alternatives (OpenAL perhaps?)
|
||||
c) what?
|
||||
|
||||
+5
-5
@@ -27,8 +27,8 @@ AM_MAINTAINER_MODE
|
||||
|
||||
# Configurables
|
||||
|
||||
CFLAGS="$CFLAGS -g -W -Wall -DHAVE_OPENGL -DSDL_PTHREADS -DGFXMODULE_SDL -DSOUNDMODULE_SDL"
|
||||
CPPFLAGS="$CPPFLAGS -g -W -Wall -DHAVE_OPENGL -DSDL_PTHREADS -DGFXMODULE_SDL -DSOUNDMODULE_SDL"
|
||||
CFLAGS="$CFLAGS -g -W -Wall -DHAVE_OPENGL -DSDL_PTHREADS -DGFXMODULE_SDL -DSOUNDMODULE_OPENAL"
|
||||
CPPFLAGS="$CPPFLAGS -g -W -Wall -DHAVE_OPENGL -DSDL_PTHREADS -DGFXMODULE_SDL -DSOUNDMODULE_OPENAL"
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
@@ -68,11 +68,11 @@ AC_CHECK_FUNCS([strupr])
|
||||
# Check for SDL
|
||||
SDL_VERSION=1.2.2
|
||||
AM_PATH_SDL($SDL_VERSION, , AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!]))
|
||||
AC_CHECK_LIB(SDL_mixer, main, , AC_MSG_ERROR([Your system is missing libSDL_mixer!]),`sdl-config --libs`)
|
||||
AC_CHECK_LIB(SDL_image, main, , AC_MSG_ERROR([Your system is missing libSDL_image!]),`sdl-config --libs`)
|
||||
AC_CHECK_LIB(SDL_sound, main, , AC_MSG_ERROR([Your system is missing libSDL_sound!]),`sdl-config --libs`)
|
||||
AC_CHECK_LIB(openal, main, , AC_MSG_ERROR([Your system is missing libopenal!]),"-lm")
|
||||
#AC_CHECK_LIB(SDL_mixer, main, , AC_MSG_ERROR([Your system is missing libSDL_mixer!]),`sdl-config --libs`)
|
||||
#AC_CHECK_HEADERS(SDL/SDL_image.h, , AC_MSG_ERROR([Your system is missing SDL_image.h!]))
|
||||
#AC_CHECK_HEADERS(SDL/SDL_mixer.h, , AC_MSG_ERROR([Your system is missing SDL_mixer.h!]))
|
||||
|
||||
# Select platform dependent OpenGL libs.. (tweak your platform here)
|
||||
case "$target" in
|
||||
@@ -211,7 +211,7 @@ AC_CONFIG_FILES([
|
||||
src/sc2code/libs/input/Makefile
|
||||
src/sc2code/libs/input/sdl/Makefile
|
||||
src/sc2code/libs/sound/Makefile
|
||||
src/sc2code/libs/sound/sdl/Makefile
|
||||
src/sc2code/libs/sound/openal/Makefile
|
||||
src/sc2code/libs/graphics/Makefile
|
||||
src/sc2code/libs/graphics/sdl/Makefile
|
||||
src/sc2code/libs/task/Makefile
|
||||
|
||||
@@ -42,7 +42,7 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I ".." /I "..\sc2code" /I "..\sc2code\libs" /I "..\sc2code\ships" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D _VW=320 /D _VH=240 /D "HAVE_OPENGL" /D "GFXMODULE_SDL" /D "SOUNDMODULE_SDL" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I ".." /I "..\sc2code" /I "..\sc2code\libs" /I "..\sc2code\ships" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D _VW=320 /D _VH=240 /D "HAVE_OPENGL" /D "GFXMODULE_SDL" /D "SOUNDMODULE_OPENAL" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -50,7 +50,7 @@ BSC32=bscmake.exe
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib SDL.lib SDLmain.lib SDL_image.lib SDL_mixer.lib SDL_sound.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"msvcrtd.lib" /out:"../../Content/Starcon2.exe"
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib SDL.lib SDLmain.lib SDL_image.lib SDL_sound.lib OpenAL32.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"msvcrtd.lib" /out:"../../Content/Starcon2.exe"
|
||||
|
||||
!ELSEIF "$(CFG)" == "Starcon2 - Win32 Debug"
|
||||
|
||||
@@ -66,7 +66,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I ".." /I "..\sc2code" /I "..\sc2code\libs" /I "..\sc2code\ships" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D _VW=320 /D _VH=240 /D "HAVE_OPENGL" /D "GFXMODULE_SDL" /D "SOUNDMODULE_SDL" /FR /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I ".." /I "..\sc2code" /I "..\sc2code\libs" /I "..\sc2code\ships" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D _VW=320 /D _VH=240 /D "HAVE_OPENGL" /D "GFXMODULE_SDL" /D "SOUNDMODULE_OPENAL" /FR /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -74,7 +74,7 @@ BSC32=bscmake.exe
|
||||
# ADD BSC32 /nologo /o"Starcon2.bsc"
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib SDL.lib SDLmain.lib SDL_image.lib SDL_mixer.lib SDL_sound.lib /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"msvcrt.lib" /out:"../../Content/Starcon2Debug.exe" /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib SDL.lib SDLmain.lib SDL_image.lib SDL_sound.lib OpenAL32.lib /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"msvcrt.lib" /out:"../../Content/Starcon2Debug.exe" /pdbtype:sept
|
||||
# SUBTRACT LINK32 /nodefaultlib
|
||||
|
||||
!ENDIF
|
||||
@@ -395,24 +395,36 @@ SOURCE=..\sc2code\libs\resource\resintrn.h
|
||||
# Begin Group "sound"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Group "sdl No. 2"
|
||||
# Begin Group "openal"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sc2code\libs\sound\sdl\modfuncs.c
|
||||
SOURCE=..\sc2code\libs\sound\openal\music.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sc2code\libs\sound\sdl\play.c
|
||||
SOURCE=..\sc2code\libs\sound\openal\sfx.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sc2code\libs\sound\sdl\sound.c
|
||||
SOURCE=..\sc2code\libs\sound\openal\sound.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sc2code\libs\sound\sdl\trackplayer.c
|
||||
SOURCE=..\sc2code\libs\sound\openal\sound.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sc2code\libs\sound\openal\stream.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sc2code\libs\sound\openal\stream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sc2code\libs\sound\openal\trackplayer.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
@@ -31,7 +31,7 @@ int ScreenHeight;
|
||||
int ScreenWidthActual;
|
||||
int ScreenHeightActual;
|
||||
int GraphicsDriver;
|
||||
int TFB_DEBUG_HALT;
|
||||
int TFB_DEBUG_HALT = 0;
|
||||
int BlendNumerator = 4;
|
||||
int BlendDenominator = 4;
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ enum
|
||||
|
||||
|
||||
int TFB_InitGraphics (int driver, int flags, int width, int height, int bpp);
|
||||
int TFB_CreateGamePlayThread (void);
|
||||
void TFB_UninitGraphics ();
|
||||
void TFB_ProcessEvents (void);
|
||||
|
||||
// 3DO Graphics Stuff
|
||||
|
||||
@@ -35,7 +35,6 @@ InitGraphics (int argc, char* argv[], COUNT KbytesRequired)
|
||||
BOOLEAN ret;
|
||||
|
||||
LoadDisplay (&_pCurDisplay);
|
||||
mem_init ();
|
||||
ActivateDisplay ();
|
||||
|
||||
DrawCommandQueue = TFB_DrawCommandQueue_Create ();
|
||||
@@ -50,7 +49,7 @@ UninitGraphics () // Also probably empty
|
||||
{
|
||||
// HFree (DrawCommandQueue); This is static now!
|
||||
|
||||
mem_uninit ();
|
||||
//mem_uninit ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -47,7 +47,6 @@ TFB_GL_InitGraphics (int driver, int flags, int width, int height, int bpp)
|
||||
|
||||
SDL_VideoDriverName (VideoName, sizeof (VideoName));
|
||||
fprintf (stderr, "SDL driver used: %s\n", VideoName);
|
||||
atexit (SDL_Quit);
|
||||
|
||||
fprintf (stderr, "SDL initialized.\n");
|
||||
fprintf (stderr, "Initializing Screen.\n");
|
||||
|
||||
@@ -48,7 +48,6 @@ TFB_Pure_InitGraphics (int driver, int flags, int width, int height, int bpp)
|
||||
// For Linux: x11 (default), dga, fbcon, directfb, svgalib,
|
||||
// ggi, aalib
|
||||
// For Windows: directx (default), windib
|
||||
atexit (SDL_Quit);
|
||||
|
||||
fprintf (stderr, "SDL initialized.\n");
|
||||
|
||||
|
||||
@@ -50,6 +50,8 @@ TFB_InitGraphics (int driver, int flags, int width, int height, int bpp)
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
atexit (TFB_UninitGraphics);
|
||||
|
||||
if (driver == TFB_GFXDRIVER_SDL_OPENGL)
|
||||
{
|
||||
#ifdef HAVE_OPENGL
|
||||
@@ -77,17 +79,10 @@ TFB_InitGraphics (int driver, int flags, int width, int height, int bpp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
TFB_CreateGamePlayThread ()
|
||||
void
|
||||
TFB_UninitGraphics (void)
|
||||
{
|
||||
TFB_DEBUG_HALT = 0;
|
||||
|
||||
GraphicsSem = SDL_CreateSemaphore (1);
|
||||
_MemorySem = SDL_CreateSemaphore (1);
|
||||
|
||||
SDL_CreateThread (Starcon2Main, NULL);
|
||||
|
||||
return 0;
|
||||
SDL_Quit ();
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -29,5 +29,6 @@ enum
|
||||
//#define TFB_INPUTFLAGS_ETC (1<<0)
|
||||
|
||||
int TFB_InitInput (int driver, int flags);
|
||||
void TFB_UninitInput (void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#ifdef GFXMODULE_SDL
|
||||
|
||||
#include "libs/graphics/sdl/sdl_common.h"
|
||||
#include "libs/input/input_common.h"
|
||||
|
||||
|
||||
Uint8 KeyboardDown[512];
|
||||
@@ -48,6 +49,8 @@ TFB_InitInput (int driver, int flags)
|
||||
int i;
|
||||
SDL_Joystick *Joystick1;
|
||||
|
||||
atexit (TFB_UninitInput);
|
||||
|
||||
if ((SDL_InitSubSystem(SDL_INIT_JOYSTICK)) == -1)
|
||||
{
|
||||
fprintf (stderr, "Couldn't initialize joystick subsystem: %s\n", SDL_GetError());
|
||||
@@ -86,6 +89,11 @@ TFB_InitInput (int driver, int flags)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
TFB_UninitInput (void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ProcessKeyboardEvent(const SDL_Event *Event)
|
||||
{
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Written by Mudry <mudry@user.sf.net>, protected by GNU GPL.
|
||||
# CVS $ Id: $
|
||||
|
||||
SUBDIRS = sdl
|
||||
SUBDIRS = openal
|
||||
|
||||
INCLUDES = @SDL_CFLAGS@ \
|
||||
-I$(top_srcdir)/src \
|
||||
@@ -12,6 +12,6 @@ INCLUDES = @SDL_CFLAGS@ \
|
||||
|
||||
noinst_LTLIBRARIES = libsound.la
|
||||
libsound_la_SOURCES = fileinst.c resinst.c sound_common.c
|
||||
libsound_la_LIBADD = sdl/libsdlsound.la
|
||||
libsound_la_LIBADD = openal/libopenalsound.la
|
||||
noinst_HEADERS = play.h redbook.h sndintrn.h trackplayer.h sound_common.h
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
# Automake template file.
|
||||
# Written by Mudry <mudry@user.sf.net>, protected by GNU GPL.
|
||||
# CVS $ Id: $
|
||||
|
||||
INCLUDES = @SDL_CFLAGS@ \
|
||||
-I$(top_srcdir)/src \
|
||||
-I$(top_srcdir)/src/sc2code \
|
||||
-I$(top_srcdir)/src/sc2code/libs
|
||||
|
||||
noinst_LTLIBRARIES = libopenalsound.la
|
||||
libopenalsound_la_SOURCES = music.c sfx.c sound.c stream.c trackplayer.c
|
||||
|
||||
noinst_HEADERS = sound.h stream.h
|
||||
|
||||
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* OpenAL specific code by Mika Kolehmainen, 2002-10-23
|
||||
*/
|
||||
|
||||
#ifdef SOUNDMODULE_OPENAL
|
||||
|
||||
#include "sound.h"
|
||||
|
||||
static MUSIC_REF curMusicRef;
|
||||
|
||||
void
|
||||
PLRPlaySong (MUSIC_REF MusicRef, BOOLEAN Continuous, BYTE Priority)
|
||||
{
|
||||
TFB_SoundSample **pmus;
|
||||
|
||||
LockMusicData (MusicRef, &pmus);
|
||||
if (pmus)
|
||||
{
|
||||
LockMutex (soundSource[MUSIC_SOURCE].stream_mutex);
|
||||
PlayStream ((*pmus), MUSIC_SOURCE, Continuous);
|
||||
UnlockMutex (soundSource[MUSIC_SOURCE].stream_mutex);
|
||||
|
||||
curMusicRef = MusicRef;
|
||||
}
|
||||
|
||||
(void) Priority; /* Satisfy compiler because of unused variable */
|
||||
}
|
||||
|
||||
void
|
||||
PLRStop (MUSIC_REF MusicRef)
|
||||
{
|
||||
if (MusicRef == curMusicRef || MusicRef == (MUSIC_REF)~0)
|
||||
{
|
||||
LockMutex (soundSource[MUSIC_SOURCE].stream_mutex);
|
||||
StopStream (MUSIC_SOURCE);
|
||||
UnlockMutex (soundSource[MUSIC_SOURCE].stream_mutex);
|
||||
UnlockMusicData (curMusicRef);
|
||||
|
||||
curMusicRef = 0;
|
||||
}
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
PLRPlaying (MUSIC_REF MusicRef)
|
||||
{
|
||||
if (curMusicRef && (MusicRef == curMusicRef || MusicRef == (MUSIC_REF)~0))
|
||||
{
|
||||
BOOLEAN playing;
|
||||
|
||||
LockMutex (soundSource[MUSIC_SOURCE].stream_mutex);
|
||||
playing = PlayingStream (MUSIC_SOURCE);
|
||||
UnlockMutex (soundSource[MUSIC_SOURCE].stream_mutex);
|
||||
|
||||
return playing;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
PLRPause (MUSIC_REF MusicRef)
|
||||
{
|
||||
if (MusicRef == curMusicRef || MusicRef == (MUSIC_REF)~0)
|
||||
{
|
||||
LockMutex (soundSource[MUSIC_SOURCE].stream_mutex);
|
||||
PauseStream (MUSIC_SOURCE);
|
||||
UnlockMutex (soundSource[MUSIC_SOURCE].stream_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PLRResume (MUSIC_REF MusicRef)
|
||||
{
|
||||
if (MusicRef == curMusicRef || MusicRef == (MUSIC_REF)~0)
|
||||
{
|
||||
LockMutex (soundSource[MUSIC_SOURCE].stream_mutex);
|
||||
ResumeStream (MUSIC_SOURCE);
|
||||
UnlockMutex (soundSource[MUSIC_SOURCE].stream_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
DestroyMusic (MUSIC_REF MusicRef)
|
||||
{
|
||||
return (FreeMusicData (MusicRef));
|
||||
}
|
||||
|
||||
void
|
||||
SetMusicVolume (COUNT Volume)
|
||||
{
|
||||
float f = (Volume / (ALfloat)MAX_VOLUME) * musicVolumeScale;
|
||||
musicVolume = Volume;
|
||||
alSourcef (soundSource[MUSIC_SOURCE].handle, AL_GAIN, f);
|
||||
}
|
||||
|
||||
MEM_HANDLE
|
||||
_GetMusicData (FILE *fp, DWORD length)
|
||||
{
|
||||
MEM_HANDLE h;
|
||||
extern char *_cur_resfile_name;
|
||||
|
||||
h = 0;
|
||||
if (_cur_resfile_name && (h = AllocMusicData (sizeof (void *))))
|
||||
{
|
||||
TFB_SoundSample **pmus;
|
||||
|
||||
LockMusicData (h, &pmus);
|
||||
if (!pmus)
|
||||
{
|
||||
UnlockMusicData (h);
|
||||
mem_release (h);
|
||||
h = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pmus = (TFB_SoundSample *) HMalloc (sizeof (TFB_SoundSample));
|
||||
|
||||
if (((*pmus)->decoder = Sound_NewSampleFromFile (_cur_resfile_name, NULL, 4096)) == 0)
|
||||
{
|
||||
fprintf (stderr, "_GetMusicData(): couldn't load %s\n", _cur_resfile_name);
|
||||
|
||||
UnlockMusicData (h);
|
||||
mem_release (h);
|
||||
h = 0;
|
||||
HFree (*pmus);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (stderr, "decoder %s rate %d channels %d\n", (*pmus)->decoder->decoder->description,
|
||||
(*pmus)->decoder->actual.rate, (*pmus)->decoder->actual.channels);
|
||||
alGenBuffers (NUM_SOUNDBUFFERS, (*pmus)->buffer);
|
||||
}
|
||||
}
|
||||
|
||||
UnlockMusicData (h);
|
||||
}
|
||||
|
||||
(void) fp; /* satisfy compiler (unused parameter) */
|
||||
(void) length; /* satisfy compiler (unused parameter) */
|
||||
return (h);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
_ReleaseMusicData (MEM_HANDLE handle)
|
||||
{
|
||||
TFB_SoundSample **pmus;
|
||||
|
||||
LockMusicData (handle, &pmus);
|
||||
if (pmus == 0)
|
||||
return (FALSE);
|
||||
|
||||
if ((*pmus)->decoder)
|
||||
{
|
||||
LockMutex (soundSource[MUSIC_SOURCE].stream_mutex);
|
||||
if (soundSource[MUSIC_SOURCE].sample == (*pmus))
|
||||
{
|
||||
StopStream (MUSIC_SOURCE);
|
||||
}
|
||||
UnlockMutex (soundSource[MUSIC_SOURCE].stream_mutex);
|
||||
|
||||
Sound_FreeSample ((*pmus)->decoder);
|
||||
alDeleteBuffers (NUM_SOUNDBUFFERS, (*pmus)->buffer);
|
||||
}
|
||||
HFree (*pmus);
|
||||
|
||||
UnlockMusicData (handle);
|
||||
mem_release (handle);
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* OpenAL specific code by Mika Kolehmainen, 2002-10-23
|
||||
*/
|
||||
|
||||
#ifdef SOUNDMODULE_OPENAL
|
||||
|
||||
#ifdef WIN32
|
||||
#include <io.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "sound.h"
|
||||
|
||||
|
||||
void
|
||||
PlayChannel (COUNT channel, PVOID sample, COUNT sample_length, COUNT loop_begin,
|
||||
COUNT loop_length, unsigned char priority)
|
||||
{
|
||||
TFB_SoundSample *tfb_sample = *(TFB_SoundSample**) sample;
|
||||
|
||||
//fprintf (stderr, "PlayChannel %d tfb_sample %x\n", channel, tfb_sample);
|
||||
|
||||
soundSource[channel].sample = tfb_sample;
|
||||
alSourceRewind (soundSource[channel].handle);
|
||||
alSourcei (soundSource[channel].handle, AL_BUFFER, tfb_sample->buffer[0]);
|
||||
alSourcePlay (soundSource[channel].handle);
|
||||
}
|
||||
|
||||
void
|
||||
StopChannel(COUNT channel, unsigned char Priority)
|
||||
{
|
||||
alSourceRewind (soundSource[channel].handle);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
ChannelPlaying (COUNT WhichChannel)
|
||||
{
|
||||
ALint state;
|
||||
|
||||
alGetSourcei (soundSource[WhichChannel].handle, AL_SOURCE_STATE, &state);
|
||||
if (state == AL_PLAYING)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
SetChannelVolume (COUNT channel, COUNT volume, BYTE priority)
|
||||
// I wonder what this whole priority business is...
|
||||
// I can probably ignore it.
|
||||
{
|
||||
alSourcef (soundSource[channel].handle, AL_GAIN,
|
||||
(volume / (ALfloat)MAX_VOLUME) * sfxVolumeScale);
|
||||
}
|
||||
|
||||
// Status: Ignored
|
||||
PBYTE
|
||||
GetSampleAddress (SOUND sound)
|
||||
// I might be prototyping this wrong, type-wise.
|
||||
{
|
||||
return ((PBYTE)GetSoundAddress (sound));
|
||||
}
|
||||
|
||||
// Status: Ignored
|
||||
COUNT
|
||||
GetSampleLength (SOUND sound)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Status: Ignored
|
||||
void
|
||||
SetChannelRate (COUNT channel, DWORD rate_hz, unsigned char priority)
|
||||
{
|
||||
}
|
||||
|
||||
// Status: Ignored
|
||||
COUNT
|
||||
GetSampleRate (SOUND sound)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
MEM_HANDLE
|
||||
_GetSoundBankData (FILE *fp, DWORD length)
|
||||
{
|
||||
#ifdef WIN32
|
||||
int omode;
|
||||
#endif
|
||||
int snd_ct, n;
|
||||
DWORD opos;
|
||||
char CurrentLine[1024], filename[1024];
|
||||
#define MAX_FX 256
|
||||
TFB_SoundSample *sndfx[MAX_FX];
|
||||
STRING_TABLE Snd;
|
||||
|
||||
opos = ftell (fp);
|
||||
|
||||
{
|
||||
char *s1, *s2;
|
||||
extern char *_cur_resfile_name;
|
||||
|
||||
if (_cur_resfile_name == 0
|
||||
|| (((s2 = 0), (s1 = strrchr (_cur_resfile_name, '/')) == 0)
|
||||
&& (s2 = strrchr (_cur_resfile_name, '\\')) == 0))
|
||||
n = 0;
|
||||
else
|
||||
{
|
||||
if (s2 > s1)
|
||||
s1 = s2;
|
||||
n = s1 - _cur_resfile_name + 1;
|
||||
strncpy (filename, _cur_resfile_name, n);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
omode = _setmode (fileno (fp), O_TEXT);
|
||||
#endif
|
||||
snd_ct = 0;
|
||||
while (fgets (CurrentLine, sizeof (CurrentLine), fp) && snd_ct < MAX_FX)
|
||||
{
|
||||
if (sscanf(CurrentLine, "%s", &filename[n]) == 1)
|
||||
{
|
||||
fprintf (stderr, "_GetSoundBankData(): loading %s\n", filename);
|
||||
|
||||
sndfx[snd_ct] = (TFB_SoundSample *) HMalloc (sizeof (TFB_SoundSample));
|
||||
sndfx[snd_ct]->decoder = Sound_NewSampleFromFile (filename, NULL, 4096);
|
||||
if (!sndfx[snd_ct]->decoder)
|
||||
{
|
||||
fprintf (stderr, "_GetSoundBankData(): couldn't load %s\n", filename);
|
||||
HFree (sndfx[snd_ct]);
|
||||
}
|
||||
else
|
||||
{
|
||||
Uint32 decoded_bytes;
|
||||
ALenum format;
|
||||
|
||||
decoded_bytes = Sound_DecodeAll (sndfx[snd_ct]->decoder);
|
||||
//fprintf (stderr, "decoded_bytes %d\n", decoded_bytes);
|
||||
|
||||
format = DetermineALFormat (sndfx[snd_ct]->decoder);
|
||||
|
||||
alGenBuffers (NUM_SOUNDBUFFERS, sndfx[snd_ct]->buffer);
|
||||
alBufferData (sndfx[snd_ct]->buffer[0], format,
|
||||
sndfx[snd_ct]->decoder->buffer, decoded_bytes,
|
||||
sndfx[snd_ct]->decoder->actual.rate);
|
||||
|
||||
Sound_FreeSample (sndfx[snd_ct]->decoder);
|
||||
sndfx[snd_ct]->decoder = NULL;
|
||||
|
||||
++snd_ct;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (stderr, "_GetSoundBankData: Bad file!\n");
|
||||
}
|
||||
|
||||
if (ftell (fp) - opos >= length)
|
||||
break;
|
||||
}
|
||||
#ifdef WIN32
|
||||
_setmode (fileno (fp), omode);
|
||||
#endif
|
||||
|
||||
Snd = 0;
|
||||
if (snd_ct && (Snd = AllocStringTable (
|
||||
sizeof (STRING_TABLE_DESC)
|
||||
+ (sizeof (DWORD) * snd_ct)
|
||||
+ (sizeof (sndfx[0]) * snd_ct)
|
||||
)))
|
||||
{
|
||||
STRING_TABLEPTR fxTab;
|
||||
|
||||
LockStringTable (Snd, &fxTab);
|
||||
if (fxTab == 0)
|
||||
{
|
||||
while (snd_ct--)
|
||||
{
|
||||
if (sndfx[snd_ct]->decoder)
|
||||
Sound_FreeSample (sndfx[snd_ct]->decoder);
|
||||
HFree (sndfx[snd_ct]);
|
||||
}
|
||||
|
||||
FreeStringTable (Snd);
|
||||
Snd = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD *offs, StringOffs;
|
||||
|
||||
fxTab->StringCount = snd_ct;
|
||||
fxTab->flags = 0;
|
||||
offs = fxTab->StringOffsets;
|
||||
StringOffs = sizeof (STRING_TABLE_DESC) + (sizeof (DWORD) * snd_ct);
|
||||
memcpy ((BYTE *)fxTab + StringOffs, sndfx, sizeof (sndfx[0]) * snd_ct);
|
||||
do
|
||||
{
|
||||
*offs++ = StringOffs;
|
||||
StringOffs += sizeof (sndfx[0]);
|
||||
} while (snd_ct--);
|
||||
UnlockStringTable (Snd);
|
||||
}
|
||||
}
|
||||
|
||||
return ((MEM_HANDLE)Snd);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
_ReleaseSoundBankData (MEM_HANDLE Snd)
|
||||
{
|
||||
STRING_TABLEPTR fxTab;
|
||||
|
||||
LockStringTable (Snd, &fxTab);
|
||||
if (fxTab)
|
||||
{
|
||||
int snd_ct;
|
||||
TFB_SoundSample **sptr;
|
||||
|
||||
snd_ct = fxTab->StringCount;
|
||||
sptr = (TFB_SoundSample **)((BYTE *)fxTab + fxTab->StringOffsets[0]);
|
||||
while (snd_ct--)
|
||||
{
|
||||
Sound_FreeSample ((*sptr)->decoder);
|
||||
alDeleteBuffers (NUM_SOUNDBUFFERS, (*sptr)->buffer);
|
||||
HFree (*sptr);
|
||||
*sptr++ = 0;
|
||||
}
|
||||
UnlockStringTable (Snd);
|
||||
FreeStringTable (Snd);
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
DestroySound(SOUND_REF target)
|
||||
{
|
||||
return (_ReleaseSoundBankData (target));
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* OpenAL specific code by Mika Kolehmainen, 2002-10-23
|
||||
*/
|
||||
|
||||
#ifdef SOUNDMODULE_OPENAL
|
||||
|
||||
#include "sound.h"
|
||||
|
||||
ALCcontext *alcContext = NULL;
|
||||
ALCdevice *alcDevice = NULL;
|
||||
ALfloat listenerPos[] = {0.0f, 0.0f, 0.0f};
|
||||
ALfloat listenerVel[] = {0.0f, 0.0f, 0.0f};
|
||||
ALfloat listenerOri[] = {0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f};
|
||||
TFB_SoundSource soundSource[NUM_SOUNDSOURCES];
|
||||
static Task StreamDecoderTask;
|
||||
|
||||
|
||||
int
|
||||
TFB_InitSound (int driver, int flags, int frequency)
|
||||
{
|
||||
int i;
|
||||
|
||||
fprintf (stderr, "Initializing OpenAL.\n");
|
||||
atexit (TFB_UninitSound);
|
||||
|
||||
#ifdef WIN32
|
||||
alcDevice = alcOpenDevice ((ALubyte*)"DirectSound3D");
|
||||
#else
|
||||
alcDevice = alcOpenDevice (NULL);
|
||||
#endif
|
||||
|
||||
if (!alcDevice)
|
||||
{
|
||||
fprintf (stderr,"Couldn't initialize OpenAL: %d\n", alcGetError (NULL));
|
||||
exit (-1);
|
||||
}
|
||||
|
||||
alcContext = alcCreateContext (alcDevice, NULL);
|
||||
if (!alcContext)
|
||||
{
|
||||
fprintf (stderr, "Couldn't create OpenAL context: %d\n", alcGetError (alcDevice));
|
||||
}
|
||||
|
||||
alcMakeContextCurrent (alcContext);
|
||||
|
||||
fprintf (stderr, "OpenAL initialized.\n");
|
||||
fprintf (stderr, " version: %s\n", alGetString (AL_VERSION));
|
||||
fprintf (stderr, " vendor: %s\n", alGetString (AL_VENDOR));
|
||||
fprintf (stderr, " renderer: %s\n", alGetString (AL_RENDERER));
|
||||
fprintf (stderr, " device: %s\n",
|
||||
alcGetString (alcDevice, ALC_DEFAULT_DEVICE_SPECIFIER));
|
||||
|
||||
fprintf (stderr, "Initializing SDL_sound.\n");
|
||||
if (!Sound_Init())
|
||||
{
|
||||
fprintf(stderr, "SDL_sound initialization failed: %s\n", Sound_GetError());
|
||||
exit (-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
const Sound_DecoderInfo **sdi;
|
||||
Sound_Version compiled, linked;
|
||||
|
||||
SOUND_VERSION (&compiled);
|
||||
Sound_GetLinkedVersion (&linked);
|
||||
|
||||
fprintf (stderr, "SDL_sound initialized.\n");
|
||||
fprintf (stderr, " compiled version: %d.%d.%d linked version: %d.%d.%d\n",
|
||||
compiled.major, compiled.minor, compiled.patch,
|
||||
linked.major, linked.minor, linked.patch);
|
||||
|
||||
for (sdi = Sound_AvailableDecoders(); *sdi != NULL; ++sdi)
|
||||
{
|
||||
fprintf (stderr, " supported format: %s\n",
|
||||
(*sdi)->description);
|
||||
}
|
||||
}
|
||||
|
||||
alListenerfv (AL_POSITION, listenerPos);
|
||||
alListenerfv (AL_VELOCITY, listenerVel);
|
||||
alListenerfv (AL_ORIENTATION, listenerOri);
|
||||
|
||||
for (i = 0; i < NUM_SOUNDSOURCES; ++i)
|
||||
{
|
||||
float zero[3] = {0.0f, 0.0f, 0.0f};
|
||||
|
||||
alGenSources (1, &soundSource[i].handle);
|
||||
alSourcei (soundSource[i].handle, AL_LOOPING, AL_FALSE);
|
||||
alSourcefv (soundSource[i].handle, AL_POSITION, zero);
|
||||
alSourcefv (soundSource[i].handle, AL_VELOCITY, zero);
|
||||
alSourcefv (soundSource[i].handle, AL_DIRECTION, zero);
|
||||
|
||||
soundSource[i].sample = NULL;
|
||||
soundSource[i].stream_looping = FALSE;
|
||||
soundSource[i].stream_should_be_playing = FALSE;
|
||||
soundSource[i].stream_mutex = CreateMutex ();
|
||||
}
|
||||
|
||||
SetSFXVolume (sfxVolumeScale);
|
||||
SetSpeechVolume (speechVolumeScale);
|
||||
SetMusicVolume (musicVolume);
|
||||
|
||||
// NOTE: change this if implementing 3D sound stuff
|
||||
alDistanceModel (AL_NONE);
|
||||
|
||||
StreamDecoderTask = AssignTask (StreamDecoderTaskFunc, 1024,
|
||||
"audio stream decoder");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
TFB_UninitSound (void)
|
||||
{
|
||||
ConcludeTask (StreamDecoderTask);
|
||||
alcMakeContextCurrent (NULL);
|
||||
alcDestroyContext (alcContext);
|
||||
alcContext = NULL;
|
||||
alcCloseDevice (alcDevice);
|
||||
alcDevice = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
StopSound (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = FIRST_SFX_SOURCE; i <= LAST_SFX_SOURCE; ++i)
|
||||
{
|
||||
alSourceRewind (soundSource[i].handle);
|
||||
}
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
SoundPlaying (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_SOUNDSOURCES; ++i)
|
||||
{
|
||||
if (soundSource[i].sample && soundSource[i].sample->decoder)
|
||||
{
|
||||
BOOLEAN result;
|
||||
LockMutex (soundSource[i].stream_mutex);
|
||||
result = PlayingStream (i);
|
||||
UnlockMutex (soundSource[i].stream_mutex);
|
||||
if (result)
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ALint state;
|
||||
alGetSourcei (soundSource[i].handle, AL_SOURCE_STATE, &state);
|
||||
if (state == AL_PLAYING)
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Status: Ignored
|
||||
BOOLEAN
|
||||
InitSound (int argc, char* argv[])
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Status: Ignored
|
||||
void
|
||||
UninitSound (void)
|
||||
{
|
||||
}
|
||||
|
||||
ALenum
|
||||
DetermineALFormat (Sound_Sample *sample)
|
||||
{
|
||||
ALenum format;
|
||||
|
||||
if (sample->actual.channels == 1)
|
||||
{
|
||||
if (sample->actual.format == AUDIO_U8 ||
|
||||
sample->actual.format == AUDIO_S8)
|
||||
{
|
||||
format = AL_FORMAT_MONO8;
|
||||
}
|
||||
else
|
||||
{
|
||||
format = AL_FORMAT_MONO16;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sample->actual.format == AUDIO_U8 ||
|
||||
sample->actual.format == AUDIO_S8)
|
||||
{
|
||||
format = AL_FORMAT_STEREO8;
|
||||
}
|
||||
else
|
||||
{
|
||||
format = AL_FORMAT_STEREO16;
|
||||
}
|
||||
}
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
void SetSFXVolume (float volume)
|
||||
{
|
||||
int i;
|
||||
for (i = FIRST_SFX_SOURCE; i <= LAST_SFX_SOURCE; ++i)
|
||||
{
|
||||
alSourcef (soundSource[i].handle, AL_GAIN, sfxVolumeScale);
|
||||
}
|
||||
}
|
||||
|
||||
void SetSpeechVolume (float volume)
|
||||
{
|
||||
alSourcef (soundSource[SPEECH_SOURCE].handle, AL_GAIN, speechVolumeScale);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* OpenAL specific code by Mika Kolehmainen, 2002-10-23
|
||||
*/
|
||||
|
||||
#include "libs/strings/strintrn.h"
|
||||
#include "libs/sound/sndintrn.h"
|
||||
#include "libs/graphics/sdl/sdl_common.h"
|
||||
#include "libs/sound/sound_common.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <al.h>
|
||||
#include <alc.h>
|
||||
#include <SDL_sound.h>
|
||||
#else
|
||||
#include <AL/al.h>
|
||||
#include <AL/alc.h>
|
||||
#include <SDL/SDL_sound.h>
|
||||
#endif
|
||||
|
||||
|
||||
#define NUM_SOUNDBUFFERS 8
|
||||
#define FIRST_SFX_SOURCE 0
|
||||
#define LAST_SFX_SOURCE 4
|
||||
#define MUSIC_SOURCE (LAST_SFX_SOURCE + 1)
|
||||
#define SPEECH_SOURCE (MUSIC_SOURCE + 1)
|
||||
#define NUM_SOUNDSOURCES (SPEECH_SOURCE + 1)
|
||||
|
||||
// audio data
|
||||
typedef struct tfb_soundsample
|
||||
{
|
||||
Sound_Sample *decoder; // if != NULL, sound is streamed
|
||||
ALuint buffer[NUM_SOUNDBUFFERS]; // if not streamed, only buffer[0] is used
|
||||
} TFB_SoundSample;
|
||||
|
||||
// equivalent to channel in legacy sound code
|
||||
typedef struct tfb_soundsource
|
||||
{
|
||||
TFB_SoundSample *sample;
|
||||
ALuint handle;
|
||||
BOOLEAN stream_looping;
|
||||
BOOLEAN stream_should_be_playing;
|
||||
Mutex stream_mutex;
|
||||
} TFB_SoundSource;
|
||||
|
||||
|
||||
extern ALCcontext *alcContext; // OpenAL context
|
||||
extern ALCdevice *alcDevice; // OpenAL device
|
||||
extern ALfloat listenerPos[]; // listener position (3 floats)
|
||||
extern ALfloat listenerVel[]; // listener velocity (3 floats)
|
||||
extern ALfloat listenerOri[]; // listener orientation (two 3 float vectors, "look at" and "up")
|
||||
extern TFB_SoundSource soundSource[];
|
||||
|
||||
ALenum DetermineALFormat (Sound_Sample *sample);
|
||||
void SetSFXVolume (float volume);
|
||||
void SetSpeechVolume (float volume);
|
||||
|
||||
#include "stream.h"
|
||||
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* By Mika Kolehmainen, 2002-10-23
|
||||
*/
|
||||
|
||||
#ifdef SOUNDMODULE_OPENAL
|
||||
|
||||
#include "sound.h"
|
||||
|
||||
BOOLEAN speech_callback = FALSE;
|
||||
|
||||
|
||||
void
|
||||
PlayStream (TFB_SoundSample *sample, ALuint source, BOOLEAN looping)
|
||||
{
|
||||
int i;
|
||||
ALenum format = DetermineALFormat (sample->decoder);
|
||||
|
||||
StopStream (source);
|
||||
|
||||
Sound_Rewind (sample->decoder);
|
||||
soundSource[source].sample = sample;
|
||||
|
||||
alSourcei (soundSource[source].handle, AL_LOOPING, AL_FALSE);
|
||||
|
||||
for (i = 0; i < NUM_SOUNDBUFFERS; ++i)
|
||||
{
|
||||
Uint32 decoded_bytes;
|
||||
|
||||
if (sample->decoder->flags & SOUND_SAMPLEFLAG_EOF ||
|
||||
sample->decoder->flags & SOUND_SAMPLEFLAG_ERROR)
|
||||
break;
|
||||
|
||||
decoded_bytes = Sound_Decode (sample->decoder);
|
||||
//fprintf (stderr, "PlayStream(): source %d sample %x decoded_bytes %d\n", source, sample, decoded_bytes);
|
||||
if (decoded_bytes == 0)
|
||||
break;
|
||||
|
||||
alBufferData (sample->buffer[i], format, sample->decoder->buffer,
|
||||
decoded_bytes, sample->decoder->actual.rate);
|
||||
|
||||
alSourceQueueBuffers (soundSource[source].handle, 1, &sample->buffer[i]);
|
||||
}
|
||||
|
||||
soundSource[source].stream_looping = looping;
|
||||
soundSource[source].stream_should_be_playing = TRUE;
|
||||
alSourcePlay (soundSource[source].handle);
|
||||
}
|
||||
|
||||
void
|
||||
StopStream (ALuint source)
|
||||
{
|
||||
ALuint queued, processed;
|
||||
ALuint *buffer;
|
||||
|
||||
soundSource[source].stream_should_be_playing = FALSE;
|
||||
soundSource[source].sample = NULL;
|
||||
alSourceStop (soundSource[source].handle);
|
||||
alGetSourcei (soundSource[source].handle, AL_BUFFERS_PROCESSED, &processed);
|
||||
alGetSourcei (soundSource[source].handle, AL_BUFFERS_QUEUED, &queued);
|
||||
|
||||
//fprintf (stderr, "StopStream(): source %d processed %d queued %d NUM_SOUNDBUFFERS %d\n",
|
||||
// source, processed, queued, NUM_SOUNDBUFFERS);
|
||||
|
||||
buffer = (ALuint *) HMalloc (sizeof (ALuint) * processed);
|
||||
alSourceUnqueueBuffers (soundSource[source].handle, processed, buffer);
|
||||
HFree (buffer);
|
||||
}
|
||||
|
||||
void
|
||||
PauseStream (ALuint source)
|
||||
{
|
||||
soundSource[source].stream_should_be_playing = FALSE;
|
||||
alSourcePause (soundSource[source].handle);
|
||||
}
|
||||
|
||||
void
|
||||
ResumeStream (ALuint source)
|
||||
{
|
||||
soundSource[source].stream_should_be_playing = TRUE;
|
||||
alSourcePlay (soundSource[source].handle);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
PlayingStream (ALuint source)
|
||||
{
|
||||
return soundSource[source].stream_should_be_playing;
|
||||
}
|
||||
|
||||
int
|
||||
StreamDecoderTaskFunc (void *data)
|
||||
{
|
||||
Task task = (Task)data;
|
||||
|
||||
while (!Task_ReadState (task, TASK_EXIT))
|
||||
{
|
||||
int i;
|
||||
|
||||
SleepThread (1);
|
||||
|
||||
for (i = MUSIC_SOURCE; i < NUM_SOUNDSOURCES; ++i)
|
||||
{
|
||||
ALuint processed;
|
||||
//ALuint queued;
|
||||
ALint state;
|
||||
ALboolean finished = AL_FALSE;
|
||||
|
||||
LockMutex (soundSource[i].stream_mutex);
|
||||
|
||||
if (!soundSource[i].sample ||
|
||||
!soundSource[i].sample->decoder ||
|
||||
!soundSource[i].stream_should_be_playing ||
|
||||
soundSource[i].sample->decoder->flags & SOUND_SAMPLEFLAG_EOF ||
|
||||
soundSource[i].sample->decoder->flags & SOUND_SAMPLEFLAG_ERROR)
|
||||
{
|
||||
UnlockMutex (soundSource[i].stream_mutex);
|
||||
continue;
|
||||
}
|
||||
|
||||
alGetSourcei (soundSource[i].handle, AL_BUFFERS_PROCESSED, &processed);
|
||||
if (processed == 0)
|
||||
{
|
||||
alGetSourcei (soundSource[i].handle, AL_SOURCE_STATE, &state);
|
||||
if (state != AL_PLAYING)
|
||||
{
|
||||
//fprintf (stderr, "StreamDecoderTaskFunc(): forcing alSourcePlay on %d\n", i);
|
||||
alSourcePlay (soundSource[i].handle);
|
||||
}
|
||||
}
|
||||
|
||||
//alGetSourcei (soundSource[i].handle, AL_BUFFERS_QUEUED, &queued);
|
||||
//fprintf (stderr, "StreamDecoderTaskFunc(): source %d, processed %d queued %d\n", i, processed, queued);
|
||||
|
||||
while (processed && !finished)
|
||||
{
|
||||
ALenum format, error;
|
||||
ALuint buffer;
|
||||
Uint32 decoded_bytes;
|
||||
|
||||
alGetError (); // clear error state
|
||||
|
||||
alSourceUnqueueBuffers (soundSource[i].handle, 1, &buffer);
|
||||
if ((error = alGetError()) != AL_NO_ERROR)
|
||||
{
|
||||
fprintf (stderr, "StreamDecoderTaskFunc(): OpenAL error after alSourceUnqueueBuffers: %x, source %d\n", error, i);
|
||||
break;
|
||||
}
|
||||
|
||||
decoded_bytes = Sound_Decode (soundSource[i].sample->decoder);
|
||||
|
||||
if (soundSource[i].sample->decoder->flags & SOUND_SAMPLEFLAG_EOF)
|
||||
{
|
||||
if (i == SPEECH_SOURCE && speech_callback)
|
||||
{
|
||||
advance_track (0);
|
||||
finished = AL_TRUE;
|
||||
soundSource[i].stream_should_be_playing = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (soundSource[i].stream_looping)
|
||||
{
|
||||
if ((Sound_Rewind (soundSource[i].sample->decoder)) == 0)
|
||||
{
|
||||
fprintf (stderr, "StreamDecoderTaskFunc(): Sound_Rewind error %s, source %d\n",
|
||||
Sound_GetError(), i);
|
||||
finished = AL_TRUE;
|
||||
soundSource[i].stream_should_be_playing = FALSE;
|
||||
}
|
||||
else if (decoded_bytes == 0)
|
||||
{
|
||||
decoded_bytes = Sound_Decode (soundSource[i].sample->decoder);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
finished = AL_TRUE;
|
||||
soundSource[i].stream_should_be_playing = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (soundSource[i].sample->decoder->flags & SOUND_SAMPLEFLAG_ERROR)
|
||||
{
|
||||
fprintf (stderr, "StreamDecoderTaskFunc(): Sound_Decode error %s, source %d\n",
|
||||
Sound_GetError(), i);
|
||||
soundSource[i].stream_should_be_playing = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (decoded_bytes > 0)
|
||||
{
|
||||
format = DetermineALFormat (soundSource[i].sample->decoder);
|
||||
alBufferData (buffer, format, soundSource[i].sample->decoder->buffer,
|
||||
decoded_bytes, soundSource[i].sample->decoder->actual.rate);
|
||||
|
||||
if ((error = alGetError()) != AL_NO_ERROR)
|
||||
{
|
||||
fprintf (stderr, "StreamDecoderTaskFunc(): OpenAL error after alBufferData: %x, source %d, decoded_bytes %d\n", error, i, decoded_bytes);
|
||||
finished = AL_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
alSourceQueueBuffers (soundSource[i].handle, 1, &buffer);
|
||||
|
||||
if ((error = alGetError()) != AL_NO_ERROR)
|
||||
{
|
||||
fprintf (stderr, "StreamDecoderTaskFunc(): OpenAL error after alSourceQueueBuffers: %x, source %d, decoded_bytes %d\n", error, i, decoded_bytes);
|
||||
finished = AL_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
processed--;
|
||||
}
|
||||
|
||||
UnlockMutex (soundSource[i].stream_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
FinishTask (task);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* OpenAL specific code by Mika Kolehmainen, 2002-10-23
|
||||
*/
|
||||
|
||||
#ifndef STREAM_H
|
||||
#define STREAM_H
|
||||
|
||||
void PlayStream (TFB_SoundSample *sample, ALuint source, BOOLEAN looping);
|
||||
void StopStream (ALuint source);
|
||||
void PauseStream (ALuint source);
|
||||
void ResumeStream (ALuint source);
|
||||
BOOLEAN PlayingStream (ALuint source);
|
||||
int StreamDecoderTaskFunc (void *data);
|
||||
|
||||
extern BOOLEAN speech_callback;
|
||||
void advance_track (int channel_finished);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,266 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* OpenAL specific code by Mika Kolehmainen, 2002-10-23
|
||||
*/
|
||||
|
||||
#ifdef SOUNDMODULE_OPENAL
|
||||
|
||||
#include "sound.h"
|
||||
#include "libs/sound/trackplayer.h"
|
||||
|
||||
extern int do_subtitles (UNICODE *pStr);
|
||||
|
||||
static int tct, tcur, no_voice;
|
||||
|
||||
#define MAX_CLIPS 50
|
||||
static struct
|
||||
{
|
||||
int text_spliced;
|
||||
UNICODE *text;
|
||||
TFB_SoundSample *sample;
|
||||
} track_clip[MAX_CLIPS];
|
||||
|
||||
|
||||
void
|
||||
JumpTrack (int abort)
|
||||
{
|
||||
speech_callback = FALSE;
|
||||
|
||||
if (track_clip[tcur].sample)
|
||||
{
|
||||
LockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
|
||||
StopStream (SPEECH_SOURCE);
|
||||
UnlockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
|
||||
}
|
||||
|
||||
no_voice = 1;
|
||||
do_subtitles ((void *)~0);
|
||||
|
||||
if (abort)
|
||||
tcur = tct;
|
||||
}
|
||||
|
||||
void
|
||||
advance_track (int channel_finished)
|
||||
{
|
||||
if (channel_finished <= 0)
|
||||
{
|
||||
if (channel_finished == 0)
|
||||
++tcur;
|
||||
if (tcur < tct)
|
||||
{
|
||||
LockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
|
||||
PlayStream (track_clip[tcur].sample, SPEECH_SOURCE, FALSE);
|
||||
UnlockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
|
||||
do_subtitles (0);
|
||||
}
|
||||
else if (channel_finished == 0)
|
||||
{
|
||||
--tcur;
|
||||
no_voice = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ResumeTrack ()
|
||||
{
|
||||
if (tcur < tct)
|
||||
{
|
||||
ALint state;
|
||||
|
||||
LockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
|
||||
alGetSourcei (soundSource[SPEECH_SOURCE].handle, AL_SOURCE_STATE, &state);
|
||||
UnlockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
|
||||
|
||||
if (!soundSource[SPEECH_SOURCE].stream_should_be_playing &&
|
||||
state == AL_PAUSED)
|
||||
{
|
||||
LockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
|
||||
ResumeStream (SPEECH_SOURCE);
|
||||
UnlockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
|
||||
}
|
||||
else if (!no_voice)
|
||||
{
|
||||
if (tcur == 0)
|
||||
{
|
||||
speech_callback = TRUE;
|
||||
}
|
||||
advance_track (-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
COUNT
|
||||
PlayingTrack ()
|
||||
{
|
||||
if (tcur < tct)
|
||||
{
|
||||
if (do_subtitles (track_clip[tcur].text) ||
|
||||
(no_voice && ++tcur < tct && do_subtitles (0)))
|
||||
{
|
||||
return (tcur + 1);
|
||||
}
|
||||
else if (track_clip[tcur].sample)
|
||||
{
|
||||
COUNT result;
|
||||
|
||||
LockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
|
||||
result = (PlayingStream (SPEECH_SOURCE) ? (COUNT)(tcur + 1) : 0);
|
||||
UnlockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
StopTrack ()
|
||||
{
|
||||
speech_callback = FALSE;
|
||||
LockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
|
||||
StopStream (SPEECH_SOURCE);
|
||||
UnlockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
|
||||
|
||||
while (tct--)
|
||||
{
|
||||
if (track_clip[tct].text_spliced)
|
||||
{
|
||||
track_clip[tct].text_spliced = 0;
|
||||
HFree (track_clip[tct].text);
|
||||
track_clip[tct].text = 0;
|
||||
}
|
||||
if (track_clip[tct].sample)
|
||||
{
|
||||
if (track_clip[tct].sample->decoder)
|
||||
{
|
||||
Sound_FreeSample (track_clip[tct].sample->decoder);
|
||||
alDeleteBuffers (NUM_SOUNDBUFFERS, track_clip[tct].sample->buffer);
|
||||
}
|
||||
HFree (track_clip[tct].sample);
|
||||
track_clip[tct].sample = 0;
|
||||
}
|
||||
}
|
||||
tct = tcur = 0;
|
||||
no_voice = 0;
|
||||
do_subtitles (0);
|
||||
}
|
||||
|
||||
void
|
||||
SpliceTrack (UNICODE *TrackName, UNICODE *TrackText)
|
||||
{
|
||||
if (TrackText)
|
||||
{
|
||||
if (TrackName == 0)
|
||||
{
|
||||
if (tct)
|
||||
{
|
||||
int slen1, slen2;
|
||||
UNICODE *oTT;
|
||||
|
||||
oTT = track_clip[tct - 1].text;
|
||||
slen1 = wstrlen (oTT);
|
||||
slen2 = wstrlen (TrackText);
|
||||
if (track_clip[tct - 1].text_spliced)
|
||||
track_clip[tct - 1].text = HRealloc (oTT, slen1 + slen2 + 1);
|
||||
else
|
||||
{
|
||||
track_clip[tct - 1].text = HMalloc (slen1 + slen2 + 1);
|
||||
wstrcpy (track_clip[tct - 1].text, oTT);
|
||||
track_clip[tct - 1].text_spliced = 1;
|
||||
}
|
||||
wstrcpy (&track_clip[tct - 1].text[slen1], TrackText);
|
||||
}
|
||||
}
|
||||
else if (tct < MAX_CLIPS)
|
||||
{
|
||||
track_clip[tct].text = TrackText;
|
||||
track_clip[tct].text_spliced = 0;
|
||||
|
||||
fprintf (stderr, "SpliceTrack(): loading %s\n", TrackName);
|
||||
|
||||
track_clip[tct].sample = (TFB_SoundSample *) HMalloc (sizeof (TFB_SoundSample));
|
||||
track_clip[tct].sample->decoder = Sound_NewSampleFromFile (TrackName, NULL, 4096);
|
||||
|
||||
if (track_clip[tct].sample->decoder)
|
||||
{
|
||||
fprintf (stderr, "decoder %s rate %d channels %d\n",
|
||||
track_clip[tct].sample->decoder->decoder->description,
|
||||
track_clip[tct].sample->decoder->actual.rate,
|
||||
track_clip[tct].sample->decoder->actual.channels);
|
||||
|
||||
alGenBuffers (NUM_SOUNDBUFFERS, track_clip[tct].sample->buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (stderr, "SpliceTrack(): couldn't load %s: %s\n",
|
||||
TrackName, Sound_GetError());
|
||||
HFree (track_clip[tct].sample);
|
||||
track_clip[tct].sample = NULL;
|
||||
}
|
||||
|
||||
++tct;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PauseTrack ()
|
||||
{
|
||||
/*if (tcur < tct && track_clip[tcur].chunk)
|
||||
Mix_Pause (VOICE_CHANNEL);*/
|
||||
}
|
||||
|
||||
void
|
||||
FastReverse ()
|
||||
{
|
||||
JumpTrack (0);
|
||||
no_voice = 0;
|
||||
tcur = 0;
|
||||
ResumeTrack ();
|
||||
}
|
||||
|
||||
void
|
||||
FastForward ()
|
||||
{
|
||||
JumpTrack (0);
|
||||
//no_voice = 0;
|
||||
}
|
||||
|
||||
int
|
||||
GetSoundData (char* data)
|
||||
// Returns the data size. Only used in oscill.c
|
||||
{
|
||||
//fprintf (stderr, "Unimplemented function activated: GetSoundData()\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Status: Unimplemented
|
||||
int
|
||||
GetSoundInfo (int *length, int *offset)
|
||||
// Umm... How does it know which sound?
|
||||
// Answer: only used in oscill.c slider so sound must be current speech
|
||||
{
|
||||
//fprintf (stderr, "Unimplemented function activated: GetSoundInfo()\n");
|
||||
*length = 1;
|
||||
*offset = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -26,47 +26,56 @@
|
||||
int
|
||||
TFB_InitSound (int driver, int flags, int frequency)
|
||||
{
|
||||
// NOTE: SDL_sound should be compiled without mikmod support
|
||||
// or potential lockup occurs because both
|
||||
// SDL_mixer and SDL_sound try to initialize it
|
||||
|
||||
char SoundcardName[256];
|
||||
int audio_rate,audio_channels;
|
||||
Uint16 audio_format;
|
||||
SDL_version compile_version;
|
||||
|
||||
fprintf (stderr, "Initializing SDL audio subsystem.\n");
|
||||
if ((SDL_InitSubSystem(SDL_INIT_AUDIO)) == -1)
|
||||
{
|
||||
fprintf (stderr, "Couldn't initialize audio subsystem: %s\n", SDL_GetError());
|
||||
exit(-1);
|
||||
}
|
||||
fprintf (stderr, "SDL audio subsystem initialized.\n");
|
||||
|
||||
fprintf (stderr, "Initializing SDL_mixer.\n");
|
||||
if (Mix_OpenAudio(frequency, AUDIO_S16, 2, 2048))
|
||||
{
|
||||
fprintf (stderr, "Unable to open audio: %s\n", Mix_GetError());
|
||||
exit (-1);
|
||||
}
|
||||
|
||||
fprintf (stderr, "SDL_mixer initialized.\n");
|
||||
atexit (Mix_CloseAudio);
|
||||
|
||||
SDL_AudioDriverName (SoundcardName, sizeof (SoundcardName));
|
||||
Mix_QuerySpec (&audio_rate, &audio_format, &audio_channels);
|
||||
fprintf (stderr, " opened %s at %d Hz %d bit %s, %d bytes audio buffer\n",
|
||||
SoundcardName, audio_rate, audio_format & 0xFF,
|
||||
audio_channels > 1 ? "stereo" : "mono", 2048);
|
||||
MIX_VERSION (&compile_version);
|
||||
fprintf (stderr, " compiled with SDL_mixer version: %d.%d.%d\n",
|
||||
compile_version.major,
|
||||
compile_version.minor,
|
||||
compile_version.patch);
|
||||
fprintf (stderr, " running with SDL_mixer version: %d.%d.%d\n",
|
||||
Mix_Linked_Version()->major,
|
||||
Mix_Linked_Version()->minor,
|
||||
Mix_Linked_Version()->patch);
|
||||
|
||||
fprintf (stderr, "Initializing SDL_sound.\n");
|
||||
fprintf (stderr, "(NOTE: if this locks up, compile SDL_sound without libmikmod support)\n");
|
||||
fflush (stderr);
|
||||
if (!Sound_Init())
|
||||
{
|
||||
fprintf(stderr, "Sound_Init() failed: %s\n", Sound_GetError());
|
||||
exit (-1);
|
||||
}
|
||||
|
||||
SDL_AudioDriverName (SoundcardName, sizeof (SoundcardName));
|
||||
|
||||
Mix_QuerySpec (&audio_rate, &audio_format, &audio_channels);
|
||||
fprintf (stderr, "Opened %s at %d Hz %d bit %s, %d bytes audio buffer\n",
|
||||
SoundcardName, audio_rate, audio_format & 0xFF,
|
||||
audio_channels > 1 ? "stereo" : "mono", 2048);
|
||||
|
||||
MIX_VERSION (&compile_version);
|
||||
fprintf (stderr, "Compiled with SDL_mixer version: %d.%d.%d\n",
|
||||
compile_version.major,
|
||||
compile_version.minor,
|
||||
compile_version.patch);
|
||||
fprintf (stderr, "Running with SDL_mixer version: %d.%d.%d\n",
|
||||
Mix_Linked_Version()->major,
|
||||
Mix_Linked_Version()->minor,
|
||||
Mix_Linked_Version()->patch);
|
||||
fprintf (stderr, "SDL_sound initialized.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,10 @@
|
||||
#include "libs/sound/sound_common.h"
|
||||
#include "libs/tasklib.h"
|
||||
|
||||
extern int _music_volume;
|
||||
int musicVolume = (MAX_VOLUME >> 1);
|
||||
float musicVolumeScale = 1.0f;
|
||||
float sfxVolumeScale = 1.0f;
|
||||
float speechVolumeScale = 1.0f;
|
||||
|
||||
static Task FadeTask;
|
||||
static SIZE TTotal;
|
||||
@@ -33,7 +36,7 @@ fade_task (void *data)
|
||||
DWORD StartTime, CurTime;
|
||||
Task task = (Task) data;
|
||||
|
||||
volume_beg = _music_volume;
|
||||
volume_beg = musicVolume;
|
||||
StartTime = CurTime = GetTimeCounter ();
|
||||
do
|
||||
{
|
||||
@@ -58,7 +61,7 @@ FadeMusic (BYTE end_vol, SIZE TimeInterval)
|
||||
|
||||
if (FadeTask)
|
||||
{
|
||||
volume_end = _music_volume;
|
||||
volume_end = musicVolume;
|
||||
TTotal = 1;
|
||||
do
|
||||
TaskSwitch ();
|
||||
|
||||
@@ -29,5 +29,11 @@ enum
|
||||
//#define TFB_SOUNDFLAGS_ETC (1<<0)
|
||||
|
||||
int TFB_InitSound (int driver, int flags, int frequency);
|
||||
void TFB_UninitSound (void);
|
||||
|
||||
extern int musicVolume;
|
||||
extern float musicVolumeScale;
|
||||
extern float sfxVolumeScale;
|
||||
extern float speechVolumeScale;
|
||||
|
||||
#endif
|
||||
|
||||
+40
-4
@@ -61,6 +61,7 @@ main (int argc, char *argv[])
|
||||
int gfxflags = 0;
|
||||
int width = 640, height = 480, bpp = 16;
|
||||
int frequency = 44100;
|
||||
int vol;
|
||||
char contentdir[1000];
|
||||
|
||||
int option_index = 0, c;
|
||||
@@ -76,6 +77,9 @@ main (int argc, char *argv[])
|
||||
{"tv", 0, NULL, 't'},
|
||||
{"contentdir", 1, NULL, 'c'},
|
||||
{"help", 0, NULL, 'h'},
|
||||
{"musicvol", 1, NULL, 'M'},
|
||||
{"sfxvol", 1, NULL, 'S'},
|
||||
{"speechvol", 1, NULL, 'T'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
@@ -85,7 +89,7 @@ main (int argc, char *argv[])
|
||||
strcpy (contentdir, "../../content");
|
||||
#endif
|
||||
|
||||
while ((c = getopt_long(argc, argv, "r:d:fobq:ptc:?h", long_options, &option_index)) != -1)
|
||||
while ((c = getopt_long(argc, argv, "r:d:fobq:ptc:?hM:S:T:", long_options, &option_index)) != -1)
|
||||
{
|
||||
switch (c) {
|
||||
case 'r':
|
||||
@@ -115,6 +119,30 @@ main (int argc, char *argv[])
|
||||
case 'c':
|
||||
sscanf(optarg, "%s", contentdir);
|
||||
break;
|
||||
case 'M':
|
||||
sscanf(optarg, "%d", &vol);
|
||||
if (vol < 0)
|
||||
vol = 0;
|
||||
if (vol > 100)
|
||||
vol = 100;
|
||||
musicVolumeScale = vol / 100.0f;
|
||||
break;
|
||||
case 'S':
|
||||
sscanf(optarg, "%d", &vol);
|
||||
if (vol < 0)
|
||||
vol = 0;
|
||||
if (vol > 100)
|
||||
vol = 100;
|
||||
sfxVolumeScale = vol / 100.0f;
|
||||
break;
|
||||
case 'T':
|
||||
sscanf(optarg, "%d", &vol);
|
||||
if (vol < 0)
|
||||
vol = 0;
|
||||
if (vol > 100)
|
||||
vol = 100;
|
||||
speechVolumeScale = vol / 100.0f;
|
||||
break;
|
||||
default:
|
||||
printf ("\nOption %s not found!\n", long_options[option_index].name);
|
||||
case '?':
|
||||
@@ -122,7 +150,7 @@ main (int argc, char *argv[])
|
||||
printf("\nThe Ur-Quan Masters\n");
|
||||
printf("Options:\n");
|
||||
printf(" -r, --res=WIDTHxHEIGHT\n");
|
||||
printf(" -d, --bpp=BITSPERPLANE\n");
|
||||
printf(" -d, --bpp=BITSPERPIXEL\n");
|
||||
printf(" -f, --fullscreen\n");
|
||||
printf(" -o, --opengl\n");
|
||||
printf(" -b, --bilinear\n");
|
||||
@@ -130,6 +158,9 @@ main (int argc, char *argv[])
|
||||
printf(" -p, --fps\n");
|
||||
printf(" -t, --tv\n");
|
||||
printf(" -c, --contentdir=CONTENTDIR\n");
|
||||
printf(" -M, --musicvol=VOLUME (0-100)\n");
|
||||
printf(" -S, --sfxvol=VOLUME (0-100)\n");
|
||||
printf(" -T, --speechvol=VOLUME (0-100)\n");
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
@@ -140,11 +171,16 @@ main (int argc, char *argv[])
|
||||
InitThreadSystem ();
|
||||
InitTimeSystem ();
|
||||
InitTaskSystem ();
|
||||
|
||||
_MemorySem = CreateSemaphore (1);
|
||||
GraphicsSem = CreateSemaphore (1);
|
||||
mem_init ();
|
||||
|
||||
TFB_InitGraphics (gfxdriver, gfxflags, width, height, bpp);
|
||||
TFB_InitSound (TFB_SOUNDDRIVER_SDL, 0, frequency);
|
||||
TFB_InitInput (TFB_INPUTDRIVER_SDL, 0);
|
||||
|
||||
TFB_CreateGamePlayThread ();
|
||||
AssignTask (Starcon2Main, 1024, "Starcon2Main");
|
||||
|
||||
for (;;)
|
||||
{
|
||||
@@ -152,5 +188,5 @@ main (int argc, char *argv[])
|
||||
TFB_FlushGraphics ();
|
||||
}
|
||||
|
||||
return 0;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user