4180 Final

Dependencies:   mbed wave_player mbed-rtos 4180Final SDFileSystem

Revision:
0:c5d6f214ba01
Child:
1:e14104308237
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Apr 26 06:56:36 2020 +0000
@@ -0,0 +1,599 @@
+// TODO: 
+//      - Add actual way to calulate scores (in play() or add helper method)
+//      - Add more inputs/outputs
+//      - add pot to increase selector size
+//      - add sound
+#include "mbed.h"
+#include "uLCD_4DGL.h"
+#include "Nav_Switch.h"
+#include "SDFileSystem.h"
+#include "microphone.h"
+#include  "rtos.h"
+
+Nav_Switch myNav(p9, p6, p7, p5, p8); //pin order on Sparkfun breakout
+uLCD_4DGL uLCD(p28, p27, p30); // serial tx, serial rx, reset pin; 
+PwmOut myled(LED1);
+//SDFileSystem sd(p11, p12, p13, p10, "sd");
+microphone mymic1(p15);
+AnalogIn pot(p16);
+
+Thread thread1;
+
+int rounds = 3;
+int curRound = 1;
+int score1 = 0;
+int score2 = 0;
+int scores1[7] = {0};
+int scores2[7] = {0};
+int curTime = 0;
+int wonRnds1 = 0;
+int wonRnds2 = 0;
+int highScoresArr[10] = {100, 90, 83, 73, 64, 54, 44, 34, 24, 14};
+int s = 0;
+int timer = 0;
+
+int main();
+void play();
+
+// thread1
+void pot_thread() {
+    while (1) {
+        if (timer == 99) {
+            s = (int) (pot * 2.0);
+            myled = pot;
+        }
+//        Thread::wait(100);
+    }
+}
+
+void clearVals() {
+    score1 = 0;
+    score2 = 0;
+    wonRnds1 = 0;
+    wonRnds2 = 0;
+    curRound = 1;
+    curTime = 0;
+    for (int i=0; i<sizeof(scores1)/4; i++) {
+        scores1[i] = 0;
+        scores2[i] = 0;
+    }
+}
+
+void saveHS() {
+    mkdir("/sd/finalProj", 0777);
+    FILE *fp = fopen("/sd/finalProj/highscores.txt", "w");
+    if(fp == NULL) {
+     uLCD.printf("Error Open \n");
+    }
+    for (int i=0; i<sizeof(highScoresArr)/4; i++) {
+        fprintf(fp, "%4d", highScoresArr[i]);
+    }
+    fclose(fp);
+}
+
+void gameOver() {
+    uLCD.filled_rectangle(13, 25, 115, 120, LRED);
+    // header
+    uLCD.color(BLACK);
+    uLCD.text_height(2);
+    uLCD.text_width(2);
+    uLCD.textbackground_color(LRED);
+    uLCD.locate(1,2);
+    uLCD.printf("Results");
+    uLCD.locate(1,3);
+    uLCD.color(DGOLD);
+    uLCD.printf("Winner:");
+    uLCD.filled_rectangle(13, 47, 115, 48, RED);
+    uLCD.text_height(3);
+    uLCD.text_width(3);
+    // get total scores
+    int total1 = 0;
+    int total2 = 0;
+    for (int i=0; i<sizeof(scores1)/4; i++) {
+        total1 += scores1[i];
+        total2 += scores2[i];
+    }
+    int avg1 = total1 / rounds;
+    int avg2 = total2 / rounds;
+    // Save new high scores if needed
+    // ---- Player1 ----
+    int indx = -1;
+    for (int i=0; i<sizeof(highScoresArr)/4; i++) {
+        if (avg1 > highScoresArr[i]) {
+            indx = i;
+            break;
+        }
+    }
+    // Save new highscore
+    if (indx != -1) {
+        for (int i=sizeof(highScoresArr)/4-1; i>indx; i--) {
+            highScoresArr[i] = highScoresArr[i-1];
+        }
+        highScoresArr[indx] = avg1;
+        saveHS();  // Save highScoresArr to SD card
+    }
+    // ---- End P1 ----
+    // ---- Player2 ----
+    indx = -1;
+    for (int i=0; i<sizeof(highScoresArr)/4; i++) {
+        if (avg2 > highScoresArr[i]) {
+            indx = i;
+            break;
+        }
+    }
+    // Save new highscore
+    if (indx != -1) {
+        for (int i=sizeof(highScoresArr)/4-1; i>indx; i--) {
+            highScoresArr[i] = highScoresArr[i-1];
+        }
+        highScoresArr[indx] = avg2;
+        saveHS();  // Save highScoresArr to SD card
+    }
+    // ---- End P2 ----
+    // Print winner info to screen
+    if (wonRnds1 > wonRnds2) {
+        uLCD.color(BLUE);
+        uLCD.locate(2,3);
+        uLCD.printf("P1");
+        uLCD.text_height(1);
+        uLCD.text_width(1);
+        uLCD.locate(3,12);
+        uLCD.printf("Rounds won: %1d", wonRnds1);
+        uLCD.locate(5,13);
+        uLCD.printf("Avg: %4d", avg1);
+        
+    } else if (wonRnds2 > wonRnds1) {
+        uLCD.color(PURPLE);
+        uLCD.locate(2,3);
+        uLCD.printf("P2");
+        uLCD.text_height(1);
+        uLCD.text_width(1);
+        uLCD.locate(3,12);
+        uLCD.printf("Rounds won: %1d", wonRnds2);
+        uLCD.locate(5,13);
+        uLCD.printf("Avg: %4d", avg2);
+    } else {
+        uLCD.locate(2,3);
+        uLCD.color(BLACK);
+        uLCD.printf("Tie");
+    }
+    uLCD.text_height(3);
+    uLCD.text_width(3);
+    while (1) {
+        timer = 0;
+         while (timer<80) {
+             if (myNav.fire()) {
+                // clear values
+                clearVals();
+                main();
+             }
+             // Blink winner
+             if (timer == 0) {
+                if (wonRnds1 > wonRnds2) {
+                    uLCD.color(BLUE);
+                    uLCD.locate(2,3);
+                    uLCD.printf("P1");
+                } else if (wonRnds2 > wonRnds1) {
+                    uLCD.color(PURPLE);
+                    uLCD.locate(2,3);
+                    uLCD.printf("P2");
+                } else {
+                    uLCD.locate(2,3);
+                    uLCD.color(BLACK);
+                    uLCD.printf("Tie");
+                }
+             } else if (timer == 60) {
+                 uLCD.color(LRED);
+                 uLCD.locate(2,3);
+                 uLCD.printf("CLS");
+             }
+             wait(.01);
+             timer++;
+         }
+    }
+}
+
+void nextRound() {
+    uLCD.filled_rectangle(13, 25, 115, 120, LRED);
+    // header
+    uLCD.color(BLACK);
+    uLCD.text_height(2);
+    uLCD.text_width(2);
+    uLCD.textbackground_color(LRED);
+    uLCD.locate(2,2);
+    uLCD.printf("ROUND%1d", curRound);
+    uLCD.locate(1,3);
+    uLCD.color(DGOLD);
+    uLCD.printf("Winner:");
+    uLCD.filled_rectangle(13, 47, 115, 48, RED);
+    uLCD.text_height(3);
+    uLCD.text_width(3);
+    if (score1 > score2) {
+        uLCD.color(BLUE);
+        uLCD.locate(2,3);
+        uLCD.printf("P1");
+        uLCD.locate(1,4);
+        uLCD.printf("%4d", score1);
+        wonRnds1++;
+    } else if (score2 > score1) {
+        uLCD.color(PURPLE);
+        uLCD.locate(2,3);
+        uLCD.printf("P2");
+        uLCD.locate(1,4);
+        uLCD.printf("%4d", score2);
+        wonRnds2++;
+    } else {
+        uLCD.locate(2,4);
+        uLCD.printf("Tie");
+    }
+    scores1[curRound-1] = score1;
+    scores2[curRound-1] = score2;
+    wait(3.0);
+    curRound++;
+    curTime = 0;
+    score1 = 0;
+    score2 = 0;
+    if (curRound > rounds) {
+        gameOver();
+    }
+    play();
+}
+
+void pause() {
+    uLCD.filled_rectangle(13, 25, 115, 120, LRED);
+    uLCD.filled_rectangle(13, 48, 115, 50, RED);
+    // header
+    uLCD.color(BLACK);
+    uLCD.text_height(2);
+    uLCD.text_width(2);
+    uLCD.textbackground_color(LRED);
+    uLCD.locate(2,2);
+    uLCD.printf("PAUSED");
+    // Choices
+    uLCD.text_height(1);
+    uLCD.text_width(1);
+    uLCD.locate(5,8);
+    uLCD.printf("Continue");
+    uLCD.locate(7,11);
+    uLCD.printf("Quit");
+    // Selector dots
+    int xPos[2] = {30, 44};
+    int yPos[2] = {67, 91};
+    int ticker = 0;
+    int oldTicker = 1;
+    for (int i=0; i<sizeof(yPos)/4; i++) {
+        uLCD.filled_circle(xPos[i], yPos[i], 1+s, RED);
+    }
+    while (1) {
+         // Fill selector circle and if necessary, clear old
+         if (oldTicker != ticker) {
+            uLCD.filled_circle(xPos[oldTicker], yPos[oldTicker], 3+s, LRED);
+            uLCD.filled_circle(xPos[oldTicker], yPos[oldTicker], 1+s, RED);
+         }
+         uLCD.filled_circle(xPos[ticker], yPos[ticker], 3+s, RED);
+         // save oldTicker spot
+         oldTicker = ticker;
+         // get new ticker position
+         timer = 0;
+         while (timer<100) {
+             if (timer == 0) {
+                 uLCD.filled_circle(xPos[ticker], yPos[ticker], 3+s, RED);
+             } else if (timer == 70) {
+                 uLCD.filled_circle(xPos[ticker], yPos[ticker], 3+s, LRED);
+             }
+             if (myNav.fire()) {
+                 uLCD.filled_circle(xPos[ticker], yPos[ticker], 2+s, GREEN);
+                 switch(ticker) {
+                     case 0:
+                        play();
+                        break;
+                     case 1:
+                        clearVals();
+                        main();
+                  }
+             } else if (myNav.up() || myNav.left()) {
+                 wait(.2);
+                 ticker = ticker - 1;
+                 if (ticker < 0) {
+                     ticker = sizeof(xPos)/4 - 1;
+                 }
+             } else if (myNav.down() || myNav.right()) {
+                 wait(.2);
+                 ticker = (ticker + 1) % (sizeof(xPos)/4);
+             }
+             wait(.01);
+             timer++;
+         }
+    }
+}
+
+void play() {
+     uLCD.background_color(GREEN);
+     uLCD.cls();
+     uLCD.filled_rectangle(0, 0, 200, 15, RED);
+     // header
+     uLCD.color(BLACK);
+     uLCD.locate(5,0);
+     uLCD.text_height(2);
+     uLCD.text_width(2);
+     uLCD.textbackground_color(RED);
+     uLCD.printf("PLAY");
+     uLCD.text_height(1);
+     uLCD.text_width(1);
+     uLCD.locate(14,1);
+     uLCD.printf("Rnd%1d", curRound);
+     // Scores headers
+     uLCD.textbackground_color(GREEN);
+     uLCD.color(BLUE);
+     uLCD.locate(5,3);
+     uLCD.printf("Player 1:");
+     uLCD.color(PURPLE);
+     uLCD.locate(5,11);
+     uLCD.printf("Player 2:");
+     // Scores
+     uLCD.text_height(4);
+     uLCD.text_width(4);
+     while (1) {
+        timer = 0;
+        // Blinking pause button
+        while (timer<25) {
+            if (myNav.fire()) {
+                uLCD.filled_rectangle(60, 68, 65, 82, GREEN);
+                uLCD.filled_rectangle(70, 68, 75, 82, GREEN);
+                wait(.1);
+                pause();
+            }
+            if (timer % 25 == 0) {
+                score1 = (int) (pot*100.0); //curTime+1000; // int(mymic1*1000.0);
+                score2 = curTime+2000;
+                uLCD.color(BLUE);
+                uLCD.locate(0,1);
+                uLCD.printf("%4d", score1);
+                uLCD.color(PURPLE);
+                uLCD.locate(0,3);
+                uLCD.printf("%4d", score2);
+                // Time bar
+                double roundTime = 15.0;  // in secs
+                int length = (int) ( (double)curTime / roundTime * 127.0);
+                uLCD.filled_rectangle(0, 65, length, 85, DGREEN);
+                if (length >= 127) {
+                    nextRound();
+                }
+                curTime++;
+            }
+            if (timer < 20){
+                uLCD.filled_rectangle(60, 68, 65, 82, LGREY);
+                uLCD.filled_rectangle(70, 68, 75, 82, LGREY);
+            } else if (timer >= 20) {
+                uLCD.filled_rectangle(60, 68, 65, 82, BLACK);
+                uLCD.filled_rectangle(70, 68, 75, 82, BLACK);
+            }
+            wait(.01);
+            timer++;
+         }
+     }
+}
+
+void highScores() {
+     uLCD.background_color(ORANGE);
+     uLCD.cls();
+     uLCD.filled_rectangle(0, 0, 200, 14, RED);
+     uLCD.color(BLACK);
+     uLCD.locate(0,0);
+     uLCD.text_height(2);
+     uLCD.text_width(2);
+     uLCD.textbackground_color(RED);
+     uLCD.printf("HighScore");
+     uLCD.line(0, 14, 200, 14, RED);
+     uLCD.line(0, 15, 200, 15, RED);
+     uLCD.text_height(1);
+     uLCD.text_width(1);
+     uLCD.locate(7,14);
+     uLCD.color(BLACK);
+     uLCD.textbackground_color(ORANGE);
+     uLCD.printf("Back");
+     uLCD.color(BLUE);
+     int rank[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+     for (int i=0; i<sizeof(rank)/4; i++) {
+         uLCD.locate(1,i+2);
+         uLCD.printf("Position %2d: %4d", rank[i], highScoresArr[i]);
+     }
+     while (1) {
+        timer = 0;
+         while (timer<50) {
+             if (timer < 30){
+                 uLCD.filled_circle(45, 115, 3+s, RED);
+             } else {
+                 uLCD.filled_circle(45, 115, 3+s, ORANGE);
+             }
+             if (myNav.fire()) {
+                 uLCD.filled_circle(45, 115, 2+s, GREEN);
+                 wait(.1);
+                 main();
+             }
+             wait(.01);
+             timer++;
+         }
+     }
+}
+
+void settings() {
+     uLCD.background_color(LGREY);
+     uLCD.cls();
+     uLCD.filled_rectangle(0, 0, 200, 15, RED);
+     uLCD.color(BLACK);
+     uLCD.locate(1,0);
+     uLCD.text_height(2);
+     uLCD.text_width(2);
+     uLCD.textbackground_color(RED);
+     uLCD.printf("Settings");
+     uLCD.text_height(1);
+     uLCD.text_width(1);
+     uLCD.locate(0,2);
+     uLCD.color(BLUE);
+     uLCD.textbackground_color(LGREY);
+     uLCD.printf("Choose how many   rounds to play:");
+     uLCD.locate(9,4);
+     uLCD.color(BLUE);
+     uLCD.printf("3");
+     uLCD.locate(9,5);
+     uLCD.printf("5");
+     uLCD.locate(9,6);
+     uLCD.printf("7");
+     uLCD.line(0, 32, 200, 32, BLUE);
+     uLCD.locate(4,7);
+     uLCD.printf("Rounds = %1d", rounds);
+     uLCD.locate(7,14);
+     uLCD.color(BLACK);
+     uLCD.printf("Back");
+     uLCD.baudrate(BAUD_3000000); //jack up baud rate to max for fast display
+     int xPos[4] = {57, 57, 57, 45};
+     int yPos[4] = {36, 42, 50, 115};
+     int ticker = 0;
+     int oldTicker = 1;
+     for (int i=0; i<sizeof(yPos)/4; i++) {
+         uLCD.filled_circle(xPos[i], yPos[i], 1+s, RED);
+     }
+     while (1) {
+         // Fill selector circle and if necessary, clear old
+         if (oldTicker != ticker) {
+            uLCD.filled_circle(xPos[oldTicker], yPos[oldTicker], 3+s, LGREY);
+            uLCD.filled_circle(xPos[oldTicker], yPos[oldTicker], 1+s, RED);
+         }
+         uLCD.filled_circle(xPos[ticker], yPos[ticker], 3+s, RED);
+         // save oldTicker spot
+         oldTicker = ticker;
+         // get new ticker position
+         timer = 0;
+         while (timer<100) {
+             if (timer == 0) {
+                 uLCD.filled_circle(xPos[ticker], yPos[ticker], 3+s, RED);
+             } else if (timer == 70) {
+                 uLCD.filled_circle(xPos[ticker], yPos[ticker], 3+s, LGREY);
+             }
+             if (myNav.fire()) {
+                 uLCD.filled_circle(xPos[ticker], yPos[ticker], 3+s, GREEN);
+                 switch(ticker) {
+                     case 0:
+                        rounds = 3;
+                        break;
+                     case 1:
+                        rounds = 5;
+                        break;
+                     case 2:
+                        rounds = 7;
+                        break;
+                     case 3:
+                        main();
+                  }
+                  uLCD.color(BLUE);
+                  uLCD.locate(4,7);
+                  uLCD.printf("Rounds = %1d", rounds);
+             } else if (myNav.up() || myNav.left()) {
+                 wait(.2);
+                 ticker = ticker - 1;
+                 if (ticker < 0) {
+                     ticker = sizeof(xPos)/4 - 1;
+                 }
+             } else if (myNav.down() || myNav.right()) {
+                 wait(.2);
+                 ticker = (ticker + 1) % (sizeof(xPos)/4);
+             }
+             wait(.01);
+             timer++;
+         }
+     }
+}
+
+int main() {
+     // read in highScoresArr from SD card
+     //FILE *fp = fopen("/sd/finalProj/highscores.txt", "r");
+     //if(fp == NULL) {
+     //uLCD.printf("Error Open \n");
+     //}
+     //for (int i=0; i<sizeof(highScoresArr)/4; i++) {
+     //   fscanf(fp, "%4d", &highScoresArr[i]);
+    // }
+     //fclose(fp);
+     // create menu interface
+     uLCD.background_color(LBLUE);
+     uLCD.cls();
+     uLCD.filled_rectangle(0, 0, 200, 14, RED);
+     uLCD.color(BLACK);
+     uLCD.locate(1,0);
+     uLCD.text_height(2);
+     uLCD.text_width(2);
+     uLCD.textbackground_color(RED);
+     uLCD.printf("Screamer");
+     uLCD.line(0, 14, 200, 14, RED);
+     uLCD.line(0, 15, 200, 15, RED);
+     uLCD.text_height(1);
+     uLCD.text_width(1);
+     uLCD.textbackground_color(LBLUE);
+     uLCD.locate(7,4);
+     uLCD.color(GREEN);
+     uLCD.printf("PLAY");
+     uLCD.locate(4,8);
+     uLCD.color(ORANGE);
+     uLCD.printf("HIGH SCORES");
+     uLCD.locate(5,13);
+     uLCD.color(LGREY);
+     uLCD.printf("SETTINGS");
+     uLCD.baudrate(BAUD_3000000); //jack up baud rate to max for fast display
+     int xPos[3] = {40, 21, 28};
+     int yPos[3] = {35, 67, 107};
+     int ticker = 0;
+     int oldTicker = 1;
+     for (int i=0; i<sizeof(yPos)/4; i++) {
+         uLCD.filled_circle(xPos[i], yPos[i], 2, RED);
+     }
+     thread1.start(pot_thread);
+     while (1) {
+         // Fill selector circle and if necessary, clear old
+         if (oldTicker != ticker) {
+            uLCD.filled_circle(xPos[oldTicker], yPos[oldTicker], 5+s, LBLUE);
+            uLCD.filled_circle(xPos[oldTicker], yPos[oldTicker], 2+s, RED);
+         }
+         uLCD.filled_circle(xPos[ticker], yPos[ticker], 5+s, RED);
+         // save oldTicker spot
+         oldTicker = ticker;
+         // get new ticker position
+         timer = 0;
+         while (timer<100) {
+             if (timer == 0) {
+                 uLCD.filled_circle(xPos[ticker], yPos[ticker], 5+s, RED);
+             } else if (timer == 70) {
+                 uLCD.filled_circle(xPos[ticker], yPos[ticker], 5+s, LBLUE);
+             }
+             if (myNav.fire()) {
+                 uLCD.filled_circle(xPos[ticker], yPos[ticker], 3+s, GREEN);
+                 wait(.1);
+                 switch(ticker) {
+                     case 0:
+                        curTime = 0;
+                        score1 = 0;
+                        score2 = 0;
+                        play();
+                        break;
+                     case 1:
+                        highScores();
+                        break;
+                     case 2:
+                        settings();
+                        break;
+                 }
+             } else if (myNav.up() || myNav.left()) {
+                 wait(.2);
+                 ticker = ticker - 1;
+                 if (ticker < 0) {
+                     ticker = sizeof(xPos)/4 - 1;
+                 }
+             } else if (myNav.down() || myNav.right()) {
+                 wait(.2);
+                 ticker = (ticker + 1) % (sizeof(xPos)/4);
+             }
+             wait(.01);
+             timer++;
+         }
+     }
+}
\ No newline at end of file