ECE 4180 Final
Dependencies: mbed wave_player mbed-rtos C12832_lcd 4DGL-uLCD-SE LCD_fonts SDFileSystem
main.cpp
- Committer:
- jcrane32
- Date:
- 2019-12-06
- Revision:
- 20:7d56cdcbc9a5
- Parent:
- 19:d65f9fb1023b
- Parent:
- 17:13e45fdcf0b0
- Child:
- 21:cbcbb3480cad
File content as of revision 20:7d56cdcbc9a5:
#include "mbed.h" #include "rtos.h" #include "stdio.h" #include <stdlib.h> #include <time.h> #include "SDFileSystem.h" #include "wave_player.h" #include "mpr121.h" #include "uLCD_4DGL.h" #include "Small_6.h" #include "Small_7.h" #include "Arial_9.h" #include "C12832_lcd.h" #include "globals.h" //#include "bubbles.h" #include "stacys_mom.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; volatile bool songselect = false; volatile bool homescreen = true; volatile bool songchange = false; 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); // Create the interrupt receiver object on pin 26 for touch pad IRQ InterruptIn interrupt(p26); // Setup the i2c bus on pins 9 and 10 I2C i2c(p9, p10); // Setup the Mpr121: // constructor(i2c object, i2c address of the mpr121) Mpr121 mpr121(&i2c, Mpr121::ADD_VSS); // Key hit/release interrupt routine //void fallInterrupt() { // int key_code=0; // int i=0; // int value=mpr121.read(0x00); // value +=mpr121.read(0x01)<<8; // for (i=0; i<12; i++) { // if (((value>>i)&0x01)==1) { // key_code=i+1; // } // } //} wave_player waver(&DACout); Thread thread1, thread2, thread3, thread4; Ticker nextsample; volatile int songNdx = 0; unsigned char *playingSong = NULL; // mutex to make the lcd lib thread safe Mutex lcd_mutex; int songnum = 1; unsigned short **currentBubbles = NULL; int bubbleNdx = 0; volatile int bubblesDrawn = 0; volatile int bubblesMissed = 0; // Thread 1 // print homescreen to LCD void homescreen_thread() { while (true) { // thread loop lcd_mutex.lock(); if (homescreen){ uLCD.cls(); uLCD.text_height(1.3); uLCD.text_width(1.9); uLCD.color(WHITE); uLCD.locate(5,0); uLCD.printf("Tap Tap"); uLCD.locate(4,1); uLCD.printf("Revolution"); uLCD.locate(0,3); uLCD.printf("Pick a song!"); uLCD.text_height(1.3); uLCD.text_width(1.9); uLCD.locate(3,5); uLCD.printf("Fireflies"); uLCD.locate(3,7); uLCD.printf("Stacy's Mom"); uLCD.locate(3,9); uLCD.printf("I Write Sins \n \t Not Tragedies"); 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,WHITE); songchange = false; } lcd_mutex.unlock(); Thread::wait(500); } } // Thread 2 // joystick control for song selection during homescreen 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<3){ songnum++; songchange = true; } Thread::wait(250); } } } // Thread 3 // reads pushbuttons to control menu void pbcontrol_thread() { // 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) { homescreen = true; songselect = false; playing = false; } if (!pb1) { songselect = true; } 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) { //lcd_mutex.lock(); // uLCD.printf("%d", bubblesMissed); // lcd_mutex.unlock(); if (bubblesMissed <= 1) { myRGBled = green; } else if (bubblesMissed <= 3) { myRGBled = blue; } else { myRGBled = red; } Thread::wait(300); } } } // Thread 5 // this thread plays music using the ticker class void playsound() { if (playing) { DACout.write(playingSong[songNdx++] / 255.0); if (songNdx>120000) { playing = false; songNdx = 0; } } else { 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); } int main() { //<<<<<<< working copy // // uLCD.baudrate(3000000); // set baud rate to max // //======= // interrupt.fall(&fallInterrupt); // interrupt.mode(PullUp); //for touch keypad // lcd_mutex.lock(); // uLCD.baudrate(3000000); // uLCD.cls(); // uLCD.media_init(); // uLCD.set_sector_address(0x0077, 0x4002); // uLCD.display_video(0,0); // wait(4); // lcd_mutex.unlock(); //>>>>>>> merge rev // seed random srand (time(NULL)); thread1.start(homescreen_thread); thread2.start(joystick_thread); thread3.start(pbcontrol_thread); 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(20,15); bubbleLanes[1] = new Lane(60,15); bubbleLanes[2] = new Lane(100,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(); homescreen = false; // "playing" is updated by playsound() thread bubbleLanes[0]->add(); // bubbleLanes[1]->add(); // bubbleLanes[2]->add(); bubbleNdx = 0; bool runninggame = true; bubblesMissed = 0; lcd_mutex.lock(); uLCD.cls(); lcd_mutex.unlock(); while (runninggame) { // draw unufilled circles at the bottom of the screen where the user should "tap" lcd_mutex.lock(); uLCD.circle(20,110, 10, GREEN); uLCD.circle(60,110, 10, GREEN); uLCD.circle(100,110, 10, GREEN); lcd_mutex.unlock(); // add bubbles to lanes // uLCD.printf("%d", fireflies_bubbles[bubbleNdx][0]); /*if (songNdx > fireflies_bubbles[bubbleNdx][0]) { // check if it's time to load a bubble bool addedbubbles = false; if (fireflies_bubbles[bubbleNdx][2]) { // check if add bubble at ndx bubbleLanes[0]->add(); addedbubbles = true; } if (fireflies_bubbles[bubbleNdx][3]) { // check if add bubble at ndx bubbleLanes[1]->add(); addedbubbles = true; } if (fireflies_bubbles[bubbleNdx][4]) { // check if add bubble at ndx bubbleLanes[2]->add(); addedbubbles = true; } if (addedbubbles) ++bubbleNdx; }*/ if (playing && ((rand() % 99) < 20)) { // 20% chance of inserting a bubble bubbleLanes[rand() % 3]->add(); } // draw all bubbles lcd_mutex.lock(); bubbleLanes[0]->draw(); bubbleLanes[1]->draw(); bubbleLanes[2]->draw(); lcd_mutex.unlock(); // TODO: check for hits with capacitive touchpad // if there is a hit, delete the bubble from the dynamic array // replace "true" in the next 3 lines with your logic of when to check for a hit // 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(); if (!playing && bubbleLanes[0]->isEmpty() && bubbleLanes[1]->isEmpty() && bubbleLanes[2]->isEmpty()) { runninggame = false; } //this wait delay may need to be tuned Thread::wait(100); } // uncomment this when gameplay works //showScore(); // return to homescreen when songselect = false; homescreen = true; } Thread::wait(100); } }