From 144bdaee8c52f3ba4934b64b94e05676d96b8939 Mon Sep 17 00:00:00 2001 From: Thorbjørn Lindeijer Date: Fri, 8 Mar 2024 21:39:31 +0100 Subject: Removed SDL2_gfx dependency Since the upgrade to SDL2 it was only used for framerate limiting, which I've replicated in a small helper class. Also reduced the framerate limit while minimized from 100 to 10 FPS. --- .gitlab-ci.yml | 1 - README.md | 8 ++++---- src/CMakeLists.txt | 2 +- src/client.cpp | 55 ++++++++++++++++++++++++++++++++++-------------------- src/client.h | 15 ++++++++++++--- 5 files changed, 52 insertions(+), 29 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d539ecc9..6a9ed7a6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -17,7 +17,6 @@ ubuntu-build: libphysfs-dev libpng-dev libsdl2-dev - libsdl2-gfx-dev libsdl2-image-dev libsdl2-mixer-dev libsdl2-net-dev diff --git a/README.md b/README.md index 605b682c..2b779725 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ either tmwAthena or manaserv. The Mana client is written in C++ and builds upon: -- SDL2, SDL2\_gfx, SDL2\_image, SDL2\_mixer, SDL2\_ttf, SDL2\_net (Media framework) +- SDL2, SDL2\_image, SDL2\_mixer, SDL2\_ttf, SDL2\_net (Media framework) - Guichan (GUI framework) - libxml2 (XML parsing and writing) - PhysicsFS (Data files) @@ -113,20 +113,20 @@ Installing the dependencies on Ubuntu: sudo apt install build-essential cmake \ libsdl2-dev libsdl2-image-dev libsdl2-mixer-dev \ - libsdl2-net-dev libsdl2-ttf-dev libsdl2-gfx-dev \ + libsdl2-net-dev libsdl2-ttf-dev \ libcurl4-openssl-dev libphysfs-dev libxml2-dev \ libguichan-dev libpng-dev gettext Installing the dependencies on macOS (with Homebrew): - brew install sdl2 sdl2_gfx sdl2_image sdl2_mixer sdl2_net sdl2_ttf \ + brew install sdl2 sdl2_image sdl2_mixer sdl2_net sdl2_ttf \ physfs curl Installing the dependencies on Fedora: sudo dnf install gcc-c++ cmake physfs-devel libcurl-devel guichan-devel \ SDL2_image-devel SDL2_mixer-devel SDL2_net-devel \ - SDL2_ttf-devel SDL2_gfx-devel + SDL2_ttf-devel Once the dependencies are installed, use CMake: diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a138578b..465ba0e8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,5 @@ include(FindPkgConfig) -pkg_check_modules(SDL2 REQUIRED sdl2>=2.0.1 SDL2_image SDL2_mixer SDL2_net SDL2_ttf SDL2_gfx) +pkg_check_modules(SDL2 REQUIRED sdl2>=2.0.1 SDL2_image SDL2_mixer SDL2_net SDL2_ttf) FIND_PACKAGE(PhysFS REQUIRED) FIND_PACKAGE(CURL REQUIRED) FIND_PACKAGE(LibXml2 REQUIRED) diff --git a/src/client.cpp b/src/client.cpp index df360d17..18d95ac8 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -29,12 +29,8 @@ #include "game.h" #include "itemshortcut.h" #include "keyboardconfig.h" -#ifdef USE_OPENGL -#include "openglgraphics.h" -#endif #include "playerrelations.h" #include "sound.h" -#include "units.h" #include "gui/changeemaildialog.h" #include "gui/changepassworddialog.h" @@ -86,8 +82,6 @@ #ifdef _WIN32 #include #include "utils/specialfolder.h" -#else -#include #endif #include @@ -152,9 +146,8 @@ int get_elapsed_time(int startTime) { if (startTime <= tick_time) return (tick_time - startTime) * MILLISECONDS_IN_A_TICK; - else - return (tick_time + (MAX_TICK_VALUE - startTime)) - * MILLISECONDS_IN_A_TICK; + + return (tick_time + (MAX_TICK_VALUE - startTime)) * MILLISECONDS_IN_A_TICK; } bool isDoubleClick(int selected) @@ -174,6 +167,36 @@ bool isDoubleClick(int selected) return false; } +/** + * A simple but effective frame rate limiter. + * Based on FPSmanager in SDL2_gfx. + */ +void FpsManager::limitFps(int fpsLimit) +{ + if (fpsLimit <= 0) + return; + + const auto ticks = SDL_GetTicks(); + + // Need to reset if the FPS limit changes + if (mBaseTicks > 0 && mFpsLimit == fpsLimit) + { + ++mFrameCount; + const auto targetTicks = mBaseTicks + mFrameCount * 1000 / mFpsLimit; + + // Make sure ticks hasn't wrapped + if (ticks > mBaseTicks && targetTicks > ticks) + { + SDL_Delay(targetTicks - ticks); + return; + } + } + + mFpsLimit = fpsLimit; + mFrameCount = 0; + mBaseTicks = ticks; +} + Client *Client::mInstance = nullptr; @@ -411,9 +434,6 @@ Client::Client(const Options &options): mLogicCounterId = SDL_AddTimer(MILLISECONDS_IN_A_TICK, nextTick, nullptr); mSecondsCounterId = SDL_AddTimer(1000, nextSecond, nullptr); - // Initialize frame limiting - SDL_initFramerate(&mFpsManager); - listen(Event::ConfigChannel); //TODO: fix having to fake a option changed event @@ -524,15 +544,13 @@ int Client::exec() frame_count++; gui->draw(); graphics->updateScreen(); + mFpsManager.limitFps(mFpsLimit); } else { - SDL_Delay(10); + mFpsManager.limitFps(10); } - if (mLimitFps) - SDL_framerateDelay(&mFpsManager); - // TODO: Add connect timeouts if (mState == STATE_CONNECT_GAME && Net::getGameHandler()->isConnected()) @@ -1012,10 +1030,7 @@ void Client::event(Event::Channel channel, const Event &event) event.getType() == Event::ConfigOptionChanged && event.getString("option") == "fpslimit") { - const int fpsLimit = config.getIntValue("fpslimit"); - mLimitFps = fpsLimit > 0; - if (mLimitFps) - SDL_setFramerate(&mFpsManager, fpsLimit); + mFpsLimit = config.getIntValue("fpslimit"); } } diff --git a/src/client.h b/src/client.h index 5b88dd5a..be591979 100644 --- a/src/client.h +++ b/src/client.h @@ -30,7 +30,6 @@ #include #include -#include #include @@ -117,6 +116,16 @@ enum State { STATE_FORCE_QUIT }; +class FpsManager +{ + int mFpsLimit = 0; + uint32_t mFrameCount = 0; + uint32_t mBaseTicks = 0; + +public: + void limitFps(int fpsLimit); +}; + /** * The core part of the client. This class initializes all subsystems, runs * the event loop, and shuts everything down again. @@ -249,8 +258,8 @@ private: SDL_TimerID mLogicCounterId = 0; SDL_TimerID mSecondsCounterId = 0; - bool mLimitFps = false; - FPSmanager mFpsManager; + int mFpsLimit = 0; + FpsManager mFpsManager; }; #endif // CLIENT_H -- cgit v1.2.3-70-g09d2