~ubuntu-branches/ubuntu/quantal/hedgewars/quantal

« back to all changes in this revision

Viewing changes to hedgewars/uSound.pas

  • Committer: Bazaar Package Importer
  • Author(s): Dmitry E. Oboukhov
  • Date: 2010-11-14 22:45:48 UTC
  • mfrom: (1.1.8 upstream) (3.2.9 sid)
  • Revision ID: james.westby@ubuntu.com-20101114224548-ws42t9rz3i4qd972
Tags: 0.9.14.1-1
* New upstream version.
 + New audio tracks
 + New forts: EvilChicken, Tank
 + New game modes: AI Survival Mode, Per Hedgehog Ammo,
   Reset Health, Reset Weapons, Unlimited Attacks
 + New grave: ring
 + Over 30 new hats
 + New themes: Art, Brick, Jungle, Stage
 + New maps: ShoppaKing, Sticks, TrophyRace (Mission)
 + New utilities: Portal Gun, Resurrector
 + New weapons: Flamethrower, Hammer, Old Limburger,
   Piano Strike, Sticky Mines
 + Weapons' projectiles will how be launched from their
   barrels instead of the hog's center
 + Flying Saucers may be used for moving below the water surface
 + New default game schemes: Clean Slate, Fort Mode, Timeless,
   Thinking with Portals, King Mode
 + New default weapon set: Clean Slate, Thinking with Portals
 + Bomb clusters/Melon parts inherit some of the original bomb's speed
 + Extended game statistics
 + Improved health bar updating
 + Hogs that blow themselves up will use triggers in they team color
 + Settings allow better control over the level of details/effects
 + Improved Lua support
 + On empty ammo switch to no weapon rather than the first available
   one (to avoid shooting by accident)
 + Display of hints in the frontend
 + Some improvements of existing Themes of Maps
 + Land destruction effects added
 + Improved fire effects
 + Improved Melon explosion effects
 + Online game lobby now features game filters
 + Other Frontend enhancements
 + Additional sounds
 + Show special game rules in Esc screen
 + Updated translation
 + Speed optimizations
 + Hedgewars will now use a sub directory of "My Documents"
   like other games instead of "%userprofile%/.hedgewars" under Windows
 + Added support for graphics cards/drivers that have a 512x512
   pixel textures limit
 + Team colors are more distinguishable from each other now
 * Fixed bug that allowed charging a weapon while on rope,
   leading to frozen timer
 * Various bug fixes
* Switched to 3.0 source format.
* Switched to cdbs build system.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
(*
 
2
 * Hedgewars, a free turn based strategy game
 
3
 * Copyright (c) 2005, 2007, 2009 Andrey Korotaev <unC0Rr@gmail.com>
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License as published by
 
7
 * the Free Software Foundation; version 2 of the License
 
8
 *
 
9
 * This program is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 * GNU General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program; if not, write to the Free Software
 
16
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 
17
 *)
 
18
 
 
19
{$INCLUDE "options.inc"}
 
20
 
 
21
unit uSound;
 
22
interface
 
23
uses SDLh, uConsts;
 
24
 
 
25
type PVoicepack = ^TVoicepack;
 
26
    TVoicepack = record
 
27
        name: shortstring;
 
28
        chunks: array [TSound] of PMixChunk;
 
29
        end;
 
30
 
 
31
var MusicFN: shortstring;
 
32
 
 
33
procedure initModule;
 
34
procedure freeModule;
 
35
 
 
36
procedure InitSound;
 
37
procedure ReleaseSound;
 
38
procedure SoundLoad;
 
39
procedure PlaySound(snd: TSound);
 
40
procedure PlaySound(snd: TSound; keepPlaying: boolean);
 
41
procedure PlaySound(snd: TSound; voicepack: PVoicepack);
 
42
procedure PlaySound(snd: TSound; voicepack: PVoicepack; keepPlaying: boolean);
 
43
function  LoopSound(snd: TSound): LongInt;
 
44
function  LoopSound(snd: TSound; voicepack: PVoicepack): LongInt;
 
45
procedure PlayMusic;
 
46
procedure PauseMusic;
 
47
procedure ResumeMusic;
 
48
procedure StopSound(snd: TSound);
 
49
procedure StopSound(chn: LongInt);
 
50
function  ChangeVolume(voldelta: LongInt): LongInt;
 
51
function  AskForVoicepack(name: shortstring): Pointer;
 
52
 
 
53
 
 
54
implementation
 
55
uses uMisc, uConsole;
 
56
 
 
57
const chanTPU = 32;
 
58
var Volume: LongInt;
 
59
    lastChan: array [TSound] of LongInt;
 
60
    voicepacks: array[0..cMaxTeams] of TVoicepack;
 
61
    defVoicepack: PVoicepack;
 
62
    Mus: PMixMusic = nil;
 
63
 
 
64
function  AskForVoicepack(name: shortstring): Pointer;
 
65
var i: Longword;
 
66
begin
 
67
i:= 0;
 
68
    while (voicepacks[i].name <> name) and (voicepacks[i].name <> '') do
 
69
    begin
 
70
        inc(i);
 
71
        TryDo(i <= cMaxTeams, 'Engine bug: AskForVoicepack i > cMaxTeams', true)
 
72
    end;
 
73
 
 
74
    voicepacks[i].name:= name;
 
75
    AskForVoicepack:= @voicepacks[i]
 
76
end;
 
77
 
 
78
procedure InitSound;
 
79
var i: TSound;
 
80
    channels: LongInt;
 
81
begin
 
82
    if not isSoundEnabled then exit;
 
83
    WriteToConsole('Init sound...');
 
84
    isSoundEnabled:= SDL_InitSubSystem(SDL_INIT_AUDIO) >= 0;
 
85
 
 
86
{$IFDEF IPHONEOS}
 
87
    channels:= 1;
 
88
{$ELSE}
 
89
    channels:= 2;
 
90
{$ENDIF}
 
91
 
 
92
    if isSoundEnabled then
 
93
        isSoundEnabled:= Mix_OpenAudio(44100, $8010, channels, 1024) = 0;
 
94
 
 
95
{$IFDEF SDL_MIXER_NEWER}
 
96
    WriteToConsole('Init SDL_mixer... ');
 
97
    SDLTry(Mix_Init(MIX_INIT_OGG) <> 0, true);
 
98
    WriteLnToConsole(msgOK);
 
99
{$ENDIF}
 
100
 
 
101
    if isSoundEnabled then
 
102
        WriteLnToConsole(msgOK)
 
103
    else
 
104
        WriteLnToConsole(msgFailed);
 
105
 
 
106
    Mix_AllocateChannels(Succ(chanTPU));
 
107
    if isMusicEnabled then
 
108
        Mix_VolumeMusic(50);
 
109
    for i:= Low(TSound) to High(TSound) do
 
110
        lastChan[i]:= -1;
 
111
 
 
112
    Volume:= 0;
 
113
    ChangeVolume(cInitVolume)
 
114
end;
 
115
 
 
116
procedure ReleaseSound;
 
117
var i: TSound;
 
118
    t: Longword;
 
119
begin
 
120
    for t:= 0 to cMaxTeams do
 
121
        if voicepacks[t].name <> '' then
 
122
            for i:= Low(TSound) to High(TSound) do
 
123
                if voicepacks[t].chunks[i] <> nil then
 
124
                    Mix_FreeChunk(voicepacks[t].chunks[i]);
 
125
 
 
126
    if Mus <> nil then
 
127
        Mix_FreeMusic(Mus);
 
128
 
 
129
{$IFDEF SDL_MIXER_NEWER}
 
130
    // make sure all instances of sdl_mixer are unloaded before continuing
 
131
    while Mix_Init(0) <> 0 do
 
132
        Mix_Quit();
 
133
{$ENDIF}
 
134
 
 
135
    Mix_CloseAudio();
 
136
end;
 
137
 
 
138
procedure SoundLoad;
 
139
var i: TSound;
 
140
    t: Longword;
 
141
    s:shortstring;
 
142
begin
 
143
    if not isSoundEnabled then exit;
 
144
 
 
145
    defVoicepack:= AskForVoicepack('Default');
 
146
 
 
147
    for t:= 0 to cMaxTeams do
 
148
        if voicepacks[t].name <> '' then
 
149
            for i:= Low(TSound) to High(TSound) do
 
150
                voicepacks[t].chunks[i]:= nil;
 
151
 
 
152
    for i:= Low(TSound) to High(TSound) do
 
153
    begin
 
154
        defVoicepack^.chunks[i]:= nil;
 
155
        // preload all the big sound files (>32k) that would otherwise lockup the game
 
156
        if (i in [sndBeeWater, sndBee, sndCake, sndHellishImpact1, sndHellish, sndHomerun, sndMolotov, sndMortar, sndRideOfTheValkyries, sndYoohoo])
 
157
            and (Soundz[i].Path <> ptVoices) and (Soundz[i].FileName <> '') then
 
158
        begin
 
159
            s:= Pathz[Soundz[i].Path] + '/' + Soundz[i].FileName;
 
160
            WriteToConsole(msgLoading + s + ' ');
 
161
            defVoicepack^.chunks[i]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), 'rb'), 1);
 
162
            TryDo(defVoicepack^.chunks[i] <> nil, msgFailed, true);
 
163
            WriteLnToConsole(msgOK);
 
164
        end;
 
165
    end;
 
166
 
 
167
end;
 
168
 
 
169
procedure PlaySound(snd: TSound);
 
170
begin
 
171
    PlaySound(snd, nil, false);
 
172
end;
 
173
 
 
174
procedure PlaySound(snd: TSound; keepPlaying: boolean);
 
175
begin
 
176
    PlaySound(snd, nil, keepPlaying);
 
177
end;
 
178
 
 
179
procedure PlaySound(snd: TSound; voicepack: PVoicepack);
 
180
begin
 
181
    PlaySound(snd, voicepack, false);
 
182
end;
 
183
 
 
184
procedure PlaySound(snd: TSound; voicepack: PVoicepack; keepPlaying: boolean);
 
185
var s:shortstring;
 
186
begin
 
187
    if (not isSoundEnabled) or fastUntilLag then
 
188
        exit;
 
189
 
 
190
    if keepPlaying and (lastChan[snd] <> -1) and (Mix_Playing(lastChan[snd]) <> 0) then
 
191
        exit;
 
192
 
 
193
    if (voicepack <> nil) then
 
194
    begin
 
195
        if (voicepack^.chunks[snd] = nil) and (Soundz[snd].Path = ptVoices) and (Soundz[snd].FileName <> '') then
 
196
        begin
 
197
            s:= Pathz[Soundz[snd].Path] + '/' + voicepack^.name + '/' + Soundz[snd].FileName;
 
198
            WriteToConsole(msgLoading + s + ' ');
 
199
            voicepack^.chunks[snd]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), 'rb'), 1);
 
200
            if voicepack^.chunks[snd] = nil then
 
201
                WriteLnToConsole(msgFailed)
 
202
            else
 
203
                WriteLnToConsole(msgOK)
 
204
        end;
 
205
        lastChan[snd]:= Mix_PlayChannelTimed(-1, voicepack^.chunks[snd], 0, -1)
 
206
    end
 
207
    else
 
208
    begin
 
209
        if (defVoicepack^.chunks[snd] = nil) and (Soundz[snd].Path <> ptVoices) and (Soundz[snd].FileName <> '') then
 
210
        begin
 
211
            s:= Pathz[Soundz[snd].Path] + '/' + Soundz[snd].FileName;
 
212
            WriteToConsole(msgLoading + s + ' ');
 
213
            defVoicepack^.chunks[snd]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), 'rb'), 1);
 
214
            TryDo(defVoicepack^.chunks[snd] <> nil, msgFailed, true);
 
215
            WriteLnToConsole(msgOK);
 
216
        end;
 
217
        lastChan[snd]:= Mix_PlayChannelTimed(-1, defVoicepack^.chunks[snd], 0, -1)
 
218
    end;
 
219
end;
 
220
 
 
221
function LoopSound(snd: TSound): LongInt;
 
222
begin
 
223
    LoopSound:= LoopSound(snd, nil)
 
224
end;
 
225
 
 
226
function LoopSound(snd: TSound; voicepack: PVoicepack): LongInt;
 
227
var s: shortstring;
 
228
begin
 
229
    if (not isSoundEnabled) or fastUntilLag then
 
230
    begin
 
231
        LoopSound:= -1;
 
232
        exit
 
233
    end;
 
234
 
 
235
    if (voicepack <> nil) then
 
236
    begin
 
237
        if (voicepack^.chunks[snd] = nil) and (Soundz[snd].Path = ptVoices) and (Soundz[snd].FileName <> '') then
 
238
        begin
 
239
            s:= Pathz[Soundz[snd].Path] + '/' + voicepack^.name + '/' + Soundz[snd].FileName;
 
240
            WriteToConsole(msgLoading + s + ' ');
 
241
            voicepack^.chunks[snd]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), 'rb'), 1);
 
242
            if voicepack^.chunks[snd] = nil then
 
243
                WriteLnToConsole(msgFailed)
 
244
            else
 
245
                WriteLnToConsole(msgOK)
 
246
        end;
 
247
        LoopSound:= Mix_PlayChannelTimed(-1, voicepack^.chunks[snd], -1, -1)
 
248
    end
 
249
    else
 
250
    begin
 
251
        if (defVoicepack^.chunks[snd] = nil) and (Soundz[snd].Path <> ptVoices) and (Soundz[snd].FileName <> '') then
 
252
        begin
 
253
            s:= Pathz[Soundz[snd].Path] + '/' + Soundz[snd].FileName;
 
254
            WriteToConsole(msgLoading + s + ' ');
 
255
            defVoicepack^.chunks[snd]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), 'rb'), 1);
 
256
            TryDo(defVoicepack^.chunks[snd] <> nil, msgFailed, true);
 
257
            WriteLnToConsole(msgOK);
 
258
        end;
 
259
        LoopSound:= Mix_PlayChannelTimed(-1, defVoicepack^.chunks[snd], -1, -1);
 
260
    end;
 
261
end;
 
262
 
 
263
procedure StopSound(snd: TSound);
 
264
begin
 
265
    if not isSoundEnabled then exit;
 
266
    if (lastChan[snd] <> -1) and (Mix_Playing(lastChan[snd]) <> 0) then
 
267
    begin
 
268
        Mix_HaltChannel(lastChan[snd]);
 
269
        lastChan[snd]:= -1;
 
270
    end;
 
271
end;
 
272
 
 
273
procedure StopSound(chn: LongInt);
 
274
begin
 
275
    if not isSoundEnabled then exit;
 
276
 
 
277
    if (chn <> -1) and (Mix_Playing(chn) <> 0) then
 
278
        Mix_HaltChannel(chn);
 
279
end;
 
280
 
 
281
procedure PlayMusic;
 
282
var s: shortstring;
 
283
begin
 
284
    if (not isSoundEnabled) or (MusicFN = '') or (not isMusicEnabled) then
 
285
        exit;
 
286
 
 
287
    s:= PathPrefix + '/Music/' + MusicFN;
 
288
    WriteToConsole(msgLoading + s + ' ');
 
289
 
 
290
    Mus:= Mix_LoadMUS(Str2PChar(s));
 
291
    TryDo(Mus <> nil, msgFailed, false);
 
292
    WriteLnToConsole(msgOK);
 
293
 
 
294
    SDLTry(Mix_FadeInMusic(Mus, -1, 3000) <> -1, false)
 
295
end;
 
296
 
 
297
function ChangeVolume(voldelta: LongInt): LongInt;
 
298
begin
 
299
    if not isSoundEnabled then
 
300
        exit(0);
 
301
 
 
302
    inc(Volume, voldelta);
 
303
    if Volume < 0 then Volume:= 0;
 
304
    Mix_Volume(-1, Volume);
 
305
    Volume:= Mix_Volume(-1, -1);
 
306
    if isMusicEnabled then Mix_VolumeMusic(Volume * 4 div 8);
 
307
    ChangeVolume:= Volume * 100 div MIX_MAX_VOLUME
 
308
end;
 
309
 
 
310
procedure PauseMusic;
 
311
begin
 
312
    if (MusicFN = '') or (not isMusicEnabled) then
 
313
        exit;
 
314
 
 
315
    Mix_PauseMusic(Mus);
 
316
end;
 
317
 
 
318
procedure ResumeMusic;
 
319
begin
 
320
    if (MusicFN = '') or (not isMusicEnabled) then
 
321
        exit;
 
322
 
 
323
    Mix_ResumeMusic(Mus);
 
324
end;
 
325
 
 
326
procedure initModule;
 
327
begin
 
328
    MusicFN:='';
 
329
end;
 
330
 
 
331
procedure freeModule;
 
332
begin
 
333
    if isSoundEnabled then
 
334
        ReleaseSound();
 
335
end;
 
336
 
 
337
end.
 
338