Space invaders with a nRF2401A wireless joypad

Dependencies:   Gameduino mbed nRF2401A

Fork of Gameduino_Invaders_game by Chris Dick

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers joystick.cpp Source File

joystick.cpp

00001 /*------------------------------------------------------------
00002   Universal joystick driver for Gameduino
00003   
00004   http://www.artlum.com/gameduino/gameduino.html#joystick
00005 ------------------------------------------------------------*/
00006 #include "joystick.h"
00007 #include "GD.h"
00008 //#include "nRF2401A.h"
00009 //#include <SPI.h>
00010 //#include <GD.h>
00011 
00012 // Change this line to enable your customized
00013 // joystick configuration
00014 // "1" = custom configuration
00015 // "0" = default (Sparkfun joystick)
00016 //
00017 #define CUSTOM_JOYSTICK 0
00018 #define WIRELESS
00019 extern GDClass GD;
00020 //extern nRF2401A    wireless_joypad;
00021 extern byte wireless_dpad;
00022 extern byte wireless_buttons;
00023 #if CUSTOM_JOYSTICK
00024 /*------------------------------------------------------------------
00025  Custom joystick configuration. This is what you need to
00026  hack to get your joystick working.
00027 
00028  The joystick layout can be customized by commenting
00029  or uncommenting the lines below.
00030  
00031  Notes
00032  -----
00033  To specify an analog pin for a button add "A0" to
00034  the pin number, eg. Analog pin 4 is "A0+4"
00035 
00036  When connecting a Joystick to an Arduino:
00037   * Digital pins 0/1 are used for system stuff.
00038   * Gameduino uses pins 2/9/10/11/13 for SPI interface
00039  
00040  That leaves digital pins 3/4/5/6/7/8/10 free, plus
00041  all the analog pins (which work as digital pins, too!)
00042 ------------------------------------------------------------------*/
00043 
00044 // eg. The following layout is good for an NES controller
00045 
00046 // Connect the four buttons to pins 3/4/5/6
00047 #define BUTTON_A_PIN 3
00048 #define BUTTON_B_PIN 4
00049 //#define BUTTON_C_PIN ?
00050 //#define BUTTON_X_PIN ?
00051 //#define BUTTON_Y_PIN ?
00052 //#define BUTTON_Z_PIN ?
00053 #define BUTTON_ST_PIN 5
00054 #define BUTTON_SEL_PIN 6
00055 
00056 // Connect the DPAD L/R/U/D to analog pins 2/3/4/5
00057 #define STICK_LEFT_PIN  (A0+2)
00058 #define STICK_RIGHT_PIN (A0+3)
00059 #define STICK_UP_PIN    (A0+4)
00060 #define STICK_DOWN_PIN  (A0+5)
00061 
00062 // Analog input is disabled...
00063 //#define ANALOG_X_PIN ?
00064 //#define ANALOG_Y_PIN ?
00065 
00066 // Make the DPAD emulate an analog joystick
00067 #define DIGITAL_EMULATE_ANALOG
00068 //#define ANALOG_EMULATE_DIGITAL
00069 
00070 #else
00071 
00072 #ifndef WIRELESS
00073 
00074 /*------------------------------------------------------------------
00075   Default: Sparkfun joystick
00076 ------------------------------------------------------------------*/
00077 #define BUTTON_A_PIN 3
00078 #define BUTTON_B_PIN 4
00079 // #define BUTTON_C_PIN ?
00080 // nb. Button X is pin 7 if you've hacked your board
00081 #define BUTTON_X_PIN 2
00082 // #define BUTTON_Y_PIN ?
00083 // #define BUTTON_Z_PIN ?
00084 #define BUTTON_ST_PIN 5
00085 #define BUTTON_SEL_PIN 6
00086 
00087 // Digital joystick/DPAD
00088 //#define STICK_LEFT_PIN  11
00089 //#define STICK_RIGHT_PIN 12
00090 //#define STICK_UP_PIN    13
00091 //#define STICK_DOWN_PIN  14
00092 
00093 // Analog joystick is enabled
00094 #define ANALOG_X_PIN 0
00095 #define ANALOG_Y_PIN 1
00096 
00097 // Enable digital joystick emulation
00098 // #define DIGITAL_EMULATE_ANALOG
00099 #define ANALOG_EMULATE_DIGITAL
00100 
00101 #endif
00102 #endif
00103 /*------------------------------------------------------
00104   Stop hacking now...!
00105   
00106   There are no user-servicable parts below this line
00107 ------------------------------------------------------*/
00108 
00109 
00110 #ifndef WIRELESS
00111 /*---------------------------------------------
00112   Joystick reader
00113 ---------------------------------------------*/
00114 static PROGMEM prog_uchar joystickPinList[] = {
00115 #ifdef BUTTON_A_PIN
00116   BUTTON_A_PIN
00117 #endif
00118 #ifdef BUTTON_B_PIN
00119   , BUTTON_B_PIN
00120 #endif
00121 #ifdef BUTTON_C_PIN
00122   , BUTTON_C_PIN
00123 #endif
00124 #ifdef BUTTON_X_PIN
00125   , BUTTON_X_PIN
00126 #endif
00127 #ifdef BUTTON_Y_PIN
00128   , BUTTON_Y_PIN
00129 #endif
00130 #ifdef BUTTON_Z_PIN
00131   , BUTTON_Z_PIN
00132 #endif
00133 #ifdef BUTTON_ST_PIN
00134   , BUTTON_ST_PIN
00135 #endif
00136 #ifdef BUTTON_SEL_PIN
00137   , BUTTON_SEL_PIN
00138 #endif
00139 #ifdef STICK_LEFT_PIN
00140   , STICK_LEFT_PIN,
00141     STICK_RIGHT_PIN,
00142     STICK_UP_PIN,
00143     STICK_DOWN_PIN
00144 #endif
00145 };
00146 #endif
00147 
00148 #ifdef WIRELESS
00149 
00150 #endif
00151 Joystick::Joystick()
00152 {
00153 #ifdef WIRELESS
00154    // wireless_joypad.attachRXHandler(&nRF2401A_rx, 0);
00155 #else
00156   // set up digital pins for dpad and buttons
00157    // const prog_uchar *pin = joystickPinList;
00158   for (byte i=0; i<sizeof(joystickPinList); ++i) {
00159     byte p = pgm_read_byte(joystickPinList+i);
00160     //pinMode(p,INPUT);
00161     //digitalWrite(p,HIGH);
00162     }
00163 #endif    
00164     
00165   
00166   stickX = stickY = 0;
00167   xCal = yCal = 0;
00168   buttons = prev = dpad = 0;
00169 
00170 #ifdef ANALOG_X_PIN
00171   dpad |= ANALOG_STICK_BIT;
00172 #endif
00173 }
00174 
00175 bool Joystick::hasAnalogStick()
00176 {
00177   return (dpad&ANALOG_STICK_BIT)!=0;
00178 }
00179 
00180 void Joystick::recalibrate()
00181 {
00182  
00183   read();
00184   xCal = stickX;
00185   yCal = stickY;
00186 }
00187 static char stickCalc(int a, char cal)
00188 {
00189   //a = ((analogRead(a)-512)/4)-cal;
00190   if (a < -128) a = -128;
00191   if (a >  127) a =  127;
00192   return char(a);
00193 }
00194 void Joystick::read()
00195 {
00196   // Joystick buttons
00197   prev = buttons;
00198   buttons = 0;
00199   #ifdef BUTTON_A_PIN
00200    // if (digitalRead(BUTTON_A_PIN)==LOW) {  buttons |= buttonA;      }
00201   #endif
00202   #ifdef BUTTON_B_PIN
00203   //  if (digitalRead(BUTTON_B_PIN)==LOW) {  buttons |= buttonB;      }
00204   #endif
00205   #ifdef BUTTON_C_PIN
00206 //    if (digitalRead(BUTTON_C_PIN)==LOW) {  buttons |= buttonC;      }
00207   #endif
00208   #ifdef BUTTON_X_PIN
00209   //  if (digitalRead(BUTTON_X_PIN)==LOW) {  buttons |= buttonX;      }
00210   #endif
00211   #ifdef BUTTON_Y_PIN
00212 //    if (digitalRead(BUTTON_Y_PIN)==LOW) {  buttons |= buttonY;      }
00213   #endif
00214   #ifdef BUTTON_Z_PIN
00215  //   if (digitalRead(BUTTON_Z_PIN)==LOW) {  buttons |= buttonZ;      }
00216   #endif
00217   #ifdef BUTTON_SEL_PIN
00218   //  if (digitalRead(BUTTON_SEL_PIN)==LOW){ buttons |= buttonSelect; }
00219   #endif
00220   #ifdef BUTTON_ST_PIN
00221   //  if (digitalRead(BUTTON_ST_PIN)==LOW){  buttons |= buttonStart;  }
00222   #endif
00223   #ifndef WIRELESS
00224   // Digital joystick/dpad
00225   dpad &= STICK_INFO_MASK;   // The top bits are informational...preserve them
00226   #else
00227   dpad = wireless_dpad;
00228   buttons = wireless_buttons;
00229   #endif
00230   
00231   #ifdef STICK_LEFT_PIN
00232   //  if (!digitalRead(STICK_LEFT_PIN))  { dpad |= STICK_LEFT_BIT;  }
00233   //  if (!digitalRead(STICK_RIGHT_PIN)) { dpad |= STICK_RIGHT_BIT; }
00234   //  if (!digitalRead(STICK_UP_PIN))    { dpad |= STICK_UP_BIT;    }
00235   //  if (!digitalRead(STICK_DOWN_PIN))  { dpad |= STICK_DOWN_BIT;  }
00236     #ifdef DIGITAL_EMULATE_ANALOG
00237       stickX = 0;
00238       if      (dpad&STICK_LEFT_BIT)  { stickX = -127; }
00239       else if (dpad&STICK_RIGHT_BIT) { stickX =  127; }
00240       stickY = 0;
00241       if      (dpad&STICK_UP_BIT)    { stickY =  127; }
00242       else if (dpad&STICK_DOWN_BIT)  { stickY = -127; }
00243     #endif
00244   #endif
00245 
00246   // Analog stick
00247   #ifdef ANALOG_X_PIN
00248     stickX = stickCalc(ANALOG_X_PIN,xCal);
00249   #endif
00250   #ifdef ANALOG_Y_PIN
00251     stickY = stickCalc(ANALOG_Y_PIN,yCal);
00252   #endif
00253   #ifdef ANALOG_EMULATE_DIGITAL
00254     if      (stickX < -40) { dpad |= STICK_LEFT_BIT;  }
00255     else if (stickX >  40) { dpad |= STICK_RIGHT_BIT; }
00256     if      (stickY >  40) { dpad |= STICK_UP_BIT;    }
00257     else if (stickY < -40) { dpad |= STICK_DOWN_BIT;  }
00258   #endif
00259 }
00260 
00261 /*--------------------------------------------------------
00262   Useful function to show joystick status on screen.
00263 
00264   Note: You won't make your program any smaller by
00265     removing this - the Arduino compiler is really,
00266     really good at discarding unused code.
00267 
00268     ie.    If you're not calling Joystick::dump() then it
00269     doesn't take up any space. Try it and see...!
00270 --------------------------------------------------------*/
00271 // Formatted output of joystick position
00272 static void jpos(int v, char *s, char t)
00273 {
00274   *s++ = t;
00275   *s++ = ':';
00276   boolean neg = (v<0);
00277   if (neg) {
00278     v = -v;
00279   }
00280   char *o = s;
00281   int m = 1000;
00282   while (m != 0) {
00283     int d = v/m;
00284     *o++ = d+'0';
00285     v -= d*m;
00286     m /= 10;
00287   }
00288   *o-- = 0;
00289   // Remove leading zeros
00290   while ((s<o) and (*s=='0')) {
00291     *s++ = ' ';
00292   }
00293   if (neg) {
00294     s[-1] = '-';
00295   }
00296 }
00297 void Joystick::dump(int sx, int sy)
00298 {
00299   char temp[32];
00300   if (hasAnalogStick()) {
00301     jpos(analogX(),temp,'X');
00302     GD.putstr(sx,sy++,temp);
00303     jpos(analogY(),temp,'Y');
00304     GD.putstr(sx,sy++,temp);
00305   }
00306   temp[0] = 'D';
00307   temp[1] = ':';
00308   char *s = temp+2;
00309   *s++ = left()  ?'L':'.';
00310   *s++ = right() ?'R':'.';
00311   *s++ = up()    ?'U':'.';
00312   *s++ = down()  ?'D':'.';
00313   *s = 0;
00314   GD.putstr(sx,sy++,temp);
00315   temp[0] = 'B';
00316   s = temp+2;
00317   *s++ = (buttons&buttonSelect)?'L':'.';
00318   *s++ = (buttons&buttonStart)?'S':'.';
00319   *s++ = (buttons&buttonZ)?'Z':'.';
00320   *s++ = (buttons&buttonY)?'Y':'.';
00321   *s++ = (buttons&buttonX)?'X':'.';
00322   *s++ = (buttons&buttonC)?'C':'.';
00323   *s++ = (buttons&buttonB)?'B':'.';
00324   *s++ = (buttons&buttonA)?'A':'.';
00325   *s = 0;
00326   GD.putstr(sx,sy++,temp);
00327 }