1
0
mirror of https://github.com/OpenTTD/OpenTTD synced 2026-01-20 02:42:42 +01:00

Codechange: Add callback to IntSettingDesc to support dynamic min/max

This commit is contained in:
glx22
2025-01-04 19:49:14 +01:00
committed by Loïc Guilloux
parent bf02cb014b
commit 7493b2d0c1
20 changed files with 81 additions and 48 deletions

View File

@@ -459,13 +459,14 @@ StringID IntSettingDesc::GetHelp() const
*/
void IntSettingDesc::SetValueDParams(uint first_param, int32_t value) const
{
auto [min_val, _] = this->GetRange();
if (this->set_value_dparams_cb != nullptr) {
this->set_value_dparams_cb(*this, first_param, value);
} else if (this->IsBoolSetting()) {
SetDParam(first_param++, value != 0 ? STR_CONFIG_SETTING_ON : STR_CONFIG_SETTING_OFF);
} else {
if ((this->flags & SF_GUI_DROPDOWN) != 0) {
SetDParam(first_param++, this->str_val - this->min + value);
SetDParam(first_param++, this->str_val - min_val + value);
} else {
SetDParam(first_param++, this->str_val + ((value == 0 && (this->flags & SF_GUI_0_IS_SPECIAL) != 0) ? 1 : 0));
}
@@ -482,6 +483,15 @@ int32_t IntSettingDesc::GetDefaultValue() const
return this->get_def_cb != nullptr ? this->get_def_cb(*this) : this->def;
}
/**
* Get the min/max range for the setting.
* @return The min/max range.
*/
std::tuple<int32_t, uint32_t> IntSettingDesc::GetRange() const
{
return this->get_range_cb != nullptr ? this->get_range_cb(*this) : std::tuple(this->min, this->max);
}
/**
* Make the value valid and then write it to the setting.
* See #MakeValidValid and #Write for more details.
@@ -505,6 +515,7 @@ void IntSettingDesc::MakeValueValidAndWrite(const void *object, int32_t val) con
*/
void IntSettingDesc::MakeValueValid(int32_t &val) const
{
auto [min_val, max_val] = this->GetRange();
/* We need to take special care of the uint32_t type as we receive from the function
* a signed integer. While here also bail out on 64-bit settings as those are not
* supported. Unsigned 8 and 16-bit variables are safe since they fit into a signed
@@ -522,8 +533,8 @@ void IntSettingDesc::MakeValueValid(int32_t &val) const
if (!(this->flags & SF_GUI_0_IS_SPECIAL) || val != 0) {
if (!(this->flags & SF_GUI_DROPDOWN)) {
/* Clamp value-type setting to its valid range */
val = Clamp(val, this->min, this->max);
} else if (val < this->min || val > (int32_t)this->max) {
val = Clamp(val, min_val, max_val);
} else if (val < min_val || val > static_cast<int32_t>(max_val)) {
/* Reset invalid discrete setting (where different values change gameplay) to its default value */
val = this->GetDefaultValue();
}
@@ -532,17 +543,17 @@ void IntSettingDesc::MakeValueValid(int32_t &val) const
}
case SLE_VAR_U32: {
/* Override the minimum value. No value below this->min, except special value 0 */
uint32_t uval = (uint32_t)val;
uint32_t uval = static_cast<uint32_t>(val);
if (!(this->flags & SF_GUI_0_IS_SPECIAL) || uval != 0) {
if (!(this->flags & SF_GUI_DROPDOWN)) {
/* Clamp value-type setting to its valid range */
uval = ClampU(uval, this->min, this->max);
} else if (uval < (uint)this->min || uval > this->max) {
uval = ClampU(uval, min_val, max_val);
} else if (uval < static_cast<uint32_t>(min_val) || uval > max_val) {
/* Reset invalid discrete setting to its default value */
uval = (uint32_t)this->GetDefaultValue();
uval = static_cast<uint32_t>(this->GetDefaultValue());
}
}
val = (int32_t)uval;
val = static_cast<int32_t>(uval);
return;
}
case SLE_VAR_I64:
@@ -1918,8 +1929,9 @@ void IConsoleGetSetting(const char *name, bool force_newgame)
} else if (sd->IsIntSetting()) {
std::string value = sd->FormatValue(object);
const IntSettingDesc *int_setting = sd->AsIntSetting();
auto [min_val, max_val] = int_setting->GetRange();
IConsolePrint(CC_INFO, "Current value for '{}' is '{}' (min: {}{}, max: {}).",
sd->GetName(), value, (sd->flags & SF_GUI_0_IS_SPECIAL) ? "(0) " : "", int_setting->min, int_setting->max);
sd->GetName(), value, (sd->flags & SF_GUI_0_IS_SPECIAL) ? "(0) " : "", min_val, max_val);
}
}