Dance Dance Revolution program for main mbed
Dependencies: 4DGL-uLCD-SE SDFileSystem mbed-rtos mbed wave_player
main.cpp
- Committer:
- wliu88
- Date:
- 2016-04-29
- Revision:
- 0:8a02ac09eae0
File content as of revision 0:8a02ac09eae0:
//FULL GAME (MAIN MBED)
#include "mbed.h"
#include "uLCD_4DGL.h"
#include "rtos.h"
#include "SDFileSystem.h"
#include <string>
#include <vector>
#include "joystick.h"
#include "background.h"
#include "arrows.h"
#include "releaser.h"
#include "songs.h"
Mutex mutex;
Mutex m;
Mutex arm;
uLCD_4DGL uLCD2(p9,p10,p16); // serial tx, serial rx, reset pin;
uLCD_4DGL uLCD(p28,p27,p29);
SDFileSystem sd(p5, p6, p7, p8, "sd");
//InterruptIn pb1(p22);
//InterruptIn pb2(p21);
volatile bool up1 = false;
volatile bool down1 = false;
volatile bool left1 = false;
volatile bool right1 = false;
volatile bool fire1 = false;
volatile bool up2 = false;
volatile bool down2 = false;
volatile bool left2 = false;
volatile bool right2 = false;
volatile bool fire2 = false;
volatile int song1 = 0;
volatile int song2 = 0;
Nav_Switch js1( p12, p14, p13, p15, p11, &up1, &down1, &left1, &right1, &fire1,&song1); //Nav_Switch(PinName up,PinName down,PinName left,PinName right,PinName fire);
Nav_Switch js2( p23, p25, p24, p21, p22, &up2, &down2, &left2, &right2, &fire2,&song2); //Nav_Switch(PinName up,PinName down,PinName left,PinName right,PinName fire);
// variables used for controlling the process
volatile bool pushed1 = false;
volatile bool pushed2 = false;
volatile bool selected1 = false;
volatile bool selected2 = false;
volatile bool process1 = false;
volatile bool process2 = false;
volatile bool finished1 = false;
volatile bool finished2 = false;
ArrowReleaser ar = ArrowReleaser();
ArrowReleaser ar2 = ArrowReleaser();
double nextdelay = 1.0;
int indx = 0;
int chk;
int chk2;
volatile int counter = 0;
volatile int counter2 = 0;
volatile bool empty = false;
volatile bool scoreScreen = false;
DigitalOut songSelected(p19);
DigitalOut specificSong(p20);
vector<string> filenames;
// helper function
// read files names in dir and put them in the variable "filenames"
void read_file_names(char *dir)
{
DIR *dp;
struct dirent *dirp;
dp = opendir(dir);
//read all directory and file names in current directory into filename vector
while((dirp = readdir(dp)) != NULL) {
string filename = string(dirp->d_name);
if ((filename[0] >= 97 && filename[0] <=122) || (filename[0] >= 65 && filename[0] <=90)) {
filenames.push_back(filename);
}
}
closedir(dp);
}
void uLCD_thread(void const *args) {
// 1. title screen
mutex.lock();
//uLCD.cls();
//uLCD.reset();
uLCD.textbackground_color(BLACK);
uLCD.color(RED);
uLCD.locate(4,0);
uLCD.printf("Dance Dance");
uLCD.locate(4,1);
uLCD.printf("Revolution!");
uLCD.locate(6,15);
uLCD.printf("Player 1");
mutex.unlock();
while(!pushed1) {
mutex.lock();
uLCD.locate(4,7);
uLCD.printf("Press CENTER");
mutex.unlock();
Thread::wait(1000);
mutex.lock();
uLCD.locate(4,7);
uLCD.printf(" ");
mutex.unlock();
pushed1 = fire1;
}
// 2. ready screen
mutex.lock();
uLCD.cls();
uLCD.locate(0,7);
uLCD.printf("Player 1 is ready!");
mutex.unlock();
Thread::wait(1000);
while(!pushed2) {
mutex.lock();
uLCD.locate(0,9);
uLCD.printf("Wait player 2...");
mutex.unlock();
}
// 3. song selection screen
while(!process1) {
Thread::yield();
}
mutex.lock();
uLCD.cls();
uLCD.printf("Select a song");
mutex.unlock();
fire1 = false;
while(!selected1 || !selected2) {
for (int i = 0; i < filenames.size(); i++) {
mutex.lock();
if (i == song1) {
uLCD.color(RED);
} else {
uLCD.color(GREEN);
}
uLCD.locate(0,i+2);
uLCD.printf("%s\n\r", filenames[i].c_str());
uLCD.locate(16,i+2);
uLCD.printf(" ");
if (i == song2) {
uLCD.color(BLUE);
uLCD.locate(16,i+2);
uLCD.printf("<-");
}
mutex.unlock();
}
if (selected1) {
mutex.lock();
uLCD.locate(0,8);
uLCD.color(RED);
uLCD.printf("Ready!");
mutex.unlock();
}
selected1 = fire1;
}
// 5. count down
mutex.lock();
uLCD.cls();
uLCD.color(RED);
uLCD.printf("%s\n\r", filenames[song1].c_str());
uLCD.locate(0,1);
uLCD.printf("is picked");
mutex.unlock();
while(!process2) {
Thread::yield();
}
mutex.lock();
uLCD.cls();
uLCD.text_width(4); //4X size text
uLCD.text_height(4);
mutex.unlock();
uLCD.color(RED);
for (int i=5; i>=0; --i) {
mutex.lock();
uLCD.locate(1,2);
uLCD.printf("%2D",i);
mutex.unlock();
Thread::wait(1000);
}
finished1 = true;
}
void uLCD2_thread(void const *args) {
// 1. title screen
mutex.lock();
//uuLCD2.cls();
//uuLCD2.reset();
uLCD2.textbackground_color(BLACK);
uLCD2.color(BLUE);
uLCD2.locate(4,0);
uLCD2.printf("Dance Dance");
uLCD2.locate(4,1);
uLCD2.printf("Revolution!");
uLCD2.locate(6,15);
uLCD2.printf("Player 2");
mutex.unlock();
while(!pushed2) {
mutex.lock();
uLCD2.locate(4,7);
uLCD2.printf("Press CENTER");
mutex.unlock();
wait(1);
mutex.lock();
uLCD2.locate(4,7);
uLCD2.printf(" ");
mutex.unlock();
pushed2 = fire2;
}
// 2. ready screen
mutex.lock();
uLCD2.cls();
uLCD2.locate(0,7);
uLCD2.printf("Player 2 is ready!");
mutex.unlock();
Thread::wait(1000);
while(!pushed1){
mutex.lock();
uLCD2.locate(0,9);
uLCD2.printf("Wait player 1...");
mutex.unlock();
}
// 3. song selection screen
Thread::wait(1000);
process1 = true;
mutex.lock();
uLCD2.cls();
uLCD2.printf("Select a song");
mutex.unlock();
fire2 = false;
while(!selected2 || !selected1) {
for (int i = 0; i < filenames.size(); i++) {
mutex.lock();
if (i == song2) {
uLCD2.color(BLUE);
} else {
uLCD2.color(GREEN);
}
uLCD2.locate(0,i+2);
uLCD2.printf("%s\n\r", filenames[i].c_str());
uLCD2.locate(16,i+2);
uLCD2.printf(" ");
// add a marker to notify player 2 about player 1's selection
if (i == song1) {
uLCD2.color(RED);
uLCD2.locate(16,i+2);
uLCD2.printf("<-");
}
mutex.unlock();
}
if (selected2) {
mutex.lock();
uLCD2.locate(0,8);
uLCD2.color(BLUE);
uLCD2.printf("Ready!");
mutex.unlock();
}
selected2 = fire2;
}
// 5. count down
mutex.lock();
uLCD2.cls();
uLCD2.color(BLUE);
uLCD2.printf("%s\n\r", filenames[song1].c_str());
uLCD2.locate(0,1);
uLCD2.printf("is picked");
mutex.unlock();
Thread::wait(3000);
process2 = true;
mutex.lock();
uLCD2.cls();
uLCD2.text_width(4); //4X size text
uLCD2.text_height(4);
mutex.unlock();
uLCD2.color(BLUE);
for (int i=5; i>=0; --i) {
mutex.lock();
uLCD2.locate(1,2);
uLCD2.printf("%2D",i);
mutex.unlock();
Thread::wait(1000);
}
finished2 = true;
}
//GAME
void arrowreleasing_thread1(void const *args) {
Thread::wait(100);
if(!song1){
while(1){
chk = 0; chk2 =0;
while(!chk && !chk2){
arm.lock();
m.lock();
chk = ar.ReleaseArrow(DemoArray2,indx,2);
m.unlock();
arm.unlock();
Thread::wait(100);
}
indx++;
if(indx == 53){
arm.lock();
ar.setTermStatus(1);
arm.unlock();
break;
}
nextdelay = DemoArray2[indx-1].getDelay();
Thread::wait(nextdelay*1000);
}
}
else{
while(1){
chk = 0; chk2 =0;
while(!chk && !chk2){
arm.lock();
m.lock();
chk = ar.ReleaseArrow(DemoArray,indx,2);
m.unlock();
arm.unlock();
Thread::wait(100);
}
indx++;
if(indx == 53){
arm.lock();
ar.setTermStatus(1);
arm.unlock();
break;
}
nextdelay = DemoArray[indx-1].getDelay();
Thread::wait(nextdelay*1000);
}
}
}
void arrowdrawing_thread1(void const *args){
int term;
while(!scoreScreen){
for(int i=0; i< 5; i++){
arm.lock();
if(ar.ActiveArrows[i].getActive()){
m.lock();
term = ar.ActiveArrows[i].update(2);
m.unlock();
if(term){
ar.ActiveArrows[i].setActive(0);
m.lock();
setup_goal_arrows();
uLCD.locate(0,0);
uLCD.printf("%d",counter);
setup_goal_arrows2();
uLCD2.locate(0,0);
uLCD2.printf("%d",counter2);
m.unlock();
term = 0;
}
}
arm.unlock();
}
/*arm.lock();
if(empty && ar.getTermStatus()){
arm.unlock();
//Song has ended and all arrows have ended
scoreScreen = true;
break;
}*/
}
}
void joystick2_thread(void const *args) {
while(!scoreScreen){
if(left2){
left2 = false;
for(int i=0; i < 5; i++){
arm.lock();
if(ar.ActiveArrows[i].getActive() && ar.ActiveArrows[i].getType() == 0 && abs(ar.ActiveArrows[i].curry - refarrow_left_y) <= 10){
arm.unlock();
counter2++;
m.lock();
uLCD2.locate(0,0);
uLCD2.printf("%d",counter2);
m.unlock();
break;
}
arm.unlock();
}
m.lock();
uLCD2.circle(refarrow_left_x,refarrow_left_y,10,0x00FF00);
m.unlock();
wait(0.04);
m.lock();
uLCD2.circle(refarrow_left_x,refarrow_left_y,10,0x000000);
uLCD2.locate(0,0);
uLCD2.printf("%d",counter2);
m.unlock();
}
if(right2){
right2 = false;
for(int i=0; i < 5; i++){
arm.lock();
if(ar.ActiveArrows[i].getActive() && ar.ActiveArrows[i].getType() == 3 && abs(ar.ActiveArrows[i].curry - refarrow_right_y) <= 10){
arm.unlock();
counter2++;
m.lock();
uLCD2.locate(0,0);
uLCD2.printf("%d",counter2);
m.unlock();
break;
}
arm.unlock();
}
m.lock();
uLCD2.circle(refarrow_right_x,refarrow_right_y,10,0x00FF00);
m.unlock();
wait(0.04);
m.lock();
uLCD2.circle(refarrow_right_x,refarrow_right_y,10,0x000000);
uLCD2.locate(0,0);
uLCD2.printf("%d",counter2);
m.unlock();
}
if(up2){
up2 = false;
for(int i=0; i < 5; i++){
arm.lock();
if(ar.ActiveArrows[i].getActive() && ar.ActiveArrows[i].getType() == 1 && abs(ar.ActiveArrows[i].curry - refarrow_up_y) <= 10){
arm.unlock();
counter2++;
m.lock();
uLCD2.locate(0,0);
uLCD2.printf("%d",counter2);
m.unlock();
break;
}
arm.unlock();
}
m.lock();
uLCD2.circle(refarrow_up_x,refarrow_up_y,10,0x00FF00);
m.unlock();
wait(0.04);
m.lock();
uLCD2.circle(refarrow_up_x,refarrow_up_y,10,0x000000);
uLCD2.locate(0,0);
uLCD2.printf("%d",counter2);
m.unlock();
}
if(down2){
down2 = false;
for(int i=0; i < 5; i++){
arm.lock();
if(ar.ActiveArrows[i].getActive() && ar.ActiveArrows[i].getType() == 2 && abs(ar.ActiveArrows[i].curry - refarrow_down_y) <= 10){
arm.unlock();
counter2++;
m.lock();
uLCD2.locate(0,0);
uLCD2.printf("%d",counter2);
m.unlock();
break;
}
arm.unlock();
}
m.lock();
uLCD2.circle(refarrow_down_x,refarrow_down_y,10,0x00FF00);
m.unlock();
wait(0.04);
m.lock();
uLCD2.circle(refarrow_down_x,refarrow_down_y,10,0x000000);
uLCD2.locate(0,0);
uLCD2.printf("%d",counter2);
m.unlock();
}
Thread::wait(10);
}
}
int main()
{
uLCD.baudrate(3000000);
uLCD2.baudrate(3000000);
read_file_names("/sd/wavfiles");
Thread thread1(uLCD_thread);
Thread thread2(uLCD2_thread);
while(true)
{
if(finished1 && finished2){
thread1.terminate();
thread2.terminate();
uLCD.cls();
uLCD2.cls();
break;
}
}
songSelected = 1;
specificSong = song1;
//GAME
uLCD.baudrate(8000);
uLCD2.baudrate(8000);
uLCD.color(GREEN);
uLCD2.color(GREEN);
uLCD.locate(0,0);
uLCD.printf("%d",counter);
setup_lining();
setup_goal_arrows();
uLCD2.locate(0,0);
uLCD2.printf("%d",counter);
setup_lining2();
setup_goal_arrows2();
wait(1);
Thread t1(arrowreleasing_thread1);
t1.set_priority(osPriorityRealtime);
Thread t2(arrowdrawing_thread1);
Thread t3(joystick2_thread);
t3.set_priority(osPriorityHigh);
while(1){
if(left1){
left1 = false;
for(int i=0; i < 5; i++){
arm.lock();
if(ar.ActiveArrows[i].getActive() && ar.ActiveArrows[i].getType() == 0 && abs(ar.ActiveArrows[i].curry - refarrow_left_y) <= 10){
arm.unlock();
counter++;
m.lock();
uLCD.locate(0,0);
uLCD.printf("%d",counter);
m.unlock();
break;
}
arm.unlock();
}
m.lock();
uLCD.circle(refarrow_left_x,refarrow_left_y,10,0x00FF00);
m.unlock();
wait(0.04);
m.lock();
uLCD.circle(refarrow_left_x,refarrow_left_y,10,0x000000);uLCD.locate(0,0);
uLCD.locate(0,0);
uLCD.printf("%d",counter);
m.unlock();
}
if(right1){
right1 = false;
for(int i=0; i < 5; i++){
arm.lock();
if(ar.ActiveArrows[i].getActive() && ar.ActiveArrows[i].getType() == 3 && abs(ar.ActiveArrows[i].curry - refarrow_right_y) <= 10){
arm.unlock();
counter++;
m.lock();
uLCD.locate(0,0);
uLCD.printf("%d",counter);
m.unlock();
break;
}
arm.unlock();
}
m.lock();
uLCD.circle(refarrow_right_x,refarrow_right_y,10,0x00FF00);
m.unlock();
wait(0.04);
m.lock();
uLCD.circle(refarrow_right_x,refarrow_right_y,10,0x000000);
uLCD.locate(0,0);
uLCD.printf("%d",counter);
m.unlock();
}
if(up1){
up1 = false;
for(int i=0; i < 5; i++){
arm.lock();
if(ar.ActiveArrows[i].getActive() && ar.ActiveArrows[i].getType() == 1 && abs(ar.ActiveArrows[i].curry - refarrow_up_y) <= 10){
arm.unlock();
counter++;
m.lock();
uLCD.locate(0,0);
uLCD.printf("%d",counter);
m.unlock();
break;
}
arm.unlock();
}
m.lock();
uLCD.circle(refarrow_up_x,refarrow_up_y,10,0x00FF00);
m.unlock();
wait(0.04);
m.lock();
uLCD.circle(refarrow_up_x,refarrow_up_y,10,0x000000);
uLCD.locate(0,0);
uLCD.printf("%d",counter);
m.unlock();
}
if(down1){
down1 = false;
for(int i=0; i < 5; i++){
arm.lock();
if(ar.ActiveArrows[i].getActive() && ar.ActiveArrows[i].getType() == 2 && abs(ar.ActiveArrows[i].curry - refarrow_down_y) <= 10){
arm.unlock();
counter++;
m.lock();
uLCD.locate(0,0);
uLCD.printf("%d",counter);
m.unlock();
break;
}
arm.unlock();
}
m.lock();
uLCD.circle(refarrow_down_x,refarrow_down_y,10,0x00FF00);
m.unlock();
wait(0.04);
m.lock();
uLCD.circle(refarrow_down_x,refarrow_down_y,10,0x000000);
uLCD.locate(0,0);
uLCD.printf("%d",counter);
m.unlock();
}
if(fire1){
//nothing
}
arm.lock();
if(ar.getTermStatus()){
empty = true;
for(int i=0; i < 5; i++){
if(ar.ActiveArrows[i].getActive()) {
empty = false;
break;
}
}
if(empty) {
scoreScreen = true;
uLCD.cls();
uLCD2.cls();
break;
}
}
arm.unlock();
wait(0.01);
}
//End of game
uLCD.cls();
uLCD2.cls();
if(counter > counter2){
end_screen();
uLCD.locate(6,6);
uLCD.color(GREEN);
uLCD.printf("YOU WIN!\n PLAYER 1 WINS!");
uLCD2.locate(5,6);
uLCD2.color(RED);
uLCD2.printf("YOU LOSE!\n PLAYER 1 WINS!");
end_screen();
}
else if (counter2 > counter) {
end_screen();
uLCD.locate(5,6);
uLCD.color(RED);
uLCD.printf("YOU LOSE!\n PLAYER 2 WINS!");
uLCD2.locate(6,6);
uLCD.color(GREEN);
uLCD2.printf("YOU WIN!\n PLAYER 2 WINS!");
end_screen();
}
else {
end_screen();
uLCD.locate(7,7);
uLCD.printf("DRAW");
uLCD2.locate(7,7);
uLCD2.printf("DRAW");
end_screen();
}
wait(5);
uLCD.cls();
uLCD2.cls();
end_screen();
uLCD.locate(6,6);
uLCD.color(GREEN);
uLCD.printf("Thanks\n for playing!");
uLCD2.locate(6,6);
uLCD2.color(GREEN);
uLCD2.printf("Thanks\n for playing!");
end_screen();
}