Skip to content

Added joystick example. #1363

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 5, 2018
Merged

Added joystick example. #1363

merged 1 commit into from
Apr 5, 2018

Conversation

binary1248
Copy link
Member

Originally used when testing #1326 but can be used with the existing code as well.

window.clear();

// Draw the label-value sf::Text objects
for (Texts::const_iterator i = texts.begin(); i != texts.end(); ++i)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there's no controller connected it will still spit out basically placeholder text for the first controller. Maybe there should be some instruction like "No controllers could be found. Connect a gamepad or joystick to test it."?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The text that is always output isn't placeholder text, they are simply the labels of the joystick items. When a joystick is connected, values will be displayed for the last joystick whose state was modified. When no joysticks are connected, no values are displayed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, but (at least to me) from a first look it's still not clear whether the program is stuck or just couldn't find any joystick. So maybe just rather than setting ID to nothing, set it to <Not connected>, if there's no controller? Similar not existing buttons/axes should possibly output "n/a" rather than nothing.

@MarioLiebisch
Copy link
Member

I'm not really sure about the whole text output only. I'd prefer something visual, even if it just consists of simple shapes. Maybe something like this (potentially with more text):
Imgur

@binary1248
Copy link
Member Author

The point of this example is to demonstrate usage of the joystick API. The predecessor to this code would output purely to the console, however it would become unreadable when outputting all the possible values of a joystick's state hence the sfml-graphics output. The current text rendering already takes up almost half of the code. Making it any more sophisticated such as in the picture you posted will shift the focus of the code away from the joystick API to the drawable API which shouldn't be the case in a joystick example. This should stay as an example and not become some kind of debug tool.

@MarioLiebisch
Copy link
Member

Yeah, probably true,

text.second.setPosition(80.f, 5.f + ((sf::Joystick::AxisCount + i + 2) * font.getLineSpacing(14)));
}

for (Texts::iterator i = texts.begin(); i != texts.end(); ++i)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, maybe just me, but I prefer to reserve i, j, etc. for numerical indices, while using a, b, etc. for iterators (even though [i]terator makes sense).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My personal convention, and thus most likely what's used in SFML, is to use it for iterators.


namespace
{
typedef std::map<std::string, std::pair<sf::Text, sf::Text> > Texts;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While convenient and using existing classes, I'd really just define a small struct for the values here, even if it's just to identify the components as label and value or something like that. It's about readability and the chained expressions with first or second just feel a bit odd.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. std::pair is never a good choice.

std::ostringstream sstr;

// Axes labels in as C strings
const char* axislabels[] = {"X", "Y", "Z", "R", "U", "V", "PovX", "PovY"};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While it's unlikely the enum values for the axes might change, I'm not really a fan of just assuming a constant/fixed order here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In core SFML code I would agree, but this is just an example, so it's a good thing if we keep this kind of boilerplate code as short as possible.

@MarioLiebisch
Copy link
Member

As an added feature, maybe allow the user to increase/decrease the movement threshold with some keys, like Page Up/Down, visualizing what it does?

@eXpl0it3r eXpl0it3r force-pushed the feature/joystick_example branch from 58850ee to 2b8dede Compare March 23, 2018 12:36
@eXpl0it3r
Copy link
Member

There are still some open suggestions, are you going to change things @binary1248? I mean it's just an example, doesn't have to be the best thing ever.

@binary1248
Copy link
Member Author

I still intend to work on this... yes.

@binary1248 binary1248 force-pushed the feature/joystick_example branch from 2b8dede to 1ca7f23 Compare March 24, 2018 16:05
@binary1248
Copy link
Member Author

@MarioLiebisch, @LaurentGomila, @eXpl0it3r: All the mentioned issues should be resolved in the current version.

@eXpl0it3r
Copy link
Member

I don't own a joystick, can someone test this?

@binary1248 binary1248 force-pushed the feature/joystick_example branch from 1ca7f23 to a786ca1 Compare March 26, 2018 23:46
@danieljpetersen
Copy link
Contributor

I just tried this out on Linux Mint 18.3

  • The Steam Controller identified as a 360 controller. It doesn't seem like this is working correctly here. Only three buttons have an effect -- The threshold value goes up when you press the X button, and it goes down when you press the Y button. Pressing the start button causes the program to exit, which I guess is to be expected.
  • Everything works perfectly with the Logitech Extreme 3D (this thing)
  • The PC version of the 360 controller also works perfectly for me.

@eXpl0it3r
Copy link
Member

eXpl0it3r commented Mar 28, 2018

Thanks for testing!

The Steam Controller identified as a 360 controller. It doesn't seem like this is working correctly here. Only three buttons have an effect -- The threshold value goes up when you press the X button, and it goes down when you press the Y button. Pressing the start button causes the program to exit, which I guess is to be expected.

Sounds more like a potential driver issue. If you have time to track down the issue, maybe there's something we need to adjust on our side?

@danieljpetersen
Copy link
Contributor

Perhaps it is a driver issue. Apparently the Steam Controller isn't mainlined into the Linux kernel yet, and you need to have Steam running in the background order for the controller to properly work.

I'll test it out on Windows.

@danieljpetersen
Copy link
Contributor

Hm. I get the same result in Windows, except this time it's not reporting that any controller is connected. I still think you're right though, it looks like the controller is mapped to keyboard keys and not presenting itself as a joystick?

@binary1248
Copy link
Member Author

This PR doesn't change the way joysticks are handled by SFML. It is merely an example of how to use the API. If wrong values are displayed, then any application making use of the SFML joystick implementation will also function incorrectly. As such, if you find and are able to reproduce any bugs in the current joystick implementation, you should discuss the issue on the forum and possibly open an issue against the actual SFML joystick implementation.

@eliasdaler
Copy link
Contributor

Logitech Gamepad F310 on Linux - everything works as expected in DirectInput and XInput modes.

Copy link
Member

@mantognini mantognini left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, it looks good and works nicely on macOS.


typedef std::map<std::string, JoystickObject> Texts;
Texts texts;
std::ostringstream sstr;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the motivation for this global ss?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having to construct/destroy the ss everywhere where it is currently used would cause unnecessary overhead. I would have liked to use std::to_string but we aren't there yet. 😉

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having to construct/destroy the ss everywhere where it is currently used would cause unnecessary overhead.

Is it something that you measured? I've always seen people instantiating (or recommending to instantiate) this locally, only where it is needed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I always use stringstreams to stringify numerical values, also when getting a rough feel for performance (frame times) as you know. I noticed a significant delta when recreating them constantly, which is why I made it a habit to just resort to using long-lived ones. It is much faster to just empty the buffer and re-fill it constantly than always have to construct/destruct the object including its internal state etc.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know about the perf cost, never had to measure it. I guess one could always encapsulate this using a static variable in a function. Not saying you should do it, just a random thought.

// Update threshold if the user wants to change it
float newThreshold = threshold;

if (sf::Keyboard::isKeyPressed(sf::Keyboard::PageUp))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have this key on my keyboard. Up seems more suitable.

if (sf::Keyboard::isKeyPressed(sf::Keyboard::PageUp))
newThreshold += 0.1f;

if (sf::Keyboard::isKeyPressed(sf::Keyboard::PageDown))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Idem with Down.

@binary1248 binary1248 force-pushed the feature/joystick_example branch from a786ca1 to 1ca226d Compare April 3, 2018 00:16
@binary1248
Copy link
Member Author

@mantognini Fixed.

@eXpl0it3r
Copy link
Member

There's a small conflict due to the iOS Demo being merged.

@binary1248 binary1248 force-pushed the feature/joystick_example branch from 1ca226d to fe1407b Compare April 5, 2018 15:30
@binary1248
Copy link
Member Author

@eXpl0it3r Fixed.

@eXpl0it3r eXpl0it3r merged commit fe1407b into master Apr 5, 2018
@eXpl0it3r eXpl0it3r deleted the feature/joystick_example branch April 5, 2018 22:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants