X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_sound.pas;h=2aa1b38cd199a2ae1b3b2817bd5bb34850e283f5;hb=HEAD;hp=074d037c29da38b5f77c4652b71665fa08d382ed;hpb=88ce644db1b40111bdb380f4357fa59bdb5173be;p=d2df-sdl.git diff --git a/src/game/g_sound.pas b/src/game/g_sound.pas index 074d037..2aa1b38 100644 --- a/src/game/g_sound.pas +++ b/src/game/g_sound.pas @@ -1,3 +1,18 @@ +(* Copyright (C) Doom 2D: Forever Developers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3 of the License ONLY. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *) +{$INCLUDE ../shared/a_modes.inc} unit g_sound; interface @@ -21,10 +36,12 @@ type function PlayAt(X, Y: Integer): Boolean; function PlayPanVolume(Pan, Volume: Single; Force: Boolean = False): Boolean; function PlayVolumeAt(X, Y: Integer; Volume: Single): Boolean; + function PlayVolumeAtRect (X, Y, W, H: Integer; Volume: Single): Boolean; function SetByName(SN: String): Boolean; function SetCoords(X, Y: Integer; Volume: Single): Boolean; + function SetCoordsRect (X, Y, W, H: Integer; Volume: Single): Boolean; - property Loop: Boolean read FLoop write FLoop; + property Loop: Boolean read FMusic write FMusic; property Name: String read FName; end; @@ -55,9 +72,9 @@ function g_Sound_PlayAt(ID: DWORD; X, Y: Integer): Boolean; function g_Sound_PlayExAt(SoundName: ShortString; X, Y: Integer): Boolean; function g_Sound_CreateWAD(var ID: DWORD; Resource: string; isMusic: Boolean = False): Boolean; -function g_Sound_CreateWADEx(SoundName: ShortString; Resource: string; isMusic: Boolean = False): Boolean; +function g_Sound_CreateWADEx(SoundName: ShortString; Resource: string; isMusic: Boolean = False; ForceNoLoop: Boolean = False): Boolean; function g_Sound_CreateFile(var ID: DWORD; FileName: string; isMusic: Boolean = False): Boolean; -function g_Sound_CreateFileEx(SoundName: ShortString; FileName: string; isMusic: Boolean = False): Boolean; +function g_Sound_CreateFileEx(SoundName: ShortString; FileName: string; isMusic: Boolean = False; ForceNoLoop: Boolean = False): Boolean; procedure g_Sound_Delete(SoundName: ShortString); function g_Sound_Exists(SoundName: string): Boolean; @@ -68,8 +85,8 @@ procedure g_Sound_SetupAllVolumes(SoundVol, MusicVol: Byte); implementation uses - e_log, SysUtils, g_console, g_options, WADEDITOR, - g_game, g_basic, g_items, g_map, fmod, fmodtypes, Math, + e_log, SysUtils, g_console, g_options, wadreader, + g_game, g_basic, g_items, g_map, Math, g_language; type @@ -119,11 +136,11 @@ begin for a := 0 to High(SoundArray) do if SoundArray[a].Name = SoundName then begin - Result := e_PlaySoundVolume(SoundArray[a].ID, gSoundLevel/255.0); + Result := (e_PlaySoundVolume(SoundArray[a].ID, gSoundLevel/255.0) >= 0); Exit; end; - e_WriteLog(Format(_lc[I_GAME_ERROR_SOUND], [SoundName]), MSG_WARNING); + e_WriteLog(Format(_lc[I_GAME_ERROR_SOUND], [SoundName]), TMsgType.Warning); end; function g_Sound_PlayExPanVolume(SoundName: ShortString; Pan: Single; Volume: Single): Boolean; @@ -137,91 +154,70 @@ begin for a := 0 to High(SoundArray) do if SoundArray[a].Name = SoundName then begin - Result := e_PlaySoundPanVolume(SoundArray[a].ID, Pan, Volume * (gSoundLevel/255.0)); + Result := (e_PlaySoundPanVolume(SoundArray[a].ID, Pan, Volume * (gSoundLevel/255.0)) >= 0); Exit; end; - e_WriteLog(Format(_lc[I_GAME_ERROR_SOUND], [SoundName]), MSG_WARNING); + e_WriteLog(Format(_lc[I_GAME_ERROR_SOUND], [SoundName]), TMsgType.Warning); end; -function PlaySoundAt(X, Y: Integer; var Pan: Single; var Volume: Single; InVolume: Single = 1.0): Boolean; -var - l1, l2, lx, rx: Integer; - d1, d2, sMaxDist: Single; - c: Boolean; -begin - l1 := gMaxDist; - l2 := gMaxDist; - sMaxDist := SOUND_MAXDIST * InVolume; - - d1 := 0.0; - - c := SOUND_MINDIST >= sMaxDist; - - if X > gMapInfo.Width then - X := gMapInfo.Width - else - if X < 0 then - X := 0; - - if Y > gMapInfo.Height then - Y := gMapInfo.Height - else - if Y < 0 then - Y := 0; +function PlaySoundAtRect (X, Y, W, H: Integer; out Pan, Volume: Single; InVolume: Single = 1.0): Boolean; + var + len1, len2: Integer; + pan1, pan2: Single; + sMaxDist: Single; - if gHearPoint1.Active then + procedure CalcDest (const p: THearPoint; out pan: Single; out len: Integer); + var XX, YY, lx, rx: Integer; begin - l1 := Round(Hypot(X - gHearPoint1.Coords.X, Y - gHearPoint1.Coords.Y)); - - lx := gHearPoint1.Coords.X - SOUND_MINDIST; - rx := gHearPoint1.Coords.X + SOUND_MINDIST; - if c then - d1 := 0.0 - else if (X >= lx) and (X <= rx) then - d1 := 0.0 - else if X < lx then - d1 := (X-lx)/sMaxDist - else - d1 := (X-rx)/sMaxDist; + pan := 0.0; len := gMaxDist; + if p.Active then + begin + XX := Max(X, Min(X + W, p.Coords.X)); + YY := Max(Y, Min(Y + H, p.Coords.Y)); + len := Round(Hypot(XX - p.Coords.X, YY - p.Coords.Y)); + if sMaxDist < SOUND_MINDIST then + begin + lx := X - SOUND_MINDIST; + rx := X + W + SOUND_MINDIST; + if p.Coords.X < lx then + pan := (lx - p.Coords.X) / sMaxDist + else if p.Coords.X > rx then + pan := (rx - p.Coords.X) / sMaxDist + end + end end; - d2 := d1; - - if gHearPoint2.Active then +begin + ASSERT((W >= 0) and (H >= 0)); + ASSERT((InVolume >= 0.0) and (InVolume <= 1.0)); + sMaxDist := SOUND_MAXDIST * InVolume; + X := Max(0, Min(X, gMapInfo.Width)); + Y := Max(0, Min(Y, gMapInfo.Height)); + CalcDest(gHearPoint1, pan1, len1); + CalcDest(gHearPoint2, pan2, len2); + if len2 < len1 then begin - l2 := Round(Hypot(X - gHearPoint2.Coords.X, Y - gHearPoint2.Coords.Y)); - - lx := gHearPoint2.Coords.X - SOUND_MINDIST; - rx := gHearPoint2.Coords.X + SOUND_MINDIST; - if c then - d2 := 0.0 - else if (X >= lx) and (X <= rx) then - d2 := 0.0 - else if X < lx then - d2 := (X-lx)/sMaxDist - else - d2 := (X-rx)/sMaxDist; + len1 := len2; + pan1 := pan2; end; - - if l2 < l1 then + if len1 >= sMaxDist then begin - l1 := l2; - d1 := d2; - end; - - if l1 >= sMaxDist then - begin - Pan := 0.0; - Volume := 0.0; - Result := False; - end + Pan := 0.0; + Volume := 0.0; + Result := False + end else - begin - Pan := d1; - Volume := 1.0 - l1/sMaxDist; - Result := True; - end; + begin + Pan := pan1; + Volume := 1.0 - len1 / sMaxDist; + Result := True + end +end; + +function PlaySoundAt(X, Y: Integer; out Pan: Single; out Volume: Single; InVolume: Single = 1.0): Boolean; +begin + Result := PlaySoundAtRect(X, Y, 0, 0, Pan, Volume, InVolume) end; function g_Sound_PlayAt(ID: DWORD; X, Y: Integer): Boolean; @@ -229,7 +225,7 @@ var Pan, Vol: Single; begin if PlaySoundAt(X, Y, Pan, Vol) then - Result := e_PlaySoundPanVolume(ID, Pan, Vol * (gSoundLevel/255.0)) + Result := (e_PlaySoundPanVolume(ID, Pan, Vol * (gSoundLevel/255.0)) >= 0) else Result := False; end; @@ -248,12 +244,11 @@ begin if SoundArray[a].Name = SoundName then begin if PlaySoundAt(X, Y, Pan, Vol) then - Result := e_PlaySoundPanVolume(SoundArray[a].ID, - Pan, Vol * (gSoundLevel/255.0)); + Result := (e_PlaySoundPanVolume(SoundArray[a].ID, Pan, Vol * (gSoundLevel/255.0)) >= 0); Exit; end; - e_WriteLog(Format(_lc[I_GAME_ERROR_SOUND], [SoundName]), MSG_WARNING); + e_WriteLog(Format(_lc[I_GAME_ERROR_SOUND], [SoundName]), TMsgType.Warning); end; function g_Sound_CreateFile(var ID: DWORD; FileName: string; isMusic: Boolean = False): Boolean; @@ -261,7 +256,7 @@ begin Result := e_LoadSound(FileName, ID, isMusic); end; -function g_Sound_CreateFileEx(SoundName: ShortString; FileName: string; isMusic: Boolean = False): Boolean; +function g_Sound_CreateFileEx(SoundName: ShortString; FileName: string; isMusic: Boolean = False; ForceNoLoop: Boolean = False): Boolean; var find_id: DWORD; begin @@ -269,7 +264,7 @@ begin find_id := FindSound(); - if not e_LoadSound(FileName, SoundArray[find_id].ID, isMusic) then + if not e_LoadSound(FileName, SoundArray[find_id].ID, isMusic, ForceNoLoop) then Exit; SoundArray[find_id].Name := SoundName; @@ -280,10 +275,8 @@ end; function g_Sound_CreateWAD(var ID: DWORD; Resource: string; isMusic: Boolean = False): Boolean; var - WAD: TWADEditor_1; - FileName, - SectionName, - ResourceName: string; + WAD: TWADFile; + FileName: string; SoundData: Pointer; ResLength: Integer; ok: Boolean; @@ -292,12 +285,12 @@ begin ok := False; // e_WriteLog('Loading sound: ' + Resource, MSG_NOTIFY); - g_ProcessResourceStr(Resource, FileName, SectionName, ResourceName); + FileName := g_ExtractWadName(Resource); - WAD := TWADEditor_1.Create(); + WAD := TWADFile.Create(); WAD.ReadFile(FileName); - if WAD.GetResource(SectionName, ResourceName, SoundData, ResLength) then + if WAD.GetResource(g_ExtractFilePathName(Resource), SoundData, ResLength) then begin if e_LoadSoundMem(SoundData, ResLength, ID, isMusic) then ok := True @@ -305,26 +298,28 @@ begin FreeMem(SoundData); end else - e_WriteLog(Format('WAD Reader error: %s', [WAD.GetLastErrorStr]), MSG_WARNING); + begin + //e_WriteLog(Format('WAD Reader error: %s', [WAD.GetLastErrorStr]), MSG_WARNING); + end; WAD.Free(); - - if not ok then + if (not ok) then begin +{$IFNDEF HEADLESS} if isMusic then - e_WriteLog(Format('Error loading music %s', [Resource]), MSG_WARNING) + e_WriteLog(Format('Error loading music %s', [Resource]), TMsgType.Warning) else - e_WriteLog(Format('Error loading sound %s', [Resource]), MSG_WARNING); + e_WriteLog(Format('Error loading sound %s', [Resource]), TMsgType.Warning); Exit; +{$ENDIF} end; - Result := True; end; -function g_Sound_CreateWADEx(SoundName: ShortString; Resource: string; isMusic: Boolean = False): Boolean; +function g_Sound_CreateWADEx(SoundName: ShortString; Resource: string; isMusic: Boolean = False; ForceNoLoop: Boolean = False): Boolean; var - WAD: TWADEditor_1; - FileName, SectionName, ResourceName: string; + WAD: TWADFile; + FileName: string; SoundData: Pointer; ResLength: Integer; find_id: DWORD; @@ -334,16 +329,16 @@ begin ok := False; // e_WriteLog('Loading sound: ' + Resource, MSG_NOTIFY); - g_ProcessResourceStr(Resource, FileName, SectionName, ResourceName); + FileName := g_ExtractWadName(Resource); find_id := FindSound(); - WAD := TWADEditor_1.Create(); + WAD := TWADFile.Create(); WAD.ReadFile(FileName); - if WAD.GetResource(SectionName, ResourceName, SoundData, ResLength) then + if WAD.GetResource(g_ExtractFilePathName(Resource), SoundData, ResLength) then begin - if e_LoadSoundMem(SoundData, ResLength, SoundArray[find_id].ID, isMusic) then + if e_LoadSoundMem(SoundData, ResLength, SoundArray[find_id].ID, isMusic, ForceNoLoop) then begin SoundArray[find_id].Name := SoundName; SoundArray[find_id].IsMusic := isMusic; @@ -353,19 +348,21 @@ begin FreeMem(SoundData); end else - e_WriteLog(Format('WAD Reader error: %s', [WAD.GetLastErrorStr]), MSG_WARNING); + begin + //e_WriteLog(Format('WAD Reader error: %s', [WAD.GetLastErrorStr]), MSG_WARNING); + end; WAD.Free(); - - if not ok then + if (not ok) then begin +{$IFNDEF HEADLESS} if isMusic then - e_WriteLog(Format('Error loading music %s', [Resource]), MSG_WARNING) + e_WriteLog(Format('Error loading music %s', [Resource]), TMsgType.Warning) else - e_WriteLog(Format('Error loading sound %s', [Resource]), MSG_WARNING); + e_WriteLog(Format('Error loading sound %s', [Resource]), TMsgType.Warning); Exit; +{$ENDIF} end; - Result := True; end; @@ -506,37 +503,44 @@ begin Result := False; end; -function TPlayableSound.PlayVolumeAt(X, Y: Integer; Volume: Single): Boolean; -var - Pan, Vol: Single; +function TPlayableSound.PlayVolumeAtRect (X, Y, W, H: Integer; Volume: Single): Boolean; + var Pan, Vol: Single; begin - if PlaySoundAt(X, Y, Pan, Vol, Volume) then - begin - Stop(); - Result := RawPlay(Pan, Volume * Vol * (gSoundLevel/255.0), FPosition); - end - else - Result := False; + Result := False; + if PlaySoundAtRect(X, Y, W, H, Pan, Vol, Volume) then + begin + Stop; + Result := RawPlay(Pan, Volume * Vol * (gSoundLevel / 255.0), FPosition) + end end; -function TPlayableSound.SetCoords(X, Y: Integer; Volume: Single): Boolean; -var - Pan, Vol: Single; +function TPlayableSound.PlayVolumeAt (X, Y: Integer; Volume: Single): Boolean; +begin + Result := Self.PlayVolumeAtRect(X, Y, 0, 0, Volume) +end; + +function TPlayableSound.SetCoordsRect (X, Y, W, H: Integer; Volume: Single): Boolean; + var Pan, Vol: Single; begin - if PlaySoundAt(X, Y, Pan, Vol, Volume) then + if PlaySoundAtRect(X, Y, W, H, Pan, Vol, Volume) then begin - SetVolume(Volume * Vol * (gSoundLevel/255.0)); + SetVolume(Volume * Vol * (gSoundLevel / 255.0)); SetPan(Pan); - Result := True; + Result := True end else begin SetVolume(0.0); SetPan(0.0); - Result := False; + Result := False end; end; +function TPlayableSound.SetCoords(X, Y: Integer; Volume: Single): Boolean; +begin + Result := Self.SetCoordsRect(X, Y, 0, 0, Volume) +end; + function TPlayableSound.SetByName(SN: String): Boolean; var id: DWORD; @@ -629,4 +633,10 @@ begin Pause(Enable); end; +{$IFDEF USE_OPENAL} +initialization + conRegVar('s_midi_soundfont', @e_SoundFont, 'soundfont to use for midi playback', 'midi soundfont'); + conRegVar('s_mod_lerp', @e_MusicLerp, 'interpolate module playback', 'module interpolation'); +{$ENDIF} + end.