1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-23 03:02:53 +01:00
rpcs3/Utilities/Config.h

395 lines
7.1 KiB
C
Raw Normal View History

2016-02-01 22:55:43 +01:00
#pragma once
#include "Utilities/types.h"
#include "Utilities/StrFmt.h"
2017-05-13 20:30:37 +02:00
#include "Utilities/Log.h"
#include <utility>
#include <string>
#include <vector>
2016-02-01 22:55:43 +01:00
#include <set>
#include <map>
namespace cfg
{
2017-08-02 12:22:53 +02:00
// Format min and max values
std::vector<std::string> make_int_range(s64 min, s64 max);
2016-02-01 22:55:43 +01:00
// Convert string to signed integer
bool try_to_int64(s64* out, const std::string& value, s64 min, s64 max);
// Internal hack
bool try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) func, const std::string&);
// Internal hack
std::vector<std::string> try_to_enum_list(decltype(&fmt_class_string<int>::format) func);
2016-02-01 22:55:43 +01:00
// Config tree entry type.
enum class type : uint
{
node = 0, // cfg::node type
2017-05-20 13:45:02 +02:00
_bool, // cfg::_bool type
_enum, // cfg::_enum type
_int, // cfg::_int type
string, // cfg::string type
2016-02-01 22:55:43 +01:00
set, // cfg::set_entry type
2017-05-13 20:30:37 +02:00
log,
2016-02-01 22:55:43 +01:00
};
// Config tree entry abstract base class
2017-05-20 13:45:02 +02:00
class _base
2016-02-01 22:55:43 +01:00
{
const type m_type;
protected:
// Ownerless entry constructor
2017-05-20 13:45:02 +02:00
_base(type _type);
2016-02-01 22:55:43 +01:00
// Owned entry constructor
2017-05-20 13:45:02 +02:00
_base(type _type, class node* owner, const std::string& name);
2016-02-01 22:55:43 +01:00
public:
2017-05-20 13:45:02 +02:00
_base(const _base&) = delete;
2016-02-01 22:55:43 +01:00
2018-09-22 21:35:52 +02:00
_base& operator=(const _base&) = delete;
2016-02-01 22:55:43 +01:00
// Get type
type get_type() const { return m_type; }
// Reset defaults
virtual void from_default() = 0;
// Convert to string (optional)
virtual std::string to_string() const
{
return{};
}
// Try to convert from string (optional)
virtual bool from_string(const std::string&);
2016-02-01 22:55:43 +01:00
// Get string list (optional)
virtual std::vector<std::string> to_list() const
{
return{};
}
// Set multiple values. Implementation-specific, optional.
virtual bool from_list(std::vector<std::string>&&);
2016-02-01 22:55:43 +01:00
};
// Config tree node which contains another nodes
2017-05-20 13:45:02 +02:00
class node : public _base
2016-02-01 22:55:43 +01:00
{
2017-05-20 13:45:02 +02:00
std::vector<std::pair<std::string, _base*>> m_nodes;
2016-02-01 22:55:43 +01:00
2017-05-20 13:45:02 +02:00
friend class _base;
2016-02-01 22:55:43 +01:00
public:
// Root node constructor
node()
2017-05-20 13:45:02 +02:00
: _base(type::node)
2016-02-01 22:55:43 +01:00
{
}
// Registered node constructor
2017-05-20 13:45:02 +02:00
node(node* owner, const std::string& name)
: _base(type::node, owner, name)
2016-02-01 22:55:43 +01:00
{
}
// Get child nodes
2017-05-20 13:45:02 +02:00
const auto& get_nodes() const
2016-02-01 22:55:43 +01:00
{
return m_nodes;
}
// Serialize node
std::string to_string() const override;
// Deserialize node
bool from_string(const std::string& value) override;
// Set default values
void from_default() override;
};
2017-05-20 13:45:02 +02:00
class _bool final : public _base
2016-02-01 22:55:43 +01:00
{
2017-05-20 13:45:02 +02:00
bool m_value;
2016-02-01 22:55:43 +01:00
2017-05-20 13:45:02 +02:00
public:
[Qt/Input] Improve pad_settings_dialog a bit (#3611) * Input: further work on remapping Xinput and begin work on remapping DS4 * Input: Improve pad_settings_dialog a bit and begin Remapping for XInput * Input: begin evdev remapping and change all handlers to use cfg::string * Input: finish work on remapping evdev and some more crap * Input: finish work on remapping Xinput and DS4 * Input: add DS4 Colors to DS4 config * Input: Improve DS4 deadzone scaling Jarves made some mistakes, so I'll fix them in the follow up commit * Input: fix Jarves fixes on DS4 deadzone and remove unnecessary usage of toUtf8 * Input: add primitive batterychecks to XInput and DS4 * Input: add mmjoystick remapping * Input: Fix evdev and some Vibration issues * Input: adjust capabilities to fix stick input for games like LoS 2 also fix threshold slider minimum also add ps button to all the handlers * Input: Further evdev work based on danilaml code review and own debugging: Fixed path issue, <= 0 issue, some captures, const, axis with same codes. Adds a map to each device that differentiates negative and positive axis mappings. adjusted rest of the file to tabs (ListDevices and beginning of threadProc) * Input: use 20ms vibration update time for xbox one elite controllers. * Input: Fix return type of Clamp() * Input: Evdev Fix * Input: Evdev Optional GetNextButtonPress presumably better than the other * Input: review changes * Input: evdev: fix wrong index in axis handling move bindpadtodevice down to keep consistency between handlers and not get crazy * Input: evdev: fix expensive add_device in GetNextButtonPress * cleanup * Input: mmjoy: fix type * Input: evdev: final fixes * Input: evdev: exclude unnecessary buttons while mapping Xbox 360 or DS4 * Input: add deadzone preview by passing necessary values in callback use 0.5 of max value for threshold in pad dialog * Input: get rid of all-uppercase variables
2017-11-27 22:31:15 +01:00
bool def;
2016-02-01 22:55:43 +01:00
2017-05-20 13:45:02 +02:00
_bool(node* owner, const std::string& name, bool def = false)
: _base(type::_bool, owner, name)
, m_value(def)
2016-02-01 22:55:43 +01:00
, def(def)
{
}
explicit operator bool() const
{
2017-05-20 13:45:02 +02:00
return m_value;
2016-02-01 22:55:43 +01:00
}
2018-05-04 22:48:05 +02:00
bool get() const
{
return m_value;
}
2017-01-25 00:22:19 +01:00
void from_default() override;
2016-02-01 22:55:43 +01:00
std::string to_string() const override
{
2017-05-20 13:45:02 +02:00
return m_value ? "true" : "false";
2016-02-01 22:55:43 +01:00
}
bool from_string(const std::string& value) override
{
if (value == "false")
2017-05-20 13:45:02 +02:00
m_value = false;
2016-02-01 22:55:43 +01:00
else if (value == "true")
2017-05-20 13:45:02 +02:00
m_value = true;
2016-02-01 22:55:43 +01:00
else
return false;
return true;
}
[Qt/Input] Improve pad_settings_dialog a bit (#3611) * Input: further work on remapping Xinput and begin work on remapping DS4 * Input: Improve pad_settings_dialog a bit and begin Remapping for XInput * Input: begin evdev remapping and change all handlers to use cfg::string * Input: finish work on remapping evdev and some more crap * Input: finish work on remapping Xinput and DS4 * Input: add DS4 Colors to DS4 config * Input: Improve DS4 deadzone scaling Jarves made some mistakes, so I'll fix them in the follow up commit * Input: fix Jarves fixes on DS4 deadzone and remove unnecessary usage of toUtf8 * Input: add primitive batterychecks to XInput and DS4 * Input: add mmjoystick remapping * Input: Fix evdev and some Vibration issues * Input: adjust capabilities to fix stick input for games like LoS 2 also fix threshold slider minimum also add ps button to all the handlers * Input: Further evdev work based on danilaml code review and own debugging: Fixed path issue, <= 0 issue, some captures, const, axis with same codes. Adds a map to each device that differentiates negative and positive axis mappings. adjusted rest of the file to tabs (ListDevices and beginning of threadProc) * Input: use 20ms vibration update time for xbox one elite controllers. * Input: Fix return type of Clamp() * Input: Evdev Fix * Input: Evdev Optional GetNextButtonPress presumably better than the other * Input: review changes * Input: evdev: fix wrong index in axis handling move bindpadtodevice down to keep consistency between handlers and not get crazy * Input: evdev: fix expensive add_device in GetNextButtonPress * cleanup * Input: mmjoy: fix type * Input: evdev: final fixes * Input: evdev: exclude unnecessary buttons while mapping Xbox 360 or DS4 * Input: add deadzone preview by passing necessary values in callback use 0.5 of max value for threshold in pad dialog * Input: get rid of all-uppercase variables
2017-11-27 22:31:15 +01:00
void set(const bool& value)
{
m_value = value;
}
2016-02-01 22:55:43 +01:00
};
// Value node with fixed set of possible values, each maps to an enum value of type T.
2017-05-20 13:45:02 +02:00
template <typename T>
class _enum final : public _base
2016-02-01 22:55:43 +01:00
{
2017-05-20 13:45:02 +02:00
T m_value;
2016-02-01 22:55:43 +01:00
public:
const T def;
2017-05-20 13:45:02 +02:00
_enum(node* owner, const std::string& name, T value = {})
: _base(type::_enum, owner, name)
2016-02-01 22:55:43 +01:00
, m_value(value)
, def(value)
{
}
operator T() const
{
2017-05-20 13:45:02 +02:00
return m_value;
2016-02-01 22:55:43 +01:00
}
2018-05-04 22:48:05 +02:00
T get() const
{
return m_value;
}
2016-02-01 22:55:43 +01:00
void from_default() override
{
m_value = def;
}
std::string to_string() const override
{
std::string result;
fmt_class_string<T>::format(result, fmt_unveil<T>::get(m_value));
return result; // TODO: ???
2016-02-01 22:55:43 +01:00
}
bool from_string(const std::string& value) override
{
u64 result;
if (try_to_enum_value(&result, &fmt_class_string<T>::format, value))
2016-02-01 22:55:43 +01:00
{
2016-08-07 15:59:46 +02:00
// No narrowing check, it's hard to do right there
m_value = static_cast<T>(static_cast<std::underlying_type_t<T>>(result));
return true;
2016-02-01 22:55:43 +01:00
}
return false;
}
std::vector<std::string> to_list() const override
{
return try_to_enum_list(&fmt_class_string<T>::format);
2016-02-01 22:55:43 +01:00
}
};
// Signed 32/64-bit integer entry with custom Min/Max range.
2017-05-20 13:45:02 +02:00
template <s64 Min, s64 Max>
class _int final : public _base
2016-02-01 22:55:43 +01:00
{
2017-05-20 13:45:02 +02:00
static_assert(Min < Max, "Invalid cfg::_int range");
2016-02-01 22:55:43 +01:00
// Prefer 32 bit type if possible
using int_type = std::conditional_t<Min >= INT32_MIN && Max <= INT32_MAX, s32, s64>;
2017-05-20 13:45:02 +02:00
int_type m_value;
2016-02-01 22:55:43 +01:00
public:
[Qt/Input] Improve pad_settings_dialog a bit (#3611) * Input: further work on remapping Xinput and begin work on remapping DS4 * Input: Improve pad_settings_dialog a bit and begin Remapping for XInput * Input: begin evdev remapping and change all handlers to use cfg::string * Input: finish work on remapping evdev and some more crap * Input: finish work on remapping Xinput and DS4 * Input: add DS4 Colors to DS4 config * Input: Improve DS4 deadzone scaling Jarves made some mistakes, so I'll fix them in the follow up commit * Input: fix Jarves fixes on DS4 deadzone and remove unnecessary usage of toUtf8 * Input: add primitive batterychecks to XInput and DS4 * Input: add mmjoystick remapping * Input: Fix evdev and some Vibration issues * Input: adjust capabilities to fix stick input for games like LoS 2 also fix threshold slider minimum also add ps button to all the handlers * Input: Further evdev work based on danilaml code review and own debugging: Fixed path issue, <= 0 issue, some captures, const, axis with same codes. Adds a map to each device that differentiates negative and positive axis mappings. adjusted rest of the file to tabs (ListDevices and beginning of threadProc) * Input: use 20ms vibration update time for xbox one elite controllers. * Input: Fix return type of Clamp() * Input: Evdev Fix * Input: Evdev Optional GetNextButtonPress presumably better than the other * Input: review changes * Input: evdev: fix wrong index in axis handling move bindpadtodevice down to keep consistency between handlers and not get crazy * Input: evdev: fix expensive add_device in GetNextButtonPress * cleanup * Input: mmjoy: fix type * Input: evdev: final fixes * Input: evdev: exclude unnecessary buttons while mapping Xbox 360 or DS4 * Input: add deadzone preview by passing necessary values in callback use 0.5 of max value for threshold in pad dialog * Input: get rid of all-uppercase variables
2017-11-27 22:31:15 +01:00
int_type def;
2016-02-01 22:55:43 +01:00
2017-05-20 13:45:02 +02:00
_int(node* owner, const std::string& name, int_type def = std::min<int_type>(Max, std::max<int_type>(Min, 0)))
: _base(type::_int, owner, name)
2016-02-01 22:55:43 +01:00
, m_value(def)
, def(def)
{
}
operator int_type() const
{
2017-05-20 13:45:02 +02:00
return m_value;
2016-02-01 22:55:43 +01:00
}
2018-05-04 22:48:05 +02:00
int_type get() const
{
return m_value;
}
2016-02-01 22:55:43 +01:00
void from_default() override
{
m_value = def;
}
std::string to_string() const override
{
2017-05-20 13:45:02 +02:00
return std::to_string(m_value);
2016-02-01 22:55:43 +01:00
}
bool from_string(const std::string& value) override
{
s64 result;
if (try_to_int64(&result, value, Min, Max))
{
m_value = static_cast<int_type>(result);
return true;
}
return false;
}
2017-08-02 12:22:53 +02:00
[Qt/Input] Improve pad_settings_dialog a bit (#3611) * Input: further work on remapping Xinput and begin work on remapping DS4 * Input: Improve pad_settings_dialog a bit and begin Remapping for XInput * Input: begin evdev remapping and change all handlers to use cfg::string * Input: finish work on remapping evdev and some more crap * Input: finish work on remapping Xinput and DS4 * Input: add DS4 Colors to DS4 config * Input: Improve DS4 deadzone scaling Jarves made some mistakes, so I'll fix them in the follow up commit * Input: fix Jarves fixes on DS4 deadzone and remove unnecessary usage of toUtf8 * Input: add primitive batterychecks to XInput and DS4 * Input: add mmjoystick remapping * Input: Fix evdev and some Vibration issues * Input: adjust capabilities to fix stick input for games like LoS 2 also fix threshold slider minimum also add ps button to all the handlers * Input: Further evdev work based on danilaml code review and own debugging: Fixed path issue, <= 0 issue, some captures, const, axis with same codes. Adds a map to each device that differentiates negative and positive axis mappings. adjusted rest of the file to tabs (ListDevices and beginning of threadProc) * Input: use 20ms vibration update time for xbox one elite controllers. * Input: Fix return type of Clamp() * Input: Evdev Fix * Input: Evdev Optional GetNextButtonPress presumably better than the other * Input: review changes * Input: evdev: fix wrong index in axis handling move bindpadtodevice down to keep consistency between handlers and not get crazy * Input: evdev: fix expensive add_device in GetNextButtonPress * cleanup * Input: mmjoy: fix type * Input: evdev: final fixes * Input: evdev: exclude unnecessary buttons while mapping Xbox 360 or DS4 * Input: add deadzone preview by passing necessary values in callback use 0.5 of max value for threshold in pad dialog * Input: get rid of all-uppercase variables
2017-11-27 22:31:15 +01:00
void set(const s64& value)
{
m_value = static_cast<int_type>(value);
}
2017-08-02 12:22:53 +02:00
std::vector<std::string> to_list() const override
{
return make_int_range(Min, Max);
}
2016-02-01 22:55:43 +01:00
};
// Alias for 32 bit int
2017-05-20 13:45:02 +02:00
using int32 = _int<INT32_MIN, INT32_MAX>;
2016-02-01 22:55:43 +01:00
// Alias for 64 bit int
2017-05-20 13:45:02 +02:00
using int64 = _int<INT64_MIN, INT64_MAX>;
2016-02-01 22:55:43 +01:00
// Simple string entry with mutex
2017-05-20 13:45:02 +02:00
class string final : public _base
2016-02-01 22:55:43 +01:00
{
std::string m_value;
public:
[Qt/Input] Improve pad_settings_dialog a bit (#3611) * Input: further work on remapping Xinput and begin work on remapping DS4 * Input: Improve pad_settings_dialog a bit and begin Remapping for XInput * Input: begin evdev remapping and change all handlers to use cfg::string * Input: finish work on remapping evdev and some more crap * Input: finish work on remapping Xinput and DS4 * Input: add DS4 Colors to DS4 config * Input: Improve DS4 deadzone scaling Jarves made some mistakes, so I'll fix them in the follow up commit * Input: fix Jarves fixes on DS4 deadzone and remove unnecessary usage of toUtf8 * Input: add primitive batterychecks to XInput and DS4 * Input: add mmjoystick remapping * Input: Fix evdev and some Vibration issues * Input: adjust capabilities to fix stick input for games like LoS 2 also fix threshold slider minimum also add ps button to all the handlers * Input: Further evdev work based on danilaml code review and own debugging: Fixed path issue, <= 0 issue, some captures, const, axis with same codes. Adds a map to each device that differentiates negative and positive axis mappings. adjusted rest of the file to tabs (ListDevices and beginning of threadProc) * Input: use 20ms vibration update time for xbox one elite controllers. * Input: Fix return type of Clamp() * Input: Evdev Fix * Input: Evdev Optional GetNextButtonPress presumably better than the other * Input: review changes * Input: evdev: fix wrong index in axis handling move bindpadtodevice down to keep consistency between handlers and not get crazy * Input: evdev: fix expensive add_device in GetNextButtonPress * cleanup * Input: mmjoy: fix type * Input: evdev: final fixes * Input: evdev: exclude unnecessary buttons while mapping Xbox 360 or DS4 * Input: add deadzone preview by passing necessary values in callback use 0.5 of max value for threshold in pad dialog * Input: get rid of all-uppercase variables
2017-11-27 22:31:15 +01:00
std::string def;
2016-02-01 22:55:43 +01:00
2017-05-20 13:45:02 +02:00
string(node* owner, const std::string& name, const std::string& def = {})
: _base(type::string, owner, name)
2016-02-01 22:55:43 +01:00
, m_value(def)
, def(def)
{
}
operator std::string() const
{
return m_value;
}
2017-05-20 13:45:02 +02:00
const std::string& get() const
2016-02-01 22:55:43 +01:00
{
2017-05-20 13:45:02 +02:00
return m_value;
2016-02-01 22:55:43 +01:00
}
std::size_t size() const
{
return m_value.size();
}
2017-01-25 00:22:19 +01:00
void from_default() override;
2016-02-01 22:55:43 +01:00
std::string to_string() const override
{
return m_value;
}
bool from_string(const std::string& value) override
{
2017-05-20 13:45:02 +02:00
m_value = value;
2016-02-01 22:55:43 +01:00
return true;
}
};
// Simple set entry with mutex (TODO: template for various types)
2017-05-20 13:45:02 +02:00
class set_entry final : public _base
2016-02-01 22:55:43 +01:00
{
std::set<std::string> m_set;
public:
// Default value is empty list in current implementation
2017-05-20 13:45:02 +02:00
set_entry(node* owner, const std::string& name)
: _base(type::set, owner, name)
2016-02-01 22:55:43 +01:00
{
}
std::set<std::string> get_set() const
{
return m_set;
}
void set_set(std::set<std::string>&& set)
{
m_set = std::move(set);
}
2017-01-25 00:22:19 +01:00
void from_default() override;
2016-02-01 22:55:43 +01:00
std::vector<std::string> to_list() const override
{
return{ m_set.begin(), m_set.end() };
}
bool from_list(std::vector<std::string>&& list) override
{
m_set = { std::make_move_iterator(list.begin()), std::make_move_iterator(list.end()) };
return true;
}
};
2017-05-20 13:45:02 +02:00
class log_entry final : public _base
2017-05-13 20:30:37 +02:00
{
std::map<std::string, logs::level> m_map;
public:
2017-05-20 13:45:02 +02:00
log_entry(node* owner, const std::string& name)
: _base(type::log, owner, name)
2017-05-13 20:30:37 +02:00
{
}
std::map<std::string, logs::level> get_map() const
{
return m_map;
}
void set_map(std::map<std::string, logs::level>&& map);
void from_default() override;
};
2016-02-01 22:55:43 +01:00
}