Fix crash when setting separation mode for vehicles with no orders list.
[openttd-joker.git] / src / music.cpp
blob2f6e2c6901e4db5f159f207d40c3625529fce060
1 /* $Id: music.cpp 23214 2011-11-14 19:24:22Z rubidium $ */
3 /*
4 * This file is part of OpenTTD.
5 * 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.
6 * 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.
7 * 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/>.
8 */
10 /** @file music.cpp The songs that OpenTTD knows. */
12 #include "stdafx.h"
14 /** The type of set we're replacing */
15 #define SET_TYPE "music"
16 #include "base_media_func.h"
18 #include "safeguards.h"
20 INSTANTIATE_BASE_MEDIA_METHODS(BaseMedia<MusicSet>, MusicSet)
22 /** Names corresponding to the music set's files */
23 static const char * const _music_file_names[] = {
24 "theme",
25 "old_0", "old_1", "old_2", "old_3", "old_4", "old_5", "old_6", "old_7", "old_8", "old_9",
26 "new_0", "new_1", "new_2", "new_3", "new_4", "new_5", "new_6", "new_7", "new_8", "new_9",
27 "ezy_0", "ezy_1", "ezy_2", "ezy_3", "ezy_4", "ezy_5", "ezy_6", "ezy_7", "ezy_8", "ezy_9",
29 /** Make sure we aren't messing things up. */
30 assert_compile(lengthof(_music_file_names) == NUM_SONGS_AVAILABLE);
32 template <class T, size_t Tnum_files, bool Tsearch_in_tars>
33 /* static */ const char * const *BaseSet<T, Tnum_files, Tsearch_in_tars>::file_names = _music_file_names;
35 template <class Tbase_set>
36 /* static */ const char *BaseMedia<Tbase_set>::GetExtension()
38 return ".obm"; // OpenTTD Base Music
41 template <class Tbase_set>
42 /* static */ bool BaseMedia<Tbase_set>::DetermineBestSet()
44 if (BaseMedia<Tbase_set>::used_set != nullptr) return true;
46 const Tbase_set *best = nullptr;
47 for (const Tbase_set *c = BaseMedia<Tbase_set>::available_sets; c != nullptr; c = c->next) {
48 if (c->GetNumMissing() != 0) continue;
50 if (best == nullptr ||
51 (best->fallback && !c->fallback) ||
52 best->valid_files < c->valid_files ||
53 (best->valid_files == c->valid_files &&
54 (best->shortname == c->shortname && best->version < c->version))) {
55 best = c;
59 BaseMedia<Tbase_set>::used_set = best;
60 return BaseMedia<Tbase_set>::used_set != nullptr;
63 bool MusicSet::FillSetDetails(IniFile *ini, const char *path, const char *full_filename)
65 bool ret = this->BaseSet<MusicSet, NUM_SONGS_AVAILABLE, false>::FillSetDetails(ini, path, full_filename);
66 if (ret) {
67 this->num_available = 0;
68 IniGroup *names = ini->GetGroup("names");
69 for (uint i = 0, j = 1; i < lengthof(this->song_name); i++) {
70 const char *filename = this->files[i].filename;
71 if (names == nullptr || StrEmpty(filename)) {
72 this->song_name[i][0] = '\0';
73 continue;
76 IniItem *item = nullptr;
77 /* As we possibly add a path to the filename and we compare
78 * on the filename with the path as in the .obm, we need to
79 * keep stripping path elements until we find a match. */
80 for (const char *p = filename; p != nullptr; p = strchr(p, PATHSEPCHAR)) {
81 /* Remove possible double path separator characters from
82 * the beginning, so we don't start reading e.g. root. */
83 while (*p == PATHSEPCHAR) p++;
85 item = names->GetItem(p, false);
86 if (item != nullptr && !StrEmpty(item->value)) break;
89 if (item == nullptr || StrEmpty(item->value)) {
90 DEBUG(grf, 0, "Base music set song name missing: %s", filename);
91 return false;
94 strecpy(this->song_name[i], item->value, lastof(this->song_name[i]));
95 this->track_nr[i] = j++;
96 this->num_available++;
99 return ret;