19 #define SET_TYPE "sounds"
32 static std::unique_ptr<RandomAccessFile> original_sound_file;
34 memset(_original_sounds, 0,
sizeof(_original_sounds));
37 if (filename ==
nullptr)
return;
40 size_t pos = original_sound_file->GetPos();
41 uint count = original_sound_file->ReadDword();
44 bool new_format =
HasBit(count, 31);
53 Debug(misc, 6,
"Incorrect number of sounds in '{}', ignoring.", filename);
57 original_sound_file->SeekTo(pos, SEEK_SET);
60 _original_sounds[i].file = original_sound_file.get();
61 _original_sounds[i].file_offset =
GB(original_sound_file->ReadDword(), 0, 31) + pos;
62 _original_sounds[i].file_size = original_sound_file->ReadDword();
69 original_sound_file->SeekTo(sound->file_offset, SEEK_SET);
72 original_sound_file->ReadBlock(name, original_sound_file->ReadByte());
73 if (new_format || strcmp(name,
"Corrupt sound") != 0) {
74 original_sound_file->SeekTo(12, SEEK_CUR);
78 uint32 tag = original_sound_file->ReadDword();
79 uint32 size = original_sound_file->ReadDword();
82 original_sound_file->ReadWord();
83 sound->channels = original_sound_file->ReadWord();
84 sound->rate = original_sound_file->ReadDword();
85 if (!new_format) sound->rate = 11025;
86 original_sound_file->ReadDword();
87 original_sound_file->ReadWord();
88 sound->bits_per_sample = original_sound_file->ReadByte();
89 original_sound_file->SeekTo(size - (2 + 2 + 4 + 4 + 2 + 1), SEEK_CUR);
90 }
else if (tag ==
'atad') {
91 sound->file_size = size;
92 sound->file = original_sound_file.get();
93 sound->file_offset = original_sound_file->GetPos();
108 sound->bits_per_sample = 8;
109 sound->file = original_sound_file.get();
110 sound->file_offset = original_sound_file->GetPos();
117 assert(sound !=
nullptr);
120 if (sound->file_size == 0 || sound->file_size > ((
size_t)-1) - 2)
return false;
122 int8 *mem = MallocT<int8>(sound->file_size + 2);
125 mem[sound->file_size ] = 0;
126 mem[sound->file_size + 1] = 0;
129 file->
SeekTo(sound->file_offset, SEEK_SET);
133 if (sound->bits_per_sample == 8) {
134 for (uint i = 0; i != sound->file_size; i++) {
139 #if TTD_ENDIAN == TTD_BIG_ENDIAN
140 if (sound->bits_per_sample == 16) {
141 uint num_samples = sound->file_size / 2;
142 int16 *samples = (int16 *)mem;
143 for (uint i = 0; i < num_samples; i++) {
144 samples[i] =
BSWAP16(samples[i]);
149 assert(sound->bits_per_sample == 8 || sound->bits_per_sample == 16);
150 assert(sound->channels == 1);
151 assert(sound->file_size != 0 && sound->rate != 0);
153 MxSetChannelRawSrc(mc, mem, sound->file_size, sound->rate, sound->bits_per_sample == 16);
158 void InitializeSound()
160 Debug(misc, 1,
"Loading sound effects...");
165 static void StartSound(SoundID sound_id,
float pan, uint volume)
167 if (volume == 0)
return;
170 if (sound ==
nullptr)
return;
173 if (sound->rate == 0 && sound->file !=
nullptr) {
176 sound->file =
nullptr;
182 if (sound->rate == 0)
return;
185 if (mc ==
nullptr)
return;
187 if (!SetBankSource(mc, sound))
return;
190 volume = sound->volume * volume;
193 MxActivateChannel(mc);
197 static const byte _vol_factor_by_zoom[] = {255, 255, 255, 190, 134, 87};
200 static const byte _sound_base_vol[] = {
201 128, 90, 128, 128, 128, 128, 128, 128,
202 128, 90, 90, 128, 128, 128, 128, 128,
203 128, 128, 128, 80, 128, 128, 128, 128,
204 128, 128, 128, 128, 128, 128, 128, 128,
205 128, 128, 90, 90, 90, 128, 90, 128,
206 128, 90, 128, 128, 128, 90, 128, 128,
207 128, 128, 128, 128, 90, 128, 128, 128,
208 128, 90, 128, 128, 128, 128, 128, 128,
209 128, 128, 90, 90, 90, 128, 128, 128,
213 static const byte _sound_idx[] = {
214 2, 3, 4, 5, 6, 7, 8, 9,
215 10, 11, 12, 13, 14, 15, 16, 17,
216 18, 19, 20, 21, 22, 23, 24, 25,
217 26, 27, 28, 29, 30, 31, 32, 33,
218 34, 35, 36, 37, 38, 39, 40, 0,
219 1, 41, 42, 43, 44, 45, 46, 47,
220 48, 49, 50, 51, 52, 53, 54, 55,
221 56, 57, 58, 59, 60, 61, 62, 63,
222 64, 65, 66, 67, 68, 69, 70, 71,
230 sound[i] = _original_sounds[_sound_idx[i]];
231 sound[i].volume = _sound_base_vol[i];
232 sound[i].priority = 0;
257 float panning = (float)screen_x / width;
269 void SndPlayTileFx(SoundID sound,
TileIndex tile)
274 int z = (y < 0 ? 0 : GetSlopePixelZ(x, y));
281 void SndPlayVehicleFx(SoundID sound,
const Vehicle *v)
289 void SndPlayFx(SoundID sound)
291 StartSound(sound, 0.5, UINT8_MAX);
300 template <
class T,
size_t Tnum_files,
bool Tsearch_in_tars>
303 template <
class Tbase_set>
309 template <
class Tbase_set>
314 const Tbase_set *best =
nullptr;
317 if (c->GetNumMissing() != 0)
continue;
319 if (best ==
nullptr ||
320 (best->fallback && !c->fallback) ||
321 best->valid_files < c->valid_files ||
322 (best->valid_files == c->valid_files &&
323 (best->shortname == c->shortname && best->version < c->version))) {