ECE 4180 Final
Dependencies: mbed wave_player mbed-rtos C12832_lcd 4DGL-uLCD-SE LCD_fonts SDFileSystem
Diff: main.cpp
- Revision:
- 19:d65f9fb1023b
- Parent:
- 11:362e25f659a5
- Child:
- 20:7d56cdcbc9a5
--- a/main.cpp Thu Dec 05 05:13:16 2019 +0000 +++ b/main.cpp Fri Dec 06 15:46:16 2019 +0000 @@ -1,28 +1,30 @@ #include "mbed.h" #include "rtos.h" +#include "stdio.h" #include "SDFileSystem.h" #include "wave_player.h" + #include "uLCD_4DGL.h" - -//setup some color objects in flash using const's - #include "Small_6.h" #include "Small_7.h" #include "Arial_9.h" -#include "stdio.h" #include "C12832_lcd.h" +#include "globals.h" + #include "bubbles.h" #include "stacys_mom.h" -#include "the_middle.h" +//#include "the_middle.h" #include "fireflies.h" #include "sins.h" #include "LED.hpp" - +#include "Lane.hpp" +#include "Bubble.hpp" + + //Setup RGB led using PWM pins and class RGBLed myRGBled(p24,p23,p22); //RGB PWM pins - char bred=0; char bgreen=0; char bblue=0; @@ -33,26 +35,34 @@ volatile bool playing = false; uLCD_4DGL uLCD(p28,p27,p30); SDFileSystem sd(p5, p6, p7, p8, "sd"); //SD card +AnalogIn joy_pot(p16); DigitalOut myled(LED1); DigitalIn pb1(p20); DigitalIn pb2(p19); AnalogOut DACout(p18); wave_player waver(&DACout); -Thread thread1, thread2, thread3; +Thread thread1, thread2, thread3, thread4; + Ticker nextsample; -int songNdx = 0; +volatile int songNdx = 0; +unsigned char *playingSong = NULL; // mutex to make the lcd lib thread safe Mutex lcd_mutex; int songnum = 1; -AnalogIn joy_pot(p16); + +unsigned short **currentBubbles = NULL; +int bubbleNdx = 0; +int bubblesDrawn = 0; +int bubblesMissed = 0; + + // Thread 1 // print homescreen to LCD -//new homescreen that doesn't have the flashing void homescreen_thread() { - while(true) { // thread loop + while (true) { // thread loop lcd_mutex.lock(); if (homescreen){ uLCD.cls(); @@ -70,141 +80,265 @@ uLCD.locate(3,5); uLCD.printf("Fireflies"); uLCD.locate(3,7); - uLCD.printf("The Middle"); + uLCD.printf("Stacy's Mom"); uLCD.locate(3,9); - uLCD.printf("Stacy's Mom"); - uLCD.locate(3,11); uLCD.printf("I Write Sins \n \t Not Tragedies"); - uLCD.filled_circle(6, 43, 4, GREEN); //new selection with circle instead of rectangle - homescreen = false;} - if (songchange){ - for (int i = 0; i < 4; i++){ - uLCD.filled_circle(6, i*15+43, 4,BLACK); + uLCD.filled_circle(6, 43, 4, WHITE); //new selection with circle instead of rectangle + homescreen = false; + } + if (songchange) { + for (int i = 0; i < 3; i++){ + uLCD.filled_circle(6, i*15+43, 4,BLACK); } - uLCD.filled_circle(6, (songnum-1)*15+43, 4,GREEN); + uLCD.filled_circle(6, (songnum-1)*15+43, 4,WHITE); songchange = false; - } - lcd_mutex.unlock(); - Thread::wait(200); + } + + lcd_mutex.unlock(); + Thread::wait(200); } } // Thread 2 // joystick control for song selection during homescreen -void joystick_thread() -{ - while(1){ +void joystick_thread() { + while (true) { + if (!playing) { // we dont want to be able to change the song if we're playing if ((joy_pot <= (1.4/3.3)) && songnum>1) { - songnum--; - songchange = true; - } - else if ((joy_pot >= (1.8/3.3)) && songnum<4){ + songnum--; + songchange = true; + } else if ((joy_pot >= (1.8/3.3)) && songnum<3){ songnum++; songchange = true; - } - Thread::wait(250); + } + Thread::wait(250); + } + } } // Thread 3 -//pb1 is to select song -//pb2 is to return to homescreen +// reads pushbuttons to control menu void pbcontrol_thread() { - pb1.mode(PullUp); - pb2.mode(PullUp); + // The pb variables will be zero when the pushbutton is pressed + pb1.mode(PullUp); //pb1 is to select song + pb2.mode(PullUp); //pb2 is to return to homescreen while(true) { // thread loop - if (!pb2) - { + if (!pb2) { homescreen = true; songselect = false; - } - if (!pb1) - { + playing = false; + } + if (!pb1) { songselect = true; - } - Thread::wait(100); // value of pot1 / 100 + } + Thread::wait(100); } } // Thread 4 +// control LED effects +void LED_thread() { + while (true) { + if (!playing) { //spin LED colors at start menu + myRGBled = red; + Thread::wait(200); + myRGBled = yellow; + Thread::wait(200); + myRGBled = orange; + Thread::wait(200); + myRGBled = blue; + Thread::wait(200); + myRGBled = green; + Thread::wait(200); + } else if (playing) { + + if (bubblesMissed <= 3) { + myRGBled = green; + } else if (bubblesMissed <= 5) { + myRGBled = yellow; + } else { + myRGBled = red; + } + + Thread::wait(300); + + } + } +} + +// Thread 5 // this thread plays music using the ticker class void playsound() { if (playing) { - //DACout = song[songNdx++]; - //if (i>**songlength**) i + DACout.write(playingSong[songNdx++] / 255.0); + if (songNdx>120000) { + playing = false; + songNdx = 0; + } } else { - DACout = 0; + DACout.write(0.0); songNdx = 0; } } +void pickSong() { + switch (songnum) { + case 1: + { + playingSong = (unsigned char *) fireflies; + playing = true; + break; + } + + case 2: + { + playingSong = (unsigned char *) stacys_mom; + playing = true; + break; + } + case 3: + { + playingSong = (unsigned char *) sins; + playing = true; + break; + } + default: + break; + } +} + + + +void showScore () { + uLCD.color(0x00FF00); // Change text color and set up menu + uLCD.text_bold(ON); + uLCD.locate(1,1); + uLCD.text_width(2); //4X size text + uLCD.text_height(2); + uLCD.printf("Thanks for playing Tap Tap Revolution!"); +// winSound(); + wait(1.5); + + uLCD.text_width(1); //4X size text + uLCD.text_height(1); + uLCD.text_bold(OFF); + uLCD.color(0xFFFFFF); + uLCD.locate(2,8); + uLCD.printf("Your Score:"); + uLCD.color(0x00FF00); + uLCD.locate(2,10); + + float scorePercent = ((bubblesDrawn - bubblesMissed) / bubblesDrawn) * 100; + uLCD.printf("%d %", scorePercent); + wait(1.2); + uLCD.cls(); + uLCD.locate(5,0); + + Thread::wait(2000); +} + + +void play() { + Lane *bubbleLanes[3]; + // these positions may need to be adjusted as I assume they're positioned incorrectly... + bubbleLanes[0] = new Lane(3,3); + bubbleLanes[1] = new Lane(3,6); + bubbleLanes[2] = new Lane(3,9); + + while (playing && !bubbleLanes[0]->isEmpty() && !bubbleLanes[1]->isEmpty() && !bubbleLanes[2]->isEmpty()) { + + } + + // return to homescreen when + homescreen = true; +} + + + int main() { - uLCD.baudrate(3000000); + uLCD.baudrate(3000000); // set baud rate to max + thread1.start(homescreen_thread); thread2.start(joystick_thread); thread3.start(pbcontrol_thread); -// nextsample.attach(&playsound, 1.0/8000.0); - //startup sound - myRGBled = blue; //tested to make sure led works, we can use whatever color(s) here - FILE *wave_file; - wave_file=fopen("/sd/cheer.wav","r"); - waver.play(wave_file); - fclose(wave_file); - while(1) - { - - if (songselect){ - myled = 0; - homescreen = false; - lcd_mutex.lock(); - uLCD.cls(); - uLCD.printf("You selected song %2d",songnum); - lcd_mutex.unlock(); - //add case statement based on songnum or something - //code for playing song from sd - switch (songnum) - { - case 1: - { - FILE *wave_file; - wave_file =fopen("/sd/4180 final project/Fireflies.wav", "r"); - waver.play(wave_file); - fclose(wave_file); - break; + thread4.start(LED_thread); + nextsample.attach(&playsound, 1.0/8000.0); + + Lane *bubbleLanes[3]; + // these positions may need to be adjusted as I assume they're positioned incorrectly... + bubbleLanes[0] = new Lane(15,15); + bubbleLanes[1] = new Lane(40,15); + bubbleLanes[2] = new Lane(80,15); + + //startup sound? + + while(true) { + if (songselect) { + homescreen = false; +// lcd_mutex.lock(); +// uLCD.cls(); +// uLCD.printf("You selected song %2d", songnum); +// lcd_mutex.unlock(); + pickSong(); + + // "playing" is updated by playsound() thread + while (playing && !bubbleLanes[0]->isEmpty() && !bubbleLanes[1]->isEmpty() && !bubbleLanes[2]->isEmpty()) { + // draw unufilled circles at the bottom of the screen where the user should "tap" + uLCD.circle(15,110, 30, GREEN); + uLCD.circle(40,110, 30, GREEN); + uLCD.circle(80,110, 30, GREEN); + + // add bubbles to lanes + if (fireflies_bubbles[bubbleNdx][0] > songNdx) { // check if it's time to load a bubble + bool addedbubbles = false; + if (fireflies_bubbles[bubbleNdx][2] > songNdx) { // check if add bubble at ndx + bubbleLanes[0]->add(); + addedbubbles = true; + } + + if (fireflies_bubbles[bubbleNdx][3] > songNdx) { // check if add bubble at ndx + bubbleLanes[1]->add(); + addedbubbles = true; + } + + if (fireflies_bubbles[bubbleNdx][4] > songNdx) { // check if add bubble at ndx + bubbleLanes[2]->add(); + addedbubbles = true; + } + + if (addedbubbles) ++songNdx; } - case 2: - { - FILE *wave_file; - wave_file =fopen("/sd/4180 final project/The_Middle.wav", "r"); - waver.play(wave_file); - fclose(wave_file); - break; - } - case 3: - { - FILE *wave_file; - wave_file =fopen("/sd/4180 final project/Stacy's_Mom.wav", "r"); - waver.play(wave_file); - fclose(wave_file); - break; - } - case 4: - { - FILE *wave_file; - wave_file =fopen("/sd/4180 final project/Sins_!_Tragedies.wav", "r"); - waver.play(wave_file); - fclose(wave_file); - break; - } - default: - break; + + // draw all bubbles + bubbleLanes[0]->draw(); + bubbleLanes[1]->draw(); + bubbleLanes[2]->draw(); + + // TODO: check for hits with capacitive touchpad + // if there is a hit, delete the bubble from the dynamic array + if (true) bubbleLanes[0]->checkHit(); + if (true) bubbleLanes[1]->checkHit(); + if (true) bubbleLanes[2]->checkHit(); + + // move down all the bubbles, deleting bubbles that are out of bounds if required + bubbleLanes[0]->moveDown(); + bubbleLanes[1]->moveDown(); + bubbleLanes[2]->moveDown(); + + //this wait delay may need to be tuned + Thread::wait(100); } - - } - Thread::wait(100); + + // uncomment this when gameplay works + //showScore(); + + // return to homescreen when + songselect = false; + homescreen = true; } + Thread::wait(100); + } } - -