mirror of
https://github.com/SFML/SFML.git
synced 2024-12-01 15:51:04 +08:00
[Android] Added the joystick implementation
This commit is contained in:
parent
fbd21962f0
commit
de791c05dc
@ -67,13 +67,9 @@ static void initializeMain(ActivityStates* states)
|
||||
ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
|
||||
states->looper = looper;
|
||||
|
||||
// Prepare the sensor event queue
|
||||
states->sensorEventQueue = ASensorManager_createEventQueue(states->sensorManager, states->looper, 2, NULL, (void*)&sf::priv::processSensorEvents);
|
||||
|
||||
// Get the default configuration
|
||||
states->config = AConfiguration_new();
|
||||
AConfiguration_fromAssetManager(states->config, states->activity->assetManager);
|
||||
|
||||
}
|
||||
|
||||
static void terminateMain(ActivityStates* states)
|
||||
@ -277,23 +273,9 @@ static void onWindowFocusChanged(ANativeActivity* activity, int focused)
|
||||
// Retrieve our activity states from the activity instance
|
||||
sf::priv::ActivityStates* states = sf::priv::retrieveStates(activity);
|
||||
|
||||
if (focused)
|
||||
{
|
||||
// We start monitoring the accelerometer with 60 events per second
|
||||
if (states->accelerometerSensor != NULL)
|
||||
{
|
||||
ASensorEventQueue_enableSensor(states->sensorEventQueue, states->accelerometerSensor);
|
||||
ASensorEventQueue_setEventRate(states->sensorEventQueue, states->accelerometerSensor, (1000L/60)*1000);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// We stop monitoring the accelerometer (it avoids consuming battery)
|
||||
if (states->accelerometerSensor != NULL)
|
||||
{
|
||||
ASensorEventQueue_disableSensor(states->sensorEventQueue, states->accelerometerSensor);
|
||||
}
|
||||
}
|
||||
// Disable or enable sensors according the window focused state
|
||||
if (states->enableSensors && states->disableSensors)
|
||||
focused ? states->enableSensors() : states->disableSensors();
|
||||
}
|
||||
|
||||
static void onContentRectChanged(ANativeActivity* activity, const ARect* rect)
|
||||
@ -345,10 +327,6 @@ void ANativeActivity_onCreate(ANativeActivity* activity, void* savedState, size_
|
||||
states->inputQueue = NULL;
|
||||
states->config = NULL;
|
||||
|
||||
states->sensorManager = ASensorManager_getInstance();
|
||||
states->accelerometerSensor = ASensorManager_getDefaultSensor(states->sensorManager, ASENSOR_TYPE_ACCELEROMETER);
|
||||
states->sensorEventQueue = NULL;
|
||||
|
||||
states->display = eglCheck(eglGetDisplay(EGL_DEFAULT_DISPLAY));
|
||||
|
||||
// As the input queue will be created before the SFML window, we need to use
|
||||
|
@ -51,10 +51,6 @@ struct ActivityStates
|
||||
AInputQueue* inputQueue;
|
||||
AConfiguration* config;
|
||||
|
||||
ASensorManager* sensorManager;
|
||||
const ASensor* accelerometerSensor;
|
||||
ASensorEventQueue* sensorEventQueue;
|
||||
|
||||
EGLDisplay display;
|
||||
EglContext* context;
|
||||
|
||||
@ -66,6 +62,9 @@ struct ActivityStates
|
||||
std::vector<Event> pendingEvents;
|
||||
int (*processEvent)(int fd, int events, void* data);
|
||||
|
||||
void (*enableSensors)();
|
||||
void (*disableSensors)();
|
||||
|
||||
std::map<int, Vector2i> touchEvents;
|
||||
|
||||
bool mainOver;
|
||||
|
@ -26,8 +26,101 @@
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Window/JoystickImpl.hpp>
|
||||
#include <SFML/System/Android/Activity.hpp>
|
||||
#include <SFML/System/Lock.hpp>
|
||||
#include <SFML/System/Vector3.hpp>
|
||||
#include <android/looper.h>
|
||||
#include <android/sensor.h>
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
enum
|
||||
{
|
||||
Accelerometer,
|
||||
Gyroscope,
|
||||
Magnetometer,
|
||||
UserAcceleration,
|
||||
AbsoluteOrientation,
|
||||
Count
|
||||
};
|
||||
|
||||
static const int32_t updateInterval = (1000L/60)*1000;
|
||||
|
||||
ALooper* looper;
|
||||
ASensorManager* sensorManager;
|
||||
ASensorEventQueue* sensorEventQueue;
|
||||
|
||||
struct
|
||||
{
|
||||
const ASensor* device;
|
||||
sf::Vector3f data;
|
||||
} sensors[Count];
|
||||
|
||||
bool areSensorsEnabled;
|
||||
|
||||
int processSensorEvents(int fd, int events, void* data)
|
||||
{
|
||||
ASensorEvent event;
|
||||
|
||||
while (ASensorEventQueue_getEvents(sensorEventQueue, &event, 1) > 0)
|
||||
{
|
||||
// Cache the latest data
|
||||
switch (event.sensor)
|
||||
{
|
||||
case ASENSOR_TYPE_ACCELEROMETER:
|
||||
sensors[Accelerometer].data.x = event.acceleration.x;
|
||||
sensors[Accelerometer].data.y = event.acceleration.y;
|
||||
sensors[Accelerometer].data.z = event.acceleration.z;
|
||||
break;
|
||||
|
||||
case ASENSOR_TYPE_GYROSCOPE:
|
||||
sensors[Gyroscope].data.x = event.vector.x;
|
||||
sensors[Gyroscope].data.y = event.vector.y;
|
||||
sensors[Gyroscope].data.z = event.vector.z;
|
||||
break;
|
||||
|
||||
case ASENSOR_TYPE_MAGNETIC_FIELD:
|
||||
sensors[Magnetometer].data.x = event.magnetic.x;
|
||||
sensors[Magnetometer].data.y = event.magnetic.y;
|
||||
sensors[Magnetometer].data.z = event.magnetic.z;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void enableSensors()
|
||||
{
|
||||
// (Re)start monitoring sensors with 60 events per second
|
||||
for (unsigned int i = 0; i < Count; ++i)
|
||||
{
|
||||
if (sensors[i].device != NULL)
|
||||
{
|
||||
ASensorEventQueue_enableSensor(sensorEventQueue, sensors[i].device);
|
||||
ASensorEventQueue_setEventRate(sensorEventQueue, sensors[i].device, updateInterval);
|
||||
}
|
||||
}
|
||||
|
||||
areSensorsEnabled = true;
|
||||
}
|
||||
|
||||
void disableSensors()
|
||||
{
|
||||
// Stop monitoring sensors (it avoids consuming battery)
|
||||
for (unsigned int i = 0; i < Count; ++i)
|
||||
{
|
||||
if (sensors[i].device != NULL)
|
||||
{
|
||||
ASensorEventQueue_disableSensor(sensorEventQueue, sensors[i].device);
|
||||
}
|
||||
}
|
||||
|
||||
areSensorsEnabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
namespace sf
|
||||
{
|
||||
namespace priv
|
||||
@ -35,25 +128,80 @@ namespace priv
|
||||
////////////////////////////////////////////////////////////
|
||||
void JoystickImpl::initialize()
|
||||
{
|
||||
// Register callbacks to pause sensors when the device is in standby mode
|
||||
ActivityStates* states = getActivity(NULL);
|
||||
|
||||
{
|
||||
Lock lock(states->mutex);
|
||||
|
||||
states->enableSensors = enableSensors;
|
||||
states->disableSensors = disableSensors;
|
||||
}
|
||||
|
||||
// Get the unique sensor manager
|
||||
sensorManager = ASensorManager_getInstance();
|
||||
|
||||
// Prepare available sensors
|
||||
sensors[Accelerometer].device = ASensorManager_getDefaultSensor(sensorManager,
|
||||
ASENSOR_TYPE_ACCELEROMETER);
|
||||
sensors[Gyroscope].device = ASensorManager_getDefaultSensor(sensorManager,
|
||||
ASENSOR_TYPE_GYROSCOPE);
|
||||
sensors[Magnetometer].device = ASensorManager_getDefaultSensor(sensorManager,
|
||||
ASENSOR_TYPE_MAGNETIC_FIELD);
|
||||
|
||||
// User acceleration and absolute orientation sensors are unavailable on Android
|
||||
// (at least, unavailable from the android C API)
|
||||
sensors[UserAcceleration].device = NULL;
|
||||
sensors[AbsoluteOrientation].device = NULL;
|
||||
|
||||
// Get the looper associated with this thread
|
||||
looper = ALooper_forThread();
|
||||
|
||||
// Create the sensor events queue and attach it to the looper
|
||||
sensorEventQueue = ASensorManager_createEventQueue(sensorManager, looper,
|
||||
1, &processSensorEvents, NULL);
|
||||
|
||||
// Set the event rate (not to consume too much battery)
|
||||
ASensorEventQueue_setEventRate(sensorEventQueue, sensors[Accelerometer].device, updateInterval);
|
||||
ASensorEventQueue_setEventRate(sensorEventQueue, sensors[Gyroscope].device, updateInterval);
|
||||
ASensorEventQueue_setEventRate(sensorEventQueue, sensors[Magnetometer].device, updateInterval);
|
||||
|
||||
// Start monitoring sensors
|
||||
enableSensors();
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void JoystickImpl::cleanup()
|
||||
{
|
||||
// Stop monitoring sensors
|
||||
disableSensors();
|
||||
|
||||
// Detach the sensor events queue from the looper and destroy it
|
||||
ASensorManager_destroyEventQueue(sensorManager, sensorEventQueue);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool JoystickImpl::isConnected(unsigned int index)
|
||||
{
|
||||
return false;
|
||||
// If sensors aren't paused and the requested sensor available
|
||||
return (areSensorsEnabled && sensors[index].device);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool JoystickImpl::open(unsigned int index)
|
||||
{
|
||||
// Save the index if sensor is available
|
||||
if(sensors[index].device)
|
||||
{
|
||||
m_index = index;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -61,18 +209,41 @@ bool JoystickImpl::open(unsigned int index)
|
||||
////////////////////////////////////////////////////////////
|
||||
void JoystickImpl::close()
|
||||
{
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
JoystickCaps JoystickImpl::getCapabilities() const
|
||||
{
|
||||
JoystickCaps caps;
|
||||
|
||||
// All the connected joysticks have (X, Y, Z) axes
|
||||
caps.axes[Joystick::X] = true;
|
||||
caps.axes[Joystick::Y] = true;
|
||||
caps.axes[Joystick::Z] = true;
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
JoystickState JoystickImpl::JoystickImpl::update()
|
||||
JoystickState JoystickImpl::update()
|
||||
{
|
||||
JoystickState state;
|
||||
|
||||
// Poll latest sensor events
|
||||
ALooper_pollAll(0, NULL, NULL, NULL);
|
||||
|
||||
// Always connected
|
||||
state.connected = sensors[m_index].device ? true : false;
|
||||
|
||||
// Use our cache
|
||||
state.axes[Joystick::X] = sensors[m_index].data.x;
|
||||
state.axes[Joystick::Y] = sensors[m_index].data.y;
|
||||
state.axes[Joystick::Z] = sensors[m_index].data.z;
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
} // namespace priv
|
||||
|
Loading…
Reference in New Issue
Block a user