Merge pull request #9873 from unknownbrackets/fullscreen

Fix and improve fullscreen on 21:9 monitors
This commit is contained in:
Henrik Rydgård 2017-08-01 10:40:15 +02:00 committed by GitHub
commit f182b79e15
11 changed files with 73 additions and 32 deletions

View File

@ -513,6 +513,7 @@ static ConfigSetting graphicsSettings[] = {
#ifndef MOBILE_DEVICE
ConfigSetting("FullScreen", &g_Config.bFullScreen, false),
ConfigSetting("FullScreenMulti", &g_Config.bFullScreenMulti, false),
#endif
// TODO: Replace these settings with a list of options

View File

@ -189,6 +189,7 @@ public:
bool bTextureSecondaryCache;
bool bVertexDecoderJit;
bool bFullScreen;
bool bFullScreenMulti;
int iInternalResolution; // 0 = Auto (native), 1 = 1x (480x272), 2 = 2x, 3 = 3x, 4 = 4x and so on.
int iAnisotropyLevel; // 0 - 5, powers of 2: 0 = 1x = no aniso
int bHighQualityDepth;

View File

@ -38,7 +38,6 @@ public:
virtual void InitSound() = 0;
virtual void UpdateSound() {}
virtual void GoFullscreen(bool) {}
virtual void ShutdownSound() = 0;
virtual void PollControllers() {}
virtual void ToggleDebugConsoleVisibility() {}

View File

@ -72,12 +72,13 @@ void CenterDisplayOutputRect(float *x, float *y, float *w, float *h, float origW
return;
}
} else if (g_Config.iSmallDisplayZoomType == 2) { // Auto Scaling
// Stretch to 1080 for 272*4. But don't distort if not widescreen (i.e. ultrawide of halfwide.)
float pixelCrop = frameH / 270.0f;
float resCommonWidescreen = pixelCrop - floor(pixelCrop);
if (!rotated && resCommonWidescreen == 0.0f) {
*x = 0;
if (!rotated && resCommonWidescreen == 0.0f && frameW >= pixelCrop * 480.0f) {
*x = floorf((frameW - pixelCrop * 480.0f) * 0.5f);
*y = floorf(-pixelCrop);
*w = floorf(frameW);
*w = floorf(pixelCrop * 480.0f);
*h = floorf(pixelCrop * 272.0f);
return;
}

View File

@ -263,6 +263,11 @@ void GameSettingsScreen::CreateViews() {
#if !defined(MOBILE_DEVICE)
graphicsSettings->Add(new CheckBox(&g_Config.bFullScreen, gr->T("FullScreen")))->OnClick.Handle(this, &GameSettingsScreen::OnFullscreenChange);
if (System_GetPropertyInt(SYSPROP_DISPLAY_COUNT) > 1) {
CheckBox *fullscreenMulti = new CheckBox(&g_Config.bFullScreenMulti, gr->T("Use all displays"));
fullscreenMulti->SetEnabledPtr(&g_Config.bFullScreen);
graphicsSettings->Add(fullscreenMulti)->OnClick.Handle(this, &GameSettingsScreen::OnFullscreenChange);
}
#endif
// Display Layout Editor: To avoid overlapping touch controls on large tablets, meet geeky demands for integer zoom/unstretched image etc.
displayEditor_ = graphicsSettings->Add(new Choice(gr->T("Display layout editor")));
@ -972,12 +977,7 @@ UI::EventReturn GameSettingsScreen::OnReloadCheats(UI::EventParams &e) {
}
UI::EventReturn GameSettingsScreen::OnFullscreenChange(UI::EventParams &e) {
#if defined(USING_WIN_UI) || defined(USING_QT_UI)
host->GoFullscreen(g_Config.bFullScreen);
#else
// SDL, basically.
System_SendMessage("toggle_fullscreen", "");
#endif
System_SendMessage("toggle_fullscreen", g_Config.bFullScreen ? "1" : "0");
return UI::EVENT_DONE;
}

View File

@ -91,7 +91,6 @@ struct VerySleepy_AddrInfo {
wchar_t name[256];
};
static RECT g_normalRC = {0};
static std::wstring windowTitle;
extern ScreenManager *screenManager;
@ -117,6 +116,7 @@ namespace MainWindow
static bool hideCursor = false;
static int g_WindowState;
static bool g_IgnoreWM_SIZE = false;
static bool inFullscreenResize = false;
static bool inResizeMove = false;
// gross hack
@ -172,7 +172,7 @@ namespace MainWindow
}
void SavePosition() {
if (g_Config.bFullScreen)
if (g_Config.bFullScreen || inFullscreenResize)
return;
WINDOWPLACEMENT placement;
@ -297,7 +297,11 @@ namespace MainWindow
graphicsContext->Pause();
}
WINDOWPLACEMENT placement = { sizeof(WINDOWPLACEMENT) };
GetWindowPlacement(hwndMain, &placement);
int oldWindowState = g_WindowState;
inFullscreenResize = true;
g_IgnoreWM_SIZE = true;
DWORD dwStyle;
@ -315,11 +319,9 @@ namespace MainWindow
} else {
// If the window was maximized before going fullscreen, make sure to restore first
// in order not to have the taskbar show up on top of PPSSPP.
if (oldWindowState == SIZE_MAXIMIZED) {
if (oldWindowState == SIZE_MAXIMIZED || placement.showCmd == SW_SHOWMAXIMIZED) {
ShowWindow(hwndMain, SW_RESTORE);
}
// Remember the normal window rectangle.
::GetWindowRect(hWnd, &g_normalRC);
// Remove caption and border styles.
dwStyle = ::GetWindowLong(hWnd, GWL_STYLE);
@ -340,15 +342,31 @@ namespace MainWindow
// Resize to the appropriate view.
// If we're returning to window mode, re-apply the appropriate size setting.
if (goingFullscreen) {
ShowWindow(hwndMain, SW_MAXIMIZE);
if (g_Config.bFullScreenMulti) {
// Maximize isn't enough to display on all monitors.
// Remember that negative coordinates may be valid.
int totalX = GetSystemMetrics(SM_XVIRTUALSCREEN);
int totalY = GetSystemMetrics(SM_YVIRTUALSCREEN);
int totalWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
int totalHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
MoveWindow(hwndMain, totalX, totalY, totalWidth, totalHeight, TRUE);
HandleSizeChange(oldWindowState);
} else {
ShowWindow(hwndMain, SW_MAXIMIZE);
}
} else {
ShowWindow(hwndMain, oldWindowState == SIZE_MAXIMIZED ? SW_MAXIMIZE : SW_RESTORE);
if (g_Config.bFullScreenMulti && oldWindowState != SIZE_MAXIMIZED) {
// Return the screen to where it was.
MoveWindow(hwndMain, g_Config.iWindowX, g_Config.iWindowY, g_Config.iWindowWidth, g_Config.iWindowHeight, TRUE);
}
if (oldWindowState == SIZE_MAXIMIZED) {
// WM_SIZE wasn't sent, since the size didn't change (it was full screen before and after.)
HandleSizeChange(oldWindowState);
}
}
inFullscreenResize = false;
CorrectCursor();
ShowOwnedPopups(hwndMain, goingFullscreen ? FALSE : TRUE);
@ -365,7 +383,6 @@ namespace MainWindow
ShowWindow(hwndMain, SW_MINIMIZE);
}
// Note that this also updates the config! Not very clean.
RECT DetermineWindowRectangle() {
const int virtualScreenWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
const int virtualScreenHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
@ -407,25 +424,25 @@ namespace MainWindow
int scale = (int)ceil(2.0 / dpi_scale);
GetWindowSizeAtResolution(scale * (portrait ? 272 : 480), scale * (portrait ? 480 : 272), &windowWidth, &windowHeight);
g_Config.iWindowWidth = windowWidth;
g_Config.iWindowHeight = windowHeight;
}
// Then center if necessary. One dimension at a time.
// Max is to make sure that if we end up making the window bigger than the screen (which is not ideal), the top left
// corner, and thus the menu etc, will be visible. Also potential workaround for #9563.
int x = g_Config.iWindowX;
int y = g_Config.iWindowY;
if (resetPositionX) {
g_Config.iWindowX = std::max(0, (currentScreenWidth - g_Config.iWindowWidth) / 2);
x = std::max(0, (currentScreenWidth - windowWidth) / 2);
}
if (resetPositionY) {
g_Config.iWindowY = std::max(0, (currentScreenHeight - g_Config.iWindowHeight) / 2);
y = std::max(0, (currentScreenHeight - windowHeight) / 2);
}
RECT rc;
rc.left = g_Config.iWindowX;
rc.right = rc.left + g_Config.iWindowWidth;
rc.top = g_Config.iWindowY;
rc.bottom = rc.top + g_Config.iWindowHeight;
rc.left = x;
rc.right = rc.left + windowWidth;
rc.top = y;
rc.bottom = rc.top + windowHeight;
return rc;
}
@ -441,6 +458,7 @@ namespace MainWindow
BOOL Show(HINSTANCE hInstance) {
hInst = hInstance; // Store instance handle in our global variable.
RECT rc = DetermineWindowRectangle();
SavePosition();
u32 style = WS_OVERLAPPEDWINDOW;

View File

@ -360,10 +360,6 @@ bool WindowsHost::CreateDesktopShortcut(std::string argumentPath, std::string ga
return false;
}
void WindowsHost::GoFullscreen(bool viewFullscreen) {
MainWindow::SendToggleFullscreen(viewFullscreen);
}
void WindowsHost::ToggleDebugConsoleVisibility() {
MainWindow::ToggleDebugConsoleVisibility();
}

View File

@ -66,8 +66,6 @@ public:
void NotifyUserMessage(const std::string &message, float duration = 1.0f, u32 color = 0x00FFFFFF, const char *id = nullptr) override;
void GoFullscreen(bool) override;
std::shared_ptr<KeyboardDevice> keyboard;
GraphicsContext *GetGraphicsContext() { return gfx_; }

View File

@ -212,6 +212,8 @@ int System_GetPropertyInt(SystemProperty prop) {
return DEVICE_TYPE_DESKTOP;
case SYSPROP_DISPLAY_DPI:
return ScreenDPI();
case SYSPROP_DISPLAY_COUNT:
return GetSystemMetrics(SM_CMONITORS);
default:
return -1;
}
@ -263,6 +265,14 @@ void System_SendMessage(const char *command, const char *parameter) {
MainWindow::BrowseAndBoot("");
} else if (!strcmp(command, "bgImage_browse")) {
MainWindow::BrowseBackground();
} else if (!strcmp(command, "toggle_fullscreen")) {
bool flag = !g_Config.bFullScreen;
if (strcmp(parameter, "0") == 0) {
flag = false;
} else if (strcmp(parameter, "1") == 0) {
flag = true;
}
MainWindow::SendToggleFullscreen(flag);
}
}

View File

@ -169,6 +169,7 @@ enum SystemProperty {
SYSPROP_DISPLAY_YRES,
SYSPROP_DISPLAY_REFRESH_RATE, // returns 1000*the refresh rate in Hz as it can be non-integer
SYSPROP_DISPLAY_DPI,
SYSPROP_DISPLAY_COUNT,
SYSPROP_MOGA_VERSION,
SYSPROP_DEVICE_TYPE,

View File

@ -66,6 +66,7 @@ GlobalUIState GetUIState();
static SDL_Window* g_Screen = NULL;
static bool g_ToggleFullScreenNextFrame = false;
static int g_ToggleFullScreenType;
static int g_QuitRequested = 0;
static int g_DesktopWidth = 0;
@ -248,6 +249,14 @@ void Vibrate(int length_ms) {
void System_SendMessage(const char *command, const char *parameter) {
if (!strcmp(command, "toggle_fullscreen")) {
g_ToggleFullScreenNextFrame = true;
if (strcmp(parameter, "1") == 0) {
g_ToggleFullScreenType = 1;
} else if (strcmp(parameter, "0") == 0) {
g_ToggleFullScreenType = 0;
} else {
// Just toggle.
g_ToggleFullScreenType = -1;
}
} else if (!strcmp(command, "finish")) {
// Do a clean exit
g_QuitRequested = true;
@ -391,7 +400,14 @@ void ToggleFullScreenIfFlagSet() {
g_ToggleFullScreenNextFrame = false;
Uint32 window_flags = SDL_GetWindowFlags(g_Screen);
SDL_SetWindowFullscreen(g_Screen, window_flags ^ SDL_WINDOW_FULLSCREEN_DESKTOP);
if (g_ToggleFullScreenType == -1) {
window_flags ^= SDL_WINDOW_FULLSCREEN_DESKTOP;
} else if (g_ToggleFullScreenType == 1) {
window_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
} else {
window_flags &= ~SDL_WINDOW_FULLSCREEN_DESKTOP;
}
SDL_SetWindowFullscreen(g_Screen, window_flags);
}
}