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: HighScoreEntry.cpp
- Revision:
- 16:d0b142ba4362
- Parent:
- 15:d8ea0c7b7e64
- Child:
- 17:194789db2215
--- a/HighScoreEntry.cpp Sat Jun 15 15:05:19 2013 +0000 +++ b/HighScoreEntry.cpp Sat Jun 15 19:27:36 2013 +0000 @@ -14,9 +14,10 @@ #include "CharBlocks.h" // blocks of characters in program memory #include "CharFrame.h" // for drawing frames made of characters #include "CharCodes.h" // character codes +#include "CharFrame.h" // for drawing frames of characters // Define this for debugging messages on serial port. -#define CHATTY +#undef CHATTY #ifdef CHATTY extern Serial pc; @@ -24,7 +25,7 @@ // Grid constants. #define GRIDX 5 -#define GRIDY 14 +#define GRIDY 16 #define GRIDCOLUMNS 20 #define GRIDROWS 3 #define GRIDCOLUMNSPACING 2 @@ -34,7 +35,9 @@ /* CONSTRUCTOR */ /***************/ HighScoreEntry::HighScoreEntry() : - cursorPos( 0 ), + charIndex( 0 ), + cursorRow( 0 ), + cursorColumn( 0 ), grid( GRIDROWS ) { // Initialise grid around which cursor moves. @@ -69,22 +72,30 @@ /* INITIALISE GRID */ /*******************/ void HighScoreEntry::InitialiseGrid( void ) { - UInt8 x, y = GRIDY; - for( UInt8 rowNumber = 0; rowNumber < GRIDROWS; ++rowNumber ) { - FieldRow *row = grid.GetRow( rowNumber ); + UInt8 code = PlayerName::MinChar; + UInt8 x = GRIDX, y = GRIDY; + UInt8 columnNumber = 0, rowNumber = 0;; + FieldRow *row = grid.GetRow( rowNumber++ ); + while( code <= PlayerName::MaxChar ) { if( row != (FieldRow*)NULL ) { + FieldCell *cell = new FieldCell(); + cell->Rect.X1 = x - 1; + cell->Rect.Y1 = y - 1; + cell->Rect.X2 = x + 1; + cell->Rect.Y2 = y + 1; + row->AddCell( cell ); + } + columnNumber++; + if( columnNumber >= GRIDCOLUMNS ) { + columnNumber = 0; x = GRIDX; - for( UInt8 columnNumber = 0; columnNumber < GRIDCOLUMNS; ++columnNumber ) { - FieldCell *cell = new FieldCell(); - cell->Rect.X1 = ( x - 1 ) << 3; - cell->Rect.Y1 = ( y - 1 ) << 3; - cell->Rect.X2 = ( ( x + 1 ) << 3 ) + 7; - cell->Rect.Y2 = ( ( y + 1 ) << 3 ) + 7; - row->AddCell( cell ); - x += GRIDCOLUMNSPACING; - } + y += GRIDROWSPACING; + row = grid.GetRow( rowNumber++ ); } - y += GRIDROWSPACING; + else { + x += GRIDCOLUMNSPACING; + } + code++; } } @@ -97,67 +108,87 @@ void HighScoreEntry::GetName( PlayerName *name, PanelControls *controls, Gameduino *gd ) { UInt16 inputs; UInt8 countdown = 0; - char *curPtr; // Initialise name to all 'A' characters. for( UInt8 i = 0; i < PlayerName::Length; ++i ) { name->Name[ i ] = 'A'; } // Draw screen. - DrawScreen( gd ); + DrawScreen( gd, name ); // Wait until player releases all controls. WaitControls( gd, controls, false ); - // Start at leftmost character. - cursorPos = 0; - // Loop until cursor moves beyond rightmost character. - while( cursorPos < PlayerName::Length ) { + // Loop until player activates done cell. + bool done = false; + while( ! done ) { // Read panel controls. controls->Read(); inputs = controls->GetInputs(); - // Point to character under cursor. - curPtr = name->Name + cursorPos; // Only react to controls every so often to slow things down. if( countdown == 0 ) { countdown = 10; + bool cursorMoved = false; + // Point to current cell before changing. + FieldCell *lastCell = grid.GetCellAt( cursorRow, cursorColumn ); if( inputs & PanelControls::Up1 ) { - // Joystick up selects next character up. - if( *curPtr >= PlayerName::MaxChar ) { - *curPtr = PlayerName::MinChar; - } - else { - (*curPtr)++; + // Joystick up moves cursor up. + if( cursorRow > 0 ) { + cursorRow--; + ValidateCursorColumn(); + cursorMoved = true; } } else if( inputs & PanelControls::Down1 ) { - // Joystick down selects previous character down. - if( *curPtr <= PlayerName::MinChar ) { - *curPtr = PlayerName::MaxChar; - } - else { - (*curPtr)--; + // Joystick down moves cursor down. + if( cursorRow < grid.GetRowCount() - 1 ) { + cursorRow++; + ValidateCursorColumn(); + cursorMoved = true; } } - else if( inputs & PanelControls::Left1 ) { - // Joystick left moves cursor back. - if( cursorPos > 0 ) { - cursorPos--; - // Wait until all controls released. - WaitControls( gd, controls, false ); + if( inputs & PanelControls::Left1 ) { + // Joystick left moves cursor left. + if( cursorColumn > 0 ) { + cursorColumn--; + cursorMoved = true; } } else if( inputs & PanelControls::Right1 ) { - // Joystick right moves cursor forwards. - cursorPos++; - // Wait until all controls released. - WaitControls( gd, controls, false ); + // Joystick right moves cursor right. + FieldRow *row = grid.GetRow( cursorRow ); + if( ( row != (FieldRow*)NULL ) && ( cursorColumn < row->GetColumnCount() - 1 ) ) { + cursorColumn++; + cursorMoved = true; + } + } + if( inputs & PanelControls::Button1 ) { + // Button 1 adds a character or possibly does something special. + if( cursorRow < grid.GetRowCount() ) { + char newChar = (char)( PlayerName::MinChar + cursorRow * GRIDCOLUMNS + cursorColumn ); + name->Name[ charIndex ] = newChar; + if( charIndex < PlayerName::Length - 1 ) { + charIndex++; + } + } + else { + // TODO. Special functions. + } + // Draw modified name. + gd->waitvblank(); + DrawName( gd, name ); + // Wait until player releases all controls. + WaitControls( gd, controls, false ); + } + // If necessary redraw the cursor. + if( cursorMoved ) { + WipeCursor( gd, lastCell ); + DrawCursor( gd, grid.GetCellAt( cursorRow, cursorColumn ) ); } } else { countdown--; } - // Wait for vertical flyback. Then draw name and do animation. + // Wait for vertical flyback. Then do animation. gd->waitvblank(); FrameCounter++; - DrawName( gd, name ); Animate( gd ); } // Wait until player releases all controls before returning. @@ -190,7 +221,8 @@ /* DRAW THE SCREEN */ /*******************/ // Pass pointer to Gameduino to draw on in gd. -void HighScoreEntry::DrawScreen( Gameduino *gd ) { +// Pass player name in name. +void HighScoreEntry::DrawScreen( Gameduino *gd, PlayerName *name ) { gd->waitvblank(); // Clear the screen to zero characters. gd->fill( Gameduino::RAM_PIC, 0, RAM_PIC_SIZE ); @@ -206,8 +238,12 @@ gd->putstr( 2, 6, " TO MOVE THE CURSOR. PRESS THE LEFT BUTTON TO" ); gd->putstr( 2, 8, " ENTER EACH LETTER. MOVE CURSOR TO FOOT OF" ); gd->putstr( 2, 10, " SCREEN AND PRESS LEFT BUTTON WHEN FINISHED." ); + // Draw player's name. + DrawName( gd, name ); // Draw character grid. DrawGrid( gd ); + // Draw cursor. + DrawCursor( gd, grid.GetCellAt( cursorRow, cursorColumn ) ); } /***************************/ @@ -240,10 +276,10 @@ // Pass pointer to Gameduino to draw on in gd. // Pass player name in name. void HighScoreEntry::DrawName( Gameduino *gd, PlayerName *name ) { - gd->putstr( 21, 11, name->Name ); - UInt16 address = Gameduino::RAM_PIC + 12 * SCREEN_CHAR_WIDTH + 21; + gd->putstr( 23, 13, name->Name ); + UInt16 address = Gameduino::RAM_PIC + 14 * SCREEN_CHAR_WIDTH + 23; for( UInt8 i = 0; i < PlayerName::Length; ++i ) { - gd->wr( address, ( i == cursorPos ) ? ArrowUp : ' ' ); + gd->wr( address, ( i == charIndex ) ? ArrowUp : ' ' ); address++; } } @@ -254,3 +290,39 @@ // Pass pointer to Gameduino to display on in gd. void HighScoreEntry::Animate( Gameduino *gd ) { } + +/*******************/ +/* WIPE THE CURSOR */ +/*******************/ +// Pass pointer to Gameduino to display on in gd. +// Pass cell to draw in cell. +void HighScoreEntry::WipeCursor( Gameduino *gd, FieldCell *cell ) { + if( cell != (FieldCell*)NULL ) { + CharFrame::Wipe( gd, cell->Rect.X1, cell->Rect.Y1, cell->Rect.GetWidth(), cell->Rect.GetHeight() ); + } +} + +/*******************/ +/* DRAW THE CURSOR */ +/*******************/ +// Pass pointer to Gameduino to display on in gd. +// Pass cell to draw in cell. +void HighScoreEntry::DrawCursor( Gameduino *gd, FieldCell *cell ) { + if( cell != (FieldCell*)NULL ) { + CharFrame::Draw( gd, cell->Rect.X1, cell->Rect.Y1, cell->Rect.GetWidth(), cell->Rect.GetHeight() ); + } +} + +/**************************/ +/* VALIDATE CURSOR COLUMN */ +/**************************/ +// If cursor column is beyond end of row then forces it back. +void HighScoreEntry::ValidateCursorColumn( void ) { + FieldRow *row = grid.GetRow( cursorRow ); + if( row != (FieldRow*)NULL ) { + UInt8 columnCount = row->GetColumnCount(); + if( cursorColumn >= columnCount ) { + cursorColumn = columnCount - 1; + } + } +}