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

Author Topic: Need Help Speeding This Up  (Read 3353 times)

0 Members and 1 Guest are viewing this topic.

n0body

  • Newbie
  • *
  • Posts: 10
    • View Profile
Need Help Speeding This Up
« on: March 17, 2015, 09:47:36 am »
Hi, I'm not very good at programming.  ;D

I'm trying to learn more with SFML.

I wrote this joystick input test program to test a maximum of 4 controllers it's got a few problems mostly the fact that it's very sluggish at least for me.

Can anyone tell me why it's so slow? I feel like I'm doing something wrong.

Here's the whole thing

#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/System/Vector2.hpp>
#include <SFML/System/String.hpp>
#include <sstream>

#define SSTR( x ) dynamic_cast< std::ostringstream & >( \
        ( std::ostringstream() << std::dec << x ) ).str()


void renderJoyStickStuff(sf::RenderWindow* wind);
void renderCrosshair(sf::RenderWindow* wind, float Xpos, float Ypos, float deadZone, sf::Color crosshairColor, int index);
sf::Text defTextObj(sf::Font fnt, int charSz, sf::Color clr, sf::Text::Style style, int xPosi, int yPosi, sf::String txt);
int centerWindowX = 0;
int centerWindowY = 0;
sf::RectangleShape xline(sf::Vector2f(20, 1));
sf::RectangleShape yline(sf::Vector2f(20, 1));
sf::Font font;
static const int MaxControllers = 4;
float curCrosshairxPos[MaxControllers - 1];
float curCrosshairyPos[MaxControllers - 1];
sf::Color textColors[3];

int main()
{
    sf::RenderWindow window(sf::VideoMode(800, 600), "SFML Joystick Input Test");
    centerWindowX = 400;
    centerWindowY = 300;
    for(int i = 0; i < MaxControllers - 1; i++)
    {
        curCrosshairxPos[i] = centerWindowX;
        curCrosshairyPos[i] = centerWindowY;
    }
    yline.setRotation(90.0f);    
    textColors[0] = sf::Color(255, 0, 0);
    textColors[1] = sf::Color(255, 102, 0);
    textColors[2] = sf::Color(255, 255, 0);
    textColors[3] = sf::Color(0, 255, 0);
    if (!font.loadFromFile("UbuntuMono-B.ttf"))
    {
        return 0;
    }
    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
            window.clear();            
            renderJoyStickStuff(&window);
            window.display();
        }
    }

    return 0;
}

void renderJoyStickStuff(sf::RenderWindow* wind)
{
    int j1BtnCount = 0, j2BtnCount = 0, textXpos = 2;
    //draw text for each controller
    for(int c = 0; c < MaxControllers; c++)
    {
        int textYpos = 0;
        //controller was detected
        if(sf::Joystick::isConnected(c))
        {
            wind->draw(defTextObj(font, 14, textColors[c], sf::Text::Regular, textXpos, textYpos, "Joy " + SSTR(c) + ": " + sf::Joystick::getIdentification(c).name));
            textYpos += 20;
            //draw text for each button
            for(int i = 0; i < sf::Joystick::getButtonCount(c); i++)
            {
                if(sf::Joystick::isButtonPressed(c, i))
                    wind->draw(defTextObj(font, 14, textColors[c], sf::Text::Regular, textXpos + 8, textYpos, "-Button" + SSTR(i) + ": Pressed"));
                else
                    wind->draw(defTextObj(font, 14, textColors[c], sf::Text::Regular, textXpos + 8, textYpos, "-Button" + SSTR(i) + ": "));
                textYpos += 20;
            }
            //draw text for x axis if any on joystick
            if(sf::Joystick::hasAxis(c, sf::Joystick::X))
            {  
                wind->draw(defTextObj(font, 14, textColors[c], sf::Text::Regular, textXpos + 8, textYpos, "-X Axis:" + SSTR(sf::Joystick::getAxisPosition(c, sf::Joystick::X))));
                textYpos += 20;
            }
            //draw text for y axis if any on joystick
            if(sf::Joystick::hasAxis(c, sf::Joystick::Y))
            {  
                wind->draw(defTextObj(font, 14, textColors[c], sf::Text::Regular, textXpos + 8, textYpos, "-Y Axis:" + SSTR(sf::Joystick::getAxisPosition(c, sf::Joystick::Y))));
                textYpos += 20;
            }
            textXpos += 200;
            //render a crosshair for each detected controller
            renderCrosshair(wind, sf::Joystick::getAxisPosition(c, sf::Joystick::X), sf::Joystick::getAxisPosition(c, sf::Joystick::Y), 25.0f, textColors[c], c);
        }
        //controller not detected :(
        else
        {
            wind->draw(defTextObj(font, 14, textColors[c], sf::Text::Regular, textXpos, textYpos, "Joy " + SSTR(c) + ": Not Detected"));
            textXpos += 200;
        }
    }
}

void renderCrosshair(sf::RenderWindow* wind, float Xpos, float Ypos, float deadZone, sf::Color crosshairColor, int index)
{
    //set the color
    xline.setFillColor(crosshairColor);
    yline.setFillColor(crosshairColor);
    //analog stick is pressed left
    if((curCrosshairxPos[index] > 10.0f) && (Xpos < -deadZone))
    {
        curCrosshairxPos[index] -= 10.0f;
    }
    //analog stick is pressed right
    if((curCrosshairxPos[index] < float(centerWindowX) * 2 - 10.0f) && (Xpos > deadZone))
    {
        curCrosshairxPos[index] += 10.0f;
    }
    //analog stick is moved up
    if((curCrosshairyPos[index] > 10.0f) && (Ypos < -deadZone))
    {
        curCrosshairyPos[index] -= 10.0f;
    }
    //analog stick is moved down
    if((curCrosshairyPos[index] < float(centerWindowY) * 2 - 10.0f) && (Ypos > deadZone))
    {
        curCrosshairyPos[index] += 10.0f;
    }
    //analog stick is released
    if((Xpos < deadZone) && (Xpos > -deadZone) && (Ypos < deadZone) && (Ypos > -deadZone))
    {
        if(curCrosshairxPos[index] > float(centerWindowX))
            curCrosshairxPos[index] -= 10.0f;
        if(curCrosshairxPos[index] < float(centerWindowX))
            curCrosshairxPos[index] += 10.0f;
        if(curCrosshairyPos[index] > float(centerWindowY))
            curCrosshairyPos[index] -= 10.0f;
        if(curCrosshairyPos[index] < float(centerWindowY))
            curCrosshairyPos[index] += 10.0f;
    }
    xline.setPosition(int(curCrosshairxPos[index]) - 10, int(curCrosshairyPos[index]));
    yline.setPosition(int(curCrosshairxPos[index]), int(curCrosshairyPos[index]) - 10);
    wind->draw(xline);
    wind->draw(yline);
    return;
}

sf::Text defTextObj(sf::Font fnt, int charSz, sf::Color clr, sf::Text::Style style, int xPosi, int yPosi, sf::String txt)
{
    sf::Text txtObj(txt, fnt, charSz);
    txtObj.setStyle(style);
    txtObj.setPosition(xPosi, yPosi);
    txtObj.setColor(clr);
    return txtObj;
}

edit: I didn't write the SSTR() thing, I stole it from the internet because I'm too lazy and stupid to figure out how to cast a number to string on my own :D
« Last Edit: March 17, 2015, 09:49:28 am by n0body »

victorlevasseur

  • Full Member
  • ***
  • Posts: 206
    • View Profile
Re: Need Help Speeding This Up
« Reply #1 on: March 17, 2015, 09:53:29 am »
Yu should put clear, the drawing instructions and display outside the event loop but in the main loop after the event loop.

n0body

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Need Help Speeding This Up
« Reply #2 on: March 17, 2015, 10:14:47 am »
Wow, thanks.

I also added 20.0f instead of 10.0f to the crosshair position in renderCrosshair() and it works exactly like I wanted it to now.

I feel pretty stupid now, I spent a few hours trying to figure out what was wrong :P

This code works perfect now  :D

#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/System/Vector2.hpp>
#include <SFML/System/String.hpp>
#include <sstream>

#define SSTR( x ) dynamic_cast< std::ostringstream & >( \
        ( std::ostringstream() << std::dec << x ) ).str()


void renderJoyStickStuff(sf::RenderWindow* wind);
void renderCrosshair(sf::RenderWindow* wind, float Xpos, float Ypos, float deadZone, sf::Color crosshairColor, int index);
sf::Text defTextObj(sf::Font fnt, int charSz, sf::Color clr, sf::Text::Style style, int xPosi, int yPosi, sf::String txt);
int centerWindowX = 0;
int centerWindowY = 0;
sf::RectangleShape xline(sf::Vector2f(20, 1));
sf::RectangleShape yline(sf::Vector2f(20, 1));
sf::Font font;
static const int MaxControllers = 4;
float curCrosshairxPos[MaxControllers - 1];
float curCrosshairyPos[MaxControllers - 1];
sf::Color textColors[3];

int main()
{
    sf::RenderWindow window(sf::VideoMode(800, 600), "SFML Joystick Input Test");
    centerWindowX = 400;
    centerWindowY = 300;
    for(int i = 0; i < MaxControllers - 1; i++)
    {
        curCrosshairxPos[i] = centerWindowX;
        curCrosshairyPos[i] = centerWindowY;
    }
    yline.setRotation(90.0f);    
    textColors[0] = sf::Color(255, 0, 0);
    textColors[1] = sf::Color(255, 102, 0);
    textColors[2] = sf::Color(255, 255, 0);
    textColors[3] = sf::Color(0, 255, 0);
    if (!font.loadFromFile("UbuntuMono-B.ttf"))
    {
        return 0;
    }
    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
        }
        window.clear();            
        renderJoyStickStuff(&window);
        window.display();
    }

    return 0;
}

void renderJoyStickStuff(sf::RenderWindow* wind)
{
    int j1BtnCount = 0, j2BtnCount = 0, textXpos = 2;
    //draw text for each controller
    for(int c = 0; c < MaxControllers; c++)
    {
        int textYpos = 0;
        //controller was detected
        if(sf::Joystick::isConnected(c))
        {
            wind->draw(defTextObj(font, 14, textColors[c], sf::Text::Regular, textXpos, textYpos, "Joy " + SSTR(c) + ": " + sf::Joystick::getIdentification(c).name));
            textYpos += 20;
            //draw text for each button
            for(int i = 0; i < sf::Joystick::getButtonCount(c); i++)
            {
                if(sf::Joystick::isButtonPressed(c, i))
                    wind->draw(defTextObj(font, 14, textColors[c], sf::Text::Regular, textXpos + 8, textYpos, "-Button" + SSTR(i) + ": Pressed"));
                else
                    wind->draw(defTextObj(font, 14, textColors[c], sf::Text::Regular, textXpos + 8, textYpos, "-Button" + SSTR(i) + ": "));
                textYpos += 20;
            }
            //draw text for x axis if any on joystick
            if(sf::Joystick::hasAxis(c, sf::Joystick::X))
            {  
                wind->draw(defTextObj(font, 14, textColors[c], sf::Text::Regular, textXpos + 8, textYpos, "-X Axis:" + SSTR(sf::Joystick::getAxisPosition(c, sf::Joystick::X))));
                textYpos += 20;
            }
            //draw text for y axis if any on joystick
            if(sf::Joystick::hasAxis(c, sf::Joystick::Y))
            {  
                wind->draw(defTextObj(font, 14, textColors[c], sf::Text::Regular, textXpos + 8, textYpos, "-Y Axis:" + SSTR(sf::Joystick::getAxisPosition(c, sf::Joystick::Y))));
                textYpos += 20;
            }
            textXpos += 200;
            //render a crosshair for each detected controller
            renderCrosshair(wind, sf::Joystick::getAxisPosition(c, sf::Joystick::X), sf::Joystick::getAxisPosition(c, sf::Joystick::Y), 25.0f, textColors[c], c);
        }
        //controller not detected :(
        else
        {
            wind->draw(defTextObj(font, 14, textColors[c], sf::Text::Regular, textXpos, textYpos, "Joy " + SSTR(c) + ": Not Detected"));
            textXpos += 200;
        }
    }
}

void renderCrosshair(sf::RenderWindow* wind, float Xpos, float Ypos, float deadZone, sf::Color crosshairColor, int index)
{
    //set the color
    xline.setFillColor(crosshairColor);
    yline.setFillColor(crosshairColor);
    //analog stick is pressed left
    if((curCrosshairxPos[index] > 10.0f) && (Xpos < -deadZone))
    {
        curCrosshairxPos[index] -= 20.0f;
    }
    //analog stick is pressed right
    if((curCrosshairxPos[index] < float(centerWindowX) * 2 - 10.0f) && (Xpos > deadZone))
    {
        curCrosshairxPos[index] += 20.0f;
    }
    //analog stick is moved up
    if((curCrosshairyPos[index] > 10.0f) && (Ypos < -deadZone))
    {
        curCrosshairyPos[index] -= 20.0f;
    }
    //analog stick is moved down
    if((curCrosshairyPos[index] < float(centerWindowY) * 2 - 10.0f) && (Ypos > deadZone))
    {
        curCrosshairyPos[index] += 20.0f;
    }
    //analog stick is released
    if((Xpos < deadZone) && (Xpos > -deadZone) && (Ypos < deadZone) && (Ypos > -deadZone))
    {
        if(curCrosshairxPos[index] > float(centerWindowX))
            curCrosshairxPos[index] -= 20.0f;
        if(curCrosshairxPos[index] < float(centerWindowX))
            curCrosshairxPos[index] += 20.0f;
        if(curCrosshairyPos[index] > float(centerWindowY))
            curCrosshairyPos[index] -= 20.0f;
        if(curCrosshairyPos[index] < float(centerWindowY))
            curCrosshairyPos[index] += 20.0f;
    }
    xline.setPosition(int(curCrosshairxPos[index]) - 10, int(curCrosshairyPos[index]));
    yline.setPosition(int(curCrosshairxPos[index]), int(curCrosshairyPos[index]) - 10);
    wind->draw(xline);
    wind->draw(yline);
    return;
}

sf::Text defTextObj(sf::Font fnt, int charSz, sf::Color clr, sf::Text::Style style, int xPosi, int yPosi, sf::String txt)
{
    sf::Text txtObj(txt, fnt, charSz);
    txtObj.setStyle(style);
    txtObj.setPosition(xPosi, yPosi);
    txtObj.setColor(clr);
    return txtObj;
}

SpeCter

  • Full Member
  • ***
  • Posts: 151
    • View Profile
Re: Need Help Speeding This Up
« Reply #3 on: March 17, 2015, 10:43:16 am »
A little sidenote:

If you are able to use C++11, you can use the function std::to_string to convert numbers to strings.

n0body

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Need Help Speeding This Up
« Reply #4 on: March 18, 2015, 04:08:58 am »
A little sidenote:

If you are able to use C++11, you can use the function std::to_string to convert numbers to strings.

Is there any good reason why I shouldn't use that if it is available?

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11033
    • View Profile
    • development blog
    • Email
Re: Need Help Speeding This Up
« Reply #5 on: March 18, 2015, 07:49:35 am »
That question doesn't make a lot of sense, but to answer it: no there's no good reason not to use it.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

n0body

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Need Help Speeding This Up
« Reply #6 on: March 19, 2015, 03:50:56 am »
I basically meant if I use it, will it still compile across all platforms as easily.

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Re: Need Help Speeding This Up
« Reply #7 on: March 19, 2015, 09:08:57 am »
Anything in the standard can be considerate as good and portable. That should 99% of the time be your first choice in fact (e.g. don't reimplement things).
SFML / OS X developer