From d7948c4bddfa3d1ef50252a8ec4f134954361dcf Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Fri, 12 Aug 2016 19:15:25 -0600 Subject: [PATCH] light: move settings system to its own files --- include/light/light.hh | 330 +---------------------------------- include/light/settings.hh | 354 ++++++++++++++++++++++++++++++++++++++ light/CMakeLists.txt | 4 +- light/entities.cc | 23 --- light/settings.cc | 44 +++++ 5 files changed, 402 insertions(+), 353 deletions(-) create mode 100644 include/light/settings.hh create mode 100644 light/settings.cc diff --git a/include/light/light.hh b/include/light/light.hh index 61fc3505..95717ac5 100644 --- a/include/light/light.hh +++ b/include/light/light.hh @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -181,275 +182,6 @@ extern byte thepalette[768]; extern std::vector tracelist; extern std::vector selfshadowlist; -void vec_from_mangle(vec3_t v, const vec3_t m); - -/* detect colors with components in 0-1 and scale them to 0-255 */ -void normalize_color_format(vec3_t color); - -/* command-line options */ - -enum class setting_source_t { - DEFAULT = 0, - MAP = 1, - COMMANDLINE = 2 -}; - -class lockable_setting_t { -protected: - setting_source_t _source; - std::vector _names; - - lockable_setting_t(std::vector names) - : _source(setting_source_t::DEFAULT), _names(names) { - assert(_names.size() > 0); - } - - bool changeSource(setting_source_t newSource) { - if (static_cast(newSource) >= static_cast(_source)) { - _source = newSource; - return true; - } - return false; - } - -public: - const std::string &primaryName() const { return _names.at(0); } - const std::vector &names() const { return _names; } - - virtual void setStringValue(const std::string &str, bool locked = false) = 0; - virtual std::string stringValue() const = 0; - - bool isChanged() const { return _source != setting_source_t::DEFAULT; } - bool isLocked() const { return _source == setting_source_t::COMMANDLINE; } - - std::string sourceString() const { - switch (_source) { - case setting_source_t::DEFAULT: return "default"; - case setting_source_t::MAP: return "map"; - case setting_source_t::COMMANDLINE: return "commandline"; - } - } -}; - -class lockable_bool_t : public lockable_setting_t { -private: - bool _default, _value; - - void setBoolValueInternal(bool f, setting_source_t newsource) { - if (changeSource(newsource)) { - _value = f; - } - } - -public: - - void setBoolValueLocked(bool f) { - setBoolValueInternal(f, setting_source_t::COMMANDLINE); - } - - void setBoolValue(bool f) { - setBoolValueInternal(f, setting_source_t::MAP); - } - - bool boolValue() const { - return _value; - } - - virtual void setStringValue(const std::string &str, bool locked = false) { - int intval = std::stoi(str); - - const bool f = (intval != 0 && intval != -1); // treat 0 and -1 as false - if (locked) setBoolValueLocked(f); - else setBoolValue(f); - } - - virtual std::string stringValue() const { - return _value ? "1" : "0"; - } - - lockable_bool_t(std::vector names, bool v) - : lockable_setting_t(names), _default(v), _value(v) {} - - lockable_bool_t(std::string name, bool v) - : lockable_bool_t(std::vector { name }, v) {} -}; - -class lockable_vec_t : public lockable_setting_t { -private: - float _default, _value, _min, _max; - - void setFloatInternal(float f, setting_source_t newsource) { - if (changeSource(newsource)) { - if (f < _min) { - logprint("WARNING: '%s': %f is less than minimum value %f.\n", - primaryName().c_str(), f, _min); - f = _min; - } - if (f > _max) { - logprint("WARNING: '%s': %f is greater than maximum value %f.\n", - primaryName().c_str(), f, _max); - f = _max; - } - _value = f; - } - } - -public: - bool boolValue() const { - return static_cast(_value); - } - - int intValue() const { - return static_cast(_value); - } - - float floatValue() const { - return _value; - } - - void setFloatValue(float f) { - setFloatInternal(f, setting_source_t::MAP); - } - - void setFloatValueLocked(float f) { - setFloatInternal(f, setting_source_t::COMMANDLINE); - } - - virtual void setStringValue(const std::string &str, bool locked = false) { - const float f = std::stof(str); - if (locked) setFloatValueLocked(f); - else setFloatValue(f); - } - - virtual std::string stringValue() const { - return std::to_string(_value); - } - - lockable_vec_t(std::vector names, float v, - float minval=-std::numeric_limits::infinity(), - float maxval=std::numeric_limits::infinity()) - : lockable_setting_t(names), _default(v), _value(v), _min(minval), _max(maxval) { - // check the default value is valid - assert(_min < _max); - assert(_value >= _min); - assert(_value <= _max); - } - - lockable_vec_t(std::string name, float v, - float minval=-std::numeric_limits::infinity(), - float maxval=std::numeric_limits::infinity()) - : lockable_vec_t(std::vector { name }, v, minval, maxval) {} -}; - -class lockable_string_t : public lockable_setting_t { -private: - std::string _default, _value; - -public: - virtual void setStringValue(const std::string &str, bool locked = false) { - if (changeSource(locked ? setting_source_t::COMMANDLINE : setting_source_t::MAP)) { - _value = str; - } - } - - virtual std::string stringValue() const { - return _value; - } - - lockable_string_t(std::vector names, std::string v) - : lockable_setting_t(names), _default(v), _value(v) {} - - lockable_string_t(std::string name, std::string v) - : lockable_string_t(std::vector { name }, v) {} -}; - -enum class vec3_transformer_t { - NONE, - MANGLE_TO_VEC, - NORMALIZE_COLOR_TO_255 -}; - - -class lockable_vec3_t : public lockable_setting_t { -private: - vec3_t _default, _value; - vec3_transformer_t _transformer; - - void transformVec3Value(const vec3_t val, vec3_t out) const { - // apply transform - switch (_transformer) { - case vec3_transformer_t::NONE: - VectorCopy(val, out); - break; - case vec3_transformer_t::MANGLE_TO_VEC: - vec_from_mangle(out, val); - break; - case vec3_transformer_t::NORMALIZE_COLOR_TO_255: - VectorCopy(val, out); - normalize_color_format(out); - break; - } - } - - void transformAndSetVec3Value(const vec3_t val, setting_source_t newsource) { - if (changeSource(newsource)) { - vec3_t tmp; - transformVec3Value(val, tmp); - VectorCopy(tmp, _value); - } - } - -public: - lockable_vec3_t(std::vector names, vec_t a, vec_t b, vec_t c, - vec3_transformer_t t = vec3_transformer_t::NONE) - : lockable_setting_t(names), _transformer(t) - { - vec3_t tmp = { a, b, c }; - transformVec3Value(tmp, _default); - VectorCopy(_default, _value); - } - - lockable_vec3_t(std::string name, vec_t a, vec_t b, vec_t c, - vec3_transformer_t t = vec3_transformer_t::NONE) - : lockable_vec3_t(std::vector { name }, a,b,c,t) {} - - const vec3_t *vec3Value() const { - return &_value; - } - - void setVec3Value(const vec3_t val) { - transformAndSetVec3Value(val, setting_source_t::MAP); - } - - void setVec3ValueLocked(const vec3_t val) { - transformAndSetVec3Value(val, setting_source_t::COMMANDLINE); - } - - virtual void setStringValue(const std::string &str, bool locked = false) { - double vec[3] = { 0.0, 0.0, 0.0 }; - - if (sscanf(str.c_str(), "%lf %lf %lf", &vec[0], &vec[1], &vec[2]) != 3) { - logprint("WARNING: Not 3 values for %s\n", primaryName().c_str()); - } - - vec3_t vec3t; - for (int i = 0; i < 3; ++i) - vec3t[i] = vec[i]; - - if (locked) setVec3ValueLocked(vec3t); - else setVec3Value(vec3t); - } - - virtual std::string stringValue() const { - std::stringstream ss; - ss << _value[0] << " " - << _value[1] << " " - << _value[2]; - return ss.str(); - } -}; - - extern int numDirtVectors; // other flags @@ -468,66 +200,6 @@ extern bool dump_face; extern int dump_vertnum; extern bool dump_vert; -// settings dictionary - -class settingsdict_t { -private: - std::map _settingsmap; - std::vector _allsettings; - -public: - settingsdict_t() {} - - settingsdict_t(std::vector settings) - : _allsettings(settings) - { - for (lockable_setting_t *setting : settings) { - assert(setting->names().size() > 0); - - for (const auto &name : setting->names()) { - assert(_settingsmap.find(name) == _settingsmap.end()); - - _settingsmap[name] = setting; - } - } - } - - lockable_setting_t *findSetting(std::string name) const { - // strip off leading underscores - if (name.find("_") == 0) { - return findSetting(name.substr(1, name.size() - 1)); - } - - auto it = _settingsmap.find(name); - if (it != _settingsmap.end()) { - return it->second; - } else { - return nullptr; - } - } - - void setSetting(std::string name, std::string value, bool cmdline) { - lockable_setting_t *setting = findSetting(name); - if (setting == nullptr) { - if (cmdline) { - Error("Unrecognized command-line option '%s'\n", name.c_str()); - } - return; - } - - setting->setStringValue(value, cmdline); - } - - void setSettings(const std::map &epairs, bool cmdline) { - for (const auto &epair : epairs) { - setSetting(epair.first, epair.second, cmdline); - } - } - - const std::vector &allSettings() const { return _allsettings; } -}; - - class modelinfo_t { #define DEFAULT_PHONG_ANGLE 89.0f diff --git a/include/light/settings.hh b/include/light/settings.hh new file mode 100644 index 00000000..64dde0de --- /dev/null +++ b/include/light/settings.hh @@ -0,0 +1,354 @@ +/* Copyright (C) 2016 Eric Wasylishen + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + See file, 'COPYING', for details. + */ + +#ifndef __LIGHT_SETTINGS_H__ +#define __LIGHT_SETTINGS_H__ + +#include +#include + +#include +#include +#include +#include +#include + +enum class setting_source_t { + DEFAULT = 0, + MAP = 1, + COMMANDLINE = 2 +}; + +enum class vec3_transformer_t { + NONE, + MANGLE_TO_VEC, + NORMALIZE_COLOR_TO_255 +}; + +void vec_from_mangle(vec3_t v, const vec3_t m); +void normalize_color_format(vec3_t color); + +class lockable_setting_t { +protected: + setting_source_t _source; + std::vector _names; + + lockable_setting_t(std::vector names) + : _source(setting_source_t::DEFAULT), _names(names) { + assert(_names.size() > 0); + } + + bool changeSource(setting_source_t newSource) { + if (static_cast(newSource) >= static_cast(_source)) { + _source = newSource; + return true; + } + return false; + } + +public: + const std::string &primaryName() const { return _names.at(0); } + const std::vector &names() const { return _names; } + + virtual void setStringValue(const std::string &str, bool locked = false) = 0; + virtual std::string stringValue() const = 0; + + bool isChanged() const { return _source != setting_source_t::DEFAULT; } + bool isLocked() const { return _source == setting_source_t::COMMANDLINE; } + + std::string sourceString() const { + switch (_source) { + case setting_source_t::DEFAULT: return "default"; + case setting_source_t::MAP: return "map"; + case setting_source_t::COMMANDLINE: return "commandline"; + } + } +}; + +class lockable_bool_t : public lockable_setting_t { +private: + bool _default, _value; + + void setBoolValueInternal(bool f, setting_source_t newsource) { + if (changeSource(newsource)) { + _value = f; + } + } + +public: + + void setBoolValueLocked(bool f) { + setBoolValueInternal(f, setting_source_t::COMMANDLINE); + } + + void setBoolValue(bool f) { + setBoolValueInternal(f, setting_source_t::MAP); + } + + bool boolValue() const { + return _value; + } + + virtual void setStringValue(const std::string &str, bool locked = false) { + int intval = std::stoi(str); + + const bool f = (intval != 0 && intval != -1); // treat 0 and -1 as false + if (locked) setBoolValueLocked(f); + else setBoolValue(f); + } + + virtual std::string stringValue() const { + return _value ? "1" : "0"; + } + + lockable_bool_t(std::vector names, bool v) + : lockable_setting_t(names), _default(v), _value(v) {} + + lockable_bool_t(std::string name, bool v) + : lockable_bool_t(std::vector { name }, v) {} +}; + +class lockable_vec_t : public lockable_setting_t { +private: + float _default, _value, _min, _max; + + void setFloatInternal(float f, setting_source_t newsource) { + if (changeSource(newsource)) { + if (f < _min) { + logprint("WARNING: '%s': %f is less than minimum value %f.\n", + primaryName().c_str(), f, _min); + f = _min; + } + if (f > _max) { + logprint("WARNING: '%s': %f is greater than maximum value %f.\n", + primaryName().c_str(), f, _max); + f = _max; + } + _value = f; + } + } + +public: + bool boolValue() const { + return static_cast(_value); + } + + int intValue() const { + return static_cast(_value); + } + + float floatValue() const { + return _value; + } + + void setFloatValue(float f) { + setFloatInternal(f, setting_source_t::MAP); + } + + void setFloatValueLocked(float f) { + setFloatInternal(f, setting_source_t::COMMANDLINE); + } + + virtual void setStringValue(const std::string &str, bool locked = false) { + const float f = std::stof(str); + if (locked) setFloatValueLocked(f); + else setFloatValue(f); + } + + virtual std::string stringValue() const { + return std::to_string(_value); + } + + lockable_vec_t(std::vector names, float v, + float minval=-std::numeric_limits::infinity(), + float maxval=std::numeric_limits::infinity()) + : lockable_setting_t(names), _default(v), _value(v), _min(minval), _max(maxval) { + // check the default value is valid + assert(_min < _max); + assert(_value >= _min); + assert(_value <= _max); + } + + lockable_vec_t(std::string name, float v, + float minval=-std::numeric_limits::infinity(), + float maxval=std::numeric_limits::infinity()) + : lockable_vec_t(std::vector { name }, v, minval, maxval) {} +}; + +class lockable_string_t : public lockable_setting_t { +private: + std::string _default, _value; + +public: + virtual void setStringValue(const std::string &str, bool locked = false) { + if (changeSource(locked ? setting_source_t::COMMANDLINE : setting_source_t::MAP)) { + _value = str; + } + } + + virtual std::string stringValue() const { + return _value; + } + + lockable_string_t(std::vector names, std::string v) + : lockable_setting_t(names), _default(v), _value(v) {} + + lockable_string_t(std::string name, std::string v) + : lockable_string_t(std::vector { name }, v) {} +}; + +class lockable_vec3_t : public lockable_setting_t { +private: + vec3_t _default, _value; + vec3_transformer_t _transformer; + + void transformVec3Value(const vec3_t val, vec3_t out) const { + // apply transform + switch (_transformer) { + case vec3_transformer_t::NONE: + VectorCopy(val, out); + break; + case vec3_transformer_t::MANGLE_TO_VEC: + vec_from_mangle(out, val); + break; + case vec3_transformer_t::NORMALIZE_COLOR_TO_255: + VectorCopy(val, out); + normalize_color_format(out); + break; + } + } + + void transformAndSetVec3Value(const vec3_t val, setting_source_t newsource) { + if (changeSource(newsource)) { + vec3_t tmp; + transformVec3Value(val, tmp); + VectorCopy(tmp, _value); + } + } + +public: + lockable_vec3_t(std::vector names, vec_t a, vec_t b, vec_t c, + vec3_transformer_t t = vec3_transformer_t::NONE) + : lockable_setting_t(names), _transformer(t) + { + vec3_t tmp = { a, b, c }; + transformVec3Value(tmp, _default); + VectorCopy(_default, _value); + } + + lockable_vec3_t(std::string name, vec_t a, vec_t b, vec_t c, + vec3_transformer_t t = vec3_transformer_t::NONE) + : lockable_vec3_t(std::vector { name }, a,b,c,t) {} + + const vec3_t *vec3Value() const { + return &_value; + } + + void setVec3Value(const vec3_t val) { + transformAndSetVec3Value(val, setting_source_t::MAP); + } + + void setVec3ValueLocked(const vec3_t val) { + transformAndSetVec3Value(val, setting_source_t::COMMANDLINE); + } + + virtual void setStringValue(const std::string &str, bool locked = false) { + double vec[3] = { 0.0, 0.0, 0.0 }; + + if (sscanf(str.c_str(), "%lf %lf %lf", &vec[0], &vec[1], &vec[2]) != 3) { + logprint("WARNING: Not 3 values for %s\n", primaryName().c_str()); + } + + vec3_t vec3t; + for (int i = 0; i < 3; ++i) + vec3t[i] = vec[i]; + + if (locked) setVec3ValueLocked(vec3t); + else setVec3Value(vec3t); + } + + virtual std::string stringValue() const { + std::stringstream ss; + ss << _value[0] << " " + << _value[1] << " " + << _value[2]; + return ss.str(); + } +}; + +// settings dictionary + +class settingsdict_t { +private: + std::map _settingsmap; + std::vector _allsettings; + +public: + settingsdict_t() {} + + settingsdict_t(std::vector settings) + : _allsettings(settings) + { + for (lockable_setting_t *setting : settings) { + assert(setting->names().size() > 0); + + for (const auto &name : setting->names()) { + assert(_settingsmap.find(name) == _settingsmap.end()); + + _settingsmap[name] = setting; + } + } + } + + lockable_setting_t *findSetting(std::string name) const { + // strip off leading underscores + if (name.find("_") == 0) { + return findSetting(name.substr(1, name.size() - 1)); + } + + auto it = _settingsmap.find(name); + if (it != _settingsmap.end()) { + return it->second; + } else { + return nullptr; + } + } + + void setSetting(std::string name, std::string value, bool cmdline) { + lockable_setting_t *setting = findSetting(name); + if (setting == nullptr) { + if (cmdline) { + Error("Unrecognized command-line option '%s'\n", name.c_str()); + } + return; + } + + setting->setStringValue(value, cmdline); + } + + void setSettings(const std::map &epairs, bool cmdline) { + for (const auto &epair : epairs) { + setSetting(epair.first, epair.second, cmdline); + } + } + + const std::vector &allSettings() const { return _allsettings; } +}; + +#endif diff --git a/light/CMakeLists.txt b/light/CMakeLists.txt index 55a87ca8..1803cc4a 100644 --- a/light/CMakeLists.txt +++ b/light/CMakeLists.txt @@ -6,7 +6,8 @@ set(LIGHT_INCLUDES ${CMAKE_SOURCE_DIR}/include/light/light.hh ${CMAKE_SOURCE_DIR}/include/light/ltface.hh ${CMAKE_SOURCE_DIR}/include/light/trace.hh - ${CMAKE_SOURCE_DIR}/include/light/litfile.hh) + ${CMAKE_SOURCE_DIR}/include/light/litfile.hh + ${CMAKE_SOURCE_DIR}/include/light/settings.hh) set(LIGHT_SOURCES entities.cc @@ -14,6 +15,7 @@ set(LIGHT_SOURCES ltface.cc trace.cc light.cc + settings.cc ${CMAKE_SOURCE_DIR}/common/bspfile.c ${CMAKE_SOURCE_DIR}/common/cmdlib.c ${CMAKE_SOURCE_DIR}/common/mathlib.c diff --git a/light/entities.cc b/light/entities.cc index 60932bf2..fb8fc6d7 100644 --- a/light/entities.cc +++ b/light/entities.cc @@ -151,29 +151,6 @@ SetupSpotlights(void) } } -void -vec_from_mangle(vec3_t v, const vec3_t m) -{ - vec3_t tmp; - - VectorScale(m, Q_PI / 180, tmp); - v[0] = cos(tmp[0]) * cos(tmp[1]); - v[1] = sin(tmp[0]) * cos(tmp[1]); - v[2] = sin(tmp[1]); -} - -/* detect colors with components in 0-1 and scale them to 0-255 */ -void -normalize_color_format(vec3_t color) -{ - if (color[0] >= 0 && color[0] <= 1 && - color[1] >= 0 && color[1] <= 1 && - color[2] >= 0 && color[2] <= 1) - { - VectorScale(color, 255, color); - } -} - static void CheckEntityFields(const globalconfig_t &cfg, light_t *entity) { diff --git a/light/settings.cc b/light/settings.cc new file mode 100644 index 00000000..159840c9 --- /dev/null +++ b/light/settings.cc @@ -0,0 +1,44 @@ +/* Copyright (C) 1996-1997 Id Software, Inc. + Copyright (C) 2016 Eric Wasylishen + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + See file, 'COPYING', for details. + */ + +#include + +void +vec_from_mangle(vec3_t v, const vec3_t m) +{ + vec3_t tmp; + + VectorScale(m, Q_PI / 180, tmp); + v[0] = cos(tmp[0]) * cos(tmp[1]); + v[1] = sin(tmp[0]) * cos(tmp[1]); + v[2] = sin(tmp[1]); +} + +/* detect colors with components in 0-1 and scale them to 0-255 */ +void +normalize_color_format(vec3_t color) +{ + if (color[0] >= 0 && color[0] <= 1 && + color[1] >= 0 && color[1] <= 1 && + color[2] >= 0 && color[2] <= 1) + { + VectorScale(color, 255, color); + } +}