13 TPlayableSound
= class(TBasicSound
)
19 destructor Destroy(); override;
20 function Play(Force
: Boolean = False): Boolean;
21 function PlayAt(X
, Y
: Integer): Boolean;
22 function PlayPanVolume(Pan
, Volume
: Single; Force
: Boolean = False): Boolean;
23 function PlayVolumeAt(X
, Y
: Integer; Volume
: Single): Boolean;
24 function SetByName(SN
: String): Boolean;
25 function SetCoords(X
, Y
: Integer; Volume
: Single): Boolean;
27 property Loop
: Boolean read FMusic write FMusic
;
28 property Name
: String read FName
;
31 TMusic
= class(TBasicSound
)
34 FSpecPause
: Boolean; // Ñïåö-ïàóçà. "Ñèëüíåå" îáû÷íîé
37 procedure SetSpecPause(Enable
: Boolean);
41 destructor Destroy(); override;
42 function Play(Force
: Boolean = False): Boolean;
43 function SetByName(SN
: String): Boolean;
44 function IsPaused(): Boolean;
45 procedure Pause(Enable
: Boolean);
47 property Name
: String read FName
;
48 property SpecPause
: Boolean read FSpecPause write SetSpecPause
;
49 property NoMusic
: Boolean read FNoMusic
;
52 function g_Sound_PlayEx(SoundName
: ShortString): Boolean;
53 function g_Sound_PlayExPanVolume(SoundName
: ShortString; Pan
: Single; Volume
: Single): Boolean;
54 function g_Sound_PlayAt(ID
: DWORD
; X
, Y
: Integer): Boolean;
55 function g_Sound_PlayExAt(SoundName
: ShortString; X
, Y
: Integer): Boolean;
57 function g_Sound_CreateWAD(var ID
: DWORD
; Resource
: string; isMusic
: Boolean = False): Boolean;
58 function g_Sound_CreateWADEx(SoundName
: ShortString; Resource
: string; isMusic
: Boolean = False): Boolean;
59 function g_Sound_CreateFile(var ID
: DWORD
; FileName
: string; isMusic
: Boolean = False): Boolean;
60 function g_Sound_CreateFileEx(SoundName
: ShortString; FileName
: string; isMusic
: Boolean = False): Boolean;
62 procedure g_Sound_Delete(SoundName
: ShortString);
63 function g_Sound_Exists(SoundName
: string): Boolean;
64 function g_Sound_Get(var ID
: DWORD
; SoundName
: ShortString): Boolean;
66 procedure g_Sound_SetupAllVolumes(SoundVol
, MusicVol
: Byte);
71 e_log
, SysUtils
, g_console
, g_options
, WADEDITOR
,
72 g_game
, g_basic
, g_items
, g_map
, Math
,
83 SoundArray
: Array of TGameSound
;
84 //SoundsMuted: Boolean = False;
87 function FindSound(): DWORD
;
91 if SoundArray
<> nil then
92 for i
:= 0 to High(SoundArray
) do
93 if SoundArray
[i
].Name
= '' then
99 if SoundArray
= nil then
101 SetLength(SoundArray
, 8);
106 Result
:= High(SoundArray
) + 1;
107 SetLength(SoundArray
, Length(SoundArray
) + 8);
111 function g_Sound_PlayEx(SoundName
: ShortString): Boolean;
116 if SoundArray
= nil then
119 for a
:= 0 to High(SoundArray
) do
120 if SoundArray
[a
].Name
= SoundName
then
122 Result
:= (e_PlaySoundVolume(SoundArray
[a
].ID
, gSoundLevel
/255.0) >= 0);
126 e_WriteLog(Format(_lc
[I_GAME_ERROR_SOUND
], [SoundName
]), MSG_WARNING
);
129 function g_Sound_PlayExPanVolume(SoundName
: ShortString; Pan
: Single; Volume
: Single): Boolean;
134 if SoundArray
= nil then
137 for a
:= 0 to High(SoundArray
) do
138 if SoundArray
[a
].Name
= SoundName
then
140 Result
:= (e_PlaySoundPanVolume(SoundArray
[a
].ID
, Pan
, Volume
* (gSoundLevel
/255.0)) >= 0);
144 e_WriteLog(Format(_lc
[I_GAME_ERROR_SOUND
], [SoundName
]), MSG_WARNING
);
147 function PlaySoundAt(X
, Y
: Integer; var Pan
: Single; var Volume
: Single; InVolume
: Single = 1.0): Boolean;
149 l1
, l2
, lx
, rx
: Integer;
150 d1
, d2
, sMaxDist
: Single;
155 sMaxDist
:= SOUND_MAXDIST
* InVolume
;
159 c
:= SOUND_MINDIST
>= sMaxDist
;
161 if X
> gMapInfo
.Width
then
167 if Y
> gMapInfo
.Height
then
173 if gHearPoint1
.Active
then
175 l1
:= Round(Hypot(X
- gHearPoint1
.Coords
.X
, Y
- gHearPoint1
.Coords
.Y
));
177 lx
:= gHearPoint1
.Coords
.X
- SOUND_MINDIST
;
178 rx
:= gHearPoint1
.Coords
.X
+ SOUND_MINDIST
;
181 else if (X
>= lx
) and (X
<= rx
) then
184 d1
:= (X
-lx
)/sMaxDist
186 d1
:= (X
-rx
)/sMaxDist
;
191 if gHearPoint2
.Active
then
193 l2
:= Round(Hypot(X
- gHearPoint2
.Coords
.X
, Y
- gHearPoint2
.Coords
.Y
));
195 lx
:= gHearPoint2
.Coords
.X
- SOUND_MINDIST
;
196 rx
:= gHearPoint2
.Coords
.X
+ SOUND_MINDIST
;
199 else if (X
>= lx
) and (X
<= rx
) then
202 d2
:= (X
-lx
)/sMaxDist
204 d2
:= (X
-rx
)/sMaxDist
;
213 if l1
>= sMaxDist
then
222 Volume
:= 1.0 - l1
/sMaxDist
;
227 function g_Sound_PlayAt(ID
: DWORD
; X
, Y
: Integer): Boolean;
231 if PlaySoundAt(X
, Y
, Pan
, Vol
) then
232 Result
:= (e_PlaySoundPanVolume(ID
, Pan
, Vol
* (gSoundLevel
/255.0)) >= 0)
237 function g_Sound_PlayExAt(SoundName
: ShortString; X
, Y
: Integer): Boolean;
244 if SoundArray
= nil then
247 for a
:= 0 to High(SoundArray
) do
248 if SoundArray
[a
].Name
= SoundName
then
250 if PlaySoundAt(X
, Y
, Pan
, Vol
) then
251 Result
:= (e_PlaySoundPanVolume(SoundArray
[a
].ID
, Pan
, Vol
* (gSoundLevel
/255.0)) >= 0);
255 e_WriteLog(Format(_lc
[I_GAME_ERROR_SOUND
], [SoundName
]), MSG_WARNING
);
258 function g_Sound_CreateFile(var ID
: DWORD
; FileName
: string; isMusic
: Boolean = False): Boolean;
260 Result
:= e_LoadSound(FileName
, ID
, isMusic
);
263 function g_Sound_CreateFileEx(SoundName
: ShortString; FileName
: string; isMusic
: Boolean = False): Boolean;
269 find_id
:= FindSound();
271 if not e_LoadSound(FileName
, SoundArray
[find_id
].ID
, isMusic
) then
274 SoundArray
[find_id
].Name
:= SoundName
;
275 SoundArray
[find_id
].IsMusic
:= isMusic
;
280 function g_Sound_CreateWAD(var ID
: DWORD
; Resource
: string; isMusic
: Boolean = False): Boolean;
285 ResourceName
: string;
293 // e_WriteLog('Loading sound: ' + Resource, MSG_NOTIFY);
294 g_ProcessResourceStr(Resource
, FileName
, SectionName
, ResourceName
);
296 WAD
:= TWADEditor_1
.Create();
297 WAD
.ReadFile(FileName
);
299 if WAD
.GetResource(SectionName
, ResourceName
, SoundData
, ResLength
) then
301 if e_LoadSoundMem(SoundData
, ResLength
, ID
, isMusic
) then
307 e_WriteLog(Format('WAD Reader error: %s', [WAD
.GetLastErrorStr
]), MSG_WARNING
);
314 e_WriteLog(Format('Error loading music %s', [Resource
]), MSG_WARNING
)
316 e_WriteLog(Format('Error loading sound %s', [Resource
]), MSG_WARNING
);
323 function g_Sound_CreateWADEx(SoundName
: ShortString; Resource
: string; isMusic
: Boolean = False): Boolean;
326 FileName
, SectionName
, ResourceName
: string;
335 // e_WriteLog('Loading sound: ' + Resource, MSG_NOTIFY);
336 g_ProcessResourceStr(Resource
, FileName
, SectionName
, ResourceName
);
338 find_id
:= FindSound();
340 WAD
:= TWADEditor_1
.Create();
341 WAD
.ReadFile(FileName
);
343 if WAD
.GetResource(SectionName
, ResourceName
, SoundData
, ResLength
) then
345 if e_LoadSoundMem(SoundData
, ResLength
, SoundArray
[find_id
].ID
, isMusic
) then
347 SoundArray
[find_id
].Name
:= SoundName
;
348 SoundArray
[find_id
].IsMusic
:= isMusic
;
355 e_WriteLog(Format('WAD Reader error: %s', [WAD
.GetLastErrorStr
]), MSG_WARNING
);
362 e_WriteLog(Format('Error loading music %s', [Resource
]), MSG_WARNING
)
364 e_WriteLog(Format('Error loading sound %s', [Resource
]), MSG_WARNING
);
371 procedure g_Sound_Delete(SoundName
: ShortString);
375 if (SoundArray
= nil) or (SoundName
= '') then
378 for a
:= 0 to High(SoundArray
) do
379 if SoundArray
[a
].Name
= SoundName
then
381 e_DeleteSound(SoundArray
[a
].ID
);
382 SoundArray
[a
].Name
:= '';
383 SoundArray
[a
].ID
:= 0;
384 SoundArray
[a
].IsMusic
:= False;
388 function g_Sound_Exists(SoundName
: string): Boolean;
394 if SoundName
= '' then
397 if SoundArray
<> nil then
398 for a
:= 0 to High(SoundArray
) do
399 if SoundArray
[a
].Name
= SoundName
then
406 function g_Sound_Get(var ID
: DWORD
; SoundName
: ShortString): Boolean;
412 if SoundName
= '' then
415 if SoundArray
<> nil then
416 for a
:= 0 to High(SoundArray
) do
417 if SoundArray
[a
].Name
= SoundName
then
419 ID
:= SoundArray
[a
].ID
;
425 procedure g_Sound_SetupAllVolumes(SoundVol
, MusicVol
: Byte);
430 Mvol
:= 0; // shut up, compiler
431 if (gSoundLevel
= SoundVol
) and (gMusicLevel
= MusicVol
) then
434 if gSoundLevel
> 0 then
436 Svol
:= SoundVol
/ gSoundLevel
;
441 Svol
:= SoundVol
/ 255.0;
445 if gMusic
<> nil then
446 if gMusicLevel
> 0 then
447 Mvol
:= gMusic
.GetVolume() * MusicVol
/ gMusicLevel
449 Mvol
:= MusicVol
/ 255.0;
451 e_ModifyChannelsVolumes(Svol
, sm
);
453 if gMusic
<> nil then
454 gMusic
.SetVolume(Mvol
);
456 gSoundLevel
:= SoundVol
;
457 gMusicLevel
:= MusicVol
;
462 constructor TPlayableSound
.Create();
468 destructor TPlayableSound
.Destroy();
473 function TPlayableSound
.Play(Force
: Boolean = False): Boolean;
475 if Force
or not IsPlaying() then
478 Result
:= RawPlay(0.0, gSoundLevel
/255.0, FPosition
);
484 function TPlayableSound
.PlayAt(X
, Y
: Integer): Boolean;
488 if PlaySoundAt(X
, Y
, Pan
, Vol
) then
491 Result
:= RawPlay(Pan
, Vol
* (gSoundLevel
/255.0), FPosition
);
497 function TPlayableSound
.PlayPanVolume(Pan
, Volume
: Single; Force
: Boolean = False): Boolean;
499 if Force
or not IsPlaying() then
502 Result
:= RawPlay(Pan
, Volume
* (gSoundLevel
/255.0), FPosition
);
508 function TPlayableSound
.PlayVolumeAt(X
, Y
: Integer; Volume
: Single): Boolean;
512 if PlaySoundAt(X
, Y
, Pan
, Vol
, Volume
) then
515 Result
:= RawPlay(Pan
, Volume
* Vol
* (gSoundLevel
/255.0), FPosition
);
521 function TPlayableSound
.SetCoords(X
, Y
: Integer; Volume
: Single): Boolean;
525 if PlaySoundAt(X
, Y
, Pan
, Vol
, Volume
) then
527 SetVolume(Volume
* Vol
* (gSoundLevel
/255.0));
539 function TPlayableSound
.SetByName(SN
: String): Boolean;
543 if g_Sound_Get(id
, SN
) then
555 constructor TMusic
.Create();
563 destructor TMusic
.Destroy();
568 function TMusic
.Play(Force
: Boolean = False): Boolean;
576 if Force
or not IsPlaying() then
579 Result
:= RawPlay(0.0, gMusicLevel
/255.0, FPosition
);
582 if Result
and FSpecPause
then
589 function TMusic
.SetByName(SN
: String): Boolean;
600 if g_Sound_Get(id
, SN
) then
612 function TMusic
.IsPaused(): Boolean;
614 Result
:= inherited IsPaused();
615 Result
:= Result
or FSpecPause
;
618 procedure TMusic
.Pause(Enable
: Boolean);
620 // Îòêëþ÷àåì ïàóçó, òîëüêî åñëè íå áûëî ñïåö-ïàóçû:
621 if Enable
or (not FSpecPause
) then
622 inherited Pause(Enable
);
625 procedure TMusic
.SetSpecPause(Enable
: Boolean);
627 FSpecPause
:= Enable
;