diff --git a/source/lib/sysdep/os/win/mahaf.cpp b/source/lib/sysdep/os/win/mahaf.cpp index 6f4425973e..eb800afb25 100644 --- a/source/lib/sysdep/os/win/mahaf.cpp +++ b/source/lib/sysdep/os/win/mahaf.cpp @@ -27,15 +27,16 @@ #include "precompiled.h" #include "lib/sysdep/os/win/mahaf.h" -#include "lib/sysdep/os/win/win.h" -#include -#include "lib/sysdep/os/win/aken/aken.h" -#include "lib/sysdep/os/win/wutil.h" #include "lib/module_init.h" +#include "lib/sysdep/os/win/wutil.h" +#include +#include "lib/sysdep/os/win/aken/aken.h" +#include "lib/sysdep/os/win/wversion.h" static HANDLE hAken = INVALID_HANDLE_VALUE; // handle to Aken driver + //----------------------------------------------------------------------------- // ioctl wrappers //----------------------------------------------------------------------------- @@ -114,7 +115,7 @@ bool mahaf_IsPhysicalMappingDangerous() { // pre-XP versions don't prevent re-mapping pages with incompatible // attributes, which may lead to disaster due to TLB corruption. - if(wutil_WindowsVersion() < WUTIL_VERSION_XP) + if(wversion_Number() < WVERSION_XP) return true; return false; diff --git a/source/lib/sysdep/os/win/wposix/wutsname.cpp b/source/lib/sysdep/os/win/wposix/wutsname.cpp index b8bd80a88b..85ace54c20 100644 --- a/source/lib/sysdep/os/win/wposix/wutsname.cpp +++ b/source/lib/sysdep/os/win/wposix/wutsname.cpp @@ -24,7 +24,7 @@ #include "lib/sysdep/os/win/wposix/wutsname.h" #include "lib/utf8.h" -#include "lib/sysdep/os/win/wutil.h" +#include "lib/sysdep/os/win/wversion.h" #include "lib/sysdep/os/win/wposix/wposix_internal.h" @@ -36,7 +36,7 @@ int uname(struct utsname* un) GetVersionExW(&vi); // OS implementation name - sprintf_s(un->sysname, ARRAY_SIZE(un->sysname), "%ls", wutil_WindowsFamily()); + sprintf_s(un->sysname, ARRAY_SIZE(un->sysname), "%ls", wversion_Family()); // release info const wchar_t* vs = vi.szCSDVersion; @@ -45,7 +45,7 @@ int uname(struct utsname* un) sprintf_s(un->release, ARRAY_SIZE(un->release), "SP %d", sp); // version - sprintf_s(un->version, ARRAY_SIZE(un->version), "%ls.%lu", wutil_WindowsVersionString(), vi.dwBuildNumber & 0xFFFF); + sprintf_s(un->version, ARRAY_SIZE(un->version), "%ls.%lu", wversion_String(), vi.dwBuildNumber & 0xFFFF); // node name DWORD buf_size = sizeof(un->nodename); diff --git a/source/lib/sysdep/os/win/wsnd.cpp b/source/lib/sysdep/os/win/wsnd.cpp index 6f3c5195aa..818776086f 100644 --- a/source/lib/sysdep/os/win/wsnd.cpp +++ b/source/lib/sysdep/os/win/wsnd.cpp @@ -34,7 +34,7 @@ #include "lib/path_util.h" #include "lib/sysdep/os/win/wdll_ver.h" -#include "lib/sysdep/os/win/win.h" +#include "lib/sysdep/os/win/wversion.h" #include "lib/sysdep/os/win/wutil.h" #include "lib/sysdep/os/win/wmi.h" @@ -134,7 +134,7 @@ LibError win_get_snd_info() // find all DLLs related to OpenAL and retrieve their versions. std::wstring versionList; - if(wutil_WindowsVersion() < WUTIL_VERSION_VISTA) + if(wversion_Number() < WVERSION_VISTA) wdll_ver_Append(GetDirectSoundDriverPath(), versionList); StringSet dlls; // ensures uniqueness (void)add_oal_dlls_in_dir(wutil_ExecutablePath(), dlls, versionList); diff --git a/source/lib/sysdep/os/win/wutil.cpp b/source/lib/sysdep/os/win/wutil.cpp index 7f6d730314..e4e02d26e0 100644 --- a/source/lib/sysdep/os/win/wutil.cpp +++ b/source/lib/sysdep/os/win/wutil.cpp @@ -380,77 +380,6 @@ static void EnableLowFragmentationHeap() } -//----------------------------------------------------------------------------- -// version - -static wchar_t windowsVersionString[20]; -static size_t windowsVersion; // see WUTIL_VERSION_* - -static void DetectWindowsVersion() -{ - // note: don't use GetVersion[Ex] because it gives the version of the - // emulated OS when running an app with compatibility shims enabled. - HKEY hKey; - if(RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) - { - DWORD size = sizeof(windowsVersionString); - (void)RegQueryValueExW(hKey, L"CurrentVersion", 0, 0, (LPBYTE)windowsVersionString, &size); - - unsigned major = 0, minor = 0; - // ICC 11.1.082 generates incorrect code for the following: - // const int ret = swscanf_s(windowsVersionString, L"%u.%u", &major, &minor); - std::wstringstream ss(windowsVersionString); - ss >> major; - wchar_t dot; - ss >> dot; - debug_assert(dot == '.'); - ss >> minor; - - debug_assert(4 <= major && major <= 0xFF); - debug_assert(minor <= 0xFF); - windowsVersion = (major << 8) | minor; - - RegCloseKey(hKey); - } - else - debug_assert(0); -} - - -const wchar_t* wutil_WindowsFamily() -{ - debug_assert(windowsVersion != 0); - switch(windowsVersion) - { - case WUTIL_VERSION_2K: - return L"Win2k"; - case WUTIL_VERSION_XP: - return L"WinXP"; - case WUTIL_VERSION_XP64: - return L"WinXP64"; - case WUTIL_VERSION_VISTA: - return L"Vista"; - case WUTIL_VERSION_7: - return L"Win7"; - default: - return L"Windows"; - } -} - - -const wchar_t* wutil_WindowsVersionString() -{ - debug_assert(windowsVersionString[0] != '\0'); - return windowsVersionString; -} - -size_t wutil_WindowsVersion() -{ - debug_assert(windowsVersion != 0); - return windowsVersion; -} - - //----------------------------------------------------------------------------- // Wow64 @@ -601,8 +530,6 @@ static LibError wutil_Init() GetDirectories(); - DetectWindowsVersion(); - ImportWow64Functions(); DetectWow64(); diff --git a/source/lib/sysdep/os/win/wutil.h b/source/lib/sysdep/os/win/wutil.h index f2161220b8..3290953340 100644 --- a/source/lib/sysdep/os/win/wutil.h +++ b/source/lib/sysdep/os/win/wutil.h @@ -176,26 +176,6 @@ extern const fs::wpath& wutil_ExecutablePath(); extern const fs::wpath& wutil_AppdataPath(); -//----------------------------------------------------------------------------- -// version - -extern const wchar_t* wutil_WindowsVersionString(); - -// (same format as WINVER) -const size_t WUTIL_VERSION_2K = 0x0500; -const size_t WUTIL_VERSION_XP = 0x0501; -const size_t WUTIL_VERSION_XP64 = 0x0502; -const size_t WUTIL_VERSION_VISTA = 0x0600; -const size_t WUTIL_VERSION_7 = 0x0601; - -/** - * @return short textual representation of the appropriate WUTIL_VERSION - **/ -extern const wchar_t* wutil_WindowsFamily(); - -LIB_API size_t wutil_WindowsVersion(); - - //----------------------------------------------------------------------------- // Wow64 diff --git a/source/lib/sysdep/os/win/wversion.cpp b/source/lib/sysdep/os/win/wversion.cpp new file mode 100644 index 0000000000..732211f3d7 --- /dev/null +++ b/source/lib/sysdep/os/win/wversion.cpp @@ -0,0 +1,100 @@ +/* Copyright (c) 2010 Wildfire Games + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "precompiled.h" +#include "lib/sysdep/os/win/wversion.h" + +#include "lib/sysdep/os/win/win.h" +#include "lib/sysdep/os/win/winit.h" + +WINIT_REGISTER_EARLY_INIT(wversion_Init); + + +static wchar_t windowsVersionString[20]; +static size_t windowsVersion; // see WVERSION_* + + +const wchar_t* wversion_Family() +{ + debug_assert(windowsVersion != 0); + switch(windowsVersion) + { + case WVERSION_2K: + return L"Win2k"; + case WVERSION_XP: + return L"WinXP"; + case WVERSION_XP64: + return L"WinXP64"; + case WVERSION_VISTA: + return L"Vista"; + case WVERSION_7: + return L"Win7"; + default: + return L"Windows"; + } +} + + +const wchar_t* wversion_String() +{ + debug_assert(windowsVersionString[0] != '\0'); + return windowsVersionString; +} + +size_t wversion_Number() +{ + debug_assert(windowsVersion != 0); + return windowsVersion; +} + + +static LibError wversion_Init() +{ + // note: don't use GetVersion[Ex] because it gives the version of the + // emulated OS when running an app with compatibility shims enabled. + HKEY hKey; + if(RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) + { + DWORD size = sizeof(windowsVersionString); + (void)RegQueryValueExW(hKey, L"CurrentVersion", 0, 0, (LPBYTE)windowsVersionString, &size); + + unsigned major = 0, minor = 0; + // ICC 11.1.082 generates incorrect code for the following: + // const int ret = swscanf_s(windowsVersionString, L"%u.%u", &major, &minor); + std::wstringstream ss(windowsVersionString); + ss >> major; + wchar_t dot; + ss >> dot; + debug_assert(dot == '.'); + ss >> minor; + + debug_assert(4 <= major && major <= 0xFF); + debug_assert(minor <= 0xFF); + windowsVersion = (major << 8) | minor; + + RegCloseKey(hKey); + } + else + debug_assert(0); + + return INFO::OK; +} diff --git a/source/lib/sysdep/os/win/wversion.h b/source/lib/sysdep/os/win/wversion.h new file mode 100644 index 0000000000..bb9246ae66 --- /dev/null +++ b/source/lib/sysdep/os/win/wversion.h @@ -0,0 +1,48 @@ +/* Copyright (c) 2010 Wildfire Games + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef INCLUDED_WVERSION +#define INCLUDED_WVERSION + +/** + * @return CurrentVersion string from registry + **/ +extern const wchar_t* wversion_String(); + +// (same format as WINVER) +const size_t WVERSION_2K = 0x0500; +const size_t WVERSION_XP = 0x0501; +const size_t WVERSION_XP64 = 0x0502; +const size_t WVERSION_VISTA = 0x0600; +const size_t WVERSION_7 = 0x0601; + +/** + * @return one of the above WVERSION* values + **/ +LIB_API size_t wversion_Number(); + +/** + * @return short textual representation of the version + **/ +extern const wchar_t* wversion_Family(); + +#endif // #ifndef INCLUDED_WVERSION diff --git a/source/ps/GameSetup/GameSetup.cpp b/source/ps/GameSetup/GameSetup.cpp index 34c44dd51f..5706a09dee 100644 --- a/source/ps/GameSetup/GameSetup.cpp +++ b/source/ps/GameSetup/GameSetup.cpp @@ -31,6 +31,9 @@ #include "lib/sysdep/cpu.h" #include "lib/sysdep/gfx.h" #include "lib/tex/tex.h" +#if OS_WIN +#include "lib/sysdep/os/win/wversion.h" +#endif #include "ps/CConsole.h" #include "ps/CLogger.h" @@ -334,12 +337,69 @@ static void InitScripting() } -static size_t ChooseCacheSize() +static size_t OperatingSystemFootprint() { #if OS_WIN - //const size_t overheadKiB = (wutil_WindowsVersion() >= WUTIL_VERSION_VISTA)? 1024 : 512; + switch(wversion_Number()) + { + case WVERSION_2K: + case WVERSION_XP: + return 150; + case WVERSION_XP64: + return 200; + default: + debug_assert(0); + //fall through + case WVERSION_VISTA: + return 300; + case WVERSION_7: + return 250; + } +#else + return 200; #endif - return 96*MiB; +} + +static size_t ChooseCacheSize() +{ + // (all sizes in MiB) + const size_t total = os_cpu_MemorySize(); + const size_t available = os_cpu_MemoryAvailable(); + debug_assert(total >= available); + const size_t inUse = total-available; + size_t os = OperatingSystemFootprint(); + debug_assert(total >= os/2); + size_t apps = (inUse > os)? (inUse - os) : 0; + size_t game = 400; + size_t cache = 200; + + // plenty of memory + if(os + apps + game + cache < total) + { + // data is currently about 500 MiB; clamp max size to twice that + // to avoid unnecessarily wiping out the OS file cache. + cache = std::min(total - os - apps - game, (size_t)1024); + } + else // below min-spec + { + // assume kernel+other apps will be swapped out + os = 9*os/10; + apps = 1*apps/3; + game = 3*game/4; + if(os + apps + game + cache < total) + cache = total - os - apps - game; + else + { + cache = 50; + debug_printf(L"Warning: memory size (%d MiB, %d used) is rather low\n", total, available); + } + } + + // ensure the value will fit in size_t + cache = std::min(cache, (size_t)(std::numeric_limits::max()/MiB)); + + debug_printf(L"Cache: %d (total: %d; available: %d)\n", cache, total, available); + return cache*MiB; }