1
0
mirror of https://github.com/narzoul/DDrawCompat synced 2024-12-30 08:55:36 +01:00

Added StatsRows=debug setting

This commit is contained in:
narzoul 2023-07-16 18:09:24 +02:00
parent df0b071ddf
commit f8fe000ac6
13 changed files with 102 additions and 26 deletions

View File

@ -27,7 +27,7 @@ namespace Config
throw ParsingError("empty list is not allowed"); throw ParsingError("empty list is not allowed");
} }
std::vector<unsigned> result; std::vector<int> result;
for (auto valueName : values) for (auto valueName : values)
{ {
auto it = std::find(m_enumNames.begin(), m_enumNames.end(), valueName); auto it = std::find(m_enumNames.begin(), m_enumNames.end(), valueName);
@ -36,7 +36,7 @@ namespace Config
throw ParsingError("invalid value: '" + valueName + "'"); throw ParsingError("invalid value: '" + valueName + "'");
} }
unsigned value = it - m_enumNames.begin(); int value = it - m_enumNames.begin();
if (std::find(result.begin(), result.end(), value) == result.end()) if (std::find(result.begin(), result.end(), value) == result.end())
{ {
result.push_back(value); result.push_back(value);

View File

@ -13,12 +13,12 @@ namespace Config
virtual std::string getValueStr() const override; virtual std::string getValueStr() const override;
const std::vector<unsigned>& get() const { return m_values; } const std::vector<int>& get() const { return m_values; }
private: private:
void setValues(const std::vector<std::string>& values) override; void setValues(const std::vector<std::string>& values) override;
const std::vector<std::string> m_enumNames; const std::vector<std::string> m_enumNames;
std::vector<unsigned> m_values; std::vector<int> m_values;
}; };
} }

View File

@ -24,7 +24,8 @@ namespace Config
LOCKRATE, LOCKRATE,
LOCKTIME, LOCKTIME,
DDIUSAGE, DDIUSAGE,
GDIOBJECTS GDIOBJECTS,
DEBUG
}; };
StatsRows() StatsRows()
@ -44,7 +45,8 @@ namespace Config
"lockrate", "lockrate",
"locktime", "locktime",
"ddiusage", "ddiusage",
"gdiobjects" "gdiobjects",
"debug"
}) })
{ {
} }

View File

@ -352,6 +352,7 @@ namespace
{ {
if (!isOverlayOnly) if (!isOverlayOnly)
{ {
statsWindow->m_presentCount++;
statsWindow->m_present.add(); statsWindow->m_present.add();
} }
statsWindow->update(); statsWindow->update();

View File

@ -7,7 +7,7 @@ namespace Overlay
ButtonControl::ButtonControl(Control& parent, const RECT& rect, const std::string& label, ClickHandler clickHandler) ButtonControl::ButtonControl(Control& parent, const RECT& rect, const std::string& label, ClickHandler clickHandler)
: Control(&parent, rect, WS_BORDER | WS_TABSTOP | WS_VISIBLE) : Control(&parent, rect, WS_BORDER | WS_TABSTOP | WS_VISIBLE)
, m_clickHandler(clickHandler) , m_clickHandler(clickHandler)
, m_label(*this, rect, label, DT_CENTER) , m_label(*this, rect, label, TA_CENTER)
{ {
} }

View File

@ -6,25 +6,22 @@ namespace Overlay
{ {
ComboBoxControl::ComboBoxControl(Control& parent, const RECT& rect, const std::vector<std::string>& values) ComboBoxControl::ComboBoxControl(Control& parent, const RECT& rect, const std::vector<std::string>& values)
: Control(&parent, rect, WS_BORDER | WS_VISIBLE) : Control(&parent, rect, WS_BORDER | WS_VISIBLE)
, m_label(*this, { rect.left, rect.top, rect.right - ARROW_SIZE, rect.bottom }, std::string(), 0)
, m_dropDown(*this, values) , m_dropDown(*this, values)
{ {
} }
void ComboBoxControl::setValue(const std::string& value) void ComboBoxControl::setValue(const std::string& value)
{ {
m_value = value; m_label.setLabel(value);
m_dropDown.select(value); m_dropDown.select(value);
invalidate();
} }
void ComboBoxControl::draw(HDC dc) void ComboBoxControl::draw(HDC dc)
{ {
RECT rect = m_rect; RECT rect = m_rect;
rect.left = m_rect.right - 17; rect.left = m_label.getRect().right;
drawArrow(dc, rect, DFCS_SCROLLDOWN); drawArrow(dc, rect, DFCS_SCROLLDOWN);
rect.left = m_rect.left + BORDER;
CALL_ORIG_FUNC(DrawTextA)(dc, m_value.c_str(), m_value.size(), &rect, DT_NOCLIP | DT_SINGLELINE | DT_VCENTER);
} }
void ComboBoxControl::onLButtonDown(POINT /*pos*/) void ComboBoxControl::onLButtonDown(POINT /*pos*/)

View File

@ -5,6 +5,7 @@
#include <Overlay/ComboBoxDropDown.h> #include <Overlay/ComboBoxDropDown.h>
#include <Overlay/Control.h> #include <Overlay/Control.h>
#include <Overlay/LabelControl.h>
namespace Overlay namespace Overlay
{ {
@ -13,14 +14,14 @@ namespace Overlay
public: public:
ComboBoxControl(Control& parent, const RECT& rect, const std::vector<std::string>& values); ComboBoxControl(Control& parent, const RECT& rect, const std::vector<std::string>& values);
std::string getValue() const { return m_value; } const std::string& getValue() const { return m_label.getLabel(); }
void setValue(const std::string& value); void setValue(const std::string& value);
private: private:
virtual void draw(HDC dc) override; virtual void draw(HDC dc) override;
virtual void onLButtonDown(POINT pos) override; virtual void onLButtonDown(POINT pos) override;
std::string m_value; LabelControl m_label;
ComboBoxDropDown m_dropDown; ComboBoxDropDown m_dropDown;
}; };
} }

View File

@ -17,7 +17,7 @@ namespace Overlay
{ {
m_labels.emplace_back(*this, m_labels.emplace_back(*this,
RECT{ 2, i * ARROW_SIZE + 2, m_rect.right - m_rect.left - 2, (i + 1) * ARROW_SIZE + 2 }, RECT{ 2, i * ARROW_SIZE + 2, m_rect.right - m_rect.left - 2, (i + 1) * ARROW_SIZE + 2 },
values[i], DT_SINGLELINE | DT_VCENTER, WS_VISIBLE | WS_TABSTOP); values[i], TA_LEFT, WS_VISIBLE | WS_TABSTOP);
} }
} }

View File

@ -3,20 +3,39 @@
namespace Overlay namespace Overlay
{ {
LabelControl::LabelControl(Control& parent, const RECT& rect, const std::string& label, UINT format, DWORD style) LabelControl::LabelControl(Control& parent, const RECT& rect, const std::string& label, UINT align, DWORD style)
: Control(&parent, rect, style) : Control(&parent, rect, style)
, m_label(label) , m_label(label)
, m_format(format) , m_wlabel(label.begin(), label.end())
, m_align(align)
, m_color(FOREGROUND_COLOR) , m_color(FOREGROUND_COLOR)
{ {
} }
void LabelControl::draw(HDC dc) void LabelControl::draw(HDC dc)
{ {
RECT r = { m_rect.left + BORDER, m_rect.top, m_rect.right - BORDER, m_rect.bottom }; LONG x = 0;
const LONG y = (m_rect.top + m_rect.bottom) / 2 - 7;
switch (m_align)
{
case TA_LEFT:
x = m_rect.left + BORDER;
break;
case TA_CENTER:
x = (m_rect.left + m_rect.right) / 2;
break;
case TA_RIGHT:
x = m_rect.right - BORDER;
break;
default:
return;
}
auto prevColor = SetTextColor(dc, (FOREGROUND_COLOR == m_color && !isEnabled()) ? DISABLED_COLOR : m_color ); auto prevColor = SetTextColor(dc, (FOREGROUND_COLOR == m_color && !isEnabled()) ? DISABLED_COLOR : m_color );
CALL_ORIG_FUNC(DrawTextA)(dc, m_label.c_str(), m_label.size(), &r, auto prevTextAlign = SetTextAlign(dc, m_align);
m_format | DT_NOCLIP | DT_SINGLELINE | DT_VCENTER); CALL_ORIG_FUNC(ExtTextOutW)(dc, x, y, ETO_IGNORELANGUAGE, nullptr, m_wlabel.c_str(), m_wlabel.length(), nullptr);
SetTextAlign(dc, prevTextAlign);
SetTextColor(dc, prevColor); SetTextColor(dc, prevColor);
} }
@ -39,6 +58,7 @@ namespace Overlay
if (m_label != label) if (m_label != label)
{ {
m_label = label; m_label = label;
m_wlabel.assign(label.begin(), label.end());
invalidate(); invalidate();
} }
} }

View File

@ -23,7 +23,8 @@ namespace Overlay
virtual void draw(HDC dc) override; virtual void draw(HDC dc) override;
std::string m_label; std::string m_label;
UINT m_format; std::wstring m_wlabel;
UINT m_align;
COLORREF m_color; COLORREF m_color;
}; };
} }

View File

@ -14,8 +14,15 @@ namespace Overlay
: Control(&parent, rect, style) : Control(&parent, rect, style)
, m_updateFunc(updateFunc) , m_updateFunc(updateFunc)
{ {
if (style & WS_GROUP)
{
m_labels.emplace_back(*this, rect, std::string(), TA_RIGHT);
return;
}
auto& columns = Config::statsColumns.get(); auto& columns = Config::statsColumns.get();
RECT r = rect; RECT r = rect;
r.left += (r.right - r.left) - getWidth();
for (unsigned i = 0; i < columns.size(); ++i) for (unsigned i = 0; i < columns.size(); ++i)
{ {
r.right = r.left + getColumnWidth(i); r.right = r.left + getColumnWidth(i);
@ -25,7 +32,7 @@ namespace Overlay
} }
else else
{ {
m_labels.emplace_back(*this, r, std::string(), DT_RIGHT); m_labels.emplace_back(*this, r, std::string(), TA_RIGHT);
} }
r.left = r.right; r.left = r.right;
} }
@ -55,6 +62,12 @@ namespace Overlay
void StatsControl::update(StatsQueue::TickCount tickCount) void StatsControl::update(StatsQueue::TickCount tickCount)
{ {
auto stats = m_updateFunc(tickCount); auto stats = m_updateFunc(tickCount);
if (m_style & WS_GROUP)
{
m_labels.front().setLabel(stats[0]);
return;
}
auto& columns = Config::statsColumns.get(); auto& columns = Config::statsColumns.get();
auto label = m_labels.begin(); auto label = m_labels.begin();
for (unsigned i = 0; i < columns.size(); ++i) for (unsigned i = 0; i < columns.size(); ++i)

View File

@ -1,6 +1,8 @@
#include <algorithm>
#include <array> #include <array>
#include <functional> #include <functional>
#include <Common/Log.h>
#include <Common/Time.h> #include <Common/Time.h>
#include <Config/Settings/StatsHotKey.h> #include <Config/Settings/StatsHotKey.h>
#include <Config/Settings/StatsPosX.h> #include <Config/Settings/StatsPosX.h>
@ -47,11 +49,11 @@ namespace
char buf[20] = {}; char buf[20] = {};
if (0 == unitIndex) if (0 == unitIndex)
{ {
snprintf(buf, sizeof(buf), "%.0f", stat); sprintf_s(buf, "%.0f", stat);
return buf; return buf;
} }
auto len = snprintf(buf, sizeof(buf), "%.2f", stat); auto len = sprintf_s(buf, "%.2f", stat);
const auto decimalPoint = strchr(buf, '.'); const auto decimalPoint = strchr(buf, '.');
const auto intLen = decimalPoint ? decimalPoint - buf : len; const auto intLen = decimalPoint ? decimalPoint - buf : len;
if (len > 4) if (len > 4)
@ -67,14 +69,31 @@ namespace
}; };
const int ROW_HEIGHT = 15; const int ROW_HEIGHT = 15;
std::array<std::string, 4> getDebugInfo(StatsQueue::TickCount /*tickCount*/)
{
const uint32_t presentCount = Gdi::GuiThread::getStatsWindow()->m_presentCount;
static uint32_t updateCount = 0;
++updateCount;
SYSTEMTIME st = {};
GetLocalTime(&st);
LOG_DEBUG << "Stats debuginfo: " << presentCount << " " << updateCount;
char debuginfo[60];
sprintf_s(debuginfo, "%u %u %02hu:%02hu:%02hu.%03hu", presentCount, updateCount,
st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
return { debuginfo };
}
} }
namespace Overlay namespace Overlay
{ {
StatsWindow::StatsWindow() StatsWindow::StatsWindow()
: Window(nullptr, : Window(nullptr,
{ 0, 0, StatsControl::getWidth(), static_cast<int>(Config::statsRows.get().size()) * ROW_HEIGHT + BORDER }, { 0, 0, getWidth(), static_cast<int>(Config::statsRows.get().size()) * ROW_HEIGHT + BORDER },
0, Config::statsTransparency.get(), Config::statsHotKey.get()) 0, Config::statsTransparency.get(), Config::statsHotKey.get())
, m_presentCount(0)
{ {
m_statsRows.push_back({ "", [](auto) { return std::array<std::string, 4>{ "cur", "avg", "min", "max" }; }, m_statsRows.push_back({ "", [](auto) { return std::array<std::string, 4>{ "cur", "avg", "min", "max" }; },
WS_VISIBLE | WS_DISABLED }); WS_VISIBLE | WS_DISABLED });
@ -92,6 +111,7 @@ namespace Overlay
m_statsRows.push_back({ "Lock time", UpdateStats(m_lock.m_time) }); m_statsRows.push_back({ "Lock time", UpdateStats(m_lock.m_time) });
m_statsRows.push_back({ "DDI usage", UpdateStats(m_ddiUsage) }); m_statsRows.push_back({ "DDI usage", UpdateStats(m_ddiUsage) });
m_statsRows.push_back({ "GDI objects", UpdateStats(m_gdiObjects) }); m_statsRows.push_back({ "GDI objects", UpdateStats(m_gdiObjects) });
m_statsRows.push_back({ "", &getDebugInfo, WS_VISIBLE | WS_GROUP });
for (auto statsRowIndex : Config::statsRows.get()) for (auto statsRowIndex : Config::statsRows.get())
{ {
@ -126,12 +146,30 @@ namespace Overlay
return (configWindow && configWindow->isVisible()) ? configWindow->getWindow() : Window::getTopmost(); return (configWindow && configWindow->isVisible()) ? configWindow->getWindow() : Window::getTopmost();
} }
LONG StatsWindow::getWidth()
{
LONG width = StatsControl::getWidth();
const auto& statsRows = Config::statsRows.get();
if (std::find(statsRows.begin(), statsRows.end(), Config::Settings::StatsRows::DEBUG) != statsRows.end())
{
width = std::max(width, 140L);
}
return width;
}
void StatsWindow::updateStats() void StatsWindow::updateStats()
{ {
static auto prevTickCount = StatsQueue::getTickCount() - 1; static auto prevTickCount = StatsQueue::getTickCount() - 1;
m_tickCount = StatsQueue::getTickCount(); m_tickCount = StatsQueue::getTickCount();
if (m_tickCount == prevTickCount) if (m_tickCount == prevTickCount)
{ {
for (auto& statsControl : m_statsControls)
{
if (statsControl.getStyle() & WS_GROUP)
{
statsControl.update(m_tickCount);
}
}
return; return;
} }

View File

@ -20,6 +20,7 @@ namespace Overlay
void updateStats(); void updateStats();
uint32_t m_presentCount;
StatsEventGroup m_present; StatsEventGroup m_present;
StatsEventGroup m_flip; StatsEventGroup m_flip;
StatsEventGroup m_blit; StatsEventGroup m_blit;
@ -40,6 +41,8 @@ namespace Overlay
virtual RECT calculateRect(const RECT& monitorRect) const override; virtual RECT calculateRect(const RECT& monitorRect) const override;
virtual HWND getTopmost() const override; virtual HWND getTopmost() const override;
static LONG getWidth();
std::list<StatsControl> m_statsControls; std::list<StatsControl> m_statsControls;
std::vector<StatsRow> m_statsRows; std::vector<StatsRow> m_statsRows;
uint64_t m_tickCount; uint64_t m_tickCount;