Thanks for the report. Do you know of any games that use these APIs, so we can validate a fix?
Specific games, unfortunately no other than "they exist" (and speculation that they use this feature for those modes - I haven't actually disassembled games to verify this API's use). This one came up as I was working on modding a game to add a battery life indicator. The following should serve as an MCVE, however:
#include <iostream>
#include <Windows.h>
int main() {
SYSTEM_POWER_STATUS sps;
if (!GetSystemPowerStatus(&sps)) return 1;
std::cout << "== BATTERY STATUS ==" << std::endl;
std::cout << "Battery Present : " << (sps.BatteryFlag < 100) << std::endl;
std::cout << "AC Line Status : " << ((int) sps.ACLineStatus) << std::endl;
std::cout << "Battery Flag : " << ((int) sps.BatteryFlag) << std::endl;
std::cout << "Battery Charge : " << ((int) sps.BatteryLifePercent) << "%" << std::endl;
std::cout << "Battery Life Time : " << ((int) sps.BatteryLifeTime) << " sec" << std::endl;
std::cout << "Battery Full Time : " << ((int) sps.BatteryFullLifeTime) << " sec" << std::endl;
return 0;
}
If an actual game that uses this feature is required, I know Garry's Mod exposes battery information (though this may be through SteamAPI instead). I've heard that Crysis, GRID 2, Shadow of Mordor, and Football Manager support this behavior (or indicators) as well, but have not been able to verify that they specifically call GetSystemPowerStatus.
SDL, however, will specifically call GetSystemPowerStatus on Windows builds: https://github.com/libsdl-org/SDL/blob/main/src/power/windows/SDL_syspower.c
Thanks for the info. I've filed an internal bug for a dev to investigate the games you've mentioned. If you do find any games that seem to have bad battery info, please do let us know. We'll keep you updated on what we find.
Turns out a Wine contributor is already working on this. You could try out his work and provide feedback on his upstream MR, see https://gitlab.winehq.org/wine/wine/-/merge_requests/134
I just got word that this was fixed upstream as of commit 89ec378, currently present on their master branch.
I'm unsure how/when/why Valve re-syncs this repo with upstream (so I won't do anything with this ticket), but the code is now there and ready to go. Thank you all for your help with this!
GOD BLESS YOU
Closing as fixed by the upstream commit in Proton 8.0 (https://github.com/ValveSoftware/wine/commit/89ec37871f6093d8336f636dc967d79579607dd3).
Note: This is an upstream bug reported to Wine as well ([#52831](https://bugs.winehq.org/show_bug.cgi?id=52831)). I am reporting this Issue here as well in hopes of requesting Valve's assistance as this bug affects the Steam Deck particularly. Sample code and possible root cause analysis are both available in the ticket on Wine's side.
Currently, the Steam Deck appears to have an incompatibility with Wine 7.6's implementation of Kernel32's
GetSystemPowerStatusAPI call. The Steam Deck exposes its battery information atBAT1and its AC line status atACADin/sys/class/power_supply:Wine (and Proton, for that matter) only read battery information from
/sys/class/power_supply/ACand/sys/class/power_supply/BAT0. This causes requests toGetSystemPowerStatusto return invalid or incomplete data.Certain games make use of this API to determine if the device is running on battery to display heads-up notifications to users or to change graphical/power settings on-the-fly (e.g. in response to low power events to preserve playtime). While titles that do this still (mostly) work under the Deck, this is a minor compatibility flaw with Wine/Proton that just happens to manifest most severely on the Deck given its battery-driven nature. Games that leverage battery-aware features would benefit from having this state exposed to them, especially on handheld gaming devices.