40b128abcc
V-Sync operation unsupported by the driver and pretty rudimentary grep. mostly linkage fixes otherwise.
798 lines
26 KiB
C++
798 lines
26 KiB
C++
/*
|
|
Copyright (c) 2013 yvt
|
|
Portion of the code is based on Serverbrowser.cpp.
|
|
|
|
This file is part of OpenSpades.
|
|
|
|
OpenSpades is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
OpenSpades is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with OpenSpades. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
#include <algorithm>
|
|
#include <cctype>
|
|
#include <utility>
|
|
#include <regex>
|
|
|
|
#include <Imports/OpenGL.h> //for gpu info
|
|
#include <Imports/SDL.h>
|
|
#include <json/json.h>
|
|
|
|
#include "StartupScreenHelper.h"
|
|
|
|
#include "StartupScreen.h"
|
|
#include <Audio/ALDevice.h>
|
|
#include <Audio/YsrDevice.h>
|
|
#include <Core/FileManager.h>
|
|
#include <Core/Settings.h>
|
|
#include <OpenSpades.h>
|
|
#include <Core/ShellApi.h>
|
|
#include <Gui/Main.h>
|
|
#include <Gui/Icon.h>
|
|
#include <Gui/PackageUpdateManager.h>
|
|
|
|
SPADES_SETTING(r_bloom);
|
|
SPADES_SETTING(r_lens);
|
|
SPADES_SETTING(r_cameraBlur);
|
|
SPADES_SETTING(r_softParticles);
|
|
SPADES_SETTING(r_mapSoftShadow);
|
|
SPADES_SETTING(r_modelShadows);
|
|
SPADES_SETTING(r_radiosity);
|
|
SPADES_SETTING(r_dlights);
|
|
SPADES_SETTING(r_water);
|
|
SPADES_SETTING(r_multisamples);
|
|
SPADES_SETTING(r_fxaa);
|
|
SPADES_SETTING(r_videoWidth);
|
|
SPADES_SETTING(r_videoHeight);
|
|
SPADES_SETTING(r_fullscreen);
|
|
SPADES_SETTING(r_fogShadow);
|
|
SPADES_SETTING(r_lensFlare);
|
|
SPADES_SETTING(r_lensFlareDynamic);
|
|
SPADES_SETTING(r_blitFramebuffer);
|
|
SPADES_SETTING(r_srgb);
|
|
SPADES_SETTING(r_shadowMapSize);
|
|
SPADES_SETTING(s_maxPolyphonics);
|
|
SPADES_SETTING(s_eax);
|
|
SPADES_SETTING(r_maxAnisotropy);
|
|
SPADES_SETTING(r_colorCorrection);
|
|
SPADES_SETTING(r_physicalLighting);
|
|
SPADES_SETTING(r_occlusionQuery);
|
|
SPADES_SETTING(r_depthOfField);
|
|
SPADES_SETTING(r_vsync);
|
|
SPADES_SETTING(r_renderer);
|
|
SPADES_SETTING(r_swUndersampling);
|
|
SPADES_SETTING(r_hdr);
|
|
SPADES_SETTING(r_temporalAA);
|
|
|
|
namespace spades {
|
|
namespace gui {
|
|
|
|
StartupScreenHelper::StartupScreenHelper()
|
|
: scr(nullptr),
|
|
shaderHighCapable(false),
|
|
postFilterHighCapable(false),
|
|
particleHighCapable(false) {
|
|
SPADES_MARK_FUNCTION();
|
|
}
|
|
|
|
StartupScreenHelper::~StartupScreenHelper() { SPADES_MARK_FUNCTION(); }
|
|
|
|
void StartupScreenHelper::StartupScreenDestroyed() {
|
|
SPADES_MARK_FUNCTION();
|
|
scr = nullptr;
|
|
}
|
|
|
|
namespace {
|
|
std::regex const localeInfoRegex("[-a-zA-Z0-9_]+\\.json");
|
|
}
|
|
|
|
void StartupScreenHelper::ExamineSystem() {
|
|
SPADES_MARK_FUNCTION();
|
|
|
|
// clear capability report
|
|
// (this function can be called multiple times via StartupScreenHelper::FixConfig)
|
|
reportLines.clear();
|
|
report.clear();
|
|
|
|
// check installed locales
|
|
SPLog("Checking installed locales");
|
|
|
|
auto localeDirectories = FileManager::EnumFiles("Locales");
|
|
locales.clear();
|
|
for (const std::string &localeInfoName : localeDirectories) {
|
|
if (!std::regex_match(localeInfoName, localeInfoRegex)) {
|
|
continue;
|
|
}
|
|
std::string locale = localeInfoName.substr(0, localeInfoName.size() - 5);
|
|
std::string localeInfoPath = "Locales/" + localeInfoName;
|
|
|
|
try {
|
|
std::string buffer = FileManager::ReadAllBytes(localeInfoPath.c_str());
|
|
LocaleInfo info;
|
|
Json::Reader reader;
|
|
Json::Value root;
|
|
if (!reader.parse(buffer.c_str(), root, false)) {
|
|
SPRaise("Failed to parse LocaleInfo.json: %s",
|
|
reader.getFormatedErrorMessages().c_str());
|
|
}
|
|
|
|
info.name = locale;
|
|
info.descriptionEnglish = root["descriptionEnglish"].asString();
|
|
info.descriptionNative = root["description"].asString();
|
|
|
|
locales.push_back(std::move(info));
|
|
|
|
SPLog("Locale '%s' found.", locale.c_str());
|
|
} catch (const std::exception &ex) {
|
|
SPLog("Error while reading the locale info for '%s': %s", locale.c_str(),
|
|
ex.what());
|
|
}
|
|
}
|
|
|
|
// check audio device availability
|
|
// Note: this only checks whether these libraries can be loaded.
|
|
|
|
SPLog("Checking YSR availability");
|
|
if (!audio::YsrDevice::TryLoadYsr()) {
|
|
incapableConfigs.insert(
|
|
std::make_pair("s_audioDriver", [](std::string value) -> std::string {
|
|
if (EqualsIgnoringCase(value, "ysr")) {
|
|
return "YSR library couldn't be loaded.";
|
|
} else {
|
|
return std::string();
|
|
}
|
|
}));
|
|
}
|
|
|
|
SPLog("Checking OpenAL availability");
|
|
if (!audio::ALDevice::TryLoad()) {
|
|
incapableConfigs.insert(
|
|
std::make_pair("s_audioDriver", [](std::string value) -> std::string {
|
|
if (EqualsIgnoringCase(value, "openal")) {
|
|
return "OpenAL library couldn't be loaded.";
|
|
} else {
|
|
return std::string();
|
|
}
|
|
}));
|
|
}
|
|
|
|
// check GL capabilities
|
|
|
|
SPLog("Performing ecapability query");
|
|
|
|
int idDisplay = 0;
|
|
|
|
int numDisplayMode = SDL_GetNumDisplayModes(idDisplay);
|
|
SDL_DisplayMode mode;
|
|
modes.clear();
|
|
if (numDisplayMode > 0) {
|
|
std::set<std::pair<int, int>> foundModes;
|
|
for (int i = 0; i < numDisplayMode; i++) {
|
|
SDL_GetDisplayMode(idDisplay, i, &mode);
|
|
if (mode.w < 800 || mode.h < 600)
|
|
continue;
|
|
if (foundModes.find(std::make_pair(mode.w, mode.h)) != foundModes.end())
|
|
continue;
|
|
|
|
foundModes.insert(std::make_pair(mode.w, mode.h));
|
|
modes.push_back(spades::IntVector3::Make(mode.w, mode.h, 0));
|
|
SPLog("Video Mode Found: %dx%d", mode.w, mode.h);
|
|
}
|
|
} else {
|
|
SPLog("Failed to get video mode list. Presetting default list");
|
|
modes.push_back(spades::IntVector3::Make(800, 600, 0));
|
|
modes.push_back(spades::IntVector3::Make(1024, 768, 0));
|
|
modes.push_back(spades::IntVector3::Make(1280, 720, 0));
|
|
modes.push_back(spades::IntVector3::Make(1920, 1080, 0));
|
|
}
|
|
|
|
bool capable = true;
|
|
SDL_Window *window = SDL_CreateWindow("OpenSpades: Please wait...", 1, 1, 1, 1,
|
|
SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS);
|
|
if (window == nullptr) {
|
|
SPLog("Failed to create SDL window: %s", SDL_GetError());
|
|
}
|
|
SDL_GLContext context = window ? SDL_GL_CreateContext(window) : nullptr;
|
|
if (window != nullptr && context == nullptr) {
|
|
SPLog("Failed to create OpenGL context: %s", SDL_GetError());
|
|
}
|
|
|
|
#ifdef __APPLE__
|
|
#elif __unix
|
|
SDL_Surface *icon = nullptr;
|
|
SDL_RWops *icon_rw = nullptr;
|
|
icon_rw = SDL_RWFromConstMem(g_appIconData, GetAppIconDataSize());
|
|
if (icon_rw != nullptr) {
|
|
icon = IMG_LoadPNG_RW(icon_rw);
|
|
SDL_FreeRW(icon_rw);
|
|
}
|
|
if (icon == nullptr) {
|
|
std::string msg = SDL_GetError();
|
|
SPLog("Failed to load icon: %s", msg.c_str());
|
|
} else {
|
|
SDL_SetWindowIcon(window, icon);
|
|
SDL_FreeSurface(icon);
|
|
}
|
|
#endif
|
|
|
|
if (!context) {
|
|
// OpenGL initialization failed!
|
|
|
|
std::string err = SDL_GetError();
|
|
SPLog("SDL_SetVideoMode failed: %s", err.c_str());
|
|
|
|
AddReport("OpenGL-capable graphics accelerator is unavailable.",
|
|
MakeVector4(1.f, 0.5f, 0.5f, 1.f));
|
|
|
|
AddReport();
|
|
|
|
AddReport("OpenGL/SDL couldn't be initialized.");
|
|
AddReport("Falling back to the software renderer.");
|
|
|
|
AddReport();
|
|
AddReport("Message from SDL:", MakeVector4(1.f, 1.f, 1.f, 0.7f));
|
|
AddReport(err, MakeVector4(1.f, 1.f, 1.f, 0.7f));
|
|
|
|
capable = false;
|
|
shaderHighCapable = false;
|
|
postFilterHighCapable = false;
|
|
particleHighCapable = false;
|
|
} else {
|
|
|
|
SDL_GL_MakeCurrent(window, context);
|
|
|
|
shaderHighCapable = true;
|
|
postFilterHighCapable = true;
|
|
particleHighCapable = true;
|
|
|
|
const char *str;
|
|
GLint maxTextureSize;
|
|
GLint max3DTextureSize;
|
|
GLint maxCombinedTextureUnits;
|
|
GLint maxVertexTextureUnits;
|
|
GLint maxVaryingComponents;
|
|
SPLog("--- OpenGL Renderer Info ---");
|
|
|
|
AddReport("OpenGL-capable graphics accelerator is available.");
|
|
|
|
if ((str = (const char *)glGetString(GL_VENDOR)) != NULL) {
|
|
SPLog("Vendor: %s", str);
|
|
AddReport(std::string("Vendor: ") + str, MakeVector4(1.f, 1.f, 1.f, 0.7f));
|
|
}
|
|
if ((str = (const char *)glGetString(GL_RENDERER)) != NULL) {
|
|
SPLog("Name: %s", str);
|
|
AddReport(std::string("Name: ") + str, MakeVector4(1.f, 1.f, 1.f, 0.7f));
|
|
}
|
|
if ((str = (const char *)glGetString(GL_VERSION)) != NULL) {
|
|
AddReport(std::string("Version: ") + str, MakeVector4(1.f, 1.f, 1.f, 0.7f));
|
|
SPLog("Version: %s", str);
|
|
}
|
|
if ((str = (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION)) != NULL) {
|
|
AddReport(std::string("GLSL Version: ") + str,
|
|
MakeVector4(1.f, 1.f, 1.f, 0.7f));
|
|
SPLog("Shading Language Version: %s", str);
|
|
}
|
|
|
|
AddReport();
|
|
|
|
maxTextureSize = 0;
|
|
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
|
|
if (maxTextureSize > 0) {
|
|
SPLog("Max Texture Size: %d", (int)maxTextureSize);
|
|
}
|
|
max3DTextureSize = 0;
|
|
glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &max3DTextureSize);
|
|
if (max3DTextureSize > 0) {
|
|
SPLog("Max 3D Texture Size: %d", (int)max3DTextureSize);
|
|
}
|
|
|
|
maxCombinedTextureUnits = 0;
|
|
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxCombinedTextureUnits);
|
|
if (maxCombinedTextureUnits > 0) {
|
|
SPLog("Max Combined Texture Image Units: %d", (int)maxCombinedTextureUnits);
|
|
}
|
|
|
|
maxVertexTextureUnits = 0;
|
|
glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxVertexTextureUnits);
|
|
if (maxVertexTextureUnits > 0) {
|
|
SPLog("Max Vertex Texture Image Units: %d", (int)maxVertexTextureUnits);
|
|
}
|
|
|
|
maxVaryingComponents = 0;
|
|
glGetIntegerv(GL_MAX_VARYING_COMPONENTS, &maxVaryingComponents);
|
|
if (maxVaryingComponents > 0) {
|
|
SPLog("Max Varying Components: %d", (int)maxVaryingComponents);
|
|
}
|
|
|
|
str = (const char *)glGetString(GL_EXTENSIONS);
|
|
std::string extensions;
|
|
if (str)
|
|
extensions = str;
|
|
const char *const requiredExtensions[] = {"GL_ARB_multitexture",
|
|
"GL_ARB_shader_objects",
|
|
"GL_ARB_shading_language_100",
|
|
"GL_ARB_texture_non_power_of_two",
|
|
"GL_ARB_vertex_buffer_object",
|
|
"GL_EXT_framebuffer_object",
|
|
NULL};
|
|
|
|
if (str) {
|
|
SPLog("--- Extensions ---");
|
|
std::vector<std::string> strs = spades::Split(str, " ");
|
|
for (size_t i = 0; i < strs.size(); i++) {
|
|
SPLog("%s", strs[i].c_str());
|
|
}
|
|
}
|
|
SPLog("------------------");
|
|
|
|
for (size_t i = 0; requiredExtensions[i]; i++) {
|
|
const char *ex = requiredExtensions[i];
|
|
if (extensions.find(ex) == std::string::npos) {
|
|
// extension not found
|
|
AddReport(std::string(ex) + " is NOT SUPPORTED!",
|
|
MakeVector4(1.f, 0.5f, 0.5f, 1.f));
|
|
capable = false;
|
|
}
|
|
}
|
|
|
|
// non-requred extensions
|
|
if (extensions.find("GL_ARB_framebuffer_sRGB") == std::string::npos) {
|
|
if (r_srgb) {
|
|
r_srgb = 0;
|
|
SPLog("Disabling r_srgb: no GL_ARB_framebuffer_sRGB");
|
|
}
|
|
|
|
incapableConfigs.insert(
|
|
std::make_pair("r_srgb", [](std::string value) -> std::string {
|
|
if (std::stoi(value) != 0) {
|
|
return "SRGB framebuffer is disabled because your video card doesn't "
|
|
"support GL_ARB_framebuffer_sRGB.";
|
|
} else {
|
|
return std::string();
|
|
}
|
|
}));
|
|
|
|
AddReport("GL_ARB_framebuffer_sRGB is NOT SUPPORTED",
|
|
MakeVector4(1.f, 1.f, 0.5f, 1.f));
|
|
AddReport(" r_srgb is disabled.", MakeVector4(1.f, 1.f, 1.f, 0.7f));
|
|
}
|
|
if (extensions.find("GL_EXT_framebuffer_blit") == std::string::npos) {
|
|
if (r_blitFramebuffer) {
|
|
r_blitFramebuffer = 0;
|
|
SPLog("Disabling r_blitFramebuffer: no GL_EXT_framebuffer_blit");
|
|
}
|
|
if (r_multisamples) {
|
|
r_multisamples = 0;
|
|
SPLog("Disabling r_multisamples: no GL_EXT_framebuffer_blit");
|
|
}
|
|
if (r_temporalAA) {
|
|
r_temporalAA = 0;
|
|
SPLog("Disabling r_temporalAA: no GL_EXT_framebuffer_blit");
|
|
}
|
|
incapableConfigs.insert(
|
|
std::make_pair("r_blitFramebuffer", [](std::string value) -> std::string {
|
|
if (std::stoi(value) != 0) {
|
|
return "r_blitFramebuffer is disabled because your video card "
|
|
"doesn't support GL_EXT_framebuffer_blit.";
|
|
} else {
|
|
return std::string();
|
|
}
|
|
}));
|
|
incapableConfigs.insert(
|
|
std::make_pair("r_temporalAA", [](std::string value) -> std::string {
|
|
if (std::stoi(value) != 0) {
|
|
return "r_temporalAA is disabled because your video card "
|
|
"doesn't support GL_EXT_framebuffer_blit.";
|
|
} else {
|
|
return std::string();
|
|
}
|
|
}));
|
|
|
|
AddReport("GL_EXT_framebuffer_blit is NOT SUPPORTED",
|
|
MakeVector4(1.f, 1.f, 0.5f, 1.f));
|
|
AddReport(" r_blitFramebuffer is disabled.", MakeVector4(1.f, 1.f, 1.f, 0.7f));
|
|
}
|
|
if (extensions.find("GL_EXT_texture_filter_anisotropic") == std::string::npos) {
|
|
if ((float)r_maxAnisotropy > 1.1f) {
|
|
r_maxAnisotropy = 1;
|
|
SPLog("Setting r_maxAnisotropy to 1: no GL_EXT_texture_filter_anisotropic");
|
|
}
|
|
|
|
incapableConfigs.insert(
|
|
std::make_pair("r_maxAnisotropy", [](std::string value) -> std::string {
|
|
if (std::stof(value) > 1.001f) {
|
|
return "Anisotropic texture filtering is disabled because your video "
|
|
"card doesn't support GL_EXT_texture_filter_anisotropic.";
|
|
} else {
|
|
return std::string();
|
|
}
|
|
}));
|
|
AddReport("GL_EXT_texture_filter_anisotropic is NOT SUPPORTED",
|
|
MakeVector4(1.f, 1.f, 0.5f, 1.f));
|
|
AddReport(" r_maxAnisotropy is disabled.", MakeVector4(1.f, 1.f, 1.f, 0.7f));
|
|
}
|
|
|
|
if (extensions.find("GL_ARB_occlusion_query") == std::string::npos) {
|
|
if (r_occlusionQuery) {
|
|
r_occlusionQuery = 0;
|
|
SPLog("Disabling r_occlusionQuery: no GL_ARB_occlusion_query");
|
|
}
|
|
incapableConfigs.insert(
|
|
std::make_pair("r_occlusionQuery", [](std::string value) -> std::string {
|
|
if (std::stoi(value)) {
|
|
return "Occlusion query is disabled because your video card doesn't "
|
|
"support GL_ARB_occlusion_query.";
|
|
} else {
|
|
return std::string();
|
|
}
|
|
}));
|
|
AddReport("GL_ARB_occlusion_query is NOT SUPPORTED",
|
|
MakeVector4(1.f, 1.f, 0.5f, 1.f));
|
|
AddReport(" r_occlusionQuery is disabled.", MakeVector4(1.f, 1.f, 1.f, 0.7f));
|
|
}
|
|
|
|
if (extensions.find("GL_NV_conditional_render") == std::string::npos) {
|
|
if (r_occlusionQuery) {
|
|
r_occlusionQuery = 0;
|
|
SPLog("Disabling r_occlusionQuery: no GL_NV_conditional_render");
|
|
}
|
|
incapableConfigs.insert(
|
|
std::make_pair("r_occlusionQuery", [](std::string value) -> std::string {
|
|
if (std::stoi(value)) {
|
|
return "Occlusion query is disabled because your video card doesn't "
|
|
"support GL_NV_conditional_render.";
|
|
} else {
|
|
return std::string();
|
|
}
|
|
}));
|
|
AddReport("GL_NV_conditional_render is NOT SUPPORTED",
|
|
MakeVector4(1.f, 1.f, 0.5f, 1.f));
|
|
AddReport(" r_occlusionQuery is disabled.", MakeVector4(1.f, 1.f, 1.f, 0.7f));
|
|
}
|
|
|
|
if (extensions.find("GL_ARB_color_buffer_float") == std::string::npos) {
|
|
if (r_hdr) {
|
|
r_hdr = 0;
|
|
SPLog("Disabling r_hdr: no GL_ARB_color_buffer_float");
|
|
}
|
|
incapableConfigs.insert(
|
|
std::make_pair("r_hdr", [](std::string value) -> std::string {
|
|
if (std::stoi(value)) {
|
|
return "HDR Rendering is disabled because your video card doesn't "
|
|
"support GL_ARB_color_buffer_float.";
|
|
} else {
|
|
return std::string();
|
|
}
|
|
}));
|
|
AddReport("GL_ARB_color_buffer_float is NOT SUPPORTED",
|
|
MakeVector4(1.f, 1.f, 0.5f, 1.f));
|
|
AddReport(" r_hdr is disabled.", MakeVector4(1.f, 1.f, 1.f, 0.7f));
|
|
}
|
|
|
|
if (extensions.find("GL_EXT_texture_array") == std::string::npos) {
|
|
if ((int)r_water >= 2) {
|
|
r_water = 1;
|
|
SPLog("Disabling Water 2: no GL_EXT_texture_array");
|
|
}
|
|
shaderHighCapable = false;
|
|
incapableConfigs.insert(
|
|
std::make_pair("r_water", [](std::string value) -> std::string {
|
|
if (std::stoi(value) >= 2) {
|
|
return "Water 2 is disabled because your video card doesn't "
|
|
"support GL_EXT_texture_array.";
|
|
} else {
|
|
return std::string();
|
|
}
|
|
}));
|
|
AddReport("GL_EXT_texture_array is NOT SUPPORTED",
|
|
MakeVector4(1.f, 1.f, 0.5f, 1.f));
|
|
AddReport(" Water 2 is disabled.", MakeVector4(1.f, 1.f, 1.f, 0.7f));
|
|
}
|
|
|
|
AddReport("Max Texture Size: " + std::to_string(maxTextureSize),
|
|
MakeVector4(1.f, 1.f, 1.f, 0.7f));
|
|
if (maxTextureSize < 1024) {
|
|
capable = false;
|
|
AddReport(" TOO SMALL (1024 required)", MakeVector4(1.f, 0.5f, 0.5f, 1.f));
|
|
}
|
|
if ((int)r_shadowMapSize > maxTextureSize) {
|
|
SPLog("Changed r_shadowMapSize from %d to %d: too small GL_MAX_TEXTURE_SIZE",
|
|
(int)r_shadowMapSize, maxTextureSize);
|
|
|
|
r_shadowMapSize = maxTextureSize;
|
|
}
|
|
|
|
AddReport("Max 3D Texture Size: " + std::to_string(max3DTextureSize),
|
|
MakeVector4(1.f, 1.f, 1.f, 0.7f));
|
|
if (max3DTextureSize < 512) {
|
|
AddReport(" Global Illumination is disabled (512 required)",
|
|
MakeVector4(1.f, 1.f, 0.5f, 1.f));
|
|
incapableConfigs.insert(
|
|
std::make_pair("r_radiosity", [](std::string value) -> std::string {
|
|
if (std::stoi(value)) {
|
|
return "Global illumination is disabled because your video card "
|
|
"doesn't support a 3D texture of at least 512x512x64.";
|
|
} else {
|
|
return std::string();
|
|
}
|
|
}));
|
|
|
|
if (r_radiosity) {
|
|
r_radiosity = 0;
|
|
SPLog("Disabling r_radiosity: too small GL_MAX_3D_TEXTURE_SIZE");
|
|
}
|
|
}
|
|
|
|
AddReport("Max Combined Texture Image Units: " +
|
|
std::to_string(maxCombinedTextureUnits),
|
|
MakeVector4(1.f, 1.f, 1.f, 0.7f));
|
|
if (maxCombinedTextureUnits < 12) {
|
|
AddReport(" Global Illumination is disabled (12 required)",
|
|
MakeVector4(1.f, 1.f, 0.5f, 1.f));
|
|
incapableConfigs.insert(
|
|
std::make_pair("r_radiosity", [](std::string value) -> std::string {
|
|
if (std::stoi(value)) {
|
|
return "Global illumination is disabled because your video card "
|
|
"supports too few combined texture image units.";
|
|
} else {
|
|
return std::string();
|
|
}
|
|
}));
|
|
|
|
if (r_radiosity) {
|
|
r_radiosity = 0;
|
|
SPLog(
|
|
"Disabling r_radiosity: too small GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS");
|
|
}
|
|
}
|
|
if (maxCombinedTextureUnits < 15) {
|
|
AddReport(" Water 2 is disabled (15 required)",
|
|
MakeVector4(1.f, 1.f, 0.5f, 1.f));
|
|
shaderHighCapable = false;
|
|
|
|
incapableConfigs.insert(
|
|
std::make_pair("r_water", [](std::string value) -> std::string {
|
|
if (std::stoi(value) >= 2) {
|
|
return "Water 2 is disabled because your video card supports too few "
|
|
"combined texture image units.";
|
|
} else {
|
|
return std::string();
|
|
}
|
|
}));
|
|
|
|
if ((int)r_water >= 2) {
|
|
r_water = 1;
|
|
SPLog("Disabling Water 2: too small GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS");
|
|
}
|
|
}
|
|
|
|
AddReport("Max Vertex Texture Image Units: " +
|
|
std::to_string(maxVertexTextureUnits),
|
|
MakeVector4(1.f, 1.f, 1.f, 0.7f));
|
|
if (maxVertexTextureUnits < 3) {
|
|
AddReport(" Water 2 is disabled (3 required)",
|
|
MakeVector4(1.f, 1.f, 0.5f, 1.f));
|
|
shaderHighCapable = false;
|
|
|
|
incapableConfigs.insert(
|
|
std::make_pair("r_water", [](std::string value) -> std::string {
|
|
if (std::stoi(value) >= 2) {
|
|
return "Water 2 is disabled because your video card supports too few "
|
|
"vertex texture image units.";
|
|
} else {
|
|
return std::string();
|
|
}
|
|
}));
|
|
|
|
if ((int)r_water >= 2) {
|
|
r_water = 1;
|
|
SPLog("Disabling Water 2: too small GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS");
|
|
}
|
|
}
|
|
|
|
AddReport("Max Varying Components: " + std::to_string(maxVaryingComponents),
|
|
MakeVector4(1.f, 1.f, 1.f, 0.7f));
|
|
if (maxVaryingComponents < 37) {
|
|
AddReport(" Shaded Particle is disabled (37 required)",
|
|
MakeVector4(1.f, 1.f, 0.5f, 1.f));
|
|
particleHighCapable = false;
|
|
|
|
incapableConfigs.insert(
|
|
std::make_pair("r_softParticles", [](std::string value) -> std::string {
|
|
if (std::stoi(value) >= 2) {
|
|
return "Shaded particle is disabled because your video card supports "
|
|
"too few varying fragment shader input components.";
|
|
} else {
|
|
return std::string();
|
|
}
|
|
}));
|
|
|
|
if ((int)r_softParticles >= 2) {
|
|
r_softParticles = 1;
|
|
SPLog(
|
|
"Disabling shaded particle: too small GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS");
|
|
}
|
|
}
|
|
|
|
AddReport();
|
|
|
|
if (capable) {
|
|
AddReport("Your video card supports all "
|
|
"required OpenGL extensions/features.",
|
|
MakeVector4(0.5f, 1.f, 0.5f, 1.f));
|
|
} else {
|
|
AddReport("Your video card/driver doesn't support "
|
|
"at least one of required OpenGL extensions/features."
|
|
" Falling back to the software renderer.",
|
|
MakeVector4(1.f, 0.5f, 0.5f, 1.f));
|
|
}
|
|
|
|
SDL_GL_DeleteContext(context);
|
|
SDL_DestroyWindow(window);
|
|
|
|
SPLog("SDL Capability Query Window finalized");
|
|
}
|
|
|
|
SPLog("OpenGL driver is OpenSpades capable: %s", capable ? "YES" : "NO");
|
|
|
|
openGLCapable = capable;
|
|
if (!openGLCapable) {
|
|
if (spades::EqualsIgnoringCase(r_renderer, "gl")) {
|
|
SPLog("Switched to software renderer");
|
|
r_renderer = "sw";
|
|
}
|
|
|
|
incapableConfigs.insert(
|
|
std::make_pair("r_renderer", [](std::string value) -> std::string {
|
|
if (spades::EqualsIgnoringCase(value, "gl")) {
|
|
return "OpenGL renderer is disabled because "
|
|
"your video card/driver doesn't support "
|
|
"at least one of required OpenGL extensions/features.";
|
|
} else {
|
|
return std::string();
|
|
}
|
|
}));
|
|
}
|
|
}
|
|
|
|
void StartupScreenHelper::FixConfigs() { ExamineSystem(); }
|
|
|
|
std::string StartupScreenHelper::GetOperatingSystemType() {
|
|
#if defined(OS_PLATFORM_LINUX)
|
|
return "Linux";
|
|
#elif defined(TARGET_OS_MAC)
|
|
return "Mac";
|
|
#elif defined(OS_PLATFORM_WINDOWS)
|
|
return "Windows";
|
|
#elif defined(__FreeBSD__)
|
|
return "FreeBSD";
|
|
#elif defined(__DragonFly__)
|
|
return "DragonFlyBSD";
|
|
#elif defined(__OpenBSD__)
|
|
return "OpenBSD";
|
|
#elif defined(__sun)
|
|
return "Solaris";
|
|
#elif defined(__HAIKU__)
|
|
return "Haiku";
|
|
#else
|
|
return std::string{};
|
|
#endif
|
|
}
|
|
|
|
PackageUpdateManager& StartupScreenHelper::GetPackageUpdateManager() {
|
|
return PackageUpdateManager::GetInstance();
|
|
}
|
|
|
|
bool StartupScreenHelper::OpenUpdateInfoURL() {
|
|
std::string url = GetPackageUpdateManager().GetLatestVersionInfoPageURL();
|
|
if (url.find("http:") != 0 && url.find("https:") != 0) {
|
|
return false;
|
|
}
|
|
return OpenURLInBrowser(url);
|
|
}
|
|
|
|
bool StartupScreenHelper::BrowseUserDirectory() {
|
|
std::string path = g_userResourceDirectory;
|
|
|
|
if (path.empty()) {
|
|
SPLog("Cannot open the user resource directory: g_userResourceDirectory is empty.");
|
|
return false;
|
|
}
|
|
|
|
return ShowDirectoryInShell(path);
|
|
}
|
|
|
|
void StartupScreenHelper::Start() {
|
|
if (scr == nullptr) {
|
|
return;
|
|
}
|
|
scr->Start();
|
|
}
|
|
|
|
int StartupScreenHelper::GetNumVideoModes() { return static_cast<int>(modes.size()); }
|
|
|
|
int StartupScreenHelper::GetVideoModeWidth(int index) {
|
|
if (index < 0 || index >= GetNumVideoModes())
|
|
SPInvalidArgument("index");
|
|
return modes[index].x;
|
|
}
|
|
int StartupScreenHelper::GetVideoModeHeight(int index) {
|
|
if (index < 0 || index >= GetNumVideoModes())
|
|
SPInvalidArgument("index");
|
|
return modes[index].y;
|
|
}
|
|
|
|
int StartupScreenHelper::GetNumReportLines() {
|
|
return static_cast<int>(reportLines.size());
|
|
}
|
|
|
|
std::string StartupScreenHelper::GetReportLineText(int index) {
|
|
if (index < 0 || index >= GetNumReportLines())
|
|
SPInvalidArgument("index");
|
|
return reportLines[index].text;
|
|
}
|
|
Vector4 StartupScreenHelper::GetReportLineColor(int index) {
|
|
if (index < 0 || index >= GetNumReportLines())
|
|
SPInvalidArgument("index");
|
|
return reportLines[index].color;
|
|
}
|
|
|
|
void StartupScreenHelper::AddReport(const std::string &text, Vector4 color) {
|
|
ReportLine l = {text, color};
|
|
reportLines.push_back(l);
|
|
report += text;
|
|
report += '\n';
|
|
}
|
|
|
|
int StartupScreenHelper::GetNumLocales() { return static_cast<int>(locales.size()); }
|
|
std::string StartupScreenHelper::GetLocale(int index) {
|
|
if (index < 0 || index >= GetNumLocales())
|
|
SPInvalidArgument("index");
|
|
return locales[index].name;
|
|
}
|
|
std::string StartupScreenHelper::GetLocaleDescriptionNative(int index) {
|
|
if (index < 0 || index >= GetNumLocales())
|
|
SPInvalidArgument("index");
|
|
return locales[index].descriptionNative;
|
|
}
|
|
std::string StartupScreenHelper::GetLocaleDescriptionEnglish(int index) {
|
|
if (index < 0 || index >= GetNumLocales())
|
|
SPInvalidArgument("index");
|
|
return locales[index].descriptionEnglish;
|
|
}
|
|
|
|
std::string StartupScreenHelper::CheckConfigCapability(const std::string &cfg,
|
|
const std::string &value) {
|
|
auto range = incapableConfigs.equal_range(cfg);
|
|
std::string ret;
|
|
bool hasMulti = false;
|
|
for (auto it = range.first; it != range.second; it++) {
|
|
auto &f = it->second;
|
|
auto err = f(value);
|
|
if (err.size() > 0) {
|
|
if (ret.size() == 0) {
|
|
ret = err;
|
|
} else {
|
|
if (!hasMulti) {
|
|
ret = "- " + ret;
|
|
hasMulti = true;
|
|
}
|
|
ret += "\n- " + err;
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
}
|
|
}
|