Fix graphics flickering/stretching on Windows (#367)
* DRY, standardized window top offset * handle_splash_events() handle multiple events per frame * accurate windows menubar height for multiple rows * Windows filter a resize event triggered by the menubar * windows expand small window to fit menubar * splash screens draw in view rect, not window rect
This commit is contained in:
@@ -145,12 +145,9 @@ void adjust_window_mode() {
|
||||
// 0 - center 1- ul 2 - ur 3 - dl 4 - dr 5 - small win
|
||||
int mode = get_int_pref("DisplayMode");
|
||||
if(mode == 5) {
|
||||
// Increase window height to make room for the menubar
|
||||
// Increase window height to make room for the menubar on Linux
|
||||
int winHeight = height;
|
||||
#ifndef _WIN32
|
||||
// Not on Windows, for some reason
|
||||
winHeight += getMenubarHeight();
|
||||
#endif
|
||||
winHeight += os_specific_y_offset();
|
||||
|
||||
mainPtr.create(sf::VideoMode(width, winHeight, 32), "Blades of Exile", sf::Style::Titlebar | sf::Style::Close, winSettings);
|
||||
|
||||
@@ -179,6 +176,7 @@ void adjust_window_mode() {
|
||||
init_fileio();
|
||||
#endif
|
||||
init_menubar();
|
||||
adjust_window_for_menubar(mode, width, height);
|
||||
showMenuBar();
|
||||
}
|
||||
|
||||
@@ -190,16 +188,6 @@ sf::FloatRect compute_viewport(const sf::RenderWindow& mainPtr, int mode, float
|
||||
// Dimensions of the OS window.
|
||||
rectangle windRect { mainPtr };
|
||||
|
||||
// This is an additional offset between the "logical" top of the window an the UI.
|
||||
// On Windows and Mac no offset is needed because the menubar is not a part of the mainPtr, but
|
||||
// on Linux it is.
|
||||
int os_specific_y_offset =
|
||||
#if defined(SFML_SYSTEM_WINDOWS) || defined(SFML_SYSTEM_MAC)
|
||||
0;
|
||||
#else
|
||||
getMenubarHeight();
|
||||
#endif
|
||||
|
||||
// Width and height: how large the viewport is. They seem to be calculated
|
||||
// in terms of *source* dimensions, with values above 1 resulting in an upscale.
|
||||
viewport.width = ui_scale * width / windRect.width();
|
||||
@@ -215,15 +203,15 @@ sf::FloatRect compute_viewport(const sf::RenderWindow& mainPtr, int mode, float
|
||||
if(mode == 0) {
|
||||
// Fullscreen centered
|
||||
viewport.left = float((windRect.width() - width) / 2) / windRect.width();
|
||||
viewport.top = float((windRect.height() - height - os_specific_y_offset) / 2)/ windRect.height();
|
||||
viewport.top = float((windRect.height() - height - os_specific_y_offset()) / 2)/ windRect.height();
|
||||
} else if(mode == 1) {
|
||||
// Fullscreen top left
|
||||
viewport.left = float(extra_horizontal_buffer) / windRect.width();
|
||||
viewport.top = float(os_specific_y_offset) / windRect.height();
|
||||
viewport.top = float(os_specific_y_offset()) / windRect.height();
|
||||
} else if(mode == 2) {
|
||||
// Fullscreen top right
|
||||
viewport.left = float(windRect.right - width - extra_horizontal_buffer) / windRect.width();
|
||||
viewport.top = float(os_specific_y_offset) / windRect.height();
|
||||
viewport.top = float(os_specific_y_offset()) / windRect.height();
|
||||
} else if(mode == 3) {
|
||||
// Fullscreen bottom left
|
||||
viewport.left = float(extra_horizontal_buffer) / windRect.width();
|
||||
@@ -231,16 +219,16 @@ sf::FloatRect compute_viewport(const sf::RenderWindow& mainPtr, int mode, float
|
||||
// there could be a windows taskbar / mac os dock / xfce taskbar / etc that consumes a part
|
||||
// of that display, and that we do not know size of. So we need to account for that somehow,
|
||||
// so we add 28 more pixels (this was the amount in the previous version of this code).
|
||||
viewport.top = float(windRect.bottom - height - os_specific_y_offset - 28) / windRect.height();
|
||||
viewport.top = float(windRect.bottom - height - os_specific_y_offset() - 28) / windRect.height();
|
||||
} else if(mode == 4) {
|
||||
// Fullscreen bottom right
|
||||
viewport.left = float(windRect.right - width - extra_horizontal_buffer) / windRect.width();
|
||||
// DIRTY HACK: same as for mode 3
|
||||
viewport.top = float(windRect.bottom - height - os_specific_y_offset - 28) / windRect.height();
|
||||
viewport.top = float(windRect.bottom - height - os_specific_y_offset() - 28) / windRect.height();
|
||||
} else if(mode == 5) {
|
||||
// Small windowed
|
||||
viewport.left = 0;
|
||||
viewport.top = float(os_specific_y_offset) / windRect.height();
|
||||
viewport.top = float(os_specific_y_offset()) / windRect.height();
|
||||
}
|
||||
|
||||
return viewport;
|
||||
|
@@ -51,6 +51,7 @@ void draw_startup_stats();
|
||||
void draw_trim(short q,short r,short which_trim,ter_num_t ground_ter);
|
||||
sf::FloatRect compute_viewport(const sf::RenderWindow&, int mode, float ui_scale, float width, float height);
|
||||
|
||||
|
||||
void draw_startup_anim(bool advance);
|
||||
|
||||
|
||||
|
@@ -69,17 +69,12 @@ void init_menubar() {
|
||||
if(winHandle == NULL) return;
|
||||
if(menuHandle == NULL)
|
||||
menuHandle = LoadMenu(GetModuleHandle(NULL), MAKEINTRESOURCE(IDC_BLADESOFEXILE));
|
||||
SetMenu(winHandle, menuHandle);
|
||||
// Now we have to do a little hack to handle menu messages.
|
||||
// We replace SFML's window procedure with our own, which checks for menu events and then forwards to SFML's procedure.
|
||||
mainProc = SetWindowLongPtr(winHandle, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(&menuProc));
|
||||
SetMenu(winHandle, menuHandle);
|
||||
|
||||
mainPtr.setActive();
|
||||
// Fix the window's viewport so that everything is drawn correctly
|
||||
sf::Vector2u sz = mainPtr.getSize();
|
||||
double menubarHeight = getMenubarHeight();
|
||||
double usableHeight = sz.y - menubarHeight;
|
||||
sf::View view(sf::FloatRect(0, 0, sz.x, usableHeight));
|
||||
mainPtr.setView(view);
|
||||
|
||||
// And now initialize the mapping from Windows menu commands to eMenu constants
|
||||
static bool inited = false;
|
||||
@@ -291,6 +286,16 @@ void showMenuBar() {
|
||||
|
||||
LRESULT CALLBACK menuProc(HWND handle, UINT message, WPARAM wParam, LPARAM lParam) {
|
||||
MSG msg = {handle, message, wParam, lParam};
|
||||
|
||||
// Adding the menubar to the window for the first time triggers an unwanted
|
||||
// resizing of the window, which we skip processing because it skews our
|
||||
// viewport:
|
||||
static bool menubarTriggeredResize = false;
|
||||
if(message == WM_SIZE && !menubarTriggeredResize) {
|
||||
menubarTriggeredResize = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(HIWORD(wParam) != 1 || message != WM_COMMAND) {
|
||||
if(TranslateAccelerator(handle, accel.handle, &msg))
|
||||
return 0;
|
||||
|
@@ -109,18 +109,23 @@ bool handle_startup_press(location the_point) {
|
||||
|
||||
void handle_splash_events() {
|
||||
sf::Event event;
|
||||
if(!mainPtr.pollEvent(event)) return;
|
||||
if(event.type == sf::Event::GainedFocus || event.type == sf::Event::MouseMoved)
|
||||
set_cursor(sword_curs);
|
||||
while(mainPtr.pollEvent(event)) {
|
||||
if(event.type == sf::Event::GainedFocus || event.type == sf::Event::MouseMoved)
|
||||
set_cursor(sword_curs);
|
||||
}
|
||||
}
|
||||
|
||||
rectangle view_rect() {
|
||||
sf::Vector2f size = mainPtr.getView().getSize();
|
||||
return rectangle(0, 0, size.y, size.x);
|
||||
}
|
||||
|
||||
void show_logo() {
|
||||
rectangle whole_window;
|
||||
rectangle whole_window = view_rect();
|
||||
|
||||
if(get_int_pref("DisplayMode") != 5)
|
||||
hideMenuBar();
|
||||
|
||||
whole_window = rectangle(mainPtr);
|
||||
double ui_scale = get_float_pref("UIScale", 1.0);
|
||||
if(ui_scale < 1) ui_scale = 1;
|
||||
rectangle logo_from = {0, 0, int(ui_scale *350), int(ui_scale * 350)};
|
||||
@@ -141,11 +146,12 @@ void show_logo() {
|
||||
}
|
||||
|
||||
void plop_fancy_startup() {
|
||||
rectangle whole_window = view_rect();
|
||||
|
||||
float ui_scale = get_float_pref("UIScale", 1.0);
|
||||
if (ui_scale<1) ui_scale=1;
|
||||
rectangle whole_window,from_rect;
|
||||
rectangle from_rect;
|
||||
rectangle intro_from = {0, 0, int(ui_scale * 480), int(ui_scale * 640)};
|
||||
whole_window = rectangle(mainPtr);
|
||||
sf::Time delay = time_in_ticks(220);
|
||||
intro_from.offset((whole_window.right - intro_from.right) / 2,(whole_window.bottom - intro_from.bottom) / 2);
|
||||
sf::Texture& pict_to_draw = *ResMgr::graphics.get("startsplash", true);
|
||||
|
Reference in New Issue
Block a user