From 63050715ee54f1e8c39f69557d6d012bd6316d6b Mon Sep 17 00:00:00 2001 From: mmbob Date: Mon, 22 Apr 2013 13:04:43 -0400 Subject: [PATCH 1/3] Replace __ImageBase. Save + load window position. Instead of using the __ImageBase global variable, use the GetModuleHandle(NULL) function to get the exe's HMODULE/HINSTANCE. Save the window position when the game is closed and restore it when it is opened. Defaults to being centered on the desktop. --- src/PowderToySDL.cpp | 98 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 92 insertions(+), 6 deletions(-) diff --git a/src/PowderToySDL.cpp b/src/PowderToySDL.cpp index c57b3b914..d5d0949da 100644 --- a/src/PowderToySDL.cpp +++ b/src/PowderToySDL.cpp @@ -53,10 +53,6 @@ Atom XA_CLIPBOARD, XA_TARGETS; char *clipboardText = NULL; -#ifdef WIN -extern "C" IMAGE_DOS_HEADER __ImageBase; -#endif - int desktopWidth = 1280, desktopHeight = 1024; SDL_Surface * sdl_scrn; @@ -276,8 +272,11 @@ int SDLOpen() exit(-1); } HWND WindowHandle = SysInfo.window; - HICON hIconSmall = (HICON)LoadImage(reinterpret_cast(&__ImageBase), MAKEINTRESOURCE(101), IMAGE_ICON, 16, 16, LR_SHARED); - HICON hIconBig = (HICON)LoadImage(reinterpret_cast(&__ImageBase), MAKEINTRESOURCE(101), IMAGE_ICON, 32, 32, LR_SHARED); + + // Use GetModuleHandle to get the Exe HMODULE/HINSTANCE + HMODULE hModExe = GetModuleHandle(NULL); + HICON hIconSmall = (HICON)LoadImage(hModExe, MAKEINTRESOURCE(101), IMAGE_ICON, 16, 16, LR_SHARED); + HICON hIconBig = (HICON)LoadImage(hModExe, MAKEINTRESOURCE(101), IMAGE_ICON, 32, 32, LR_SHARED); SendMessage(WindowHandle, WM_SETICON, ICON_SMALL, (LPARAM)hIconSmall); SendMessage(WindowHandle, WM_SETICON, ICON_BIG, (LPARAM)hIconBig); #elif defined(LIN) @@ -543,6 +542,83 @@ int GetModifiers() return SDL_GetModState(); } +#ifdef WIN + +// Returns true if the loaded position was set +// Returns false if something went wrong: SDL_GetWMInfo failed or the loaded position was invalid +bool LoadWindowPosition() +{ + SDL_SysWMinfo sysInfo; + SDL_VERSION(&sysInfo.version); + if (SDL_GetWMInfo(&sysInfo) > 0) + { + RECT rcWindow; + GetWindowRect(sysInfo.window, &rcWindow); + + int windowW = rcWindow.right - rcWindow.left - 1; + int windowH = rcWindow.bottom - rcWindow.top - 1; + + int windowX = Client::Ref().GetPrefInteger("WindowX", INT_MAX); + int windowY = Client::Ref().GetPrefInteger("WindowY", INT_MAX); + + bool setDefaultPos = true; + + if (windowX != INT_MAX && windowY != INT_MAX) + { + POINT windowPoints[] = { + {windowX, windowY}, // Top-left + {windowX + windowW, windowY + windowH} // Bottom-right + }; + + MONITORINFO monitor; + monitor.cbSize = sizeof(monitor); + if (GetMonitorInfo(MonitorFromPoint(windowPoints[0], MONITOR_DEFAULTTOPRIMARY), &monitor) != 0) + { + // Only use the saved window position if it lies inside the visible screen + if (PtInRect(&monitor.rcMonitor, windowPoints[0]) && PtInRect(&monitor.rcMonitor, windowPoints[1])) + { + SetWindowPos(sysInfo.window, 0, windowX, windowY, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER); + + setDefaultPos = false; + } + } + } + + if (setDefaultPos) + { + // Center the window on the primary desktop by default + SetWindowPos(sysInfo.window, 0, (desktopWidth - windowW) / 2, (desktopHeight - windowH) / 2, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER); + } + + // True if we didn't use the default, i.e. the position was valid + return !setDefaultPos; + } + + return false; +} + +// Returns true if the window position was saved +bool SaveWindowPosition() +{ + SDL_SysWMinfo sysInfo; + SDL_VERSION(&sysInfo.version); + if (SDL_GetWMInfo(&sysInfo) > 0) + { + WINDOWPLACEMENT placement; + placement.length = sizeof(placement); + GetWindowPlacement(sysInfo.window, &placement); + + Client::Ref().SetPref("WindowX", placement.rcNormalPosition.left); + Client::Ref().SetPref("WindowY", placement.rcNormalPosition.top); + + return true; + } + + return false; +} + +#endif + int main(int argc, char * argv[]) { currentWidth = XRES+BARSIZE; @@ -603,6 +679,12 @@ int main(int argc, char * argv[]) int sdlStatus = SDLOpen(); sdl_scrn = SDLSetScreen(tempScale, tempFullscreen); + +#ifdef WIN + // Must be after SDLSetScreen to account for scale + LoadWindowPosition(); +#endif + #ifdef OGLI SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1); //glScaled(2.0f, 2.0f, 1.0f); @@ -734,6 +816,10 @@ int main(int argc, char * argv[]) EngineProcess(); +#ifdef WIN + SaveWindowPosition(); +#endif + ui::Engine::Ref().CloseWindow(); delete gameController; delete ui::Engine::Ref().g; From e166640cbbe6d990175e835ae9ff463d9bae34f1 Mon Sep 17 00:00:00 2001 From: mmbob Date: Mon, 22 Apr 2013 13:05:10 -0400 Subject: [PATCH 2/3] Fix reading hexadecimal in TPTScriptInterface Instead of subtracting 'A', subtract 'a' --- src/cat/TPTScriptInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cat/TPTScriptInterface.cpp b/src/cat/TPTScriptInterface.cpp index 5d9a5e05b..f8c6af66a 100644 --- a/src/cat/TPTScriptInterface.cpp +++ b/src/cat/TPTScriptInterface.cpp @@ -137,7 +137,7 @@ int TPTScriptInterface::parseNumber(char * stringData) if(cc >= '0' && cc <= '9') currentNumber += cc - '0'; else if(cc >= 'a' && cc <= 'f') - currentNumber += (cc - 'A') + 10; + currentNumber += (cc - 'a') + 10; else if(cc >= 'A' && cc <= 'F') currentNumber += (cc - 'A') + 10; else From df14a771240ca11c17299d2137d474dee1fb3c6e Mon Sep 17 00:00:00 2001 From: mmbob Date: Thu, 2 May 2013 13:00:13 -0400 Subject: [PATCH 3/3] LoadWindowPosition has a better default position LoadWindowPosition now positions the window on the nearest monitor if the window is not inside a monitor. --- src/PowderToySDL.cpp | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/src/PowderToySDL.cpp b/src/PowderToySDL.cpp index d5d0949da..ab76bdf2e 100644 --- a/src/PowderToySDL.cpp +++ b/src/PowderToySDL.cpp @@ -558,40 +558,47 @@ bool LoadWindowPosition() int windowW = rcWindow.right - rcWindow.left - 1; int windowH = rcWindow.bottom - rcWindow.top - 1; - int windowX = Client::Ref().GetPrefInteger("WindowX", INT_MAX); - int windowY = Client::Ref().GetPrefInteger("WindowY", INT_MAX); + int savedWindowX = Client::Ref().GetPrefInteger("WindowX", INT_MAX); + int savedWindowY = Client::Ref().GetPrefInteger("WindowY", INT_MAX); + + // Center the window on the primary desktop by default + int newWindowX = (desktopWidth - windowW) / 2; + int newWindowY = (desktopHeight - windowH) / 2; - bool setDefaultPos = true; + bool success = false; - if (windowX != INT_MAX && windowY != INT_MAX) + if (savedWindowX != INT_MAX && savedWindowY != INT_MAX) { POINT windowPoints[] = { - {windowX, windowY}, // Top-left - {windowX + windowW, windowY + windowH} // Bottom-right + {savedWindowX, savedWindowY}, // Top-left + {savedWindowX + windowW, savedWindowY + windowH} // Bottom-right }; MONITORINFO monitor; monitor.cbSize = sizeof(monitor); - if (GetMonitorInfo(MonitorFromPoint(windowPoints[0], MONITOR_DEFAULTTOPRIMARY), &monitor) != 0) + if (GetMonitorInfo(MonitorFromPoint(windowPoints[0], MONITOR_DEFAULTTONEAREST), &monitor) != 0) { // Only use the saved window position if it lies inside the visible screen if (PtInRect(&monitor.rcMonitor, windowPoints[0]) && PtInRect(&monitor.rcMonitor, windowPoints[1])) { - SetWindowPos(sysInfo.window, 0, windowX, windowY, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER); + newWindowX = savedWindowX; + newWindowY = savedWindowY; - setDefaultPos = false; + success = true; + } + else + { + // Center the window on the nearest monitor + newWindowX = monitor.rcMonitor.left + (monitor.rcMonitor.right - monitor.rcMonitor.left - windowW) / 2; + newWindowY = monitor.rcMonitor.top + (monitor.rcMonitor.bottom - monitor.rcMonitor.top - windowH) / 2; } } } - if (setDefaultPos) - { - // Center the window on the primary desktop by default - SetWindowPos(sysInfo.window, 0, (desktopWidth - windowW) / 2, (desktopHeight - windowH) / 2, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER); - } + SetWindowPos(sysInfo.window, 0, newWindowX, newWindowY, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER); // True if we didn't use the default, i.e. the position was valid - return !setDefaultPos; + return success; } return false;