Fixed some issues with the resolution list (fixes #1772)
Awhile back I added some code to remove any resolutions from the list that exceeded the current DPI. I seem to have misunderstood some of the functionality. First, off, GetCurrentDisplayMode doesn't seem to return current resolution. From my tests, it seems to return a "maximum maximized size" of some sort equal to GetUsableDisplayBounds - 1 (see below): * Render output size: 800, 600 * Display mode size: 1536, 864 * Window size: 800, 600 * Display Bounds: x: 0, y: 0, w: 1537, h: 865 * Usable display bounds: x: 0, y: 0, w: 1537, h: 865 The actual window size, which @celticminstrel informs me is what we should be measuring here, is actually returned by either GetWindowSize or GetRenderOutputSize. According to SDL, the latter should return pixel size and the former screen coordinates. In my tests, though, the results are the same. This might be different on macOS or iOS. Either way, I've changed current_resolution(), getx(), and gety() to use the results of GetWindowSize(). Additionally, it seems I don't need to multiply any display modes by the DPI scale factor if I check the sizes against the aforementioned "max maximized area" w/h. For that I use GetDisplayBounds however... though again, I'm not sure that's the best way to do this. It does seem to work correctly to fix the aforementioned bug, anyway. I'll need to figure out more about the handling of DPI on Windows vs macOS or iOS. There's an implication that the measurements some of these functions return is different.
This commit is contained in:
parent
82829b0011
commit
b4990801ef
4 changed files with 57 additions and 8 deletions
|
@ -209,8 +209,8 @@ public:
|
|||
* mapx is the width of the portion of the display which shows the game area.
|
||||
* Between mapx and x is the sidebar region.
|
||||
*/
|
||||
int w() const { return screen_.getx(); } /**< width */
|
||||
int h() const { return screen_.gety(); } /**< height */
|
||||
int w() const { return screen_.get_window() ? screen_.get_window()->get_output_size().x : 0; } /**< width */
|
||||
int h() const { return screen_.get_window() ? screen_.get_window()->get_output_size().y : 0; } /**< height */
|
||||
const SDL_Rect& minimap_area() const
|
||||
{ return theme_.mini_map_location(screen_area()); }
|
||||
const SDL_Rect& palette_area() const
|
||||
|
|
|
@ -73,6 +73,22 @@ void window::set_size(const int w, const int h)
|
|||
SDL_SetWindowSize(window_, w, h);
|
||||
}
|
||||
|
||||
SDL_Point window::get_size()
|
||||
{
|
||||
SDL_Point res;
|
||||
SDL_GetWindowSize(*this, &res.x, &res.y);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
SDL_Point window::get_output_size()
|
||||
{
|
||||
SDL_Point res;
|
||||
SDL_GetRendererOutputSize(*this, &res.x, &res.y);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void window::center()
|
||||
{
|
||||
SDL_SetWindowPosition(window_, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
|
||||
|
|
|
@ -83,6 +83,21 @@ public:
|
|||
*/
|
||||
void set_size(const int w, const int h);
|
||||
|
||||
/**
|
||||
* Gets the window's size, in screen coordinates.
|
||||
*
|
||||
* For the most part, this seems to return the same result as @ref get_output_size. However,
|
||||
* SDL indicates for high DPI displays these two functions could differ. I could not observe
|
||||
* any change in behavior with DPI virtualization on or off, but to be safe, I'm keeping the
|
||||
* two functions seperate and using this for matters of window resolution.
|
||||
*
|
||||
* - vultraz, 6/27/2017
|
||||
*/
|
||||
SDL_Point get_size();
|
||||
|
||||
/** Gets the window's renderer output size, in pixels */
|
||||
SDL_Point get_output_size();
|
||||
|
||||
/**
|
||||
* Dummy function for centering the window.
|
||||
*/
|
||||
|
|
|
@ -131,7 +131,13 @@ bool CVideo::non_interactive() const
|
|||
|
||||
SDL_Rect screen_area()
|
||||
{
|
||||
return {0, 0, frameBuffer->w, frameBuffer->h};
|
||||
sdl::window* w = CVideo::get_singleton().get_window();
|
||||
if(!w) {
|
||||
return sdl::empty_rect;
|
||||
}
|
||||
|
||||
SDL_Point size = w->get_size();
|
||||
return {0, 0, size.x, size.y};
|
||||
}
|
||||
|
||||
void CVideo::video_event_handler::handle_window_event(const SDL_Event &event)
|
||||
|
@ -282,7 +288,11 @@ void CVideo::setMode(int x, int y, const MODE_EVENT mode)
|
|||
|
||||
int CVideo::getx() const
|
||||
{
|
||||
return frameBuffer->w;
|
||||
if(!window) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return window->get_size().y;
|
||||
}
|
||||
|
||||
int CVideo::gety() const
|
||||
|
@ -390,14 +400,23 @@ std::vector<std::pair<int, int>> CVideo::get_available_resolutions(const bool in
|
|||
const std::pair<int,int> min_res = std::make_pair(preferences::min_window_width, preferences::min_window_height);
|
||||
const std::pair<int,int> current_res = current_resolution();
|
||||
|
||||
#if 0
|
||||
// DPI scale factor.
|
||||
float scale_h, scale_v;
|
||||
std::tie(scale_h, scale_v) = get_dpi_scale_factor();
|
||||
#endif
|
||||
|
||||
// The maximum size to which this window can be set. For some reason this won't
|
||||
// pop up as a display mode of its own.
|
||||
SDL_Rect bounds;
|
||||
SDL_GetDisplayBounds(display_index, &bounds);
|
||||
|
||||
SDL_DisplayMode mode;
|
||||
|
||||
for(int i = 0; i < modes; ++i) {
|
||||
if(SDL_GetDisplayMode(display_index, i, &mode) == 0) {
|
||||
// Exclude any results outside the range of the current DPI.
|
||||
if(mode.w > current_res.first * scale_h && mode.h > current_res.second * scale_v) {
|
||||
if(mode.w > bounds.w && mode.h > bounds.h) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -428,10 +447,9 @@ surface& CVideo::getSurface()
|
|||
|
||||
std::pair<int,int> CVideo::current_resolution()
|
||||
{
|
||||
SDL_DisplayMode mode;
|
||||
SDL_GetCurrentDisplayMode(window->get_display_index(), &mode);
|
||||
SDL_Point size = window->get_size();
|
||||
|
||||
return std::make_pair(mode.w, mode.h);
|
||||
return std::make_pair(size.x, size.y);
|
||||
}
|
||||
|
||||
bool CVideo::isFullScreen() const {
|
||||
|
|
Loading…
Add table
Reference in a new issue