Richard Ellingworth / Mbed 2 deprecated RobotRic

Dependencies:   25LCxxx_SPI CommonTypes Gameduino mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers GameRobotRic.cpp Source File

GameRobotRic.cpp

00001 /*
00002  * SOURCE FILE : GameRobotRic.cpp
00003  *
00004  * The RobotRic game class.
00005  *
00006  */
00007 
00008 #include "GameRobotRic.h"          // this module's prototypes
00009 #include "Types.h"                 // various integer types etc.
00010 #include "LevelCollection.h"       // all the levels
00011 #include "sprite.h"                // sprite data
00012 #include "RobotRicCharacterSet.h"  // character set used in this game
00013 #include "HighScoreEntry.h"        // for getting player's name for high score table
00014 #include "GDExtra.h"               // extra Gameduino functions
00015 #include "GDConst.h"               // a few more Gameduino constants
00016 #include "ArenaConst.h"            // gameplay arena constants
00017 
00018 // Define following for debugging messages to serial port.
00019 #undef CHATTY
00020 
00021 // Define following to reset all high scores on power up.
00022 #undef RESETHIGHSCORES
00023 
00024 // Number of lives player starts with.
00025 #define START_LIVES 5
00026 
00027 // Serial link to PC over USB cable. Globally accessible.
00028 Serial pc( USBTX, USBRX );
00029 
00030 /**************************/
00031 /* CHECK FOR A HIGH SCORE */
00032 /**************************/
00033 // Pass pointer to a Gameduino to display on in gd.
00034 // Pass pointer to high score table in highScores.
00035 // Pass score that was achieved in score.
00036 void GameRobotRic::CheckForHighScore( Gameduino *gd, HighScoreTable *highScores, UInt32 score ) {
00037     UInt8 tablePos;
00038     // Enter name into high score table if score is high enough.
00039     if( ( tablePos = highScores->GetPositionInTable( score ) ) < highScores->GetCapacity() ) {
00040         // Player has made it onto the high score table.
00041         // Get player to input name.
00042         HighScoreEntry nameGetter;
00043         PlayerName name;
00044         nameGetter.GetName( &name, &controls, gd );
00045         // Add name and score to table.
00046         highScores->Add( tablePos, &name, score );
00047     }
00048 }
00049 
00050 /*****************/
00051 /* PLAY THE GAME */
00052 /*****************/
00053 // This NEVER exits.
00054 void GameRobotRic::Play( void ) {
00055     // Change baud rate on PC serial link.
00056     pc.baud( 115200 );
00057     #ifdef CHATTY
00058         pc.puts( "Program has restarted!\r\n" );
00059     #endif
00060     // Make a digital output for use as the Gameduino chip select pin. Deselect it.
00061     DigitalOut gameduinoCS( p8 );
00062     gameduinoCS = 1;
00063     // Initialise an SPI link for communications with Gameduino and the serial EEPROM.
00064     // This is different from how the Maple version of RobotRic did it. It used an
00065     // I2C EEPROM.
00066     // Use pin 5 for MOSI.
00067     // Use pin 6 for MISO.
00068     // Use pin 7 for SCK.
00069     SPI spi( p5, p6, p7 );
00070     // 8MHz clock should be OK.
00071     spi.frequency( 8000000 );
00072     // Set SPI format to use.
00073     // Use 8 bits per SPI frame.
00074     // Use SPI mode 0. Clock normally low. Data captured on rising edge.
00075     spi.format( 8, 0 );
00076     // Make a Gameduino and pass SPI link and digital output for chip select.
00077     Gameduino gd( &spi, &gameduinoCS );
00078     // Reset the Gameduino.
00079     gd.begin();
00080     gd.copy( Gameduino::RAM_SPRIMG, sprite_sprimg, sizeof( sprite_sprimg ) );
00081     // Copy sprite palette data into Gameduino memory.
00082     gd.copy( Gameduino::RAM_SPRPAL, sprite_sprpal, sizeof( sprite_sprpal ) );
00083     // Initialise character set pixel data RAM.
00084     gd.copy( Gameduino::RAM_CHR, RobotRicCharacterSet::PixelData, ( LAST_CHAR_IN_CHARACTER_SET + 1 ) << 4 );
00085     // Initialise character set pixel palette RAM.
00086     gd.copy( Gameduino::RAM_PAL, RobotRicCharacterSet::PaletteData, ( LAST_CHAR_IN_CHARACTER_SET + 1 ) << 3 );
00087     // Turn off JK collision detection. Every sprite collides with every other.
00088     // Did it this way because I could not resolve some problems with wandering humans.
00089     // Suppose JK collision detection were used. The player sprite is of type J and humans
00090     // are of type K so collisions between them will register allowing humans to be rescued.
00091     // However, I also need some enemies (Crushers for example) to be able to collide with
00092     // humans so they would need to be J type to collide with humans. But then player and
00093     // enemies are both J type and so collisions between players and enemies are not detected.
00094     gd.wr( Gameduino::JK_MODE, 0 );
00095     // Pass Gameduino to sound manager.
00096     SoundManager::Instance.SetGameduino( &gd );
00097     // Initialise serial EEPROM object which is on same SPI bus as the Gameduino.
00098     Ser25LCxxx eeprom( &spi, p14, 32768, 64 );
00099     // Create a high score table that uses the EEPROM.
00100     HighScoreTable highScores( &eeprom );
00101     // Start on the attract level.
00102     UInt8 levelNumber = LevelCollection::AttractLevel;
00103     player.Lives = START_LIVES;
00104     LevelCollection levels;
00105     Level *level;
00106     Level::LevelExitCode exitCode;
00107     // Initialise panel controls.
00108     controls.InitialisePins();
00109     // Specify controls player should use.
00110     player.SetControls( &controls );
00111     // Restrict players movement.
00112     player.MovementRestricted = true;
00113     player.Bounds = &ArenaRectangle;
00114     // If configured to do so reset high scores.
00115     #ifdef RESETHIGHSCORES
00116         highScores.WriteEEPROMDefaults();
00117     #endif    
00118     // Repeat forever.
00119     while( true ) {
00120         // Get level specified by level number.
00121         level = levels.GetLevel( levelNumber );
00122         // If failed to get level with that number go back to first normal level.
00123         // This will happen if player completes last level.
00124         if( level == NULL ) {
00125             levelNumber = LevelCollection::FirstNormalLevel;
00126             // Refetch level.
00127             level = levels.GetLevel( levelNumber );
00128         }
00129         // Pass reference to high score table.
00130         level->SetHighScores( &highScores );
00131         // Set player that is playing the level.
00132         level->SetPlayer( &player );
00133         // Set Gameduino to use.
00134         level->SetGameduino( &gd );
00135         // Play the level.
00136         exitCode = level->Play();
00137         // Free memory used by level.
00138         levels.FreeLevel( level );
00139         // If player was killed then decrement lives otherwise
00140         // advance to next level.
00141         switch( exitCode ) {
00142         case Level::GameOver :
00143             // TODO : Do some sort of game over fuss.
00144             CheckForHighScore( &gd, &highScores, player.Score );
00145             // Go back to attract level and reset player lives and score.
00146             levelNumber = LevelCollection::AttractLevel;
00147             player.Lives = START_LIVES;
00148             player.Score = 0;
00149             break;
00150         case Level::Completed :
00151             levelNumber++;
00152             break;
00153         }
00154     }
00155 }
00156 
00157 
00158