diff --git a/changes.txt b/changes.txt index 5d20dc20b..782c165e3 100644 --- a/changes.txt +++ b/changes.txt @@ -29,6 +29,8 @@ Released: N/A * Added Joystick:hasSensor. * Added Joystick:isSensorEnabled and Joystick:setSensorEnabled. * Added Joystick:getSensorData. +* Added Joystick:getPowerInfo which exposes infomation about batteries in a controller are and if they're charging. +* Added Joystick:getConnectionState which indicates if a joystick is connected wired or wireless. * Added new Gamepad API buttons: "misc1", "paddle1", "paddle2", "paddle3", "paddle4". and "touchpad". * Added World:getFixturesInArea(). * Added support for saving .exr image files via ImageData:encode. diff --git a/src/modules/joystick/Joystick.cpp b/src/modules/joystick/Joystick.cpp index 526d15d65..dfd95880d 100644 --- a/src/modules/joystick/Joystick.cpp +++ b/src/modules/joystick/Joystick.cpp @@ -135,5 +135,23 @@ STRINGMAP_CLASS_BEGIN(Joystick, Joystick::InputType, Joystick::INPUT_TYPE_MAX_EN } STRINGMAP_CLASS_END(Joystick, Joystick::InputType, Joystick::INPUT_TYPE_MAX_ENUM, inputType) +STRINGMAP_CLASS_BEGIN(Joystick, Joystick::PowerType, Joystick::POWER_MAX_ENUM, powerState) +{ + { "unknown", Joystick::POWER_UNKNOWN }, + { "onbattery", Joystick::POWER_ON_BATTERY }, + { "nobattery", Joystick::POWER_NO_BATTERY }, + { "charging", Joystick::POWER_CHARGING }, + { "charged", Joystick::POWER_CHARGED }, +} +STRINGMAP_CLASS_END(Joystick, Joystick::PowerType, Joystick::POWER_MAX_ENUM, powerState) + +STRINGMAP_CLASS_BEGIN(Joystick, Joystick::ConnectionType, Joystick::CONNECTION_MAX_ENUM, connectionState) +{ + { "unknown", Joystick::CONNECTION_UNKNOWN }, + { "wired", Joystick::CONNECTION_WIRED }, + { "wireless", Joystick::CONNECTION_WIRELESS }, +} +STRINGMAP_CLASS_END(Joystick, Joystick::ConnectionType, Joystick::CONNECTION_MAX_ENUM, connectionState) + } // joystick } // love diff --git a/src/modules/joystick/Joystick.h b/src/modules/joystick/Joystick.h index 9bfa62aa2..300613b8c 100644 --- a/src/modules/joystick/Joystick.h +++ b/src/modules/joystick/Joystick.h @@ -144,6 +144,24 @@ class Joystick : public Object INPUT_TYPE_MAX_ENUM }; + enum PowerType + { + POWER_UNKNOWN, /**< cannot determine power status */ + POWER_ON_BATTERY, /**< Not plugged in, running on the battery */ + POWER_NO_BATTERY, /**< Plugged in, no battery available */ + POWER_CHARGING, /**< Plugged in, charging battery */ + POWER_CHARGED, /**< Plugged in, battery charged */ + POWER_MAX_ENUM + }; + + enum ConnectionType + { + CONNECTION_UNKNOWN, + CONNECTION_WIRED, + CONNECTION_WIRELESS, + CONNECTION_MAX_ENUM + }; + // Represents a gamepad input value, e.g. the "x" button or the left trigger. struct GamepadInput { @@ -223,6 +241,8 @@ class Joystick : public Object virtual bool isSensorEnabled(Sensor::SensorType type) const = 0; virtual void setSensorEnabled(Sensor::SensorType type, bool enabled) = 0; virtual std::vector getSensorData(Sensor::SensorType type) const = 0; + virtual PowerType getPowerInfo(int &batteryPercent) const = 0; + virtual ConnectionType getConnectionState() const = 0; STRINGMAP_CLASS_DECLARE(Hat); STRINGMAP_CLASS_DECLARE(JoystickType); @@ -230,6 +250,8 @@ class Joystick : public Object STRINGMAP_CLASS_DECLARE(GamepadAxis); STRINGMAP_CLASS_DECLARE(GamepadButton); STRINGMAP_CLASS_DECLARE(InputType); + STRINGMAP_CLASS_DECLARE(PowerType); + STRINGMAP_CLASS_DECLARE(ConnectionType); static float clampval(float x); diff --git a/src/modules/joystick/sdl/Joystick.cpp b/src/modules/joystick/sdl/Joystick.cpp index ae0168de4..efceccca8 100644 --- a/src/modules/joystick/sdl/Joystick.cpp +++ b/src/modules/joystick/sdl/Joystick.cpp @@ -462,6 +462,36 @@ void Joystick::getDeviceInfo(int &vendorID, int &productID, int &productVersion) } } +Joystick::PowerType Joystick::getPowerInfo(int& batteryPercent) const +{ + // Gets the battery state of a joystick/gamepad + Joystick::PowerType powerState = Joystick::PowerType::POWER_UNKNOWN; + SDL_PowerState batteryState; + + if (!isConnected()) + return powerState; + + batteryState = SDL_GetJoystickPowerInfo(joyhandle, &batteryPercent); + + getConstant(batteryState, powerState); + return powerState; +} + +Joystick::ConnectionType Joystick::getConnectionState() const +{ + // Gets the connection state of a joystick/gamepad (wired / wireless etc) + Joystick::ConnectionType connectionState = Joystick::ConnectionType::CONNECTION_UNKNOWN; + SDL_JoystickConnectionState sdlConnectionState; + + if (!isConnected()) + return connectionState; + + sdlConnectionState = SDL_GetJoystickConnectionState(joyhandle); + + getConstant(sdlConnectionState, connectionState); + return connectionState; +} + bool Joystick::isVibrationSupported() { if (!isConnected()) @@ -614,6 +644,26 @@ bool Joystick::getConstant(Joystick::GamepadButton in, SDL_GamepadButton &out) return gpButtons.find(in, out); } +bool Joystick::getConstant(SDL_PowerState in, Joystick::PowerType &out) +{ + return powerStates.find(in, out); +} + +bool Joystick::getConstant(Joystick::PowerType in, SDL_PowerState &out) +{ + return powerStates.find(in, out); +} + +bool Joystick::getConstant(SDL_JoystickConnectionState in, Joystick::ConnectionType &out) +{ + return connectionStates.find(in, out); +} + +bool Joystick::getConstant(Joystick::ConnectionType in, SDL_JoystickConnectionState &out) +{ + return connectionStates.find(in, out); +} + EnumMap::Entry Joystick::hatEntries[] = { {Joystick::HAT_CENTERED, SDL_HAT_CENTERED}, @@ -668,6 +718,26 @@ EnumMap Joystick::gpButtons(Joystick::gpButtonEntries, sizeof(Joystick::gpButtonEntries)); +EnumMap::Entry Joystick::powerEntries[] = +{ + {Joystick::POWER_UNKNOWN, SDL_POWERSTATE_UNKNOWN}, + {Joystick::POWER_ON_BATTERY, SDL_POWERSTATE_ON_BATTERY}, + {Joystick::POWER_NO_BATTERY, SDL_POWERSTATE_NO_BATTERY}, + {Joystick::POWER_CHARGING, SDL_POWERSTATE_CHARGING}, + {Joystick::POWER_CHARGED, SDL_POWERSTATE_CHARGED}, +}; + +EnumMap Joystick::powerStates(Joystick::powerEntries, sizeof(Joystick::powerEntries)); + +EnumMap::Entry Joystick::connectionStateEntries[] = +{ + {Joystick::CONNECTION_UNKNOWN, SDL_JOYSTICK_CONNECTION_UNKNOWN}, + {Joystick::CONNECTION_WIRED, SDL_JOYSTICK_CONNECTION_WIRED}, + {Joystick::CONNECTION_WIRELESS, SDL_JOYSTICK_CONNECTION_WIRELESS}, +}; + +EnumMap Joystick::connectionStates(Joystick::connectionStateEntries, sizeof(Joystick::connectionStateEntries)); + } // sdl } // joystick } // love diff --git a/src/modules/joystick/sdl/Joystick.h b/src/modules/joystick/sdl/Joystick.h index 99b92a764..13ca2177d 100644 --- a/src/modules/joystick/sdl/Joystick.h +++ b/src/modules/joystick/sdl/Joystick.h @@ -84,6 +84,8 @@ class Joystick : public love::joystick::Joystick int getID() const override; void getDeviceInfo(int &vendorID, int &productID, int &productVersion) const override; + PowerType getPowerInfo(int& batteryPercent) const override; + ConnectionType getConnectionState() const override; bool isVibrationSupported() override; bool setVibration(float left, float right, float duration = -1.0f) override; @@ -104,6 +106,12 @@ class Joystick : public love::joystick::Joystick static bool getConstant(SDL_GamepadButton in, GamepadButton &out); static bool getConstant(GamepadButton in, SDL_GamepadButton &out); + static bool getConstant(SDL_PowerState in, PowerType &out); + static bool getConstant(PowerType in, SDL_PowerState &out); + + static bool getConstant(SDL_JoystickConnectionState in, ConnectionType &out); + static bool getConstant(ConnectionType in, SDL_JoystickConnectionState &out); + private: Joystick() {} @@ -129,6 +137,11 @@ class Joystick : public love::joystick::Joystick static EnumMap::Entry gpButtonEntries[]; static EnumMap gpButtons; + static EnumMap::Entry powerEntries[]; + static EnumMap powerStates; + + static EnumMap::Entry connectionStateEntries[]; + static EnumMap connectionStates; }; } // sdl diff --git a/src/modules/joystick/sdl/JoystickModule.cpp b/src/modules/joystick/sdl/JoystickModule.cpp index 71be57de0..3a0a6d260 100644 --- a/src/modules/joystick/sdl/JoystickModule.cpp +++ b/src/modules/joystick/sdl/JoystickModule.cpp @@ -49,7 +49,7 @@ JoystickModule::JoystickModule() int count = 0; SDL_JoystickID *sticks = SDL_GetJoysticks(&count); for (int i = 0; i < count; i++) - addJoystick((int64) sticks[i]); + addJoystick((int64)sticks[i]); SDL_free(sticks); // Start joystick event watching. Joysticks are automatically added and diff --git a/src/modules/joystick/wrap_Joystick.cpp b/src/modules/joystick/wrap_Joystick.cpp index 5c49bf1f4..a58a873f5 100644 --- a/src/modules/joystick/wrap_Joystick.cpp +++ b/src/modules/joystick/wrap_Joystick.cpp @@ -447,6 +447,39 @@ int w_Joystick_getSensorData(lua_State *L) return (int) data.size(); } +int w_Joystick_getDevicePowerInfo(lua_State *L) +{ + Joystick *j = luax_checkjoystick(L, 1); + + int batteryPercent = 0; + const char *str; + Joystick::PowerType state = j->getPowerInfo(batteryPercent); + + if (!Joystick::getConstant(state, str)) + str = "unknown"; + + lua_pushstring(L, str); + + if (batteryPercent >= 0) + lua_pushnumber(L, batteryPercent); + else + lua_pushnil(L); + + return 2; +} + +int w_Joystick_getDeviceConnectionState(lua_State *L) +{ + Joystick *j = luax_checkjoystick(L, 1); + + const char *str = "unknown"; + Joystick::getConstant(j->getConnectionState(), str); + + lua_pushstring(L, str); + + return 1; +} + #endif // LOVE_ENABLE_SENSOR // List of functions to wrap. @@ -457,6 +490,8 @@ static const luaL_Reg w_Joystick_functions[] = { "getID", w_Joystick_getID }, { "getGUID", w_Joystick_getGUID }, { "getDeviceInfo", w_Joystick_getDeviceInfo }, + { "getDevicePowerInfo", w_Joystick_getDevicePowerInfo }, + { "getDeviceConnectionState", w_Joystick_getDeviceConnectionState }, { "getJoystickType", w_Joystick_getJoystickType }, { "getAxisCount", w_Joystick_getAxisCount }, { "getButtonCount", w_Joystick_getButtonCount },