When you switch off the
battery pack on the GamePack or unplug it from your computer, the AVR
chip loses power and you lose all your data stored in standard
memory. This means we need to write the hi scores to an area of
memory that will persist even when power is lost in order to recover
them again when the game restarts. The ATMega2560 comes with 4kb EEPROM. Data stored here will remain even when power is lost.
The WinAVR development
tools contains a library to read and write from EEPROM and it is
pretty simple to use. See this blog post for some details about using it. The save/load
functionality is encapsulated in the HiScores class in Tetris.
Here are some code
snippets from this class:
You need to include the library:
Detecting if valid data has been saved:
You need to include the library:
#include <avr/eeprom.h>
Detecting if valid data has been saved:
uint8_t data_flag = eeprom_read_byte((uint8_t*)DATA_FLAG_ADDRESS);
if(data_flag == VALID_DATA_FLAG){
return true;
}else{
return false;
}
It is dangerous to assume that the data you want is present in the address you are looking in without some kind of check to confirm the data exists. For example if you run the game for the very first time, no high score data will exist. Who knows what data is written to the addresses you expect to read from. This can be solved by setting a single byte address to a value that indicates that valid data exists. If you read this address and the value is correct, you can assume the other addresses also contain valid data. If not, then you should not assume valid data in the other addresses. This mechanism makes resetting the hi score very easy as you don't actually have to erase the data, just set the flag to not be valid so the existing data will be ignored and overwritten (you can see this in HighScore.cpp).
Save a name and score
to EEPROM:
//indicate there is valid data to be read
eeprom_write_byte((uint8_t*)DATA_FLAG_ADDRESS, VALID_DATA_FLAG);
//save the player name
for(int i=0 ; i<player_name_length_ ; i++){
eeprom_write_byte((uint8_t*)(DATA_NAME_ADDRESS+i), player_name[i]);
}
//terminate the name array
eeprom_write_byte((uint8_t*)(DATA_NAME_ADDRESS+player_name_length_), '\0');
//save the player score
eeprom_write_word((uint16_t*)(DATA_SCORE_ADDRESS), score);
An example set of data saved in Tetris is as follows:
Address: 1 2 3 4 5 6 7
Data: 9 B O B \0 123
Where address 1 contains the valid check flag (where a value of 9 means valid data exists). This gives us a name of BOB (terminated by the null character) and a hi score of 123. The score is a stored as a 2 byte word.
Load the name and score back from EEPROM:
//extra character to include the terminating character
char* player_name = new char[player_name_length_+1];
for(int i=0 ; i<player_name_length_+1 ; i++){
player_name[i] = eeprom_read_byte((uint8_t*)(DATA_NAME_ADDRESS+i));
}
int score = eeprom_read_word((uint16_t*)(DATA_SCORE_ADDRESS));
Note: It is important to terminate the player name with a null character so no garbage gets appended on the end when you are displaying it on the screen. The graphics function text(char*, int, int) that will take the player name will stop looking for characters when it encounters the null character so without it you may get all sorts of stuff appended to the name.
The
LandingScreen loads the hi score data and displays it to the player.
The NameEntryScreen saves the hi score data back. Simples.
You can download version 2 of the Tetris Eclipse project here.
Check out a video of the hi score persistence in action. You can also see the game transition screens implemented from the last post:
Watch the video on youtube if you want to see the annotations. They seem to have been chopped off in this tiny format and I don't see a way to make it any bigger.
Note: There is a super secret button combo to reset the high score. On the landing screen where it says press A to continue, if you hold down the B button then press A, the screen will say 'HI SCORE RESET' and then continue.
You can download version 2 of the Tetris Eclipse project here.
Check out a video of the hi score persistence in action. You can also see the game transition screens implemented from the last post:
Watch the video on youtube if you want to see the annotations. They seem to have been chopped off in this tiny format and I don't see a way to make it any bigger.
Note: There is a super secret button combo to reset the high score. On the landing screen where it says press A to continue, if you hold down the B button then press A, the screen will say 'HI SCORE RESET' and then continue.