1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-02-03 13:01:33 +02:00

Changes to resolution check on window creation (#747)

* Changes to resolution check on window creation:
1. Allow scaled rendering in window mode
2. Match closest logical rendering resolution while scaling is used
This commit is contained in:
Soar Qin 2022-06-06 14:46:24 +08:00 committed by GitHub
parent 1a6ee0d697
commit b061c4988c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -381,27 +381,6 @@ int main(int argc, char * argv[])
logGlobal->info("\t%s", driverName);
}
config::CConfigHandler::GuiOptionsMap::key_type resPair((int)res["width"].Float(), (int)res["height"].Float());
if (conf.guiOptions.count(resPair) == 0)
{
// selected resolution was not found - complain & fallback to something that we do have.
logGlobal->error("Selected resolution %dx%d was not found!", resPair.first, resPair.second);
if (conf.guiOptions.empty())
{
logGlobal->error("Unable to continue - no valid resolutions found! Please reinstall VCMI to fix this");
exit(1);
}
else
{
Settings newRes = settings.write["video"]["screenRes"];
newRes["width"].Float() = conf.guiOptions.begin()->first.first;
newRes["height"].Float() = conf.guiOptions.begin()->first.second;
conf.SetResolution((int)newRes["width"].Float(), (int)newRes["height"].Float());
logGlobal->error("Falling back to %dx%d", newRes["width"].Integer(), newRes["height"].Integer());
}
}
setScreenRes((int)res["width"].Float(), (int)res["height"].Float(), (int)video["bitsPerPixel"].Float(), video["fullscreen"].Bool(), (int)video["displayIndex"].Float());
logGlobal->info("\tInitializing screen: %d ms", pomtime.getDiff());
}
@ -1056,6 +1035,54 @@ static bool recreateWindow(int w, int h, int bpp, bool fullscreen, int displayIn
bool bufOnScreen = (screenBuf == screen);
bool realFullscreen = settings["video"]["realFullscreen"].Bool();
/* match best rendering resolution */
int renderWidth = 0, renderHeight = 0;
auto aspectRatio = (float)w / (float)h;
auto minDiff = 10.f;
for (const auto& pair : conf.guiOptions)
{
int pWidth, pHeight;
std::tie(pWidth, pHeight) = pair.first;
/* filter out resolution which is larger than window */
if (pWidth > w || pHeight > h)
{
continue;
}
auto ratio = (float)pWidth / (float)pHeight;
auto diff = fabs(aspectRatio - ratio);
/* select closest aspect ratio */
if (diff < minDiff)
{
renderWidth = pWidth;
renderHeight = pHeight;
minDiff = diff;
}
/* select largest resolution meets prior conditions.
* since there are resolutions like 1366x768(not exactly 16:9), a deviation of 0.005 is allowed. */
else if (fabs(diff - minDiff) < 0.005f && pWidth > renderWidth)
{
renderWidth = pWidth;
renderHeight = pHeight;
}
}
if (renderWidth == 0)
{
// no matching resolution for upscaling - complain & fallback to default resolution.
logGlobal->error("Failed to match rendering resolution for %dx%d!", w, h);
Settings newRes = settings.write["video"]["screenRes"];
std::tie(w, h) = conf.guiOptions.begin()->first;
newRes["width"].Float() = w;
newRes["height"].Float() = h;
conf.SetResolution(w, h);
logGlobal->error("Falling back to %dx%d", w, h);
renderWidth = w;
renderHeight = h;
}
else
{
logGlobal->info("Set logical rendering resolution to %dx%d", renderWidth, renderHeight);
}
cleanupRenderer();
if(nullptr == mainWindow)
@ -1101,10 +1128,10 @@ static bool recreateWindow(int w, int h, int bpp, bool fullscreen, int displayIn
if(fullscreen)
{
if(realFullscreen)
mainWindow = SDL_CreateWindow(NAME.c_str(), SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex), SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex), w, h, SDL_WINDOW_FULLSCREEN);
mainWindow = SDL_CreateWindow(NAME.c_str(), SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex), SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex), renderWidth, renderHeight, SDL_WINDOW_FULLSCREEN);
else //in windowed full-screen mode use desktop resolution
mainWindow = SDL_CreateWindow(NAME.c_str(), SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex),SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex), 0, 0, SDL_WINDOW_FULLSCREEN_DESKTOP);
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "best");
}
else
{
@ -1143,8 +1170,8 @@ static bool recreateWindow(int w, int h, int bpp, bool fullscreen, int displayIn
SDL_DisplayMode mode;
SDL_GetDesktopDisplayMode(displayIndex, &mode);
mode.w = w;
mode.h = h;
mode.w = renderWidth;
mode.h = renderHeight;
SDL_SetWindowDisplayMode(mainWindow, &mode);
}
@ -1155,7 +1182,7 @@ static bool recreateWindow(int w, int h, int bpp, bool fullscreen, int displayIn
SDL_SetWindowPosition(mainWindow, SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex), SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex));
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "best");
}
else
{
@ -1168,7 +1195,7 @@ static bool recreateWindow(int w, int h, int bpp, bool fullscreen, int displayIn
if(!(fullscreen && realFullscreen))
{
SDL_RenderSetLogicalSize(mainRenderer, w, h);
SDL_RenderSetLogicalSize(mainRenderer, renderWidth, renderHeight);
//following line is bugged not only on android, do not re-enable without checking
//#ifndef VCMI_ANDROID
@ -1191,10 +1218,10 @@ static bool recreateWindow(int w, int h, int bpp, bool fullscreen, int displayIn
int amask = 0xFF000000;
#endif
screen = SDL_CreateRGBSurface(0,w,h,bpp,rmask,gmask,bmask,amask);
screen = SDL_CreateRGBSurface(0,renderWidth,renderHeight,bpp,rmask,gmask,bmask,amask);
if(nullptr == screen)
{
logGlobal->error("Unable to create surface %dx%d with %d bpp: %s", w, h, bpp, SDL_GetError());
logGlobal->error("Unable to create surface %dx%d with %d bpp: %s", renderWidth, renderHeight, bpp, SDL_GetError());
throw std::runtime_error("Unable to create surface");
}
//No blending for screen itself. Required for proper cursor rendering.
@ -1203,7 +1230,7 @@ static bool recreateWindow(int w, int h, int bpp, bool fullscreen, int displayIn
screenTexture = SDL_CreateTexture(mainRenderer,
SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STREAMING,
w, h);
renderWidth, renderHeight);
if(nullptr == screenTexture)
{