Sensor in Joystick.

This commit is contained in:
Miku AuahDark
2022-12-05 23:09:50 +08:00
parent bdbd4a9a58
commit 0442128006
6 changed files with 191 additions and 0 deletions
+8
View File
@@ -24,6 +24,7 @@
// LOVE
#include "common/Object.h"
#include "common/StringMap.h"
#include "sensor/Sensor.h"
// stdlib
#include <vector>
@@ -38,6 +39,8 @@ class Joystick : public Object
{
public:
using Sensor = love::sensor::Sensor;
static love::Type type;
// Joystick hat values.
@@ -198,6 +201,11 @@ public:
virtual bool setVibration() = 0;
virtual void getVibration(float &left, float &right) = 0;
virtual bool hasSensor(Sensor::SensorType type) const = 0;
virtual bool isSensorEnabled(Sensor::SensorType type) const = 0;
virtual void setSensorEnabled(Sensor::SensorType type, bool enabled) = 0;
virtual std::vector<float> getSensorData(Sensor::SensorType type) const = 0;
STRINGMAP_CLASS_DECLARE(Hat);
STRINGMAP_CLASS_DECLARE(GamepadType);
STRINGMAP_CLASS_DECLARE(GamepadAxis);
+84
View File
@@ -22,6 +22,10 @@
#include "common/config.h"
#include "Joystick.h"
#include "common/int.h"
#include "sensor/sdl/Sensor.h"
// SDL
#include <SDL_version.h>
// C++
#include <algorithm>
@@ -643,6 +647,86 @@ void Joystick::getVibration(float &left, float &right)
right = vibration.right;
}
bool Joystick::hasSensor(Sensor::SensorType type) const
{
#if SDL_VERSION_ATLEAST(2, 0, 14) && defined(LOVE_ENABLE_SENSOR)
using SDLSensor = love::sensor::sdl::Sensor;
if (!isGamepad())
return false;
return SDL_GameControllerHasSensor(controller, SDLSensor::convert(type)) == SDL_TRUE;
#else
return false;
#endif
}
bool Joystick::isSensorEnabled(Sensor::SensorType type) const
{
#if SDL_VERSION_ATLEAST(2, 0, 14) && defined(LOVE_ENABLE_SENSOR)
using SDLSensor = love::sensor::sdl::Sensor;
if (!isGamepad())
return false;
return SDL_GameControllerIsSensorEnabled(controller, SDLSensor::convert(type)) == SDL_TRUE;
#else
return false;
#endif
}
void Joystick::setSensorEnabled(Sensor::SensorType type, bool enabled)
{
#if SDL_VERSION_ATLEAST(2, 0, 14) && defined(LOVE_ENABLE_SENSOR)
using SDLSensor = love::sensor::sdl::Sensor;
if (!isGamepad())
throw love::Exception("Sensor is only supported on gamepad");
if (SDL_GameControllerSetSensorEnabled(controller, SDLSensor::convert(type), enabled ? SDL_TRUE : SDL_FALSE) != 0)
{
const char *name = nullptr;
SDLSensor::getConstant(type, name);
throw love::Exception("Could not open \"%s\" SDL gamepad sensor (%s)", name, SDL_GetError());
}
#else
throw love::Exception("Compiled version of SDL or LOVE does not support gamepad sensor");
#endif
}
std::vector<float> Joystick::getSensorData(Sensor::SensorType type) const
{
#if SDL_VERSION_ATLEAST(2, 0, 14) && defined(LOVE_ENABLE_SENSOR)
using SDLSensor = love::sensor::sdl::Sensor;
if (!isGamepad())
throw love::Exception("Sensor is only supported on gamepad");
std::vector<float> data(3);
if (!isSensorEnabled(type))
{
const char *name = nullptr;
SDLSensor::getConstant(type, name);
throw love::Exception("\"%s\" gamepad sensor is not enabled", name);
}
if (SDL_GameControllerGetSensorData(controller, SDLSensor::convert(type), data.data(), data.size()) != 0)
{
const char *name = nullptr;
SDLSensor::getConstant(type, name);
throw love::Exception("Could not get \"%s\" SDL gamepad sensor data (%s)", name, SDL_GetError());
}
return data;
#else
throw love::Exception("Compiled version of SDL or LOVE does not support gamepad sensor");
#endif
}
bool Joystick::getConstant(Uint8 in, Joystick::Hat &out)
{
return hats.find(in, out);
+5
View File
@@ -88,6 +88,11 @@ public:
bool setVibration() override;
void getVibration(float &left, float &right) override;
bool hasSensor(Sensor::SensorType type) const override;
bool isSensorEnabled(Sensor::SensorType type) const override;
void setSensorEnabled(Sensor::SensorType type, bool enabled) override;
std::vector<float> getSensorData(Sensor::SensorType type) const override;
static bool getConstant(Hat in, Uint8 &out);
static bool getConstant(Uint8 in, Hat &out);
+80
View File
@@ -21,6 +21,7 @@
// LOVE
#include "wrap_Joystick.h"
#include "wrap_JoystickModule.h"
#include "sensor/Sensor.h"
#include <vector>
@@ -367,6 +368,78 @@ int w_Joystick_getVibration(lua_State *L)
return 2;
}
#ifdef LOVE_ENABLE_SENSOR
int w_Joystick_hasSensor(lua_State *L)
{
using namespace love::sensor;
Joystick *j = luax_checkjoystick(L, 1);
const char *sensorType = luaL_checkstring(L, 2);
Sensor::SensorType type;
if (!Sensor::getConstant(sensorType, type))
luax_enumerror(L, "sensor type", Sensor::getConstants(type), sensorType);
luax_pushboolean(L, j->hasSensor(type));
return 1;
}
int w_Joystick_isSensorEnabled(lua_State *L)
{
using namespace love::sensor;
Joystick *j = luax_checkjoystick(L, 1);
const char *sensorType = luaL_checkstring(L, 2);
Sensor::SensorType type;
if (!Sensor::getConstant(sensorType, type))
luax_enumerror(L, "sensor type", Sensor::getConstants(type), sensorType);
luax_pushboolean(L, j->isSensorEnabled(type));
return 1;
}
int w_Joystick_setSensorEnabled(lua_State *L)
{
using namespace love::sensor;
Joystick *j = luax_checkjoystick(L, 1);
const char *sensorType = luaL_checkstring(L, 2);
Sensor::SensorType type;
if (!Sensor::getConstant(sensorType, type))
luax_enumerror(L, "sensor type", Sensor::getConstants(type), sensorType);
bool enabled = luax_checkboolean(L, 3);
luax_catchexcept(L, [&]() { j->setSensorEnabled(type, enabled); });
return 0;
}
int w_Joystick_getSensorData(lua_State *L)
{
using namespace love::sensor;
Joystick *j = luax_checkjoystick(L, 1);
const char *sensorType = luaL_checkstring(L, 2);
Sensor::SensorType type;
if (!Sensor::getConstant(sensorType, type))
luax_enumerror(L, "sensor type", Sensor::getConstants(type), sensorType);
std::vector<float> data;
luax_catchexcept(L, [&]() { data = j->getSensorData(type); });
for (float f: data)
lua_pushnumber(L, f);
return (int) data.size();
}
#endif // LOVE_ENABLE_SENSOR
// List of functions to wrap.
static const luaL_Reg w_Joystick_functions[] =
{
@@ -396,6 +469,13 @@ static const luaL_Reg w_Joystick_functions[] =
{ "setVibration", w_Joystick_setVibration },
{ "getVibration", w_Joystick_getVibration },
#ifdef LOVE_ENABLE_SENSOR
{ "hasSensor", w_Joystick_hasSensor },
{ "isSensorEnabled", w_Joystick_isSensorEnabled },
{ "setSensorEnabled", w_Joystick_setSensorEnabled },
{ "getSensorData", w_Joystick_setSensorEnabled },
#endif
// From wrap_JoystickModule.
{ "getConnectedIndex", w_getIndex },
+13
View File
@@ -156,6 +156,19 @@ Sensor::SensorType Sensor::convert(SDL_SensorType type)
}
}
SDL_SensorType Sensor::convert(Sensor::SensorType type)
{
switch (type)
{
case SENSOR_ACCELEROMETER:
return SDL_SENSOR_ACCEL;
case SENSOR_GYROSCOPE:
return SDL_SENSOR_GYRO;
default:
return SDL_SENSOR_UNKNOWN;
}
}
}
}
}
+1
View File
@@ -54,6 +54,7 @@ public:
const char *getSensorName(SensorType type) override;
static SensorType convert(SDL_SensorType type);
static SDL_SensorType convert(SensorType type);
private:
std::map<SensorType, SDL_Sensor*> sensors;