Invaders game for the Gameduino

Dependencies:   Gameduino mbed

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