sdl

FORK: Simple Directmedia Layer
git clone https://git.neptards.moe/neptards/sdl.git
Log | Files | Refs

SDL_coremotionsensor.m (6385B)


      1 /*
      2   Simple DirectMedia Layer
      3   Copyright (C) 1997-2020 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 {
     37     SDL_SensorType type;
     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) {
    165                     SDL_PrivateSensorUpdate(sensor, data, SDL_arraysize(data));
    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) {
    181                     SDL_PrivateSensorUpdate(sensor, data, SDL_arraysize(data));
    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 
    217 SDL_SensorDriver SDL_COREMOTION_SensorDriver =
    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: */