Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed mbed-rtos 4180Final SDFileSystem
main.cpp
- Committer:
- bfarmer
- Date:
- 2020-04-27
- Revision:
- 5:3a9b8a625aa8
- Parent:
- 4:e060ee6a74b5
File content as of revision 5:3a9b8a625aa8:
// 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 "menumusic.h"
//#include "the_middle.h"
//#include "wave_player.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);
AnalogOut DACout(p18);
DigitalOut led(LED2);
Thread thread1;
// Stuff for sound
unsigned char *music = NULL;
//wave_player waver(&DACout);
Ticker nextsample;
volatile int sIndx = 0;
int playMusic = 0;
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();
void playMenuMusic() {
if (playMusic) {
music = (unsigned char*) menumusic;
led = 1;
DACout.write(music[sIndx++] / 255.0);
if(sIndx > 20000) { //120000
sIndx = 0;
led = 0;
}
} else {
DACout.write(0.0);
sIndx = 0;
}
}
// 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);
nextsample.attach(&playMenuMusic, 1.0/22000.0);
while (1) {
// play music
playMusic = 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;
playMusic = 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++;
}
}
}