1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-15 11:03:00 +01:00

Adjust code, deprecate and fallback to HW if software was selected

This commit is contained in:
ζeh Matt
2025-04-30 18:04:06 +03:00
parent bac84cf17f
commit 730ceb5c33
7 changed files with 100 additions and 88 deletions

View File

@@ -10,14 +10,13 @@
#pragma once
#include <memory>
#include <openrct2/core/Guard.hpp>
#include <openrct2/drawing/IDrawingEngine.h>
namespace OpenRCT2::Ui
{
struct IUiContext;
[[nodiscard]] std::unique_ptr<Drawing::IDrawingEngine> CreateSoftwareDrawingEngine(
const std::shared_ptr<IUiContext>& uiContext);
[[nodiscard]] std::unique_ptr<Drawing::IDrawingEngine> CreateHardwareDisplayDrawingEngine(
const std::shared_ptr<IUiContext>& uiContext);
#ifndef DISABLE_OPENGL
@@ -33,8 +32,6 @@ namespace OpenRCT2::Ui
{
switch (type)
{
case DrawingEngine::Software:
return CreateSoftwareDrawingEngine(uiContext);
case DrawingEngine::SoftwareWithHardwareDisplay:
return CreateHardwareDisplayDrawingEngine(uiContext);
#ifndef DISABLE_OPENGL
@@ -42,6 +39,7 @@ namespace OpenRCT2::Ui
return CreateOpenGLDrawingEngine(uiContext);
#endif
default:
Guard::Fail("Unknown renderer: %u", static_cast<uint32_t>(type));
return nullptr;
}
}

View File

@@ -426,8 +426,27 @@ namespace OpenRCT2::Ui::Windows
window_options_misc_widgets,
window_options_advanced_widgets,
};
// clang-format on
static constexpr std::pair<StringId, DrawingEngine> kDrawingEngineChoices[] = {
{ STR_DRAWING_ENGINE_SOFTWARE_WITH_HARDWARE_DISPLAY, DrawingEngine::SoftwareWithHardwareDisplay },
#ifndef DISABLE_OPENGL
{ STR_DRAWING_ENGINE_OPENGL, DrawingEngine::OpenGL },
#endif
};
static constexpr int32_t getDrawingEngineIndex(DrawingEngine engine)
{
for (int32_t i = 0; i < static_cast<int32_t>(std::size(kDrawingEngineChoices)); ++i)
{
if (kDrawingEngineChoices[i].second == engine)
return i;
}
Guard::Fail("Unsupported drawing engine: %u", EnumValue(engine));
return -1;
}
#pragma endregion
class OptionsWindow final : public Window
@@ -792,18 +811,14 @@ namespace OpenRCT2::Ui::Windows
break;
case WIDX_DRAWING_ENGINE_DROPDOWN:
{
int32_t numItems = 3;
#ifdef DISABLE_OPENGL
numItems = 2;
#endif
const auto numItems = static_cast<int32_t>(std::size(kDrawingEngineChoices));
for (int32_t i = 0; i < numItems; i++)
{
gDropdownItems[i].Format = STR_DROPDOWN_MENU_LABEL;
gDropdownItems[i].Args = DrawingEngineStringIds[i];
gDropdownItems[i].Args = kDrawingEngineChoices[i].first;
}
ShowDropdown(widget, numItems);
Dropdown::SetChecked(EnumValue(Config::Get().general.DrawingEngine), true);
Dropdown::SetChecked(getDrawingEngineIndex(Config::Get().general.DrawingEngine), true);
break;
}
case WIDX_SCALE_UP:
@@ -859,11 +874,10 @@ namespace OpenRCT2::Ui::Windows
}
break;
case WIDX_DRAWING_ENGINE_DROPDOWN:
if (dropdownIndex != EnumValue(Config::Get().general.DrawingEngine))
if (DrawingEngine selectedEngine = kDrawingEngineChoices[dropdownIndex].second;
selectedEngine != Config::Get().general.DrawingEngine)
{
DrawingEngine dstEngine = static_cast<DrawingEngine>(dropdownIndex);
Config::Get().general.DrawingEngine = dstEngine;
Config::Get().general.DrawingEngine = selectedEngine;
RefreshVideo();
Config::Save();
Invalidate();
@@ -895,25 +909,11 @@ namespace OpenRCT2::Ui::Windows
}
// Disable Steam Overlay checkbox when using software or OpenGL rendering.
if (Config::Get().general.DrawingEngine == DrawingEngine::Software
|| Config::Get().general.DrawingEngine == DrawingEngine::OpenGL)
{
disabled_widgets |= (1uLL << WIDX_STEAM_OVERLAY_PAUSE);
}
else
{
disabled_widgets &= ~(1uLL << WIDX_STEAM_OVERLAY_PAUSE);
}
// TODO: Check if this even works properly.
disabled_widgets |= (1uLL << WIDX_STEAM_OVERLAY_PAUSE);
// Disable changing VSync for Software engine, as we can't control its use of VSync
if (Config::Get().general.DrawingEngine == DrawingEngine::Software)
{
disabled_widgets |= (1uLL << WIDX_USE_VSYNC_CHECKBOX);
}
else
{
disabled_widgets &= ~(1uLL << WIDX_USE_VSYNC_CHECKBOX);
}
// VSync.
disabled_widgets &= ~(1uLL << WIDX_USE_VSYNC_CHECKBOX);
SetCheckboxValue(WIDX_UNCAP_FPS_CHECKBOX, Config::Get().general.UncapFPS);
SetCheckboxValue(WIDX_USE_VSYNC_CHECKBOX, Config::Get().general.UseVSync);
@@ -925,7 +925,9 @@ namespace OpenRCT2::Ui::Windows
// Dropdown captions for straightforward strings.
widgets[WIDX_FULLSCREEN].text = FullscreenModeNames[Config::Get().general.FullscreenMode];
widgets[WIDX_DRAWING_ENGINE].text = DrawingEngineStringIds[EnumValue(Config::Get().general.DrawingEngine)];
const auto selectedDrawingEngine = getDrawingEngineIndex(Config::Get().general.DrawingEngine);
widgets[WIDX_DRAWING_ENGINE].text = kDrawingEngineChoices[selectedDrawingEngine].first;
}
void DisplayDraw(DrawPixelInfo& dpi)

View File

@@ -136,7 +136,7 @@ namespace OpenRCT2
std::unique_ptr<GameScene> _gameScene;
IScene* _activeScene = nullptr;
DrawingEngine _drawingEngineType = DrawingEngine::Software;
DrawingEngine _drawingEngineType = DrawingEngine::SoftwareWithHardwareDisplay;
std::unique_ptr<IDrawingEngine> _drawingEngine;
std::unique_ptr<Painter> _painter;
@@ -612,59 +612,74 @@ namespace OpenRCT2
{
assert(_drawingEngine == nullptr);
_drawingEngineType = Config::Get().general.DrawingEngine;
auto drawingEngineFactory = _uiContext->GetDrawingEngineFactory();
auto drawingEngine = drawingEngineFactory->Create(_drawingEngineType, _uiContext);
if (drawingEngine == nullptr)
{
if (_drawingEngineType == DrawingEngine::Software)
const auto initializeEngine = [&](DrawingEngine engine) -> std::unique_ptr<IDrawingEngine> {
try
{
_drawingEngineType = DrawingEngine::None;
LOG_FATAL("Unable to create a drawing engine.");
exit(-1);
auto drawingEngineFactory = _uiContext->GetDrawingEngineFactory();
auto drawingEngine = drawingEngineFactory->Create(engine, _uiContext);
if (drawingEngine == nullptr)
{
LOG_FATAL("Unable to create a drawing engine.");
return nullptr;
}
drawingEngine->Initialise();
drawingEngine->SetVSync(Config::Get().general.UseVSync);
return drawingEngine;
}
catch (std::exception& ex)
{
LOG_ERROR(ex.what());
LOG_ERROR("Unable to initialise drawing engine.");
return nullptr;
}
return nullptr;
};
auto drawingEngineType = Config::Get().general.DrawingEngine;
if (drawingEngineType == DrawingEngine::SoftwareDeprecated)
{
drawingEngineType = DrawingEngine::SoftwareWithHardwareDisplay;
}
// Attempt to create drawing engine of the type specified in the config.
{
auto drawingEngine = initializeEngine(_drawingEngineType);
if (drawingEngine != nullptr)
{
_drawingEngine = std::move(drawingEngine);
}
else
{
LOG_ERROR("Unable to create drawing engine. Falling back to software.");
// Fallback to software
Config::Get().general.DrawingEngine = DrawingEngine::Software;
Config::Save();
DrawingEngineInit();
}
}
else
{
try
{
drawingEngine->Initialise();
drawingEngine->SetVSync(Config::Get().general.UseVSync);
_drawingEngine = std::move(drawingEngine);
}
catch (const std::exception& ex)
{
if (_drawingEngineType == DrawingEngine::Software)
// If the drawing engine creation failed, try to create a software engine.
if (drawingEngineType == DrawingEngine::OpenGL)
{
_drawingEngineType = DrawingEngine::None;
LOG_ERROR(ex.what());
LOG_FATAL("Unable to initialise a drawing engine.");
exit(-1);
}
else
{
LOG_ERROR(ex.what());
LOG_ERROR("Unable to initialise drawing engine. Falling back to software.");
drawingEngineType = DrawingEngine::SoftwareWithHardwareDisplay;
// Fallback to software
Config::Get().general.DrawingEngine = DrawingEngine::Software;
Config::Get().general.DrawingEngine = _drawingEngineType;
Config::Save();
DrawingEngineInit();
LOG_ERROR("Trying fallback back to software...");
drawingEngine = initializeEngine(_drawingEngineType);
if (drawingEngine != nullptr)
{
_drawingEngine = std::move(drawingEngine);
}
else
{
LOG_FATAL("Unable to create any renderer.");
exit(-1);
}
}
}
}
Config::Get().general.DrawingEngine = drawingEngineType;
Config::Save();
WindowCheckAllValidZoom();
}

View File

@@ -101,7 +101,6 @@ namespace OpenRCT2::Config
});
static const auto Enum_DrawingEngine = ConfigEnum<DrawingEngine>({
ConfigEnumEntry<DrawingEngine>("SOFTWARE", DrawingEngine::Software),
ConfigEnumEntry<DrawingEngine>("SOFTWARE_HWD", DrawingEngine::SoftwareWithHardwareDisplay),
ConfigEnumEntry<DrawingEngine>("OPENGL", DrawingEngine::OpenGL),
});
@@ -212,7 +211,7 @@ namespace OpenRCT2::Config
// Default config setting is false until the games canvas can be separated from the effect
model->DayNightCycle = reader->GetBoolean("day_night_cycle", false);
const bool isHardware = model->DrawingEngine != DrawingEngine::Software;
const bool isHardware = true;
model->EnableLightFx = isHardware && reader->GetBoolean("enable_light_fx", false);
model->EnableLightFxForVehicles = isHardware && reader->GetBoolean("enable_light_fx_for_vehicles", false);
model->UpperCaseBanners = reader->GetBoolean("upper_case_banners", false);
@@ -265,6 +264,12 @@ namespace OpenRCT2::Config
model->FileBrowserShowSizeColumn = reader->GetBoolean("file_browser_show_size_column", true);
model->FileBrowserShowDateColumn = reader->GetBoolean("file_browser_show_date_column", true);
model->FileBrowserShowPreviews = reader->GetBoolean("file_browser_show_previews", true);
// Used to be an option but is now removed, SoftwareWithHardwareDisplay substitutes for Software.
if (model->DrawingEngine == DrawingEngine::SoftwareDeprecated)
{
model->DrawingEngine = DrawingEngine::SoftwareWithHardwareDisplay;
}
}
}

View File

@@ -19,7 +19,7 @@
enum class DrawingEngine : int32_t
{
None = -1,
Software,
SoftwareDeprecated,
SoftwareWithHardwareDisplay,
OpenGL,
Count,

View File

@@ -28,12 +28,6 @@ using namespace OpenRCT2::Drawing;
using namespace OpenRCT2::Paint;
using namespace OpenRCT2::Ui;
StringId DrawingEngineStringIds[] = {
STR_DRAWING_ENGINE_SOFTWARE,
STR_DRAWING_ENGINE_SOFTWARE_WITH_HARDWARE_DISPLAY,
STR_DRAWING_ENGINE_OPENGL,
};
DrawingEngine drawing_engine_get_type()
{
auto context = GetContext();

View File

@@ -16,8 +16,6 @@ struct DrawPixelInfo;
enum class DrawingEngine : int32_t;
extern StringId DrawingEngineStringIds[3];
DrawingEngine drawing_engine_get_type();
bool DrawingEngineRequiresNewWindow(DrawingEngine srcEngine, DrawingEngine dstEngine);
void DrawingEngineInit();