Full IPOD Like GUI Demo - MBED + SmartGPU2 board

Dependencies:   SMARTGPU2 mbed

Revision:
0:9ec50d21947d
Child:
1:2845aaa91e22
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Jul 10 03:29:21 2013 +0000
@@ -0,0 +1,766 @@
+/**************************************************************************************/
+/*SMARTGPU2 intelligent embedded graphics processor unit
+ those examples are for use the SMARTGPU2 with the mbed microcontoller, just connect tx,rx,and reset
+ Board:
+ http://vizictechnologies.com/#/smart-gpu-2/4577779046
+ 
+ www.vizictechnologies.com 
+ Vizic Technologies copyright 2013 */
+/**************************************************************************************/
+
+#include "mbed.h"
+#include "SMARTGPU2.h"
+#include "stdlib.h"
+
+SMARTGPU2 lcd(TXPIN,RXPIN,RESETPIN);  //create our object called "lcd"
+
+//defines for GUI
+#define HALFX 240/2
+#define HALFY 320/2
+
+//declare our structures POINT and ICON
+POINT point;
+ICON icon;
+       
+//array to store file names 25 characters max, also used as working file array
+char name[25];
+
+//Array with the names of the icons under "FullGUI/Ics" folder, names of 25 characters max
+#define TOTALICONS  13          //number of available icons, current sketch supports 25 icons max
+const char iconNames[TOTALICONS][25]={"backlight","calculator","clock","games","maps","media","notes","photos","wifi","settings","calls","music","wall"};
+
+//array used by games
+#define MOLEHOLE 3        //position of the array where mole hole image is contained
+#define HITMOLE 4         //position of the array where hit mole image is contained
+#define MISSMOLE 5        //position of the array where miss mole image is contained
+const char moleType[6][9]={"MoleHap","MoleSee","MoleBad","MoleHole","MolePun","MoleMiss"}; //array containing the names of the different called images    
+
+//General/Miscellaneous Functions
+/**************************************************/
+/**************************************************/
+/**************************************************/
+unsigned char getTouchIconMainMenu(void){
+  unsigned int icPress;  
+
+  while(lcd.touchScreen(&point)==INVALID);      //wait for a touch  
+  //PROCEDURE TO DIVIDE THE TOUCHSCREEN AREA IN 4 x 5 EQUAL PARTS--------------------------------------------
+  //Divide screen into 4 equal horizontal parts for icons
+  icPress= (point.x/(LCD_HEIGHT/4)) + 1; //LCD_HEIGHT is 240    
+  //Divide Screen into 5 equal vertical parts for icons
+  icPress = icPress + (((point.y)/(LCD_WIDTH/5)) * 4); //LCD_WIDTH is 320
+  //------------------------------------------------------------------------------------------------- 
+ return icPress; //return decoded coordinate from 1 to 20
+}
+
+//obtain from EEPROM FLASH memory the name of the current stored wallpaper on the "name" array
+void getCurrentWallFromEEPROM(void){
+  NUMBEROFBYTES bytesRead;
+  lcd.fillBuffFromEEPROMPage(PAGE0); //copy PAGE0 to EEPROM RAM buffer
+  lcd.readEEPROMBuff(name,0,14,&bytesRead);   //read 14 bytes of the EEPROM RAM buffer to name array, wallpapers must not exceed 14 chars in name lenght
+  if(strstr(name, 0x00) != 0x00){    //find a null character in name, if not find, add the 0x00 NULL character
+    name[0] = 0x00;
+  }
+}
+
+//save current contents of "name" array on EEPROM PAGE0 at address 0x0000
+void saveWallpaperToEEPROM(void){
+  NUMBEROFBYTES bytesWritten;
+  lcd.initClearEEPROMBuff();                  //Initialize EEPROM RAM Buffer
+  lcd.writeEEPROMBuff(name,0,sizeof(name),&bytesWritten); //write all the contents of "name" array to EEPROM RAM Buffer
+  lcd.eraseEEPROMPage(PAGE0);                 //erase all contents on the PAGE0
+  lcd.saveBuffToEEPROMPage(PAGE0);            //now save to EEPROM PAGE0 the contents of the EEPROM RAM Buffer(the name array + 0xFFs)
+}
+
+/**************************************************/
+void drawHeader(char *text){
+  NUMBEROFBYTES charsPrinted;
+  unsigned int batteryPercentage = 65;  
+  //draw header and text
+  lcd.drawRectangle(0,0,MAX_X_PORTRAIT,13,BLACK,FILL);  //draw upper bar
+  lcd.setTextSize(FONT0);
+  lcd.setTextColour(WHITE);
+  lcd.setTextBackFill(TRANS);
+  lcd.string(2,0,MAX_X_PORTRAIT,20,"Vizic",&charsPrinted);          //draw Vizic string
+  lcd.string(85,0,MAX_X_PORTRAIT,20,text,&charsPrinted);            //draw string
+  //draw battery icon according to the battery percentage variable
+  lcd.drawRectangle(215,0,215+((batteryPercentage*15)/100),10,GREEN,FILL);
+  lcd.drawRectangle(215,0,230,10,WHITE,UNFILL);
+  lcd.drawRectangle(230,4,232,6,WHITE,FILL);  
+}
+
+//Cuts the .ext and updates the name
+void cutFileExtension(char *name, char *ext){
+  char *pch;
+  pch=strstr(name,ext);        //find the .ext extension to the name
+  strncpy(pch,0x00,1);         //cut/replace the .ext extension for the NULL 0x00 character      
+}
+
+ //This function call the desired image in the position of the desired hole - used by games()
+void showMole(char mole, char hole){  
+  switch(hole){
+    case 1:
+      lcd.imageBMPSD(38,70,(char*)moleType[mole]); // hole 1
+    break;
+    case 2:
+      lcd.imageBMPSD(138,70,(char*)moleType[mole]); // hole 2
+    break;  
+    case 3:
+      lcd.imageBMPSD(240,70,(char*)moleType[mole]); // hole 3
+    break;    
+    case 4:
+      lcd.imageBMPSD(38,147,(char*)moleType[mole]); // hole 4
+    break;  
+    case 5:
+      lcd.imageBMPSD(138,147,(char*)moleType[mole]); // hole 5
+    break;
+    case 6:
+      lcd.imageBMPSD(240,147,(char*)moleType[mole]); // hole 6
+    break;
+    default:
+    break;
+  } 
+}
+
+//This function returns 1 if a touch has been made in a specified hole -used by games
+char touchOnHole(char hole){
+  char hit=0; 
+  switch(hole){
+    case 1:
+      if(point.x>0 && point.x<111 && point.y>65 && point.y<146) hit=1;   //check if the last touch was inside this area
+    break;
+    case 2:
+      if(point.x>110 && point.x<211 && point.y>65 && point.y<146) hit=1; //check if the last touch was inside this area
+    break;  
+    case 3:
+      if(point.x>210 && point.x<320 && point.y>65 && point.y<146) hit=1; //check if the last touch was inside this area
+    break;    
+    case 4:
+      if(point.x>0 && point.x<111 && point.y>145 && point.y<240) hit=1;  //check if the last touch was inside this area
+    break;  
+    case 5:
+      if(point.x>110 && point.x<211 && point.y>145 && point.y<240) hit=1;//check if the last touch was inside this area
+    break;
+    case 6:
+      if(point.x>210 && point.x<320 && point.y>145 && point.y<240) hit=1;//check if the last touch was inside this area
+    break;
+    default:
+    break;
+  }  
+  return hit;  
+}
+
+ //function used by music
+void drawControlRR(ACTIVE state){
+  //draw button
+  lcd.objButton(0,265,79,315,state,"");
+  //draw symbol
+  lcd.drawTriangle(0+10,265+((315-265)/2),0+39,265+10,0+39,315-10,BLACK,FILL);
+  lcd.drawTriangle(0+39,265+((315-265)/2),0+79-10,265+10,0+79-10,315-10,BLACK,FILL);
+}
+
+//function used by music
+void drawControlFF(ACTIVE state){
+  //draw button  
+  lcd.objButton(160,265,MAX_X_PORTRAIT,315,state,"");    
+  //draw symbol
+  lcd.drawTriangle(160+10,265+10,160+10,315-10,160+39,265+((315-265)/2),BLACK,FILL);  
+  lcd.drawTriangle(160+39,265+10,160+39,315-10,239-10,265+((315-265)/2),BLACK,FILL);  
+} 
+
+//function used by music
+void drawControlPLAY(char symbol){
+  //draw button  
+  lcd.objButton(80,265,159,315,SELECTED,"");  
+  //draw symbol
+  if(symbol){      //PLAY
+    lcd.drawTriangle(80+10,265+10,80+10,315-10,159-10,265+((315-265)/2),BLACK,FILL);
+  }else{           //PAUSE
+    lcd.drawRectangle(80+10,265+10,80+10+25,315-10,BLACK,FILL);
+    lcd.drawRectangle(159-10-25,265+10,159-10,315-10,BLACK,FILL);
+  }
+}
+
+//function that draws buttons and current progress bar - used by media
+void drawButtonsAndProgress(unsigned long currFrame, unsigned long totFrames){
+  lcd.objButton(0,200,159,230,DESELECTED,"Continue");
+  lcd.objButton(161,200,MAX_X_LANDSCAPE,230,DESELECTED,"Return...");
+  lcd.drawRectangle(0,170,(currFrame*MAX_X_LANDSCAPE)/(totFrames),190,RED,FILL);                 //scale currentFrame value to 0-319 pixels
+  lcd.drawRectangle((currFrame*MAX_X_LANDSCAPE)/(totFrames),170,MAX_X_LANDSCAPE,190,BLACK,FILL); //scale currentFrame value to 0-319 pixels 
+}
+
+//Main applications, the next applications are called by the main loop menu
+/**************************************************/
+/**************************************************/
+/**************************************************/
+//draws Main Menu
+void drawMainMenu(void){  
+  unsigned int i=0, x=8, y=20;
+  SMARTGPUREPLY res;
+  char aux[25];
+
+  strcpy(aux,"Wall/");                      //copy to name the string "Wall/"
+  getCurrentWallFromEEPROM();                   //fill global "name" array with the current EEPROM Stored name
+  strcat(aux,name);                             //concatenate the currentWall name to "Wall/"
+  if(lcd.imageBMPSD(0,0,aux)!=OK) lcd.erase();  //try to draw WallPaper Image, if fail, just erase screen
+  //now draw all top icons
+  lcd.SDFopenDir("Ics");                     //open the folder with the icons
+  while(i<TOTALICONS){                       
+    res=lcd.imageBMPSD(x,y,(char*)iconNames[i++]);  //try to draw icon and advance i
+    if(res == OK){                           //draw icon file, only if command success then advance x and y position
+      x+=50+8;                               //advance the icon size 50 + 8 the space between icons
+      if(x>230){                             //if x > 230, means we have reach the end of file and must advance 1 coloumn
+        x=8;                                 //reset x
+        y+=50+10;                            //advance the icon size 50 + 10 the space between icons
+        if(y>300) break;                     //if there are more than 20 icons, break and ignore, current sketch supports only 20 icons max
+      }
+    }
+  }
+  lcd.SDFopenDir("..");                      //return/go up to parent dir one level
+  drawHeader("Main Menu");
+  wait_ms(350);                              //A little delay to avoid fast image changing   
+}
+
+/**************************************************/
+void backlight(void){
+  static unsigned char currentBacklightValue=100; //0-100
+  NUMBEROFBYTES charsPrinted;
+  
+  lcd.drawGradientRect(0,0,MAX_X_PORTRAIT,MAX_Y_PORTRAIT,BLACK,MAGENTA,VERTICAL); //draw a fullscreen gradient rectangle
+  lcd.setTextSize(FONT3);
+  lcd.setTextColour(WHITE);
+  lcd.setTextBackFill(TRANS);
+  lcd.string(40,45,MAX_X_PORTRAIT,MAX_Y_PORTRAIT,"Brightness Bar",&charsPrinted);
+  lcd.objSlider(10,80,MAX_X_PORTRAIT-10,150,currentBacklightValue,101,HORIZONTAL);
+  lcd.objButton(10,280,MAX_X_PORTRAIT-10,310,DESELECTED,"Return");
+  drawHeader("Adjustments:");  
+  while(1){
+    while(lcd.touchScreen(&point)==INVALID);//wait for a touch on screen to do something
+    if((point.x>10) && (point.x<MAX_X_PORTRAIT-10) && (point.y>80) && (point.y<150)){  //if touch inside brightness bar
+      currentBacklightValue= ((point.x-10)*100)/(MAX_X_PORTRAIT-10-10);                //scale obtained touch value to 0-100
+      lcd.objSlider(10,80,MAX_X_PORTRAIT-10,150,currentBacklightValue,101,HORIZONTAL); //update slider
+      lcd.bright(currentBacklightValue);                                               //set new brightness value
+      wait_ms(150);
+    }
+    if(point.y>280){ //if touch inside return button
+      lcd.objButton(10,280,MAX_X_PORTRAIT-10,310,SELECTED,"Return");
+      wait_ms(300);
+      return; //exit function
+    }     
+  }
+}
+
+/**************************************************/
+void clocks(void){
+  int hours=4,mins=48,secs=0,i=0;
+  int xs,ys,xm,ym,xh,yh;
+  int angleH,angleM,angleS;
+  int handHour=55;//hand size
+  int handMin=70; //hand size
+  int handSec=75; //hand size 
+  
+  lcd.drawGradientRect(0,0,MAX_X_PORTRAIT,MAX_Y_PORTRAIT,BLACK,MAGENTA,VERTICAL); //draw a fullscreen gradient rectangle
+  lcd.objButton(10,280,MAX_X_PORTRAIT-10,310,DESELECTED,"Return");
+  drawHeader("Clocks:");    
+  //drawClock Body
+  lcd.drawCircle(HALFX,HALFY,80,BLACK,FILL);
+  lcd.drawCircle(HALFX,HALFY,80,WHITE,UNFILL);  
+  
+  while(1){
+    //Do some Math to get the second point of the clock hands. (first point is always the center of the clock)
+    angleS=secs*6;                           //get the current seconds in angle form, a circle have 360 degrees divided by 60 seconds = 6, then we multiply the 6 by the current seconds to get current angle
+    xs=(sin((angleS*3.14)/180)) * handSec;   //get X component of the second's hand
+    ys=(cos((angleS*3.14)/180)) * handSec;   //get Y component of the second's hand
+    angleM=mins*6;                           //get the current minutes in angle form, a circle have 360 degrees divided by 60 minutes = 6, then we multiply the 6 by the current minutes to get current angle
+    xm=(sin((angleM*3.14)/180)) * handMin;   //get X component of the minutes's hand
+    ym=(cos((angleM*3.14)/180)) * handMin;   //get Y component of the minutes's hand 
+    angleH=hours*30;                         //get the current hours in angle form, a circle have 360 degrees divided by 12 hours = 30, then we multiply the 30 by the current hours to get current angle
+    xh=(sin((angleH*3.14)/180)) * handHour;  //get X component of the hours's hand
+    yh=(cos((angleH*3.14)/180)) * handHour;  //get Y component of the hours's hand
+     
+    //Draw current time hands  
+    lcd.drawLine(HALFX,HALFY,HALFX+xm,HALFY-ym,WHITE); // Draw the minutes hand, first point is the center of the clock, and the second is the point obtained by doing math
+    lcd.drawLine(HALFX,HALFY,HALFX+xh,HALFY-yh,WHITE); // Draw the hours hand, first point is the center of the clock, and the second is the point obtained by doing math
+    lcd.drawLine(HALFX,HALFY,HALFX+xs,HALFY-ys,RED);   // Draw the seconds hand, first point is the center of the clock, and the second is the point obtained by doing math
+    lcd.drawCircle(HALFX,HALFY,3,RED,FILL);            // Draw the center of the second's hand
+ 
+    for(i=0;i<10;i++){                                 //loop for 10 times a delay of 100ms asking for a touch - this gives a total delay of 1 second
+      if(lcd.touchScreen(&point)==VALID){ //ask for a touch on screen to do something
+        if(point.y>280){ //if touch inside return button
+          lcd.objButton(10,280,MAX_X_PORTRAIT-10,310,SELECTED,"Return");
+          wait_ms(300);
+          return; //exit function
+        }    
+      }
+      wait_ms(100);
+    }
+  
+    //time managing
+    secs++;                                         // increase seconds
+    if(secs==60){                                   // if we reach 60 seconds
+      mins++;                                       // increase the minutes
+      if(mins==60){                                 // if we reach 60 minutes
+        hours++;                                    // increase the minutes
+        if(hours==12){                              // if we reach 12 hours
+          hours=0;                                  // clear hours
+        } 
+        mins=0;                                     // clear minutes
+      }            
+      secs=0;                                       // clear seconds
+    }                      
+    //Erase all hands         
+    lcd.drawLine(HALFX,HALFY,HALFX+xs,HALFY-ys,BLACK); // Erase Second's hand
+    lcd.drawLine(HALFX,HALFY,HALFX+xm,HALFY-ym,BLACK); // Erase Minute's hand
+    lcd.drawLine(HALFX,HALFY,HALFX+xh,HALFY-yh,BLACK); // Erase Hour's hand            
+  } 
+}  
+
+/**************************************************/
+void photos(void){
+  unsigned int dirs=0,pics=0;
+  static unsigned int i=0;           //static to save last image position even we exit function
+  NUMBEROFBYTES charsPrinted;
+  
+  lcd.orientation(LANDSCAPE_LEFT);  //set orientation as landscape
+  lcd.setTextColour(WHITE);
+  lcd.setTextSize(FONT3);
+  lcd.setTextBackFill(TRANS);
+  lcd.drawGradientRect(0,0,MAX_X_LANDSCAPE,MAX_Y_LANDSCAPE,BLACK,MAGENTA,VERTICAL);
+  lcd.string(80,110,MAX_X_LANDSCAPE,MAX_Y_LANDSCAPE,"Photo Gallery",&charsPrinted);
+  lcd.setTextSize(FONT2);  
+  wait_ms(1000);
+  lcd.SDFopenDir("Photos");          //open the folder with the photos
+  lcd.SDFgetList(&dirs,&pics);           //get number of files/Pics under the current folder "Photos"
+  
+  while(1){  
+    lcd.SDFgetFileName(i,name);                        //get the name of the pic file number i
+    cutFileExtension(name,".bmp");                     //cut to name the .bmp extension
+    lcd.imageBMPSD(0,0,name);                          //Load image from SD card, all images are 320x240(full screen) so we load them from top left corner X:0,Y:0
+    wait_ms(200);                                      //A little delay to avoid fast image changing    
+    lcd.string(60,220,319,239,"<Tap center to Exit>",&charsPrinted); //Show text
+    while(lcd.touchScreen(&point)==INVALID);           //wait for a touch to do something    
+    //check if we go to the next image, or to the previous one
+    if(point.x>219){                                   //if the received touch was on the right corner of the screen we advance the image, else we decrease and go to previous image
+      i++;                                             //decrease image selector
+      if(i>=pics){                                     //if we reach the position of the last image, we restart to image 0
+        i=0;                 
+      }        
+    }
+    else if(point.x<100){
+      if(i>0){                                         //if we can decrease i
+        i--;    
+      }else{                                           //if we decrease i will be less than zero, so we move to last image instead
+        i=pics-1;  
+      }
+    }
+    else{                                              //touch on center, EXIT      
+      break;
+    }   
+  }
+  lcd.SDFopenDir("..");                                //return/go up to parent dir one level
+  lcd.orientation(PORTRAIT_LOW);                       //change to portrait mode    
+  wait_ms(300);
+}
+
+/**************************************************/
+void media(){
+  unsigned int i=0, row=0, vids=0;
+  unsigned long currentFrame=0, currentSecond=0;
+  VIDDATA videoData;
+  NUMBEROFBYTES charsPrinted;
+  
+  lcd.orientation(LANDSCAPE_LEFT);   //set orientation as landscape
+  lcd.setTextColour(WHITE);
+  lcd.setTextSize(FONT3);
+  lcd.setTextBackFill(TRANS);
+  lcd.drawGradientRect(0,0,MAX_X_LANDSCAPE,MAX_Y_LANDSCAPE,BLACK,MAGENTA,VERTICAL);
+  lcd.string(80,110,MAX_X_LANDSCAPE,MAX_Y_LANDSCAPE,"Video Player",&charsPrinted);
+  lcd.stopWAVFile();                 //stop current playing song if any   
+  wait_ms(1000);
+  lcd.SDFopenDir("Videos");          //open the folder with the videos
+  lcd.setTextSize(FONT2);
+
+  while(1){
+    lcd.drawGradientRect(0,0,MAX_X_LANDSCAPE,MAX_Y_LANDSCAPE,BLACK,MAGENTA,VERTICAL);
+    lcd.string(5,0,MAX_X_LANDSCAPE,MAX_Y_LANDSCAPE,"Available Videos:      (EXIT)",&charsPrinted);
+    i=0; row=1; vids=0;
+    while(1){                          //list names
+      lcd.SDFgetFileName(i++,name);    //get the name of the vid file number i
+      if(name[0]==0x00) break;         //if name is invalid, meand end of files 
+      if(strstr(name,".vid")!=0x00){   //if .vid extension is found in the file name: print      
+        lcd.objButton(15,(row*30),MAX_X_LANDSCAPE-15,30+(row*30),DESELECTED,name);  row++;
+        vids++;  
+      }//else ignore name/file
+    }
+    
+    while(lcd.touchScreen(&point)==INVALID); //wait for a touch to perform action
+    row=point.y/30;                    //decode touch point by dividing it by 30 (240/8) which gives the 30 pixels spacing between buttons
+    if(row==0){                        //touch on header (EXIT);
+      lcd.SDFopenDir("..");            //return/go up to parent dir one level
+      lcd.orientation(PORTRAIT_LOW);   //change to portrait mode     
+      wait_ms(300); 
+      return;                          //EXIT media()
+    }else if(row > vids) continue;     //if touch on invalid row, where no button is present, go to top while(1)
+    i=0;
+    while(row){ //get name of obtained row
+      lcd.SDFgetFileName(i++,name);    //get the name of the vid file number i  
+      if(strstr(name,".vid")!=0x00) row--;   //if .vid extension is found in the file name: decrease row variable
+    }
+    //Try to play video
+    cutFileExtension(name,".vid");    //cut to name the .vid extension  
+    if(lcd.allocateVideoSD(name,&videoData)!=OK) continue; //try to allocate video, if fail, continue to top while(1)
+    //up to here video is successfully allocated..
+    currentFrame=0;  currentSecond=0; //reset variables
+    lcd.playWAVFile(name,&charsPrinted); //open audio if any, must be named the same as the video expept for the .extension
+    while(1){
+      if(lcd.playVideoSD(0,0,videoData.framesPerSec)!=OK) break; //play video for 1 second(this equal the obtained frames per second parameter) break if error
+      currentSecond++; currentFrame+=videoData.framesPerSec;
+      if(lcd.touchScreen(&point)==VALID){  //check about each ~1 second for a touch, if Valid:
+        lcd.pauseWAVFile();           //stop audio
+        //draw buttons and progress bar
+        drawButtonsAndProgress(currentFrame, videoData.totalFrames);
+        wait_ms(300);
+        while(1){
+          while(lcd.touchScreen(&point)==INVALID || point.y<170); //while no valid touch or touch outside buttons
+          if(point.y > 200) break;                              //if touch on buttons, break while(1) and go to next ifs
+          //advance file to received touch in progress bar value...
+          currentFrame=((unsigned long)point.x * (unsigned long)videoData.totalFrames) / MAX_X_LANDSCAPE; //obtain new current frame value 0-319
+          currentFrame= (currentFrame/(unsigned long)videoData.framesPerSec)*((unsigned long)videoData.framesPerSec); //convert currentFrame to a factor of videoData.framesPerSecond
+          currentSecond=(currentFrame/(unsigned long)videoData.framesPerSec);
+          lcd.setFrameVideoSD(currentFrame);                    //set new obtained frame
+          lcd.playVideoSD(0,0,1);                               //show new frame
+          lcd.advanceWAVFile(currentSecond);                    //set new value to audio file
+          //update buttons and progress bar
+          drawButtonsAndProgress(currentFrame, videoData.totalFrames);
+          wait_ms(50);
+        }
+        if(point.x < 160){           //touch on continue button
+          lcd.objButton(0,200,159,230,SELECTED,"Continue");
+          wait_ms(300);
+          lcd.pauseWAVFile();        //resume audio
+        }else{                       //touch on return button
+          lcd.objButton(161,200,319,230,SELECTED,"Return...");
+          lcd.stopWAVFile();
+          wait_ms(300);
+          break;                     //exit playback        
+        }
+      }
+    }          
+  }
+}
+
+/**************************************************/
+void notes(){
+  lcd.imageBMPSD(0,0,"Misc/notes");          //load notes design
+  lcd.objButton(10,280,MAX_X_PORTRAIT-10,310,DESELECTED,"Return");
+  drawHeader("Adjustments:");
+  wait_ms(200);                              //A little delay to avoid fast image changing
+
+  while(1){    
+    while(lcd.touchScreen(&point)==INVALID); //wait for a touch to do something    
+    if(point.y<65){                          //Touch on upper Icons
+      //clear note block
+      lcd.imageBMPSD(0,0,"Misc/notes");      //load notes design
+      lcd.objButton(10,280,MAX_X_PORTRAIT-10,310,DESELECTED,"Return");
+      drawHeader("Note pad:");
+    }else if(point.y<280){                   //touch on notepad
+      lcd.drawCircle(point.x,point.y,1,BLACK,FILL); //draw         
+    }else{                                   //touch on return button
+      lcd.objButton(10,280,MAX_X_PORTRAIT-10,310,SELECTED,"Return");    
+      wait_ms(300);
+      return;                                //exit
+    }                                
+  }                                 
+}
+
+/**************************************************/
+void games(){
+  int x;
+  char hitFlag=0,hole,mole,moleCounter=20,points=0,pointsTotal[4]="00 ";        //array to store the points
+  NUMBEROFBYTES charsPrinted;
+  
+  lcd.orientation(LANDSCAPE_LEFT); //set orientation as landscape  
+  lcd.SDFopenDir("Games");          //Open the Games folder that contains the images of the Application
+
+ while(1){                         //loop forever
+  lcd.drawGradientRect(0,0,MAX_X_LANDSCAPE,MAX_Y_LANDSCAPE,BLACK,MAGENTA,VERTICAL); 
+  lcd.setTextColour(WHITE);
+  lcd.setTextSize(FONT5);
+  lcd.setTextBackFill(TRANS);  
+  lcd.string(10,80,MAX_X_LANDSCAPE,MAX_Y_LANDSCAPE,"MOLE STOMP!!!",&charsPrinted); //show name string
+  wait_ms(1000);  
+  lcd.string(22,130,MAX_X_LANDSCAPE,MAX_Y_LANDSCAPE,"GET READY!!!",&charsPrinted); //show ready string
+  wait_ms(1500);
+  lcd.imageBMPSD(0,0,"MoleArea");  //show area   
+  lcd.setTextSize(FONT2);
+  lcd.setTextBackFill(FILLED); 
+  lcd.setTextBackColour(BLUE);     //set the all text background to blue  
+  
+  //Start the game!
+  while(moleCounter>0){            //loop the game while moleCounter reaches zero moles
+    mole=rand()%3;                 //get a random mole 0-2
+    hole=rand()%7;                 //get a random hole 0-6
+    showMole(mole,hole);           //show the random mole on the random hole
+    for(x=0;x<3000;x++){            //wait some time for the player hit the mole(less time=more difficulty, more time=easy play)
+      if(lcd.touchScreen(&point)==VALID){  //if we receive a touch on screen
+        if(touchOnHole(hole)){     //if the touch is on the hole of the current mole
+          hitFlag=1;               //turn on the hit mole flag
+          break;                   //end the waiting time
+        }
+        if(point.x > 270 && point.y < 50) moleCounter=0; //touch on X symbol, end game
+      }  
+    }
+    if(hitFlag==1){               //if the last mole was hit
+      showMole(HITMOLE,hole);     //we show the hit mole
+      points++;                   //increase hit mole counter or points
+      hitFlag=0;                  //clear the hit flag
+    }else{                        //if the last mole was missed
+      showMole(MISSMOLE,hole);    //show the mole hiding
+    }
+    pointsTotal[0]=(points/10)+0x30;  //get the tens of the points and convert them to ascii
+    pointsTotal[1]=(points%10)+0x30;  //get the ones of the points and convert them to ascii
+    lcd.string(33,27,100,100,pointsTotal,&charsPrinted); //draw the points  
+    wait_ms(350);
+    showMole(MOLEHOLE,hole);          //show the bare hole
+    moleCounter--;                    //decrease the mole counter
+  }
+  
+  //Game over, display results
+  lcd.setTextColour(YELLOW);
+  lcd.setTextSize(FONT3);
+  lcd.setTextBackFill(TRANS);    
+  lcd.string(80,50,300,220,"Whacked Moles:",&charsPrinted);   
+  lcd.setTextColour(BLUE);  
+  lcd.string(153,75,300,220,pointsTotal,&charsPrinted); //draw the converted to ascii points array 
+  lcd.setTextColour(RED);  
+  lcd.setTextSize(FONT2);  
+  lcd.string(50,140,319,239,"TOUCH TO RESTART",&charsPrinted);
+  lcd.objButton(10,200,MAX_X_LANDSCAPE-10,230,DESELECTED,"Return");
+  wait_ms(1000);
+
+  while(lcd.touchScreen(&point)==INVALID);   //wait for a touch on screen to restart or exit
+  if(point.y>200){                           //touch on return button
+    lcd.objButton(10,200,MAX_X_LANDSCAPE-10,230,SELECTED,"Return");
+    break;                                   //exit while(1) loop
+  }//else re-start game
+  moleCounter=20;                   //reset the moleCounter
+  points=0;                         //reset points
+  lcd.erase();                      //erase screen and restart all
+ }   
+  lcd.SDFopenDir("..");                                //return/go up to parent dir one level
+  lcd.orientation(PORTRAIT_LOW);                       //change to portrait mode    
+  wait_ms(300);
+}
+
+/**************************************************/
+void music(){
+  STATE state; static char pause=1;
+  unsigned int dirs=0,songs=0;
+  static unsigned int currentSong=0, volume=100;//static to save current song and volume even we exit function
+  NUMBEROFBYTES charsPrinted;
+  
+  lcd.SDFopenDir("Music");          //Open the folder that contains the songs in .wav format
+  lcd.SDFgetList(&dirs,&songs);     //get number of files/songs under the current folder "Music"
+  
+  lcd.setTextColour(WHITE);
+  lcd.setTextSize(FONT3);
+  lcd.setTextBackFill(TRANS);
+  lcd.drawGradientRect(0,0,MAX_X_PORTRAIT,MAX_Y_PORTRAIT,BLACK,MAGENTA,VERTICAL);
+  lcd.string(50,140,MAX_X_PORTRAIT,MAX_Y_PORTRAIT,"Music Player",&charsPrinted);
+  wait_ms(1000);
+  lcd.erase();  
+  drawHeader("Music:");
+  lcd.getWAVPlayState(&state);      //get playing state
+  if(state==DISABLE) pause=1;       //if not playing, set pause to active
+  drawControlPLAY(pause);           //draw button according to pause
+  drawControlRR(DESELECTED);
+  drawControlFF(DESELECTED); 
+  //draw current volume bar
+  lcd.drawRectangle(0,245,(volume*MAX_X_PORTRAIT)/(100),260,YELLOW,FILL);  //scale volume value to 0-239 pixels
+  lcd.drawRectangle((volume*MAX_X_PORTRAIT)/(100),245,319,260,BLACK,FILL); //scale volume value to 0-239 pixels 
+    
+  while(1){
+    lcd.getWAVPlayState(&state);                         //get playing state  
+    if(state==DISABLE){pause=1; drawControlPLAY(pause);} //if not playing, set pause to active and update button
+    if(pause==0) lcd.drawGradientRect(0,70,MAX_X_PORTRAIT,240,(rand()%0xFFFF),(rand()%0xFFFF),HORIZONTAL);
+    
+    wait_ms(100);
+    if(lcd.touchScreen(&point)==VALID){           //ask for touch and if valid..
+      if(point.y>265){                            //Touch on controls
+        if(point.x<80){                           //touch on << icon
+          drawControlRR(SELECTED);
+          lcd.advanceWAVFile(0);                  //rewind song to beginning
+          wait_ms(300);                           //wait                    
+          drawControlRR(DESELECTED);
+        }else if(point.x<160){                    //touch on Play/Pause icon
+          if(state == ENABLE){                    //if playing
+            lcd.pauseWAVFile();                   //pause playing
+            pause=!pause;
+          }else{                                  //begin to play any song
+            lcd.SDFgetFileName(currentSong,name); //get the name of the song file number currentSong
+            cutFileExtension(name,".wav");        //cut to name the .wav extension
+            lcd.playWAVFile(name,&charsPrinted); //play file - returns the duration of the song in seconds
+            lcd.drawRectangle(0,25,MAX_X_PORTRAIT,70,BLACK,FILL);   //erase previous name
+            lcd.string(10,30,MAX_X_PORTRAIT,MAX_Y_PORTRAIT,name,&charsPrinted); //print new name
+            pause=0; 
+          }        
+          wait_ms(300);          
+        }else{ //point.x<240                      //touch on >> icon
+          drawControlFF(SELECTED);
+          lcd.stopWAVFile();                      //stop current playing song if any
+          currentSong++;                          //advance current song
+          if(currentSong>=songs) currentSong=0;   //check
+          lcd.SDFgetFileName(currentSong,name);   //get the name of the song file number currentSong
+          cutFileExtension(name,".wav");          //cut to name the .wav extension
+          lcd.playWAVFile(name,&charsPrinted);    //play file
+          lcd.drawRectangle(0,25,MAX_X_PORTRAIT,70,BLACK,FILL);   //erase previous name
+          lcd.string(10,30,MAX_X_PORTRAIT,MAX_Y_PORTRAIT,name,&charsPrinted); //print new name         
+          pause=0;
+          wait_ms(300);                             //wait          
+          drawControlFF(DESELECTED);
+        }
+        drawControlPLAY(pause);                   //update button        
+      }else if(point.y>240){                      //Touch on volume bar
+        volume=(point.x*100)/MAX_X_PORTRAIT;      //obtain new volume parameter by scaling to 0-239 pixels
+        lcd.setVolumeWAV(volume);                 //set new volume to SmartGPU Audio
+        //update volume bar
+        lcd.drawRectangle(0,245,(volume*MAX_X_PORTRAIT)/(100),260,YELLOW,FILL);             //scale volume value to 0-239 pixels
+        lcd.drawRectangle((volume*MAX_X_PORTRAIT)/(100),245,MAX_X_PORTRAIT,260,BLACK,FILL); //scale volume value to 0-239 pixels         
+        wait_ms(50);
+      }else if(point.y<20){                       //if touch on main header, go to main menu
+        lcd.SDFopenDir("..");                     //return/go up to parent dir one level
+        wait_ms(300);      
+        return;
+      }
+    } 
+  }
+}
+
+/**************************************************/
+void wallpaper(){
+  unsigned int dirs=0,walls=0, i=0;
+  NUMBEROFBYTES charsPrinted;
+  
+  lcd.SDFopenDir("Wall") ;          //Open the folder that contains the wallpaper images
+  lcd.SDFgetList(&dirs,&walls);     //get number of files/Pics under the current folder "Wall"
+  
+  lcd.setTextColour(WHITE);
+  lcd.setTextSize(FONT3);
+  lcd.setTextBackFill(TRANS);
+  lcd.drawGradientRect(0,0,MAX_X_PORTRAIT,MAX_Y_PORTRAIT,BLACK,MAGENTA,VERTICAL);
+  lcd.string(55,140,MAX_X_PORTRAIT,MAX_Y_PORTRAIT,"Wallpapers",&charsPrinted);
+  wait_ms(1000);
+ 
+  while(1){  
+    lcd.SDFgetFileName(i,name);                        //get the name of the wall file number i
+    cutFileExtension(name,".bmp");                     //cut to name the .bmp extension
+    lcd.imageBMPSD(0,0,name);                          //Load image from SD card, all images are 240x320(full screen) so we load them from top left corner X:0,Y:0
+    drawHeader("Wallpapers:");
+    wait_ms(200);                                      //A little delay to avoid fast image changing    
+    lcd.objButton(10,25,MAX_X_PORTRAIT-10,55,DESELECTED,"Set as Wall");    
+    lcd.objButton(10,280,MAX_X_PORTRAIT-10,310,DESELECTED,"Return");
+    
+    while(lcd.touchScreen(&point)==INVALID);           //wait for a touch to do something    
+    
+    if(point.y > 280){                                 //if touch on "return" button, break to exit while(1);
+      lcd.objButton(10,280,MAX_X_PORTRAIT-10,310,SELECTED,"Return");
+      lcd.SDFopenDir("..");                            //return/go up to parent dir one level
+      wait_ms(300);      
+      return;                                          //EXIT                           
+    }
+    if(point.y < 60){                                  //if touch on "set as wall" button
+      lcd.objButton(10,25,MAX_X_PORTRAIT-10,55,SELECTED,"Set as Wall");
+      lcd.setTextSize(FONT2);
+      lcd.string(22,140,MAX_X_PORTRAIT,MAX_Y_PORTRAIT,"Saved on EEPROM",&charsPrinted);
+      saveWallpaperToEEPROM();                         //Save the current contents of "name" array to EEPROM
+      wait_ms(500);
+      continue;
+    }     
+    //check if we go to the next image, or to the previous one
+    if(point.x>120){                                   //if the received touch was on the right side of the screen we advance the image, else we decrease and go to previous image
+      i++;                                             //decrease image selector
+      if(i>=walls){                                    //if we reach the position of the last image, we restart to image 0
+        i=0;                 
+      }        
+    }else{                                             //touch on left side of screen
+      if(i>0){                                         //if we can decrease i
+        i--;    
+      }else{                                           //if we decrease i will be less than zero, so we move to last image instead
+        i=walls-1;  
+      }
+    }   
+  }    
+}
+
+/***************************************************/
+/***************************************************/
+void initializeSmartGPU2(void){      //Initialize SMARTGPU2 Board
+  lcd.reset();                       //physically reset SMARTGPU2
+  lcd.start();                       //initialize the SMARTGPU2 processor
+}
+
+/***************************************************/
+/***************************************************/
+/***************************************************/
+/***************************************************/
+int main() {
+  unsigned char icons;
+    
+  initializeSmartGPU2();           //Init communication with SmartGPU2 board
+  
+  lcd.baudChange(BAUD7);           //set high baud for advanced applications
+  lcd.orientation(PORTRAIT_LOW);   //set orientation as portrait  
+  lcd.initDACAudio(ENABLE);        //Turn on the Audio DACs
+  lcd.audioBoost(ENABLE);          //ENABLE boost  
+  lcd.SDFopenDir("FullGUI");       //Open the FullGUI folder that contains the images of the Application
+
+  while(1){
+    //draw MainMenu
+    drawMainMenu();
+    
+    icons=getTouchIconMainMenu();  //ask for a touch on one of the icons of main menu and return icon#
+    switch(icons){
+      case 1: //case icon 1
+        backlight();
+      break;  
+      case 2: //case icon 2
+        //calculator();
+      break;
+      case 3: //case icon 3
+        clocks();
+      break;
+      case 4: //case icon 4
+        games();
+      break;
+      case 5: //case icon 5
+        //maps();
+      break;
+      case 6: //case icon 6
+        media();
+      break;
+      case 7: //case icon 7
+        notes();
+      break;
+      case 8: //case icon 8
+        photos();
+      break;
+      case 9: //case icon 9
+        //wifi();
+      break;
+      case 10: //case icon 10
+        //settings();
+      break;      
+      case 11: //case icon 11
+        //calls();
+      break; 
+      case 12: //case icon 12
+        music();
+      break; 
+      case 13: //case icon 13
+        wallpaper();
+      break;      
+      default:
+        //do nothing
+      break;       
+    }
+  }  
+}
\ No newline at end of file