src/haptic/android/SDL_syshaptic.c
author Sam Lantinga <slouken@libsdl.org>
Wed, 03 Jan 2018 10:03:25 -0800
changeset 11811 5d94cb6b24d3
parent 11763 5c8fc26757d7
child 12152 cb129c06aa86
permissions -rw-r--r--
Updated copyright for 2018
slouken@11238
     1
/*
slouken@11238
     2
  Simple DirectMedia Layer
slouken@11811
     3
  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
slouken@11238
     4
slouken@11238
     5
  This software is provided 'as-is', without any express or implied
slouken@11238
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@11238
     7
  arising from the use of this software.
slouken@11238
     8
slouken@11238
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@11238
    10
  including commercial applications, and to alter it and redistribute it
slouken@11238
    11
  freely, subject to the following restrictions:
slouken@11238
    12
slouken@11238
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@11238
    14
     claim that you wrote the original software. If you use this software
slouken@11238
    15
     in a product, an acknowledgment in the product documentation would be
slouken@11238
    16
     appreciated but is not required.
slouken@11238
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@11238
    18
     misrepresented as being the original software.
slouken@11238
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@11238
    20
*/
slouken@11238
    21
#include "../../SDL_internal.h"
slouken@11238
    22
slouken@11238
    23
#ifdef SDL_HAPTIC_ANDROID
slouken@11238
    24
slouken@11238
    25
#include "SDL_assert.h"
slouken@11238
    26
#include "SDL_timer.h"
slouken@11238
    27
#include "SDL_syshaptic_c.h"
slouken@11238
    28
#include "../SDL_syshaptic.h"
slouken@11238
    29
#include "SDL_haptic.h"
slouken@11238
    30
#include "../../core/android/SDL_android.h"
slouken@11238
    31
#include "SDL_joystick.h"
slouken@11238
    32
#include "../../joystick/SDL_sysjoystick.h"     /* For the real SDL_Joystick */
slouken@11238
    33
#include "../../joystick/android/SDL_sysjoystick_c.h"     /* For joystick hwdata */
slouken@11238
    34
slouken@11238
    35
slouken@11238
    36
typedef struct SDL_hapticlist_item
slouken@11238
    37
{
slouken@11238
    38
    int device_id;
slouken@11238
    39
    char *name;
slouken@11238
    40
    SDL_Haptic *haptic;
slouken@11238
    41
    struct SDL_hapticlist_item *next;
slouken@11238
    42
} SDL_hapticlist_item;
slouken@11238
    43
slouken@11238
    44
static SDL_hapticlist_item *SDL_hapticlist = NULL;
slouken@11238
    45
static SDL_hapticlist_item *SDL_hapticlist_tail = NULL;
slouken@11238
    46
static int numhaptics = 0;
slouken@11238
    47
slouken@11238
    48
slouken@11238
    49
int
slouken@11238
    50
SDL_SYS_HapticInit(void)
slouken@11238
    51
{
slouken@11238
    52
    /* Support for device connect/disconnect is API >= 16 only,
slouken@11238
    53
     * so we poll every three seconds
slouken@11238
    54
     * Ref: http://developer.android.com/reference/android/hardware/input/InputManager.InputDeviceListener.html
slouken@11238
    55
     */
slouken@11238
    56
    static Uint32 timeout = 0;
slouken@11238
    57
    if (SDL_TICKS_PASSED(SDL_GetTicks(), timeout)) {
slouken@11238
    58
        timeout = SDL_GetTicks() + 3000;
slouken@11238
    59
        Android_JNI_PollHapticDevices();
slouken@11238
    60
    }
slouken@11238
    61
    return (numhaptics);
slouken@11238
    62
}
slouken@11238
    63
slouken@11238
    64
int
slouken@11238
    65
SDL_SYS_NumHaptics(void)
slouken@11238
    66
{
slouken@11238
    67
    return (numhaptics);
slouken@11238
    68
}
slouken@11238
    69
slouken@11238
    70
static SDL_hapticlist_item *
slouken@11238
    71
HapticByOrder(int index)
slouken@11238
    72
{
slouken@11238
    73
    SDL_hapticlist_item *item = SDL_hapticlist;
slouken@11238
    74
    if ((index < 0) || (index >= numhaptics)) {
slouken@11238
    75
        return NULL;
slouken@11238
    76
    }
slouken@11238
    77
    while (index > 0) {
slouken@11238
    78
        SDL_assert(item != NULL);
slouken@11238
    79
        --index;
slouken@11238
    80
        item = item->next;
slouken@11238
    81
    }
slouken@11238
    82
    return item;
slouken@11238
    83
}
slouken@11238
    84
slouken@11238
    85
static SDL_hapticlist_item *
slouken@11238
    86
HapticByDevId (int device_id)
slouken@11238
    87
{
slouken@11238
    88
    SDL_hapticlist_item *item;
slouken@11238
    89
    for (item = SDL_hapticlist; item != NULL; item = item->next) {
slouken@11238
    90
        if (device_id == item->device_id) {
slouken@11299
    91
            /*SDL_Log("=+=+=+=+=+= HapticByDevId id [%d]", device_id);*/
slouken@11238
    92
            return item;
slouken@11238
    93
        }
slouken@11238
    94
    }
slouken@11238
    95
    return NULL;
slouken@11238
    96
}
slouken@11238
    97
slouken@11238
    98
const char *
slouken@11238
    99
SDL_SYS_HapticName(int index)
slouken@11238
   100
{
slouken@11238
   101
    SDL_hapticlist_item *item = HapticByOrder(index);
slouken@11238
   102
    if (item == NULL ) {
slouken@11238
   103
        SDL_SetError("No such device");
slouken@11238
   104
        return NULL;
slouken@11238
   105
    }
slouken@11238
   106
    return item->name;
slouken@11238
   107
}
slouken@11238
   108
slouken@11238
   109
slouken@11238
   110
static SDL_hapticlist_item *
slouken@11238
   111
OpenHaptic(SDL_Haptic *haptic, SDL_hapticlist_item *item)
slouken@11238
   112
{
slouken@11238
   113
    if (item == NULL ) {
slouken@11238
   114
        SDL_SetError("No such device");
slouken@11238
   115
        return NULL;
slouken@11238
   116
    }
slouken@11238
   117
    if (item->haptic != NULL) {
slouken@11238
   118
        SDL_SetError("Haptic already opened");
slouken@11238
   119
        return NULL;
slouken@11238
   120
    }
slouken@11238
   121
slouken@11238
   122
    haptic->hwdata = (struct haptic_hwdata *)item;
slouken@11238
   123
    item->haptic = haptic;
slouken@11238
   124
slouken@11238
   125
    haptic->supported = SDL_HAPTIC_LEFTRIGHT;
slouken@11238
   126
    haptic->neffects = 1;
slouken@11238
   127
    haptic->nplaying = haptic->neffects;
slouken@11238
   128
    haptic->effects = (struct haptic_effect *)SDL_malloc (sizeof (struct haptic_effect) * haptic->neffects);
slouken@11238
   129
    if (haptic->effects == NULL) {
slouken@11238
   130
        SDL_OutOfMemory();
slouken@11238
   131
        return NULL;
slouken@11238
   132
    }
slouken@11238
   133
    SDL_memset(haptic->effects, 0, sizeof (struct haptic_effect) * haptic->neffects);
slouken@11238
   134
    return item;
slouken@11238
   135
}
slouken@11238
   136
slouken@11238
   137
static SDL_hapticlist_item *
slouken@11238
   138
OpenHapticByOrder(SDL_Haptic *haptic, int index)
slouken@11238
   139
{
slouken@11238
   140
    return OpenHaptic (haptic, HapticByOrder(index));
slouken@11238
   141
}
slouken@11238
   142
slouken@11238
   143
static SDL_hapticlist_item *
slouken@11238
   144
OpenHapticByDevId(SDL_Haptic *haptic, int device_id)
slouken@11238
   145
{
slouken@11238
   146
    return OpenHaptic (haptic, HapticByDevId(device_id));
slouken@11238
   147
}
slouken@11238
   148
slouken@11238
   149
int
slouken@11238
   150
SDL_SYS_HapticOpen(SDL_Haptic *haptic)
slouken@11238
   151
{
slouken@11238
   152
    return (OpenHapticByOrder(haptic, haptic->index) == NULL ? -1 : 0);
slouken@11238
   153
}
slouken@11238
   154
slouken@11238
   155
slouken@11238
   156
int
slouken@11238
   157
SDL_SYS_HapticMouse(void)
slouken@11238
   158
{
slouken@11238
   159
    return 0;
slouken@11238
   160
}
slouken@11238
   161
slouken@11238
   162
slouken@11238
   163
int
slouken@11238
   164
SDL_SYS_JoystickIsHaptic(SDL_Joystick *joystick)
slouken@11238
   165
{
slouken@11238
   166
    SDL_hapticlist_item *item;
slouken@11238
   167
    item = HapticByDevId(((joystick_hwdata *)joystick->hwdata)->device_id);
slouken@11763
   168
    return (item != NULL) ? 1 : 0;
slouken@11238
   169
}
slouken@11238
   170
slouken@11238
   171
slouken@11238
   172
int
slouken@11238
   173
SDL_SYS_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick)
slouken@11238
   174
{
slouken@11238
   175
    return (OpenHapticByDevId(haptic, ((joystick_hwdata *)joystick->hwdata)->device_id) == NULL ? -1 : 0);
slouken@11238
   176
}
slouken@11238
   177
slouken@11238
   178
slouken@11238
   179
int
slouken@11238
   180
SDL_SYS_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick)
slouken@11238
   181
{
slouken@11238
   182
    return (((SDL_hapticlist_item *)haptic->hwdata)->device_id == ((joystick_hwdata *)joystick->hwdata)->device_id ? 1 : 0);
slouken@11238
   183
}
slouken@11238
   184
slouken@11238
   185
slouken@11238
   186
void
slouken@11238
   187
SDL_SYS_HapticClose(SDL_Haptic * haptic)
slouken@11238
   188
{
slouken@11238
   189
    ((SDL_hapticlist_item *)haptic->hwdata)->haptic = NULL;
slouken@11238
   190
    haptic->hwdata = NULL;
slouken@11238
   191
    return;
slouken@11238
   192
}
slouken@11238
   193
slouken@11238
   194
slouken@11238
   195
void
slouken@11238
   196
SDL_SYS_HapticQuit(void)
slouken@11238
   197
{
slouken@11238
   198
    SDL_hapticlist_item *item = NULL;
slouken@11238
   199
    SDL_hapticlist_item *next = NULL;
slouken@11238
   200
slouken@11238
   201
    for (item = SDL_hapticlist; item; item = next) {
slouken@11238
   202
        next = item->next;
slouken@11238
   203
        SDL_free(item);
slouken@11238
   204
    }
slouken@11238
   205
slouken@11238
   206
    SDL_hapticlist = SDL_hapticlist_tail = NULL;
slouken@11238
   207
    numhaptics = 0;
slouken@11238
   208
    return;
slouken@11238
   209
}
slouken@11238
   210
slouken@11238
   211
slouken@11238
   212
int
slouken@11238
   213
SDL_SYS_HapticNewEffect(SDL_Haptic * haptic,
slouken@11238
   214
                        struct haptic_effect *effect, SDL_HapticEffect * base)
slouken@11238
   215
{
slouken@11238
   216
    return 0;
slouken@11238
   217
}
slouken@11238
   218
slouken@11238
   219
slouken@11238
   220
int
slouken@11238
   221
SDL_SYS_HapticUpdateEffect(SDL_Haptic * haptic,
slouken@11238
   222
                           struct haptic_effect *effect,
slouken@11238
   223
                           SDL_HapticEffect * data)
slouken@11238
   224
{
slouken@11238
   225
    return 0;
slouken@11238
   226
}
slouken@11238
   227
slouken@11238
   228
slouken@11238
   229
int
slouken@11238
   230
SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect,
slouken@11238
   231
                        Uint32 iterations)
slouken@11238
   232
{
slouken@11238
   233
    Android_JNI_HapticRun (((SDL_hapticlist_item *)haptic->hwdata)->device_id, effect->effect.leftright.length);
slouken@11238
   234
    return 0;
slouken@11238
   235
}
slouken@11238
   236
slouken@11238
   237
slouken@11238
   238
int
slouken@11238
   239
SDL_SYS_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
slouken@11238
   240
{
slouken@11238
   241
    return 0;
slouken@11238
   242
}
slouken@11238
   243
slouken@11238
   244
slouken@11238
   245
void
slouken@11238
   246
SDL_SYS_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
slouken@11238
   247
{
slouken@11238
   248
    return;
slouken@11238
   249
}
slouken@11238
   250
slouken@11238
   251
slouken@11238
   252
int
slouken@11238
   253
SDL_SYS_HapticGetEffectStatus(SDL_Haptic * haptic,
slouken@11238
   254
                              struct haptic_effect *effect)
slouken@11238
   255
{
slouken@11238
   256
    return 0;
slouken@11238
   257
}
slouken@11238
   258
slouken@11238
   259
slouken@11238
   260
int
slouken@11238
   261
SDL_SYS_HapticSetGain(SDL_Haptic * haptic, int gain)
slouken@11238
   262
{
slouken@11238
   263
    return 0;
slouken@11238
   264
}
slouken@11238
   265
slouken@11238
   266
slouken@11238
   267
int
slouken@11238
   268
SDL_SYS_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter)
slouken@11238
   269
{
slouken@11238
   270
    return 0;
slouken@11238
   271
}
slouken@11238
   272
slouken@11238
   273
int
slouken@11238
   274
SDL_SYS_HapticPause(SDL_Haptic * haptic)
slouken@11238
   275
{
slouken@11238
   276
    return 0;
slouken@11238
   277
}
slouken@11238
   278
slouken@11238
   279
int
slouken@11238
   280
SDL_SYS_HapticUnpause(SDL_Haptic * haptic)
slouken@11238
   281
{
slouken@11238
   282
    return 0;
slouken@11238
   283
}
slouken@11238
   284
slouken@11238
   285
int
slouken@11238
   286
SDL_SYS_HapticStopAll(SDL_Haptic * haptic)
slouken@11238
   287
{
slouken@11238
   288
    return 0;
slouken@11238
   289
}
slouken@11238
   290
slouken@11238
   291
slouken@11238
   292
slouken@11238
   293
int
slouken@11238
   294
Android_AddHaptic(int device_id, const char *name)
slouken@11238
   295
{
slouken@11238
   296
    SDL_hapticlist_item *item;
slouken@11238
   297
    item = (SDL_hapticlist_item *) SDL_calloc(1, sizeof (SDL_hapticlist_item));
slouken@11238
   298
    if (item == NULL) {
slouken@11238
   299
        return -1;
slouken@11238
   300
    }
slouken@11238
   301
slouken@11238
   302
    item->device_id = device_id;
slouken@11238
   303
    item->name = SDL_strdup (name);
slouken@11238
   304
    if (item->name == NULL) {
slouken@11238
   305
        SDL_free (item);
slouken@11238
   306
        return -1;
slouken@11238
   307
    }
slouken@11238
   308
slouken@11238
   309
    if (SDL_hapticlist_tail == NULL) {
slouken@11238
   310
        SDL_hapticlist = SDL_hapticlist_tail = item;
slouken@11238
   311
    } else {
slouken@11238
   312
        SDL_hapticlist_tail->next = item;
slouken@11238
   313
        SDL_hapticlist_tail = item;
slouken@11238
   314
    }
slouken@11238
   315
slouken@11238
   316
    ++numhaptics;
slouken@11238
   317
    return numhaptics;
slouken@11238
   318
}
slouken@11238
   319
slouken@11238
   320
int 
slouken@11238
   321
Android_RemoveHaptic(int device_id)
slouken@11238
   322
{
slouken@11238
   323
    SDL_hapticlist_item *item;
slouken@11238
   324
    SDL_hapticlist_item *prev = NULL;
slouken@11238
   325
slouken@11238
   326
    for (item = SDL_hapticlist; item != NULL; item = item->next) {
slouken@11238
   327
        /* found it, remove it. */
slouken@11238
   328
        if (device_id == item->device_id) {
slouken@11238
   329
            const int retval = item->haptic ? item->haptic->index : -1;
slouken@11238
   330
slouken@11238
   331
            if (prev != NULL) {
slouken@11238
   332
                prev->next = item->next;
slouken@11238
   333
            } else {
slouken@11238
   334
                SDL_assert(SDL_hapticlist == item);
slouken@11238
   335
                SDL_hapticlist = item->next;
slouken@11238
   336
            }
slouken@11238
   337
            if (item == SDL_hapticlist_tail) {
slouken@11238
   338
                SDL_hapticlist_tail = prev;
slouken@11238
   339
            }
slouken@11238
   340
slouken@11238
   341
            /* Need to decrement the haptic count */
slouken@11238
   342
            --numhaptics;
slouken@11238
   343
            /* !!! TODO: Send a haptic remove event? */
slouken@11238
   344
slouken@11238
   345
            SDL_free(item->name);
slouken@11238
   346
            SDL_free(item);
slouken@11238
   347
            return retval;
slouken@11238
   348
        }
slouken@11238
   349
        prev = item;
slouken@11238
   350
    }
slouken@11238
   351
    return -1;
slouken@11238
   352
}
slouken@11238
   353
slouken@11238
   354
slouken@11238
   355
#endif /* SDL_HAPTIC_ANDROID */
slouken@11238
   356
slouken@11238
   357
/* vi: set ts=4 sw=4 expandtab: */