Feature: configurable refresh-rate and change default to 60fps

Most modern games run on 60 fps, and for good reason. This gives
a much smoother experiences.

As some people have monitors that can do 144Hz or even 240Hz, allow
people to configure the refresh rate. Of course, the higher you
set the value, the more time the game spends on drawing pixels
instead of simulating the game, which has an effect on simulation
speed.

The simulation will still always run at 33.33 fps, and is not
influences by this setting.
pull/221/head
Patric Stout 3 years ago committed by Patric Stout
parent eb9b1ad68d
commit fa170b9ace

@ -189,7 +189,7 @@ namespace {
PerformanceData(1), // PFE_ACC_GL_AIRCRAFT
PerformanceData(1), // PFE_GL_LANDSCAPE
PerformanceData(1), // PFE_GL_LINKGRAPH
PerformanceData(GL_RATE), // PFE_DRAWING
PerformanceData(1000.0 / 30), // PFE_DRAWING
PerformanceData(1), // PFE_ACC_DRAWWORLD
PerformanceData(60.0), // PFE_VIDEO
PerformanceData(1000.0 * 8192 / 44100), // PFE_SOUND
@ -468,7 +468,7 @@ struct FramerateWindow : Window {
this->speed_gameloop.SetRate(gl_rate / _pf_data[PFE_GAMELOOP].expected_rate, 1.0);
if (this->small) return; // in small mode, this is everything needed
this->rate_drawing.SetRate(_pf_data[PFE_DRAWING].GetRate(), _pf_data[PFE_DRAWING].expected_rate);
this->rate_drawing.SetRate(_pf_data[PFE_DRAWING].GetRate(), _settings_client.gui.refresh_rate);
int new_active = 0;
for (PerformanceElement e = PFE_FIRST; e < PFE_MAX; e++) {

@ -147,6 +147,7 @@ struct GUISettings {
byte starting_colour; ///< default color scheme for the company to start a new game with
bool show_newgrf_name; ///< Show the name of the NewGRF in the build vehicle window
bool auto_remove_signals; ///< automatically remove signals when in the way during rail construction
uint16 refresh_rate; ///< How often we refresh the screen (time between draw-ticks).
uint16 console_backlog_timeout; ///< the minimum amount of time items should be in the console backlog before they will be removed in ~3 seconds granularity.
uint16 console_backlog_length; ///< the minimum amount of items in the console backlog before items will be removed.

@ -3354,6 +3354,16 @@ def = 100
min = 10
max = 65500
[SDTC_VAR]
var = gui.refresh_rate
type = SLE_UINT16
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
def = 60
min = 10
max = 1000
cat = SC_EXPERT
startup = true
[SDTC_BOOL]
var = sound.news_ticker
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC

@ -485,20 +485,20 @@ void VideoDriver_Allegro::MainLoop()
if (cur_ticks >= next_game_tick || (_fast_forward && !_pause_mode)) {
if (_fast_forward && !_pause_mode) {
next_game_tick = cur_ticks + std::chrono::milliseconds(MILLISECONDS_PER_TICK);
next_game_tick = cur_ticks + this->GetGameInterval();
} else {
next_game_tick += std::chrono::milliseconds(MILLISECONDS_PER_TICK);
next_game_tick += this->GetGameInterval();
/* Avoid next_game_tick getting behind more and more if it cannot keep up. */
if (next_game_tick < cur_ticks - std::chrono::milliseconds(ALLOWED_DRIFT * MILLISECONDS_PER_TICK)) next_game_tick = cur_ticks;
if (next_game_tick < cur_ticks - ALLOWED_DRIFT * this->GetGameInterval()) next_game_tick = cur_ticks;
}
GameLoop();
}
if (cur_ticks >= next_draw_tick) {
next_draw_tick += std::chrono::milliseconds(MILLISECONDS_PER_TICK);
next_draw_tick += this->GetDrawInterval();
/* Avoid next_draw_tick getting behind more and more if it cannot keep up. */
if (next_draw_tick < cur_ticks - std::chrono::microseconds(ALLOWED_DRIFT * MILLISECONDS_PER_TICK)) next_draw_tick = cur_ticks;
if (next_draw_tick < cur_ticks - ALLOWED_DRIFT * this->GetDrawInterval()) next_draw_tick = cur_ticks;
bool old_ctrl_pressed = _ctrl_pressed;

@ -675,20 +675,20 @@ void VideoDriver_Cocoa::GameLoop()
if (cur_ticks >= next_game_tick || (_fast_forward && !_pause_mode)) {
if (_fast_forward && !_pause_mode) {
next_game_tick = cur_ticks + std::chrono::milliseconds(MILLISECONDS_PER_TICK);
next_game_tick = cur_ticks + this->GetGameInterval();
} else {
next_game_tick += std::chrono::milliseconds(MILLISECONDS_PER_TICK);
next_game_tick += this->GetGameInterval();
/* Avoid next_game_tick getting behind more and more if it cannot keep up. */
if (next_game_tick < cur_ticks - std::chrono::milliseconds(ALLOWED_DRIFT * MILLISECONDS_PER_TICK)) next_game_tick = cur_ticks;
if (next_game_tick < cur_ticks - ALLOWED_DRIFT * this->GetGameInterval()) next_game_tick = cur_ticks;
}
::GameLoop();
}
if (cur_ticks >= next_draw_tick) {
next_draw_tick += std::chrono::milliseconds(MILLISECONDS_PER_TICK);
next_draw_tick += this->GetDrawInterval();
/* Avoid next_draw_tick getting behind more and more if it cannot keep up. */
if (next_draw_tick < cur_ticks - std::chrono::microseconds(ALLOWED_DRIFT * MILLISECONDS_PER_TICK)) next_draw_tick = cur_ticks;
if (next_draw_tick < cur_ticks - ALLOWED_DRIFT * this->GetDrawInterval()) next_draw_tick = cur_ticks;
bool old_ctrl_pressed = _ctrl_pressed;

@ -294,11 +294,11 @@ void VideoDriver_Dedicated::MainLoop()
if (cur_ticks >= next_game_tick || _ddc_fastforward) {
if (_ddc_fastforward) {
next_game_tick = cur_ticks + std::chrono::milliseconds(MILLISECONDS_PER_TICK);
next_game_tick = cur_ticks + this->GetGameInterval();
} else {
next_game_tick += std::chrono::milliseconds(MILLISECONDS_PER_TICK);
next_game_tick += this->GetGameInterval();
/* Avoid next_game_tick getting behind more and more if it cannot keep up. */
if (next_game_tick < cur_ticks - std::chrono::milliseconds(ALLOWED_DRIFT * MILLISECONDS_PER_TICK)) next_game_tick = cur_ticks;
if (next_game_tick < cur_ticks - ALLOWED_DRIFT * this->GetGameInterval()) next_game_tick = cur_ticks;
}
GameLoop();

@ -793,9 +793,9 @@ void VideoDriver_SDL::LoopOnce()
}
if (cur_ticks >= next_draw_tick) {
next_draw_tick += std::chrono::milliseconds(MILLISECONDS_PER_TICK);
next_draw_tick += this->GetDrawInterval();
/* Avoid next_draw_tick getting behind more and more if it cannot keep up. */
if (next_draw_tick < cur_ticks - std::chrono::microseconds(ALLOWED_DRIFT * MILLISECONDS_PER_TICK)) next_draw_tick = cur_ticks;
if (next_draw_tick < cur_ticks - ALLOWED_DRIFT * this->GetDrawInterval()) next_draw_tick = cur_ticks;
bool old_ctrl_pressed = _ctrl_pressed;

@ -731,11 +731,11 @@ void VideoDriver_SDL::MainLoop()
if (cur_ticks >= next_game_tick || (_fast_forward && !_pause_mode)) {
if (_fast_forward && !_pause_mode) {
next_game_tick = cur_ticks + std::chrono::milliseconds(MILLISECONDS_PER_TICK);
next_game_tick = cur_ticks + this->GetGameInterval();
} else {
next_game_tick += std::chrono::milliseconds(MILLISECONDS_PER_TICK);
next_game_tick += this->GetGameInterval();
/* Avoid next_game_tick getting behind more and more if it cannot keep up. */
if (next_game_tick < cur_ticks - std::chrono::milliseconds(ALLOWED_DRIFT * MILLISECONDS_PER_TICK)) next_game_tick = cur_ticks;
if (next_game_tick < cur_ticks - ALLOWED_DRIFT * this->GetGameInterval()) next_game_tick = cur_ticks;
}
/* The gameloop is the part that can run asynchronously. The rest
@ -746,9 +746,9 @@ void VideoDriver_SDL::MainLoop()
}
if (cur_ticks >= next_draw_tick) {
next_draw_tick += std::chrono::milliseconds(MILLISECONDS_PER_TICK);
next_draw_tick += this->GetDrawInterval();
/* Avoid next_draw_tick getting behind more and more if it cannot keep up. */
if (next_draw_tick < cur_ticks - std::chrono::microseconds(ALLOWED_DRIFT * MILLISECONDS_PER_TICK)) next_draw_tick = cur_ticks;
if (next_draw_tick < cur_ticks - ALLOWED_DRIFT * this->GetDrawInterval()) next_draw_tick = cur_ticks;
bool old_ctrl_pressed = _ctrl_pressed;

@ -13,7 +13,9 @@
#include "../driver.h"
#include "../core/geometry_type.hpp"
#include "../core/math_func.hpp"
#include "../settings_type.h"
#include "../zoom_type.h"
#include <chrono>
#include <vector>
extern std::string _ini_videodriver;
@ -153,6 +155,16 @@ protected:
_cur_resolution.height = ClampU(res.height * 3 / 4, DEFAULT_WINDOW_HEIGHT, UINT16_MAX / 2);
}
}
std::chrono::steady_clock::duration GetGameInterval()
{
return std::chrono::milliseconds(MILLISECONDS_PER_TICK);
}
std::chrono::steady_clock::duration GetDrawInterval()
{
return std::chrono::microseconds(1000000 / _settings_client.gui.refresh_rate);
}
};
#endif /* VIDEO_VIDEO_DRIVER_HPP */

@ -1208,11 +1208,11 @@ void VideoDriver_Win32::MainLoop()
if (cur_ticks >= next_game_tick || (_fast_forward && !_pause_mode)) {
if (_fast_forward && !_pause_mode) {
next_game_tick = cur_ticks + std::chrono::milliseconds(MILLISECONDS_PER_TICK);
next_game_tick = cur_ticks + this->GetGameInterval();
} else {
next_game_tick += std::chrono::milliseconds(MILLISECONDS_PER_TICK);
next_game_tick += this->GetGameInterval();
/* Avoid next_game_tick getting behind more and more if it cannot keep up. */
if (next_game_tick < cur_ticks - std::chrono::milliseconds(ALLOWED_DRIFT * MILLISECONDS_PER_TICK)) next_game_tick = cur_ticks;
if (next_game_tick < cur_ticks - ALLOWED_DRIFT * this->GetGameInterval()) next_game_tick = cur_ticks;
}
/* Flush GDI buffer to ensure we don't conflict with the drawing thread. */
@ -1226,9 +1226,9 @@ void VideoDriver_Win32::MainLoop()
}
if (cur_ticks >= next_draw_tick) {
next_draw_tick += std::chrono::milliseconds(MILLISECONDS_PER_TICK);
next_draw_tick += this->GetDrawInterval();
/* Avoid next_draw_tick getting behind more and more if it cannot keep up. */
if (next_draw_tick < cur_ticks - std::chrono::microseconds(ALLOWED_DRIFT * MILLISECONDS_PER_TICK)) next_draw_tick = cur_ticks;
if (next_draw_tick < cur_ticks - ALLOWED_DRIFT * this->GetDrawInterval()) next_draw_tick = cur_ticks;
bool old_ctrl_pressed = _ctrl_pressed;

Loading…
Cancel
Save