14 TPlayableSound
= class(TBasicSound
)
20 destructor Destroy(); override;
21 function Play(Force
: Boolean = False): Boolean;
22 function PlayAt(X
, Y
: Integer): Boolean;
23 function PlayPanVolume(Pan
, Volume
: Single; Force
: Boolean = False): Boolean;
24 function PlayVolumeAt(X
, Y
: Integer; Volume
: Single): Boolean;
25 function SetByName(SN
: String): Boolean;
26 function SetCoords(X
, Y
: Integer; Volume
: Single): Boolean;
28 property Loop
: Boolean read FMusic write FMusic
;
29 property Name
: String read FName
;
32 TMusic
= class(TBasicSound
)
35 FSpecPause
: Boolean; // Ñïåö-ïàóçà. "Ñèëüíåå" îáû÷íîé
38 procedure SetSpecPause(Enable
: Boolean);
42 destructor Destroy(); override;
43 function Play(Force
: Boolean = False): Boolean;
44 function SetByName(SN
: String): Boolean;
45 function IsPaused(): Boolean;
46 procedure Pause(Enable
: Boolean);
48 property Name
: String read FName
;
49 property SpecPause
: Boolean read FSpecPause write SetSpecPause
;
50 property NoMusic
: Boolean read FNoMusic
;
53 function g_Sound_PlayEx(SoundName
: ShortString): Boolean;
54 function g_Sound_PlayExPanVolume(SoundName
: ShortString; Pan
: Single; Volume
: Single): Boolean;
55 function g_Sound_PlayAt(ID
: DWORD
; X
, Y
: Integer): Boolean;
56 function g_Sound_PlayExAt(SoundName
: ShortString; X
, Y
: Integer): Boolean;
58 function g_Sound_CreateWAD(var ID
: DWORD
; Resource
: string; isMusic
: Boolean = False): Boolean;
59 function g_Sound_CreateWADEx(SoundName
: ShortString; Resource
: string; isMusic
: Boolean = False): Boolean;
60 function g_Sound_CreateFile(var ID
: DWORD
; FileName
: string; isMusic
: Boolean = False): Boolean;
61 function g_Sound_CreateFileEx(SoundName
: ShortString; FileName
: string; isMusic
: Boolean = False): Boolean;
63 procedure g_Sound_Delete(SoundName
: ShortString);
64 function g_Sound_Exists(SoundName
: string): Boolean;
65 function g_Sound_Get(var ID
: DWORD
; SoundName
: ShortString): Boolean;
67 procedure g_Sound_SetupAllVolumes(SoundVol
, MusicVol
: Byte);
72 e_log
, SysUtils
, g_console
, g_options
, wadreader
,
73 g_game
, g_basic
, g_items
, g_map
, Math
,
84 SoundArray
: Array of TGameSound
;
85 //SoundsMuted: Boolean = False;
88 function FindSound(): DWORD
;
92 if SoundArray
<> nil then
93 for i
:= 0 to High(SoundArray
) do
94 if SoundArray
[i
].Name
= '' then
100 if SoundArray
= nil then
102 SetLength(SoundArray
, 8);
107 Result
:= High(SoundArray
) + 1;
108 SetLength(SoundArray
, Length(SoundArray
) + 8);
112 function g_Sound_PlayEx(SoundName
: ShortString): Boolean;
117 if SoundArray
= nil then
120 for a
:= 0 to High(SoundArray
) do
121 if SoundArray
[a
].Name
= SoundName
then
123 Result
:= (e_PlaySoundVolume(SoundArray
[a
].ID
, gSoundLevel
/255.0) >= 0);
127 e_WriteLog(Format(_lc
[I_GAME_ERROR_SOUND
], [SoundName
]), MSG_WARNING
);
130 function g_Sound_PlayExPanVolume(SoundName
: ShortString; Pan
: Single; Volume
: Single): Boolean;
135 if SoundArray
= nil then
138 for a
:= 0 to High(SoundArray
) do
139 if SoundArray
[a
].Name
= SoundName
then
141 Result
:= (e_PlaySoundPanVolume(SoundArray
[a
].ID
, Pan
, Volume
* (gSoundLevel
/255.0)) >= 0);
145 e_WriteLog(Format(_lc
[I_GAME_ERROR_SOUND
], [SoundName
]), MSG_WARNING
);
148 function PlaySoundAt(X
, Y
: Integer; var Pan
: Single; var Volume
: Single; InVolume
: Single = 1.0): Boolean;
150 l1
, l2
, lx
, rx
: Integer;
151 d1
, d2
, sMaxDist
: Single;
156 sMaxDist
:= SOUND_MAXDIST
* InVolume
;
160 c
:= SOUND_MINDIST
>= sMaxDist
;
162 if X
> gMapInfo
.Width
then
168 if Y
> gMapInfo
.Height
then
174 if gHearPoint1
.Active
then
176 l1
:= Round(Hypot(X
- gHearPoint1
.Coords
.X
, Y
- gHearPoint1
.Coords
.Y
));
178 lx
:= gHearPoint1
.Coords
.X
- SOUND_MINDIST
;
179 rx
:= gHearPoint1
.Coords
.X
+ SOUND_MINDIST
;
182 else if (X
>= lx
) and (X
<= rx
) then
185 d1
:= (X
-lx
)/sMaxDist
187 d1
:= (X
-rx
)/sMaxDist
;
192 if gHearPoint2
.Active
then
194 l2
:= Round(Hypot(X
- gHearPoint2
.Coords
.X
, Y
- gHearPoint2
.Coords
.Y
));
196 lx
:= gHearPoint2
.Coords
.X
- SOUND_MINDIST
;
197 rx
:= gHearPoint2
.Coords
.X
+ SOUND_MINDIST
;
200 else if (X
>= lx
) and (X
<= rx
) then
203 d2
:= (X
-lx
)/sMaxDist
205 d2
:= (X
-rx
)/sMaxDist
;
214 if l1
>= sMaxDist
then
223 Volume
:= 1.0 - l1
/sMaxDist
;
228 function g_Sound_PlayAt(ID
: DWORD
; X
, Y
: Integer): Boolean;
232 if PlaySoundAt(X
, Y
, Pan
, Vol
) then
233 Result
:= (e_PlaySoundPanVolume(ID
, Pan
, Vol
* (gSoundLevel
/255.0)) >= 0)
238 function g_Sound_PlayExAt(SoundName
: ShortString; X
, Y
: Integer): Boolean;
245 if SoundArray
= nil then
248 for a
:= 0 to High(SoundArray
) do
249 if SoundArray
[a
].Name
= SoundName
then
251 if PlaySoundAt(X
, Y
, Pan
, Vol
) then
252 Result
:= (e_PlaySoundPanVolume(SoundArray
[a
].ID
, Pan
, Vol
* (gSoundLevel
/255.0)) >= 0);
256 e_WriteLog(Format(_lc
[I_GAME_ERROR_SOUND
], [SoundName
]), MSG_WARNING
);
259 function g_Sound_CreateFile(var ID
: DWORD
; FileName
: string; isMusic
: Boolean = False): Boolean;
261 Result
:= e_LoadSound(FileName
, ID
, isMusic
);
264 function g_Sound_CreateFileEx(SoundName
: ShortString; FileName
: string; isMusic
: Boolean = False): Boolean;
270 find_id
:= FindSound();
272 if not e_LoadSound(FileName
, SoundArray
[find_id
].ID
, isMusic
) then
275 SoundArray
[find_id
].Name
:= SoundName
;
276 SoundArray
[find_id
].IsMusic
:= isMusic
;
281 function g_Sound_CreateWAD(var ID
: DWORD
; Resource
: string; isMusic
: Boolean = False): Boolean;
286 ResourceName
: string;
294 // e_WriteLog('Loading sound: ' + Resource, MSG_NOTIFY);
295 g_ProcessResourceStr(Resource
, FileName
, SectionName
, ResourceName
);
297 WAD
:= TWADFile
.Create();
298 WAD
.ReadFile(FileName
);
300 if WAD
.GetResource(SectionName
, ResourceName
, SoundData
, ResLength
) then
302 if e_LoadSoundMem(SoundData
, ResLength
, ID
, isMusic
) then
309 //e_WriteLog(Format('WAD Reader error: %s', [WAD.GetLastErrorStr]), MSG_WARNING);
317 e_WriteLog(Format('Error loading music %s', [Resource
]), MSG_WARNING
)
319 e_WriteLog(Format('Error loading sound %s', [Resource
]), MSG_WARNING
);
326 function g_Sound_CreateWADEx(SoundName
: ShortString; Resource
: string; isMusic
: Boolean = False): Boolean;
329 FileName
, SectionName
, ResourceName
: string;
338 // e_WriteLog('Loading sound: ' + Resource, MSG_NOTIFY);
339 g_ProcessResourceStr(Resource
, FileName
, SectionName
, ResourceName
);
341 find_id
:= FindSound();
343 WAD
:= TWADFile
.Create();
344 WAD
.ReadFile(FileName
);
346 if WAD
.GetResource(SectionName
, ResourceName
, SoundData
, ResLength
) then
348 if e_LoadSoundMem(SoundData
, ResLength
, SoundArray
[find_id
].ID
, isMusic
) then
350 SoundArray
[find_id
].Name
:= SoundName
;
351 SoundArray
[find_id
].IsMusic
:= isMusic
;
359 //e_WriteLog(Format('WAD Reader error: %s', [WAD.GetLastErrorStr]), MSG_WARNING);
367 e_WriteLog(Format('Error loading music %s', [Resource
]), MSG_WARNING
)
369 e_WriteLog(Format('Error loading sound %s', [Resource
]), MSG_WARNING
);
376 procedure g_Sound_Delete(SoundName
: ShortString);
380 if (SoundArray
= nil) or (SoundName
= '') then
383 for a
:= 0 to High(SoundArray
) do
384 if SoundArray
[a
].Name
= SoundName
then
386 e_DeleteSound(SoundArray
[a
].ID
);
387 SoundArray
[a
].Name
:= '';
388 SoundArray
[a
].ID
:= 0;
389 SoundArray
[a
].IsMusic
:= False;
393 function g_Sound_Exists(SoundName
: string): Boolean;
399 if SoundName
= '' then
402 if SoundArray
<> nil then
403 for a
:= 0 to High(SoundArray
) do
404 if SoundArray
[a
].Name
= SoundName
then
411 function g_Sound_Get(var ID
: DWORD
; SoundName
: ShortString): Boolean;
417 if SoundName
= '' then
420 if SoundArray
<> nil then
421 for a
:= 0 to High(SoundArray
) do
422 if SoundArray
[a
].Name
= SoundName
then
424 ID
:= SoundArray
[a
].ID
;
430 procedure g_Sound_SetupAllVolumes(SoundVol
, MusicVol
: Byte);
435 Mvol
:= 0; // shut up, compiler
436 if (gSoundLevel
= SoundVol
) and (gMusicLevel
= MusicVol
) then
439 if gSoundLevel
> 0 then
441 Svol
:= SoundVol
/ gSoundLevel
;
446 Svol
:= SoundVol
/ 255.0;
450 if gMusic
<> nil then
451 if gMusicLevel
> 0 then
452 Mvol
:= gMusic
.GetVolume() * MusicVol
/ gMusicLevel
454 Mvol
:= MusicVol
/ 255.0;
456 e_ModifyChannelsVolumes(Svol
, sm
);
458 if gMusic
<> nil then
459 gMusic
.SetVolume(Mvol
);
461 gSoundLevel
:= SoundVol
;
462 gMusicLevel
:= MusicVol
;
467 constructor TPlayableSound
.Create();
473 destructor TPlayableSound
.Destroy();
478 function TPlayableSound
.Play(Force
: Boolean = False): Boolean;
480 if Force
or not IsPlaying() then
483 Result
:= RawPlay(0.0, gSoundLevel
/255.0, FPosition
);
489 function TPlayableSound
.PlayAt(X
, Y
: Integer): Boolean;
493 if PlaySoundAt(X
, Y
, Pan
, Vol
) then
496 Result
:= RawPlay(Pan
, Vol
* (gSoundLevel
/255.0), FPosition
);
502 function TPlayableSound
.PlayPanVolume(Pan
, Volume
: Single; Force
: Boolean = False): Boolean;
504 if Force
or not IsPlaying() then
507 Result
:= RawPlay(Pan
, Volume
* (gSoundLevel
/255.0), FPosition
);
513 function TPlayableSound
.PlayVolumeAt(X
, Y
: Integer; Volume
: Single): Boolean;
517 if PlaySoundAt(X
, Y
, Pan
, Vol
, Volume
) then
520 Result
:= RawPlay(Pan
, Volume
* Vol
* (gSoundLevel
/255.0), FPosition
);
526 function TPlayableSound
.SetCoords(X
, Y
: Integer; Volume
: Single): Boolean;
530 if PlaySoundAt(X
, Y
, Pan
, Vol
, Volume
) then
532 SetVolume(Volume
* Vol
* (gSoundLevel
/255.0));
544 function TPlayableSound
.SetByName(SN
: String): Boolean;
548 if g_Sound_Get(id
, SN
) then
560 constructor TMusic
.Create();
568 destructor TMusic
.Destroy();
573 function TMusic
.Play(Force
: Boolean = False): Boolean;
581 if Force
or not IsPlaying() then
584 Result
:= RawPlay(0.0, gMusicLevel
/255.0, FPosition
);
587 if Result
and FSpecPause
then
594 function TMusic
.SetByName(SN
: String): Boolean;
605 if g_Sound_Get(id
, SN
) then
617 function TMusic
.IsPaused(): Boolean;
619 Result
:= inherited IsPaused();
620 Result
:= Result
or FSpecPause
;
623 procedure TMusic
.Pause(Enable
: Boolean);
625 // Îòêëþ÷àåì ïàóçó, òîëüêî åñëè íå áûëî ñïåö-ïàóçû:
626 if Enable
or (not FSpecPause
) then
627 inherited Pause(Enable
);
630 procedure TMusic
.SetSpecPause(Enable
: Boolean);
632 FSpecPause
:= Enable
;