Henry Triff / Mbed 2 deprecated ELEC2645_Project_el18ht

Dependencies:   mbed

Graphics/Graphics.cpp

Committer:
HenryWTriff
Date:
2020-02-11
Revision:
4:9f41fc1c2ad1
Parent:
3:ceed6d026b8b
Child:
5:2d9f3c36bcb9

File content as of revision 4:9f41fc1c2ad1:

#include "Graphics.h"

//***********
//  Sprites
//***********

int flag[8][8] = {
    {4,1,1,1,1,1,1,1},
    {4,1,1,0,1,0,1,1},
    {4,1,0,1,0,1,1,1},
    {4,1,1,0,1,0,1,1},
    {4,1,1,1,1,1,1,1},
    {4,4,4,4,4,4,1,1},
    {4,4,4,4,4,4,1,1},
    {4,4,4,4,4,4,1,1},
};

int car[8][8] = {
    {4,4,4,4,4,4,4,4},
    {4,4,4,4,4,4,4,4},
    {4,1,1,1,1,1,1,4},
    {4,4,4,1,1,4,4,4},
    {4,4,4,1,1,4,4,4},
    {1,4,1,1,1,1,4,1},
    {1,1,1,0,0,1,1,1},
    {1,4,1,1,1,1,4,1},
};

//**************************
//  MAIN GRAPHICS FUNCTION
//**************************

void Graphics::Draw_Map(int game_fps, Point_2D translation, int angle, float squish, Line_2D *Track_Lines, Line_2D *Track_Dotted_Lines, Point_2D *Track_Flags, Map_Data map_info, N5110 &LCD)
{

    Line_2D Track_Lines_Transformed[map_info.number_of_track_lines];
    Line_2D Track_Dotted_Lines_Transformed[map_info.number_of_dotted_lines];
    Point_2D Transformed_Flags[map_info.number_of_flags];

    for(int i = 0; i < map_info.number_of_track_lines; i++) {
        Track_Lines_Transformed[i] = Track_Lines[i];
        //Translation
        Track_Lines_Transformed[i].from = Translate_Point(Track_Lines_Transformed[i].from, Round(translation.x), Round(translation.y));
        Track_Lines_Transformed[i].to = Translate_Point(Track_Lines_Transformed[i].to, Round(translation.x), Round(translation.y));
        //Rotation
        Track_Lines_Transformed[i].from = Rotate_Point(Track_Lines_Transformed[i].from, angle);
        Track_Lines_Transformed[i].to = Rotate_Point(Track_Lines_Transformed[i].to, angle);
        //Squish
        Track_Lines_Transformed[i].from = Squish_Point(Track_Lines_Transformed[i].from, squish);
        Track_Lines_Transformed[i].to = Squish_Point(Track_Lines_Transformed[i].to, squish);
    }

    for(int i = 0; i < map_info.number_of_dotted_lines; i++) {
        Track_Dotted_Lines_Transformed[i] = Track_Dotted_Lines[i];
        //Translation
        Track_Dotted_Lines_Transformed[i].from = Translate_Point(Track_Dotted_Lines_Transformed[i].from, Round(translation.x), Round(translation.y));
        Track_Dotted_Lines_Transformed[i].to = Translate_Point(Track_Dotted_Lines_Transformed[i].to, Round(translation.x), Round(translation.y));
        //Rotation
        Track_Dotted_Lines_Transformed[i].from = Rotate_Point(Track_Dotted_Lines_Transformed[i].from, angle);
        Track_Dotted_Lines_Transformed[i].to = Rotate_Point(Track_Dotted_Lines_Transformed[i].to, angle);
        //Squish
        Track_Dotted_Lines_Transformed[i].from = Squish_Point(Track_Dotted_Lines_Transformed[i].from, squish);
        Track_Dotted_Lines_Transformed[i].to = Squish_Point(Track_Dotted_Lines_Transformed[i].to, squish);
    }

    for(int i = 0; i < map_info.number_of_flags; i++) {
        Transformed_Flags[i] = Track_Flags[i];
        //Translation
        Transformed_Flags[i] = Translate_Point(Transformed_Flags[i], Round(translation.x), Round(translation.y));
        //Rotation
        Transformed_Flags[i] = Rotate_Point(Transformed_Flags[i], angle);
        //Squish
        Transformed_Flags[i] = Squish_Point(Transformed_Flags[i], squish);
    }

    LCD.clear();
    for(int i = 0; i < map_info.number_of_track_lines; i++) {
        Graphics_Draw_Line(Track_Lines_Transformed[i].from, Track_Lines_Transformed[i].to, true, LCD);
    }

    for(int i = 0; i < map_info.number_of_dotted_lines; i++) {
        Graphics_Draw_Line(Track_Dotted_Lines_Transformed[i].from, Track_Dotted_Lines_Transformed[i].to,false, LCD);
    }

    for(int i = 0; i < map_info.number_of_flags; i++) {
        Graphics_Draw_Sprite(Transformed_Flags[i], 8, 8, (int *)flag, LCD);
    }
    
    Point_2D car_position = {4,0};
    Graphics_Draw_Sprite(car_position,8,8,(int *)car, LCD);

    LCD.refresh();
    wait((1 / float(game_fps)));
}


//*******************
//  SCREEN SETTINGS
//*******************

void Graphics::Change_Contrast(N5110 &LCD, Gamepad &Device)
{
    LCD.setContrast((0.35 + 0.2 * Device.read_pot1()));
}


//**************
//  TRANSFORM
//**************

//ROTATE
Point_2D Graphics::Rotate_Point(Point_2D point, float angle)
{
    angle = (angle * PI)/180;
    float x_rotated = point.x * cos(angle) - point.y * sin(angle);
    float y_rotated = point.y * cos(angle) + point.x * sin(angle);
    return {x_rotated, y_rotated};
}
//TRANSLATE
Point_2D Graphics::Translate_Point(Point_2D point, int translate_x, int translate_y)
{
    float x_translated = point.x - translate_x;
    float y_translated = point.y - translate_y;
    return {x_translated, y_translated};
}
//SQUISH
Point_2D Graphics::Squish_Point(Point_2D point, float squish)
{
    float x_squish = point.x;
    float y_squish = point.y * squish;
    return {x_squish, y_squish};
}

//********
//  MATH
//********

int Graphics::Round(float number)
{
    int number_int = (number * 10);
    int remainder = number_int % 10;
    if(remainder < 5) {
        return ((number_int - remainder) / 10);
    } else {
        return ((number_int + (10 - remainder)) / 10);
    }
}

float Graphics::Gradient(Point_2D from, Point_2D to)
{
    float change_in_y = to.y - from.y;
    float change_in_x = to.x - from.x;
    float gradient = change_in_y / change_in_x;
    if(gradient < 0.001 && gradient > -0.001) {
        return 0;
    } else {
        return gradient;
    }
}

bool Graphics::Gradient_Check_Infinate(Point_2D from, Point_2D to)
{
    float change_in_x = to.x - from.x;
    if(change_in_x < 0.001 && change_in_x > -0.001) {
        return true;
    } else {
        return false;
    }
}

//*************
//  DRAW LINE
//*************

void Graphics::Graphics_Draw_Line(Point_2D from, Point_2D to, bool solid, N5110 &LCD) //Draw a line between two points on only the portion of the screen
{

    if( Gradient_Check_Infinate(from, to)  == false ) { //Checking to see if the line is vertical
        Point_2D plot_x_from = {0,0};
        Point_2D plot_x_to = {0,0};
        Point_2D plot_y_from = {0,0};
        Point_2D plot_y_to = {0,0};

        float gradient = Gradient(from, to); // Calculating the gradient
        float y_intercept = (from.y - gradient * from.x); // Calulating the y intercept y - mx = c
        float x_intercept = (from.x - from.y / gradient); // Calculating the x intercept x - y/m = d

        if(gradient <= 1 && gradient >= -1) {
            //Reordering from and to so that the for loops below can use ++
            if(to.x < from.x) {
                plot_x_from = to;
                plot_x_to = from;
            } else {
                plot_x_from = from;
                plot_x_to = to;
            }
            if(solid == true) {
                for(int x = Round(plot_x_from.x); x <= Round(plot_x_to.x); x++) { //Iterating through the x points
                    int y = -(Round((gradient * x) + y_intercept)); //Calculating the value of y for each x point
                    Point_2D plot_x = {x+42, y+36}; //Assigning them to a Plot_2D variable and transforming so the centre of the screen is 0,0
                    if(plot_x.x <= 84 && plot_x.x >= 0 && plot_x.y <=48 && plot_x.y >= 0) {
                        LCD.setPixel(plot_x.x, plot_x.y, true); //Plotting the points
                    }
                }
            } else {
                for(int x = Round(plot_x_from.x); x <= Round(plot_x_to.x); x+=2) { //Iterating through the x points
                    int y = -(Round((gradient * x) + y_intercept)); //Calculating the value of y for each x point
                    Point_2D plot_x = {x+42, y+36}; //Assigning them to a Plot_2D variable and transforming so the centre of the screen is 0,0
                    if(plot_x.x <= 84 && plot_x.x >= 0 && plot_x.y <=48 && plot_x.y >= 0) {
                        LCD.setPixel(plot_x.x, plot_x.y, true); //Plotting the points
                    }
                }
            }
        } else {
            if(to.y < from.y) {
                plot_y_from = to;
                plot_y_to = from;
            } else {
                plot_y_from = from;
                plot_y_to = to;
            }
            if(solid == true) {
                for(int y = Round(plot_y_from.y); y <= Round(plot_y_to.y); y++) { //Iterating through the Y points
                    int x = Round((y / gradient) + x_intercept); //Calculating the value of x for every y point
                    Point_2D plot_y = {x+42, (-y)+36}; //Assigning them to a Plot_2D variable and transforming so the centre of the screen is 0,0
                    if(plot_y.x <= 84 && plot_y.x >= 0 && plot_y.y <=48 && plot_y.y >= 0) {
                        LCD.setPixel(plot_y.x, plot_y.y, true); //Plotting the points
                    }
                }
            } else {
                for(int y = Round(plot_y_from.y); y <= Round(plot_y_to.y); y+=2) { //Iterating through the Y points
                    int x = Round((y / gradient) + x_intercept); //Calculating the value of x for every y point
                    Point_2D plot_y = {x+42, (-y)+36}; //Assigning them to a Plot_2D variable and transforming so the centre of the screen is 0,0
                    if(plot_y.x <= 84 && plot_y.x >= 0 && plot_y.y <=48 && plot_y.y >= 0) {
                        LCD.setPixel(plot_y.x, plot_y.y, true); //Plotting the points
                    }
                }
            }
        }

    } else {
        Point_2D plot_y_from = {0,0};
        Point_2D plot_y_to = {0,0};
        //Reordering from and to so that the for loops below can use ++
        if(to.y < from.y) {
            plot_y_from = to;
            plot_y_to = from;
        } else {
            plot_y_from = from;
            plot_y_to = to;
        }
        float x_intercept = from.x; //Calculating the x_intercept
        if(solid == true) {
            for(int y = plot_y_from.y; y <= plot_y_to.y; y++) {
                Point_2D plot_y = {x_intercept+42, (-y)+36}; //Assigning them to a Plot_2D variable and transforming so the centre of the screen is 0,0
                LCD.setPixel(plot_y.x, plot_y.y, true); //Plotting the points
            }
        } else {
            for(int y = plot_y_from.y; y <= plot_y_to.y; y+=2) {
                Point_2D plot_y = {x_intercept+42, (-y)+36}; //Assigning them to a Plot_2D variable and transforming so the centre of the screen is 0,0
                LCD.setPixel(plot_y.x, plot_y.y, true); //Plotting the points
            }
        }
    }
}

//***************
//  DRAW SPRITE
//***************

void Graphics::Graphics_Draw_Sprite(Point_2D point, int x_size, int y_size, int *sprite, N5110 &LCD)
{
    Point_2D zeroed_point = {Round(point.x) + 42 - x_size, Round(-point.y) + 36 - y_size};
    if(zeroed_point.x <= 84 && zeroed_point.x >= 0 && zeroed_point.y <= 48 && zeroed_point.y >= 0) {
        for(int y = 0; y < y_size; y++) {
            for(int x = 0; x < x_size; x++) {
                if(*((sprite + y*y_size)+x) == 1) {
                    LCD.setPixel((zeroed_point.x + x), (zeroed_point.y + y), true);
                } else if(*((sprite + y*y_size)+x) == 0) {
                    LCD.setPixel((zeroed_point.x + x), (zeroed_point.y + y), false);
                }
            }
        }
    }
}