mirror of https://github.com/OpenTTD/OpenTTD
74 lines
2.8 KiB
C++
74 lines
2.8 KiB
C++
/*
|
|
* This file is part of OpenTTD.
|
|
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
|
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/** @file soundloader.cpp Handling of loading sounds. */
|
|
|
|
#include "stdafx.h"
|
|
#include "debug.h"
|
|
#include "sound_type.h"
|
|
#include "soundloader_type.h"
|
|
#include "soundloader_func.h"
|
|
#include "string_func.h"
|
|
#include "newgrf_sound.h"
|
|
#include "random_access_file_type.h"
|
|
|
|
#include "safeguards.h"
|
|
|
|
template class ProviderManager<SoundLoader>;
|
|
|
|
bool LoadSoundData(SoundEntry &sound, bool new_format, SoundID sound_id, const std::string &name)
|
|
{
|
|
/* Check for valid sound size. */
|
|
if (sound.file_size == 0 || sound.file_size > SIZE_MAX - 2) return false;
|
|
|
|
size_t pos = sound.file->GetPos();
|
|
sound.data = std::make_shared<std::vector<uint8_t>>();
|
|
for (auto &loader : ProviderManager<SoundLoader>::GetProviders()) {
|
|
sound.file->SeekTo(pos, SEEK_SET);
|
|
if (loader->Load(sound, new_format, *sound.data)) break;
|
|
}
|
|
|
|
if (sound.data->empty()) {
|
|
Debug(grf, 0, "LoadSound [{}]: Failed to load sound '{}' for slot {}", sound.file->GetSimplifiedFilename(), name, sound_id);
|
|
return false;
|
|
}
|
|
|
|
assert(sound.bits_per_sample == 8 || sound.bits_per_sample == 16);
|
|
assert(sound.channels == 1);
|
|
assert(sound.rate != 0);
|
|
|
|
Debug(grf, 2, "LoadSound [{}]: channels {}, sample rate {}, bits per sample {}, length {}", sound.file->GetSimplifiedFilename(), sound.channels, sound.rate, sound.bits_per_sample, sound.file_size);
|
|
|
|
/* Mixer always requires an extra sample at the end for the built-in linear resampler. */
|
|
sound.data->resize(sound.data->size() + sound.channels * sound.bits_per_sample / 8);
|
|
sound.data->shrink_to_fit();
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool LoadBasesetSound(SoundEntry &sound, bool new_format, SoundID sound_id)
|
|
{
|
|
sound.file->SeekTo(sound.file_offset, SEEK_SET);
|
|
|
|
/* Read name of sound for diagnostics. */
|
|
size_t name_len = sound.file->ReadByte();
|
|
std::string name(name_len, '\0');
|
|
sound.file->ReadBlock(name.data(), name_len);
|
|
|
|
return LoadSoundData(sound, new_format, sound_id, StrMakeValid(name));
|
|
}
|
|
|
|
bool LoadSound(SoundEntry &sound, SoundID sound_id)
|
|
{
|
|
switch (sound.source) {
|
|
case SoundSource::BasesetOldFormat: return LoadBasesetSound(sound, false, sound_id);
|
|
case SoundSource::BasesetNewFormat: return LoadBasesetSound(sound, true, sound_id);
|
|
case SoundSource::NewGRF: return LoadNewGRFSound(sound, sound_id);
|
|
default: NOT_REACHED();
|
|
}
|
|
}
|