SFML community forums

Help => Window => Topic started by: NoobsArePeople2 on January 04, 2014, 04:59:41 am

Title: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: NoobsArePeople2 on January 04, 2014, 04:59:41 am
I've made an update to expose the name, product ID and manufacturer ID for joysticks. This is ticket #152 on Github (https://github.com/SFML/SFML/issues/152). The commit with these changes is on my fork of SFML (https://github.com/NoobsArePeople2/SFML/commit/ddd7ce00b0e0f350528b4a6b124a96a1113f0c37).

I'm a C++ noob so I'd like to get a good code review of this change before doing a pull request. Also, I haven't been able to properly test this on Linux (it compiles in VM but by VM software doesn't allow me to connect USB devices) so I'm not certain it functions properly on that platform. If a pull request is preferrable to this forum post let me know and I can do that.

The Changes

JoystickCaps has been renamed JoystickInfo. In addition to the name change three properties have been added to it:

1. name: the name of the joystick.
2. manufacturerID: the joystick manufacturer's ID.
3. productID: the product ID of the joystick.

sf::Joystick has three new functions that correspond with these values:

1. getName(unsigned int index): return the name of the joystick at index as an sf::String.
2. getManufacturerID(unsigned int index): returns the manufacturer ID at index as an unsigned int.
3. getProductID(unsigned int index): returns the product ID at index as an unsigned int.

Testing

I've been using this update on Mac OS and Windows for awhile and all is well (for me anyway). The Linux implementation compiles but I'm running Ubuntu in a virtual machine and am unable to connect USB devices to it so I cannot put it to the test.

Platforms

On the Mac side of things I'm running 10.7 Lion with Xcode 4.6. I'm compiling with C++11 support using Clang.

On Windows I'm running Windows 8 x64 with Mingw 4.6.2.

On Ubuntu I'm running 13.10 x64 with GCC 4.8.x.

Controllers

I've tested with the following controllers (drivers listed in instances were the manufacturer does not provide one for the platform):

- Xbox 360, wired (Windows, Mac via Tattiebogle v0.08 Driver (http://tattiebogle.net/index.php/ProjectRoot/Xbox360Controller/OsxDriver))
- Xbox 360, wireless (Windows)
- PS3 (Windows via Motioninjoy v0.7 Driver (http://www.motioninjoy.com/), Mac)
- Wiimote, no attachments, with nunchuck, with classic controller (Mac via WJoy v0.7.1 Driver (https://code.google.com/p/wjoy/))



I feel good about the Mac and Windows implementations. Can someone please give the Linux version a try and let me know how/if it works?
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: Foaly on January 13, 2014, 12:21:57 am
This looks good! Sadly I don't have a joystick here to test it.
Maybe you should also leave a note about your fork on the github tracker, so this doesn't get lost in the forum.
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: NoobsArePeople2 on January 13, 2014, 04:59:52 am
This looks good!
:)
Sadly I don't have a joystick here to test it.
:(

I've posted to the #152 ticket on Github with a note about this thread.

As an aside, are you running Linux? In a dual-boot setup with Windows perhaps? I'd like to get something like that setup so I can properly test Linux stuff but all the guides I've read make me a bit worried that I might hose my Windows install.

Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: Fizix on January 13, 2014, 09:16:50 am
As an aside, are you running Linux? In a dual-boot setup with Windows perhaps? I'd like to get something like that setup so I can properly test Linux stuff but all the guides I've read make me a bit worried that I might hose my Windows install.

Try the Ubuntu windows installer.  You can dual boot without having to change partitions.  And you can even uninstall it if you don't like it.

http://www.ubuntu.com/download/desktop/install-ubuntu-with-windows (http://www.ubuntu.com/download/desktop/install-ubuntu-with-windows)
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: Mario on January 13, 2014, 10:48:35 am
If you've got a not too old CPU with virtualization instructions, I'd just use virtualization to boot a Unix installation while you're in Windows (Core 2 Quad is more than enough, although an i-7 will get you almost native speeds).

I'm using Linux Mint inside Virtual Box and it runs flawlessly. No need to worry about dual booting. Although I've used Wubi in the past, I think it might cause problems with newer systems and secure boot. Other than that, it's pretty safe to use, just like any Windows program. Just make sure to stay away from partitioning tools and things such as Grub while under Unix.

Back to the patch:

While I haven't tried it, just out of interest: Do you even have to go through the registry to get the name under Windows? The JOYCAPS structure (http://msdn.microsoft.com/en-us/library/windows/desktop/dd757103(v=vs.85).aspx) already got a name field. Although I'm not sure how accurate this is or if it's still populated.

Also not sure about the UNICODE macro magic, since all versions of Windows being supported got the full wide char set implemented (so just use that).

Plus I think it shouldn't return "Unknown Joystick" if a device isn't present/connected at all.
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: NoobsArePeople2 on January 13, 2014, 06:26:26 pm
If you've got a not too old CPU with virtualization instructions, I'd just use virtualization to boot a Unix installation while you're in Windows (Core 2 Quad is more than enough, although an i-7 will get you almost native speeds).

I'm using Linux Mint inside Virtual Box and it runs flawlessly. No need to worry about dual booting. Although I've used Wubi in the past, I think it might cause problems with newer systems and secure boot. Other than that, it's pretty safe to use, just like any Windows program. Just make sure to stay away from partitioning tools and things such as Grub while under Unix.

I'll give VirtualBox a try. I've been using Hyper-V as it ships with Win8 Pro but it lacks USB support. I'm running an i7 so it sounds like VB should run great.

Quote
While I haven't tried it, just out of interest: Do you even have to go through the registry to get the name under Windows? The JOYCAPS structure (http://msdn.microsoft.com/en-us/library/windows/desktop/dd757103(v=vs.85).aspx) already got a name field. Although I'm not sure how accurate this is or if it's still populated.

Unfortunately you do. I don't remember the exact value JOYCAPS gives but it's something like "USB Joystick" for every device I tried.

Quote
Also not sure about the UNICODE macro magic, since all versions of Windows being supported got the full wide char set implemented (so just use that).

I can switch it but it looked to me like SFML is setting a similar macro via CMake to force Windows to Unicode mode so I was trying to go with the flow there and no require Unicode functions.

Quote
Plus I think it shouldn't return "Unknown Joystick" if a device isn't present/connected at all.

It should only return "Unknown Joystick" if the joystick is connected but we fail to read the name value for some reason. My thought here is that we should return some known value and allow the joystick to function even if we can't suss out the name. Maybe there's a better way to handle this case?
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: NoobsArePeople2 on January 13, 2014, 06:28:38 pm
Quote
Try the Ubuntu windows installer.  You can dual boot without having to change partitions.  And you can even uninstall it if you don't like it.

http://www.ubuntu.com/download/desktop/install-ubuntu-with-windows (http://www.ubuntu.com/download/desktop/install-ubuntu-with-windows)

That looks awesome! I think I'm going to try VirtualBox first, it being the path of least resistance and all but I do want to get a non-virtualized version of Linux up and running at some point.

Any experience using this with Windows 8 (Win8 seems to frustrate dual-boot setups)?
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: Foaly on January 15, 2014, 01:04:21 am
To answer the question: I also use a virtual machine (VirtualBox) and Ubuntu. The host machine is a win 8. And I didn't run into any problems yet.
@Mario: Parsing the registry seems to be the only option. Laurent said that here (http://en.sfml-dev.org/forums/index.php?topic=13628.msg95326#msg95326).
I also agree that "Unknown Joystick" might be a bit confusing, but that again one should check beforehand with sf::Joystick::isConnected if the Joystick is even connected.
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: NoobsArePeople2 on January 16, 2014, 07:35:25 am
To answer the question: I also use a virtual machine (VirtualBox) and Ubuntu. The host machine is a win 8. And I didn't run into any problems yet.

Lucky you ;) I installed VB and it promptly disabled my ethernet adapter so no internet. "Okay", I thought, I'll just restart. That should fix it! Then Win8 sat at the boot screen for 30 minutes. So I cut the power by holding down the power button...which can apparently cause issue with my SSD such that the system cannot recognize it until you power cycle the SSD which takes an hour. Anyway, there was lots of swearing and I ended up getting myself a nice beer but I did eventually get it to work!

I've made some comments on Github but I'll recap here. On Ubuntu 13.10:

I'm able to get the joystick name no problem ("Microsoft X-Box 360 pad" in this case).
I'm not able to get the vendor or product IDs. It's probably something simple but I'm not seeing it.

Quote
I also agree that "Unknown Joystick" might be a bit confusing, but that again one should check beforehand with sf::Joystick::isConnected if the Joystick is even connected.

So there's two ways this gets set:

1. It's the default value for a new JoystickInfo struct.
2. A joystick gets connected, SFML tries to read the value but errors out for some reason. In this case SFML sets the name to "Unknown Joystick".

After having debugged an issue on Linux that was not obvious because JoystickInfo.name defaulted to "Unknown Joystick" I'm in 100% agreement that this is confusing (was about 96% before ;) ). In the second case I think SFML should set some known, default value that can be interpreted as "I tried and failed".

I've changed the first case to an empty string ("") and left the latter alone.
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: NoobsArePeople2 on January 16, 2014, 07:42:52 am
Also not sure about the UNICODE macro magic, since all versions of Windows being supported got the full wide char set implemented (so just use that).

So I tried removing the _UNICODE macro and explicitly using all the wide char set versions of the functions for reading the registry (e.g., RegQueryValueExW instead of RegQueryValueEx). These work fine except that the registry key REGSTR_VAL_JOYOEMNAME is not wchar_t but rather char_t so I get an error.

Maybe the problem is that I'm using Mingw? It looks to me like Cmake is setting a UNICODE macro when building SFML on Windows but the Mingw headers are using a _UNICODE macro. Does that sound plausible? If that's the case what's the best way to go about handling this situation?
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: Foaly on January 17, 2014, 12:55:15 am
Uh that sucks... I've had a small problem when I updated VirtualBox, but it was a quick fix. Well at least it's working now!
I might be able to get a hold of a joystick, so hopefully I will be able do some testing soon.

About the default value. In my opinion the most self explaining option would be to have the default value of JoystickInfo.name set to "No Joystick". If a new joystick gets connected SFML tries to retrieve the joysticks name and save it. If it fails the name should get set to "Unknown Joystick". And if the joystick gets disconnected the name should be set back to "No Joystick". An empty string might get misinterpreted as no result or something is not working.
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: NoobsArePeople2 on January 17, 2014, 02:59:06 am
Your JoystickInfo.name settings sound good to me. I'll make the change.

It'd be great if you could get a joystick for testing.
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: Foaly on January 19, 2014, 11:54:15 pm
I was able to get a hold of a joystick. Now i just need to find some time :D I will try to do some testing this week.
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: NoobsArePeople2 on January 20, 2014, 06:48:23 pm
I was able to get a hold of a joystick. Now i just need to find some time :D I will try to do some testing this week.

Woohoo! I haven't looked in a few days, but I'm stumped on getting the vendor and product IDs so any thoughts you have there are welcome.
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: Foaly on January 21, 2014, 12:23:33 am
I didn't have time to test it, but like suggested on your github tracker I think you have to declare inpid like this:
struct input_id inpid;
Your reference page (http://www.linuxjournal.com/node/6429/print) is a bit unclear in that point, but I think that's what they mean with:
Quote
The argument is a pointer to an input_id structure
and that's how SDL does it. And it would fit to the error you are getting about the arguments begin invalid. Like I said, I couldn't test it though.

edit: also I would rename it to inputID. SFMLs variable names are usually not abriviated and in camelCase.
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: NoobsArePeople2 on January 21, 2014, 10:25:28 pm
So I tried that with no joy. Do we know that SDL's implementation works?

From my reading using struct before the declaration is related to C syntax (getting this from StackOverflow (http://stackoverflow.com/questions/7729646/using-struct-keyword-in-variable-declaration-in-c)). The chosen answer for the question states that using the struct keyword in this way restricts the identifier lookup to user defined classes. This seems odd as we want to use the input_id defined in the standard Linux headers. Maybe I'm understanding that wrong? That SO post points to some further reading here (http://stackoverflow.com/questions/1675351/typedef-struct-vs-struct-definitions/1675446#1675446).

I'm a little under the weather right now so I'm planning on giving this a fresh look later this week. I think the next thing I'll do is compile SDL on Linux and see what their implementation gives me. My reference article is over tens years old, things may have changed.

Agreed on the renaming stuff to match SFML conventions.
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: Antidote on January 22, 2014, 08:10:53 am
@NoobsArePeople2
I've gotten it to work intermittently, it seems to depend on the device, some report, some don't.
When it fails just set them to 0 and don't worry about it.
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: NoobsArePeople2 on January 22, 2014, 07:23:15 pm
@Antidote

Good to know. Perhaps it's driver related then. Can you post a list of the devices that do and don't work? Are you running in a VM?
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: Antidote on January 22, 2014, 08:47:50 pm
About the VM, nope 100% hardware for my quadboot.
About the controller, my old SideWinder was the only one I have that returned anything.

Those are the only ones I had to test.
Ones that don't are:
DS3
Nyko Airflo (Shows up as Honeybee)
And the Xbox 360 controller.
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: NoobsArePeople2 on January 22, 2014, 10:08:19 pm
Awesome! Thanks for the details.
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: Antidote on January 23, 2014, 12:47:08 am
No problem, glad to help.
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: NoobsArePeople2 on January 24, 2014, 08:13:14 am
I've created a simple SDL app to read joystick names and GUIDs. SDL doesn't have an API for something like getJoystickVendorID(), instead you read the GUID. For Linux you can see the GUID implementation here (http://hg.libsdl.org/SDL/file/7e01e3908f41/src/joystick/linux/SDL_sysjoystick.c#l124).

My test app is on Github here (https://github.com/NoobsArePeople2/SDLGamepad).

Using my wired 360 controller on Ubuntu (running in a VM) I get the following output from my SDL test app:

Name: Microsofy X-Box 360 pad
GUID: 030000005e0400008e02000014010000

If I'm reading the SDL source code correctly this means SDL sees the vendor ID as "5e04" and the product ID as "8e02". SDL forces bytes into a little endian representation so these might typically be written as "0x045e" and "0x028e" which match what lsusb -v outputs for me:

...a bunch of stuff...
idVendor: 0x045e
idProduct: 0x028e
...a bunch more stuff stuff...

So SDL looks to be getting the correct values. With my latest commit (see here (https://github.com/NoobsArePeople2/SFML/commit/845ad67d85a9b759ea5ed3b32d72405a83afc4d0)) my vendor/product ID reading is essentially identical to SDL's yet I'm still seeing EINVAL when attempting to read the EVIOCGID ioctl.

I think we should be able to get the correct values (at least with the 360 pad anyway). Going to keep digging on this.


Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: NoobsArePeople2 on January 26, 2014, 03:19:27 am
Short version: By using udev I'm able to get the manufacturer and product IDs! See commit (https://github.com/NoobsArePeople2/SFML/commit/852b7b446eade891f643d9e98c59f72e57cf9800). People of Linux, please test and let me know how this works for you.

Long version:

I spent some time digging through the SDL joystick implementation and reading up on iotcl and this is what I've found. SDL looks for joysticks in /dev/input/event while SFML looks in /dev/input/js. This means SDL must use the "EV" iotcls like EVIOCGNAME while SFML must use the "JS" ioctls like JSIOCGNAME. When attempting to mix and match I get EINVAL errors (EVIOCGNAME fails with an EINVAL error in SFML but it's JS counterpart JSIOCGNAME works great).

Unfortunately there is not a JS version of EVIOCGID, the ioctl used for retrieve an input_id struct, and hence the vendor and product IDs. SFML could switch to use /dev/input/event rather than /dev/input/js but it's my understanding that "js" is the more modern way of handling joysticks (also, my install of Ubuntu would get a "permission denied" error when attempting to read "event" which is odd since SDL worked...).

Enter libudev (http://www.freedesktop.org/software/systemd/libudev/). I had seen mention of udev before in the tracker (here (https://github.com/SFML/SFML/issues/96)) in which Laurent posted a tutorial for udev (http://www.signal11.us/oss/udev/). Using it is pretty straightforward and it looks to be the standard way for working with hardware devices on Linux systems. It also provides a really easy way to read vendor and product IDs. The downside is that we've introduced another dependency for the Linux implementation of SFML.

The commit with the udev update (https://github.com/NoobsArePeople2/SFML/commit/852b7b446eade891f643d9e98c59f72e57cf9800) uses udev to retrieve the vendor (manufacturer) and product IDs and the JSIOCGNAME ioctl to get the joystick name. It also updates Cmake to link udev when compiling SFML on Linux.

While the Cmake update works I'm not really sure it's the best way to do it. A cursory google yields a FindUDev.cmake (https://github.com/Razor-qt/razor-qt/blob/master/cmake/FindUDev.cmake) file. Honestly, I don't know enough about Cmake to know the best way so I guess reading up on that is next ;)
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: NoobsArePeople2 on February 02, 2014, 05:01:03 am
Today I put my Linux joystick updates to the test in several Linux distros:


All of these are virtualized in VirtualBox running in a Windows 8 x64 host. For testing I've used an official wired Microsoft XBox 360 pad. On Windows I'm using the official MS driver for the pad and it's passed through to Linux via VirtualBox's USB support.

In all cases udev was installed by default. This is expected as the udev Wikipedia entry (http://en.wikipedia.org/wiki/Udev) notes that udev was merged into systemd in April 2012. It also notes that some Distros like Debian (upon which Ubuntu and Mint are based) ship is separately. In my test, I did the default install for all distros and udev was present in every case so I think it safe to assume udev will be present and running on most Linux distros.

I did however need to install libudev (the development version) in order to have the udev headers. This means the Linux version of SFML will have a new dependency (to go along with pthread, freetype, etc): udev. I've updated CMake to include udev for Linux.

On Windows there was some concern about some macro magic I was doing with _UNICODE. I did some reading on this and found this StackOverflow question (http://stackoverflow.com/questions/4661304/define-unicode-not-working-with-mingw-codeblocks) which lead to this blog post (http://blogs.msdn.com/b/oldnewthing/archive/2004/02/12/71851.aspx). The short version is the UNICODE define affects everything in the Windows headers and _UNICODE affects everything in the C runtime headers. So, in order to fully force the Windows version to Unicode both UNICODE and _UNICODE need to be defined.

I've squashed all my changes into a single commit and submitted a pull request here (https://github.com/SFML/SFML/pull/528).

Thanks everyone for all the help!
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: Nexus on February 13, 2014, 04:30:29 pm
Since it's a general API question, I'll post it here and not in the pull request (https://github.com/SFML/SFML/pull/528):

Instead of three sf::Joystick methods getName(), getManufacturerId() and getProductId(), it would be a good idea to have a dedicated type for this kind of information. This introduces some structure and makes it easier to pass the related information around.

There is already sf::priv::JoystickInfo used internally, can we expose this struct in the API? Maybe we should make it a nested type of the sf::Joystick class, that is:
class Joystick
{
public:
    struct Info
    {
        JoystickInfo();

        unsigned int buttonCount;               ///< Number of buttons supported by the joystick
        bool         axes[Joystick::AxisCount]; ///< Support for each axis
        sf::String   name;                      ///< Name of the joystick
        unsigned int manufacturerId;            ///< Manufacturer identifier
        unsigned int productId;                 ///< Product identifier
    };

    static Info getInfo(unsigned int joystick);
};
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: NoobsArePeople2 on February 18, 2014, 12:02:39 am
What you've described is essentially what's happening with the current get*() methods behind the scenes. This is what getProductId() looks like:

Code: [Select]
unsigned int Joystick::getProductId(unsigned int joystick)
{
    return priv::JoystickManager::getInstance().getInfo(joystick).productId;
}

Making this change would reduce the number of methods in the joystick API by 4, replacing getButtonCount(), hasAxis(), getName(), getProductId(), and getManufacturerId() with getInfo(). Which might be nice but it's not as if there are dozens of methods in the joystick API (or likely to be many more).

On the downside, the convenience of hasAxis() would be lost with this change. Conceptually, I think going with getInfo() breaks from the logic of the current API.

As it stands all of the methods of sf::Joystick ask a specific question about the capabilities or state of a specific joystick: isConnected(), isButtonPressed(), hasAxis(), etc. getInfo() changes that so we instead ask specific questions about joystick state but a non-specific, indirect question about joystick info.

Further, when reading code I think sf::Joystick::getName(index) is easier to read and comprehend than sf::Joystick::getInfo(index).name.

While it would be easier to pass around a JoystickInfo object rather than multiple properties this doesn't strike me as something that will be happening all that much -- probably only when a joystick is first connected and being configured. I prefer the readability of the current API.
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: Nexus on February 18, 2014, 10:37:34 am
You're making good points.

hasAxis() and getButtonCount() exist already now, so they won't be removed. Thus, the info structure would only contain 3 members (name, manufacturer ID, product ID)... The question is whether it's worth aggregating these attributes to a common type.

Any other opinions on the topic?
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: Laurent on February 18, 2014, 11:30:30 am
Vendor ID and product ID always go together. Then, if we have a structure for them, why not put the name in it as well?

Another argument: sf::Font already does it this way. Even if it defines only one attribute (the font family), it is put in a Font::Info structure that is accessed with the getInfo() function.
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: NoobsArePeople2 on February 18, 2014, 06:08:06 pm
hasAxis() and getButtonCount() exist already now, so they won't be removed. Thus, the info structure would only contain 3 members (name, manufacturer ID, product ID)... The question is whether it's worth aggregating these attributes to a common type.

So this is a slight change from your previous proposal. Now JoystickInfo would not contain buttonCount or axes. Would axes and buttonCount go back into a JoystickCapabilities struct?

That makes more sense to me. That said, let me play devil's advocate:

It seems odd to me that we'd put name, vendor ID and product ID into an info structure but leave out button count and axes. All those things fall under the category of "info". And they are all contained in the current JoystickInfo struct (from the pull request (https://github.com/SFML/SFML/pull/528)).

Looking at that from the perspective of a developer using SFML I'd expect a getInfo() method to return all available info to me, not some subset of it.
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: Laurent on February 18, 2014, 06:19:11 pm
A struct with name and IDs would obviously not be named JoystickInfo, but rather JoystickIdentification or similar. Which solves the problem of not having buttons and axes in it.
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: NoobsArePeople2 on February 26, 2014, 11:45:25 pm
Okay, it sounds like this is the current proposal for the new information:

class Joystick
{
public:
    struct Identification
    {
        Identification()
        {
            name = "No Joystick";
            manufacturerId = 0;
            productId = 0;
        }

        sf::String   name;                      ///< Name of the joystick
        unsigned int manufacturerId;            ///< Manufacturer identifier
        unsigned int productId;                 ///< Product identifier
    };

    static Identification getIdentification(unsigned int joystick);
};
 

The previously existing info (button count and axes) would remain where it is and sf::JoystickInfo would be renamed back to sf::JoystickCapabilities. I think this works nicely.
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: Nexus on February 27, 2014, 10:58:07 pm
That looks mostly good; it would be nice if the constructor were defined at the end of the .cpp file and the constructor initializer list were used, in order to be consistent with other SFML classes:
Joystick::Identification::Identification() :
name          ("No Joystick"),
manufacturerId(0),
productId     (0)
{
}

If there are no other objections, I will test the code on the weekend and give you further feedback. You said you already tested it, so the main things should work. But the more joysticks and operating systems we can investigate, the better.

So, if anybody is willing to participate in testing, that would be appreciated (especially for OS X or FreeBSD)!
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: NoobsArePeople2 on February 28, 2014, 01:05:55 am
I haven't implemented FreeBSD, when using FreeBSD the getName(), etc functions all return the defaults.  I wasn't able to get a KDE nor Gnome installed on FreeBSD, nor could I find any documentation on the usb api SFML is using. Is the FreeBSD version working? The code for it seemed spare and there isn't an official download on the SFML download page.

Agreed on the contructor/initialization list. If we're liking this API change I can make all the updates to the PR before the weekend (probably Friday evening). No sense testing what we've got if we're making a bunch of API changes now.
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: NoobsArePeople2 on March 01, 2014, 04:44:56 am
If there are no other objections, I will test the code on the weekend and give you further feedback. You said you already tested it, so the main things should work. But the more joysticks and operating systems we can investigate, the better.

I just pushed up a commit with the sf::Joystick::Identification change as discussed. Tested things out on the following:


All the Linux distros are tested using VirtualBox with a Windows host OS. Everything seems to be working okay. Going to take some more time tomorrow to go over things and test out my other controllers.

BTW, I wrote this quick and dirty app for testing joysticks awhile back. Link. (https://github.com/NoobsArePeople2/SFMLGamepadTest)
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: Nexus on March 01, 2014, 06:54:20 pm
Thanks for everything so far! I'll get back to you after trying it out.
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: NoobsArePeople2 on March 01, 2014, 11:13:42 pm
Did some more in-depth testing this morning.

Windows 8 x64

Compiled with Mingw GCC 4.8.1.


Linux

All distros are 64 bit and tested via VirtualBox running from a Windows 8x64 host. I tested the following distros:



There are two drivers for the Xbox 360 pad on Linux: xpad and xboxdrv. Xpad is shipped with the kernal and is the defacto "official" Linux driver. Xboxdrv is a third party driver that must be installed manually (and part of the installation is disabling xpad entirely). So it's an either-or situation with these drivers.

I wanted to give xboxdrv a try because Linux was not recognizing my wireless 360 pad. So I did some Googling and found that people were also using xboxdrv. Now, my wireless pad may not be recognized due to the VM situation but it appears that xpad doesn't recognize it while xboxdrv does.

When testing the pad with jstest-gtk in Ubuntu all the sticks, triggers and buttons work as expected. Similarly, when using the lsusb -v command in Terminal I can see the product and manufacturer IDs. However, when running in my gamepad testing app neither the product nor manufacturer ID can be read. Both the triggers are ignored as well.

For the product and manufacturer IDs I think the problem is that I xboxdrv needs to be run as a daemon (docs (http://pingus.seul.org/~grumbel/xboxdrv/xboxdrv.html)) but I unable to do this even when I sudo to root. This bears some more investigation but I really don't feel like dealing with manually configuring Linux drivers today so I'll come back to it tomorrow or next week ;) Possibly the issue with the triggers is related.

I'd be great if someone can test wireless 360 pads on a native Linux install (non-VM) so we can see if xpad will recognize them.

Here's the link to the reference I used for setting up xboxdrv: link (http://www.omgubuntu.co.uk/2013/07/dealing-with-xbox-controllers-in-ubuntu).

Mac OS Lion (10.7)

SFML compiled with Clang and C++11 enabled.

Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: Nexus on March 02, 2014, 11:48:37 am
Thanks a lot for the detailed investigation! I think you shouldn't waste too much time with driver-specific issues (unless you enjoy it :P). It's already very nice if we can add this feature and it works with the standard drivers in the most cases -- it's still possible to improve the implementation over time, especially when we get feedback from more people. But currently you're doing all the work alone.

I can test on a native Linux Ubuntu 12.04, but I do not own any wireless joysticks. If anybody is willing to help, don't hesitate!
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: Nexus on March 02, 2014, 08:16:01 pm
I've tested two gamepads and one joystick for Windows 7, Windows 8 and Ubuntu 12.04. All of them are native operating systems.

The product and manufacturer IDs were recognized consistently on all systems. The names showed slight differences:
Is it usual that Linux also includes the vendor (or at least tries to) in the description, while Windows often doesn't?

But apart from those deviations, for which SFML probably can't do anything, it works quite well :)

One thing I also noticed, but which is not part of this issue, is that Linux also recognizes the accelerometer in my laptop as a fourth joystick.
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: NoobsArePeople2 on March 02, 2014, 09:35:09 pm
From my testing the names for devices seem to be completely arbitrary on every OS. It's possible that Linux either adds the vendor name or it's convention for driver authors to do so. I suspect most controller drivers for Windows are written by the manufacturer while Linux versions are added by the community which may also have something to do with differing naming schemes for the same device.

In any case it's probably best to rely on the vendor and manufacturer IDs to accurately identify controllers in code and use the name to identify the controller to the user.

I also noticed that I get extra joysticks on Linux -- one of them is the VirtualBox mouse integration device and another is a VirtualBox USB tablet (which I assume has to do with my drawing tablet). In both cases these devices appear as joysticks in /dev/input/js so in that since SFML is picking them up as expected. Perhaps the Linux implementation should be extended to further test connected joysticks to ensure they are actually joysticks.

Quote
JessTech ColourRumblePad (wrong manufacturer: Saitek is correct)

Does the manufacturer ID correspond with Saitek? Here's a list of USB IDs. (http://www.linux-usb.org/usb.ids)
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: NoobsArePeople2 on March 02, 2014, 09:37:38 pm
I think you shouldn't waste too much time with driver-specific issues (unless you enjoy it :P).

A sick, twisted part of me kinda wants to dig into this but I think I'll pass for now if you're not worried about it. A little further investigation shows that xpad works well for most people so it's not like we leave a ton of folks out in the cold by not fully supporting non-standard drivers.
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: Nexus on March 02, 2014, 10:55:50 pm
Perhaps the Linux implementation should be extended to further test connected joysticks to ensure they are actually joysticks.
Yep. In my example, the accelerometer simply had no buttons, so that would also be a possibility to detect it. This check also seems to be used elsewhere (https://github.com/xbmc/xbmc/pull/3640). But let's keep that for later.

Does the manufacturer ID correspond with Saitek? Here's a list of USB IDs. (http://www.linux-usb.org/usb.ids)
No. According to that list, it's indeed "Jess Technology Co., Ltd" (0f30). But Windows uses the same manufacturer ID and assigns it to Saitek. It looks like others (http://linux-kernel.2935.n7.nabble.com/Rumble-support-for-Jess-Saitek-quot-color-rumble-pad-quot-td571431.html) have had this assignment, too.

I'm wondering whether vendorId would be a better name than manufacturerId. It seems to be a bit more often used (e.g. in Android API (http://developer.android.com/reference/android/view/InputDevice.html#getVendorId()), but also discussions across the Internet). On the other hand, "manufacturer" might be more expressive.

I've also added a few remarks to the pull request. What do you think, are there important things left for a first version?
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: NoobsArePeople2 on March 03, 2014, 02:10:51 am
Yep. In my example, the accelerometer simply had no buttons, so that would also be a possibility to detect it. This check also seems to be used elsewhere (https://github.com/xbmc/xbmc/pull/3640). But let's keep that for later.
Sounds good.

Quote from: Nexus
No. According to that list, it's indeed "Jess Technology Co., Ltd" (0f30). But Windows uses the same manufacturer ID and assigns it to Saitek. It looks like others (http://linux-kernel.2935.n7.nabble.com/Rumble-support-for-Jess-Saitek-quot-color-rumble-pad-quot-td571431.html) have had this assignment, too.

Hmmm...Googling reveals a company called Jess Tech that does make gamepads. I wonder if they are a re-badge of Saitek pads for certain markets?

Quote from: Nexus
I'm wondering whether vendorId would be a better name than manufacturerId. It seems to be a bit more often used (e.g. in Android API (http://developer.android.com/reference/android/view/InputDevice.html#getVendorId()), but also discussions across the Internet). On the other hand, "manufacturer" might be more expressive.

I've been going back and forth on this as "manufacturer" is rather a pain to type (especially compared with "vendor") and, as you mentioned, "vendor" tends to be used more often. Honestly, I went with "manufacturer" because I implemented the Windows version first and that's how the value is referred to in the JOYCAPS (http://msdn.microsoft.com/en-us/library/windows/desktop/dd757103(v=vs.85).aspx) structure. I could go either way, though I'm inclined toward changing it to vendor for the reasons above.

Quote
I've also added a few remarks to the pull request.

I saw that, looking through them in detail now but they seem straightforward.

Quote
What do you think, are there important things left for a first version?

I think we could ship this feature as-is and I'd be an immediately useful improvement to SFML. The Linux driver issue discussed earlier in the thread is something I'd like to get worked out but I don't think it's needed for a v1 release.
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: Laurent on March 03, 2014, 07:51:52 am
"Vendor ID" is indeed the standard word for USB devices.
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: Nexus on March 09, 2014, 02:42:32 pm
The pull request has been merged. Thanks again for your great efforts.
Title: Re: Exposed Joystick Name, Product ID and Manufacturer ID
Post by: NoobsArePeople2 on March 09, 2014, 05:27:13 pm
The pull request has been merged. Thanks again for your great efforts.

Excellent! Glad to help.