SDL  2.0
SDL_coremotionsensor.m
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 
22 #include "SDL_config.h"
23 
24 #ifdef SDL_SENSOR_COREMOTION
25 
26 /* This is the system specific header for the SDL sensor API */
27 #include <CoreMotion/CoreMotion.h>
28 
29 #include "SDL_error.h"
30 #include "SDL_sensor.h"
31 #include "SDL_coremotionsensor.h"
32 #include "../SDL_syssensor.h"
33 #include "../SDL_sensor_c.h"
34 
35 typedef struct
36 {
38  SDL_SensorID instance_id;
39 } SDL_CoreMotionSensor;
40 
41 static CMMotionManager *SDL_motion_manager;
42 static SDL_CoreMotionSensor *SDL_sensors;
43 static int SDL_sensors_count;
44 
45 static int
46 SDL_COREMOTION_SensorInit(void)
47 {
48  int i, sensors_count = 0;
49 
50  if (!SDL_motion_manager) {
51  SDL_motion_manager = [[CMMotionManager alloc] init];
52  }
53 
54  if (SDL_motion_manager.accelerometerAvailable) {
55  ++sensors_count;
56  }
57  if (SDL_motion_manager.gyroAvailable) {
58  ++sensors_count;
59  }
60 
61  if (sensors_count > 0) {
62  SDL_sensors = (SDL_CoreMotionSensor *)SDL_calloc(sensors_count, sizeof(*SDL_sensors));
63  if (!SDL_sensors) {
64  return SDL_OutOfMemory();
65  }
66 
67  i = 0;
68  if (SDL_motion_manager.accelerometerAvailable) {
69  SDL_sensors[i].type = SDL_SENSOR_ACCEL;
70  SDL_sensors[i].instance_id = SDL_GetNextSensorInstanceID();
71  ++i;
72  }
73  if (SDL_motion_manager.gyroAvailable) {
74  SDL_sensors[i].type = SDL_SENSOR_GYRO;
75  SDL_sensors[i].instance_id = SDL_GetNextSensorInstanceID();
76  ++i;
77  }
78  SDL_sensors_count = sensors_count;
79  }
80  return 0;
81 }
82 
83 static int
84 SDL_COREMOTION_SensorGetCount(void)
85 {
86  return SDL_sensors_count;
87 }
88 
89 static void
90 SDL_COREMOTION_SensorDetect(void)
91 {
92 }
93 
94 static const char *
95 SDL_COREMOTION_SensorGetDeviceName(int device_index)
96 {
97  switch (SDL_sensors[device_index].type) {
98  case SDL_SENSOR_ACCEL:
99  return "Accelerometer";
100  case SDL_SENSOR_GYRO:
101  return "Gyro";
102  default:
103  return "Unknown";
104  }
105 }
106 
107 static SDL_SensorType
108 SDL_COREMOTION_SensorGetDeviceType(int device_index)
109 {
110  return SDL_sensors[device_index].type;
111 }
112 
113 static int
114 SDL_COREMOTION_SensorGetDeviceNonPortableType(int device_index)
115 {
116  return SDL_sensors[device_index].type;
117 }
118 
119 static SDL_SensorID
120 SDL_COREMOTION_SensorGetDeviceInstanceID(int device_index)
121 {
122  return SDL_sensors[device_index].instance_id;
123 }
124 
125 static int
126 SDL_COREMOTION_SensorOpen(SDL_Sensor *sensor, int device_index)
127 {
128  struct sensor_hwdata *hwdata;
129 
130  hwdata = (struct sensor_hwdata *)SDL_calloc(1, sizeof(*hwdata));
131  if (hwdata == NULL) {
132  return SDL_OutOfMemory();
133  }
134  sensor->hwdata = hwdata;
135 
136  switch (sensor->type)
137  {
138  case SDL_SENSOR_ACCEL:
139  [SDL_motion_manager startAccelerometerUpdates];
140  break;
141  case SDL_SENSOR_GYRO:
142  [SDL_motion_manager startGyroUpdates];
143  break;
144  default:
145  break;
146  }
147  return 0;
148 }
149 
150 static void
151 SDL_COREMOTION_SensorUpdate(SDL_Sensor *sensor)
152 {
153  switch (sensor->type)
154  {
155  case SDL_SENSOR_ACCEL:
156  {
157  CMAccelerometerData *accelerometerData = SDL_motion_manager.accelerometerData;
158  if (accelerometerData) {
159  CMAcceleration acceleration = accelerometerData.acceleration;
160  float data[3];
161  data[0] = acceleration.x * SDL_STANDARD_GRAVITY;
162  data[1] = acceleration.y * SDL_STANDARD_GRAVITY;
163  data[2] = acceleration.z * SDL_STANDARD_GRAVITY;
164  if (SDL_memcmp(data, sensor->hwdata->data, sizeof(data)) != 0) {
166  SDL_memcpy(sensor->hwdata->data, data, sizeof(data));
167  }
168  }
169  }
170  break;
171  case SDL_SENSOR_GYRO:
172  {
173  CMGyroData *gyroData = SDL_motion_manager.gyroData;
174  if (gyroData) {
175  CMRotationRate rotationRate = gyroData.rotationRate;
176  float data[3];
177  data[0] = rotationRate.x;
178  data[1] = rotationRate.y;
179  data[2] = rotationRate.z;
180  if (SDL_memcmp(data, sensor->hwdata->data, sizeof(data)) != 0) {
182  SDL_memcpy(sensor->hwdata->data, data, sizeof(data));
183  }
184  }
185  }
186  break;
187  default:
188  break;
189  }
190 }
191 
192 static void
193 SDL_COREMOTION_SensorClose(SDL_Sensor *sensor)
194 {
195  if (sensor->hwdata) {
196  switch (sensor->type)
197  {
198  case SDL_SENSOR_ACCEL:
199  [SDL_motion_manager stopAccelerometerUpdates];
200  break;
201  case SDL_SENSOR_GYRO:
202  [SDL_motion_manager stopGyroUpdates];
203  break;
204  default:
205  break;
206  }
207  SDL_free(sensor->hwdata);
208  sensor->hwdata = NULL;
209  }
210 }
211 
212 static void
213 SDL_COREMOTION_SensorQuit(void)
214 {
215 }
216 
218 {
219  SDL_COREMOTION_SensorInit,
220  SDL_COREMOTION_SensorGetCount,
221  SDL_COREMOTION_SensorDetect,
222  SDL_COREMOTION_SensorGetDeviceName,
223  SDL_COREMOTION_SensorGetDeviceType,
224  SDL_COREMOTION_SensorGetDeviceNonPortableType,
225  SDL_COREMOTION_SensorGetDeviceInstanceID,
226  SDL_COREMOTION_SensorOpen,
227  SDL_COREMOTION_SensorUpdate,
228  SDL_COREMOTION_SensorClose,
229  SDL_COREMOTION_SensorQuit,
230 };
231 
232 #endif /* SDL_SENSOR_COREMOTION */
233 
234 /* vi: set ts=4 sw=4 expandtab: */
SDL_PrivateSensorUpdate
int SDL_PrivateSensorUpdate(SDL_Sensor *sensor, float *data, int num_values)
Definition: SDL_sensor.c:476
SDL_SensorDriver
Definition: SDL_syssensor.h:51
NULL
#define NULL
Definition: begin_code.h:167
SDL_error.h
SDL_STANDARD_GRAVITY
#define SDL_STANDARD_GRAVITY
Definition: SDL_sensor.h:97
SDL_coremotionsensor.h
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1973
SDL_SENSOR_GYRO
Definition: SDL_sensor.h:74
SDL_SensorType
SDL_SensorType
Definition: SDL_sensor.h:69
SDL_memcpy
#define SDL_memcpy
Definition: SDL_dynapi_overrides.h:387
SDL_COREMOTION_SensorDriver
SDL_SensorDriver SDL_COREMOTION_SensorDriver
sensor_hwdata
Definition: SDL_androidsensor.h:24
SDL_memcmp
#define SDL_memcmp
Definition: SDL_dynapi_overrides.h:389
SDL_free
#define SDL_free
Definition: SDL_dynapi_overrides.h:377
SDL_sensor.h
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_arraysize
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:115
SDL_calloc
#define SDL_calloc
Definition: SDL_dynapi_overrides.h:375
SDL_sensors
static SDL_Sensor * SDL_sensors
Definition: SDL_sensor.c:46
SDL_GetNextSensorInstanceID
SDL_SensorID SDL_GetNextSensorInstanceID()
Definition: SDL_sensor.c:112
SDL_SENSOR_ACCEL
Definition: SDL_sensor.h:73
SDL_config.h
type
GLuint GLuint GLsizei GLenum type
Definition: SDL_opengl.h:1570
i
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
SDL_SensorID
Sint32 SDL_SensorID
Definition: SDL_sensor.h:60