feat: Add frame time graph to FPS display
This commit is contained in:
parent
bf6b2db0cb
commit
e951359a46
@ -366,6 +366,7 @@ namespace hex {
|
|||||||
|
|
||||||
void addInitArgument(const std::string &key, const std::string &value = { });
|
void addInitArgument(const std::string &key, const std::string &value = { });
|
||||||
|
|
||||||
|
void setLastFrameTime(double time);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ProgramArguments {
|
struct ProgramArguments {
|
||||||
@ -557,6 +558,8 @@ namespace hex {
|
|||||||
bool updateImHex(UpdateType updateType);
|
bool updateImHex(UpdateType updateType);
|
||||||
|
|
||||||
void addStartupTask(const std::string &name, bool async, const std::function<bool()> &function);
|
void addStartupTask(const std::string &name, bool async, const std::function<bool()> &function);
|
||||||
|
|
||||||
|
double getLastFrameTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -381,7 +381,6 @@ namespace hex {
|
|||||||
|
|
||||||
// Default to true means we forward to ourselves by default
|
// Default to true means we forward to ourselves by default
|
||||||
static bool s_isMainInstance = true;
|
static bool s_isMainInstance = true;
|
||||||
|
|
||||||
void setMainInstanceStatus(bool status) {
|
void setMainInstanceStatus(bool status) {
|
||||||
s_isMainInstance = status;
|
s_isMainInstance = status;
|
||||||
}
|
}
|
||||||
@ -436,6 +435,12 @@ namespace hex {
|
|||||||
getInitArguments()[key] = value;
|
getInitArguments()[key] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static double s_lastFrameTime;
|
||||||
|
void setLastFrameTime(double time) {
|
||||||
|
s_lastFrameTime = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isMainInstance() {
|
bool isMainInstance() {
|
||||||
@ -687,6 +692,11 @@ namespace hex {
|
|||||||
RequestAddInitTask::post(name, async, function);
|
RequestAddInitTask::post(name, async, function);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double getLastFrameTime() {
|
||||||
|
return impl::s_lastFrameTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ImHexApi::Messaging {
|
namespace ImHexApi::Messaging {
|
||||||
|
@ -82,6 +82,9 @@ namespace hex::init {
|
|||||||
static ImColor getHighlightColor(u32 index) {
|
static ImColor getHighlightColor(u32 index) {
|
||||||
static auto highlightConfig = nlohmann::json::parse(romfs::get("splash_colors.json").string());
|
static auto highlightConfig = nlohmann::json::parse(romfs::get("splash_colors.json").string());
|
||||||
static std::list<nlohmann::json> selectedConfigs;
|
static std::list<nlohmann::json> selectedConfigs;
|
||||||
|
static nlohmann::json selectedConfig;
|
||||||
|
|
||||||
|
static std::mt19937 random(std::random_device{}());
|
||||||
|
|
||||||
if (selectedConfigs.empty()) {
|
if (selectedConfigs.empty()) {
|
||||||
const auto now = []{
|
const auto now = []{
|
||||||
@ -110,15 +113,14 @@ namespace hex::init {
|
|||||||
// Remove the default color theme if there's another one available
|
// Remove the default color theme if there's another one available
|
||||||
if (selectedConfigs.size() != 1)
|
if (selectedConfigs.size() != 1)
|
||||||
selectedConfigs.erase(selectedConfigs.begin());
|
selectedConfigs.erase(selectedConfigs.begin());
|
||||||
|
|
||||||
|
selectedConfig = *std::next(selectedConfigs.begin(), random() % selectedConfigs.size());
|
||||||
|
|
||||||
|
log::debug("Using '{}' highlight color theme", selectedConfig["name"].get<std::string>());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::mt19937 random(std::random_device{}());
|
|
||||||
|
|
||||||
static const auto &selectedConfig = *std::next(selectedConfigs.begin(), random() % selectedConfigs.size());
|
|
||||||
|
|
||||||
const auto colorString = selectedConfig["colors"][index % selectedConfig["colors"].size()].get<std::string>();
|
const auto colorString = selectedConfig["colors"][index % selectedConfig["colors"].size()].get<std::string>();
|
||||||
|
|
||||||
log::debug("Using '{}' highlight color theme", selectedConfig["name"].get<std::string>());
|
|
||||||
if (colorString == "random") {
|
if (colorString == "random") {
|
||||||
float r, g, b;
|
float r, g, b;
|
||||||
ImGui::ColorConvertHSVtoRGB(
|
ImGui::ColorConvertHSVtoRGB(
|
||||||
|
@ -211,6 +211,8 @@ namespace hex {
|
|||||||
this->fullFrame();
|
this->fullFrame();
|
||||||
frameCount += 1;
|
frameCount += 1;
|
||||||
|
|
||||||
|
ImHexApi::System::impl::setLastFrameTime(glfwGetTime() - m_lastStartFrameTime);
|
||||||
|
|
||||||
// Limit frame rate
|
// Limit frame rate
|
||||||
// If the target FPS are below 15, use the monitor refresh rate, if it's above 200, don't limit the frame rate
|
// If the target FPS are below 15, use the monitor refresh rate, if it's above 200, don't limit the frame rate
|
||||||
const auto targetFPS = ImHexApi::System::getTargetFPS();
|
const auto targetFPS = ImHexApi::System::getTargetFPS();
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include <fonts/codicons_font.h>
|
#include <fonts/codicons_font.h>
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
#include <imgui_internal.h>
|
#include <imgui_internal.h>
|
||||||
|
#include <implot.h>
|
||||||
#include <hex/ui/imgui_imhex_extensions.h>
|
#include <hex/ui/imgui_imhex_extensions.h>
|
||||||
|
|
||||||
#include <content/popups/popup_notification.hpp>
|
#include <content/popups/popup_notification.hpp>
|
||||||
@ -73,6 +74,31 @@ namespace hex::plugin::builtin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ImGuiExt::TextFormatted("FPS {0:3}.{1:02}", u32(framerate), u32(framerate * 100) % 100);
|
ImGuiExt::TextFormatted("FPS {0:3}.{1:02}", u32(framerate), u32(framerate * 100) % 100);
|
||||||
|
|
||||||
|
if (ImGui::IsItemHovered()) {
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2());
|
||||||
|
if (ImGui::BeginTooltip()) {
|
||||||
|
if (ImPlot::BeginPlot("##frame_time_graph", scaled({ 200, 100 }), ImPlotFlags_CanvasOnly | ImPlotFlags_NoFrame | ImPlotFlags_NoInputs)) {
|
||||||
|
ImPlot::SetupAxes("", "", ImPlotAxisFlags_NoLabel | ImPlotAxisFlags_NoTickLabels, ImPlotAxisFlags_NoLabel | ImPlotAxisFlags_LockMin | ImPlotAxisFlags_AutoFit);
|
||||||
|
ImPlot::SetupAxisLimits(ImAxis_Y1, 0, 0.01, ImPlotCond_Always);
|
||||||
|
ImPlot::SetupAxisFormat(ImAxis_Y1, [](double value, char* buff, int size, void*) -> int {
|
||||||
|
return snprintf(buff, size, "%dms", int(value * 1000.0));
|
||||||
|
}, nullptr);
|
||||||
|
ImPlot::SetupAxisTicks(ImAxis_Y1, 0, 0.01, 3);
|
||||||
|
|
||||||
|
static std::vector<double> values(100);
|
||||||
|
|
||||||
|
values.push_back(ImHexApi::System::getLastFrameTime());
|
||||||
|
if (values.size() > 100)
|
||||||
|
values.erase(values.begin());
|
||||||
|
|
||||||
|
ImPlot::PlotLine("FPS", values.data(), values.size());
|
||||||
|
ImPlot::EndPlot();
|
||||||
|
}
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
ImGui::PopStyleVar();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user