We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 5028 - Virtual Joysticks (new joystick backend)
Summary: Virtual Joysticks (new joystick backend)
Status: RESOLVED FIXED
Alias: None
Product: SDL
Classification: Unclassified
Component: joystick (show other bugs)
Version: HG 2.0
Hardware: All All
: P2 normal
Assignee: Sam Lantinga
QA Contact: Sam Lantinga
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-03-13 18:53 UTC by David Ludwig
Modified: 2020-04-13 23:09 UTC (History)
1 user (show)

See Also:


Attachments
patch #1, based against SDL 2.0.12 (26.35 KB, patch)
2020-03-13 18:53 UTC, David Ludwig
Details | Diff
patch for the build error in SDL_sysjoystick.c (633 bytes, patch)
2020-03-14 20:01 UTC, Malte Kießling
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description David Ludwig 2020-03-13 18:53:15 UTC
Created attachment 4254 [details]
patch #1, based against SDL 2.0.12

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!
Comment 1 David Ludwig 2020-03-13 19:05:16 UTC
To note, I am currently hosting my own development of this at https://osdn.net/projects/sdl-dll/scm/hg/sdl-dll/commits?branch=virtual-joysticks
Comment 2 David Ludwig 2020-03-13 19:16:43 UTC
My hg repo on osdn.net is, as of this writing, having some issues when pushing, so it is a few commits behind.  The patch attached to this bugzilla case is, however, up to date.
Comment 3 David Ludwig 2020-03-13 19:30:00 UTC
Ok, my repo's back up, and the latest changes are now there.
Comment 4 Sam Lantinga 2020-03-14 02:11:06 UTC
Patch added!
https://hg.libsdl.org/SDL/rev/958bd91f4f4c

A few things to do off the top of my head:
* Add autotools build support
* Add the new files to the Windows and Mac projects
* Remove ball support (really, nobody uses this)
Comment 5 Malte Kießling 2020-03-14 20:01:35 UTC
Created attachment 4255 [details]
patch for the build error in SDL_sysjoystick.c

I get a build error in SDL_sysjoystick.c:74 for the merged patch, but its nothing to sweat about, just -Werror=declaration-after-statement doing its usual stuff. 


Have a nice weekend folks :) And don't overstock on toilet paper, it tastes horrible!
Comment 6 Sam Lantinga 2020-03-15 00:45:33 UTC
Patch added, thanks!
https://hg.libsdl.org/SDL/rev/d195863f8226

We're running low though, and the local stores are all out...
Comment 7 David Ludwig 2020-03-15 17:39:17 UTC
I removed ball support, and will try to work on additional build system support, within the next few days.

Good luck wherever y'all are at.  It does look like Amazon, at least, still has toilet paper in stock, though I've yet to try it myself (and might be, soon enough!)
Comment 8 David Ludwig 2020-03-15 17:42:13 UTC
For posterity and convenience, here is a link to the ball-removal change: https://hg.libsdl.org/SDL/rev/4377c59b636e

I also added a bit more documentation to SDL_joystick.h, regarding SDL_JoystickSetVirtual* calls and the need to invoke SDL_JoystickUpdate: https://hg.libsdl.org/SDL/rev/c88387a1e0e2
Comment 9 David Ludwig 2020-03-16 04:29:38 UTC
More commits to this are in SDL hg's default branch:

Xcode build support was added via https://hg.libsdl.org/SDL/rev/a9723f168294

Windows+MSVC support was added via two changes: https://hg.libsdl.org/SDL/rev/a0ab6d4ff5e7 and https://hg.libsdl.org/SDL/rev/4ee09b18876b

autotools-build support was added via https://hg.libsdl.org/SDL/rev/49320151ca4d


Please note that virtual joystick support is currently disabled, by default, in all builds.
Comment 10 David Ludwig 2020-04-10 19:35:05 UTC
Ick, I noticed that virtual joysticks are, in fact, enabled-by-default for CMake-made builds.

Should I assume that this ought to be disabled, for now?
Comment 11 Sam Lantinga 2020-04-13 15:19:40 UTC
(In reply to David Ludwig from comment #10)
> Ick, I noticed that virtual joysticks are, in fact, enabled-by-default for
> CMake-made builds.
> 
> Should I assume that this ought to be disabled, for now?

I went ahead and enabled it by default for autoconf builds as well:
https://hg.libsdl.org/SDL/rev/5ccab1c0bdd9

... and for all the other builds too:
https://hg.libsdl.org/SDL/rev/e4fe9547334c

With this, I'm going to mark this bug complete. Feel free to open new ones if you want to add functionality or find other bugs.
Comment 12 David Ludwig 2020-04-13 23:09:08 UTC
That’s great news.  Thanks!