Kyle Sturgess / Mbed 2 deprecated GameProject

Dependencies:   N5110 mbed

Fork of DocTest by Craig Evans

main.cpp

Committer:
200784123
Date:
2015-05-10
Revision:
3:b78d65300f24
Parent:
2:5446154a4028

File content as of revision 3:b78d65300f24:

/**
@file main.cpp

@brief Program implementation

*/
#include "main.h"

int main(){
    ///minimal amount of code in the main, see All() for more
    All();
}
///all of the function that would normally reside in the main
void All(){
    calibrateJoystick(); ///get the centred values of the joystick
    bright=5;
    while(1) {
        if(screen)
            lcd.inverseMode();
        if(!screen)
            lcd.normalMode();
        lcd.refresh();
        Initialise();
        start();
    }
}

///all of the variable, flags, tickers, and anything else that needs to set each time it's powered up
void Initialise(){
    lcd.init();
    Power.attach(&powerDown,1.0);///increases the power counter every second
    backlight.attach(&brightness,1.0/10.0);///updates the brightness 10 times a second
    pollJoystick.attach(&updateJoystick,1.0/10.0);  /// read joystick 10 times per second
    i=1;
    j=24;
    life=3;
    winFlag=0;
    startFlag=1;
    buzzer.period(0.002);
    c=1;
}

///goes into deep power down if nothing happens for a set time
void powerDown(){
    power++;
    if(power==55){
        red1=0;
        red2=0.1*bright;
        red3=0;
        yel=0.1*bright;
        buzzer=0.4;
    }
    if(power==56){
        red1=0.1*bright;
        red2=0;
        red3=0.1*bright;
        yel=0;
        buzzer=0.9;
    }
    if(power==57){
        red1=0;
        red2=0.1*bright;
        red3=0;
        yel=0.1*bright;
        buzzer=0.4;
    }
    if(power==58){
        red1=0.1*bright;
        red2=0;
        red3=0.1*bright;
        yel=0;
        buzzer=0.9;
    }
    if(power==59){
        red1=0;
        red2=0.1*bright;
        red3=0;
        yel=0.1*bright;
        buzzer=0.4;
    }
    if(power>=60){
        red1=0.1*bright;
        red2=0;
        red3=0.1*bright;
        yel=0;
        buzzer=0.9;
        DeepPowerDown();
    }
}


///the start screen, shows up at the begining and when the player runs out of lives
///links to the options menu, the highscores, the level select etc.
void start(){
    power=0;
    clear();
    lcd.refresh();
    butt.rise(&menus);
    push.rise(&menus);
    startFlag=1;
    while(c) {
        lcd.clearPixel(i,j);
        lcd.printString("Click",25,2);
        lcd.refresh();
    }
    clear();
    while(startFlag) {
        lcd.clearPixel(i,j);
        while(joystick.direction!=CENTRE) {
            lcd.clearPixel(i,j);
            ///do nothing, stay on current screen
            lcd.printString("^ Options ^",10,0);
            lcd.printString("< Score Inv. >",0,2);
            lcd.printString("v Levels v",12,5);
            lcd.refresh();
        }
        if(joystick.direction==CENTRE) {
            lcd.clearPixel(i,j);
            lcd.printString("^ Options ^",10,0);
            lcd.printString("< Score Inv. >",0,2);
            lcd.printString("v Levels v",12,5);
            lcd.refresh();
            ///for some reason if UP is used to change the flag then it goes straight to the maze
        }
        if(joystick.direction==UP) {
            power=0;
            lcd.clearPixel(i,j);
            toggle();
            Options();
        }
        if (joystick.direction==DOWN) {
            power=0;
            lcd.clearPixel(i,j);
            toggle();
            Levels();
        }
        if(joystick.direction==LEFT) {
            power=0;
            lcd.clearPixel(i,j);
            toggle();
            Score();
        }
        if(joystick.direction==RIGHT) {
            power=0;
            lcd.clearPixel(i,j);
            ///go to the inverse function
            screen=!screen;
            if(screen)
                lcd.inverseMode();
            if(!screen)
                lcd.normalMode();
            lcd.refresh();
        }
    }
    lcd.clearPixel(i,j);
    clear();
}
///function called to escape back to the main menu
void menus(){
    power=0;
    lcd.clearPixel(i,j);
    clear();
    timeout.attach_us(&toggle,10);
}
///function called to toggle, clear, or set various flags
void toggle(){
    power=0;
    l=!l;
    r=!r;
    u=!u;
    d=!d;
    c=0;
    b=!b;
    startFlag=1;
}
///the options menu, links to the reset, brightness, and end game
void Options(){
    power=0;
    lcd.clearPixel(i,j);
    clear();
    while(u) {
        lcd.clearPixel(i,j);
        while(joystick.direction!=CENTRE) {
            ///do nothing, just sit on current screen
            lcd.clearPixel(i,j);
            lcd.printString("~~~~~~~~~~~~~~",0,0);
            lcd.printString("^ Brightness ^",0,1);
            lcd.printString("< Reset",10,2);
            lcd.printString("End >",30,3);
            lcd.printString("v Back v",15,4);
            lcd.printString("~~~~~~~~~~~~~~",0,5);
            lcd.refresh();
        }
        lcd.clearPixel(i,j);
        lcd.printString("~~~~~~~~~~~~~~",0,0);
        lcd.printString("^ Brightness ^",0,1);
        lcd.printString("< Reset",10,2);
        lcd.printString("End >",30,3);
        lcd.printString("v Back v",15,4);
        lcd.printString("~~~~~~~~~~~~~~",0,5);
        lcd.refresh();
        if(joystick.direction==DOWN) {
            power=0;
            lcd.clearPixel(i,j);
            ///escape back to the first menu
            start();
        }
        if (joystick.direction==UP) {
            power=0;
            lcd.clearPixel(i,j);
            ///go to the brightness function
            clear();
            while(b) {
                lcd.clearPixel(i,j);
                red1=0.1*bright;
                red2=0.1*bright;
                red3=0.1*bright;
                yel=0.1*bright;
                push.rise(&Dark);
                butt.rise(&Light);
                lcd.printString("click joy - up",0,1);
                lcd.printString("or pink - down",0,3);
                lcd.printString("v Back v",15,5);
                lcd.refresh();
                if(joystick.direction==DOWN) {
                    Options();
                }
            }
        }
        if (joystick.direction==LEFT) {
            power=0;
            lcd.clearPixel(i,j);
            toggle();
            score1=0;
            scoreWrite1();
            score2=0;
            scoreWrite2();
            score3=0;
            scoreWrite3();
        }
        if(joystick.direction==RIGHT) {
            power=0;
            lcd.clearPixel(i,j);
            winFlag=1;
            endGame();
        }
    }
    lcd.clearPixel(i,j);
    clear();
}
///debouncing code for the light() function
void Light(){
    timeout.attach_us(&light,100);
}
///debouncing code for the dark() function
void Dark(){
    timeout.attach_us(&dark,100);
}
///function called to increase the LED and backlight birghtness variable
void light(){
    bright++;
    if(bright>10)
        bright=10;
}
///function called to decrease the LED and backlight brightness variable
void dark(){
    bright--;
    if(bright<1)
        bright=1;
}
///function called to set the LCD backlight brightness from the brigtness variable
void brightness(){
    lcd.setBrightness(0.1*bright);
}
///the level select menu, allows the player to choose between three levels by moveing the joystick left, down, or right
void Levels(){
    power=0;
    push.rise(&menus);
    butt.rise(&menus);
    clear();
    while(d) {
        lcd.clearPixel(i,j);
        while(joystick.direction!=CENTRE) {
            ///do nothing, stay on current screen
            lcd.clearPixel(i,j);
            lcd.printString("~~~~~~~~~~~~~~",0,0);
            lcd.printString("Left = 1",10,2);
            lcd.printString("Down = 2",10,3);
            lcd.printString("Right = 3",10,4);
            lcd.printString("^ Back ^",15,1);
            lcd.printString("~~~~~~~~~~~~~~",0,5);
            lcd.refresh();
        }
        lcd.clearPixel(i,j);
        lcd.printString("~~~~~~~~~~~~~~",0,0);
        lcd.printString("Left = 1",10,2);
        lcd.printString("Down = 2",10,3);
        lcd.printString("Right = 3",10,4);
        lcd.printString("^ Back ^",15,1);
        lcd.printString("~~~~~~~~~~~~~~",0,5);
        lcd.refresh();
        if(joystick.direction==UP) {
            power=0;
            lcd.clearPixel(i,j);
            ///escape back to the first menu
            toggle();
            start();
        }
        if(joystick.direction==LEFT) {
            power=0;
            lcd.clearPixel(i,j);
            ///go to the preview screen for level 1
            clear();
            while(joystick.direction==LEFT) {
                lcd.clearPixel(i,j);
                lcd.printString("Level 1",15,2);
                lcd.refresh();
                mazeFlag=1;
            }
            clear();
            mainGame();
        }
        if(joystick.direction==DOWN) {
            power=0;
            lcd.clearPixel(i,j);
            ///go to the preview screen for level 2
            clear();
            while(joystick.direction==DOWN) {
                lcd.clearPixel(i,j);
                lcd.printString("Level 2",15,2);
                lcd.refresh();
                mazeFlag=2;
            }
            clear();
            mainGame();
        }
        if(joystick.direction==RIGHT) {
            power=0;
            lcd.clearPixel(i,j);
            ///go to the preview screen for level 3
            clear();
            while(joystick.direction==RIGHT) {
                power=0;
                lcd.clearPixel(i,j);
                lcd.printString("Level 3",15,2);
                lcd.refresh();
                mazeFlag=3;
            }
            clear();
            mainGame();
        }

    }
    lcd.clearPixel(i,j);
    clear();
}
///the scores menu, displays the currently saved high score for the three levels
/// moving the joystick different directions displays the scores for the different levels
void Score(){
    power=0;
    lcd.clearPixel(i,j);
    push.rise(&menus);
    butt.rise(&menus);
    clear();
    while(l) {
        lcd.clearPixel(i,j);
        while(joystick.direction!=CENTRE) {
            ///do nothing, stay on current screen
            lcd.clearPixel(i,j);
            lcd.printString("~~~~~~~~~~~~~~",0,0);
            lcd.printString("High Score",10,1);
            lcd.printString("> Back >",15,4);
            lcd.printString("~~~~~~~~~~~~~~",0,5);
            lcd.refresh();
        }
        lcd.clearPixel(i,j);
        lcd.printString("~~~~~~~~~~~~~~",0,0);
        lcd.printString("High Score",10,1);
        lcd.printString("> Back >",15,4);
        lcd.printString("~~~~~~~~~~~~~~",0,5);
        lcd.refresh();
        if(joystick.direction==RIGHT) {
            power=0;
            ///escape back to the first menu
            start();
        }
        if(joystick.direction==UP) {
            power=0;
            lcd.clearPixel(i,j);
            ///show the high score/fastest time for level 1
            clear();
            while(joystick.direction!=DOWN){
                lcd.clearPixel(i,j);
                lcd.printString("Level 1 best",7,1);
                scoreRead1();
                lcd.refresh();
            }
            clear();
        }else if(joystick.direction==LEFT) {
            power=0;
            lcd.clearPixel(i,j);
            ///show the high score/fastest time for level 2
            clear();
            while(joystick.direction!=RIGHT){
                lcd.clearPixel(i,j);
                lcd.printString("Level 2 best",7,1);
                scoreRead2();
                lcd.refresh();
            }
            clear();
        }else if(joystick.direction==DOWN) {
            power=0;
            lcd.clearPixel(i,j);
            ///show the high score/fastest time for level 3
            clear();
            while(joystick.direction!=UP){
                lcd.clearPixel(i,j);
                lcd.printString("Level 3 best",7,1);
                scoreRead3();                
                lcd.refresh();
            }
            clear();
        }
    }
    lcd.clearPixel(i,j);
    clear();
}


///writes the score for the first level to file
void scoreWrite1(){
    FILE *fp = fopen("/local/score1.txt","w");///opens the file score1.txt
    ///if the file doesn't exist it creates it, if it exists it updates
    fprintf(fp,"%i",score1);///prints the integer value for the score to file
    fclose(fp);
}
///reads the currently saved score for the first level
void scoreRead1(){
    int Score1;///tells it that the value to be read is an integer value
    
    FILE *fp1 = fopen("/local/score1.txt","r");///opens score1.txt
    fscanf(fp1,"%i",&Score1);///searches the file for an integer 
    fclose(fp1);
    
    char Points1[14];///bufer to store the points value
    sprintf(Points1,"%i",Score1);///sends the score to the buffer
    lcd.printString(Points1,30,3);///prints the score to the LCD
}

///writes the score for the second level to file
void scoreWrite2(){
    FILE *fp2 = fopen("/local/score2.txt","w");///opens the file score2.txt
    ///if the file doesn't exist it creates it, if it exists it updates
    fprintf(fp2,"%i",score2);///prints the integer value for the score to file
    fclose(fp2);
}
///reads the currently saved score for the second level
void scoreRead2(){
    int Score2;///tells it that the value to be read is an integer value
    
    FILE *fp3 = fopen("/local/score2.txt","r");///opens score2.txt
    fscanf(fp3,"%i",&Score2);///searches the file for an integer
    fclose(fp3);
    
    char Points2[14];///bufer to store the points value
    sprintf(Points2,"%i",Score2);///sends the score to the buffer
    lcd.printString(Points2,30,3);///prints the score to the LCD
}

///writes the score for the third level to file
void scoreWrite3(){
    FILE *fp4 = fopen("/local/score3.txt","w");///opens the file score3.txt
    ///if the file doesn't exist it creates it, if it exists it updates
    fprintf(fp4,"%i",score3);///prints the integer value for the score to file
    fclose(fp4);
}
///reads the curently saved score for the third level
void scoreRead3(){
    int Score3;///tells it that the value to be read is an integer value
    
    FILE *fp5 = fopen("/local/score3.txt","r");///opens score3.txt
    fscanf(fp5,"%i",&Score3);///searches the file for an integer 
    fclose(fp5);
    
    char Points3[14];///bufer to store the points value
    sprintf(Points3,"%i",Score3);///sends the score to the buffer
    lcd.printString(Points3,30,3);///prints the score to the LCD
}
///function called to quite the game and return to the menu
///, has the same effect on the game as running out of lives while playing
void pause(){
    power=0;
    lcd.clearPixel(i,j);
    i=1;
    j=24;
    winFlag=0;
    life=0;
}
///all of the functions that make up the main game
void mainGame(){ 
    count.attach(&counter,1.0);///counts every second for the lives function etc.
    flash.attach(&Flash,0.25);
    push.rise(&pause);
    butt.rise(&pause);
    life=3;
    startFlag=0;
    winFlag=0;
    clear();
    maze1();
    i=1;
    j=24;
    while(life&&!winFlag) {
        power=0;
        border();
        if (printFlag) {
            printFlag=0;
            move();
        }
        collide1();
        winning();
        lives();
        if(flashFlag)
            lcd.clearPixel(i,j);
        if(!flashFlag||joystick.direction!=CENTRE)
            lcd.setPixel(i,j);
        lcd.refresh();
    }
    if(mazeFlag==1){
        score1=mazeFlag*life*(100-countFlag);///change this equation to change how the score is set
        if(screen)
            score1=score1+50;///change this equation to change how the score is set
        
        int Score1;///tells it that the value to be read is an integer value
    
        FILE *fp1 = fopen("/local/score1.txt","r");///opens score1.txt
        fscanf(fp1,"%i",&Score1);///searches the file for an integer followed by a string
        fclose(fp1);
        
        if(score1>Score1)
            scoreWrite1();
    }
    if(mazeFlag==2){
        score2=mazeFlag*life*(100-countFlag);///change this equation to change how the score is set
        if(screen)
            score2=score2+50;///change this equation to change how the score is set
        
        int Score2;///tells it that the value to be read is an integer value
    
        FILE *fp3 = fopen("/local/score2.txt","r");///opens score2.txt
        fscanf(fp3,"%i",&Score2);///searches the file for an integer
        fclose(fp3);
        
        if(score2>Score2)
            scoreWrite2();
    }
    if(mazeFlag==3){
        score3=mazeFlag*life*(100-countFlag);///change this equation to change how the score is set
        if(screen)
            score3=score3+50;///change this equation to change how the score is set
        
        int Score3;///tells it that the value to be read is an integer value
    
        FILE *fp5 = fopen("/local/score3.txt","r");///opens score3.txt
        fscanf(fp5,"%i",&Score3);///searches the file for an integer followed by a string
        fclose(fp5);
        
        if(score3>Score3)
            scoreWrite3();
    }
    clear();
}

///mini game fashioned after the style of etch-a-sketch
void endGame(){
    flash.attach(&Flash,0.25);
    red1=0;
    red2=0;
    red3=0;
    yel=0;
    buzzer=0;
    push.rise(&menus);
    butt.rise(&clear);
    lcd.clear();
    i=42;
    j=24;
    while(b) {
        power=0;
        endBorder();
        lcd.setPixel(i,j);
        if(flashFlag)
            lcd.clearPixel(i,j);
        if(!flashFlag||joystick.direction!=CENTRE)
            lcd.setPixel(i,j);
        if(printFlag) {
            printFlag=0;
            endMove();
            lcd.refresh();
        }
    }
    lcd.clearPixel(i,j);
    clear();
    lcd.refresh();
    i=1;
    j=24;
}

///function called to clear the screen in the mini game if the external button is pressed
///and anywhere else its called
void clear(){
    lcd.clearPixel(i,j);
    lcd.clear();
    lcd.refresh();
}

///function linked to the flash ticker
///toggles the flag between 0 and 1 and sets the pixel to flash
void Flash(){
    flashFlag=!flashFlag;
    lcd.setPixel(i,j);
}

///function called to check if the goal area has been reached in the time
///if not then the player is sent back to the begining of the level
///also indicates when time is running out on the buzzer and yellow LED
///added a safe zone at the start of the maze so the counter doesn't start straight away
///being in the safe zone stops the counter and flashes the yellow LED
void counter(){
    buzzer=0;
    if((i==0||i==1||i==2||i==3)){
        yel=!yel;
        countFlag=0;
    }
    if(!(i==0||i==1||i==2||i==3))
        yel=0;
    if(startFlag){
        red1=0;
        red2=0;
        red3=0;
        yel=0;
    }
    /////the possition of the safe zone
    if(!startFlag&&!(i==0||i==1||i==2||i==3))
        countFlag++;
    /////if the current pixel is in the safe zone
    if(mazeFlag==3){
        if(!winFlag&&(countFlag==37||countFlag==38||countFlag==39)) {///change these numbers to change the warning time before the time limit
        yel=0.1*bright;
        buzzer=0.9;
        }
        if(countFlag==40) {///change this number to change the time limi for the level
            countFlag=0;
            yel=0;
            buzzer=0;
            life--;
            lcd.clearPixel(i,j);
            if(!winFlag) {
                i=1;
                j=24;
            }
        }
    }
    if(mazeFlag==2){
        if(!winFlag&&(countFlag==42||countFlag==43||countFlag==44)) {///change these numbers to change the warning time before the time limit
        yel=0.1*bright;
        buzzer=0.9;
        }
        if(countFlag==45) {///change this number to change the time limi for the level
            countFlag=0;
            yel=0;
            buzzer=0;
            life--;
            lcd.clearPixel(i,j);
            if(!winFlag) {
                i=1;
                j=24;
            }
        }
    }
    if(mazeFlag==1){
        if(!winFlag&&(countFlag==27||countFlag==28||countFlag==29)) {///change these numbers to change the warning time before the time limit
        yel=0.1*bright;
        buzzer=0.9;
        }
        if(countFlag==30) {///change this number to change the time limi for the level
            countFlag=0;
            yel=0;
            buzzer=0;
            life--;
            lcd.clearPixel(i,j);
            if(!winFlag) {
                i=1;
                j=24;
            }
        }
    }
}

///displays the number of remaining level attempts, or lives, on the red LEDS
void lives(){
    if(life==3) {
        red1=0.1*bright;
        red2=0.1*bright;
        red3=0.1*bright;
    } else if(life==2) {
        red1=0.0;
        red2=0.1*bright;
        red3=0.1*bright;
    } else if(life==1) {
        red1=0.0;
        red2=0.0;
        red3=0.1*bright;
    } else {
        red1=0.0;
        red2=0.0;
        red3=0.0;
        start();
    }
}

///function that checks if the goal area has been reached
void winning(){
        if(j==0){///if the pixel reaches the top top of the screen
            lcd.clearPixel(i,j);
            i=1;
            j=24;
            winFlag=1;
        }
}

///displays the maze by opening a picture and setting the pixels accordingly
void maze1(){
    for (int x = 0; x <= ny-1; x++) {
        if(mazeFlag==1){
            img = fopen("/local/TEST.BMP", "r");///TEST.BMP, 3x3 walls, 5x5 corridoors, if the corners are solid then the player dies when they go into one beacause the number of neighbouring pixels is the same as a collision
        }
        if(mazeFlag==2){
            img = fopen("/local/MAZE1.BMP", "r");///MAZE1.BMP, 3x3 walls, 4x4 corridoors, if the corners are solid then the player dies when they go into one beacause the number of neighbouring pixels is the same as a collision
        }
        if(mazeFlag==3){
            img = fopen("/local/MAZE2.BMP", "r");////MAZE2.BMP, 3x3 walls, 3x3 corridorrs, if the corners are solid then the player dies when they go into one beacause the number of neighbouring pixels is the same as a collision
        }
        fseek (img , 54 + (nx*x*3) , SEEK_SET);
        fread(imgbuffer, (nx*3), 1, img);
        fclose(img);
        for (int y = 0; y <= nx-1; y++) {
            int red = imgbuffer[y*3];
            if (red == 0) {
                lcd.setPixel(y,(ny-1)-x);
            }
        }
    }
    lcd.refresh();
}


///hardwall boundary so the player can't go off the screen
void border(){
    if (i>=nx)
        i=nx-1;
    if (i<=0)
        i=0;
    if (j>=ny)
        j=ny-1;
    if (j<=0)
        j=0;
}

///portal boundary, so the player can go from one side to another or top to bottom, used in the mini game only
void endBorder(){
    if (i>=nx)
        i=0;
    if (i<0)
        i=nx-1;
    if (j>=ny)
        j=0;
    if (j<0)
        j=ny-1;
}
///function called to check if the player is trying to move through a solid object
void collide1(){    
    int block=0;
    if(joystick.direction==UP){
        if(lcd.getPixel(i,j)&&lcd.getPixel(i,j-1)){
            block++;
        }
        if(lcd.getPixel(i+1,j)||lcd.getPixel(i-1,j)){
            block++;
        }
    }
    if(joystick.direction==DOWN){
        if(lcd.getPixel(i,j)&&lcd.getPixel(i,j+1)){
            block++;
        }
        if(lcd.getPixel(i+1,j)||lcd.getPixel(i-1,j)){
            block++;
        }
    }
    if(joystick.direction==LEFT){
        if(lcd.getPixel(i,j)&&lcd.getPixel(i-1,j)){
            block++;
        }
        if(lcd.getPixel(i,j+1)||lcd.getPixel(i,j-1)){
            block++;
        }
    }
    if(joystick.direction==RIGHT){
        if(lcd.getPixel(i,j)&&lcd.getPixel(i+1,j)){
            block++;
        }
        if(lcd.getPixel(i,j+1)||lcd.getPixel(i,j-1)){
            block++;
        }
    }
    if(block==2){
        if(!(i==0||i==1||i==2||i==3)){///outside the safe zone
            lcd.clearPixel(i,j);
            clear();
            maze1();
            life--;
            i=1;
            j=24;
            countFlag=0;
        }else{
            lcd.clearPixel(i,j);
            clear();
            maze1();
            i=1;
            j=24;
            countFlag=0;
        }
    }
}
    
///checks the joystick direction and alters the possition of the pixel accordingly while clearing off where the pixel just was
///used in the main game only
void move(){
    if (joystick.direction == DOWN) {
        j++;
        lcd.clearPixel(i,j-1);
    }
    if (joystick.direction == UP) {
        j--;
        lcd.clearPixel(i,j+1);
    }
    if (joystick.direction == LEFT) {
        i--;
        lcd.clearPixel(i+1,j);
    }
    if (joystick.direction == RIGHT) {
        i++;
        lcd.clearPixel(i-1,j);
    }
}

///checks the direction of the joystick and updates the position of the pixel accordingly
///keeps the path drawn unless cleared by the button, see clear()
void endMove(){
    if (joystick.direction == DOWN) {
        j++;
    }
    if (joystick.direction == UP) {
        j--;
    }
    if (joystick.direction == LEFT) {
        i--;
    }
    if (joystick.direction == RIGHT) {
        i++;
    }
}

/* Joystick
Example code of how to read a joystick

https://www.sparkfun.com/products/9032

Craig A. Evans
7 March 2015
*/

/// read default positions of the joystick to calibrate later readings
void calibrateJoystick(){
    button.mode(PullDown);
    ///// must not move during calibration
    joystick.x0 = xPot;  /// initial positions in the range 0.0 to 1.0 (0.5 if centred exactly)
    joystick.y0 = yPot;
}
 /// read current joystick values relative to calibrated values (in range -0.5 to 0.5, 0.0 is centred)
void updateJoystick(){
    joystick.x = xPot - joystick.x0;
    joystick.y = yPot - joystick.y0;
    /// read button state
    joystick.button = button;
   
    /// calculate direction depending on x,y values
    /// tolerance allows a little lee-way in case joystick not exactly in the stated direction

    if ( fabs(joystick.y) < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
        joystick.direction = CENTRE;
    } else if ( joystick.y > DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
        joystick.direction = DOWN;
    } else if ( joystick.y < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
        joystick.direction = UP;
    } else if ( joystick.x > DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) {
        joystick.direction = RIGHT;
    } else if ( joystick.x < DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) {
        joystick.direction = LEFT;
    }
    /// set flag for printing
    printFlag = 1;
}