SFML community forums

Help => Window => Topic started by: myroidtc on November 18, 2013, 07:02:51 am

Title: Joystick PoV Axes Flipped
Post by: myroidtc on November 18, 2013, 07:02:51 am
I'm using SFML 2.1 Visual C++ 11 (2012) - 64 bits and Windows 7.

sf::Joystick::Axis::PovX corresponds to the d-pad vertical instead of the horizontal for me. I've tested with two controllers (DualShock 4 and Xbox 360) and the axis names are consistently flipped. All the other axes are fine.

Is this a bug or are the names arbitrary? Might the OS have something to do with it? It's not that big of a deal, I'm simply curious as to why this might happen.
Title: Re: Joystick PoV Axes Flipped
Post by: Laurent on November 18, 2013, 07:39:53 am
Is it the same with other applications, or is it just SFML?
Title: Re: Joystick PoV Axes Flipped
Post by: myroidtc on November 18, 2013, 08:47:14 am
It seems to be just SFML. The hat works as expected in the Windows calibration thing and some other applications like JoyToKey and PCSX2 correctly detect the hat direction.

When pressing "up" on the dpad,

sf::Joystick::getAxisPosition(currentJoystick, sf::Joystick::Axis::PovX)

returns -100.0 while "down" returns 100.0. Note that it's PovX and not PovY.
Title: Re: Joystick PoV Axes Flipped
Post by: fallahn on November 18, 2013, 08:27:33 pm
Ah! Yes, I found this back in April or so when I started working on my current project - and then promptly forgot about it. Just looked at my source and found I'd made a comment about it, so I tried it just now and can confirm pushing left on and X360 DPad returns a negative value on PovY (and vice versa). Am using the current version of SFML from Github on multiple Win 7 machines - although when I started I was probably using a pre 2.0 release. (I tend just just rebuild SFML every few weeks or so when I feel like it, sorry can't be more specific than that)
Title: Re: Joystick PoV Axes Flipped
Post by: NoobsArePeople2 on November 21, 2013, 08:35:05 pm
I can confirm I also have this issue on Windows 8 with SFML 2.0. I compiled from source using mingw.
Title: Re: Joystick PoV Axes Flipped
Post by: wintertime on November 21, 2013, 09:52:17 pm
I guess I know the root of the problem. This is a proposed fix if you want to try (though its only based on your description above, not on actual knowledge of the used joystick functions):
diff --git a/src/SFML/Window/Win32/JoystickImpl.cpp b/src/SFML/Window/Win32/JoystickImpl.cpp
index c2645e8..7f2bec2 100644
--- a/src/SFML/Window/Win32/JoystickImpl.cpp
+++ b/src/SFML/Window/Win32/JoystickImpl.cpp
@@ -167,8 +167,8 @@ JoystickState JoystickImpl::update()
         if (pos.dwPOV != 0xFFFF)
         {
             float angle = pos.dwPOV / 18000.f * 3.141592654f;
-            state.axes[Joystick::PovX] = std::cos(angle) * 100;
-            state.axes[Joystick::PovY] = std::sin(angle) * 100;
+            state.axes[Joystick::PovX] = std::sin(angle) * 100;
+            state.axes[Joystick::PovY] = std::cos(angle) * 100;
         }
         else
         {
 
Title: Re: Joystick PoV Axes Flipped
Post by: Laurent on November 21, 2013, 10:55:21 pm
Quote
though its only based on your description above, not on actual knowledge of the used joystick functions
So this is a really bad fix ;)

Until we know how pos.dwPOV must be interpreted (which the doc doesn't clearly explains, if I remember correctly), we can't write a proper fix. Your "fix" could work for some cases but not all. For example, instead of switching axes, maybe it's rather a rotation by 90° that must be done.
Title: Re: Joystick PoV Axes Flipped
Post by: wintertime on November 21, 2013, 11:05:40 pm
They wrote they could use the numbers from the other axis directly, so it would hopefully work. If there is no docs and 3 people write its that way?
I dont have a joystick here for testing and knew I saw that place in the code including your comment about how weird it is to calculate this from an angle (and they did apparently not know the exact place to look), thats why I put the code up for them to try, not for direct including into SFML. ;)
Title: Re: Joystick PoV Axes Flipped
Post by: zsbzsb on November 22, 2013, 12:08:08 am
If there is no docs

Fret not, for there is documentation... (http://msdn.microsoft.com/en-us/library/windows/desktop/dd757112%28v=vs.85%29.aspx)
.
.
.
.
Welcome to MSDN  :P


Quote from: MSDN
Current position of the point-of-view control. Values for this member are in the range 0 through 35,900. These values represent the angle, in degrees, of each view multiplied by 100.
Title: Re: Joystick PoV Axes Flipped
Post by: Laurent on November 22, 2013, 07:41:44 am
There is no doc explaining how to interpret the angle (where is "0", is it clockwise or counter clockwise).
Title: Re: Joystick PoV Axes Flipped
Post by: Jebbs on November 22, 2013, 07:55:46 am
Is it not safe to assume that it is the same as a unit circle?
Title: Re: Joystick PoV Axes Flipped
Post by: zsbzsb on November 22, 2013, 01:39:46 pm
There is no doc explaining how to interpret the angle (where is "0", is it clockwise or counter clockwise).

Actually I just looked at this again and there is what we need. Take a look at the remarks section near the bottom (of the article I linked above).


Quote from: MSDN
Most devices with a point-of-view control have only five positions. When the JOY_RETURNPOV flag is set, these positions are reported by using the following constants:


So according to this we should set that flag in the initialize function...

joyInfo.dwFlags =  JOY_RETURNPOV;

Then the returned angle should be constrained to the following quote. And as you can see 0 degrees is up/forward while 90 degrees is to the right. Therefore switching the sin/cos calls around should fix the issue.

Quote from: MSDN
JOY_POVBACKWARD   Point-of-view hat is pressed backward. The value 18,000 represents an orientation of 180.00 degrees (to the rear).

JOY_POVCENTERED   Point-of-view hat is in the neutral position. The value -1 means the point-of-view hat has no angle to report.

JOY_POVFORWARD   Point-of-view hat is pressed forward. The value 0 represents an orientation of 0.00 degrees (straight ahead).

JOY_POVLEFT   Point-of-view hat is being pressed to the left. The value 27,000 represents an orientation of 270.00 degrees (90.00 degrees to the left).

JOY_POVRIGHT   Point-of-view hat is pressed to the right. The value 9,000 represents an orientation of 90.00 degrees (to the right).
Title: Re: Joystick PoV Axes Flipped
Post by: Laurent on November 22, 2013, 02:50:51 pm
Quote
So according to this we should set that flag in the initialize function
That would limit the output to 4 directions while we currently have the full [0 .. 360] range.

Quote
And as you can see 0 degrees is up/forward while 90 degrees is to the right. Therefore switching the sin/cos calls around should fix the issue.
Right, these indications should be enough to verify the formula.
Title: Re: Joystick PoV Axes Flipped
Post by: zsbzsb on November 22, 2013, 03:10:49 pm
That would limit the output to 4 directions while we currently have the full [0 .. 360] range.

Well that isn't the way I understood it  :-\
Title: Re: Joystick PoV Axes Flipped
Post by: Laurent on November 22, 2013, 05:08:36 pm
What did you understand?
Title: Re: Joystick PoV Axes Flipped
Post by: wintertime on November 22, 2013, 05:21:03 pm
That it can be returned in two ways:
Quote
JOY_RETURNPOV   The dwPOV member contains valid information about the point-of-view control, expressed in discrete units.
JOY_RETURNPOVCTS   The dwPOV member contains valid information about the point-of-view control expressed in continuous, one-hundredth degree units.
Quote
The default joystick driver currently supports these five discrete directions. If an application can accept only the defined point-of-view values, it must use the JOY_RETURNPOV flag. If an application can accept other degree readings, it should use the JOY_RETURNPOVCTS flag to obtain continuous data if it is available. The JOY_RETURNPOVCTS flag also supports the JOY_POV constants used with the JOY_RETURNPOV flag.
Title: Re: Joystick PoV Axes Flipped
Post by: Mario on November 24, 2013, 09:07:45 pm
Guess it's working as intended. It's quirky, yes, but I think this is intentional, considering the POV originated as a coolie hat. Due to this X is indeed forward/backward, while Y is left/right. I'd say leave the current behavior, but add a note to the documentation, maybe even some simple vector graphics explaining orientations?

From MSDN (http://msdn.microsoft.com/en-us/library/windows/hardware/gg487464.aspx) (note this is about DirectInput):
Quote
Hat switch controls must report a Null value when not pressed. When pressed, the logical minimum value represents north, and increasing logical values represent directions equally spaced clockwise around the compass. For example, Table 2 describes two different types of hat switches, one with eight positions and one with four positions.
Of course this speaks of enum/logical values rather than angles, but I'd say it's just the logical next step. The important part is the orientation: 0 degrees is north here.

So SFML's orientation is correct and it's obviously not hardware dependent (as long as the hardware follows these guidelines). So question is which orientation should SFML use? How's the orientation on other platforms?
Title: Re: Joystick PoV Axes Flipped
Post by: NoobsArePeople2 on November 24, 2013, 09:34:02 pm
So SFML's orientation is correct and it's obviously not hardware dependent (as long as the hardware follows these guidelines). So question is which orientation should SFML use? How's the orientation on other platforms?

My feeling is that it should be left as-is for a couple reasons.

First, legacy support: this is (probably) how SFML has always worked and it hasn't been an issue til now. While not the best reason this is certainly worth considering.

Second: sf::Joystick is a thin wrapper over each platform's joystick API, as such it shouldn't interpret or normalize data returned by a platform's API. For example, on Windows the 360 pad's triggers report a value of 0 when not pressed but they report a value of -100 when not pressed on Mac. Likewise, button indexes are inconsistent across joysticks and platforms. I feel that sf::Joystick should just report what the system gives it and leave it to the developer to properly interpret that information.

Regardless, making a note of this in the docs is definitely a good idea as this feels like a bug.
Title: Re: Joystick PoV Axes Flipped
Post by: Laurent on November 24, 2013, 10:40:17 pm
Although it's fine to have 0 at north (it's just a valid convention like any other), I think it's definitely wrong to report "left" when you move your POV up -- because "left" is not a convention, it has a unique physical meaning ;).

And this is not what the OS reports, it is just how SFML converts the angle to axes. So this is a bug. And it should be fixed.
Title: Re: Joystick PoV Axes Flipped
Post by: Laurent on November 26, 2013, 10:30:55 pm
Done. Feel free to check if it is working as expected now :)