This is a ball on the Mbed.

Dependencies:   4DGL-uLCD-SE IMUfilter ITG3200 Music mbed-rtos mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main_legacy.cpp Source File

main_legacy.cpp

00001 #include "mbed.h"
00002 #include "uLCD_4DGL.h"
00003 #include "rtos.h"
00004 #include "Music.h"
00005 #include "IMU_RPY.h"
00006 
00007 DigitalOut myled(LED1);
00008 AnalogIn xpot(p19);
00009 AnalogIn ypot(p20);
00010 uLCD_4DGL uLCD(p9,p10,p11);
00011 music ms(p21);
00012 
00013 Mutex xmutex,ymutex;
00014 char mazearr[128][128];
00015 char ballx, bally;
00016 char ballx_old, bally_old;
00017 float ballxvel, ballyvel, ballvel;
00018 enum LEVELSELECT {LEVEL1, LEVEL2, LEVEL3};
00019 LEVELSELECT gamestate = LEVEL1;
00020 
00021 //Sound bytes
00022 char s1[] = "E4:8; E4:8; R:8; E4:8; R:8; C4:8; E4:4; G4:4; R:4; G3:4; R:4;";
00023 int s1_len = 61;
00024 char wallbeep[] = "C4:48;";
00025 int wallbeep_len = 6;
00026 char victory[] = "A4:12; R:32; A4:12; R:32; A4:12; R:32; A4:4; R:8; F4:4; R:8; G4:4; R:8; A4:4; R:16; G4:20; R:32; A4:4;";
00027 int victory_len = 102;
00028 double tempo = 180;
00029 
00030 void displayTitle();
00031 void displayMaze();
00032 void updateVelocity();
00033 void updateBall();
00034 void loadLevel();
00035 void displayVictory();
00036 
00037 //xthread and ythread act as the physics engine, simulating velocity and wall detection
00038 void xthread(void const *args)
00039 {
00040     while(1)
00041     {
00042         xmutex.lock();
00043         ymutex.lock();
00044         if(ballxvel > 0)
00045         {
00046             if(mazearr[ballx+1][bally] != 1)
00047             {
00048                 ballx++;
00049             }
00050             else
00051             {
00052                 ballxvel = -ballxvel;
00053                 
00054                 ms.play(wallbeep,tempo,wallbeep_len);
00055             }
00056         }
00057         else if (ballxvel < 0)
00058         {
00059             if(mazearr[ballx-1][bally] != 1)
00060             {
00061                 ballx--;
00062             }
00063             else
00064             {
00065                 ms.play(wallbeep,tempo,wallbeep_len);
00066                 ballxvel = -ballxvel;
00067             }
00068         }
00069         xmutex.unlock();
00070         ymutex.unlock();
00071         Thread::wait(100-98*abs(ballxvel));
00072     }
00073 } 
00074 void ythread(void const *args)
00075 {
00076     while(1)
00077     {
00078         xmutex.lock();
00079         ymutex.lock();
00080         if(ballyvel > 0)
00081         {
00082             if(mazearr[ballx][bally+1] != 1)
00083             {
00084                 bally++;
00085             }
00086             else
00087             {
00088                 ballyvel = -ballyvel;
00089                 ms.play(wallbeep,tempo,wallbeep_len);
00090             }
00091         }
00092         else if (ballyvel < 0)
00093         {
00094             if(mazearr[ballx][bally-1] != 1)
00095             {
00096                 bally--;
00097             }
00098             else
00099             {
00100                 ballyvel = -ballyvel;
00101                 ms.play(wallbeep,tempo,wallbeep_len);
00102             }
00103         }
00104         xmutex.unlock();
00105         ymutex.unlock();
00106         Thread::wait(100-98*abs(ballyvel));
00107     }
00108 }
00109 
00110 int main() {
00111     //Overclock uLCD
00112     uLCD.baudrate(3000000);
00113     
00114     //Title Screen
00115     //displayTitle();
00116     
00117     //Display Maze
00118     loadLevel();
00119     displayMaze();
00120     
00121     //Music init
00122     ms.freq(240);
00123     ms.play(s1,tempo,s1_len);
00124     //ms.play(victory, tempo, victory_len);
00125     
00126     //Start physics engine threads
00127     Thread t1(xthread);
00128     Thread t2(ythread);
00129     
00130     //Initial velocity
00131     ballxvel = 0.5;
00132     ballyvel = -1;
00133         
00134     //Execution Loop
00135     while(1) {
00136         
00137         updateVelocity();
00138         updateBall();
00139         
00140     }
00141 }
00142 
00143 //This will be where the gyro values are used to accelerate/decelerate the ball
00144 void updateVelocity()
00145 {
00146     xmutex.lock();
00147     ymutex.lock();
00148     //These should be 0.0 - 1.0 values
00149     //ballxvel = 0.25;
00150     //ballyvel = -0.25;    //Note: positive yvel will send the ball DOWN due to the uLCD coordinate system
00151     xmutex.unlock();
00152     ymutex.unlock();
00153 }
00154 
00155 //Move the ball around and draw to the screen
00156 void updateBall()
00157 {
00158     xmutex.lock();
00159     ymutex.lock();
00160     
00161     uLCD.pixel(ballx_old,bally_old,BLACK);  //Wipe the old ball
00162     uLCD.pixel(ballx,bally,0xFFFF00);   //Out with the old in with the new!
00163     ballx_old = ballx;
00164     bally_old = bally;
00165     
00166     xmutex.unlock();
00167     ymutex.unlock();
00168     
00169     //Draw start/end zones
00170     uLCD.filled_rectangle(2,2,22,22,GREEN);
00171     uLCD.filled_rectangle(106,106,126,126,0xFFFF00);
00172     
00173     //Check victory condition
00174     if(ballx > 106 && bally > 106)
00175     {
00176         displayVictory();   
00177     }
00178 }
00179 
00180 //Take whats in the mazearr and write it
00181 void displayMaze()
00182 {
00183     //Clear previous maze
00184     uLCD.filled_rectangle(0, 0, 128, 128, BLACK);
00185     
00186     //Write in new maze
00187     for(int i = 0; i < 128; i++)
00188     {
00189         for(int j = 0; j < 128; j++)
00190         {
00191             if(mazearr[i][j] == 1)
00192             {
00193                 uLCD.pixel(i,j,RED);
00194             }
00195         }
00196     }
00197 }
00198 
00199 //This function will load a different map into the mazearray depending on the level selected
00200 void loadLevel()
00201 {
00202     //Load ball into starting zone
00203     ballx = 12;
00204     bally = 12;
00205     
00206     //Zero out the previous maze
00207     for(int i = 0; i < 128; i++)
00208     {
00209         for(int j = 0; j < 128; j++)
00210         {
00211             mazearr[i][j] = 0;
00212         }
00213     }
00214     
00215     //Load in test maze
00216     switch(gamestate)
00217     {
00218         case LEVEL1:
00219             //Load a test maze
00220             for(int i = 0; i <= 127; i++)
00221             {
00222                 mazearr[i][0] = 1;
00223                mazearr[i][127] = 1;
00224                mazearr[0][i] = 1;
00225                 mazearr[127][i] = 1;
00226             }
00227             for(int i = 0; i <= 100; i++)
00228             {
00229                mazearr[i][50] = 1;
00230             }
00231             for(int i = 0; i <= 75; i++) {
00232                mazearr[i][95] = 1;
00233             }
00234             for(int i = 50; i <= 75; i++) {
00235                 mazearr[50][i] = 1;
00236             }    
00237             break;
00238         
00239          case LEVEL2:
00240             //Load a test maze
00241             for(int i = 0; i <= 127; i++)
00242             {
00243                 mazearr[i][0] = 1;
00244                mazearr[i][127] = 1;
00245                mazearr[0][i] = 1;
00246                 mazearr[127][i] = 1;
00247             }
00248             for(int i = 0; i <= 100; i++)
00249             {
00250                mazearr[i][24] = 1;
00251             }
00252             for(int i = 100; i <= 125; i++) {
00253                mazearr[i][95] = 1;
00254             }
00255             for(int i = 100; i <= 125; i++) {
00256                 mazearr[95][i] = 1;
00257             }      
00258             for(int i = 40; i <= 65; i++) {
00259                 mazearr[i][i] = 1;
00260             }      
00261              for(int i = 80; i <= 95; i++) {
00262                 mazearr[i][i] = 1;
00263             } 
00264             break;
00265         
00266     }    
00267 }
00268 
00269 //Victory screen - 5 sec delay and then next level
00270 void displayVictory()
00271 {
00272     //Lock out physics engine (hacky way to stop ball movement)
00273     xmutex.lock();
00274     ymutex.lock();
00275     
00276     ms.play(victory, tempo, victory_len);
00277             
00278     //Move ball to start zone
00279     ballx = 12;
00280     bally = 12;
00281     
00282     while(1)
00283     {
00284         uLCD.text_width(2);
00285         uLCD.text_height(2);
00286         uLCD.locate(1,3);
00287         uLCD.printf("VICTORY!");
00288         wait(5);
00289         if (gamestate == LEVEL1)
00290         {
00291             gamestate = LEVEL2;
00292             loadLevel();
00293             displayMaze();
00294             wait(1);
00295             break;
00296         }
00297     } 
00298     xmutex.unlock();
00299     ymutex.unlock();
00300 }
00301 
00302 //Game title screen
00303 void displayTitle()
00304 {
00305     while(1)
00306     {
00307         uLCD.text_width(2);
00308         uLCD.text_height(2);
00309         uLCD.locate(0,0);
00310         uLCD.printf("SuperMbed");        
00311         uLCD.text_width(2);
00312         uLCD.text_height(3);
00313         uLCD.locate(2,1);
00314         uLCD.printf("Ball!");
00315     }
00316 }