Skip to content

Commit

Permalink
Fixed some issues with the resolution list (fixes #1772)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Vultraz committed Jun 27, 2017
1 parent 99f52d0 commit 7aa79c3
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 8 deletions.
8 changes: 8 additions & 0 deletions src/sdl/window.cpp
Expand Up @@ -71,6 +71,14 @@ 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;
Expand Down
12 changes: 11 additions & 1 deletion src/sdl/window.hpp
Expand Up @@ -85,8 +85,18 @@ class window
void set_size(const int w, const int h);

/**
* Gets the Window's output size, in pixels.
* 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();

/**
Expand Down
22 changes: 15 additions & 7 deletions src/video.cpp
Expand Up @@ -142,7 +142,7 @@ SDL_Rect screen_area()
return sdl::empty_rect;
}

SDL_Point size = w->get_output_size();
SDL_Point size = w->get_size();
return {0, 0, size.x, size.y};
}

Expand Down Expand Up @@ -277,7 +277,7 @@ int CVideo::getx() const
return 0;
}

return window->get_output_size().x;
return window->get_size().x;
}

int CVideo::gety() const
Expand All @@ -286,7 +286,7 @@ int CVideo::gety() const
return 0;
}

return window->get_output_size().y;
return window->get_size().y;
}

SDL_Renderer* CVideo::get_renderer()
Expand Down Expand Up @@ -431,14 +431,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;
}

Expand Down Expand Up @@ -470,10 +479,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 {
Expand Down

0 comments on commit 7aa79c3

Please sign in to comment.