From de3f29d7b23ef9447ee4c59f34fcf44f8cdc4601 Mon Sep 17 00:00:00 2001 From: frosch Date: Mon, 2 Oct 2023 14:37:43 +0200 Subject: [PATCH] Add: store base graphics parameters in openttd.cfg. --- src/base_media_base.h | 4 ++++ src/base_media_func.h | 3 +++ src/gfxinit.cpp | 10 ++++++++++ src/newgrf_config.cpp | 6 ++++++ src/newgrf_config.h | 1 + src/openttd.cpp | 6 ++++++ src/settings.cpp | 20 ++++++++++++++++++++ 7 files changed, 50 insertions(+) diff --git a/src/base_media_base.h b/src/base_media_base.h index 9cd36ef336..f85c9c40f8 100644 --- a/src/base_media_base.h +++ b/src/base_media_base.h @@ -96,6 +96,7 @@ struct BaseSet { } bool FillSetDetails(const IniFile &ini, const std::string &path, const std::string &full_filename, bool allow_empty_filename = true); + void CopyCompatibleConfig([[maybe_unused]] const T &src) {} /** * Get the description for the given ISO code. @@ -253,6 +254,7 @@ public: bool FillSetDetails(const IniFile &ini, const std::string &path, const std::string &full_filename); GRFConfig *GetExtraConfig() const { return this->extra_cfg.get(); } GRFConfig &GetOrCreateExtraConfig() const; + void CopyCompatibleConfig(const GraphicsSet &src); static MD5File::ChecksumResult CheckMD5(const MD5File *file, Subdirectory subdir); }; @@ -264,6 +266,8 @@ public: struct Ini { std::string name; uint32_t shortname; ///< unique key for base set + uint32_t extra_version; ///< version of the extra GRF + std::vector extra_params; ///< parameters for the extra GRF }; static inline Ini ini_data; diff --git a/src/base_media_func.h b/src/base_media_func.h index 28ad0e305f..2d30528df5 100644 --- a/src/base_media_func.h +++ b/src/base_media_func.h @@ -198,6 +198,9 @@ bool BaseMedia::AddFile(const std::string &filename, size_t basepath_ *prev = set; set->next = duplicate->next; + /* Keep baseset configuration, if compatible */ + set->CopyCompatibleConfig(*duplicate); + /* If the duplicate set is currently used (due to rescanning this can happen) * update the currently used set to the new one. This will 'lie' about the * version number until a new game is started which isn't a big problem */ diff --git a/src/gfxinit.cpp b/src/gfxinit.cpp index b2fb5fd70a..aa4d1c66fc 100644 --- a/src/gfxinit.cpp +++ b/src/gfxinit.cpp @@ -193,6 +193,7 @@ static void LoadSpriteTables() /* Baseset extra graphics */ GRFConfig *extra = new GRFConfig(used_set->GetOrCreateExtraConfig()); + if (extra->num_params == 0) extra->SetParameterDefaults(); ClrBit(extra->flags, GCF_INIT_ONLY); extra->next = top; @@ -388,6 +389,15 @@ GRFConfig &GraphicsSet::GetOrCreateExtraConfig() const return *this->extra_cfg; } +void GraphicsSet::CopyCompatibleConfig(const GraphicsSet &src) +{ + const GRFConfig *src_cfg = src.GetExtraConfig(); + if (src_cfg == nullptr || src_cfg->num_params == 0) return; + GRFConfig &dest_cfg = this->GetOrCreateExtraConfig(); + if (dest_cfg.IsCompatible(src_cfg->version)) return; + dest_cfg.CopyParams(*src_cfg); +} + /** * Calculate and check the MD5 hash of the supplied GRF. * @param file The file get the hash of. diff --git a/src/newgrf_config.cpp b/src/newgrf_config.cpp index c45498ee2b..f3cec8b5a5 100644 --- a/src/newgrf_config.cpp +++ b/src/newgrf_config.cpp @@ -66,6 +66,12 @@ GRFConfig::GRFConfig(const GRFConfig &config) : { } +void GRFConfig::SetParams(const std::vector &pars) +{ + this->num_params = static_cast(std::min(this->param.size(), pars.size())); + std::copy(pars.begin(), pars.begin() + this->num_params, this->param.begin()); +} + /** * Return whether this NewGRF can replace an older version of the same NewGRF. */ diff --git a/src/newgrf_config.h b/src/newgrf_config.h index 3620501b19..8596eab563 100644 --- a/src/newgrf_config.h +++ b/src/newgrf_config.h @@ -174,6 +174,7 @@ struct GRFConfig : ZeroedMemoryAllocator { struct GRFConfig *next; ///< NOSAVE: Next item in the linked list bool IsCompatible(uint32_t old_version) const; + void SetParams(const std::vector &pars); void CopyParams(const GRFConfig &src); std::optional GetTextfile(TextfileType type) const; diff --git a/src/openttd.cpp b/src/openttd.cpp index 1856743724..611d21f1e3 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -706,6 +706,12 @@ int openttd_main(int argc, char *argv[]) } else if (BaseGraphics::ini_data.shortname != 0) { graphics_set = BaseGraphics::ini_data.name; valid_graphics_set = BaseGraphics::SetSetByShortname(BaseGraphics::ini_data.shortname); + if (valid_graphics_set && !BaseGraphics::ini_data.extra_params.empty()) { + GRFConfig &extra_cfg = BaseGraphics::GetUsedSet()->GetOrCreateExtraConfig(); + if (extra_cfg.IsCompatible(BaseGraphics::ini_data.extra_version)) { + extra_cfg.SetParams(BaseGraphics::ini_data.extra_params); + } + } } else if (!BaseGraphics::ini_data.name.empty()) { graphics_set = BaseGraphics::ini_data.name; valid_graphics_set = BaseGraphics::SetSetByName(BaseGraphics::ini_data.name); diff --git a/src/settings.cpp b/src/settings.cpp index e072d8b7bd..d86c153828 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -999,6 +999,20 @@ static void GraphicsSetLoadConfig(IniFile &ini) if (const IniItem *item = group->GetItem("shortname"); item != nullptr && item->value && item->value->size() == 8) { BaseGraphics::ini_data.shortname = BSWAP32(std::strtoul(item->value->c_str(), nullptr, 16)); } + + if (const IniItem *item = group->GetItem("extra_version"); item != nullptr && item->value) BaseGraphics::ini_data.extra_version = std::strtoul(item->value->c_str(), nullptr, 10); + + if (const IniItem *item = group->GetItem("extra_params"); item != nullptr && item->value) { + auto &extra_params = BaseGraphics::ini_data.extra_params; + extra_params.resize(lengthof(GRFConfig::param)); + int count = ParseIntList(item->value->c_str(), &extra_params.front(), extra_params.size()); + if (count < 0) { + SetDParamStr(0, BaseGraphics::ini_data.name); + ShowErrorMessage(STR_CONFIG_ERROR, STR_CONFIG_ERROR_ARRAY, WL_CRITICAL); + count = 0; + } + extra_params.resize(count); + } } } @@ -1187,6 +1201,12 @@ static void GraphicsSetSaveConfig(IniFile &ini) group.GetOrCreateItem("name").SetValue(used_set->name); group.GetOrCreateItem("shortname").SetValue(fmt::format("{:08X}", BSWAP32(used_set->shortname))); + + const GRFConfig *extra_cfg = used_set->GetExtraConfig(); + if (extra_cfg != nullptr && extra_cfg->num_params > 0) { + group.GetOrCreateItem("extra_version").SetValue(fmt::format("{}", extra_cfg->version)); + group.GetOrCreateItem("extra_params").SetValue(GRFBuildParamList(extra_cfg)); + } } /* Save a GRF configuration to the given group name */