mirror of
https://github.com/vcmi/vcmi.git
synced 2025-08-15 20:03:15 +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:
@@ -381,27 +381,6 @@ int main(int argc, char * argv[])
|
|||||||
logGlobal->info("\t%s", driverName);
|
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());
|
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());
|
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 bufOnScreen = (screenBuf == screen);
|
||||||
bool realFullscreen = settings["video"]["realFullscreen"].Bool();
|
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();
|
cleanupRenderer();
|
||||||
|
|
||||||
if(nullptr == mainWindow)
|
if(nullptr == mainWindow)
|
||||||
@@ -1101,10 +1128,10 @@ static bool recreateWindow(int w, int h, int bpp, bool fullscreen, int displayIn
|
|||||||
if(fullscreen)
|
if(fullscreen)
|
||||||
{
|
{
|
||||||
if(realFullscreen)
|
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
|
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);
|
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
|
else
|
||||||
{
|
{
|
||||||
@@ -1143,8 +1170,8 @@ static bool recreateWindow(int w, int h, int bpp, bool fullscreen, int displayIn
|
|||||||
|
|
||||||
SDL_DisplayMode mode;
|
SDL_DisplayMode mode;
|
||||||
SDL_GetDesktopDisplayMode(displayIndex, &mode);
|
SDL_GetDesktopDisplayMode(displayIndex, &mode);
|
||||||
mode.w = w;
|
mode.w = renderWidth;
|
||||||
mode.h = h;
|
mode.h = renderHeight;
|
||||||
|
|
||||||
SDL_SetWindowDisplayMode(mainWindow, &mode);
|
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_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
|
else
|
||||||
{
|
{
|
||||||
@@ -1168,7 +1195,7 @@ static bool recreateWindow(int w, int h, int bpp, bool fullscreen, int displayIn
|
|||||||
|
|
||||||
if(!(fullscreen && realFullscreen))
|
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
|
//following line is bugged not only on android, do not re-enable without checking
|
||||||
//#ifndef VCMI_ANDROID
|
//#ifndef VCMI_ANDROID
|
||||||
@@ -1191,10 +1218,10 @@ static bool recreateWindow(int w, int h, int bpp, bool fullscreen, int displayIn
|
|||||||
int amask = 0xFF000000;
|
int amask = 0xFF000000;
|
||||||
#endif
|
#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)
|
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");
|
throw std::runtime_error("Unable to create surface");
|
||||||
}
|
}
|
||||||
//No blending for screen itself. Required for proper cursor rendering.
|
//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,
|
screenTexture = SDL_CreateTexture(mainRenderer,
|
||||||
SDL_PIXELFORMAT_ARGB8888,
|
SDL_PIXELFORMAT_ARGB8888,
|
||||||
SDL_TEXTUREACCESS_STREAMING,
|
SDL_TEXTUREACCESS_STREAMING,
|
||||||
w, h);
|
renderWidth, renderHeight);
|
||||||
|
|
||||||
if(nullptr == screenTexture)
|
if(nullptr == screenTexture)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user