hedgewars/uSound.pas
changeset 6580 6155187bf599
parent 6551 a2f39cb9af62
child 6700 e04da46ee43c
equal deleted inserted replaced
6579:fc52f7c22c9b 6580:6155187bf599
   109     // First, attempt to locate a localised version of the voice
   109     // First, attempt to locate a localised version of the voice
   110     if cLocale <> 'en' then
   110     if cLocale <> 'en' then
   111         begin
   111         begin
   112         locName:= name+'_'+cLocale;
   112         locName:= name+'_'+cLocale;
   113         path:= UserPathz[ptVoices] + '/' + locName;
   113         path:= UserPathz[ptVoices] + '/' + locName;
   114         if DirectoryExists(path) then name:= locName
   114         if DirectoryExists(path) then
       
   115             name:= locName
   115         else
   116         else
   116             begin
   117             begin
   117             path:= Pathz[ptVoices] + '/' + locName;
   118             path:= Pathz[ptVoices] + '/' + locName;
   118             if DirectoryExists(path) then name:= locName
   119             if DirectoryExists(path) then
   119             else if Length(cLocale) > 2 then
   120                 name:= locName
       
   121             else if Length(cLocale) > 2
       
   122                 then
   120                 begin
   123                 begin
   121                 locName:= name+'_'+Copy(cLocale,1,2);
   124                 locName:= name+'_'+Copy(cLocale,1,2);
   122                 path:= UserPathz[ptVoices] + '/' + locName;
   125                 path:= UserPathz[ptVoices] + '/' + locName;
   123                 if DirectoryExists(path) then name:= locName
   126                 if DirectoryExists(path) then
       
   127                     name:= locName
   124                 else
   128                 else
   125                     begin
   129                     begin
   126                     path:= Pathz[ptVoices] + '/' + locName;
   130                     path:= Pathz[ptVoices] + '/' + locName;
   127                     if DirectoryExists(path) then name:= locName
   131                     if DirectoryExists(path) then
       
   132                         name:= locName
   128                     end
   133                     end
   129                 end
   134                 end
   130             end
   135             end
   131         end;
   136         end;
   132 
   137 
   143 
   148 
   144 procedure InitSound;
   149 procedure InitSound;
   145 var i: TSound;
   150 var i: TSound;
   146     channels: LongInt;
   151     channels: LongInt;
   147 begin
   152 begin
   148     if not isSoundEnabled then exit;
   153     if not isSoundEnabled then
       
   154         exit;
   149     WriteToConsole('Init sound...');
   155     WriteToConsole('Init sound...');
   150     isSoundEnabled:= SDL_InitSubSystem(SDL_INIT_AUDIO) >= 0;
   156     isSoundEnabled:= SDL_InitSubSystem(SDL_INIT_AUDIO) >= 0;
   151 
   157 
   152 {$IFDEF MOBILE}
   158 {$IFDEF MOBILE}
   153     channels:= 1;
   159     channels:= 1;
   216 
   222 
   217 procedure SoundLoad;
   223 procedure SoundLoad;
   218 var i: TSound;
   224 var i: TSound;
   219     t: Longword;
   225     t: Longword;
   220 begin
   226 begin
   221     if not isSoundEnabled then exit;
   227     if not isSoundEnabled then
       
   228         exit;
   222 
   229 
   223     defVoicepack:= AskForVoicepack('Default');
   230     defVoicepack:= AskForVoicepack('Default');
   224 
   231 
   225     // initialize all voices to nil so that they can be loaded when needed
   232     // initialize all voices to nil so that they can be loaded when needed
   226     for t:= 0 to cMaxTeams do
   233     for t:= 0 to cMaxTeams do
   275     if (voicepack <> nil) then
   282     if (voicepack <> nil) then
   276         begin
   283         begin
   277         if (voicepack^.chunks[snd] = nil) and (Soundz[snd].Path = ptVoices) and (Soundz[snd].FileName <> '') then
   284         if (voicepack^.chunks[snd] = nil) and (Soundz[snd].Path = ptVoices) and (Soundz[snd].FileName <> '') then
   278             begin
   285             begin
   279             s:= UserPathz[Soundz[snd].Path] + '/' + voicepack^.name + '/' + Soundz[snd].FileName;
   286             s:= UserPathz[Soundz[snd].Path] + '/' + voicepack^.name + '/' + Soundz[snd].FileName;
   280             if not FileExists(s) then s:= Pathz[Soundz[snd].Path] + '/' + voicepack^.name + '/' + Soundz[snd].FileName;
   287             if not FileExists(s) then
       
   288                 s:= Pathz[Soundz[snd].Path] + '/' + voicepack^.name + '/' + Soundz[snd].FileName;
   281             WriteToConsole(msgLoading + s + ' ');
   289             WriteToConsole(msgLoading + s + ' ');
   282             voicepack^.chunks[snd]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), 'rb'), 1);
   290             voicepack^.chunks[snd]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), 'rb'), 1);
   283             if voicepack^.chunks[snd] = nil then
   291             if voicepack^.chunks[snd] = nil then
   284                 WriteLnToConsole(msgFailed)
   292                 WriteLnToConsole(msgFailed)
   285             else
   293             else
   290     else
   298     else
   291         begin
   299         begin
   292         if (defVoicepack^.chunks[snd] = nil) and (Soundz[snd].Path <> ptVoices) and (Soundz[snd].FileName <> '') then
   300         if (defVoicepack^.chunks[snd] = nil) and (Soundz[snd].Path <> ptVoices) and (Soundz[snd].FileName <> '') then
   293             begin
   301             begin
   294             s:= UserPathz[Soundz[snd].Path] + '/' + Soundz[snd].FileName;
   302             s:= UserPathz[Soundz[snd].Path] + '/' + Soundz[snd].FileName;
   295             if not FileExists(s) then s:= Pathz[Soundz[snd].Path] + '/' + Soundz[snd].FileName;
   303             if not FileExists(s) then
       
   304                 s:= Pathz[Soundz[snd].Path] + '/' + Soundz[snd].FileName;
   296             WriteToConsole(msgLoading + s + ' ');
   305             WriteToConsole(msgLoading + s + ' ');
   297             defVoicepack^.chunks[snd]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), 'rb'), 1);
   306             defVoicepack^.chunks[snd]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), 'rb'), 1);
   298             SDLTry(defVoicepack^.chunks[snd] <> nil, true);
   307             SDLTry(defVoicepack^.chunks[snd] <> nil, true);
   299             WriteLnToConsole(msgOK);
   308             WriteLnToConsole(msgOK);
   300             end;
   309             end;
   303 end;
   312 end;
   304 
   313 
   305 procedure AddVoice(snd: TSound; voicepack: PVoicepack);
   314 procedure AddVoice(snd: TSound; voicepack: PVoicepack);
   306 var i : LongInt;
   315 var i : LongInt;
   307 begin
   316 begin
   308     if (not isSoundEnabled) or fastUntilLag or ((LastVoice.snd = snd) and  (LastVoice.voicepack = voicepack)) then exit;
   317     if (not isSoundEnabled) or fastUntilLag or ((LastVoice.snd = snd) and  (LastVoice.voicepack = voicepack)) then
       
   318         exit;
   309     if (snd = sndVictory) or (snd = sndFlawless) then
   319     if (snd = sndVictory) or (snd = sndFlawless) then
   310         begin
   320         begin
   311         Mix_FadeOutChannel(-1, 800);
   321         Mix_FadeOutChannel(-1, 800);
   312         for i:= 0 to 7 do VoiceList[i].snd:= sndNone;
   322         for i:= 0 to 7 do
       
   323             VoiceList[i].snd:= sndNone;
   313         LastVoice.snd:= sndNone;
   324         LastVoice.snd:= sndNone;
   314         end;
   325         end;
   315 
   326 
   316     i:= 0;
   327     i:= 0;
   317     while (i<8) and (VoiceList[i].snd <> sndNone) do inc(i);
   328     while (i<8) and (VoiceList[i].snd <> sndNone) do
       
   329         inc(i);
   318 
   330 
   319     // skip playing same sound for same hog twice
   331     // skip playing same sound for same hog twice
   320     if (i>0) and (VoiceList[i-1].snd = snd) and (VoiceList[i-1].voicepack = voicepack) then exit;
   332     if (i>0) and (VoiceList[i-1].snd = snd) and (VoiceList[i-1].voicepack = voicepack) then
       
   333         exit;
   321     VoiceList[i].snd:= snd;
   334     VoiceList[i].snd:= snd;
   322     VoiceList[i].voicepack:= voicepack;
   335     VoiceList[i].voicepack:= voicepack;
   323 end;
   336 end;
   324 
   337 
   325 procedure PlayNextVoice;
   338 procedure PlayNextVoice;
   326 var i : LongInt;
   339 var i : LongInt;
   327 begin
   340 begin
   328     if (not isSoundEnabled) or fastUntilLag or ((LastVoice.snd <> sndNone) and (lastChan[LastVoice.snd] <> -1) and (Mix_Playing(lastChan[LastVoice.snd]) <> 0)) then exit;
   341     if (not isSoundEnabled) or fastUntilLag or ((LastVoice.snd <> sndNone) and (lastChan[LastVoice.snd] <> -1) and (Mix_Playing(lastChan[LastVoice.snd]) <> 0)) then
       
   342         exit;
   329     i:= 0;
   343     i:= 0;
   330     while (i<8) and (VoiceList[i].snd = sndNone) do inc(i);
   344     while (i<8) and (VoiceList[i].snd = sndNone) do
       
   345         inc(i);
   331     
   346     
   332     if (VoiceList[i].snd <> sndNone) then
   347     if (VoiceList[i].snd <> sndNone) then
   333         begin
   348         begin
   334         LastVoice.snd:= VoiceList[i].snd;
   349         LastVoice.snd:= VoiceList[i].snd;
   335         LastVoice.voicepack:= VoiceList[i].voicepack;
   350         LastVoice.voicepack:= VoiceList[i].voicepack;
   357 
   372 
   358 function LoopSound(snd: TSound; voicepack: PVoicepack; fadems: LongInt): LongInt;
   373 function LoopSound(snd: TSound; voicepack: PVoicepack; fadems: LongInt): LongInt;
   359 var s: shortstring;
   374 var s: shortstring;
   360 begin
   375 begin
   361     if (not isSoundEnabled) or fastUntilLag then
   376     if (not isSoundEnabled) or fastUntilLag then
   362     begin
   377         begin
   363         LoopSound:= -1;
   378         LoopSound:= -1;
   364         exit
   379         exit
   365     end;
   380         end;
   366 
   381 
   367     if (voicepack <> nil) then
   382     if (voicepack <> nil) then
   368     begin
   383         begin
   369         if (voicepack^.chunks[snd] = nil) and (Soundz[snd].Path = ptVoices) and (Soundz[snd].FileName <> '') then
   384         if (voicepack^.chunks[snd] = nil) and (Soundz[snd].Path = ptVoices) and (Soundz[snd].FileName <> '') then
   370         begin
   385            begin
   371             s:= UserPathz[Soundz[snd].Path] + '/' + voicepack^.name + '/' + Soundz[snd].FileName;
   386             s:= UserPathz[Soundz[snd].Path] + '/' + voicepack^.name + '/' + Soundz[snd].FileName;
   372             if not FileExists(s) then s:= Pathz[Soundz[snd].Path] + '/' + voicepack^.name + '/' + Soundz[snd].FileName;
   387             if not FileExists(s) then
       
   388                 s:= Pathz[Soundz[snd].Path] + '/' + voicepack^.name + '/' + Soundz[snd].FileName;
   373             WriteToConsole(msgLoading + s + ' ');
   389             WriteToConsole(msgLoading + s + ' ');
   374             voicepack^.chunks[snd]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), 'rb'), 1);
   390             voicepack^.chunks[snd]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), 'rb'), 1);
   375             if voicepack^.chunks[snd] = nil then
   391             if voicepack^.chunks[snd] = nil then
   376                 WriteLnToConsole(msgFailed)
   392                 WriteLnToConsole(msgFailed)
   377             else
   393             else
   378                 WriteLnToConsole(msgOK)
   394                 WriteLnToConsole(msgOK)
   379         end;
   395             end;
   380         LoopSound:= Mix_PlayChannelTimed(-1, voicepack^.chunks[snd], -1, -1)
   396         LoopSound:= Mix_PlayChannelTimed(-1, voicepack^.chunks[snd], -1, -1)
   381     end
   397         end
   382     else
   398     else
   383     begin
   399         begin
   384         if (defVoicepack^.chunks[snd] = nil) and (Soundz[snd].Path <> ptVoices) and (Soundz[snd].FileName <> '') then
   400         if (defVoicepack^.chunks[snd] = nil) and (Soundz[snd].Path <> ptVoices) and (Soundz[snd].FileName <> '') then
   385         begin
   401             begin
   386             s:= UserPathz[Soundz[snd].Path] + '/' + Soundz[snd].FileName;
   402             s:= UserPathz[Soundz[snd].Path] + '/' + Soundz[snd].FileName;
   387             if not FileExists(s) then s:= Pathz[Soundz[snd].Path] + '/' + Soundz[snd].FileName;
   403             if not FileExists(s) then
       
   404                 s:= Pathz[Soundz[snd].Path] + '/' + Soundz[snd].FileName;
   388             WriteToConsole(msgLoading + s + ' ');
   405             WriteToConsole(msgLoading + s + ' ');
   389             defVoicepack^.chunks[snd]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), 'rb'), 1);
   406             defVoicepack^.chunks[snd]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), 'rb'), 1);
   390             SDLTry(defVoicepack^.chunks[snd] <> nil, true);
   407             SDLTry(defVoicepack^.chunks[snd] <> nil, true);
   391             WriteLnToConsole(msgOK);
   408             WriteLnToConsole(msgOK);
   392         end;
   409             end;
   393         if fadems > 0 then
   410         if fadems > 0 then
   394             LoopSound:= Mix_FadeInChannelTimed(-1, defVoicepack^.chunks[snd], -1, fadems, -1)
   411             LoopSound:= Mix_FadeInChannelTimed(-1, defVoicepack^.chunks[snd], -1, fadems, -1)
   395         else
   412         else
   396             LoopSound:= Mix_PlayChannelTimed(-1, defVoicepack^.chunks[snd], -1, -1);
   413             LoopSound:= Mix_PlayChannelTimed(-1, defVoicepack^.chunks[snd], -1, -1);
   397     end;
   414         end;
   398 end;
   415 end;
   399 
   416 
   400 procedure StopSound(snd: TSound);
   417 procedure StopSound(snd: TSound);
   401 begin
   418 begin
   402     if not isSoundEnabled then exit;
   419     if not isSoundEnabled then
       
   420         exit;
   403 
   421 
   404     if (lastChan[snd] <> -1) and (Mix_Playing(lastChan[snd]) <> 0) then
   422     if (lastChan[snd] <> -1) and (Mix_Playing(lastChan[snd]) <> 0) then
   405     begin
   423         begin
   406         Mix_HaltChannel(lastChan[snd]);
   424         Mix_HaltChannel(lastChan[snd]);
   407         lastChan[snd]:= -1;
   425         lastChan[snd]:= -1;
   408     end;
   426         end;
   409 end;
   427 end;
   410 
   428 
   411 procedure StopSound(chn: LongInt);
   429 procedure StopSound(chn: LongInt);
   412 begin
   430 begin
   413     if not isSoundEnabled then exit;
   431     if not isSoundEnabled then
       
   432         exit;
   414 
   433 
   415     if (chn <> -1) and (Mix_Playing(chn) <> 0) then
   434     if (chn <> -1) and (Mix_Playing(chn) <> 0) then
   416         Mix_HaltChannel(chn);
   435         Mix_HaltChannel(chn);
   417 end;
   436 end;
   418 
   437 
   419 procedure StopSound(chn, fadems: LongInt);
   438 procedure StopSound(chn, fadems: LongInt);
   420 begin
   439 begin
   421     if not isSoundEnabled then exit;
   440     if not isSoundEnabled then
       
   441         exit;
   422 
   442 
   423     if (chn <> -1) and (Mix_Playing(chn) <> 0) then
   443     if (chn <> -1) and (Mix_Playing(chn) <> 0) then
   424         Mix_FadeOutChannel(chn, fadems);
   444         Mix_FadeOutChannel(chn, fadems);
   425 end;
   445 end;
   426 
   446 
   429 begin
   449 begin
   430     if (not isSoundEnabled) or (MusicFN = '') or (not isMusicEnabled) then
   450     if (not isSoundEnabled) or (MusicFN = '') or (not isMusicEnabled) then
   431         exit;
   451         exit;
   432 
   452 
   433     s:= UserPathPrefix + '/Data/Music/' + MusicFN;
   453     s:= UserPathPrefix + '/Data/Music/' + MusicFN;
   434     if not FileExists(s) then s:= PathPrefix + '/Music/' + MusicFN;
   454     if not FileExists(s) then
       
   455         s:= PathPrefix + '/Music/' + MusicFN;
   435     WriteToConsole(msgLoading + s + ' ');
   456     WriteToConsole(msgLoading + s + ' ');
   436 
   457 
   437     Mus:= Mix_LoadMUS(Str2PChar(s));
   458     Mus:= Mix_LoadMUS(Str2PChar(s));
   438     SDLTry(Mus <> nil, false);
   459     SDLTry(Mus <> nil, false);
   439     WriteLnToConsole(msgOK);
   460     WriteLnToConsole(msgOK);
   445 begin
   466 begin
   446     if not isSoundEnabled then
   467     if not isSoundEnabled then
   447         exit(0);
   468         exit(0);
   448 
   469 
   449     inc(Volume, voldelta);
   470     inc(Volume, voldelta);
   450     if Volume < 0 then Volume:= 0;
   471     if Volume < 0 then
       
   472         Volume:= 0;
   451     Mix_Volume(-1, Volume);
   473     Mix_Volume(-1, Volume);
   452     Volume:= Mix_Volume(-1, -1);
   474     Volume:= Mix_Volume(-1, -1);
   453     if isMusicEnabled then Mix_VolumeMusic(Volume * 4 div 8);
   475     if isMusicEnabled then
       
   476         Mix_VolumeMusic(Volume * 4 div 8);
   454     ChangeVolume:= Volume * 100 div MIX_MAX_VOLUME
   477     ChangeVolume:= Volume * 100 div MIX_MAX_VOLUME
   455 end;
   478 end;
   456 
   479 
   457 procedure PauseMusic;
   480 procedure PauseMusic;
   458 begin
   481 begin
   459     if (MusicFN = '') or (not isMusicEnabled) then
   482     if (MusicFN = '') or (not isMusicEnabled) then
   460         exit;
   483         exit;
   461 
   484 
   462     if Mus <> nil then
   485     if Mus <> nil then
   463     	Mix_PauseMusic(Mus);
   486         Mix_PauseMusic(Mus);
   464 end;
   487 end;
   465 
   488 
   466 procedure ResumeMusic;
   489 procedure ResumeMusic;
   467 begin
   490 begin
   468     if (MusicFN = '') or (not isMusicEnabled) then
   491     if (MusicFN = '') or (not isMusicEnabled) then
   469         exit;
   492         exit;
   470 
   493 
   471     if Mus <> nil then
   494     if Mus <> nil then
   472     	Mix_ResumeMusic(Mus);
   495         Mix_ResumeMusic(Mus);
   473 end;
   496 end;
   474 
   497 
   475 procedure ChangeMusic;
   498 procedure ChangeMusic;
   476 begin
   499 begin
   477     if (MusicFN = '') or (not isMusicEnabled) then
   500     if (MusicFN = '') or (not isMusicEnabled) then
   493         end
   516         end
   494 end;
   517 end;
   495 
   518 
   496 procedure chVoicepack(var s: shortstring);
   519 procedure chVoicepack(var s: shortstring);
   497 begin
   520 begin
   498     if CurrentTeam = nil then OutError(errmsgIncorrectUse + ' "/voicepack"', true);
   521     if CurrentTeam = nil then
       
   522         OutError(errmsgIncorrectUse + ' "/voicepack"', true);
   499     if s[1]='"' then Delete(s, 1, 1);
   523     if s[1]='"' then Delete(s, 1, 1);
   500     if s[byte(s[0])]='"' then Delete(s, byte(s[0]), 1);
   524     if s[byte(s[0])]='"' then
       
   525         Delete(s, byte(s[0]), 1);
   501     CurrentTeam^.voicepack:= AskForVoicepack(s)
   526     CurrentTeam^.voicepack:= AskForVoicepack(s)
   502 end;
   527 end;
   503 
   528 
   504 procedure initModule;
   529 procedure initModule;
   505 begin
   530 begin