#include <NESpad.h>

/*

 this is a test of the NESpad library
 a nintendo joystick midi drum kit, mostly stolen from
 tod e. kurt's much more interesting piezo disc drum kit

 you can get the NESpad library here: http://rahji.com/NESpad

 08/21/2007 rob duarte - rahji@rahji.com
 
*/

// what midi channel we're sending on
#define drumchan          1  

#define UNPRESSED         0
#define PRESSED           1

// general midi drum notes
#define note_bassdrum     35
#define note_snaredrum    38
#define note_hihatclosed  42
#define note_hihatopen    44
#define note_crash        49

#define ledPin            13  // goes on when we're sending midi data

boolean ButtonAState      = UNPRESSED;
boolean ButtonBState      = UNPRESSED;
boolean ButtonSelectState = UNPRESSED;
boolean ButtonStartState  = UNPRESSED;

NESpad nintendo = NESpad();

byte state = 0; // joystick buttons state
// (it ends up looking like a bitmap with 1's for buttons that are pressed and 0's for unpressed)


void setup() 
{
  pinMode(ledPin, OUTPUT);
  Serial.begin(31250);   // set MIDI baud rate
}


void loop() 
{  
  state = nintendo.buttons();

  // if the button is pressed right now and it's last state was UNPRESSED...
  if ( (state & NES_A) && ButtonAState == UNPRESSED ) 
  {
    note(drumchan,  note_bassdrum, 100);   // turn on the note
    ButtonAState = PRESSED;                // and mark this button as being pressed
  } 
  // otherwise if the button is unpressed right now but it was PRESSED the last time we checked...
  else if ( !(state & NES_A) && ButtonAState == PRESSED ) 
  {
    note(drumchan, note_bassdrum, 0);      // turn off the note
    ButtonAState = UNPRESSED;              // and mark this button as being unpressed
  }

  if ( (state & NES_B) && ButtonBState == UNPRESSED ) {
    note(drumchan,  note_snaredrum, 100);
    ButtonBState = PRESSED;
  } else if ( !(state & NES_B) && ButtonBState == PRESSED ) {
    note(drumchan, note_snaredrum, 0);
    ButtonBState = UNPRESSED;
  }
    
  if ( (state & NES_START) && ButtonStartState == UNPRESSED ) {
    note(drumchan,  note_hihatopen, 100);
    ButtonStartState = PRESSED;
  } else if ( !(state & NES_START) && ButtonStartState == PRESSED ) {
    note(drumchan, note_hihatopen, 0);
    ButtonStartState = UNPRESSED;
  }
  
  if ( (state & NES_SELECT) && ButtonSelectState == UNPRESSED ) {
    note(drumchan,  note_hihatclosed, 100);
    ButtonSelectState = PRESSED;
  } else if ( !(state & NES_SELECT) && ButtonSelectState == PRESSED ) {
    note(drumchan, note_hihatclosed, 0);
    ButtonSelectState = UNPRESSED;
  }
  
}

// Send a MIDI note-on message.  Like pressing a piano key
void note(byte channel, byte note, byte velocity) {
  midiMsg( (0x80 | (channel<<4)), note, velocity);
}

// Send a general MIDI message
void midiMsg(byte cmd, byte data1, byte data2) {
  digitalWrite(ledPin,HIGH);  // indicate we're sending MIDI data
  Serial.print(cmd, BYTE);
  Serial.print(data1, BYTE);
  Serial.print(data2, BYTE);
  digitalWrite(ledPin,LOW);
}
