My ELEC2645 project. Nikollao Sulollari. 200804685

Dependencies:   N5110 SoftPWM mbed

Fork of Treasure_Hunt by ELEC2645 (2015/16)

main.h

Committer:
Nikollao
Date:
2016-04-27
Revision:
10:1d229362c134
Parent:
9:ce2d9c42edea
Child:
11:53caf3d944a9

File content as of revision 10:1d229362c134:

/**
@file main.h
@brief Header file contains functions and variables
@brief Treasure Hunt - Embedded Systems Project
@brief Revision 1.0
@author Nikollao Sulollari
@Date 26/03/2016
*/

#ifndef MAIN_H
#define MAIN_H
#include "mbed.h"
#include "N5110.h"

#define DIRECTION_TOLERANCE 0.05
/**
@nameSpace r_led
@brief output for status of red LED
*/
DigitalOut r_led(LED_RED);

/**
@nameSpace g_led
@brief output for status of green LED
*/
DigitalOut g_led(LED_GREEN);

/**
@nameSpace b_led
@brief output for status of blue LED
*/
DigitalOut b_led(LED_BLUE);

/**
@nameSpace lcd
@brief object of the N5110 class
*/
N5110 lcd(PTE26 , PTA0 , PTC4 , PTD0 , PTD2 , PTD1 , PTC3);

/**
@nameSpace pc
@brief serial connection between mbed and pc
*/
Serial pc(USBTX,USBRX);

// K64F on-board switches
InterruptIn sw2(SW2);
InterruptIn sw3(SW3);


/**
@nameSpace xPot
@brief read x-axis position from the value of the joystick
*/
AnalogIn xPot(PTB2);

/**
@nameSpace yPot
@brief read y-axis position from the value of the joystick
*/
AnalogIn yPot(PTB3);

/**
@nameSpace button
@brief interrupt executes an event triggered task
*/
InterruptIn button(PTB10);

/**
@nameSpace button
@brief interrupt executes an event triggered task
*/
InterruptIn button1(PTB18);

/**
@nameSpace buzzer
@brief create PWM signal to set buzzer duty cycle and period
*/
PwmOut buzzer(PTB9);

/**
@nameSpace ticker
@brief interrupt executes a time-triggered task
*/
Ticker ticker;


/**
@nameSpace game_ticker
@brief interrupt executes a time-triggered task
*/
Ticker game_ticker;

/**
@nameSpace timeout
@brief interrupt calls a function after a specified amount of time
*/
Timeout timeout;


/**
@nameSpace DirectionName
@brief define joystick's direction based on its x,y values
*/
enum DirectionName {
    UP,
    DOWN,
    LEFT,
    RIGHT,
    CENTRE,
    UP_LEFT,
    UP_RIGHT,
    DOWN_LEFT,
    DOWN_RIGHT
};

/**
@nameSpace Joystick
@brief create strcut Joystick
*/
typedef struct JoyStick Joystick;
struct JoyStick {
    double x;    /// current x value
    double x0;   /// 'centred' x value
    double y;    /// current y value
    double y0;   /// 'centred' y value
    int button; /// button state (assume pull-down used, so 1 = pressed, 0 = unpressed)
    DirectionName direction;  // current direction
};
/// create struct variable
Joystick joystick;

/**
Displays an error message
*/
void error();

/**
set-up serial port
*/
void init_serial();

/**
 set-up the on-board LEDs and switches
*/
void init_K64F();

/**
Set-up random variables and game menu
*/
void init_game();

/**
Set-up flag to 1
*/

/**
Set-up flag to 1
*/
void timer_isr();

/**
Set-up flag to 1
*/

/**
Set-up flag to 1
*/
void game_timer_isr();

/**
Set-up flag to 1
*/
void sw2_isr();

/**
Set-up flag to 1
*/
void sw3_isr();

/**
Set-up flag to 1
*/
void button_isr();

/**
Set-up flag to 1
*/
void timeout_isr();


/**
Set current position to default position of Joystick
*/
void calibrateJoystick();

/**
Update the values of the joystick to get current position
*/
void updateJoystick();

/**
Create an enemy rectangular shape
*/
void enemyRect();

/**
Create circle shape enemy
*/
void enemyCircle();

/**
creates the hero of the game
*/
void hero();

/**
Shows the right direction
*/
void guidance();

/**
Locates obstacles in the screen
*/
void obstacles();

/**
Gets enemies depending on the level
*/
void enemies();

/**
Get s vslue of the .y position, control menu
*/
int menu();

//testing
void checkOverlap();
void userTouched();

/**
Check for intrersection
@param i loops through x direction
@param j loops through y direction
@returns the number of pixels aroun the hero detected
*/
int intersection(int i, int j);


//vars
volatile int rectX; /*!< used to determine x-axis position of the rect enemy */

volatile int rectY ;/*!< used to determine y-axis position of the rect enemy */

volatile int circleX;/*!< used to determine x-axis position of the circular enemy */

volatile int circleY;/*!< used to determine y-axis position of the circular enemy */

volatile int heroX;/*!<  used to move the hero along x-axis */

volatile int heroY;/*!<  used to move the hero along y-axis */

volatile int level = 0; /*!< initiate the level difficulty of the game */

volatile int g_timer_flag = 0; /*!< set timer flag in the isr, timer trigger interrupt */

volatile int g_game_timer_flag = 0;  /*!< set timer flag in the isr, timer trigger interrupt */

volatile int g_sw2_flag = 0;  /*!< set timer flag in the isr, event trigger interrupt */

volatile int g_sw3_flag = 0;  /*!< set timer flag in the isr, event trigger interrupt */

volatile int g_button_flag = 0;  /*!< set flag in the isr, event trigger interrupt */

volatile int g_button1_flag = 0; /*!< set flag in the isr, event trigger interrupt */

volatile int option = 0;  /*!< select option in menu based on Joystick's movement */

volatile int play = 0; /*!< counts the number of plays */

volatile int tries = 0;/*!< counts the number of trials */

volatile int n;/*!< number of pixels overlapping */
//int pixels[84][48];

int reset = 0; /*!< used to save current level of difficulty */

int objectX = 0; /*!< used to move obstacles in the x-axis */

int objectY = 20; /*!< used to move obstacles in the y-axis */

int state = 0; /*!< controls the direction of the objtacle */

int objectX1 = 58; /*!< used to move obstacles in the x-axis */

int state1 = 1; /*!< controls the direction of the objtacle */


void enemies()

{
    /// generate enemies in the screen depending on the level difficulty

    if (level == 0) {

        enemyRect();
        //enemyCircle();
    } else if (level == 1) {

        enemyRect();
        //enemyCircle();
    } else if (level == 2) {

    } else if (level == 3) {

    }
    enemyCircle();
}

void enemyRect()
{
    ///generate rect shape enemy
    lcd.drawRect(rectX,rectY,5,4,1);
    rectX = rectX + rand()%4 - 2;
    rectY++; ///enemy moving towards hero
}

void hero()
{
    ///cotrol hero
    
    if (xPot > 0.60) { 
        heroX++;
    }
     else if (xPot < 0.40){
        heroX--;
    } else {
        heroX = heroX; 
    }
    
    if (yPot > 0.60) {
        heroY--;
    } 
    else if (yPot < 0.40) {
        heroY++;
    } else {
        heroY = heroY;
    }
    ///set x-axis boundaries so hero does not go out of screen
    if (heroX > 35) {
        heroX = 35;
    }
    if (heroX < -40) {
        heroX = -40;
    }
    ///draw hero
    lcd.drawLine(40+heroX, 47+heroY, 48+heroX, 43+heroY,1);
    lcd.drawLine(40+heroX, 43+heroY,48+heroX, 47+heroY,1);
    lcd.drawLine(44+heroX, 45+heroY,44+heroX, 41+heroY,1);
    lcd.drawCircle(44+heroX, 39+heroY,2,0);
}

void enemyCircle()
{
    ///generate circle shape enemy
    lcd.drawCircle(circleX,circleY,4,1);
    circleY = circleY + rand() %4 - 2;
    
    if (circleY <= 10) {
        circleY = 10;
    }if (circleY >= 35) {
        circleY = 35;
    }
    

    circleX++; ///enemy moving towards hero
}

void init_game()
{
    ///initialise game
    //button.mode(PullNone);
    srand(time(NULL)); /// generate random numbers
    rectY = 0; /// init rectX, rectY
    rectX = rand() %40 + 20;
    circleY = rand() %20 + 10; /// init circleX, circleY
    circleX = 0;

    if ( play == 0) { ///if its first play print welcome message, otherwise don't

        lcd.setBrightness(0.5); // put LED backlight on 50%
        timeout.attach(&timeout_isr,2);
        lcd.printString("Welcome to",11,1);
        lcd.printString("Treasure Hunt!",1,3);
        lcd.refresh();
        sleep();
        lcd.clear();
    }
    game_ticker.attach(game_timer_isr,0.2);

    while (1) {

        if (g_game_timer_flag) {

            g_game_timer_flag = 0;
            updateJoystick();
            lcd.clear();
            menu(); ///get Joystick's value to select option in menu
            //option = menu();

            if (option == 0) { /// select Start Game

                lcd.printString("Start Game <",0,0);
                lcd.printString("Settings",0,2);
                lcd.printString("Exit",0,4);
            } else if (option == 1) { /// select Settings

                lcd.printString("Start Game",0,0);
                lcd.printString("Settings <",0,2);
                lcd.printString("Exit",0,4);
            } else { /// select Exit

                lcd.printString("Start Game",0,0);
                lcd.printString("Settings",0,2);
                lcd.printString("Exit <",0,4);
            }
        }
        if (g_button_flag) {

            g_button_flag = 0;

            if (option == 0) {

                game_ticker.detach();
                break;
            } else if (option == 1) {
                
                lcd.clear();
                g_button_flag = 0;
                while(1) {
                    //settings_menu();
                    pc.printf("Modify Settings!");
                    lcd.printString("Lcd Inverse <",0,0);
                    if (g_button_flag) {

                        lcd.inverseMode();
                        break;
                    }
                    sleep();
                }
            } else {

                lcd.turnOff();
                deepsleep();
            }
        }
        sleep();
    }
}
void guidance()
{
    /// show arrow to act as guidance towards the treasure
    if (level < 7) { ///check level of difficulty

        lcd.drawLine(42,0,42,4,1);
        lcd.drawLine(42,0,40,2,1);
        lcd.drawLine(42,0,44,2,1);
    } else if (level == 7) {

        lcd.printString("F",42,0); /// print the treasure icon
    } else if (level == 8) {

        ticker.detach();
        lcd.clear();
        lcd.printString("Well done!",0,0);
        lcd.refresh();
        timeout.attach(&timeout_isr,2);
        sleep();
        lcd.clear();
        lcd.printString("Play again <",0,0);
        lcd.refresh();
        sleep();

        if  (g_button_flag) {

            g_button_flag = 0;
            level = 0;
           // play++;
            lcd.clear();
            //main();
        }
    }
}

void obstacles()
{           
    /// place obstacles in the screen
    /// as level difficulty increases, more obstacles are added
    if (level == 1) {

        lcd.drawRect(10,15,2,2,1);
        lcd.drawRect(74,15,2,2,1);
    } else if (level == 2) {

        lcd.drawRect(10,15,2,2,1);
        lcd.drawRect(74,15,2,2,1);
        lcd.drawRect(10,28,2,2,1);
        lcd.drawRect(74,28,2,2,1);
    } else if (level == 3) {

        lcd.drawRect(5,12,2,2,1);
        lcd.drawRect(79,12,2,2,1);
        lcd.drawRect(5,30,2,2,1);
        lcd.drawRect(79,30,2,2,1);
        lcd.drawRect(28,12,2,2,1);
        lcd.drawRect(52,12,2,2,1);
        lcd.drawRect(28,30,2,2,1);
        lcd.drawRect(52,30,2,2,1);
    } else if (level == 4) {

        lcd.drawRect(5 ,12+ rand() %4 - 2,2,2,1);
        lcd.drawRect(79 + rand() %4 - 2,12 + rand() %4 - 2,2,2,1);
        lcd.drawRect(5+ rand() %4 - 2,30 ,2,2,1);
        lcd.drawRect(79 + rand() %4 - 2,30,2,2,1);
        lcd.drawRect(28 + rand() %4 - 2,12+ rand() %4,2,2,1);
        lcd.drawRect(52,12 + rand() %4 - 2,2,2,1);
        lcd.drawRect(28,30 + rand() %4 - 2,2,2,1);
        lcd.drawRect(52 + rand() %4 - 2,30,2,2,1);
    }
    if (objectX == 0) { ///check position of obstacle
            state = 0; ///assign states to the position of the obstacle
        } 
        else if (objectX == 60) { 
            state = 1;
        } else {
            state = state;
        }
       if (state == 0) { ///if state is 0 increase position on x-axis
            objectX++;
        } else {
            objectX--; ///else if state is 1 decrease position on x-axis
        } 
        
        if (objectX1 == 68) {
          
          state1 = 1;
        }
         else if (objectX1 == 10) {
          state1 = 0;
        }
        if (state1 == 1) {
            objectX1--;
        } else if (state1 == 0) {
            objectX1++;
        }
        objectY = objectY + rand() %4 - 2; ///set poistion of obstacle on y-axis to be valuable
        ///keep moving object within boundaries
        if (objectY <= 10) { 
            objectY = 10;
        } 
        if (objectY >= 37) {
            objectY = 37;
        }
     if ( level == 5) {
        
        lcd.drawLine(15,10,15,37,1);
        lcd.drawLine(71,10,71,37,1);
        
        lcd.drawRect(11+objectX,objectY,2,2,1); ///draw obstacle
        
        lcd.drawRect(80,10,2,2,1);
        lcd.drawRect(5,10,2,2,1);
        lcd.drawRect(80,20,2,2,1);
        lcd.drawRect(5,20,2,2,1);
        lcd.drawRect(80,30,2,2,1);
        lcd.drawRect(5,30,2,2,1);
        
    } 
    else if (level == 6) {
        
        lcd.drawLine(15,10,15,37,1); ///draw boundaries
        lcd.drawLine(71,10,71,37,1);
        
        lcd.drawRect(11+objectX,objectY,2,2,1); /// draw moving obstacles on screen
        lcd.drawRect(objectX1,10+objectY,2,2,1);    
        lcd.drawRect(80,10,2,2,1); ///draw stable obstacles 
        lcd.drawRect(5,10,2,2,1);
        lcd.drawRect(80,20,2,2,1);
        lcd.drawRect(5,20,2,2,1);
        lcd.drawRect(80,30,2,2,1);
        lcd.drawRect(5,30,2,2,1);
    } 
    else if (level == 7) {

        /*
        lcd.drawLine(50,15,30,15,1);
        lcd.drawLine(30,15,30,35,1);
        lcd.drawLine(30,25,45,25,1);
        */
    }
}


void calibrateJoystick()
{
    // 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;
}
void updateJoystick()
{
    // read current joystick values relative to calibrated values (in range -0.5 to 0.5, 0.0 is centred)
    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 = UP;
    } else if ( joystick.y < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
        joystick.direction = DOWN;
    } 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;
    } else if (joystick.y > DIRECTION_TOLERANCE  && joystick.x  < DIRECTION_TOLERANCE) {
        joystick.direction = UP_LEFT;
    } else if (joystick.y > DIRECTION_TOLERANCE && joystick.x > DIRECTION_TOLERANCE) {
        joystick.direction = UP_RIGHT;
    } else if (joystick.y < DIRECTION_TOLERANCE && joystick.x < DIRECTION_TOLERANCE) {
        joystick.direction = DOWN_LEFT;
    }   else if (joystick.y < DIRECTION_TOLERANCE && joystick.x > DIRECTION_TOLERANCE) {
        joystick.direction = DOWN_RIGHT;
    }
}

int menu()
{

    if (joystick.y <= 0.33) { /// if Joystick moves up
        option = 0; /// the pointer moves upper in the menu display
    } else if (joystick.y <= 0.66) { /// if joystick moves down
        option = 1; /// else pointer moves down
    } else {
        option = 2;
    }
    return option;
}

int intersection(int i, int j)
{
    /// check for overlap between enemies and hero
    n=0;

    if (lcd.getPixel(i-1,j-1)!=0) //pixel to the top-left
        n++; // increase n by 1
    if (lcd.getPixel(i-1,j)!=0) //pixel to the left
        n++; // increase n by 1
    if (lcd.getPixel(i-1,j+1)!=0) //pixel to the bottom-left
        n++; // increase n by 1
    if (lcd.getPixel(i,j-1)!=0) // pixel to the top
        n++; // increase n by 1
    if (lcd.getPixel(i,j+1)!=0) //pixel to the bottom
        n++; // increase n by 1
    if (lcd.getPixel(i+1,j-1)!=0) //pixel to the top-right
        n++; // increase n by 1
    if (lcd.getPixel(i+1,j)!=0) // pixel to the right
        n++; // increase n by 1
    if (lcd.getPixel(i+1,j+1)!=0) //pixel to the bottom right
        n++; // increase n by 1
    return n;
}

void checkOverlap()
{

    for (int i=40+heroX; i<50+heroX; i++) {
        for (int j=35+heroY; j<48+heroY; j++) {
            
            int count = intersection(i,j); 
            //lcd.setPixel(i,j);
        }
    }
}

void error()
{
    /// display error message
    while (1) {

        lcd.printString("Error!",0,0);
        r_led = 0;
        wait(0.2);
        r_led = 1;
        wait(0.2);
    }
}

#endif