GAMEPAD: add battery reporting for gamepad devices

(xone,xpadneo,ds4,ds5,switch)
xone-gamepad
Alessandro Toia 2 years ago
parent a029dfaaf2
commit 4be3ba20c2

@ -0,0 +1,147 @@
#include "gamepad.h"
#include <filesystem.h>
#include <iostream>
#include <algorithm>
#include <spdlog/spdlog.h>
namespace fs = ghc::filesystem;
using namespace std;
std::vector<gamepad> gamepad_data;
std::vector<std::string> list;
bool gamepad_found = false;
int gamepad_count = 0;
int xone_count = 0;
int ds4_count = 0;
int ds5_count = 0;
int switch_count = 0;
std::string xbox_paths [2]{"gip","xpadneo"};
bool operator<(const gamepad& a, const gamepad& b)
{
return a.name < b.name;
}
void gamepad_update(){
fs::path path("/sys/class/power_supply");
list.clear();
xone_count = 0;
ds4_count = 0;
ds5_count = 0;
switch_count = 0;
for (auto &p : fs::directory_iterator(path)) {
string fileName = p.path().filename();
//CHECK XONE AND XPADNEO DEVICES
for (string n : xbox_paths ) {
if (fileName.find(n) != std::string::npos) {
list.push_back(p.path());
gamepad_found = true;
xone_count += 1;
}
}
//CHECK FOR DUAL SHOCK 4 DEVICES
if (fileName.find("sony_controller") != std::string::npos) {
list.push_back(p.path());
gamepad_found = true;
ds4_count +=1 ;
}
if (fileName.find("ps-controller") != std::string::npos) {
list.push_back(p.path());
gamepad_found = true;
ds5_count +=1 ;
}
//CHECK FOR NINTENDO SWITCH DEVICES
if (fileName.find("nintendo_switch_controller") != std::string::npos) {
list.push_back(p.path());
gamepad_found = true;
switch_count += 1;
}
}
}
void gamepad_info () {
gamepad_count = 0;
gamepad_data.clear();
int xone_counter = 0;
int ds4_counter = 0;
int ds5_counter = 0;
int switch_counter = 0;
for (auto &path : list ) {
//Set devices paths
std::string capacity = path + "/capacity";
std::string capacity_level = path + "/capacity_level";
std::string status = path + "/status";
std::ifstream input_capacity(capacity);
std::ifstream input_capacity_level(capacity_level);
std::ifstream input_status(status);
std::string line;
gamepad_data.push_back(gamepad());
//Xone devices
if (path.find("gip") != std::string::npos || path.find("xpadneo") != std::string::npos) {
if (xone_count == 1 )
gamepad_data[gamepad_count].name = "XBOX PAD";
else
gamepad_data[gamepad_count].name = "XBOX PAD-" + to_string(xone_counter + 1);
xone_counter++;
}
//DualShock 4 devices
if (path.find("sony_controller") != std::string::npos) {
if (ds4_count == 1)
gamepad_data[gamepad_count].name = "DS4 PAD";
else
gamepad_data[gamepad_count].name = "DS4 PAD-" + to_string(ds4_counter + 1);
ds4_counter++;
}
//DualSense 5 devices
if (path.find("ps-controller") != std::string::npos) {
if (ds5_count == 1)
gamepad_data[gamepad_count].name = "DS5 PAD";
else
gamepad_data[gamepad_count].name = "DS5 PAD-" + to_string(ds5_counter + 1);
ds5_counter++;
}
//Nintendo Switch devices
if (path.find("nintendo_switch_controller") != std::string::npos) {
if (switch_count == 1)
gamepad_data[gamepad_count].name = "SWITCH PAD";
else
gamepad_data[gamepad_count].name = "SWITCH PAD-" + to_string(switch_counter + 1);
switch_counter++;
}
//Get device status
if (std::getline(input_status, line))
gamepad_data[gamepad_count].state = line;
//Get device Battery
if (fs::exists(capacity)) {
if (std::getline(input_capacity, line)) {
switch(std::stoi(line)) {
case 0 ... 25:
gamepad_data[gamepad_count].battery = "Low";
break;
case 26 ... 49:
gamepad_data[gamepad_count].battery = "Normal";
break;
case 50 ... 74:
gamepad_data[gamepad_count].battery = "High";
break;
case 75 ... 100:
gamepad_data[gamepad_count].battery = "Full";
break;
}
}
}
else {
if (std::getline(input_capacity_level, line)) {
gamepad_data[gamepad_count].battery = line;
}
}
std::sort(gamepad_data.begin(), gamepad_data.end());
gamepad_count += 1;
}
}

@ -0,0 +1,25 @@
#pragma once
#ifndef MANGOHUD_GAMEPAD_H
#define MANGOHUD_GAMEPAD_H
#include <vector>
#include <string>
struct gamepad {
std::string battery;
std::string state;
std::string name;
};
extern std::vector<gamepad> gamepad_data;
extern bool gamepad_found;
extern int gamepad_count;
extern int xone_count;
extern int ds4_count;
extern int ds5_count;
extern int switch_count;
void gamepad_update();
void gamepad_info();
#endif // MANGOHUD_GAMEPAD_H

@ -8,6 +8,7 @@
#include "hud_elements.h"
#include "logging.h"
#include "battery.h"
#include "gamepad.h"
#include "cpu.h"
#include "memory.h"
#include "mesa/util/macros.h"
@ -588,7 +589,7 @@ void HudElements::frame_timing(){
int width = ImGui::GetContentRegionAvailWidth() * HUDElements.params->table_columns - 30;
#else
int width = ImGui::GetContentRegionAvailWidth() * HUDElements.params->table_columns;
#endif
#endif
ImGui::PlotLines(hash, get_time_stat, HUDElements.sw_stats,
ARRAY_SIZE(HUDElements.sw_stats->frames_stats), 0,
NULL, min_time, max_time,
@ -852,6 +853,41 @@ void HudElements::gamescope_frame_timing(){
#endif
}
void HudElements::gamepad_battery()
{
#ifdef __linux__
gamepad_update();
if (gamepad_found) {
gamepad_info();
for (int i = 0; i < gamepad_count; i++) {
std::string battery = gamepad_data[i].battery;
std::string state = gamepad_data[i].state;
std::string name = gamepad_data[i].name;
ImGui::TableNextRow(); ImGui::TableNextColumn();
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::TextColored(HUDElements.colors.engine, "%s", name.c_str());
ImGui::TableNextColumn();
if (state == "Charging")
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%s", ICON_FK_USB);
else {
if (battery == "Full")
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%s", ICON_FK_BATTERY_FULL);
else if (battery == "High")
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%s", ICON_FK_BATTERY_THREE_QUARTERS);
else if (battery == "Normal")
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%s", ICON_FK_BATTERY_HALF);
else if (battery == "Low")
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%s", ICON_FK_BATTERY_QUARTER);
else
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%s", ICON_FK_USB);
}
ImGui::PopFont();
}
}
#endif
}
void HudElements::graphs(){
ImGui::TableNextRow(); ImGui::TableNextColumn();
ImGui::Dummy(ImVec2(0.0f, real_font_size.y));
@ -1003,6 +1039,7 @@ void HudElements::sort_elements(const std::pair<std::string, std::string>& optio
if (param == "fps_only") { ordered_functions.push_back({fps_only, value}); }
if (param == "fsr") { ordered_functions.push_back({gamescope_fsr, value}); }
if (param == "debug") { ordered_functions.push_back({gamescope_frame_timing, value}); }
if (param == "gamepad_battery") { ordered_functions.push_back({gamepad_battery, value}); }
if (param == "graphs"){
if (!HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_graphs])
HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_graphs] = true;

@ -61,6 +61,8 @@ class HudElements{
static void fps_only();
static void gamescope_fsr();
static void gamescope_frame_timing();
static void xone_battery();
static void gamepad_battery();
void convert_colors(struct overlay_params& params);
void convert_colors(bool do_conv, struct overlay_params& params);

@ -82,6 +82,7 @@ if is_unixy
'pci_ids.cpp',
'battery.cpp',
'control.cpp',
'gamepad.cpp',
)
opengl_files = files(

@ -582,6 +582,7 @@ parse_overlay_config(struct overlay_params *params,
params->enabled[OVERLAY_PARAM_ENABLED_legacy_layout] = true;
params->enabled[OVERLAY_PARAM_ENABLED_frametime] = true;
params->enabled[OVERLAY_PARAM_ENABLED_fps_only] = false;
params->enabled[OVERLAY_PARAM_ENABLED_gamepad_battery] = false;
params->fps_sampling_period = 500000000; /* 500ms */
params->width = 0;
params->height = 140;

@ -78,6 +78,8 @@ typedef unsigned long KeySym;
OVERLAY_PARAM_BOOL(fsr) \
OVERLAY_PARAM_BOOL(mangoapp_steam) \
OVERLAY_PARAM_BOOL(debug) \
OVERLAY_PARAM_BOOL(xone_battery) \
OVERLAY_PARAM_BOOL(gamepad_battery) \
OVERLAY_PARAM_CUSTOM(fps_sampling_period) \
OVERLAY_PARAM_CUSTOM(output_folder) \
OVERLAY_PARAM_CUSTOM(output_file) \

Loading…
Cancel
Save