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:
Sat Jun 15 15:05:19 2013 +0000
Revision:
15:d8ea0c7b7e64
Parent:
14:46a353b2a8e8
Child:
16:d0b142ba4362
Started adding code to represent a grid of rectangles which is used on high score entry screen. See FieldGrid, FieldRow and FieldCell classes and use in HighScoreEntry.cpp.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
RichardE 0:5fa232ee5fdf 1 /*
RichardE 0:5fa232ee5fdf 2 * SOURCE FILE : HighScoreEntry.cpp
RichardE 0:5fa232ee5fdf 3 *
RichardE 0:5fa232ee5fdf 4 * Definition of class HighScoreEntry.
RichardE 0:5fa232ee5fdf 5 * Routine to allow player to enter their name using joysticks.
RichardE 0:5fa232ee5fdf 6 *
RichardE 0:5fa232ee5fdf 7 */
RichardE 0:5fa232ee5fdf 8
RichardE 0:5fa232ee5fdf 9 #include "HighScoreEntry.h"
RichardE 0:5fa232ee5fdf 10 #include "Gameduino.h" // Gameduino stuff
RichardE 4:673eb9735d44 11 #include "GDExtra.h" // more Gameduino stuff
RichardE 4:673eb9735d44 12 #include "GDConst.h" // Gameduino constants
RichardE 4:673eb9735d44 13 #include "FrameCounter.h" // counter updated every vertical flyback
RichardE 4:673eb9735d44 14 #include "CharBlocks.h" // blocks of characters in program memory
RichardE 4:673eb9735d44 15 #include "CharFrame.h" // for drawing frames made of characters
RichardE 4:673eb9735d44 16 #include "CharCodes.h" // character codes
RichardE 0:5fa232ee5fdf 17
RichardE 15:d8ea0c7b7e64 18 // Define this for debugging messages on serial port.
RichardE 15:d8ea0c7b7e64 19 #define CHATTY
RichardE 15:d8ea0c7b7e64 20
RichardE 15:d8ea0c7b7e64 21 #ifdef CHATTY
RichardE 15:d8ea0c7b7e64 22 extern Serial pc;
RichardE 15:d8ea0c7b7e64 23 #endif
RichardE 15:d8ea0c7b7e64 24
RichardE 15:d8ea0c7b7e64 25 // Grid constants.
RichardE 15:d8ea0c7b7e64 26 #define GRIDX 5
RichardE 15:d8ea0c7b7e64 27 #define GRIDY 14
RichardE 15:d8ea0c7b7e64 28 #define GRIDCOLUMNS 20
RichardE 15:d8ea0c7b7e64 29 #define GRIDROWS 3
RichardE 15:d8ea0c7b7e64 30 #define GRIDCOLUMNSPACING 2
RichardE 15:d8ea0c7b7e64 31 #define GRIDROWSPACING 2
RichardE 15:d8ea0c7b7e64 32
RichardE 0:5fa232ee5fdf 33 /***************/
RichardE 0:5fa232ee5fdf 34 /* CONSTRUCTOR */
RichardE 0:5fa232ee5fdf 35 /***************/
RichardE 0:5fa232ee5fdf 36 HighScoreEntry::HighScoreEntry() :
RichardE 15:d8ea0c7b7e64 37 cursorPos( 0 ),
RichardE 15:d8ea0c7b7e64 38 grid( GRIDROWS )
RichardE 0:5fa232ee5fdf 39 {
RichardE 15:d8ea0c7b7e64 40 // Initialise grid around which cursor moves.
RichardE 15:d8ea0c7b7e64 41 InitialiseGrid();
RichardE 15:d8ea0c7b7e64 42 #ifdef CHATTY
RichardE 15:d8ea0c7b7e64 43 for( UInt8 rowNum = 0; rowNum < grid.GetRowCount(); ++rowNum ) {
RichardE 15:d8ea0c7b7e64 44 FieldRow *row = grid.GetRow( rowNum );
RichardE 15:d8ea0c7b7e64 45 if( row != (FieldRow*)NULL ) {
RichardE 15:d8ea0c7b7e64 46 FieldCell *cell = row->GetFirstCell();
RichardE 15:d8ea0c7b7e64 47 UInt8 columnNum = 0;
RichardE 15:d8ea0c7b7e64 48 while( cell != (FieldCell*)NULL ) {
RichardE 15:d8ea0c7b7e64 49 pc.printf(
RichardE 15:d8ea0c7b7e64 50 "Row %d column %d -> %d,%d,%d,%d\r\n",
RichardE 15:d8ea0c7b7e64 51 (int)rowNum, (int)columnNum,
RichardE 15:d8ea0c7b7e64 52 (int)cell->Rect.X1, (int)cell->Rect.Y1, (int)cell->Rect.X2, (int)cell->Rect.Y2
RichardE 15:d8ea0c7b7e64 53 );
RichardE 15:d8ea0c7b7e64 54 cell = row->GetNextCell();
RichardE 15:d8ea0c7b7e64 55 columnNum++;
RichardE 15:d8ea0c7b7e64 56 }
RichardE 15:d8ea0c7b7e64 57 }
RichardE 15:d8ea0c7b7e64 58 }
RichardE 15:d8ea0c7b7e64 59 #endif
RichardE 0:5fa232ee5fdf 60 }
RichardE 0:5fa232ee5fdf 61
RichardE 0:5fa232ee5fdf 62 /**************/
RichardE 0:5fa232ee5fdf 63 /* DESTRUCTOR */
RichardE 0:5fa232ee5fdf 64 /**************/
RichardE 0:5fa232ee5fdf 65 HighScoreEntry::~HighScoreEntry() {
RichardE 0:5fa232ee5fdf 66 }
RichardE 0:5fa232ee5fdf 67
RichardE 15:d8ea0c7b7e64 68 /*******************/
RichardE 15:d8ea0c7b7e64 69 /* INITIALISE GRID */
RichardE 15:d8ea0c7b7e64 70 /*******************/
RichardE 15:d8ea0c7b7e64 71 void HighScoreEntry::InitialiseGrid( void ) {
RichardE 15:d8ea0c7b7e64 72 UInt8 x, y = GRIDY;
RichardE 15:d8ea0c7b7e64 73 for( UInt8 rowNumber = 0; rowNumber < GRIDROWS; ++rowNumber ) {
RichardE 15:d8ea0c7b7e64 74 FieldRow *row = grid.GetRow( rowNumber );
RichardE 15:d8ea0c7b7e64 75 if( row != (FieldRow*)NULL ) {
RichardE 15:d8ea0c7b7e64 76 x = GRIDX;
RichardE 15:d8ea0c7b7e64 77 for( UInt8 columnNumber = 0; columnNumber < GRIDCOLUMNS; ++columnNumber ) {
RichardE 15:d8ea0c7b7e64 78 FieldCell *cell = new FieldCell();
RichardE 15:d8ea0c7b7e64 79 cell->Rect.X1 = ( x - 1 ) << 3;
RichardE 15:d8ea0c7b7e64 80 cell->Rect.Y1 = ( y - 1 ) << 3;
RichardE 15:d8ea0c7b7e64 81 cell->Rect.X2 = ( ( x + 1 ) << 3 ) + 7;
RichardE 15:d8ea0c7b7e64 82 cell->Rect.Y2 = ( ( y + 1 ) << 3 ) + 7;
RichardE 15:d8ea0c7b7e64 83 row->AddCell( cell );
RichardE 15:d8ea0c7b7e64 84 x += GRIDCOLUMNSPACING;
RichardE 15:d8ea0c7b7e64 85 }
RichardE 15:d8ea0c7b7e64 86 }
RichardE 15:d8ea0c7b7e64 87 y += GRIDROWSPACING;
RichardE 15:d8ea0c7b7e64 88 }
RichardE 15:d8ea0c7b7e64 89 }
RichardE 15:d8ea0c7b7e64 90
RichardE 0:5fa232ee5fdf 91 /*********************/
RichardE 0:5fa232ee5fdf 92 /* GET A PLAYER NAME */
RichardE 0:5fa232ee5fdf 93 /*********************/
RichardE 0:5fa232ee5fdf 94 // Pass pointer to place to store name in name.
RichardE 0:5fa232ee5fdf 95 // Pass pointer to controls to read in controls.
RichardE 4:673eb9735d44 96 // Pass pointer to Gameduino to display on in gd.
RichardE 4:673eb9735d44 97 void HighScoreEntry::GetName( PlayerName *name, PanelControls *controls, Gameduino *gd ) {
RichardE 0:5fa232ee5fdf 98 UInt16 inputs;
RichardE 0:5fa232ee5fdf 99 UInt8 countdown = 0;
RichardE 0:5fa232ee5fdf 100 char *curPtr;
RichardE 0:5fa232ee5fdf 101 // Initialise name to all 'A' characters.
RichardE 0:5fa232ee5fdf 102 for( UInt8 i = 0; i < PlayerName::Length; ++i ) {
RichardE 0:5fa232ee5fdf 103 name->Name[ i ] = 'A';
RichardE 0:5fa232ee5fdf 104 }
RichardE 0:5fa232ee5fdf 105 // Draw screen.
RichardE 4:673eb9735d44 106 DrawScreen( gd );
RichardE 0:5fa232ee5fdf 107 // Wait until player releases all controls.
RichardE 4:673eb9735d44 108 WaitControls( gd, controls, false );
RichardE 0:5fa232ee5fdf 109 // Start at leftmost character.
RichardE 0:5fa232ee5fdf 110 cursorPos = 0;
RichardE 0:5fa232ee5fdf 111 // Loop until cursor moves beyond rightmost character.
RichardE 0:5fa232ee5fdf 112 while( cursorPos < PlayerName::Length ) {
RichardE 0:5fa232ee5fdf 113 // Read panel controls.
RichardE 0:5fa232ee5fdf 114 controls->Read();
RichardE 0:5fa232ee5fdf 115 inputs = controls->GetInputs();
RichardE 0:5fa232ee5fdf 116 // Point to character under cursor.
RichardE 0:5fa232ee5fdf 117 curPtr = name->Name + cursorPos;
RichardE 0:5fa232ee5fdf 118 // Only react to controls every so often to slow things down.
RichardE 0:5fa232ee5fdf 119 if( countdown == 0 ) {
RichardE 0:5fa232ee5fdf 120 countdown = 10;
RichardE 0:5fa232ee5fdf 121 if( inputs & PanelControls::Up1 ) {
RichardE 0:5fa232ee5fdf 122 // Joystick up selects next character up.
RichardE 0:5fa232ee5fdf 123 if( *curPtr >= PlayerName::MaxChar ) {
RichardE 0:5fa232ee5fdf 124 *curPtr = PlayerName::MinChar;
RichardE 0:5fa232ee5fdf 125 }
RichardE 0:5fa232ee5fdf 126 else {
RichardE 0:5fa232ee5fdf 127 (*curPtr)++;
RichardE 0:5fa232ee5fdf 128 }
RichardE 0:5fa232ee5fdf 129 }
RichardE 0:5fa232ee5fdf 130 else if( inputs & PanelControls::Down1 ) {
RichardE 0:5fa232ee5fdf 131 // Joystick down selects previous character down.
RichardE 0:5fa232ee5fdf 132 if( *curPtr <= PlayerName::MinChar ) {
RichardE 0:5fa232ee5fdf 133 *curPtr = PlayerName::MaxChar;
RichardE 0:5fa232ee5fdf 134 }
RichardE 0:5fa232ee5fdf 135 else {
RichardE 0:5fa232ee5fdf 136 (*curPtr)--;
RichardE 0:5fa232ee5fdf 137 }
RichardE 0:5fa232ee5fdf 138 }
RichardE 0:5fa232ee5fdf 139 else if( inputs & PanelControls::Left1 ) {
RichardE 0:5fa232ee5fdf 140 // Joystick left moves cursor back.
RichardE 0:5fa232ee5fdf 141 if( cursorPos > 0 ) {
RichardE 0:5fa232ee5fdf 142 cursorPos--;
RichardE 0:5fa232ee5fdf 143 // Wait until all controls released.
RichardE 4:673eb9735d44 144 WaitControls( gd, controls, false );
RichardE 0:5fa232ee5fdf 145 }
RichardE 0:5fa232ee5fdf 146 }
RichardE 0:5fa232ee5fdf 147 else if( inputs & PanelControls::Right1 ) {
RichardE 0:5fa232ee5fdf 148 // Joystick right moves cursor forwards.
RichardE 0:5fa232ee5fdf 149 cursorPos++;
RichardE 0:5fa232ee5fdf 150 // Wait until all controls released.
RichardE 4:673eb9735d44 151 WaitControls( gd, controls, false );
RichardE 0:5fa232ee5fdf 152 }
RichardE 0:5fa232ee5fdf 153 }
RichardE 0:5fa232ee5fdf 154 else {
RichardE 0:5fa232ee5fdf 155 countdown--;
RichardE 0:5fa232ee5fdf 156 }
RichardE 0:5fa232ee5fdf 157 // Wait for vertical flyback. Then draw name and do animation.
RichardE 4:673eb9735d44 158 gd->waitvblank();
RichardE 0:5fa232ee5fdf 159 FrameCounter++;
RichardE 4:673eb9735d44 160 DrawName( gd, name );
RichardE 4:673eb9735d44 161 Animate( gd );
RichardE 0:5fa232ee5fdf 162 }
RichardE 0:5fa232ee5fdf 163 // Wait until player releases all controls before returning.
RichardE 4:673eb9735d44 164 WaitControls( gd, controls, false );
RichardE 0:5fa232ee5fdf 165 }
RichardE 0:5fa232ee5fdf 166
RichardE 0:5fa232ee5fdf 167 /*********************/
RichardE 0:5fa232ee5fdf 168 /* WAIT FOR CONTROLS */
RichardE 0:5fa232ee5fdf 169 /*********************/
RichardE 4:673eb9735d44 170 // Pass pointer to Gameduino to display on in gd.
RichardE 0:5fa232ee5fdf 171 // Pass pointer to controls to read in controls.
RichardE 0:5fa232ee5fdf 172 // Pass true in waitActivate to wait for a control to be used.
RichardE 0:5fa232ee5fdf 173 // Pass false to wait for release.
RichardE 4:673eb9735d44 174 void HighScoreEntry::WaitControls( Gameduino *gd, PanelControls *controls, bool waitActivate ) {
RichardE 4:673eb9735d44 175 bool released = false;
RichardE 0:5fa232ee5fdf 176 UInt16 inputs;
RichardE 0:5fa232ee5fdf 177 while( ! released ) {
RichardE 0:5fa232ee5fdf 178 controls->Read();
RichardE 0:5fa232ee5fdf 179 inputs = controls->GetInputs();
RichardE 0:5fa232ee5fdf 180 released = ( waitActivate ? ( inputs != 0 ) : ( inputs == 0 ) );
RichardE 0:5fa232ee5fdf 181 if( ! released ) {
RichardE 4:673eb9735d44 182 gd->waitvblank();
RichardE 0:5fa232ee5fdf 183 FrameCounter++;
RichardE 4:673eb9735d44 184 Animate( gd );
RichardE 0:5fa232ee5fdf 185 }
RichardE 0:5fa232ee5fdf 186 }
RichardE 0:5fa232ee5fdf 187 }
RichardE 0:5fa232ee5fdf 188
RichardE 0:5fa232ee5fdf 189 /*******************/
RichardE 0:5fa232ee5fdf 190 /* DRAW THE SCREEN */
RichardE 0:5fa232ee5fdf 191 /*******************/
RichardE 4:673eb9735d44 192 // Pass pointer to Gameduino to draw on in gd.
RichardE 4:673eb9735d44 193 void HighScoreEntry::DrawScreen( Gameduino *gd ) {
RichardE 4:673eb9735d44 194 gd->waitvblank();
RichardE 0:5fa232ee5fdf 195 // Clear the screen to zero characters.
RichardE 4:673eb9735d44 196 gd->fill( Gameduino::RAM_PIC, 0, RAM_PIC_SIZE );
RichardE 0:5fa232ee5fdf 197 // Turn off all the sprites.
RichardE 0:5fa232ee5fdf 198 for( UInt16 s = 0; s < SPRITE_COUNT; ++s ) {
RichardE 4:673eb9735d44 199 gd->sprite( s, 0, 400, 0, 0 );
RichardE 0:5fa232ee5fdf 200 }
RichardE 0:5fa232ee5fdf 201 // Draw border around screen.
RichardE 4:673eb9735d44 202 CharFrame::Draw( gd, 0, 0, VISIBLE_CHAR_WIDTH, VISIBLE_CHAR_HEIGHT );
RichardE 14:46a353b2a8e8 203 // Draw instructions.
RichardE 14:46a353b2a8e8 204 gd->putstr( 2, 2, " CONGRATULATIONS : YOU HAVE A HIGH SCORE!" );
RichardE 14:46a353b2a8e8 205 gd->putstr( 2, 4, "PLEASE ENTER YOUR NAME USING THE LEFT JOYSTICK" );
RichardE 14:46a353b2a8e8 206 gd->putstr( 2, 6, " TO MOVE THE CURSOR. PRESS THE LEFT BUTTON TO" );
RichardE 14:46a353b2a8e8 207 gd->putstr( 2, 8, " ENTER EACH LETTER. MOVE CURSOR TO FOOT OF" );
RichardE 14:46a353b2a8e8 208 gd->putstr( 2, 10, " SCREEN AND PRESS LEFT BUTTON WHEN FINISHED." );
RichardE 14:46a353b2a8e8 209 // Draw character grid.
RichardE 14:46a353b2a8e8 210 DrawGrid( gd );
RichardE 14:46a353b2a8e8 211 }
RichardE 14:46a353b2a8e8 212
RichardE 14:46a353b2a8e8 213 /***************************/
RichardE 14:46a353b2a8e8 214 /* DRAW THE CHARACTER GRID */
RichardE 14:46a353b2a8e8 215 /***************************/
RichardE 14:46a353b2a8e8 216 // Pass pointer to Gameduino to draw on in gd.
RichardE 14:46a353b2a8e8 217 void HighScoreEntry::DrawGrid( Gameduino *gd ) {
RichardE 14:46a353b2a8e8 218 UInt8 code = PlayerName::MinChar;
RichardE 14:46a353b2a8e8 219 UInt8 x = GRIDX, y = GRIDY;
RichardE 14:46a353b2a8e8 220 UInt8 columnNumber = 0;
RichardE 14:46a353b2a8e8 221 char str [] = "X";
RichardE 14:46a353b2a8e8 222 while( code <= PlayerName::MaxChar ) {
RichardE 14:46a353b2a8e8 223 str[ 0 ] = (char)code++;
RichardE 14:46a353b2a8e8 224 gd->putstr( x, y, str );
RichardE 14:46a353b2a8e8 225 columnNumber++;
RichardE 14:46a353b2a8e8 226 if( columnNumber >= GRIDCOLUMNS ) {
RichardE 14:46a353b2a8e8 227 columnNumber = 0;
RichardE 14:46a353b2a8e8 228 x = GRIDX;
RichardE 14:46a353b2a8e8 229 y += GRIDROWSPACING;
RichardE 14:46a353b2a8e8 230 }
RichardE 14:46a353b2a8e8 231 else {
RichardE 14:46a353b2a8e8 232 x += GRIDCOLUMNSPACING;
RichardE 14:46a353b2a8e8 233 }
RichardE 14:46a353b2a8e8 234 }
RichardE 0:5fa232ee5fdf 235 }
RichardE 0:5fa232ee5fdf 236
RichardE 0:5fa232ee5fdf 237 /********************************/
RichardE 0:5fa232ee5fdf 238 /* DRAW THE NAME AND THE CURSOR */
RichardE 0:5fa232ee5fdf 239 /********************************/
RichardE 4:673eb9735d44 240 // Pass pointer to Gameduino to draw on in gd.
RichardE 0:5fa232ee5fdf 241 // Pass player name in name.
RichardE 4:673eb9735d44 242 void HighScoreEntry::DrawName( Gameduino *gd, PlayerName *name ) {
RichardE 4:673eb9735d44 243 gd->putstr( 21, 11, name->Name );
RichardE 4:673eb9735d44 244 UInt16 address = Gameduino::RAM_PIC + 12 * SCREEN_CHAR_WIDTH + 21;
RichardE 0:5fa232ee5fdf 245 for( UInt8 i = 0; i < PlayerName::Length; ++i ) {
RichardE 4:673eb9735d44 246 gd->wr( address, ( i == cursorPos ) ? ArrowUp : ' ' );
RichardE 0:5fa232ee5fdf 247 address++;
RichardE 0:5fa232ee5fdf 248 }
RichardE 0:5fa232ee5fdf 249 }
RichardE 0:5fa232ee5fdf 250
RichardE 0:5fa232ee5fdf 251 /********************/
RichardE 0:5fa232ee5fdf 252 /* UPDATE ANIMATION */
RichardE 0:5fa232ee5fdf 253 /********************/
RichardE 4:673eb9735d44 254 // Pass pointer to Gameduino to display on in gd.
RichardE 4:673eb9735d44 255 void HighScoreEntry::Animate( Gameduino *gd ) {
RichardE 0:5fa232ee5fdf 256 }