Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Joystick fix in SFML 1.6  (Read 8556 times)

0 Members and 1 Guest are viewing this topic.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Joystick fix in SFML 1.6
« on: January 05, 2010, 06:02:00 pm »
Hi

I've just commited a fix for joysticks in the SVN trunk, and I need you to test it.

There are 3 things to test:
- Ensuring that everything works (buttons and axes)
- Comparing the value returned for the POV on Linux and Windows (the Y axis may be inverted)
- Test joysticks 3 and 4, as I added support for them

The Mac OS X implementation is not up-to-date yet.

Thanks to all the future testers :)
Laurent Gomila - SFML developer

Ceylo

  • Hero Member
  • *****
  • Posts: 2325
    • View Profile
    • http://sfemovie.yalir.org/
    • Email
Re: Joystick fix in SFML 1.6
« Reply #1 on: January 05, 2010, 07:12:42 pm »
Quote from: "Laurent"
The Mac OS X implementation is not up-to-date yet.

Now it is. Still with an minimal "empty" implementation though.
Want to play movies in your SFML application? Check out sfeMovie!

Dravere

  • Newbie
  • *
  • Posts: 37
    • View Profile
Joystick fix in SFML 1.6
« Reply #2 on: January 05, 2010, 08:03:01 pm »
For anyone that wants to test:
Code: [Select]

#include <SFML/Graphics.hpp>

#include <string>
#include <sstream>


std::string CreateJoystickDump(sf::Input const& input);
void PrintJoyState(std::ostream& out, sf::Input const& input, unsigned int joyId);


int main()
{
sf::RenderWindow mainWindow(sf::VideoMode(800, 600), "Joystick Test");

mainWindow.UseVerticalSync(true);

std::string dump;

sf::Event evt;
sf::String text;
sf::Input const& input = mainWindow.GetInput();

while(mainWindow.IsOpened())
{
while(mainWindow.GetEvent(evt))
{
if(sf::Event::Closed == evt.Type)
{
mainWindow.Close();
}
else if(sf::Event::KeyReleased == evt.Type &&
sf::Key::Escape == evt.Key.Code)
{
mainWindow.Close();
}
}

dump = CreateJoystickDump(input);

mainWindow.Clear();

text.SetText(dump);
mainWindow.Draw(text);

mainWindow.Display();
}

return 0;
}

/************************************************************************/

std::string CreateJoystickDump(sf::Input const& input)
{
std::ostringstream oss;

PrintJoyState(oss, input, 0);

oss << "\n---------------\n";

PrintJoyState(oss, input, 1);

oss << "\n---------------\n";

PrintJoyState(oss, input, 2);

oss << "\n---------------\n";

PrintJoyState(oss, input, 3);

return oss.str();
}

/************************************************************************/

void PrintJoyState(std::ostream& out, sf::Input const& input, unsigned int joyId)
{
out << " X: " << input.GetJoystickAxis(joyId, sf::Joy::AxisX);
out << " Y: " << input.GetJoystickAxis(joyId, sf::Joy::AxisY);
out << " Z: " << input.GetJoystickAxis(joyId, sf::Joy::AxisZ);

out << '\n';

out << " R: " << input.GetJoystickAxis(joyId, sf::Joy::AxisR);
out << " U: " << input.GetJoystickAxis(joyId, sf::Joy::AxisU);
out << " V: " << input.GetJoystickAxis(joyId, sf::Joy::AxisV);

out << '\n';

out << " POV: " << input.GetJoystickAxis(joyId, sf::Joy::AxisPOV);

out << '\n';

for(unsigned int button = 0; button < 16; ++button)
{
out << ' ' << input.IsJoystickButtonDown(joyId, button);
}
}


To my results (Win7 x64):
- Joystick 3 and 4 won't work with sf::Input, because you forgot to increase the array size there and the reaction on the events :)
- Joystick 1 seems to work. I had no time to test a joystick 2 yet. And I have no third or fourth joystick :)
- POV is initially 0. I checked joyGetPosEx, there it is 65535. Looks like an update is missing. There is also the question, do you want to intercept this middle position? A value of 655.35 as middle position is a bit special :)
You could perhaps introduce a negative value.

If we already are at it:
On my computer with my joystick (couldn't test this on another computer yet) the joyGetPosEx function returns valid axis values only after the joystick was moved once a bit after app startup. Do you know any solution to this? Is this windows related? Driver related? At least it isn't SFML related :)

Will do further tests, perhaps also on Linux, as soon as I have some spare time.

Dravere

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Joystick fix in SFML 1.6
« Reply #3 on: January 05, 2010, 08:21:25 pm »
Thanks a lot for this piece of code :)

Quote
Joystick 3 and 4 won't work with sf::Input, because you forgot to increase the array size there and the reaction on the events

So stupid :lol:
It's fixed.

Quote
Joystick 1 seems to work. I had no time to test a joystick 2 yet. And I have no third or fourth joystick

Great :)

Quote
POV is initially 0. I checked joyGetPosEx, there it is 65535. Looks like an update is missing. There is also the question, do you want to intercept this middle position? A value of 655.35 as middle position is a bit special
You could perhaps introduce a negative value

Yep, that's what I was thinking about. Thanks for the default value on Windows, I didn't know what it was.
Using a negative value (like -1) sounds good.

Quote
On my computer with my joystick (couldn't test this on another computer yet) the joyGetPosEx function returns valid axis values only after the joystick was moved once a bit after app startup. Do you know any solution to this? Is this windows related? Driver related? At least it isn't SFML related

I have no idea. Do you mean that the returned values are completely random until you move?
Laurent Gomila - SFML developer

Dravere

  • Newbie
  • *
  • Posts: 37
    • View Profile
Joystick fix in SFML 1.6
« Reply #4 on: January 06, 2010, 01:07:57 am »
Quote from: "Laurent"
So stupid :lol:
It's fixed.

But not submitted :)
For futher testing I made my own fix. Not really hard:
- Changing 2 to 4 at two lines in Input.hpp
- Adding 2+2 lines in Input.cpp Constructor.
- Changing 2 to 4 in Input.cpp at IsJoystickButtonDown
- Adding 2 lines in Input.cpp at OnEvent (LostFocus)

I found a software on the internet (PPJoy) that could create virtual joysticks. So I could test joystick 3 and 4. Didn't find any further errors yet. But PPJoy can't simulate Axis U and V, also there is no POV simulation.
Anyway, I don't think there will be an error, because the code is the same as for joystick 1 and 2 :)

Will do some further testing on WinXP later (tomorrow/today).

Quote from: "Laurent"
I have no idea. Do you mean that the returned values are completely random until you move?

No, they are all set to 0. That wouldn't do anything to axis X, Y and R, because normally you start the app without having the joystick full on the left or something like this.
But for example the axis Z (throttle) is also at 0. But this means on most games that you want 50% throttle. As soon as I move the stick the first time, it will get to 100 (0%). A very very very small problem something you don't need to investigate any further, if you don't know something about it. I only wanted to ask, if perhaps somebody already knows something about this :)

PS: I don't recommend PPJoy. You need to activate testsigning on Vista and Win7 so you can use it.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Joystick fix in SFML 1.6
« Reply #5 on: January 06, 2010, 08:22:04 am »
Quote
But not submitted

Should be ok now.

Quote
I found a software on the internet (PPJoy) that could create virtual joysticks. So I could test joystick 3 and 4. Didn't find any further errors yet.

Great.

Quote
No, they are all set to 0. That wouldn't do anything to axis X, Y and R, because normally you start the app without having the joystick full on the left or something like this.
But for example the axis Z (throttle) is also at 0. But this means on most games that you want 50% throttle. As soon as I move the stick the first time, it will get to 100 (0%). A very very very small problem something you don't need to investigate any further, if you don't know something about it. I only wanted to ask, if perhaps somebody already knows something about this

Ok I see. I probably won't be able to do something about it :?
Laurent Gomila - SFML developer

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Joystick fix in SFML 1.6
« Reply #6 on: January 06, 2010, 09:58:44 am »
Quote from: "Laurent"
Quote
But not submitted

Should be ok now.

Actually, I just realized that all my last changes were in the sfml2 branch... shame on me.

I also added the special value of -1 for the centered POV position, as well as new constants:
- Mouse::Count becomes Mouse::ButtonCount
- Joy::Count is now the number of joysticks
- Added Joy::AxisCount and Joy::ButtonCount
Laurent Gomila - SFML developer

Dravere

  • Newbie
  • *
  • Posts: 37
    • View Profile
Joystick fix in SFML 1.6
« Reply #7 on: January 06, 2010, 03:00:14 pm »
Ok, did make now further testing with the new code:
1. There is an error in the submitted code :)
Code: [Select]
Win32/Joystick.cpp - Line 97 : JoystickState State = { 0 };
JoystickState isn't a POD anymore because of the constructor, so change this line to:
Code: [Select]
JoystickState State;
2. POV is initially still on 0. I simply changed Input::ResetStates to (marked the single line nearly at the end):
Code: [Select]
void Input::ResetStates()
{
    for (int i = 0; i < Key::Count; ++i)
        myKeys[i] = false;

    for (int i = 0; i < Mouse::ButtonCount; ++i)
        myMouseButtons[i] = false;

    for (int i = 0; i < Joy::Count; ++i)
    {
        for (int j = 0; j < Joy::ButtonCount; ++j)
            myJoystickButtons[i][j] = false;

        for (int j = 0; j < Joy::AxisCount; ++j)
            myJoystickAxis[i][j] = 0.f;
       
        myJoystickAxis[i][Joy::AxisPOV] = -1.f; // <- I added this
    }
}


After those changes everything worked very well on Win7 x64 with 2 real joysticks. So I moved to WinXP x86 and there also was no problem too.

Well, then I made the fatal error to try this on linux (I hate linux, somehow). After "hours" of setting up sfml, I had my usual problems with linux, I finally achieved it. I think it was worth, because there were several errors. Perhaps I better say first what does work:
- Buttons
- X and Y axes.

That is it :)
Now to the errors:
- POV is somehow mapped to R. Only upward (0°) and downward (180°) gives any output: 100 and -100, but not degrees.
- Ruder (normaly on R) is mapped to Z. At least there are correct values.
- Throttle (normaly on Z) isn't recognized at all.

Edit: Forgot, I'm using KUbuntu Jaunty Jackalope 9.04.


Feature that I may suggest:
- Add a function to re-identify joysticks while running the app. So you can plug in a joystick while the app is running and after calling this function, the joystick will be recognized. No restart of the app is needed.

Dravere

PS: No linux guys here to test? I don't want to do this :lol:

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Joystick fix in SFML 1.6
« Reply #8 on: January 06, 2010, 03:29:37 pm »
1. Thanks. I hate doing all these "last minute" modifications, I'm not really focused on the code and I always forget something or make mistakes.

2. Okay, I fixed it.

Quote
- POV is somehow mapped to R. Only upward (0°) and downward (180°) gives any output: 100 and -100, but not degrees.
- Ruder (normaly on R) is mapped to Z. At least there are correct values.
- Throttle (normaly on Z) isn't recognized at all.

I was expecting this kind of errors... There's no documentation at all about the joystick API on Linux (well, it's more a header with constants than a real API).
I tried something, let me know if it works or if it's worse :lol:

Quote
Feature that I may suggest:
- Add a function to re-identify joysticks while running the app. So you can plug in a joystick while the app is running and after calling this function, the joystick will be recognized. No restart of the app is needed.

Yep, I'll see that for SFML 2 ;)
Laurent Gomila - SFML developer

Dravere

  • Newbie
  • *
  • Posts: 37
    • View Profile
Joystick fix in SFML 1.6
« Reply #9 on: January 09, 2010, 02:38:28 am »
Reporting live from Ubuntu 9.10 x86 Karmic Koala:
- X Axis works
- Y Axis works
- Z Axis (throttle) works
- R Axis (rudder) works
- U Axis can't test this one
- V Axis can't test this one
- POV, is initially -1 but doesn't receive any updates, so doesn't work.

I checked if my joystick works and it seems so. Then I checked your sourcecode and probably found the error. You're checking hat-X and hat-Y against 1, 0 or -1. The values I received from my test application were 32767, 0, -32767 ;)

To the U and V axis, I can't test this ones, because I have no joystick that have U or V axes.

Dravere

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Joystick fix in SFML 1.6
« Reply #10 on: January 09, 2010, 10:13:02 am »
Quote
Then I checked your sourcecode and probably found the error. You're checking hat-X and hat-Y against 1, 0 or -1. The values I received from my test application were 32767, 0, -32767

Thanks, it's fixed :)
Laurent Gomila - SFML developer

Dravere

  • Newbie
  • *
  • Posts: 37
    • View Profile
Joystick fix in SFML 1.6
« Reply #11 on: January 09, 2010, 04:20:58 pm »
Quote from: "Laurent"
Thanks, it's fixed :)

But still infested with bugs :)

I had to change the following commented things in sfml/window/linux/joystick.cpp, starting at line 122:
Code: [Select]
// break; <- moved down, so the if/else can be executed ;)

if (myPovX > 0)
{
    if      (myPovY > 0) myState.Axis[Joy::AxisPOV] = 135.f; // 315.f;
    else if (myPovY < 0) myState.Axis[Joy::AxisPOV] = 45.f;
    else                 myState.Axis[Joy::AxisPOV] = 90.f;  // 0.f;
}
else if (myPovX < 0)
{
    if      (myPovY > 0) myState.Axis[Joy::AxisPOV] = 225.f;
    else if (myPovY < 0) myState.Axis[Joy::AxisPOV] = 315.f; // 135.f;
    else                 myState.Axis[Joy::AxisPOV] = 270.f; // 180.f;
}
else
{
    if      (myPovY > 0) myState.Axis[Joy::AxisPOV] = 180.f; // 270.f;
    else if (myPovY < 0) myState.Axis[Joy::AxisPOV] = 0.f;   // 90.f;
    else                 myState.Axis[Joy::AxisPOV] = -1.f;
}
break; // <- inserted


And while testing this I found a new bug ... I feel somehow sorry :)
Under Linux, if you move the window, the joystick status vanishes and resets. I don't know if this has something to do with linux or sfml and probably isn't so important, because you won't play a game and move the windows around at the same time *g*

Dravere

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Joystick fix in SFML 1.6
« Reply #12 on: January 09, 2010, 06:22:59 pm »
Quote
But still infested with bugs

Unfortunately. I'm thinking about buying a cheap joystick just to be able to maintain this code properly :?

Thanks for your fixes. Do the corrected POV values match those given on Windows?

Quote
Under Linux, if you move the window, the joystick status vanishes and resets

What the hell... :shock:
Laurent Gomila - SFML developer

Dravere

  • Newbie
  • *
  • Posts: 37
    • View Profile
Joystick fix in SFML 1.6
« Reply #13 on: January 09, 2010, 06:41:58 pm »
Quote from: "Laurent"
Unfortunately. I'm thinking about buying a cheap joystick just to be able to maintain this code properly :?

They can be really cheap. Or ask a friend if he has an old one ;)

Quote from: "Laurent"
Thanks for your fixes. Do the corrected POV values match those given on Windows?

Yes, that is how I correted them. They now conform to:
Code: [Select]

         0°
  315°   |   45°
       \   /
270° -   o   - 90°
       /   \
  225°   |   135°
        180°


Dravere

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Joystick fix in SFML 1.6
« Reply #14 on: January 09, 2010, 07:14:02 pm »
Ok, thank you a lot :)

Now everything should be ok right? :lol:
Laurent Gomila - SFML developer