diff --git a/openVulkanoCpp/Host/SystemInfo.hpp b/openVulkanoCpp/Host/SystemInfo.hpp index 2825457..25e1361 100644 --- a/openVulkanoCpp/Host/SystemInfo.hpp +++ b/openVulkanoCpp/Host/SystemInfo.hpp @@ -24,7 +24,7 @@ namespace OpenVulkano enum class DeviceOrientation { Portrait, PortraitUpsideDown, LandscapeLeft, LandscapeRight, FaceUp, FaceDown, Unknown }; - enum class InterfaceOrientation { Portrait, PortraitUpsideDown, LandscapeLeft, LandscapeRight, Landscape = LandscapeLeft }; + enum class InterfaceOrientation { Portrait, PortraitUpsideDown, LandscapeLeft, LandscapeRight, Landscape = LandscapeLeft, Unknown }; class SystemInfo { diff --git a/openVulkanoCpp/Host/Windows/SystemInfo.cpp b/openVulkanoCpp/Host/Windows/SystemInfo.cpp index 6457544..99d7819 100644 --- a/openVulkanoCpp/Host/Windows/SystemInfo.cpp +++ b/openVulkanoCpp/Host/Windows/SystemInfo.cpp @@ -12,16 +12,33 @@ #include #include #include +#include +#include +#include // NOTE(vb): Windows defines macros like GetUserName that are used to automatically select the appropriate function version (GetUserNameA for ANSI and GetUserNameW for Unicode) // based on whether the _UNICODE macro is defined, so we manually undefine these macros to avoid naming collisions. #undef GetUserName +// link this for power settings +#pragma comment(lib, "PowrProf.lib") + namespace OpenVulkano { namespace { enum class SYS_MEM_TYPE { TOTAL_PHYS, AVAIL_PHYS }; + + enum BatteryChargeStatus + { + MEDIUM = 0, // [low, high] + HIGH = 1, // > 66% + LOW = 2, // < 33% + CRITICAL = 4, // <5% + CHARGING = 8, + NO_SYSTEM_BATTERY = 128, + UNKNOWN = 255 + }; size_t ReadSystemMemInfo(SYS_MEM_TYPE type) { @@ -137,7 +154,7 @@ namespace OpenVulkano return "Windows"; } - OsVersion SystemInfo::GetOsVersion() + OsVersion SystemInfo::GetOsVersion() { OSVERSIONINFOA info; ZeroMemory(&info, sizeof(OSVERSIONINFOA)); @@ -148,14 +165,19 @@ namespace OpenVulkano std::string SystemInfo::GetOsNameHumanReadable() { - OSVERSIONINFOEXA info; - ZeroMemory(&info, sizeof(OSVERSIONINFOEXA)); - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionEx((OSVERSIONINFOA *)&info); + NTSTATUS(WINAPI *RtlGetVersion)(LPOSVERSIONINFOEXW); + OSVERSIONINFOEXW info; + *(FARPROC*)&RtlGetVersion = GetProcAddress(GetModuleHandleA("ntdll"), "RtlGetVersion"); + info.dwOSVersionInfoSize = sizeof(info); + RtlGetVersion(&info); if (info.wProductType == VER_NT_WORKSTATION) { if (info.dwMajorVersion == 10) + { + if (info.dwBuildNumber >= 22000) + return "Windows 11"; return "Windows 10"; + } else if (info.dwMajorVersion == 6) { switch (info.dwMinorVersion) @@ -172,7 +194,35 @@ namespace OpenVulkano else { if (info.dwMajorVersion == 10) - return "Windows Server 2016"; + { + switch (info.dwBuildNumber) + { + case 14393: + return "Windows Server 2016"; + case 16299: + return "Windows Server 1709"; + case 17134: + return "Windows Server 1803"; + case 17763: + return "Windows Server 2019"; + case 18362: + return "Windows Server 1903"; + case 18363: + return "Windows Server 1909"; + case 19041: + return "Windows Server 2004"; + case 19042: + return "Windows Server 20H2"; + case 20348: + return "Windows Server 2022"; + case 25398: + return "Windows Server 23H2"; + case 26100: + return "Windows Server 2025"; + default: + return "Windows Server"; + } + } else if (info.dwMajorVersion == 6) { switch (info.dwMinorVersion) @@ -188,14 +238,17 @@ namespace OpenVulkano } } - DeviceType SystemInfo::GetDeviceType() + DeviceType SystemInfo::GetDeviceType() { return DeviceType::PC; } - size_t SystemInfo::GetCpuCoreCount() + size_t SystemInfo::GetCpuCoreCount() { - return 0; //TODO + SYSTEM_INFO info; + ZeroMemory(&info, sizeof(SYSTEM_INFO)); + GetSystemInfo(&info); + return info.dwNumberOfProcessors; } size_t SystemInfo::GetCpuThreadCount() @@ -210,22 +263,46 @@ namespace OpenVulkano CpuThermalState SystemInfo::GetCpuThermalState() { - return CpuThermalState::Normal; + return CpuThermalState::Normal; // TODO } bool SystemInfo::IsDeviceInLowPowerMode() { - return false; //TODO + GUID* activePowerMode; + bool res = false; + if(PowerGetActiveScheme(0, &activePowerMode) == 0) + { + res = IsEqualGUID(*activePowerMode, GUID_MIN_POWER_SAVINGS); + } + LocalFree(activePowerMode); + return res; } BatteryState SystemInfo::GetDeviceBatteryState() { - return BatteryState::Unavailable; //TODO + SYSTEM_POWER_STATUS info; + GetSystemPowerStatus(&info); + BYTE batteryFlag = info.BatteryFlag; + if (batteryFlag & BatteryChargeStatus::CHARGING) + { + if (info.BatteryLifePercent == 100) + return BatteryState::ChargingFull; + return BatteryState::Charging; + } + else if (batteryFlag >= BatteryChargeStatus::MEDIUM && batteryFlag <= BatteryChargeStatus::CRITICAL) + { + return BatteryState::Unplugged; + } + // BatteryState::NotCharging is impossible to distinguish + // NO_SYSTEM_BATTERY or UNKNOWN + return BatteryState::Unavailable; } float SystemInfo::GetDeviceBatteryLevel() { - return 0; //TODO + SYSTEM_POWER_STATUS info; + GetSystemPowerStatus(&info); + return info.BatteryLifePercent != 255 ? static_cast(info.BatteryLifePercent) : 0; } void SystemInfo::EnableEnergyEvents() @@ -240,7 +317,24 @@ namespace OpenVulkano DeviceOrientation SystemInfo::GetDeviceOrientation() { - return DeviceOrientation::LandscapeRight; //TODO + DEVMODEA devmode; + ZeroMemory(&devmode, sizeof(devmode)); + devmode.dmSize = sizeof(DEVMODE); + if (EnumDisplaySettingsA(0, ENUM_CURRENT_SETTINGS, &devmode)) + { + DWORD width = devmode.dmPelsWidth; + DWORD height = devmode.dmPelsHeight; + if (width > height) + { + // landscape + return devmode.dmDisplayOrientation == DMDO_180 ? DeviceOrientation::LandscapeLeft : + DeviceOrientation::LandscapeRight; + } + // portrait + return devmode.dmDisplayOrientation == DMDO_180 ? DeviceOrientation::PortraitUpsideDown : + DeviceOrientation::Portrait; + } + return DeviceOrientation::Unknown; } void SystemInfo::EnableDeviceOrientationEvents() @@ -250,6 +344,19 @@ namespace OpenVulkano InterfaceOrientation SystemInfo::GetInterfaceOrientation() { - return InterfaceOrientation::Landscape; //TODO + DeviceOrientation devOrient = GetDeviceOrientation(); + switch (devOrient) + { + case OpenVulkano::DeviceOrientation::Portrait: + return InterfaceOrientation::Portrait; + case OpenVulkano::DeviceOrientation::PortraitUpsideDown: + return InterfaceOrientation::PortraitUpsideDown; + case OpenVulkano::DeviceOrientation::LandscapeLeft: + return InterfaceOrientation::LandscapeRight; + case OpenVulkano::DeviceOrientation::LandscapeRight: + return InterfaceOrientation::LandscapeLeft; + default: + return InterfaceOrientation::Unknown; + } } } \ No newline at end of file