From 5823ba6c18432e083ec103ce74921270d7e071d6 Mon Sep 17 00:00:00 2001
From: James Cowgill <jcowgill@debian.org>
Date: Sun, 16 Mar 2025 00:53:18 +0000
Subject: [PATCH] Port to SFML 3.0

Mostly straightforward with a few more complex changes:
* Include `<GL/gl.h>` instead of `<GL/glx.h>`. The glx header
  includes `Xlib.h` which has a `#define Status` which breaks the SFML 3
  headers.
* Change: the `clamp` define to an inline function. The define breaks
  modern C++ stl headers (eg `std::clamp` breaks).
* Rewrite the credits geometry using a triangle strip.
* Rewrite `PollEvent` which has significantly changed in SFML 3.
---
 build/Installer/extremetuxracer.wxs |   8 +-
 configure.ac                        |   8 +-
 src/audio.cpp                       |  11 ++-
 src/bh.h                            |   2 +-
 src/common.cpp                      |   2 +-
 src/common.h                        |   6 +-
 src/config_screen.cpp               |   6 +-
 src/credits.cpp                     |  36 +++-----
 src/event.cpp                       |   6 +-
 src/event_select.cpp                |   8 +-
 src/font.cpp                        |  14 +--
 src/game_over.cpp                   |   2 +-
 src/game_type_select.cpp            |  19 +++--
 src/gui.cpp                         | 128 ++++++++++++++--------------
 src/loading.cpp                     |   4 +-
 src/newplayer.cpp                   |   4 +-
 src/ogl_test.cpp                    |   2 +-
 src/particles.cpp                   |  23 +++--
 src/paused.cpp                      |  10 +--
 src/race_select.cpp                 |  12 +--
 src/racing.cpp                      |  46 +++++-----
 src/regist.cpp                      |   4 +-
 src/score.cpp                       |  10 +--
 src/splash_screen.cpp               |  16 ++--
 src/states.cpp                      |  85 +++++++-----------
 src/textures.cpp                    |   4 +-
 src/tool_char.cpp                   |  62 +++++++-------
 src/tool_frame.cpp                  |  88 +++++++++----------
 src/winsys.cpp                      |  33 +++----
 src/winsys.h                        |   2 +-
 30 files changed, 316 insertions(+), 345 deletions(-)

diff --git a/build/Installer/extremetuxracer.wxs b/build/Installer/extremetuxracer.wxs
index 7c513b89..83e906fd 100644
--- a/build/Installer/extremetuxracer.wxs
+++ b/build/Installer/extremetuxracer.wxs
@@ -29,10 +29,10 @@
           </Component>
           <Component Id='SFML' Guid='$(var.sfmlGUID)'>
             <File Id='openal32.dll' Name='openal32.dll' DiskId='1' Source='$(var.BinDir)\openal32.dll' />
-            <File Id='sfml_system_2.dll' Name='sfml-system-2.dll' DiskId='1' Source='$(var.BinDir)\sfml-system-2.dll' KeyPath='yes' />
-            <File Id='sfml_window_2.dll' Name='sfml-window-2.dll' DiskId='1' Source='$(var.BinDir)\sfml-window-2.dll' />
-            <File Id='sfml_graphics_2.dll' Name='sfml-graphics-2.dll' DiskId='1' Source='$(var.BinDir)\sfml-graphics-2.dll' />
-            <File Id='sfml_audio_2.dll' Name='sfml-audio-2.dll' DiskId='1' Source='$(var.BinDir)\sfml-audio-2.dll' />
+            <File Id='sfml_system_3.dll' Name='sfml-system-3.dll' DiskId='1' Source='$(var.BinDir)\sfml-system-3.dll' KeyPath='yes' />
+            <File Id='sfml_window_3.dll' Name='sfml-window-3.dll' DiskId='1' Source='$(var.BinDir)\sfml-window-3.dll' />
+            <File Id='sfml_graphics_3.dll' Name='sfml-graphics-3.dll' DiskId='1' Source='$(var.BinDir)\sfml-graphics-3.dll' />
+            <File Id='sfml_audio_3.dll' Name='sfml-audio-3.dll' DiskId='1' Source='$(var.BinDir)\sfml-audio-3.dll' />
           </Component>
         </Directory>
         <Merge Id="CRT" Language="0" SourceFile="$(var.CrtMergeModule)" DiskId="1" />
diff --git a/configure.ac b/configure.ac
index 13b1c494..4118e1c1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -50,28 +50,28 @@ esac
 AC_FUNC_MALLOC
 AC_CHECK_FUNCS([floor getcwd memmove memset mkdir pow sqrt strchr strdup])
 
-PKG_CHECK_MODULES([SFML_SYSTEM], [sfml-system >= 2.4],
+PKG_CHECK_MODULES([SFML_SYSTEM], [sfml-system >= 3.0],
 [
   CPPFLAGS="${CPPFLAGS} $SFML_SYSTEM_CFLAGS"
   LIBS="${LIBS} $SFML_SYSTEM_LIBS"
 ],
 [AC_MSG_ERROR([sfml-system not found])])
 
-PKG_CHECK_MODULES([SFML_AUDIO], [sfml-audio >= 2.4],
+PKG_CHECK_MODULES([SFML_AUDIO], [sfml-audio >= 3.0],
 [
   CPPFLAGS="${CPPFLAGS} $SFML_AUDIO_CFLAGS"
   LIBS="${LIBS} $SFML_AUDIO_LIBS"
 ],
 [AC_MSG_ERROR([sfml-audio not found])])
 
-PKG_CHECK_MODULES([SFML_WINDOW], [sfml-window >= 2.4],
+PKG_CHECK_MODULES([SFML_WINDOW], [sfml-window >= 3.0],
 [
   CPPFLAGS="${CPPFLAGS} $SFML_WINDOW_CFLAGS"
   LIBS="${LIBS} $SFML_WINDOW_LIBS"
 ],
 [AC_MSG_ERROR([sfml-window not found])])
 
-PKG_CHECK_MODULES([SFML_GRAPHICS], [sfml-graphics >= 2.4],
+PKG_CHECK_MODULES([SFML_GRAPHICS], [sfml-graphics >= 3.0],
 [
   CPPFLAGS="${CPPFLAGS} $SFML_GRAPHICS_CFLAGS"
   LIBS="${LIBS} $SFML_GRAPHICS_LIBS"
diff --git a/src/audio.cpp b/src/audio.cpp
index c0ccb713..1496e41f 100644
--- a/src/audio.cpp
+++ b/src/audio.cpp
@@ -31,7 +31,7 @@ CMusic Music;
 struct TSound {
 	sf::SoundBuffer data;
 	sf::Sound player;
-	explicit TSound(int volume) {
+	explicit TSound(int volume) : player(data) {
 		setVolume(volume);
 	}
 	void setVolume(int volume) {
@@ -39,8 +39,8 @@ struct TSound {
 	}
 
 	void Play(bool loop) {
-		if (player.getStatus() == sf::Sound::Playing) return;
-		player.setLoop(loop);
+		if (player.getStatus() == sf::Sound::Status::Playing) return;
+		player.setLooping(loop);
 		player.play();
 	}
 };
@@ -57,7 +57,6 @@ bool CSound::LoadChunk(const std::string& name, const std::string& filename) {
 	sounds.emplace_back(new TSound(param.sound_volume));
 	if (!sounds.back()->data.loadFromFile(filename)) // Try loading sound buffer
 		return false;
-	sounds.back()->player.setBuffer(sounds.back()->data);
 	SoundIndex[name] = sounds.size()-1;
 	return true;
 }
@@ -132,7 +131,7 @@ void CSound::Halt(std::size_t soundid) {
 	if (soundid >= sounds.size()) return;
 
 	// loop_count must be -1 (endless loop) for halt
-	if (sounds[soundid]->player.getLoop())
+	if (sounds[soundid]->player.isLooping())
 		sounds[soundid]->player.stop();
 }
 
@@ -249,7 +248,7 @@ bool CMusic::Play(sf::Music* music, bool loop, int volume) {
 	volume = clamp(0, volume, MIX_MAX_VOLUME);
 	if (music != curr_music) {
 		music->setVolume(volume);
-		music->setLoop(loop);
+		music->setLooping(loop);
 		if (curr_music)
 			curr_music->stop();
 		curr_music = music;
diff --git a/src/bh.h b/src/bh.h
index c1899014..8bebf400 100644
--- a/src/bh.h
+++ b/src/bh.h
@@ -68,7 +68,7 @@ GNU General Public License for more details.
 #	include <pwd.h>
 #	include <dirent.h>
 #	include <sys/time.h>
-#	include <GL/glx.h>
+#	include <GL/gl.h>
 #	define SEP "/"
 #endif
 
diff --git a/src/common.cpp b/src/common.cpp
index b444739a..49cfd7da 100644
--- a/src/common.cpp
+++ b/src/common.cpp
@@ -30,7 +30,7 @@ GNU General Public License for more details.
 //				color utils
 // --------------------------------------------------------------------
 
-#define TColor(r, g, b, a) sf::Color(static_cast<sf::Uint8>(r*255), static_cast<sf::Uint8>(g*255), static_cast<sf::Uint8>(b*255), static_cast<sf::Uint8>(a*255))
+#define TColor(r, g, b, a) sf::Color(static_cast<std::uint8_t>(r*255), static_cast<std::uint8_t>(g*255), static_cast<std::uint8_t>(b*255), static_cast<std::uint8_t>(a*255))
 const sf::Color colDYell =		TColor(1.0, 0.8, 0.0, 1.0);
 const sf::Color colDDYell =		TColor(0.8, 0.6, 0.0, 1.0);
 const sf::Color colLYell =		TColor(1.0, 1.0, 0.4, 1.0);
diff --git a/src/common.h b/src/common.h
index 4c878490..f1cc0fdf 100644
--- a/src/common.h
+++ b/src/common.h
@@ -21,8 +21,10 @@ GNU General Public License for more details.
 #include "bh.h"
 #include "matrices.h"
 
-
-#define clamp(minimum, x, maximum) (std::max(std::min(x, maximum), minimum))
+template<typename T>
+inline T clamp(T min, T x, T max) {
+	return std::max(std::min(x, max), min);
+}
 
 #ifndef M_PI
 #	define M_PI 3.1415926535
diff --git a/src/config_screen.cpp b/src/config_screen.cpp
index 0e7200bd..ce86a735 100644
--- a/src/config_screen.cpp
+++ b/src/config_screen.cpp
@@ -97,13 +97,13 @@ void CGameConfig::Keyb(sf::Keyboard::Key key, bool release, int x, int y) {
 	if (release) return;
 
 	switch (key) {
-		case sf::Keyboard::U:
+		case sf::Keyboard::Key::U:
 			param.ui_snow = !param.ui_snow;
 			break;
-		case sf::Keyboard::Escape:
+		case sf::Keyboard::Key::Escape:
 			State::manager.RequestEnterState(*State::manager.PreviousState());
 			break;
-		case sf::Keyboard::Return:
+		case sf::Keyboard::Key::Enter:
 			if (textbuttons[0]->focussed())
 				State::manager.RequestEnterState(*State::manager.PreviousState());
 			else if (textbuttons[1]->focussed())
diff --git a/src/credits.cpp b/src/credits.cpp
index a0e0f23e..b8497dd6 100644
--- a/src/credits.cpp
+++ b/src/credits.cpp
@@ -39,7 +39,7 @@ CCredits Credits;
 static float y_offset = 0;
 static bool moving = true;
 sf::RenderTexture* RT = 0;
-sf::VertexArray arr(sf::Quads, 12);
+sf::VertexArray arr(sf::PrimitiveType::TriangleStrip, 8);
 sf::RenderStates states(sf::BlendAlpha);
 
 void CCredits::LoadCreditList() {
@@ -73,8 +73,7 @@ void CCredits::DrawCreditsText(float time_step) {
 	float offs = 0.f;
 	if (moving) y_offset += time_step * 30;
 
-	sf::Text text;
-	text.setFont(FT.getCurrentFont());
+	sf::Text text(FT.getCurrentFont());
 	RT->clear(colTBackr);
 	for (std::vector<TCredits>::const_iterator i = CreditList.begin(); i != CreditList.end(); ++i) {
 		offs = h - TOP_Y - y_offset + i->offs;
@@ -90,7 +89,7 @@ void CCredits::DrawCreditsText(float time_step) {
 		}
 		text.setCharacterSize(FT.AutoSizeN(i->size)+1);
 		text.setString(i->text);
-		text.setPosition((Winsys.resolution.width - text.getLocalBounds().width) / 2, offs);
+		text.setPosition({(Winsys.resolution.width - text.getLocalBounds().size.x) / 2, offs});
 		RT->draw(text);
 	}
 	RT->display();
@@ -103,10 +102,10 @@ void CCredits::DrawCreditsText(float time_step) {
 void CCredits::Keyb(sf::Keyboard::Key key, bool release, int x, int y) {
 	if (release) return;
 	switch (key) {
-		case sf::Keyboard::M:
+		case sf::Keyboard::Key::M:
 			moving = !moving;
 			break;
-		case sf::Keyboard::U:
+		case sf::Keyboard::Key::U:
 			param.ui_snow = !param.ui_snow;
 			break;
 		default:
@@ -128,25 +127,18 @@ void CCredits::Enter() {
 	Music.Play(param.credits_music, true);
 	y_offset = 0;
 	moving = true;
-	RT = new sf::RenderTexture();
-	RT->create(Winsys.resolution.width, Winsys.resolution.height - TOP_Y - BOTT_Y + 2 * FADE);
+	RT = new sf::RenderTexture({Winsys.resolution.width, Winsys.resolution.height - TOP_Y - BOTT_Y + 2 * FADE});
 
 	float w = Winsys.resolution.width;
 	float h = Winsys.resolution.height;
-	arr[0] = sf::Vertex(sf::Vector2f(0, TOP_Y - FADE), colTBackr, sf::Vector2f(0, 0));
-	arr[1] = sf::Vertex(sf::Vector2f(0, TOP_Y), colWhite, sf::Vector2f(0, FADE));
-	arr[2] = sf::Vertex(sf::Vector2f(w, TOP_Y), colWhite, sf::Vector2f(w, FADE));
-	arr[3] = sf::Vertex(sf::Vector2f(w, TOP_Y - FADE), colTBackr, sf::Vector2f(w, 0));
-
-	arr[4] = sf::Vertex(sf::Vector2f(0, TOP_Y), colWhite, sf::Vector2f(0, FADE));
-	arr[5] = sf::Vertex(sf::Vector2f(0, h - BOTT_Y), colWhite, sf::Vector2f(0, RT->getSize().y - FADE));
-	arr[6] = sf::Vertex(sf::Vector2f(w, h - BOTT_Y), colWhite, sf::Vector2f(w, RT->getSize().y - FADE));
-	arr[7] = sf::Vertex(sf::Vector2f(w, TOP_Y), colWhite, sf::Vector2f(w, FADE));
-
-	arr[8] = sf::Vertex(sf::Vector2f(0, h - BOTT_Y), colWhite, sf::Vector2f(0, RT->getSize().y - FADE));
-	arr[9] = sf::Vertex(sf::Vector2f(0, h - BOTT_Y + FADE), colTBackr, sf::Vector2f(0, RT->getSize().y));
-	arr[10] = sf::Vertex(sf::Vector2f(w, h - BOTT_Y + FADE), colTBackr, sf::Vector2f(w, RT->getSize().y));
-	arr[11] = sf::Vertex(sf::Vector2f(w, h - BOTT_Y), colWhite, sf::Vector2f(w, RT->getSize().y - FADE));
+	arr[0] = sf::Vertex{sf::Vector2f(w, TOP_Y - FADE), colTBackr, sf::Vector2f(w, 0)};
+	arr[1] = sf::Vertex{sf::Vector2f(0, TOP_Y - FADE), colTBackr, sf::Vector2f(0, 0)};
+	arr[2] = sf::Vertex{sf::Vector2f(w, TOP_Y), colWhite, sf::Vector2f(w, FADE)};
+	arr[3] = sf::Vertex{sf::Vector2f(0, TOP_Y), colWhite, sf::Vector2f(0, FADE)};
+	arr[4] = sf::Vertex{sf::Vector2f(w, h - BOTT_Y), colWhite, sf::Vector2f(w, RT->getSize().y - FADE)};
+	arr[5] = sf::Vertex{sf::Vector2f(0, h - BOTT_Y), colWhite, sf::Vector2f(0, RT->getSize().y - FADE)};
+	arr[6] = sf::Vertex{sf::Vector2f(w, h - BOTT_Y + FADE), colTBackr, sf::Vector2f(w, RT->getSize().y)};
+	arr[7] = sf::Vertex{sf::Vector2f(0, h - BOTT_Y + FADE), colTBackr, sf::Vector2f(0, RT->getSize().y)};
 
 	states.texture = &RT->getTexture();
 }
diff --git a/src/event.cpp b/src/event.cpp
index a1f5c48a..33fe410b 100644
--- a/src/event.cpp
+++ b/src/event.cpp
@@ -67,14 +67,14 @@ void StartRace() {
 void CEvent::Keyb(sf::Keyboard::Key key, bool release, int x, int y) {
 	if (release) return;
 	switch (key) {
-		case sf::Keyboard::Return:
+		case sf::Keyboard::Key::Enter:
 			if (textbuttons[0]->focussed() && ready < 1) StartRace();
 			else State::manager.RequestEnterState(EventSelect);
 			break;
-		case sf::Keyboard::Escape:
+		case sf::Keyboard::Key::Escape:
 			State::manager.RequestEnterState(EventSelect);
 			break;
-		case sf::Keyboard::U:
+		case sf::Keyboard::Key::U:
 			param.ui_snow = !param.ui_snow;
 			break;
 		default:
diff --git a/src/event_select.cpp b/src/event_select.cpp
index f954e882..e1f28223 100644
--- a/src/event_select.cpp
+++ b/src/event_select.cpp
@@ -53,17 +53,17 @@ void EnterEvent() {
 void CEventSelect::Keyb(sf::Keyboard::Key key, bool release, int x, int y) {
 	if (release) return;
 	switch (key) {
-		case sf::Keyboard::Escape:
+		case sf::Keyboard::Key::Escape:
 			State::manager.RequestEnterState(GameTypeSelect);
 			break;
-		case sf::Keyboard::Q:
+		case sf::Keyboard::Key::Q:
 			State::manager.RequestQuit();
 			break;
-		case sf::Keyboard::Return:
+		case sf::Keyboard::Key::Enter:
 			if (textbuttons[1]->focussed()) State::manager.RequestEnterState(GameTypeSelect);
 			else if (Events.IsUnlocked(event->GetValue(), cup->GetValue())) EnterEvent();
 			break;
-		case sf::Keyboard::U:
+		case sf::Keyboard::Key::U:
 			param.ui_snow = !param.ui_snow;
 			break;
 		default:
diff --git a/src/font.cpp b/src/font.cpp
index 8a2970f4..8d53f28d 100644
--- a/src/font.cpp
+++ b/src/font.cpp
@@ -110,7 +110,7 @@ void CFont::Clear() {
 
 int CFont::LoadFont(const std::string& name, const std::string& path) {
 	fonts.push_back(new sf::Font());
-	if (!fonts.back()->loadFromFile(path)) {
+	if (!fonts.back()->openFromFile(path)) {
 		Message("Failed to open font");
 		return -1;
 	}
@@ -196,10 +196,10 @@ int CFont::AutoDistanceN(int rel_val) const {
 void CFont::DrawText(float x, float y, const sf::String& text, std::size_t font, unsigned int size) const {
 	if (font >= fonts.size()) return;
 
-	sf::Text temp(text, *fonts[font], size);
+	sf::Text temp(*fonts[font], text, size);
 	if (x == CENTER)
-		x = (Winsys.resolution.width - temp.getLocalBounds().width) / 2;
-	temp.setPosition(x, y);
+		x = (Winsys.resolution.width - temp.getLocalBounds().size.x) / 2;
+	temp.setPosition({x, y});
 	temp.setFillColor(curr_col);
 	temp.setOutlineColor(curr_col);
 	Winsys.draw(temp);
@@ -219,9 +219,9 @@ void CFont::DrawString(float x, float y, const sf::String& s, const std::string
 void CFont::GetTextSize(const sf::String& text, float &x, float &y, std::size_t font, unsigned int size) const {
 	if (font >= fonts.size()) { x = 0; y = 0; return; }
 
-	sf::Text temp(text, *fonts[font], size);
-	x = temp.getGlobalBounds().width;
-	y = temp.getGlobalBounds().height;
+	sf::Text temp(*fonts[font], text, size);
+	x = temp.getGlobalBounds().size.x;
+	y = temp.getGlobalBounds().size.y;
 }
 
 void CFont::GetTextSize(const sf::String& text, float &x, float &y, const std::string &fontname, unsigned int size) const {
diff --git a/src/game_over.cpp b/src/game_over.cpp
index 204db54b..e5cb744c 100644
--- a/src/game_over.cpp
+++ b/src/game_over.cpp
@@ -55,7 +55,7 @@ void QuitGameOver() {
 
 void CGameOver::Keyb(sf::Keyboard::Key key, bool release, int x, int y) {
 	if (release) return;
-	if (key == sf::Keyboard::Enter || key == sf::Keyboard::Escape) QuitGameOver();
+	if (key == sf::Keyboard::Key::Enter || key == sf::Keyboard::Key::Escape) QuitGameOver();
 }
 
 void CGameOver::Mouse(int button, int state, int x, int y) {
diff --git a/src/game_type_select.cpp b/src/game_type_select.cpp
index 169a242f..ef40ce37 100644
--- a/src/game_type_select.cpp
+++ b/src/game_type_select.cpp
@@ -38,7 +38,7 @@ GNU General Public License for more details.
 CGameTypeSelect GameTypeSelect;
 
 static TTextButton* textbuttons[7];
-static sf::Sprite logo;
+static std::optional<sf::Sprite> logo;
 
 void EnterPractice() {
 	g_game.game_type = PRACTICING;
@@ -73,16 +73,16 @@ void CGameTypeSelect::Keyb(sf::Keyboard::Key key, bool release, int x, int y) {
 	if (release) return;
 
 	switch (key) {
-		case sf::Keyboard::U:
+		case sf::Keyboard::Key::U:
 			param.ui_snow = !param.ui_snow;
 			break;
-		case sf::Keyboard::Escape:
+		case sf::Keyboard::Key::Escape:
 			State::manager.RequestQuit();
 			break;
-		case sf::Keyboard::Return:
+		case sf::Keyboard::Key::Enter:
 			QuitGameType();
 			break;
-		case sf::Keyboard::W:
+		case sf::Keyboard::Key::W:
 			Music.FreeMusics();
 			break;
 		default:
@@ -113,9 +113,10 @@ void CGameTypeSelect::Enter() {
 	textbuttons[4] = AddTextButton(Trans.Text(43), CENTER, top + dist * 4, siz);
 	textbuttons[5] = AddTextButton(Trans.Text(4), CENTER, top + dist * 5, siz);
 	textbuttons[6] = AddTextButton(Trans.Text(5), CENTER, top + dist * 6, siz);
-	logo.setTexture(Tex.GetSFTexture(T_TITLE));
-	logo.setScale(Winsys.scale, Winsys.scale);
-	logo.setPosition((Winsys.resolution.width - logo.getTextureRect().width) / 2, (5));
+
+	logo = sf::Sprite(Tex.GetSFTexture(T_TITLE));
+	logo->setScale({Winsys.scale, Winsys.scale});
+	logo->setPosition({(Winsys.resolution.width - logo->getTextureRect().size.x) / 2.0f, (5)});
 
 	Music.Play(param.menu_music, true);
 }
@@ -129,7 +130,7 @@ void CGameTypeSelect::Loop(float time_step) {
 		draw_ui_snow();
 	}
 
-	Winsys.draw(logo);
+	Winsys.draw(*logo);
 	DrawGUIFrame();
 	DrawGUI();
 
diff --git a/src/gui.cpp b/src/gui.cpp
index 77048768..242f0365 100644
--- a/src/gui.cpp
+++ b/src/gui.cpp
@@ -78,11 +78,11 @@ void TWidget::MouseMove(int x, int y) {
 
 TLabel::TLabel(const sf::String& string, int x, int y, const sf::Color& color)
 	: TWidget(x, y, 0, 0, false)
-	, text(string, FT.getCurrentFont(), FT.GetSize()) {
+	, text(FT.getCurrentFont(), string, FT.GetSize()) {
 	if (x == CENTER)
-		text.setPosition((Winsys.resolution.width - text.getLocalBounds().width) / 2, y);
+		text.setPosition({(Winsys.resolution.width - text.getLocalBounds().size.x) / 2, y});
 	else
-		text.setPosition(x, y);
+		text.setPosition(sf::Vector2f(x, y));
 	text.setFillColor(color);
 	text.setOutlineColor(color);
 }
@@ -103,7 +103,7 @@ void TLabel::Draw() const {
 }
 
 sf::Vector2f TLabel::GetSize() const {
-	return sf::Vector2f(text.getLocalBounds().width, text.getLocalBounds().height);
+	return text.getLocalBounds().size;
 
 }
 
@@ -115,9 +115,9 @@ TLabel* AddLabel(const sf::String& string, int x, int y, const sf::Color& color)
 TFramedText::TFramedText(int x, int y, int width, int height, int line, const sf::Color& backcol, const sf::String& string, unsigned int ftsize, bool borderFocus_)
 	: TWidget(x, y, width, height, false)
 	, frame(sf::Vector2f(width - line * 2, height - line * 2))
-	, text(string, FT.getCurrentFont(), ftsize)
+	, text(FT.getCurrentFont(), string, ftsize)
 	, borderFocus(borderFocus_) {
-	text.setPosition(x + line + 20, y + line);
+	text.setPosition(sf::Vector2f(x + line + 20, y + line));
 	if (!borderFocus) {
 		text.setFillColor(colWhite);
 		text.setOutlineColor(colWhite);
@@ -125,7 +125,7 @@ TFramedText::TFramedText(int x, int y, int width, int height, int line, const sf
 		text.setFillColor(colDYell);
 		text.setOutlineColor(colDYell);
 	}
-	frame.setPosition(x + line, y + line);
+	frame.setPosition(sf::Vector2f(x + line, y + line));
 	frame.setOutlineThickness(line);
 	frame.setFillColor(backcol);
 	frame.setOutlineColor(colWhite);
@@ -172,12 +172,12 @@ TFramedText* AddFramedText(int x, int y, int width, int height, int line, const
 
 TTextButton::TTextButton(int x, int y, const sf::String& text_, int ftsize)
 	: TWidget(x, y, 0, 0)
-	, text(text_, FT.getCurrentFont(), ftsize) {
+	, text(FT.getCurrentFont(), text_, ftsize) {
 	if (ftsize < 0) text.setCharacterSize(FT.AutoSizeN(4));
 
-	int len = text.getLocalBounds().width;
+	int len = text.getLocalBounds().size.x;
 	if (x == CENTER) position.x = (Winsys.resolution.width - len) / 2;
-	text.setPosition(position.x, position.y);
+	text.setPosition(sf::Vector2f(position.x, position.y));
 	int offs = ftsize / 5;
 	mouseRect.left = position.x-20;
 	mouseRect.top = position.y+offs;
@@ -211,15 +211,15 @@ TTextButton* AddTextButtonN(const sf::String& text, int x, int y, int rel_ftsize
 
 TTextField::TTextField(int x, int y, int width, int height, const sf::String& text_)
 	: TWidget(x, y, width, height)
-	, text(text_, FT.getCurrentFont(), FT.AutoSizeN(5))
+	, text(FT.getCurrentFont(), text_, FT.AutoSizeN(5))
 	, frame(sf::Vector2f(width-6.f, height-6.f))
 	, cursorShape(sf::Vector2f(2.f, 30.f * Winsys.scale))
 	, maxLng(32)
 	, time(0.0)
 	, cursor(false) {
-	text.setPosition(mouseRect.left + 20, mouseRect.top);
+	text.setPosition(sf::Vector2f(mouseRect.left + 20, mouseRect.top));
 	cursorShape.setFillColor(colYellow);
-	frame.setPosition(x + 3, y + 3);
+	frame.setPosition(sf::Vector2f(x + 3, y + 3));
 	frame.setOutlineThickness(3);
 	frame.setFillColor(colMBackgr);
 	frame.setOutlineColor(colWhite);
@@ -244,7 +244,7 @@ void TTextField::TextEnter(char c) {
 
 void TTextField::SetCursorPos(std::size_t new_pos) {
 	cursorPos = new_pos;
-	cursorShape.setPosition(text.findCharacterPos(cursorPos).x, mouseRect.top + 9);
+	cursorShape.setPosition(sf::Vector2f(text.findCharacterPos(cursorPos).x, mouseRect.top + 9));
 }
 
 void TTextField::Focussed() {
@@ -270,7 +270,7 @@ bool TTextField::Click(int x, int y) {
 			cursorPos++;
 			first = second;
 		}
-		cursorShape.setPosition(text.findCharacterPos(cursorPos).x, mouseRect.top + 9);
+		cursorShape.setPosition(sf::Vector2f(text.findCharacterPos(cursorPos).x, mouseRect.top + 9));
 		return true;
 	}
 	return false;
@@ -283,22 +283,22 @@ static void eraseFromText(sf::Text& text, std::size_t pos) {
 }
 void TTextField::Key(sf::Keyboard::Key key, bool released) {
 	switch (key) {
-		case sf::Keyboard::Delete:
+		case sf::Keyboard::Key::Delete:
 			if (cursorPos < text.getString().getSize()) eraseFromText(text, cursorPos);
 			break;
-		case sf::Keyboard::BackSpace:
+		case sf::Keyboard::Key::Backspace:
 			if (cursorPos > 0) { eraseFromText(text, cursorPos-1); SetCursorPos(cursorPos - 1); }
 			break;
-		case sf::Keyboard::Right:
+		case sf::Keyboard::Key::Right:
 			if (cursorPos < text.getString().getSize()) SetCursorPos(cursorPos + 1);
 			break;
-		case sf::Keyboard::Left:
+		case sf::Keyboard::Key::Left:
 			if (cursorPos > 0) SetCursorPos(cursorPos - 1);
 			break;
-		case sf::Keyboard::Home:
+		case sf::Keyboard::Key::Home:
 			SetCursorPos(0);
 			break;
-		case sf::Keyboard::End:
+		case sf::Keyboard::Key::End:
 			SetCursorPos(text.getString().getSize());
 			break;
 		default:
@@ -321,22 +321,22 @@ TTextField* AddTextField(const sf::String& text, int x, int y, int width, int he
 
 TCheckbox::TCheckbox(int x, int y, int width, const sf::String& tag_)
 	: TWidget(x, y, 32 * Winsys.scale / 0.8f, 32 * Winsys.scale / 0.8f)
-	, text(tag_, FT.getCurrentFont(), FT.GetSize())
+	, text(FT.getCurrentFont(), tag_, FT.GetSize())
 	, back(Tex.GetSFTexture(CHECKBOX))
 	, checkmark(Tex.GetSFTexture(CHECKMARK_SMALL))
 	, checked(false) {
-	text.setPosition(x, y);
-	back.setPosition(x + width - 32, y);
-	checkmark.setPosition(x + width - 32, y);
+	text.setPosition(sf::Vector2f(x, y));
+	back.setPosition(sf::Vector2f(x + width - 32, y));
+	checkmark.setPosition(sf::Vector2f(x + width - 32, y));
 	mouseRect.left = x + width - 32;
-	back.setScale(Winsys.scale / 0.8f, Winsys.scale / 0.8f);
-	checkmark.setScale(Winsys.scale / 0.8f, Winsys.scale / 0.8f);
+	back.setScale({Winsys.scale / 0.8f, Winsys.scale / 0.8f});
+	checkmark.setScale({Winsys.scale / 0.8f, Winsys.scale / 0.8f});
 }
 
 void TCheckbox::SetPosition(int x, int y) {
-	text.setPosition(x, y);
-	back.setPosition(x, y);
-	checkmark.setPosition(x, y);
+	text.setPosition(sf::Vector2f(x, y));
+	back.setPosition(sf::Vector2f(x, y));
+	checkmark.setPosition(sf::Vector2f(x, y));
 }
 
 void TCheckbox::Focussed() {
@@ -367,7 +367,7 @@ bool TCheckbox::Click(int x, int y) {
 void TCheckbox::Key(sf::Keyboard::Key key, bool released) {
 	if (released) return;
 
-	if (key == sf::Keyboard::Space || key == sf::Keyboard::Return) {
+	if (key == sf::Keyboard::Key::Space || key == sf::Keyboard::Key::Enter) {
 		checked = !checked;
 	}
 }
@@ -383,9 +383,9 @@ TIconButton::TIconButton(int x, int y, const sf::Texture& texture, float size_,
 	, size(size_)
 	, maximum(max_)
 	, value(value_) {
-	sprite.setScale(size / (texture.getSize().x / 2.f), size / (texture.getSize().y / 2.f));
-	sprite.setPosition(x, y);
-	frame.setPosition(x, y);
+	sprite.setScale({size / (texture.getSize().x / 2.f), size / (texture.getSize().y / 2.f)});
+	sprite.setPosition(sf::Vector2f(x, y));
+	frame.setPosition(sf::Vector2f(x, y));
 	frame.setOutlineColor(colWhite);
 	frame.setOutlineThickness(3.f);
 	SetValue(value_);
@@ -398,19 +398,19 @@ void TIconButton::SetValue(int _value) {
 	else if (value < 0)
 		value = maximum;
 
-	sf::Vector2u texSize = sprite.getTexture()->getSize();
+	sf::Vector2i texSize(sprite.getTexture().getSize());
 	switch (value) {
 		case 0:
-			sprite.setTextureRect(sf::IntRect(0, 0, texSize.x / 2, texSize.y / 2));
+			sprite.setTextureRect(sf::IntRect({0, 0}, texSize / 2));
 			break;
 		case 1:
-			sprite.setTextureRect(sf::IntRect(texSize.x / 2, 0, texSize.x / 2, texSize.y / 2));
+			sprite.setTextureRect(sf::IntRect({texSize.x / 2, 0}, texSize / 2));
 			break;
 		case 2:
-			sprite.setTextureRect(sf::IntRect(0, texSize.y / 2, texSize.x / 2, texSize.y / 2));
+			sprite.setTextureRect(sf::IntRect({0, texSize.y / 2}, texSize / 2));
 			break;
 		case 3:
-			sprite.setTextureRect(sf::IntRect(texSize.x / 2, texSize.y / 2, texSize.x / 2, texSize.y / 2));
+			sprite.setTextureRect(sf::IntRect(texSize / 2, texSize / 2));
 			break;
 	}
 }
@@ -438,9 +438,9 @@ bool TIconButton::Click(int x, int y) {
 void TIconButton::Key(sf::Keyboard::Key key, bool released) {
 	if (released) return;
 
-	if (key == sf::Keyboard::Down) { // Arrow down/left
+	if (key == sf::Keyboard::Key::Down) { // Arrow down/left
 		SetValue(value - 1);
-	} else if (key == sf::Keyboard::Up) { // Arrow up/right
+	} else if (key == sf::Keyboard::Key::Up) { // Arrow up/right
 		SetValue(value + 1);
 	}
 }
@@ -454,8 +454,8 @@ TArrow::TArrow(int x, int y, bool down_)
 	: TWidget(x, y, 32 * Winsys.scale / 0.8f, 16 * Winsys.scale / 0.8f)
 	, sprite(Tex.GetSFTexture(LB_ARROWS))
 	, down(down_) {
-	sprite.setPosition(x, y);
-	sprite.setScale(Winsys.scale / 0.8f, Winsys.scale / 0.8f);
+	sprite.setPosition(sf::Vector2f(x, y));
+	sprite.setScale({Winsys.scale / 0.8f, Winsys.scale / 0.8f});
 
 	SetTexture();
 }
@@ -480,8 +480,8 @@ void TArrow::SetTexture() {
 	if (down)
 		type += 3;
 
-	sf::Vector2u texSize = sprite.getTexture()->getSize();
-	sprite.setTextureRect(sf::IntRect(textl[type] * texSize.x, texbr[type] * texSize.y, texSize.x / 2, texSize.y / 4));
+	sf::Vector2i texSize(sprite.getTexture().getSize());
+	sprite.setTextureRect(sf::IntRect({textl[type] * texSize.x, texbr[type] * texSize.y}, {texSize.x / 2, texSize.y / 4}));
 }
 
 void TArrow::Draw() const {
@@ -533,14 +533,14 @@ bool TUpDown::Click(int x, int y) {
 void TUpDown::Key(sf::Keyboard::Key key, bool released) {
 	if (released) return;
 
-	if ((!swapArrows && key == sf::Keyboard::Up) || (swapArrows && key == sf::Keyboard::Down)) { // Arrow up
+	if ((!swapArrows && key == sf::Keyboard::Key::Up) || (swapArrows && key == sf::Keyboard::Key::Down)) { // Arrow up
 		if (value > minimum) {
 			value--;
 			lower.SetActive(true);
 			if (value == minimum)
 				higher.SetActive(false);
 		}
-	} else if ((!swapArrows && key == sf::Keyboard::Down) || (swapArrows && key == sf::Keyboard::Up)) { // Arrow down
+	} else if ((!swapArrows && key == sf::Keyboard::Key::Down) || (swapArrows && key == sf::Keyboard::Key::Up)) { // Arrow down
 		if (value < maximum) {
 			value++;
 			higher.SetActive(true);
@@ -590,7 +590,7 @@ void DrawFrameX(int x, int y, int w, int h, int line, const sf::Color& backcol,
 	w -= line * 2;
 	h -= line * 2;
 	sf::RectangleShape shape(sf::Vector2f(w, h));
-	shape.setPosition(x, y);
+	shape.setPosition(sf::Vector2f(x, y));
 	shape.setOutlineThickness(line);
 	shape.setFillColor(sf::Color(backcol.r, backcol.g, backcol.b, backcol.a * transp));
 	shape.setOutlineColor(sf::Color(framecol.r, framecol.g, framecol.b, framecol.a * transp));
@@ -617,8 +617,8 @@ void DrawBonusExt(int y, std::size_t numraces, std::size_t num) {
 	DrawFrameX(lleft[2], y, framewidth, 40, 1, col2, colBlack, 1);
 
 	static sf::Sprite tuxbonus(Tex.GetSFTexture(TUXBONUS));
-	sf::Vector2u size = tuxbonus.getTexture()->getSize();
-	tuxbonus.setTextureRect(sf::IntRect(0, 0, size.x, size.y/2));
+	sf::Vector2i size(tuxbonus.getTexture().getSize());
+	tuxbonus.setTextureRect(sf::IntRect({0, 0}, {size.x, size.y/2}));
 
 	for (std::size_t i=0; i<maxtux; i++) {
 		std::size_t majr = (i/numraces);
@@ -627,7 +627,7 @@ void DrawBonusExt(int y, std::size_t numraces, std::size_t num) {
 		int x = lleft[majr] + (int)minr * 40 + 6;
 
 		if (i<num) {
-			tuxbonus.setPosition(x, y + 4);
+			tuxbonus.setPosition(sf::Vector2f(x, y + 4));
 			Winsys.draw(tuxbonus);
 		}
 	}
@@ -639,9 +639,9 @@ void DrawGUIFrame() {
 	static sf::Sprite top_left(Tex.GetSFTexture(TOP_LEFT));
 	static sf::Sprite top_right(Tex.GetSFTexture(TOP_RIGHT));
 
-	bottom_left.setPosition(0, Winsys.resolution.height - bottom_left.getTexture()->getSize().y);
-	bottom_right.setPosition(Winsys.resolution.width - bottom_right.getTexture()->getSize().x, Winsys.resolution.height - bottom_right.getTexture()->getSize().y);
-	top_right.setPosition(Winsys.resolution.width - top_right.getTexture()->getSize().x, 0);
+	bottom_left.setPosition(sf::Vector2f(0, Winsys.resolution.height - bottom_left.getTexture().getSize().y));
+	bottom_right.setPosition(sf::Vector2f(Winsys.resolution.width - bottom_right.getTexture().getSize().x, Winsys.resolution.height - bottom_right.getTexture().getSize().y));
+	top_right.setPosition(sf::Vector2f(Winsys.resolution.width - top_right.getTexture().getSize().x, 0));
 
 	Winsys.draw(bottom_left);
 	Winsys.draw(bottom_right);
@@ -654,8 +654,8 @@ void DrawGUIBackground(float scale) {
 
 	static sf::Sprite logo(Tex.GetSFTexture(T_TITLE));
 	scale *= 0.5f;
-	logo.setScale(scale, scale);
-	logo.setPosition((Winsys.resolution.width - logo.getTextureRect().width*scale)/2, 5);
+	logo.setScale({scale, scale});
+	logo.setPosition({(Winsys.resolution.width - logo.getTextureRect().size.x*scale)/2, 5});
 	Winsys.draw(logo);
 }
 
@@ -663,10 +663,10 @@ void DrawCursor() {
 	static sf::Sprite s(Tex.GetSFTexture(MOUSECURSOR));
 	static bool init = false;
 	if (!init) {
-		s.setScale((double) Winsys.resolution.width / 1400, (double) Winsys.resolution.width / 1400);
+		s.setScale(sf::Vector2f((double) Winsys.resolution.width / 1400, (double) Winsys.resolution.width / 1400));
 		init = true;
 	}
-	s.setPosition(cursor_pos.x, cursor_pos.y);
+	s.setPosition(sf::Vector2f(cursor_pos.x, cursor_pos.y));
 	Winsys.draw(s);
 }
 
@@ -716,25 +716,25 @@ TWidget* MouseMoveGUI(int x, int y) {
 TWidget* KeyGUI(sf::Keyboard::Key key, bool released) {
 	if (!released) {
 		switch (key) {
-			case sf::Keyboard::Tab:
-				if (sf::Keyboard::isKeyPressed(sf::Keyboard::LShift) || sf::Keyboard::isKeyPressed(sf::Keyboard::RShift))
+			case sf::Keyboard::Key::Tab:
+				if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::LShift) || sf::Keyboard::isKeyPressed(sf::Keyboard::Key::RShift))
 					DecreaseFocus();
 				else
 					IncreaseFocus();
 				break;
-			case sf::Keyboard::Up:
+			case sf::Keyboard::Key::Up:
 				if (!locked_UD)
 					DecreaseFocus();
 				break;
-			case sf::Keyboard::Left:
+			case sf::Keyboard::Key::Left:
 				if (!locked_LR)
 					DecreaseFocus();
 				break;
-			case sf::Keyboard::Down:
+			case sf::Keyboard::Key::Down:
 				if (!locked_UD)
 					IncreaseFocus();
 				break;
-			case sf::Keyboard::Right:
+			case sf::Keyboard::Key::Right:
 				if (!locked_LR)
 					IncreaseFocus();
 				break;
diff --git a/src/loading.cpp b/src/loading.cpp
index 5fa02b78..3f4923c7 100644
--- a/src/loading.cpp
+++ b/src/loading.cpp
@@ -50,8 +50,8 @@ void CLoading::Loop(float time_step) {
 	}
 
 	sf::Sprite logo(Tex.GetSFTexture(TEXLOGO));
-	logo.setScale(0.35f, 0.35f);
-	logo.setPosition((Winsys.resolution.width - logo.getTextureRect().width*0.35f) / 2, 40);
+	logo.setScale({0.35f, 0.35f});
+	logo.setPosition({(Winsys.resolution.width - logo.getTextureRect().size.x*0.35f) / 2, 40});
 	Winsys.draw(logo);
 	DrawGUIFrame();
 
diff --git a/src/newplayer.cpp b/src/newplayer.cpp
index 073e6eab..169077d1 100644
--- a/src/newplayer.cpp
+++ b/src/newplayer.cpp
@@ -49,10 +49,10 @@ void CNewPlayer::Keyb(sf::Keyboard::Key key, bool release, int x, int y) {
 
 	KeyGUI(key, release);
 	switch (key) {
-		case sf::Keyboard::Escape:
+		case sf::Keyboard::Key::Escape:
 			State::manager.RequestEnterState(Regist);
 			break;
-		case sf::Keyboard::Return:
+		case sf::Keyboard::Key::Enter:
 			if (textbuttons[0]->focussed()) State::manager.RequestEnterState(Regist);
 			else QuitAndAddPlayer();
 			break;
diff --git a/src/ogl_test.cpp b/src/ogl_test.cpp
index b0994823..f3df64da 100644
--- a/src/ogl_test.cpp
+++ b/src/ogl_test.cpp
@@ -45,7 +45,7 @@ void SetTestLight() {
 
 void COglTest::Keyb(sf::Keyboard::Key key, bool release, int x, int y) {
 	if (release) return;
-	if (key == sf::Keyboard::Escape) {
+	if (key == sf::Keyboard::Key::Escape) {
 		State::manager.RequestQuit();
 	}
 }
diff --git a/src/particles.cpp b/src/particles.cpp
index 459149ed..39589ce4 100644
--- a/src/particles.cpp
+++ b/src/particles.cpp
@@ -66,32 +66,31 @@ static TVector2d push_position(0, 0);
 static TVector2d last_push_position;
 static bool push_position_initialized = false;
 
-TGuiParticle::TGuiParticle(float x, float y) {
-	const sf::Texture& texture = Tex.GetSFTexture(SNOW_PART);
-	sprite.setTexture(texture);
-	sprite.setPosition(x*static_cast<float>(Winsys.resolution.width), y*static_cast<float>(Winsys.resolution.height));
+TGuiParticle::TGuiParticle(float x, float y) : sprite(Tex.GetSFTexture(SNOW_PART)) {
+	const sf::Vector2i tex_size(sprite.getTexture().getSize());
+	sprite.setPosition({x*static_cast<float>(Winsys.resolution.width), y*static_cast<float>(Winsys.resolution.height)});
 	sprite.setColor(sf::Color(255, 255, 255, 76));
 	double p_dist = FRandom();
 
 	size = PARTICLE_MIN_SIZE + (1.0 - p_dist) * PARTICLE_SIZE_RANGE;
 
-	sprite.setScale(size / (texture.getSize().x / 2), size / (texture.getSize().y / 2));
+	sprite.setScale({size / (tex_size.x / 2.0f), size / (tex_size.y / 2.0f)});
 	vel.x = 0;
 	vel.y = BASE_VELOCITY + p_dist * VELOCITY_RANGE;
 
 	int type = std::rand() % 4;
 	switch (type) {
 		case 0:
-			sprite.setTextureRect(sf::IntRect(0, 0, texture.getSize().x / 2, texture.getSize().y / 2));
+			sprite.setTextureRect(sf::IntRect({0, 0}, tex_size / 2));
 			break;
 		case 1:
-			sprite.setTextureRect(sf::IntRect(texture.getSize().x / 2, 0, texture.getSize().x / 2, texture.getSize().y / 2));
+			sprite.setTextureRect(sf::IntRect({tex_size.x / 2, 0}, tex_size / 2));
 			break;
 		case 2:
-			sprite.setTextureRect(sf::IntRect(texture.getSize().x / 2, texture.getSize().y / 2, texture.getSize().x / 2, texture.getSize().y / 2));
+			sprite.setTextureRect(sf::IntRect(tex_size / 2, tex_size / 2));
 			break;
 		case 3:
-			sprite.setTextureRect(sf::IntRect(0, texture.getSize().y / 2, texture.getSize().x / 2, texture.getSize().y / 2));
+			sprite.setTextureRect(sf::IntRect({0, tex_size.y / 2}, tex_size / 2));
 			break;
 	}
 }
@@ -122,7 +121,7 @@ void TGuiParticle::Update(float time_step, float push_timestep, const TVector2d&
 	y += vel.y * time_step * (size / PARTICLE_SIZE_RANGE);
 
 	x = clamp(-0.05f, x, 1.05f);
-	sprite.setPosition(x*Winsys.resolution.width, y*Winsys.resolution.height);
+	sprite.setPosition({x*Winsys.resolution.width, y*Winsys.resolution.height});
 }
 
 void init_ui_snow() {
@@ -159,10 +158,10 @@ void update_ui_snow(float time_step) {
 			if (particles_2d.size() > BASE_snowparticles * Winsys.resolution.width && FRandom() > 0.2) {
 				p = particles_2d.erase(p);
 			} else {
-				p->sprite.setPosition(static_cast<float>(Winsys.resolution.width)*FRandom(), static_cast<float>(Winsys.resolution.height) * (-FRandom()*BASE_VELOCITY));
+				p->sprite.setPosition(sf::Vector2f(static_cast<float>(Winsys.resolution.width)*FRandom(), static_cast<float>(Winsys.resolution.height) * (-FRandom()*BASE_VELOCITY)));
 				double p_dist = FRandom();
 				p->size = PARTICLE_MIN_SIZE + (1.f - p_dist) * PARTICLE_SIZE_RANGE;
-				p->sprite.setScale(p->size / (p->sprite.getTexture()->getSize().x / 2), p->size / (p->sprite.getTexture()->getSize().x / 2));
+				p->sprite.setScale({p->size / (p->sprite.getTexture().getSize().x / 2.0f), p->size / (p->sprite.getTexture().getSize().x / 2.0f)});
 				p->vel.x = 0;
 				p->vel.y = BASE_VELOCITY + p_dist*VELOCITY_RANGE;
 				++p;
diff --git a/src/paused.cpp b/src/paused.cpp
index cba005a9..355740b1 100644
--- a/src/paused.cpp
+++ b/src/paused.cpp
@@ -45,19 +45,19 @@ static bool trees = true;
 void CPaused::Keyb(sf::Keyboard::Key key, bool release, int x, int y) {
 	if (release) return;
 	switch (key) {
-		case sf::Keyboard::C:
+		case sf::Keyboard::Key::C:
 			Winsys.TakeScreenshot();
 			break;
-		case sf::Keyboard::F5:
+		case sf::Keyboard::Key::F5:
 			sky = !sky;
 			break;
-		case sf::Keyboard::F6:
+		case sf::Keyboard::Key::F6:
 			fog = !fog;
 			break;
-		case sf::Keyboard::F7:
+		case sf::Keyboard::Key::F7:
 			terr = !terr;
 			break;
-		case sf::Keyboard::F8:
+		case sf::Keyboard::Key::F8:
 			trees = !trees;
 			break;
 		default:
diff --git a/src/race_select.cpp b/src/race_select.cpp
index a8cf688b..ca073ac5 100644
--- a/src/race_select.cpp
+++ b/src/race_select.cpp
@@ -109,24 +109,24 @@ void CRaceSelect::Keyb(sf::Keyboard::Key key, bool release, int x, int y) {
 	KeyGUI(key, release);
 	UpdateInfo();
 	switch (key) {
-		case sf::Keyboard::Escape:
+		case sf::Keyboard::Key::Escape:
 			State::manager.RequestEnterState(GameTypeSelect);
 			break;
-		case sf::Keyboard::U:
+		case sf::Keyboard::Key::U:
 			param.ui_snow = !param.ui_snow;
 			break;
-		case sf::Keyboard::T:
+		case sf::Keyboard::Key::T:
 			g_game.force_treemap = !g_game.force_treemap;
 			break;
-		case sf::Keyboard::C:
+		case sf::Keyboard::Key::C:
 			g_game.treesize++;
 			if (g_game.treesize > 5) g_game.treesize = 1;
 			break;
-		case sf::Keyboard::V:
+		case sf::Keyboard::Key::V:
 			g_game.treevar++;
 			if (g_game.treevar > 5) g_game.treevar = 1;
 			break;
-		case sf::Keyboard::Return:
+		case sf::Keyboard::Key::Enter:
 			if (textbuttons[1]->focussed())
 				State::manager.RequestEnterState(GameTypeSelect);
 			else
diff --git a/src/racing.cpp b/src/racing.cpp
index e5ea391d..a26a69c2 100644
--- a/src/racing.cpp
+++ b/src/racing.cpp
@@ -69,61 +69,61 @@ static int lastsound = -1;
 void CRacing::Keyb(sf::Keyboard::Key key, bool release, int x, int y) {
 	switch (key) {
 		// steering flipflops
-		case sf::Keyboard::Up:
-                case sf::Keyboard::W:
+		case sf::Keyboard::Key::Up:
+		case sf::Keyboard::Key::W:
 			key_paddling = !release;
 			break;
-		case sf::Keyboard::Down:
-                case sf::Keyboard::S:
+		case sf::Keyboard::Key::Down:
+		case sf::Keyboard::Key::S:
 			key_braking = !release;
 			break;
-		case sf::Keyboard::Left:
-                case sf::Keyboard::A:
+		case sf::Keyboard::Key::Left:
+		case sf::Keyboard::Key::A:
 			left_turn = !release;
 			break;
-		case sf::Keyboard::Right:
-                case sf::Keyboard::D:
+		case sf::Keyboard::Key::Right:
+		case sf::Keyboard::Key::D:
 			right_turn = !release;
 			break;
-		case sf::Keyboard::Space:
+		case sf::Keyboard::Key::Space:
 			key_charging = !release;
 			break;
-		case sf::Keyboard::T:
+		case sf::Keyboard::Key::T:
 			trick_modifier = !release;
 			break;
 
 		// mode changing and other actions
-		case sf::Keyboard::Escape:
+		case sf::Keyboard::Key::Escape:
 			if (!release) {
 				g_game.raceaborted = true;
 				g_game.race_result = -1;
 				State::manager.RequestEnterState(GameOver);
 			}
 			break;
-		case sf::Keyboard::P:
+		case sf::Keyboard::Key::P:
 			if (!release) State::manager.RequestEnterState(Paused);
 			break;
-		case sf::Keyboard::R:
+		case sf::Keyboard::Key::R:
 			if (!release) State::manager.RequestEnterState(Reset);
 			break;
-		case sf::Keyboard::C:
+		case sf::Keyboard::Key::C:
 			if (!release) Winsys.TakeScreenshot();
 			break;
 
 		// view changing
-		case sf::Keyboard::Num1:
+		case sf::Keyboard::Key::Num1:
 			if (!release) {
 				set_view_mode(g_game.player->ctrl, ABOVE);
 				param.view_mode = ABOVE;
 			}
 			break;
-		case sf::Keyboard::Num2:
+		case sf::Keyboard::Key::Num2:
 			if (!release) {
 				set_view_mode(g_game.player->ctrl, FOLLOW);
 				param.view_mode = FOLLOW;
 			}
 			break;
-		case sf::Keyboard::Num3:
+		case sf::Keyboard::Key::Num3:
 			if (!release) {
 				set_view_mode(g_game.player->ctrl, BEHIND);
 				param.view_mode = BEHIND;
@@ -131,22 +131,22 @@ void CRacing::Keyb(sf::Keyboard::Key key, bool release, int x, int y) {
 			break;
 
 		// toggle display settings
-		case sf::Keyboard::H:
+		case sf::Keyboard::Key::H:
 			if (!release) param.show_hud = !param.show_hud;
 			break;
-		case sf::Keyboard::F:
+		case sf::Keyboard::Key::F:
 			if (!release) param.display_fps = !param.display_fps;
 			break;
-		case sf::Keyboard::F5:
+		case sf::Keyboard::Key::F5:
 			if (!release) sky = !sky;
 			break;
-		case sf::Keyboard::F6:
+		case sf::Keyboard::Key::F6:
 			if (!release) fog = !fog;
 			break;
-		case sf::Keyboard::F7:
+		case sf::Keyboard::Key::F7:
 			if (!release) terr = !terr;
 			break;
-		case sf::Keyboard::F8:
+		case sf::Keyboard::Key::F8:
 			if (!release) trees = !trees;
 			break;
 		default:
diff --git a/src/regist.cpp b/src/regist.cpp
index e9f249c3..4710025a 100644
--- a/src/regist.cpp
+++ b/src/regist.cpp
@@ -52,10 +52,10 @@ void CRegist::Keyb(sf::Keyboard::Key key, bool release, int x, int y) {
 	TWidget* focussed = KeyGUI(key, release);
 	if (release) return;
 	switch (key) {
-		case sf::Keyboard::Escape:
+		case sf::Keyboard::Key::Escape:
 			State::manager.RequestQuit();
 			break;
-		case sf::Keyboard::Return:
+		case sf::Keyboard::Key::Enter:
 			if (focussed == textbuttons[1]) {
 				g_game.player = Players.GetPlayer(player->GetValue());
 				State::manager.RequestEnterState(NewPlayer);
diff --git a/src/score.cpp b/src/score.cpp
index c1cabda3..e35b9431 100644
--- a/src/score.cpp
+++ b/src/score.cpp
@@ -175,19 +175,19 @@ void CScore::Keyb(sf::Keyboard::Key key, bool release, int x, int y) {
 	KeyGUI(key, release);
 	if (release) return;
 	switch (key) {
-		case sf::Keyboard::Escape:
+		case sf::Keyboard::Key::Escape:
 			State::manager.RequestEnterState(*State::manager.PreviousState());
 			break;
-		case sf::Keyboard::Q:
+		case sf::Keyboard::Key::Q:
 			State::manager.RequestQuit();
 			break;
-		case sf::Keyboard::S:
+		case sf::Keyboard::Key::S:
 			Score.SaveHighScore();
 			break;
-		case sf::Keyboard::L:
+		case sf::Keyboard::Key::L:
 			Score.LoadHighScore();
 			break;
-		case sf::Keyboard::Return:
+		case sf::Keyboard::Key::Enter:
 			State::manager.RequestEnterState(*State::manager.PreviousState());
 			break;
 		default:
diff --git a/src/splash_screen.cpp b/src/splash_screen.cpp
index 87f761ff..a23255d7 100644
--- a/src/splash_screen.cpp
+++ b/src/splash_screen.cpp
@@ -50,17 +50,17 @@ void CSplashScreen::Loop(float time_step) {
 	Trans.LoadTranslations(param.language);  // Before first texts are being displayed
 
 	sf::Sprite logo(Tex.GetSFTexture(TEXLOGO));
-	logo.setScale(Winsys.scale/2.f, Winsys.scale/2.f);
-	logo.setPosition((Winsys.resolution.width - logo.getTextureRect().width*(Winsys.scale / 2)) / 2, 60);
+	logo.setScale({Winsys.scale/2.f, Winsys.scale/2.f});
+	logo.setPosition({(Winsys.resolution.width - logo.getTextureRect().size.x*(Winsys.scale / 2)) / 2, 60});
 
 	if (!Failure) {
 		FT.AutoSizeN(6);
-		sf::Text t1(Trans.Text(67), FT.getCurrentFont(), FT.GetSize());
+		sf::Text t1(FT.getCurrentFont(), Trans.Text(67), FT.GetSize());
 		int top = AutoYPosN(60);
-		t1.setPosition((Winsys.resolution.width - t1.getLocalBounds().width) / 2, top);
-		sf::Text t2(Trans.Text(68), FT.getCurrentFont(), FT.GetSize());
+		t1.setPosition(sf::Vector2f((Winsys.resolution.width - t1.getLocalBounds().size.x) / 2, top));
+		sf::Text t2(FT.getCurrentFont(), Trans.Text(68), FT.GetSize());
 		int dist = FT.AutoDistanceN(3);
-		t2.setPosition((Winsys.resolution.width - t2.getLocalBounds().width) / 2, top + dist);
+		t2.setPosition(sf::Vector2f((Winsys.resolution.width - t2.getLocalBounds().size.x) / 2, top + dist));
 
 		Winsys.draw(t1);
 		Winsys.draw(t2);
@@ -99,10 +99,10 @@ void CSplashScreen::Loop(float time_step) {
 		else { // Failure
 			FT.AutoSizeN(6);
 			int top = AutoYPosN(60);
-			Failure = new sf::Text(reason, FT.getCurrentFont(), FT.GetSize());
+			Failure = new sf::Text(FT.getCurrentFont(), reason, FT.GetSize());
 			Failure->setFillColor(colDRed);
 			Failure->setOutlineColor(colDRed);
-			Failure->setPosition((Winsys.resolution.width - Failure->getLocalBounds().width) / 2, top);
+			Failure->setPosition(sf::Vector2f((Winsys.resolution.width - Failure->getLocalBounds().size.x) / 2, top));
 		}
 	}
 }
diff --git a/src/states.cpp b/src/states.cpp
index 935e9c40..6a671ba7 100644
--- a/src/states.cpp
+++ b/src/states.cpp
@@ -53,63 +53,38 @@ void State::Manager::EnterNextState() {
 }
 
 void State::Manager::PollEvent() {
-	sf::Event event;
-	sf::Keyboard::Key key;
-
-	while (Winsys.PollEvent(event)) {
+	while (const auto event = Winsys.PollEvent()) {
 		if (!next) {
-			switch (event.type) {
-				case sf::Event::KeyPressed:
-					key = event.key.code;
-					current->Keyb(key, false, sf::Mouse::getPosition().x, sf::Mouse::getPosition().y);
-					break;
-
-				case sf::Event::KeyReleased:
-					key = event.key.code;
-					current->Keyb(key, true, sf::Mouse::getPosition().x, sf::Mouse::getPosition().y);
-					break;
-
-				case sf::Event::TextEntered:
-					current->TextEntered(static_cast<char>(event.text.unicode));
-					break;
-
-				case sf::Event::MouseButtonPressed:
-				case sf::Event::MouseButtonReleased:
-					current->Mouse(event.mouseButton.button, event.type == sf::Event::MouseButtonPressed, event.mouseButton.x, event.mouseButton.y);
-					break;
-
-				case sf::Event::MouseMoved: {
-					TVector2i old = cursor_pos;
-					cursor_pos.x = event.mouseMove.x;
-					cursor_pos.y = event.mouseMove.y;
-					current->Motion(event.mouseMove.x - old.x, event.mouseMove.y - old.y);
-					break;
+			if (const auto *keyPressed = event->getIf<sf::Event::KeyPressed>()) {
+				current->Keyb(keyPressed->code, false, sf::Mouse::getPosition().x, sf::Mouse::getPosition().y);
+			} else if (const auto *keyReleased = event->getIf<sf::Event::KeyReleased>()) {
+				current->Keyb(keyReleased->code, true, sf::Mouse::getPosition().x, sf::Mouse::getPosition().y);
+			} else if (const auto *textEntered = event->getIf<sf::Event::TextEntered>()) {
+				current->TextEntered(static_cast<char>(textEntered->unicode));
+			} else if (const auto *mousePressed = event->getIf<sf::Event::MouseButtonPressed>()) {
+				current->Mouse(static_cast<int>(mousePressed->button), true, mousePressed->position.x, mousePressed->position.y);
+			} else if (const auto *mouseReleased = event->getIf<sf::Event::MouseButtonReleased>()) {
+				current->Mouse(static_cast<int>(mouseReleased->button), false, mouseReleased->position.x, mouseReleased->position.y);
+			} else if (const auto *mouseMoved = event->getIf<sf::Event::MouseMoved>()) {
+				TVector2i old = cursor_pos;
+				cursor_pos.x = mouseMoved->position.x;
+				cursor_pos.y = mouseMoved->position.y;
+				current->Motion(mouseMoved->position.x - old.x, mouseMoved->position.y - old.y);
+			} else if (const auto *joystickMoved = event->getIf<sf::Event::JoystickMoved>()) {
+				float val = joystickMoved->position / 100.f;
+				current->Jaxis(joystickMoved->axis == sf::Joystick::Axis::X ? 0 : 1, val);
+			} else if (const auto *joystickPressed = event->getIf<sf::Event::JoystickButtonPressed>()) {
+				current->Jbutt(joystickPressed->button, true);
+			} else if (const auto *joystickReleased = event->getIf<sf::Event::JoystickButtonReleased>()) {
+				current->Jbutt(joystickReleased->button, false);
+			} else if (const auto *resized = event->getIf<sf::Event::Resized>()) {
+				if (Winsys.resolution.width != resized->size.x || Winsys.resolution.height != resized->size.y) {
+					Winsys.resolution.width = resized->size.x;
+					Winsys.resolution.height = resized->size.y;
+					Winsys.SetupVideoMode(resized->size.x, resized->size.y);
 				}
-
-				case sf::Event::JoystickMoved: {
-					float val = event.joystickMove.position / 100.f;
-					current->Jaxis(event.joystickMove.axis == sf::Joystick::X ? 0 : 1, val);
-					break;
-				}
-				case sf::Event::JoystickButtonPressed:
-				case sf::Event::JoystickButtonReleased:
-					current->Jbutt(event.joystickButton.button, event.type == sf::Event::JoystickButtonPressed);
-					break;
-
-				case sf::Event::Resized:
-					if (Winsys.resolution.width != event.size.width || Winsys.resolution.height != event.size.height) {
-						Winsys.resolution.width = event.size.width;
-						Winsys.resolution.height = event.size.height;
-						Winsys.SetupVideoMode(event.size.width, event.size.height);
-					}
-					break;
-
-				case sf::Event::Closed:
-					quit = true;
-					break;
-
-				default:
-					break;
+			} else if (event->is<sf::Event::Closed>()) {
+				quit = true;
 			}
 		}
 	}
diff --git a/src/textures.cpp b/src/textures.cpp
index dc9eef33..498759d0 100644
--- a/src/textures.cpp
+++ b/src/textures.cpp
@@ -158,8 +158,8 @@ void TTexture::DrawFrame(int x, int y, int w, int h, int frame, const sf::Color&
 		DrawFrameX(x - frame, y - frame, w + 2 * frame, h + 2 * frame, frame, colTransp, col, 1.f);
 
 	sf::Sprite temp(texture);
-	temp.setPosition(x, y);
-	temp.setScale((float) w / (float) texture.getSize().x, (float) h / (float) texture.getSize().y);
+	temp.setPosition(sf::Vector2f(x, y));
+	temp.setScale({(float) w / (float) texture.getSize().x, (float) h / (float) texture.getSize().y});
 	Winsys.draw(temp);
 }
 
diff --git a/src/tool_char.cpp b/src/tool_char.cpp
index 122b8dbb..81265426 100644
--- a/src/tool_char.cpp
+++ b/src/tool_char.cpp
@@ -124,111 +124,111 @@ void CharKeys(sf::Keyboard::Key key, bool release, int x, int y) {
 	must_render = true;
 
 	if (ToolsFinalStage()) {
-		if (key == sf::Keyboard::Y || key == sf::Keyboard::J) {
+		if (key == sf::Keyboard::Key::Y || key == sf::Keyboard::Key::J) {
 			SaveToolCharacter();
 			SaveToolFrame();
 			State::manager.RequestQuit();
-		} else if (key == sf::Keyboard::N) State::manager.RequestQuit();
+		} else if (key == sf::Keyboard::Key::N) State::manager.RequestQuit();
 		return;
 	}
 
-	if (key == sf::Keyboard::LShift || key == sf::Keyboard::RShift) shift = !release;
-	if (key == sf::Keyboard::LControl || key == sf::Keyboard::RControl) control = !release;
-	if (key == sf::Keyboard::LAlt || key == sf::Keyboard::RAlt) alt = !release;
+	if (key == sf::Keyboard::Key::LShift || key == sf::Keyboard::Key::RShift) shift = !release;
+	if (key == sf::Keyboard::Key::LControl || key == sf::Keyboard::Key::RControl) control = !release;
+	if (key == sf::Keyboard::Key::LAlt || key == sf::Keyboard::Key::RAlt) alt = !release;
 
 	if (release) return;
 
 	int type = action->type[curr_act];
 	switch (key) {
-		case sf::Keyboard::Tab:
+		case sf::Keyboard::Key::Tab:
 			SetToolMode(1);
 			break;
-		case sf::Keyboard::Escape:
-		case sf::Keyboard::Q:
+		case sf::Keyboard::Key::Escape:
+		case sf::Keyboard::Key::Q:
 			QuitTool();
 			break;
-		case sf::Keyboard::F10:
-		case sf::Keyboard::C:
+		case sf::Keyboard::Key::F10:
+		case sf::Keyboard::Key::C:
 			Winsys.TakeScreenshot();
 			break;
-		case sf::Keyboard::S:
+		case sf::Keyboard::Key::S:
 			SaveToolCharacter();
 			break;
-		case sf::Keyboard::M:
+		case sf::Keyboard::Key::M:
 			TestChar.useMaterials = !TestChar.useMaterials;
 			break;
-		case sf::Keyboard::H:
+		case sf::Keyboard::Key::H:
 			TestChar.useHighlighting = !TestChar.useHighlighting;
 			break;
-		case sf::Keyboard::R:
+		case sf::Keyboard::Key::R:
 			TestChar.Reset();
 			ReloadToolCharacter();
 			Tools.Enter();
 			break;
-		case sf::Keyboard::U:
+		case sf::Keyboard::Key::U:
 			if (action != nullptr) {
 				RecallAction(action);
 				TestChar.RefreshNode(curr_node);
 			}
 			break;
-		case sf::Keyboard::Add:
-		case sf::Keyboard::Equal: // zoom in
+		case sf::Keyboard::Key::Add:
+		case sf::Keyboard::Key::Equal: // zoom in
 			zposition += 0.1f;
 			xposition -= 0.03f;
 			break;
-		case sf::Keyboard::Dash: // zoom out
+		case sf::Keyboard::Key::Hyphen: // zoom out
 			zposition -= 0.1f;
 			xposition += 0.03f;
 			break;
 
 		// set rotations for view
-		case sf::Keyboard::Num1:
+		case sf::Keyboard::Key::Num1:
 			SetRotation(0, 0, 0);
 			break;
-		case sf::Keyboard::Num2:
+		case sf::Keyboard::Key::Num2:
 			SetRotation(-50, 180, 15);
 			break;
-		case sf::Keyboard::Num3:
+		case sf::Keyboard::Key::Num3:
 			SetRotation(0, 180, 0);
 			break;
-		case sf::Keyboard::Num4:
+		case sf::Keyboard::Key::Num4:
 			SetRotation(0, -80, 0);
 			break;
 
 		// select node
-		case sf::Keyboard::PageUp:
+		case sf::Keyboard::Key::PageUp:
 			ChangeNode(-1);
 			break;
-		case sf::Keyboard::PageDown:
+		case sf::Keyboard::Key::PageDown:
 			ChangeNode(1);
 			break;
-		case sf::Keyboard::End:
+		case sf::Keyboard::Key::End:
 			ChangeNode(charbase);
 			break;
-		case sf::Keyboard::Home:
+		case sf::Keyboard::Key::Home:
 			ChangeNode(-charbase);
 			break;
 
 		// select action
-		case sf::Keyboard::Down:
+		case sf::Keyboard::Key::Down:
 			if (curr_act < lastact) curr_act++;
 			if (action->type[curr_act] == 4) comp = 0;
 			else comp = 1;
 			break;
-		case sf::Keyboard::Up:
+		case sf::Keyboard::Key::Up:
 			if (curr_act > 0) curr_act--;
 			if (action->type[curr_act] == 4) comp = 0;
 			else comp = 1;
 			break;
-		case sf::Keyboard::Left:
+		case sf::Keyboard::Key::Left:
 			ChangeValue(type, -1);
 			break;
-		case sf::Keyboard::Right:
+		case sf::Keyboard::Key::Right:
 			ChangeValue(type, 1);
 			break;
 
 		// select value
-		case sf::Keyboard::Space:
+		case sf::Keyboard::Key::Space:
 			if (type == 0 || type == 4) {
 				comp++;
 				if (comp > 3) comp = 0;
diff --git a/src/tool_frame.cpp b/src/tool_frame.cpp
index a8b15ed6..87fb5c9c 100644
--- a/src/tool_frame.cpp
+++ b/src/tool_frame.cpp
@@ -57,139 +57,139 @@ void SingleFrameKeys(sf::Keyboard::Key key, bool release, int x, int y) {
 	TKeyframe *frame = TestFrame.GetFrame(curr_frame);
 
 	// setting the camera change state
-	if (key == sf::Keyboard::F1) {GluCamera.turnright = !release; return;}
-	else if (key == sf::Keyboard::F2) { GluCamera.turnleft = !release; return; }
-	if (key == sf::Keyboard::F3) { GluCamera.nearer = !release; return; }
-	else if (key == sf::Keyboard::F4) { GluCamera.farther = !release; return; }
+	if (key == sf::Keyboard::Key::F1) {GluCamera.turnright = !release; return;}
+	else if (key == sf::Keyboard::Key::F2) { GluCamera.turnleft = !release; return; }
+	if (key == sf::Keyboard::Key::F3) { GluCamera.nearer = !release; return; }
+	else if (key == sf::Keyboard::Key::F4) { GluCamera.farther = !release; return; }
 
 	// additional keys if needed
-	if (key == sf::Keyboard::LShift || key == sf::Keyboard::RShift) shift = !release;
-	if (key == sf::Keyboard::LControl) control = !release;
-	if (key == sf::Keyboard::LAlt) alt = !release;
+	if (key == sf::Keyboard::Key::LShift || key == sf::Keyboard::Key::RShift) shift = !release;
+	if (key == sf::Keyboard::Key::LControl) control = !release;
+	if (key == sf::Keyboard::Key::LAlt) alt = !release;
 	if (shift) keyfact = -1;
 	else keyfact = 1;
 
 	if (release) return;
 
 	switch (key) {
-		case sf::Keyboard::Y:
-		case sf::Keyboard::J:
+		case sf::Keyboard::Key::Y:
+		case sf::Keyboard::Key::J:
 			if (ToolsFinalStage()) {
 				SaveToolCharacter();
 				SaveToolFrame();
 				State::manager.RequestQuit();
 			}
 			break;
-		case sf::Keyboard::N:
+		case sf::Keyboard::Key::N:
 			if (ToolsFinalStage()) State::manager.RequestQuit();
 			break;
 
-		case sf::Keyboard::Escape:
-		case sf::Keyboard::Q:
+		case sf::Keyboard::Key::Escape:
+		case sf::Keyboard::Key::Q:
 			QuitTool();
 			break;
-		case sf::Keyboard::S:
+		case sf::Keyboard::Key::S:
 			SaveToolFrame();
 			break;
-		case sf::Keyboard::Tab:
+		case sf::Keyboard::Key::Tab:
 			SetToolMode(0);
 			break;
 
-		case sf::Keyboard::A:
+		case sf::Keyboard::Key::A:
 			TestFrame.AddFrame();
 			SetFrameChanged(true);
 			break;
-		case sf::Keyboard::Insert:
+		case sf::Keyboard::Key::Insert:
 			TestFrame.InsertFrame(curr_frame);
 			SetFrameChanged(true);
 			break;
-		case sf::Keyboard::Delete:
+		case sf::Keyboard::Key::Delete:
 			curr_frame = TestFrame.DeleteFrame(curr_frame);
 			SetFrameChanged(true);
 			break;
-		case sf::Keyboard::PageDown:
+		case sf::Keyboard::Key::PageDown:
 			if (curr_frame < TestFrame.numFrames()-1) curr_frame++;
 			break;
-		case sf::Keyboard::PageUp:
+		case sf::Keyboard::Key::PageUp:
 			if (curr_frame > 0) curr_frame--;
 			break;
-		case sf::Keyboard::Up:
+		case sf::Keyboard::Key::Up:
 			if (curr_joint > 0) curr_joint--;
 			break;
-		case sf::Keyboard::Down:
+		case sf::Keyboard::Key::Down:
 			if (curr_joint < last_joint) curr_joint++;
 			break;
-		case sf::Keyboard::Right:
+		case sf::Keyboard::Key::Right:
 			if (curr_joint < 4) frame->val[curr_joint] += 0.05;
 			else frame->val[curr_joint] += 1;
 			SetFrameChanged(true);
 			break;
-		case sf::Keyboard::Left:
+		case sf::Keyboard::Key::Left:
 			if (curr_joint < 4) frame->val[curr_joint] -= 0.05;
 			else frame->val[curr_joint] -= 1;
 			SetFrameChanged(true);
 			break;
-		case sf::Keyboard::Num0:
+		case sf::Keyboard::Key::Num0:
 			frame->val[curr_joint] = 0.0;
 			SetFrameChanged(true);
 			break;
-		case sf::Keyboard::Space:
+		case sf::Keyboard::Key::Space:
 			if (curr_joint < 4) frame->val[curr_joint] += 0.05 * keyfact;
 			else frame->val[curr_joint] += 1 * keyfact;
 			SetFrameChanged(true);
 			break;
 
-		case sf::Keyboard::Return:
+		case sf::Keyboard::Key::Enter:
 			TestFrame.InitTest(ref_position, &TestChar);
 			SetToolMode(2);
 			must_render = true;
 			break;
 
-		case sf::Keyboard::M :
+		case sf::Keyboard::Key::M :
 			TestChar.useMaterials = !TestChar.useMaterials;
 			break;
-		case sf::Keyboard::H:
+		case sf::Keyboard::Key::H:
 			TestChar.useHighlighting = !TestChar.useHighlighting;
 			break;
-		case sf::Keyboard::C:
+		case sf::Keyboard::Key::C:
 			if (control) TestFrame.CopyToClipboard(curr_frame);
 			else TestFrame.ClearFrame(curr_frame);
 			SetFrameChanged(true);
 			break;
-		case sf::Keyboard::V:
+		case sf::Keyboard::Key::V:
 			if (control) TestFrame.PasteFromClipboard(curr_frame);
 			SetFrameChanged(true);
 			break;
-		case sf::Keyboard::P:
+		case sf::Keyboard::Key::P:
 			if (curr_frame>0)
 				TestFrame.CopyFrame(curr_frame-1, curr_frame);
 			break;
-		case sf::Keyboard::F10:
+		case sf::Keyboard::Key::F10:
 			Winsys.TakeScreenshot();
 			break;
 
-		case sf::Keyboard::Num1:
+		case sf::Keyboard::Key::Num1:
 			GluCamera.angle = 0;
 			break;
-		case sf::Keyboard::Num2:
+		case sf::Keyboard::Key::Num2:
 			GluCamera.angle = 45;
 			break;
-		case sf::Keyboard::Num3:
+		case sf::Keyboard::Key::Num3:
 			GluCamera.angle = 90;
 			break;
-		case sf::Keyboard::Num4:
+		case sf::Keyboard::Key::Num4:
 			GluCamera.angle = 135;
 			break;
-		case sf::Keyboard::Num5:
+		case sf::Keyboard::Key::Num5:
 			GluCamera.angle = 180;
 			break;
-		case sf::Keyboard::Num6:
+		case sf::Keyboard::Key::Num6:
 			GluCamera.angle = 225;
 			break;
-		case sf::Keyboard::Num7:
+		case sf::Keyboard::Key::Num7:
 			GluCamera.angle = 270;
 			break;
-		case sf::Keyboard::Num8:
+		case sf::Keyboard::Key::Num8:
 			GluCamera.angle = 315;
 			break;
 		default:
@@ -291,14 +291,14 @@ void RenderSingleFrame(float timestep) {
 void SequenceKeys(sf::Keyboard::Key key, bool release, int x, int y) {
 	if (release) return;
 	switch (key) {
-		case sf::Keyboard::Return:
+		case sf::Keyboard::Key::Enter:
 			keyrun = true;
 			break;
-		case sf::Keyboard::Escape:
-		case sf::Keyboard::Tab:
+		case sf::Keyboard::Key::Escape:
+		case sf::Keyboard::Key::Tab:
 			SetToolMode(1);
 			break;
-		case sf::Keyboard::Q:
+		case sf::Keyboard::Key::Q:
 			QuitTool();
 			break;
 		default:
diff --git a/src/winsys.cpp b/src/winsys.cpp
index 7c4fd4b0..36035417 100644
--- a/src/winsys.cpp
+++ b/src/winsys.cpp
@@ -46,7 +46,7 @@ CWinsys::CWinsys()
 	}
 
 	sf::VideoMode desktopMode = sf::VideoMode::getDesktopMode();
-	resolutions[0] = TScreenRes(desktopMode.width, desktopMode.height);
+	resolutions[0] = TScreenRes(desktopMode.size.x, desktopMode.size.y);
 	resolutions[1] = TScreenRes(800, 600);
 	resolutions[2] = TScreenRes(1024, 768);
 	resolutions[3] = TScreenRes(1152, 864);
@@ -89,20 +89,24 @@ void CWinsys::SetupVideoMode(const TScreenRes& res) {
 			bpp = sf::VideoMode::getDesktopMode().bitsPerPixel;
 			break;
 	}
-	sf::Uint32 style = sf::Style::Close | sf::Style::Titlebar;
+	std::uint32_t style = sf::Style::Close | sf::Style::Titlebar;
+	sf::State state = sf::State::Windowed;
 	if (param.fullscreen)
-		style |= sf::Style::Fullscreen;
+		state = sf::State::Fullscreen;
 
 	resolution = res;
 
 	ResetRenderMode();
 
+	sf::ContextSettings ctx;
+	ctx.depthBits = bpp;
+	ctx.majorVersion = 1;
+	ctx.minorVersion = 2;
 #ifdef USE_STENCIL_BUFFER
-	sf::ContextSettings ctx(bpp, 8, 0, 1, 2);
-#else
-	sf::ContextSettings ctx(bpp, 0, 0, 1, 2);
+	ctx.stencilBits = 8;
 #endif
-	window.create(sf::VideoMode(resolution.width, resolution.height, bpp), WINDOW_TITLE, style, ctx);
+
+	window.create(sf::VideoMode({resolution.width, resolution.height}, bpp), WINDOW_TITLE, style, state, ctx);
 	if (param.framerate)
 		window.setFramerateLimit(param.framerate);
 #ifdef _WIN32
@@ -158,19 +162,18 @@ void CWinsys::PrintJoystickInfo() const {
 		int buttons = sf::Joystick::getButtonCount(i);
 		std::cout << "Joystick has " << buttons << " button" << (buttons == 1 ? "" : "s") << '\n';
 		std::cout << "Axes: ";
-		if (sf::Joystick::hasAxis(i, sf::Joystick::R)) std::cout << "R ";
-		if (sf::Joystick::hasAxis(i, sf::Joystick::U)) std::cout << "U ";
-		if (sf::Joystick::hasAxis(i, sf::Joystick::V)) std::cout << "V ";
-		if (sf::Joystick::hasAxis(i, sf::Joystick::X)) std::cout << "X ";
-		if (sf::Joystick::hasAxis(i, sf::Joystick::Y)) std::cout << "Y ";
-		if (sf::Joystick::hasAxis(i, sf::Joystick::Z)) std::cout << "Z ";
+		if (sf::Joystick::hasAxis(i, sf::Joystick::Axis::R)) std::cout << "R ";
+		if (sf::Joystick::hasAxis(i, sf::Joystick::Axis::U)) std::cout << "U ";
+		if (sf::Joystick::hasAxis(i, sf::Joystick::Axis::V)) std::cout << "V ";
+		if (sf::Joystick::hasAxis(i, sf::Joystick::Axis::X)) std::cout << "X ";
+		if (sf::Joystick::hasAxis(i, sf::Joystick::Axis::Y)) std::cout << "Y ";
+		if (sf::Joystick::hasAxis(i, sf::Joystick::Axis::Z)) std::cout << "Z ";
 		std::cout << '\n';
 	}
 }
 
 void CWinsys::TakeScreenshot() const {
-	sf::Texture tex;
-	tex.create(window.getSize().x, window.getSize().y);
+	sf::Texture tex(window.getSize());
 	tex.update(window);
 	sf::Image img = tex.copyToImage();
 
diff --git a/src/winsys.h b/src/winsys.h
index 89969ca6..a31f2ff1 100644
--- a/src/winsys.h
+++ b/src/winsys.h
@@ -62,7 +62,7 @@ class CWinsys {
 	void clear() { window.clear(colBackgr); }
 	void beginSFML() { if (!sfmlRenders) window.pushGLStates(); sfmlRenders = true; }
 	void endSFML() { if (sfmlRenders) window.popGLStates(); sfmlRenders = false; }
-	bool PollEvent(sf::Event& event) { return window.pollEvent(event); }
+	std::optional<sf::Event> PollEvent() { return window.pollEvent(); }
 	const sf::Window& getWindow() const { return window; }
 	void TakeScreenshot() const;
 };
