SDL/src
Sam Lantinga 2be75c6a61 Fixed bug 5028 - Virtual Joysticks (new joystick backend)
David Ludwig

I have created a new driver for SDL's Joystick and Game-Controller subsystem: a Virtual driver.  This driver allows one to create a software-based joystick, which to SDL applications will look and react like a real joystick, but whose state can be set programmatically.  A primary use case for this is to help enable developers to add touch-screen joysticks to their apps.

The driver comes with a set of new, public APIs, with functions to attach and detach joysticks, set virtual-joystick state, and to determine if a joystick is a virtual-one.

Use of virtual joysticks goes as such:

1. Attach one or more virtual joysticks by calling SDL_JoystickAttachVirtual.  If successful, this returns the virtual-device's joystick-index.
2. Open the virtual joysticks (using indicies returned by SDL_JoystickAttachVirtual).
3. Call any of the SDL_JoystickSetVirtual* functions when joystick-state changes.  Please note that virtual-joystick state will only get applied on the next call to SDL_JoystickUpdate, or when pumping or polling for SDL events (via SDL_PumpEvents or SDL_PollEvent).


Here is a listing of the new, public APIs, at present and subject to change:

------------------------------------------------------------

/**
 * Attaches a new virtual joystick.
 * Returns the joystick's device index, or -1 if an error occurred.
 */
extern DECLSPEC int SDLCALL SDL_JoystickAttachVirtual(SDL_JoystickType type, int naxes, int nballs, int nbuttons, int nhats);

/**
 * Detaches a virtual joystick
 * Returns 0 on success, or -1 if an error occurred.
 */
extern DECLSPEC int SDLCALL SDL_JoystickDetachVirtual(int device_index);

/**
 * Indicates whether or not a virtual-joystick is at a given device index.
 */
extern DECLSPEC SDL_bool SDLCALL SDL_JoystickIsVirtual(int device_index);

/**
 * Set values on an opened, virtual-joystick's controls.
 * Returns 0 on success, -1 on error.
 */
extern DECLSPEC int SDLCALL SDL_JoystickSetVirtualAxis(SDL_Joystick * joystick, int axis, Sint16 value);
extern DECLSPEC int SDLCALL SDL_JoystickSetVirtualBall(SDL_Joystick * joystick, int ball, Sint16 xrel, Sint16 yrel);
extern DECLSPEC int SDLCALL SDL_JoystickSetVirtualButton(SDL_Joystick * joystick, int button, Uint8 value);
extern DECLSPEC int SDLCALL SDL_JoystickSetVirtualHat(SDL_Joystick * joystick, int hat, Uint8 value);

------------------------------------------------------------

Miscellaneous notes on the initial patch, which are also subject to change:

1. no test code is present in SDL, yet.  This should, perhaps, change.  Initial development was done with an ImGui-based app, which potentially is too thick for use in SDL-official.  If tests are to be added, what kind of tests?  Automated?  Graphical?

2. virtual game controllers can be created by calling SDL_JoystickAttachVirtual with a joystick-type of SDL_JOYSTICK_TYPE_GAME_CONTROLLER, with naxes (num axes) set to SDL_CONTROLLER_AXIS_MAX, and with nbuttons (num buttons) set to SDL_CONTROLLER_BUTTON_MAX.  When updating their state, values of type SDL_GameControllerAxis or SDL_GameControllerButton can be casted to an int and used for the control-index (in calls to SDL_JoystickSetVirtual* functions).

3. virtual joysticks' guids are mostly all-zeros with the exception of the last two bytes, the first of which is a 'v', to indicate that the guid is a virtual one, and the second of which is a SDL_JoystickType that has been converted into a Uint8.

4. virtual joysticks are ONLY turned into virtual game-controllers if and when their joystick-type is set to SDL_JOYSTICK_TYPE_GAMECONTROLLER.  This is controlled by having SDL's default list of game-controllers have a single entry for a virtual game controller (of guid, "00000000000000000000000000007601", which is subject to the guid-encoding described above).

5. regarding having to call SDL_JoystickUpdate, either directly or indirectly via SDL_PumpEvents or SDL_PollEvents, before new virtual-joystick state becomes active (as specified via SDL_JoystickSetVirtual* function-calls), this was done to match behavior found in SDL's other joystick drivers, almost all of which will only update SDL-state during SDL_JoystickUpdate.

6. the initial patch is based off of SDL 2.0.12

7. the virtual joystick subsystem is disabled by default.  It should be possible to enable it by building with SDL_JOYSTICK_VIRTUAL=1



Questions, comments, suggestions, or bug reports very welcome!
2020-03-13 19:08:45 -07:00
..
atomic Add basic support for compiling on RISC OS 2020-02-13 20:50:47 +00:00
audio winrt: Wait for EnumerationCompleted before leaving WASAPI_EnumerateEndpoints 2020-03-03 12:31:41 -05:00
core Resolved conflict and added Android_JNI_RequestPermission() 2020-02-13 10:19:05 -08:00
cpuinfo Improved CPU detection on ARM platforms 2020-02-04 16:46:22 +00:00
dynapi Fixed bug 5028 - Virtual Joysticks (new joystick backend) 2020-03-13 19:08:45 -07:00
events Fixed warnings building with mingw64 2020-03-08 21:24:06 -07:00
file Fixed compile warning 2020-02-10 13:59:05 -08:00
filesystem Updated copyright date for 2020 2020-01-16 20:49:25 -08:00
haptic Updated copyright date for 2020 2020-01-16 20:49:25 -08:00
hidapi Fixed exception at shutdown if the controllers are closed after the HIDDeviceManager is shutdown 2020-03-13 13:05:32 -07:00
joystick Fixed bug 5028 - Virtual Joysticks (new joystick backend) 2020-03-13 19:08:45 -07:00
libm Fixed compiler warning 2020-01-29 20:09:16 -08:00
loadso Updated copyright date for 2020 2020-01-16 20:49:25 -08:00
main Backed out changeset 51622f74dc85 2020-03-10 18:35:31 -07:00
power Updated copyright date for 2020 2020-01-16 20:49:25 -08:00
render Fixed bug 4991 - Pixel shader problem when recreating a texture for direct3d renderer 2020-03-08 19:23:21 -07:00
sensor Updated copyright date for 2020 2020-01-16 20:49:25 -08:00
stdlib Fixed bug 5022 - SDL_iconv_string can get stuck in an infinite loop when encountering invalid characters 2020-03-10 16:29:28 -07:00
test test: Reimplemented SDLTest_CommonUsage() to restore binary compatibility. 2020-02-12 13:09:38 -05:00
thread Fixed bug 4992 - UWP/WinRT does not set thread priority when using SDL_SetThreadPriority 2020-03-01 12:50:42 -08:00
timer Updated copyright date for 2020 2020-01-16 20:49:25 -08:00
video Fixed regression in bug 4966 - KMSDRM: Add dynamic modeset support 2020-03-07 08:48:04 -08:00
SDL.c Updated copyright date for 2020 2020-01-16 20:49:25 -08:00
SDL_assert.c Updated copyright date for 2020 2020-01-16 20:49:25 -08:00
SDL_assert_c.h Updated copyright date for 2020 2020-01-16 20:49:25 -08:00
SDL_dataqueue.c Updated copyright date for 2020 2020-01-16 20:49:25 -08:00
SDL_dataqueue.h Updated copyright date for 2020 2020-01-16 20:49:25 -08:00
SDL_error.c Updated copyright date for 2020 2020-01-16 20:49:25 -08:00
SDL_error_c.h Updated copyright date for 2020 2020-01-16 20:49:25 -08:00
SDL_hints.c Updated copyright date for 2020 2020-01-16 20:49:25 -08:00
SDL_hints_c.h Updated copyright date for 2020 2020-01-16 20:49:25 -08:00
SDL_internal.h SDL_LEAN_AND_MEAN defaults off 2020-01-23 01:03:23 -08:00
SDL_log.c Updated copyright date for 2020 2020-01-16 20:49:25 -08:00