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

Revision:
3:a6a0cd726ca0
Parent:
2:bb0f631a6068
--- a/HighScoreTable.cpp	Thu Jun 06 20:11:28 2013 +0000
+++ b/HighScoreTable.cpp	Fri Jun 07 20:29:59 2013 +0000
@@ -47,13 +47,21 @@
  *
  */
 
+// Define this for debugging messages to be sent to serial port.
+#undef CHATTY
+
+#ifdef CHATTY
+    #include "mbed.h"
+    extern Serial pc;
+#endif
+
 #include "HighScoreTable.h"
 
 /***************/
 /* CONSTRUCTOR */
 /***************/
 // Pass pointer to an SPI EEPROM which contains the high scores.
-HighScoreTable::HighScoreTable( SPIEEPROM *e ) :
+HighScoreTable::HighScoreTable( Ser25LCxxx *e ) :
     eeprom( e )
 {
 }
@@ -115,15 +123,15 @@
     // a single byte a whole page is written so might as well
     // write a whole page in one go. Only drawback is more RAM
     // is required.
-    UInt8 buffer[ memoryUsed ];
-    if( eeprom->ReadBytes( eepromAddress, buffer, memoryUsed ) ) {
+    char *buffer = eeprom->read( eepromAddress, memoryUsed );
+    if( buffer != NULL ) {
         // Fetch index for lowest score in the table.
         UInt8 index = buffer[ capacity - 1 ];
         // Make sure index is within range.
         if( index < capacity ) {
             // Point to section of buffer that contains name and score for
             // lowest score.
-            UInt8 *address = buffer + capacity + ( index << 3 );
+            UInt8 *address = (UInt8*)( buffer + capacity + ( index << 3 ) );
             // Copy characters of name into buffer.
             for( UInt8 i = 0; i < PlayerName::Length; ++i ) {
                 *address++ = name->Name[ i ];
@@ -139,7 +147,9 @@
             // Insert index of newly written record at insertion point.
             buffer[ pos ] = index;
             // Write the buffer back to EEPROM.
-            eeprom->WriteBytes( eepromAddress, buffer, memoryUsed ); 
+            eeprom->write( eepromAddress, memoryUsed, buffer );
+            // Free memory used by buffer.
+            free( buffer );
         }
     }
 }
@@ -151,27 +161,37 @@
 // Player name is returned in object pointed to by name.
 // Player score is returned in integer pointed to by score.
 void HighScoreTable::Get( UInt8 pos, PlayerName *name, UInt32 *score ) const {
-    // Write default values to name and score.
+  // Write default values to name and score.
   for( UInt8 i = 0; i < PlayerName::Length; ++i ) {
     name->Name[ i ] = (UInt8)'X';
   }
   name->Name[ PlayerName::Length ] = 0;
-    *score = 0;
+  *score = 0;
   // Fetch index from EEPROM.
-  UInt8 index;
-    if( ! eeprom->ReadBytes( eepromAddress + pos, &index, 1 ) ) {
+  UInt8 *index = (UInt8*)eeprom->read( eepromAddress + pos, 1 );
+  if( index == NULL ) {
         return;
-    }
+  }
   // Point to appropriate part of data table.
-  UInt16 address = eepromAddress + capacity + ( index << 3 );
+  UInt16 address = eepromAddress + capacity + ( *index << 3 );
+  // Free buffer containing index.
+  free( index );
   // Read out characters and store in name.
-    if( ! eeprom->ReadBytes( address, (UInt8*)name->Name, PlayerName::Length ) ) {
-        return;
-    }
+  char *rawName = eeprom->read( address, PlayerName::Length );
+  if( rawName == NULL ) {
+    return;
+  }
+  memcpy( name->Name, rawName, PlayerName::Length );
   name->Name[ PlayerName::Length ] = 0;
-    address += PlayerName::Length;
+  address += PlayerName::Length;
+  free( rawName );
   // Read out score.
-    eeprom->ReadBytes( address, (UInt8*)score, 4 );
+  char *rawScore = eeprom->read( address, 4 );
+  if( rawScore == NULL ) {
+    return;
+  }
+  *score = *((UInt32*)rawScore);
+  free( rawScore );
 }
 
 /********************************/
@@ -179,53 +199,84 @@
 /********************************/
 // Returns true if EEPROM is valid.
 bool HighScoreTable::EEPROMValid( void ) {
+  #ifdef CHATTY
+    pc.printf( "Checking validity.\r\n" );
+  #endif
   UInt8 b, b2;
+  // Read index from EEPROM.
+  char *index = eeprom->read( eepromAddress, capacity );
+  if( index == NULL ) {
+    return false;
+  }
   // Check all entries in the index are within range and are unique.
   for( UInt8 i = 0; i < capacity; ++i ) {
-    // Read byte from EEPROM.
-        if( ! eeprom->ReadBytes( eepromAddress + i, &b, 1 ) ) {
-            return false;
-        }
-    // Check index read is less than capacity.
+    b = index[ i ];
+    #ifdef CHATTY
+      pc.printf( "index[ %u ] = %u\r\n", (unsigned)i, (unsigned)b );
+    #endif
     if( b >= capacity ) {
+      free( index );
       return false;
     }
     // Check if any of the following bytes in the index have
     // the same value.
     for( UInt8 j = i + 1; j < capacity; ++j ) {
-            if( ! eeprom->ReadBytes( eepromAddress + j, &b2, 1 ) ) {
-                return false;
-            }
+      b2 = index [ j ];
       if( b == b2 ) {
+        #ifdef CHATTY
+            pc.printf( "index[ %u ] has the same value!\r\n", (unsigned)j );
+        #endif
+        free( index );
         return false;
       }
     }
   }
+  // Free memory used by index.
+  free( index );
   // Check all entries in the data part of the table are valid.
   UInt16 address = eepromAddress + capacity;
   for( UInt8 i = 0; i < capacity; ++i ) {
+    // Read name and score.
+    char *entry = eeprom->read( address, 8 );
+    if( entry == NULL ) {
+      return false;
+    }
+    #ifdef CHATTY
+        pc.printf( "Checking entry %u.\r\n", i );
+        pc.puts( "Name:" );
+    #endif
     // Check name consists only of uppercase letters.
     for( UInt8 j = 0; j < PlayerName::Length; ++j ) {
-            // Read byte from EEPROM.
-            if( ! eeprom->ReadBytes( address++, &b, 1 ) ) {
-                return false;
-            }
+      b = (UInt8)entry[ j ];
+      #ifdef CHATTY
+        pc.putc( b );
+      #endif
       if( ( b < PlayerName::MinChar ) || ( b > PlayerName::MaxChar ) ) {
+        free( entry );
         return false;
       }
     }
+    #ifdef CHATTY
+        pc.puts( "\r\nScore:" );
+    #endif
     // Check score consists only of valid BCD numbers.
-    for( UInt8 j = 0; j < 4; ++j ) {
-            // Read byte from EEPROM.
-            if( ! eeprom->ReadBytes( address++, &b, 1 ) ) {
-                return false;
-            }
+    for( UInt8 j = PlayerName::Length; j < PlayerName::Length + 4; ++j ) {
+      b = (UInt8)entry[ j ];
+      #ifdef CHATTY
+        pc.printf( "%02X ", (int)b );
+      #endif
       if( ( ( b & 0x0F ) > 0x09 ) || ( ( b & 0xF0 ) > 0x90 ) ) {
+        free( entry );
         return false;
       }
     }
-    // Skip over unused byte.
-    address++;
+    #ifdef CHATTY
+        pc.puts( "\r\n" );
+    #endif
+    // Finished with name and score.
+    free( entry );
+    // Skip to next entry.
+    address += 8;
   }
   // EEPROM is valid
   return true;
@@ -236,9 +287,9 @@
 /****************************/
 // This may take a second or two to execute!
 void HighScoreTable::WriteEEPROMDefaults( void ) {
-    UInt8 buffer[ memoryUsed ];
+  UInt8 buffer[ memoryUsed ];
   // Write index with ascending integers.
-    UInt8 *ptr = buffer;
+  UInt8 *ptr = buffer;
   for( UInt8 i = 0; i < capacity; ++i ) {
     *ptr++ =  i;
   }
@@ -246,14 +297,14 @@
   for( UInt8 i = 0; i < capacity; ++i ) {
     // Write a name of "AAA".
     for( UInt8 j = 0; j < PlayerName::Length; ++j ) {
-            *ptr++ = (UInt8)'A';
+      *ptr++ = (UInt8)'A';
     }
-        // Write a score of zero.
+    // Write a score of zero.
     *((UInt32*)ptr) = 0;
-        ptr += 4;
-        // Write zero to unused byte.
-        *ptr++ = 0;    
-    }
-    // Write the buffer to EEPROM.
-    eeprom->WriteBytes( eepromAddress, buffer, memoryUsed ); 
+    ptr += 4;
+    // Write zero to unused byte.
+    *ptr++ = 0;    
+  }
+  // Write the buffer to EEPROM.
+  eeprom->write( eepromAddress, memoryUsed, (char*)buffer ); 
 }