Space invaders with a nRF2401A wireless joypad

Dependencies:   Gameduino mbed nRF2401A

Fork of Gameduino_Invaders_game by Chris Dick

Gameduino and an nRF2401A hooked up to an mbed on an mbeduino:

/media/uploads/TheChrisyd/2014-03-08_22.53.54.jpg

Revision:
0:8a7c58553b44
Child:
1:f44175dd69fd
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/utils.h	Thu Jun 21 19:13:34 2012 +0000
@@ -0,0 +1,232 @@
+#ifndef COM_ARTLUM_GDUTILS_INCLUDED
+#define COM_ARTLUM_GDUTILS_INCLUDED
+#include "arduino.h"
+#include "GD.h"
+//#include "WProgram.h"
+
+/*---------------------------------------------------
+  Coprocessor controller - makes it easy to do
+  raster effects (eg. split screens) without
+  writing any FORTH.
+  
+  The way this works is that you build a list of
+  instructions in memory (a "copperlist") and
+  the coprocessor will execute the list on every
+  video frame.
+  
+  Code samples:
+  
+  void setup() {
+    ...
+    // Make a copperlist to change a palette color on line 100
+    // The copperlist is stored on the Gameduino at address 0x3f80
+    Coprocessor::reset();
+    CopperlistBuilder cp;
+    cp.begin(0x3f80);
+    cp.wait(100);
+    cp.write16(PALETTE4A, 0x7fff);
+    cp.end();  // And start using the new copperlist
+  }
+ 
+  Modifying an existing copperlist:
+  
+  // Make a copperlist to set the horizontal scroll register
+  // on line 220 and modify the copperlist.
+  // a) Build the list
+  unsigned int XscrollInst;
+  void setup() {
+    ...
+    CopperlistBuilder cp;
+    cp.begin(0x3f80);
+    cp.wait(220);
+    XscrollInst = cp.position();    // Get current output location
+    cp.write16(SCROLL_X, 0);
+    cp.end();
+  }
+  // b) Modify the list with current 'xscroll'
+  void loop() {
+    CopperlistBuilder cp;
+    cp.begin(XscrollInst)           // Where the 'write16()' instruction is
+    cp.write16(SCROLL_X, xscroll);  // Overwrite the previous instruction
+  }
+
+  Notes: 
+  The Coprocessor object uses the "COMM" block
+  of memory at 0x2980 so don't mess with it.
+
+  The coprocessor also provides support for the
+  sound functions below.
+---------------------------------------------------*/
+class Coprocessor {
+public:
+  // This initializes everything and load the coprocessor code.
+  // You should call this in your setup() function after "GD.begin();"
+  //
+  // The sample page is the page of Gameduino memory to
+  // use as a buffer for sample playback. It *must* be
+  // on a page boundry (ie. bottom 8 bits are 0) and
+  // the whole page will be used so you can't use it
+  // for anything else.
+  static void reset(unsigned int samplePage=0x3f00);  // Default: Use memory from 0x3f00 to 0x3fff
+  
+  // Select a copperlist. The list will start running on the next video frame.
+  // nb. The "CopperlistBuilder::end()" function normally calls this automatically
+  // (unless you tell it not to...)
+  static void setCopperlist(unsigned int addr);
+  
+  // Where the sample playback page is located
+  static unsigned int samplePage();
+
+  // Where the coprocessor is currently reading samples
+  // from in the sample page. Use this info to keep the
+  // page full of fresh sample data for playback
+  static byte sampleReadPos();
+
+  // A copy of the coprocessor YLINE register
+  static int yline();
+};
+
+// This object helps you make a copperlist in memory
+class CopperlistBuilder {
+  unsigned int out,start;
+  void put(byte);
+  void put16(unsigned int);
+public:
+  // Available commands are:
+  // * Wait for a raster line
+  // * Write a byte to a memory location
+  // * Write a 16-bit word to a memory location
+  // * Copy a block of memory from one place to another
+  void begin(unsigned int dest);
+    void wait(int line);
+    void write(unsigned int addr, byte val);
+    void write16(unsigned int addr, unsigned int val);
+    void copy(unsigned int src, unsigned int dst, unsigned int numBytes);
+  void end(bool executeNow=true);
+
+  // Where I'm currently outputting
+  unsigned int position();
+};
+
+
+/*------------------------------------------------------------------
+  Sound functions - play synthesized sounds and sound samples
+  
+  These functions require support from the Coprocessor object
+  above. If you load different microcode they'll stop working...
+------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------
+  Synthesized sounds
+------------------------------------------------------------------*/
+#define SYNTHSOUNDS 0
+#if SYNTHSOUNDS
+// ADSR volume envelope
+struct ADSR {
+  byte attack;      // Attack time (in clock ticks)
+  byte decay;       // Decay time (in clock ticks)
+  byte sustain;     // Sustain level [0..255]
+  byte release;     // Release time (in clock ticks)
+  ADSR(byte a=4, byte d=4, byte s=90, byte r=30);
+  byte evaluate(unsigned int elapsedTime, unsigned int releaseTime);
+};
+
+// Change pitch of a sound as it plays
+struct PitchModulator {
+  // Vibrato
+  byte vibratoDelay;   // Delay before vibrato starts (in clock ticks)
+  byte vibrato;        // Amount of vibrato (percentage of note pitch)
+  char vibratoDelta;   // Added to 'vibrato' every clock tick 
+  // Pitch Sweep
+  byte sweepDelay;     // Delay before sweep starts (in clock ticks)
+  byte sweep;
+  char sweepDelta;
+  PitchModulator() {
+    vibratoDelay = 0;
+    vibrato = 0;
+    vibratoDelta = 0;
+  }
+  int evaluate(int startpitch, unsigned int time);
+};
+
+// All the parameters for a sound
+struct Sound {
+  ADSR adsr;
+  PitchModulator pm;
+};
+
+class SoundPlayer {
+  // Playback parameters
+  Sound sound;
+  byte volume;
+  unsigned int pitch;
+  unsigned int duration;
+  // Internal vars
+  unsigned int ticks;
+  bool active, releasing;
+  // Sound players form a linked list
+  bool isLinked;
+  SoundPlayer *link;
+  // The SoundPlayer is updated from SoundController
+  void update();
+  friend class SoundController;
+  // You can't copy me...
+  SoundPlayer(const SoundPlayer&);
+  void operator=(const SoundPlayer&);
+public:
+  SoundPlayer();
+  
+  // Set the sound parameters
+  SoundPlayer& setSound(const Sound&);
+
+  // Set playback volume in range [0..255], default = 255
+  SoundPlayer& setVolume(byte);
+ 
+  // Play a sound, pitch in Hz, duration in clock ticks.
+  // If duration is 'infinite' then the sound plays until you call 'release()'
+  // One "clock tick" is equivalent to one call to "SoundController::update()"
+  enum { infinite=0x7fff };
+  void play(unsigned int pitchHz, unsigned int duration=infinite);
+  
+  // Make the current sound enter the 'release' phase
+  void release();
+  
+  // Stop sound playback immediately
+  void stop();
+};
+#endif
+
+/*------------------------------------------------------------------
+  Main sound controller object
+------------------------------------------------------------------*/
+struct SoundController {
+  // Reset all sounds, return to silence
+  static void reset();
+
+  // Update all sound - call this at least once every video frame.
+  // The frequency at which you call this function is one "clock tick" for synthesised sounds
+  static void update();
+
+  // Play a sound sample from program memory
+  // Samples are eight bits and will be played at
+  // the system sample rate (see "Coprocessor").
+  // if "numBytes" is negative, the sample will repeat until you play
+  // another sample on the channel (eg. pass a null pointer to "playSample()"...)
+  static void playSample(prog_char*, int numBytes, byte channel);
+};
+
+
+
+/*------------------------------------------------------------
+  Useful little functions
+------------------------------------------------------------*/
+// Show a number on screen
+void showNumber(int n, byte x, byte y);
+void showHexNumber(unsigned int n, byte x, byte y);
+
+// Send screenshot to serial port
+
+void sendScreenshot();
+
+// COM_ARTLUM_GDUTILS_INCLUDED
+#endif