239 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			239 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
 | 
						|
////////////////////////////////////////////////////////////
 | 
						|
// Headers
 | 
						|
////////////////////////////////////////////////////////////
 | 
						|
#include <SFML/Graphics.hpp>
 | 
						|
#include <algorithm>
 | 
						|
#include <sstream>
 | 
						|
#include <iomanip>
 | 
						|
#include <string>
 | 
						|
#include <map>
 | 
						|
 | 
						|
 | 
						|
namespace
 | 
						|
{
 | 
						|
    struct JoystickObject
 | 
						|
    {
 | 
						|
        sf::Text label;
 | 
						|
        sf::Text value;
 | 
						|
    };
 | 
						|
 | 
						|
    typedef std::map<std::string, JoystickObject> Texts;
 | 
						|
    Texts texts;
 | 
						|
    std::ostringstream sstr;
 | 
						|
    float threshold = 0.1f;
 | 
						|
 | 
						|
    // Axes labels in as C strings
 | 
						|
    const char* axislabels[] = {"X", "Y", "Z", "R", "U", "V", "PovX", "PovY"};
 | 
						|
 | 
						|
    // Helper to set text entries to a specified value
 | 
						|
    template<typename T>
 | 
						|
    void set(const char* label, const T& value)
 | 
						|
    {
 | 
						|
        sstr.str("");
 | 
						|
        sstr << value;
 | 
						|
        texts[label].value.setString(sstr.str());
 | 
						|
    }
 | 
						|
 | 
						|
    // Update joystick identification
 | 
						|
    void updateIdentification(unsigned int index)
 | 
						|
    {
 | 
						|
        sstr.str("");
 | 
						|
        sstr << "Joystick " << index << ":";
 | 
						|
        texts["ID"].label.setString(sstr.str());
 | 
						|
        texts["ID"].value.setString(sf::Joystick::getIdentification(index).name);
 | 
						|
    }
 | 
						|
 | 
						|
    // Update joystick axes
 | 
						|
    void updateAxes(unsigned int index)
 | 
						|
    {
 | 
						|
        for (unsigned int j = 0; j < sf::Joystick::AxisCount; ++j)
 | 
						|
        {
 | 
						|
            if (sf::Joystick::hasAxis(index, static_cast<sf::Joystick::Axis>(j)))
 | 
						|
                set(axislabels[j], sf::Joystick::getAxisPosition(index, static_cast<sf::Joystick::Axis>(j)));
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    // Update joystick buttons
 | 
						|
    void updateButtons(unsigned int index)
 | 
						|
    {
 | 
						|
        for (unsigned int j = 0; j < sf::Joystick::getButtonCount(index); ++j)
 | 
						|
        {
 | 
						|
            sstr.str("");
 | 
						|
            sstr << "Button " << j;
 | 
						|
 | 
						|
            set(sstr.str().c_str(), sf::Joystick::isButtonPressed(index, j));
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    // Helper to update displayed joystick values
 | 
						|
    void updateValues(unsigned int index)
 | 
						|
    {
 | 
						|
        if (sf::Joystick::isConnected(index)) {
 | 
						|
            // Update the label-value sf::Text objects based on the current joystick state
 | 
						|
            updateIdentification(index);
 | 
						|
            updateAxes(index);
 | 
						|
            updateButtons(index);
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////
 | 
						|
/// Entry point of application
 | 
						|
///
 | 
						|
/// \return Application exit code
 | 
						|
///
 | 
						|
////////////////////////////////////////////////////////////
 | 
						|
int main()
 | 
						|
{
 | 
						|
    // Create the window of the application
 | 
						|
    sf::RenderWindow window(sf::VideoMode(400, 680), "Joystick", sf::Style::Close);
 | 
						|
    window.setVerticalSyncEnabled(true);
 | 
						|
 | 
						|
    // Load the text font
 | 
						|
    sf::Font font;
 | 
						|
    if (!font.loadFromFile("resources/sansation.ttf"))
 | 
						|
        return EXIT_FAILURE;
 | 
						|
 | 
						|
    // Set up our string conversion parameters
 | 
						|
    sstr.precision(2);
 | 
						|
    sstr.setf(std::ios::fixed | std::ios::boolalpha);
 | 
						|
 | 
						|
    // Set up our joystick identification sf::Text objects
 | 
						|
    texts["ID"].label.setPosition(5.f, 5.f);
 | 
						|
    texts["ID"].value.setPosition(80.f, 5.f);
 | 
						|
 | 
						|
    texts["ID"].label.setString("<Not Connected>");
 | 
						|
    texts["ID"].value.setString("");
 | 
						|
 | 
						|
    // Set up our threshold sf::Text objects
 | 
						|
    sstr.str("");
 | 
						|
    sstr << threshold << "  (Change with up/down arrow keys)";
 | 
						|
 | 
						|
    texts["Threshold"].label.setPosition(5.f, 5.f + 2 * font.getLineSpacing(14));
 | 
						|
    texts["Threshold"].value.setPosition(80.f, 5.f + 2 * font.getLineSpacing(14));
 | 
						|
 | 
						|
    texts["Threshold"].label.setString("Threshold:");
 | 
						|
    texts["Threshold"].value.setString(sstr.str());
 | 
						|
 | 
						|
    // Set up our label-value sf::Text objects
 | 
						|
    for (unsigned int i = 0; i < sf::Joystick::AxisCount; ++i)
 | 
						|
    {
 | 
						|
        JoystickObject& object = texts[axislabels[i]];
 | 
						|
 | 
						|
        object.label.setPosition(5.f, 5.f + ((i + 4) * font.getLineSpacing(14)));
 | 
						|
        object.label.setString(std::string(axislabels[i]) + ":");
 | 
						|
 | 
						|
        object.value.setPosition(80.f, 5.f + ((i + 4) * font.getLineSpacing(14)));
 | 
						|
        object.value.setString("N/A");
 | 
						|
    }
 | 
						|
 | 
						|
    for (unsigned int i = 0; i < sf::Joystick::ButtonCount; ++i)
 | 
						|
    {
 | 
						|
        sstr.str("");
 | 
						|
        sstr << "Button " << i;
 | 
						|
        JoystickObject& object = texts[sstr.str()];
 | 
						|
 | 
						|
        object.label.setPosition(5.f, 5.f + ((sf::Joystick::AxisCount + i + 4) * font.getLineSpacing(14)));
 | 
						|
        object.label.setString(sstr.str() + ":");
 | 
						|
 | 
						|
        object.value.setPosition(80.f, 5.f + ((sf::Joystick::AxisCount + i + 4) * font.getLineSpacing(14)));
 | 
						|
        object.value.setString("N/A");
 | 
						|
    }
 | 
						|
 | 
						|
    for (Texts::iterator it = texts.begin(); it != texts.end(); ++it)
 | 
						|
    {
 | 
						|
        it->second.label.setFont(font);
 | 
						|
        it->second.label.setCharacterSize(14);
 | 
						|
        it->second.label.setFillColor(sf::Color::White);
 | 
						|
 | 
						|
        it->second.value.setFont(font);
 | 
						|
        it->second.value.setCharacterSize(14);
 | 
						|
        it->second.value.setFillColor(sf::Color::White);
 | 
						|
    }
 | 
						|
 | 
						|
    // Update initially displayed joystick values if a joystick is already connected on startup
 | 
						|
    for (unsigned int i = 0; i < sf::Joystick::Count; ++i)
 | 
						|
    {
 | 
						|
        if (sf::Joystick::isConnected(i))
 | 
						|
        {
 | 
						|
            updateValues(i);
 | 
						|
            break;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    while (window.isOpen())
 | 
						|
    {
 | 
						|
        // Handle events
 | 
						|
        sf::Event event;
 | 
						|
        while (window.pollEvent(event))
 | 
						|
        {
 | 
						|
            // Window closed or escape key pressed: exit
 | 
						|
            if ((event.type == sf::Event::Closed) ||
 | 
						|
               ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape)))
 | 
						|
            {
 | 
						|
                window.close();
 | 
						|
                break;
 | 
						|
            }
 | 
						|
            else if ((event.type == sf::Event::JoystickButtonPressed) ||
 | 
						|
                     (event.type == sf::Event::JoystickButtonReleased) ||
 | 
						|
                     (event.type == sf::Event::JoystickMoved) ||
 | 
						|
                     (event.type == sf::Event::JoystickConnected))
 | 
						|
            {
 | 
						|
                // Update displayed joystick values
 | 
						|
                updateValues(event.joystickConnect.joystickId);
 | 
						|
            }
 | 
						|
            else if (event.type == sf::Event::JoystickDisconnected)
 | 
						|
            {
 | 
						|
                // Reset displayed joystick values to empty
 | 
						|
                for (Texts::iterator it = texts.begin(); it != texts.end(); ++it)
 | 
						|
                    it->second.value.setString("N/A");
 | 
						|
 | 
						|
                texts["ID"].label.setString("<Not Connected>");
 | 
						|
                texts["ID"].value.setString("");
 | 
						|
 | 
						|
                sstr.str("");
 | 
						|
                sstr << threshold << "  (Change with up/down arrow keys)";
 | 
						|
 | 
						|
                texts["Threshold"].value.setString(sstr.str());
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        // Update threshold if the user wants to change it
 | 
						|
        float newThreshold = threshold;
 | 
						|
 | 
						|
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
 | 
						|
            newThreshold += 0.1f;
 | 
						|
 | 
						|
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
 | 
						|
            newThreshold -= 0.1f;
 | 
						|
 | 
						|
        newThreshold = std::min(std::max(newThreshold, 0.1f), 100.0f);
 | 
						|
 | 
						|
        if (newThreshold != threshold)
 | 
						|
        {
 | 
						|
            threshold = newThreshold;
 | 
						|
            window.setJoystickThreshold(threshold);
 | 
						|
 | 
						|
            sstr.str("");
 | 
						|
            sstr << threshold << "  (Change with up/down arrow keys)";
 | 
						|
 | 
						|
            texts["Threshold"].value.setString(sstr.str());
 | 
						|
        }
 | 
						|
 | 
						|
        // Clear the window
 | 
						|
        window.clear();
 | 
						|
 | 
						|
        // Draw the label-value sf::Text objects
 | 
						|
        for (Texts::const_iterator it = texts.begin(); it != texts.end(); ++it)
 | 
						|
        {
 | 
						|
            window.draw(it->second.label);
 | 
						|
            window.draw(it->second.value);
 | 
						|
        }
 | 
						|
 | 
						|
        // Display things on screen
 | 
						|
        window.display();
 | 
						|
    }
 | 
						|
}
 |