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
Diff: HighScoreTable.cpp
- 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 ); }