Rearrange the main game event loop a little
This patch is contributed by @x-qq and should improve CPU usage on Linux.
This commit is contained in:
@@ -117,8 +117,25 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
menu_activate();
|
menu_activate();
|
||||||
restore_cursor();
|
restore_cursor();
|
||||||
while(!All_Done)
|
// As of year 2020, the game is causing too high CPU load on modern CPUs (i7-7700HQ), but due
|
||||||
Handle_One_Event();
|
// to mistakes in architecture we cannot simply use SFML's native framerate capping
|
||||||
|
// mechanism (setFramerateLimit), so we have to make our own.
|
||||||
|
//
|
||||||
|
// Note that due to the fact that various underlying pieces of code redraw, redisplay and
|
||||||
|
// pause the game as they see fit, this is not exactly framerate capping.
|
||||||
|
// ~xq
|
||||||
|
sf::Clock framerate_clock;
|
||||||
|
const sf::Int64 desired_microseconds_per_frame { 1000000 / 60}; // us / FPS
|
||||||
|
while(!All_Done) {
|
||||||
|
// If this call indicates that it did something expensive by returning true,
|
||||||
|
// we do the performance capping. The logic here is that we do not want to
|
||||||
|
// do expensive things too many times per second.
|
||||||
|
// ~xq
|
||||||
|
if(!Handle_One_Event()) continue;
|
||||||
|
const sf::Int64 remaining_time_budget = desired_microseconds_per_frame - framerate_clock.getElapsedTime().asMicroseconds();
|
||||||
|
if(remaining_time_budget > 0) sf::sleep(sf::microseconds(remaining_time_budget));
|
||||||
|
framerate_clock.restart();
|
||||||
|
}
|
||||||
|
|
||||||
close_program();
|
close_program();
|
||||||
return 0;
|
return 0;
|
||||||
@@ -194,12 +211,12 @@ void init_boe(int argc, char* argv[]) {
|
|||||||
showMenuBar();
|
showMenuBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Handle_One_Event() {
|
// Return true if we redrew the screen
|
||||||
|
bool Handle_One_Event() {
|
||||||
static const long twentyTicks = time_in_ticks(20).asMilliseconds();
|
static const long twentyTicks = time_in_ticks(20).asMilliseconds();
|
||||||
static const long fortyTicks = time_in_ticks(40).asMilliseconds();
|
static const long fortyTicks = time_in_ticks(40).asMilliseconds();
|
||||||
|
|
||||||
through_sending();
|
through_sending();
|
||||||
Handle_Update();
|
|
||||||
|
|
||||||
if((animTimer.getElapsedTime().asMilliseconds() >= fortyTicks) && (overall_mode != MODE_STARTUP) && (anim_onscreen) && get_bool_pref("DrawTerrainAnimation", true)) {
|
if((animTimer.getElapsedTime().asMilliseconds() >= fortyTicks) && (overall_mode != MODE_STARTUP) && (anim_onscreen) && get_bool_pref("DrawTerrainAnimation", true)) {
|
||||||
animTimer.restart();
|
animTimer.restart();
|
||||||
@@ -226,18 +243,18 @@ void Handle_One_Event() {
|
|||||||
}
|
}
|
||||||
flushingInput = false;
|
flushingInput = false;
|
||||||
redraw_screen(REFRESH_NONE);
|
redraw_screen(REFRESH_NONE);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
switch(event.type) {
|
switch(event.type) {
|
||||||
case sf::Event::KeyPressed:
|
case sf::Event::KeyPressed:
|
||||||
if(flushingInput) return;
|
if(flushingInput) return false;
|
||||||
if(!(event.key.*systemKey))
|
if(!(event.key.*systemKey))
|
||||||
handle_keystroke(event);
|
handle_keystroke(event);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case sf::Event::MouseButtonPressed:
|
case sf::Event::MouseButtonPressed:
|
||||||
if(flushingInput) return;
|
if(flushingInput) return false;
|
||||||
Mouse_Pressed();
|
Mouse_Pressed();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -249,14 +266,16 @@ void Handle_One_Event() {
|
|||||||
case sf::Event::GainedFocus:
|
case sf::Event::GainedFocus:
|
||||||
Handle_Update();
|
Handle_Update();
|
||||||
makeFrontWindow(mainPtr);
|
makeFrontWindow(mainPtr);
|
||||||
// fallthru
|
change_cursor({event.mouseMove.x, event.mouseMove.y});
|
||||||
|
return true;
|
||||||
|
|
||||||
case sf::Event::MouseMoved:
|
case sf::Event::MouseMoved:
|
||||||
change_cursor({event.mouseMove.x, event.mouseMove.y});
|
change_cursor({event.mouseMove.x, event.mouseMove.y});
|
||||||
break;
|
flushingInput = false;
|
||||||
|
return false;
|
||||||
|
|
||||||
case sf::Event::MouseWheelMoved:
|
case sf::Event::MouseWheelMoved:
|
||||||
if(flushingInput) return;
|
if(flushingInput) return false;
|
||||||
handle_scroll(event);
|
handle_scroll(event);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -291,6 +310,7 @@ void Handle_One_Event() {
|
|||||||
break; // There's several events we don't need to handle at all
|
break; // There's several events we don't need to handle at all
|
||||||
}
|
}
|
||||||
flushingInput = false; // TODO: Could there be a case when the key and mouse input that needs to be flushed has other events interspersed?
|
flushingInput = false; // TODO: Could there be a case when the key and mouse input that needs to be flushed has other events interspersed?
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#include <SFML/Graphics.hpp>
|
#include <SFML/Graphics.hpp>
|
||||||
|
|
||||||
int main(int argc, char* argv[]);
|
int main(int argc, char* argv[]);
|
||||||
void Handle_One_Event();
|
bool Handle_One_Event();
|
||||||
void Handle_Update();
|
void Handle_Update();
|
||||||
void Mouse_Pressed();
|
void Mouse_Pressed();
|
||||||
void close_program();
|
void close_program();
|
||||||
|
|||||||
Reference in New Issue
Block a user