mirror of https://github.com/OpenTTD/OpenTTD
Add: Option to (dis-)allow accelerated video drivers. (#8819)
The video drivers using the OpenGL backend are currently our only accelerated drivers. The options defaults to off for macOS builds and to on everywhere else. Co-authored-by: Michael Lutz <michi@icosahedron.de>pull/8741/head
parent
6e2a96c133
commit
b93d7dd3cb
|
@ -9,10 +9,12 @@
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
#include "error.h"
|
||||||
#include "sound/sound_driver.hpp"
|
#include "sound/sound_driver.hpp"
|
||||||
#include "music/music_driver.hpp"
|
#include "music/music_driver.hpp"
|
||||||
#include "video/video_driver.hpp"
|
#include "video/video_driver.hpp"
|
||||||
#include "string_func.h"
|
#include "string_func.h"
|
||||||
|
#include "table/strings.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
@ -111,6 +113,8 @@ bool DriverFactoryBase::SelectDriverImpl(const std::string &name, Driver::Type t
|
||||||
if (d->type != type) continue;
|
if (d->type != type) continue;
|
||||||
if (d->priority != priority) continue;
|
if (d->priority != priority) continue;
|
||||||
|
|
||||||
|
if (type == Driver::DT_VIDEO && !_video_hw_accel && d->UsesHardwareAcceleration()) continue;
|
||||||
|
|
||||||
Driver *oldd = *GetActiveDriver(type);
|
Driver *oldd = *GetActiveDriver(type);
|
||||||
Driver *newd = d->CreateInstance();
|
Driver *newd = d->CreateInstance();
|
||||||
*GetActiveDriver(type) = newd;
|
*GetActiveDriver(type) = newd;
|
||||||
|
@ -125,6 +129,12 @@ bool DriverFactoryBase::SelectDriverImpl(const std::string &name, Driver::Type t
|
||||||
*GetActiveDriver(type) = oldd;
|
*GetActiveDriver(type) = oldd;
|
||||||
DEBUG(driver, 1, "Probing %s driver '%s' failed with error: %s", GetDriverTypeName(type), d->name, err);
|
DEBUG(driver, 1, "Probing %s driver '%s' failed with error: %s", GetDriverTypeName(type), d->name, err);
|
||||||
delete newd;
|
delete newd;
|
||||||
|
|
||||||
|
if (type == Driver::DT_VIDEO && _video_hw_accel && d->UsesHardwareAcceleration()) {
|
||||||
|
_video_hw_accel = false;
|
||||||
|
ErrorMessageData msg(STR_VIDEO_DRIVER_ERROR, STR_VIDEO_DRIVER_ERROR_NO_HARDWARE_ACCELERATION);
|
||||||
|
ScheduleErrorMessage(msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
usererror("Couldn't find any suitable %s driver", GetDriverTypeName(type));
|
usererror("Couldn't find any suitable %s driver", GetDriverTypeName(type));
|
||||||
|
|
|
@ -107,6 +107,15 @@ protected:
|
||||||
|
|
||||||
virtual ~DriverFactoryBase();
|
virtual ~DriverFactoryBase();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does the driver use hardware acceleration (video-drivers only).
|
||||||
|
* @return True if the driver uses hardware acceleration.
|
||||||
|
*/
|
||||||
|
virtual bool UsesHardwareAcceleration() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Shuts down all active drivers
|
* Shuts down all active drivers
|
||||||
|
|
|
@ -1001,6 +1001,10 @@ STR_GAME_OPTIONS_RESOLUTION :{BLACK}Screen r
|
||||||
STR_GAME_OPTIONS_RESOLUTION_TOOLTIP :{BLACK}Select the screen resolution to use
|
STR_GAME_OPTIONS_RESOLUTION_TOOLTIP :{BLACK}Select the screen resolution to use
|
||||||
STR_GAME_OPTIONS_RESOLUTION_OTHER :other
|
STR_GAME_OPTIONS_RESOLUTION_OTHER :other
|
||||||
|
|
||||||
|
STR_GAME_OPTIONS_VIDEO_ACCELERATION :{BLACK}Hardware acceleration
|
||||||
|
STR_GAME_OPTIONS_VIDEO_ACCELERATION_TOOLTIP :{BLACK}Check this box to allow OpenTTD to try to use hardware acceleration. A changed setting will only be applied upon game restart
|
||||||
|
STR_GAME_OPTIONS_VIDEO_ACCELERATION_RESTART :{WHITE}The setting will only take effect after a game restart
|
||||||
|
|
||||||
STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Interface size
|
STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Interface size
|
||||||
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Select the interface element size to use
|
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Select the interface element size to use
|
||||||
|
|
||||||
|
@ -1787,6 +1791,10 @@ STR_CONFIG_ERROR_INVALID_BASE_MUSIC_NOT_FOUND :{WHITE}... igno
|
||||||
STR_CONFIG_ERROR_OUT_OF_MEMORY :{WHITE}Out of memory
|
STR_CONFIG_ERROR_OUT_OF_MEMORY :{WHITE}Out of memory
|
||||||
STR_CONFIG_ERROR_SPRITECACHE_TOO_BIG :{WHITE}Allocating {BYTES} of spritecache failed. The spritecache was reduced to {BYTES}. This will reduce the performance of OpenTTD. To reduce memory requirements you can try to disable 32bpp graphics and/or zoom-in levels
|
STR_CONFIG_ERROR_SPRITECACHE_TOO_BIG :{WHITE}Allocating {BYTES} of spritecache failed. The spritecache was reduced to {BYTES}. This will reduce the performance of OpenTTD. To reduce memory requirements you can try to disable 32bpp graphics and/or zoom-in levels
|
||||||
|
|
||||||
|
# Video initalization errors
|
||||||
|
STR_VIDEO_DRIVER_ERROR :{WHITE}Error with video settings...
|
||||||
|
STR_VIDEO_DRIVER_ERROR_NO_HARDWARE_ACCELERATION :{WHITE}... no compatible GPU found. Hardware acceleration disabled
|
||||||
|
|
||||||
# Intro window
|
# Intro window
|
||||||
STR_INTRO_CAPTION :{WHITE}OpenTTD {REV}
|
STR_INTRO_CAPTION :{WHITE}OpenTTD {REV}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include "querystring_gui.h"
|
#include "querystring_gui.h"
|
||||||
#include "fontcache.h"
|
#include "fontcache.h"
|
||||||
#include "zoom_func.h"
|
#include "zoom_func.h"
|
||||||
|
#include "video/video_driver.hpp"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -381,6 +382,13 @@ struct GameOptionsWindow : Window {
|
||||||
this->SetDirty();
|
this->SetDirty();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case WID_GO_VIDEO_ACCEL_BUTTON:
|
||||||
|
_video_hw_accel = !_video_hw_accel;
|
||||||
|
ShowErrorMessage(STR_GAME_OPTIONS_VIDEO_ACCELERATION_RESTART, INVALID_STRING_ID, WL_INFO);
|
||||||
|
this->SetWidgetLoweredState(WID_GO_VIDEO_ACCEL_BUTTON, _video_hw_accel);
|
||||||
|
this->SetDirty();
|
||||||
|
break;
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
int selected;
|
int selected;
|
||||||
DropDownList list = this->BuildDropDownList(widget, &selected);
|
DropDownList list = this->BuildDropDownList(widget, &selected);
|
||||||
|
@ -493,6 +501,7 @@ struct GameOptionsWindow : Window {
|
||||||
{
|
{
|
||||||
if (!gui_scope) return;
|
if (!gui_scope) return;
|
||||||
this->SetWidgetLoweredState(WID_GO_FULLSCREEN_BUTTON, _fullscreen);
|
this->SetWidgetLoweredState(WID_GO_FULLSCREEN_BUTTON, _fullscreen);
|
||||||
|
this->SetWidgetLoweredState(WID_GO_VIDEO_ACCEL_BUTTON, _video_hw_accel);
|
||||||
|
|
||||||
bool missing_files = BaseGraphics::GetUsedSet()->GetNumMissing() == 0;
|
bool missing_files = BaseGraphics::GetUsedSet()->GetNumMissing() == 0;
|
||||||
this->GetWidget<NWidgetCore>(WID_GO_BASE_GRF_STATUS)->SetDataTip(missing_files ? STR_EMPTY : STR_GAME_OPTIONS_BASE_GRF_STATUS, STR_NULL);
|
this->GetWidget<NWidgetCore>(WID_GO_BASE_GRF_STATUS)->SetDataTip(missing_files ? STR_EMPTY : STR_GAME_OPTIONS_BASE_GRF_STATUS, STR_NULL);
|
||||||
|
@ -521,14 +530,16 @@ static const NWidgetPart _nested_game_options_widgets[] = {
|
||||||
EndContainer(),
|
EndContainer(),
|
||||||
NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_RESOLUTION, STR_NULL),
|
NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_RESOLUTION, STR_NULL),
|
||||||
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_RESOLUTION_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_STRING, STR_GAME_OPTIONS_RESOLUTION_TOOLTIP), SetFill(1, 0), SetPadding(0, 0, 3, 0),
|
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_RESOLUTION_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_STRING, STR_GAME_OPTIONS_RESOLUTION_TOOLTIP), SetFill(1, 0), SetPadding(0, 0, 3, 0),
|
||||||
NWidget(NWID_HORIZONTAL),
|
NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0), SetPadding(0, 0, 3, 0),
|
||||||
NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_FULLSCREEN, STR_NULL),
|
NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_FULLSCREEN, STR_NULL),
|
||||||
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_FULLSCREEN_BUTTON), SetMinimalSize(21, 9), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_FULLSCREEN_TOOLTIP),
|
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_FULLSCREEN_BUTTON), SetMinimalSize(21, 9), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_FULLSCREEN_TOOLTIP),
|
||||||
EndContainer(),
|
EndContainer(),
|
||||||
|
NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0),
|
||||||
|
NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_VIDEO_ACCELERATION, STR_NULL),
|
||||||
|
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_VIDEO_ACCEL_BUTTON), SetMinimalSize(21, 9), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_VIDEO_ACCELERATION_TOOLTIP),
|
||||||
|
EndContainer(),
|
||||||
EndContainer(),
|
EndContainer(),
|
||||||
NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_GUI_ZOOM_FRAME, STR_NULL),
|
NWidget(NWID_SPACER), SetMinimalSize(0, 0), SetFill(0, 1),
|
||||||
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_GUI_ZOOM_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_STRING, STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP), SetFill(1, 0),
|
|
||||||
EndContainer(),
|
|
||||||
EndContainer(),
|
EndContainer(),
|
||||||
|
|
||||||
NWidget(NWID_VERTICAL), SetPIP(0, 6, 0),
|
NWidget(NWID_VERTICAL), SetPIP(0, 6, 0),
|
||||||
|
@ -538,7 +549,9 @@ static const NWidgetPart _nested_game_options_widgets[] = {
|
||||||
NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME, STR_NULL),
|
NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME, STR_NULL),
|
||||||
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_CURRENCY_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_STRING, STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP), SetFill(1, 0),
|
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_CURRENCY_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_STRING, STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP), SetFill(1, 0),
|
||||||
EndContainer(),
|
EndContainer(),
|
||||||
NWidget(NWID_SPACER), SetMinimalSize(0, 0), SetFill(0, 1),
|
NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_GUI_ZOOM_FRAME, STR_NULL),
|
||||||
|
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_GUI_ZOOM_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_STRING, STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP), SetFill(1, 0),
|
||||||
|
EndContainer(),
|
||||||
NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_FONT_ZOOM, STR_NULL),
|
NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_FONT_ZOOM, STR_NULL),
|
||||||
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_FONT_ZOOM_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_STRING, STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP), SetFill(1, 0),
|
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_FONT_ZOOM_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_STRING, STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP), SetFill(1, 0),
|
||||||
EndContainer(),
|
EndContainer(),
|
||||||
|
|
|
@ -12,6 +12,9 @@ static const char *_support8bppmodes = "no|system|hardware";
|
||||||
#ifdef WITH_COCOA
|
#ifdef WITH_COCOA
|
||||||
extern bool _allow_hidpi_window;
|
extern bool _allow_hidpi_window;
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef WITH_COCOA
|
||||||
|
#define WITHOUT_COCOA
|
||||||
|
#endif
|
||||||
|
|
||||||
static const SettingDescGlobVarList _misc_settings[] = {
|
static const SettingDescGlobVarList _misc_settings[] = {
|
||||||
[post-amble]
|
[post-amble]
|
||||||
|
@ -60,6 +63,20 @@ var = _fullscreen
|
||||||
def = false
|
def = false
|
||||||
cat = SC_BASIC
|
cat = SC_BASIC
|
||||||
|
|
||||||
|
[SDTG_BOOL]
|
||||||
|
ifdef = WITH_COCOA
|
||||||
|
name = ""video_hw_accel""
|
||||||
|
var = _video_hw_accel
|
||||||
|
def = false
|
||||||
|
cat = SC_BASIC
|
||||||
|
|
||||||
|
[SDTG_BOOL]
|
||||||
|
ifdef = WITHOUT_COCOA
|
||||||
|
name = ""video_hw_accel""
|
||||||
|
var = _video_hw_accel
|
||||||
|
def = true
|
||||||
|
cat = SC_BASIC
|
||||||
|
|
||||||
[SDTG_OMANY]
|
[SDTG_OMANY]
|
||||||
name = ""support8bpp""
|
name = ""support8bpp""
|
||||||
type = SLE_UINT8
|
type = SLE_UINT8
|
||||||
|
|
|
@ -54,6 +54,9 @@ class FVideoDriver_CocoaOpenGL : public DriverFactoryBase {
|
||||||
public:
|
public:
|
||||||
FVideoDriver_CocoaOpenGL() : DriverFactoryBase(Driver::DT_VIDEO, 9, "cocoa-opengl", "Cocoa OpenGL Video Driver") {}
|
FVideoDriver_CocoaOpenGL() : DriverFactoryBase(Driver::DT_VIDEO, 9, "cocoa-opengl", "Cocoa OpenGL Video Driver") {}
|
||||||
Driver *CreateInstance() const override { return new VideoDriver_CocoaOpenGL(); }
|
Driver *CreateInstance() const override { return new VideoDriver_CocoaOpenGL(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool UsesHardwareAcceleration() const override { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* VIDEO_COCOA_OGL_H */
|
#endif /* VIDEO_COCOA_OGL_H */
|
||||||
|
|
|
@ -122,7 +122,7 @@ protected:
|
||||||
|
|
||||||
class FVideoDriver_CocoaQuartz : public DriverFactoryBase {
|
class FVideoDriver_CocoaQuartz : public DriverFactoryBase {
|
||||||
public:
|
public:
|
||||||
FVideoDriver_CocoaQuartz() : DriverFactoryBase(Driver::DT_VIDEO, 10, "cocoa", "Cocoa Video Driver") {}
|
FVideoDriver_CocoaQuartz() : DriverFactoryBase(Driver::DT_VIDEO, 8, "cocoa", "Cocoa Video Driver") {}
|
||||||
Driver *CreateInstance() const override { return new VideoDriver_CocoaQuartz(); }
|
Driver *CreateInstance() const override { return new VideoDriver_CocoaQuartz(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -51,4 +51,7 @@ class FVideoDriver_SDL_OpenGL : public DriverFactoryBase {
|
||||||
public:
|
public:
|
||||||
FVideoDriver_SDL_OpenGL() : DriverFactoryBase(Driver::DT_VIDEO, 8, "sdl-opengl", "SDL OpenGL Video Driver") {}
|
FVideoDriver_SDL_OpenGL() : DriverFactoryBase(Driver::DT_VIDEO, 8, "sdl-opengl", "SDL OpenGL Video Driver") {}
|
||||||
/* virtual */ Driver *CreateInstance() const override { return new VideoDriver_SDL_OpenGL(); }
|
/* virtual */ Driver *CreateInstance() const override { return new VideoDriver_SDL_OpenGL(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool UsesHardwareAcceleration() const override { return true; }
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
#include "../window_func.h"
|
#include "../window_func.h"
|
||||||
#include "video_driver.hpp"
|
#include "video_driver.hpp"
|
||||||
|
|
||||||
|
bool _video_hw_accel; ///< Whether to consider hardware accelerated video drivers.
|
||||||
|
|
||||||
bool VideoDriver::Tick()
|
bool VideoDriver::Tick()
|
||||||
{
|
{
|
||||||
auto cur_ticks = std::chrono::steady_clock::now();
|
auto cur_ticks = std::chrono::steady_clock::now();
|
||||||
|
|
|
@ -23,6 +23,7 @@ extern std::string _ini_videodriver;
|
||||||
extern std::vector<Dimension> _resolutions;
|
extern std::vector<Dimension> _resolutions;
|
||||||
extern Dimension _cur_resolution;
|
extern Dimension _cur_resolution;
|
||||||
extern bool _rightclick_emulate;
|
extern bool _rightclick_emulate;
|
||||||
|
extern bool _video_hw_accel;
|
||||||
|
|
||||||
/** The base of all video drivers. */
|
/** The base of all video drivers. */
|
||||||
class VideoDriver : public Driver {
|
class VideoDriver : public Driver {
|
||||||
|
|
|
@ -175,6 +175,9 @@ class FVideoDriver_Win32OpenGL : public DriverFactoryBase {
|
||||||
public:
|
public:
|
||||||
FVideoDriver_Win32OpenGL() : DriverFactoryBase(Driver::DT_VIDEO, 10, "win32-opengl", "Win32 OpenGL Video Driver") {}
|
FVideoDriver_Win32OpenGL() : DriverFactoryBase(Driver::DT_VIDEO, 10, "win32-opengl", "Win32 OpenGL Video Driver") {}
|
||||||
/* virtual */ Driver *CreateInstance() const override { return new VideoDriver_Win32OpenGL(); }
|
/* virtual */ Driver *CreateInstance() const override { return new VideoDriver_Win32OpenGL(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool UsesHardwareAcceleration() const override { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* WITH_OPENGL */
|
#endif /* WITH_OPENGL */
|
||||||
|
|
|
@ -32,6 +32,7 @@ enum GameOptionsWidgets {
|
||||||
WID_GO_BASE_MUSIC_TEXTFILE, ///< Open base music readme, changelog (+1) or license (+2).
|
WID_GO_BASE_MUSIC_TEXTFILE, ///< Open base music readme, changelog (+1) or license (+2).
|
||||||
WID_GO_BASE_MUSIC_DESCRIPTION = WID_GO_BASE_MUSIC_TEXTFILE + TFT_END, ///< Description of selected base music set.
|
WID_GO_BASE_MUSIC_DESCRIPTION = WID_GO_BASE_MUSIC_TEXTFILE + TFT_END, ///< Description of selected base music set.
|
||||||
WID_GO_FONT_ZOOM_DROPDOWN, ///< Dropdown for the font zoom level.
|
WID_GO_FONT_ZOOM_DROPDOWN, ///< Dropdown for the font zoom level.
|
||||||
|
WID_GO_VIDEO_ACCEL_BUTTON, ///< Toggle for video acceleration.
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Widgets of the #GameSettingsWindow class. */
|
/** Widgets of the #GameSettingsWindow class. */
|
||||||
|
|
Loading…
Reference in New Issue