Codechange: Store base set related texts in std::strings.

This commit is contained in:
Michael Lutz 2020-05-17 23:32:06 +02:00
parent 715aa67a9c
commit a49fdb7ebb
15 changed files with 108 additions and 91 deletions

View File

@ -15,6 +15,7 @@
#include "gfx_type.h" #include "gfx_type.h"
#include "textfile_type.h" #include "textfile_type.h"
#include "textfile_gui.h" #include "textfile_gui.h"
#include <unordered_map>
/* Forward declare these; can't do 'struct X' in functions as older GCCs barf on that */ /* Forward declare these; can't do 'struct X' in functions as older GCCs barf on that */
struct IniFile; struct IniFile;
@ -46,7 +47,7 @@ struct MD5File {
*/ */
template <class T, size_t Tnum_files, bool Tsearch_in_tars> template <class T, size_t Tnum_files, bool Tsearch_in_tars>
struct BaseSet { struct BaseSet {
typedef SmallMap<const char *, const char *> TranslatedStrings; typedef std::unordered_map<std::string, std::string> TranslatedStrings;
/** Number of files in this set */ /** Number of files in this set */
static const size_t NUM_FILES = Tnum_files; static const size_t NUM_FILES = Tnum_files;
@ -57,7 +58,7 @@ struct BaseSet {
/** Internal names of the files in this set. */ /** Internal names of the files in this set. */
static const char * const *file_names; static const char * const *file_names;
const char *name; ///< The name of the base set std::string name; ///< The name of the base set
TranslatedStrings description; ///< Description of the base set TranslatedStrings description; ///< Description of the base set
uint32 shortname; ///< Four letter short variant of the name uint32 shortname; ///< Four letter short variant of the name
uint32 version; ///< The version of this base set uint32 version; ///< The version of this base set
@ -72,13 +73,6 @@ struct BaseSet {
/** Free everything we allocated */ /** Free everything we allocated */
~BaseSet() ~BaseSet()
{ {
free(this->name);
for (auto &pair : this->description) {
free(pair.first);
free(pair.second);
}
for (uint i = 0; i < NUM_FILES; i++) { for (uint i = 0; i < NUM_FILES; i++) {
free(this->files[i].filename); free(this->files[i].filename);
free(this->files[i].missing_warning); free(this->files[i].missing_warning);
@ -116,20 +110,19 @@ struct BaseSet {
* @param isocode the isocode to search for * @param isocode the isocode to search for
* @return the description * @return the description
*/ */
const char *GetDescription(const char *isocode = nullptr) const const char *GetDescription(const std::string &isocode) const
{ {
if (isocode != nullptr) { if (!isocode.empty()) {
/* First the full ISO code */ /* First the full ISO code */
for (const auto &pair : this->description) { auto desc = this->description.find(isocode);
if (strcmp(pair.first, isocode) == 0) return pair.second; if (desc != this->description.end()) return desc->second.c_str();
}
/* Then the first two characters */ /* Then the first two characters */
for (const auto &pair : this->description) { desc = this->description.find(isocode.substr(0, 2));
if (strncmp(pair.first, isocode, 2) == 0) return pair.second; if (desc != this->description.end()) return desc->second.c_str();
}
} }
/* Then fall back */ /* Then fall back */
return this->description.front().second; return this->description.at(std::string{}).c_str();
} }
/** /**
@ -183,7 +176,7 @@ protected:
static const char *GetExtension(); static const char *GetExtension();
public: public:
/** The set as saved in the config file. */ /** The set as saved in the config file. */
static const char *ini_set; static std::string ini_set;
/** /**
* Determine the graphics pack that has to be used. * Determine the graphics pack that has to be used.
@ -203,7 +196,7 @@ public:
static Tbase_set *GetAvailableSets(); static Tbase_set *GetAvailableSets();
static bool SetSet(const char *name); static bool SetSet(const std::string &name);
static char *GetSetsList(char *p, const char *last); static char *GetSetsList(char *p, const char *last);
static int GetNumSets(); static int GetNumSets();
static int GetIndexOfUsedSet(); static int GetIndexOfUsedSet();
@ -219,7 +212,7 @@ public:
static bool HasSet(const ContentInfo *ci, bool md5sum); static bool HasSet(const ContentInfo *ci, bool md5sum);
}; };
template <class Tbase_set> /* static */ const char *BaseMedia<Tbase_set>::ini_set; template <class Tbase_set> /* static */ std::string BaseMedia<Tbase_set>::ini_set;
template <class Tbase_set> /* static */ const Tbase_set *BaseMedia<Tbase_set>::used_set; template <class Tbase_set> /* static */ const Tbase_set *BaseMedia<Tbase_set>::used_set;
template <class Tbase_set> /* static */ Tbase_set *BaseMedia<Tbase_set>::available_sets; template <class Tbase_set> /* static */ Tbase_set *BaseMedia<Tbase_set>::available_sets;
template <class Tbase_set> /* static */ Tbase_set *BaseMedia<Tbase_set>::duplicate_sets; template <class Tbase_set> /* static */ Tbase_set *BaseMedia<Tbase_set>::duplicate_sets;

View File

@ -42,16 +42,16 @@ bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(IniFile *ini, const
IniItem *item; IniItem *item;
fetch_metadata("name"); fetch_metadata("name");
this->name = stredup(item->value->c_str()); this->name = *item->value;
fetch_metadata("description"); fetch_metadata("description");
this->description[stredup("")] = stredup(item->value->c_str()); this->description[std::string{}] = *item->value;
/* Add the translations of the descriptions too. */ /* Add the translations of the descriptions too. */
for (const IniItem *item = metadata->item; item != nullptr; item = item->next) { for (const IniItem *item = metadata->item; item != nullptr; item = item->next) {
if (item->name.compare(0, 12, "description.") != 0) continue; if (item->name.compare(0, 12, "description.") != 0) continue;
this->description[stredup(item->name.c_str() + 12)] = stredup(item->value.value_or("").c_str()); this->description[item->name.substr(12)] = item->value.value_or("");
} }
fetch_metadata("shortname"); fetch_metadata("shortname");
@ -179,7 +179,7 @@ bool BaseMedia<Tbase_set>::AddFile(const char *filename, size_t basepath_length,
/* The more complete set takes precedence over the version number. */ /* The more complete set takes precedence over the version number. */
if ((duplicate->valid_files == set->valid_files && duplicate->version >= set->version) || if ((duplicate->valid_files == set->valid_files && duplicate->version >= set->version) ||
duplicate->valid_files > set->valid_files) { duplicate->valid_files > set->valid_files) {
DEBUG(grf, 1, "Not adding %s (%i) as base " SET_TYPE " set (duplicate, %s)", set->name, set->version, DEBUG(grf, 1, "Not adding %s (%i) as base " SET_TYPE " set (duplicate, %s)", set->name.c_str(), set->version,
duplicate->valid_files > set->valid_files ? "less valid files" : "lower version"); duplicate->valid_files > set->valid_files ? "less valid files" : "lower version");
set->next = BaseMedia<Tbase_set>::duplicate_sets; set->next = BaseMedia<Tbase_set>::duplicate_sets;
BaseMedia<Tbase_set>::duplicate_sets = set; BaseMedia<Tbase_set>::duplicate_sets = set;
@ -195,7 +195,7 @@ bool BaseMedia<Tbase_set>::AddFile(const char *filename, size_t basepath_length,
* version number until a new game is started which isn't a big problem */ * version number until a new game is started which isn't a big problem */
if (BaseMedia<Tbase_set>::used_set == duplicate) BaseMedia<Tbase_set>::used_set = set; if (BaseMedia<Tbase_set>::used_set == duplicate) BaseMedia<Tbase_set>::used_set = set;
DEBUG(grf, 1, "Removing %s (%i) as base " SET_TYPE " set (duplicate, %s)", duplicate->name, duplicate->version, DEBUG(grf, 1, "Removing %s (%i) as base " SET_TYPE " set (duplicate, %s)", duplicate->name.c_str(), duplicate->version,
duplicate->valid_files < set->valid_files ? "less valid files" : "lower version"); duplicate->valid_files < set->valid_files ? "less valid files" : "lower version");
duplicate->next = BaseMedia<Tbase_set>::duplicate_sets; duplicate->next = BaseMedia<Tbase_set>::duplicate_sets;
BaseMedia<Tbase_set>::duplicate_sets = duplicate; BaseMedia<Tbase_set>::duplicate_sets = duplicate;
@ -209,7 +209,7 @@ bool BaseMedia<Tbase_set>::AddFile(const char *filename, size_t basepath_length,
ret = true; ret = true;
} }
if (ret) { if (ret) {
DEBUG(grf, 1, "Adding %s (%i) as base " SET_TYPE " set", set->name, set->version); DEBUG(grf, 1, "Adding %s (%i) as base " SET_TYPE " set", set->name.c_str(), set->version);
} }
} else { } else {
delete set; delete set;
@ -226,18 +226,18 @@ bool BaseMedia<Tbase_set>::AddFile(const char *filename, size_t basepath_length,
* @return true if it could be loaded * @return true if it could be loaded
*/ */
template <class Tbase_set> template <class Tbase_set>
/* static */ bool BaseMedia<Tbase_set>::SetSet(const char *name) /* static */ bool BaseMedia<Tbase_set>::SetSet(const std::string &name)
{ {
extern void CheckExternalFiles(); extern void CheckExternalFiles();
if (StrEmpty(name)) { if (name.empty()) {
if (!BaseMedia<Tbase_set>::DetermineBestSet()) return false; if (!BaseMedia<Tbase_set>::DetermineBestSet()) return false;
CheckExternalFiles(); CheckExternalFiles();
return true; return true;
} }
for (const Tbase_set *s = BaseMedia<Tbase_set>::available_sets; s != nullptr; s = s->next) { for (const Tbase_set *s = BaseMedia<Tbase_set>::available_sets; s != nullptr; s = s->next) {
if (strcmp(name, s->name) == 0) { if (name == s->name) {
BaseMedia<Tbase_set>::used_set = s; BaseMedia<Tbase_set>::used_set = s;
CheckExternalFiles(); CheckExternalFiles();
return true; return true;
@ -257,7 +257,7 @@ template <class Tbase_set>
{ {
p += seprintf(p, last, "List of " SET_TYPE " sets:\n"); p += seprintf(p, last, "List of " SET_TYPE " sets:\n");
for (const Tbase_set *s = BaseMedia<Tbase_set>::available_sets; s != nullptr; s = s->next) { for (const Tbase_set *s = BaseMedia<Tbase_set>::available_sets; s != nullptr; s = s->next) {
p += seprintf(p, last, "%18s: %s", s->name, s->GetDescription()); p += seprintf(p, last, "%18s: %s", s->name.c_str(), s->GetDescription({}));
int invalid = s->GetNumInvalid(); int invalid = s->GetNumInvalid();
if (invalid != 0) { if (invalid != 0) {
int missing = s->GetNumMissing(); int missing = s->GetNumMissing();
@ -376,11 +376,11 @@ template <class Tbase_set>
* @param set_type the type of the BaseSet to instantiate * @param set_type the type of the BaseSet to instantiate
*/ */
#define INSTANTIATE_BASE_MEDIA_METHODS(repl_type, set_type) \ #define INSTANTIATE_BASE_MEDIA_METHODS(repl_type, set_type) \
template const char *repl_type::ini_set; \ template std::string repl_type::ini_set; \
template const char *repl_type::GetExtension(); \ template const char *repl_type::GetExtension(); \
template bool repl_type::AddFile(const char *filename, size_t pathlength, const char *tar_filename); \ template bool repl_type::AddFile(const char *filename, size_t pathlength, const char *tar_filename); \
template bool repl_type::HasSet(const struct ContentInfo *ci, bool md5sum); \ template bool repl_type::HasSet(const struct ContentInfo *ci, bool md5sum); \
template bool repl_type::SetSet(const char *name); \ template bool repl_type::SetSet(const std::string &name); \
template char *repl_type::GetSetsList(char *p, const char *last); \ template char *repl_type::GetSetsList(char *p, const char *last); \
template int repl_type::GetNumSets(); \ template int repl_type::GetNumSets(); \
template int repl_type::GetIndexOfUsedSet(); \ template int repl_type::GetIndexOfUsedSet(); \

View File

@ -167,15 +167,15 @@ char *CrashLog::LogConfiguration(char *buffer, const char *last) const
" Sound set: %s (%u)\n" " Sound set: %s (%u)\n"
" Video driver: %s\n\n", " Video driver: %s\n\n",
BlitterFactory::GetCurrentBlitter() == nullptr ? "none" : BlitterFactory::GetCurrentBlitter()->GetName(), BlitterFactory::GetCurrentBlitter() == nullptr ? "none" : BlitterFactory::GetCurrentBlitter()->GetName(),
BaseGraphics::GetUsedSet() == nullptr ? "none" : BaseGraphics::GetUsedSet()->name, BaseGraphics::GetUsedSet() == nullptr ? "none" : BaseGraphics::GetUsedSet()->name.c_str(),
BaseGraphics::GetUsedSet() == nullptr ? UINT32_MAX : BaseGraphics::GetUsedSet()->version, BaseGraphics::GetUsedSet() == nullptr ? UINT32_MAX : BaseGraphics::GetUsedSet()->version,
_current_language == nullptr ? "none" : _current_language->file, _current_language == nullptr ? "none" : _current_language->file,
MusicDriver::GetInstance() == nullptr ? "none" : MusicDriver::GetInstance()->GetName(), MusicDriver::GetInstance() == nullptr ? "none" : MusicDriver::GetInstance()->GetName(),
BaseMusic::GetUsedSet() == nullptr ? "none" : BaseMusic::GetUsedSet()->name, BaseMusic::GetUsedSet() == nullptr ? "none" : BaseMusic::GetUsedSet()->name.c_str(),
BaseMusic::GetUsedSet() == nullptr ? UINT32_MAX : BaseMusic::GetUsedSet()->version, BaseMusic::GetUsedSet() == nullptr ? UINT32_MAX : BaseMusic::GetUsedSet()->version,
_networking ? (_network_server ? "server" : "client") : "no", _networking ? (_network_server ? "server" : "client") : "no",
SoundDriver::GetInstance() == nullptr ? "none" : SoundDriver::GetInstance()->GetName(), SoundDriver::GetInstance() == nullptr ? "none" : SoundDriver::GetInstance()->GetName(),
BaseSounds::GetUsedSet() == nullptr ? "none" : BaseSounds::GetUsedSet()->name, BaseSounds::GetUsedSet() == nullptr ? "none" : BaseSounds::GetUsedSet()->name.c_str(),
BaseSounds::GetUsedSet() == nullptr ? UINT32_MAX : BaseSounds::GetUsedSet()->version, BaseSounds::GetUsedSet() == nullptr ? UINT32_MAX : BaseSounds::GetUsedSet()->version,
VideoDriver::GetInstance() == nullptr ? "none" : VideoDriver::GetInstance()->GetName() VideoDriver::GetInstance() == nullptr ? "none" : VideoDriver::GetInstance()->GetName()
); );

View File

@ -122,7 +122,7 @@ void CheckExternalFiles()
const GraphicsSet *used_set = BaseGraphics::GetUsedSet(); const GraphicsSet *used_set = BaseGraphics::GetUsedSet();
DEBUG(grf, 1, "Using the %s base graphics set", used_set->name); DEBUG(grf, 1, "Using the %s base graphics set", used_set->name.c_str());
static const size_t ERROR_MESSAGE_LENGTH = 256; static const size_t ERROR_MESSAGE_LENGTH = 256;
static const size_t MISSING_FILE_MESSAGE_LENGTH = 128; static const size_t MISSING_FILE_MESSAGE_LENGTH = 128;
@ -137,7 +137,7 @@ void CheckExternalFiles()
if (used_set->GetNumInvalid() != 0) { if (used_set->GetNumInvalid() != 0) {
/* Not all files were loaded successfully, see which ones */ /* Not all files were loaded successfully, see which ones */
add_pos += seprintf(add_pos, last, "Trying to load graphics set '%s', but it is incomplete. The game will probably not run correctly until you properly install this set or select another one. See section 4.1 of README.md.\n\nThe following files are corrupted or missing:\n", used_set->name); add_pos += seprintf(add_pos, last, "Trying to load graphics set '%s', but it is incomplete. The game will probably not run correctly until you properly install this set or select another one. See section 4.1 of README.md.\n\nThe following files are corrupted or missing:\n", used_set->name.c_str());
for (uint i = 0; i < GraphicsSet::NUM_FILES; i++) { for (uint i = 0; i < GraphicsSet::NUM_FILES; i++) {
MD5File::ChecksumResult res = GraphicsSet::CheckMD5(&used_set->files[i], BASESET_DIR); MD5File::ChecksumResult res = GraphicsSet::CheckMD5(&used_set->files[i], BASESET_DIR);
if (res != MD5File::CR_MATCH) add_pos += seprintf(add_pos, last, "\t%s is %s (%s)\n", used_set->files[i].filename, res == MD5File::CR_MISMATCH ? "corrupt" : "missing", used_set->files[i].missing_warning); if (res != MD5File::CR_MATCH) add_pos += seprintf(add_pos, last, "\t%s is %s (%s)\n", used_set->files[i].filename, res == MD5File::CR_MISMATCH ? "corrupt" : "missing", used_set->files[i].missing_warning);
@ -147,7 +147,7 @@ void CheckExternalFiles()
const SoundsSet *sounds_set = BaseSounds::GetUsedSet(); const SoundsSet *sounds_set = BaseSounds::GetUsedSet();
if (sounds_set->GetNumInvalid() != 0) { if (sounds_set->GetNumInvalid() != 0) {
add_pos += seprintf(add_pos, last, "Trying to load sound set '%s', but it is incomplete. The game will probably not run correctly until you properly install this set or select another one. See section 4.1 of README.md.\n\nThe following files are corrupted or missing:\n", sounds_set->name); add_pos += seprintf(add_pos, last, "Trying to load sound set '%s', but it is incomplete. The game will probably not run correctly until you properly install this set or select another one. See section 4.1 of README.md.\n\nThe following files are corrupted or missing:\n", sounds_set->name.c_str());
assert_compile(SoundsSet::NUM_FILES == 1); assert_compile(SoundsSet::NUM_FILES == 1);
/* No need to loop each file, as long as there is only a single /* No need to loop each file, as long as there is only a single

View File

@ -65,7 +65,7 @@ struct MusicSystem {
void BuildPlaylists(); void BuildPlaylists();
void ChangePlaylist(PlaylistChoices pl); void ChangePlaylist(PlaylistChoices pl);
void ChangeMusicSet(const char *set_name); void ChangeMusicSet(const std::string &set_name);
void Shuffle(); void Shuffle();
void Unshuffle(); void Unshuffle();
@ -167,12 +167,10 @@ void MusicSystem::ChangePlaylist(PlaylistChoices pl)
* Change to named music set, and reset playback. * Change to named music set, and reset playback.
* @param set_name Name of music set to select * @param set_name Name of music set to select
*/ */
void MusicSystem::ChangeMusicSet(const char *set_name) void MusicSystem::ChangeMusicSet(const std::string &set_name)
{ {
BaseMusic::SetSet(set_name); BaseMusic::SetSet(set_name);
BaseMusic::ini_set = set_name;
free(BaseMusic::ini_set);
BaseMusic::ini_set = stredup(set_name);
this->BuildPlaylists(); this->BuildPlaylists();
this->ChangePlaylist(this->selected_playlist); this->ChangePlaylist(this->selected_playlist);
@ -433,8 +431,7 @@ void MusicLoop()
void ChangeMusicSet(int index) void ChangeMusicSet(int index)
{ {
if (BaseMusic::GetIndexOfUsedSet() == index) return; if (BaseMusic::GetIndexOfUsedSet() == index) return;
const char *name = BaseMusic::GetSet(index)->name; _music.ChangeMusicSet(BaseMusic::GetSet(index)->name);
_music.ChangeMusicSet(name);
} }
/** /**
@ -464,7 +461,7 @@ struct MusicTrackSelectionWindow : public Window {
SetDParam(0, STR_MUSIC_PLAYLIST_ALL + _settings_client.music.playlist); SetDParam(0, STR_MUSIC_PLAYLIST_ALL + _settings_client.music.playlist);
break; break;
case WID_MTS_CAPTION: case WID_MTS_CAPTION:
SetDParamStr(0, BaseMusic::GetUsedSet()->name); SetDParamStr(0, BaseMusic::GetUsedSet()->name.c_str());
break; break;
} }
} }

View File

@ -925,7 +925,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
list.emplace_back(new DropDownListStringItem(STR_NONE, -1, false)); list.emplace_back(new DropDownListStringItem(STR_NONE, -1, false));
for (uint i = 0; i < this->grf_presets.size(); i++) { for (uint i = 0; i < this->grf_presets.size(); i++) {
list.emplace_back(new DropDownListCharStringItem(this->grf_presets[i].c_str(), i, false)); list.emplace_back(new DropDownListCharStringItem(this->grf_presets[i], i, false));
} }
this->DeleteChildWindows(WC_QUERY_STRING); // Remove the parameter query window this->DeleteChildWindows(WC_QUERY_STRING); // Remove the parameter query window

View File

@ -537,9 +537,9 @@ int openttd_main(int argc, char *argv[])
char *sounddriver = nullptr; char *sounddriver = nullptr;
char *videodriver = nullptr; char *videodriver = nullptr;
char *blitter = nullptr; char *blitter = nullptr;
char *graphics_set = nullptr; std::string graphics_set;
char *sounds_set = nullptr; std::string sounds_set;
char *music_set = nullptr; std::string music_set;
Dimension resolution = {0, 0}; Dimension resolution = {0, 0};
/* AfterNewGRFScan sets save_config to true after scanning completed. */ /* AfterNewGRFScan sets save_config to true after scanning completed. */
bool save_config = false; bool save_config = false;
@ -563,9 +563,9 @@ int openttd_main(int argc, char *argv[])
int i; int i;
while ((i = mgo.GetOpt()) != -1) { while ((i = mgo.GetOpt()) != -1) {
switch (i) { switch (i) {
case 'I': free(graphics_set); graphics_set = stredup(mgo.opt); break; case 'I': graphics_set = mgo.opt; break;
case 'S': free(sounds_set); sounds_set = stredup(mgo.opt); break; case 'S': sounds_set = mgo.opt; break;
case 'M': free(music_set); music_set = stredup(mgo.opt); break; case 'M': music_set = mgo.opt; break;
case 'm': free(musicdriver); musicdriver = stredup(mgo.opt); break; case 'm': free(musicdriver); musicdriver = stredup(mgo.opt); break;
case 's': free(sounddriver); sounddriver = stredup(mgo.opt); break; case 's': free(sounddriver); sounddriver = stredup(mgo.opt); break;
case 'v': free(videodriver); videodriver = stredup(mgo.opt); break; case 'v': free(videodriver); videodriver = stredup(mgo.opt); break;
@ -731,17 +731,16 @@ int openttd_main(int argc, char *argv[])
InitWindowSystem(); InitWindowSystem();
BaseGraphics::FindSets(); BaseGraphics::FindSets();
if (graphics_set == nullptr && BaseGraphics::ini_set != nullptr) graphics_set = stredup(BaseGraphics::ini_set); if (graphics_set.empty() && !BaseGraphics::ini_set.empty()) graphics_set = BaseGraphics::ini_set;
if (!BaseGraphics::SetSet(graphics_set)) { if (!BaseGraphics::SetSet(graphics_set)) {
if (!StrEmpty(graphics_set)) { if (!graphics_set.empty()) {
BaseGraphics::SetSet(nullptr); BaseGraphics::SetSet({});
ErrorMessageData msg(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_BASE_GRAPHICS_NOT_FOUND); ErrorMessageData msg(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_BASE_GRAPHICS_NOT_FOUND);
msg.SetDParamStr(0, graphics_set); msg.SetDParamStr(0, graphics_set.c_str());
ScheduleErrorMessage(msg); ScheduleErrorMessage(msg);
} }
} }
free(graphics_set);
/* Initialize game palette */ /* Initialize game palette */
GfxInitPalettes(); GfxInitPalettes();
@ -802,30 +801,28 @@ int openttd_main(int argc, char *argv[])
InitializeScreenshotFormats(); InitializeScreenshotFormats();
BaseSounds::FindSets(); BaseSounds::FindSets();
if (sounds_set == nullptr && BaseSounds::ini_set != nullptr) sounds_set = stredup(BaseSounds::ini_set); if (sounds_set.empty() && !BaseSounds::ini_set.empty()) sounds_set = BaseSounds::ini_set;
if (!BaseSounds::SetSet(sounds_set)) { if (!BaseSounds::SetSet(sounds_set)) {
if (StrEmpty(sounds_set) || !BaseSounds::SetSet(nullptr)) { if (sounds_set.empty() || !BaseSounds::SetSet({})) {
usererror("Failed to find a sounds set. Please acquire a sounds set for OpenTTD. See section 1.4 of README.md."); usererror("Failed to find a sounds set. Please acquire a sounds set for OpenTTD. See section 1.4 of README.md.");
} else { } else {
ErrorMessageData msg(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_BASE_SOUNDS_NOT_FOUND); ErrorMessageData msg(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_BASE_SOUNDS_NOT_FOUND);
msg.SetDParamStr(0, sounds_set); msg.SetDParamStr(0, sounds_set.c_str());
ScheduleErrorMessage(msg); ScheduleErrorMessage(msg);
} }
} }
free(sounds_set);
BaseMusic::FindSets(); BaseMusic::FindSets();
if (music_set == nullptr && BaseMusic::ini_set != nullptr) music_set = stredup(BaseMusic::ini_set); if (music_set.empty() && !BaseMusic::ini_set.empty()) music_set = BaseMusic::ini_set;
if (!BaseMusic::SetSet(music_set)) { if (!BaseMusic::SetSet(music_set)) {
if (StrEmpty(music_set) || !BaseMusic::SetSet(nullptr)) { if (music_set.empty() || !BaseMusic::SetSet({})) {
usererror("Failed to find a music set. Please acquire a music set for OpenTTD. See section 1.4 of README.md."); usererror("Failed to find a music set. Please acquire a music set for OpenTTD. See section 1.4 of README.md.");
} else { } else {
ErrorMessageData msg(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_BASE_MUSIC_NOT_FOUND); ErrorMessageData msg(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_BASE_MUSIC_NOT_FOUND);
msg.SetDParamStr(0, music_set); msg.SetDParamStr(0, music_set.c_str());
ScheduleErrorMessage(msg); ScheduleErrorMessage(msg);
} }
} }
free(music_set);
if (sounddriver == nullptr && _ini_sounddriver != nullptr) sounddriver = stredup(_ini_sounddriver); if (sounddriver == nullptr && _ini_sounddriver != nullptr) sounddriver = stredup(_ini_sounddriver);
DriverFactoryBase::SelectDriver(sounddriver, Driver::DT_SOUND); DriverFactoryBase::SelectDriver(sounddriver, Driver::DT_SOUND);
@ -875,22 +872,15 @@ int openttd_main(int argc, char *argv[])
exit_noshutdown: exit_noshutdown:
/* These three are normally freed before bootstrap. */ /* These three are normally freed before bootstrap. */
free(graphics_set);
free(videodriver); free(videodriver);
free(blitter); free(blitter);
exit_bootstrap: exit_bootstrap:
/* These are normally freed before exit, but after bootstrap. */ /* These are normally freed before exit, but after bootstrap. */
free(sounds_set);
free(music_set);
free(musicdriver); free(musicdriver);
free(sounddriver); free(sounddriver);
exit_normal: exit_normal:
free(BaseGraphics::ini_set);
free(BaseSounds::ini_set);
free(BaseMusic::ini_set);
free(_ini_musicdriver); free(_ini_musicdriver);
free(_ini_sounddriver); free(_ini_sounddriver);
free(_ini_videodriver); free(_ini_videodriver);
@ -1142,9 +1132,9 @@ void SwitchToMode(SwitchMode new_mode)
case SM_MENU: // Switch to game intro menu case SM_MENU: // Switch to game intro menu
LoadIntroGame(); LoadIntroGame();
if (BaseSounds::ini_set == nullptr && BaseSounds::GetUsedSet()->fallback) { if (BaseSounds::ini_set.empty() && BaseSounds::GetUsedSet()->fallback) {
ShowErrorMessage(STR_WARNING_FALLBACK_SOUNDSET, INVALID_STRING_ID, WL_CRITICAL); ShowErrorMessage(STR_WARNING_FALLBACK_SOUNDSET, INVALID_STRING_ID, WL_CRITICAL);
BaseSounds::ini_set = stredup(BaseSounds::GetUsedSet()->name); BaseSounds::ini_set = BaseSounds::GetUsedSet()->name;
} }
break; break;

View File

@ -310,7 +310,7 @@ static bool MakePNGImage(const char *name, ScreenshotCallback *callb, void *user
char buf[8192]; char buf[8192];
char *p = buf; char *p = buf;
p += seprintf(p, lastof(buf), "Graphics set: %s (%u)\n", BaseGraphics::GetUsedSet()->name, BaseGraphics::GetUsedSet()->version); p += seprintf(p, lastof(buf), "Graphics set: %s (%u)\n", BaseGraphics::GetUsedSet()->name.c_str(), BaseGraphics::GetUsedSet()->version);
p = strecpy(p, "NewGRFs:\n", lastof(buf)); p = strecpy(p, "NewGRFs:\n", lastof(buf));
for (const GRFConfig *c = _game_mode == GM_MENU ? nullptr : _grfconfig; c != nullptr; c = c->next) { for (const GRFConfig *c = _game_mode == GM_MENU ? nullptr : _grfconfig; c != nullptr; c = c->next) {
p += seprintf(p, lastof(buf), "%08X ", BSWAP32(c->ident.grfid)); p += seprintf(p, lastof(buf), "%08X ", BSWAP32(c->ident.grfid));

View File

@ -414,6 +414,7 @@ static const void *StringToVal(const SettingDescBase *desc, const char *orig_str
return desc->def; return desc->def;
} }
case SDT_STDSTRING:
case SDT_STRING: return orig_str; case SDT_STRING: return orig_str;
case SDT_INTLIST: return str; case SDT_INTLIST: return str;
default: break; default: break;
@ -565,6 +566,22 @@ static void IniLoadSettings(IniFile *ini, const SettingDesc *sd, const char *grp
} }
break; break;
case SDT_STDSTRING:
switch (GetVarMemType(sld->conv)) {
case SLE_VAR_STR:
case SLE_VAR_STRQ:
if (p != nullptr) {
reinterpret_cast<std::string *>(ptr)->assign((const char *)p);
} else {
reinterpret_cast<std::string *>(ptr)->clear();
}
break;
default: NOT_REACHED();
}
break;
case SDT_INTLIST: { case SDT_INTLIST: {
if (!LoadIntList((const char*)p, ptr, sld->length, GetVarMemType(sld->conv))) { if (!LoadIntList((const char*)p, ptr, sld->length, GetVarMemType(sld->conv))) {
ErrorMessageData msg(STR_CONFIG_ERROR, STR_CONFIG_ERROR_ARRAY); ErrorMessageData msg(STR_CONFIG_ERROR, STR_CONFIG_ERROR_ARRAY);
@ -701,6 +718,22 @@ static void IniSaveSettings(IniFile *ini, const SettingDesc *sd, const char *grp
} }
break; break;
case SDT_STDSTRING:
switch (GetVarMemType(sld->conv)) {
case SLE_VAR_STR: strecpy(buf, reinterpret_cast<std::string *>(ptr)->c_str(), lastof(buf)); break;
case SLE_VAR_STRQ:
if (reinterpret_cast<std::string *>(ptr)->empty()) {
buf[0] = '\0';
} else {
seprintf(buf, lastof(buf), "\"%s\"", reinterpret_cast<std::string *>(ptr)->c_str());
}
break;
default: NOT_REACHED();
}
break;
case SDT_INTLIST: case SDT_INTLIST:
MakeIntList(buf, lastof(buf), ptr, sld->length, sld->conv); MakeIntList(buf, lastof(buf), ptr, sld->length, sld->conv);
break; break;

View File

@ -152,7 +152,7 @@ struct BaseSetTextfileWindow : public TextfileWindow {
{ {
if (widget == WID_TF_CAPTION) { if (widget == WID_TF_CAPTION) {
SetDParam(0, content_type); SetDParam(0, content_type);
SetDParamStr(1, this->baseset->name); SetDParamStr(1, this->baseset->name.c_str());
} }
} }
}; };
@ -335,10 +335,10 @@ struct GameOptionsWindow : Window {
case WID_GO_RESOLUTION_DROPDOWN: SetDParam(0, GetCurRes() == _resolutions.size() ? STR_GAME_OPTIONS_RESOLUTION_OTHER : SPECSTR_RESOLUTION_START + GetCurRes()); break; case WID_GO_RESOLUTION_DROPDOWN: SetDParam(0, GetCurRes() == _resolutions.size() ? STR_GAME_OPTIONS_RESOLUTION_OTHER : SPECSTR_RESOLUTION_START + GetCurRes()); break;
case WID_GO_GUI_ZOOM_DROPDOWN: SetDParam(0, _gui_zoom_dropdown[ZOOM_LVL_OUT_4X - _gui_zoom]); break; case WID_GO_GUI_ZOOM_DROPDOWN: SetDParam(0, _gui_zoom_dropdown[ZOOM_LVL_OUT_4X - _gui_zoom]); break;
case WID_GO_FONT_ZOOM_DROPDOWN: SetDParam(0, _font_zoom_dropdown[ZOOM_LVL_OUT_4X - _font_zoom]); break; case WID_GO_FONT_ZOOM_DROPDOWN: SetDParam(0, _font_zoom_dropdown[ZOOM_LVL_OUT_4X - _font_zoom]); break;
case WID_GO_BASE_GRF_DROPDOWN: SetDParamStr(0, BaseGraphics::GetUsedSet()->name); break; case WID_GO_BASE_GRF_DROPDOWN: SetDParamStr(0, BaseGraphics::GetUsedSet()->name.c_str()); break;
case WID_GO_BASE_GRF_STATUS: SetDParam(0, BaseGraphics::GetUsedSet()->GetNumInvalid()); break; case WID_GO_BASE_GRF_STATUS: SetDParam(0, BaseGraphics::GetUsedSet()->GetNumInvalid()); break;
case WID_GO_BASE_SFX_DROPDOWN: SetDParamStr(0, BaseSounds::GetUsedSet()->name); break; case WID_GO_BASE_SFX_DROPDOWN: SetDParamStr(0, BaseSounds::GetUsedSet()->name.c_str()); break;
case WID_GO_BASE_MUSIC_DROPDOWN: SetDParamStr(0, BaseMusic::GetUsedSet()->name); break; case WID_GO_BASE_MUSIC_DROPDOWN: SetDParamStr(0, BaseMusic::GetUsedSet()->name.c_str()); break;
case WID_GO_BASE_MUSIC_STATUS: SetDParam(0, BaseMusic::GetUsedSet()->GetNumInvalid()); break; case WID_GO_BASE_MUSIC_STATUS: SetDParam(0, BaseMusic::GetUsedSet()->GetNumInvalid()); break;
} }
} }
@ -481,10 +481,9 @@ struct GameOptionsWindow : Window {
void SetMediaSet(int index) void SetMediaSet(int index)
{ {
if (_game_mode == GM_MENU) { if (_game_mode == GM_MENU) {
const char *name = T::GetSet(index)->name; auto name = T::GetSet(index)->name;
free(T::ini_set); T::ini_set = name;
T::ini_set = stredup(name);
T::SetSet(name); T::SetSet(name);
this->reload = true; this->reload = true;

View File

@ -27,8 +27,9 @@ enum SettingDescType : byte {
SDT_MANYOFMANY = 3, ///< bitmasked number where MULTIPLE bits may be set SDT_MANYOFMANY = 3, ///< bitmasked number where MULTIPLE bits may be set
SDT_INTLIST = 4, ///< list of integers separated by a comma ',' SDT_INTLIST = 4, ///< list of integers separated by a comma ','
SDT_STRING = 5, ///< string with a pre-allocated buffer SDT_STRING = 5, ///< string with a pre-allocated buffer
SDT_STDSTRING = 6, ///< \c std::string
SDT_END, SDT_END,
/* 10 more possible primitives */ /* 9 more possible primitives */
}; };

View File

@ -17,6 +17,7 @@ SDTG_LIST = SDTG_LIST($name, $type, $length, $flags, $guiflags, $var, $def,
SDTG_MMANY = SDTG_MMANY($name, $type, $flags, $guiflags, $var, $def, $full, $str, $strhelp, $strval, $proc, $from, $to, $cat), SDTG_MMANY = SDTG_MMANY($name, $type, $flags, $guiflags, $var, $def, $full, $str, $strhelp, $strval, $proc, $from, $to, $cat),
SDTG_OMANY = SDTG_OMANY($name, $type, $flags, $guiflags, $var, $def, $max, $full, $str, $strhelp, $strval, $proc, $from, $to, $cat), SDTG_OMANY = SDTG_OMANY($name, $type, $flags, $guiflags, $var, $def, $max, $full, $str, $strhelp, $strval, $proc, $from, $to, $cat),
SDTG_STR = SDTG_STR($name, $type, $flags, $guiflags, $var, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat), SDTG_STR = SDTG_STR($name, $type, $flags, $guiflags, $var, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat),
SDTG_SSTR = SDTG_SSTR($name, $type, $flags, $guiflags, $var, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat),
SDTG_BOOL = SDTG_BOOL($name, $flags, $guiflags, $var, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat), SDTG_BOOL = SDTG_BOOL($name, $flags, $guiflags, $var, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat),
SDTG_VAR = SDTG_VAR($name, $type, $flags, $guiflags, $var, $def, $min, $max, $interval, $str, $strhelp, $strval, $proc, $from, $to, $cat), SDTG_VAR = SDTG_VAR($name, $type, $flags, $guiflags, $var, $def, $min, $max, $interval, $str, $strhelp, $strval, $proc, $from, $to, $cat),
SDTG_END = SDTG_END() SDTG_END = SDTG_END()
@ -58,21 +59,21 @@ max = 2
full = _support8bppmodes full = _support8bppmodes
cat = SC_BASIC cat = SC_BASIC
[SDTG_STR] [SDTG_SSTR]
name = ""graphicsset"" name = ""graphicsset""
type = SLE_STRQ type = SLE_STRQ
var = BaseGraphics::ini_set var = BaseGraphics::ini_set
def = nullptr def = nullptr
cat = SC_BASIC cat = SC_BASIC
[SDTG_STR] [SDTG_SSTR]
name = ""soundsset"" name = ""soundsset""
type = SLE_STRQ type = SLE_STRQ
var = BaseSounds::ini_set var = BaseSounds::ini_set
def = nullptr def = nullptr
cat = SC_BASIC cat = SC_BASIC
[SDTG_STR] [SDTG_SSTR]
name = ""musicset"" name = ""musicset""
type = SLE_STRQ type = SLE_STRQ
var = BaseMusic::ini_set var = BaseMusic::ini_set

View File

@ -74,6 +74,9 @@ static size_t ConvertLandscape(const char *value);
#define SDTG_STR(name, type, flags, guiflags, var, def, str, strhelp, strval, proc, from, to, cat)\ #define SDTG_STR(name, type, flags, guiflags, var, def, str, strhelp, strval, proc, from, to, cat)\
SDTG_GENERAL(name, SDT_STRING, SL_STR, type, flags, guiflags, var, sizeof(var), def, 0, 0, 0, nullptr, str, strhelp, strval, proc, from, to, cat) SDTG_GENERAL(name, SDT_STRING, SL_STR, type, flags, guiflags, var, sizeof(var), def, 0, 0, 0, nullptr, str, strhelp, strval, proc, from, to, cat)
#define SDTG_SSTR(name, type, flags, guiflags, var, def, str, strhelp, strval, proc, from, to, cat)\
SDTG_GENERAL(name, SDT_STDSTRING, SL_STDSTR, type, flags, guiflags, var, sizeof(var), def, 0, 0, 0, nullptr, str, strhelp, strval, proc, from, to, cat)
#define SDTG_OMANY(name, type, flags, guiflags, var, def, max, full, str, strhelp, strval, proc, from, to, cat)\ #define SDTG_OMANY(name, type, flags, guiflags, var, def, max, full, str, strhelp, strval, proc, from, to, cat)\
SDTG_GENERAL(name, SDT_ONEOFMANY, SL_VAR, type, flags, guiflags, var, 0, def, 0, max, 0, full, str, strhelp, strval, proc, from, to, cat) SDTG_GENERAL(name, SDT_ONEOFMANY, SL_VAR, type, flags, guiflags, var, 0, def, 0, max, 0, full, str, strhelp, strval, proc, from, to, cat)

View File

@ -65,7 +65,7 @@ StringID DropDownListParamStringItem::String() const
StringID DropDownListCharStringItem::String() const StringID DropDownListCharStringItem::String() const
{ {
SetDParamStr(0, this->raw_string); SetDParamStr(0, this->raw_string.c_str());
return this->string; return this->string;
} }

View File

@ -68,9 +68,9 @@ public:
*/ */
class DropDownListCharStringItem : public DropDownListStringItem { class DropDownListCharStringItem : public DropDownListStringItem {
public: public:
const char *raw_string; std::string raw_string;
DropDownListCharStringItem(const char *raw_string, int result, bool masked) : DropDownListStringItem(STR_JUST_RAW_STRING, result, masked), raw_string(raw_string) {} DropDownListCharStringItem(const std::string &raw_string, int result, bool masked) : DropDownListStringItem(STR_JUST_RAW_STRING, result, masked), raw_string(raw_string) {}
StringID String() const override; StringID String() const override;
}; };