Skip to content

Commit

Permalink
Window positon tweaks and fullscreen in OpenGL (#333)
Browse files Browse the repository at this point in the history
* Fixed window pos not restored with OpenGL

* Fixed fullscreen in OpenGL (again)

Fixes going full screen on the next monitor when the game was on the second half of the screen.

* Set Fullscreen state only when call succeeds

Also some logging so we hopefully know why it failed.

* Consistent behavior for getting monitor

SDL always gets the monitor  at the middle of the window. Now DXGI does too. Also only resets the position if there is no pixel of the window on any screen.

* also get current monitor on resize (DirectX)

* Correct typo

Co-authored-by: Kenix3 <[email protected]>

---------

Co-authored-by: Kenix3 <[email protected]>
  • Loading branch information
Spodi and Kenix3 authored Aug 6, 2023
1 parent 507a2c4 commit 0a57812
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 21 deletions.
39 changes: 33 additions & 6 deletions src/graphic/Fast3D/gfx_dxgi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,18 +197,36 @@ std::vector<std::tuple<HMONITOR, RECT, BOOL>> GetMonitorList() {
}

// Uses coordinates to get a Monitor handle from a list
bool GetMonitorAtCoords(std::vector<std::tuple<HMONITOR, RECT, BOOL>> MonitorList, int x, int y,
bool GetMonitorAtCoords(std::vector<std::tuple<HMONITOR, RECT, BOOL>> MonitorList, int x, int y, UINT cx, UINT cy,
std::tuple<HMONITOR, RECT, BOOL>& MonitorInfo) {
RECT wr = { x, y, (x + cx), (y + cy) };
std::tuple<HMONITOR, RECT, BOOL> primary;
for (std::tuple<HMONITOR, RECT, BOOL> i : MonitorList) {
if (PtInRect(&get<1>(i), POINT(x, y))) {
if (PtInRect(&get<1>(i), POINT((x + (cx / 2)), (y + (cy / 2))))) {
MonitorInfo = i;
return true;
}
if (get<2>(i)) {
primary = i;
}
}
RECT intersection;
LONG area;
LONG lastArea = 0;
std::tuple<HMONITOR, RECT, BOOL> biggest;
for (std::tuple<HMONITOR, RECT, BOOL> i : MonitorList) {
if (IntersectRect(&intersection, &get<1>(i), &wr)) {
area = (intersection.right - intersection.left) * (intersection.bottom - intersection.top);
if (area > lastArea) {
lastArea = area;
biggest = i;
}
}
}
if (lastArea > 0) {
MonitorInfo = biggest;
return true;
}
MonitorInfo = primary; // Fallback to primary, when out of bounds.
return false;
}
Expand Down Expand Up @@ -237,7 +255,7 @@ static void toggle_borderless_window_full_screen(bool enable, bool call_callback
dxgi.current_height = conf->GetInt("Window.Height", 480);
dxgi.posX = conf->GetInt("Window.PositionX", 100);
dxgi.posY = conf->GetInt("Window.PositionY", 100);
if (!GetMonitorAtCoords(dxgi.monitor_list, dxgi.posX, dxgi.posY,
if (!GetMonitorAtCoords(dxgi.monitor_list, dxgi.posX, dxgi.posY, dxgi.current_width, dxgi.current_height,
Monitor)) { // Fallback to default when out of bounds.
dxgi.posX = 100;
dxgi.posY = 100;
Expand Down Expand Up @@ -340,11 +358,18 @@ static LRESULT CALLBACK gfx_dxgi_wnd_proc(HWND h_wnd, UINT message, WPARAM w_par
case WM_SIZE:
dxgi.current_width = LOWORD(l_param);
dxgi.current_height = HIWORD(l_param);
GetMonitorAtCoords(dxgi.monitor_list, dxgi.posX, dxgi.posY, dxgi.current_width, dxgi.current_height,
newMonitor);
if (get<0>(newMonitor) != get<0>(dxgi.h_Monitor)) {
dxgi.h_Monitor = newMonitor;
GetMonitorHzPeriod(dxgi.h_Monitor, dxgi.detected_hz, dxgi.display_period);
}
break;
case WM_MOVE:
dxgi.posX = GET_X_LPARAM(l_param);
dxgi.posY = GET_Y_LPARAM(l_param);
GetMonitorAtCoords(dxgi.monitor_list, dxgi.posX, dxgi.posY, newMonitor);
GetMonitorAtCoords(dxgi.monitor_list, dxgi.posX, dxgi.posY, dxgi.current_width, dxgi.current_height,
newMonitor);
if (get<0>(newMonitor) != get<0>(dxgi.h_Monitor)) {
dxgi.h_Monitor = newMonitor;
GetMonitorHzPeriod(dxgi.h_Monitor, dxgi.detected_hz, dxgi.display_period);
Expand Down Expand Up @@ -389,7 +414,8 @@ static LRESULT CALLBACK gfx_dxgi_wnd_proc(HWND h_wnd, UINT message, WPARAM w_par
break;
case WM_DISPLAYCHANGE:
dxgi.monitor_list = GetMonitorList();
GetMonitorAtCoords(dxgi.monitor_list, dxgi.posX, dxgi.posY, dxgi.h_Monitor);
GetMonitorAtCoords(dxgi.monitor_list, dxgi.posX, dxgi.posY, dxgi.current_width, dxgi.current_height,
dxgi.h_Monitor);
GetMonitorHzPeriod(dxgi.h_Monitor, dxgi.detected_hz, dxgi.display_period);
break;
default:
Expand Down Expand Up @@ -452,7 +478,8 @@ void gfx_dxgi_init(const char* game_name, const char* gfx_api_name, bool start_i
dxgi.monitor_list = GetMonitorList();
dxgi.posX = posX;
dxgi.posY = posY;
if (!GetMonitorAtCoords(dxgi.monitor_list, dxgi.posX, dxgi.posY, dxgi.h_Monitor)) {
if (!GetMonitorAtCoords(dxgi.monitor_list, dxgi.posX, dxgi.posY, dxgi.current_width, dxgi.current_height,
dxgi.h_Monitor)) {
dxgi.posX = 100;
dxgi.posY = 100;
}
Expand Down
36 changes: 21 additions & 15 deletions src/graphic/Fast3D/gfx_sdl2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,20 +223,21 @@ static void set_fullscreen(bool on, bool call_callback) {
if (fullscreen_state == on) {
return;
}
fullscreen_state = on;
int display_in_use = SDL_GetWindowDisplayIndex(wnd);
SDL_DisplayMode mode;
if (display_in_use < 0) {
SDL_GetDesktopDisplayMode(0, &mode);
} else {
SDL_GetDesktopDisplayMode(display_in_use, &mode);
SPDLOG_WARN("Can't detect on which monitor we are. Probably out of display area?");
SPDLOG_WARN(SDL_GetError());
}

if (on) {
// OTRTODO: Get mode from config.
window_width = mode.w;
window_height = mode.h;
SDL_ShowCursor(false);
SDL_DisplayMode mode;
if (SDL_GetDesktopDisplayMode(display_in_use, &mode) >= 0) {
SDL_SetWindowDisplayMode(wnd, &mode);
SDL_ShowCursor(false);
} else {
SPDLOG_ERROR(SDL_GetError());
}
} else {
auto conf = LUS::Context::GetInstance()->GetConfig();
window_width = conf->GetInt("Window.Width", 640);
Expand All @@ -248,11 +249,16 @@ static void set_fullscreen(bool on, bool call_callback) {
posY = 100;
}
SDL_SetWindowPosition(wnd, posX, posY);
SDL_SetWindowSize(wnd, window_width, window_height);
}
if (SDL_SetWindowFullscreen(wnd, on ? (CVarGetInteger("gSdlWindowedFullscreen", 0) ? SDL_WINDOW_FULLSCREEN_DESKTOP
: SDL_WINDOW_FULLSCREEN)
: 0) >= 0) {
fullscreen_state = on;
} else {
SPDLOG_ERROR("Failed to switch from or to fullscreen mode.");
SPDLOG_ERROR(SDL_GetError());
}
SDL_SetWindowSize(wnd, window_width, window_height);
SDL_SetWindowFullscreen(
wnd,
on ? (CVarGetInteger("gSdlWindowedFullscreen", 0) ? SDL_WINDOW_FULLSCREEN_DESKTOP : SDL_WINDOW_FULLSCREEN) : 0);
SDL_SetCursor(SDL_DISABLE);

if (on_fullscreen_changed_callback != NULL && call_callback) {
Expand Down Expand Up @@ -333,15 +339,15 @@ static void gfx_sdl_init(const char* game_name, const char* gfx_api_name, bool s
flags = flags | SDL_WINDOW_METAL;
}

wnd = SDL_CreateWindow(title, posX, posY, window_width, window_height, flags);
LUS::GuiWindowInitData window_impl;

int display_in_use = SDL_GetWindowDisplayIndex(wnd);
if (display_in_use < 0) { // Fallback to default if out of bounds
posX = 100;
posY = 100;
}

wnd = SDL_CreateWindow(title, posX, posY, window_width, window_height, flags);
LUS::GuiWindowInitData window_impl;

if (use_opengl) {
#ifndef __SWITCH__
SDL_GL_GetDrawableSize(wnd, &window_width, &window_height);
Expand Down

0 comments on commit 0a57812

Please sign in to comment.