sdl

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

SDL_virtualjoystick.c (10310B)


      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 #include "../../SDL_internal.h"
     22 
     23 #if defined(SDL_JOYSTICK_VIRTUAL)
     24 
     25 /* This is the virtual implementation of the SDL joystick API */
     26 
     27 #include "SDL_virtualjoystick_c.h"
     28 #include "../SDL_sysjoystick.h"
     29 #include "../SDL_joystick_c.h"
     30 
     31 extern SDL_JoystickDriver SDL_VIRTUAL_JoystickDriver;
     32 
     33 static joystick_hwdata * g_VJoys = NULL;
     34 
     35 
     36 static joystick_hwdata *
     37 VIRTUAL_HWDataForIndex(int device_index)
     38 {
     39     joystick_hwdata *vjoy = g_VJoys;
     40     while (vjoy) {
     41         if (device_index == 0)
     42             break;
     43         --device_index;
     44         vjoy = vjoy->next;
     45     }
     46     return vjoy;
     47 }
     48 
     49 
     50 static void
     51 VIRTUAL_FreeHWData(joystick_hwdata *hwdata)
     52 {
     53     joystick_hwdata * cur = g_VJoys;
     54     joystick_hwdata * prev = NULL;
     55  
     56     if (!hwdata) {
     57         return;
     58     }
     59     if (hwdata->axes) {
     60         SDL_free((void *)hwdata->axes);
     61         hwdata->axes = NULL;
     62     }
     63     if (hwdata->buttons) {
     64         SDL_free((void *)hwdata->buttons);
     65         hwdata->buttons = NULL;
     66     }
     67     if (hwdata->hats) {
     68         SDL_free(hwdata->hats);
     69         hwdata->hats = NULL;
     70     }
     71 
     72     /* Remove hwdata from SDL-global list */
     73     while (cur) {
     74         if (hwdata == cur) {
     75             if (prev) {
     76                 prev->next = cur->next;
     77             } else {
     78                 g_VJoys = cur->next;
     79             }
     80             break;
     81         }
     82         prev = cur;
     83         cur = cur->next;
     84     }
     85 
     86     SDL_free(hwdata);
     87 }
     88 
     89 
     90 int
     91 SDL_JoystickAttachVirtualInner(SDL_JoystickType type,
     92                                int naxes,
     93                                int nbuttons,
     94                                int nhats)
     95 {
     96     joystick_hwdata *hwdata = NULL;
     97     int device_index = -1;
     98 
     99     hwdata = SDL_calloc(1, sizeof(joystick_hwdata));
    100     if (!hwdata) {
    101         VIRTUAL_FreeHWData(hwdata);
    102         return SDL_OutOfMemory();
    103     }
    104 
    105     hwdata->naxes = naxes;
    106     hwdata->nbuttons = nbuttons;
    107     hwdata->nhats = nhats;
    108     hwdata->name = "Virtual Joystick";
    109 
    110     /* Note that this is a Virtual device and what subtype it is */
    111     hwdata->guid.data[14] = 'v';
    112     hwdata->guid.data[15] = (Uint8)type;
    113 
    114     /* Allocate fields for different control-types */
    115     if (naxes > 0) {
    116         hwdata->axes = SDL_calloc(naxes, sizeof(Sint16));
    117         if (!hwdata->axes) {
    118             VIRTUAL_FreeHWData(hwdata);
    119             return SDL_OutOfMemory();
    120         }
    121     }
    122     if (nbuttons > 0) {
    123         hwdata->buttons = SDL_calloc(nbuttons, sizeof(Uint8));
    124         if (!hwdata->buttons) {
    125             VIRTUAL_FreeHWData(hwdata);
    126             return SDL_OutOfMemory();
    127         }
    128     }
    129     if (nhats > 0) {
    130         hwdata->hats = SDL_calloc(nhats, sizeof(Uint8));
    131         if (!hwdata->hats) {
    132             VIRTUAL_FreeHWData(hwdata);
    133             return SDL_OutOfMemory();
    134         }
    135     }
    136 
    137     /* Allocate an instance ID for this device */
    138     hwdata->instance_id = SDL_GetNextJoystickInstanceID();
    139 
    140     /* Add virtual joystick to SDL-global lists */
    141     hwdata->next = g_VJoys;
    142     g_VJoys = hwdata;
    143     SDL_PrivateJoystickAdded(hwdata->instance_id);
    144 
    145     /* Return the new virtual-device's index */
    146     device_index = SDL_JoystickGetDeviceIndexFromInstanceID(hwdata->instance_id);
    147     return device_index;
    148 }
    149 
    150 
    151 int
    152 SDL_JoystickDetachVirtualInner(int device_index)
    153 {
    154     SDL_JoystickID instance_id;
    155     joystick_hwdata *hwdata = VIRTUAL_HWDataForIndex(device_index);
    156     if (!hwdata) {
    157         return SDL_SetError("Virtual joystick data not found");
    158     }
    159     instance_id = hwdata->instance_id;
    160     VIRTUAL_FreeHWData(hwdata);
    161     SDL_PrivateJoystickRemoved(instance_id);
    162     return 0;
    163 }
    164 
    165 
    166 int
    167 SDL_JoystickSetVirtualAxisInner(SDL_Joystick * joystick, int axis, Sint16 value)
    168 {
    169     joystick_hwdata *hwdata;
    170 
    171     SDL_LockJoysticks();
    172 
    173     if (!joystick || !joystick->hwdata) {
    174         SDL_UnlockJoysticks();
    175         return SDL_SetError("Invalid joystick");
    176     }
    177 
    178     hwdata = (joystick_hwdata *)joystick->hwdata;
    179     if (axis < 0 || axis >= hwdata->nbuttons) {
    180         SDL_UnlockJoysticks();
    181         return SDL_SetError("Invalid axis index");
    182     }
    183 
    184     hwdata->axes[axis] = value;
    185 
    186     SDL_UnlockJoysticks();
    187     return 0;
    188 }
    189 
    190 
    191 int
    192 SDL_JoystickSetVirtualButtonInner(SDL_Joystick * joystick, int button, Uint8 value)
    193 {
    194     joystick_hwdata *hwdata;
    195 
    196     SDL_LockJoysticks();
    197 
    198     if (!joystick || !joystick->hwdata) {
    199         SDL_UnlockJoysticks();
    200         return SDL_SetError("Invalid joystick");
    201     }
    202 
    203     hwdata = (joystick_hwdata *)joystick->hwdata;
    204     if (button < 0 || button >= hwdata->nbuttons) {
    205         SDL_UnlockJoysticks();
    206         return SDL_SetError("Invalid button index");
    207     }
    208 
    209     hwdata->buttons[button] = value;
    210 
    211     SDL_UnlockJoysticks();
    212     return 0;
    213 }
    214 
    215 
    216 int
    217 SDL_JoystickSetVirtualHatInner(SDL_Joystick * joystick, int hat, Uint8 value)
    218 {
    219     joystick_hwdata *hwdata;
    220 
    221     SDL_LockJoysticks();
    222 
    223     if (!joystick || !joystick->hwdata) {
    224         SDL_UnlockJoysticks();
    225         return SDL_SetError("Invalid joystick");
    226     }
    227 
    228     hwdata = (joystick_hwdata *)joystick->hwdata;
    229     if (hat < 0 || hat >= hwdata->nbuttons) {
    230         SDL_UnlockJoysticks();
    231         return SDL_SetError("Invalid hat index");
    232     }
    233 
    234     hwdata->hats[hat] = value;
    235 
    236     SDL_UnlockJoysticks();
    237     return 0;
    238 }
    239 
    240 
    241 static int
    242 VIRTUAL_JoystickInit(void)
    243 {
    244     return 0;
    245 }
    246 
    247 
    248 static int
    249 VIRTUAL_JoystickGetCount(void)
    250 {
    251     int count = 0;
    252     joystick_hwdata *cur = g_VJoys;
    253     while (cur) {
    254         ++count;
    255         cur = cur->next;
    256     }
    257     return count;
    258 }
    259 
    260 
    261 static void
    262 VIRTUAL_JoystickDetect(void)
    263 {
    264 }
    265 
    266 
    267 static const char *
    268 VIRTUAL_JoystickGetDeviceName(int device_index)
    269 {
    270     joystick_hwdata *hwdata = VIRTUAL_HWDataForIndex(device_index);
    271     if (!hwdata) {
    272         return NULL;
    273     }
    274     return hwdata->name ? hwdata->name : "";
    275 }
    276 
    277 
    278 static int
    279 VIRTUAL_JoystickGetDevicePlayerIndex(int device_index)
    280 {
    281     return -1;
    282 }
    283 
    284 
    285 static void
    286 VIRTUAL_JoystickSetDevicePlayerIndex(int device_index, int player_index)
    287 {
    288 }
    289 
    290 
    291 static SDL_JoystickGUID
    292 VIRTUAL_JoystickGetDeviceGUID(int device_index)
    293 {
    294     joystick_hwdata *hwdata = VIRTUAL_HWDataForIndex(device_index);
    295     if (!hwdata) {
    296         SDL_JoystickGUID guid;
    297         SDL_zero(guid);
    298         return guid;
    299     }
    300     return hwdata->guid;
    301 }
    302 
    303 
    304 static SDL_JoystickID
    305 VIRTUAL_JoystickGetDeviceInstanceID(int device_index)
    306 {
    307     joystick_hwdata *hwdata = VIRTUAL_HWDataForIndex(device_index);
    308     if (!hwdata) {
    309         return -1;
    310     }
    311     return hwdata->instance_id;
    312 }
    313 
    314 
    315 static int
    316 VIRTUAL_JoystickOpen(SDL_Joystick * joystick, int device_index)
    317 {
    318     joystick_hwdata *hwdata = VIRTUAL_HWDataForIndex(device_index);
    319     if (!hwdata) {
    320         return SDL_SetError("No such device");
    321     }
    322     if (hwdata->opened) {
    323         return SDL_SetError("Joystick already opened");
    324     }
    325     joystick->instance_id = hwdata->instance_id;
    326     joystick->hwdata = hwdata;
    327     joystick->naxes = hwdata->naxes;
    328     joystick->nbuttons = hwdata->nbuttons;
    329     joystick->nhats = hwdata->nhats;
    330     hwdata->opened = SDL_TRUE;
    331     return 0;
    332 }
    333 
    334 
    335 static int
    336 VIRTUAL_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
    337 {
    338     return SDL_Unsupported();
    339 }
    340 
    341 static int
    342 VIRTUAL_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left_rumble, Uint16 right_rumble)
    343 {
    344     return SDL_Unsupported();
    345 }
    346 
    347 
    348 static SDL_bool
    349 VIRTUAL_JoystickHasLED(SDL_Joystick * joystick)
    350 {
    351     return SDL_FALSE;
    352 }
    353 
    354 
    355 static int
    356 VIRTUAL_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue)
    357 {
    358     return SDL_Unsupported();
    359 }
    360 
    361 static int
    362 VIRTUAL_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
    363 {
    364     return SDL_Unsupported();
    365 }
    366 
    367 
    368 static void
    369 VIRTUAL_JoystickUpdate(SDL_Joystick * joystick)
    370 {
    371     joystick_hwdata *hwdata;
    372     int i;
    373 
    374     if (!joystick) {
    375         return;
    376     }
    377     if (!joystick->hwdata) {
    378         return;
    379     }
    380 
    381     hwdata = (joystick_hwdata *)joystick->hwdata;
    382 
    383     for (i = 0; i < hwdata->naxes; ++i) {
    384         SDL_PrivateJoystickAxis(joystick, i, hwdata->axes[i]);
    385     }
    386     for (i = 0; i < hwdata->nbuttons; ++i) {
    387         SDL_PrivateJoystickButton(joystick, i, hwdata->buttons[i]);
    388     }
    389     for (i = 0; i < hwdata->nhats; ++i) {
    390         SDL_PrivateJoystickHat(joystick, i, hwdata->hats[i]);
    391     }
    392 }
    393 
    394 
    395 static void
    396 VIRTUAL_JoystickClose(SDL_Joystick * joystick)
    397 {
    398     joystick_hwdata *hwdata;
    399 
    400     if (!joystick) {
    401         return;
    402     }
    403     if (!joystick->hwdata) {
    404         return;
    405     }
    406 
    407     hwdata = (joystick_hwdata *)joystick->hwdata;
    408     hwdata->opened = SDL_FALSE;
    409 }
    410 
    411 
    412 static void
    413 VIRTUAL_JoystickQuit(void)
    414 {
    415     while (g_VJoys) {
    416         VIRTUAL_FreeHWData(g_VJoys);
    417     }
    418 }
    419 
    420 static SDL_bool
    421 VIRTUAL_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
    422 {
    423     return SDL_FALSE;
    424 }
    425 
    426 SDL_JoystickDriver SDL_VIRTUAL_JoystickDriver =
    427 {
    428     VIRTUAL_JoystickInit,
    429     VIRTUAL_JoystickGetCount,
    430     VIRTUAL_JoystickDetect,
    431     VIRTUAL_JoystickGetDeviceName,
    432     VIRTUAL_JoystickGetDevicePlayerIndex,
    433     VIRTUAL_JoystickSetDevicePlayerIndex,
    434     VIRTUAL_JoystickGetDeviceGUID,
    435     VIRTUAL_JoystickGetDeviceInstanceID,
    436     VIRTUAL_JoystickOpen,
    437     VIRTUAL_JoystickRumble,
    438     VIRTUAL_JoystickRumbleTriggers,
    439     VIRTUAL_JoystickHasLED,
    440     VIRTUAL_JoystickSetLED,
    441     VIRTUAL_JoystickSetSensorsEnabled,
    442     VIRTUAL_JoystickUpdate,
    443     VIRTUAL_JoystickClose,
    444     VIRTUAL_JoystickQuit,
    445     VIRTUAL_JoystickGetGamepadMapping
    446 };
    447 
    448 #endif /* SDL_JOYSTICK_VIRTUAL || SDL_JOYSTICK_DISABLED */
    449 
    450 /* vi: set ts=4 sw=4 expandtab: */