Skip to content

Commit

Permalink
fix: default battery to 100% to avoid annoying warnings
Browse files Browse the repository at this point in the history
Also:
- fixed mac address and get_sys_nodes for Wolf
- Added proper battery test
  • Loading branch information
ABeltramo committed Jun 17, 2024
1 parent 2739465 commit 8a33706
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 10 deletions.
6 changes: 4 additions & 2 deletions include/inputtino/input.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,10 @@ class PS5Joypad : public Joypad {

std::vector<std::string> get_nodes() const override;

std::string get_mac_address() const;

std::vector<std::string> get_sys_nodes() const;

void set_pressed_buttons(int newly_pressed) override;
void set_triggers(int16_t left, int16_t right) override;
void set_stick(STICK_POSITION stick_type, short x, short y) override;
Expand Down Expand Up @@ -426,8 +430,6 @@ class PS5Joypad : public Joypad {
protected:
typedef struct PS5JoypadState PS5JoypadState;
std::shared_ptr<PS5JoypadState> _state;
std::string get_mac_address() const;
std::vector<std::string> get_sys_nodes() const;

private:
PS5Joypad(uint16_t vendor_id);
Expand Down
12 changes: 9 additions & 3 deletions src/uhid/joypad_ps5.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ static void on_uhid_event(std::shared_ptr<PS5JoypadState> state, uhid_event ev,
if (state->on_rumble) {
(*state->on_rumble)(left, right);
}
} else if(report->valid_flag0 == 0 && report->valid_flag1 == 0 && report->valid_flag2 == 0){
} else if (report->valid_flag0 == 0 && report->valid_flag1 == 0 && report->valid_flag2 == 0) {
// Seems to be a special stop rumble event, let's propagate it
if (state->on_rumble) {
(*state->on_rumble)(0, 0);
Expand Down Expand Up @@ -130,6 +130,9 @@ PS5Joypad::PS5Joypad(uint16_t vendor_id) : _state(std::make_shared<PS5JoypadStat
// Set touchpad as not pressed
this->_state->current_state.points[0].contact = 1;
this->_state->current_state.points[1].contact = 1;
// Set the battery to 100% (so that if the client doesn't report it we don't trigger annoying low battery warnings)
this->_state->current_state.battery_charge = 10;
this->_state->current_state.battery_status = BATTERY_FULL;
}

PS5Joypad::~PS5Joypad() {
Expand Down Expand Up @@ -174,7 +177,8 @@ template <typename T> std::string to_hex(T i) {

std::string PS5Joypad::get_mac_address() const {
std::stringstream stream;
stream << std::hex << (unsigned int)_state->mac_address[0] << ":" << (unsigned int)_state->mac_address[1] << ":"
stream << std::hex << std::setfill('0') << std::setw(2) //
<< (unsigned int)_state->mac_address[0] << ":" << (unsigned int)_state->mac_address[1] << ":"
<< (unsigned int)_state->mac_address[2] << ":" << (unsigned int)_state->mac_address[3] << ":"
<< (unsigned int)_state->mac_address[4] << ":" << (unsigned int)_state->mac_address[5];
return stream.str();
Expand Down Expand Up @@ -212,7 +216,9 @@ std::vector<std::string> PS5Joypad::get_sys_nodes() const {
std::ifstream dev_uniq_file{dev_uniq_path};
std::string line;
std::getline(dev_uniq_file, line);
nodes.push_back(dev_entry.path().string());
if (line == target_mac) {
nodes.push_back(dev_entry.path().string());
}
} else {
fprintf(stderr, "Unable to get joypad nodes, path %s does not exist\n", dev_uniq_path.string().c_str());
}
Expand Down
73 changes: 68 additions & 5 deletions tests/testJoypads.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#include "catch2/catch_all.hpp"
#include <filesystem>
#include <fstream>
#include <inputtino/input.hpp>
#include <iostream>
#include <SDL.h>
Expand Down Expand Up @@ -86,6 +88,25 @@ void test_buttons(SDL_GameController *gc, Joypad &joypad) {
REQUIRE(SDL_GameControllerGetButton(gc, SDL_CONTROLLER_BUTTON_Y) == 1);
}

/**
* @param power_supply_path (ex:
* "/sys/devices/virtual/misc/uhid/0003:054C:0CE6.0016/power_supply/ps-controller-battery-00:21:c1:75:88:38/")
* @return a pair of <capacity, status> as read from the system
*/
std::pair<int, std::string> get_system_battery(const std::filesystem::path &power_supply_path) {
// It's fairly simple, we have to read two files: capacity and status
std::ifstream capacity_file(power_supply_path / "capacity");
std::ifstream status_file(power_supply_path / "status");
if (!capacity_file.is_open() || !status_file.is_open()) {
return {0, "Unknown"};
}
int capacity = 0;
std::string status;
capacity_file >> capacity;
status_file >> status;
return {capacity, status};
}

TEST_CASE_METHOD(SDLTestsFixture, "PS Joypad", "[SDL]") {
// Create the controller
auto joypad = std::move(*PS5Joypad::create());
Expand Down Expand Up @@ -292,11 +313,53 @@ TEST_CASE_METHOD(SDLTestsFixture, "PS Joypad", "[SDL]") {
}

{ // Test battery
joypad.set_battery(inputtino::PS5Joypad::BATTERY_CHARGHING, 80);
auto joy = SDL_GameControllerGetJoystick(gc);
auto level = SDL_JoystickCurrentPowerLevel(joy);
if (level != SDL_JOYSTICK_POWER_UNKNOWN) // TODO: SDL doesn't seem to pick it up..
REQUIRE(level == SDL_JOYSTICK_POWER_MEDIUM);
// SDL doesn't seem to pick it up..
// auto joy = SDL_GameControllerGetJoystick(gc);
// auto level = SDL_JoystickCurrentPowerLevel(joy);
// REQUIRE(level == SDL_JOYSTICK_POWER_MEDIUM);

auto base_path =
std::filesystem::path(
joypad.get_sys_nodes()[0]) // "/sys/devices/virtual/misc/uhid/0003:054C:0CE6.0017/input/input123"
.parent_path() // "/sys/devices/virtual/misc/uhid/0003:054C:0CE6.0017/input/"
.parent_path() // "/sys/devices/virtual/misc/uhid/0003:054C:0CE6.0017/"
/ "power_supply" // "/sys/devices/virtual/misc/uhid/0003:054C:0CE6.0017/power_supply"
/ ("ps-controller-battery-" + joypad.get_mac_address());
REQUIRE(std::filesystem::exists(base_path));

{ // Defaults to full if nothing is set
auto [capacity, status] = get_system_battery(base_path);
REQUIRE(capacity == 100);
REQUIRE(status == "Full");
}

{
joypad.set_battery(inputtino::PS5Joypad::BATTERY_CHARGHING, 80);
auto [capacity, status] = get_system_battery(base_path);
REQUIRE(capacity == 85);
REQUIRE(status == "Charging");
}

{
joypad.set_battery(inputtino::PS5Joypad::BATTERY_CHARGHING, 10);
auto [capacity, status] = get_system_battery(base_path);
REQUIRE(capacity == 15);
REQUIRE(status == "Charging");
}

{
joypad.set_battery(inputtino::PS5Joypad::BATTERY_DISCHARGING, 75);
auto [capacity, status] = get_system_battery(base_path);
REQUIRE(capacity == 75);
REQUIRE(status == "Discharging");
}

{
joypad.set_battery(inputtino::PS5Joypad::BATTERY_FULL, 100);
auto [capacity, status] = get_system_battery(base_path);
REQUIRE(capacity == 100);
REQUIRE(status == "Full");
}
}

// Adaptive triggers aren't supported by SDL
Expand Down

0 comments on commit 8a33706

Please sign in to comment.