mirror of
https://github.com/The-Powder-Toy/The-Powder-Toy.git
synced 2025-07-28 20:20:18 +02:00
Add draw limit variant that mirrors the display's refresh rate
This commit is contained in:
@@ -12,3 +12,15 @@ struct FpsLimitExplicit
|
||||
float value;
|
||||
};
|
||||
using FpsLimit = std::variant<FpsLimitVsync, FpsLimitNone, FpsLimitExplicit>;
|
||||
|
||||
struct DrawLimitDisplay
|
||||
{
|
||||
};
|
||||
struct DrawLimitNone
|
||||
{
|
||||
};
|
||||
struct DrawLimitExplicit
|
||||
{
|
||||
int value;
|
||||
};
|
||||
using DrawLimit = std::variant<DrawLimitDisplay, DrawLimitNone, DrawLimitExplicit>;
|
||||
|
@@ -156,6 +156,7 @@ void SDLOpen()
|
||||
SDLSetScreen();
|
||||
|
||||
int displayIndex = SDL_GetWindowDisplayIndex(sdl_window);
|
||||
std::optional<int> refreshRate;
|
||||
if (displayIndex >= 0)
|
||||
{
|
||||
SDL_Rect rect;
|
||||
@@ -164,7 +165,13 @@ void SDLOpen()
|
||||
desktopWidth = rect.w;
|
||||
desktopHeight = rect.h;
|
||||
}
|
||||
SDL_DisplayMode displayMode;
|
||||
if (!SDL_GetCurrentDisplayMode(displayIndex, &displayMode) && displayMode.refresh_rate)
|
||||
{
|
||||
refreshRate = displayMode.refresh_rate;
|
||||
}
|
||||
}
|
||||
ui::Engine::Ref().SetRefreshRate(refreshRate);
|
||||
|
||||
StopTextInput();
|
||||
}
|
||||
@@ -460,15 +467,24 @@ void EngineProcess()
|
||||
engine.Tick();
|
||||
|
||||
{
|
||||
int drawcap = ui::Engine::Ref().GetDrawingFrequencyLimit();
|
||||
auto drawLimit = ui::Engine::Ref().GetDrawingFrequencyLimit();
|
||||
auto nowNs = uint64_t(SDL_GetTicks()) * UINT64_C(1'000'000);
|
||||
if (!drawcap || drawSchedule.HasElapsed(nowNs))
|
||||
std::optional<int> effectiveDrawLimit;
|
||||
if (auto *drawLimitExplicit = std::get_if<DrawLimitExplicit>(&drawLimit))
|
||||
{
|
||||
effectiveDrawLimit = drawLimitExplicit->value;
|
||||
}
|
||||
if (std::get_if<DrawLimitDisplay>(&drawLimit))
|
||||
{
|
||||
effectiveDrawLimit = engine.GetRefreshRate();
|
||||
}
|
||||
if (!effectiveDrawLimit || drawSchedule.HasElapsed(nowNs))
|
||||
{
|
||||
engine.Draw();
|
||||
drawSchedule.SetNow(nowNs);
|
||||
if (drawcap)
|
||||
if (effectiveDrawLimit)
|
||||
{
|
||||
drawSchedule.Arm(float(drawcap));
|
||||
drawSchedule.Arm(float(*effectiveDrawLimit));
|
||||
}
|
||||
SDLSetScreen();
|
||||
blit(engine.g->Data());
|
||||
|
@@ -11,7 +11,7 @@
|
||||
using namespace ui;
|
||||
|
||||
Engine::Engine():
|
||||
drawingFrequencyLimit(0),
|
||||
drawingFrequencyLimit(DrawLimitDisplay{}),
|
||||
FrameIndex(0),
|
||||
state_(nullptr),
|
||||
windowTargetPosition(0, 0),
|
||||
|
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <stack>
|
||||
#include "common/String.h"
|
||||
#include "common/ExplicitSingleton.h"
|
||||
@@ -47,8 +48,8 @@ namespace ui
|
||||
void Exit();
|
||||
void ConfirmExit();
|
||||
|
||||
void SetDrawingFrequencyLimit(int limit) {drawingFrequencyLimit = limit;}
|
||||
inline int GetDrawingFrequencyLimit() {return drawingFrequencyLimit;}
|
||||
void SetDrawingFrequencyLimit(DrawLimit limit) {drawingFrequencyLimit = limit;}
|
||||
inline DrawLimit GetDrawingFrequencyLimit() {return drawingFrequencyLimit;}
|
||||
void SetFastQuit(bool fastquit) { FastQuit = fastquit; }
|
||||
inline bool GetFastQuit() {return FastQuit; }
|
||||
void SetGlobalQuit(bool newGlobalQuit) { GlobalQuit = newGlobalQuit; }
|
||||
@@ -78,7 +79,7 @@ namespace ui
|
||||
return fpsLimit;
|
||||
}
|
||||
|
||||
int drawingFrequencyLimit;
|
||||
DrawLimit drawingFrequencyLimit;
|
||||
Graphics * g;
|
||||
bool GraveExitsConsole;
|
||||
|
||||
@@ -99,6 +100,7 @@ namespace ui
|
||||
Window* state_;
|
||||
Point windowTargetPosition;
|
||||
bool ignoreEvents = false;
|
||||
std::optional<int> refreshRate;
|
||||
|
||||
// saved appearances of windows that are in the backround and
|
||||
// thus are not currently being redrawn
|
||||
@@ -141,5 +143,15 @@ namespace ui
|
||||
bool GetForceIntegerScaling() const { return windowFrameOps.forceIntegerScaling; }
|
||||
bool GetResizable () const { return windowFrameOps.resizable; }
|
||||
bool GetBlurryScaling () const { return windowFrameOps.blurryScaling; }
|
||||
|
||||
std::optional<int> GetRefreshRate() const
|
||||
{
|
||||
return refreshRate;
|
||||
}
|
||||
|
||||
void SetRefreshRate(std::optional<int> newRefreshRate)
|
||||
{
|
||||
refreshRate = newRefreshRate;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@@ -239,13 +239,35 @@ static int drawCap(lua_State *L)
|
||||
int acount = lua_gettop(L);
|
||||
if (acount == 0)
|
||||
{
|
||||
lua_pushinteger(L, ui::Engine::Ref().GetDrawingFrequencyLimit());
|
||||
auto drawLimit = ui::Engine::Ref().GetDrawingFrequencyLimit();
|
||||
if (std::holds_alternative<DrawLimitDisplay>(drawLimit))
|
||||
{
|
||||
lua_pushliteral(L, "display");
|
||||
}
|
||||
else if (std::holds_alternative<DrawLimitNone>(drawLimit))
|
||||
{
|
||||
lua_pushinteger(L, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushinteger(L, std::get<DrawLimitExplicit>(drawLimit).value);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
int drawcap = luaL_checkint(L, 1);
|
||||
if (lua_isstring(L, 1) && byteStringEqualsLiteral(tpt_lua_toByteString(L, 1), "display"))
|
||||
{
|
||||
ui::Engine::Ref().SetDrawingFrequencyLimit(DrawLimitDisplay{});
|
||||
return 0;
|
||||
}
|
||||
int drawcap = luaL_checkinteger(L, 1);
|
||||
if(drawcap < 0)
|
||||
return luaL_error(L, "draw cap too small");
|
||||
ui::Engine::Ref().SetDrawingFrequencyLimit(drawcap);
|
||||
if (drawcap == 0)
|
||||
{
|
||||
ui::Engine::Ref().SetDrawingFrequencyLimit(DrawLimitNone{});
|
||||
return 0;
|
||||
}
|
||||
ui::Engine::Ref().SetDrawingFrequencyLimit(DrawLimitExplicit{ drawcap });
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user