Final Game. Have fun!!! :-)

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

main.cpp

Committer:
dkelsey6
Date:
2018-05-02
Revision:
2:fae2bc19d19d
Parent:
1:2bedd9befb88
Child:
3:0d678aefc1d0

File content as of revision 2:fae2bc19d19d:

#include "mbed.h"
#include "rtos.h"
#include "uLCD_4DGL.h"
#include "SDFileSystem.h"
#include "wave_player.h"
#include <string>

const int songLength = 600; //adjust as needed

//Arrays for notes
int L1[songLength];
int L2[songLength];
int L3[songLength];
int L4[songLength];

int timespace = -6; //count for drawing the circles

char blueIn = '0'; //Bluetooth setup
int selectedSong = 0;
Serial bluemod(p13,p14); //serial tx, serial rx

//Flips the LEDs when you hit one of the buttons
DigitalOut myled(LED1);
DigitalOut myled2(LED2);
DigitalOut myled3(LED3);
DigitalOut myled4(LED4);

AnalogOut DACout(p18); //speaker analog out

uLCD_4DGL uLCD(p28,p27,p30); // serial tx, serial rx, reset pin;

SDFileSystem sd(p5, p6, p7, p8, "sd");

FILE *wav_file; // song file
wave_player player(&DACout); // the player

int value = 0; //keypad input value
int points = 0; //points
int playGame = 1;
int restartGame = 1;

void mainMenu()
{      
    uLCD.locate(5,0);
    uLCD.printf("Welcome!");
    uLCD.locate(2,2);
    uLCD.printf("Choose a song\n\n");
    uLCD.printf("1: GTShake\n\n");
    uLCD.printf("2: DarkHorse\n\n");
    uLCD.printf("3: OneRepublic\n\n");
    uLCD.printf("4: ShakeItOff\n\n");
    
    int startGame = 0;
    while(!startGame){ //Loop until a valid song is selected
        while(bluemod.readable()){
            
            blueIn = bluemod.getc(); //Read bluetooth input and select song.
            switch(blueIn) {
                case '1':
                    selectedSong = 1;
                    break;
                case '2':
                    selectedSong = 2;
                    break;
                case '3':
                    selectedSong = 3;
                    break;
                case '4':
                    selectedSong = 4;
                    break;
            }
            break; //Only read 1 character at a time
        }
        
        if(selectedSong >= 1 && selectedSong <= 4) //Start game once song is selected
            startGame = 1;
    }
}

void endScreen()
{
    uLCD.cls();
    uLCD.printf("Score: %d\n\n", points);
    
    uLCD.printf("1: Play Again\n");
    uLCD.printf("2: Quit.");
    
    while(restartGame < 0)  //Loop waiting for bluetooth input
    {
        while(bluemod.readable()){
            blueIn = bluemod.getc(); //Read bluetooth input and select song.
            
            if(blueIn == '1'){
                restartGame = 1;    //if 1 go back to main menu
                break;
            }
            else if(blueIn == '2'){
                restartGame = 0;     //if 2 end game
                break;
            }
        }
    }
}


/******Interrupt functions go here********/

/*****************************************/

void lcdThread1(void const *args) {
    while (true) {
        timespace += 1;
        if (timespace < 256)  // <- get rid of this so while loop goes to end of song
        {
            //delete any circles in the yellow circles
            uLCD.filled_circle(110, 20, 12, 0x000000);
            uLCD.filled_circle(110, 50, 12, 0x000000);
            uLCD.filled_circle(110, 80, 12, 0x000000);
            uLCD.filled_circle(110, 110, 12, 0x000000);
            
            //draw the path of the circles
            if (timespace >= 0){
                if (L1[timespace] == 1){
                    uLCD.filled_circle(86, 20, 10, 0x000000);
                    uLCD.filled_circle(110, 20, 12, 0x0000FF);}
                if (L2[timespace] == 1){
                    uLCD.filled_circle(86, 50, 10, 0x000000);
                    uLCD.filled_circle(110, 50, 12, 0x00FFFF);}
                if (L3[timespace] == 1){
                    uLCD.filled_circle(86, 80, 10, 0x000000);
                    uLCD.filled_circle(110, 80, 12, 0x00FF00);}
                if (L4[timespace] == 1){
                    uLCD.filled_circle(86, 110, 10, 0x000000);
                    uLCD.filled_circle(110, 110, 12, 0x008000);}
            }
            if (timespace >= -1){
                if (L1[timespace+1] == 1){
                    uLCD.filled_circle(66, 20, 8, 0x000000);
                    uLCD.filled_circle(86, 20, 10, 0x0000FF);}
                if (L2[timespace+1] == 1){
                    uLCD.filled_circle(66, 50, 8, 0x000000);
                    uLCD.filled_circle(86, 50, 10, 0x00FFFF);}
                if (L3[timespace+1] == 1){
                    uLCD.filled_circle(66, 80, 8, 0x000000);
                    uLCD.filled_circle(86, 80, 10, 0x00FF00);}
                if (L4[timespace+1] == 1){
                    uLCD.filled_circle(66, 110, 8, 0x000000);
                    uLCD.filled_circle(86, 110, 10, 0x008000);}
            }
            if (timespace >= -2){
                if (L1[timespace+2] == 1){
                    uLCD.filled_circle(50, 20, 6, 0x000000);
                    uLCD.filled_circle(66, 20, 8, 0x0000FF);}
                if (L2[timespace+2] == 1){
                    uLCD.filled_circle(50, 50, 6, 0x000000);
                    uLCD.filled_circle(66, 50, 8, 0x00FFFF);}
                if (L3[timespace+2] == 1){
                    uLCD.filled_circle(50, 80, 6, 0x000000);
                    uLCD.filled_circle(66, 80, 8, 0x00FF00);}
                if (L4[timespace+2] == 1){
                    uLCD.filled_circle(50, 110, 6, 0x000000);
                    uLCD.filled_circle(66, 110, 8, 0x008000);}
            }
            if (timespace >= -3){
                if (L1[timespace+3] == 1){
                    uLCD.filled_circle(38, 20, 4, 0x000000);
                    uLCD.filled_circle(50, 20, 6, 0x0000FF);}
                if (L2[timespace+3] == 1){
                    uLCD.filled_circle(38, 50, 4, 0x000000);
                    uLCD.filled_circle(50, 50, 6, 0x00FFFF);}
                if (L3[timespace+3] == 1){
                    uLCD.filled_circle(38, 80, 4, 0x000000);
                    uLCD.filled_circle(50, 80, 6, 0x00FF00);}
                if (L4[timespace+3] == 1){
                    uLCD.filled_circle(38, 110, 4, 0x000000);
                    uLCD.filled_circle(50, 110, 6, 0x008000);}
            }
            if (timespace >= -4){
                if (L1[timespace+4] == 1){
                    uLCD.filled_circle(30, 20, 2, 0x000000);
                    uLCD.filled_circle(38, 20, 4, 0x0000FF);}
                if (L2[timespace+4] == 1){
                    uLCD.filled_circle(30, 50, 2, 0x000000);
                    uLCD.filled_circle(38, 50, 4, 0x00FFFF);}
                if (L3[timespace+4] == 1){
                    uLCD.filled_circle(30, 80, 2, 0x000000);
                    uLCD.filled_circle(38, 80, 4, 0x00FF00);}
                if (L4[timespace+4] == 1){
                    uLCD.filled_circle(30, 110, 2, 0x000000);
                    uLCD.filled_circle(38, 110, 4, 0x008000);}
            }
            if (L1[timespace+5] == 1){
                uLCD.filled_circle(30, 20, 2, 0x0000FF);}
            if (L2[timespace+5] == 1){
                uLCD.filled_circle(30, 50, 2, 0x00FFFF);}
            if (L3[timespace+5] == 1){
                uLCD.filled_circle(30, 80, 2, 0x00FF00);}
            if (L4[timespace+5] == 1){
                uLCD.filled_circle(30, 110, 2, 0x008000);}
        }
        else //when the game is over
        {
            playGame = 0;
        }
        //draw yellow circles
        uLCD.circle(110,20,12, 0xFFFF00);
        uLCD.circle(110,50,12, 0xFFFF00);
        uLCD.circle(110,80,12, 0xFFFF00);
        uLCD.circle(110,110,12, 0xFFFF00);
        
        Thread::wait(250);

    }
}

//Thread to play song, song is selected in mainMenu()
void wavThread(void const *args) {
    Thread::wait(1200);
    
    switch(selectedSong) {
        case 1:
            wav_file = fopen("/sd/GTShake.wav", "r");
            break;
        case 2:
            wav_file = fopen("/sd/DarkHorse.wav", "r");
            break;
        case 3:
            wav_file = fopen("/sd/OneRepublic.wav", "r");
            break;
        case 4:
            wav_file = fopen("/sd/ShakeItOff.wav", "r");
            break;
        default:
            wav_file = fopen("/sd/ShakeItOff.wav", "r");
            break;
    }
        
    player.play(wav_file);
    while (true) {
        Thread::wait(100);
    }
}

//Test method for writing notes to a specified file
//Example usage: writeFile("/sd/", "test"); writes data to /sd/test.txt
void writeFile(const string path, const string fileName)
{
    char name[64];
    snprintf(name, sizeof(name), "%s%s.txt", path.c_str(), fileName.c_str());
    printf("%s\n", name);
    FILE *fp = fopen(name, "w");
    
    if(fp == NULL) {
        error("Could not open file for write\n");
    } else {
        for(int i = 0; i < songLength; i++) {
            fprintf(fp, "%d\n", i%4 + 1);
        }
    }
    fclose(fp); 
}

//Function to read notes from a text file into arrays
//parameters: path of file (string), name of file with no suffix (string)
//Example: readFile("/sd/", "test"); gets data from file /sd/test.txt
// 
void readFile(const string path, const string fileName)
{
    char name[64];
    snprintf(name, sizeof(name), "%s%s.txt", path.c_str(), fileName.c_str());
    FILE *fp = fopen(name, "r");
    
    int index = 0;
    int c;
    
    do {
        c = getc(fp);
        if(c != '\n') {
            switch (c){
                case '1':
                    L1[index] = 1;
                    L2[index] = 0;
                    L3[index] = 0;
                    L4[index] = 0;
                    break;
                case '2':
                    L1[index] = 0;
                    L2[index] = 1;
                    L3[index] = 0;
                    L4[index] = 0;
                    break;
                case '3':
                    L1[index] = 0;
                    L2[index] = 0;
                    L3[index] = 1;
                    L4[index] = 0;
                    break;
                case '4':
                    L1[index] = 0;
                    L2[index] = 0;
                    L3[index] = 0;
                    L4[index] = 1;
                    break;
            }
            index++;
        }
        
    } while (c!=EOF);
    
    fclose(fp);
}

 
int main() {    
    
    uLCD.baudrate(3000000); //Set up Display
    
    while(restartGame)
    {
        mainMenu(); //Game stays at menu until player chooses song
        
        switch(selectedSong) {
            case 1:
                readFile("/sd/", "GTShake");
                break;
            case 2:
                readFile("/sd/", "DarkHorse");
                break;
            case 3:
                readFile("/sd/", "OneRepublic");
                break;
            case 4:
                readFile("/sd/", "ShakeItOff");
                break;
            default:
                readFile("/sd/", "ShakeItOff");
                break;
        }
        
        //start threads
        Thread thread1(lcdThread1); //thread that displays the circles
        Thread thread2(wavThread); //thread that plays the song
        
        //declare interrupt
        //interrupt.mode(PullUp);
        
        while (playGame) {   
            Thread::wait(100);
        }
        
        //End Threads
        thread1.terminate();
        thread2.terminate();
        
        //reset game state switches
        playGame = 1;
        restartGame = -1;
        
        endScreen(); //Game stays at end screen until player restarts or quits
        uLCD.cls();
    }
}