Added missing files from previous commit
authorSam Lantinga <slouken@libsdl.org>
Tue, 04 Feb 2020 15:27:25 -0800
changeset 1348219e0bdbce46d
parent 13481 2f70560af6d4
child 13483 9c763de27c67
Added missing files from previous commit
src/joystick/hidapi/SDL_hidapi_rumble.c
src/joystick/hidapi/SDL_hidapi_rumble.h
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/joystick/hidapi/SDL_hidapi_rumble.c	Tue Feb 04 15:27:25 2020 -0800
     1.3 @@ -0,0 +1,188 @@
     1.4 +/*
     1.5 +  Simple DirectMedia Layer
     1.6 +  Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
     1.7 +
     1.8 +  This software is provided 'as-is', without any express or implied
     1.9 +  warranty.  In no event will the authors be held liable for any damages
    1.10 +  arising from the use of this software.
    1.11 +
    1.12 +  Permission is granted to anyone to use this software for any purpose,
    1.13 +  including commercial applications, and to alter it and redistribute it
    1.14 +  freely, subject to the following restrictions:
    1.15 +
    1.16 +  1. The origin of this software must not be misrepresented; you must not
    1.17 +     claim that you wrote the original software. If you use this software
    1.18 +     in a product, an acknowledgment in the product documentation would be
    1.19 +     appreciated but is not required.
    1.20 +  2. Altered source versions must be plainly marked as such, and must not be
    1.21 +     misrepresented as being the original software.
    1.22 +  3. This notice may not be removed or altered from any source distribution.
    1.23 +*/
    1.24 +#include "../../SDL_internal.h"
    1.25 +
    1.26 +#ifdef SDL_JOYSTICK_HIDAPI
    1.27 +
    1.28 +/* Handle rumble on a separate thread so it doesn't block the application */
    1.29 +
    1.30 +#include "SDL_assert.h"
    1.31 +#include "SDL_thread.h"
    1.32 +#include "SDL_hidapijoystick_c.h"
    1.33 +#include "SDL_hidapi_rumble.h"
    1.34 +
    1.35 +
    1.36 +typedef struct SDL_HIDAPI_RumbleRequest
    1.37 +{
    1.38 +    SDL_HIDAPI_Device *device;
    1.39 +    Uint8 data[USB_PACKET_LENGTH];
    1.40 +    int size;
    1.41 +    struct SDL_HIDAPI_RumbleRequest *prev;
    1.42 +
    1.43 +} SDL_HIDAPI_RumbleRequest;
    1.44 +
    1.45 +typedef struct SDL_HIDAPI_RumbleContext
    1.46 +{
    1.47 +    volatile SDL_bool running;
    1.48 +    SDL_Thread *thread;
    1.49 +    SDL_mutex *lock;
    1.50 +    SDL_sem *request_sem;
    1.51 +    SDL_HIDAPI_RumbleRequest *requests_head;
    1.52 +    SDL_HIDAPI_RumbleRequest *requests_tail;
    1.53 +} SDL_HIDAPI_RumbleContext;
    1.54 +
    1.55 +static SDL_HIDAPI_RumbleContext rumble_context;
    1.56 +
    1.57 +static int SDL_HIDAPI_RumbleThread(void *data)
    1.58 +{
    1.59 +    SDL_HIDAPI_RumbleContext *ctx = (SDL_HIDAPI_RumbleContext *)data;
    1.60 +
    1.61 +    SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH);
    1.62 +
    1.63 +    while (ctx->running) {
    1.64 +        SDL_HIDAPI_RumbleRequest *request = NULL;
    1.65 +
    1.66 +        SDL_SemWait(ctx->request_sem);
    1.67 +
    1.68 +        SDL_LockMutex(ctx->lock);
    1.69 +        request = ctx->requests_tail;
    1.70 +        if (request) {
    1.71 +            if (request == ctx->requests_head) {
    1.72 +                ctx->requests_head = NULL;
    1.73 +            }
    1.74 +            ctx->requests_tail = request->prev;
    1.75 +        }
    1.76 +        SDL_UnlockMutex(ctx->lock);
    1.77 +
    1.78 +        if (request) {
    1.79 +            SDL_LockMutex(request->device->dev_lock);
    1.80 +            hid_write(request->device->dev, request->data, request->size);
    1.81 +            SDL_UnlockMutex(request->device->dev_lock);
    1.82 +            (void)SDL_AtomicDecRef(&request->device->rumble_pending);
    1.83 +            SDL_free(request);
    1.84 +        }
    1.85 +    }
    1.86 +    return 0;
    1.87 +}
    1.88 +
    1.89 +static void
    1.90 +SDL_HIDAPI_StopRumbleThread(SDL_HIDAPI_RumbleContext *ctx)
    1.91 +{
    1.92 +    ctx->running = SDL_FALSE;
    1.93 +
    1.94 +    if (ctx->thread) {
    1.95 +        int result;
    1.96 +
    1.97 +        SDL_SemPost(ctx->request_sem);
    1.98 +        SDL_WaitThread(ctx->thread, &result);
    1.99 +        ctx->thread = NULL;
   1.100 +    }
   1.101 +
   1.102 +    /* This should always be called with an empty queue */
   1.103 +    SDL_assert(!ctx->requests_head);
   1.104 +    SDL_assert(!ctx->requests_tail);
   1.105 +
   1.106 +    if (ctx->request_sem) {
   1.107 +        SDL_DestroySemaphore(ctx->request_sem);
   1.108 +        ctx->request_sem = NULL;
   1.109 +    }
   1.110 +
   1.111 +    if (ctx->lock) {
   1.112 +        SDL_DestroyMutex(ctx->lock);
   1.113 +        ctx->lock = NULL;
   1.114 +    }
   1.115 +}
   1.116 +
   1.117 +static int
   1.118 +SDL_HIDAPI_StartRumbleThread(SDL_HIDAPI_RumbleContext *ctx)
   1.119 +{
   1.120 +    ctx->lock = SDL_CreateMutex();
   1.121 +    if (!ctx->lock) {
   1.122 +        SDL_HIDAPI_StopRumbleThread(ctx);
   1.123 +        return -1;
   1.124 +    }
   1.125 +
   1.126 +    ctx->request_sem = SDL_CreateSemaphore(0);
   1.127 +    if (!ctx->request_sem) {
   1.128 +        SDL_HIDAPI_StopRumbleThread(ctx);
   1.129 +        return -1;
   1.130 +    }
   1.131 +
   1.132 +    ctx->running = SDL_TRUE;
   1.133 +    ctx->thread = SDL_CreateThread(SDL_HIDAPI_RumbleThread, "HIDAPI Rumble", ctx);
   1.134 +    if (!ctx->thread) {
   1.135 +        SDL_HIDAPI_StopRumbleThread(ctx);
   1.136 +        return -1;
   1.137 +    }
   1.138 +    return 0;
   1.139 +}
   1.140 +
   1.141 +int SDL_HIDAPI_SendRumble(SDL_HIDAPI_Device *device, const Uint8 *data, int size)
   1.142 +{
   1.143 +    SDL_HIDAPI_RumbleContext *ctx = &rumble_context;
   1.144 +    SDL_HIDAPI_RumbleRequest *request;
   1.145 +
   1.146 +    if (size > sizeof(request->data)) {
   1.147 +        return SDL_SetError("Couldn't send rumble, size %d is greater than %d", size, sizeof(request->data));
   1.148 +    }
   1.149 +
   1.150 +    if (!ctx->running) {
   1.151 +        if (SDL_HIDAPI_StartRumbleThread(ctx) < 0) {
   1.152 +            return -1;
   1.153 +        }
   1.154 +    }
   1.155 +
   1.156 +    request = (SDL_HIDAPI_RumbleRequest *)SDL_calloc(1, sizeof(*request));
   1.157 +    if (!request) {
   1.158 +        return SDL_OutOfMemory();
   1.159 +    }
   1.160 +    request->device = device;
   1.161 +    SDL_memcpy(request->data, data, size);
   1.162 +    request->size = size;
   1.163 +
   1.164 +    SDL_AtomicIncRef(&device->rumble_pending);
   1.165 +    
   1.166 +    SDL_LockMutex(ctx->lock);
   1.167 +    if (ctx->requests_head) {
   1.168 +        ctx->requests_head->prev = request;
   1.169 +    } else {
   1.170 +        ctx->requests_tail = request;
   1.171 +    }
   1.172 +    ctx->requests_head = request;
   1.173 +    SDL_UnlockMutex(ctx->lock);
   1.174 +
   1.175 +    SDL_SemPost(ctx->request_sem);
   1.176 +
   1.177 +    return size;
   1.178 +}
   1.179 +
   1.180 +void SDL_HIDAPI_QuitRumble()
   1.181 +{
   1.182 +    SDL_HIDAPI_RumbleContext *ctx = &rumble_context;
   1.183 +
   1.184 +    if (ctx->running) {
   1.185 +        SDL_HIDAPI_StopRumbleThread(ctx);
   1.186 +    }
   1.187 +}
   1.188 +
   1.189 +#endif /* SDL_JOYSTICK_HIDAPI */
   1.190 +
   1.191 +/* vi: set ts=4 sw=4 expandtab: */
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/joystick/hidapi/SDL_hidapi_rumble.h	Tue Feb 04 15:27:25 2020 -0800
     2.3 @@ -0,0 +1,31 @@
     2.4 +/*
     2.5 +  Simple DirectMedia Layer
     2.6 +  Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
     2.7 +
     2.8 +  This software is provided 'as-is', without any express or implied
     2.9 +  warranty.  In no event will the authors be held liable for any damages
    2.10 +  arising from the use of this software.
    2.11 +
    2.12 +  Permission is granted to anyone to use this software for any purpose,
    2.13 +  including commercial applications, and to alter it and redistribute it
    2.14 +  freely, subject to the following restrictions:
    2.15 +
    2.16 +  1. The origin of this software must not be misrepresented; you must not
    2.17 +     claim that you wrote the original software. If you use this software
    2.18 +     in a product, an acknowledgment in the product documentation would be
    2.19 +     appreciated but is not required.
    2.20 +  2. Altered source versions must be plainly marked as such, and must not be
    2.21 +     misrepresented as being the original software.
    2.22 +  3. This notice may not be removed or altered from any source distribution.
    2.23 +*/
    2.24 +#include "../../SDL_internal.h"
    2.25 +
    2.26 +#ifdef SDL_JOYSTICK_HIDAPI
    2.27 +
    2.28 +/* Handle rumble on a separate thread so it doesn't block the application */
    2.29 +int SDL_HIDAPI_SendRumble(SDL_HIDAPI_Device *device, const Uint8 *data, int size);
    2.30 +void SDL_HIDAPI_QuitRumble();
    2.31 +
    2.32 +#endif /* SDL_JOYSTICK_HIDAPI */
    2.33 +
    2.34 +/* vi: set ts=4 sw=4 expandtab: */