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

main.cpp

Committer:
sucrelv
Date:
2014-10-21
Revision:
0:3b5e97ab5884

File content as of revision 0:3b5e97ab5884:

#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);
    }
}