diff -r bf14c7c1be02 -r bf8b7c166b3c hedgewars/uSound.pas --- a/hedgewars/uSound.pas Sun Oct 28 14:08:13 2018 +0100 +++ b/hedgewars/uSound.pas Tue Oct 30 23:08:43 2018 +0100 @@ -62,14 +62,15 @@ // Plays the sound snd [from a given voicepack], // if keepPlaying is given and true, // then the sound's playback won't be interrupted if asked to play again. -procedure PlaySound(snd: TSound); -procedure PlaySound(snd: TSound; keepPlaying: boolean); -procedure PlaySound(snd: TSound; keepPlaying: boolean; ignoreMask: boolean); -procedure PlaySound(snd: TSound; keepPlaying, ignoreMask, soundAsMusic: boolean); -procedure PlaySoundV(snd: TSound; voicepack: PVoicepack); -procedure PlaySoundV(snd: TSound; voicepack: PVoicepack; keepPlaying: boolean); -procedure PlaySoundV(snd: TSound; voicepack: PVoicepack; keepPlaying, ignoreMask: boolean); -procedure PlaySoundV(snd: TSound; voicepack: PVoicepack; keepPlaying, ignoreMask, soundAsMusic: boolean); +// Returns true if sound was found and is played, false otherwise. +function PlaySound(snd: TSound): boolean; +function PlaySound(snd: TSound; keepPlaying: boolean): boolean; +function PlaySound(snd: TSound; keepPlaying: boolean; ignoreMask: boolean): boolean; +function PlaySound(snd: TSound; keepPlaying, ignoreMask, soundAsMusic: boolean): boolean; +function PlaySoundV(snd: TSound; voicepack: PVoicepack): boolean; +function PlaySoundV(snd: TSound; voicepack: PVoicepack; keepPlaying: boolean): boolean; +function PlaySoundV(snd: TSound; voicepack: PVoicepack; keepPlaying, ignoreMask: boolean): boolean; +function PlaySoundV(snd: TSound; voicepack: PVoicepack; keepPlaying, ignoreMask, soundAsMusic: boolean): boolean; // Plays/stops a sound to replace the main background music temporarily. procedure PlayMusicSound(snd: TSound); @@ -89,8 +90,11 @@ procedure StopSoundChan(chn: LongInt); procedure StopSoundChan(chn, fadems: LongInt); +// Add voice to the voice queue procedure AddVoice(snd: TSound; voicepack: PVoicepack); -procedure AddVoice(snd: TSound; voicepack: PVoicepack; ignoreMask: boolean); +procedure AddVoice(snd: TSound; voicepack: PVoicepack; ignoreMask, isFallback: boolean); + +// Actually play next voice procedure PlayNextVoice; @@ -125,6 +129,7 @@ var Volume: LongInt; SoundTimerTicks: Longword; + LastVoiceFailed: boolean; implementation uses uVariables, uConsole, uCommands, uDebug, uPhysFSLayer; @@ -140,14 +145,14 @@ isAutoDampening: boolean; isSEBackup: boolean; VoiceList : array[0..7] of TVoice = ( - ( snd: sndNone; voicepack: nil), - ( snd: sndNone; voicepack: nil), - ( snd: sndNone; voicepack: nil), - ( snd: sndNone; voicepack: nil), - ( snd: sndNone; voicepack: nil), - ( snd: sndNone; voicepack: nil), - ( snd: sndNone; voicepack: nil), - ( snd: sndNone; voicepack: nil)); + ( snd: sndNone; voicepack: nil; isFallback: false), + ( snd: sndNone; voicepack: nil; isFallback: false), + ( snd: sndNone; voicepack: nil; isFallback: false), + ( snd: sndNone; voicepack: nil; isFallback: false), + ( snd: sndNone; voicepack: nil; isFallback: false), + ( snd: sndNone; voicepack: nil; isFallback: false), + ( snd: sndNone; voicepack: nil; isFallback: false), + ( snd: sndNone; voicepack: nil; isFallback: false)); Soundz: array[TSound] of record FileName: string[31]; Path, AltPath : TPathType; @@ -499,45 +504,47 @@ GetFallbackV := sndNone; end; -procedure PlaySound(snd: TSound); +function PlaySound(snd: TSound): boolean; begin - PlaySoundV(snd, nil, false, false, false); + PlaySound:= PlaySoundV(snd, nil, false, false, false); end; -procedure PlaySound(snd: TSound; keepPlaying: boolean); +function PlaySound(snd: TSound; keepPlaying: boolean): boolean; begin - PlaySoundV(snd, nil, keepPlaying, false, false); + PlaySound:= PlaySoundV(snd, nil, keepPlaying, false, false); end; -procedure PlaySound(snd: TSound; keepPlaying: boolean; ignoreMask: boolean); +function PlaySound(snd: TSound; keepPlaying: boolean; ignoreMask: boolean): boolean; begin - PlaySoundV(snd, nil, keepPlaying, ignoreMask, false); + PlaySound:= PlaySoundV(snd, nil, keepPlaying, ignoreMask, false); end; -procedure PlaySound(snd: TSound; keepPlaying: boolean; ignoreMask, soundAsMusic: boolean); +function PlaySound(snd: TSound; keepPlaying: boolean; ignoreMask, soundAsMusic: boolean): boolean; begin - PlaySoundV(snd, nil, keepPlaying, ignoreMask, soundAsMusic); + PlaySound:= PlaySoundV(snd, nil, keepPlaying, ignoreMask, soundAsMusic); end; -procedure PlaySoundV(snd: TSound; voicepack: PVoicepack); +function PlaySoundV(snd: TSound; voicepack: PVoicepack): boolean; begin - PlaySoundV(snd, voicepack, false, false, false); + PlaySoundV:= PlaySoundV(snd, voicepack, false, false, false); end; -procedure PlaySoundV(snd: TSound; voicepack: PVoicepack; keepPlaying: boolean); +function PlaySoundV(snd: TSound; voicepack: PVoicepack; keepPlaying: boolean): boolean; begin - PlaySoundV(snd, voicepack, keepPlaying, false, false); + PlaySoundV:= PlaySoundV(snd, voicepack, keepPlaying, false, false); end; -procedure PlaySoundV(snd: TSound; voicepack: PVoicepack; keepPlaying, ignoreMask: boolean); +function PlaySoundV(snd: TSound; voicepack: PVoicepack; keepPlaying, ignoreMask: boolean): boolean; begin - PlaySoundV(snd, voicepack, keepPlaying, ignoreMask, false); + PlaySoundV:= PlaySoundV(snd, voicepack, keepPlaying, ignoreMask, false); end; -procedure PlaySoundV(snd: TSound; voicepack: PVoicepack; keepPlaying, ignoreMask, soundAsMusic: boolean); +function PlaySoundV(snd: TSound; voicepack: PVoicepack; keepPlaying, ignoreMask, soundAsMusic: boolean): boolean; var s:shortstring; rwops: PSDL_RWops; begin + s:= cPathz[Soundz[snd].Path] + '/' + voicepack^.name + '/' + Soundz[snd].FileName; + PlaySoundV:= false; if ((not isSoundEnabled) and (not (soundAsMusic and isMusicEnabled))) or fastUntilLag then exit; @@ -576,7 +583,8 @@ else WriteLnToConsole(msgOK) end; - lastChan[snd]:= Mix_PlayChannelTimed(-1, voicepack^.chunks[snd], 0, -1) + lastChan[snd]:= Mix_PlayChannelTimed(-1, voicepack^.chunks[snd], 0, -1); + PlaySoundV:= true; end else begin @@ -597,7 +605,8 @@ if SDLCheck(defVoicepack^.chunks[snd] <> nil, 'Mix_LoadWAV_RW', true) then exit; WriteLnToConsole(msgOK); end; - lastChan[snd]:= Mix_PlayChannelTimed(-1, defVoicepack^.chunks[snd], 0, -1) + lastChan[snd]:= Mix_PlayChannelTimed(-1, defVoicepack^.chunks[snd], 0, -1); + PlaySoundV:= true; end; end; @@ -615,10 +624,23 @@ procedure AddVoice(snd: TSound; voicepack: PVoicepack); begin - AddVoice(snd, voicepack, false); + AddVoice(snd, voicepack, false, false); end; -procedure AddVoice(snd: TSound; voicepack: PVoicepack; ignoreMask: boolean); +{ +AddVoice: Add a voice to the voice queue. +* snd: Sound ID +* voicepack: Hedgehog voicepack +* ignoreMask: If true, the sound will be played anyway if masked by Lua +* isFallback: If true, this sound is added as fallback if the sound previously added to the + queue was not found. Useful to make sure a voice is always played, even if + a voicepack is incomplete. + Example: + AddVoice(sndRevenge, voiceAttacker); + AddVoice(sndRegret, voiceVictim, false, true); + --> plays sndRegret if sndRevenge could not be played. +} +procedure AddVoice(snd: TSound; voicepack: PVoicepack; ignoreMask, isFallback: boolean); var i : LongInt; begin @@ -646,11 +668,13 @@ begin VoiceList[i].snd:= snd; VoiceList[i].voicepack:= voicepack; + VoiceList[i].isFallback:= isFallback; end end; procedure PlayNextVoice; var i : LongInt; + played : boolean; begin if (not isSoundEnabled) or fastUntilLag or ((LastVoice.snd <> sndNone) and (lastChan[LastVoice.snd] <> -1) and (Mix_Playing(lastChan[LastVoice.snd]) <> 0)) then exit; @@ -658,14 +682,19 @@ while (i sndNone) then + played:= false; + if (VoiceList[i].snd <> sndNone) and ((not VoiceList[i].isFallback) or LastVoiceFailed) then begin LastVoice.snd:= VoiceList[i].snd; LastVoice.voicepack:= VoiceList[i].voicepack; + LastVoice.isFallback:= VoiceList[i].isFallback; VoiceList[i].snd:= sndNone; - PlaySoundV(LastVoice.snd, LastVoice.voicepack) + played:= PlaySoundV(LastVoice.snd, LastVoice.voicepack); + // Remember if sound was not played. + LastVoiceFailed:= (not played); end - else LastVoice.snd:= sndNone; + else + LastVoice.snd:= sndNone; end; function LoopSound(snd: TSound): LongInt; @@ -965,6 +994,7 @@ Volume:= 0; SoundTimerTicks:= 0; defVoicepack:= AskForVoicepack('Default'); + LastVoiceFailed:= false; for i:= Low(TSound) to High(TSound) do lastChan[i]:= -1;