From 791d9ced6cfd2a2dd7f983e30b78a63157c06f0c Mon Sep 17 00:00:00 2001 From: gewlitys Date: Sat, 5 Jul 2003 22:33:48 +0000 Subject: [PATCH] Added support for positional (stereo) sound effects, currently works only with OpenAL git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@1021 8092fc87-c524-0410-9efc-e669fe64eaf9 --- sc2/ChangeLog | 2 + sc2/doc/users/manual.txt | 5 + sc2/src/options.c | 1 + sc2/src/options.h | 2 +- sc2/src/sc2code/element.h | 10 +- sc2/src/sc2code/gameinp.c | 2 +- sc2/src/sc2code/libs/sndlib.h | 13 +- sc2/src/sc2code/libs/sound/mixsdl/mixer.c | 6 + sc2/src/sc2code/libs/sound/mixsdl/mixer.h | 3 + .../sc2code/libs/sound/mixsdl/sound_mixsdl.h | 2 + .../sc2code/libs/sound/openal/sound_openal.c | 9 +- sc2/src/sc2code/libs/sound/sfx.c | 54 +++++++-- sc2/src/sc2code/libs/sound/sound.c | 1 + sc2/src/sc2code/libs/sound/sound.h | 1 + sc2/src/sc2code/libs/sound/sound_chooser.c | 12 ++ sc2/src/sc2code/libs/sound/sound_chooser.h | 3 + sc2/src/sc2code/melee.c | 4 +- sc2/src/sc2code/misc.c | 2 +- sc2/src/sc2code/pickmele.c | 4 +- sc2/src/sc2code/planets/devices.c | 6 +- sc2/src/sc2code/planets/lander.c | 28 ++--- sc2/src/sc2code/planets/report.c | 2 +- sc2/src/sc2code/planets/scan.c | 2 +- sc2/src/sc2code/process.c | 111 +++++++++++++++++- sc2/src/sc2code/settings.c | 8 +- sc2/src/sc2code/ship.c | 13 +- sc2/src/sc2code/ships/androsyn/androsyn.c | 2 +- sc2/src/sc2code/ships/arilou/arilou.c | 2 +- sc2/src/sc2code/ships/blackurq/blackurq.c | 2 +- sc2/src/sc2code/ships/chenjesu/chenjesu.c | 14 +-- sc2/src/sc2code/ships/chmmr/chmmr.c | 7 +- sc2/src/sc2code/ships/druuge/druuge.c | 2 +- sc2/src/sc2code/ships/human/human.c | 2 +- sc2/src/sc2code/ships/ilwrath/ilwrath.c | 4 +- sc2/src/sc2code/ships/melnorme/melnorme.c | 14 ++- sc2/src/sc2code/ships/mmrnmhrm/mmrnmhrm.c | 2 +- sc2/src/sc2code/ships/mycon/mycon.c | 2 +- sc2/src/sc2code/ships/orz/orz.c | 8 +- sc2/src/sc2code/ships/pkunk/pkunk.c | 4 +- sc2/src/sc2code/ships/sis_ship/sis_ship.c | 2 +- sc2/src/sc2code/ships/slylandr/slylandr.c | 2 +- sc2/src/sc2code/ships/spathi/spathi.c | 8 +- sc2/src/sc2code/ships/syreen/syreen.c | 2 +- sc2/src/sc2code/ships/thradd/thradd.c | 2 +- sc2/src/sc2code/ships/umgah/umgah.c | 2 +- sc2/src/sc2code/ships/urquan/urquan.c | 12 +- sc2/src/sc2code/ships/utwig/utwig.c | 4 +- sc2/src/sc2code/ships/vux/vux.c | 4 +- sc2/src/sc2code/ships/yehat/yehat.c | 2 +- sc2/src/sc2code/ships/zoqfot/zoqfot.c | 2 +- sc2/src/sc2code/starcon.h | 3 +- sc2/src/sc2code/tactrans.c | 6 +- sc2/src/sc2code/weapon.c | 2 +- sc2/src/starcon2.c | 8 +- 54 files changed, 322 insertions(+), 110 deletions(-) diff --git a/sc2/ChangeLog b/sc2/ChangeLog index 19fa20ee4..6ab0af463 100644 --- a/sc2/ChangeLog +++ b/sc2/ChangeLog @@ -1,4 +1,6 @@ Changes towards version 0.3: +- Added support for positional (stereo) sound effects, currently + works only with OpenAL -Mika - Fixed screen transitions from homeworld conversations (bug #348) -Michael - Fixed Fwiffo join_us_refusals initialization (bug #405) -Mika - Fix Druuge transactions to not elevate crew costs baselessly (bug #235), diff --git a/sc2/doc/users/manual.txt b/sc2/doc/users/manual.txt index 15c3125d7..fa2f40818 100644 --- a/sc2/doc/users/manual.txt +++ b/sc2/doc/users/manual.txt @@ -106,6 +106,11 @@ well with some sound cards. Use "none" as a last resort if you cannot get other drivers to work, or if you have no soundcard. + --stereosfx (no short version) + +Enables positional sound effects in melee. Currently works only when +using openal. + -u (or --nosubtitles) Disables subtitles. diff --git a/sc2/src/options.c b/sc2/src/options.c index 3bc591cf4..28e7c16db 100644 --- a/sc2/src/options.c +++ b/sc2/src/options.c @@ -37,6 +37,7 @@ int optMeleeScale = TFB_SCALE_TRILINEAR; char *configDir, *saveDir, *meleeDir; BOOLEAN optSubtitles = TRUE; +BOOLEAN optStereoSFX = FALSE; void prepareConfigDir (void) { diff --git a/sc2/src/options.h b/sc2/src/options.h index 03dcbed03..672576033 100644 --- a/sc2/src/options.h +++ b/sc2/src/options.h @@ -34,7 +34,7 @@ extern int optSmoothScroll; extern int optMeleeScale; extern BOOLEAN optSubtitles; - +extern BOOLEAN optStereoSFX; extern char *configDir; extern char *meleeDir; diff --git a/sc2/src/sc2code/element.h b/sc2/src/sc2code/element.h index 386481f1c..e973cc697 100644 --- a/sc2/src/sc2code/element.h +++ b/sc2/src/sc2code/element.h @@ -150,9 +150,9 @@ extern void FreeElement (HELEMENT hElement); #define GetTailElement() GetTailLink (&disp_q) #define LockElement(h,eptr) *(eptr) = (ELEMENTPTR)LockLink (&disp_q, h) #define UnlockElement(h) UnlockLink (&disp_q, h) -#define RemoveElement(h) RemoveQueue (&disp_q, h) #define GetPredElement(l) _GetPredLink (l) #define GetSuccElement(l) _GetSuccLink (l) +extern void RemoveElement (HLINK hLink); extern void RedrawQueue (BOOLEAN clear); extern BOOLEAN DeltaEnergy (ELEMENTPTR ElementPtr, SIZE @@ -160,9 +160,11 @@ extern BOOLEAN DeltaEnergy (ELEMENTPTR ElementPtr, SIZE extern BOOLEAN DeltaCrew (ELEMENTPTR ElementPtr, SIZE crew_delta); -extern void PlaySound (SOUND S, BYTE Priority); - -extern void ProcessSound (SOUND Sound); +extern void PlaySound (SOUND S, SoundPosition Pos, + ELEMENTPTR PositionalObject, BYTE Priority); +extern void ProcessSound (SOUND Sound, ELEMENTPTR PositionalObject); +extern SoundPosition CalcSoundPosition (ELEMENTPTR ElementPtr); +extern SoundPosition NotPositional (void); extern void PreProcessStatus (PELEMENT ShipPtr); extern void PostProcessStatus (PELEMENT ShipPtr); diff --git a/sc2/src/sc2code/gameinp.c b/sc2/src/sc2code/gameinp.c index a47fdfe0d..54e90280b 100644 --- a/sc2/src/sc2code/gameinp.c +++ b/sc2/src/sc2code/gameinp.c @@ -301,7 +301,7 @@ DoInput (PVOID pInputState, BOOLEAN resetInput) if (CurrentMenuState.select) S = SetAbsSoundIndex (S, 1); - PlaySoundEffect (S, 0, 0); + PlaySoundEffect (S, 0, NotPositional (), NULL, 0); } } while ((*((PINPUT_STATE_DESC)pInputState)->InputFunc) (pInputState)); diff --git a/sc2/src/sc2code/libs/sndlib.h b/sc2/src/sc2code/libs/sndlib.h index f6e64575a..bdf33379c 100644 --- a/sc2/src/sc2code/libs/sndlib.h +++ b/sc2/src/sc2code/libs/sndlib.h @@ -26,6 +26,12 @@ typedef STRING_TABLE SOUND_REF; typedef STRING SOUND; typedef STRINGPTR SOUNDPTR; +typedef struct soundposition +{ + BOOLEAN positional; + int x, y; +} SoundPosition; + #define InitSoundResources InitStringTableResources #define CaptureSound CaptureStringTable #define ReleaseSound ReleaseStringTable @@ -60,9 +66,12 @@ extern void PLRStop (MUSIC_REF MusicRef); extern BOOLEAN PLRPlaying (MUSIC_REF MusicRef); extern void PLRPause (MUSIC_REF MusicRef); extern void PLRResume (MUSIC_REF MusicRef); -extern void PlayChannel (COUNT Channel, PVOID lpSample, COUNT SampLen, - COUNT LoopBegin, COUNT LoopLen, BYTE Priority); +extern void PlayChannel (COUNT channel, PVOID sample, SoundPosition pos, + void *positional_object, unsigned char priority); extern BOOLEAN ChannelPlaying (COUNT Channel); +extern void * GetPositionalObject (COUNT channel); +extern void SetPositionalObject (COUNT channel, void *positional_object); +extern void UpdateSoundPosition (COUNT channel, SoundPosition pos); extern void StopChannel (COUNT Channel, BYTE Priority); extern void SetMusicVolume (COUNT Volume); extern void SetChannelVolume (COUNT Channel, COUNT Volume, BYTE diff --git a/sc2/src/sc2code/libs/sound/mixsdl/mixer.c b/sc2/src/sc2code/libs/sound/mixsdl/mixer.c index ff362bc4e..710496362 100644 --- a/sc2/src/sc2code/libs/sound/mixsdl/mixer.c +++ b/sc2/src/sc2code/libs/sound/mixsdl/mixer.c @@ -550,6 +550,12 @@ mixSDL_Sourcef (mixSDL_Object srcobj, mixSDL_SourceProp pname, float value) mixSDL_UnlockMutex (src_mutex); } +/* set source float array property (CURRENTLY NOT IMPLEMENTED) */ +void mixSDL_Sourcefv (mixSDL_Object srcobj, mixSDL_SourceProp pname, float *value) +{ +} + + /* get source integer property */ void mixSDL_GetSourcei (mixSDL_Object srcobj, mixSDL_SourceProp pname, diff --git a/sc2/src/sc2code/libs/sound/mixsdl/mixer.h b/sc2/src/sc2code/libs/sound/mixsdl/mixer.h index 8508c2503..debf246cd 100644 --- a/sc2/src/sc2code/libs/sound/mixsdl/mixer.h +++ b/sc2/src/sc2code/libs/sound/mixsdl/mixer.h @@ -61,6 +61,7 @@ enum */ typedef enum { + MIX_POSITION = 0x1004, MIX_LOOPING = 0x1007, MIX_BUFFER = 0x1009, MIX_GAIN = 0x100A, @@ -231,6 +232,8 @@ void mixSDL_Sourcei (mixSDL_Object srcobj, mixSDL_SourceProp pname, mixSDL_IntVal value); void mixSDL_Sourcef (mixSDL_Object srcobj, mixSDL_SourceProp pname, float value); +void mixSDL_Sourcefv (mixSDL_Object srcobj, mixSDL_SourceProp pname, + float *value); void mixSDL_GetSourcei (mixSDL_Object srcobj, mixSDL_SourceProp pname, mixSDL_IntVal *value); void mixSDL_GetSourcef (mixSDL_Object srcobj, mixSDL_SourceProp pname, diff --git a/sc2/src/sc2code/libs/sound/mixsdl/sound_mixsdl.h b/sc2/src/sc2code/libs/sound/mixsdl/sound_mixsdl.h index 5db3e4d79..8ed8ba549 100644 --- a/sc2/src/sc2code/libs/sound/mixsdl/sound_mixsdl.h +++ b/sc2/src/sc2code/libs/sound/mixsdl/sound_mixsdl.h @@ -37,6 +37,7 @@ #define TFBSound_IsSource mixSDL_IsSource #define TFBSound_Sourcei mixSDL_Sourcei #define TFBSound_Sourcef mixSDL_Sourcef +#define TFBSound_Sourcefv mixSDL_Sourcefv #define TFBSound_GetSourcei mixSDL_GetSourcei #define TFBSound_GetSourcef mixSDL_GetSourcef #define TFBSound_SourceRewind mixSDL_SourceRewind @@ -70,3 +71,4 @@ #define TFBSOUND_BUFFERS_QUEUED MIX_BUFFERS_QUEUED #define TFBSOUND_NO_ERROR MIX_NO_ERROR #define TFBSOUND_SIZE MIX_SIZE +#define TFBSOUND_POSITION MIX_POSITION diff --git a/sc2/src/sc2code/libs/sound/openal/sound_openal.c b/sc2/src/sc2code/libs/sound/openal/sound_openal.c index 0d8f8021a..45cea706f 100644 --- a/sc2/src/sc2code/libs/sound/openal/sound_openal.c +++ b/sc2/src/sc2code/libs/sound/openal/sound_openal.c @@ -17,6 +17,7 @@ #ifdef HAVE_OPENAL #include "libs/sound/sound.h" +#include "options.h" ALCcontext *alcContext = NULL; ALCdevice *alcDevice = NULL; @@ -98,9 +99,11 @@ TFB_alInitSound (int driver, int flags) SetSFXVolume (sfxVolumeScale); SetSpeechVolume (speechVolumeScale); SetMusicVolume ((COUNT) musicVolume); - - // NOTE: change this if implementing 3D sound stuff - alDistanceModel (AL_NONE); + + if (optStereoSFX) + alDistanceModel (AL_INVERSE_DISTANCE); + else + alDistanceModel (AL_NONE); StreamDecoderTask = AssignTask (StreamDecoderTaskFunc, 1024, "audio stream decoder"); diff --git a/sc2/src/sc2code/libs/sound/sfx.c b/sc2/src/sc2code/libs/sound/sfx.c index ea435127b..4fc9c74df 100644 --- a/sc2/src/sc2code/libs/sound/sfx.c +++ b/sc2/src/sc2code/libs/sound/sfx.c @@ -20,28 +20,32 @@ #include #include "sound.h" +#include "options.h" static void CheckFinishedChannels (void); void -PlayChannel (COUNT channel, PVOID sample, COUNT sample_length, COUNT loop_begin, - COUNT loop_length, unsigned char priority) +PlayChannel (COUNT channel, PVOID sample, SoundPosition pos, + void *positional_object, unsigned char priority) { - TFB_SoundSample *tfb_sample = *(TFB_SoundSample**) sample; + TFB_SoundSample *tfb_sample = *(TFB_SoundSample**) sample; + StopSource (channel); // all finished (stopped) channels can be cleaned up at this point // since this is the only func that can initiate an sfx sound CheckFinishedChannels (); + soundSource[channel].sample = tfb_sample; + soundSource[channel].positional_object = positional_object; + + if (optStereoSFX) + UpdateSoundPosition (channel, pos); + TFBSound_Sourcei (soundSource[channel].handle, TFBSOUND_BUFFER, tfb_sample->buffer[0]); TFBSound_SourcePlay (soundSource[channel].handle); - /* ignored arguments */ - (void)sample_length; - (void)loop_begin; - (void)loop_length; - (void)priority; + (void) priority; } void @@ -83,6 +87,40 @@ ChannelPlaying (COUNT WhichChannel) return FALSE; } +void * +GetPositionalObject (COUNT channel) +{ + return soundSource[channel].positional_object; +} + +void +SetPositionalObject (COUNT channel, void *positional_object) +{ + soundSource[channel].positional_object = positional_object; +} + +void +UpdateSoundPosition (COUNT channel, SoundPosition pos) +{ + const float ATTENUATION = 70.0f; + float fpos[3]; + + if (pos.positional) + { + fpos[0] = pos.x / ATTENUATION; + fpos[1] = 0.0f; + fpos[2] = pos.y / ATTENUATION; + TFBSound_Sourcefv (soundSource[channel].handle, TFBSOUND_POSITION, fpos); + //fprintf (stderr, "UpdateSoundPosition(): channel %d, pos %d %d, posobj %x\n", + // channel, pos.x, pos.y, (unsigned int)soundSource[channel].positional_object); + } + else + { + fpos[0] = fpos[1] = fpos[2] = 0.0f; + TFBSound_Sourcefv (soundSource[channel].handle, TFBSOUND_POSITION, fpos); + } +} + void SetChannelVolume (COUNT channel, COUNT volume, BYTE priority) // I wonder what this whole priority business is... diff --git a/sc2/src/sc2code/libs/sound/sound.c b/sc2/src/sc2code/libs/sound/sound.c index 2817f2fab..ba2266c74 100644 --- a/sc2/src/sc2code/libs/sound/sound.c +++ b/sc2/src/sc2code/libs/sound/sound.c @@ -39,6 +39,7 @@ CleanSource (int iSource) #define MAX_STACK_BUFFERS 64 TFBSound_IntVal processed; + soundSource[iSource].positional_object = NULL; TFBSound_GetSourcei (soundSource[iSource].handle, TFBSOUND_BUFFERS_PROCESSED, &processed); if (processed != 0) diff --git a/sc2/src/sc2code/libs/sound/sound.h b/sc2/src/sc2code/libs/sound/sound.h index 9759b4580..e63cfe264 100644 --- a/sc2/src/sc2code/libs/sound/sound.h +++ b/sc2/src/sc2code/libs/sound/sound.h @@ -77,6 +77,7 @@ typedef struct tfb_soundsource bool stream_should_be_playing; Mutex stream_mutex; sint32 start_time; + void *positional_object; // for oscilloscope void *sbuffer; diff --git a/sc2/src/sc2code/libs/sound/sound_chooser.c b/sc2/src/sc2code/libs/sound/sound_chooser.c index d01902fc7..659d8b0dd 100644 --- a/sc2/src/sc2code/libs/sound/sound_chooser.c +++ b/sc2/src/sc2code/libs/sound/sound_chooser.c @@ -103,6 +103,16 @@ TFBSound_Sourcef (TFBSound_Object srcobj, TFBSound_SourceProp pname, float value (mixSDL_SourceProp) tfb_enum_lookup[pname], value); } +void +TFBSound_Sourcefv (TFBSound_Object srcobj, TFBSound_SourceProp pname, float *value) +{ + if (SoundDriver == TFB_SOUNDDRIVER_OPENAL) + alSourcefv ((ALuint) srcobj, (ALenum) tfb_enum_lookup[pname], value); + else + mixSDL_Sourcefv ((mixSDL_Object) srcobj, + (mixSDL_SourceProp) tfb_enum_lookup[pname], value); +} + void TFBSound_GetSourcei (TFBSound_Object srcobj, TFBSound_SourceProp pname, TFBSound_IntVal *value) @@ -260,6 +270,7 @@ TFB_choose_InitSound (int driver, int flags) tfb_enum_lookup[TFBSOUND_BUFFERS_PROCESSED] = AL_BUFFERS_PROCESSED; tfb_enum_lookup[TFBSOUND_BUFFERS_QUEUED] = AL_BUFFERS_QUEUED; tfb_enum_lookup[TFBSOUND_SIZE] = AL_SIZE; + tfb_enum_lookup[TFBSOUND_POSITION] = AL_POSITION; TFBSOUND_NO_ERROR = AL_NO_ERROR; TFBSOUND_PAUSED = AL_PAUSED; TFBSOUND_PLAYING = AL_PLAYING; @@ -280,6 +291,7 @@ TFB_choose_InitSound (int driver, int flags) tfb_enum_lookup[TFBSOUND_BUFFERS_PROCESSED] = MIX_BUFFERS_PROCESSED; tfb_enum_lookup[TFBSOUND_BUFFERS_QUEUED] = MIX_BUFFERS_QUEUED; tfb_enum_lookup[TFBSOUND_SIZE] = MIX_SIZE; + tfb_enum_lookup[TFBSOUND_POSITION] = MIX_POSITION; TFBSOUND_NO_ERROR = MIX_NO_ERROR; TFBSOUND_PAUSED = MIX_PAUSED; TFBSOUND_PLAYING = MIX_PLAYING; diff --git a/sc2/src/sc2code/libs/sound/sound_chooser.h b/sc2/src/sc2code/libs/sound/sound_chooser.h index 8aa351bda..896b5cf3a 100644 --- a/sc2/src/sc2code/libs/sound/sound_chooser.h +++ b/sc2/src/sc2code/libs/sound/sound_chooser.h @@ -57,6 +57,8 @@ void TFBSound_Sourcei (TFBSound_Object srcobj, TFBSound_SourceProp pname, TFBSound_IntVal value); void TFBSound_Sourcef (TFBSound_Object srcobj, TFBSound_SourceProp pname, float value); +void TFBSound_Sourcefv (TFBSound_Object srcobj, TFBSound_SourceProp pname, + float *value); void TFBSound_GetSourcei (TFBSound_Object srcobj, TFBSound_SourceProp pname, TFBSound_IntVal *value); void TFBSound_GetSourcef (TFBSound_Object srcobj, TFBSound_SourceProp pname, @@ -96,6 +98,7 @@ enum TFBSOUND_BUFFERS_PROCESSED, TFBSOUND_BUFFERS_QUEUED, TFBSOUND_SIZE, + TFBSOUND_POSITION, TFBSOUND_ENUMSIZE }; diff --git a/sc2/src/sc2code/melee.c b/sc2/src/sc2code/melee.c index fd2df85ac..909de7f9f 100644 --- a/sc2/src/sc2code/melee.c +++ b/sc2/src/sc2code/melee.c @@ -1663,7 +1663,7 @@ DoMelee (PMELEE_STATE pMS) if (pMS->star_bucks[0] == 0 || pMS->star_bucks[1] == 0) { PlaySoundEffect (SetAbsSoundIndex (MenuSounds, 2), - 0, GAME_SOUND_PRIORITY); + 0, NotPositional (), NULL, GAME_SOUND_PRIORITY); break; } @@ -1724,7 +1724,7 @@ DoMelee (PMELEE_STATE pMS) DoSaveTeam (pMS); else PlaySoundEffect (SetAbsSoundIndex (MenuSounds, 2), - 0, GAME_SOUND_PRIORITY); + 0, NotPositional (), NULL, GAME_SOUND_PRIORITY); break; case CONTROLS_TOP: case CONTROLS_BOT: diff --git a/sc2/src/sc2code/misc.c b/sc2/src/sc2code/misc.c index 64eea16fb..b0d46fd66 100644 --- a/sc2/src/sc2code/misc.c +++ b/sc2/src/sc2code/misc.c @@ -280,7 +280,7 @@ crew_collision (PELEMENT ElementPtr0, PPOINT pPt0, GetElementStarShip (ElementPtr1, &StarShipPtr); if (!(StarShipPtr->RaceDescPtr->ship_info.ship_flags & CREW_IMMUNE)) { - ProcessSound (SetAbsSoundIndex (GameSounds, GRAB_CREW)); + ProcessSound (SetAbsSoundIndex (GameSounds, GRAB_CREW), ElementPtr1); DeltaCrew ((ELEMENTPTR)ElementPtr1, 1); } } diff --git a/sc2/src/sc2code/pickmele.c b/sc2/src/sc2code/pickmele.c index 60c5d1975..1d0548048 100644 --- a/sc2/src/sc2code/pickmele.c +++ b/sc2/src/sc2code/pickmele.c @@ -243,7 +243,7 @@ GetMeleeStarShip (STARSHIPPTR LastStarShipPtr, COUNT which_player) row = new_row; col = new_col; - PlaySoundEffect (MenuSounds, 0, 0); + PlaySoundEffect (MenuSounds, 0, NotPositional (), NULL, 0); SetSemaphore (GraphicsSem); ChangeSelection: flash_rect.corner.x = PICK_X_OFFS @@ -312,7 +312,7 @@ ChangeSelection: StarShipPtr->captains_name_index = 0; UnlockStarShip (&race_q[which_player], hBattleShip); - PlaySoundEffect (SetAbsSoundIndex (MenuSounds, 1), 0, 0); + PlaySoundEffect (SetAbsSoundIndex (MenuSounds, 1), 0, NotPositional (), NULL, 0); WaitForSoundEnd (0); } diff --git a/sc2/src/sc2code/planets/devices.c b/sc2/src/sc2code/planets/devices.c index b42522921..11a94c2dc 100644 --- a/sc2/src/sc2code/planets/devices.c +++ b/sc2/src/sc2code/planets/devices.c @@ -210,7 +210,7 @@ DeviceFailed (BYTE which_device) BYTE fade_buf[1]; PlaySoundEffect (SetAbsSoundIndex (MenuSounds, 3), - 0, GAME_SOUND_PRIORITY); + 0, NotPositional (), NULL, GAME_SOUND_PRIORITY); fade_buf[0] = FadeAllToWhite; SleepThreadUntil (XFormColorMap ((COLORMAPPTR)fade_buf, ONE_SECOND * 1) + (ONE_SECOND * 2)); @@ -457,10 +457,10 @@ DoManipulateDevices (PMENU_STATE pMS) NewState = LOBYTE (status); if (NewState) PlaySoundEffect (SetAbsSoundIndex (MenuSounds, 2), - 0, GAME_SOUND_PRIORITY); + 0, NotPositional (), NULL, GAME_SOUND_PRIORITY); else if (HIBYTE (status) == 0) PlaySoundEffect (SetAbsSoundIndex (MenuSounds, 3), - 0, GAME_SOUND_PRIORITY); + 0, NotPositional (), NULL, GAME_SOUND_PRIORITY); ClearSemaphore (GraphicsSem); return ((BOOLEAN)NewState); diff --git a/sc2/src/sc2code/planets/lander.c b/sc2/src/sc2code/planets/lander.c index 0b72bba07..573c17b3e 100644 --- a/sc2/src/sc2code/planets/lander.c +++ b/sc2/src/sc2code/planets/lander.c @@ -215,7 +215,7 @@ object_animation (PELEMENT ElementPtr) SetAbsFrameIndex (pPrim->Object.Stamp.frame, 0); PlaySound (SetAbsSoundIndex (LanderSounds, LIFEFORM_CANNED), - GAME_SOUND_PRIORITY); + NotPositional (), NULL, GAME_SOUND_PRIORITY); } } @@ -250,7 +250,7 @@ object_animation (PELEMENT ElementPtr) SetPrimColor (pPrim, BUILD_COLOR (0x8000 | MAKE_RGB15 (0x1F, 0x1F, 0x1F), s)); if (frame_index == 13) PlaySound (SetAbsSoundIndex (LanderSounds, EARTHQUAKE_DISASTER), - GAME_SOUND_PRIORITY); + NotPositional (), NULL, GAME_SOUND_PRIORITY); } if (ElementPtr->mass_points == LAVASPOT_DISASTER @@ -437,7 +437,7 @@ DeltaLanderCrew (SIZE crew_delta, COUNT which_disaster) s.frame = SetAbsFrameIndex (LanderFrame[0], 56); PlaySound (SetAbsSoundIndex (LanderSounds, LANDER_INJURED), - GAME_SOUND_PRIORITY); + NotPositional (), NULL, GAME_SOUND_PRIORITY); } s.origin.x = 11 + (6 * (crew_delta % NUM_CREW_COLS)); @@ -456,7 +456,7 @@ FillLanderHold (PPLANETSIDE_DESC pPSD, COUNT scan, COUNT NumRetrieved) CONTEXT OldContext; PlaySound (SetAbsSoundIndex (LanderSounds, LANDER_PICKUP), - GAME_SOUND_PRIORITY); + NotPositional (), NULL, GAME_SOUND_PRIORITY); if (scan == BIOLOGICAL_SCAN) { @@ -639,7 +639,7 @@ CheckObjectCollision (COUNT index) { PlaySound (SetAbsSoundIndex ( LanderSounds, BIOLOGICAL_DISASTER - ), GAME_SOUND_PRIORITY); + ), NotPositional (), NULL, GAME_SOUND_PRIORITY); DeltaLanderCrew (-1, BIOLOGICAL_DISASTER); } UnlockElement (hElement); @@ -703,7 +703,7 @@ CheckObjectCollision (COUNT index) PlaySound (SetAbsSoundIndex ( LanderSounds, LANDER_HITS - ), GAME_SOUND_PRIORITY); + ), NotPositional (), NULL, GAME_SOUND_PRIORITY); } UnlockElement (hElement); break; @@ -771,7 +771,7 @@ CheckObjectCollision (COUNT index) } PlaySound (SetAbsSoundIndex ( LanderSounds, LANDER_FULL - ), GAME_SOUND_PRIORITY); + ), NotPositional (), NULL, GAME_SOUND_PRIORITY); continue; case BIOLOGICAL_SCAN: if (pPSD->BiologicalLevel < MAX_SCROUNGED) @@ -787,7 +787,7 @@ CheckObjectCollision (COUNT index) } PlaySound (SetAbsSoundIndex ( LanderSounds, LANDER_FULL - ), GAME_SOUND_PRIORITY); + ), NotPositional (), NULL, GAME_SOUND_PRIORITY); continue; } } @@ -920,7 +920,7 @@ AddLightning (void) PutElement (hLightningElement); PlaySound (SetAbsSoundIndex (LanderSounds, LIGHTNING_DISASTER), - GAME_SOUND_PRIORITY); + NotPositional (), NULL, GAME_SOUND_PRIORITY); } } @@ -1000,7 +1000,7 @@ BuildObjectList (void) { AddGroundDisaster (LAVASPOT_DISASTER); PlaySound (SetAbsSoundIndex (LanderSounds, LAVASPOT_DISASTER), - GAME_SOUND_PRIORITY); + NotPositional (), NULL, GAME_SOUND_PRIORITY); } if (HIBYTE (LOWORD (rand_val)) < pPSD->TectonicsChance) @@ -1463,7 +1463,7 @@ InitPlanetSide (void) SetSemaphore (GraphicsSem); PlaySound (SetAbsSoundIndex (LanderSounds, LANDER_DEPARTS), - GAME_SOUND_PRIORITY + 1); + NotPositional (), NULL, GAME_SOUND_PRIORITY + 1); SetContext (SpaceContext); AnimateLaunch (LanderFrame[5], FALSE); #ifdef SPIN_ON_LAUNCH @@ -1632,7 +1632,7 @@ SetVelocityComponents ( PlaySound (SetAbsSoundIndex ( LanderSounds, LANDER_DESTROYED - ), GAME_SOUND_PRIORITY + 1); + ), NotPositional (), NULL, GAME_SOUND_PRIORITY + 1); } } @@ -1749,7 +1749,7 @@ SetVelocityComponents ( PlaySound (SetAbsSoundIndex ( LanderSounds, LANDER_SHOOTS - ), GAME_SOUND_PRIORITY); + ), NotPositional (), NULL, GAME_SOUND_PRIORITY); wdx = SHUTTLE_FIRE_WAIT; if (GET_GAME_STATE (IMPROVED_LANDER_SHOT)) @@ -1999,7 +1999,7 @@ PlanetSide (PMENU_STATE pMS) { PSD.InTransit = TRUE; PlaySound (SetAbsSoundIndex (LanderSounds, LANDER_RETURNS), - GAME_SOUND_PRIORITY + 1); + NotPositional (), NULL, GAME_SOUND_PRIORITY + 1); TimeIn = GetTimeCounter (); for (index = NUM_LANDING_DELTAS; index >= 0; --index) diff --git a/sc2/src/sc2code/planets/report.c b/sc2/src/sc2code/planets/report.c index 67527e42e..7104e312f 100644 --- a/sc2/src/sc2code/planets/report.c +++ b/sc2/src/sc2code/planets/report.c @@ -140,7 +140,7 @@ MakeReport (SOUND ReadOutSounds, UNICODE *pStr, COUNT StrLen) font_DrawText (&t); ClearSemaphore (GraphicsSem); - PlaySound (ReadOutSounds, GAME_SOUND_PRIORITY); + PlaySound (ReadOutSounds, NotPositional (), NULL, GAME_SOUND_PRIORITY); if (t.pStr[0] == ',') TimeOut += ONE_SECOND / 4; diff --git a/sc2/src/sc2code/planets/scan.c b/sc2/src/sc2code/planets/scan.c index 3a6e2a9cc..a42125fdf 100644 --- a/sc2/src/sc2code/planets/scan.c +++ b/sc2/src/sc2code/planets/scan.c @@ -996,7 +996,7 @@ DoScan (PMENU_STATE pMS) || GLOBAL_SIS (CrewEnlisted) == 0) { PlaySoundEffect (SetAbsSoundIndex (MenuSounds, 2), - 0, GAME_SOUND_PRIORITY); + 0, NotPositional (), NULL, GAME_SOUND_PRIORITY); return (TRUE); } diff --git a/sc2/src/sc2code/process.c b/sc2/src/sc2code/process.c index f42217ffb..3c9bc3dfc 100644 --- a/sc2/src/sc2code/process.c +++ b/sc2/src/sc2code/process.c @@ -620,6 +620,7 @@ ProcessCollisions (HELEMENT hSuccElement, register ELEMENTPTR ElementPtr, #define MAX_SOUNDS 8 static BYTE num_sounds; static SOUND sound_buf[MAX_SOUNDS]; +static ELEMENTPTR sound_posobj[MAX_SOUNDS]; static VIEW_STATE PreProcessQueue (PSIZE pscroll_x, PSIZE pscroll_y) @@ -882,7 +883,6 @@ PostProcessQueue (register VIEW_STATE view_state, register SIZE scroll_x, { hNextElement = GetSuccElement (ElementPtr); UnlockElement (hElement); - RemoveElement (hElement); FreeElement (hElement); } @@ -1053,7 +1053,8 @@ InitDisplayList (void) } void -PlaySound (SOUND S, BYTE Priority) +PlaySound (SOUND S, SoundPosition Pos, ELEMENTPTR PositionalObject, + BYTE Priority) { #define MIN_FX_CHANNEL 1 #define NUM_FX_CHANNELS 4 /* obviously number of channels @@ -1098,7 +1099,7 @@ PlaySound (SOUND S, BYTE Priority) } lru_channel[NUM_FX_CHANNELS - 1] = chan; - PlaySoundEffect (S, chan + MIN_FX_CHANNEL, Priority); + PlaySoundEffect (S, chan + MIN_FX_CHANNEL, Pos, PositionalObject, Priority); } UWORD nth_frame; @@ -1108,12 +1109,30 @@ RedrawQueue (BOOLEAN clear) { SIZE scroll_x, scroll_y; VIEW_STATE view_state; + int i; SetContext (StatusContext); view_state = PreProcessQueue (&scroll_x, &scroll_y); PostProcessQueue (view_state, scroll_x, scroll_y); + if (optStereoSFX) + { + for (i = 0; i <= NUM_FX_CHANNELS; ++i) + { + /* Updates positional sound effects */ + + ELEMENTPTR posobj; + if (ChannelPlaying (i) && ((posobj = GetPositionalObject (i)) != NULL)) + { + SoundPosition pos; + pos = CalcSoundPosition (posobj); + if (pos.positional) + UpdateSoundPosition (i, pos); + } + } + } + SetContext (SpaceContext); if (LOBYTE (GLOBAL (CurrentActivity)) == SUPER_MELEE || !(GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD))) @@ -1139,11 +1158,15 @@ RedrawQueue (BOOLEAN clear) if (num_sounds > 0) { SOUND *pSound; + ELEMENTPTR *pSoundPosObj; pSound = sound_buf; + pSoundPosObj = sound_posobj; do { - PlaySound (*pSound++, GAME_SOUND_PRIORITY); + SoundPosition pos = CalcSoundPosition (*pSoundPosObj); + PlaySound (*pSound++, pos, *pSoundPosObj++, + GAME_SOUND_PRIORITY); } while (--num_sounds); } } @@ -1151,15 +1174,59 @@ RedrawQueue (BOOLEAN clear) } void -ProcessSound (SOUND Sound) +ProcessSound (SOUND Sound, ELEMENTPTR PositionalObject) { if (Sound == (SOUND)~0) { memset (sound_buf, 0, sizeof (sound_buf)); + memset (sound_posobj, 0, sizeof (sound_posobj)); num_sounds = MAX_SOUNDS; } else if (num_sounds < MAX_SOUNDS) - sound_buf[num_sounds++] = Sound; + { + sound_buf[num_sounds] = Sound; + sound_posobj[num_sounds++] = PositionalObject; + } +} + +SoundPosition +CalcSoundPosition (ELEMENTPTR ElementPtr) +{ + SoundPosition pos; + + if (ElementPtr == NULL) + { + pos.x = pos.y = 0; + pos.positional = FALSE; + } + else + { + GRAPHICS_PRIM objtype; + + objtype = GetPrimType (&DisplayArray[ElementPtr->PrimIndex]); + if (objtype == LINE_PRIM) + { + pos.x = DisplayArray[ElementPtr->PrimIndex].Object.Line.first.x; + pos.y = DisplayArray[ElementPtr->PrimIndex].Object.Line.first.y; + } + else + { + pos.x = DisplayArray[ElementPtr->PrimIndex].Object.Point.x; + pos.y = DisplayArray[ElementPtr->PrimIndex].Object.Point.y; + } + + pos.x -= (SPACE_WIDTH >> 1); + pos.y -= (SPACE_HEIGHT >> 1); + pos.positional = TRUE; + } + + return pos; +} + +SoundPosition +NotPositional (void) +{ + return CalcSoundPosition (NULL); } void @@ -1190,3 +1257,35 @@ Untarget (ELEMENTPTR ElementPtr) } } +void +RemoveElement (HLINK hLink) +{ + if (optStereoSFX) + { + ELEMENTPTR ElementPtr, PosObj; + + LockElement (hLink, &ElementPtr); + if (ElementPtr != NULL) + { + int i; + for (i = 0; i <= NUM_FX_CHANNELS; ++i) + { + if ((PosObj = GetPositionalObject (i)) == ElementPtr) + { + SetPositionalObject (i, NULL); + break; + } + } + for (i = 0; i < num_sounds; ++i) + { + if (sound_posobj[i] == ElementPtr) + { + sound_posobj[i] = NULL; + break; + } + } + } + UnlockElement (hLink); + } + RemoveQueue (&disp_q, hLink); +} diff --git a/sc2/src/sc2code/settings.c b/sc2/src/sc2code/settings.c index ede8ebb3d..faaf54076 100644 --- a/sc2/src/sc2code/settings.c +++ b/sc2/src/sc2code/settings.c @@ -80,16 +80,14 @@ ToggleSoundEffect (void) } void -PlaySoundEffect (SOUND S, COUNT Channel, BYTE Priority) +PlaySoundEffect (SOUND S, COUNT Channel, SoundPosition Pos, + void *PositionalObject, BYTE Priority) { if (!(GLOBAL (glob_flags) & SOUND_DISABLED)) { SetChannelVolume (Channel, MAX_VOLUME >> 1, Priority); SetChannelRate (Channel, GetSampleRate (S), Priority); - PlayChannel (Channel, - GetSampleAddress (S), - GetSampleLength (S), - 0, 0, Priority); + PlayChannel (Channel, GetSampleAddress (S), Pos, PositionalObject, Priority); } } diff --git a/sc2/src/sc2code/ship.c b/sc2/src/sc2code/ship.c index 39e90f0e6..fc63d2272 100644 --- a/sc2/src/sc2code/ship.c +++ b/sc2/src/sc2code/ship.c @@ -300,13 +300,13 @@ ship_postprocess (register { HELEMENT *WeaponPtr; STARSHIPPTR StarShipPtr; + BOOLEAN played_sfx = FALSE; GetElementStarShip (ElementPtr, &StarShipPtr); WeaponPtr = &Weapon[0]; do { HELEMENT w; - w = *WeaponPtr++; if (w) { @@ -314,12 +314,19 @@ ship_postprocess (register EPtr = LockElement (w, &EPtr); SetElementStarShip (EPtr, StarShipPtr); + if (!played_sfx) + { + ProcessSound (RDPtr->ship_data.ship_sounds, EPtr); + played_sfx = TRUE; + } UnlockElement (w); PutElement (w); } } while (--num_weapons); - ProcessSound (RDPtr->ship_data.ship_sounds); + + if (!played_sfx) + ProcessSound (RDPtr->ship_data.ship_sounds, ElementPtr); } StarShipPtr->weapon_counter = @@ -357,7 +364,7 @@ collision (PELEMENT damage = TARGET_DAMAGED_FOR_1_PT + (damage >> 1); if (damage > TARGET_DAMAGED_FOR_6_PLUS_PT) damage = TARGET_DAMAGED_FOR_6_PLUS_PT; - ProcessSound (SetAbsSoundIndex (GameSounds, damage)); + ProcessSound (SetAbsSoundIndex (GameSounds, damage), ElementPtr0); } } (void) pPt0; /* Satisfying compiler (unused parameter) */ diff --git a/sc2/src/sc2code/ships/androsyn/androsyn.c b/sc2/src/sc2code/ships/androsyn/androsyn.c index 552fab3f6..a0d1c18a8 100644 --- a/sc2/src/sc2code/ships/androsyn/androsyn.c +++ b/sc2/src/sc2code/ships/androsyn/androsyn.c @@ -347,7 +347,7 @@ androsynth_postprocess (PELEMENT ElementPtr) { ProcessSound (SetAbsSoundIndex ( /* COMET_ON */ - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1)); + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); ElementPtr->turn_wait = 0; ElementPtr->thrust_wait = 0; } diff --git a/sc2/src/sc2code/ships/arilou/arilou.c b/sc2/src/sc2code/ships/arilou/arilou.c index 8dd2663fd..fdc015fb6 100644 --- a/sc2/src/sc2code/ships/arilou/arilou.c +++ b/sc2/src/sc2code/ships/arilou/arilou.c @@ -214,7 +214,7 @@ arilou_preprocess (PELEMENT ElementPtr) ProcessSound (SetAbsSoundIndex ( /* HYPERJUMP */ - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1)); + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); StarShipPtr->special_counter = StarShipPtr->RaceDescPtr->characteristics.special_wait; } diff --git a/sc2/src/sc2code/ships/blackurq/blackurq.c b/sc2/src/sc2code/ships/blackurq/blackurq.c index d58ff0279..22af128de 100644 --- a/sc2/src/sc2code/ships/blackurq/blackurq.c +++ b/sc2/src/sc2code/ships/blackurq/blackurq.c @@ -519,7 +519,7 @@ black_urquan_postprocess (PELEMENT ElementPtr) spawn_gas_cloud (ElementPtr); ProcessSound (SetAbsSoundIndex ( - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1)); + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); StarShipPtr->special_counter = SPECIAL_WAIT; } diff --git a/sc2/src/sc2code/ships/chenjesu/chenjesu.c b/sc2/src/sc2code/ships/chenjesu/chenjesu.c index e4730c015..836cdad65 100644 --- a/sc2/src/sc2code/ships/chenjesu/chenjesu.c +++ b/sc2/src/sc2code/ships/chenjesu/chenjesu.c @@ -157,7 +157,7 @@ crystal_postprocess (PELEMENT ElementPtr) ProcessSound (SetAbsSoundIndex ( /* CRYSTAL_FRAGMENTS */ - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1)); + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); } static void @@ -285,7 +285,7 @@ doggy_death (PELEMENT ElementPtr) GetElementStarShip (ElementPtr, &StarShipPtr); ProcessSound (SetAbsSoundIndex ( /* DOGGY_DIES */ - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 3)); + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 3), ElementPtr); ElementPtr->state_flags &= ~DISAPPEARING; ElementPtr->state_flags |= NONSOLID | FINITE_LIFE; @@ -316,7 +316,7 @@ doggy_collision (PELEMENT ElementPtr0, PPOINT pPt0, PELEMENT ElementPtr1, PPOINT GetElementStarShip (ElementPtr0, &StarShipPtr); ProcessSound (SetAbsSoundIndex ( /* DOGGY_STEALS_ENERGY */ - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 2)); + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 2), ElementPtr0); GetElementStarShip (ElementPtr1, &StarShipPtr); if (StarShipPtr->RaceDescPtr->ship_info.energy_level < ENERGY_DRAIN) DeltaEnergy (ElementPtr1, -StarShipPtr->RaceDescPtr->ship_info.energy_level); @@ -373,6 +373,10 @@ spawn_doggy (PELEMENT ElementPtr) SetElementStarShip (DoggyElementPtr, StarShipPtr); + ProcessSound (SetAbsSoundIndex ( + /* RELEASE_DOGGY */ + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 4), DoggyElementPtr); + UnlockElement (hDoggyElement); } } @@ -533,10 +537,6 @@ chenjesu_postprocess (PELEMENT ElementPtr) && DeltaEnergy (ElementPtr, -SPECIAL_ENERGY_COST)) { spawn_doggy (ElementPtr); - - ProcessSound (SetAbsSoundIndex ( - /* RELEASE_DOGGY */ - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 4)); } StarShipPtr->special_counter = 1; diff --git a/sc2/src/sc2code/ships/chmmr/chmmr.c b/sc2/src/sc2code/ships/chmmr/chmmr.c index 1a320b2ec..36b003f23 100644 --- a/sc2/src/sc2code/ships/chmmr/chmmr.c +++ b/sc2/src/sc2code/ships/chmmr/chmmr.c @@ -317,9 +317,14 @@ chmmr_postprocess (PELEMENT ElementPtr) && DeltaEnergy (ElementPtr, -SPECIAL_ENERGY_COST)) { COUNT facing; + ELEMENTPTR ShipElementPtr; + LockElement (ElementPtr->hTarget, &ShipElementPtr); + ProcessSound (SetAbsSoundIndex ( - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1)); + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ShipElementPtr); + + UnlockElement (ElementPtr->hTarget); facing = 0; if (TrackShip (ElementPtr, &facing) >= 0) diff --git a/sc2/src/sc2code/ships/druuge/druuge.c b/sc2/src/sc2code/ships/druuge/druuge.c index 880ec062b..7728f2cfd 100644 --- a/sc2/src/sc2code/ships/druuge/druuge.c +++ b/sc2/src/sc2code/ships/druuge/druuge.c @@ -285,7 +285,7 @@ druuge_preprocess (PELEMENT ElementPtr) { ProcessSound (SetAbsSoundIndex ( /* BURN UP CREW */ - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1)); + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); DeltaCrew (ElementPtr, -1); DeltaEnergy (ElementPtr, SPECIAL_ENERGY_COST); diff --git a/sc2/src/sc2code/ships/human/human.c b/sc2/src/sc2code/ships/human/human.c index 36e403d49..e8e9226e3 100644 --- a/sc2/src/sc2code/ships/human/human.c +++ b/sc2/src/sc2code/ships/human/human.c @@ -216,7 +216,7 @@ spawn_point_defense (PELEMENT ElementPtr) ProcessSound (SetAbsSoundIndex ( /* POINT_DEFENSE_LASER */ - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1)); + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); StarShipPtr->special_counter = StarShipPtr->RaceDescPtr->characteristics.special_wait; PaidFor = TRUE; diff --git a/sc2/src/sc2code/ships/ilwrath/ilwrath.c b/sc2/src/sc2code/ships/ilwrath/ilwrath.c index 84a22e890..1be20edb0 100644 --- a/sc2/src/sc2code/ships/ilwrath/ilwrath.c +++ b/sc2/src/sc2code/ships/ilwrath/ilwrath.c @@ -246,7 +246,7 @@ ilwrath_preprocess (PELEMENT ElementPtr) { ProcessSound (SetAbsSoundIndex ( /* CLOAKING_OFF */ - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 2)); + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 2), ElementPtr); SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01)); if (weapon_discharge) @@ -347,7 +347,7 @@ ilwrath_preprocess (PELEMENT ElementPtr) ProcessSound (SetAbsSoundIndex ( /* CLOAKING_ON */ - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1)); + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); StarShipPtr->special_counter = StarShipPtr->RaceDescPtr->characteristics.special_wait; diff --git a/sc2/src/sc2code/ships/melnorme/melnorme.c b/sc2/src/sc2code/ships/melnorme/melnorme.c index 7eca64445..08cfeaf2c 100644 --- a/sc2/src/sc2code/ships/melnorme/melnorme.c +++ b/sc2/src/sc2code/ships/melnorme/melnorme.c @@ -176,7 +176,7 @@ pump_up_postprocess (PELEMENT ElementPtr) EPtr->current.image.frame, NUM_PUMP_ANIMS ); ProcessSound (SetAbsSoundIndex ( - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 2)); + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 2), EPtr); } EPtr->thrust_wait = LEVEL_COUNTER; } @@ -229,7 +229,7 @@ pump_up_postprocess (PELEMENT ElementPtr) SINE (angle, WORLD_TO_VELOCITY (PUMPUP_SPEED))); ProcessSound (SetAbsSoundIndex ( - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 3)); + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 3), EPtr); } UnlockElement (hPumpUp); @@ -624,10 +624,14 @@ melnorme_postprocess (PELEMENT ElementPtr) initialize_confusion (ElementPtr, &Confusion); if (Confusion) { - PutElement (Confusion); - + ELEMENTPTR CMissilePtr; + LockElement (Confusion, &CMissilePtr); + ProcessSound (SetAbsSoundIndex ( - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1)); + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), CMissilePtr); + + UnlockElement (Confusion); + PutElement (Confusion); StarShipPtr->special_counter = StarShipPtr->RaceDescPtr->characteristics.special_wait; } diff --git a/sc2/src/sc2code/ships/mmrnmhrm/mmrnmhrm.c b/sc2/src/sc2code/ships/mmrnmhrm/mmrnmhrm.c index 5aa802f4e..e93862ced 100644 --- a/sc2/src/sc2code/ships/mmrnmhrm/mmrnmhrm.c +++ b/sc2/src/sc2code/ships/mmrnmhrm/mmrnmhrm.c @@ -358,7 +358,7 @@ mmrnmhrm_postprocess (PELEMENT ElementPtr) ProcessSound (SetAbsSoundIndex ( /* TRANSFORM */ - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1)); + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); DeltaEnergy (ElementPtr, -StarShipPtr->RaceDescPtr->characteristics.special_energy_cost); diff --git a/sc2/src/sc2code/ships/mycon/mycon.c b/sc2/src/sc2code/ships/mycon/mycon.c index ace66ce89..eb0b378af 100644 --- a/sc2/src/sc2code/ships/mycon/mycon.c +++ b/sc2/src/sc2code/ships/mycon/mycon.c @@ -339,7 +339,7 @@ mycon_postprocess (PELEMENT ElementPtr) ProcessSound (SetAbsSoundIndex ( /* GROW_NEW_CREW */ - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1)); + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); if ((add_crew = REGENERATION_AMOUNT) > StarShipPtr->RaceDescPtr->ship_info.max_crew - ElementPtr->crew_level) add_crew = StarShipPtr->RaceDescPtr->ship_info.max_crew - ElementPtr->crew_level; diff --git a/sc2/src/sc2code/ships/orz/orz.c b/sc2/src/sc2code/ships/orz/orz.c index 755f58113..4aeb56c3a 100644 --- a/sc2/src/sc2code/ships/orz/orz.c +++ b/sc2/src/sc2code/ships/orz/orz.c @@ -417,7 +417,7 @@ LeftShip: ElementPtr->state_flags |= DISAPPEARING; ProcessSound (SetAbsSoundIndex ( - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 4)); + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 4), ElementPtr); goto LeftShip; } else if (randval < (0x0100 / 2 + 0x0100 / 16)) @@ -432,7 +432,7 @@ LeftShip: GetFrameCount (ElementPtr->next.image.farray[0]) - 1); ModifySilhouette (ShipPtr, &s, 0); ProcessSound (SetAbsSoundIndex ( - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 3)); + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 3), ElementPtr); } } @@ -779,7 +779,7 @@ marine_collision (PELEMENT ElementPtr0, PPOINT pPt0, PELEMENT ElementPtr1, PPOIN } ProcessSound (SetAbsSoundIndex ( - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 2)); + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 2), ElementPtr1); } ElementPtr0->state_flags &= ~COLLISION; @@ -992,7 +992,7 @@ turret_postprocess (PELEMENT ElementPtr) DeltaCrew (ShipPtr, -1); ProcessSound (SetAbsSoundIndex ( - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1)); + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), SpaceMarinePtr); StarShipPtr->special_counter = StarShipPtr->RaceDescPtr->characteristics.special_wait; diff --git a/sc2/src/sc2code/ships/pkunk/pkunk.c b/sc2/src/sc2code/ships/pkunk/pkunk.c index ba694b87f..5a044d5e4 100644 --- a/sc2/src/sc2code/ships/pkunk/pkunk.c +++ b/sc2/src/sc2code/ships/pkunk/pkunk.c @@ -463,7 +463,7 @@ PELEMENT ElementPtr; ProcessSound (SetAbsSoundIndex ( StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1 - )); + ), ElementPtr); ElementPtr->life_span = PHOENIX_LIFE; SetPrimType (&(GLOBAL (DisplayArray))[ElementPtr->PrimIndex], @@ -532,7 +532,7 @@ PELEMENT ElementPtr; } while (CurSound == LastSound); ProcessSound (SetAbsSoundIndex ( StarShipPtr->RaceDescPtr->ship_data.ship_sounds, CurSound - )); + ), ElementPtr); LastSound = CurSound; DeltaEnergy (ElementPtr, SPECIAL_ENERGY_COST); diff --git a/sc2/src/sc2code/ships/sis_ship/sis_ship.c b/sc2/src/sc2code/ships/sis_ship/sis_ship.c index 78208b675..fdf9c7695 100644 --- a/sc2/src/sc2code/ships/sis_ship/sis_ship.c +++ b/sc2/src/sc2code/ships/sis_ship/sis_ship.c @@ -378,7 +378,7 @@ spawn_point_defense (PELEMENT ElementPtr) ProcessSound (SetAbsSoundIndex ( /* POINT_DEFENSE_LASER */ - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1)); + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); StarShipPtr->special_counter = StarShipPtr->RaceDescPtr->characteristics.special_wait; PaidFor = TRUE; diff --git a/sc2/src/sc2code/ships/slylandr/slylandr.c b/sc2/src/sc2code/ships/slylandr/slylandr.c index 7f7b103d5..d82e7eb71 100644 --- a/sc2/src/sc2code/ships/slylandr/slylandr.c +++ b/sc2/src/sc2code/ships/slylandr/slylandr.c @@ -329,7 +329,7 @@ harvest_space_junk (PELEMENT ElementPtr) GetElementStarShip (ElementPtr, &StarShipPtr); ProcessSound (SetAbsSoundIndex ( - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1)); + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); DeltaEnergy (ElementPtr, MAX_ENERGY); } } diff --git a/sc2/src/sc2code/ships/spathi/spathi.c b/sc2/src/sc2code/ships/spathi/spathi.c index ee5049615..4ad7cdac9 100644 --- a/sc2/src/sc2code/ships/spathi/spathi.c +++ b/sc2/src/sc2code/ships/spathi/spathi.c @@ -166,6 +166,11 @@ spawn_butt_missile (PELEMENT ShipPtr) LockElement (ButtMissile, &ButtPtr); ButtPtr->turn_wait = TRACK_WAIT; SetElementStarShip (ButtPtr, StarShipPtr); + + ProcessSound (SetAbsSoundIndex ( + /* LAUNCH_BUTT_MISSILE */ + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ButtPtr); + UnlockElement (ButtMissile); PutElement (ButtMissile); } @@ -262,9 +267,6 @@ spathi_postprocess (PELEMENT ElementPtr) && StarShipPtr->special_counter == 0 && DeltaEnergy (ElementPtr, -SPECIAL_ENERGY_COST)) { - ProcessSound (SetAbsSoundIndex ( - /* LAUNCH_BUTT_MISSILE */ - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1)); spawn_butt_missile (ElementPtr); StarShipPtr->special_counter = diff --git a/sc2/src/sc2code/ships/syreen/syreen.c b/sc2/src/sc2code/ships/syreen/syreen.c index 775e9136a..f24e662db 100644 --- a/sc2/src/sc2code/ships/syreen/syreen.c +++ b/sc2/src/sc2code/ships/syreen/syreen.c @@ -247,7 +247,7 @@ syreen_postprocess (PELEMENT ElementPtr) { ProcessSound (SetAbsSoundIndex ( /* SYREEN_SONG */ - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1)); + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); spawn_crew (ElementPtr); StarShipPtr->special_counter = diff --git a/sc2/src/sc2code/ships/thradd/thradd.c b/sc2/src/sc2code/ships/thradd/thradd.c index 5f421d45f..f706b04d8 100644 --- a/sc2/src/sc2code/ships/thradd/thradd.c +++ b/sc2/src/sc2code/ships/thradd/thradd.c @@ -357,7 +357,7 @@ thraddash_preprocess (PELEMENT ElementPtr) InsertElement (hTrailElement, GetHeadElement ()); ProcessSound (SetAbsSoundIndex ( - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1)); + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); } } } diff --git a/sc2/src/sc2code/ships/umgah/umgah.c b/sc2/src/sc2code/ships/umgah/umgah.c index 3423e106c..14fae53df 100644 --- a/sc2/src/sc2code/ships/umgah/umgah.c +++ b/sc2/src/sc2code/ships/umgah/umgah.c @@ -335,7 +335,7 @@ umgah_preprocess (PELEMENT ElementPtr) ProcessSound (SetAbsSoundIndex ( /* ZIP_BACKWARDS */ - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1)); + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); facing = FACING_TO_ANGLE (StarShipPtr->ShipFacing) + HALF_CIRCLE; DeltaVelocityComponents (&ElementPtr->velocity, COSINE (facing, WORLD_TO_VELOCITY (JUMP_DIST)), diff --git a/sc2/src/sc2code/ships/urquan/urquan.c b/sc2/src/sc2code/ships/urquan/urquan.c index 306ebf26a..b3d9b7c82 100644 --- a/sc2/src/sc2code/ships/urquan/urquan.c +++ b/sc2/src/sc2code/ships/urquan/urquan.c @@ -164,15 +164,17 @@ fighter_postprocess (PELEMENT ElementPtr) LockElement (Laser, &LaserPtr); SetElementStarShip (LaserPtr, StarShipPtr); + + ProcessSound (SetAbsSoundIndex ( + /* FIGHTER_ZAP */ + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 2), LaserPtr); + UnlockElement (Laser); PutElement (Laser); } ElementPtr->postprocess_func = 0; ElementPtr->thrust_wait = FIGHTER_WEAPON_WAIT; - ProcessSound (SetAbsSoundIndex ( - /* FIGHTER_ZAP */ - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 2)); } static void @@ -358,7 +360,7 @@ fighter_collision (PELEMENT ElementPtr0, PPOINT pPt0, PELEMENT ElementPtr1, PPOI { ProcessSound (SetAbsSoundIndex ( /* FIGHTERS_RETURN */ - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 3)); + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 3), ElementPtr1); DeltaCrew (ElementPtr1, 1); ElementPtr0->state_flags |= DISAPPEARING | COLLISION; } @@ -513,7 +515,7 @@ urquan_postprocess (PELEMENT ElementPtr) { ProcessSound (SetAbsSoundIndex ( /* LAUNCH_FIGHTERS */ - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1)); + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); spawn_fighters (ElementPtr); StarShipPtr->special_counter = SPECIAL_WAIT; diff --git a/sc2/src/sc2code/ships/utwig/utwig.c b/sc2/src/sc2code/ships/utwig/utwig.c index cddc3d23d..8d101e2b1 100644 --- a/sc2/src/sc2code/ships/utwig/utwig.c +++ b/sc2/src/sc2code/ships/utwig/utwig.c @@ -274,7 +274,7 @@ utwig_preprocess (PELEMENT ElementPtr) ElementPtr->life_span - (NORMAL_LIFE + 1)); ProcessSound (SetAbsSoundIndex ( - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1)); + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); } if (!(StarShipPtr->cur_status_flags & SPECIAL)) @@ -289,7 +289,7 @@ utwig_preprocess (PELEMENT ElementPtr) StarShipPtr->special_counter = StarShipPtr->RaceDescPtr->characteristics.special_wait; ProcessSound (SetAbsSoundIndex ( - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 2)); + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 2), ElementPtr); } } diff --git a/sc2/src/sc2code/ships/vux/vux.c b/sc2/src/sc2code/ships/vux/vux.c index 64584742a..cfc8440e5 100644 --- a/sc2/src/sc2code/ships/vux/vux.c +++ b/sc2/src/sc2code/ships/vux/vux.c @@ -165,7 +165,7 @@ limpet_collision (PELEMENT ElementPtr0, PPOINT pPt0, PELEMENT GetElementStarShip (ElementPtr0, &StarShipPtr); ProcessSound (SetAbsSoundIndex ( /* LIMPET_AFFIXES */ - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 2)); + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 2), ElementPtr1); s.frame = SetAbsFrameIndex ( StarShipPtr->RaceDescPtr->ship_data.weapon[0], (COUNT)TFB_Random () ); @@ -290,7 +290,7 @@ vux_postprocess (PELEMENT ElementPtr) { ProcessSound (SetAbsSoundIndex ( /* LAUNCH_LIMPET */ - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1)); + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); spawn_limpets (ElementPtr); StarShipPtr->special_counter = diff --git a/sc2/src/sc2code/ships/yehat/yehat.c b/sc2/src/sc2code/ships/yehat/yehat.c index bc66d56d7..fcc1f5342 100644 --- a/sc2/src/sc2code/ships/yehat/yehat.c +++ b/sc2/src/sc2code/ships/yehat/yehat.c @@ -241,7 +241,7 @@ yehat_postprocess (PELEMENT ElementPtr) ProcessSound (SetAbsSoundIndex ( /* YEHAT_SHIELD_ON */ - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1)); + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); DeltaEnergy (ElementPtr, -SPECIAL_ENERGY_COST); } } diff --git a/sc2/src/sc2code/ships/zoqfot/zoqfot.c b/sc2/src/sc2code/ships/zoqfot/zoqfot.c index 0a64e5234..4a94e5ef3 100644 --- a/sc2/src/sc2code/ships/zoqfot/zoqfot.c +++ b/sc2/src/sc2code/ships/zoqfot/zoqfot.c @@ -334,7 +334,7 @@ zoqfotpik_postprocess (PELEMENT ElementPtr) { ProcessSound (SetAbsSoundIndex ( /* STICK_OUT_TONGUE */ - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1)); + StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); StarShipPtr->special_counter = StarShipPtr->RaceDescPtr->characteristics.special_wait; diff --git a/sc2/src/sc2code/starcon.h b/sc2/src/sc2code/starcon.h index f2bff5d3c..89d31f5d7 100644 --- a/sc2/src/sc2code/starcon.h +++ b/sc2/src/sc2code/starcon.h @@ -201,7 +201,8 @@ extern void StopMusic (void); extern void ResumeMusic (void); extern void PauseMusic (void); extern void ToggleSoundEffect (void); -extern void PlaySoundEffect (SOUND S, COUNT Channel, BYTE Priority); +extern void PlaySoundEffect (SOUND S, COUNT Channel, SoundPosition Pos, + void *PositionalObject, BYTE Priority); extern BOOLEAN CopyProtection (void); diff --git a/sc2/src/sc2code/tactrans.c b/sc2/src/sc2code/tactrans.c index f7cbb849f..5d5e05205 100644 --- a/sc2/src/sc2code/tactrans.c +++ b/sc2/src/sc2code/tactrans.c @@ -49,7 +49,7 @@ new_ship (PELEMENT DeadShipPtr) { STARSHIPPTR DeadStarShipPtr; - ProcessSound ((SOUND)~0); + ProcessSound ((SOUND)~0, NULL); GetElementStarShip (DeadShipPtr, &DeadStarShipPtr); if (!(DeadShipPtr->state_flags & PLAYER_SHIP)) @@ -288,7 +288,7 @@ ship_death (PELEMENT ShipPtr) PlaySound (SetAbsSoundIndex ( StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1 - ), GAME_SOUND_PRIORITY + 1); + ), CalcSoundPosition (ShipPtr), ShipPtr, GAME_SOUND_PRIORITY + 1); DeltaCrew ((ELEMENTPTR)ShipPtr, -(SIZE)ShipPtr->crew_level); if (VictoriousStarShipPtr == 0) @@ -299,7 +299,7 @@ ship_death (PELEMENT ShipPtr) ShipPtr->preprocess_func = explosion_preprocess; PlaySound (SetAbsSoundIndex (GameSounds, SHIP_EXPLODES), - GAME_SOUND_PRIORITY + 1); + CalcSoundPosition (ShipPtr), ShipPtr, GAME_SOUND_PRIORITY + 1); } } diff --git a/sc2/src/sc2code/weapon.c b/sc2/src/sc2code/weapon.c index 9f62db2f5..cad159d42 100644 --- a/sc2/src/sc2code/weapon.c +++ b/sc2/src/sc2code/weapon.c @@ -158,7 +158,7 @@ weapon_collision (PELEMENT damage = TARGET_DAMAGED_FOR_1_PT + (damage >> 1); if (damage > TARGET_DAMAGED_FOR_6_PLUS_PT) damage = TARGET_DAMAGED_FOR_6_PLUS_PT; - ProcessSound (SetAbsSoundIndex (GameSounds, damage)); + ProcessSound (SetAbsSoundIndex (GameSounds, damage), HitElementPtr); } if (GetPrimType (&DisplayArray[WeaponElementPtr->PrimIndex]) != LINE_PRIM) diff --git a/sc2/src/starcon2.c b/sc2/src/starcon2.c index 92824d01b..d71846668 100644 --- a/sc2/src/starcon2.c +++ b/sc2/src/starcon2.c @@ -97,7 +97,8 @@ main (int argc, char *argv[]) MENU_OPT, FONT_OPT, SCROLL_OPT, - SOUND_OPT + SOUND_OPT, + STEREOSFX_OPT }; int option_index = 0, c; @@ -126,6 +127,7 @@ main (int argc, char *argv[]) {"font", 1, NULL, FONT_OPT}, {"scroll", 1, NULL, SCROLL_OPT}, {"sound", 1, NULL, SOUND_OPT}, + {"stereosfx", 0, NULL, STEREOSFX_OPT}, {0, 0, 0, 0} }; @@ -277,6 +279,9 @@ main (int argc, char *argv[]) snddriver = TFB_SOUNDDRIVER_MIXSDL; } break; + case STEREOSFX_OPT: + optStereoSFX = TRUE; + break; default: printf ("\nOption %s not found!\n", long_options[option_index].name); case '?': @@ -298,6 +303,7 @@ main (int argc, char *argv[]) printf(" -q, --audioquality=QUALITY (high, medium or low, default medium)\n"); printf(" -u, --nosubtitles\n"); printf(" --sound=DRIVER (openal, mixsdl, none; default mixsdl)\n"); + printf(" --stereosfx (enables positional sound effects, currently only for openal)\n"); printf("The following options can take either '3do' or 'pc' as an option:\n"); printf(" -m, --music : Music version (default 3do)\n"); printf(" --cscan : coarse-scan display, pc=text, 3do=hieroglyphs (default 3do)\n");