mirror of
https://github.com/vcmi/vcmi.git
synced 2025-02-03 13:01:33 +02:00
Merge pull request #1386 from IvanSavenko/resolutions_filter
Do not allow selecting resolutions not supported by display
This commit is contained in:
commit
c8c38ac922
@ -31,6 +31,7 @@
|
||||
"vcmi.systemOptions.resolutionButton.help" : "{Select resolution}\n\n Change in-game screen resolution. Game restart required to apply new resolution.",
|
||||
"vcmi.systemOptions.resolutionMenu.hover" : "Select resolution",
|
||||
"vcmi.systemOptions.resolutionMenu.help" : "Change in-game screen resolution.",
|
||||
"vcmi.systemOptions.fullscreenFailed" : "{Fullscreen}\n\n Failed to switch to fullscreen mode! Current resolution is not supported by display!",
|
||||
|
||||
"vcmi.townHall.missingBase" : "Base building %s must be built first",
|
||||
"vcmi.townHall.noCreaturesToRecruit" : "There are no creatures to recruit!",
|
||||
|
@ -49,14 +49,6 @@ SDL_Color CSDL_Ext::toSDL(const ColorRGBA & color)
|
||||
return result;
|
||||
}
|
||||
|
||||
Rect CSDL_Ext::getDisplayBounds()
|
||||
{
|
||||
SDL_Rect displayBounds;
|
||||
SDL_GetDisplayBounds(std::max(0, SDL_GetWindowDisplayIndex(mainWindow)), &displayBounds);
|
||||
|
||||
return fromSDL(displayBounds);
|
||||
}
|
||||
|
||||
void CSDL_Ext::setColors(SDL_Surface *surface, SDL_Color *colors, int firstcolor, int ncolors)
|
||||
{
|
||||
SDL_SetPaletteColors(surface->format->palette,colors,firstcolor,ncolors);
|
||||
@ -878,7 +870,42 @@ void CSDL_Ext::getClipRect(SDL_Surface * src, Rect & other)
|
||||
other = CSDL_Ext::fromSDL(rect);
|
||||
}
|
||||
|
||||
bool CSDL_Ext::isResolutionSupported(const std::vector<Point> & resolutions, const Point toTest )
|
||||
{
|
||||
#if defined(VCMI_ANDROID) || defined(VCMI_IOS)
|
||||
// ios can use any resolution
|
||||
// presumably, same goes for Android
|
||||
return true;
|
||||
#else
|
||||
// in fullscreen only resolutions supported by monitor can be used
|
||||
return vstd::contains(resolutions, toTest);
|
||||
#endif
|
||||
}
|
||||
|
||||
std::vector<Point> CSDL_Ext::getSupportedResolutions()
|
||||
{
|
||||
int displayID = SDL_GetWindowDisplayIndex(mainWindow);
|
||||
return getSupportedResolutions(displayID);
|
||||
}
|
||||
|
||||
std::vector<Point> CSDL_Ext::getSupportedResolutions( int displayIndex)
|
||||
{
|
||||
std::vector<Point> result;
|
||||
|
||||
int modesCount = SDL_GetNumDisplayModes(displayIndex);
|
||||
|
||||
for (int i =0; i < modesCount; ++i)
|
||||
{
|
||||
SDL_DisplayMode mode;
|
||||
if (SDL_GetDisplayMode(displayIndex, i, &mode) != 0)
|
||||
continue;
|
||||
|
||||
Point resolution(mode.w, mode.h);
|
||||
|
||||
result.push_back(resolution);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template SDL_Surface * CSDL_Ext::createSurfaceWithBpp<2>(int, int);
|
||||
template SDL_Surface * CSDL_Ext::createSurfaceWithBpp<3>(int, int);
|
||||
|
@ -81,9 +81,6 @@ typedef void (*TColorPutterAlpha)(uint8_t *&ptr, const uint8_t & R, const uint8_
|
||||
uint32_t colorTouint32_t(const SDL_Color * color); //little endian only
|
||||
SDL_Color makeColor(ui8 r, ui8 g, ui8 b, ui8 a);
|
||||
|
||||
/// returns dimensions of display on which VCMI window is located
|
||||
Rect getDisplayBounds();
|
||||
|
||||
void drawLine(SDL_Surface * sur, int x1, int y1, int x2, int y2, const SDL_Color & color1, const SDL_Color & color2);
|
||||
void drawBorder(SDL_Surface * sur, int x, int y, int w, int h, const SDL_Color &color, int depth = 1);
|
||||
void drawBorder(SDL_Surface * sur, const Rect &r, const SDL_Color &color, int depth = 1);
|
||||
@ -107,6 +104,11 @@ typedef void (*TColorPutterAlpha)(uint8_t *&ptr, const uint8_t & R, const uint8_
|
||||
void applyEffectBpp( SDL_Surface * surf, const Rect & rect, int mode );
|
||||
void applyEffect(SDL_Surface * surf, const Rect & rect, int mode); //mode: 0 - sepia, 1 - grayscale
|
||||
|
||||
bool isResolutionSupported(const std::vector<Point> & resolutions, const Point toTest );
|
||||
|
||||
std::vector<Point> getSupportedResolutions();
|
||||
std::vector<Point> getSupportedResolutions( int displayIndex);
|
||||
|
||||
void setColorKey(SDL_Surface * surface, SDL_Color color);
|
||||
|
||||
///set key-color to 0,255,255
|
||||
|
@ -63,6 +63,8 @@
|
||||
#include "../lib/NetPacksBase.h"
|
||||
#include "../lib/StartInfo.h"
|
||||
|
||||
#include <SDL_surface.h>
|
||||
|
||||
CRecruitmentWindow::CCreatureCard::CCreatureCard(CRecruitmentWindow * window, const CCreature * crea, int totalAmount)
|
||||
: CIntObject(LCLICK | RCLICK),
|
||||
parent(window),
|
||||
@ -540,7 +542,7 @@ CSystemOptionsWindow::CSystemOptionsWindow()
|
||||
|
||||
fullscreen = std::make_shared<CToggleButton>(Point(246, 215), "sysopchk.def", CButton::tooltipLocalized("vcmi.systemOptions.fullscreenButton"), [&](bool value)
|
||||
{
|
||||
setBoolSetting("video", "fullscreen", value);
|
||||
setFullscreenMode(value);
|
||||
});
|
||||
fullscreen->setSelected(settings["video"]["fullscreen"].Bool());
|
||||
|
||||
@ -552,27 +554,82 @@ CSystemOptionsWindow::CSystemOptionsWindow()
|
||||
gameResLabel = std::make_shared<CLabel>(170, 292, FONT_MEDIUM, ETextAlignment::CENTER, Colors::YELLOW, resolutionToString(screenRes["width"].Integer(), screenRes["height"].Integer()));
|
||||
}
|
||||
|
||||
void CSystemOptionsWindow::selectGameRes()
|
||||
void CSystemOptionsWindow::setFullscreenMode( bool on)
|
||||
{
|
||||
std::vector<std::string> items;
|
||||
fillSelectableResolutions();
|
||||
|
||||
#ifndef VCMI_IOS
|
||||
Rect displayBounds = CSDL_Ext::getDisplayBounds();
|
||||
#endif
|
||||
const auto & screenRes = settings["video"]["screenRes"];
|
||||
const Point desiredResolution(screenRes["width"].Integer(), screenRes["height"].Integer());
|
||||
const Point currentResolution(screen->w, screen->h);
|
||||
|
||||
if (!isResolutionSupported(currentResolution, on))
|
||||
{
|
||||
fullscreen->setSelected(!on);
|
||||
LOCPLINT->showInfoDialog(CGI->generaltexth->translate("vcmi.systemOptions.fullscreenFailed"));
|
||||
return;
|
||||
}
|
||||
|
||||
setBoolSetting("video", "fullscreen", on);
|
||||
|
||||
if (!isResolutionSupported(desiredResolution, on))
|
||||
{
|
||||
// user changed his desired resolution and switched to fullscreen
|
||||
// however resolution he selected before is not available in fullscreen
|
||||
// so reset it back to currect resolution which is confirmed to be supported earlier
|
||||
Settings gameRes = settings.write["video"]["screenRes"];
|
||||
gameRes["width"].Float() = currentResolution.x;
|
||||
gameRes["height"].Float() = currentResolution.y;
|
||||
|
||||
gameResLabel->setText(resolutionToString(currentResolution.x, currentResolution.y));
|
||||
}
|
||||
}
|
||||
|
||||
void CSystemOptionsWindow::fillSelectableResolutions()
|
||||
{
|
||||
selectableResolutions.clear();
|
||||
|
||||
size_t currentResolutionIndex = 0;
|
||||
size_t i = 0;
|
||||
for(const auto & it : conf.guiOptions)
|
||||
{
|
||||
const auto & resolution = it.first;
|
||||
#ifndef VCMI_IOS
|
||||
if(displayBounds.w < resolution.first || displayBounds.h < resolution.second)
|
||||
continue;
|
||||
#endif
|
||||
const Point dimensions(it.first.first, it.first.second);
|
||||
|
||||
auto resolutionStr = resolutionToString(resolution.first, resolution.second);
|
||||
if(isResolutionSupported(dimensions))
|
||||
selectableResolutions.push_back(dimensions);
|
||||
}
|
||||
|
||||
boost::range::sort(selectableResolutions, [](const auto & left, const auto & right)
|
||||
{
|
||||
return left.x * left.y < right.x * right.y;
|
||||
});
|
||||
}
|
||||
|
||||
bool CSystemOptionsWindow::isResolutionSupported(const Point & resolution)
|
||||
{
|
||||
return isResolutionSupported( resolution, settings["video"]["fullscreen"].Bool());
|
||||
}
|
||||
|
||||
bool CSystemOptionsWindow::isResolutionSupported(const Point & resolution, bool fullscreen)
|
||||
{
|
||||
if (!fullscreen)
|
||||
return true;
|
||||
|
||||
auto supportedList = CSDL_Ext::getSupportedResolutions();
|
||||
|
||||
return CSDL_Ext::isResolutionSupported(supportedList, resolution);
|
||||
}
|
||||
|
||||
void CSystemOptionsWindow::selectGameRes()
|
||||
{
|
||||
fillSelectableResolutions();
|
||||
|
||||
std::vector<std::string> items;
|
||||
size_t currentResolutionIndex = 0;
|
||||
size_t i = 0;
|
||||
for(const auto & it : selectableResolutions)
|
||||
{
|
||||
auto resolutionStr = resolutionToString(it.x, it.y);
|
||||
if(gameResLabel->getText() == resolutionStr)
|
||||
currentResolutionIndex = i;
|
||||
|
||||
items.push_back(std::move(resolutionStr));
|
||||
++i;
|
||||
}
|
||||
@ -586,20 +643,21 @@ void CSystemOptionsWindow::selectGameRes()
|
||||
|
||||
void CSystemOptionsWindow::setGameRes(int index)
|
||||
{
|
||||
auto iter = conf.guiOptions.begin();
|
||||
std::advance(iter, index);
|
||||
assert(index >= 0 && index < selectableResolutions.size());
|
||||
|
||||
//do not set resolution to illegal one (0x0)
|
||||
assert(iter!=conf.guiOptions.end() && iter->first.first > 0 && iter->first.second > 0);
|
||||
if ( index < 0 || index >= selectableResolutions.size() )
|
||||
return;
|
||||
|
||||
Point resolution = selectableResolutions[index];
|
||||
|
||||
Settings gameRes = settings.write["video"]["screenRes"];
|
||||
gameRes["width"].Float() = iter->first.first;
|
||||
gameRes["height"].Float() = iter->first.second;
|
||||
gameRes["width"].Float() = resolution.x;
|
||||
gameRes["height"].Float() = resolution.y;
|
||||
|
||||
std::string resText;
|
||||
resText += boost::lexical_cast<std::string>(iter->first.first);
|
||||
resText += std::to_string(resolution.x);
|
||||
resText += "x";
|
||||
resText += boost::lexical_cast<std::string>(iter->first.second);
|
||||
resText += std::to_string(resolution.y);
|
||||
gameResLabel->setText(resText);
|
||||
}
|
||||
|
||||
|
@ -226,6 +226,9 @@ private:
|
||||
|
||||
SettingsListener onFullscreenChanged;
|
||||
|
||||
std::vector<Point> supportedResolutions;
|
||||
std::vector<Point> selectableResolutions;
|
||||
|
||||
//functions bound to buttons
|
||||
void bloadf(); //load game
|
||||
void bsavef(); //save game
|
||||
@ -234,6 +237,11 @@ private:
|
||||
void brestartf(); //restart game
|
||||
void bmainmenuf(); //return to main menu
|
||||
|
||||
void setFullscreenMode( bool on);
|
||||
void fillSelectableResolutions();
|
||||
bool isResolutionSupported(const Point & resolution);
|
||||
bool isResolutionSupported(const Point & resolution, bool fullscreen);
|
||||
|
||||
void selectGameRes();
|
||||
void setGameRes(int index);
|
||||
void closeAndPushEvent(EUserEvent code);
|
||||
|
Loading…
x
Reference in New Issue
Block a user