branch | webgl |
changeset 8330 | aaefa587e277 |
parent 8096 | 453917e94e55 |
parent 8231 | a41d84553ae8 |
child 8444 | 75db7bb8dce8 |
8116:d24257910f8d | 8330:aaefa587e277 |
---|---|
19 {$INCLUDE "options.inc"} |
19 {$INCLUDE "options.inc"} |
20 |
20 |
21 unit uSound; |
21 unit uSound; |
22 (* |
22 (* |
23 * This unit controls the sounds and music of the game. |
23 * This unit controls the sounds and music of the game. |
24 * Doesn't really do anything if isSoundEnabled = false. |
24 * Doesn't really do anything if isSoundEnabled = false and isMusicEnabled = false |
25 * |
25 * |
26 * There are three basic types of sound controls: |
26 * There are three basic types of sound controls: |
27 * Music - The background music of the game: |
27 * Music - The background music of the game: |
28 * * will only be played if isMusicEnabled = true |
28 * * will only be played if isMusicEnabled = true |
29 * * can be started, changed, paused and resumed |
29 * * can be started, changed, paused and resumed |
118 Mus: PMixMusic; // music pointer |
118 Mus: PMixMusic; // music pointer |
119 MusicFN: shortstring; // music file name |
119 MusicFN: shortstring; // music file name |
120 isMusicEnabled: boolean; |
120 isMusicEnabled: boolean; |
121 isSoundEnabled: boolean; |
121 isSoundEnabled: boolean; |
122 isSEBackup: boolean; |
122 isSEBackup: boolean; |
123 VoiceList : array[0..7] of TVoice = ( |
|
124 ( snd: sndNone; voicepack: nil), |
|
125 ( snd: sndNone; voicepack: nil), |
|
126 ( snd: sndNone; voicepack: nil), |
|
127 ( snd: sndNone; voicepack: nil), |
|
128 ( snd: sndNone; voicepack: nil), |
|
129 ( snd: sndNone; voicepack: nil), |
|
130 ( snd: sndNone; voicepack: nil), |
|
131 ( snd: sndNone; voicepack: nil)); |
|
132 Soundz: array[TSound] of record |
|
133 FileName: string[31]; |
|
134 Path : TPathType; |
|
135 end = ( |
|
136 (FileName: ''; Path: ptNone ),// sndNone |
|
137 (FileName: 'grenadeimpact.ogg'; Path: ptSounds),// sndGrenadeImpact |
|
138 (FileName: 'explosion.ogg'; Path: ptSounds),// sndExplosion |
|
139 (FileName: 'throwpowerup.ogg'; Path: ptSounds),// sndThrowPowerUp |
|
140 (FileName: 'throwrelease.ogg'; Path: ptSounds),// sndThrowRelease |
|
141 (FileName: 'splash.ogg'; Path: ptSounds),// sndSplash |
|
142 (FileName: 'shotgunreload.ogg'; Path: ptSounds),// sndShotgunReload |
|
143 (FileName: 'shotgunfire.ogg'; Path: ptSounds),// sndShotgunFire |
|
144 (FileName: 'graveimpact.ogg'; Path: ptSounds),// sndGraveImpact |
|
145 (FileName: 'mineimpact.ogg'; Path: ptSounds),// sndMineImpact |
|
146 (FileName: 'minetick.ogg'; Path: ptSounds),// sndMineTicks |
|
147 (FileName: 'Droplet1.ogg'; Path: ptSounds),// sndMudballImpact |
|
148 (FileName: 'pickhammer.ogg'; Path: ptSounds),// sndPickhammer |
|
149 (FileName: 'gun.ogg'; Path: ptSounds),// sndGun |
|
150 (FileName: 'bee.ogg'; Path: ptSounds),// sndBee |
|
151 (FileName: 'Jump1.ogg'; Path: ptVoices),// sndJump1 |
|
152 (FileName: 'Jump2.ogg'; Path: ptVoices),// sndJump2 |
|
153 (FileName: 'Jump3.ogg'; Path: ptVoices),// sndJump3 |
|
154 (FileName: 'Yessir.ogg'; Path: ptVoices),// sndYesSir |
|
155 (FileName: 'Laugh.ogg'; Path: ptVoices),// sndLaugh |
|
156 (FileName: 'Illgetyou.ogg'; Path: ptVoices),// sndIllGetYou |
|
157 (FileName: 'JustYouWait.ogg'; Path: ptVoices),// sndJustYouWait |
|
158 (FileName: 'Incoming.ogg'; Path: ptVoices),// sndIncoming |
|
159 (FileName: 'Missed.ogg'; Path: ptVoices),// sndMissed |
|
160 (FileName: 'Stupid.ogg'; Path: ptVoices),// sndStupid |
|
161 (FileName: 'Firstblood.ogg'; Path: ptVoices),// sndFirstBlood |
|
162 (FileName: 'Boring.ogg'; Path: ptVoices),// sndBoring |
|
163 (FileName: 'Byebye.ogg'; Path: ptVoices),// sndByeBye |
|
164 (FileName: 'Sameteam.ogg'; Path: ptVoices),// sndSameTeam |
|
165 (FileName: 'Nutter.ogg'; Path: ptVoices),// sndNutter |
|
166 (FileName: 'Reinforcements.ogg'; Path: ptVoices),// sndReinforce |
|
167 (FileName: 'Traitor.ogg'; Path: ptVoices),// sndTraitor |
|
168 (FileName: 'Youllregretthat.ogg'; Path: ptVoices),// sndRegret |
|
169 (FileName: 'Enemydown.ogg'; Path: ptVoices),// sndEnemyDown |
|
170 (FileName: 'Coward.ogg'; Path: ptVoices),// sndCoward |
|
171 (FileName: 'Hurry.ogg'; Path: ptVoices),// sndHurry |
|
172 (FileName: 'Watchit.ogg'; Path: ptVoices),// sndWatchIt |
|
173 (FileName: 'Kamikaze.ogg'; Path: ptVoices),// sndKamikaze |
|
174 (FileName: 'cake2.ogg'; Path: ptSounds),// sndCake |
|
175 (FileName: 'Ow1.ogg'; Path: ptVoices),// sndOw1 |
|
176 (FileName: 'Ow2.ogg'; Path: ptVoices),// sndOw2 |
|
177 (FileName: 'Ow3.ogg'; Path: ptVoices),// sndOw3 |
|
178 (FileName: 'Ow4.ogg'; Path: ptVoices),// sndOw4 |
|
179 (FileName: 'Firepunch1.ogg'; Path: ptVoices),// sndFirepunch1 |
|
180 (FileName: 'Firepunch2.ogg'; Path: ptVoices),// sndFirepunch2 |
|
181 (FileName: 'Firepunch3.ogg'; Path: ptVoices),// sndFirepunch3 |
|
182 (FileName: 'Firepunch4.ogg'; Path: ptVoices),// sndFirepunch4 |
|
183 (FileName: 'Firepunch5.ogg'; Path: ptVoices),// sndFirepunch5 |
|
184 (FileName: 'Firepunch6.ogg'; Path: ptVoices),// sndFirepunch6 |
|
185 (FileName: 'Melon.ogg'; Path: ptVoices),// sndMelon |
|
186 (FileName: 'Hellish.ogg'; Path: ptSounds),// sndHellish |
|
187 (FileName: 'Yoohoo.ogg'; Path: ptSounds),// sndYoohoo |
|
188 (FileName: 'rcplane.ogg'; Path: ptSounds),// sndRCPlane |
|
189 (FileName: 'whipcrack.ogg'; Path: ptSounds),// sndWhipCrack |
|
190 (FileName:'ride_of_the_valkyries.ogg'; Path: ptSounds),// sndRideOfTheValkyries |
|
191 (FileName: 'denied.ogg'; Path: ptSounds),// sndDenied |
|
192 (FileName: 'placed.ogg'; Path: ptSounds),// sndPlaced |
|
193 (FileName: 'baseballbat.ogg'; Path: ptSounds),// sndBaseballBat |
|
194 (FileName: 'steam.ogg'; Path: ptSounds),// sndVaporize |
|
195 (FileName: 'warp.ogg'; Path: ptSounds),// sndWarp |
|
196 (FileName: 'suddendeath.ogg'; Path: ptSounds),// sndSuddenDeath |
|
197 (FileName: 'mortar.ogg'; Path: ptSounds),// sndMortar |
|
198 (FileName: 'shutterclick.ogg'; Path: ptSounds),// sndShutter |
|
199 (FileName: 'homerun.ogg'; Path: ptSounds),// sndHomerun |
|
200 (FileName: 'molotov.ogg'; Path: ptSounds),// sndMolotov |
|
201 (FileName: 'Takecover.ogg'; Path: ptVoices),// sndCover |
|
202 (FileName: 'Uh-oh.ogg'; Path: ptVoices),// sndUhOh |
|
203 (FileName: 'Oops.ogg'; Path: ptVoices),// sndOops |
|
204 (FileName: 'Nooo.ogg'; Path: ptVoices),// sndNooo |
|
205 (FileName: 'Hello.ogg'; Path: ptVoices),// sndHello |
|
206 (FileName: 'ropeshot.ogg'; Path: ptSounds),// sndRopeShot |
|
207 (FileName: 'ropeattach.ogg'; Path: ptSounds),// sndRopeAttach |
|
208 (FileName: 'roperelease.ogg'; Path: ptSounds),// sndRopeRelease |
|
209 (FileName: 'switchhog.ogg'; Path: ptSounds),// sndSwitchHog |
|
210 (FileName: 'Victory.ogg'; Path: ptVoices),// sndVictory |
|
211 (FileName: 'Flawless.ogg'; Path: ptVoices),// sndFlawless |
|
212 (FileName: 'sniperreload.ogg'; Path: ptSounds),// sndSniperReload |
|
213 (FileName: 'steps.ogg'; Path: ptSounds),// sndSteps |
|
214 (FileName: 'lowgravity.ogg'; Path: ptSounds),// sndLowGravity |
|
215 (FileName: 'hell_growl.ogg'; Path: ptSounds),// sndHellishImpact1 |
|
216 (FileName: 'hell_ooff.ogg'; Path: ptSounds),// sndHellishImpact2 |
|
217 (FileName: 'hell_ow.ogg'; Path: ptSounds),// sndHellishImpact3 |
|
218 (FileName: 'hell_ugh.ogg'; Path: ptSounds),// sndHellishImpact4 |
|
219 (FileName: 'melonimpact.ogg'; Path: ptSounds),// sndMelonImpact |
|
220 (FileName: 'Droplet1.ogg'; Path: ptSounds),// sndDroplet1 |
|
221 (FileName: 'Droplet2.ogg'; Path: ptSounds),// sndDroplet2 |
|
222 (FileName: 'Droplet3.ogg'; Path: ptSounds),// sndDroplet3 |
|
223 (FileName: 'egg.ogg'; Path: ptSounds),// sndEggBreak |
|
224 (FileName: 'drillgun.ogg'; Path: ptSounds),// sndDrillRocket |
|
225 (FileName: 'PoisonCough.ogg'; Path: ptVoices),// sndPoisonCough |
|
226 (FileName: 'PoisonMoan.ogg'; Path: ptVoices),// sndPoisonMoan |
|
227 (FileName: 'BirdyLay.ogg'; Path: ptSounds),// sndBirdyLay |
|
228 (FileName: 'Whistle.ogg'; Path: ptSounds),// sndWhistle |
|
229 (FileName: 'beewater.ogg'; Path: ptSounds),// sndBeeWater |
|
230 (FileName: '1C.ogg'; Path: ptSounds),// sndPiano0 |
|
231 (FileName: '2D.ogg'; Path: ptSounds),// sndPiano1 |
|
232 (FileName: '3E.ogg'; Path: ptSounds),// sndPiano2 |
|
233 (FileName: '4F.ogg'; Path: ptSounds),// sndPiano3 |
|
234 (FileName: '5G.ogg'; Path: ptSounds),// sndPiano4 |
|
235 (FileName: '6A.ogg'; Path: ptSounds),// sndPiano5 |
|
236 (FileName: '7B.ogg'; Path: ptSounds),// sndPiano6 |
|
237 (FileName: '8C.ogg'; Path: ptSounds),// sndPiano7 |
|
238 (FileName: '9D.ogg'; Path: ptSounds),// sndPiano8 |
|
239 (FileName: 'skip.ogg'; Path: ptSounds),// sndSkip |
|
240 (FileName: 'sinegun.ogg'; Path: ptSounds),// sndSineGun |
|
241 (FileName: 'Ooff1.ogg'; Path: ptVoices),// sndOoff1 |
|
242 (FileName: 'Ooff2.ogg'; Path: ptVoices),// sndOoff2 |
|
243 (FileName: 'Ooff3.ogg'; Path: ptVoices),// sndOoff3 |
|
244 (FileName: 'hammer.ogg'; Path: ptSounds),// sndWhack |
|
245 (FileName: 'Comeonthen.ogg'; Path: ptVoices),// sndComeonthen |
|
246 (FileName: 'parachute.ogg'; Path: ptSounds),// sndParachute |
|
247 (FileName: 'bump.ogg'; Path: ptSounds),// sndBump |
|
248 (FileName: 'hogchant3.ogg'; Path: ptSounds),// sndResurrector |
|
249 (FileName: 'plane.ogg'; Path: ptSounds),// sndPlane |
|
250 (FileName: 'TARDIS.ogg'; Path: ptSounds) // sndTardis |
|
251 ); |
|
252 |
|
123 |
253 |
124 |
254 |
125 function AskForVoicepack(name: shortstring): Pointer; |
255 function AskForVoicepack(name: shortstring): Pointer; |
126 var i: Longword; |
256 var i: Longword; |
127 locName, path: shortstring; |
257 locName, path: shortstring; |
155 AskForVoicepack:= @voicepacks[i] |
285 AskForVoicepack:= @voicepacks[i] |
156 end; |
286 end; |
157 |
287 |
158 procedure InitSound; |
288 procedure InitSound; |
159 const channels: LongInt = {$IFDEF MOBILE}1{$ELSE}2{$ENDIF}; |
289 const channels: LongInt = {$IFDEF MOBILE}1{$ELSE}2{$ENDIF}; |
160 begin |
290 var success: boolean; |
161 if not isSoundEnabled then |
291 begin |
292 if not (isSoundEnabled or isMusicEnabled) then |
|
162 exit; |
293 exit; |
163 WriteToConsole('Init sound...'); |
294 WriteToConsole('Init sound...'); |
164 isSoundEnabled:= SDL_InitSubSystem(SDL_INIT_AUDIO) >= 0; |
295 success:= SDL_InitSubSystem(SDL_INIT_AUDIO) >= 0; |
165 |
296 |
166 if isSoundEnabled then |
297 if success then |
167 isSoundEnabled:= Mix_OpenAudio(44100, $8010, channels, 1024) = 0; |
298 success:= Mix_OpenAudio(44100, $8010, channels, 1024) = 0; |
168 |
299 |
169 if isSoundEnabled then |
300 if success then |
170 WriteLnToConsole(msgOK) |
301 WriteLnToConsole(msgOK) |
171 else |
302 else |
303 begin |
|
172 WriteLnToConsole(msgFailed); |
304 WriteLnToConsole(msgFailed); |
305 isSoundEnabled:= false; |
|
306 isMusicEnabled:= false; |
|
307 end; |
|
173 |
308 |
174 WriteToConsole('Init SDL_mixer... '); |
309 WriteToConsole('Init SDL_mixer... '); |
175 SDLTry(Mix_Init(MIX_INIT_OGG) <> 0, true); |
310 SDLTry(Mix_Init(MIX_INIT_OGG) <> 0, true); |
176 WriteLnToConsole(msgOK); |
311 WriteLnToConsole(msgOK); |
177 |
312 |
178 Mix_AllocateChannels(Succ(chanTPU)); |
313 Mix_AllocateChannels(Succ(chanTPU)); |
179 ChangeVolume(cInitVolume); |
314 ChangeVolume(cInitVolume); |
180 end; |
315 end; |
181 |
316 |
182 procedure ResetSound; |
317 procedure ResetSound; |
183 begin |
318 begin |
184 isSoundEnabled:= isSEBackup; |
319 isSoundEnabled:= isSEBackup; |
254 if (voicepack <> nil) then |
389 if (voicepack <> nil) then |
255 begin |
390 begin |
256 if (voicepack^.chunks[snd] = nil) and (Soundz[snd].Path = ptVoices) and (Soundz[snd].FileName <> '') then |
391 if (voicepack^.chunks[snd] = nil) and (Soundz[snd].Path = ptVoices) and (Soundz[snd].FileName <> '') then |
257 begin |
392 begin |
258 s:= cPathz[Soundz[snd].Path] + '/' + voicepack^.name + '/' + Soundz[snd].FileName; |
393 s:= cPathz[Soundz[snd].Path] + '/' + voicepack^.name + '/' + Soundz[snd].FileName; |
259 if (not FileExists(s)) and (snd in [sndFirePunch2, sndFirePunch3, sndFirePunch4, sndFirePunch5, sndFirePunch6]) then |
394 if (not pfsExists(s)) and (snd in [sndFirePunch2, sndFirePunch3, sndFirePunch4, sndFirePunch5, sndFirePunch6]) then |
260 s:= cPathz[Soundz[sndFirePunch1].Path] + '/' + voicepack^.name + '/' + Soundz[snd].FileName; |
395 s:= cPathz[Soundz[sndFirePunch1].Path] + '/' + voicepack^.name + '/' + Soundz[snd].FileName; |
261 WriteToConsole(msgLoading + s + ' '); |
396 WriteToConsole(msgLoading + s + ' '); |
262 voicepack^.chunks[snd]:= Mix_LoadWAV_RW(rwopsOpenRead(s), 1); |
397 voicepack^.chunks[snd]:= Mix_LoadWAV_RW(rwopsOpenRead(s), 1); |
263 if voicepack^.chunks[snd] = nil then |
398 if voicepack^.chunks[snd] = nil then |
264 WriteLnToConsole(msgFailed) |
399 WriteLnToConsole(msgFailed) |
287 if (not isSoundEnabled) or fastUntilLag or ((LastVoice.snd = snd) and (LastVoice.voicepack = voicepack)) then |
422 if (not isSoundEnabled) or fastUntilLag or ((LastVoice.snd = snd) and (LastVoice.voicepack = voicepack)) then |
288 exit; |
423 exit; |
289 if (snd = sndVictory) or (snd = sndFlawless) then |
424 if (snd = sndVictory) or (snd = sndFlawless) then |
290 begin |
425 begin |
291 Mix_FadeOutChannel(-1, 800); |
426 Mix_FadeOutChannel(-1, 800); |
292 for i:= 0 to 7 do |
427 for i:= 0 to High(VoiceList) do |
293 VoiceList[i].snd:= sndNone; |
428 VoiceList[i].snd:= sndNone; |
294 LastVoice.snd:= sndNone; |
429 LastVoice.snd:= sndNone; |
295 end; |
430 end; |
296 |
431 |
297 i:= 0; |
432 i:= 0; |
309 var i : LongInt; |
444 var i : LongInt; |
310 begin |
445 begin |
311 if (not isSoundEnabled) or fastUntilLag or ((LastVoice.snd <> sndNone) and (lastChan[LastVoice.snd] <> -1) and (Mix_Playing(lastChan[LastVoice.snd]) <> 0)) then |
446 if (not isSoundEnabled) or fastUntilLag or ((LastVoice.snd <> sndNone) and (lastChan[LastVoice.snd] <> -1) and (Mix_Playing(lastChan[LastVoice.snd]) <> 0)) then |
312 exit; |
447 exit; |
313 i:= 0; |
448 i:= 0; |
314 while (i<8) and (VoiceList[i].snd = sndNone) do |
449 while (i<High(VoiceList)) and (VoiceList[i].snd = sndNone) do |
315 inc(i); |
450 inc(i); |
316 |
451 |
317 if (VoiceList[i].snd <> sndNone) then |
452 if (VoiceList[i].snd <> sndNone) then |
318 begin |
453 begin |
319 LastVoice.snd:= VoiceList[i].snd; |
454 LastVoice.snd:= VoiceList[i].snd; |
320 LastVoice.voicepack:= VoiceList[i].voicepack; |
455 LastVoice.voicepack:= VoiceList[i].voicepack; |
321 VoiceList[i].snd:= sndNone; |
456 VoiceList[i].snd:= sndNone; |
411 end; |
546 end; |
412 |
547 |
413 procedure PlayMusic; |
548 procedure PlayMusic; |
414 var s: shortstring; |
549 var s: shortstring; |
415 begin |
550 begin |
416 if (not isSoundEnabled) or (MusicFN = '') or (not isMusicEnabled) then |
551 if (MusicFN = '') or (not isMusicEnabled) then |
417 exit; |
552 exit; |
418 |
553 |
419 s:= '/Music/' + MusicFN; |
554 s:= '/Music/' + MusicFN; |
420 WriteToConsole(msgLoading + s + ' '); |
555 WriteToConsole(msgLoading + s + ' '); |
421 |
556 |
432 end; |
567 end; |
433 |
568 |
434 function ChangeVolume(voldelta: LongInt): LongInt; |
569 function ChangeVolume(voldelta: LongInt): LongInt; |
435 begin |
570 begin |
436 ChangeVolume:= 0; |
571 ChangeVolume:= 0; |
437 if (not isSoundEnabled) or ((voldelta = 0) and (not (cInitVolume = 0))) then |
572 if not (isSoundEnabled or isMusicEnabled) or ((voldelta = 0) and (not (cInitVolume = 0))) then |
438 exit; |
573 exit; |
439 |
574 |
440 inc(Volume, voldelta); |
575 inc(Volume, voldelta); |
441 if Volume < 0 then |
576 if Volume < 0 then |
442 Volume:= 0; |
577 Volume:= 0; |
472 ChangeVolume(previousVolume - Volume); |
607 ChangeVolume(previousVolume - Volume); |
473 end; |
608 end; |
474 |
609 |
475 procedure MuteAudio; |
610 procedure MuteAudio; |
476 begin |
611 begin |
477 if not isSoundEnabled then |
612 if not (isSoundEnabled or isMusicEnabled) then |
478 exit; |
613 exit; |
479 |
614 |
480 if (isAudioMuted) then |
615 if (isAudioMuted) then |
481 begin |
616 begin |
482 ResumeMusic; |
617 ResumeMusic; |
587 if voicepacks[t].name <> '' then |
722 if voicepacks[t].name <> '' then |
588 for i:= Low(TSound) to High(TSound) do |
723 for i:= Low(TSound) to High(TSound) do |
589 voicepacks[t].chunks[i]:= nil; |
724 voicepacks[t].chunks[i]:= nil; |
590 |
725 |
591 (* on MOBILE SDL_mixer has to be compiled against Tremor (USE_OGG_TREMOR) |
726 (* on MOBILE SDL_mixer has to be compiled against Tremor (USE_OGG_TREMOR) |
592 or sound files bigger than 32k will lockup the game *) |
727 or sound files bigger than 32k will lockup the game on slow cpu *) |
593 for i:= Low(TSound) to High(TSound) do |
728 for i:= Low(TSound) to High(TSound) do |
594 defVoicepack^.chunks[i]:= nil; |
729 defVoicepack^.chunks[i]:= nil; |
595 |
730 |
596 end; |
731 end; |
597 |
732 |
598 procedure freeModule; |
733 procedure freeModule; |
599 begin |
734 begin |
600 if isSoundEnabled then |
735 if isSoundEnabled or isMusicEnabled then |
601 ReleaseSound(true); |
736 ReleaseSound(true); |
602 end; |
737 end; |
603 |
738 |
604 end. |
739 end. |
605 |
740 |