22#define SET_TYPE "sounds"
27static std::array<SoundEntry, ORIGINAL_SAMPLE_COUNT> _original_sounds;
35 static std::unique_ptr<RandomAccessFile> original_sound_file;
37 _original_sounds.fill({});
40 if (filename.empty())
return;
42 original_sound_file = std::make_unique<RandomAccessFile>(filename,
BASESET_DIR);
43 size_t pos = original_sound_file->GetPos();
44 uint count = original_sound_file->ReadDword();
47 auto source =
HasBit(count, 31) ? SoundSource::BasesetNewFormat : SoundSource::BasesetOldFormat;
56 Debug(misc, 6,
"Incorrect number of sounds in '{}', ignoring.", filename);
60 original_sound_file->SeekTo(pos, SEEK_SET);
63 for (
auto &sound : _original_sounds) {
64 sound.file = original_sound_file.get();
65 sound.file_offset =
GB(original_sound_file->ReadDword(), 0, 31) + pos;
66 sound.file_size = original_sound_file->ReadDword();
67 sound.source = source;
73 assert(sound !=
nullptr);
75 if (sound->file !=
nullptr) {
76 if (!LoadSound(*sound, sound_id)) {
78 sound->file =
nullptr;
81 sound->file =
nullptr;
85 if (sound->data->empty())
return false;
87 MxSetChannelRawSrc(mc, sound->data, sound->rate, sound->bits_per_sample == 16);
94 Debug(misc, 1,
"Loading sound effects...");
100static void StartSound(SoundID sound_id,
float pan, uint volume)
102 if (volume == 0)
return;
105 if (sound ==
nullptr)
return;
107 if (sound->rate == 0) {
110 if (sound->file ==
nullptr)
return;
114 if (mc ==
nullptr)
return;
116 if (!SetBankSource(mc, sound, sound_id))
return;
119 volume = sound->volume * volume;
122 MxActivateChannel(mc);
126static const uint8_t _vol_factor_by_zoom[] = {255, 255, 255, 190, 134, 87};
129static const uint8_t _sound_base_vol[] = {
130 128, 90, 128, 128, 128, 128, 128, 128,
131 128, 90, 90, 128, 128, 128, 128, 128,
132 128, 128, 128, 80, 128, 128, 128, 128,
133 128, 128, 128, 128, 128, 128, 128, 128,
134 128, 128, 90, 90, 90, 128, 90, 128,
135 128, 90, 128, 128, 128, 90, 128, 128,
136 128, 128, 128, 128, 90, 128, 128, 128,
137 128, 90, 128, 128, 128, 128, 128, 128,
138 128, 128, 90, 90, 90, 128, 128, 128,
142static const uint8_t _sound_idx[] = {
143 2, 3, 4, 5, 6, 7, 8, 9,
144 10, 11, 12, 13, 14, 15, 16, 17,
145 18, 19, 20, 21, 22, 23, 24, 25,
146 26, 27, 28, 29, 30, 31, 32, 33,
147 34, 35, 36, 37, 38, 39, 40, 0,
148 1, 41, 42, 43, 44, 45, 46, 47,
149 48, 49, 50, 51, 52, 53, 54, 55,
150 56, 57, 58, 59, 60, 61, 62, 63,
151 64, 65, 66, 67, 68, 69, 70, 71,
159 sound[i] = _original_sounds[_sound_idx[i]];
160 sound[i].volume = _sound_base_vol[i];
161 sound[i].priority = 0;
187 *sound = _original_sounds[_sound_idx[i]];
188 sound->volume = _sound_base_vol[i];
215 float panning = (float)screen_x / width;
220 _vol_factor_by_zoom[vp->
zoom]
227void SndPlayTileFx(SoundID sound,
TileIndex tile)
239void SndPlayVehicleFx(SoundID sound,
const Vehicle *v)
247void SndPlayFx(SoundID sound)
249 StartSound(sound, 0.5, UINT8_MAX);
258template <
class T,
size_t Tnum_files,
bool Tsearch_in_tars>
261template <
class Tbase_set>
267template <
class Tbase_set>
272 const Tbase_set *best =
nullptr;
275 if (c->GetNumMissing() != 0)
continue;
277 if (best ==
nullptr ||
278 (best->fallback && !c->fallback) ||
279 best->valid_files < c->valid_files ||
280 (best->valid_files == c->valid_files &&
281 (best->shortname == c->shortname && best->version < c->version))) {
debug_inline constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
debug_inline static constexpr uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
constexpr T ClrBit(T &x, const uint8_t y)
Clears a bit in a variable.
static std::string ini_set
The set as saved in the config file.
#define Debug(category, level, format_string,...)
Ouptut a line of debugging information.
@ BASESET_DIR
Subdirectory for all base data (base sets, intro game)
int GetSlopePixelZ(int x, int y, bool ground_vehicle)
Return world Z coordinate of a given point of a tile.
Functions related to OTTD's landscape.
Point RemapCoords(int x, int y, int z)
Map 3D world or tile coordinate to equivalent 2D coordinate as used in the viewports and smallmap.
static debug_inline uint TileY(TileIndex tile)
Get the Y component of a tile.
static debug_inline uint TileX(TileIndex tile)
Get the X component of a tile.
void MxCloseAllChannels()
Close all mixer channels.
void MxSetChannelVolume(MixerChannel *mc, uint volume, float pan)
Set volume and pan parameters for a sound.
Functions to mix sound samples.
SoundEntry * AllocateSound(uint num)
Allocate sound slots.
Functions related to NewGRF provided sounds.
Class related to random access to files.
A number of safeguards to prevent using unsafe methods.
static void SndPlayScreenCoordFx(SoundID sound, int left, int right, int top, int bottom)
Decide 'where' (between left and right speaker) to play the sound effect.
static const char *const _sound_file_names[]
Names corresponding to the sound set's files.
static void OpenBankFile(const std::string &filename)
void ChangeSoundSet(int index)
Change the configured sound set and reset sounds.
static const uint ORIGINAL_SAMPLE_COUNT
The number of sounds in the original sample.cat.
Functions related to sound loaders.
Definition of base types and functions in a cross-platform compatible way.
#define lengthof(array)
Return the length of an fixed size array.
Information about a single base set.
static uint MaxY()
Gets the maximum Y coordinate within the map, including MP_VOID.
static debug_inline uint MaxX()
Gets the maximum X coordinate within the map, including MP_VOID.
Coordinates of a point in 2D.
uint8_t grf_container_ver
NewGRF container version if the sound is from a NewGRF.
All data of a sounds set.
Rect coord
NOSAVE: Graphical bounding box of the vehicle, i.e. what to redraw on moves.
Data structure for viewport, display of a part of the world.
ZoomLevel zoom
The zoom level of the viewport.
int virtual_top
Virtual top coordinate.
int virtual_left
Virtual left coordinate.
int virtual_width
width << zoom
int virtual_height
height << zoom
Data structure for an opened window.
AllWindows< false > IterateFromBack
Iterate all windows in Z order from back to front.
static const uint TILE_SIZE
Tile size in world coordinates.
Base class for all vehicles.
void InvalidateWindowData(WindowClass cls, WindowNumber number, int data, bool gui_scope)
Mark window data of the window of a given class and specific window number as invalid (in need of re-...
Window functions not directly related to making/drawing windows.
Functions, definitions and such used only by the GUI.
@ WN_GAME_OPTIONS_GAME_OPTIONS
Game options.
@ WC_GAME_OPTIONS
Game options window; Window numbers:
@ ZOOM_LVL_END
End for iteration.