ELEC2645 (2018/19) / Mbed 2 deprecated el17cd

Dependencies:   mbed

Rasturizer/Rasturizer.cpp

Committer:
el17cd
Date:
2019-04-05
Revision:
30:91038c2afec7
Parent:
29:4a02f0bae202

File content as of revision 30:91038c2afec7:

#include "Rasturizer.h"
N5110 lcd(PTC9,PTC0,PTC7,PTD2,PTD1,PTC11);


Rasturizer::Rasturizer(){
    for(int i = 0; i < 6; i++){
        selectionCube.getFace(i).setVisible(true);
    }
}

void Rasturizer::init(){
    lcd.init();
    fov = 50;
}

float Rasturizer::xTo2D(float x, float z){
    return x * (fov/z) + 42;
}

float Rasturizer::yTo2D(float y, float z){
    return y * (fov/z) + 21;
}

void Rasturizer::drawHorizon(float angle){
    lcd.drawLine(0,
             21-rint(-angle*40),
             84,
             21+rint(-angle*40),
             1);
}

void Rasturizer::drawFace(Face *face, float angle){
    float points[4][3];
    float y, x;

    
    for(int vertex = 0; vertex < 4; vertex++){
        for(int axis = 0; axis < 3; axis++){
            points[vertex][axis] = face->getVertexValue(vertex, axis);
        }
        y = points[vertex][1];
        x = points[vertex][0];
        
        points[vertex][0] = x*cos(-angle)-y*sin(-angle);
        points[vertex][1] = y*cos(-angle)+x*sin(-angle);
    }
    
    if (checkOnScreen(points)){
        rasterizeFace(points, face);
        drawFaceOutline(points);
    }
}

void Rasturizer::rasterizeFace(float (&points)[4][3], Face *face){
    int diffX1, diffY1, diffX2, diffY2;
    float stepBottomY, stepTopX, stepTopY;
    diffX1 = xTo2D(points[0][0], points[0][2])-xTo2D(points[1][0], points[1][2]); //Calculate difference between top horizontal edge x coordnates
    diffY1 = yTo2D(points[0][1], points[0][2])-yTo2D(points[1][1], points[1][2]); //Calculate difference between right vertical edge y coordinates
    diffX2 = xTo2D(points[2][0], points[2][2])-xTo2D(points[3][0], points[3][2]); //Calculate difference between bottom horizontal edge x coordinates
    diffY2 = yTo2D(points[2][1], points[2][2])-yTo2D(points[3][1], points[3][2]); //Calculate difference between left horizontal edge y coordinates
    if(diffX2 != 0 && face->getVisible()){
        stepBottomY = (float)diffY2/(float)diffX2; //increment multiplier for Y axis on bottom edge of face
        stepTopX = (float)diffX1/(float)diffX2; //increment multiplier for X axis on top edge of face
        stepTopY = (float)diffY1/(float)diffX2; //increment multiplier for Y axis on top edge of face
        
        drawFillLines(points, diffX2, stepBottomY, stepTopX, stepTopY); //fill the face with white lines
    }
}

void Rasturizer::drawFillLines(float (&points)[4][3], int diffX2, int stepBottomY, int stepTopX, int stepTopY){
    for(int step = 0; step< abs(diffX2); step++){
        if(diffX2 > 0){
            lcd.drawLine(rint(xTo2D(points[0][0], points[0][2])-stepTopX*step),
                rint(yTo2D(points[0][1], points[0][2])-stepTopY*step),
                rint(xTo2D(points[3][0], points[3][2])+step), 
                rint(yTo2D(points[3][1], points[3][2])+stepBottomY*step),
                0);
        }
        else{
            lcd.drawLine(rint(xTo2D(points[0][0], points[0][2])+stepTopX*step),
                rint(yTo2D(points[0][1], points[0][2])+stepTopY*step),
                rint(xTo2D(points[3][0], points[3][2])-step), 
                rint(yTo2D(points[3][1], points[3][2])-stepBottomY*step),
                0);
        }
    }
}

void Rasturizer::drawFaceOutline(float(&points)[4][3]){
    for (int i = 0; i < 3; i++){     
        lcd.drawLine(rint(xTo2D(points[i][0], points[i][2])),
            rint(yTo2D(points[i][1], points[i][2])),
            rint(xTo2D(points[i+1][0], points[i+1][2])),
            rint(yTo2D(points[i+1][1], points[i+1][2])),
            1);
    }
    lcd.drawLine(rint(xTo2D(points[0][0], points[0][2])),
        rint(yTo2D(points[0][1], points[0][2])),
        rint(xTo2D(points[3][0], points[3][2])),
        rint(yTo2D(points[3][1], points[3][2])),
        1);
}

void Rasturizer::drawAllFaces(Face *faceArray, int noOfCubes, float angle){
    Face temp;
    for (int f = 0; f< (noOfCubes*6)-1; f++){
        for (int f2 = 0; f2< (noOfCubes*6)-f-1; f2++){
            if(faceArray[f2].getAvgZ() < faceArray[f2+1].getAvgZ()){
                temp = faceArray[f2+1];
                faceArray[f2+1] = faceArray[f2];
                faceArray[f2] = temp;
            }
        }
    }
    for (int f = 0; f< noOfCubes*6 ; f++){
        drawFace(&faceArray[f], angle/15);
    }
}

bool Rasturizer::checkOnScreen(float (&points)[4][3]){
    if (points[0][2] < 6 || points[1][2] < 6 || points[2][2] < 6 || points[3][2] < 6){
        return false;
    }
    else if ((xTo2D(points[0][0], points[0][2]) < 0 ||  xTo2D(points[0][0], points[0][2]) > 84)
    && (xTo2D(points[1][0], points[1][2]) < 0 ||  xTo2D(points[1][0], points[1][2]) > 84)
    && (xTo2D(points[2][0], points[2][2]) < 0 ||  xTo2D(points[2][0], points[2][2]) > 84)
    && (xTo2D(points[3][0], points[3][2]) < 0 ||  xTo2D(points[3][0], points[3][2]) > 84)){
        return false;
    }
    return true;
}

void Rasturizer::print(const char *text, int x, int y){
    lcd.printString(text, x, y);
}

void Rasturizer::printScore(int score, int x, int y){
    char buffer[5];
    sprintf(buffer, "%d", score/3);
    print(buffer, x, y);
    memset(buffer, 0, sizeof buffer);    
}

void Rasturizer::clear(){
    lcd.clear();
}

void Rasturizer::refresh(){
    lcd.refresh();
    wait_ms(1000/60);
}

void Rasturizer::turnOff(){
    lcd.turnOff();
}

void Rasturizer::drawDeathScreen(bool selection, int highScore){
    Face faces[6];
    int x, y, z;
    if(selection == true){
        x = -30;
        y = -3;
        z = 50;
    }
    else{
        x = -30;
        y = 15;
        z = 50;
    }
    
    print("Best:", 30, 0);
    printScore(highScore, 60, 0);
    drawDeathButtons();
    drawSelectionCube(x, y, z, 2);
}

void Rasturizer::drawDeathButtons(){
    lcd.drawRect(24, 14, 45, 11, FILL_WHITE);
    lcd.drawRect(24, 14, 45, 11, FILL_TRANSPARENT);
    lcd.printString("Restart",26,2);
    lcd.drawRect(24, 30, 45, 11, FILL_WHITE);
    lcd.drawRect(24, 30, 45, 11, FILL_TRANSPARENT);
    lcd.printString("Menu",35,4);
}

void Rasturizer::drawHomeScreen(int selection){
    int x, y, z;
    if(selection == 0){
        x = -30;
        y = -12;
        z = 50;
    }
    else if(selection == 1){
        x = -30;
        y = 5;
        z = 50;
    }
    else{
        x = -30;
        y = 22;
        z = 50;
    }
    drawHomeButtons();
    drawSelectionCube(x, y, z, -1);
}

void Rasturizer::drawHomeButtons(){
    lcd.drawRect(24, 6, 45, 10, FILL_WHITE);
    lcd.printString("Play",35,1);
    lcd.drawRect(24, 6, 45, 10, FILL_TRANSPARENT);

    lcd.drawRect(24, 22, 45, 10, FILL_WHITE);
    lcd.printString("Help",35,3);
    lcd.drawRect(24, 22, 45, 10, FILL_TRANSPARENT);

    lcd.drawRect(24, 38, 45, 10, FILL_WHITE);
    lcd.printString("Quit",35,5);
    lcd.drawRect(24, 38, 45, 10, FILL_TRANSPARENT);
}

void Rasturizer::drawSelectionCube(int x, int y, int z, int rotationSpeed){
    Face faces[6];
    selectionCube.translate(x, y, z);
    
    for(int i = 0; i < 6; i++){
        faces[i] = selectionCube.getFace(i);
    }
    drawAllFaces(faces, 1, 0);
    selectionCube.rotateX(-0.05*rotationSpeed);
    selectionCube.rotateY(-0.025*rotationSpeed);
    selectionCube.rotateZ(0.04*rotationSpeed);
    selectionCube.translate(-x, -y, -z);
}

void Rasturizer::drawHelpScreen1(){
    lcd.printString("Use the",20,1);
    lcd.printString("joystick",17,2);
    lcd.printString("to move",20,3);
    lcd.printString("left and right",0,4);
}

void Rasturizer::drawHelpScreen2(){
    lcd.printString("Dodge the",15,1);
    lcd.printString("cubes as they",3,2);
    lcd.printString("move closer",10,3);
    lcd.printString("to you",25,4);
}

void Rasturizer::drawHelpScreen3(){
    lcd.printString("Good Luck!",15,2);
}