Browse Source

Sensor in Joystick.

Miku AuahDark 2 years ago
parent
commit
0442128006

+ 8 - 0
src/modules/joystick/Joystick.h

@@ -24,6 +24,7 @@
 // LOVE
 // LOVE
 #include "common/Object.h"
 #include "common/Object.h"
 #include "common/StringMap.h"
 #include "common/StringMap.h"
+#include "sensor/Sensor.h"
 
 
 // stdlib
 // stdlib
 #include <vector>
 #include <vector>
@@ -38,6 +39,8 @@ class Joystick : public Object
 {
 {
 public:
 public:
 
 
+	using Sensor = love::sensor::Sensor;
+
 	static love::Type type;
 	static love::Type type;
 
 
 	// Joystick hat values.
 	// Joystick hat values.
@@ -198,6 +201,11 @@ public:
 	virtual bool setVibration() = 0;
 	virtual bool setVibration() = 0;
 	virtual void getVibration(float &left, float &right) = 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(Hat);
 	STRINGMAP_CLASS_DECLARE(GamepadType);
 	STRINGMAP_CLASS_DECLARE(GamepadType);
 	STRINGMAP_CLASS_DECLARE(GamepadAxis);
 	STRINGMAP_CLASS_DECLARE(GamepadAxis);

+ 84 - 0
src/modules/joystick/sdl/Joystick.cpp

@@ -22,6 +22,10 @@
 #include "common/config.h"
 #include "common/config.h"
 #include "Joystick.h"
 #include "Joystick.h"
 #include "common/int.h"
 #include "common/int.h"
+#include "sensor/sdl/Sensor.h"
+
+// SDL
+#include <SDL_version.h>
 
 
 // C++
 // C++
 #include <algorithm>
 #include <algorithm>
@@ -643,6 +647,86 @@ void Joystick::getVibration(float &left, float &right)
 	right = vibration.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)
 bool Joystick::getConstant(Uint8 in, Joystick::Hat &out)
 {
 {
 	return hats.find(in, out);
 	return hats.find(in, out);

+ 5 - 0
src/modules/joystick/sdl/Joystick.h

@@ -88,6 +88,11 @@ public:
 	bool setVibration() override;
 	bool setVibration() override;
 	void getVibration(float &left, float &right) 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(Hat in, Uint8 &out);
 	static bool getConstant(Uint8 in, Hat &out);
 	static bool getConstant(Uint8 in, Hat &out);
 
 

+ 80 - 0
src/modules/joystick/wrap_Joystick.cpp

@@ -21,6 +21,7 @@
 // LOVE
 // LOVE
 #include "wrap_Joystick.h"
 #include "wrap_Joystick.h"
 #include "wrap_JoystickModule.h"
 #include "wrap_JoystickModule.h"
+#include "sensor/Sensor.h"
 
 
 #include <vector>
 #include <vector>
 
 
@@ -367,6 +368,78 @@ int w_Joystick_getVibration(lua_State *L)
 	return 2;
 	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.
 // List of functions to wrap.
 static const luaL_Reg w_Joystick_functions[] =
 static const luaL_Reg w_Joystick_functions[] =
 {
 {
@@ -396,6 +469,13 @@ static const luaL_Reg w_Joystick_functions[] =
 	{ "setVibration", w_Joystick_setVibration },
 	{ "setVibration", w_Joystick_setVibration },
 	{ "getVibration", w_Joystick_getVibration },
 	{ "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.
 	// From wrap_JoystickModule.
 	{ "getConnectedIndex", w_getIndex },
 	{ "getConnectedIndex", w_getIndex },
 
 

+ 13 - 0
src/modules/sensor/sdl/Sensor.cpp

@@ -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 - 0
src/modules/sensor/sdl/Sensor.h

@@ -54,6 +54,7 @@ public:
 	const char *getSensorName(SensorType type) override;
 	const char *getSensorName(SensorType type) override;
 
 
 	static SensorType convert(SDL_SensorType type);
 	static SensorType convert(SDL_SensorType type);
+	static SDL_SensorType convert(SensorType type);
 
 
 private:
 private:
 	std::map<SensorType, SDL_Sensor*> sensors;
 	std::map<SensorType, SDL_Sensor*> sensors;