This is a remake of tetris game for mbed. Please see detail here http://developer.mbed.org/users/sucrelv/notebook/tetris-game-on-mbed

Dependencies:   4DGL-uLCD-SE PinDetect SDFileSystem mbed-rtos mbed wave_player

Files at this revision

API Documentation at this revision

Comitter:
sucrelv
Date:
Tue Oct 21 15:10:36 2014 +0000
Commit message:
initial upload

Changed in this revision

4DGL-uLCD-SE.lib Show annotated file Show diff for this revision Revisions of this file
Board.cpp Show annotated file Show diff for this revision Revisions of this file
Board.h Show annotated file Show diff for this revision Revisions of this file
Game.cpp Show annotated file Show diff for this revision Revisions of this file
Game.h Show annotated file Show diff for this revision Revisions of this file
Pieces.cpp Show annotated file Show diff for this revision Revisions of this file
Pieces.h Show annotated file Show diff for this revision Revisions of this file
PinDetect.lib Show annotated file Show diff for this revision Revisions of this file
SDFileSystem.lib Show annotated file Show diff for this revision Revisions of this file
Shiftbrite/Shiftbrite.cpp Show annotated file Show diff for this revision Revisions of this file
Shiftbrite/Shiftbrite.h Show annotated file Show diff for this revision Revisions of this file
Speaker.h Show annotated file Show diff for this revision Revisions of this file
TextLCD/TextLCD.cpp Show annotated file Show diff for this revision Revisions of this file
TextLCD/TextLCD.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-rtos.lib Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
wave_player.lib Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/4DGL-uLCD-SE.lib	Tue Oct 21 15:10:36 2014 +0000
@@ -0,0 +1,1 @@
+https://mbed.org/users/4180_1/code/4DGL-uLCD-SE/#e39a44de229a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Board.cpp	Tue Oct 21 15:10:36 2014 +0000
@@ -0,0 +1,216 @@
+#include "Board.h"
+
+/*
+==================
+Init
+==================
+*/
+Board::Board (Pieces *pPieces, int pScreenHeight)
+{
+    // Get the screen height
+    mScreenHeight = pScreenHeight;
+
+    // Get the pointer to the pieces class
+    mPieces = pPieces;
+
+    //Init the board blocks with free positions
+    InitBoard();
+}
+
+
+/*
+======================================                                  
+Init the board blocks with free positions
+====================================== 
+*/
+void Board::InitBoard()
+{
+    for (int i = 0; i < BOARD_WIDTH; i++)
+        for (int j = 0; j < BOARD_HEIGHT; j++)
+            mBoard[i][j] = POS_FREE;
+}
+
+/* 
+======================================                                  
+Store a piece in the board by filling the blocks
+
+Parameters:
+
+>> pX:      Horizontal position in blocks
+>> pY:      Vertical position in blocks
+>> pPiece:  Piece to draw
+>> pRotation:   1 of the 4 possible rotations
+====================================== 
+*/
+void Board::StorePiece (int pX, int pY, int pPiece, int pRotation)
+{
+    // Store each block of the piece into the board
+    for (int i1 = pX, i2 = 0; i1 < pX + PIECE_BLOCKS; i1++, i2++)
+    {
+        for (int j1 = pY, j2 = 0; j1 < pY + PIECE_BLOCKS; j1++, j2++)
+        {   
+            // Store only the blocks of the piece that are not holes
+            if (mPieces->GetBlockType (pPiece, pRotation, j2, i2) != 0)     
+                mBoard[i1][j1] = POS_FILLED;    
+        }
+    }
+}
+
+
+/* 
+======================================                                  
+Check if the game is over becase a piece have achived the upper position
+
+Returns true or false
+====================================== 
+*/
+bool Board::IsGameOver()
+{
+    //If the first line has blocks, then, game over
+    for (int i = 0; i < BOARD_WIDTH; i++)
+    {
+        if (mBoard[i][0] == POS_FILLED) return true;
+    }
+
+    return false;
+}
+
+
+/* 
+======================================                                  
+Delete a line of the board by moving all above lines down
+
+Parameters:
+
+>> pY:      Vertical position in blocks of the line to delete
+====================================== 
+*/
+void Board::DeleteLine (int pY)
+{
+    // Moves all the upper lines one row down
+    for (int j = pY; j > 0; j--)
+    {
+        for (int i = 0; i < BOARD_WIDTH; i++)
+        {
+            mBoard[i][j] = mBoard[i][j-1];
+        }
+    }   
+}
+
+
+/* 
+======================================                                  
+Delete all the lines that should be removed
+====================================== 
+*/
+int Board::DeletePossibleLines ()
+{
+    int count =0;
+    for (int j = 0; j < BOARD_HEIGHT; j++)
+    {
+        int i = 0;
+        while (i < BOARD_WIDTH)
+        {
+            if (mBoard[i][j] != POS_FILLED) break;
+            i++;
+        }
+
+        if (i == BOARD_WIDTH) 
+        {
+            DeleteLine (j);
+            count++;
+        }
+    }
+    return count;
+}
+
+
+/* 
+======================================                                  
+Returns 1 (true) if the this block of the board is empty, 0 if it is filled
+
+Parameters:
+
+>> pX:      Horizontal position in blocks
+>> pY:      Vertical position in blocks
+====================================== 
+*/
+bool Board::IsFreeBlock (int pX, int pY)
+{
+    if (mBoard [pX][pY] == POS_FREE) return true; else return false;
+}
+
+
+/* 
+======================================                                  
+Returns the horizontal position (isn pixels) of the block given like parameter
+
+Parameters:
+
+>> pPos:    Horizontal position of the block in the board
+====================================== 
+*/
+int Board::GetXPosInPixels (int pPos)
+{
+    return  ( ( BOARD_POSITION - (BLOCK_SIZE * (BOARD_WIDTH / 2)) ) + (pPos * BLOCK_SIZE) );
+}
+
+
+/* 
+======================================                                  
+Returns the vertical position (in pixels) of the block given like parameter
+
+Parameters:
+
+>> pPos:    Horizontal position of the block in the board
+====================================== 
+*/
+int Board::GetYPosInPixels (int pPos)
+{
+    return ( (mScreenHeight - (BLOCK_SIZE * BOARD_HEIGHT)) + (pPos * BLOCK_SIZE) );
+}
+
+
+/* 
+======================================                                  
+Check if the piece can be stored at this position without any collision
+Returns true if the movement is  possible, false if it not possible
+
+Parameters:
+
+>> pX:      Horizontal position in blocks
+>> pY:      Vertical position in blocks
+>> pPiece:  Piece to draw
+>> pRotation:   1 of the 4 possible rotations
+====================================== 
+*/
+bool Board::IsPossibleMovement (int pX, int pY, int pPiece, int pRotation)
+{
+    // Checks collision with pieces already stored in the board or the board limits
+    // This is just to check the 5x5 blocks of a piece with the appropiate area in the board
+    for (int i1 = pX, i2 = 0; i1 < pX + PIECE_BLOCKS; i1++, i2++)
+    {
+        for (int j1 = pY, j2 = 0; j1 < pY + PIECE_BLOCKS; j1++, j2++)
+        {   
+            // Check if the piece is outside the limits of the board
+            if (    i1 < 0          || 
+                i1 > BOARD_WIDTH  - 1   ||
+                j1 > BOARD_HEIGHT - 1)
+            {
+                if (mPieces->GetBlockType (pPiece, pRotation, j2, i2) != 0)
+                    return 0;       
+            }
+
+            // Check if the piece have collisioned with a block already stored in the map
+            if (j1 >= 0)    
+            {
+                if ((mPieces->GetBlockType (pPiece, pRotation, j2, i2) != 0) &&
+                    (!IsFreeBlock (i1, j1)) )
+                    return false;
+            }
+        }
+    }
+
+    // No collision
+    return true;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Board.h	Tue Oct 21 15:10:36 2014 +0000
@@ -0,0 +1,49 @@
+#ifndef _BOARD_
+#define _BOARD_
+
+// ------ Includes -----
+
+#include "Pieces.h"
+
+// ------ Defines -----
+
+#define BOARD_LINE_WIDTH 6          // Width of each of the two lines that delimit the board
+#define BLOCK_SIZE 6              // Width and Height of each block of a piece
+#define BOARD_POSITION 50          // Center position of the board from the left of the screen
+#define BOARD_WIDTH 10              // Board width in blocks 
+#define BOARD_HEIGHT 20             // Board height in blocks
+#define MIN_VERTICAL_MARGIN 8      // Minimum vertical margin for the board limit      
+#define MIN_HORIZONTAL_MARGIN 20    // Minimum horizontal margin for the board limit
+#define PIECE_BLOCKS 5              // Number of horizontal and vertical blocks of a matrix piece
+
+
+// --------------------------------------------------------------------------------
+//                                   Board
+// --------------------------------------------------------------------------------
+
+class Board
+{
+public:
+
+    Board                       (Pieces *pPieces, int pScreenHeight);
+
+    int GetXPosInPixels         (int pPos);
+    int GetYPosInPixels         (int pPos);
+    bool IsFreeBlock            (int pX, int pY);
+    bool IsPossibleMovement     (int pX, int pY, int pPiece, int pRotation);
+    void StorePiece             (int pX, int pY, int pPiece, int pRotation);
+    int DeletePossibleLines    ();
+    bool IsGameOver             ();
+
+private:
+
+    enum { POS_FREE, POS_FILLED };          // POS_FREE = free position of the board; POS_FILLED = filled position of the board
+    int mBoard [BOARD_WIDTH][BOARD_HEIGHT]; // Board that contains the pieces
+    Pieces *mPieces;
+    int mScreenHeight;
+
+    void InitBoard();
+    void DeleteLine (int pY);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Game.cpp	Tue Oct 21 15:10:36 2014 +0000
@@ -0,0 +1,196 @@
+#include "Game.h"
+
+/* 
+======================================                                  
+Init
+====================================== 
+*/
+Game::Game(Board *pBoard, Pieces *pPieces, int pScreenHeight, uLCD_4DGL *pLCD,int initPiece,int initPos,int initNextPiece,int initNextPos) 
+{
+    mScreenHeight = pScreenHeight;
+    
+    // Get the pointer to the Board and Pieces classes
+    mBoard = pBoard;
+    mPieces = pPieces;
+    uLCD = pLCD;
+    // Game initialization
+    InitGame (initPiece,initPos,initNextPiece,initNextPos);
+}
+
+
+
+/* 
+======================================                                  
+Initial parameters of the game
+====================================== 
+*/
+void Game::InitGame(int initPiece,int initPos,int initNextPiece,int initNextPos)
+{
+    //points
+    points = 0;
+    clearedLineCount=0;
+
+    // First piece
+    mPiece          = initPiece;
+    mRotation       = initPos;
+    mPosX           = (BOARD_WIDTH / 2) + mPieces->GetXInitialPosition (mPiece, mRotation);
+    mPosY           = mPieces->GetYInitialPosition (mPiece, mRotation);
+
+    //  Next piece
+    mNextPiece      = initNextPiece;
+    mNextRotation   = initNextPos;
+    mNextPosX       = BOARD_WIDTH + 2;
+    mNextPosY       = 2;    
+}
+
+
+/* 
+======================================                                  
+Create a random piece
+====================================== 
+*/
+void Game::CreateNewPiece(int piece,int pos)
+{
+    // The new piece
+    mPiece          = mNextPiece;
+    mRotation       = mNextRotation;
+    mPosX           = (BOARD_WIDTH / 2) + mPieces->GetXInitialPosition (mPiece, mRotation);
+    mPosY           = mPieces->GetYInitialPosition (mPiece, mRotation);
+
+    // Random next piece
+    mNextPiece      = piece;
+    mNextRotation   = pos;
+}
+
+
+/* 
+======================================                                  
+Draw piece
+
+Parameters:
+
+>> pX:      Horizontal position in blocks
+>> pY:      Vertical position in blocks
+>> pPiece:  Piece to draw
+>> pRotation:   1 of the 4 possible rotations
+====================================== 
+*/
+void Game::DrawPiece (int pX, int pY, int pPiece, int pRotation, int colorIndex)
+{
+    // Obtain the position in pixel in the screen of the block we want to draw
+    int mPixelsX = mBoard->GetXPosInPixels (pX);
+    int mPixelsY = mBoard->GetYPosInPixels (pY);
+    int mColors [7]={16711680, 15955765, 16761893, 45401, 44763, 12462572, 29669};
+    // Travel the matrix of blocks of the piece and draw the blocks that are filled
+    for (int i = 0; i < PIECE_BLOCKS; i++)
+    {
+        for (int j = 0; j < PIECE_BLOCKS; j++)
+        {
+            if (mPieces->GetBlockType (pPiece, pRotation, j, i) != 0)
+                uLCD->filled_rectangle  (mPixelsX + i * BLOCK_SIZE, 
+                                    mPixelsY + j * BLOCK_SIZE, 
+                                    (mPixelsX + i * BLOCK_SIZE) + BLOCK_SIZE - 1, 
+                                    (mPixelsY + j * BLOCK_SIZE) + BLOCK_SIZE - 1, 
+                                    mColors[colorIndex]);
+        }
+    }
+}
+
+
+/* 
+======================================                                  
+Draw board
+
+Draw the two lines that delimit the board
+====================================== 
+*/
+void Game::DrawBoard ()
+{
+    // Calculate the limits of the board in pixels  
+    int mX1 = BOARD_POSITION - (BLOCK_SIZE * (BOARD_WIDTH / 2)) - 1;
+    int mX2 = BOARD_POSITION + (BLOCK_SIZE * (BOARD_WIDTH / 2));
+    int mY = mScreenHeight - (BLOCK_SIZE * BOARD_HEIGHT);
+    
+    // Check that the vertical margin is not to small
+    //assert (mY > MIN_VERTICAL_MARGIN);
+
+    // Rectangles that delimits the board
+    uLCD->filled_rectangle (mX1 - BOARD_LINE_WIDTH, mY, mX1, mScreenHeight - 1, BLUE);
+    uLCD->filled_rectangle (mX2, mY, mX2 + BOARD_LINE_WIDTH, mScreenHeight - 1, BLUE);
+    
+    // Check that the horizontal margin is not to small
+    //assert (mX1 > MIN_HORIZONTAL_MARGIN);
+
+    // Drawing the blocks that are already stored in the board
+    mX1 += 1;
+    for (int i = 0; i < BOARD_WIDTH; i++)
+    {
+        for (int j = 0; j < BOARD_HEIGHT; j++)
+        {   
+            // Check if the block is filled, if so, draw it
+            if (!mBoard->IsFreeBlock(i, j)) 
+                uLCD->filled_rectangle (    mX1 + i * BLOCK_SIZE, 
+                                        mY + j * BLOCK_SIZE, 
+                                        (mX1 + i * BLOCK_SIZE) + BLOCK_SIZE - 1, 
+                                        (mY + j * BLOCK_SIZE) + BLOCK_SIZE - 1, 
+                                        10066329);
+        }
+    }   
+}
+
+
+/* 
+======================================                                  
+Draw scene
+
+Draw all the objects of the scene
+====================================== 
+*/
+void Game::DrawScene ()
+{
+    DrawBoard();
+    DrawPiece (mPosX, mPosY, mPiece, mRotation, mPiece);                    // Draw the playing piece
+    DrawPiece (mNextPosX, mNextPosY, mNextPiece, mNextRotation, mNextPiece);    // Draw the next piece
+}
+
+void Game::ErasePiece (int pX, int pY, int pPiece, int pRotation)
+{
+    if(pPiece==-1) return;
+    // Obtain the position in pixel in the screen of the block we want to draw
+    int mPixelsX = mBoard->GetXPosInPixels (pX);
+    int mPixelsY = mBoard->GetYPosInPixels (pY);
+
+    // Travel the matrix of blocks of the piece and draw the blocks that are filled
+    for (int i = 0; i < PIECE_BLOCKS; i++)
+    {
+        for (int j = 0; j < PIECE_BLOCKS; j++)
+        {
+            if (mPieces->GetBlockType (pPiece, pRotation, j, i) != 0)
+                uLCD->filled_rectangle  (mPixelsX + i * BLOCK_SIZE, 
+                                    mPixelsY + j * BLOCK_SIZE, 
+                                    (mPixelsX + i * BLOCK_SIZE) + BLOCK_SIZE - 1, 
+                                    (mPixelsY + j * BLOCK_SIZE) + BLOCK_SIZE - 1, 
+                                    0);
+        }
+    }
+}
+
+void Game::AddPoints(int newGain)
+{
+    points+=newGain;
+}
+
+void Game::AddClearedLines(int newGain)
+{
+    clearedLineCount+=newGain;
+}
+
+int Game::GetPoints()
+{
+    return points;
+}
+
+int Game::GetClearedLines()
+{
+    return clearedLineCount;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Game.h	Tue Oct 21 15:10:36 2014 +0000
@@ -0,0 +1,56 @@
+#ifndef _GAME_
+#define _GAME_
+
+// ------ Includes -----
+
+#include "Board.h"
+#include "Pieces.h"
+#include "uLCD_4DGL.h"
+
+// ------ Defines -----
+
+#define WAIT_TIME 500           // Number of milliseconds that the piece remains before going 1 block down */ 
+
+
+// --------------------------------------------------------------------------------
+//                                   Game
+// --------------------------------------------------------------------------------
+
+class Game
+{
+public:
+
+    Game (Board *pBoard, Pieces *pPieces, int pScreenHeight, uLCD_4DGL *uLCD,int,int,int,int);
+
+    void DrawScene ();
+    void CreateNewPiece (int,int);
+    void ErasePiece(int x,int y,int piece, int rotation);
+    void DrawBoard ();
+    void AddPoints(int);
+    void AddClearedLines(int);
+    int GetPoints();
+    int GetClearedLines();
+    
+    int mPosX, mPosY;               // Position of the piece that is falling down
+    int mPiece, mRotation;          // Kind and rotation the piece that is falling down
+    int points;
+    int clearedLineCount;
+    
+
+private:
+
+    int mScreenHeight;              // Screen height in pixels
+    int mNextPosX, mNextPosY;       // Position of the next piece
+    int mNextPiece, mNextRotation;  // Kind and rotation of the next piece
+    
+    Board *mBoard;
+    Pieces *mPieces;
+    uLCD_4DGL *uLCD;
+
+    
+    void InitGame(int,int,int,int);
+    void DrawPiece (int pX, int pY, int pPiece, int pRotation, int colorIndex);
+    
+};
+
+#endif // _GAME_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Pieces.cpp	Tue Oct 21 15:10:36 2014 +0000
@@ -0,0 +1,332 @@
+#include "Pieces.h"
+
+// Pieces definition
+char mPieces [7 /*kind */ ][4 /* rotation */ ][5 /* horizontal blocks */ ][5 /* vertical blocks */ ] =
+{
+// Square
+  {
+   {
+    {0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0},
+    {0, 0, 2, 1, 0},
+    {0, 0, 1, 1, 0},
+    {0, 0, 0, 0, 0}
+    },
+   {
+    {0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0},
+    {0, 0, 2, 1, 0},
+    {0, 0, 1, 1, 0},
+    {0, 0, 0, 0, 0}
+    },
+   {
+    {0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0},
+    {0, 0, 2, 1, 0},
+    {0, 0, 1, 1, 0},
+    {0, 0, 0, 0, 0}
+    },
+   {
+    {0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0},
+    {0, 0, 2, 1, 0},
+    {0, 0, 1, 1, 0},
+    {0, 0, 0, 0, 0}
+    }
+   },
+
+// I
+  {
+   {
+    {0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0},
+    {0, 1, 2, 1, 1},
+    {0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0}
+    },
+   {
+    {0, 0, 0, 0, 0},
+    {0, 0, 1, 0, 0}, 
+    {0, 0, 2, 0, 0},
+    {0, 0, 1, 0, 0},
+    {0, 0, 1, 0, 0}
+    },
+   {
+    {0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0},
+    {1, 1, 2, 1, 0},
+    {0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0}
+    },
+   {
+    {0, 0, 1, 0, 0},
+    {0, 0, 1, 0, 0},
+    {0, 0, 2, 0, 0},
+    {0, 0, 1, 0, 0},
+    {0, 0, 0, 0, 0}
+    }
+   }
+  ,
+// L
+  {
+   {
+    {0, 0, 0, 0, 0},
+    {0, 0, 1, 0, 0},
+    {0, 0, 2, 0, 0},
+    {0, 0, 1, 1, 0},
+    {0, 0, 0, 0, 0}
+    },
+   {
+    {0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0},
+    {0, 1, 2, 1, 0},
+    {0, 1, 0, 0, 0},
+    {0, 0, 0, 0, 0}
+    },
+   {
+    {0, 0, 0, 0, 0},
+    {0, 1, 1, 0, 0},
+    {0, 0, 2, 0, 0},
+    {0, 0, 1, 0, 0},
+    {0, 0, 0, 0, 0}
+    },
+   {
+    {0, 0, 0, 0, 0},
+    {0, 0, 0, 1, 0},
+    {0, 1, 2, 1, 0},
+    {0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0}
+    }
+   },
+// L mirrored
+  {
+   {
+    {0, 0, 0, 0, 0},
+    {0, 0, 1, 0, 0},
+    {0, 0, 2, 0, 0},
+    {0, 1, 1, 0, 0},
+    {0, 0, 0, 0, 0}
+    },
+   {
+    {0, 0, 0, 0, 0},
+    {0, 1, 0, 0, 0},
+    {0, 1, 2, 1, 0},
+    {0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0}
+    },
+   {
+    {0, 0, 0, 0, 0},
+    {0, 0, 1, 1, 0},
+    {0, 0, 2, 0, 0},
+    {0, 0, 1, 0, 0},
+    {0, 0, 0, 0, 0}
+    },
+   {
+    {0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0},
+    {0, 1, 2, 1, 0},
+    {0, 0, 0, 1, 0},
+    {0, 0, 0, 0, 0}
+    }
+   },
+// N
+  {
+   {
+    {0, 0, 0, 0, 0},
+    {0, 0, 0, 1, 0},
+    {0, 0, 2, 1, 0},
+    {0, 0, 1, 0, 0},
+    {0, 0, 0, 0, 0}
+    },
+   {
+    {0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0},
+    {0, 1, 2, 0, 0},
+    {0, 0, 1, 1, 0},
+    {0, 0, 0, 0, 0}
+    },
+   {
+    {0, 0, 0, 0, 0},
+    {0, 0, 1, 0, 0},
+    {0, 1, 2, 0, 0},
+    {0, 1, 0, 0, 0},
+    {0, 0, 0, 0, 0}
+    },
+   {
+    {0, 0, 0, 0, 0},
+    {0, 1, 1, 0, 0},
+    {0, 0, 2, 1, 0},
+    {0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0}
+    }
+   },
+// N mirrored
+  {
+   {
+    {0, 0, 0, 0, 0},
+    {0, 0, 1, 0, 0},
+    {0, 0, 2, 1, 0},
+    {0, 0, 0, 1, 0},
+    {0, 0, 0, 0, 0}
+    },
+   {
+    {0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0},
+    {0, 0, 2, 1, 0},
+    {0, 1, 1, 0, 0},
+    {0, 0, 0, 0, 0}
+    },
+   {
+    {0, 0, 0, 0, 0},
+    {0, 1, 0, 0, 0},
+    {0, 1, 2, 0, 0},
+    {0, 0, 1, 0, 0},
+    {0, 0, 0, 0, 0}
+    },
+   {
+    {0, 0, 0, 0, 0},
+    {0, 0, 1, 1, 0},
+    {0, 1, 2, 0, 0},
+    {0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0}
+    }
+   },
+// T
+  {
+   {
+    {0, 0, 0, 0, 0},
+    {0, 0, 1, 0, 0},
+    {0, 0, 2, 1, 0},
+    {0, 0, 1, 0, 0},
+    {0, 0, 0, 0, 0}
+    },
+   {
+    {0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0},
+    {0, 1, 2, 1, 0},
+    {0, 0, 1, 0, 0},
+    {0, 0, 0, 0, 0}
+    },
+   {
+    {0, 0, 0, 0, 0},
+    {0, 0, 1, 0, 0},
+    {0, 1, 2, 0, 0},
+    {0, 0, 1, 0, 0},
+    {0, 0, 0, 0, 0}
+    },
+   {
+    {0, 0, 0, 0, 0},
+    {0, 0, 1, 0, 0},
+    {0, 1, 2, 1, 0},
+    {0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0}
+    }
+   }
+};
+
+
+// Displacement of the piece to the position where it is first drawn in the board when it is created
+int mPiecesInitialPosition  [7 /*kind */ ][4 /* rotation */ ][2 /* position */] =
+{
+/* Square */
+  {
+    {-2, -3}, 
+    {-2, -3},
+    {-2, -3},
+    {-2, -3}
+   },
+/* I */
+  {
+    {-2, -2},
+    {-2, -3},
+    {-2, -2},
+    {-2, -3}
+   },
+/* L */
+  {
+    {-2, -3},
+    {-2, -3},
+    {-2, -3},
+    {-2, -2}
+   },
+/* L mirrored */
+  {
+    {-2, -3},
+    {-2, -2},
+    {-2, -3},
+    {-2, -3}
+   },
+/* N */
+  {
+    {-2, -3},
+    {-2, -3},
+    {-2, -3},
+    {-2, -2}
+   },
+/* N mirrored */
+  {
+    {-2, -3},
+    {-2, -3},
+    {-2, -3},
+    {-2, -2}
+   },
+/* T */
+  {
+    {-2, -3},
+    {-2, -3},
+    {-2, -3},
+    {-2, -2}
+   },
+};
+
+
+/* 
+======================================                                  
+Return the type of a block (0 = no-block, 1 = normal block, 2 = pivot block)
+
+Parameters:
+
+>> pPiece:      Piece to draw
+>> pRotation:   1 of the 4 possible rotations
+>> pX:          Horizontal position in blocks
+>> pY:          Vertical position in blocks
+====================================== 
+*/
+int Pieces::GetBlockType (int pPiece, int pRotation, int pX, int pY)
+{
+    return mPieces [pPiece][pRotation][pX][pY];
+}
+
+
+/* 
+======================================                                  
+Returns the horizontal displacement of the piece that has to be applied in order to create it in the
+correct position.
+
+Parameters:
+
+>> pPiece:  Piece to draw
+>> pRotation:   1 of the 4 possible rotations
+====================================== 
+*/
+int Pieces::GetXInitialPosition (int pPiece, int pRotation)
+{
+    return mPiecesInitialPosition [pPiece][pRotation][0];
+}
+
+
+/* 
+======================================                                  
+Returns the vertical displacement of the piece that has to be applied in order to create it in the
+correct position.
+
+Parameters:
+
+>> pPiece:  Piece to draw
+>> pRotation:   1 of the 4 possible rotations
+====================================== 
+*/
+int Pieces::GetYInitialPosition (int pPiece, int pRotation)
+{
+    return mPiecesInitialPosition [pPiece][pRotation][1];
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Pieces.h	Tue Oct 21 15:10:36 2014 +0000
@@ -0,0 +1,12 @@
+#ifndef _PIECES_
+#define _PIECES_
+class Pieces
+{
+public:
+
+    int GetBlockType        (int pPiece, int pRotation, int pX, int pY);
+    int GetXInitialPosition (int pPiece, int pRotation);
+    int GetYInitialPosition (int pPiece, int pRotation);
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PinDetect.lib	Tue Oct 21 15:10:36 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/AjK/code/PinDetect/#cb3afc45028b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SDFileSystem.lib	Tue Oct 21 15:10:36 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/SDFileSystem/#c8f66dc765d4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Shiftbrite/Shiftbrite.cpp	Tue Oct 21 15:10:36 2014 +0000
@@ -0,0 +1,30 @@
+#include "mbed.h"
+#include "Shiftbrite.h"
+
+
+
+
+Shiftbrite::Shiftbrite(PinName pin_e, PinName pin_l, PinName pin_do,PinName pin_di, PinName pin_clk): _pin_e(pin_e), _pin_l(pin_l), _spi(pin_do, pin_di, pin_clk)
+{
+   SPI _spi(pin_do, pin_di, pin_clk);
+   _pin_l=0;
+   _pin_e=0;
+    _spi.format(16,0);
+    _spi.frequency(500000);
+}
+
+
+void Shiftbrite::RGB(int red, int green, int blue){
+
+    unsigned int low_color=0;
+    unsigned int high_color=0;
+    high_color=(blue<<4)|((red&0x3C0)>>6);
+    low_color=(((red&0x3F)<<10)|(green));
+    _spi.write(high_color);
+    _spi.write(low_color);
+    _pin_l=1;
+    _pin_l=0;
+    
+    }
+    
+    
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Shiftbrite/Shiftbrite.h	Tue Oct 21 15:10:36 2014 +0000
@@ -0,0 +1,16 @@
+#include "mbed.h"
+
+
+class Shiftbrite{
+public:
+    Shiftbrite(PinName pin_e, PinName pin_l, PinName pin_do,PinName pin_di, PinName pin_clk);
+    void RGB(int red, int green, int blue);
+    
+    
+ private:
+    DigitalOut _pin_e;
+    DigitalOut _pin_l;
+    SPI _spi;
+    
+    
+    };
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Speaker.h	Tue Oct 21 15:10:36 2014 +0000
@@ -0,0 +1,19 @@
+#include "mbed.h"
+// new class to play a note on Speaker based on PwmOut class
+class Speaker
+{
+public:
+    Speaker(PinName pin) : _pin(pin) {
+// _pin(pin) means pass pin to the Speaker Constructor
+    }
+// class method to play a note based on PwmOut class
+    void PlayNote(float frequency, float duration, float volume) {
+        _pin.period(1.0/frequency);
+        _pin = volume/2.0;
+        wait(duration);
+        _pin = 0.0;
+    }
+
+private:
+    PwmOut _pin;
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TextLCD/TextLCD.cpp	Tue Oct 21 15:10:36 2014 +0000
@@ -0,0 +1,159 @@
+/* mbed TextLCD Library, for a 4-bit LCD based on HD44780
+ * Copyright (c) 2007-2010, sford, http://mbed.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "TextLCD.h"
+#include "mbed.h"
+
+TextLCD::TextLCD(PinName rs, PinName e, PinName d4, PinName d5,
+                 PinName d6, PinName d7, LCDType type) : _rs(rs),
+        _e(e), _d(d4, d5, d6, d7),
+        _type(type) {
+
+    _e  = 1;
+    _rs = 0;            // command mode
+
+    wait(0.015);        // Wait 15ms to ensure powered up
+
+    // send "Display Settings" 3 times (Only top nibble of 0x30 as we've got 4-bit bus)
+    for (int i=0; i<3; i++) {
+        writeByte(0x3);
+        wait(0.00164);  // this command takes 1.64ms, so wait for it
+    }
+    writeByte(0x2);     // 4-bit mode
+    wait(0.000040f);    // most instructions take 40us
+
+    writeCommand(0x28); // Function set 001 BW N F - -
+    writeCommand(0x0C);
+    writeCommand(0x6);  // Cursor Direction and Display Shift : 0000 01 CD S (CD 0-left, 1-right S(hift) 0-no, 1-yes
+    cls();
+}
+
+void TextLCD::character(int column, int row, int c) {
+    int a = address(column, row);
+    writeCommand(a);
+    writeData(c);
+}
+
+void TextLCD::cls() {
+    writeCommand(0x01); // cls, and set cursor to 0
+    wait(0.00164f);     // This command takes 1.64 ms
+    locate(0, 0);
+}
+
+void TextLCD::locate(int column, int row) {
+    _column = column;
+    _row = row;
+}
+
+int TextLCD::_putc(int value) {
+    if (value == '\n') {
+        _column = 0;
+        _row++;
+        if (_row >= rows()) {
+            _row = 0;
+        }
+    } else {
+        character(_column, _row, value);
+        _column++;
+        if (_column >= columns()) {
+            _column = 0;
+            _row++;
+            if (_row >= rows()) {
+                _row = 0;
+            }
+        }
+    }
+    return value;
+}
+
+int TextLCD::_getc() {
+    return -1;
+}
+
+void TextLCD::writeByte(int value) {
+    _d = value >> 4;
+    wait(0.000040f); // most instructions take 40us
+    _e = 0;
+    wait(0.000040f);
+    _e = 1;
+    _d = value >> 0;
+    wait(0.000040f);
+    _e = 0;
+    wait(0.000040f);  // most instructions take 40us
+    _e = 1;
+}
+
+void TextLCD::writeCommand(int command) {
+    _rs = 0;
+    writeByte(command);
+}
+
+void TextLCD::writeData(int data) {
+    _rs = 1;
+    writeByte(data);
+}
+
+int TextLCD::address(int column, int row) {
+    switch (_type) {
+        case LCD20x4:
+            switch (row) {
+                case 0:
+                    return 0x80 + column;
+                case 1:
+                    return 0xc0 + column;
+                case 2:
+                    return 0x94 + column;
+                case 3:
+                    return 0xd4 + column;
+            }
+        case LCD16x2B:
+            return 0x80 + (row * 40) + column;
+        case LCD16x2:
+        case LCD20x2:
+        default:
+            return 0x80 + (row * 0x40) + column;
+    }
+}
+
+int TextLCD::columns() {
+    switch (_type) {
+        case LCD20x4:
+        case LCD20x2:
+            return 20;
+        case LCD16x2:
+        case LCD16x2B:
+        default:
+            return 16;
+    }
+}
+
+int TextLCD::rows() {
+    switch (_type) {
+        case LCD20x4:
+            return 4;
+        case LCD16x2:
+        case LCD16x2B:
+        case LCD20x2:
+        default:
+            return 2;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TextLCD/TextLCD.h	Tue Oct 21 15:10:36 2014 +0000
@@ -0,0 +1,111 @@
+/* mbed TextLCD Library, for a 4-bit LCD based on HD44780
+ * Copyright (c) 2007-2010, sford, http://mbed.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MBED_TEXTLCD_H
+#define MBED_TEXTLCD_H
+
+#include "mbed.h"
+
+/** A TextLCD interface for driving 4-bit HD44780-based LCDs
+ *
+ * Currently supports 16x2, 20x2 and 20x4 panels
+ *
+ * @code
+ * #include "mbed.h"
+ * #include "TextLCD.h"
+ * 
+ * TextLCD lcd(p10, p12, p15, p16, p29, p30); // rs, e, d4-d7
+ * 
+ * int main() {
+ *     lcd.printf("Hello World!\n");
+ * }
+ * @endcode
+ */
+class TextLCD : public Stream {
+public:
+
+    /** LCD panel format */
+    enum LCDType {
+        LCD16x2     /**< 16x2 LCD panel (default) */
+        , LCD16x2B  /**< 16x2 LCD panel alternate addressing */
+        , LCD20x2   /**< 20x2 LCD panel */
+        , LCD20x4   /**< 20x4 LCD panel */
+    };
+
+    /** Create a TextLCD interface
+     *
+     * @param rs    Instruction/data control line
+     * @param e     Enable line (clock)
+     * @param d4-d7 Data lines for using as a 4-bit interface
+     * @param type  Sets the panel size/addressing mode (default = LCD16x2)
+     */
+    TextLCD(PinName rs, PinName e, PinName d4, PinName d5, PinName d6, PinName d7, LCDType type = LCD16x2);
+
+#if DOXYGEN_ONLY
+    /** Write a character to the LCD
+     *
+     * @param c The character to write to the display
+     */
+    int putc(int c);
+
+    /** Write a formated string to the LCD
+     *
+     * @param format A printf-style format string, followed by the
+     *               variables to use in formating the string.
+     */
+    int printf(const char* format, ...);
+#endif
+
+    /** Locate to a screen column and row
+     *
+     * @param column  The horizontal position from the left, indexed from 0
+     * @param row     The vertical position from the top, indexed from 0
+     */
+    void locate(int column, int row);
+
+    /** Clear the screen and locate to 0,0 */
+    void cls();
+
+    int rows();
+    int columns();
+
+protected:
+
+    // Stream implementation functions
+    virtual int _putc(int value);
+    virtual int _getc();
+
+    int address(int column, int row);
+    void character(int column, int row, int c);
+    void writeByte(int value);
+    void writeCommand(int command);
+    void writeData(int data);
+
+    DigitalOut _rs, _e;
+    BusOut _d;
+    LCDType _type;
+
+    int _column;
+    int _row;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Oct 21 15:10:36 2014 +0000
@@ -0,0 +1,480 @@
+#include "mbed.h"
+#include "Game.h"
+#include "PinDetect.h"
+#include "Speaker.h"
+#include "TextLCD.h"
+#include "Shiftbrite.h"
+#include "SDFileSystem.h"
+#include "wave_player.h"
+#include "rtos.h"
+
+uLCD_4DGL uLCD(p28, p27, p29);
+TextLCD textLCD(p26, p25, p24, p23, p22, p15); 
+Speaker mySpeaker(p21);
+Shiftbrite myShiftbrite(p9, p10, p11, p12, p13);
+SDFileSystem sd(p5, p6, p7, p8, "sd"); //SD card
+Serial pc(USBTX, USBRX);
+
+PinDetect LEFT_KEY(p16);
+PinDetect RIGHT_KEY(p19);
+PinDetect ROTATE_KEY(p17);
+PinDetect DOWN_KEY(p30);
+
+int SinglePiecePoints = 50;
+int LineClearPoints = 200;
+int key_input = 0;
+bool gameStarted = false;
+void input_left()
+{
+    if(!gameStarted)
+    {   gameStarted=true;
+        return;
+    }
+    key_input = 1;
+    mySpeaker.PlayNote(400.0,0.05,0.025);
+    mySpeaker.PlayNote(500.0,0.05,0.025);
+}
+
+void input_right()
+{
+    if(!gameStarted)
+    {   gameStarted=true;
+        return;
+    }
+    key_input = 2;
+    mySpeaker.PlayNote(400.0,0.05,0.025);
+    mySpeaker.PlayNote(500.0,0.05,0.025);
+}
+
+void input_rotate()
+{
+    if(!gameStarted)
+    {   gameStarted=true;
+        return;
+    }
+    key_input = 3;
+    mySpeaker.PlayNote(600.0,0.05,0.025);
+    mySpeaker.PlayNote(700.0,0.05,0.025);
+    mySpeaker.PlayNote(800.0,0.05,0.025);
+    mySpeaker.PlayNote(900.0,0.05,0.025);
+}
+
+void input_down()
+{
+    if(!gameStarted)
+    {   gameStarted=true;
+        return;
+    }
+    key_input=4;
+    mySpeaker.PlayNote(500.0,0.05,0.025);
+    mySpeaker.PlayNote(1500.0,0.05,0.025);
+    mySpeaker.PlayNote(500.0,0.05,0.025);
+    mySpeaker.PlayNote(1500.0,0.05,0.025);
+}
+
+void clear_board()
+{
+    uLCD.filled_rectangle(20,0,79,128,0);
+}
+
+void clear_next_piece()
+{
+    uLCD.filled_rectangle(92,20,122,50,0);
+}
+
+void UpdateGameStatus(int points,int lines)
+{
+    textLCD.locate(7,0);
+    textLCD.printf("%d",points);
+    textLCD.locate(13,1);
+    textLCD.printf("%d",lines);
+}
+
+void FlashLight(void const *args)
+{
+    myShiftbrite.RGB(0,0,0);
+    myShiftbrite.RGB(0,0,0);
+        
+    myShiftbrite.RGB(0,0,42);
+    myShiftbrite.RGB(0,0,42);
+    Thread::wait(100);
+        
+        
+    myShiftbrite.RGB(0,0,0);
+    myShiftbrite.RGB(0,42,0);
+    Thread::wait(100);
+        
+    myShiftbrite.RGB(0,0,42);
+    myShiftbrite.RGB(0,0,42);
+    Thread::wait(100);
+        
+    myShiftbrite.RGB(0,0,0);
+    myShiftbrite.RGB(0,0,0);    
+}
+
+void GameOverLight(void const *args)
+{
+    
+    myShiftbrite.RGB(0,0,0);
+    myShiftbrite.RGB(0,0,0);
+        
+    myShiftbrite.RGB(0,0,200);
+    Thread::wait(100);
+    myShiftbrite.RGB(0,0,0);
+    Thread::wait(100);
+    myShiftbrite.RGB(0,0,200);
+    Thread::wait(100);
+    myShiftbrite.RGB(0,0,0);  
+    Thread::wait(100);
+    myShiftbrite.RGB(0,0,200);
+    Thread::wait(100); 
+    myShiftbrite.RGB(0,0,0);  
+    Thread::wait(100); 
+    myShiftbrite.RGB(0,0,200);
+    Thread::wait(100);
+    myShiftbrite.RGB(0,0,0);  
+    Thread::wait(100);
+    myShiftbrite.RGB(0,0,200);
+    Thread::wait(100); 
+    myShiftbrite.RGB(0,0,0);
+    Thread::wait(100); 
+    myShiftbrite.RGB(0,0,200);
+    Thread::wait(100);
+    myShiftbrite.RGB(0,0,0);
+    Thread::wait(100);
+    myShiftbrite.RGB(0,0,200);
+    Thread::wait(100);
+    myShiftbrite.RGB(0,0,0);  
+    Thread::wait(100);
+    myShiftbrite.RGB(0,0,200);
+    Thread::wait(100); 
+    myShiftbrite.RGB(0,0,0);  
+    Thread::wait(100); 
+    myShiftbrite.RGB(0,0,200);
+    Thread::wait(100);
+    myShiftbrite.RGB(0,0,0);  
+    Thread::wait(100);
+    myShiftbrite.RGB(0,0,200);
+    Thread::wait(100); 
+    myShiftbrite.RGB(0,0,0); 
+}
+
+void GameStartLight(void const *args)
+{
+    
+    myShiftbrite.RGB(0,0,0);
+    myShiftbrite.RGB(0,0,0);
+        
+    myShiftbrite.RGB(0,200,0);
+    Thread::wait(100);
+    myShiftbrite.RGB(0,0,0);
+    myShiftbrite.RGB(0,0,0);
+    Thread::wait(100);
+    myShiftbrite.RGB(0,200,0);
+    Thread::wait(100);
+    myShiftbrite.RGB(0,0,0); 
+    myShiftbrite.RGB(0,0,0); 
+    Thread::wait(100);
+    myShiftbrite.RGB(0,200,0);
+    Thread::wait(100); 
+    myShiftbrite.RGB(0,0,0); 
+    myShiftbrite.RGB(0,0,0); 
+    Thread::wait(100); 
+    myShiftbrite.RGB(0,200,0);
+    Thread::wait(100);
+    myShiftbrite.RGB(0,0,0);  
+    myShiftbrite.RGB(0,0,0);
+    Thread::wait(100);
+    myShiftbrite.RGB(0,200,0);
+    Thread::wait(100); 
+    myShiftbrite.RGB(0,0,0);
+    myShiftbrite.RGB(0,0,0);
+    
+}
+
+void PlayStartSound()
+{
+    mySpeaker.PlayNote(500.0,0.05,0.025);
+    mySpeaker.PlayNote(600.0,0.05,0.025);
+    mySpeaker.PlayNote(700.0,0.05,0.025);
+    mySpeaker.PlayNote(800.0,0.05,0.025);
+    mySpeaker.PlayNote(900.0,0.05,0.025);
+    mySpeaker.PlayNote(1000.0,0.05,0.025);
+    mySpeaker.PlayNote(1100.0,0.05,0.025);
+    mySpeaker.PlayNote(1200.0,0.05,0.025);
+    mySpeaker.PlayNote(600.0,0.05,0.025);
+    mySpeaker.PlayNote(700.0,0.05,0.025);
+    mySpeaker.PlayNote(800.0,0.05,0.025);
+    mySpeaker.PlayNote(900.0,0.05,0.025);
+    mySpeaker.PlayNote(1000.0,0.05,0.025);
+    mySpeaker.PlayNote(1100.0,0.05,0.025);
+    mySpeaker.PlayNote(1200.0,0.05,0.025);
+    mySpeaker.PlayNote(1300.0,0.05,0.025);
+    mySpeaker.PlayNote(700.0,0.05,0.025);
+    mySpeaker.PlayNote(800.0,0.05,0.025);
+    mySpeaker.PlayNote(900.0,0.05,0.025);
+    mySpeaker.PlayNote(1000.0,0.05,0.025);
+    mySpeaker.PlayNote(1100.0,0.05,0.025);
+    mySpeaker.PlayNote(1200.0,0.05,0.025);
+    mySpeaker.PlayNote(1300.0,0.05,0.025);
+    mySpeaker.PlayNote(1400.0,0.05,0.025);
+}
+
+void PlayOverSound()
+{
+    mySpeaker.PlayNote(1400.0,0.05,0.025);
+    mySpeaker.PlayNote(1300.0,0.05,0.025);
+    mySpeaker.PlayNote(1200.0,0.05,0.025);
+    mySpeaker.PlayNote(1100.0,0.05,0.025);
+    mySpeaker.PlayNote(1000.0,0.05,0.025);
+    mySpeaker.PlayNote(900.0,0.05,0.025);
+    mySpeaker.PlayNote(800.0,0.05,0.025);
+    mySpeaker.PlayNote(700.0,0.05,0.025);
+    mySpeaker.PlayNote(1300.0,0.05,0.025);
+    mySpeaker.PlayNote(1200.0,0.05,0.025);
+    mySpeaker.PlayNote(1100.0,0.05,0.025);
+    mySpeaker.PlayNote(1000.0,0.05,0.025);
+    mySpeaker.PlayNote(900.0,0.05,0.025);
+    mySpeaker.PlayNote(800.0,0.05,0.025);
+    mySpeaker.PlayNote(700.0,0.05,0.025);
+    mySpeaker.PlayNote(600.0,0.05,0.025);
+    mySpeaker.PlayNote(1200.0,0.05,0.025);
+    mySpeaker.PlayNote(1100.0,0.05,0.025);
+    mySpeaker.PlayNote(1000.0,0.05,0.025);
+    mySpeaker.PlayNote(900.0,0.05,0.025);
+    mySpeaker.PlayNote(800.0,0.05,0.025);
+    mySpeaker.PlayNote(700.0,0.05,0.025);
+    mySpeaker.PlayNote(600.0,0.05,0.025);
+    mySpeaker.PlayNote(500.0,0.05,0.025);
+}
+
+void PlayClearSound()
+{
+    mySpeaker.PlayNote(900.0,0.2,0.025);
+    mySpeaker.PlayNote(1000.0,0.2,0.025);
+    mySpeaker.PlayNote(1100.0,0.2,0.025);
+    mySpeaker.PlayNote(1000.0,0.2,0.025);
+    mySpeaker.PlayNote(9000.0,0.2,0.025);
+}
+
+int RandomGen(char range)
+{
+    pc.printf("%c",range);
+    while(!pc.readable()) wait(0.5);
+    char buffer[4];
+    pc.gets(buffer,4);
+    int i = buffer[0]-'0';
+    return i;
+}
+
+int main()
+{
+    //hardware setup
+    LEFT_KEY.mode(PullUp);
+    RIGHT_KEY.mode(PullUp);
+    ROTATE_KEY.mode(PullUp);
+    DOWN_KEY.mode(PullUp);
+    
+    LEFT_KEY.attach_deasserted(&input_left);
+    RIGHT_KEY.attach_deasserted(&input_right);
+    ROTATE_KEY.attach_deasserted(&input_rotate);
+    DOWN_KEY.attach_deasserted(&input_down);
+    
+    LEFT_KEY.setSampleFrequency();
+    RIGHT_KEY.setSampleFrequency();
+    ROTATE_KEY.setSampleFrequency();
+    DOWN_KEY.setSampleFrequency();
+    uLCD.baudrate(3000000);
+    
+    myShiftbrite.RGB(0,0,0);
+    myShiftbrite.RGB(0,0,0);
+    
+    sd.disk_initialize();
+    uLCD.media_init();
+    uLCD.set_sector_address(0x001D, 0x7801);
+    uLCD.display_image(0,0);
+    
+    textLCD.cls();
+    textLCD.locate(0,0);
+    textLCD.printf("Waiting for PC...");
+    pc.baud(9600);
+    pc.format(8,SerialBase::None,1);
+    pc.printf("0");
+    while(!pc.readable()) wait(0.5);
+    char buffer[4];
+    pc.gets(buffer,4);
+    
+    //wait for game start
+    textLCD.cls();
+    textLCD.locate(0,0);
+    textLCD.printf("TETRIS READY!!");
+    textLCD.locate(0,1);
+    textLCD.printf("PRESS ANY KEY...");
+    while(!gameStarted) wait(0.5);
+    PlayStartSound();
+    textLCD.cls();
+    textLCD.printf("Starting game   now...");
+    wait(2);
+    textLCD.cls();
+    textLCD.locate(0,0);
+    textLCD.printf("Points");
+    textLCD.locate(0,1);
+    textLCD.printf("Cleared Line");
+    Thread t1(GameStartLight);
+    //game classes init
+    bool isGameOver = false;
+    int mScreenHeight = 128;
+    Pieces mPieces;
+    Board mBoard (&mPieces, mScreenHeight);
+    int a = RandomGen('a');
+    int b = RandomGen('b');
+    int c = RandomGen('a');
+    int d = RandomGen('b');
+    Game mGame (&mBoard, &mPieces, mScreenHeight, &uLCD,a,b,c,d);
+
+
+    // ----- Main Loop -----
+    int prevX=0;
+    int prevY=0;
+    int prevPiece=-1;
+    int prevRot=0;
+    Timer timer;
+    timer.start();
+    key_input=0;
+    bool needErase = false;
+    uLCD.cls();
+    while (1)
+    {
+        if(isGameOver) 
+        {
+            wait(1);
+            continue;
+        }
+        // ----- Draw ----
+        if(needErase)
+        {
+            mGame.ErasePiece(prevX,prevY,prevPiece,prevRot);
+            needErase=false;
+        }
+        mGame.DrawScene();
+        
+        prevX=mGame.mPosX;
+        prevY=mGame.mPosY;
+        prevPiece=mGame.mPiece;
+        prevRot=mGame.mRotation;
+
+        // ----- Input -----
+        switch (key_input)
+        {
+            case (2): //right
+            {
+                if (mBoard.IsPossibleMovement (mGame.mPosX + 1, mGame.mPosY, mGame.mPiece, mGame.mRotation))
+                    {mGame.mPosX++;needErase=true;}
+                break;
+            }
+
+            case (1): //left
+            {
+                if (mBoard.IsPossibleMovement (mGame.mPosX - 1, mGame.mPosY, mGame.mPiece, mGame.mRotation))
+                    {mGame.mPosX--;needErase=true;}  
+                break;
+            }
+
+            case (4)://down
+            {
+                // Check collision from up to down
+                while (mBoard.IsPossibleMovement(mGame.mPosX, mGame.mPosY, mGame.mPiece, mGame.mRotation)) { mGame.mPosY++; }
+                needErase=true;
+                mBoard.StorePiece (mGame.mPosX, mGame.mPosY - 1, mGame.mPiece, mGame.mRotation);
+                mGame.AddPoints(SinglePiecePoints);
+                int linesDeleted = mBoard.DeletePossibleLines ();
+                if(linesDeleted>0)
+                {
+                    mGame.AddClearedLines(linesDeleted);
+                    mGame.AddPoints(LineClearPoints*linesDeleted);
+                    Thread t1(FlashLight);
+                    PlayClearSound();
+                    clear_board();
+                }
+                UpdateGameStatus(mGame.GetPoints(),mGame.GetClearedLines());
+
+                if (mBoard.IsGameOver())
+                {
+                    isGameOver=true;
+                    uLCD.cls();
+                    uLCD.media_init();
+                    uLCD.set_sector_address(0x001D, 0x7842);
+                    uLCD.display_image(0,0);
+                    Thread t2(GameOverLight);
+                    PlayOverSound();
+                    
+                }
+                
+                if(!isGameOver)
+                {
+                mGame.CreateNewPiece(RandomGen('a'),RandomGen('b'));
+                clear_next_piece();
+                }
+                break;
+            }
+
+            case (3)://rotate
+            {
+                if (mBoard.IsPossibleMovement (mGame.mPosX, mGame.mPosY, mGame.mPiece, (mGame.mRotation + 1) % 4))
+                    {mGame.mRotation = (mGame.mRotation + 1) % 4;needErase=true;}
+                break;
+            }
+            
+            case (0):{break;}
+        }
+        key_input = 0;
+        
+        // ----- Vertical movement -----
+
+        if(timer.read_ms()>WAIT_TIME)
+        {
+            needErase=true;
+            if(!isGameOver)
+            {
+                if (mBoard.IsPossibleMovement (mGame.mPosX, mGame.mPosY + 1, mGame.mPiece, mGame.mRotation))
+                {
+                    mGame.mPosY++;
+                }
+                else
+                {
+                    mBoard.StorePiece (mGame.mPosX, mGame.mPosY, mGame.mPiece, mGame.mRotation);
+                    mGame.AddPoints(SinglePiecePoints);
+                    int linesDeleted = mBoard.DeletePossibleLines ();
+                    if(linesDeleted>0)
+                    {
+                        mGame.AddClearedLines(linesDeleted);
+                        mGame.AddPoints(LineClearPoints*linesDeleted);
+                        Thread t1(FlashLight);
+                        PlayClearSound();
+                        clear_board();
+                    }
+                    UpdateGameStatus(mGame.GetPoints(),mGame.GetClearedLines());
+                        
+                    if (mBoard.IsGameOver())
+                    {
+                        isGameOver=true;
+                        uLCD.cls();
+                        uLCD.media_init();
+                        uLCD.set_sector_address(0x001D, 0x7842);
+                        uLCD.display_image(0,0);
+                        Thread t2(GameOverLight);
+                        PlayOverSound();
+                    }
+                    
+                    if(!isGameOver)
+                    {
+                    mGame.CreateNewPiece(RandomGen('a'),RandomGen('b'));
+                    clear_next_piece();
+                    }
+                }
+            }
+            timer.reset();
+        }
+            wait(0.1);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos.lib	Tue Oct 21 15:10:36 2014 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/users/mbed_official/code/mbed-rtos/#631c0f1008c3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Tue Oct 21 15:10:36 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/552587b429a1
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wave_player.lib	Tue Oct 21 15:10:36 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/sravet/code/wave_player/#acc3e18e77ad