hedgewars/uSound.pas
changeset 3532 04e2fea3e83a
parent 3529 0e968ba12a84
child 3615 b78d7959540a
equal deleted inserted replaced
3527:c4e0ef164162 3532:04e2fea3e83a
    38 procedure SoundLoad;
    38 procedure SoundLoad;
    39 procedure PlaySound(snd: TSound);
    39 procedure PlaySound(snd: TSound);
    40 procedure PlaySound(snd: TSound; keepPlaying: boolean);
    40 procedure PlaySound(snd: TSound; keepPlaying: boolean);
    41 procedure PlaySound(snd: TSound; voicepack: PVoicepack);
    41 procedure PlaySound(snd: TSound; voicepack: PVoicepack);
    42 procedure PlaySound(snd: TSound; voicepack: PVoicepack; keepPlaying: boolean);
    42 procedure PlaySound(snd: TSound; voicepack: PVoicepack; keepPlaying: boolean);
    43 function LoopSound(snd: TSound): LongInt;
    43 function  LoopSound(snd: TSound): LongInt;
    44 function LoopSound(snd: TSound; voicepack: PVoicepack): LongInt;
    44 function  LoopSound(snd: TSound; voicepack: PVoicepack): LongInt;
    45 procedure PlayMusic;
    45 procedure PlayMusic;
    46 procedure PauseMusic;
    46 procedure PauseMusic;
    47 procedure ResumeMusic;
    47 procedure ResumeMusic;
    48 procedure StopSound(snd: TSound);
    48 procedure StopSound(snd: TSound);
    49 procedure StopSound(chn: LongInt);
    49 procedure StopSound(chn: LongInt);
    63 
    63 
    64 function  AskForVoicepack(name: shortstring): Pointer;
    64 function  AskForVoicepack(name: shortstring): Pointer;
    65 var i: Longword;
    65 var i: Longword;
    66 begin
    66 begin
    67 i:= 0;
    67 i:= 0;
    68 while (voicepacks[i].name <> name) and (voicepacks[i].name <> '') do
    68     while (voicepacks[i].name <> name) and (voicepacks[i].name <> '') do
    69     begin
    69     begin
    70     inc(i);
    70         inc(i);
    71     TryDo(i <= cMaxTeams, 'Engine bug: AskForVoicepack i > cMaxTeams', true)
    71         TryDo(i <= cMaxTeams, 'Engine bug: AskForVoicepack i > cMaxTeams', true)
    72     end;
    72     end;
    73 
    73 
    74 voicepacks[i].name:= name;
    74     voicepacks[i].name:= name;
    75 AskForVoicepack:= @voicepacks[i]
    75     AskForVoicepack:= @voicepacks[i]
    76 end;
    76 end;
    77 
    77 
    78 procedure InitSound;
    78 procedure InitSound;
    79 var i: TSound;
    79 var i: TSound;
    80 begin
    80 begin
   108 
   108 
   109 procedure ReleaseSound;
   109 procedure ReleaseSound;
   110 var i: TSound;
   110 var i: TSound;
   111     t: Longword;
   111     t: Longword;
   112 begin
   112 begin
   113 for t:= 0 to cMaxTeams do
   113     for t:= 0 to cMaxTeams do
   114     if voicepacks[t].name <> '' then
   114         if voicepacks[t].name <> '' then
   115         for i:= Low(TSound) to High(TSound) do
   115             for i:= Low(TSound) to High(TSound) do
   116             if voicepacks[t].chunks[i] <> nil then
   116                 if voicepacks[t].chunks[i] <> nil then
   117                 Mix_FreeChunk(voicepacks[t].chunks[i]);
   117                     Mix_FreeChunk(voicepacks[t].chunks[i]);
   118 
   118 
   119 if Mus <> nil then
   119     if Mus <> nil then
   120     Mix_FreeMusic(Mus);
   120         Mix_FreeMusic(Mus);
   121 
   121 
   122 {$IFDEF SDL_MIXER_NEWER}
   122 {$IFDEF SDL_MIXER_NEWER}
   123 // make sure all instances of sdl_mixer are unloaded before continuing
   123     // make sure all instances of sdl_mixer are unloaded before continuing
   124 while Mix_Init(0) <> 0 do
   124     while Mix_Init(0) <> 0 do
   125     Mix_Quit();
   125         Mix_Quit();
   126 {$ENDIF}    
   126 {$ENDIF}    
   127 
   127 
   128 Mix_CloseAudio();
   128     Mix_CloseAudio();
   129 end;
   129 end;
   130 
   130 
   131 procedure SoundLoad;
   131 procedure SoundLoad;
   132 var i: TSound;
   132 var i: TSound;
   133     s: shortstring;
   133     s: shortstring;
   135 begin
   135 begin
   136     if not isSoundEnabled then exit;
   136     if not isSoundEnabled then exit;
   137 
   137 
   138     defVoicepack:= AskForVoicepack('Default');
   138     defVoicepack:= AskForVoicepack('Default');
   139 
   139 
   140 for i:= Low(TSound) to High(TSound) do
   140     for i:= Low(TSound) to High(TSound) do
   141     if (Soundz[i].Path <> ptVoices) and (Soundz[i].FileName <> '') then
   141         if (Soundz[i].Path <> ptVoices) and (Soundz[i].FileName <> '') then
   142         begin
   142         begin
   143         s:= Pathz[Soundz[i].Path] + '/' + Soundz[i].FileName;
   143             s:= Pathz[Soundz[i].Path] + '/' + Soundz[i].FileName;
   144         WriteToConsole(msgLoading + s + ' ');
   144             WriteToConsole(msgLoading + s + ' ');
   145         defVoicepack^.chunks[i]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), 'rb'), 1);
   145             defVoicepack^.chunks[i]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), 'rb'), 1);
   146         TryDo(defVoicepack^.chunks[i] <> nil, msgFailed, true);
   146             TryDo(defVoicepack^.chunks[i] <> nil, msgFailed, true);
   147         WriteLnToConsole(msgOK);
   147             WriteLnToConsole(msgOK);
   148         end;
   148         end;
   149 
   149 
   150 for t:= 0 to cMaxTeams do
   150     for t:= 0 to cMaxTeams do
   151     if voicepacks[t].name <> '' then
   151         if voicepacks[t].name <> '' then
   152         for i:= Low(TSound) to High(TSound) do
   152             for i:= Low(TSound) to High(TSound) do
   153             if (Soundz[i].Path = ptVoices) and (Soundz[i].FileName <> '') then
   153                 if (Soundz[i].Path = ptVoices) and (Soundz[i].FileName <> '') then
   154                 begin
   154                 begin
   155                 s:= Pathz[Soundz[i].Path] + '/' + voicepacks[t].name + '/' + Soundz[i].FileName;
   155                     s:= Pathz[Soundz[i].Path] + '/' + voicepacks[t].name + '/' + Soundz[i].FileName;
   156                 WriteToConsole(msgLoading + s + ' ');
   156                     WriteToConsole(msgLoading + s + ' ');
   157                 voicepacks[t].chunks[i]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), 'rb'), 1);
   157                     voicepacks[t].chunks[i]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), 'rb'), 1);
   158                 if voicepacks[t].chunks[i] = nil then
   158                     if voicepacks[t].chunks[i] = nil then
   159                     WriteLnToConsole(msgFailed)
   159                         WriteLnToConsole(msgFailed)
   160                 else
   160                     else
   161                     WriteLnToConsole(msgOK)
   161                         WriteLnToConsole(msgOK)
   162                 end;
   162                 end;
   163 end;
   163 end;
   164 
   164 
   165 procedure PlaySound(snd: TSound);
   165 procedure PlaySound(snd: TSound);
   166 begin
   166 begin
   177     PlaySound(snd, voicepack, false);
   177     PlaySound(snd, voicepack, false);
   178 end;
   178 end;
   179 
   179 
   180 procedure PlaySound(snd: TSound; voicepack: PVoicepack; keepPlaying: boolean);
   180 procedure PlaySound(snd: TSound; voicepack: PVoicepack; keepPlaying: boolean);
   181 begin
   181 begin
   182 if (not isSoundEnabled) or fastUntilLag then exit;
   182     if (not isSoundEnabled) or fastUntilLag then
   183 
   183         exit;
   184 if keepPlaying and (lastChan[snd] <> -1) and (Mix_Playing(lastChan[snd]) <> 0) then
   184 
   185     exit;
   185     if keepPlaying and (lastChan[snd] <> -1) and (Mix_Playing(lastChan[snd]) <> 0) then
   186 
   186         exit;
   187 if (voicepack <> nil) and (voicepack^.chunks[snd] <> nil) then
   187 
   188     lastChan[snd]:= Mix_PlayChannelTimed(-1, voicepack^.chunks[snd], 0, -1)
   188     if (voicepack <> nil) and (voicepack^.chunks[snd] <> nil) then
   189 else
   189         lastChan[snd]:= Mix_PlayChannelTimed(-1, voicepack^.chunks[snd], 0, -1)
   190     lastChan[snd]:= Mix_PlayChannelTimed(-1, defVoicepack^.chunks[snd], 0, -1)
   190     else
       
   191         lastChan[snd]:= Mix_PlayChannelTimed(-1, defVoicepack^.chunks[snd], 0, -1)
   191 end;
   192 end;
   192 
   193 
   193 function LoopSound(snd: TSound): LongInt;
   194 function LoopSound(snd: TSound): LongInt;
   194 begin
   195 begin
   195     LoopSound:= LoopSound(snd, nil)
   196     LoopSound:= LoopSound(snd, nil)
   196 end;
   197 end;
   197 
   198 
   198 function LoopSound(snd: TSound; voicepack: PVoicepack): LongInt;
   199 function LoopSound(snd: TSound; voicepack: PVoicepack): LongInt;
   199 begin
   200 begin
   200 if (not isSoundEnabled) or fastUntilLag then
   201     if (not isSoundEnabled) or fastUntilLag then
   201     begin
   202     begin
   202     LoopSound:= -1;
   203         LoopSound:= -1;
   203     exit
   204         exit
   204     end;
   205     end;
   205 
   206 
   206 if (voicepack <> nil) and (voicepack^.chunks[snd] <> nil) then
   207     if (voicepack <> nil) and (voicepack^.chunks[snd] <> nil) then
   207     LoopSound:= Mix_PlayChannelTimed(-1, voicepack^.chunks[snd], -1, -1)
   208         LoopSound:= Mix_PlayChannelTimed(-1, voicepack^.chunks[snd], -1, -1)
   208 else
   209     else
   209     LoopSound:= Mix_PlayChannelTimed(-1, defVoicepack^.chunks[snd], -1, -1)
   210         LoopSound:= Mix_PlayChannelTimed(-1, defVoicepack^.chunks[snd], -1, -1)
   210 end;
   211 end;
   211 
   212 
   212 procedure StopSound(snd: TSound);
   213 procedure StopSound(snd: TSound);
   213 begin
   214 begin
   214 if not isSoundEnabled then exit;
   215     if not isSoundEnabled then exit;
   215 if (lastChan[snd] <> -1) and (Mix_Playing(lastChan[snd]) <> 0) then
   216     if (lastChan[snd] <> -1) and (Mix_Playing(lastChan[snd]) <> 0) then
   216     begin
   217     begin
   217     Mix_HaltChannel(lastChan[snd]);
   218         Mix_HaltChannel(lastChan[snd]);
   218     lastChan[snd]:= -1;
   219         lastChan[snd]:= -1;
   219     end;
   220     end;
   220 end;
   221 end;
   221 
   222 
   222 procedure StopSound(chn: LongInt);
   223 procedure StopSound(chn: LongInt);
   223 begin
   224 begin
   224 if not isSoundEnabled then exit;
   225     if not isSoundEnabled then exit;
   225 if (chn <> -1) and (Mix_Playing(chn) <> 0) then Mix_HaltChannel(chn);
   226 
       
   227     if (chn <> -1) and (Mix_Playing(chn) <> 0) then
       
   228         Mix_HaltChannel(chn);
   226 end;
   229 end;
   227 
   230 
   228 procedure PlayMusic;
   231 procedure PlayMusic;
   229 var s: shortstring;
   232 var s: shortstring;
   230 begin
   233 begin
   231 if (not isSoundEnabled)
   234     if (not isSoundEnabled) or (MusicFN = '') or (not isMusicEnabled) then
   232     or (MusicFN = '')
   235         exit;
   233     or (not isMusicEnabled) then exit;
   236 
   234 
   237     s:= PathPrefix + '/Music/' + MusicFN;
   235 s:= PathPrefix + '/Music/' + MusicFN;
   238     WriteToConsole(msgLoading + s + ' ');
   236 WriteToConsole(msgLoading + s + ' ');
   239 
   237 
   240     Mus:= Mix_LoadMUS(Str2PChar(s));
   238 Mus:= Mix_LoadMUS(Str2PChar(s));
   241     TryDo(Mus <> nil, msgFailed, false);
   239 TryDo(Mus <> nil, msgFailed, false);
   242     WriteLnToConsole(msgOK);
   240 WriteLnToConsole(msgOK);
   243 
   241 
   244     SDLTry(Mix_FadeInMusic(Mus, -1, 3000) <> -1, false)
   242 SDLTry(Mix_FadeInMusic(Mus, -1, 3000) <> -1, false)
       
   243 end;
   245 end;
   244 
   246 
   245 function ChangeVolume(voldelta: LongInt): LongInt;
   247 function ChangeVolume(voldelta: LongInt): LongInt;
   246 begin
   248 begin
   247 if not isSoundEnabled then
   249     if not isSoundEnabled then
   248     exit(0);
   250         exit(0);
   249 
   251 
   250 inc(Volume, voldelta);
   252     inc(Volume, voldelta);
   251 if Volume < 0 then Volume:= 0;
   253     if Volume < 0 then Volume:= 0;
   252 Mix_Volume(-1, Volume);
   254     Mix_Volume(-1, Volume);
   253 Volume:= Mix_Volume(-1, -1);
   255     Volume:= Mix_Volume(-1, -1);
   254 if isMusicEnabled then Mix_VolumeMusic(Volume * 4 div 8);
   256     if isMusicEnabled then Mix_VolumeMusic(Volume * 4 div 8);
   255 ChangeVolume:= Volume * 100 div MIX_MAX_VOLUME
   257     ChangeVolume:= Volume * 100 div MIX_MAX_VOLUME
   256 end;
   258 end;
   257 
   259 
   258 procedure PauseMusic;
   260 procedure PauseMusic;
   259 begin
   261 begin
   260 if (MusicFN = '') or (not isMusicEnabled) then exit;
   262     if (MusicFN = '') or (not isMusicEnabled) then
   261 
   263         exit;
   262 Mix_PauseMusic(Mus);
   264 
       
   265     Mix_PauseMusic(Mus);
   263 end;
   266 end;
   264 
   267 
   265 procedure ResumeMusic;
   268 procedure ResumeMusic;
   266 begin
   269 begin
   267 if (MusicFN = '') or (not isMusicEnabled) then exit;
   270     if (MusicFN = '') or (not isMusicEnabled) then
   268 
   271         exit;
   269 Mix_ResumeMusic(Mus);
   272 
       
   273     Mix_ResumeMusic(Mus);
   270 end;
   274 end;
   271 
   275 
   272 procedure initModule;
   276 procedure initModule;
   273 begin
   277 begin
   274     MusicFN:='';
   278     MusicFN:='';