hedgewars/uSound.pas
changeset 7021 0c75512a8920
parent 6990 40e5af28d026
child 7024 3e1cca870090
--- a/hedgewars/uSound.pas	Sat May 05 00:01:12 2012 +0400
+++ b/hedgewars/uSound.pas	Sat May 05 15:17:16 2012 +0100
@@ -35,25 +35,24 @@
 interface
 uses SDLh, uConsts, uTypes, sysutils;
 
-var MusicFN: shortstring; // music file name
-    previousVolume: LongInt; // cached volume value
-
 procedure initModule;
 procedure freeModule;
 
-procedure InitSound; // Initiates sound-system if isSoundEnabled.
-procedure ReleaseSound(complete: boolean); // Releases sound-system and used resources.
-procedure SoundLoad; // Preloads some sounds for performance reasons.
-
+procedure InitSound;                            // Initiates sound-system if isSoundEnabled.
+procedure ReleaseSound(complete: boolean);      // Releases sound-system and used resources.
+procedure SetSound;                             // Reset sound state to the previous state.
+procedure SetSound(enabled: boolean);           // Enable/disable sound-system and backup status.
 
 // MUSIC
 
-// Obvious music commands for music track specified in MusicFN.
-procedure PlayMusic;
-procedure PauseMusic;
-procedure ResumeMusic;
-procedure ChangeMusic; // Replaces music track with current MusicFN and plays it.
-procedure StopMusic; // Stops and releases the current track
+// Obvious music commands for music track
+procedure SetMusic(enabled: boolean);           // Enable/disable music.
+procedure SetMusic(musicname: shortstring);     // Enable/disable music and set name of musicfile to play.
+procedure PlayMusic;                            // Play music from the start.
+procedure PauseMusic;                           // Pause music.
+procedure ResumeMusic;                          // Resume music from pause point.
+procedure ChangeMusic(musicname: shortstring);  // Replaces music track with musicname and plays it.
+procedure StopMusic;                            // Stops and releases the current track.
 
 
 // SOUNDS
@@ -85,13 +84,16 @@
 
 // MISC
 
+// Set the initial volume
+procedure SetVolume(volume: LongInt);
+
 // Modifies the sound volume of the game by voldelta and returns the new volume level.
 function  ChangeVolume(voldelta: LongInt): LongInt;
 
 // Returns a pointer to the voicepack with the given name.
 function  AskForVoicepack(name: shortstring): Pointer;
 
-// Drastically lower the volume when we lose focus (and restore the previous value)
+// Drastically lower the volume when we lose focus (and restore the previous value).
 procedure DampenAudio;
 procedure UndampenAudio;
 
@@ -104,6 +106,13 @@
     voicepacks: array[0..cMaxTeams] of TVoicepack;
     defVoicepack: PVoicepack;
     Mus: PMixMusic = nil;
+    MusicFN: shortstring; // music file name
+    previousVolume: LongInt; // cached volume value
+    isMusicEnabled: boolean;
+    isSoundEnabled: boolean;
+    isSEBackup: boolean;
+    cInitVolume: LongInt;
+
 
 function  AskForVoicepack(name: shortstring): Pointer;
 var i: Longword;
@@ -151,44 +160,43 @@
 end;
 
 procedure InitSound;
-var i: TSound;
-    channels: LongInt;
+const channels: LongInt = {$IFDEF MOBILE}1{$ELSE}2{$ENDIF};
 begin
     if not isSoundEnabled then
         exit;
     WriteToConsole('Init sound...');
     isSoundEnabled:= SDL_InitSubSystem(SDL_INIT_AUDIO) >= 0;
 
-{$IFDEF MOBILE}
-    channels:= 1;
-{$ELSE}
-    channels:= 2;
-{$ENDIF}
-
     if isSoundEnabled then
         isSoundEnabled:= Mix_OpenAudio(44100, $8010, channels, 1024) = 0;
 
-    WriteToConsole('Init SDL_mixer... ');
-    SDLTry(Mix_Init(MIX_INIT_OGG) <> 0, true);
-    WriteLnToConsole(msgOK);
-
     if isSoundEnabled then
         WriteLnToConsole(msgOK)
     else
         WriteLnToConsole(msgFailed);
 
+    WriteToConsole('Init SDL_mixer... ');
+    SDLTry(Mix_Init(MIX_INIT_OGG) <> 0, true);
+    WriteLnToConsole(msgOK);
+
     Mix_AllocateChannels(Succ(chanTPU));
-    if isMusicEnabled then
-        Mix_VolumeMusic(50);
-    for i:= Low(TSound) to High(TSound) do
-        lastChan[i]:= -1;
+    ChangeVolume(cInitVolume);
+    defVoicepack:= AskForVoicepack('Default');
+end;
 
-    Volume:= 0;
-    ChangeVolume(cInitVolume)
+procedure SetSound;
+begin
+    isSoundEnabled:= isSEBackup;
+end;
+
+procedure SetSound(enabled: boolean);
+begin
+    isSEBackup:= isSoundEnabled;
+    isSoundEnabled:= enabled;
 end;
 
 // when complete is false, this procedure just releases some of the chucks on inactive channels
-// this way music is not stopped, nor are chucks currently being plauyed
+// in this way music is not stopped, nor are chucks currently being played
 procedure ReleaseSound(complete: boolean);
 var i: TSound;
     t: Longword;
@@ -224,41 +232,6 @@
         end;
 end;
 
-procedure SoundLoad;
-var i: TSound;
-    t: Longword;
-begin
-    if not isSoundEnabled then
-        exit;
-
-    defVoicepack:= AskForVoicepack('Default');
-
-    // initialize all voices to nil so that they can be loaded when needed
-    for t:= 0 to cMaxTeams do
-        if voicepacks[t].name <> '' then
-            for i:= Low(TSound) to High(TSound) do
-                voicepacks[t].chunks[i]:= nil;
-
-    for i:= Low(TSound) to High(TSound) do
-    begin
-        defVoicepack^.chunks[i]:= nil;
-        (* this is not necessary when SDL_mixer is compiled with USE_OGG_TREMOR
-        // preload all the big sound files (>32k) that would otherwise lockup the game
-        if (i in [sndBeeWater, sndBee, sndCake, sndHellishImpact1, sndHellish, sndHomerun,
-                  sndMolotov, sndMortar, sndRideOfTheValkyries, sndYoohoo])
-            and (Soundz[i].Path <> ptVoices) and (Soundz[i].FileName <> '') then
-        begin
-            s:= UserPathz[Soundz[i].Path] + '/' + Soundz[i].FileName;
-            if not FileExists(s) then s:= Pathz[Soundz[i].Path] + '/' + Soundz[i].FileName;
-            WriteToConsole(msgLoading + s + ' ');
-            defVoicepack^.chunks[i]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), 'rb'), 1);
-            SDLTry(defVoicepack^.chunks[i] <> nil, true);
-            WriteLnToConsole(msgOK);
-        end;*)
-    end;
-
-end;
-
 procedure PlaySound(snd: TSound);
 begin
     PlaySound(snd, nil, false);
@@ -466,6 +439,11 @@
     SDLTry(Mix_FadeInMusic(Mus, -1, 3000) <> -1, false)
 end;
 
+procedure SetVolume(volume: LongInt);
+begin
+    cInitVolume:= volume;
+end;
+
 function ChangeVolume(voldelta: LongInt): LongInt;
 begin
     ChangeVolume:= 0;
@@ -475,7 +453,9 @@
     inc(Volume, voldelta);
     if Volume < 0 then
         Volume:= 0;
+    // apply Volume to all channels
     Mix_Volume(-1, Volume);
+    // get assigned Volume
     Volume:= Mix_Volume(-1, -1);
     if isMusicEnabled then
         Mix_VolumeMusic(Volume * 4 div 8);
@@ -490,7 +470,19 @@
 
 procedure UndampenAudio;
 begin
-ChangeVolume(previousVolume - Volume);
+    ChangeVolume(previousVolume - Volume);
+end;
+
+procedure SetMusic(enabled: boolean);
+begin
+    isMusicEnabled:= enabled;
+    MusicFN:= '';
+end;
+
+procedure SetMusic(musicname: shortstring);
+begin
+    isMusicEnabled:= not (musicname = '');    
+    MusicFN:= musicname;
 end;
 
 procedure PauseMusic;
@@ -511,8 +503,9 @@
         Mix_ResumeMusic(Mus);
 end;
 
-procedure ChangeMusic;
+procedure ChangeMusic(musicname: shortstring);
 begin
+    MusicFN:= musicname;
     if (MusicFN = '') or (not isMusicEnabled) then
         exit;
 
@@ -543,9 +536,32 @@
 end;
 
 procedure initModule;
+var t: LongInt;
+    i: TSound;
 begin
     RegisterVariable('voicepack', @chVoicepack, false);
+
     MusicFN:='';
+    isMusicEnabled:= true;
+    isSoundEnabled:= true;
+    isSEBackup:= isSoundEnabled;
+    cInitVolume:= 100;
+    Volume:= 0;
+
+    for i:= Low(TSound) to High(TSound) do
+        lastChan[i]:= -1;
+
+    // initialize all voices to nil so that they can be loaded lazily
+    for t:= 0 to cMaxTeams do
+        if voicepacks[t].name <> '' then
+            for i:= Low(TSound) to High(TSound) do
+                voicepacks[t].chunks[i]:= nil;
+
+    (* on MOBILE SDL_mixer has to be compiled against Tremor (USE_OGG_TREMOR)
+       or sound files bigger than 32k will lockup the game*)
+    for i:= Low(TSound) to High(TSound) do
+        defVoicepack^.chunks[i]:= nil;
+
 end;
 
 procedure freeModule;