Implement an optional FPS counter (#850)
Shows a counter at the top of the screen, indicating the number of frames drawn per second, based on std::chrono.
This commit is contained in:
parent
6d5b481b61
commit
86de7364ac
|
@ -1,5 +1,6 @@
|
|||
21.03+ (???)
|
||||
------------------------------------------------------------------------
|
||||
- Feature: [#451] Optionally show an FPS counter at the top of the screen.
|
||||
- Fix: [#804] Enter key not confirming save prompt.
|
||||
- Fix: [#809] Audio calculation not using the z axis.
|
||||
- Fix: [#825] Potential crash when opening town rename prompt.
|
||||
|
|
|
@ -2213,3 +2213,5 @@ strings:
|
|||
2158: "Enable sandbox mode"
|
||||
2159: "Allow manual driving"
|
||||
2160: "Allow building while paused"
|
||||
2161: "Show FPS counter"
|
||||
2162: "{SMALLFONT}{COLOUR BLACK}This shows a counter at the top of the screen, indicating the number of frames drawn per second."
|
||||
|
|
|
@ -93,6 +93,8 @@ namespace OpenLoco::Config
|
|||
_new_config.autosave_frequency = config["autosave_frequency"].as<int32_t>();
|
||||
if (config["autosave_amount"])
|
||||
_new_config.autosave_amount = config["autosave_amount"].as<int32_t>();
|
||||
if (config["showFPS"])
|
||||
_new_config.showFPS = config["showFPS"].as<bool>();
|
||||
|
||||
return _new_config;
|
||||
}
|
||||
|
@ -141,6 +143,7 @@ namespace OpenLoco::Config
|
|||
node["zoom_to_cursor"] = _new_config.zoom_to_cursor;
|
||||
node["autosave_frequency"] = _new_config.autosave_frequency;
|
||||
node["autosave_amount"] = _new_config.autosave_amount;
|
||||
node["showFPS"] = _new_config.showFPS;
|
||||
|
||||
std::ofstream stream(configPath);
|
||||
if (stream.is_open())
|
||||
|
|
|
@ -156,6 +156,7 @@ namespace OpenLoco::Config
|
|||
bool zoom_to_cursor = true;
|
||||
int32_t autosave_frequency = 1;
|
||||
int32_t autosave_amount = 12;
|
||||
bool showFPS = false;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
#include "FPSCounter.h"
|
||||
#include "../Graphics/Colour.h"
|
||||
#include "../Graphics/Gfx.h"
|
||||
#include "../Localisation/StringManager.h"
|
||||
#include "../Ui.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace OpenLoco::Drawing
|
||||
{
|
||||
using Clock_t = std::chrono::high_resolution_clock;
|
||||
using TimePoint_t = Clock_t::time_point;
|
||||
|
||||
static TimePoint_t _referenceTime;
|
||||
static uint32_t _currentFrameCount;
|
||||
static float _currentFPS;
|
||||
|
||||
static float measureFPS()
|
||||
{
|
||||
_currentFrameCount++;
|
||||
|
||||
auto currentTime = Clock_t::now();
|
||||
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - _referenceTime).count() / 1000.0;
|
||||
|
||||
if (elapsed > 1.0)
|
||||
{
|
||||
_currentFPS = _currentFrameCount / elapsed;
|
||||
_currentFrameCount = 0;
|
||||
_referenceTime = currentTime;
|
||||
}
|
||||
|
||||
return _currentFPS;
|
||||
}
|
||||
|
||||
void drawFPS()
|
||||
{
|
||||
// Measure FPS
|
||||
const float fps = measureFPS();
|
||||
|
||||
// Format string
|
||||
char buffer[64];
|
||||
buffer[0] = ControlCodes::font_bold;
|
||||
buffer[1] = ControlCodes::outline;
|
||||
buffer[2] = ControlCodes::colour_white;
|
||||
|
||||
const char* formatString = (_currentFPS >= 10.0f ? "%.0f" : "%.1f");
|
||||
snprintf(&buffer[3], std::size(buffer) - 3, formatString, fps);
|
||||
|
||||
auto& dpi = Gfx::screenDpi();
|
||||
|
||||
// Draw text
|
||||
const int stringWidth = Gfx::getStringWidth(buffer);
|
||||
const auto x = Ui::width() / 2 - (stringWidth / 2);
|
||||
const auto y = 2;
|
||||
Gfx::drawString(&dpi, x, y, Colour::black, buffer);
|
||||
|
||||
// Make area dirty so the text doesn't get drawn over the last
|
||||
Gfx::setDirtyBlocks(x - 16, y - 4, x + 16, 16);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
namespace OpenLoco::Drawing
|
||||
{
|
||||
void drawFPS();
|
||||
}
|
|
@ -1500,4 +1500,6 @@ namespace OpenLoco::StringIds
|
|||
constexpr string_id cheat_enable_sandbox_mode = 2158;
|
||||
constexpr string_id cheat_allow_manual_driving = 2159;
|
||||
constexpr string_id cheat_allow_building_while_paused = 2160;
|
||||
constexpr string_id option_show_fps_counter = 2161;
|
||||
constexpr string_id option_show_fps_counter_tooltip = 2162;
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include "Config.h"
|
||||
#include "Console.h"
|
||||
#include "Drawing/FPSCounter.h"
|
||||
#include "GameCommands.h"
|
||||
#include "Graphics/Gfx.h"
|
||||
#include "Gui.h"
|
||||
|
@ -432,6 +433,12 @@ namespace OpenLoco::Ui
|
|||
}
|
||||
}
|
||||
|
||||
// Draw FPS counter?
|
||||
if (Config::getNew().showFPS)
|
||||
{
|
||||
Drawing::drawFPS();
|
||||
}
|
||||
|
||||
// Copy pixels from the virtual screen buffer to the surface
|
||||
auto& dpi = Gfx::screenDpi();
|
||||
if (dpi.bits != nullptr)
|
||||
|
|
|
@ -166,7 +166,7 @@ namespace OpenLoco::Ui::Options
|
|||
|
||||
namespace Display
|
||||
{
|
||||
static const Gfx::ui_size_t _window_size = { 400, 184 };
|
||||
static const Gfx::ui_size_t _window_size = { 400, 199 };
|
||||
|
||||
namespace Widx
|
||||
{
|
||||
|
@ -179,6 +179,7 @@ namespace OpenLoco::Ui::Options
|
|||
display_scale,
|
||||
display_scale_down_btn,
|
||||
display_scale_up_btn,
|
||||
show_fps,
|
||||
landscape_smoothing,
|
||||
gridlines_on_landscape,
|
||||
vehicles_min_scale,
|
||||
|
@ -197,20 +198,18 @@ namespace OpenLoco::Ui::Options
|
|||
makeWidget({ 235, 64 }, { 156, 12 }, widget_type::wt_18, 1, StringIds::display_resolution_label_format),
|
||||
makeWidget({ 379, 65 }, { 11, 10 }, widget_type::wt_11, 1, StringIds::dropdown),
|
||||
makeStepperWidgets({ 235, 79 }, { 156, 12 }, widget_type::wt_17, 1, StringIds::empty),
|
||||
makeWidget({ 10, 99 }, { 346, 12 }, widget_type::checkbox, 1, StringIds::landscape_smoothing, StringIds::landscape_smoothing_tip),
|
||||
makeWidget({ 10, 114 }, { 346, 12 }, widget_type::checkbox, 1, StringIds::gridlines_on_landscape, StringIds::gridlines_on_landscape_tip),
|
||||
makeWidget({ 235, 133 }, { 156, 12 }, widget_type::wt_18, 1, StringIds::empty, StringIds::vehicles_min_scale_tip),
|
||||
makeWidget({ 379, 134 }, { 11, 10 }, widget_type::wt_11, 1, StringIds::dropdown, StringIds::vehicles_min_scale_tip),
|
||||
makeWidget({ 235, 148 }, { 156, 12 }, widget_type::wt_18, 1, StringIds::empty, StringIds::station_names_min_scale_tip),
|
||||
makeWidget({ 379, 149 }, { 11, 10 }, widget_type::wt_11, 1, StringIds::dropdown, StringIds::station_names_min_scale_tip),
|
||||
makeWidget({ 235, 163 }, { 156, 12 }, widget_type::wt_18, 1, StringIds::empty),
|
||||
makeWidget({ 379, 164 }, { 11, 10 }, widget_type::wt_11, 1, StringIds::dropdown),
|
||||
makeWidget({ 10, 99 }, { 346, 12 }, widget_type::checkbox, 1, StringIds::option_show_fps_counter, StringIds::option_show_fps_counter_tooltip),
|
||||
makeWidget({ 10, 114 }, { 346, 12 }, widget_type::checkbox, 1, StringIds::landscape_smoothing, StringIds::landscape_smoothing_tip),
|
||||
makeWidget({ 10, 129 }, { 346, 12 }, widget_type::checkbox, 1, StringIds::gridlines_on_landscape, StringIds::gridlines_on_landscape_tip),
|
||||
makeDropdownWidgets({ 235, 148 }, { 156, 12 }, widget_type::wt_18, 1, StringIds::empty, StringIds::vehicles_min_scale_tip),
|
||||
makeDropdownWidgets({ 235, 163 }, { 156, 12 }, widget_type::wt_18, 1, StringIds::empty, StringIds::station_names_min_scale_tip),
|
||||
makeDropdownWidgets({ 235, 178 }, { 156, 12 }, widget_type::wt_18, 1, StringIds::empty),
|
||||
widgetEnd(),
|
||||
};
|
||||
|
||||
static window_event_list _events;
|
||||
|
||||
static constexpr uint64_t enabledWidgets = Common::enabledWidgets | (1 << Display::Widx::landscape_smoothing) | (1 << Display::Widx::gridlines_on_landscape) | (1 << Display::Widx::vehicles_min_scale) | (1 << Display::Widx::vehicles_min_scale_btn) | (1 << Display::Widx::station_names_min_scale) | (1 << Display::Widx::station_names_min_scale_btn) | (1 << Display::Widx::construction_marker) | (1 << Display::Widx::construction_marker_btn) | (1 << Display::Widx::display_scale_up_btn) | (1 << Display::Widx::display_scale_down_btn);
|
||||
static constexpr uint64_t enabledWidgets = Common::enabledWidgets | (1 << Widx::show_fps) | (1 << Display::Widx::landscape_smoothing) | (1 << Display::Widx::gridlines_on_landscape) | (1 << Display::Widx::vehicles_min_scale) | (1 << Display::Widx::vehicles_min_scale_btn) | (1 << Display::Widx::station_names_min_scale) | (1 << Display::Widx::station_names_min_scale_btn) | (1 << Display::Widx::construction_marker) | (1 << Display::Widx::construction_marker_btn) | (1 << Display::Widx::display_scale_up_btn) | (1 << Display::Widx::display_scale_down_btn);
|
||||
|
||||
// 0x004BFB8C
|
||||
static void onMouseUp(window* w, widget_index wi)
|
||||
|
@ -230,6 +229,15 @@ namespace OpenLoco::Ui::Options
|
|||
Options::tabOnMouseUp(w, wi);
|
||||
return;
|
||||
|
||||
case Widx::show_fps:
|
||||
{
|
||||
auto& cfg = OpenLoco::Config::getNew();
|
||||
cfg.showFPS ^= 1;
|
||||
OpenLoco::Config::writeNewConfig();
|
||||
Gfx::invalidateScreen();
|
||||
return;
|
||||
}
|
||||
|
||||
case Widx::landscape_smoothing:
|
||||
{
|
||||
auto& cfg = OpenLoco::Config::get();
|
||||
|
@ -556,6 +564,12 @@ namespace OpenLoco::Ui::Options
|
|||
w->widgets[Widx::vehicles_min_scale].text = scale_string_ids[Config::get().vehicles_min_scale];
|
||||
w->widgets[Widx::station_names_min_scale].text = scale_string_ids[Config::get().station_names_min_scale];
|
||||
|
||||
w->activated_widgets &= ~(1 << Widx::show_fps);
|
||||
if (Config::getNew().showFPS)
|
||||
{
|
||||
w->activated_widgets |= (1 << Widx::show_fps);
|
||||
}
|
||||
|
||||
w->activated_widgets &= ~(1 << Widx::landscape_smoothing);
|
||||
if ((Config::get().flags & Config::flags::landscape_smoothing) == 0)
|
||||
{
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
<ClCompile Include="Config.cpp" />
|
||||
<ClCompile Include="Console.cpp" />
|
||||
<ClCompile Include="Date.cpp" />
|
||||
<ClCompile Include="Drawing\FPSCounter.cpp" />
|
||||
<ClCompile Include="Drawing\SoftwareDrawingEngine.cpp" />
|
||||
<ClCompile Include="Economy.cpp" />
|
||||
<ClCompile Include="EditorController.cpp" />
|
||||
|
@ -206,6 +207,7 @@
|
|||
<ClInclude Include="Core\Span.hpp" />
|
||||
<ClInclude Include="Currency.h" />
|
||||
<ClInclude Include="Date.h" />
|
||||
<ClInclude Include="Drawing\FPSCounter.h" />
|
||||
<ClInclude Include="Drawing\SoftwareDrawingEngine.h" />
|
||||
<ClInclude Include="Economy.h" />
|
||||
<ClInclude Include="EditorController.h" />
|
||||
|
|
Loading…
Reference in New Issue