Nintendo Controller mapping to NES Emulator

Sorry I had to break this down into two threads because of the text limit

Step 4 Coding Java

Now here is where things start to really cook. If you have taken some time to play with the Arduino sketch you will probably understand what events we are looking to capture in this Java class, but if you haven't here is a quick cheat sheet.

Arduino Events

'A' = A button is pressed 0 = A button is released
'B' = B button is pressed 1 = B button is released
'U' = Up button is pressed 2 = Up button is released
'D' = Down button is pressed 3 = Down button is released
'L' = Left button is pressed 4 = Left button is released
'R' = Right button is pressed 5 = Right button is released
'S' = Start button is pressed 6 = Start button is released
'E' = Select button is pressed 7 = Select button is released

Now if you have never captured Arduino Serial output in java before head over and check out this page Arduino Playground - Java. Now cut and paste the Java code below into your favorite IDE. Start up the program, and your controller should automatically be recognized. Start pressing buttons and you will see the same output in the Console as you did when you ran the pure Arduino Sketch except that there might be multiple commands sent in each iteration of our Arduino program. That is why we used String.contains() instead of String .equals() in our if statements. You should now be able to open Notepad and start pressing buttons on your Controller to see letters being outputted.

package driver;

import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.io.InputStream;
import java.io.OutputStream;
import gnu.io.CommPortIdentifier; 
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent; 
import gnu.io.SerialPortEventListener; 
import java.util.Enumeration;

public class Driver implements SerialPortEventListener {
      SerialPort serialPort;
        /** The port we're normally going to use. */
      private static final String PORT_NAMES[] = { 
                  "/dev/tty.usbserial-A9007UX1", // Mac OS X
                  "/dev/ttyUSB0", // Linux
                  "COM3", // Windows
                  };
      
      private Robot robot;
      
      /** Buffered input stream from the port */
      private InputStream input;
      /** The output stream to the port */
      private OutputStream output;
      /** Milliseconds to block while waiting for port open */
      private static final int TIME_OUT = 2000;
      /** Default bits per second for COM port. */
      private static final int DATA_RATE = 9600;
      
      /*
       * These booleans will ensure that our buttons are only pressed down once. Just like
       * in our Arduino sketch false = not pressed.
       */
      public Boolean a             = false;
      public Boolean b             = false;
      public Boolean up             = false;
      public Boolean down       = false;
      public Boolean left       = false;
      public Boolean right       = false;
      public Boolean start       = false;
      public Boolean select       = false;

      public void initialize() throws AWTException {
            
            CommPortIdentifier portId = null;
            Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();
            robot = new Robot();

            // iterate through, looking for the port
            while (portEnum.hasMoreElements()) {
                  CommPortIdentifier currPortId = (CommPortIdentifier) portEnum.nextElement();
                  for (String portName : PORT_NAMES) {
                        if (currPortId.getName().equals(portName)) {
                              portId = currPortId;
                              break;
                        }
                  }
            }

            if (portId == null) {
                  System.out.println("Could not find COM port.");
                  return;
            }

            try {
                  // open serial port, and use class name for the appName.
                  serialPort = (SerialPort) portId.open(this.getClass().getName(),
                              TIME_OUT);

                  // set port parameters
                  serialPort.setSerialPortParams(DATA_RATE,
                              SerialPort.DATABITS_8,
                              SerialPort.STOPBITS_1,
                              SerialPort.PARITY_NONE);

                  // open the streams
                  input = serialPort.getInputStream();
                  output = serialPort.getOutputStream();

                  // add event listeners
                  serialPort.addEventListener(this);
                  serialPort.notifyOnDataAvailable(true);
            } catch (Exception e) {
                  System.err.println(e.toString());
            }
      }

      /**
       * This should be called when you stop using the port.
       * This will prevent port locking on platforms like Linux.
       */
      public synchronized void close() {
            if (serialPort != null) {
                  serialPort.removeEventListener();
                  serialPort.close();
            }
      }

      /**
       * Handle an event on the serial port. Read the data and print it.
       */
      public synchronized void serialEvent(SerialPortEvent oEvent) {
            if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
                  try {
                        int available = input.available();
                        byte chunk[] = new byte[available];
                        input.read(chunk, 0, available);
                        
                        sendCommand(new String(chunk));
                        
                  } catch (Exception e) {
                        System.err.println(e.toString());
                  }
            }
      }
      
      public void sendCommand(String command){
            if(command.equals(""))
                  return;
            if(command == null)
                  return;
            
            System.out.println(command);
            
            //Switches for the A Button
            if(command.contains("A")){
                  if(!a){
                        robot.keyPress(KeyEvent.VK_A);
                        a = true;
                  }
            }
            if(command.contains("0")){
                  a = false;
                  robot.keyRelease(KeyEvent.VK_A);
            }
            
            //Switches for the B Button
            if(command.contains("B")){
                  if(!b){
                        robot.keyPress(KeyEvent.VK_B);
                        b = true;
                  }
            }
            if(command.contains("1")){
                  b = false;
                  robot.keyRelease(KeyEvent.VK_B);
            }
            
            // Switches for the UP button
            if(command.contains("U")){
                  if(!up){
                        up = true;
                        robot.keyPress(KeyEvent.VK_UP);
                  }
            }
            if(command.contains("2")){
                  up = false;
                  robot.keyRelease(KeyEvent.VK_UP);
            }
            
            //Switches for the down button
            if(command.contains("D")){
                  if(!down){
                        robot.keyPress(KeyEvent.VK_DOWN);
                        down = true;
                  }
            }
            if(command.contains("3")){
                  down = false;
                  robot.keyRelease(KeyEvent.VK_DOWN);
            }
            
            //Switches for the Left button
            if(command.contains("L")){
                  if(!left){
                        robot.keyPress(KeyEvent.VK_LEFT);
                        left = true;
                  }
            }
            if(command.contains("4")){
                  left = false;
                  robot.keyRelease(KeyEvent.VK_LEFT);
            }
            
            //Switches for the right button
            if(command.contains("R")){
                  if(!right){
                        robot.keyPress(KeyEvent.VK_RIGHT);
                        right = true;
                  }
            }
            if(command.contains("5")){
                  right = false;
                  robot.keyRelease(KeyEvent.VK_RIGHT);
            }
            
            //Switches for the Start button
            if(command.contains("S")){
                  if(!start){
                        robot.keyPress(KeyEvent.VK_ENTER);
                        start = true;
                  }
            }
            if(command.contains("6")){
                  start = false;
                  robot.keyRelease(KeyEvent.VK_ENTER);
            }
            
            //Switches for the select button
            if(command.contains("E")){
                  if(!select){
                        robot.keyPress(KeyEvent.VK_S);
                        select = true;
                  }
            }
            if(command.contains("7")){
                  select = false;
                  robot.keyRelease(KeyEvent.VK_S);
            }      
      }

      public static void main(String[] args) throws Exception {
            Driver main = new Driver();
            main.initialize();
            System.out.println("Started");
      }
}

Now finally to test in a real emulator! I am using Nestopia with a Super Mario Bros Rom. First note that when you start up Nestopia head over to Options -> Input to make sure all of our keystrokes are mapped correctly. Once they are start up the Rom of your choice and enjoy!
Thanks and I hope to update this tutorial with the NES Port soldering once it comes in the mail. Hope you all enjoyed this.