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
Revision 16:d0b142ba4362, committed 2013-06-15
- Comitter:
- RichardE
- Date:
- Sat Jun 15 19:27:36 2013 +0000
- Parent:
- 15:d8ea0c7b7e64
- Child:
- 17:194789db2215
- Commit message:
- Entering of high scores nearly there. Just requires code to allow you to backspace and confirm when you have finished.
Changed in this revision
--- a/CharFrame.cpp Sat Jun 15 15:05:19 2013 +0000 +++ b/CharFrame.cpp Sat Jun 15 19:27:36 2013 +0000 @@ -55,3 +55,35 @@ gd->wr( address, BottomRight ); } +/****************/ +/* WIPE A FRAME */ +/****************/ +// Pass Gameduino to draw on in gd. +// Pass x coordinate of top left in x. +// Pass y coordinate of top left in y. +// Pass width in w. +// Pass height in h. +void CharFrame::Wipe( Gameduino *gd, UInt8 x, UInt8 y, UInt8 w, UInt8 h ) { + // Calculate address for top left. + unsigned int rowStart = Gameduino::RAM_PIC + y * SCREEN_CHAR_WIDTH + x; + unsigned int address; + UInt8 count; + // Wipe top edge. + address = rowStart; + for( count = w; count > 0; --count ) { + gd->wr( address++, TransparentChar ); + } + // Wipe left and right edges. + address = rowStart + SCREEN_CHAR_WIDTH; + if( h > 2 ) { + for( count = h - 2; count > 0; --count ) { + gd->wr( address, TransparentChar ); + gd->wr( address + w - 1, TransparentChar ); + } + } + // Wipe bottom edge. + address = rowStart + SCREEN_CHAR_WIDTH * ( h - 1 ); + for( count = w; count > 0; --count ) { + gd->wr( address++, TransparentChar ); + } +}
--- a/CharFrame.h Sat Jun 15 15:05:19 2013 +0000 +++ b/CharFrame.h Sat Jun 15 19:27:36 2013 +0000 @@ -26,6 +26,16 @@ // Pass height in h. static void Draw( Gameduino *gd, UInt8 x, UInt8 y, UInt8 w, UInt8 h ); + /****************/ + /* WIPE A FRAME */ + /****************/ + // Pass Gameduino to draw on in gd. + // Pass x coordinate of top left in x. + // Pass y coordinate of top left in y. + // Pass width in w. + // Pass height in h. + static void Wipe( Gameduino *gd, UInt8 x, UInt8 y, UInt8 w, UInt8 h ); + }; #endif
--- a/FieldGrid.h Sat Jun 15 15:05:19 2013 +0000 +++ b/FieldGrid.h Sat Jun 15 19:27:36 2013 +0000 @@ -44,6 +44,22 @@ return rowCount; } + /*****************************************/ + /* GET CELL AT PARTICULAR ROW AND COLUMN */ + /*****************************************/ + // Pass row number in rowNum. + // Pass column number in columnNum. + // Returns pointer to cell or NULL if cell does not exist. + FieldCell *GetCellAt( UInt8 rowNum, UInt8 columnNum ) { + FieldRow *row = GetRow( rowNum ); + if( row != (FieldRow*)NULL ) { + return row->GetCellAt( columnNum ); + } + else { + return (FieldCell*)NULL; + } + } + private : // Pointer to array of FieldRow objects, one for each row in the grid.
--- a/FieldRow.h Sat Jun 15 15:05:19 2013 +0000 +++ b/FieldRow.h Sat Jun 15 19:27:36 2013 +0000 @@ -72,7 +72,21 @@ } return result; } - + + /********************************/ + /* GET NUMBER OF COLUMNS IN ROW */ + /********************************/ + // Returns number of columns in row. + UInt8 GetColumnCount( void ) { + UInt8 count = 0; + FieldCell *cell = GetFirstCell(); + while( cell != (FieldCell*)NULL ) { + count++; + cell = GetNextCell(); + } + return count; + } + private : // The root cell of the row.
--- 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; + } + } +}
--- a/HighScoreEntry.h Sat Jun 15 15:05:19 2013 +0000 +++ b/HighScoreEntry.h Sat Jun 15 19:27:36 2013 +0000 @@ -40,9 +40,12 @@ private : - // Position of cursor (zero for first character). - UInt8 cursorPos; - + // Index of character being modified in the name. + UInt8 charIndex; + + // Grid row and column number for cursor. + UInt8 cursorRow, cursorColumn; + // Grid around which cursor moves. FieldGrid grid; @@ -64,7 +67,8 @@ /* DRAW THE SCREEN */ /*******************/ // Pass pointer to Gameduino to display on in gd. - void DrawScreen( Gameduino *gd ); + // Pass player name in name. + void DrawScreen( Gameduino *gd, PlayerName *name ); /***************************/ /* DRAW THE CHARACTER GRID */ @@ -85,6 +89,26 @@ // Pass pointer to Gameduino to display on in gd. void Animate( Gameduino *gd ); + /*******************/ + /* WIPE THE CURSOR */ + /*******************/ + // Pass pointer to Gameduino to display on in gd. + // Pass cell to draw in cell. + void WipeCursor( Gameduino *gd, FieldCell *cell ); + + /*******************/ + /* DRAW THE CURSOR */ + /*******************/ + // Pass pointer to Gameduino to display on in gd. + // Pass cell to draw in cell. + void DrawCursor( Gameduino *gd, FieldCell *cell ); + + /**************************/ + /* VALIDATE CURSOR COLUMN */ + /**************************/ + // If cursor column is beyond end of row then forces it back. + void ValidateCursorColumn( void ); + }; #endif