Space invaders with a nRF2401A wireless joypad
Dependencies: Gameduino mbed nRF2401A
Fork of Gameduino_Invaders_game by
Gameduino and an nRF2401A hooked up to an mbed on an mbeduino:
Diff: joystick.cpp
- Revision:
- 0:8a7c58553b44
- Child:
- 1:f44175dd69fd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/joystick.cpp Thu Jun 21 19:13:34 2012 +0000 @@ -0,0 +1,305 @@ +/*------------------------------------------------------------ + Universal joystick driver for Gameduino + + http://www.artlum.com/gameduino/gameduino.html#joystick +------------------------------------------------------------*/ +#include "joystick.h" +#include "GD.h" +//#include <SPI.h> +//#include <GD.h> + +// Change this line to enable your customized +// joystick configuration +// "1" = custom configuration +// "0" = default (Sparkfun joystick) +// +#define CUSTOM_JOYSTICK 0 + + +#if CUSTOM_JOYSTICK +/*------------------------------------------------------------------ + Custom joystick configuration. This is what you need to + hack to get your joystick working. + + The joystick layout can be customized by commenting + or uncommenting the lines below. + + Notes + ----- + To specify an analog pin for a button add "A0" to + the pin number, eg. Analog pin 4 is "A0+4" + + When connecting a Joystick to an Arduino: + * Digital pins 0/1 are used for system stuff. + * Gameduino uses pins 2/9/10/11/13 for SPI interface + + That leaves digital pins 3/4/5/6/7/8/10 free, plus + all the analog pins (which work as digital pins, too!) +------------------------------------------------------------------*/ + +// eg. The following layout is good for an NES controller + +// Connect the four buttons to pins 3/4/5/6 +#define BUTTON_A_PIN 3 +#define BUTTON_B_PIN 4 +//#define BUTTON_C_PIN ? +//#define BUTTON_X_PIN ? +//#define BUTTON_Y_PIN ? +//#define BUTTON_Z_PIN ? +#define BUTTON_ST_PIN 5 +#define BUTTON_SEL_PIN 6 + +// Connect the DPAD L/R/U/D to analog pins 2/3/4/5 +#define STICK_LEFT_PIN (A0+2) +#define STICK_RIGHT_PIN (A0+3) +#define STICK_UP_PIN (A0+4) +#define STICK_DOWN_PIN (A0+5) + +// Analog input is disabled... +//#define ANALOG_X_PIN ? +//#define ANALOG_Y_PIN ? + +// Make the DPAD emulate an analog joystick +#define DIGITAL_EMULATE_ANALOG +//#define ANALOG_EMULATE_DIGITAL + +#else +/*------------------------------------------------------------------ + Default: Sparkfun joystick +------------------------------------------------------------------*/ +#define BUTTON_A_PIN 3 +#define BUTTON_B_PIN 4 +// #define BUTTON_C_PIN ? +// nb. Button X is pin 7 if you've hacked your board +#define BUTTON_X_PIN 2 +// #define BUTTON_Y_PIN ? +// #define BUTTON_Z_PIN ? +#define BUTTON_ST_PIN 5 +#define BUTTON_SEL_PIN 6 + +// Digital joystick/DPAD +//#define STICK_LEFT_PIN 11 +//#define STICK_RIGHT_PIN 12 +//#define STICK_UP_PIN 13 +//#define STICK_DOWN_PIN 14 + +// Analog joystick is enabled +#define ANALOG_X_PIN 0 +#define ANALOG_Y_PIN 1 + +// Enable digital joystick emulation +// #define DIGITAL_EMULATE_ANALOG +#define ANALOG_EMULATE_DIGITAL + +#endif + +/*------------------------------------------------------ + Stop hacking now...! + + There are no user-servicable parts below this line +------------------------------------------------------*/ +#define STICK_LEFT_BIT 0x01 +#define STICK_RIGHT_BIT 0x02 +#define STICK_UP_BIT 0x04 +#define STICK_DOWN_BIT 0x08 +#define ANALOG_STICK_BIT 0x80 +#define STICK_INFO_MASK (ANALOG_STICK_BIT) + +/*--------------------------------------------- + Joystick reader +---------------------------------------------*/ +static PROGMEM prog_uchar joystickPinList[] = { +#ifdef BUTTON_A_PIN + BUTTON_A_PIN +#endif +#ifdef BUTTON_B_PIN + , BUTTON_B_PIN +#endif +#ifdef BUTTON_C_PIN + , BUTTON_C_PIN +#endif +#ifdef BUTTON_X_PIN + , BUTTON_X_PIN +#endif +#ifdef BUTTON_Y_PIN + , BUTTON_Y_PIN +#endif +#ifdef BUTTON_Z_PIN + , BUTTON_Z_PIN +#endif +#ifdef BUTTON_ST_PIN + , BUTTON_ST_PIN +#endif +#ifdef BUTTON_SEL_PIN + , BUTTON_SEL_PIN +#endif +#ifdef STICK_LEFT_PIN + , STICK_LEFT_PIN, + STICK_RIGHT_PIN, + STICK_UP_PIN, + STICK_DOWN_PIN +#endif +}; +Joystick::Joystick() +{ + // set up digital pins for dpad and buttons + // const prog_uchar *pin = joystickPinList; + for (byte i=0; i<sizeof(joystickPinList); ++i) { + byte p = pgm_read_byte(joystickPinList+i); + //pinMode(p,INPUT); + //digitalWrite(p,HIGH); + } + stickX = stickY = 0; + xCal = yCal = 0; + buttons = prev = dpad = 0; + +#ifdef ANALOG_X_PIN + dpad |= ANALOG_STICK_BIT; +#endif +} +bool Joystick::hasAnalogStick() +{ + return (dpad&ANALOG_STICK_BIT)!=0; +} +void Joystick::recalibrate() +{ + read(); + xCal = stickX; + yCal = stickY; +} +static char stickCalc(int a, char cal) +{ + //a = ((analogRead(a)-512)/4)-cal; + if (a < -128) a = -128; + if (a > 127) a = 127; + return char(a); +} +void Joystick::read() +{ + // Joystick buttons + prev = buttons; + buttons = 0; + #ifdef BUTTON_A_PIN + // if (digitalRead(BUTTON_A_PIN)==LOW) { buttons |= buttonA; } + #endif + #ifdef BUTTON_B_PIN + // if (digitalRead(BUTTON_B_PIN)==LOW) { buttons |= buttonB; } + #endif + #ifdef BUTTON_C_PIN +// if (digitalRead(BUTTON_C_PIN)==LOW) { buttons |= buttonC; } + #endif + #ifdef BUTTON_X_PIN + // if (digitalRead(BUTTON_X_PIN)==LOW) { buttons |= buttonX; } + #endif + #ifdef BUTTON_Y_PIN +// if (digitalRead(BUTTON_Y_PIN)==LOW) { buttons |= buttonY; } + #endif + #ifdef BUTTON_Z_PIN + // if (digitalRead(BUTTON_Z_PIN)==LOW) { buttons |= buttonZ; } + #endif + #ifdef BUTTON_SEL_PIN + // if (digitalRead(BUTTON_SEL_PIN)==LOW){ buttons |= buttonSelect; } + #endif + #ifdef BUTTON_ST_PIN + // if (digitalRead(BUTTON_ST_PIN)==LOW){ buttons |= buttonStart; } + #endif + + // Digital joystick/dpad + dpad &= STICK_INFO_MASK; // The top bits are informational...preserve them + #ifdef STICK_LEFT_PIN + // if (!digitalRead(STICK_LEFT_PIN)) { dpad |= STICK_LEFT_BIT; } + // if (!digitalRead(STICK_RIGHT_PIN)) { dpad |= STICK_RIGHT_BIT; } + // if (!digitalRead(STICK_UP_PIN)) { dpad |= STICK_UP_BIT; } + // if (!digitalRead(STICK_DOWN_PIN)) { dpad |= STICK_DOWN_BIT; } + #ifdef DIGITAL_EMULATE_ANALOG + stickX = 0; + if (dpad&STICK_LEFT_BIT) { stickX = -127; } + else if (dpad&STICK_RIGHT_BIT) { stickX = 127; } + stickY = 0; + if (dpad&STICK_UP_BIT) { stickY = 127; } + else if (dpad&STICK_DOWN_BIT) { stickY = -127; } + #endif + #endif + + // Analog stick + #ifdef ANALOG_X_PIN + stickX = stickCalc(ANALOG_X_PIN,xCal); + #endif + #ifdef ANALOG_Y_PIN + stickY = stickCalc(ANALOG_Y_PIN,yCal); + #endif + #ifdef ANALOG_EMULATE_DIGITAL + if (stickX < -40) { dpad |= STICK_LEFT_BIT; } + else if (stickX > 40) { dpad |= STICK_RIGHT_BIT; } + if (stickY > 40) { dpad |= STICK_UP_BIT; } + else if (stickY < -40) { dpad |= STICK_DOWN_BIT; } + #endif +} + +/*-------------------------------------------------------- + Useful function to show joystick status on screen. + + Note: You won't make your program any smaller by + removing this - the Arduino compiler is really, + really good at discarding unused code. + + ie. If you're not calling Joystick::dump() then it + doesn't take up any space. Try it and see...! +--------------------------------------------------------*/ +// Formatted output of joystick position +static void jpos(int v, char *s, char t) +{ + *s++ = t; + *s++ = ':'; + boolean neg = (v<0); + if (neg) { + v = -v; + } + char *o = s; + int m = 1000; + while (m != 0) { + int d = v/m; + *o++ = d+'0'; + v -= d*m; + m /= 10; + } + *o-- = 0; + // Remove leading zeros + while ((s<o) and (*s=='0')) { + *s++ = ' '; + } + if (neg) { + s[-1] = '-'; + } +} +void Joystick::dump(int sx, int sy) +{ + char temp[32]; + if (hasAnalogStick()) { + jpos(analogX(),temp,'X'); + GD.putstr(sx,sy++,temp); + jpos(analogY(),temp,'Y'); + GD.putstr(sx,sy++,temp); + } + temp[0] = 'D'; + temp[1] = ':'; + char *s = temp+2; + *s++ = left() ?'L':'.'; + *s++ = right() ?'R':'.'; + *s++ = up() ?'U':'.'; + *s++ = down() ?'D':'.'; + *s = 0; + GD.putstr(sx,sy++,temp); + temp[0] = 'B'; + s = temp+2; + *s++ = (buttons&buttonSelect)?'L':'.'; + *s++ = (buttons&buttonStart)?'S':'.'; + *s++ = (buttons&buttonZ)?'Z':'.'; + *s++ = (buttons&buttonY)?'Y':'.'; + *s++ = (buttons&buttonX)?'X':'.'; + *s++ = (buttons&buttonC)?'C':'.'; + *s++ = (buttons&buttonB)?'B':'.'; + *s++ = (buttons&buttonA)?'A':'.'; + *s = 0; + GD.putstr(sx,sy++,temp); +} \ No newline at end of file