A Beginner’s Guide to Joysticks and Fightsticks

I’ve been playing a lot of fighting games and Street Fighter IV recently, and while I’m looking to up my game through practice, I still want to have the right tools for the job – and this means having a good fightstick. I currently have a Mad Catz Tournament Edition (TE) for the Xbox 360 which uses a Sanwa joystick and buttons – and frankly it’s excellent.

However, I’ve been trying to take my new-found fightin’ chops back to some older games like the Street Fighter Alpha series, SNK Vs. Capcom etc, and for that I have an X-Arcade (XA) dual-stick with a PS1/PS2/DC/Gamecube/Wii adapter. While the X-Arcade stick is okay for fighting games, it’s absolutely nowhere near as good as the TE, and quite frankly I perform pretty poorly with it – missing simple shory’s, ‘doukens and supers all over the place.

A MadKatz Tournament Edition fightstick

An X-Arcade Dual Stick joystick

I know I can do these moves consistently on the TE, but I live in a world of fail on the XA i.e. if I flub an ultra on the TE I’m disappointed, but I’m barely able to even make an ultra on the XA. So what’s going on?

Continue reading A Beginner’s Guide to Joysticks and Fightsticks

The Leap motion input device looks incredible

The Leap is a new 3D input motion controller in a similar vein to the Kinect, but with apparently about 200x the resolution – how amazing is that?

To quote the Leap people:

Leap represents an entirely new way to interact with your computers. It’s more accurate than a mouse, as reliable as a keyboard and more sensitive than a touchscreen. For the first time, you can control a computer in three dimensions with your natural hand and finger movements.

I’ve applied for a free dev-kit, so fingers-crossed! Worst case though, the sensor’s only meant to be around the $70 mark when they come out.

Would so love to work with this tech for my Ph.D research… looks like it solves a lot of problems right off the bat. Awesome!

How-To: Get valid integer input in C++ (a stupidly long solution to a stupidly simple problem)

Update: See the comments for a far, far more elegent and robust solution courtesy of the mighty shetboy!


One of the assessments I’ve got my diploma class doing at the moment is to fix all the bugs in some deliberately shonky C++ code. The code just asks for a name (string) and an age in years (int), and it then multiplies the age in years by 365 to give a rough indication of how many days you’ve been alive. So for example if I enter Al and 34 it comes back with:

Hi, Al! You’ve been alive for roughly 12410 days!

The problems come thick and fast though if you want to verify that the age in years entered is really an integer value. You CAN do so like this:

  1. #include <iostream>
  2. using namespace std;
  3.  
  4. int main()
  5. {
  6.     int yearsOld       = 0;
  7.     bool gotValidInput = false;
  8.  
  9.     do
  10.     {
  11.         cout << "Please enter your age in years: ";
  12.         cin >> yearsOld;
  13.  
  14.         if (cin.fail())
  15.         {
  16.             cin.clear();
  17.             cin.ignore();
  18.             cout << "Invalid entry! Whole numbers only, dawg!" << endl;
  19.         }
  20.         else
  21.         {
  22.             // We got some valid input! Set the flag so we can leave the loop!
  23.             gotValidInput = true;
  24.         }
  25.  
  26.     } while ( gotValidInput == false );
  27.  
  28.     cout << "Valid value is: " << yearsOld << endl;
  29.  
  30.     return 0;
  31. }

But you then end up with output like this where each character fails individually:

Please enter your age in years: Mooo...
Invalid entry! Whole numbers only, dawg!
Please enter your age in years: Invalid entry! Whole numbers only, dawg!
Please enter your age in years: Invalid entry! Whole numbers only, dawg!
Please enter your age in years: Invalid entry! Whole numbers only, dawg!
Please enter your age in years: Invalid entry! Whole numbers only, dawg!
Please enter your age in years: Invalid entry! Whole numbers only, dawg!
Please enter your age in years: Invalid entry! Whole numbers only, dawg!
Please enter your age in years:

Obviously that’s no good, so I researched a bit and came up with a solution but –DAMN– it doesn’t feel like the right one… Check out all this clumsiness:

  1. #include <iostream>
  2. #include <sstream>
  3.  
  4. using namespace std;
  5.  
  6. int getValidInteger(string prompt)
  7. {
  8.     bool debug = true;                        // Toggle for verbosity
  9.  
  10.     bool   valid;                             // Our exit flag - we only get out of the do..while loop when this is true
  11.     bool   mixedOperators;                    // Did the user enter a mixture of + and - operators (i.e. -5+3)
  12.     bool   multipleOperators;                 // Did the user enter multiple + or - operators      (i.e. -5-3 or +5+3)
  13.     int    userInt = 0;                       // Integer value we finally return after validation
  14.     string userInput;                         // User input is taken as a string before being wrangled...
  15.     int    foundInvalidInputLocation;         // Character location of any invalid input
  16.  
  17.     string validCharacters  = "+-0123456789"; // All the valid characters we're willing to accept as valid integer input
  18.  
  19.     do
  20.     {
  21.         // Set our initial flags
  22.         valid                     = false;
  23.         mixedOperators            = false;
  24.         multipleOperators         = false;
  25.         foundInvalidInputLocation = 0;
  26.  
  27.         // Display the prompt and get the user input as a string
  28.         cout << endl << prompt << endl;
  29.         getline(cin, userInput);
  30.  
  31.         // Convert the user input string into a input stringstream then...
  32.         istringstream iss(userInput);
  33.  
  34.         // ...try to convert the istringstream into an integer.
  35.         if (iss >> userInt)
  36.         {
  37.             if (debug)
  38.             {
  39.                 cout << "This already is or can be made into a valid integer!" << endl;
  40.             }
  41.  
  42.             // Now cast our input string-stream back to a string and...
  43.             string test = iss.str();
  44.  
  45.             // ...test to see if we found any illegal characters (because "123Foo!" -WILL- convert to the int 123, but we want legit input!
  46.             foundInvalidInputLocation = test.find_first_not_of(validCharacters);
  47.  
  48.             if (debug)
  49.             {
  50.                 cout << "Value of foundInvalidInputLocation is: " << foundInvalidInputLocation << endl;
  51.             }
  52.  
  53.             // Check whether we found an character which cannot be part of a valid int (-1 indicates no invalid character found)
  54.             if (foundInvalidInputLocation != -1)
  55.             {
  56.                 if (debug)
  57.                 {
  58.                     cout << "Although we can cast the provided input to an int..." << endl;
  59.                     cout << "...the original input contained at least one invalid character at location: " << foundInvalidInputLocation << endl;
  60.                 }
  61.             }
  62.             else // No non-digit characters found? Then we were likely given a legitimate int - but we still need to do more testing to be sure!
  63.             {
  64.                 // Find the locations of the first and last plus and minus operators in our converted-from-iss string
  65.                 int firstMinusOperatorLoc = test.find_first_of("-");
  66.                 int lastMinusOperatorLoc  = test.find_last_of("-");
  67.                 int firstPlusOperatorLoc  = test.find_first_of("+");
  68.                 int lastPlusOperatorLoc   = test.find_last_of("+");
  69.  
  70.                 if (debug)
  71.                 {
  72.                     // Wax lyrical about multiple negative operators if detected...
  73.                     cout << "First and last minus signs are at: " << firstMinusOperatorLoc << " and " << lastMinusOperatorLoc << " Match?: ";
  74.                     firstMinusOperatorLoc == lastMinusOperatorLoc? cout << "Yes! This is good!" << endl : cout << "No! Multiple minus operators detected!" << endl;
  75.  
  76.                     // Wax lyrical about multiple positive operators if detected...
  77.                     cout << "First and last plus signs are at: " << firstPlusOperatorLoc << " and " << lastPlusOperatorLoc << " Match?: ";
  78.                     firstPlusOperatorLoc == lastPlusOperatorLoc? cout << "Yes! This is good!" << endl : cout << "No! Multiple plus operators detected!" << endl;
  79.                 }
  80.  
  81.                 // Got a mixture of both positive and negative operators in the input? Then it's not a valid int!
  82.                 if ( (firstMinusOperatorLoc != -1) && (firstPlusOperatorLoc != -1) )
  83.                 {
  84.                     if (debug)
  85.                     {
  86.                         cout << "Mixed + and - operators detected, so flagging this as invalid input!" << endl;
  87.                     }
  88.  
  89.                     mixedOperators = true;
  90.                 }
  91.                 else // No mixed operators? Then we can continue to check for multiple operators...
  92.                 {
  93.                     if (debug)
  94.                     {
  95.                         cout << "No mixed operators - continuing... " << endl;
  96.                     }
  97.  
  98.                     // Got multiple negative or positive operators in the input? Then it's not a valid int!
  99.                     if ( (firstMinusOperatorLoc != lastMinusOperatorLoc) || (firstPlusOperatorLoc != lastPlusOperatorLoc) )
  100.                     {
  101.                         if (debug)
  102.                         {
  103.                             cout << "Multiple + or - operators detected, so flagging this as invalid input!" << endl;
  104.                         }
  105.  
  106.                         multipleOperators = true;
  107.                     }
  108.                     else
  109.                     {
  110.                         if (debug)
  111.                         {
  112.                             cout << "No multiple operators - continuing... " << endl;
  113.                         }
  114.                     }
  115.  
  116.                 } // End of if mixed operator check else-block
  117.  
  118.                 // If we've finally got here and we don't have mixed or multiple operators - then FINALLY we know we have a valid int...
  119.                 if ( (mixedOperators == false) && (multipleOperators == false) )
  120.                 {
  121.                     if (debug) { cout << "Got a truly valid int! Hurrah!" << endl; }
  122.  
  123.                     // ...so set our exit flag to get out of the do..while loop
  124.                     valid = true;
  125.                 }
  126.  
  127.             } // End of if (foundInvalidInputLocation != -1) else section
  128.  
  129.         } // End of if (iss >> userInt) section
  130.         else
  131.         {
  132.             cout << "That's not a valid integer value!" << endl;
  133.         }
  134.  
  135.     } while (valid == false);
  136.  
  137.     // Because we got out of the loop, we must have a valid integer, which we can now return!
  138.     return userInt;
  139. }
  140.  
  141.  
  142. int main()
  143. {
  144.     int x = getValidInteger("Please enter a valid integer: ");
  145.  
  146.     cout << endl << "The value of our valid integer is: " << x << endl;
  147.  
  148.     //system("pause");
  149.     return 0;
  150. }

That works perfectly well as far as I’m concerned (remember – I’m not trying to validate the int to be within a given range or anything – I just want a valid int!) but something is surely wrong here… this should be a one-liner, or maybe three or four lines at the absolute most, not 140 lines or so…

Anyone got any suggestions on how to do this the right way? (In C++ not C, so no atoi or C-strings, and no boost library please! Just “standard” C++!).

Simple OpenGL Keyboard and Mouse FPS Controls

Note: This was written in January 2011 – I just never posted it, but I’d already uploaded the video to YouTube and someone asked for the code, so here it is, in all its fixed-pipeline glory ;)

Update – September 2013: I took these camera controls and wrapped them up into a Camera class in a later post which you can find here: https://r3dux.org/2012/12/a-c-camera-class-for-simple-opengl-fps-controls/. When I did this I wasn’t used to GLM (the OpenGL Mathematics library) so I just rolled my own Vec3 class – you can happily substitute glm::vec3’s if you’d like, and in fact I’d recommend it. Cheers!


I’m working on my OpenGL skills (or lack thereof) at the moment, and wanted to implement some 3D movement controls kinda of like a FPS with clipping off, so I read some chapters of the hallowed OpenGL SuperBible and did some googling, where I came across Swiftless‘ camera tutorials (Part 1, Part 2, Part 3) which gave me a really good start (Thank you, Swiftless!) on how to manipulate the ModelView matrix so we can move around a 3D scene, only it wasn’t quite perfect…

Strange things would happen like you’d look vertically downwards (i.e. directly down the negative Y axis), then you’d push forward – and yeah, you’d move “down”, but you’d also move “forward” at the same time (oh, and I’m putting things like “down” and “forward” in quotes because these concepts are all relative to your viewing orientation – not because I’m trying to be “sarcastic” or anything =P)

Anyways, I had a play with it and sorted it out after spending some time looking at the graphs for trigonometric functions and doing a little bit of off-setting and range-limiting as required. Check it out:

It actually looks quite a lot better running live than in the video due to mis-matched frame-capture rates and the like, but you get the idea =D

Full source code is available after the jump.

Cheers!

Continue reading Simple OpenGL Keyboard and Mouse FPS Controls

PS3 Motion Input

http://www.youtube.com/watch?v=w0puP8nrIU8

I’m really in two minds about this and Natal… but then when the Wii was first announced and you could see the Wiimotes for the first time it just screamed fad!, but once you do a little bowling or tennis is all sort of made sense… It was so new it just seemed wrong, but with time became commonplace.

On one hand, it might be cool to have true motion tracking, and I’m sure there could be some good uses for it – throwing grenades/punches, light sabres, manipulating object on screen – that sort of thing. But on the other hand, it really does look like some freakish plastic ice-cream or over-sized roll-on deodorant, and I’m not sure I want to play Fight Night Round 5 flailing my arms and dripping with sweat…

So the Sony device has buttons while the Natal is button free – and I can definitely see positives and negatives for both systems – but as to which will be the best, and which if any, I’ll really want to use, I genuinely have no idea until I can give them both a shot. And that assumes that the price is right… What do you reckon?