diff --git a/DDrawCompat/Config/Config.cpp b/DDrawCompat/Config/Config.cpp index 6df8fdd..08fe19b 100644 --- a/DDrawCompat/Config/Config.cpp +++ b/DDrawCompat/Config/Config.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -73,6 +74,7 @@ namespace Config Settings::SpriteDetection spriteDetection; Settings::SpriteFilter spriteFilter; Settings::SpriteTexCoord spriteTexCoord; + Settings::StatsColumns statsColumns; Settings::StatsHotKey statsHotKey; Settings::SupportedResolutions supportedResolutions; Settings::SupportedDepthFormats supportedDepthFormats; diff --git a/DDrawCompat/Config/EnumListSetting.cpp b/DDrawCompat/Config/EnumListSetting.cpp new file mode 100644 index 0000000..c067f8c --- /dev/null +++ b/DDrawCompat/Config/EnumListSetting.cpp @@ -0,0 +1,47 @@ +#include +#include + +namespace Config +{ + EnumListSetting::EnumListSetting(const std::string& name, const std::string& default, + const std::vector& enumNames) + : ListSetting(name, default) + , m_enumNames(enumNames) + { + } + + std::string EnumListSetting::getValueStr() const + { + std::string result; + for (auto value : m_values) + { + result += ", " + m_enumNames[value]; + } + return result.substr(2); + } + + void EnumListSetting::setValues(const std::vector& values) + { + if (values.empty()) + { + throw ParsingError("empty list is not allowed"); + } + + std::vector result; + for (auto valueName : values) + { + auto it = std::find(m_enumNames.begin(), m_enumNames.end(), valueName); + if (it == m_enumNames.end()) + { + throw ParsingError("invalid value: '" + valueName + "'"); + } + + unsigned value = it - m_enumNames.begin(); + if (std::find(result.begin(), result.end(), value) == result.end()) + { + result.push_back(value); + } + } + m_values = result; + } +} diff --git a/DDrawCompat/Config/EnumListSetting.h b/DDrawCompat/Config/EnumListSetting.h new file mode 100644 index 0000000..b02fcc9 --- /dev/null +++ b/DDrawCompat/Config/EnumListSetting.h @@ -0,0 +1,24 @@ +#pragma once + +#include + +#include + +namespace Config +{ + class EnumListSetting : public ListSetting + { + public: + EnumListSetting(const std::string& name, const std::string& default, const std::vector& enumNames); + + virtual std::string getValueStr() const override; + + const std::vector& get() const { return m_values; } + + private: + void setValues(const std::vector& values) override; + + const std::vector m_enumNames; + std::vector m_values; + }; +} diff --git a/DDrawCompat/Config/Settings/StatsColumns.h b/DDrawCompat/Config/Settings/StatsColumns.h new file mode 100644 index 0000000..436d8ef --- /dev/null +++ b/DDrawCompat/Config/Settings/StatsColumns.h @@ -0,0 +1,22 @@ +#pragma once + +#include + +namespace Config +{ + namespace Settings + { + class StatsColumns : public EnumListSetting + { + public: + enum Column { CUR, AVG, MIN, MAX, LABEL }; + + StatsColumns() + : EnumListSetting("StatsColumns", "label, cur, avg, min, max", { "cur", "avg", "min", "max", "label"}) + { + } + }; + } + + extern Settings::StatsColumns statsColumns; +} diff --git a/DDrawCompat/DDrawCompat.vcxproj b/DDrawCompat/DDrawCompat.vcxproj index 5337b6a..55bea6f 100644 --- a/DDrawCompat/DDrawCompat.vcxproj +++ b/DDrawCompat/DDrawCompat.vcxproj @@ -153,6 +153,7 @@ + @@ -191,6 +192,7 @@ + @@ -328,6 +330,7 @@ + diff --git a/DDrawCompat/DDrawCompat.vcxproj.filters b/DDrawCompat/DDrawCompat.vcxproj.filters index c1b9582..c649937 100644 --- a/DDrawCompat/DDrawCompat.vcxproj.filters +++ b/DDrawCompat/DDrawCompat.vcxproj.filters @@ -666,6 +666,12 @@ Header Files\Config\Settings + + Header Files\Config\Settings + + + Header Files\Config + @@ -1055,6 +1061,9 @@ Source Files\Config\Settings + + Source Files\Config + diff --git a/DDrawCompat/Overlay/StatsControl.cpp b/DDrawCompat/Overlay/StatsControl.cpp index 151a874..250f858 100644 --- a/DDrawCompat/Overlay/StatsControl.cpp +++ b/DDrawCompat/Overlay/StatsControl.cpp @@ -1,30 +1,69 @@ +#include #include #include +namespace +{ + const int NAME_LABEL_WIDTH = 70; + const int VALUE_LABEL_WIDTH = 40; +} + namespace Overlay { StatsControl::StatsControl(StatsWindow& parent, const RECT& rect, const std::string& caption, UpdateFunc updateFunc, DWORD style) : Control(&parent, rect, style) - , m_captionLabel(*this, { rect.left, rect.top, - rect.left + NAME_LABEL_WIDTH, rect.bottom }, caption, 0, WS_DISABLED | WS_VISIBLE) - , m_curLabel(*this, { m_captionLabel.getRect().right, rect.top, - m_captionLabel.getRect().right + VALUE_LABEL_WIDTH, rect.bottom}, std::string(), DT_RIGHT) - , m_avgLabel(*this, { m_curLabel.getRect().right, rect.top, - m_curLabel.getRect().right + VALUE_LABEL_WIDTH, rect.bottom }, std::string(), DT_RIGHT) - , m_minLabel(*this, { m_avgLabel.getRect().right, rect.top, - m_avgLabel.getRect().right + VALUE_LABEL_WIDTH, rect.bottom }, std::string(), DT_RIGHT) - , m_maxLabel(*this, { m_minLabel.getRect().right, rect.top, - m_minLabel.getRect().right + VALUE_LABEL_WIDTH, rect.bottom }, std::string(), DT_RIGHT) , m_updateFunc(updateFunc) { + auto& columns = Config::statsColumns.get(); + RECT r = rect; + for (unsigned i = 0; i < columns.size(); ++i) + { + r.right = r.left + getColumnWidth(i); + if (Config::Settings::StatsColumns::LABEL == columns[i]) + { + m_labels.emplace_back(*this, r, caption, 0, WS_DISABLED | WS_VISIBLE); + } + else + { + m_labels.emplace_back(*this, r, std::string(), DT_RIGHT); + } + r.left = r.right; + } + } + + int StatsControl::getColumnWidth(unsigned index) + { + auto& columns = Config::statsColumns.get(); + if (index >= columns.size()) + { + return 0; + } + return Config::Settings::StatsColumns::LABEL == columns[index] ? NAME_LABEL_WIDTH : VALUE_LABEL_WIDTH; + } + + int StatsControl::getWidth() + { + int width = 0; + auto& columns = Config::statsColumns.get(); + for (unsigned i = 0; i < columns.size(); ++i) + { + width += getColumnWidth(i); + } + return width; } void StatsControl::update(StatsQueue::TickCount tickCount) { auto stats = m_updateFunc(tickCount); - m_curLabel.setLabel(stats[0]); - m_avgLabel.setLabel(stats[1]); - m_minLabel.setLabel(stats[2]); - m_maxLabel.setLabel(stats[3]); + auto& columns = Config::statsColumns.get(); + auto label = m_labels.begin(); + for (unsigned i = 0; i < columns.size(); ++i) + { + if (Config::Settings::StatsColumns::LABEL != columns[i]) + { + label->setLabel(stats[columns[i]]); + } + ++label; + } } } diff --git a/DDrawCompat/Overlay/StatsControl.h b/DDrawCompat/Overlay/StatsControl.h index 9f07460..7d95002 100644 --- a/DDrawCompat/Overlay/StatsControl.h +++ b/DDrawCompat/Overlay/StatsControl.h @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -13,21 +14,17 @@ namespace Overlay class StatsControl : public Control { public: - static const int NAME_LABEL_WIDTH = 70; - static const int VALUE_LABEL_WIDTH = 40; - typedef std::function(StatsQueue::TickCount)> UpdateFunc; StatsControl(StatsWindow& parent, const RECT& rect, const std::string& caption, UpdateFunc updateFunc, DWORD style); void update(StatsQueue::TickCount tickCount); + static int getColumnWidth(unsigned index); + static int getWidth(); + private: - LabelControl m_captionLabel; - LabelControl m_curLabel; - LabelControl m_avgLabel; - LabelControl m_minLabel; - LabelControl m_maxLabel; + std::list m_labels; UpdateFunc m_updateFunc; }; } diff --git a/DDrawCompat/Overlay/StatsWindow.cpp b/DDrawCompat/Overlay/StatsWindow.cpp index b3442d3..ea515d7 100644 --- a/DDrawCompat/Overlay/StatsWindow.cpp +++ b/DDrawCompat/Overlay/StatsWindow.cpp @@ -66,8 +66,7 @@ namespace namespace Overlay { StatsWindow::StatsWindow() - : Window(nullptr, { 0, 0, StatsControl::NAME_LABEL_WIDTH + 4 * StatsControl::VALUE_LABEL_WIDTH, 105 + BORDER }, - 0, Config::statsHotKey.get()) + : Window(nullptr, { 0, 0, StatsControl::getWidth(), 105 + BORDER}, 0, Config::statsHotKey.get()) { addControl("", [](StatsQueue::TickCount) { return std::array{ "cur", "avg", "min", "max" }; }, WS_VISIBLE | WS_DISABLED).update(0);