Yep, thats it. Why do u need write access on those devices?
Hi
To send messages to the devices (like for force feedback and some of the other diagnositics/setup information) it needs to be writeable (else you can’t write the message :)). I think that some devices could be opened read only, queried, and then work out if I need write access, but for now it (and when I was developing it) having write access as well didn’t seem like an issue.
I did want to print an error message when it failed to open a devices, so that it was obvious where the error was, but some distributions include a whole list of device files regardless of wether they exist or not, jinput will try and open them, so you would always get error messages there that it couldn’t open the device, I might put this back in though.
Cheers
Endolf
@endolf: You asked my for some code regarding the topic of finding the right controller. Well lets have a look at this. It is currently used to find my gamepad.
private Controller getStick(Controller[] controllers) {
for(int i=0;i<controllers.length;i++) {
Controller.Type type = controllers[i].getType();
if(type.equals(Controller.Type.GAMEPAD) ||
type.equals(Controller.Type.STICK) ||
type.equals(Controller.Type.UNKNOWN)) {
return controllers[i];
}
}
return null;
}
This all looks logical until “type.equals(Controller.Type.UNKNOWN))”. The problem is that under Linux no device identifies itself as a gamepad or stick with the corresponding Controller.Type instance. If I leave the last check out the gamepad is not found in Linux (but this works in Windows ).
Another bad thing: In another thread I have shown you that my PC speaker is now a Controller as well and is now recognized by this method. Very bad because I wanted a pad or joystick-like device :’(
This is the first thing I want to see corrected.
Regarding the primary problem of this thread (identify used Axis at runtime, save something into a config file, find the Axis which was described in the config file) I would propose generating something like a unique identifier. This identifier should include device name and manufacturer.
In Linux I think it would be a good idea to include the name of the device filename as well because this makes the identifier truly unique.
With that information it would be very easy what to save to a config file:
- controller id
- [subcontroller index]
- axis index
- extend value
- game event
When the game is started and no controller is found with a corresponding identifier the game would know that it should be careful using another device because subcontroller and/or axis may not exist any more. Auto sensing them again would solve that easily.
Other platforms should be able to follow that to: In Windows you can use DirectInput’s device type and the order in which DInput gives you the device.
So what do you think about that?
Hi
I know it’s been a while since you posted this, but I am working on it. Currently I have some sigsegv’s under linux, which I think is due to my logitec keyboard which has two sub controllers, one for the main qwerty bit, and one for the mouse wheel, the volume controls etc etc, hopefully I can get this resolved soon and get back to you.
Cheers
Endolf
Ok
Issues 25 and 26 have been sorted now, and I can confirm I see the same thing, I will have a look at the code that guesses the device type at some point and see if I can get it playing nicely. Can you give me the output from
ant texttest
so that I can see what values your devices have and compare those with mine and see if I can come up with some new guessing rules.
Thanks
Endolf
Ok, I still want the output from that test, but I found a bug, and have updated CVS, the jinput bug can be tracked/modified from here.
Thanks
Endolf
[quote]1)
@endolf: You asked my for some code regarding the topic of finding the right controller. Well lets have a look at this. It is currently used to find my gamepad.
This all looks logical until “type.equals(Controller.Type.UNKNOWN))”. The problem is that under Linux no device identifies itself as a gamepad or stick with the corresponding Controller.Type instance. If I leave the last check out the gamepad is not found in Linux (but this works in Windows ).
[/quote]
issue 27 should fix this.
[quote]Another bad thing: In another thread I have shown you that my PC speaker is now a Controller as well and is now recognized by this method. Very bad because I wanted a pad or joystick-like device :’(
This is the first thing I want to see corrected.
[/quote]
you should now be able to remove the UNKNOWN check from that list and get sticks and gamepads.
[quote]2)
Regarding the primary problem of this thread (identify used Axis at runtime, save something into a config file, find the Axis which was described in the config file) I would propose generating something like a unique identifier. This identifier should include device name and manufacturer. So what do you think about that?
[/quote]
Hows about the string from getName, and the order it appears in the controllers array. Then you can get the axis id and use those. The problem with this is that under linux especially (I don’t know about windows), if I boot my system, then plug in some devices, they appear in /dev/input in the order they were plugged in, however, on reboot, they appear in the order of the USB ports and allowing for USB hub drivers to load, so the order may be very different. Using any kind of index or native deviceID from jinput will cause this, the only thing you can be sure is the same is the name and type (for the same jinput binaries).
HTH
Endolf
it works! thank you!
Here the texttest output of the new plugins: (only gamepad and mouse)
Mega World
Type: gamepad
Axis Count: 18
Axis 0: X axis
Identifier: x
AxisType: Absolute Analog
Axis 1: Y axis
Identifier: y
AxisType: Absolute Analog
Axis 2: Button 0
Identifier: Button 0
AxisType: Absolute Digital
Axis 3: Button 1
Identifier: Button 1
AxisType: Absolute Digital
Axis 4: Button 2
Identifier: Button 2
AxisType: Absolute Digital
Axis 5: Button 3
Identifier: Button 3
AxisType: Absolute Digital
Axis 6: Button A
Identifier: Button A
AxisType: Absolute Digital
Axis 7: Button B
Identifier: Button B
AxisType: Absolute Digital
Axis 8: Button C
Identifier: Button C
AxisType: Absolute Digital
Axis 9: Button X
Identifier: Button X
AxisType: Absolute Digital
Axis 10: Button Y
Identifier: Button Y
AxisType: Absolute Digital
Axis 11: Button Z
Identifier: Button Z
AxisType: Absolute Digital
Axis 12: Thumb Left Button
Identifier: Thumb Left Button
AxisType: Absolute Digital
Axis 13: Thumb Right Button
Identifier: Thumb Right Button
AxisType: Absolute Digital
Axis 14: Second Thumb Left Button
Identifier: Second Thumb Left Button
AxisType: Absolute Digital
Axis 15: Second Thumb Right Button
Identifier: Second Thumb Right Button
AxisType: Absolute Digital
Axis 16: Select Button
Identifier: Select Button
AxisType: Absolute Digital
Axis 17: Uknown button
Identifier: Uknown button
AxisType: Absolute Digital
Microsoft Microsoft IntelliMouse® Optical
Type: mouse
Axis Count: 0
[quote]it works! thank you!
[/quote]
Your welcome. I’m glad your gamepad is found as one, it’s up to the driver what they call the buttons, my gamepad has it’s native button IDs different to your so it gets detected as a stick, however, the name of mine contains the text ‘Gamepad’. Can you guess how I got mine to be detected as a gamepad in the ‘guess what type of controller this is’ code? ;D
Endolf
No need to guess because I know how the Linux plugin guesses itself
Sorry but I was curious of how the plugins actually work. Its a shame that you are forced to guess the device type that way.
I found my ‘PC speaker’ is incorrectly identified as a stick. Maybe thats because it has no axes. What about throwing away all zero-axis controllers?
What about overriding the kernel’s name scheme (at least for non-keyboards)?
Whenever you identify a certain type of axis you increase an id and name it: + id
This will have the following result:
.
.
.
Axis 16: Button 10
Identifier: Button 10
AxisType: Absolute Digital
Axis 17: Button 11
Identifier: Button 11
AxisType: Absolute Digital
[quote]I found my ‘PC speaker’ is incorrectly identified as a stick. Maybe thats because it has no axes. What about throwing away all zero-axis controllers?
[/quote]
what, no keyboards?
Endolf
well Axis is used for keys and buttons. Maybe put this after getSupportedButtons() in LinuxDevice.guessType():
// without any buttons this device is and should be reported as of
// unknown type
if(numButtons == 0) {
// nothing is needed to be set, because guessType is already set to unknown
return;
}
– EDIT: had to use numButtons …
Hi
What I was going to do was either add a 0 check for each characteristic if statement, or add another one that sees if they are all 0, as I suspect that in the case of the speaker they are all 0
Endolf
Try now ;D
Endolf
Yeah much better now but there is still a problem:
I think the Axis.Identifier class should be used as a typesafe enum and therefore you should not create any instances of it. Instead the existing instances have to be mapped.
Currently there is no benefit by calling someAxis.getIdentifier() because its name is the same as someAxis.getName() and a comparison with any Axis.Identifier instance will fail.
(The same problem applies to the MacOS implementation of the mouse!)
Btw: I find the linux plugin is in a very good state. Especially the native code is clearly separated from the Java code. I know that it is harder to write the Windows version because of DirectInput’s nasty callbacks but even there ‘business code’ should really live only in ONE world. And I think we all know which is the better one
Ok, type safe enums are a 1.5 feature arn’t they?, and thats still beta, I know jinput requires a 2.6 kernel for some features, but requiring everyone to have 1.5 isn’t an option yet, not for something like that.
The axis identifiers being equal might need to be updated, right now I have another sigsegv to fix, so it’s far more important :), raise an issue on jinput.dev.java.net to remind me
Cheers
Endolf
err no … as of <1.5 typesafe enums are like a design pattern.
To achieve type-safeness one declares a private constructor and then creates some public final instances with it:
public class TypeSafe {
public final TypeSafe CONSTANT1 = new TypeSafe();
public final TypeSafe CONSTANT2 = new TypeSafe();
private TypeSafe(){
}
}
This is a minimal example. But as you can see that Axis.Identifier uses exactly this pattern (but I wonder why the constructor is ‘protected’).
And btw Typesafe enums in 1.5 are internally much the same as this.
reported this as a bug
I looked at StandardKeyboard.java to see how Axis.Identifier is used there and in the hope to find a confirmation of what I thought the class is used for but did not find that and now I am confused:
Why does Axis.Identifier declares some constant instances which invite everyone to do ‘==’-like checking and is then subclassed and instantiated everywhere?
Non constant and subclassed Axis.Identifier instances are completely useless because they provide mostly the same information like the axis which they belong to?
And now the really confusing part: The constant instances of Axis.Identifier are only (and only there) used from the DX8 plugin’s native code!
Can someone sheer me up with some good news?
Amazing!
After wakeup I finally got it. Now I know what Axis.Identifier is meant to be. Look up this thread’s topic: Axis.Identifier wanted to be the answer.
It could not achieve that goal because some implementations broke the rule of uniqueness of the name of an Axis.Identifier (and subclasses) instance.
Eg: the linux plugin gives the name ‘unknown’ to all Axis-objects and its identifiers.
having said that:
When I first got my hands on JInput I generated the Javadoc and simply guessed how to use certain things of the library. These static constant instances of Axis.Identifier called X, Y, RX, RY etc. looked truly like a nice method of getting the actual Axis type. And for the DirectInput plugin this is true! All buttons on my gamepad get the same instance of Axis.Identifier. If I want to write an application that needed to select the first button it can find programmatically it would simply search for the first controller which is a GAMEPAD or STICK and then use Axis.Identifier.BUTTON to find some buttons.
So in conclusion we have the following:
a) once in a time Axis.Identifier was meant as an AxisType-identifier
b) after that time someone thought it would be the way to reidentify a certain Axis (Axis.Identifier’s name could be saved to disk …)
but neither a) nor b) are implemented consistly and there is a need for both!
Any comments on this?