Allegro.cc - Online Community

Allegro.cc Forums » Allegro Development » Controllers configuration

This thread is locked; no one can reply to it. rss feed Print
 1   2 
Controllers configuration
Max Savenkov
Member #4,613
May 2004
avatar

After spending some time trying to think of a way to map "stick 0 axis 2" to something more human-readable, I took a minute to run a Google search, and found out that SDL has this nice database of controllers. Such a database allows to determine if "stick 0" is a d-pad, thumb-controller, or something else.

SDL's database relies on SDL-style GUIDs for joysticks. With Allegro, presently there is no way to get such a GUID, or data from which it could be constructed (Allegro 5 API only returns human-readable name of joystick).

So, what I'm thinking about, shouldn't Allegro borrow this functionality from SDL? At least as far a GUID generation, but preferably also loading of SDL-style controller database files and classification of buttons/sticks by user's request.

Some thoughts on possible API:

int al_get_joystick_guid( ALLEGRO_JOYSTICK *joystick, char *buffer, int length ); // Allow user access to GUIDs; maybe use something like ALLEGRO_JOYSTICK_GUID instead of buffer and length?

int al_load_joystick_mapping( const char *filename ); // To load controller database
int al_register_joystick_mapping( const char *mapping_string ); // To register a new mapping string, without loading it from file

bool al_has_mapping_for_joystick( ALLEGRO_JOYSTICK *joystick ); // To check if Allegro has a registered mapping for specified joystick (in case user want some special handling for this case)

ALLEGRO_JOYSTICK_BUTTON al_get_joystick_button_mapping( ALLEGRO_JOYSTICK *joystick, int button ); // To convert button index into more descriptive constant

ALLEGRO_JOYSTICK_STICK al_get_joystick_stick_mapping( ALLEGRO_JOYSTICK *joystick, int stick ); // To convert stick index into more descriptive constant

// ALLEGRO_JOYSTICK_BUTTON and ALLEGRO_JOYSTICK_STICK could be pretty much copied from SDL:
// https://wiki.libsdl.org/SDL_GameControllerButton
// https://wiki.libsdl.org/SDL_GameControllerAxis

Such API would allow Allegro users to:
a) Define default control schemes for games more intelligently (i.e. "'A' button is Fire vs. '0th' button is Fire). This applies more to sticks/axis than to buttons, since they vary wildly (my Logitech F310 uses 2nd stick for D-pad, for heavens sake!).

b) Display control scheme for user more intelligently in tutorial or control definition menu (i.e. draw a picture of D-pad instead of writing godawful things like "Stick 2 Axis 2 Positive"

The second problem could be solved by displaying results from al_get_joystick_button_name and al_get_joystick_stick/axis_name to user, but this is not a very good solution, since these results are platform-dependent and localized by system, and therefore could require font with Unicode characters support when the game itself does not require one.

The first problem, presently, could not be solved at all, unless you want to create a mapping database that depends on reported controller name (you don't).

If developers think this is a good idea, I guess I can work on borrowing SDL implementation of joystick GUID generation and the rest of functionality. It shouldn't be too hard, and shouldn't touch the rest of library too much.

Or maybe I'm missing some alternative solution? If so, please tell me :) Mapping problem currently stops me from completing nearly-ready game, and I'm itching to do something about it!

Chris Katko
Member #1,881
January 2002
avatar

This looks like a very good idea.

[edit]

I've mentioned in passing that I want to do an Allegro controller addon that rigidly separates controllers from their actions. Programs expose actions, controllers expose controls, and the addon takes care of linking them based on relationships on a configuration file. So basically, you can load (or create) a map for any controller to control anything (users can at their own on any date when new controllers show up!), and the addon is aware of whatever state you're in. This means that controls can map differently when in a menu system, verses in a round/map/etc, or even different states (driving/walking/flying) in a game. Controls are labelled, and you can have "translators" which sit in-between and convert input data (ala keyboard buttons becomes joystick positions or vice-versa. Multiple letters of text from keyboard can become buttons/axis, and more.).

I don't want to de-rail your thread, but I felt it was pretty related.

Mapping problem currently stops me from completing nearly-ready game

Someones finishing an A5 game, for the love of God, people, help this man! ;)

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs
"Political Correctness is fascism disguised as manners" --George Carlin

Max Savenkov
Member #4,613
May 2004
avatar

Hm, there is almost always a system such as you describe in any large game. But it might be a bit too high level for Allegro. Then again, if this is an optional addon, why not?

Someones finishing an A5 game, for the love of God, people, help this man! ;)

It's been in development for more than 3 years already (and could be done in, like, 3 months if I worked full time, probably), and I really wish I could push it out and start working on something else! :)

SiegeLord
Member #7,827
October 2006
avatar

The GUID idea seems reasonable, but the rest not as much (which isn't a problem, since everything builds on the GUID thing). Perhaps the first can go into the core and the rest be an addon?

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

Max Savenkov
Member #4,613
May 2004
avatar

Yes, addon sounds fine.

Chris Katko
Member #1,881
January 2002
avatar

Now I thought DirectX stripped out all ID information, hence requiring RawInput for using things like multiple mice and keyboards.

According to this post (regarding Linux):

Quote:

The GUID is an SDL2 specific ID, there is no direct way to get it with system tool. The GUID is build by squishing the bus, vendor, product and version numbers into a single value, you can see it here:

So my point being, is there an ID we can use to begin with?

[edit]

This post (scroll down) seems to indicate that GUID is "made up" on Linux, but from DirectX on Windows. So if Allegro is going to be cross-platform, these will be things that have to be looked into.

Quote:

In Windows, it looks like the GUID comes directly from directx; SDL doesn't synthesize it.

I also checked the Linux code, and SDL creates a GUID starting with the bus type and then either some string literal that comes from the joystick's path, or it's created with the (16-bit) vendor code, the product code, and the version code each followed by 16 bits of 0. I'm not going to pretend I know how Linux works, so I have no idea what any of this is.

How is input handled in Linux? Is it all from an X server?

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs
"Political Correctness is fascism disguised as manners" --George Carlin

beoran
Member #12,636
March 2011

I worked on joysticks before and the trouble is that we'd need databases with thousands of devices. Some kind of unique id per joystick type is possible (though not on all platforms), and could be a nice addition to the core, but I'm not sure that I like SDL's ideas about the mappings. So I sorta agree with Siegelord here...

Chris Katko
Member #1,881
January 2002
avatar

beoran said:

databases with thousands of devices.

Thousands being the XBox 360 controller and...

I mean does anybody even use other controllers anymore? They're just so... damn perfect. I don't even use my 360, just the controllers! Many Steam/PC games support them, especially games ported from consoles.

As long as users can roll their own, or download maps, that won't be a problem at all (can even have a form of package manager). But this all seems better suited to my controller addon.

Then again, we're adding VOC support which applies to old games using a very specific technology. So I have no idea what criteria fits anymore. ???

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs
"Political Correctness is fascism disguised as manners" --George Carlin

Max Savenkov
Member #4,613
May 2004
avatar

Thousands being the XBox 360 controller and...

My damn Logitech doesn't have the same mapping as a generice XBox-compatible controller :( I learned that the hard way today.

beoran said:

the trouble is that we'd need databases with thousands of devices.

Yes, but what's the alternative? Device itself, unfortunately, does not tell us any information about itself. I mean, OK, such database support might not be a good fit for core Allegro, but as an addon, it looks fine, doesn't it?

I remember old EA games were always lugging around a HUGE file with mappings for different devices. Not sure where they hide it now... Maybe MOST devices only use one mapping (XBox360 or DualShock-compatible)? I got that impression from SDL's database where they have a generic mapping for "XInput gamepad".

Gideon Weems
Member #3,925
October 2003

Interesting info.

The first thing I noticed: There aren't as many items in the database as I expected. As a component of SDL, contributions are more or less limited to SDL users. It would make sense to have a separate repository, upon which SDL, Allegro, and any other library could depend.

If this is going to be an add-on, I hope that's the direction it takes. I would have a few contributions from Japan that aren't in the database, as well. Either way, good luck if you're going to do this. It would be a worthwhile addition (particularly the GUIDs).

const char * al_get_joystick_guid( ALLEGRO_JOYSTICK *joystick ); // <-- Why not this?  Dealing with char buffers is annoying.

beoran
Member #12,636
March 2011

Well I think I am in favor of the al_get_joystick_guid function in core, but keep in mind that on some platforms this will be wholly synthetic.

A database to look up those guids in is definitely for an add-on IMO.

SiegeLord
Member #7,827
October 2006
avatar

I don't mind that the GUID is arbitrary, the point is that it's a GUID. That said, it might be a good idea to future-proof the API by passing a version to the al_get_joystick_guid function, in case we move away from SDL's algorithm (or some cross-framework solution pops up).

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

Thomas Fjellstrom
Member #476
June 2000
avatar

Or we just specify that GUIDs aren't really stable, so don't expect them to stay the same permanently?

How is input handled in Linux? Is it all from an X server?

I think we use Xinput or Xinput2 (for the newer code that supports haptics). I briefly looked at the Xinput2/XI2 protocol spec and I don't see a uuid or a stable id of any kind in it, so I assume it doesn't exist there.

Evdev provides the following info apis on the joystick api:

        /* function      3rd arg  */
  #define JSIOCGAXES  /* get number of axes    char   */
  #define JSIOCGBUTTONS  /* get number of buttons  char   */
  #define JSIOCGVERSION  /* get driver version    int   */
  #define JSIOCGNAME(len) /* get identifier string  char   */
  #define JSIOCSCORR  /* set correction values  &js_corr */
  #define JSIOCGCORR  /* get correction values  &js_corr */

So all you can get there is the axes, buttons, the string identifier (I assume comes directly from the joystick, or if the hw doesn't provide one, the hardware driver provides one...)

So yeah, it doesn't look like theres a uuid at all on linux for input devices. Best you can get it seems is the bus, vendor and device ids.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

pkrcel
Member #14,001
February 2012

Vendor and Device IDs seems to be plenty of info for a GUID database, or am I missing something obvious?

It is unlikely that Google shares your distaste for capitalism. - Derezo
If one had the eternity of time, one would do things later. - Johan Halmén

SiegeLord
Member #7,827
October 2006
avatar

Or we just specify that GUIDs aren't really stable, so don't expect them to stay the same permanently?

It occurs to me that if we could just consider it a part of the API, we could just change it alongside with the minor version... i.e. people will need to check ALLEGRO_VERSION to see what thing to decode.

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

Thomas Fjellstrom
Member #476
June 2000
avatar

In general one doesn't decode GUIDs. They are just unique IDs, sometimes specified to not change.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

SiegeLord
Member #7,827
October 2006
avatar

Perhaps decode is the wrong word... I meant map the GUID to the key mappings mentioned in the first post.

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

Thomas Fjellstrom
Member #476
June 2000
avatar

Maybe its better to just export the vendor and device ids? those wont change.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

beoran
Member #12,636
March 2011

That would be great except that IIRC on Android (or other platforms) you can't even get those reliably... :p

Thomas Fjellstrom
Member #476
June 2000
avatar

Do those platforms have stable ids?

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Max Savenkov
Member #4,613
May 2004
avatar

Why not this? Dealing with char buffers is annoying.
const char * al_get_joystick_guid( ALLEGRO_JOYSTICK *joystick );

Because guid is a binary buffer. If function is defined that way, outside users won't be able to know its length. We might use a special structure, ALLEGRO_JOYSTICK_GUID or something, to avoid forcing user to deal with buffer allocation, or we may change signature to accept ( ALLEGRO_JOYSTICK *joystick, char **buffer, int *length ), so we could return a pointer to cached guid value and its length.

About guids for various platforms:

On most platforms, SDL uses first 16 bytes of controller's name as a guid. Unless we really want to compile our own incompatible controller database, we are forced to follow their lead.

Actually, I'm not sure if using device name for configuration identifier is a bad idea anywhere besides Windows. Sure, Windows likes to return localized strings instead of useful unique names, but does any other platform do that?

Of course, it would be better to use a hash of controller name instead of first 16 bytes, so things like "GameCompany Pad1" and "GameCompany Pad100500" would have different ids! This seems to be a (potentialy, very bad) flaw in SDL implementation, but again - if we want to use their database, we'll have to go with it :( Maybe it would be better to submit a patch to SDL correcting this.

I've searched for other open-source controller databases, but it seems nobody compiled a more comprehensive one than SDL.

Gideon Weems
Member #3,925
October 2003

I completely misinterpreted that. Yes, ID's would be binary.

This seems to be a (potentialy, very bad) flaw in SDL implementation...

It definitely would be... though what's the first column?

6d0419c2000000000000504944564944,Logitech F710 Gamepad
88880803000000000000504944564944,PS3 Controller
4c056802000000000000504944564944,PS3 Controller
25090500000000000000504944564944,PS3 DualShock

I came across a thread you might be interested in.

beoran
Member #12,636
March 2011

Yeah, I also contributed to that thread there. I proposed a controller "database" in XML (or JSON) format. Actualy this would be quite useful but I guess no one has the time/money to go out there and actually compile such a database. The database could have different fields for SDL and Allegro UUID's too, so no need for compatibility...

Something more rudimentary can be found here:

http://devnewton.bci.im/en/gamepad_db

Ah, a longer list is here, stil quite limited:

https://github.com/gabomdq/SDL_GameControllerDB/blob/master/gamecontrollerdb.txt

Max Savenkov
Member #4,613
May 2004
avatar

beoran said:

Actualy this would be quite useful but I guess no one has the time/money to go out there and actually compile such a database.

I think a tool that would allow users to create/report configurations would populate such database quite quickly if included with large number of games, or with few moderately popular ones. But first, someone need to create such tool, set up things server-side to accept submissions and allow someone to check and moderate them.

It definitely would be... though what's the first column?

This examples are all from Windows portion of file, and under Windows SDL uses a part of DirectX device GUID. Actually, all OSes for which SDL database has entries (Linux, Windows, OS X) have "good" guids.

Quote:

I came across a thread you might be interested in

Thank you, I have already encountered it when searching for controller databases.

Chris Katko
Member #1,881
January 2002
avatar

I think a tool that would allow users to create/report configurations would populate such database quite quickly if included with large number of games, or with few moderately popular ones. But first, someone need to create such tool, set up things server-side to accept submissions and allow someone to check and moderate them.

That wouldn't be that hard at all. Just a decent amount of work (a weekend, maybe two). Make a client app that validates the users submissions before allowing them to be sent. They go into an "inbox" SQL table. The server has basic duplication detection, and refuses large volumes of spamming. Moderators can sift through them and the ones they approve get moved over into main SQL table.

The biggest issue I see is the moderator not being able to truly validate the input unless he or she has the device. If we get 5, 10, 15 people sending the same values, that's much more reliable though.

The other issue I see is someone actually setting up a server.

Instead of re-inventing the wheel, it might be easier to ask SDL for permission to use their list and re-implement their hash algorithm. We'll also be contributing back to them by populating their list as we see new ones.

Instead of having an automated solution, we could just ship the gamepad config text file (parsed at run-time) with our games, and tell the user they can download updated versions at the Allegro/SDL mirror and replace the file manually.

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs
"Political Correctness is fascism disguised as manners" --George Carlin

 1   2 


Go to: