src/joystick/iphoneos/SDL_sysjoystick.m
author Philipp Wiesemann <philipp.wiesemann@arcor.de>
Fri, 16 Jan 2015 23:07:10 +0100
changeset 9311 a4b031e28de8
parent 8921 4a9feef61c85
child 9380 07b7c1005a23
child 9535 a66a7f7e8cd8
permissions -rw-r--r--
Fixed wrong documentation in joystick implementation source.
slouken@2765
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@8149
     3
  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
slouken@2765
     4
slouken@5535
     5
  This software is provided 'as-is', without any express or implied
slouken@5535
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     7
  arising from the use of this software.
slouken@2765
     8
slouken@5535
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
    10
  including commercial applications, and to alter it and redistribute it
slouken@5535
    11
  freely, subject to the following restrictions:
slouken@2765
    12
slouken@5535
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@5535
    14
     claim that you wrote the original software. If you use this software
slouken@5535
    15
     in a product, an acknowledgment in the product documentation would be
slouken@5535
    16
     appreciated but is not required.
slouken@5535
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@5535
    18
     misrepresented as being the original software.
slouken@5535
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@2765
    20
*/
icculus@8093
    21
#include "../../SDL_internal.h"
slouken@2765
    22
philipp@8138
    23
/* This is the iOS implementation of the SDL joystick API */
slouken@2765
    24
slouken@2765
    25
#include "SDL_joystick.h"
slouken@8921
    26
#include "SDL_stdinc.h"
slouken@2765
    27
#include "../SDL_sysjoystick.h"
slouken@2765
    28
#include "../SDL_joystick_c.h"
slouken@2765
    29
slouken@8921
    30
#import <CoreMotion/CoreMotion.h>
slouken@8921
    31
slouken@8921
    32
/* needed for SDL_IPHONE_MAX_GFORCE macro */
slouken@8921
    33
#import "SDL_config_iphoneos.h"
slouken@8921
    34
slouken@8921
    35
const char *accelerometerName = "iOS accelerometer";
slouken@8921
    36
slouken@8921
    37
static CMMotionManager *motionManager = nil;
slouken@2765
    38
slouken@2765
    39
/* Function to scan the system for joysticks.
philipp@9311
    40
 * Joystick 0 should be the system default joystick.
slouken@2765
    41
 * It should return 0, or -1 on an unrecoverable fatal error.
slouken@2765
    42
 */
slouken@2765
    43
int
slouken@2765
    44
SDL_SYS_JoystickInit(void)
slouken@2765
    45
{
slouken@2765
    46
    return (1);
slouken@2765
    47
}
slouken@2765
    48
slouken@6707
    49
int SDL_SYS_NumJoysticks()
slouken@6707
    50
{
slouken@6707
    51
    return 1;
slouken@6707
    52
}
slouken@6707
    53
slouken@6707
    54
void SDL_SYS_JoystickDetect()
slouken@6707
    55
{
slouken@6707
    56
}
slouken@6707
    57
slouken@2765
    58
/* Function to get the device-dependent name of a joystick */
slouken@2765
    59
const char *
slouken@6707
    60
SDL_SYS_JoystickNameForDeviceIndex(int device_index)
slouken@2765
    61
{
slouken@6707
    62
    return accelerometerName;
slouken@6707
    63
}
slouken@6707
    64
slouken@6707
    65
/* Function to perform the mapping from device index to the instance id for this index */
slouken@6707
    66
SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
slouken@6707
    67
{
slouken@6707
    68
    return device_index;
slouken@2765
    69
}
slouken@2765
    70
slouken@2765
    71
/* Function to open a joystick for use.
slouken@2765
    72
   The joystick to open is specified by the index field of the joystick.
slouken@2765
    73
   This should fill the nbuttons and naxes fields of the joystick structure.
slouken@2765
    74
   It returns 0, or -1 if there is an error.
slouken@2765
    75
 */
slouken@2765
    76
int
slouken@6693
    77
SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
slouken@2765
    78
{
slouken@6707
    79
    joystick->naxes = 3;
slouken@6707
    80
    joystick->nhats = 0;
slouken@6707
    81
    joystick->nballs = 0;
slouken@6707
    82
    joystick->nbuttons = 0;
slouken@8921
    83
slouken@8921
    84
    if (motionManager == nil) {
slouken@8921
    85
        motionManager = [[CMMotionManager alloc] init];
slouken@8921
    86
    }
slouken@8921
    87
slouken@8921
    88
    /* Shorter times between updates can significantly increase CPU usage. */
slouken@8921
    89
    motionManager.accelerometerUpdateInterval = 0.1;
slouken@8921
    90
    [motionManager startAccelerometerUpdates];
slouken@8921
    91
slouken@6707
    92
    return 0;
slouken@6707
    93
}
slouken@6707
    94
slouken@6707
    95
/* Function to determine is this joystick is attached to the system right now */
slouken@6707
    96
SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
slouken@6707
    97
{
slouken@6707
    98
    return SDL_TRUE;
slouken@2765
    99
}
slouken@2765
   100
slouken@8921
   101
static void SDL_SYS_AccelerometerUpdate(SDL_Joystick * joystick)
slouken@8921
   102
{
slouken@8921
   103
    const float maxgforce = SDL_IPHONE_MAX_GFORCE;
slouken@8921
   104
    const SInt16 maxsint16 = 0x7FFF;
slouken@8921
   105
    CMAcceleration accel;
slouken@8921
   106
slouken@8921
   107
    if (!motionManager.accelerometerActive) {
slouken@8921
   108
        return;
slouken@8921
   109
    }
slouken@8921
   110
slouken@8921
   111
    accel = [[motionManager accelerometerData] acceleration];
slouken@8921
   112
slouken@8921
   113
    /*
slouken@8921
   114
     Convert accelerometer data from floating point to Sint16, which is what
slouken@8921
   115
     the joystick system expects.
slouken@8921
   116
slouken@8921
   117
     To do the conversion, the data is first clamped onto the interval
slouken@8921
   118
     [-SDL_IPHONE_MAX_G_FORCE, SDL_IPHONE_MAX_G_FORCE], then the data is multiplied
slouken@8921
   119
     by MAX_SINT16 so that it is mapped to the full range of an Sint16.
slouken@8921
   120
slouken@8921
   121
     You can customize the clamped range of this function by modifying the
slouken@8921
   122
     SDL_IPHONE_MAX_GFORCE macro in SDL_config_iphoneos.h.
slouken@8921
   123
slouken@8921
   124
     Once converted to Sint16, the accelerometer data no longer has coherent
slouken@8921
   125
     units. You can convert the data back to units of g-force by multiplying
slouken@8921
   126
     it in your application's code by SDL_IPHONE_MAX_GFORCE / 0x7FFF.
slouken@8921
   127
     */
slouken@8921
   128
slouken@8921
   129
    /* clamp the data */
slouken@8921
   130
    accel.x = SDL_min(SDL_max(accel.x, -maxgforce), maxgforce);
slouken@8921
   131
    accel.y = SDL_min(SDL_max(accel.y, -maxgforce), maxgforce);
slouken@8921
   132
    accel.z = SDL_min(SDL_max(accel.z, -maxgforce), maxgforce);
slouken@8921
   133
slouken@8921
   134
    /* pass in data mapped to range of SInt16 */
slouken@8921
   135
    SDL_PrivateJoystickAxis(joystick, 0, (accel.x / maxgforce) * maxsint16);
slouken@8921
   136
    SDL_PrivateJoystickAxis(joystick, 1, -(accel.y / maxgforce) * maxsint16);
slouken@8921
   137
    SDL_PrivateJoystickAxis(joystick, 2, (accel.z / maxgforce) * maxsint16);
slouken@8921
   138
}
slouken@8921
   139
slouken@2765
   140
/* Function to update the state of a joystick - called as a device poll.
slouken@2765
   141
 * This function shouldn't update the joystick structure directly,
slouken@2765
   142
 * but instead should call SDL_PrivateJoystick*() to deliver events
slouken@2765
   143
 * and update joystick device state.
slouken@2765
   144
 */
slouken@2765
   145
void
slouken@2765
   146
SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
slouken@2765
   147
{
slouken@8921
   148
    SDL_SYS_AccelerometerUpdate(joystick);
slouken@2765
   149
}
slouken@2765
   150
slouken@2765
   151
/* Function to close a joystick after use */
slouken@2765
   152
void
slouken@2765
   153
SDL_SYS_JoystickClose(SDL_Joystick * joystick)
slouken@2765
   154
{
slouken@8921
   155
    [motionManager stopAccelerometerUpdates];
slouken@8921
   156
    joystick->closed = 1;
slouken@2765
   157
}
slouken@2765
   158
slouken@2765
   159
/* Function to perform any system-specific joystick related cleanup */
slouken@2765
   160
void
slouken@2765
   161
SDL_SYS_JoystickQuit(void)
slouken@2765
   162
{
slouken@8921
   163
    if (motionManager != nil) {
slouken@8921
   164
        [motionManager release];
slouken@8921
   165
        motionManager = nil;
slouken@8921
   166
    }
slouken@2765
   167
}
slouken@6693
   168
slouken@6744
   169
SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
slouken@6693
   170
{
slouken@6744
   171
    SDL_JoystickGUID guid;
slouken@7191
   172
    /* the GUID is just the first 16 chars of the name for now */
slouken@6707
   173
    const char *name = SDL_SYS_JoystickNameForDeviceIndex( device_index );
slouken@6693
   174
    SDL_zero( guid );
slouken@6693
   175
    SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
slouken@6693
   176
    return guid;
slouken@6693
   177
}
slouken@6693
   178
slouken@6744
   179
SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick)
slouken@6693
   180
{
slouken@6744
   181
    SDL_JoystickGUID guid;
slouken@7191
   182
    /* the GUID is just the first 16 chars of the name for now */
slouken@6693
   183
    const char *name = joystick->name;
slouken@6693
   184
    SDL_zero( guid );
slouken@6693
   185
    SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
slouken@6693
   186
    return guid;
slouken@6693
   187
}
slouken@6693
   188
slouken@2765
   189
/* vi: set ts=4 sw=4 expandtab: */