1 #include "sound.h"
2
3 // max volume factor: means that the interval 0% -> 100% is split in 5
4 int32_t MAX_VOLUME_FACTOR = 5;
5
6 // General helper that unifies the playing
7 static void play_sound (eSounds sound, int32_t x, int32_t vol, int32_t freq);
8
9
10 /** @brief play a weapon or item fire sample according to @a type, panned using @a x.
11 *
12 * This just plays what weapon[]/item[] globals hold for a sound.
13 *
14 * @param[in] type The weapon or item type.
15 * @param[in] x The x-coordinate where the sound is played.
16 * @param[in] vol The volume (0 - 255)
17 * @param[in] freq Frequency, 1000 is normal, 500 is half, 2000 is double and so on.
18 **/
play_fire_sound(int32_t type,int32_t x,int32_t vol,int32_t freq)19 void play_fire_sound(int32_t type, int32_t x, int32_t vol, int32_t freq)
20 {
21 int32_t sndNum = -1;
22
23 if (type >= WEAPONS) {
24 if (item[type - WEAPONS].sound > -1)
25 sndNum = item[type - WEAPONS].sound;
26 } else {
27 if (weapon[type].sound > -1)
28 sndNum = weapon[type].sound;
29 }
30
31 if ( (sndNum > -1) && (sndNum < SND_COUNT) )
32 play_sound(static_cast<eSounds>(sndNum), x, vol, freq);
33 }
34
35
36 /** @brief play a weapon or item explosion sample according to @a type, panned using @a x.
37 *
38 * This plays the sound listed in weapon[]/item[] globals unless special rules
39 * apply.
40 *
41 * @param[in] type The weapon or item type.
42 * @param[in] x The x-coordinate where the sound is played.
43 * @param[in] vol The volume (0 - 255)
44 * @param[in] freq Frequency, 1000 is normal, 500 is half, 2000 is double and so on.
45 **/
play_explosion_sound(int32_t type,int32_t x,int32_t vol,int32_t freq)46 void play_explosion_sound(int32_t type, int32_t x, int32_t vol, int32_t freq)
47 {
48 int32_t sndNum = -1;
49
50 if (SHAPED_CHARGE == type)
51 sndNum = SND_EXPL_SHAPED_CHARGE;
52 else if (WIDE_BOY == type)
53 sndNum = SND_EXPL_WIDE_BOY;
54 else if (CUTTER == type)
55 sndNum = SND_EXPL_CUTTER;
56 else if ( (SML_NAPALM <= type) && (LRG_NAPALM >= type)) {
57 sndNum = SND_EXPL_NAPALM;
58 freq += 333 * (LRG_NAPALM - type);
59 } else if (NAPALM_JELLY == type) {
60 sndNum = SND_EXPL_NAPALM_BURN;
61 freq += (rand() % 200) - 100;
62 vol -= rand() % 64;
63 } else if (PERCENT_BOMB == type)
64 sndNum = SND_EXPL_PER_CENT_BOMB;
65 else if (REDUCER == type)
66 sndNum = SND_EXPL_REDUCER;
67 else if ( ((DIRT_BALL <= type) && (SMALL_DIRT_SPREAD >= type))
68 || ((RIOT_CHARGE <= type) && (RIOT_BLAST >= type)) )
69 sndNum = SND_EXPL_DIRT_BALL_BOMB;
70 else {
71 // Default handling
72 if (type >= WEAPONS)
73 sndNum = item[type - WEAPONS].sound + SND_EXPL_MISS_SML;
74 else
75 sndNum = weapon[type].sound + SND_EXPL_MISS_SML;
76 }
77
78 if ( (sndNum > -1) && (sndNum < SND_COUNT) )
79 play_sound(static_cast<eSounds>(sndNum), x, vol, freq);
80 }
81
82
83 /** @brief plays the currently set background music modified by set volume factor
84 **/
play_music()85 void play_music()
86 {
87 if (env.loadBackgroundMusic())
88 play_sound(SND_BG_MUSIC, 128, 255, 1000);
89 }
90
91
92 /** @brief play a natural sample according to @a type, panned using @a x.
93 *
94 * @param[in] type The natural type.
95 * @param[in] x The x-coordinate where the sound is played.
96 * @param[in] vol The volume (0 - 255)
97 * @param[in] freq Frequency, 1000 is normal, 500 is half, 2000 is double and so on.
98 **/
99
play_natural_sound(int32_t type,int32_t x,int32_t vol,int32_t freq)100 void play_natural_sound(int32_t type, int32_t x, int32_t vol, int32_t freq)
101 {
102 int32_t sndNum = -1;
103
104 if (SML_METEOR == type) {
105 sndNum = naturals[SML_METEOR - WEAPONS].sound;
106 vol -= rand() % 128;
107 freq += 100 + (rand() % 100);
108 } else if (MED_METEOR == type) {
109 sndNum = naturals[MED_METEOR - WEAPONS].sound;
110 vol -= rand() % 64;
111 freq += rand() % 100;
112 } else if (LRG_METEOR == type) {
113 sndNum = naturals[LRG_METEOR - WEAPONS].sound;
114 vol -= rand() % 64;
115 freq += rand() % 250;
116 } else if (SML_LIGHTNING == type) {
117 sndNum = naturals[SML_LIGHTNING - WEAPONS].sound;
118 vol -= rand() % 128;
119 freq += 100 + (rand() % 100);
120 } else if (MED_LIGHTNING == type) {
121 sndNum = naturals[MED_LIGHTNING - WEAPONS].sound;
122 vol -= rand() % 64;
123 freq += rand() % 100;
124 } else if (LRG_LIGHTNING == type) {
125 sndNum = naturals[LRG_LIGHTNING - WEAPONS].sound;
126 vol -= rand() % 64;
127 freq += rand() % 250;
128 } else if (DIRT_FRAGMENT == type) {
129 sndNum = SND_NATU_DIRT_FALL;
130 vol -= rand() % 64;
131 // freq is manipulated by the call
132 }
133
134 if ( (sndNum > -1) && (sndNum < SND_COUNT)
135 && ( (SND_NATU_DIRT_FALL != sndNum)
136 || (global.used_voices < (env.voices - 8))) )
137 play_sound(static_cast<eSounds>(sndNum), x, vol, freq);
138 }
139
140
141 /** @brief play an interface sample according to @a sound.
142 *
143 * @param[in] sound The sound to play.
144 **/
145
play_interface_sound(eSounds sound)146 void play_interface_sound(eSounds sound)
147 {
148 if (SND_INTE_BUTTON_CLICK == sound)
149 play_sound(sound, env.halfWidth, 128, 1000);
150 }
151
152
153 // Global helpers implementation
play_sound(eSounds sound,int32_t x,int32_t vol,int32_t freq)154 static void play_sound(eSounds sound, int32_t x, int32_t vol, int32_t freq)
155 {
156 if (global.used_voices < env.voices) {
157 int32_t xVol = (vol * env.volume_factor) / MAX_VOLUME_FACTOR;
158
159 if ( (sound < SND_BG_MUSIC)
160 && env.sounds[sound]
161 && (vol > 0)
162 && (freq > 0) ) {
163 play_sample(env.sounds[sound],
164 xVol,
165 x <= 0 ? 31
166 : x >= env.screenWidth ? 192
167 : 31 + (x * 191 / env.screenWidth),
168 freq, false);
169 } else if (SND_BG_MUSIC == sound)
170 play_sample(env.background_music, xVol, x, freq, true);
171
172 ++global.used_voices;
173 }
174 }
175