How To Build A USB SNES Controller For The PC, iPad, And PS3 – Part 4: The Build

Posted on: No Comments

So now we know what we’re building, the theory behind all the input standards, and the code that’s going to power it. All we need to do now is test and build it. Thankfully, we can test our creating without ever lifting a soldering iron.

The Test Rig

This is what we need to build in order to test the controller:
IMG_0772
The controller doesn’t require a socket. All I did was bend back some high gauge wire onto itself, but there’s a variety of ways you can get wires plugged into the controller.
IMG_0774
The SNES pinout is as follows:
snes_pinout
Once you’ve got the wires in place, find some way to connect them to the Teensy. I happened to have a Teensy++ with Header Pins laying around, so that’s what I used to test the code. Once the controller has been plugged into the Teensy, connect the Teensy to your computer. Upload the code and test out the three modes. You can test out the PS3 functionality by plugging your testing rig into the PS3 and pressing Start-Select-X. If you have a iPad Camera Connection Kit, you can test the iCade functionality on your iPad now as well.

IMG_0779

The Parts

To build our multiplatform USB SNES controller, you will need:
IMG_0784
A Super Nintendo controller. These aren’t too hard to come by, but there are plenty of fakes floating around. Make sure the logo is silkscreened on the controller, not embossed on the plastic. My local non-Gamestop used game store had legitimate used SNES controllers for $20, but I was fortunate enough to discover that there were several auctions on eBay for Japanese Super Famicon controllers, which an end auction price and shipping of roughly $20.
IMG_0809
As we discussed in Part 3, we’re using a Teensy for the brains of our controller. The Teensy 3.0 is the most recent Teensy, but I used the Teensy 2.0 in my controller. It’s still available, and a bit cheaper. Both will do though. $16.
IMG_0893
Did I mention our controller is also going to house an 8GB flash drive? It’s going to house an 8GB flash drive. When you plug the controller into the computer, the flash drive will mount as well, allowing you to carry all your games along with you. $9.
IMG_0885
We need a USB hub to wire all of this together. I’ve used this style USB hub with success in the past. $5.
412doYe0JpL._SS500_
You’re going to need a long cord coming out of your SNES controller, as well as a very short Mini-USB cable. You can kill two birds with one stone by ordering a long Mini-USB Male to USB Male cord. You can splice this cable from any USB device you happen to have laying around. I already owned one of these, but I forgot to take a picture of it. $5.
IMG_0779
As mentioned in the testing section, you’ll need the iPad Connection Kit if you want to use it on the iPad. It’s $30. There’s also a version for the new Lightening iPads. It’s still $30.
11101-02a
You’ll need some soldering tools too. A basic set like this can run you as low as $20. Not pictured: The ability to solder.
The entire controller costs roughly $85 if you don’t already own one of those parts. That doesn’t include the tools needed to make it, or the weekend afternoon it takes to build. Unfortunately, due to the high costs, there’s no way one could practically sell one of these for less than $100. Thanks, but it’s a fun learning experience to build, and I’m not going to make them for anyone who asks.

The Build

We need to remove the casing from several parts.
IMG_0893
First, remove the casing from your flash drive.
IMG_0886
Next, remove the casing from the USB hub.
IMG_0899
Clip the USB sockets and plug off. If your hub has a long cord on it, you may want to keep the plug on.
IMG_0900
Desolder the wires from the hub, leaving just the bare circuitboard. Take care not to complete de-pad the solder points, or else you won’t have anything to attach new parts to.
IMG_0902
Using four short pieces of cable, solder the pins coming out of the USB flash drive’s socket onto the USB hub. Make sure you have the order of the pins correctly, and make sure you don’t accidentally de-pad the hub. If that happens, that socket will be useless, and you’ll have to try again. That happened to me when I was building this, which is why the position is completely different in the next photo.
IMG_0903See that little white thing? That’s the Mini-USB “cable”. It’s been stripped down as small as possible and soldered down onto the USB hub. I was lucky to have a cable who’s internal wires matched the same colors as the wires we snipped off the USB hub.
IMG_0904Remember what I was saying about making sure not to de-pad the hub? Seriously, be careful!
IMG_0905At this point you’ll want to solder on the long length of USB cable we have remaining from that short snippet of Mini-USB cable. Once it’s soldered into place, you can test your hub to make sure that the flash drive and  Teensy both still work.
IMG_0895Put your contraption aside and get the SNES controller out.
IMG_0896Remove the screws. No tricks here, just five standard Philips head screws.
IMG_0897This is what the innards look like. Give the black plug in the middle a firm tug, and it should pop out.
IMG_0906Solder the five wires onto the Teensy. The wires colors match the pinout at the top of this page.
IMG_0910By now hopefully all of your parts loosely fit on the SNES controller. Now there’s just one more thing you need to do.
IMG_0911The back of the controller doesn’t have any room on it for our parts.
IMG_0913Bust out your Dremel. You have a Dremel, right?
IMG_0912Don’t forget the safety goggles! You don’t want chips of plastic in your eye.
IMG_0914Get to work!
IMG_0916There’s three spots you need to level out. They don’t have to be perfectly flat, but they should be close to it.
That’s it, you’re done! Lay all the parts down, slowly close the lid, and screw the two pieces together. By the way, in case you were wondering: Yes, you can use two at once.
IMG_0918That’s the end of my guide. I hope this was all informative. Feel free to ask any questions in the comments below.

 

How To Build A USB SNES Controller For The PC, iPad, And PS3 – Part 3: Code

Posted on: No Comments

Now that we’ve gone over the theory, we know that we need a device capable of reading the current button state of the SNES controller, and can send keyboard and gamepad inputs in variety of standards. My go-to device for this sort of project typically is the Arduino. It’s inexpensive, its programs are written in straightforward C/C++, and there’s an enormous amount of community support around it. However, the Arduino has historically been very bad at handling USB HID output. Until its recent switch to the ARM platform, USB HID output was nigh impossible. While the Arduino Uno, Leonardo, and Micro can all now handle USB HID output, the library for it is still a bit nascent and cumbersome to use.

wiring_pinout2So for this project I’ve opted to use the Teensy. The Teensy costs $16, can flawlessly handle USB HID output, and to top it all off, is compatible with the Arduino IDE and most libraries. Once you’ve procured your Teensy, install the Arduino IDE and the Teensyduino add-on.

Next we need to decide how we’re going to read the button input. Several guides suggest soldering a wire to every button pad on the controller, but the more common method is to have your microcontroller mimic how the SNES console would read the controller. The SNES controller protocol is fairly straightforward, and is outlined exhaustively here. In a nutshell:

The latch pin on the SNES fires roughly every 60hz. This locks the button state on the controller’s IC. Six microseconds after the latch is set, the SNES sends 16 pulses along the clock pin. Which each clock pulse, the controller sends the state of one of the buttons. The last 4 clock pulses are unused, since the controller only has 12 buttons.

It wouldn’t be difficult to recreate this behavior ourself, but as fate would have it, someone has already done it for us. Rob Duarte has a well coded Arduino library called NESPad, which also works with the SNES. Download and install it in your Arduino’s library folder.

Now we can actually begin coding. The program’s broken into three methods: Keyboard Input, Gamepad Input, and iCade Input. I’m going to show coding snippets of each of the three methods before we put it all together.

Keyboard Input

The Teensy has two keyboard methods: Basic and Manual. The basic method is useful for sending entire strings to a computer, where the manual mode is more useful for sending multiple keys simultaneously, or for holding multiple keys down. Here is an example of Teensyduino’s basic mode:

void setup() { }
void loop() {
  Keyboard.print("Hello World ");
  delay(5000);
}

This code waits 5 seconds, then types out “Hello World”. It’s useful for a multitude of projects, but not our particular keyboard-gamepad mode. We’ll instead be using Teensyduino’s manual mode:

void setup() { }
void loop() {
  Keyboard.set_key1(KEY_A);
  delay(1000);
  Keyboard.set_key2(KEY_B);
  delay(1000);
  Keyboard.set_key3(KEY_C);
  delay(1000);
  Keyboard.send_now();
}

This code behaves a bit differently. Setting a key does not send it to the computer. This code waits three seconds, then sends A, B, and C all simultaneously to the computer. Let’s look at another example:

void setup() { }
void loop() {
  Keyboard.set_key1(KEY_A);
  Keyboard.send_now();
  delay(1000);
  Keyboard.set_key2(KEY_B);
  Keyboard.send_now();
  delay(1000);
  Keyboard.set_key3(KEY_C);
  Keyboard.send_now();
  delay(1000);
}

set_key() remains set until it is cleared, so this bit of code would send A, then AB, then ABC, and then ABC on every subsequent loop. If we wanted to have the program send A, then B, then C all individually, there are two ways we could go about it:

void setup() { }
void loop() {
  Keyboard.set_key1(KEY_A);
  Keyboard.send_now();
  delay(1000);
  Keyboard.set_key1(KEY_B);
  Keyboard.send_now();
  delay(1000);
  Keyboard.set_key1(KEY_C);
  Keyboard.send_now();
  delay(1000);
}

This code just uses a single channel, and rewrites it for every subsequent key. Alternatively, we could use:

void setup() { }
void loop() {
  Keyboard.set_key1(KEY_A);
  Keyboard.set_key2(0);
  Keyboard.send_now();
  delay(1000);
  Keyboard.set_key1(0);
  Keyboard.set_key2(KEY_B);
  Keyboard.set_key3(0);
  Keyboard.send_now();
  delay(1000);
  Keyboard.set_key1(0);
  Keyboard.set_key2(0);
  Keyboard.set_key3(KEY_C);
  Keyboard.send_now();
  delay(1000);
}

This snippet takes advantage of Keyboard.set_key(0) to clear the previous set_key uses before each send_now. We’ll be taking advantage of it in our code. Further documentation on Teensyduino’s keyboard input can be found here.

Gamepad Input

Gamepad input works much in the same fashion as keyboard input. We’ll be using the gamepad manual mode excessively here.

void setup() {
  Joystick.useManualSend(true);
}
void loop() {
Joystick.button(1, 1);
  Joystick.button(2, 0);
  Joystick.button(3, 0);
  Joystick.send_now();
  delay(1000);
  Joystick.button(1, 0);
  Joystick.button(2, 1);
  Joystick.button(3, 0);
  Joystick.send_now();
  delay(1000);
  Joystick.button(1, 0);
  Joystick.button(2, 0);
  Joystick.button(3, 1);
  Joystick.send_now();
  delay(1000);
  Joystick.button(1, 1);
  Joystick.button(2, 1);
  Joystick.button(3, 1);
  Joystick.send_now();
  delay(1000);
}

This code sends the gamepad Button1 signal, then Button2, then Button3, then Button1, Button2, and Button3 altogether. Further documentation can be found here.

iCade Input

The iCade standard is outlined exhaustively in Part 2 of this guide. To recap, when a button is pushed, it should instantaneously send a single character out, then when that button is released it should send a single character out. Due to this behavior, a boolean variable needs to be created for every button. When a change in button state is noticed, the boolean is checked to see if the button was previously being held down. If the button wasn’t being held down, the initial button press character is sent. If it was being held down, the release key is sent.

bool previouslyHeld = false;
char keyPressed = 'a';
char keyReleased = 'b';
void setup() { }
void loop() {
bool isButtonBeingPressed = //Read Button Code Goes Here;
  if((isButtonBeingPressed == False) && (previouslyHeld == True)) {
    Keyboard.print(keyReleased);
    previouslyHeld = false;
  }
  if((isButtonBeingPressed == True) && (previouslyHeld == False)) {
    Keyboard.print(keyPressed);
    previouslyHeld = true;
  }
}

This code uses the Teensyduino Basic Keyboard mode. Due to the way the iCade handles buttons being held down, Manual Keyboard Mode isn’t required.

Finished Code

The completed code integrates these three methods. Before the controller sends any keys out, it checks to see if Start, Select, and a face button are being held down. Start-Select-Y will put the controller into Keyboard Mode, Start-Select-X will put the controller into Gamepad Mode, Start-Select-A will put the controller into iCade mode with the default layout, and Start-Select-B will put the controller into the iCade mode with an alternate layout. I’ve exhaustively commented the code to make it more readable. The heavily commented code can be downloaded here, and a much more lightly commented version can be downloaded here.

//** Multiplatform SNES Controller **//
//** Creative Commons Attribution-ShareAlike 3.0 Unported **//
//** Explanatory, help comments are designated by matching //** and **//. API comments designated with a standard //

#include <SNESpad.h>

//** Reading The Button State From The SNES Controller **//
//** The latch pin on the SNES fires roughly every 60hz. This locks the button state on the controller's IC. Six microseconds after the latch is set, the SNES sends 16 pulses along the clock pin. Which each clock pulse, the controller sends the state of one of the buttons. The last 4 clock pulses are unused, since the controller only has 12 buttons. More information about the controller's internal working can be found here: http://db.gamefaqs.com/console/snes/file/snes_pinouts.txt **//
//** The Arduino/Teensy can recreate this behavior fairly easily. However, unless you plan on learning more about wheels, it's best not to reinvent them. Rob Duarte has created a very efficient Arduino library called NESPad, which thankfully also works on the SNES controller. We'll be using it for this program. It can be found here: http://code.google.com/p/nespad/ **/
// SNESpad(Latch Pin, Clock Pin, Data Pin);
SNESpad nintendo = SNESpad(2, 3, 4);

//** The iCade sends a separate key for presses and releases. The default iCade mappings for the controller are defined her. **//
// SNES Controller Mapping: A Y B X UP DOWN LEFT RIGHT L R SELECT START
char keyPress[12] = {'o', 'k', 'l', 'i', 'w', 'x', 'a', 'd', 'h', 'j', 'y', 'u'};
char keyRelease[12] = {'g', 'p', 'v', 'm', 'e', 'z', 'q', 'c', 'r', 'n', 't', 'f'};

//** state is used to hold the SNESPad library's representation of the current state of the SNES controller's buttons. SNESPad comes with several literals (SNES_A, SNES_B, SNES_START, SNES_UP, etc). If compared using a bit comparison, state & SNES_A will resolve to true if the controller's A button is currently being pressed. **//
// Current state of SNES buttons.
int state = 0;

//** Fairly straight forward. The controller starts off in keyboard-emulation mode. Holding Start and Select, then tapping one of the four face buttons will chance the modes. Y = 0, X = 1, A = 2, B = 2 with different key layout **//
// 0 = Keyboard, 1 = Gamepad, 2 = iCade
int mode = 2;

//** Keyboard Mode Only: USB Keyboards can only send six signals simultaneously.
bool channelSet[] = {0, 0, 0, 0, 0, 0};

//** iCade Mode Only: When the controller detects a change in the buttons, it will check that button's corresponding 'previous' variable. If the 'previous' variable is false, that indicates that the button is being initially pushed. If the 'previous' variable is true, that indicates that the button was previously being held down, and has now been let go. **//
// iCade "Hold" variables.
bool previous[12];

void setup() {
  //** The Teensy has two HID modes: Basic and Manual. Basic sends the keypress/joypress as soon as the command is executed. Manual allows you to stack multiple commands to allow for more fine tune controls. In particular, manual mode excels at multiple simultaneous button presses, and held down buttons, so we'll be using it here. **/
  Joystick.useManualSend(true);
  //** Initialize all 12 previous values to false. **//
  for(int i = 0; i < 12; i++) {
    previous[i] = false;
  }
}

void loop() {
  //** Read the current state of the buttons using SNESPad **//
  state = nintendo.buttons();

  //** if Keyboard Mode **//
  if(mode == 0) {
    //** Since we're in useManualSend(true) mode, we need clear out the keyboard's six set_key variables each time we iterate through loop() **//
    Keyboard.set_key1(0);
    channelState[0] = 0;
    Keyboard.set_key2(0);
    channelState[1] = 0;
    Keyboard.set_key3(0);
    channelState[2] = 0;
    Keyboard.set_key4(0);
    channelState[3] = 0;
    Keyboard.set_key5(0);
    channelState[4] = 0;
    Keyboard.set_key6(0);
    channelState[5] = 0;
  }
  //** if Joystick Mode **//
  else if(mode == 1) {
    //** Much like keyboard mode, we need to clear our the joystick's two axis and eight button inputs each time we iterate through loop() **//
    Joystick.X(512);
    Joystick.Y(512);
    Joystick.button(1, 0);
    Joystick.button(2, 0);
    Joystick.button(3, 0);
    Joystick.button(4, 0);
    Joystick.button(5, 0);
    Joystick.button(6, 0);
    Joystick.button(7, 0);
    Joystick.button(8, 0);
  }
  else {
    //** The ~ character is a bitwise 'not' in Arduino code. if(~state & SNES_Y) checks to see if the Y button is not being held down. if(previous[0] == true) checks to see if the Y button was being held down in the previous loop() iteration. If a button is currently not being held down, AND it was being held down in the previous iteration of loop(), the 'release' iCade key should be sent. If a button is not being held down AND the button was not being held down in the last loop, nothing should be sent. **//
    if((~state & SNES_A) && (previous[0] == true)) {
      //** Unlike the Keyboard and Joypad mode, the iCade mode can function in the Teensy's basic HID mode, and use Keyboard.print() to instantaneously send characters to the iPad. **]]
      Keyboard.print(keyRelease[0]);
      previous[0] = false;
    }
    if((~state & SNES_Y) && (previous[1] == true)) {
      Keyboard.print(keyRelease[1]);
      previous[1] = false;
    }
    if((~state & SNES_B) && (previous[2] == true)) {
      Keyboard.print(keyRelease[2]);
      previous[2] = false;
    }
    if((~state & SNES_X) && (previous[3] == true)) {
      Keyboard.print(keyRelease[3]);
      previous[3] = false;
    }
    if((~state & SNES_UP) && (previous[4] == true)) {
      Keyboard.print(keyRelease[4]);
      previous[4] = false;
    }
    if((~state & SNES_DOWN) && (previous[5] == true)) {
      Keyboard.print(keyRelease[5]);
      previous[5] = false;
    }
    if((~state & SNES_LEFT) && (previous[6] == true)) {
      Keyboard.print(keyRelease[6]);
      previous[6] = false;
    }
    if((~state & SNES_RIGHT) && (previous[7] == true)) {
      Keyboard.print(keyRelease[7]);
      previous[7] = false;
    }
    if((~state & SNES_L) && (previous[8] == true)) {
      Keyboard.print(keyRelease[8]);
      previous[8] = false;
    }
    if((~state & SNES_R) && (previous[9] == true)) {
      Keyboard.print(keyRelease[9]);
      previous[9] = false;
    }
    if((~state & SNES_SELECT) && (previous[10] == true)) {
      Keyboard.print(keyRelease[10]);
      previous[10] = false;
    }
    if((~state & SNES_START) && (previous[11] == true)) {
      Keyboard.print(keyRelease[11]);
      previous[11] = false;
    }
  }

  //** Now that all of our buttons have been reset and cleared, here is where we set them based on their current state. **//

  // Cycle through button states.
  //** Is the A button being held down? **//
  if(state & SNES_A) {
    //** Is the controller in keyboard mode? **//
    if(mode == 0) {
      //** Send the 'A' key to the computer. **/
      setChannel(KEY_A);
    }
    //** Is the controller in gamepad mode? **//
    else if(mode == 1) {
      //** Send the JOY_1 command to the computer. **/
      Joystick.button(1, 1);
    }
    //** Is the controller in iCade mode, and was the button previously not held down? **//
    else if(mode == 2 && previous[0] == false) {
      //** Immediately send the 'o' key to the iPad. **//
      Keyboard.print(keyPress[0]);
      //** Mark that the button is currently being held. **//
      previous[0] = true;
    }
  }
  if(state & SNES_Y) {
    if(mode == 0) {
      setChannel(KEY_Y);
    }
    else if(mode == 1) {
      Joystick.button(3, 1);
    }
    else if(mode == 2 && previous[1] == false) {
      Keyboard.print(keyPress[1]);
      previous[1] = true;
    }
  }
  if(state & SNES_B) {
    if(mode == 0) {
      setChannel(KEY_B);
    }
    else if(mode == 1) {
      Joystick.button(2, 1);
    }
    else if(mode == 2 && previous[2] == false) {
      Keyboard.print(keyPress[2]);
      previous[2] = true;
    }
  }
  if(state & SNES_X) {
    if(mode == 0) {
      setChannel(KEY_X);
    }
    else if(mode == 1) {
      Joystick.button(0, 1);
    }
    else if(mode == 2 && previous[3] == false) {
      Keyboard.print(keyPress[3]);
      previous[3] = true;
    }
  }
  if(state & SNES_UP) {
    if(mode == 0) {
      setChannel(KEY_UP);
    }
    else if(mode == 1) {
      Joystick.Y(0);
    }
    else if(mode == 2 && previous[4] == false) {
      Keyboard.print(keyPress[4]);
      previous[4] = true;
    }
  }
  if(state & SNES_DOWN) {
    if(mode == 0) {
      setChannel(KEY_DOWN);
    }
    else if(mode == 1) {
      Joystick.Y(1023);
    }
    else if(mode == 2 && previous[5] == false) {
      Keyboard.print(keyPress[5]);
      previous[5] = true;
    }
  }
  if(state & SNES_LEFT) {
    if(mode == 0) {
      setChannel(KEY_LEFT);
    }
    else if(mode == 1) {
      Joystick.X(0);
    }
    else if(mode == 2 && previous[6] == false) {
      Keyboard.print(keyPress[6]);
      previous[6] = true;
    }
  }
  if(state & SNES_RIGHT) {
    if(mode == 0) {
      setChannel(KEY_RIGHT);
    }
    else if(mode == 1) {
      Joystick.X(1023);
    }
    else if(mode == 2 && previous[7] == false) {
      Keyboard.print(keyPress[7]);
      previous[7] = true;
    }
  }
  if(state & SNES_L) {
    if(mode == 0) {
      setChannel(KEY_Q);
    }
    else if(mode == 1) {
      Joystick.button(6, 1);
    }
    else if(mode == 2 && previous[8] == false) {
      Keyboard.print(keyPress[8]);
      previous[8] = true;
    }
  }
  if(state & SNES_R) {
    if(mode == 0) {
      setChannel(KEY_P);
    }
    else if(mode == 1) {
      Joystick.button(7, 1);
    }
    else if(mode == 2 && previous[9] == false) {
      Keyboard.print(keyPress[9]);
      previous[9] = true;
    }
  }
  if(state & SNES_SELECT) {
    if(mode == 0) {
      setChannel(KEY_TAB);
    }
    else if(mode == 1) {
      Joystick.button(8, 1);
    }
    else if(mode == 2 && previous[10] == false) {
      Keyboard.print(keyPress[10]);
      previous[10] = true;
    }
  }
  if(state & SNES_START) {
    if(mode == 0) {
      setChannel(KEY_ENTER);
    }
    else if(mode == 1) {
      Joystick.button(9, 1);
    }
    else if(mode == 2 && previous[11] == false) {
      Keyboard.print(keyPress[11]);
      previous[11] = true;
    }
  }
  //** End Key Setting **//

  //** Mode Switching Code. The controller starts off in keyboard-emulation mode. Holding Start and Select, then tapping one of the four face buttons will chance the modes. Y = 0, X = 1, A = 2, B = 2 with different key layout. **//
  if((state & SNES_START) && (state & SNES_SELECT) && (state &SNES_Y)) {
    mode = 0; //Keyboard Mode
  }
  else if((state & SNES_START) && (state & SNES_SELECT) && (state &SNES_X)) {
    mode = 1; //Joypad Mode
  }
  else if((state & SNES_START) && (state & SNES_SELECT) && (state &SNES_A)) {
    mode = 2; //iCade Mode 1

    //** Start+Select+B uses a different iCade button layout than Start+Select+A. This chunk of code resets it to the default layout. **//
    // Restore default iControlPad style controls
    keyPress[1] = 'k';
    keyPress[3] = 'i';
    keyPress[10] = 'y';
    keyPress[11] = 'u';

    keyRelease[1] = 'p';
    keyRelease[3] = 'm';
    keyRelease[10] = 't';
    keyRelease[11] = 'f';
  }
  else if((state & SNES_START) && (state & SNES_SELECT) && (state &SNES_B)) {
    mode = 2; //iCade Mode 2

    //** Certain games use iCade button layouts which are incompatible with the default. This second iCade setting lets you create custom layouts just for them. **//
    // Swap Start/Select with Y/X.
    // Certain games use the top two left buttons as the main buttons for their games.
    // This tweak makes games like Super Crate Box playable.
    keyPress[10] = 'k';
    keyPress[11] = 'i';
    keyPress[1] = 'y';
    keyPress[3] = 'u';

    keyRelease[10] = 'p';
    keyRelease[11] = 'm';
    keyRelease[1] = 't';
    keyRelease[3] = 'f';
  }
  //** If in keyboard mode, send the current button presses as keyboard presses. **//
  else if(mode == 0) {
    Keyboard.send_now();
  }
  //** If in Joypad mode, send the current button presses as joypad presses. **//
  else if(mode == 1) {
    Joystick.send_now();
  }
  //** iCade mode's button presses are sent using the USB HID basic mode, and so there is no need for a send_now() command.
}

//** USB keyboards can send six key signals at the same time. setChannel receives a byte code of a keyboard key, and attempts to assign it to an empty channel. If seven or more keys are being held down, all signals past the first six will not be sent. A full list of keyboard byte codes can be viewed here: http://www.pjrc.com/teensy/usb_keyboard.html **//
void setChannel(byte key) {
  bool buttonSet = false;
  for(int i = 0; i < 6; i++) {
    if(buttonSet == false) {
      if(channelSet[i] == false) {
        if(i == 0) {
          Keyboard.set_key1(key);
          channelSet[i] = true;
          buttonSet = true;
        }
        else if(i == 1) {
          Keyboard.set_key2(key);
          channelSet[i] = true;
          buttonSet = true;
        }
        else if(i == 2) {
          Keyboard.set_key3(key);
          channelSet[i] = true;
          buttonSet = true;
        }
        else if(i == 3) {
          Keyboard.set_key4(key);
          channelSet[i] = true;
          buttonSet = true;
        }
        else if(i == 4) {
          Keyboard.set_key5(key);
          channelSet[i] = true;
          buttonSet = true;
        }
        else if(i == 5) {
          Keyboard.set_key6(key);
          channelSet[i] = true;
          buttonSet = true;
        }
      }
    }
  }
}

In Part 4 of this guide, I’ll explain how to physically build the finished product.

How To Build A USB SNES Controller For The PC, iPad, And PS3 – Part 2: Theory

Posted on: No Comments

Before we can start building the controller, we need to figure out how each platform talks to its hardware. Just because the PC, iPad, and PS3 all use USB doesn’t mean that they’re immediately going to be able to use the same input methods. Without further adieu, let’s begin.

The PC – Gamepad Input

The most straightforward means of using the SNES controller on a PC is to make it into a USB Gamepad. Windows, Mac, and Linux all accept standardized gamepad input. This standard is shared with joysticks as well, and as such gamepads are often referred to as “joypads”. The variable nomenclature also comes from the joystick world. While their shape, size, and available buttons often differ, below is an example of your typical joystick and gamepad layouts:

Teensydunio Joystick Example

Teensyduino Gamepad Example

This standard is more than capable of accommodating the SNES controller.

SNES Mapping

So that’s all there is to getting an SNES controller to masquerade as a gamepad. For those of you observant enough to notice that JOY_3 and JOY_4 are missing, hold your questions off for now.

The PC – Keyboard Input

Didn’t we just do the PC? Well, yes. However, not every PC game accepts standard gamepad input unfortunately. There’s a plethora of PC titles which for whatever reason only accept keyboard input. That answer’s not going to fly if you’re going to put all this effort into making a USB controller though, so let’s see what we can do.

SNES Mapping 2

This looks like a reasonable enough key mapping. Everyone’s got their own preferences, but this is typically what I use when playing a (legally obtained) game on an emulator. There’s one small catch however: USB Keyboards typically can only send roughly 6 keys at the same time. Thankfully, this isn’t a huge issue with the SNES controller. You can press a diagonal direction, two face buttons, and both shoulder buttons without any commands being lost. If you tried pressing start, select, or any additional face buttons, those keys would not be sent. However, you’d have to contort your hand in a remarkably uncomfortable manner to pull this off, and I can’t recall any games requiring a six button combo at any point in time. Still, for this reason, gamepad input is preferable to keyboard input if both are available.

The PS3 – Gamepad Input Redux

Confession time: I do not own a PS3. I haven’t tested any of this personally, but in my searching on the web, I’ve discovered that apparently the PS3 accepts standard USB gamepad input. If you plug a USB gamepad into your PS3, this is how it should behave:

PS3 Mapping

Look familiar? You guessed it: We can reuse our PC gamepad mapping on the PS3. There’s one small cravat however. The PS3 “Home” button is only possible to use if you specifically identify the device as a PS3 gamepad. It’s a rather technical process, and would most likely muck up any of the multi-platform things we’re trying to do on the PC and iPad side. So as far as I can tell without ever having tested any of this, you should be able to use this controller on a PS3 without any issues beyond a lack of access to the home button.

The 360 – Impossible

I figured I’d shoot this question down before someone asks it in the comments. Microsoft very strictly licenses all its 3rd party products. It’s nearly impossible to recreate a 360 controller on your own. The only luck people have had making their own 360 controllers is using a method called “padhacking“. It involves embedding an entire 360 controller’s circuit board in the controller you’re trying to build, so sadly it’s mostly suited only for arcade style fight-sticks.

The iPad – iCade Keyboard Input

So now we get to the real meat of the issue: Just how on Earth are you supposed to use a USB SNES controller on the iPad? Well, to answer your first question, you plug it into the iPad Camera Kit USB dongle. There’s also a Lightening version of it out now. It’s worth noting that this adapter doesn’t work on the iPhone. The phone version of iOS doesn’t have the right bits installed unfortunately. There was a group of hackers trying to enable support for it a while back, but it appears that the projects had fizzled out into obscurity.

Great, so we can plug the controller into an iPad. That doesn’t do us a lick of good unless there’s software that knows how to recognize it. The iPad is a fully touch device, it was never designed to have someone press buttons in order to trigger actions. This is the point where we would normally be out of luck, but thankfully ThinkGeek and Ion have lent us a significant hand.

Last year the two teamed up to create the iCade. The iCade is a small arcade cabinet style dock for the iPad, complete with joystick and button controls. This dock was designed to work with a specific Atari game, but Ion published an iOS controller standard that any developer can use in their game. Over the last year, a sizable number of games have been made adhering to this spec. To give our controller the maximum amount of compatibility across applications, we’ll be sticking with Ion’s spec as well.

Certifying a third party device to use Apple’s dock connector standard is an expensive, difficult, and time consuming process. Devices given Apple’s approval are also generally tied specifically to the manufacturer’s app, and aren’t allowed to be open to other developers. In order to get around this, Ion simply didn’t use Apple’s dock connector. The iCade is nothing more than a fancy Bluetooth keyboard. Much like our example for the PC, the iCade simply sends keyboard commands.

This presents a problem however. As I pointed out above, there’s a limit to how many keys you can hold down simultaneously on a keyboard, even a bluetooth one. Unlike the SNES controller, the iCade is also much more likely to encounter a situation in which the user has the ability to hold several buttons down at the same time. In order to solve this, the Ion developers got very clever.

iCade Example

Let me explain their solution with an example. You’re at the dinner table, and your friend is pouring water for you. He wants to know how much water to give you, and so you come up with two different methods of letting him know when to stop pouring. The first method you try is to just say “keep going” over and over. “Keep going keep going keep going keep going keep going.” He starts pouring when you start talking, and he stops pouring when you stop talking. The alternative is for you to just say “start” when he should start pouring, and “stop” when he should stop pouring. That’s the two ways a keyboard can work as well.

In our first example, when you press a button, that letter is continually sent to the computer. It knows when you let go because you no longer are sending it. This requires multiple letter signals to be send over an extended period of time as you hold down multiple buttons.

In the second example, the way the iCade does it, the device sends out a single character briefly when you start pressing the button, and then a different character when you stop pressing it. This method requires a bit more code on both the sending and receiving end, but it keeps the communication channel near empty the entire time. In the example shown above, the “y” key is sent to the iPad when you start pressing the button, and the “t” key is sent when you stop. It could be receiving no data at all from the iCade and still know you’re holding a button down, since it’s only received a “y” and not it’s terminating “t”.

It should be noted that Ion is bad at writing documentation, all of the letters the iCade sends are lower case, not upper case like the images suggest. Here is the button mapping for the original iCade:

Now all that’s left is to find a sensible way of converting this into a gamepad layout. It turns out there are several iCade-protocol supporting gamepads already on the market, so let’s see what they used. Here’s the first of them, the iControlPad:

iControlPad Mapping

Looks sensible enough. Let’s see what Gametel did with their controller:

Gametel Mapping

Err, that’s different… Oh hey! iCade came out with their own gamepad! The iCade Mobile! Let’s see what it maps to:

iCade Mobile Mapping

Ugh.

Facepalm

For what it’s worth, I usually go with the iControlPad mapping. It was first, and most of the emulators available for the iPad expect to see them in that configuration. In the next section of this how-to we’ll set up our control to support multiple iOS key mappings anyways, so don’t worry about it too much. Speaking of the next section, it looks like we’re done here. Stay tuned for the actual hardware and code we’ll need to implement the above.

How To Build A USB SNES Controller For The PC, iPad, And PS3 – Part 1: Background

Posted on: No Comments

USB SNES ControllerLet’s just cut to the chase: The Super Nintendo had one fine controller. Four face buttons arranged in the shape of a diamond, shoulder buttons, two menu buttons, and a directional pad. Whether Nintendo meant to or not, their controller set the standard for gaming input devices for decades to come. Despite the fact that today’s controllers have analog sticks, motion controls, and touch screens, you can still clearly see the SNES’s influence at work.

Despite all our advances in technology, there are certain things that Super Nintendo’s controller actually does better than modern controllers. Platformers, fighting games, or anything else that requires precise, split second controls generally suffers on today’s first-person shooter oriented controllers. Beyond that, there’s nothing like replying the classics as they were meant to be played. Games like Super Mario World loose some of their charm when you’re forced to mash away at a bulky 360 controller.

So, short of dusting off your SNES, how is a gamer supposed to keep using the SNES controller? Well, it turns out that this isn’t a novel question. Realizing the SNES controller’s popularity, Club Nintendo of Japan actually put out a replica SNES controller for the Wii. It was a limited release, and fetches a pretty penny on eBay and other sites. There’s a pretty close facsimile of it up on ThinkGeek for $20 however.

Those are all recreations though, what if you want to use the real McCoy? It turns out that question has been asked many times as well. There’s a plethora of SNES to USB adapters out there, ready and waiting to let you play emulators on your PC with your authentic SNES controller. I’m particularly fond of the RetroZone adapter, but there are some cheaper dual controller adapters out there. RetroZone also has a SNES to Gamecube adapter, which is particularly handy for playing legitimate Wii Virtual Console games with an authentic controller.

So, there you have it, a simple way of using an SNES controller on modern hardware. Dongles are a simple, cheap, straightforward method that 99% of people out there will be perfectly happy with. If you’re catching onto the theme of this blog however, you’ll realize that I’m about to ask: What if you don’t want to use a dongle? What if you want to turn an SNES controller into a 100% USB device?

It turns out that question is also one which has been answered many times. In fact, people are starting to get clever now. There are guides for how to make a USB SNES controller with a motion sensor, a USB controller with an integrated flash drive, or even just into straight up Bluetooth controller. Hacking something with an SNES controller is practically an electronics hobbyist rite of passage. If you’re just looking to turn your SNES controller into a USB controller for your PC, I once again highly recommend looking into RetroZone’s RetroKit. It’s simple, straightforward, and comes with everything you need. If you’ve got the most minimal amount of soldering skills, you can pull it off.

So, point made, plugging a SNES controller into a PC via USB isn’t exactly an untrod path. The Wii doesn’t allow USB controllers, but as we saw above, there are plenty of solutions for getting a Super Nintendo controller to work on your Wii. So what about the PS3? Nice try, someone’s done that as well. I’ve exhausted my title now, right? SNES to iPad. That’s new! That’s novel! Right? Well… technically. Someone’s already made a homebrew NES to iPad adapter. Adding SNES support to the theory behind a NES adapter isn’t exactly groundbreaking work.

So why am I bothering to write this guide? What new cards am I putting on the table?

I’m going to do three controllers in one, and an integrated flash drive to boot. Welcome to my USB SNES Controller for the PC, iPad, and PS3 how-to. The four parts to this guide can be found here: Part 1, Part 2, Part 3, Part 4.

Why Deus Ex: Human Revolution Is Not Available On The Mac On Steam

Posted on: No Comments

Today’s Macs make fairly competent gaming machines. Anyone who tries to tell you otherwise either has bad information or is biased. Using Apple’s Boot Camp utility, Macs can run Windows just as well as any other PC. Once a Mac user has Windows installed, there’s nothing keeping them from downloading and purchasing games through Steam, Origin, or Blizzard, and enjoying them just as much as the next PC user.

Which is what Mac users generally have to do. Most triple A titles such as EA’s Mass Effect 3 never get a Mac port. While dual booting has some minor irritations, Mac users deal with them in order to play the games that they want to. However, whenever a developer takes the time to actually make their game cross platform, such as the case of Diablo 3 and Portal 2, the good will that the companies produce far outstrips any monetary gain that finance department could calculate. There seems to be a slowly growing trend of releasing games in cross platform versions, particular as part of Valve’s Steamplay program. However, there will always be companies willing to cut corners, which is where Deus Ex: Human Revolution unfortunately comes in.

Deus Ex: Human Revolution was originally released for the PC on August 23, 2011. If you were a Mac gamer like me, you had no choice but to buy the PC version through Steam, and play it on your Windows partition. The game was great, with the exception of it’s infamous boss battles of course. I played through it once, always intending to go back and try a stealth run, but I eventually deleted it to make room for other games on my small Windows partition. So imagine my delight when on April 26, 2012 the game was released for the Mac. Finally I had an excuse to go back and replay the game. Without the hassle of dual booting, there wasn’t much stopping me from going back and enjoying the game I had purchased, perhaps I’d even buy the game’s DLC this time around.

Except, there was something stopping me. Deus Ex: Human Revolution is only available for the Mac through the Mac App Store. Surely there was some sort of mistake, right? I had already purchased the game, surely Eidos wasn’t trying to milk another $50 just for Mac compatabily. Well, things are a bit more complicated than that. Eidos didn’t actually make the Mac version of Human Revolution. A company called Feral Interactive did. Feral paid Eidos for the rights to sell Human Revolution on the Mac, and is the company that actually makes the money on each Mac sale. This poses a problem when you consider adding Steamplay support. Valve credits a sale to a platform based off of which platform the majority of gameplay is played on during the first week of the sale. In the case Human Revolution, that platform would be the PC for me, since the Mac version didn’t exist at the time. Even if I sank multiple hours into the Mac port, Feral wouldn’t see a dime for their hard work. By forcing PC and Mac versions into a single product listing, the PC and Mac publishers also have to agree on a pricing scheme for the game. While Eidos is a large company and can take a hit on events such as Steam’s Summer Sale, the smaller Mac porters cannot.

So all of this makes sense for the publishers involved, but where does this leave the Mac consumers? Well, hosed mostly. The type of gamers I described in the scenario above are your most diehard fans. It’s great that Feral can make some money but putting games up on the Mac App Store, but for the people who proactively did a somewhat technical solution in dual booting, it just leaves a bad taste in our mouths. Publishers should be working harder to make quality multi platform games, such as the aforementioned Diablo 3 and Portal 2. These sorts of development shortcuts irritate your most loyal fans, and it’s made worse by obtuse, confusing, or nonexistent PR explanations of why this situation has been allowed to come to pass. The best explanation of this situation is a Steam Forum post for crying out loud. Even if nothing else changes, developers should be more straightforward with the fact that Mac gamers are getting the short end of the stick because they can’t figure out how to split profits in a way that doesn’t punish their dual platform customers.

How To Fix The One Unread Message Bug in Messages for Mac

Posted on: 2 Comments

As part of OS X Mountain Lion, Apple is completely revamping their instant messenger client. Instead of the classic iChat program, the new OS is going to ship with a program called Messages. There’s currently a beta of Messages out for OS X Lion, and the initial impressions of it have been rather mixed. I personally am sticking with Adium for my instant messenger needs, but I still have Messages installed on my desktop so that I can send iMessages without having to get my phone out.

There is one problem however. In the current version of the Messages beta, the program will occasionally show a badge on it’s dock icon indicating that there’s one unread message. If you pull the app up however, there won’t be anything new waiting for you. While this isn’t a huge bug, it’s still rather irritating for OCD types who like having all their badge icons cleared out.

To remove the one unread message badge, open up the Terminal application, it’s located in your Application folder’s Utility folder. In that window, type, “killall Dock” without quotes. That should clear everything up for the time being. After entering that command, you can exit the Terminal application.

How To Disable The Search Feature Of The Motorola Nyxboard Hybrid

Posted on: 4 Comments

So I recently received one of these for my birthday:

By the wonderful one of these. It’s a very unique remote, and works very well with this:

However, this isn’t any ordinary remote… It you turn it over, it becomes this:

Which is super convenient… except for one issue. When you flip it over, it sends a signal to the software, which pulls up this:

While I’m sure it’s useful for some people, it’s quickly become an irritant for me. Thankfully, you can get rid of it by going here:

And then here:

Then select this:

Finally, turn off this:

So, you get all that?

To put it in more search engine optimized terms, I was recently gifted a Pulse-Eight Motorola Nyxboard Hybrid by @Mageuzi. It’s a HTPC remote designed for Windows, Mac, and Linux computers which allows you to control media center software such as XBMC. While the remote’s universal, it was made with XBMC in mind, but it also recognizes that HTPC users sometimes need to use more than a 4-way direction pad and a select button. If you flip the remote over onto it’s backside, the remote becomes a full handheld keyboard, complete with a mouse emulator. It’s all well and good… except for one feature that Pulse-Eight and Motorola decided to build into the remote. When you flip it over, the remote sends an F7 command to the HTPC, which XBMC interprets as a request to open up the search box. I don’t ever search for anything in XBMC, so the flip-search feature is pretty useless to me. While I recognize that I’m never going to use 100% of every feature in a product I buy, it is a bit irritating to have to click OK through a dialog box every time I want to use the keyboard or mouse of my remote. If you also would like to turn off this feature, go to the Settings section of XBMC, then it’s System section, then the Input section, and finally the Peripherals option. Once you uncheck “Enable Side Switch Commands”, your Nyxboard will stop bringing up the search box every time you turn it over.

Useful Stuff: ASCII Pronunciation Rules for Programmers

Posted on: No Comments

You know that top row of your keyboard? The one you don’t really use that often?

No no no, not that one. The number keys!

Yeah, those! Well see those little symbols over them? You probably use them every now and then without thinking about it too much. You’ve no doubt typed out currencies, percentages and made those overly enthusastic emoticons ^_^.

So what exactly is a ^ ? Is it a circumflex? A carrot? A fang? A chevron? Turns out, it’s all of those things, and more. You might be asking yourself, “So what? As long as I can type out my ^_^ face, I don’t care.” Well, these proper names might not be useful for the average person, but to a programmer, the myriad of symbols and characters that they use every day are incredibly important to them. You can’t go 10 minutes in programming without using ! { } [ ] ^ * # + = and the like. The various names of all the symbols can be difficult to keep track of, especially the more obscure ones. Thankfully, Jeff Atwood over at CodingHorror.com has come up with a nifty guide to keep all of the various names straight. If you’re a coder, or just a language geek, you owe it to yourself to check it out.

████ SOPA

Posted on: No Comments

███████ everything ████ ███ █ is █ █████ ██ fine ██ ███. ████’█ ██ ██████. The ████ ███ █ government ████ ███ ██ knows ████ ███ best ███ ██.

How To Get the Latest Version of MAME Running On Mac OS X Lion [Part 3 of 3]

Posted on: 10 Comments

Welcome back to Part Three of my guide on getting MAME to run on Mac OS X Lion. In the first part I covered the basic MAME installation, and in second part I covered how to configure it. Finally, I’m going to go over the basics of configuring a GUI frontend for the command line based MAME.

This portion of the guide is completely optional. In its current state, you can use MAME to its fullest. However, most people do not like the basic MAME UI, which is very poor at managing large numbers of games. On the Windows side, the excellent MAME32UI solves this problem for us with very little configuration. Unfortunately, we as Mac users do not have the option to use this piece of software.

Thankfully, there exists a comparable frontend called M+GUI, which is cross platform. M+GUI is almost as good, and is thankfully also kept up to date on the Mac. You can download the latest version as of this blog’s posting here. [Mirror] Use Google to find the latest version if you’re reading this post a few months from now.

After the .zip file is download, extract it and browse to the resulting folder. Inside of it you’ll see the mamepgui application and a readme. Move the application to your Applications folder, and trash the readme. Upon your first launch, you should see something similar to:

This screen is asking for the executable of our MAME install. Just browse to the folder you stored it in, and point it at mame64.

Once you hit Open, M+GUI will begin to index the games in your /roms folder. If you do not use the /roms folder, you’ll have to set the rom directory manually in the settings. From here, everything is fairly self explanatory. I may come back and update this guide with a few preferences that I personally use, but my life has gotten unexpectedly busy, so I’m unfortunately cutting this guide a little short. Hope it helped someone out there. Feel free to leave a comment if it did!