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
HighScoreTable.cpp@3:a6a0cd726ca0, 2013-06-07 (annotated)
- Committer:
- RichardE
- Date:
- Fri Jun 07 20:29:59 2013 +0000
- Revision:
- 3:a6a0cd726ca0
- Parent:
- 2:bb0f631a6068
Abandoned writing serial EEPROM class and used Ser25LCxxx library instead. HighScoreTable class appears to be reading and writing correctly to EEPROM and high scores are displayed correctly.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
RichardE | 2:bb0f631a6068 | 1 | /* |
RichardE | 2:bb0f631a6068 | 2 | * SOURCE FILE : HighScoreTable.cpp |
RichardE | 2:bb0f631a6068 | 3 | * |
RichardE | 2:bb0f631a6068 | 4 | * Definition of class HighScoreTable. |
RichardE | 2:bb0f631a6068 | 5 | * Maintains a table of high scores with a name and a score for each entry in the table. |
RichardE | 2:bb0f631a6068 | 6 | * |
RichardE | 2:bb0f631a6068 | 7 | * The table is stored in EEPROM at an address specified when you call the constructor. |
RichardE | 2:bb0f631a6068 | 8 | * The table is structured as follows. This shows a table with a capacity of 3. |
RichardE | 2:bb0f631a6068 | 9 | * |
RichardE | 2:bb0f631a6068 | 10 | * Byte offset Usage |
RichardE | 2:bb0f631a6068 | 11 | * ----------- ----- |
RichardE | 2:bb0f631a6068 | 12 | * 0 Index of highest score in data that follows |
RichardE | 2:bb0f631a6068 | 13 | * 1 Index of second highest score in data that follows |
RichardE | 2:bb0f631a6068 | 14 | * 2 Index of third highest score in data that follows |
RichardE | 2:bb0f631a6068 | 15 | * |
RichardE | 2:bb0f631a6068 | 16 | * 3 First character of player's name |
RichardE | 2:bb0f631a6068 | 17 | * 4 Second character of player's name |
RichardE | 2:bb0f631a6068 | 18 | * 5 Third character of player's name |
RichardE | 2:bb0f631a6068 | 19 | * 6 LSB of score (in BCD) |
RichardE | 2:bb0f631a6068 | 20 | * 7 Byte 1 of score (in BCD) |
RichardE | 2:bb0f631a6068 | 21 | * 8 Byte 2 of score (in BCD) |
RichardE | 2:bb0f631a6068 | 22 | * 9 MSB of score (in BCD) |
RichardE | 2:bb0f631a6068 | 23 | * 10 Unused |
RichardE | 2:bb0f631a6068 | 24 | * |
RichardE | 2:bb0f631a6068 | 25 | * 11 First character of player's name |
RichardE | 2:bb0f631a6068 | 26 | * 12 Second character of player's name |
RichardE | 2:bb0f631a6068 | 27 | * 13 Third character of player's name |
RichardE | 2:bb0f631a6068 | 28 | * 14 LSB of score (in BCD) |
RichardE | 2:bb0f631a6068 | 29 | * 15 Byte 1 of score (in BCD) |
RichardE | 2:bb0f631a6068 | 30 | * 16 Byte 2 of score (in BCD) |
RichardE | 2:bb0f631a6068 | 31 | * 17 MSB of score (in BCD) |
RichardE | 2:bb0f631a6068 | 32 | * 18 Unused |
RichardE | 2:bb0f631a6068 | 33 | * |
RichardE | 2:bb0f631a6068 | 34 | * 19 First character of player's name |
RichardE | 2:bb0f631a6068 | 35 | * 20 Second character of player's name |
RichardE | 2:bb0f631a6068 | 36 | * 21 Third character of player's name |
RichardE | 2:bb0f631a6068 | 37 | * 22 LSB of score (in BCD) |
RichardE | 2:bb0f631a6068 | 38 | * 23 Byte 1 of score (in BCD) |
RichardE | 2:bb0f631a6068 | 39 | * 24 Byte 2 of score (in BCD) |
RichardE | 2:bb0f631a6068 | 40 | * 25 MSB of score (in BCD) |
RichardE | 2:bb0f631a6068 | 41 | * 26 Unused |
RichardE | 2:bb0f631a6068 | 42 | * |
RichardE | 2:bb0f631a6068 | 43 | * So, assuming the capacity of the table is N, the first N bytes form an index which is used to locate |
RichardE | 2:bb0f631a6068 | 44 | * items in the remaining N*8 bytes that follow. This is done so that inserting a new entry only involves |
RichardE | 2:bb0f631a6068 | 45 | * overwriting one name/score record and updating the index. You don't have to re-write all the records |
RichardE | 2:bb0f631a6068 | 46 | * that move down the table to make room for the new one. |
RichardE | 2:bb0f631a6068 | 47 | * |
RichardE | 2:bb0f631a6068 | 48 | */ |
RichardE | 2:bb0f631a6068 | 49 | |
RichardE | 3:a6a0cd726ca0 | 50 | // Define this for debugging messages to be sent to serial port. |
RichardE | 3:a6a0cd726ca0 | 51 | #undef CHATTY |
RichardE | 3:a6a0cd726ca0 | 52 | |
RichardE | 3:a6a0cd726ca0 | 53 | #ifdef CHATTY |
RichardE | 3:a6a0cd726ca0 | 54 | #include "mbed.h" |
RichardE | 3:a6a0cd726ca0 | 55 | extern Serial pc; |
RichardE | 3:a6a0cd726ca0 | 56 | #endif |
RichardE | 3:a6a0cd726ca0 | 57 | |
RichardE | 2:bb0f631a6068 | 58 | #include "HighScoreTable.h" |
RichardE | 2:bb0f631a6068 | 59 | |
RichardE | 2:bb0f631a6068 | 60 | /***************/ |
RichardE | 2:bb0f631a6068 | 61 | /* CONSTRUCTOR */ |
RichardE | 2:bb0f631a6068 | 62 | /***************/ |
RichardE | 2:bb0f631a6068 | 63 | // Pass pointer to an SPI EEPROM which contains the high scores. |
RichardE | 3:a6a0cd726ca0 | 64 | HighScoreTable::HighScoreTable( Ser25LCxxx *e ) : |
RichardE | 2:bb0f631a6068 | 65 | eeprom( e ) |
RichardE | 2:bb0f631a6068 | 66 | { |
RichardE | 2:bb0f631a6068 | 67 | } |
RichardE | 2:bb0f631a6068 | 68 | |
RichardE | 2:bb0f631a6068 | 69 | /**************/ |
RichardE | 2:bb0f631a6068 | 70 | /* DESTRUCTOR */ |
RichardE | 2:bb0f631a6068 | 71 | /**************/ |
RichardE | 2:bb0f631a6068 | 72 | HighScoreTable::~HighScoreTable() { |
RichardE | 2:bb0f631a6068 | 73 | } |
RichardE | 2:bb0f631a6068 | 74 | |
RichardE | 2:bb0f631a6068 | 75 | /****************************************/ |
RichardE | 2:bb0f631a6068 | 76 | /* VALIDATE EEPROM USED FOR HIGH SCORES */ |
RichardE | 2:bb0f631a6068 | 77 | /****************************************/ |
RichardE | 2:bb0f631a6068 | 78 | // Checks EEPROM used for high scores and |
RichardE | 2:bb0f631a6068 | 79 | // if any of it looks like nonsense it |
RichardE | 2:bb0f631a6068 | 80 | // rewrites the whole table with defaults. |
RichardE | 2:bb0f631a6068 | 81 | void HighScoreTable::ValidateEEPROM( void ) { |
RichardE | 2:bb0f631a6068 | 82 | // Check if contents of EEPROM make sense. |
RichardE | 2:bb0f631a6068 | 83 | // If not then rewrite EEPROM with defaults. |
RichardE | 2:bb0f631a6068 | 84 | if( ! EEPROMValid() ) { |
RichardE | 2:bb0f631a6068 | 85 | WriteEEPROMDefaults(); |
RichardE | 2:bb0f631a6068 | 86 | } |
RichardE | 2:bb0f631a6068 | 87 | } |
RichardE | 2:bb0f631a6068 | 88 | |
RichardE | 2:bb0f631a6068 | 89 | /**********************************************/ |
RichardE | 2:bb0f631a6068 | 90 | /* DETERMINE POSITION OF A SCORE IN THE TABLE */ |
RichardE | 2:bb0f631a6068 | 91 | /**********************************************/ |
RichardE | 2:bb0f631a6068 | 92 | // Pass score in score. |
RichardE | 2:bb0f631a6068 | 93 | // Returns position in table (0 is top score). |
RichardE | 2:bb0f631a6068 | 94 | // If position returned is >= capacity of table then score is not high |
RichardE | 2:bb0f631a6068 | 95 | // enough to place in table. |
RichardE | 2:bb0f631a6068 | 96 | UInt8 HighScoreTable::GetPositionInTable( UInt32 score ) const { |
RichardE | 2:bb0f631a6068 | 97 | // Look through table for a score less than the one passed. |
RichardE | 2:bb0f631a6068 | 98 | PlayerName name; |
RichardE | 2:bb0f631a6068 | 99 | UInt32 tableScore = (UInt32)0; |
RichardE | 2:bb0f631a6068 | 100 | for( UInt8 i = 0; i < capacity; ++i ) { |
RichardE | 2:bb0f631a6068 | 101 | Get( i, &name, &tableScore ); |
RichardE | 2:bb0f631a6068 | 102 | if( tableScore < score ) { |
RichardE | 2:bb0f631a6068 | 103 | // Found a score that is less. |
RichardE | 2:bb0f631a6068 | 104 | // Return index at which it was found. |
RichardE | 2:bb0f631a6068 | 105 | return i; |
RichardE | 2:bb0f631a6068 | 106 | } |
RichardE | 2:bb0f631a6068 | 107 | } |
RichardE | 2:bb0f631a6068 | 108 | // No score found that is less than the one passed. |
RichardE | 2:bb0f631a6068 | 109 | // Return capacity of table to indicate not found. |
RichardE | 2:bb0f631a6068 | 110 | return capacity; |
RichardE | 0:5fa232ee5fdf | 111 | } |
RichardE | 2:bb0f631a6068 | 112 | |
RichardE | 2:bb0f631a6068 | 113 | /*********************************/ |
RichardE | 2:bb0f631a6068 | 114 | /* ADD ENTRY TO HIGH SCORE TABLE */ |
RichardE | 2:bb0f631a6068 | 115 | /*********************************/ |
RichardE | 2:bb0f631a6068 | 116 | // Pass position in table to put entry in pos. |
RichardE | 2:bb0f631a6068 | 117 | // Pass name of player in name. |
RichardE | 2:bb0f631a6068 | 118 | // Pass score in score. |
RichardE | 2:bb0f631a6068 | 119 | void HighScoreTable::Add( UInt8 pos, const PlayerName *name, UInt32 score ) { |
RichardE | 2:bb0f631a6068 | 120 | // Read the entire index, high scores and names out of EEPROM. |
RichardE | 2:bb0f631a6068 | 121 | // Going to do manipulations in RAM to minimise the number of |
RichardE | 2:bb0f631a6068 | 122 | // writes we need to do to EEPROM. Remember every time we write |
RichardE | 2:bb0f631a6068 | 123 | // a single byte a whole page is written so might as well |
RichardE | 2:bb0f631a6068 | 124 | // write a whole page in one go. Only drawback is more RAM |
RichardE | 2:bb0f631a6068 | 125 | // is required. |
RichardE | 3:a6a0cd726ca0 | 126 | char *buffer = eeprom->read( eepromAddress, memoryUsed ); |
RichardE | 3:a6a0cd726ca0 | 127 | if( buffer != NULL ) { |
RichardE | 2:bb0f631a6068 | 128 | // Fetch index for lowest score in the table. |
RichardE | 2:bb0f631a6068 | 129 | UInt8 index = buffer[ capacity - 1 ]; |
RichardE | 2:bb0f631a6068 | 130 | // Make sure index is within range. |
RichardE | 2:bb0f631a6068 | 131 | if( index < capacity ) { |
RichardE | 2:bb0f631a6068 | 132 | // Point to section of buffer that contains name and score for |
RichardE | 2:bb0f631a6068 | 133 | // lowest score. |
RichardE | 3:a6a0cd726ca0 | 134 | UInt8 *address = (UInt8*)( buffer + capacity + ( index << 3 ) ); |
RichardE | 2:bb0f631a6068 | 135 | // Copy characters of name into buffer. |
RichardE | 2:bb0f631a6068 | 136 | for( UInt8 i = 0; i < PlayerName::Length; ++i ) { |
RichardE | 2:bb0f631a6068 | 137 | *address++ = name->Name[ i ]; |
RichardE | 2:bb0f631a6068 | 138 | } |
RichardE | 2:bb0f631a6068 | 139 | // Copy bytes of score into buffer. |
RichardE | 2:bb0f631a6068 | 140 | *((UInt32*)address) = score; |
RichardE | 2:bb0f631a6068 | 141 | address += 4; |
RichardE | 2:bb0f631a6068 | 142 | // Move all entries in the index below insertion point down one |
RichardE | 2:bb0f631a6068 | 143 | // to make room for new entry. |
RichardE | 2:bb0f631a6068 | 144 | for( UInt8 i = capacity - 1; i > pos; --i ) { |
RichardE | 2:bb0f631a6068 | 145 | buffer[ i ] = buffer[ i - 1 ]; |
RichardE | 2:bb0f631a6068 | 146 | } |
RichardE | 2:bb0f631a6068 | 147 | // Insert index of newly written record at insertion point. |
RichardE | 2:bb0f631a6068 | 148 | buffer[ pos ] = index; |
RichardE | 2:bb0f631a6068 | 149 | // Write the buffer back to EEPROM. |
RichardE | 3:a6a0cd726ca0 | 150 | eeprom->write( eepromAddress, memoryUsed, buffer ); |
RichardE | 3:a6a0cd726ca0 | 151 | // Free memory used by buffer. |
RichardE | 3:a6a0cd726ca0 | 152 | free( buffer ); |
RichardE | 2:bb0f631a6068 | 153 | } |
RichardE | 2:bb0f631a6068 | 154 | } |
RichardE | 2:bb0f631a6068 | 155 | } |
RichardE | 2:bb0f631a6068 | 156 | |
RichardE | 2:bb0f631a6068 | 157 | /****************************/ |
RichardE | 2:bb0f631a6068 | 158 | /* GET ENTRY FROM THE TABLE */ |
RichardE | 2:bb0f631a6068 | 159 | /****************************/ |
RichardE | 2:bb0f631a6068 | 160 | // Pass position to fetch from in pos. |
RichardE | 2:bb0f631a6068 | 161 | // Player name is returned in object pointed to by name. |
RichardE | 2:bb0f631a6068 | 162 | // Player score is returned in integer pointed to by score. |
RichardE | 2:bb0f631a6068 | 163 | void HighScoreTable::Get( UInt8 pos, PlayerName *name, UInt32 *score ) const { |
RichardE | 3:a6a0cd726ca0 | 164 | // Write default values to name and score. |
RichardE | 2:bb0f631a6068 | 165 | for( UInt8 i = 0; i < PlayerName::Length; ++i ) { |
RichardE | 2:bb0f631a6068 | 166 | name->Name[ i ] = (UInt8)'X'; |
RichardE | 2:bb0f631a6068 | 167 | } |
RichardE | 2:bb0f631a6068 | 168 | name->Name[ PlayerName::Length ] = 0; |
RichardE | 3:a6a0cd726ca0 | 169 | *score = 0; |
RichardE | 2:bb0f631a6068 | 170 | // Fetch index from EEPROM. |
RichardE | 3:a6a0cd726ca0 | 171 | UInt8 *index = (UInt8*)eeprom->read( eepromAddress + pos, 1 ); |
RichardE | 3:a6a0cd726ca0 | 172 | if( index == NULL ) { |
RichardE | 2:bb0f631a6068 | 173 | return; |
RichardE | 3:a6a0cd726ca0 | 174 | } |
RichardE | 2:bb0f631a6068 | 175 | // Point to appropriate part of data table. |
RichardE | 3:a6a0cd726ca0 | 176 | UInt16 address = eepromAddress + capacity + ( *index << 3 ); |
RichardE | 3:a6a0cd726ca0 | 177 | // Free buffer containing index. |
RichardE | 3:a6a0cd726ca0 | 178 | free( index ); |
RichardE | 2:bb0f631a6068 | 179 | // Read out characters and store in name. |
RichardE | 3:a6a0cd726ca0 | 180 | char *rawName = eeprom->read( address, PlayerName::Length ); |
RichardE | 3:a6a0cd726ca0 | 181 | if( rawName == NULL ) { |
RichardE | 3:a6a0cd726ca0 | 182 | return; |
RichardE | 3:a6a0cd726ca0 | 183 | } |
RichardE | 3:a6a0cd726ca0 | 184 | memcpy( name->Name, rawName, PlayerName::Length ); |
RichardE | 2:bb0f631a6068 | 185 | name->Name[ PlayerName::Length ] = 0; |
RichardE | 3:a6a0cd726ca0 | 186 | address += PlayerName::Length; |
RichardE | 3:a6a0cd726ca0 | 187 | free( rawName ); |
RichardE | 2:bb0f631a6068 | 188 | // Read out score. |
RichardE | 3:a6a0cd726ca0 | 189 | char *rawScore = eeprom->read( address, 4 ); |
RichardE | 3:a6a0cd726ca0 | 190 | if( rawScore == NULL ) { |
RichardE | 3:a6a0cd726ca0 | 191 | return; |
RichardE | 3:a6a0cd726ca0 | 192 | } |
RichardE | 3:a6a0cd726ca0 | 193 | *score = *((UInt32*)rawScore); |
RichardE | 3:a6a0cd726ca0 | 194 | free( rawScore ); |
RichardE | 2:bb0f631a6068 | 195 | } |
RichardE | 2:bb0f631a6068 | 196 | |
RichardE | 2:bb0f631a6068 | 197 | /********************************/ |
RichardE | 2:bb0f631a6068 | 198 | /* DETERMINE IF EEPROM IS VALID */ |
RichardE | 2:bb0f631a6068 | 199 | /********************************/ |
RichardE | 2:bb0f631a6068 | 200 | // Returns true if EEPROM is valid. |
RichardE | 2:bb0f631a6068 | 201 | bool HighScoreTable::EEPROMValid( void ) { |
RichardE | 3:a6a0cd726ca0 | 202 | #ifdef CHATTY |
RichardE | 3:a6a0cd726ca0 | 203 | pc.printf( "Checking validity.\r\n" ); |
RichardE | 3:a6a0cd726ca0 | 204 | #endif |
RichardE | 2:bb0f631a6068 | 205 | UInt8 b, b2; |
RichardE | 3:a6a0cd726ca0 | 206 | // Read index from EEPROM. |
RichardE | 3:a6a0cd726ca0 | 207 | char *index = eeprom->read( eepromAddress, capacity ); |
RichardE | 3:a6a0cd726ca0 | 208 | if( index == NULL ) { |
RichardE | 3:a6a0cd726ca0 | 209 | return false; |
RichardE | 3:a6a0cd726ca0 | 210 | } |
RichardE | 2:bb0f631a6068 | 211 | // Check all entries in the index are within range and are unique. |
RichardE | 2:bb0f631a6068 | 212 | for( UInt8 i = 0; i < capacity; ++i ) { |
RichardE | 3:a6a0cd726ca0 | 213 | b = index[ i ]; |
RichardE | 3:a6a0cd726ca0 | 214 | #ifdef CHATTY |
RichardE | 3:a6a0cd726ca0 | 215 | pc.printf( "index[ %u ] = %u\r\n", (unsigned)i, (unsigned)b ); |
RichardE | 3:a6a0cd726ca0 | 216 | #endif |
RichardE | 2:bb0f631a6068 | 217 | if( b >= capacity ) { |
RichardE | 3:a6a0cd726ca0 | 218 | free( index ); |
RichardE | 2:bb0f631a6068 | 219 | return false; |
RichardE | 2:bb0f631a6068 | 220 | } |
RichardE | 2:bb0f631a6068 | 221 | // Check if any of the following bytes in the index have |
RichardE | 2:bb0f631a6068 | 222 | // the same value. |
RichardE | 2:bb0f631a6068 | 223 | for( UInt8 j = i + 1; j < capacity; ++j ) { |
RichardE | 3:a6a0cd726ca0 | 224 | b2 = index [ j ]; |
RichardE | 2:bb0f631a6068 | 225 | if( b == b2 ) { |
RichardE | 3:a6a0cd726ca0 | 226 | #ifdef CHATTY |
RichardE | 3:a6a0cd726ca0 | 227 | pc.printf( "index[ %u ] has the same value!\r\n", (unsigned)j ); |
RichardE | 3:a6a0cd726ca0 | 228 | #endif |
RichardE | 3:a6a0cd726ca0 | 229 | free( index ); |
RichardE | 2:bb0f631a6068 | 230 | return false; |
RichardE | 2:bb0f631a6068 | 231 | } |
RichardE | 2:bb0f631a6068 | 232 | } |
RichardE | 2:bb0f631a6068 | 233 | } |
RichardE | 3:a6a0cd726ca0 | 234 | // Free memory used by index. |
RichardE | 3:a6a0cd726ca0 | 235 | free( index ); |
RichardE | 2:bb0f631a6068 | 236 | // Check all entries in the data part of the table are valid. |
RichardE | 2:bb0f631a6068 | 237 | UInt16 address = eepromAddress + capacity; |
RichardE | 2:bb0f631a6068 | 238 | for( UInt8 i = 0; i < capacity; ++i ) { |
RichardE | 3:a6a0cd726ca0 | 239 | // Read name and score. |
RichardE | 3:a6a0cd726ca0 | 240 | char *entry = eeprom->read( address, 8 ); |
RichardE | 3:a6a0cd726ca0 | 241 | if( entry == NULL ) { |
RichardE | 3:a6a0cd726ca0 | 242 | return false; |
RichardE | 3:a6a0cd726ca0 | 243 | } |
RichardE | 3:a6a0cd726ca0 | 244 | #ifdef CHATTY |
RichardE | 3:a6a0cd726ca0 | 245 | pc.printf( "Checking entry %u.\r\n", i ); |
RichardE | 3:a6a0cd726ca0 | 246 | pc.puts( "Name:" ); |
RichardE | 3:a6a0cd726ca0 | 247 | #endif |
RichardE | 2:bb0f631a6068 | 248 | // Check name consists only of uppercase letters. |
RichardE | 2:bb0f631a6068 | 249 | for( UInt8 j = 0; j < PlayerName::Length; ++j ) { |
RichardE | 3:a6a0cd726ca0 | 250 | b = (UInt8)entry[ j ]; |
RichardE | 3:a6a0cd726ca0 | 251 | #ifdef CHATTY |
RichardE | 3:a6a0cd726ca0 | 252 | pc.putc( b ); |
RichardE | 3:a6a0cd726ca0 | 253 | #endif |
RichardE | 2:bb0f631a6068 | 254 | if( ( b < PlayerName::MinChar ) || ( b > PlayerName::MaxChar ) ) { |
RichardE | 3:a6a0cd726ca0 | 255 | free( entry ); |
RichardE | 2:bb0f631a6068 | 256 | return false; |
RichardE | 2:bb0f631a6068 | 257 | } |
RichardE | 2:bb0f631a6068 | 258 | } |
RichardE | 3:a6a0cd726ca0 | 259 | #ifdef CHATTY |
RichardE | 3:a6a0cd726ca0 | 260 | pc.puts( "\r\nScore:" ); |
RichardE | 3:a6a0cd726ca0 | 261 | #endif |
RichardE | 2:bb0f631a6068 | 262 | // Check score consists only of valid BCD numbers. |
RichardE | 3:a6a0cd726ca0 | 263 | for( UInt8 j = PlayerName::Length; j < PlayerName::Length + 4; ++j ) { |
RichardE | 3:a6a0cd726ca0 | 264 | b = (UInt8)entry[ j ]; |
RichardE | 3:a6a0cd726ca0 | 265 | #ifdef CHATTY |
RichardE | 3:a6a0cd726ca0 | 266 | pc.printf( "%02X ", (int)b ); |
RichardE | 3:a6a0cd726ca0 | 267 | #endif |
RichardE | 2:bb0f631a6068 | 268 | if( ( ( b & 0x0F ) > 0x09 ) || ( ( b & 0xF0 ) > 0x90 ) ) { |
RichardE | 3:a6a0cd726ca0 | 269 | free( entry ); |
RichardE | 2:bb0f631a6068 | 270 | return false; |
RichardE | 2:bb0f631a6068 | 271 | } |
RichardE | 2:bb0f631a6068 | 272 | } |
RichardE | 3:a6a0cd726ca0 | 273 | #ifdef CHATTY |
RichardE | 3:a6a0cd726ca0 | 274 | pc.puts( "\r\n" ); |
RichardE | 3:a6a0cd726ca0 | 275 | #endif |
RichardE | 3:a6a0cd726ca0 | 276 | // Finished with name and score. |
RichardE | 3:a6a0cd726ca0 | 277 | free( entry ); |
RichardE | 3:a6a0cd726ca0 | 278 | // Skip to next entry. |
RichardE | 3:a6a0cd726ca0 | 279 | address += 8; |
RichardE | 2:bb0f631a6068 | 280 | } |
RichardE | 2:bb0f631a6068 | 281 | // EEPROM is valid |
RichardE | 2:bb0f631a6068 | 282 | return true; |
RichardE | 2:bb0f631a6068 | 283 | } |
RichardE | 2:bb0f631a6068 | 284 | |
RichardE | 2:bb0f631a6068 | 285 | /****************************/ |
RichardE | 2:bb0f631a6068 | 286 | /* WRITE DEFAULTS TO EEPROM */ |
RichardE | 2:bb0f631a6068 | 287 | /****************************/ |
RichardE | 2:bb0f631a6068 | 288 | // This may take a second or two to execute! |
RichardE | 2:bb0f631a6068 | 289 | void HighScoreTable::WriteEEPROMDefaults( void ) { |
RichardE | 3:a6a0cd726ca0 | 290 | UInt8 buffer[ memoryUsed ]; |
RichardE | 2:bb0f631a6068 | 291 | // Write index with ascending integers. |
RichardE | 3:a6a0cd726ca0 | 292 | UInt8 *ptr = buffer; |
RichardE | 2:bb0f631a6068 | 293 | for( UInt8 i = 0; i < capacity; ++i ) { |
RichardE | 2:bb0f631a6068 | 294 | *ptr++ = i; |
RichardE | 2:bb0f631a6068 | 295 | } |
RichardE | 2:bb0f631a6068 | 296 | // Write data table with zero score entries. |
RichardE | 2:bb0f631a6068 | 297 | for( UInt8 i = 0; i < capacity; ++i ) { |
RichardE | 2:bb0f631a6068 | 298 | // Write a name of "AAA". |
RichardE | 2:bb0f631a6068 | 299 | for( UInt8 j = 0; j < PlayerName::Length; ++j ) { |
RichardE | 3:a6a0cd726ca0 | 300 | *ptr++ = (UInt8)'A'; |
RichardE | 2:bb0f631a6068 | 301 | } |
RichardE | 3:a6a0cd726ca0 | 302 | // Write a score of zero. |
RichardE | 2:bb0f631a6068 | 303 | *((UInt32*)ptr) = 0; |
RichardE | 3:a6a0cd726ca0 | 304 | ptr += 4; |
RichardE | 3:a6a0cd726ca0 | 305 | // Write zero to unused byte. |
RichardE | 3:a6a0cd726ca0 | 306 | *ptr++ = 0; |
RichardE | 3:a6a0cd726ca0 | 307 | } |
RichardE | 3:a6a0cd726ca0 | 308 | // Write the buffer to EEPROM. |
RichardE | 3:a6a0cd726ca0 | 309 | eeprom->write( eepromAddress, memoryUsed, (char*)buffer ); |
RichardE | 2:bb0f631a6068 | 310 | } |