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

Committer:
RichardE
Date:
Tue Jun 11 21:04:48 2013 +0000
Revision:
14:46a353b2a8e8
Parent:
10:bfa1c307c99d
Child:
17:194789db2215
Started to modify how high scores are entered but not finished. Currently asks for a name when program first starts. Remove this code later.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
RichardE 0:5fa232ee5fdf 1 /*
RichardE 0:5fa232ee5fdf 2 * SOURCE FILE : GameRobotRic.cpp
RichardE 0:5fa232ee5fdf 3 *
RichardE 0:5fa232ee5fdf 4 * The RobotRic game class.
RichardE 0:5fa232ee5fdf 5 *
RichardE 0:5fa232ee5fdf 6 */
RichardE 0:5fa232ee5fdf 7
RichardE 0:5fa232ee5fdf 8 #include "GameRobotRic.h" // this module's prototypes
RichardE 0:5fa232ee5fdf 9 #include "Types.h" // various integer types etc.
RichardE 0:5fa232ee5fdf 10 #include "LevelCollection.h" // all the levels
RichardE 2:bb0f631a6068 11 #include "sprite.h" // sprite data
RichardE 2:bb0f631a6068 12 #include "RobotRicCharacterSet.h" // character set used in this game
RichardE 4:673eb9735d44 13 #include "HighScoreEntry.h" // for getting player's name for high score table
RichardE 4:673eb9735d44 14 #include "GDExtra.h" // extra Gameduino functions
RichardE 4:673eb9735d44 15 #include "GDConst.h" // a few more Gameduino constants
RichardE 4:673eb9735d44 16 #include "ArenaConst.h" // gameplay arena constants
RichardE 0:5fa232ee5fdf 17
RichardE 3:a6a0cd726ca0 18 // Define following for debugging messages to serial port.
RichardE 3:a6a0cd726ca0 19 #define CHATTY
RichardE 3:a6a0cd726ca0 20
RichardE 0:5fa232ee5fdf 21 // Number of lives player starts with.
RichardE 0:5fa232ee5fdf 22 #define START_LIVES 5
RichardE 0:5fa232ee5fdf 23
RichardE 3:a6a0cd726ca0 24 // Serial link to PC over USB cable. Globally accessible.
RichardE 3:a6a0cd726ca0 25 Serial pc( USBTX, USBRX );
RichardE 3:a6a0cd726ca0 26
RichardE 0:5fa232ee5fdf 27 /**************************/
RichardE 0:5fa232ee5fdf 28 /* CHECK FOR A HIGH SCORE */
RichardE 0:5fa232ee5fdf 29 /**************************/
RichardE 4:673eb9735d44 30 // Pass pointer to a Gameduino to display on in gd.
RichardE 0:5fa232ee5fdf 31 // Pass pointer to high score table in highScores.
RichardE 0:5fa232ee5fdf 32 // Pass score that was achieved in score.
RichardE 4:673eb9735d44 33 void GameRobotRic::CheckForHighScore( Gameduino *gd, HighScoreTable *highScores, UInt32 score ) {
RichardE 0:5fa232ee5fdf 34 UInt8 tablePos;
RichardE 0:5fa232ee5fdf 35 // Enter name into high score table if score is high enough.
RichardE 14:46a353b2a8e8 36 if( ( tablePos = highScores->GetPositionInTable( score ) ) < highScores->GetCapacity() ) {
RichardE 0:5fa232ee5fdf 37 // Player has made it onto the high score table.
RichardE 0:5fa232ee5fdf 38 // Get player to input name.
RichardE 0:5fa232ee5fdf 39 HighScoreEntry nameGetter;
RichardE 0:5fa232ee5fdf 40 PlayerName name;
RichardE 4:673eb9735d44 41 nameGetter.GetName( &name, &controls, gd );
RichardE 0:5fa232ee5fdf 42 // Add name and score to table.
RichardE 0:5fa232ee5fdf 43 highScores->Add( tablePos, &name, score );
RichardE 0:5fa232ee5fdf 44 }
RichardE 0:5fa232ee5fdf 45 }
RichardE 0:5fa232ee5fdf 46
RichardE 0:5fa232ee5fdf 47 /*****************/
RichardE 0:5fa232ee5fdf 48 /* PLAY THE GAME */
RichardE 0:5fa232ee5fdf 49 /*****************/
RichardE 0:5fa232ee5fdf 50 // This NEVER exits.
RichardE 0:5fa232ee5fdf 51 void GameRobotRic::Play( void ) {
RichardE 6:8bbdb70bc11c 52 // Change baud rate on PC serial link.
RichardE 6:8bbdb70bc11c 53 pc.baud( 115200 );
RichardE 6:8bbdb70bc11c 54 #ifdef CHATTY
RichardE 6:8bbdb70bc11c 55 pc.puts( "Program has restarted!\r\n" );
RichardE 6:8bbdb70bc11c 56 #endif
RichardE 2:bb0f631a6068 57 // Make a digital output for use as the Gameduino chip select pin. Deselect it.
RichardE 2:bb0f631a6068 58 DigitalOut gameduinoCS( p8 );
RichardE 2:bb0f631a6068 59 gameduinoCS = 1;
RichardE 2:bb0f631a6068 60 // Initialise an SPI link for communications with Gameduino and the serial EEPROM.
RichardE 2:bb0f631a6068 61 // This is different from how the Maple version of RobotRic did it. It used an
RichardE 2:bb0f631a6068 62 // I2C EEPROM.
RichardE 0:5fa232ee5fdf 63 // Use pin 5 for MOSI.
RichardE 0:5fa232ee5fdf 64 // Use pin 6 for MISO.
RichardE 0:5fa232ee5fdf 65 // Use pin 7 for SCK.
RichardE 0:5fa232ee5fdf 66 SPI spi( p5, p6, p7 );
RichardE 0:5fa232ee5fdf 67 // 8MHz clock should be OK.
RichardE 0:5fa232ee5fdf 68 spi.frequency( 8000000 );
RichardE 0:5fa232ee5fdf 69 // Set SPI format to use.
RichardE 0:5fa232ee5fdf 70 // Use 8 bits per SPI frame.
RichardE 3:a6a0cd726ca0 71 // Use SPI mode 0. Clock normally low. Data captured on rising edge.
RichardE 0:5fa232ee5fdf 72 spi.format( 8, 0 );
RichardE 0:5fa232ee5fdf 73 // Make a Gameduino and pass SPI link and digital output for chip select.
RichardE 2:bb0f631a6068 74 Gameduino gd( &spi, &gameduinoCS );
RichardE 0:5fa232ee5fdf 75 // Reset the Gameduino.
RichardE 0:5fa232ee5fdf 76 gd.begin();
RichardE 2:bb0f631a6068 77 gd.copy( Gameduino::RAM_SPRIMG, sprite_sprimg, sizeof( sprite_sprimg ) );
RichardE 2:bb0f631a6068 78 // Copy sprite palette data into Gameduino memory.
RichardE 2:bb0f631a6068 79 gd.copy( Gameduino::RAM_SPRPAL, sprite_sprpal, sizeof( sprite_sprpal ) );
RichardE 2:bb0f631a6068 80 // Initialise character set pixel data RAM.
RichardE 2:bb0f631a6068 81 gd.copy( Gameduino::RAM_CHR, RobotRicCharacterSet::PixelData, ( LAST_CHAR_IN_CHARACTER_SET + 1 ) << 4 );
RichardE 2:bb0f631a6068 82 // Initialise character set pixel palette RAM.
RichardE 2:bb0f631a6068 83 gd.copy( Gameduino::RAM_PAL, RobotRicCharacterSet::PaletteData, ( LAST_CHAR_IN_CHARACTER_SET + 1 ) << 3 );
RichardE 2:bb0f631a6068 84 // Turn off JK collision detection. Every sprite collides with every other.
RichardE 2:bb0f631a6068 85 // Did it this way because I could not resolve some problems with wandering humans.
RichardE 2:bb0f631a6068 86 // Suppose JK collision detection were used. The player sprite is of type J and humans
RichardE 2:bb0f631a6068 87 // are of type K so collisions between them will register allowing humans to be rescued.
RichardE 2:bb0f631a6068 88 // However, I also need some enemies (Crushers for example) to be able to collide with
RichardE 2:bb0f631a6068 89 // humans so they would need to be J type to collide with humans. But then player and
RichardE 2:bb0f631a6068 90 // enemies are both J type and so collisions between players and enemies are not detected.
RichardE 2:bb0f631a6068 91 gd.wr( Gameduino::JK_MODE, 0 );
RichardE 9:fa7e7b37b632 92 // Pass Gameduino to sound manager.
RichardE 9:fa7e7b37b632 93 SoundManager::Instance.SetGameduino( &gd );
RichardE 2:bb0f631a6068 94 // Initialise serial EEPROM object which is on same SPI bus as the Gameduino.
RichardE 3:a6a0cd726ca0 95 Ser25LCxxx eeprom( &spi, p14, 32768, 64 );
RichardE 0:5fa232ee5fdf 96 // Create a high score table that uses the EEPROM.
RichardE 0:5fa232ee5fdf 97 HighScoreTable highScores( &eeprom );
RichardE 2:bb0f631a6068 98 // Start on the attract level.
RichardE 2:bb0f631a6068 99 UInt8 levelNumber = LevelCollection::AttractLevel;
RichardE 4:673eb9735d44 100 player.Lives = START_LIVES;
RichardE 4:673eb9735d44 101 LevelCollection levels;
RichardE 4:673eb9735d44 102 Level *level;
RichardE 4:673eb9735d44 103 Level::LevelExitCode exitCode;
RichardE 4:673eb9735d44 104 // Initialise panel controls.
RichardE 4:673eb9735d44 105 controls.InitialisePins();
RichardE 4:673eb9735d44 106 // Specify controls player should use.
RichardE 4:673eb9735d44 107 player.SetControls( &controls );
RichardE 4:673eb9735d44 108 // Restrict players movement.
RichardE 4:673eb9735d44 109 player.MovementRestricted = true;
RichardE 4:673eb9735d44 110 player.Bounds = &ArenaRectangle;
RichardE 14:46a353b2a8e8 111
RichardE 14:46a353b2a8e8 112 // REMOVE THIS!
RichardE 14:46a353b2a8e8 113 CheckForHighScore( &gd, &highScores, 0x10000 );
RichardE 14:46a353b2a8e8 114
RichardE 14:46a353b2a8e8 115
RichardE 4:673eb9735d44 116 // Repeat forever.
RichardE 4:673eb9735d44 117 while( true ) {
RichardE 4:673eb9735d44 118 // Get level specified by level number.
RichardE 4:673eb9735d44 119 level = levels.GetLevel( levelNumber );
RichardE 4:673eb9735d44 120 // If failed to get level with that number go back to first normal level.
RichardE 4:673eb9735d44 121 // This will happen if player completes last level.
RichardE 4:673eb9735d44 122 if( level == NULL ) {
RichardE 4:673eb9735d44 123 levelNumber = LevelCollection::FirstNormalLevel;
RichardE 4:673eb9735d44 124 // Refetch level.
RichardE 4:673eb9735d44 125 level = levels.GetLevel( levelNumber );
RichardE 4:673eb9735d44 126 }
RichardE 4:673eb9735d44 127 // Pass reference to high score table.
RichardE 4:673eb9735d44 128 level->SetHighScores( &highScores );
RichardE 4:673eb9735d44 129 // Set player that is playing the level.
RichardE 4:673eb9735d44 130 level->SetPlayer( &player );
RichardE 4:673eb9735d44 131 // Set Gameduino to use.
RichardE 4:673eb9735d44 132 level->SetGameduino( &gd );
RichardE 4:673eb9735d44 133 // Play the level.
RichardE 4:673eb9735d44 134 exitCode = level->Play();
RichardE 10:bfa1c307c99d 135 // Free memory used by level.
RichardE 10:bfa1c307c99d 136 levels.FreeLevel( level );
RichardE 4:673eb9735d44 137 // If player was killed then decrement lives otherwise
RichardE 4:673eb9735d44 138 // advance to next level.
RichardE 4:673eb9735d44 139 switch( exitCode ) {
RichardE 10:bfa1c307c99d 140 case Level::GameOver :
RichardE 10:bfa1c307c99d 141 // TODO : Do some sort of game over fuss.
RichardE 10:bfa1c307c99d 142 CheckForHighScore( &gd, &highScores, player.Score );
RichardE 10:bfa1c307c99d 143 // Go back to attract level and reset player lives and score.
RichardE 10:bfa1c307c99d 144 levelNumber = LevelCollection::AttractLevel;
RichardE 10:bfa1c307c99d 145 player.Lives = START_LIVES;
RichardE 10:bfa1c307c99d 146 player.Score = 0;
RichardE 10:bfa1c307c99d 147 break;
RichardE 10:bfa1c307c99d 148 case Level::Completed :
RichardE 10:bfa1c307c99d 149 levelNumber++;
RichardE 10:bfa1c307c99d 150 break;
RichardE 4:673eb9735d44 151 }
RichardE 0:5fa232ee5fdf 152 }
RichardE 0:5fa232ee5fdf 153 }
RichardE 0:5fa232ee5fdf 154
RichardE 4:673eb9735d44 155
RichardE 4:673eb9735d44 156