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

Author Topic: SFML joystick problem?  (Read 12952 times)

0 Members and 1 Guest are viewing this topic.

n0body

  • Newbie
  • *
  • Posts: 10
    • View Profile
SFML joystick problem?
« on: March 16, 2015, 02:26:52 am »
Hi, I wrote some shitty code to test out sfml's joystick stuff

Here's the shitty code (I just threw this together in like 5 minutes)
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>


void renderJoyStickText(sf::RenderWindow* wind);


int main()
{
    sf::RenderWindow window(sf::VideoMode(800, 600), "SFML Joystick Input Test");
    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
            window.clear();            
            renderJoyStickText(&window);
            window.display();
        }
    }

    return 0;
}


void renderJoyStickText(sf::RenderWindow* wind)
{
    int joy2Ypos = 20;
    bool joy1identified = false;
   
    sf::Font font;
    sf::Text joy1_text;
    sf::Text joy2_text;
    sf::Text joy1_nameText;
    if (!font.loadFromFile("UbuntuMono-B.ttf"))
    {
        return;
    }
    joy1_text.setFont(font);
    joy1_text.setCharacterSize(14);
    joy1_text.setColor(sf::Color::Yellow);
    joy1_text.setStyle(sf::Text::Regular);
    joy1_text.setPosition(2,0);
    joy2_text.setFont(font);
    joy2_text.setCharacterSize(14);
    joy2_text.setColor(sf::Color::Red);
    joy2_text.setStyle(sf::Text::Regular);
    joy2_text.setPosition(2,joy2Ypos);
    if(sf::Joystick::isConnected(0))
    {
        joy1_text.setString("Joy 1: True");
        joy1_nameText.setFont(font);
        joy1_nameText.setCharacterSize(14);
        joy1_nameText.setColor(sf::Color::Yellow);
        joy1_nameText.setStyle(sf::Text::Regular);
        joy1_nameText.setPosition(5,20);
        joy1_nameText.setString("-name:" + sf::Joystick::getIdentification(0).name);
        joy2Ypos += 20;
        joy1identified = true;
    }
    else
    {
        joy1_text.setString("Joy 1: False");
        if(joy1identified)
        {
            joy1identified = false;
            joy2Ypos = 20;
        }
    }
    if(sf::Joystick::isConnected(1))
    {
        joy2_text.setString("Joy 2: True");
    }
    else
    {
        joy2_text.setString("Joy 2: False");
    }
    joy2_text.setPosition(2,joy2Ypos);
    wind->draw(joy1_text);
    if(joy1identified)
        wind->draw(joy1_nameText);
    wind->draw(joy2_text);
}


Now, here's what happens when i run this:

First I get this weird output when the program starts:
Unable to get joystick attribute. Could not find USB device for joystick at index 0.
Unable to get joystick attribute. Could not find USB device for joystick at index 0.
Failed to flush inotify of all pending joystick events.
Unable to get joystick attribute. Could not find USB device for joystick at index 1.
Unable to get joystick attribute. Could not find USB device for joystick at index 1.
 


the window lags a little bit, but then seemingly works fine.

Now, if I unplug the joystick while the program is still running it spams the console with this:

Failed to flush inotify of all pending joystick events.
Failed to flush inotify of all pending joystick events.
Failed to flush inotify of all pending joystick events.
Failed to flush inotify of all pending joystick events.
Failed to flush inotify of all pending joystick events.
Failed to flush inotify of all pending joystick events.
 

Here's a shitty video I made to show what happens.
https://www.youtube.com/embed/sK0pgl1vxnA

The joystick I'm using is a crappy $4.00 dual port playstation 2 -> usb converter with only one joystick plugged into slot one. It always registers both joysticks as plugged in when i plug it into a usb port even if I don't have any joysticks plugged into either slot. This is normal, It's just how the device was made I guess.

So, why does this happen?

When I was using older libraries, I didn't get the errors when the program launched, but I couldn't use the sf::Joystick::getIdentification function because it wasn't there yet I guess.

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: SFML joystick problem?
« Reply #1 on: March 16, 2015, 02:38:46 am »
If you built SFML yourself, can you make the necessary changes to this part of SFML/src/SFML/Window/Unix/JoystickImpl.cpp to print out errno as well?

Something like:
if (lseek(notifyFd, 0, SEEK_END) < 0)
    err() << "Failed to flush inotify of all pending joystick events: " << errno << std::endl;

Run the same test and post back here with the printed error number. :)
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

n0body

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: SFML joystick problem?
« Reply #2 on: March 16, 2015, 02:44:37 am »
If you built SFML yourself, can you make the necessary changes to this part of SFML/src/SFML/Window/Unix/JoystickImpl.cpp to print out errno as well?

Something like:
if (lseek(notifyFd, 0, SEEK_END) < 0)
    err() << "Failed to flush inotify of all pending joystick events: " << errno << std::endl;

Run the same test and post back here with the printed error number. :)

I actually didn't build it myself, but I'll build it myself and add that then report back with what happens.

n0body

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: SFML joystick problem?
« Reply #3 on: March 16, 2015, 03:47:56 am »
Ok, here's what it's spamming now that I rebuilt with that code when I unplug while it's running:

Failed to flush inotify of all pending joystick events.29
Failed to flush inotify of all pending joystick events.29
Failed to flush inotify of all pending joystick events.29
Failed to flush inotify of all pending joystick events.29
Failed to flush inotify of all pending joystick events.29
Failed to flush inotify of all pending joystick events.29
Failed to flush inotify of all pending joystick events.29
Failed to flush inotify of all pending joystick events.29
Failed to flush inotify of all pending joystick events.29
Failed to flush inotify of all pending joystick events.29
Failed to flush inotify of all pending joystick events.29
 

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: SFML joystick problem?
« Reply #4 on: March 16, 2015, 05:42:58 am »
Hmm... Yeah this error has happened at least once in the past. For some mysterious reason the seek fails even though the file descriptor is still open. Maybe it might be worth considering reverting to the previous behaviour of just reading until there is nothing left. That didn't cause any such mysterious problems if I remember correctly.

Here is the new block that flushes the file descriptor, replace the old one with it and it should not flood your output any longer:
// Flush all the pending events
struct inotify_event event;
int result = read(notifyFd, &event, sizeof(event));
while ((result >= 0) && hasInotifyEvent())
    result = read(notifyFd, &event, sizeof(event));

if (result < 0)
    err() << "Failed to flush inotify of all pending joystick events." << std::endl;

As for the USB device issue, can you post the output of "ls -l /dev/input/*" and "lsusb -v" both with and without your device plugged in? Thanks.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

n0body

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: SFML joystick problem?
« Reply #5 on: March 16, 2015, 06:12:39 am »
Ok, I'll try that out. :D

Here's the output, it was too long to paste in here so I put it on pastebin.
http://pastebin.com/YapxdZqX


EDIT:

I recompiled with that block and commented out the other part, and it's still spamming with the error, I recompiled with test at the end to make sure it's actually changed and using the new code:
Failed to flush inotify of all pending joystick events. test

EDIT 2:
Don't know if this helps anything, but result is always -1, I recompiled with this change:
if (result < 0)
            err() << "Failed to flush inotify of all pending joystick events. result:" << result << std::endl;

and it spams output with:
Failed to flush inotify of all pending joystick events. result:-1

EDIT 3:  :P
Recompiled with this change, and it no longer spams the output, everything works as it should when unplugging/plugging the usb joystick:
        if (result < -1)
            err() << "Failed to flush inotify of all pending joystick events. result:" << result << std::endl;
I don't know if this is wrong, but it has silenced the error spam.
« Last Edit: March 16, 2015, 06:55:59 am by n0body »

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: SFML joystick problem?
« Reply #6 on: March 16, 2015, 07:06:44 am »
Can you provide the output of the following command when the device is plugged in?
Code: [Select]
find /dev/input/ -iname 'js*' -exec udevadm info -q all '{}' \;It will query udev for the device information (including path) that SFML fails to query. It should help solve the problem.

This might also be related (or even the same as) an existing issue on the tracker:
https://github.com/SFML/SFML/issues/776

EDIT: If the udevadm command isn't available on your system, you might have to install the udev package.
« Last Edit: March 16, 2015, 07:08:53 am by binary1248 »
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

n0body

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: SFML joystick problem?
« Reply #7 on: March 16, 2015, 08:00:59 am »
Yeah, here's the output

$ find /dev/input/ -iname 'js*' -exec udevadm info -q all '{}' \;
P: /devices/pci0000:00/0000:00:10.0/usb6/6-1/6-1:1.0/input/input121/js1
N: input/js1
S: input/by-id/usb-0810_Twin_USB_Joystick-joystick
S: input/by-path/pci-0000:00:10.0-usb-0:1:1.0-joystick
E: DEVLINKS=/dev/input/by-id/usb-0810_Twin_USB_Joystick-joystick /dev/input/by-path/pci-0000:00:10.0-usb-0:1:1.0-joystick
E: DEVNAME=/dev/input/js1
E: DEVPATH=/devices/pci0000:00/0000:00:10.0/usb6/6-1/6-1:1.0/input/input121/js1
E: ID_BUS=usb
E: ID_FOR_SEAT=input-pci-0000_00_10_0-usb-0_1_1_0
E: ID_INPUT=1
E: ID_INPUT_JOYSTICK=1
E: ID_MODEL=Twin_USB_Joystick
E: ID_MODEL_ENC=Twin\x20USB\x20Joystick
E: ID_MODEL_ID=0001
E: ID_PATH=pci-0000:00:10.0-usb-0:1:1.0
E: ID_PATH_TAG=pci-0000_00_10_0-usb-0_1_1_0
E: ID_REVISION=0106
E: ID_SERIAL=0810_Twin_USB_Joystick
E: ID_TYPE=hid
E: ID_USB_DRIVER=usbhid
E: ID_USB_INTERFACES=:030000:
E: ID_USB_INTERFACE_NUM=00
E: ID_VENDOR=0810
E: ID_VENDOR_ENC=0810
E: ID_VENDOR_ID=0810
E: MAJOR=13
E: MINOR=1
E: SUBSYSTEM=input
E: TAGS=:seat:uaccess:
E: USEC_INITIALIZED=90765466996

P: /devices/pci0000:00/0000:00:10.0/usb6/6-1/6-1:1.0/input/input120/js0
N: input/js0
S: input/by-id/usb-0810_Twin_USB_Joystick-joystick
S: input/by-path/pci-0000:00:10.0-usb-0:1:1.0-joystick
E: DEVLINKS=/dev/input/by-id/usb-0810_Twin_USB_Joystick-joystick /dev/input/by-path/pci-0000:00:10.0-usb-0:1:1.0-joystick
E: DEVNAME=/dev/input/js0
E: DEVPATH=/devices/pci0000:00/0000:00:10.0/usb6/6-1/6-1:1.0/input/input120/js0
E: ID_BUS=usb
E: ID_FOR_SEAT=input-pci-0000_00_10_0-usb-0_1_1_0
E: ID_INPUT=1
E: ID_INPUT_JOYSTICK=1
E: ID_MODEL=Twin_USB_Joystick
E: ID_MODEL_ENC=Twin\x20USB\x20Joystick
E: ID_MODEL_ID=0001
E: ID_PATH=pci-0000:00:10.0-usb-0:1:1.0
E: ID_PATH_TAG=pci-0000_00_10_0-usb-0_1_1_0
E: ID_REVISION=0106
E: ID_SERIAL=0810_Twin_USB_Joystick
E: ID_TYPE=hid
E: ID_USB_DRIVER=usbhid
E: ID_USB_INTERFACES=:030000:
E: ID_USB_INTERFACE_NUM=00
E: ID_VENDOR=0810
E: ID_VENDOR_ENC=0810
E: ID_VENDOR_ID=0810
E: MAJOR=13
E: MINOR=0
E: SUBSYSTEM=input
E: TAGS=:seat:uaccess:
E: USEC_INITIALIZED=1690765466899
 



I've noticed that if you plug the joystick in after you open the program, or if you unplug then replug there's a bunch of latency when calling sf::Joystick::isButtonPressed(), but if I have the joystick already plugged in and then run the program, there isn't any latency when calling sf::Joystick::isButtonPressed.

I slapped this crap together real quick to test the buttons.

Of course, I noticed after writing this that it is actually the wrong way to get joystick input, I should have used joystickbutton events, but it does work and I'm still learning  ;D
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <sstream>


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


void renderJoyStickText(sf::RenderWindow* wind);

int main()
{
    sf::RenderWindow window(sf::VideoMode(800, 600), "SFML Joystick Input Test");
    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
            window.clear();            
            renderJoyStickText(&window);
            window.display();
        }
    }

    return 0;
}


void renderJoyStickText(sf::RenderWindow* wind)
{
    int joy2Ypos = 20;
    bool joy1identified = false;
    int j1BtnCount = 0;
   
    sf::Font font;
    sf::Text joy1_text;
    sf::Text joy2_text;
    sf::Text joy1_nameText;
    if (!font.loadFromFile("UbuntuMono-B.ttf"))
    {
        return;
    }
    joy1_text.setFont(font);
    joy1_text.setCharacterSize(14);
    joy1_text.setColor(sf::Color::Yellow);
    joy1_text.setStyle(sf::Text::Regular);
    joy1_text.setPosition(2,0);
    joy2_text.setFont(font);
    joy2_text.setCharacterSize(14);
    joy2_text.setColor(sf::Color::Red);
    joy2_text.setStyle(sf::Text::Regular);
    joy2_text.setPosition(2,joy2Ypos);
    if(sf::Joystick::isConnected(0))
    {
        joy1_text.setString("Joy 1: True");
        joy1_nameText.setFont(font);
        joy1_nameText.setCharacterSize(14);
        joy1_nameText.setColor(sf::Color::Yellow);
        joy1_nameText.setStyle(sf::Text::Regular);
        joy1_nameText.setPosition(5,20);
        joy1_nameText.setString("-name:" + sf::Joystick::getIdentification(0).name);
        joy2Ypos += 20;
        joy1identified = true;
    }
    else
    {
        joy1_text.setString("Joy 1: False");
        if(joy1identified)
        {
            joy1identified = false;
            joy2Ypos = 20;
        }
    }
    if(sf::Joystick::isConnected(1))
    {
        joy2_text.setString("Joy 2: True");
    }
    else
    {
        joy2_text.setString("Joy 2: False");
    }
    wind->draw(joy1_text);
    if(joy1identified)
    {
        wind->draw(joy1_nameText);
        j1BtnCount = sf::Joystick::getButtonCount(0);
        sf::Text j1BtnText[j1BtnCount];
        //draw text for each button
        for(int i = 0; i < j1BtnCount; i++)
        {
            joy2Ypos += 20;
            j1BtnText[i].setFont(font);
            j1BtnText[i].setCharacterSize(14);
            j1BtnText[i].setColor(sf::Color::Yellow);
            j1BtnText[i].setStyle(sf::Text::Regular);
            j1BtnText[i].setPosition(5, joy2Ypos - 20);
            if(sf::Joystick::isButtonPressed(0, i))
                j1BtnText[i].setString("Button " + SSTR(i) + ": Pressed");
            else
                j1BtnText[i].setString("Button " + SSTR(i) + ": ");
            wind->draw(j1BtnText[i]);
        }
    }
    joy2_text.setPosition(2,joy2Ypos);
    wind->draw(joy2_text);
}

I definitely get the same error messages exactly like that issue, so it's likely the same problem.
« Last Edit: March 16, 2015, 08:21:28 am by n0body »

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: SFML joystick problem?
« Reply #8 on: March 23, 2015, 02:23:12 pm »
I made a pull request with fixes that should apply to your scenario as well.

You can find it here: https://github.com/SFML/SFML/pull/838
The branch is here: https://github.com/SFML/SFML/tree/bugfix/joystick_unix
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

Glocke

  • Sr. Member
  • ****
  • Posts: 289
  • Hobby Dev/GameDev
    • View Profile
Re: SFML joystick problem?
« Reply #9 on: March 28, 2015, 01:00:30 am »
Hi, I also face this problem on my Linux machine. So I compiled your bugfix and the annoying message was gone. Unfortunately the framerate collapses when connecting more gamepads. Here's some testing code:
#include <iostream>
#include <SFML/Window.hpp>

int main() {
        sf::Window window{{50, 50}, "Joystick Test"};
        std::size_t frames = 0u;
        sf::Time elapsed;
       
        while (window.isOpen()) {
                sf::Clock clock;
               
                sf::Event event;
                while (window.pollEvent(event)) {
                        if (event.type == sf::Event::Closed) {
                                window.close();
                        } else if (event.type == sf::Event::JoystickConnected) {
                                std::cout << "Joystick #" << event.joystickConnect.joystickId
                                        << " was connected" << std::endl;
                        } else if (event.type == sf::Event::JoystickDisconnected) {
                                std::cout << "Joystick #" << event.joystickConnect.joystickId
                                        << " was disconnected" << std::endl;
                        }
                }
               
                window.display();
                ++frames;
                elapsed += clock.restart();
                if (elapsed > sf::seconds(1.f)) {
                        elapsed -= sf::seconds(1.f);
                        std::cout << frames << " FPS" << std::endl;
                        frames = 0u;
                }
        }
}
 

And that's the output on my machine (a netbook). An older SFML version was working without any problems (I guess it was 2.0)
63 FPS
60 FPS
60 FPS
59 FPS
60 FPS
60 FPS
60 FPS
60 FPS
Joystick #1 was connected
55 FPS
23 FPS
28 FPS
26 FPS
33 FPS
25 FPS
31 FPS
29 FPS
33 FPS
Joystick #3 was connected
28 FPS
13 FPS
12 FPS
14 FPS
16 FPS
18 FPS
22 FPS
21 FPS
Unable to get name for joystick /dev/input/event7
Failed to get vendor ID of joystick /dev/input/event7
Failed to get product ID of joystick /dev/input/event7
21 FPS
Joystick #1 was disconnected
36 FPS
45 FPS
45 FPS
44 FPS
Unable to get name for joystick /dev/input/event6
Failed to get vendor ID of joystick /dev/input/event6
Failed to get product ID of joystick /dev/input/event6
Joystick #3 was disconnected
54 FPS
60 FPS
^C
 

Also shutting down the entire application is delayed for several seconds (around ~10sec) but I cannot reproduce this each time. There's also another message when disconnecting (see log).
The devices I'm using are two no-name USB gamepads. I haven't had any problems with them yet (I'm using them for years).

If you need further information to bugfix that, just tell me. The machine is:
Linux netbook 3.13.0-32-generic #57-Ubuntu SMP Tue Jul 15 03:51:12 UTC 2014 i686 i686 i686 GNU/Linux

Kind regards
Glocke

/EDIT: My gamepad as a button to activate those sticks (X/Y, U/V axis). Most games map X/Y to the game pads arrow keys if the axis are disabled. So I tried to use them while the axis are enabled:
35 FPS
Joystick #1 has moved axis PovY at -100
Joystick #1 has moved axis PovY at 0
Joystick #1 has moved axis PovY at -100
Joystick #1 has moved axis PovY at 0
29 FPS
Unable to get name for joystick /dev/input/event6
Failed to get vendor ID of joystick /dev/input/event6
Failed to get product ID of joystick /dev/input/event6
Failed to open joystick /dev/input/event6: 24
Failed to open joystick /dev/input/event6: 24
Failed to open joystick /dev/input/event6: 24
Failed to open joystick /dev/input/event6: 24
Failed to open joystick /dev/input/event6: 24
Failed to open joystick /dev/input/event6: 24
Failed to open joystick /dev/input/event6: 24
Joystick #1 has moved axis PovX at 100
Failed to open joystick /dev/input/event6: 24
Failed to open joystick /dev/input/event6: 24
Failed to open joystick /dev/input/event6: 24
Failed to open joystick /dev/input/event6: 24
Failed to open joystick /dev/input/event6: 24
 
PovY seems to be the "up" key... but suddenly the joystick seems to be unavailable and the console is flooded by those failed-to-open's  ???
Unfortunately, I cannot reproduce this behavior each time. But disabling the axis on the gamepad resets the mapping of the "arrow" keys to X/Y axis (as it should).

And yet another edit: I build SFML 2.1 from source and tested my demo app: everything's fine there :)
« Last Edit: March 28, 2015, 01:40:17 am by Glocke »
Current project: Racod's Lair - Rogue-inspired Coop Action RPG

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: SFML joystick problem?
« Reply #10 on: March 28, 2015, 10:48:55 am »
Thanks for testing.

Can you provide the output of:
Code: [Select]
find /dev/input/* -not -path "/dev/input/by-path*" -exec udevadm info -q all '{}' \;and
Code: [Select]
udevadm monitor --propertyThe second command will only print out useful information when you connect/disconnect your devices, so just do what you did when you tested your code and it should be enough information for me.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

Glocke

  • Sr. Member
  • ****
  • Posts: 289
  • Hobby Dev/GameDev
    • View Profile
Re: SFML joystick problem?
« Reply #11 on: March 28, 2015, 11:52:35 am »
Thanks for testing.
I'm happy to help you :)

Code: [Select]
find /dev/input/* -not -path "/dev/input/by-path*" -exec udevadm info -q all '{}' \;
(click to show/hide)

Code: [Select]
udevadm monitor --property
Here's the log from my demo application (just for being complete)
(click to show/hide)

And here's the monitor log:
(click to show/hide)

If you need more information, just ask :)
Current project: Racod's Lair - Rogue-inspired Coop Action RPG

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: SFML joystick problem?
« Reply #12 on: March 28, 2015, 03:13:09 pm »
I just pushed a fixed version that properly ignores evdev device nodes. It should work properly now.

Mind testing the new version? :D
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

Glocke

  • Sr. Member
  • ****
  • Posts: 289
  • Hobby Dev/GameDev
    • View Profile
Re: SFML joystick problem?
« Reply #13 on: March 28, 2015, 03:17:12 pm »
I just pushed a fixed version that properly ignores evdev device nodes. It should work properly now.
Again at https://github.com/SFML/SFML/tree/bugfix/joystick_unix ?

Mind testing the new version? :D
Of course :) I'm in!

Current project: Racod's Lair - Rogue-inspired Coop Action RPG

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: SFML joystick problem?
« Reply #14 on: March 28, 2015, 03:20:39 pm »
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).