mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 02:32:36 +01:00
cfg: Implement float config entry
Add missing string empty checks
This commit is contained in:
parent
d1bd936765
commit
0113224cb6
@ -60,9 +60,15 @@ std::vector<std::string> cfg::make_int_range(s64 min, s64 max)
|
||||
|
||||
bool try_to_int64(s64* out, std::string_view value, s64 min, s64 max)
|
||||
{
|
||||
if (value.empty())
|
||||
{
|
||||
if (out) cfg_log.error("cfg::try_to_uint64(): called with an empty string");
|
||||
return false;
|
||||
}
|
||||
|
||||
s64 result;
|
||||
const char* start = &value.front();
|
||||
const char* end = &value.back() + 1;
|
||||
const char* start = value.data();
|
||||
const char* end = start + value.size();
|
||||
int base = 10;
|
||||
int sign = +1;
|
||||
|
||||
@ -72,7 +78,7 @@ bool try_to_int64(s64* out, std::string_view value, s64 min, s64 max)
|
||||
start += 1;
|
||||
}
|
||||
|
||||
if (start[0] == '0' && (start[1] == 'x' || start[1] == 'X'))
|
||||
if (start[0] == '0' && value.size() >= 2 && (start[1] == 'x' || start[1] == 'X'))
|
||||
{
|
||||
// Limited hex support
|
||||
base = 16;
|
||||
@ -106,12 +112,18 @@ std::vector<std::string> cfg::make_uint_range(u64 min, u64 max)
|
||||
|
||||
bool try_to_uint64(u64* out, std::string_view value, u64 min, u64 max)
|
||||
{
|
||||
if (value.empty())
|
||||
{
|
||||
if (out) cfg_log.error("cfg::try_to_uint64(): called with an empty string");
|
||||
return false;
|
||||
}
|
||||
|
||||
u64 result;
|
||||
const char* start = &value.front();
|
||||
const char* end = &value.back() + 1;
|
||||
const char* start = value.data();
|
||||
const char* end = start + value.size();
|
||||
int base = 10;
|
||||
|
||||
if (start[0] == '0' && (start[1] == 'x' || start[1] == 'X'))
|
||||
if (start[0] == '0' && value.size() >= 2 && (start[1] == 'x' || start[1] == 'X'))
|
||||
{
|
||||
// Limited hex support
|
||||
base = 16;
|
||||
@ -136,6 +148,42 @@ bool try_to_uint64(u64* out, std::string_view value, u64 min, u64 max)
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<std::string> cfg::make_float_range(f64 min, f64 max)
|
||||
{
|
||||
return {std::to_string(min), std::to_string(max)};
|
||||
}
|
||||
|
||||
bool try_to_float(f64* out, std::string_view value, f64 min, f64 max)
|
||||
{
|
||||
if (value.empty())
|
||||
{
|
||||
if (out) cfg_log.error("cfg::try_to_float(): called with an empty string");
|
||||
return false;
|
||||
}
|
||||
|
||||
// std::from_chars float is yet to be implemented on Xcode it seems
|
||||
// And strtod doesn't support ranged view so we need to ensure it meets a null terminator
|
||||
const std::string str = std::string{value};
|
||||
|
||||
char* end_check{};
|
||||
const double result = std::strtod(str.data(), &end_check);
|
||||
|
||||
if (end_check != str.data() + str.size())
|
||||
{
|
||||
if (out) cfg_log.error("cfg::try_to_float('%s'): invalid float", value);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (result < min || result > max)
|
||||
{
|
||||
if (out) cfg_log.error("cfg::try_to_float('%s'): out of bounds (%f..%f)", value, min, max);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (out) *out = result;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cfg::try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) func, std::string_view value)
|
||||
{
|
||||
u64 max = umax;
|
||||
@ -162,8 +210,8 @@ bool cfg::try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) f
|
||||
}
|
||||
|
||||
u64 result;
|
||||
const char* start = &value.front();
|
||||
const char* end = &value.back() + 1;
|
||||
const char* start = value.data();
|
||||
const char* end = start + value.size();
|
||||
int base = 10;
|
||||
|
||||
if (start[0] == '0' && (start[1] == 'x' || start[1] == 'X'))
|
||||
|
@ -20,6 +20,9 @@ namespace cfg
|
||||
// Format min and max unsigned values
|
||||
std::vector<std::string> make_uint_range(u64 min, u64 max);
|
||||
|
||||
// Format min and max float values
|
||||
std::vector<std::string> make_float_range(f64 min, f64 max);
|
||||
|
||||
// Internal hack
|
||||
bool try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) func, std::string_view);
|
||||
|
||||
@ -309,6 +312,72 @@ namespace cfg
|
||||
}
|
||||
};
|
||||
|
||||
// Float entry with custom Min/Max range.
|
||||
template <s32 Min, s32 Max>
|
||||
class _float final : public _base
|
||||
{
|
||||
static_assert(Min < Max, "Invalid cfg::_float range");
|
||||
|
||||
using float_type = f64;
|
||||
atomic_t<float_type> m_value;
|
||||
|
||||
public:
|
||||
float_type def;
|
||||
|
||||
// Expose range
|
||||
static constexpr float_type max = Max;
|
||||
static constexpr float_type min = Min;
|
||||
|
||||
_float(node* owner, const std::string& name, float_type def = std::min<float_type>(Max, std::max<float_type>(Min, 0)), bool dynamic = false)
|
||||
: _base(type::_int, owner, name, dynamic)
|
||||
, m_value(def)
|
||||
, def(def)
|
||||
{
|
||||
}
|
||||
|
||||
operator float_type() const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
|
||||
float_type get() const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
|
||||
void from_default() override
|
||||
{
|
||||
m_value = def;
|
||||
}
|
||||
|
||||
std::string to_string() const override
|
||||
{
|
||||
return std::to_string(m_value);
|
||||
}
|
||||
|
||||
bool from_string(std::string_view value, bool /*dynamic*/ = false) override
|
||||
{
|
||||
f64 result;
|
||||
if (try_to_float(&result, value, Min, Max))
|
||||
{
|
||||
m_value = static_cast<float_type>(result);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void set(const f64& value)
|
||||
{
|
||||
m_value = static_cast<float_type>(value);
|
||||
}
|
||||
|
||||
std::vector<std::string> to_list() const override
|
||||
{
|
||||
return make_float_range(Min, Max);
|
||||
}
|
||||
};
|
||||
|
||||
// Alias for 32 bit int
|
||||
using int32 = _int<s32{smin}, s32{smax}>;
|
||||
|
||||
|
@ -27,6 +27,9 @@ bool try_to_int64(s64* out, std::string_view value, s64 min, s64 max);
|
||||
// Convert string to unsigned integer
|
||||
bool try_to_uint64(u64* out, std::string_view value, u64 min, u64 max);
|
||||
|
||||
// Convert string to float
|
||||
bool try_to_float(f64* out, std::string_view value, f64 min, f64 max);
|
||||
|
||||
// Get the file extension of a file path ("png", "jpg", etc.)
|
||||
std::string get_file_extension(const std::string& file_path);
|
||||
|
||||
|
@ -166,7 +166,7 @@ struct cfg_root : cfg::node
|
||||
cfg::_int<1, 8> consecutive_frames_to_skip{ this, "Consecutive Frames To Skip", 1, true};
|
||||
cfg::_int<50, 800> resolution_scale_percent{ this, "Resolution Scale", 100 };
|
||||
cfg::uint<0, 16> anisotropic_level_override{ this, "Anisotropic Filter Override", 0, true };
|
||||
cfg::_int<-32, 32> texture_lod_bias{ this, "Texture LOD Bias Addend", 0, true };
|
||||
cfg::_float<-32, 32> texture_lod_bias{ this, "Texture LOD Bias Addend", 0, true };
|
||||
cfg::_int<1, 1024> min_scalable_dimension{ this, "Minimum Scalable Dimension", 16 };
|
||||
cfg::_int<0, 16> shader_compiler_threads_count{ this, "Shader Compiler Threads", 0 };
|
||||
cfg::_int<0, 30000000> driver_recovery_timeout{ this, "Driver Recovery Timeout", 1000000, true };
|
||||
|
Loading…
Reference in New Issue
Block a user