Any thoughts on a "JoyDB"-style site?
#1
In looking to the input options, I was wondering:

Has anyone ever looked into building something like TheMovieDB or TheTVDB, but for controllers?

The idea would be relatively straightforward:

- Keep a database of vendor/product IDs
- Keep a list of how its buttons are mapped and named (button names, button colors, etc.)
- Keep a list of which analog sliders control which buttons/triggers/sticks, etc.

The idea would be that an application could submit a newly connected controller's Vendor/Device IDs and pull down a button map it could use for configuration. So if you have a Playstation adapter sent back, you know which numbers are triangle/square/circle/X, and know the different between the Xbox 360's AXBY arrangement on a Wii U Pro controller's.

Extending the concept would make it possible to do stuff like:

- Knowing whether a controller has any of the common button arrangements, which would tell you that it has availability for a 4-, 6-, or even 8-button face buttons arrangement, or 4 shoulder buttons, etc., and being able to take advantage of that information to map things properly.
- Storing basic shape information (from as simple as "hand controller with two prongs" or even to-scale SVG diagrams of the controller) so that the configuration screen can show you precisely what buttons you're changing

It's just a thought.
Reply
#2
I'm basically building exactly this. Currently I store:

- Controller provider (API the controller is discovered on, e.g. "xinput", "directinput", "sdl", etc; possibly extended by user-defined values)
- Controller name (as identified by the driver)
- Vendor/product ID (not always available)
- List of how buttons and axes (including analog sliders) map to a 360 controller

Can you help figure out what else we need to store? I would like button names and colors, because maybe someday we'll be able to use these in the GUI. Controller images / diagrams might be difficult, but we could at least include some standard ones.

For shape information, I was thinking of an auxiliary database of how a 360 controller maps to each system's controllers. That way, we can map any random controller to any system controller using the 360 controller in the middle. Do you think this is sufficient, or do we need more detailed shape information for each individual controller?
Reply
#3
The dream setup would be something like this:

  1. Button Names - Should have capacity for non-alphanumeric symbols, which can be added as needed.
    • Maybe a language option? Not sure if any controllers change with region though.
    • To scale-SVG picture for the button to go with controller SVG option below
    • Maybe button shapes? (again, not sure how many buttons are non-circular outside of GC's bean buttons or start/select-style buttons, but this could have stuff like convex/concave)
  2. Button Colors
    • Letter/Symbol color
    • Button color (so PSX would have mostly gray as the symbols have colors, Xbox 360 the other way around)
  3. Button/Stick Arrangements
    • This one's a two-parter. First, a list of arrangements, and then whether the controller HAS these arrangements. So 2-, (NES/Master System), 4- (SNES/Playstation), 6-(Genesis Arcade, Saturn), and 8-(Most arcade sticks), 2/3/4 shoulder buttons (SNES/GameCube/Playstation arrangements). Single Stick, dual stick, etc.
    • Then the actual mapping. So we should probably just assume a button order, with something like Tekken notation. e.g. a 4-button is: 1 2 (first row) / 3 4 (second row) and 6-button is 1 2 3 / 4 5 6, and so on.
    • Extra bit - Dance pads? If so, we'd want to store d-pad directions as separate buttons internally.
  4. Controller structure. This would allow the software to dynamically "draw" a controller. Conceivably, this would have 3 levels of fallback:
    • Super-basic shape descriptions (rectangle, two-prong, three-prong, etc.) with pre-determined spots (left, right, middle, shoulders, back) that allow for quickly dropping off the arrangements inside. This would be the "fall back" and would exist for every controller. Extra: Multi-part controllers? (racing wheel paddles and the like)
    • A simple arrangement of squares that "make up" the build. This would allow a closer approximation of what the controller would look like
    • A full SVG of the controller. We would need to lock down the scale, and probably determine the format for buttons/sticks locations. This would effecitvely let us have a controller that looks just like it's supposed to - Legally dubious? (IANAL) a/b would allow us to go without c if it is too questionable.

  5. Stick types. This is where it gets a bit tricky, and there's probably need to be some logic to deal with anything past the console-orinted pair of "thumb stick" or "thumb stick that clicks". If flight sticks are a go, we'd probably get the most common shapes, and have further entries for single-instance arrangements. Not sure how we'd structure this, though, especially for shapes that aren't trivial to make 2-dimensional.
  6. Analog/Pointer types. Similar to 4, but this would cover everything from sticks to analog triggers/pedals.
  7. Pointer types. Anything that has relative or absolute positioning of a pointer, like a mouse, wiimote, PS move controller, or even a tablet.

If we can't always get Vendor/Product IDs, we may want fallbacks and a way to "guess" the type of device.

The basic idea is twofold -

  1. We can handle any incomming controller type, and map it as needed. 360 Xinput can be an "output" of the library, and as long as we know how "4 face buttons" and "4 shoulder buttons" map out (or if one or the other is missing), we can map things accoridingly. Heck, we should technically be able to handle a controller having a "2 shoulder buttons and 6 face buttons " arrangement properly. Or at least, in a way that never changes across software and controllers. So you could plug an N64 controller or a Capcom 6-button playstation controller and know how that each of the main 8 buttons are going to map identically in Skullgirls (for example).
  2. Eventually, games could pull down the data and effectively generate a button diagram for any controller, and even know if the controller being used doesn't have enough buttons/sticks/etc..

This is just me brainstorming, so fee free to tell me if none of this sounds like a good idea. If it looks interesting, I can try to hash out some basic diagrams and data structures. I'm not a programmer, but I probably know enough to write things up properly, even if it's just to get a better idea as to what to keep and what to toss.

BTW, a lot of people (especially on Android) miss this detail: The Xbox 360 controller's shoulder triggers don't have a specific on-pad "button", so you'll probably want to set a certain percentage of "push" on the analog side to count as a button press.
Reply
#4
Looks like you have a programmer's ability to compress a wide range of information into a computable subset, MukiDA. I'd be interested to see how close your data structures match up against my working versions.

Each joystick API we use ATM identifies joysticks by their name. I assume the driver looks up the joystick's VID/PID in a hardcoded database (see xpad.c). If we want VID/PID, we need to use outside API calls (or possibly import xpad.c and do a reverse lookup).

The only other info the driver tells us is the controller's raw button count, hat count and axis count. This leads to the mapping challenge:
- A physical button can be a raw button (digital)
- A physical button can be a raw axis (pressure sensitive in the range [0.0, 1.0], inclusive)
- A physical trigger can be a raw button (digital) or a raw semi-axis (on Xbox controllers, right trigger is axis 3 going positive, left trigger is axis 3 going negative)
- A physical dpad can be a raw hat (trivial), four raw buttons, or two raw axes that can take the tri-state values (-1.0, 0.0, 1.0)
- A physical analog stick is made of up to two raw axes
- An accelerometer is made of up to three raw axes
- How does a slider look? Hopefully like a semi-axis trigger in [0.0, 1.0], because our API doesn't have any single-axis features in [-1.0, 1.0] (though analog sticks can have one axis unmapped)

So here's the raw controller info provided by the driver:

Logical Controller
- Providing API
- Driver name
- VID/PID
- raw button, hat and axis count
- A button map - 1:N relationship to Physical Features for mapping raw elements

For a given physical controller, each provider will identify the raw info differently. Driver name will be different, VID/PID may be unknown, and DirectInput might report 2 buttons and 1 hat while Linux reports 6 buttons and 0 hats. So, each physical controller can have multiple logical representations.

Physical Controller
- VID/PID
- Common name (translatable)
- svg/png icon
- 1:N relationship to Logical Controllers

Button map: Because each logical controller can have different raw button/hat/axis configurations, and I assume the button order can differ between APIs, a different button map is needed for each logical controller. Physical features are identified by their corresponding Xbox 360(ish) feature:

Code:
JOY_ID_BUTTON_A,
JOY_ID_BUTTON_B,
JOY_ID_BUTTON_X,
JOY_ID_BUTTON_Y,
JOY_ID_BUTTON_C,
JOY_ID_BUTTON_Z,
JOY_ID_BUTTON_START,
JOY_ID_BUTTON_SELECT,
JOY_ID_BUTTON_MODE,
JOY_ID_BUTTON_L,
JOY_ID_BUTTON_R,
JOY_ID_TRIGGER_L,
JOY_ID_TRIGGER_R,
JOY_ID_BUTTON_L_STICK,
JOY_ID_BUTTON_R_STICK,
JOY_ID_BUTTON_LEFT,
JOY_ID_BUTTON_RIGHT,
JOY_ID_BUTTON_UP,
JOY_ID_BUTTON_DOWN,
JOY_ID_ANALOG_STICK_L,
JOY_ID_ANALOG_STICK_R,
JOY_ID_ACCELEROMETER,

This allows for 19 digital/analog buttons/triggers, 2 analog sticks and 1 accelerometer (maybe someday a gyro too).

Physical Feature
- Corresponding Xbox 360 ID
- Raw element mapping (one of: raw button, hat direction, semi-axis, up to two axes, up to three axes)
- Button name (possibly translatable)
- Button color
- Symbol color
- SVG/png Icon

Phew. That's my current abstraction.

Shape information? Can you think of how this might be used in the GUI? Dynamic button diagram generation might lie outside the scope of this project, but if you can think of a way for it to be used by a simply python configuration utility...

Stick types? Flight sticks? X-rotation and Y-rotation can simply be mapped to the second analog stick (I think this is how it's done in DirectInput). Triggers/pedals are handled by giving analog buttons a range in [0.0, 1.0].

I'm wary to handle pointer types, because we already have extensive touch handling/gesture recognition.

Face button and trigger configuration - this kind of shape information might be useful in automatically generating mappings for non-360 systems. Or should we just store mappings to multiple systems, in addition to 360?
Reply
#5
Don't forget this would have to be configured on a *per-core* (or per-system) basis. The classic example is the 360 controller mapping NES button A/B to the controller A/B which results in an extremely awkward hand position due to the upward angle.

Instead you would want NES A button to be mapped to the 360 X, and and NES B button mapped to the A button on 360 controller.

Just food for thought, one more wrinkle in the equation.
Reply
#6
Maybe approach an existing open website like TheGamesDB.net to host the database for stuff like so that updates can be scraped online by Kodi and other projects?

http://thegamesdb.net

https://github.com/TheGamesDB/TheGamesDB
Reply
#7
I don't think it needs an entire site of this.

Wouldn't an XML file on guthub would be enough?
Reply
#8
(2015-01-20, 14:43)zag Wrote: Wouldn't an XML file on guthub would be enough?

It is not enough if you want data from casual users too!
Reply
#9
(2015-01-20, 19:10)Namerp Wrote:
(2015-01-20, 14:43)zag Wrote: Wouldn't an XML file on guthub would be enough?

It is not enough if you want data from casual users too!

It would be if retroplayer would submit anonymous data from the user. Would only need USB ID and their layout. If several people use the same layout, it becomes default for new users. When you connect a new gamepad you might be prompted with the message "We do not recognize your gamepad, please configure." And the configure menu has a check box (ticked by default) "Submit as best layout"

The submissions can be moderated (if very few submissions with the same USB ID, and automated for common USB IDs
Reply
#10
Related ideas from the input thread regarding a mapping customizer GUI application http://forum.kodi.tv/showthread.php?tid=211138
(2015-01-20, 14:25)Hedda Wrote: Maybe try to copy the input to output translator code from the "Kade" open source adapter device project?

https://www.kickstarter.com/projects/kad...rs-and-con

It sounds as if this project already have mapped the schemes needed to translate controller input/output.

https://github.com/kadevice/KADE

Also their "KADE Loader" is an open source GUI software for creating or modifying custom mappings.

http://kadevice.com and http://kadevice.com/forum

Image

Image

Image
Reply
#11
(2015-01-19, 06:20)garbear Wrote: The only other info the driver tells us is the controller's raw button count, hat count and axis count. This leads to the mapping challenge:
- A physical button can be a raw button (digital)
- A physical button can be a raw axis (pressure sensitive in the range [0.0, 1.0], inclusive)
- A physical trigger can be a raw button (digital) or a raw semi-axis (on Xbox controllers, right trigger is axis 3 going positive, left trigger is axis 3 going negative)
- A physical dpad can be a raw hat (trivial), four raw buttons, or two raw axes that can take the tri-state values (-1.0, 0.0, 1.0)
- A physical analog stick is made of up to two raw axes
- An accelerometer is made of up to three raw axes
- How does a slider look? Hopefully like a semi-axis trigger in [0.0, 1.0], because our API doesn't have any single-axis features in [-1.0, 1.0] (though analog sticks can have one axis unmapped)

It gets a little tricky, because this setup effectively has 3 levels:

1. The info we get from the driver
2. The way we read that info
3. The final mapping that games will use

What should be done is to abstract all the driver naming quirks away, because any app that uses the API has pre-designated mappings for sticks. (see below)

button_01 -> button_20 (or whatever the limit is for that particular controller)
and
axis_01 -> axis_10 (again, however many it has)

It would be better to store each cardinal direction as an individual axis. This way, *every* axis has a 0.0->1.0 range. Yes, it means twice as many axes for joysticks, but it also means we don't need to do anything special for triggers, and can handle as many sticks or triggers as the controller might have. Heck, drop the hat switch designator and treat every direction as a button. That way you can handle things like dance pads without trouble.

(BTW, ignore Windows' gamepad mapping. It treats L 'n R on a 360 controller as opposite ends of the Z axis, so holding both is the same as holding NEITHER)

So let's go back to the 360 controller example. Each arrangement would be stored as a simple array of the buttons that makes it up, or some designator like "N_A" if it doesn't exist on the physical controller.

So the 360 controller would have an arrangement like this:
(assume a standard windows setup, minus the d-pad, which I've designated buttons 10 through 14)

4_button_arrangement=[button_03,button_04,button_01,button_02]
6_button_arrangement=[n_a]
8_button_arrangement=[n_a]
10_button_arrangement=[n_a]
2_button_shoulder=[button_05,button_06]
3_button_shoulder=[button_05,button_06,axis_09+axis_08]
--- (this would make either shoulder bumper function, say, for a GameCube emulator)
4_button_shoulder=[button_05,button_06,axis_09,axis_10]
left_stick=[axis_01,axis_02,axis_03,axis_04,button_09]
right_stick=[axis_05,axis_06,axis_07,axis_08,button_10]
dpad=[button_11,button_12,button_13,button_14]
(would assume a static order, like up,down,left,right, like the button arrangements have)
start=[button_07]
select=[button_08]
left_trigger=[axis_09]
right_trigger=[axis_10]

Why store the triggers as a separate variable? Because for something like a GameCube remote, it could handle "knowing" that there are fully analog triggers available, along with actual "click" buttons for those triggers.

Conversely, a 6-button fight pad would be similar, only with these differences:

6_button_arrangement=[button_03,button_04,button_01,button_02,button_05,button_06]
2_button_shoulder=[button_05,button_06]
3_button_shoulder=[n_a]
4_button_shoulder=[n_a]
left_trigger=[n_a]
right_trigger=[n_a]

Another added bonus is that it would let you correctly map a 360 arcade stick, which does its own messy re-arrangement of the Xbox buttons. Take a look at these images, and note that those buttons are color-coded correctly; meaning X/Y/B are all in the top row. (yeesh)

For sticks, btw, I forget the term (where you can define a structure or function with more than one argument count), but there should be an option in the joystick mapping to read a 5th entry as a "click" of that joystick, or ignore it if only 4 entries are present.

A bonus would be if axis+range could be mapped individually. It would let you do something like mapping multiple percentages the axes to individual buttons. Not sure how many games that would be handy for, tho. Off the top of my head, you could use it for character games that have a run button to replace it with semi-analog running.

You could even do odd stuff like give the application a "southpaw" variable (for stuff like first/third person shooters), where it internally switches the stick arrangements so that the application doesn't have to change its own internal mappings. This should be a switch rather than a toggle, so an application can just set something like set_southpaw=true when playing, and simply do set_southpaw=false when menus get opened or interactions start.
Reply
#12
(2015-01-21, 19:34)MukiDA Wrote: It would be better to store each cardinal direction as an individual axis. This way, *every* axis has a 0.0->1.0 range. Yes, it means twice as many axes for joysticks, but it also means we don't need to do anything special for triggers, and can handle as many sticks or triggers as the controller might have.

Oops, I missed the ability to map analog sticks to buttons/hat directions. Right now they can only be mapped to axes (although the axes can be inverted). I think the need to emulate an analog stick using buttons is relatively rare, though. I can't think of any cases off the top of my head. I'll probably leave this out to keep the API simpler.

(2015-01-21, 19:34)MukiDA Wrote: Heck, drop the hat switch designator and treat every direction as a button. That way you can handle things like dance pads without trouble.

This is done. Translating dpads to buttons happens at the last possible instance, so low-level interfaces (such as the one the configuration GUI will need) still have access to raw hats from the driver.

(2015-01-21, 19:34)MukiDA Wrote: (BTW, ignore Windows' gamepad mapping. It treats L 'n R on a 360 controller as opposite ends of the Z axis, so holding both is the same as holding NEITHER)

Yea, combining L and R onto a single axis is stupid and limiting but we can't do anything about it, that information is lost by the driver before it gets to us.

(2015-01-21, 19:34)MukiDA Wrote: For sticks, btw, I forget the term (where you can define a structure or function with more than one argument count), but there should be an option in the joystick mapping to read a 5th entry as a "click" of that joystick, or ignore it if only 4 entries are present.
.
It's called overloading. Can you think of a use case for this?

(2015-01-21, 19:34)MukiDA Wrote: A bonus would be if axis+range could be mapped individually. It would let you do something like mapping multiple percentages the axes to individual buttons. Not sure how many games that would be handy for, tho. Off the top of my head, you could use it for character games that have a run button to replace it with semi-analog running.

I think the use cases for this are too small in exchange for the complexity it introduces.

(2015-01-21, 19:34)MukiDA Wrote: You could even do odd stuff like give the application a "southpaw" variable (for stuff like first/third person shooters), where it internally switches the stick arrangements so that the application doesn't have to change its own internal mappings. This should be a switch rather than a toggle, so an application can just set something like set_southpaw=true when playing, and simply do set_southpaw=false when menus get opened or interactions start.

Giving applications access to our internals is something we should avoid. This complicates the API between us and the application, which means more complexity in the application which leads to more maintenance and more bugs. The challenge here is to be thorough but concise.
Reply
#13
Haha I built my custom arcade with an old xbox and a 2 Kade Controllers.

Image
Reply
#14
very nice

all Kade controllers probably use the same VID/PID for their usb driver. this might make it difficult to differentiate between different hardware configurations for automatic configuration. This could be solved by a custom driver for Kodi (which the new Peripheral API enables), or maybe just disable auto-configuring Kade controllers as manual configuration is a breeze with the WIP configuration GUI.
Reply
#15
I vote for doing it like Steam, if you don't opt out you will send anonymous USB ID and layout. But make it clear with a warning when you go into the configuring the controller the first time
Reply

Logout Mark Read Team Forum Stats Members Help
Any thoughts on a "JoyDB"-style site?0