Version of Robotron arcade game using LPC1768, a Gameduino shield, a serial EEPROM (for high scores), two microswitch joysticks and two buttons plus a box to put it in. 20 levels of mayhem.

Dependencies:   25LCxxx_SPI CommonTypes Gameduino mbed

Files at this revision

API Documentation at this revision

Comitter:
RichardE
Date:
Sat Jun 08 11:24:05 2013 +0000
Parent:
3:a6a0cd726ca0
Child:
5:0b0651ac7832
Commit message:
Pulled in more code. Now panel controls are working. Level 0 (attract mode) now goes round an endless loop sending state of panel controls up serial port to PC.

Changed in this revision

ArenaConst.cpp Show annotated file Show diff for this revision Revisions of this file
ArenaConst.h Show annotated file Show diff for this revision Revisions of this file
BCDNumber.cpp Show annotated file Show diff for this revision Revisions of this file
BCDNumber.h Show annotated file Show diff for this revision Revisions of this file
BulletManager.cpp Show annotated file Show diff for this revision Revisions of this file
BulletManager.h Show annotated file Show diff for this revision Revisions of this file
BulletObject.h Show annotated file Show diff for this revision Revisions of this file
BulletVelocities.h Show annotated file Show diff for this revision Revisions of this file
FrameCounter.cpp Show annotated file Show diff for this revision Revisions of this file
FrameCounter.h Show annotated file Show diff for this revision Revisions of this file
GameObject.cpp Show annotated file Show diff for this revision Revisions of this file
GameObject.h Show annotated file Show diff for this revision Revisions of this file
GameObjectLocator.cpp Show annotated file Show diff for this revision Revisions of this file
GameObjectLocator.h Show annotated file Show diff for this revision Revisions of this file
GameObjectTypes.h Show annotated file Show diff for this revision Revisions of this file
GameRobotRic.cpp Show annotated file Show diff for this revision Revisions of this file
GameRobotRic.h Show annotated file Show diff for this revision Revisions of this file
HighScoreEntry.cpp Show annotated file Show diff for this revision Revisions of this file
HighScoreEntry.h Show annotated file Show diff for this revision Revisions of this file
Int16Pair.h Show annotated file Show diff for this revision Revisions of this file
Level.h Show annotated file Show diff for this revision Revisions of this file
Level0.cpp Show annotated file Show diff for this revision Revisions of this file
PanelControls.h Show annotated file Show diff for this revision Revisions of this file
PlayerObject.cpp Show annotated file Show diff for this revision Revisions of this file
PlayerObject.h Show annotated file Show diff for this revision Revisions of this file
Random.h Show annotated file Show diff for this revision Revisions of this file
Rectangle.cpp Show annotated file Show diff for this revision Revisions of this file
Rectangle.h Show annotated file Show diff for this revision Revisions of this file
SpriteGroup.h Show annotated file Show diff for this revision Revisions of this file
SpriteImageId.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ArenaConst.cpp	Sat Jun 08 11:24:05 2013 +0000
@@ -0,0 +1,11 @@
+#include "ArenaConst.h"
+#include "GameObject.h"
+
+// Rectangle defining boundaries of arena.
+Rectangle ArenaRectangle(
+    GameObject::FromPixel( ARENA_MIN_X ),
+    GameObject::FromPixel( ARENA_MIN_Y ),
+    GameObject::FromPixel( ARENA_MIN_X + ARENA_WIDTH - 1 ),
+    GameObject::FromPixel( ARENA_MIN_Y + ARENA_HEIGHT - 1 )
+);
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ArenaConst.h	Sat Jun 08 11:24:05 2013 +0000
@@ -0,0 +1,38 @@
+/*
+ * SOURCE FILE : ArenaConst.h
+ *
+ * A few more constants associated with screen coordinates for gameplay arena.
+ *
+ */
+
+#ifndef ArenaConstIncluded
+  
+  #define ArenaConstIncluded
+
+  #include "GameObject.h"
+  #include "GDConst.h"
+  #include "Rectangle.h"
+  
+  // Pixel coordinates and dimensions.
+  #define ARENA_MIN_X 8
+  #define ARENA_WIDTH 384
+  #define ARENA_MIN_Y 16
+  #define ARENA_HEIGHT 272
+  
+  // Character coordinates and dimensions.
+  #define ARENA_BORDER_X 0
+  #define ARENA_BORDER_Y 1
+  #define ARENA_BORDER_WIDTH 50
+  #define ARENA_BORDER_HEIGHT 36
+
+  // Rectangle defining boundaries of arena.
+  extern Rectangle ArenaRectangle;
+    
+  // Start coordinates for player. NOT pixel coordinates.
+  #define PLAYER_START_X GameObject::FromPixel( ( ARENA_MIN_X + ( ( ARENA_WIDTH - SPRITE_PIXEL_WIDTH ) >> 1 ) ) )
+  #define PLAYER_START_Y GameObject::FromPixel( ( ARENA_MIN_Y + ( ( ARENA_HEIGHT - SPRITE_PIXEL_HEIGHT ) >> 1 ) ) )
+
+#endif
+
+/* END of ArenaConst.h */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BCDNumber.cpp	Sat Jun 08 11:24:05 2013 +0000
@@ -0,0 +1,60 @@
+/*
+ * SOURCE FILE : BCDNumber.cpp
+ *
+ * A 4 byte unsigned BCD integer.
+ *
+ */
+
+#include "BCDNumber.h"
+
+/***********************/
+/* ADD TWO BCD NUMBERS */
+/***********************/
+// Pass first number in A.
+// Pass second number in B.
+// Pass pointer to result in result.
+// Pass carry flag in carry.
+// Remember numbers are BCD coded so 0x99999999 means 9 million,
+// 9 hundred and 99 thousand, 9 hundred and 99.
+// Returns carry flag. If this is set then overflow occurred.
+bool BCDNumber::Add( UInt32 numA, UInt32 numB, UInt32 *result, bool carry ) {
+  const UInt8 *ptrA = (const UInt8*)&numA;
+  const UInt8 *ptrB = (const UInt8*)&numB;
+  UInt8 *ptrR = (UInt8*)result;
+  UInt8 sum, digits;
+  for( UInt8 b = 0; b < ByteCount; ++b ) {
+    digits = 0;
+    // Add together lower 4 bits.
+    sum = ( *ptrA & 0xF ) + ( *ptrB & 0xF );
+    // If carry flag set then add one.
+    if( carry ) {
+      sum++;
+    }
+    // If result is >= 10 then set carry and subtract 10 from sum.
+    carry = ( sum >= 10 );
+    if( carry ) {
+      sum -= 10;
+    }
+    // Write lower 4 bits.
+    digits |= sum;
+    // Add together upper 4 bits and carry.
+    sum = ( ( *ptrA & 0xF0 ) >> 4 ) + ( ( *ptrB & 0xF0 ) >> 4 );
+    // If carry flag set then add one.
+    if( carry ) {
+      sum++;
+    }
+    // If result is >= 10 then set carry and subtract 10 from sum.
+    carry = ( sum >= 10 );
+    if( carry ) {
+      sum -= 10;
+    }
+    // Write upper 4 bits.
+    digits |= ( sum << 4 );
+    // Store digits in result and skip to next byte.
+    *ptrR++ = digits;
+    ptrA++;
+    ptrB++;
+  }
+  return carry;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BCDNumber.h	Sat Jun 08 11:24:05 2013 +0000
@@ -0,0 +1,39 @@
+/*
+ * SOURCE FILE : BCDNumber.h
+ *
+ * A 4 byte unsigned BCD integer.
+ *
+ */
+
+#ifndef BCDNumberIncluded
+  
+  #define BCDNumberIncluded
+  
+  #include "Types.h"
+  
+  class BCDNumber {
+    
+  public :
+  
+    enum {
+      ByteCount = 4,          // Number of bytes used to store number.
+    };
+
+    /***********************/
+    /* ADD TWO BCD NUMBERS */
+    /***********************/
+    // Pass first number in A.
+    // Pass second number in B.
+    // Pass pointer to result in result.
+    // Pass carry flag in carry.
+    // Remember numbers are BCD coded so 0x99999999 means 9 million,
+    // 9 hundred and 99 thousand, 9 hundred and 99.
+    // Returns carry flag. If this is set then overflow occurred.
+    static bool Add( UInt32 numA, UInt32 numB, UInt32 *result, bool carry = false );
+    
+  };
+
+#endif
+
+/* END of BCDNumber.h */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BulletManager.cpp	Sat Jun 08 11:24:05 2013 +0000
@@ -0,0 +1,81 @@
+/*
+ * SOURCE FILE : BulletManager.cpp
+ *
+ * Responsible for managing a collection of bullets.
+ *
+ */
+
+#include "BulletManager.h"
+// #include "BulletObject.h"
+// #include "ArenaConst.h"
+#include "GDExtra.h"
+
+/***************/
+/* CONSTRUCTOR */
+/***************/
+// Pass number of sprite to use for first bullet.
+// MaxBullets consequtive sprites will be used for bullets.
+BulletManager::BulletManager( UInt8 firstSpriteNumber ) {
+#if 0
+  // Initialise aspects of bullets that never change.
+  BulletObject *bullet;
+  for( UInt8 b = 0; b < MaxBullets; ++b ) {
+    bullet = bullets + b;
+    bullet->SpriteNumber = firstSpriteNumber + b;
+    bullet->PixelWidth = 6;
+    bullet->PixelHeight = 6;
+    bullet->Bounds = &ArenaRectangle;
+  }
+#endif
+}
+
+/**********************/
+/* START A BULLET OFF */
+/**********************/
+// Pass start coordinates in x and y (NOT pixel coordinates).
+// Pass bullet velocities in hv and vv (NOT pixel velocities).
+// Returns true if bullet was started successfully.
+bool BulletManager::StartBullet( Int16 x, Int16 y, Int16 hv, Int16 vv ) {
+#if 0
+  // Try and find an unused bullet slot.
+  UInt8 index;
+  if( GameObject::FindUnusedObject( bulletPointers, MaxBullets, &index ) ) {
+    // Found a free bullet slot. Point to entry in bullets array.
+    BulletObject *bullet = bullets + index;
+    bulletPointers[ index ] = bullet;
+    bullet->Start( x, y, hv, vv );
+    return true;
+  }
+  else {
+    // No free bullet slots.
+    return false;
+  }
+#else
+return false;
+#endif
+}
+
+/************************/
+/* KILL A SINGLE BULLET */
+/************************/
+// Pass index of bullet in b.
+void BulletManager::KillBullet( UInt8 b ) {
+#if 0
+    GameObject *bullet = bulletPointers[ b ];
+    if( bullet != (GameObject*)NULL ) {
+      bulletPointers[ b ] = (BulletObject*)NULL;
+      // Hide bullet sprite by setting y coordinate to 400.
+      GDExtra::HideSprite( bullet->SpriteNumber );
+    }
+#endif
+}
+
+/********************/
+/* KILL ALL BULLETS */
+/********************/
+void BulletManager::KillAllBullets( void ) {
+  for( UInt8 b = 0; b < MaxBullets; ++b ) {
+    KillBullet( b );
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BulletManager.h	Sat Jun 08 11:24:05 2013 +0000
@@ -0,0 +1,73 @@
+/*
+ * SOURCE FILE : BulletManager.h
+ *
+ * Responsible for managing a collection of bullets.
+ *
+ */
+
+#ifndef BulletManagerIncluded
+  
+  #define BulletManagerIncluded
+  
+  #include "Types.h"
+  #include "BulletObject.h"
+  
+  class BulletManager {
+  
+  public :
+
+    enum {
+      MaxBullets = 20,    // maximum number of bullets on the go at one tine.
+    };
+    
+    /***************/
+    /* CONSTRUCTOR */
+    /***************/
+    // Pass number of sprite to use for first bullet.
+    // MaxBullets consequtive sprites will be used for bullets.
+    BulletManager( UInt8 firstSpriteNumber );
+    
+    /**********************/
+    /* START A BULLET OFF */
+    /**********************/
+    // Pass start coordinates in x and y (NOT pixel coordinates).
+    // Pass bullet velocities in hv and vv (NOT pixel velocities).
+    // Returns true if bullet was started successfully.
+    bool StartBullet( Int16 x, Int16 y, Int16 hv, Int16 vv );
+    
+    /************************/
+    /* KILL A SINGLE BULLET */
+    /************************/
+    // Pass index of bullet in b.
+    void KillBullet( UInt8 b );
+
+    /********************/
+    /* KILL ALL BULLETS */
+    /********************/
+    void KillAllBullets( void );
+    
+    /************************************************/
+    /* GET ARRAY CONTAINING POINTERS TO ALL BULLETS */
+    /************************************************/
+    // Returns pointer to array of GameObject pointers.
+    // The array has BulletManager::MaxBullets pointers in it.
+    GameObject **GetBullets( void ) {
+      return bulletPointers;
+    }
+    
+  private :
+
+    // All the bullets.
+    BulletObject bullets[ MaxBullets ];
+
+    // Pointers to all the bullets.
+    // Entries in this array will be NULL for bullets that are not active.
+    // When bullet is active it will point to the corresponding entry in the bullets array.
+    GameObject *bulletPointers[ MaxBullets ];
+    
+  };
+  
+#endif
+
+/* END of BulletManager.h */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BulletObject.h	Sat Jun 08 11:24:05 2013 +0000
@@ -0,0 +1,90 @@
+/*
+ * SOURCE FILE : BulletObject.h
+ *
+ * Represents a bullet type objects with horizontal and vertical velocities.
+ *
+ */
+
+#ifndef BulletObjectIncluded
+  
+  #define BulletObjectIncluded
+
+  #include "Gameduino.h"
+  #include "GameObject.h"
+  #include "SpriteImageId.h"
+  #include "SpriteGroup.h"
+
+  class BulletObject : public GameObject {
+    
+  public :
+
+    /***************/
+    /* CONSTRUCTOR */
+    /***************/
+    BulletObject() :
+      imageNumber( PlayerBulletImage ),
+      spriteGroup( GoodGuy )
+    {
+      DeleteWhenRestricted = true;
+    }
+    
+    /**************/
+    /* DESTRUCTOR */
+    /**************/
+    virtual ~BulletObject() {
+    }
+    
+    /************************/
+    /* GET GAME OBJECT TYPE */
+    /************************/
+    // Returns type of game object.
+    virtual GameObjectTypes GetType( void ) {
+      return BulletObjectType;
+    }
+
+    /****************/
+    /* START BULLET */
+    /****************/
+    void Start( Int16 x, Int16 y, Int16 hv, Int16 vv ) {
+      Xco = x;
+      Yco = y;
+      hSpeed = hv;
+      vSpeed = vv;
+      Visible = true;
+    }
+    
+    /************************/
+    /* MOVE THE GAME OBJECT */
+    /************************/
+    virtual void ProtectedMove( void ) {
+      Xco += hSpeed;
+      Yco += vSpeed;
+    }
+
+    /************************/
+    /* DRAW THE GAME OBJECT */
+    /************************/
+    // This is only called after it has been established that the
+    // game object is visible.
+    virtual void Draw( void ) {
+      // GD.sprite( SpriteNumber, ToPixel( Xco ), ToPixel( Yco ), imageNumber, 0, 0, spriteGroup );
+    }
+   
+  private :
+
+    // Number of sprite image used for bullet.
+    SpriteImageId imageNumber;
+
+    // Indicates whether these are good or bad bullets for
+    // purposes of collision detection.
+    SpriteGroup spriteGroup;
+    
+    // Horizontal and vertical velocities.
+    Int16 hSpeed, vSpeed;
+
+  };
+    
+#endif
+
+/* END of BulletObject.h */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BulletVelocities.h	Sat Jun 08 11:24:05 2013 +0000
@@ -0,0 +1,121 @@
+/*
+ * SOURCE FILE : BulletVelocities.h
+ *
+ * Converts from set of joystick inputs to horizontal and vertical velocities.
+ *
+ */
+
+#ifndef BulletVelocitiesIncluded
+  
+  #define BulletVelocitiesIncluded
+
+  #include "Int16Pair.h"
+  
+  class BulletVelocities {
+  
+  public :
+
+    /***************/
+    /* CONSTRUCTOR */
+    /***************/
+    // Pass velocity for a horizontally moving bullet in h.
+    // Pass velocity for a vertically moving bullet in v.
+    BulletVelocities( Int16 h, Int16 v ) {
+      // Calculate velocities used on the diagonal.
+      // This is really doing hd = h * cos( 45 degrees ) and
+      // vd = v * sin( 45 degrees ).
+      Int16 hd = (Int16)floor( (double)h * 0.707 + 0.5 );
+      Int16 vd = (Int16)floor( (double)v * 0.707 + 0.5 );
+      // Initialise the table of velocities.
+      Int16Pair *ptr = pairs;
+      // No joystick contacts closed. Index 0.
+      ptr->X = 0;
+      ptr->Y = 0;
+      ptr++;
+      // Joystick up. Index 1
+      ptr->X = 0;
+      ptr->Y = -v;
+      ptr++;
+      // Joystick down. Index 2.
+      ptr->X = 0;
+      ptr->Y = v;
+      ptr++;
+      // Joystick up and down (impossible). Index 3.
+      ptr->X = 0;
+      ptr->Y = v;
+      ptr++;
+      // Joystick left. Index 4.
+      ptr->X = -h;
+      ptr->Y = 0;
+      ptr++;
+      // Joystick left and up. Index 5.
+      ptr->X = -hd;
+      ptr->Y = -vd;
+      ptr++;
+      // Joystick left and down. Index 6.
+      ptr->X = -hd;
+      ptr->Y = vd;
+      ptr++;
+      // Joystick up, down and left (impossible). Index 7.
+      ptr->X = 0;
+      ptr->Y = v;
+      ptr++;
+      // Joystick right. Index 8.
+      ptr->X = h;
+      ptr->Y = 0;
+      ptr++;
+      // Joystick right and up. Index 9.
+      ptr->X = hd;
+      ptr->Y = -vd;
+      ptr++;
+      // Joystick right and down. Index 10.
+      ptr->X = hd;
+      ptr->Y = vd;
+      ptr++;
+      // Joystick up, down and right (impossible). Index 11.
+      ptr->X = 0;
+      ptr->Y = v;
+      ptr++;
+      // Joystick left and right (impossible). Index 12.
+      ptr->X = 0;
+      ptr->Y = v;
+      ptr++;
+      // Joystick up, left and right (impossible). Index 13.
+      ptr->X = 0;
+      ptr->Y = v;
+      ptr++;
+      // Joystick down, left and right (impossible) Index 14.
+      ptr->X = 0;
+      ptr->Y = v;
+      ptr++;
+      // Joystick up, down, left and right (impossible). Index 15.
+      ptr->X = 0;
+      ptr->Y = v;
+      ptr++;
+    }
+
+    /*******************************************************/
+    /* GET VELOCITIES FOR A COMBINATION OF JOYSTICK INPUTS */
+    /*******************************************************/
+    // Pass a map containing joystick inputs where a set bit indicates a closed contact.
+    // Bits must be ordered as follows :
+    // Bit 0 = Up.
+    // Bit 1 = Down.
+    // Bit 2 = Left.
+    // Bit 3 = Right.
+    // Remaining bits are ignored.
+    const Int16Pair *GetVelocities( UInt8 joyMap ) const {
+      return pairs + ( joyMap & 0x0F );
+    }
+    
+  private :
+
+    // Horizontal and vertical velocities for each combination of joystick inputs.    
+    Int16Pair pairs[ 16 ];
+    
+  };
+  
+#endif
+
+/* END of BulletVelocities.h */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FrameCounter.cpp	Sat Jun 08 11:24:05 2013 +0000
@@ -0,0 +1,11 @@
+/*
+ * SOURCE FILE : FrameCounter.h
+ *
+ * A counter updated on every vertical fram flyback.
+ *
+ */
+
+#include "Types.h"
+
+UInt8 FrameCounter = 0;  
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FrameCounter.h	Sat Jun 08 11:24:05 2013 +0000
@@ -0,0 +1,17 @@
+/*
+ * SOURCE FILE : FrameCounter.h
+ *
+ * A counter updated on every vertical frame flyback.
+ *
+ */
+
+#ifndef FrameCounterIncluded
+
+  #include "Types.h"
+
+  extern UInt8 FrameCounter;  
+  
+#endif
+
+/* END of FrameCounter.h */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GameObject.cpp	Sat Jun 08 11:24:05 2013 +0000
@@ -0,0 +1,236 @@
+/*
+ * SOURCE FILE : GameObject.cpp
+ *
+ * The abstract base class for all graphical game objects.
+ *
+ */
+
+#include "GameObject.h"
+#include "GameObjectLocator.h"
+// #include "ArenaConst.h"
+#include "GDExtra.h"
+
+/**********************************/
+/* INITIALISE AN ARRAY OF OBJECTS */
+/**********************************/
+// Really only intended for the initialisation of enemy objects and humans.
+// Each object in the array is allocated a consecutive sprite number and is positioned
+// randomly in the arena. The objects movement is restricted to within the arena.
+// Pass pointer to array of pointers to GameObjects in objects.
+// Pass number of pointers in the array in objectCount.
+// Pass pointer to a sprite number in spriteNumber. This number is incremented by this method.
+void GameObject::InitialiseAll( GameObject **objects, UInt8 objectCount, UInt8 *spriteNumber ) {
+#if 0
+  GameObject *object;
+  for( UInt8 i = 0; i < objectCount; ++i ) {
+    object = objects[ i ];
+    if( object != (GameObject*)NULL ) {
+      // Use next sprite number.
+      object->SpriteNumber = *spriteNumber;
+      // Position object randomly.
+      GameObjectLocator::Locate( object );
+      // Restrict movement to arena.
+      object->MovementRestricted = true;
+      object->Bounds = &ArenaRectangle;
+    }
+        // Next sprite number.
+        (*spriteNumber)++;
+  }
+#endif
+}
+
+/****************************/
+/* MOVE AN ARRAY OF OBJECTS */
+/****************************/
+// Pass pointer to array of pointers to GameObjects in objects.
+// Pass number of pointers in the array in objectCount.
+// Returns true if any non-null objects were found in the array.
+bool GameObject::MoveAll( GameObject **objects, UInt8 objectCount ) {
+  GameObject *object;
+  bool foundNonNull = false;
+  for( UInt8 i = 0; i < objectCount; ++i ) {
+    object = objects[ i ];
+    if( object != (GameObject*)NULL ) {
+      foundNonNull = true;
+      object->Move();
+    }
+  }
+  return foundNonNull;
+}
+
+/****************************/
+/* DRAW AN ARRAY OF OBJECTS */
+/****************************/
+// Pass pointer to array of pointers to GameObjects in objects.
+// Pass number of pointers in the array in objectCount.
+void GameObject::DrawAll( GameObject **objects, UInt8 objectCount ) {
+#if 0
+  GameObject *object;
+  for( UInt8 i = 0; i < objectCount; ++i ) {
+    object = objects[ i ];
+    if( object != (GameObject*)NULL ) {
+      // Check if object is visible.
+      // If not then it wants killing off and a NULL
+      // should be written to the array of pointers
+      // and the sprite should be hidden.
+      if( ! object->Visible ) {
+        objects[ i ] = (GameObject*)NULL;
+        GDExtra::HideSprite( object->SpriteNumber );
+      }
+      else {
+        object->Draw();
+      }
+    }
+  }
+#endif
+}
+
+/************************************************/
+/* FIND AN UNUSED OBJECT IN AN ARRAY OF OBJECTS */
+/************************************************/
+// Pass pointer to array of pointers to GameObjects in objects.
+// Pass number of pointers in the array in objectCount.
+// Pass pointer to variable that will hold index of object found in index.
+// Returns true if an unused object was found, false if not.
+// An unused object is indicated by a null pointer in the array.
+bool GameObject::FindUnusedObject( GameObject **objects, UInt8 objectCount, UInt8 *index ) {
+  for( UInt8 i = 0; i < objectCount; ++i ) {
+    if( objects[ i ] == (GameObject*)NULL ) {
+      // Found a null pointer. Store index in index pointer
+      // and return true.
+      *index = i;
+      return true;
+    }
+  }
+  // Did not find a null pointer.
+  return false;
+}
+
+/****************************************************/
+/* FIND COLLISIONS WITH ALL THE OBJECTS IN AN ARRAY */
+/****************************************************/
+// Pass pointer to array of pointers to GameObjects in objects.
+// Pass number of pointers in the array in objectCount.
+// Pass pointer to a function that takes two UInt8 parameters in func.
+// The first parameter is the index of the object in the objects array that hit something.
+// The second parameter is the sprite number of the sprite which it hit.
+void GameObject::FindCollisions( GameObject **objects, UInt8 objectCount, void (*func)( UInt8, UInt8 ) ) {
+#if 0
+  GameObject *object;
+  UInt8 hitSpriteNumber;
+  // Repeat for each non-null object in the array.
+  for( UInt8 i = 0; i < objectCount; ++i ) {
+    object = objects[ i ];
+    if( object != (GameObject*)NULL ) {
+      // Get sprite number that has collided with the sprite number of the object.
+      hitSpriteNumber = GD.rd( COLLISION + object->SpriteNumber );
+      // If result is 0xFF then no collision was found.
+      if( hitSpriteNumber != 0xFF ) {
+        // Collision, so call function to deal with it.
+        func( i, hitSpriteNumber );
+      }
+    }
+  }
+#endif
+}
+
+/*************************************************************************/
+/* FIND AN OBJECT WITH A PARTICULAR SPRITE NUMBER IN AN ARRAY OF OBJECTS */
+/*************************************************************************/
+// Pass pointer to array of pointers to GameObjects in objects.
+// Pass number of pointers in the array in objectCount.
+// Pass sprite number to look for in spriteNumber.
+// Index of object with given sprite number written to variable pointed to by index.
+// Returns true if sprite number was found, false if not.
+bool GameObject::FindSpriteNumber( GameObject **objects, UInt8 objectCount, UInt8 spriteNumber, UInt8 *index ) {
+  GameObject *object;
+  for( UInt8 i = 0; i < objectCount; ++i ) {
+    object = objects[ i ];
+    if( ( object != (GameObject*)NULL ) && ( object->SpriteNumber == spriteNumber ) ) {
+      *index = i;
+      return true;
+    }
+  }
+  // Did not find sprite number.
+  return false;
+}
+
+/**********************************************/
+/* FIND NEAREST OBJECT IN AN ARRAY OF OBJECTS */
+/**********************************************/
+// Pass pointer to array of pointers to GameObjects in objects.
+// Pass number of pointers in the array in objectCount.
+// Pass x and y coordinates of point you want to check.
+// Pass pointer to validation function in ValidFunc.
+// This is used to establish if a particular object is to be considered
+// when finding nearest object. It should return true if object should be considered
+// or false to ignore it. Pass NULL if all objects are considered valid.
+// Pass pointer to variable that will hold index of object found in index.
+// Returns true if nearest object was found, false if not (maybe no objects in array).
+bool GameObject::FindNearestObject(
+    GameObject **objects, UInt8 objectCount,
+    Int16 x, Int16 y,
+    bool (*ValidFunc)( GameObject *object ),
+    UInt8 *index
+) {
+  GameObject *object;
+    bool found = false;
+    Int16 minDistance = 0x7FFF, distance;
+  for( UInt8 i = 0; i < objectCount; ++i ) {
+    object = objects[ i ];
+    if(
+            ( object != (GameObject*)NULL ) &&
+            ( ( ValidFunc == NULL ) || ValidFunc( object ) )
+        ) {
+            // This calculation doesn't really calculate the distance between points.
+            // Should really be calculating square root of the sum of the squares of the
+            // difference between coordinates. Could leave out the square root.
+            // However, this is a lot quicker, has less danger of overflow and is a
+            // fairly good approximation for the purposes of a game.
+            distance = abs( x - object->Xco ) + abs( y - object->Yco );
+            if( distance < minDistance ) {
+                found = true;
+                minDistance = distance;
+                *index = i;
+            }
+    }
+  }
+  return found;
+}
+
+/***************************************************************************/
+/* REMOVE ALL OBJECTS IN AN ARRAY THAT ARE NOT RETAINED ON A LEVEL RESTART */
+/***************************************************************************/
+// Pass pointer to array of pointers to GameObjects in objects.
+// Pass number of pointers in the array in objectCount.
+// All objects pointed to in the array that have their RetainOnLevelRestart property set
+// to false are removed by writing NULL into the array.
+void GameObject::RemoveUnretainedObjects( GameObject **objects, UInt8 objectCount ) {
+  GameObject *object;
+  for( UInt8 i = 0; i < objectCount; ++i ) {
+    object = objects[ i ];
+    if( ( object != (GameObject*)NULL ) && ! object->RetainOnLevelRestart ) {
+            objects[ i ] = (GameObject*)NULL;
+    }
+  }
+}
+
+/*******************************/
+/* MOVE TOWARDS ANOTHER OBJECT */
+/*******************************/
+// Pass object to move towards in object.
+// Pass speed at which to move in speed.
+void GameObject::MoveTowards( GameObject *object, Int16 speed ) {
+  if( Xco <= object->Xco - speed ) {
+    Xco += speed;
+  }
+  else if( Xco >= object->Xco + speed ) {
+    Xco -= speed;
+  }
+  if( Yco <= object->Yco - speed ) {
+    Yco += speed;
+  }
+  else if( Yco >= object->Yco + speed ) {
+    Yco -= speed;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GameObject.h	Sat Jun 08 11:24:05 2013 +0000
@@ -0,0 +1,285 @@
+/*
+ * SOURCE FILE : GameObject.h
+ *
+ * The abstract base class for all graphical game objects.
+ *
+ */
+
+#ifndef GameObjectIncluded
+  
+  #define GameObjectIncluded
+
+  #include "Gameduino.h"              // Gameduino stuff
+  #include "Types.h"
+  #include "GDConst.h"
+  #include "SpriteImageId.h"
+  #include "SpriteGroup.h"
+  #include "GameObjectTypes.h"
+  #include "Rectangle.h"
+  
+  class GameObject {
+    
+  public :
+
+    // Bitmasks to use with RestrictionFlags.
+    enum RestrictionMask {
+      UpRestriction = 1,
+      DownRestriction = 2,
+      LeftRestriction = 4,
+      RightRestriction = 8,
+    };
+    
+    // X coordinate (NOT pixel coordinate).
+    Int16 Xco;
+    
+    // Y coordinate (NOT pixel coordinate).
+    Int16 Yco;
+
+    // Pixel width.
+    UInt8 PixelWidth;
+    
+    // Pixel height.
+    UInt8 PixelHeight;
+    
+    // Visibility flag.
+    bool Visible;
+    
+    // Limits for object movement.
+    Rectangle *Bounds;
+    
+    // Indicates if movement is restricted.
+    bool MovementRestricted;
+    
+    // Indicates object should be deleted when moves outside restricted area.
+    bool DeleteWhenRestricted;
+    
+    // Flags which are set when object is being restricted.
+    // Only works when MovementRestricted is true.
+    // If MovementRestricted is false RestrictionFlags are always all zero.
+    // Use RestrictionMask enumeration with this field.
+    UInt8 RestrictionFlags;
+    
+    // Indicates which Gameduino sprite is being used for this object.
+    UInt8 SpriteNumber;
+    
+        // Determines if object is retained on a level restart.
+        // Most enemy objects are retained on a level restart, although their positions change.
+        // However, enemy bullets (for example) are killed off on a level restart.
+        bool RetainOnLevelRestart;
+        
+    /***************/
+    /* CONSTRUCTOR */
+    /***************/
+    GameObject() :
+      Xco( FromPixel( 100 ) ),
+      Yco( FromPixel( 100 ) ),
+      PixelWidth( SPRITE_PIXEL_WIDTH ),
+      PixelHeight( SPRITE_PIXEL_HEIGHT ),
+      Visible( true ),
+      Bounds( NULL ),
+      MovementRestricted( true ),
+      DeleteWhenRestricted( false ),
+      RestrictionFlags( 0 ),
+      SpriteNumber( 0 ),
+            RetainOnLevelRestart( true )
+    {
+    }
+
+    /**************/
+    /* DESTRUCTOR */
+    /**************/
+    // Must be virtual!
+    // If not then could end up calling the base class
+    // destructor for a derived class. Not pretty.
+    virtual ~GameObject() {
+    }
+     
+    /************************/
+    /* GET GAME OBJECT TYPE */
+    /************************/
+    // Returns type of game object.
+    virtual GameObjectTypes GetType( void ) = 0;
+    
+    // Note that coordinates for all game objects are NOT screen pixel coordinates.
+    // The coordinate system used has a much higher resolution that the screen.
+    // This allows objects to move at a speed of less than one pixel per screen update.
+    // Use the methods ToPixel and FromPixel to convert between game object coordinates
+    // and pixel coordinates.
+    
+    /********************************/
+    /* CONVERT TO PIXEL COORDINATES */
+    /********************************/
+    // Returns pixel equivalent of coordinate.
+    static Int16 ToPixel( Int16 x ) {
+      return ( x >> 6 );
+    }
+    
+    /**********************************/
+    /* CONVERT FROM PIXEL COORDINATES */
+    /**********************************/
+    // Returns pixel equivalent of coordinate.
+    static Int16 FromPixel( Int16 x ) {
+      return ( x << 6 );
+    }
+    
+    /************************/
+    /* MOVE THE GAME OBJECT */
+    /************************/
+    void Move( void ) {
+      ProtectedMove();
+      // Calculate coordinates for edges of object.
+      Int16 dx = FromPixel( ( SPRITE_PIXEL_WIDTH - PixelWidth ) >> 1 );
+      Int16 dy = FromPixel( ( SPRITE_PIXEL_HEIGHT - PixelHeight ) >> 1 );
+      Int16 left = Xco + dx;
+      Int16 top = Yco + dy;
+      Int16 right = left + FromPixel( PixelWidth - 1 );
+      Int16 bottom = top + FromPixel( PixelHeight - 1 );
+      RestrictionFlags = 0;
+      // Kill off or restrict movement if moved outside restricted area.
+      // Do nothing if Bounds is NULL.
+      if( Bounds != NULL ) {
+        if( DeleteWhenRestricted ) {
+          if(
+            left < Bounds->X1 ||
+            right > Bounds->X2 ||
+            top < Bounds->Y1 ||
+            bottom > Bounds->Y2
+          ) {
+            Visible = false;
+          }
+        }
+        else if( MovementRestricted ) {
+          if( left < Bounds->X1 ) {
+            Xco = Bounds->X1 - dx;
+            RestrictionFlags |= (UInt8)LeftRestriction;
+          }
+          else if( right > Bounds->X2 ) {
+            Xco = Bounds->X2 - FromPixel( PixelWidth - 1 );
+            RestrictionFlags |= (UInt8)RightRestriction;
+          }
+          if( top < Bounds->Y1 ) {
+            Yco = Bounds->Y1 - dy;
+            RestrictionFlags |= (UInt8)UpRestriction;
+          }
+          else if( bottom > Bounds->Y2 ) {
+            Yco = Bounds->Y2 - FromPixel( PixelHeight - 1 );
+            RestrictionFlags |= (UInt8)DownRestriction;
+          }
+        }
+      }
+    }
+
+    /************************/
+    /* DRAW THE GAME OBJECT */
+    /************************/
+    // Note if Visible is false this should not draw anything
+    // and/or hide the visible object.
+    virtual void Draw( void ) = 0;
+    
+    /**********************************/
+    /* INITIALISE AN ARRAY OF OBJECTS */
+    /**********************************/
+    // Really only intended for the initialisation of enemy objects and humans.
+    // Each object in the array is allocated a consecutive sprite number and is positioned
+    // randomly in the arena. The objects movement is restricted to within the arena.
+    // Pass pointer to array of pointers to GameObjects in objects.
+    // Pass number of pointers in the array in objectCount.
+    // Pass pointer to a sprite number in spriteNumber. This number is incremented by this method.
+    static void InitialiseAll( GameObject **objects, UInt8 objectCount, UInt8 *spriteNumber );
+
+    /****************************/
+    /* MOVE AN ARRAY OF OBJECTS */
+    /****************************/
+    // Pass pointer to array of pointers to GameObjects in objects.
+    // Pass number of pointers in the array in objectCount.
+    // Returns true if any non-null objects were found in the array.
+    static bool MoveAll( GameObject **objects, UInt8 objectCount );
+
+    /****************************/
+    /* DRAW AN ARRAY OF OBJECTS */
+    /****************************/
+    // Pass pointer to array of pointers to GameObjects in objects.
+    // Pass number of pointers in the array in objectCount.
+    static void DrawAll( GameObject **objects, UInt8 objectCount );
+
+    /************************************************/
+    /* FIND AN UNUSED OBJECT IN AN ARRAY OF OBJECTS */
+    /************************************************/
+    // Pass pointer to array of pointers to GameObjects in objects.
+    // Pass number of pointers in the array in objectCount.
+    // Pass pointer to variable that will hold index of object found in index.
+    // Returns true if an unused object was found, false if not.
+    // An unused object is indicated by a null pointer in the array.
+    static bool FindUnusedObject( GameObject **objects, UInt8 objectCount, UInt8 *index );
+
+    /****************************************************/
+    /* FIND COLLISIONS WITH ALL THE OBJECTS IN AN ARRAY */
+    /****************************************************/
+    // Pass pointer to array of pointers to GameObjects in objects.
+    // Pass number of pointers in the array in objectCount.
+    // Pass pointer to a function that takes two UInt8 parameters in func.
+    // The first parameter is the index of the object in the objects array that hit something.
+    // The second parameter is the sprite number of the sprite which it hit.
+    static void FindCollisions( GameObject **objects, UInt8 objectCount, void (*func)( UInt8, UInt8 ) );
+    
+    /*************************************************************************/
+    /* FIND AN OBJECT WITH A PARTICULAR SPRITE NUMBER IN AN ARRAY OF OBJECTS */
+    /*************************************************************************/
+    // Pass pointer to array of pointers to GameObjects in objects.
+    // Pass number of pointers in the array in objectCount.
+    // Pass sprite number to look for in spriteNumber.
+    // Index of object with given sprite number written to variable pointed to by index.
+    // Returns true if sprite number was found, false if not.
+    static bool FindSpriteNumber( GameObject **objects, UInt8 objectCount, UInt8 spriteNumber, UInt8 *index );
+
+    /**********************************************/
+    /* FIND NEAREST OBJECT IN AN ARRAY OF OBJECTS */
+    /**********************************************/
+    // Pass pointer to array of pointers to GameObjects in objects.
+    // Pass number of pointers in the array in objectCount.
+        // Pass x and y coordinates of point you want to check.
+        // Pass pointer to validation function in ValidFunc.
+        // This is used to establish if a particular object is to be considered
+        // when finding nearest object. It should return true if object should be considered
+        // or false to ignore it. Pass NULL if all objects are considered valid.
+    // Pass pointer to variable that will hold index of object found in index.
+    // Returns true if nearest object was found, false if not (maybe no objects in array).
+    static bool FindNearestObject(
+            GameObject **objects, UInt8 objectCount,
+            Int16 x, Int16 y,
+            bool (*ValidFunc)( GameObject *object ),
+            UInt8 *index
+        );
+
+        /***************************************************************************/
+        /* REMOVE ALL OBJECTS IN AN ARRAY THAT ARE NOT RETAINED ON A LEVEL RESTART */
+        /***************************************************************************/
+    // Pass pointer to array of pointers to GameObjects in objects.
+    // Pass number of pointers in the array in objectCount.
+        // All objects pointed to in the array that have their RetainOnLevelRestart property set
+        // to false are removed by writing NULL into the array.
+        static void RemoveUnretainedObjects( GameObject **objects, UInt8 objectCount );
+        
+        /*******************************/
+        /* MOVE TOWARDS ANOTHER OBJECT */
+        /*******************************/
+        // Pass object to move towards in object.
+        // Pass speed at which to move in speed.
+        void MoveTowards( GameObject *object, Int16 speed );
+        
+  protected :
+  
+    /************************/
+    /* MOVE THE GAME OBJECT */
+    /************************/
+    virtual void ProtectedMove( void ) = 0;
+  
+  private :
+
+  };
+    
+#endif
+
+/* END of GameObject.h */
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GameObjectLocator.cpp	Sat Jun 08 11:24:05 2013 +0000
@@ -0,0 +1,71 @@
+/*
+ * SOURCE FILE : GameObjectLocator.cpp
+ *
+ * Code for randomly positioning objects.
+ *
+ */
+
+#include "GameObjectLocator.h"
+#include "ArenaConst.h"
+#include "Random.h"
+
+// Indicates which quadrant to put next object in.
+UInt8 GameObjectLocator::quad = 0;
+
+/*************************************/
+/* POSITION OBJECT RANDOMLY IN ARENA */
+/*************************************/
+// Pass object to locate in obj.
+void GameObjectLocator::Locate( GameObject *obj ) {
+  Int16 x, y;
+  
+  // Calculate start pixel coordinates for player.
+  Int16 ppx = GameObject::ToPixel( PLAYER_START_X );
+  Int16 ppy = GameObject::ToPixel( PLAYER_START_Y );
+  
+  // Keep calculating random coordinates until coordinates chosen
+  // are some distance away from chase object.
+  do {
+    
+    x = Random::Get( ( ARENA_WIDTH >> 1 ) - SPRITE_PIXEL_WIDTH - 4 );
+    y = Random::Get( ( ARENA_HEIGHT >> 1 ) - SPRITE_PIXEL_HEIGHT - 4 );
+    
+    switch( quad ) {
+      
+    case 0 :
+      x += ARENA_MIN_X;
+      y += ARENA_MIN_Y;
+      break;
+      
+    case 1 :
+      x = ARENA_MIN_X + ARENA_WIDTH - SPRITE_PIXEL_WIDTH - x;
+      y += ARENA_MIN_Y;
+      break;
+      
+    case 2 :
+      x += ARENA_MIN_X;
+      y = ARENA_MIN_Y + ARENA_HEIGHT - SPRITE_PIXEL_HEIGHT - y;
+      break;
+      
+    case 3 :
+      x = ARENA_MIN_X + ARENA_WIDTH - SPRITE_PIXEL_WIDTH - x;
+      y = ARENA_MIN_Y + ARENA_HEIGHT - SPRITE_PIXEL_HEIGHT - y;
+      break;
+
+    }
+    
+  } while(
+    ( abs( x - ppx ) < ( SPRITE_PIXEL_WIDTH << 1 ) ) &&
+    ( abs( y - ppy ) < ( SPRITE_PIXEL_HEIGHT << 1 ) )
+  );
+  
+  obj->Xco = GameObject::FromPixel( x );
+  obj->Yco = GameObject::FromPixel( y );
+
+  // Use next quadrant on next call.
+  quad++;
+  quad &= 3;
+  
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GameObjectLocator.h	Sat Jun 08 11:24:05 2013 +0000
@@ -0,0 +1,34 @@
+/*
+ * SOURCE FILE : GameObjectLocator.h
+ *
+ * Code for randomly positioning objects.
+ *
+ */
+
+#ifndef GameObjectLocatorIncluded
+  
+  #define GameObjectLocatorIncluded
+
+  #include "GameObject.h"
+  
+  class GameObjectLocator {
+  
+  public :
+  
+    /*************************************/
+    /* POSITION OBJECT RANDOMLY IN ARENA */
+    /*************************************/
+    // Pass object to locate in obj.
+    static void Locate( GameObject *obj );
+
+  private :
+
+    // Indicates which quadrant to put next object in.
+    static UInt8 quad;
+    
+  };
+  
+#endif
+
+/* END of GameObjectLocator.h */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GameObjectTypes.h	Sat Jun 08 11:24:05 2013 +0000
@@ -0,0 +1,27 @@
+/*
+ * SOURCE FILE : GameObjectTypes.h
+ *
+ * Enumeration of all the game object types.
+ *
+ */
+
+#ifndef GameObjectTypesIncluded
+  
+  #define GameObjectTypesIncluded
+
+  // Note that different kinds of enemies can be distinguished using the EnemyType enumeration.
+  
+  enum GameObjectTypes {
+    PlayerObjectType,
+    BulletObjectType,
+    ExplosionObjectType,
+    EnemyObjectType,
+    HumanObjectType,
+    FiftyObjectType,
+    StarObjectType,
+  };
+  
+#endif
+
+/* END of GameObjectTypes.h */
+
--- a/GameRobotRic.cpp	Fri Jun 07 20:29:59 2013 +0000
+++ b/GameRobotRic.cpp	Sat Jun 08 11:24:05 2013 +0000
@@ -10,13 +10,10 @@
 #include "LevelCollection.h"       // all the levels
 #include "sprite.h"                // sprite data
 #include "RobotRicCharacterSet.h"  // character set used in this game
-#if 0
-    #include "GDExtra.h"               // extra Gameduino functions
-    #include "GDConst.h"               // a few more Gameduino constants
-    #include "ArenaConst.h"            // gameplay arena constants
-    #include "I2CEEPROM.h"                         // for access to serial EEPROM
-    #include "HighScoreEntry.h"                 // for getting player's name for high score table
-#endif
+#include "HighScoreEntry.h"        // for getting player's name for high score table
+#include "GDExtra.h"               // extra Gameduino functions
+#include "GDConst.h"               // a few more Gameduino constants
+#include "ArenaConst.h"            // gameplay arena constants
 
 // Define following for debugging messages to serial port.
 #define CHATTY
@@ -24,24 +21,16 @@
 // Number of lives player starts with.
 #define START_LIVES 5
 
-// Pin allocations for I2C communications link.
-#define EEPROM_SCL 5
-#define EEPROM_SDA 7
-#define EEPROM_WP 8
-
-// Address of EEPROM set using A0, A1 and A2 pins.
-#define ADDRESS_OF_EEPROM 0
-
 // Serial link to PC over USB cable. Globally accessible.
 Serial pc( USBTX, USBRX );
 
 /**************************/
 /* CHECK FOR A HIGH SCORE */
 /**************************/
+// Pass pointer to a Gameduino to display on in gd.
 // Pass pointer to high score table in highScores.
 // Pass score that was achieved in score.
-void GameRobotRic::CheckForHighScore( HighScoreTable *highScores, UInt32 score ) {
-#if 0
+void GameRobotRic::CheckForHighScore( Gameduino *gd, HighScoreTable *highScores, UInt32 score ) {
     UInt8 tablePos;
     // Enter name into high score table if score is high enough.
     if( ( tablePos = highScores->GetPositionInTable( player.Score ) ) < highScores->GetCapacity() ) {
@@ -49,11 +38,10 @@
         // Get player to input name.
         HighScoreEntry nameGetter;
         PlayerName name;
-        nameGetter.GetName( &name, &controls );
+        nameGetter.GetName( &name, &controls, gd );
         // Add name and score to table.
         highScores->Add( tablePos, &name, score );
     }
-#endif
 }
 
 /*****************/
@@ -61,9 +49,9 @@
 /*****************/
 // This NEVER exits.
 void GameRobotRic::Play( void ) {
-    #ifdef CHATTY
-        pc.puts( "Program has restarted!\r\n" );
-    #endif
+#ifdef CHATTY
+    pc.puts( "Program has restarted!\r\n" );
+#endif
     // Make a digital output for use as the Gameduino chip select pin. Deselect it.
     DigitalOut gameduinoCS( p8 );
     gameduinoCS = 1;
@@ -105,63 +93,55 @@
     HighScoreTable highScores( &eeprom );
     // Start on the attract level.
     UInt8 levelNumber = LevelCollection::AttractLevel;
-#if 0
-  player.Lives = START_LIVES;
-#endif
-  LevelCollection levels;
-  Level *level;
-  Level::LevelExitCode exitCode;
-#if 0
-  // Initialise panel controls.
-  controls.InitialisePins();
-  // Specify controls player should use.
-  player.SetControls( &controls );
-  // Restrict players movement.
-  player.MovementRestricted = true;
-  player.Bounds = &ArenaRectangle;
-#endif
-  // Repeat forever.
-  while( true ) {
-    // Get level specified by level number.
-    level = levels.GetLevel( levelNumber );
-    // If failed to get level with that number go back to first normal level.
-    // This will happen if player completes last level.
-    if( level == NULL ) {
-      levelNumber = LevelCollection::FirstNormalLevel;
-      // Refetch level.
-      level = levels.GetLevel( levelNumber );
+    player.Lives = START_LIVES;
+    LevelCollection levels;
+    Level *level;
+    Level::LevelExitCode exitCode;
+    // Initialise panel controls.
+    controls.InitialisePins();
+    // Specify controls player should use.
+    player.SetControls( &controls );
+    // Restrict players movement.
+    player.MovementRestricted = true;
+    player.Bounds = &ArenaRectangle;
+    // Repeat forever.
+    while( true ) {
+        // Get level specified by level number.
+        level = levels.GetLevel( levelNumber );
+        // If failed to get level with that number go back to first normal level.
+        // This will happen if player completes last level.
+        if( level == NULL ) {
+            levelNumber = LevelCollection::FirstNormalLevel;
+            // Refetch level.
+            level = levels.GetLevel( levelNumber );
+        }
+        // Pass reference to high score table.
+        level->SetHighScores( &highScores );
+        // Set player that is playing the level.
+        level->SetPlayer( &player );
+        // Set Gameduino to use.
+        level->SetGameduino( &gd );
+        // Play the level.
+        exitCode = level->Play();
+        // If player was killed then decrement lives otherwise
+        // advance to next level.
+        switch( exitCode ) {
+            case Level::GameOver :
+                // TODO : Do some sort of game over fuss.
+                CheckForHighScore( &gd, &highScores, player.Score );
+                // Go back to attract level and reset player lives and score.
+                levelNumber = LevelCollection::AttractLevel;
+                player.Lives = START_LIVES;
+                player.Score = 0;
+                break;
+            case Level::Completed :
+                levelNumber++;
+                break;
+        }
+        // Wait a bit.
+        wait( (float)2 );
     }
-    // Pass reference to high score table.
-    level->SetHighScores( &highScores );
-#if 0
-    // Set player that is playing the level.
-    level->SetPlayer( &player );
-#endif
-    // Set Gameduino to use.
-    level->SetGameduino( &gd );
-    // Play the level.
-    exitCode = level->Play();
-    // If player was killed then decrement lives otherwise
-    // advance to next level.
-    switch( exitCode ) {
-    case Level::GameOver :
-#if 0
-            // TODO : Do some sort of game over fuss.
-            CheckForHighScore( &highScores, player.Score );
-#endif
-            // Go back to attract level and reset player lives and score.
-            levelNumber = LevelCollection::AttractLevel;
-#if 0
-            player.Lives = START_LIVES;
-            player.Score = 0;
-#endif
-      break;
-    case Level::Completed :
-      levelNumber++;
-      break;
-    }
-    // Wait a bit.
-    wait( (float)2 );
-  }
 }
 
+
+
--- a/GameRobotRic.h	Fri Jun 07 20:29:59 2013 +0000
+++ b/GameRobotRic.h	Sat Jun 08 11:24:05 2013 +0000
@@ -11,7 +11,8 @@
 
   #include "Gameduino.h"          // Gameduino stuff
   #include "Game.h"               // base class for all games
-  // #include "PlayerObject.h"
+  #include "PanelControls.h"      // for joysticks and buttons
+  #include "PlayerObject.h"
   #include "HighScoreTable.h"     // for high score table stored in external EEPROM
 
   class GameRobotRic : public Game {
@@ -27,17 +28,18 @@
   private :
   
     // The one and only player.
-    // PlayerObject player;
+    PlayerObject player;
     
     // Controls used by player.
-    // PanelControls controls;
+    PanelControls controls;
     
     /**************************/
     /* CHECK FOR A HIGH SCORE */
     /**************************/
+    // Pass pointer to a Gameduino to display on in gd.
     // Pass pointer to high score table in highScores.
     // Pass score that was achieved in score.
-    void CheckForHighScore( HighScoreTable *highScores, UInt32 score );
+    void CheckForHighScore( Gameduino *gd, HighScoreTable *highScores, UInt32 score );
 
   };
     
--- a/HighScoreEntry.cpp	Fri Jun 07 20:29:59 2013 +0000
+++ b/HighScoreEntry.cpp	Sat Jun 08 11:24:05 2013 +0000
@@ -8,14 +8,12 @@
 
 #include "HighScoreEntry.h"
 #include "Gameduino.h"       // Gameduino stuff
-#if 0
-    #include "GDExtra.h"         // more Gameduino stuff
-    #include "GDConst.h"         // Gameduino constants
-    #include "CharBlocks.h"      // blocks of characters in program memory
-    #include "CharFrame.h"       // for drawing frames made of characters
-    #include "CharCodes.h"       // character codes
-    #include "FrameCounter.h"    // counter updated every vertical flyback
-#endif
+#include "GDExtra.h"         // more Gameduino stuff
+#include "GDConst.h"         // Gameduino constants
+#include "FrameCounter.h"    // counter updated every vertical flyback
+#include "CharBlocks.h"      // blocks of characters in program memory
+#include "CharFrame.h"       // for drawing frames made of characters
+#include "CharCodes.h"       // character codes
 
 /***************/
 /* CONSTRUCTOR */
@@ -36,8 +34,8 @@
 /*********************/
 // Pass pointer to place to store name in name.
 // Pass pointer to controls to read in controls.
-#if 0
-void HighScoreEntry::GetName( PlayerName *name, PanelControls *controls ) {
+// Pass pointer to Gameduino to display on in gd.
+void HighScoreEntry::GetName( PlayerName *name, PanelControls *controls, Gameduino *gd ) {
   UInt16 inputs;
   UInt8 countdown = 0;
   char *curPtr;
@@ -46,9 +44,9 @@
     name->Name[ i ] = 'A';
   }
   // Draw screen.
-  DrawScreen();
+  DrawScreen( gd );
   // Wait until player releases all controls.
-  WaitControls( controls, false );
+  WaitControls( gd, controls, false );
   // Start at leftmost character.
   cursorPos = 0;
   // Loop until cursor moves beyond rightmost character.
@@ -84,90 +82,86 @@
         if( cursorPos > 0 ) {
           cursorPos--;
           // Wait until all controls released.
-          WaitControls( controls, false );
+          WaitControls( gd, controls, false );
         }
       }
       else if( inputs & PanelControls::Right1 ) {
         // Joystick right moves cursor forwards.
         cursorPos++;
         // Wait until all controls released.
-        WaitControls( controls, false );
+        WaitControls( gd, controls, false );
       }
     }
     else {
       countdown--;
     }
     // Wait for vertical flyback. Then draw name and do animation.
-    GD.waitvblank();
+    gd->waitvblank();
     FrameCounter++;
-    DrawName( name );
-    Animate();
+    DrawName( gd, name );
+    Animate( gd );
   }
   // Wait until player releases all controls before returning.
-  WaitControls( controls, false );
+  WaitControls( gd, controls, false );
 }
-#endif
 
 /*********************/
 /* WAIT FOR CONTROLS */
 /*********************/
+// Pass pointer to Gameduino to display on in gd.
 // Pass pointer to controls to read in controls.
 // Pass true in waitActivate to wait for a control to be used.
 // Pass false to wait for release.
-#if 0
-void HighScoreEntry::WaitControls( PanelControls *controls, bool waitActivate ) {
-  boolean released = false;
+void HighScoreEntry::WaitControls( Gameduino *gd, PanelControls *controls, bool waitActivate ) {
+  bool released = false;
   UInt16 inputs;
   while( ! released ) {
     controls->Read();
     inputs = controls->GetInputs();
     released = ( waitActivate ? ( inputs != 0 ) : ( inputs == 0 ) );
     if( ! released ) {
-      GD.waitvblank();
+      gd->waitvblank();
       FrameCounter++;
-      Animate();
+      Animate( gd );
     }
   }
 }
-#endif
 
 /*******************/
 /* DRAW THE SCREEN */
 /*******************/
-void HighScoreEntry::DrawScreen( void ) {
-#if 0
-  GD.waitvblank();
+// Pass pointer to Gameduino to draw on in gd.
+void HighScoreEntry::DrawScreen( Gameduino *gd ) {
+  gd->waitvblank();
   // Clear the screen to zero characters.
-  GD.fill( RAM_PIC, 0, RAM_PIC_SIZE );
+  gd->fill( Gameduino::RAM_PIC, 0, RAM_PIC_SIZE );
   // Turn off all the sprites.
   for( UInt16 s = 0; s < SPRITE_COUNT; ++s ) {
-    GD.sprite( s, 0, 400, 0, 0 );
+    gd->sprite( s, 0, 400, 0, 0 );
   }
   // Draw border around screen.
-  CharFrame::Draw( 0, 0, VISIBLE_CHAR_WIDTH, VISIBLE_CHAR_HEIGHT );
+  CharFrame::Draw( gd, 0, 0, VISIBLE_CHAR_WIDTH, VISIBLE_CHAR_HEIGHT );
   // Draw logo.
-  GDExtra::WriteProgCharBlock( 2, 2, CharBlocks::EnterNameInstructionText );
-#endif
+  GDExtra::WriteProgCharBlock( gd, 2, 2, CharBlocks::EnterNameInstructionText );
 }
 
 /********************************/
 /* DRAW THE NAME AND THE CURSOR */
 /********************************/
+// Pass pointer to Gameduino to draw on in gd.
 // Pass player name in name.
-void HighScoreEntry::DrawName( PlayerName *name ) {
-#if 0
-  GD.putstr( 21, 11, name->Name );
-  UInt16 address = RAM_PIC + 12 * SCREEN_CHAR_WIDTH + 21;
+void HighScoreEntry::DrawName( Gameduino *gd, PlayerName *name ) {
+  gd->putstr( 21, 11, name->Name );
+  UInt16 address = Gameduino::RAM_PIC + 12 * SCREEN_CHAR_WIDTH + 21;
   for( UInt8 i = 0; i < PlayerName::Length; ++i ) {
-    GD.wr( address, ( i == cursorPos ) ? ArrowUp : ' ' );
+    gd->wr( address, ( i == cursorPos ) ? ArrowUp : ' ' );
     address++;
   }
-#endif
 }
 
 /********************/
 /* UPDATE ANIMATION */
 /********************/
-void HighScoreEntry::Animate( void ) {
+// Pass pointer to Gameduino to display on in gd.
+void HighScoreEntry::Animate( Gameduino *gd ) {
 }
-
--- a/HighScoreEntry.h	Fri Jun 07 20:29:59 2013 +0000
+++ b/HighScoreEntry.h	Sat Jun 08 11:24:05 2013 +0000
@@ -11,8 +11,9 @@
   #define HighScoreEntryDefined
 
   #include "Types.h"
-  // #include "PanelControls.h"   // for reading panel controls.
+  #include "PanelControls.h"   // for reading panel controls.
   #include "PlayerName.h"
+  #include "Gameduino.h"
   
   class HighScoreEntry {
 
@@ -33,7 +34,8 @@
     /*********************/
     // Pass pointer to place to store name in name.
     // Pass pointer to controls to read in controls.
-    // void GetName( PlayerName *name, PanelControls *controls );
+    // Pass pointer to Gameduino to display on in gd.
+    void GetName( PlayerName *name, PanelControls *controls, Gameduino *gd );
 
 private :
 
@@ -43,26 +45,30 @@
     /*********************/
     /* WAIT FOR CONTROLS */
     /*********************/
+    // Pass pointer to Gameduino to display on in gd.
     // Pass pointer to controls to read in controls.
     // Pass true in waitActivate to wait for a control to be used.
     // Pass false to wait for release.
-    // void WaitControls( PanelControls *controls, bool waitActivate );
+    void WaitControls( Gameduino *gd, PanelControls *controls, bool waitActivate );
 
     /*******************/
     /* DRAW THE SCREEN */
     /*******************/
-    void DrawScreen( void );    
+    // Pass pointer to Gameduino to display on in gd.
+    void DrawScreen( Gameduino *gd );    
 
     /********************************/
     /* DRAW THE NAME AND THE CURSOR */
     /********************************/
+    // Pass pointer to Gameduino to display on in gd.
     // Pass player name in name.
-    void DrawName( PlayerName *name );
+    void DrawName( Gameduino *gd, PlayerName *name );
     
     /********************/
     /* UPDATE ANIMATION */
     /********************/
-    void Animate( void );
+    // Pass pointer to Gameduino to display on in gd.
+    void Animate( Gameduino *gd );
 
   };
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Int16Pair.h	Sat Jun 08 11:24:05 2013 +0000
@@ -0,0 +1,45 @@
+/*
+ * SOURCE FILE : Int16Pair.h
+ *
+ * Pair of Int16s in a class.
+ *
+ */
+
+#ifndef Int16PairIncluded
+  
+  #define Int16PairIncluded
+
+  #include "Types.h"
+  
+  class Int16Pair {
+    
+  public :
+
+    // X and Y components.  
+    Int16 X, Y;
+    
+    /***************/
+    /* CONSTRUCTOR */
+    /***************/
+    Int16Pair() :
+      X( 0 ),
+      Y( 0 )
+    {
+    }
+    
+    /***************/
+    /* CONSTRUCTOR */
+    /***************/
+    // Pass X and Y components in x and y.
+    Int16Pair( Int16 x, Int16 y ) :
+      X( x ),
+      Y( y )
+    {
+    }
+    
+  };
+  
+#endif
+
+/* END of Int16Pair.h */
+
--- a/Level.h	Fri Jun 07 20:29:59 2013 +0000
+++ b/Level.h	Sat Jun 08 11:24:05 2013 +0000
@@ -19,6 +19,8 @@
   #include "StringData.h"
   #include "HighScoreTable.h"
   #include "CharFrame.h"
+  #include "PanelControls.h"
+  #include "PlayerObject.h"
 #if 0
   #include "ArenaConst.h"
   #include "SpriteImageId.h"
@@ -68,11 +70,9 @@
     /* SET PLAYER WHO IS PLAYING THE LEVEL */
     /***************************************/
     // Pass pointer to player in p.
-#if 0
     void SetPlayer( PlayerObject *p ) {
       player = p;
     }
-#endif
     
     // Enumeration of reasons why level ended.
     enum LevelExitCode {
@@ -95,7 +95,7 @@
     Gameduino *gd;
     
     // Player playing the level.
-    // PlayerObject *player;
+    PlayerObject *player;
     
     /*************/
     /* PLAY LOOP */
--- a/Level0.cpp	Fri Jun 07 20:29:59 2013 +0000
+++ b/Level0.cpp	Sat Jun 08 11:24:05 2013 +0000
@@ -6,10 +6,10 @@
  */
 
 #include "Level0.h"
-#if 0
-    #include "CharBlocks.h"
-    #include "EEPROMDump.h"
-#endif
+#include "CharBlocks.h"
+
+// REMOVE THIS!
+extern Serial pc;
 
 /***************/
 /* CONSTRUCTOR */
@@ -82,7 +82,6 @@
                DrawHighScores();
            }
       }
-      #if 0
       // Must have a player with non-NULL controls.
       PanelControls *controls;
       if(
@@ -99,9 +98,9 @@
         do {
           controls->Read();
           inputs = controls->GetInputs();
-        } while( inputs == 0 );
+          pc.printf( "Inputs = %04X\r\n", (int)inputs );
+        } while( true /* inputs == 0 */ );
       }
-      #endif
     }
     return Completed;
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PanelControls.h	Sat Jun 08 11:24:05 2013 +0000
@@ -0,0 +1,107 @@
+/*
+ * SOURCE FILE : PanelControls.h
+ *
+ * Responsible for reading joysticks and buttons.
+ * This is the version for mbed LPC1768.
+ * There is a version kicking around for the LPC11U24 that uses different inputs for joystick 2.
+ *
+ */
+
+#ifndef PanelControlsIncluded
+  
+  #define PanelControlsIncluded
+
+  #include "mbed.h"
+  #include "Types.h"
+  
+  class PanelControls {
+    
+  public :
+
+    /***************/
+    /* CONSTRUCTOR */
+    /***************/
+    PanelControls() :
+      inputs( 0 ),
+      bus( (BusIn*)NULL )
+    {
+    }
+    
+    /**************/
+    /* DESTRUCTOR */
+    /**************/
+    ~PanelControls() {
+      delete bus;
+    }
+    
+    /*************************/
+    /* INITIALISE INPUT PINS */
+    /*************************/
+    void InitialisePins( void ) {
+      // Create an input bus.
+      bus = new BusIn(
+        p23, p24, p25, p26, // joystick 1 up, down, left, right
+        p21, p22, p27, p28, // joystick 2 up, down, left, right
+        p29, p30            // button 1, button 2
+      );
+    }
+    
+    /*****************************/
+    /* READ ALL THE PANEL INPUTS */
+    /*****************************/
+    // Returns a bitmap of all the inputs.
+    void Read( void ) {
+      if( bus == (BusIn*)NULL ) {
+        inputs = 0;
+      }
+      else {
+        // Note that a closed contact registers as a zero
+        // which is why the bitwise not operator (~) is used.
+        inputs = ~*bus & 0x3FF;
+      }
+    }
+    
+    // Masks to use with GetInputs method.
+    enum Mask {
+      Up1 = 1,
+      Down1 = 2,
+      Left1 = 4,
+      Right1 = 8,
+      Up2 = 16,
+      Down2 = 32,
+      Left2 = 64,
+      Right2 = 128,
+      Button1 = 256,
+      Button2 = 512,
+    };
+    
+    // Bit numbers indicating where readings for each joystick start in the map.
+    // Can use these with right shift operator.
+    enum Bits {
+      Joy1 = 0,      // joystick 1 readings start at bit 0
+      Joy2 = 4,      // joystick 2 readings start at bit 4
+      Buttons = 8,   // button readings start at bit 8
+    };
+    
+    /***************************/
+    /* GET STATE OF THE INPUTS */
+    /***************************/
+    // Returns a bitmap of the state of the inputs
+    // last time Read was called.
+    UInt16 GetInputs( void ) {
+      return inputs;
+    }
+    
+  private :
+  
+    // Stored state of inputs.
+    UInt16 inputs;
+
+    // Input bus used to read inputs.
+    BusIn *bus;
+        
+  };
+    
+#endif
+
+/* END of PanelControls.h */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PlayerObject.cpp	Sat Jun 08 11:24:05 2013 +0000
@@ -0,0 +1,163 @@
+/*
+ * SOURCE FILE : PlayerObject.cpp
+ *
+ * Represents the player objects.
+ *
+ */
+
+#include "PlayerObject.h"
+// #include "SoundManager.h"
+// #include "Sounds.h"
+// #include "FrameCounter.h"
+
+// Bullet velocity information.
+BulletVelocities PlayerObject::bulletVelocities( FromPixel( 2 ), FromPixel( 2 ) );
+
+// Player velocity information.
+BulletVelocities PlayerObject::playerVelocities( FromPixel( 1 ), FromPixel( 1 ) );
+
+/***************/
+/* CONSTRUCTOR */
+/***************/
+PlayerObject::PlayerObject() :
+  Lives( 5 ),
+  Score( 0 ),
+  controls( (PanelControls*)NULL ),
+  playerBullets( 200 ),              // parameter is first sprite number used for bullets
+  bulletCountdown( 0 )
+{
+}
+
+/**************/
+/* DESTRUCTOR */
+/**************/
+PlayerObject::~PlayerObject() {
+}
+
+/************************/
+/* MOVE THE GAME OBJECT */
+/************************/
+void PlayerObject::ProtectedMove( void ) {
+#if 0
+  // Do nothing if controls are not specified.
+  if( controls != (PanelControls*)NULL ) {
+    // Read joysticks and buttons. Buttons are not used.
+    UInt16 map = controls->GetInputs();
+    // Extract bits relating to joystick 1 (player movement).
+    UInt16 joy1Map = ( map >> PanelControls::Joy1 ) & 0x0F;
+    // Fetch velocities associated with this combination of joystick inputs.
+    const Int16Pair *pair = playerVelocities.GetVelocities( joy1Map );
+    // Add on velocities to player coordinates.
+    Xco += pair->X;
+    Yco += pair->Y;
+    // Deal with starting a new bullet.
+    if( bulletCountdown > 0 ) {
+      bulletCountdown--;
+    }
+    else {
+      // Extract bits relating to joystick 2 (bullet firing).
+      UInt16 joy2Map = ( map >> PanelControls::Joy2 ) & 0x0F;
+      // Only start a bullet if at least one joystick contact is closed.
+      if( joy2Map != 0 ) {
+        // Fetch velocities associated with this combination of joystick inputs.
+        pair = bulletVelocities.GetVelocities( joy2Map );
+        // Try and start a new bullet.
+        if( playerBullets.StartBullet( Xco, Yco, pair->X, pair->Y ) ) {
+          // If bullet was started then make a bullet sound.
+          SoundManager::Instance.PlaySound( Sounds::FireGun, 0, 0 );
+        }
+        // Reset countdown until another bullet can start.
+        bulletCountdown = 8;
+      }
+    }
+  }
+#endif
+}
+
+/************************/
+/* DRAW THE GAME OBJECT */
+/************************/
+// This is only called after it has been established that the
+// game object is visible.
+void PlayerObject::Draw( void ) {
+#if 0
+  SpriteTransform transform;
+  SpriteImageId imageId;
+  // Check controls have been specified.
+  if( controls != (PanelControls*)NULL ) {
+    // Read joysticks and buttons. Buttons are not used.
+    UInt16 map = controls->GetInputs();
+    // Work out which sprite image to use and how to transform it.
+    // Player shifts from left to right foot every 4 frames.
+    bool leftFootUp = ( ( FrameCounter & 4 ) != 0 );
+    if( map & PanelControls::Left2 ) {
+      // Firing to the left.
+      transform = STNormal;
+      if( map & PanelControls::Up2 ) {
+        // Firing left and up.
+        imageId = leftFootUp ? PlayerGunUpLeftFootUpImage : PlayerGunUpRightFootUpImage;
+      }
+      else if( map & PanelControls::Down2 ) {
+        // Firing left and down.
+        imageId = leftFootUp ? PlayerGunDownLeftFootUpImage : PlayerGunDownRightFootUpImage;
+      }
+      else {
+        // Firing left and level.
+        imageId = leftFootUp ? PlayerGunLevelLeftFootUpImage : PlayerGunLevelRightFootUpImage;
+      }
+    }
+    else if( map & PanelControls::Right2 ) {
+      // Firing to the right.
+      transform = STFlipX;
+      if( map & PanelControls::Up2 ) {
+        // Firing right and up. Image is flipped so left foot becomes right foot.
+        imageId = leftFootUp ? PlayerGunUpRightFootUpImage : PlayerGunUpLeftFootUpImage;
+      }
+      else if( map & PanelControls::Down2 ) {
+        // Firing right and down. Image is flipped so left foot becomes right foot.
+        imageId = leftFootUp ? PlayerGunDownRightFootUpImage : PlayerGunDownLeftFootUpImage;
+      }
+      else {
+        // Firing right and level. Image is flipped so left foot becomes right foot.
+        imageId = leftFootUp ? PlayerGunLevelRightFootUpImage : PlayerGunLevelLeftFootUpImage;
+      }
+    }
+    else {
+      // Firing up, down or not firing.
+      transform = leftFootUp ? STNormal : STFlipX;
+      // Use a different image if firing up.
+      imageId = ( map & PanelControls::Up2 ) ? PlayerBothGunsUpImage : PlayerImage;
+    }
+  }
+  else {
+    // Controls have not been specified so use standing still image.
+    transform = STNormal;
+    imageId = PlayerImage;
+  }
+  GD.sprite( SpriteNumber, ToPixel( Xco ), ToPixel( Yco ), imageId, 0, transform, GoodGuy );
+#endif
+}
+
+/*************************/
+/* ADD TO PLAYER'S SCORE */
+/*************************/
+// Pass number of points to add in points (THIS IS BCD CODED!).
+void PlayerObject::AddToScore( UInt16 points ) {
+  // Get fourth digit from the right of the score.
+  UInt8 digit = (UInt8)( ( Score & 0xF000 ) >> 12 );
+  // Add on points.
+  if( BCDNumber::Add( Score, points, &Score ) ) {
+    // If score overflows then stick at maximum.
+    Score = 0x99999999UL;
+  }
+  // Check if the fourth digit from the right has changed.
+  // If it has then you must have passed through a thousand point
+  // boundary so award an extra life but don't let it overflow.
+#if 0
+  if( ( digit != (UInt8)( ( Score & 0xF000 ) >> 12 ) ) && ( Lives < 255 ) ) {
+    SoundManager::Instance.PlaySound( Sounds::ExtraLife, 0, 0 );
+    Lives++;
+  }
+#endif
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PlayerObject.h	Sat Jun 08 11:24:05 2013 +0000
@@ -0,0 +1,136 @@
+/*
+ * SOURCE FILE : PlayerObject.h
+ *
+ * Represents the player objects.
+ *
+ */
+
+#ifndef PlayerObjectIncluded
+  
+  #define PlayerObjectIncluded
+
+  #include "Gameduino.h"
+  #include "GameObject.h"
+  #include "BulletManager.h"
+  #include "PanelControls.h"
+  #include "BulletVelocities.h"
+  #include "SpriteImageId.h"
+  #include "BCDNumber.h"
+  
+  class PlayerObject : public GameObject {
+    
+  public :
+
+    // Lives remaining.
+    UInt8 Lives;
+    
+    // Score as a BCD number.
+    UInt32 Score;
+    
+    /***************/
+    /* CONSTRUCTOR */
+    /***************/
+    PlayerObject();
+
+    /**************/
+    /* DESTRUCTOR */
+    /**************/
+    virtual ~PlayerObject();
+
+    /**************************************/
+    /* SET CONTROLS FOR THE PLAYER TO USE */
+    /**************************************/
+    // Pass controls to use in pc.
+    void SetControls( PanelControls *pc ) {
+      controls = pc;
+    }
+
+    /*****************************************/
+    /* GET CONTROLS BEING USED BY THE PLAYER */
+    /*****************************************/
+    PanelControls *GetControls( void ) const {
+      return controls;
+    }
+    
+    /******************************/
+    /* READ THE PLAYER'S CONTROLS */
+    /******************************/
+    void ReadControls( void ) {
+      if( controls != (PanelControls*)NULL ) {
+        controls->Read();
+      }
+    }
+    
+    /************************/
+    /* GET GAME OBJECT TYPE */
+    /************************/
+    // Returns type of game object.
+    virtual GameObjectTypes GetType( void ) {
+      return PlayerObjectType;
+    }
+
+    /************************/
+    /* MOVE THE GAME OBJECT */
+    /************************/
+    virtual void ProtectedMove( void );
+
+    /************************/
+    /* DRAW THE GAME OBJECT */
+    /************************/
+    // This is only called after it has been established that the
+    // game object is visible.
+    virtual void Draw( void );
+
+    /*********************************/
+    /* KILL A SINGLE PLAYER'S BULLET */
+    /*********************************/
+    // Pass index of bullet in b.
+    void KillBullet( UInt8 b ) {
+      playerBullets.KillBullet( b );
+    }
+    
+    /*****************************/
+    /* KILL ALL PLAYER'S BULLETS */
+    /*****************************/
+    void KillAllBullets( void ) {
+      playerBullets.KillAllBullets();
+    }
+
+    /*********************************************************/
+    /* GET ARRAY CONTAINING POINTERS TO ALL PLAYER'S BULLETS */
+    /*********************************************************/
+    // Returns pointer to array of GameObject pointers.
+    // The array has BulletManager::MaxBullets pointers in it.
+    GameObject **GetBullets( void ) {
+      return playerBullets.GetBullets();
+    }
+    
+    /*************************/
+    /* ADD TO PLAYER'S SCORE */
+    /*************************/
+    // Pass number of points to add in points (THIS IS BCD CODED!).
+    void AddToScore( UInt16 points );
+    
+  private :
+
+    // Pointer to object used to read joysticks and buttons.
+    PanelControls *controls;
+    
+    // Manages player's bullets.
+    BulletManager playerBullets;
+    
+    // Countdown until next bullet available.
+    UInt8 bulletCountdown;
+    
+    // Bullet velocity information.
+    static BulletVelocities bulletVelocities;
+
+    // Player movement velocities.
+    static BulletVelocities playerVelocities;
+
+  };
+    
+#endif
+
+/* END of PlayerObject.h */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Random.h	Sat Jun 08 11:24:05 2013 +0000
@@ -0,0 +1,40 @@
+/*
+ * SOURCE FILE : Random.h
+ *
+ * Definition of class Random.
+ * Generates random numbers a bit like the random function used by Arduino and Maple and so on.
+ *
+ */
+
+#ifndef RandomDefined
+
+  #define RandomDefined
+
+  #include <stdlib.h>
+  
+  class Random {
+
+  public :
+
+    /***********************/
+    /* GET A RANDOM NUMBER */
+    /***********************/
+    // Get a random number between min and max.
+    // Result may be equal to min but is always less than max.
+    static long Get( long min, long max ) {
+        return min + ( rand() % ( max - min ) );
+    }
+    
+    /***********************/
+    /* GET A RANDOM NUMBER */
+    /***********************/
+    static long Get( long max ) {
+        return Get( 0L, max );
+    }
+        
+  };
+
+#endif
+
+/* END of Random.h */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Rectangle.cpp	Sat Jun 08 11:24:05 2013 +0000
@@ -0,0 +1,40 @@
+/*
+ * SOURCE FILE : Rectangle.cpp
+ *
+ * Definition of class Rectangle.
+ * Represents a rectangular area.
+ *
+ */
+
+#include "Rectangle.h"
+
+/***************/
+/* CONSTRUCTOR */
+/***************/
+Rectangle::Rectangle() :
+  X1( 0 ),
+  Y1( 0 ),
+  X2( 9 ),
+  Y2( 9 )
+{
+}
+
+/***************/
+/* CONSTRUCTOR */
+/***************/
+// Pass coordinates of top left in x1 and y1.
+// Pass coordinates of bottom right in x2 and y2.
+Rectangle::Rectangle( Int16 x1, Int16 y1, Int16 x2, Int16 y2 ) :
+  X1( x1 ),
+  Y1( y1 ),
+  X2( x2 ),
+  Y2( y2 )
+{
+}
+
+/**************/
+/* DESTRUCTOR */
+/**************/
+Rectangle::~Rectangle() {
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Rectangle.h	Sat Jun 08 11:24:05 2013 +0000
@@ -0,0 +1,63 @@
+/*
+ * SOURCE FILE : Rectangle.h
+ *
+ * Definition of class Rectangle.
+ * Represents a rectangular area.
+ *
+ */
+
+#ifndef RectangleDefined
+
+  #define RectangleDefined
+
+  #include "Types.h"
+  
+  class Rectangle {
+
+  public :
+
+    // Coordinates of top left.
+    Int16 X1, Y1;
+    
+    // Coordinates of bottom right.
+    Int16 X2, Y2;
+    
+    /***************/
+    /* CONSTRUCTOR */
+    /***************/
+    Rectangle();
+
+    /***************/
+    /* CONSTRUCTOR */
+    /***************/
+    // Pass coordinates of top left in x1 and y1.
+    // Pass coordinates of bottom right in x2 and y2.
+    Rectangle( Int16 x1, Int16 y1, Int16 x2, Int16 y2 );
+
+    /**************/
+    /* DESTRUCTOR */
+    /**************/
+    virtual ~Rectangle();
+
+    /*******************/
+    /* CALCULATE WIDTH */
+    /*******************/
+    // Returns width of rectangle.
+    Int16 GetWidth( void ) const {
+      return X2 - X1 + 1;
+    }
+    
+    /********************/
+    /* CALCULATE HEIGHT */
+    /********************/
+    // Returns height of rectangle.
+    Int16 GetHeight( void ) const {
+      return Y2 - Y1 + 1;
+    }
+    
+  };
+
+#endif
+
+/* END of Rectangle.h */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SpriteGroup.h	Sat Jun 08 11:24:05 2013 +0000
@@ -0,0 +1,21 @@
+/*
+ * SOURCE FILE : SpriteGroup.h
+ *
+ * Enumeration of the two groups of sprites.
+ * Mainly of use for sprite collision detection.
+ *
+ */
+
+#ifndef SpriteGroupIncluded
+  
+  #define SpriteGroupIncluded
+
+  enum SpriteGroup {
+    GoodGuy = 0,        // J collision class
+    BadGuy = 1,         // K collision class
+  };
+  
+#endif
+
+/* END of SpriteGroup.h */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SpriteImageId.h	Sat Jun 08 11:24:05 2013 +0000
@@ -0,0 +1,57 @@
+/*
+ * SOURCE FILE : SpriteImageId.h
+ *
+ * Image ID numbers for sprites. Ordering is important.
+ * These are ordered the same way as the sprite images in the sprite RAM of the Gameduino.
+ *
+ */
+
+#ifndef SpriteImageIdIncluded
+  
+  #define SpriteImageIdIncluded
+
+  enum SpriteImageId {
+    PlayerImage = 0,
+    PlayerBulletImage = 1,
+    GruntImage = 2,
+    Explosion0Image = 3,
+    Explosion1Image = 4,
+    Explosion2Image = 5,
+    Explosion3Image = 6,
+    Explosion4Image = 7,
+    Explosion5Image = 8,
+    Explosion6Image = 9,
+    Explosion7Image = 10,
+    Explosion8Image = 11,
+    Explosion9Image = 12,
+    BlueMeanyImage = 13,
+    SkullImage = 14,
+    Woman0Image = 15,
+    Woman1Image = 16,
+    Woman2Image = 17,
+    FiftyImage = 18,
+    PlayerGunUpLeftFootUpImage = 19,
+    PlayerGunUpRightFootUpImage = 20,
+    PlayerGunLevelLeftFootUpImage = 21,
+    PlayerGunLevelRightFootUpImage = 22,
+    PlayerGunDownLeftFootUpImage = 23,
+    PlayerGunDownRightFootUpImage = 24,
+    PlayerBothGunsUpImage = 25,
+    Man0Image = 26,
+    Man1Image = 27,
+    Man2Image = 28,
+    Star0Image = 29,
+    Star1Image = 30,
+        Crusher0Image = 31,
+        Crusher1Image = 32,
+        Crusher2Image = 33,
+        BrainImage = 34,
+        MutantWomanImage = 35,
+        MutantManImage = 36,
+        BrainBulletImage = 37,
+  };
+  
+#endif
+
+/* END of SpriteImageId.h */
+