Racing Cars game using N5110 LCD and thumb Joystick

Dependencies:   N5110 PowerControl beep mbed

main.cpp

Committer:
el13gs
Date:
2015-05-11
Revision:
8:699055e89c7d
Parent:
7:edf0f1fcb16b

File content as of revision 8:699055e89c7d:

/**
@file main.cpp
@brief Contains all functions implementations, and main program
*/
#include "main.h"

int main()

{

    Peripheral_PowerDown(0xFFFFFFFF); //turn off all peripherals
    /* turn on only the required peripherals */
    Peripheral_PowerUp(0x800000);
    Peripheral_PowerUp(0x200000);
    Peripheral_PowerUp(0x40);
    Peripheral_PowerUp(0x8000);
    Peripheral_PowerUp(0x1000);

    sprintf(soundString,"%s","YES"); //set the Sound Initial String to YES

    calibrateJoystick();  // get centred values of joystick
    pollJoystick.attach(&updateJoystick,1.0/20.0);  // read joystick 30 times per second

    lcd.setXYAddress(0,0);//set the XY address to 0.0 as initialising condition
    initTable();//initialise the array table
    lcd.init();//initialise LCD screen
    lcd.refresh();
    /* PRINT WELCOMING MESSAGES */
    lcd.printString("RACING CARS",9,1);
    wait(0.5);
    lcd.printString("GAME",29,2);
    wait(0.5);
    lcd.printString("by Giorgos",14,4);
    wait(0.5);
    lcd.printString("Savvides",16,5);
    wait(2);
    lcd.clear();
    lcd.refresh();
    lcd.printString("USE JOYSTICK",0,0);
    lcd.printString("AND BUTTONS ",0,1);
    lcd.printString("ON THE RIGHT",0,2);
    lcd.printString("TO NAVIGATE",0,3);
    lcd.printString("HAVE FUN!!!",12,5);
    wait(3.5);
    start.rise(&startButtonPressed); // Call function startButtonPressed when START button pressed
    reset.rise(&resetButtonPressed); // Call function resetButtonPressed when RESET button pressed

MainMenu:
    /* INITIAL DISPLAY IN MAIN MENU */

    int menuPointer=1; // set the Pointer in Main Menu initially to 1
    startButtonFlag=0; // reset the pointing flags
    resetButtonFlag=0; // reset the pointing flags
    clearCells(84,48); // clear the whole Screen Cells
    lcd.refresh(); // refresh are done after and before setting or clearing Pixels
    lcd.drawCircle(22,19,2,1); //initial condition draw pointer around Play submenu
    lcd.drawCircle(53,19,2,1); //initial condition draw pointer around Play submenu

    lcd.printString("MAIN MENU",15,0); //print title
    lcd.printString("Play",26,2); //print submenu title
    lcd.printString("Options",20,3); //print submenu title
    lcd.drawLine(15,9,65,9,1);//underline main menu title
    wait(0.1);
    /* While start Button is not pressed user can navigate through main Menu Submenus */
    while(startButtonFlag==0) {

        /* when joystick moves down, pointer selects Options subMenu */
        if (joystick.direction==DOWN) {
            lcd.drawCircle(16,27,2,1); //draw pointer around Options submenu when selected
            lcd.drawCircle(64,27,2,1); //draw pointer around Options submenu when selected

            lcd.clearCircle(53,19,2,1); //clear pointer around Play submenu
            lcd.clearCircle(22,19,2,1); //clear pointer around Play submenu

            menuPointer=2; //set Pointer to 2
        }

        /* when joystick moves up, pointer selects Options subMenu */
        if(joystick.direction==UP) {
            lcd.drawCircle(22,19,2,1); //draw pointer around Play submenu when selected
            lcd.drawCircle(53,19,2,1); //draw pointer around Play submenu when selected

            lcd.clearCircle(16,27,2,1); //clear pointer around Options submenu
            lcd.clearCircle(64,27,2,1); //clear pointer around Options submenu
            menuPointer=1; //set Pointer to 1
        }
        sleep();
    }

    /* SELECT POINTER CONDITION */
    switch(menuPointer) {

            /* Case when Play was selected */
        case 1:
            /*INITIAL GAME CONDITIONS */
            startButtonFlag=0; //reset start Button Flag
            gamePlays=1; // Begin the game with pointer set to 1
            lives=5; // set lives to 5
            round=1; // set round number to 1
            coins=0; // set coin number to 0
            clearCells(84,48); //clear the whole LCD screen

            lcd.refresh();
            lcd.printString("READY?",20,3);
            wait(0.75);
            lcd.printString("GET SET",20,3);
            wait(1);
            lcd.printString(" GO !!!",20,3);
            wait(1);
            lcd.clear();
            lcd.refresh();


            gameReset(); // set and draw initial player and enemies position
            timer.attach(&movePlayer,0.1);// attach timer to call function that moves the Player


            while(gamePlays) {

                //print Round number on buffer and display
                sprintf(roundBuffer,"%d",round);
                lcd.printString(roundBuffer,74,3);
                lcd.refresh();

                //print Lives number on buffer and display
                sprintf(livesBuffer,"%d",lives);
                lcd.printString(livesBuffer,74,1);
                lcd.refresh();

                //print Coins number on buffer and display
                sprintf(coinsBuffer,"%d",coins);
                lcd.printString(coinsBuffer,72,5);

                lcd.refresh();
                enemy1MovesDown(); //move enemy 1 downwards

                checkPlayerPos(); //check player position frequently
                if (gamePlays==0) {  // if gameplay is 0 returns to initial MAIN MENU
                    goto MainMenu;
                }

                lcd.refresh();
                enemy2MovesDown(); //move enemy 2 downwards

                checkPlayerPos();
                if (gamePlays==0) {
                    goto MainMenu;
                }

                lcd.refresh();
                enemy3MovesDown(); //move enemy 3 downwards

                checkPlayerPos();
                if (gamePlays==0) {
                    goto MainMenu;
                }
                coinMoves(); // move coin downwards
                lcd.refresh();
                checkPlayerPos();
                if (gamePlays==0) {
                    goto MainMenu;
                }
            }

            break;

        case 2:

            int optionsMenu=1; // set options Menu enabled
            optionsPointer=1;
            startButtonFlag=0; //reset START Button Flag

            clearCells(84,48); // clear all screen Cells
            lcd.refresh();
            wait(0.02);
            /* PRINT OPTIONS SUBMENU DISPLAY */
            lcd.printString("OPTIONS",18,0);
            lcd.printString("Exit",23,5);
            lcd.printString("Brightness",6,3);
            lcd.printString("Sound",6,2);
            lcd.drawLine(15,8,61,8,1); //underline Options Menu title

            /* Print brightness value ranged from 1 to 10 to user */
            sprintf(brightnessBuffer,"%d",brightnessDisplay);
            lcd.printString(brightnessBuffer,68,3);

            /* Print Sound string value , "YES" or "NO"*/
            lcd.printString(soundString,40,2);

            /* USER NAVIGATES WHILE IN OPTIONS MENU */
            while(optionsMenu) {

                /* If direction is up pointer value decrease by 1 (cannot decrease to less than 1) */
                if (joystick.direction==UP) {
                    optionsPointer--;
                    if(optionsPointer==0) {
                        optionsPointer=1;
                    }
                }
                wait(0.05);

                /* If direction is down, pointer value increase by 1 (cannot increase to more than 3) */
                if(joystick.direction==DOWN) {
                    optionsPointer++;
                    if(optionsPointer>3) {
                        optionsPointer=3;
                    }
                }
                /* CASES FOR EACH POINTER VALUE */
                /* when it is 1, Sound submenu is selected */
                if (optionsPointer==1) {
                    /* print Circle pointer around Sound submenu */
                    lcd.drawCircle(2,19,2,1);
                    lcd.clearCircle(2,27,2,1);
                    lcd.clearCircle(19,44,2,1);
                    /* if pointer is 1 and joystick direction is left, sound is enabled (=1)*/
                    if(joystick.direction==LEFT) {
                        sounds=1;
                        lcd.refresh();
                        sprintf(soundString,"%s","YES");
                        lcd.printString(soundString,40,2);
                    }
                    /* if pointer is 1 and joystick direction is right, sound is disabled (=0)*/
                    if(joystick.direction==RIGHT) {
                        sounds=0;
                        lcd.refresh();
                        sprintf(soundString,"%s","NO "); //print string in buffer
                        lcd.printString(soundString,40,2); //display value of buffer
                    }
                    sleep();
                }
                /* when it is 2, brightness submenu is selected */
                if (optionsPointer==2) {
                    /* print Circle pointer around Brightness submenu */
                    lcd.drawCircle(2,27,2,1);
                    lcd.clearCircle(2,19,2,1);
                    lcd.clearCircle(19,44,2,1);

                    /* if pointer is 2 and joystick direction is left, brightness decreases by 0.1*/
                    if(joystick.direction==LEFT) {
                        brightness=brightness-.1;
                        brightnessDisplay=brightnessDisplay-1; // user displayed value also decrease
                        if(brightness<0.1||brightnessDisplay<0) { // brightnessDisplay and brightness never go below 0 and 0.1 respectively
                            brightnessDisplay=1;
                            brightness=0.1;
                        }
                        lcd.setBrightness(brightness); //sets the brightness

                        /* print brightness Display on screen */
                        sprintf(brightnessBuffer,"%d",brightnessDisplay);
                        lcd.printString(brightnessBuffer,68,3);
                    }

                    /* if pointer is 2 and joystick direction is right, brightness increases by 0.1*/
                    if(joystick.direction==RIGHT) {
                        brightness=brightness+.1;
                        brightnessDisplay=brightnessDisplay+1; // user displayed value also increase
                        if(brightness>0.9||brightnessDisplay>9) {// brightnessDisplay and brightness never go above 9 and 0.9 respectively
                            brightnessDisplay=9;
                            brightness=0.9;
                        }
                        lcd.setBrightness(brightness); //sets the brightness

                        /* print brightness Display on screen */
                        sprintf(brightnessBuffer,"%d",brightnessDisplay);
                        lcd.printString(brightnessBuffer,68,3);
                    }
                    sleep();
                }
                if (optionsPointer==3) {
                    /* print Circle pointer around Exit submenu */
                    lcd.drawCircle(19,44,2,1);
                    lcd.clearCircle(2,19,2,1);
                    lcd.clearCircle(2,27,2,1);

                    /* if START button is press while pointer is on Exit goes back to Main Menu label */
                    if(startButtonFlag) {
                        startButtonFlag=0;
                        wait(0.5);
                        optionsMenu=0;
                        goto MainMenu;
                    }
                    sleep();
                }
                wait(0.05);
                sleep();

            }
            break;
    }
}

void startButtonPressed()
{
    startButtonFlag=!startButtonFlag;
}

void resetButtonPressed()
{
    resetButtonFlag=!resetButtonFlag;
}

void movePlayer()
{
    if (gamePlays) {
        /* if direction is RIGHT clears the previous Car shape and draws the next one by increasing the x position */
        if (joystick.direction==RIGHT&&x+w<58) {

            clearRect(x,v,w,h);
            lcd.refresh();
            x=x+4;
            lcd.drawRect(x,v,w,h,0);
            lcd.refresh();
        }
        /* if direction is LEFT clears the previous Car shape and draws the next one by decreasing the x position */
        if (joystick.direction==LEFT&&x+w>10) {

            clearRect(x,v,w,h);
            lcd.refresh();
            x=x-4;

            lcd.drawRect(x,v,w,h,0);
            lcd.refresh();
        }
        /* if direction is UP clears the previous Car shape and draws the next one by decreasing the y position */
        if (joystick.direction==UP && v>2) {

            clearRect(x,v,w,h);
            lcd.refresh();
            v=v-4;
            lcd.drawRect(x,v,w,h,0);
            lcd.refresh();
        }
        /* if direction is DOWN clears the previous Car shape and draws the next one by increasing the y position */
        if (joystick.direction==DOWN && v<32) {
            clearRect(x,v,w,h);
            lcd.refresh();
            v=v+4;
            lcd.drawRect(x,v,w,h,0);
            lcd.refresh();
        }

    }
}

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;
}
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 = 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 = LEFT;
    } else if ( joystick.x < DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) {
        joystick.direction = RIGHT;
    } else {
        joystick.direction = UNKNOWN;
    }

    // set flag for printing
    printFlag = 1;
}


void clearRect(int x,int v,int w,int h)
{
    // loop through the array cells, clear the Pixels and array cells value(=0)
    for(int i=x; i<=x+w; i++) {
        for(int j=v; j<=v+h; j++) {
            lcd.clearPixel(i,j);
            table[i][j]=0;
        }
    }
}


void enemy1MovesDown()
{
    clearRect(enemy1x,(j-a),w,h); // clears the previous Enemy Car
    lcd.refresh();
    lcd.drawRect(enemy1x,j,w,h,1); //draws the next enemy Car
    lcd.refresh();
    setRectCells(enemy1x,j,w,h); //set the current enemy cells to 1
    lcd.refresh();
    wait(0.05);

    j=j+a; //increase the y-position counter

    if(j>70) { // after reaching certain y position, randomize it again br
        j=-(rand()%95+85);
    }

}

void enemy2MovesDown()
{
    clearRect(enemy2x,(p-a),w,h); // clears the previous Enemy Car
    lcd.refresh();
    lcd.drawRect(enemy2x,p,w,h,1); //draws the next enemy Car
    lcd.refresh();
    setRectCells(enemy2x,p,w,h); //set the current enemy cells to 1
    lcd.refresh();
    wait(0.05);
    p=p+a; //increase the y-position counter

    if(p>70) {
        p=-(rand()%60+40);
    }

}

void enemy3MovesDown()
{
    clearRect(enemy3x,(q-a),w,h);
    lcd.refresh();
    lcd.drawRect(enemy3x,q,w,h,1);
    lcd.refresh();
    setRectCells(enemy3x,q,w,h);
    lcd.refresh();
    wait(0.05);
    lcd.refresh();
    q=q+a;
    if (q>70) {
        q=-(rand()%34+3);
    }

}

void setRectCells(int x,int v,int w,int h)
{
// Sets the Rectangle Array Cells equal to 1, indicating there is an enemy
    for(int i=x; i<=x+w; i++) {
        for(int j=v; j<=v+h; j++) {
            if(j>0&&j<48) {
                table[i][j]=1;
            }
        }
    }
}

void initTable()
{
    // initialise the Array's cells, set them equal to 0
    for (int i=0; i<=83; i++) {
        for(int j=0; j<=47; j++) {
            table[i][j]=0;
        }
    }
}

void checkPlayerPos()
{
    // frequently calling this function to check if player touched an enemy or a coin
    /* if player cells equal to 1, means he touched enemy, so loose function is being called */
    if (table[x+w][v+h]==1||table[x][v+h]==1||table[x][v]==1||table[x+w][v]==1) {
        loose();
    }
    /* if player cells equal to 2, means he touched a coin */
    if (table[x+w][v+h]==2||table[x][v+h]==2||table[x][v]==2||table[x+w][v]==2) {
        coins=coins+5; //each coin's value is 5,total coins increase by 5
        clearCoin(c); //clear the collected Coin
        lcd.drawRect(x,v,w,h,0);//redraw Player boundaries that were cleared by Coin
        if(sounds) { // if sound is enabled in options menu sound produced when got a coin
            buzzer.beep(2200,0.4); //produce sound of frequency 2200 Hz and duration 0.4 s
            buzzer.beep(1000,0.2);
            lcd.setBrightness(brightness); //set brightness again, frequency produced interfere with LCD pin
        }
        coinAppear=0; //switch coin status to disappear

        /* then Check the total number of coins, to produce to next Round */

        if(coins==30) { // if coins are 40 proceed to next Round
            round=2; // change Round Value
            gamePlays=0; // stop gameplay, preventing user moving on screen
            clearCells(84,48); //clear all Cells
            lcd.refresh();
            lcd.printString("ROUND 2",10,2); //print Round message
            wait(1);
            clearCells(84,48);// clear all Cells
            lcd.refresh();
            gamePlays=1;//start gameplay
            gameReset();//reset player and enemies positions
            a=6; //change enemies acceleration (a is added to y positions counter)
        }
        if(coins==70) { // if coins are 70 proceed to next Round
            round=3; // change Round Value
            gamePlays=0;// stop gameplay, preventing user moving on screen
            clearCells(84,48); //clear all Cells
            lcd.refresh();
            lcd.printString("ROUND 3",10,2); //print Round message
            wait(1);
            clearCells(84,48); // clear all Cells
            lcd.refresh();
            gamePlays=1; //start gameplay
            gameReset(); //reset player and enemies positions
            a=8; //change enemies acceleration (a is added to y positions counter)
        }
        if(coins==90) {  // if coins are 90, player WINS the game
            timer.detach(); //stop player moving
            clearCells(84,48); //clear pixels
            lcd.clear(); //clear LCD
            lcd.refresh();
            lcd.printString("CONGRATS!",0,2); //print win message
            lcd.printString("YOU WON!",8,3); //print win message
            wait(4);
            gamePlays=0; //game finishes
        }
    }
}

void coinMoves()
{
    if(table[xPos][c]==1||table[xPos][c+4]==1||table[xPos+4][c+4]==1) { //prevent coin from appearing above enemies
        clearCoin(c); //clear current Coin
        coinAppear=0; //make coin disappear (prevent from being redrawn)
    }
    clearCoin(c); //clear current Coin
    c=c+4; // increase Coin's y coordinate counter
    drawCoin(c); //draw next Coin position
    if(c>80) { // if counter exceeds 80, randomizes x and y positions and make it reappear
        c=-(rand()%10);
        xPos=rand()%52+4;
        coinAppear=1;
    }
}

void drawCoin(int c)
{
    if (c>4&&c<48&&coinAppear==1) { //check if coin c point(y pos) is within LCD limits
        lcd.drawCircle(xPos,c,4,0); //Draw Coin Circle Pixels
        setCircleCells(xPos,c,4);// Set Coin array's cells values to 2

        // "c" character Print on coin
        lcd.setPixel(xPos,c-1);
        lcd.setPixel(xPos,c+2);
        lcd.setPixel(xPos+1,c-1);
        lcd.setPixel(xPos+1,c+2);
        lcd.setPixel(xPos-1,c);
        lcd.setPixel(xPos-1,c+1);

        lcd.refresh();
    }
}

void clearCoin(int c)
{
    if(c>4&&c<48&&coinAppear==1) { // if c point of the Coin within the LCD limits
        lcd.clearCircle(xPos,c,4,1); //Clear the Coin
        clearCircleCells(xPos,c,4);// Set Coin array's cells values to 0
        lcd.refresh();
    }
}

void loose()
{

    if (sounds) { //check if sound is enabled and produce a "loose" sound of frequency 400 Hz
        buzzer.beep(400,0.2);
        lcd.setBrightness(brightness); //set brightness
    }
    timer.detach(); //detach moving Player function timer, so player cannot move
    lives=lives-1; //decrease lives value
    startButtonFlag=0; //reset START button flag
    resetButtonFlag=0;//reset SELECT button flag
    if(lives==0) { //if lives are equal to 0, Game Over is displayed

        clearCells(84,48);
        lcd.refresh();
        lcd.clear();

        wait(1);
        while(startButtonFlag==0&&resetButtonFlag==0) { //while no button is pressed
            lcd.printString("Game Over!!!",0,0);
            lcd.printString("Press START",0,2);
            lcd.printString("to try again",0,3);
            lcd.printString("or RESET",0,4);
            lcd.printString("to exit :)",0,5);
        }
        if(startButtonFlag) { //START button pressed, resets the game
            a=4;
            gamePlays=1;
            lives=5;
            coins=0;
            round=1;
            clearCells(84,48);
            gameReset();
            startButtonFlag=0;
            wait(1);
            timer.attach(&movePlayer,0.1);
        }
        if (resetButtonFlag) { //RESET button pressed, sets gameplay to 0 ( when gameplay is 0 , returns to MAIN MENU)
            gamePlays=0;
            resetButtonFlag=0;
        }
    }

    else {
        clearCells(60,48); //else if lives are not 0, clearCells and reset the game
        lcd.refresh();
        gameReset(); // reset player and enemies values
        wait(2);
        gamePlays=1;// game is being played
        timer.attach(&movePlayer,0.1); //attach move Player function
    }
}

void gameReset()
{
    initTable(); // initialise the array (set cells values to 0)
    x=26; //initial player x position
    v=30; //initial player y position
    lcd.drawRect(x,v,w,h,0); //draw player at initial position
    lcd.refresh();
    j=-70; // enemy y position, initialise
    q=-10; // enemy y position, initialise
    p=-40; // enemy y position, initialise

}


void setCircleCells(int x0,int y0,int radius)
{
    //function from N5110 Library, works only for filled circle
    int x = radius;
    int y = 0;

    while(x >= y) {

        setLineCells(x+x0,y+y0,-x+x0,y+y0,0); //set line's Cells values to 2
        setLineCells(y+x0,x+y0,-y+x0,x+y0,0);//set line's Cells values to 2
        setLineCells(y+x0,-x+y0,-y+x0,-x+y0,0);//set line's Cells values to 2
        setLineCells(x+x0,-y+y0,-x+x0,-y+y0,0);//set line's Cells values to 2

        y++;
    }
}

void clearCircleCells(int x0,int y0,int radius)
{
    //function from N5110 Library, works only for filled circle
    int x = radius;
    int y = 0;

    while(x >= y) {
        clearLineCells(x+x0,y+y0,-x+x0,y+y0,0);//set line's Cells values to 0
        clearLineCells(y+x0,x+y0,-y+x0,x+y0,0);//set line's Cells values to 0
        clearLineCells(y+x0,-x+y0,-y+x0,-x+y0,0);//set line's Cells values to 0
        clearLineCells(x+x0,-y+y0,-x+x0,-y+y0,0);//set line's Cells values to 0
        y++;
    }
}

void clearCells(int x,int y)
{
    // loops through cells, clears the pixels and set the cells value equal to 0
    for(int i=0; i<=x; i++) {
        for (int j=0; j<=y; j++) {
            lcd.clearPixel(i,j);
            table[i][j]=0;
        }
    }
    lcd.refresh();
}


void setLineCells(int x0,int y0,int x1,int y1,int type)
{
    //function from N5110 Library
    int y_range = y1-y0;  // calc range of y and x
    int x_range = x1-x0;
    int start,stop,step;

    // if dotted line, set step to 2, else step is 1
    step = (type==2) ? 2:1;

    // make sure we loop over the largest range to get the most pixels on the display
    // for instance, if drawing a vertical line (x_range = 0), we need to loop down the y pixels
    // or else we'll only end up with 1 pixel in the x column
    if ( abs(x_range) > abs(y_range) ) {

        // ensure we loop from smallest to largest or else for-loop won't run as expected
        start = x1>x0 ? x0:x1;
        stop =  x1>x0 ? x1:x0;

        // loop between x pixels
        for (int x = start; x<= stop ; x+=step) {
            // do linear interpolation
            int y = y0 + (y1-y0)*(x-x0)/(x1-x0);
            table[x][y]=2;  // set table values to 2
        }
    } else {

        // ensure we loop from smallest to largest or else for-loop won't run as expected
        start = y1>y0 ? y0:y1;
        stop =  y1>y0 ? y1:y0;

        for (int y = start; y<= stop ; y+=step) {
            // do linear interpolation
            int x = x0 + (x1-x0)*(y-y0)/(y1-y0);
            table[x][y]=2;  // set table values to 2
        }
    }

}

void clearLineCells(int x0,int y0,int x1,int y1,int type)
{
    //function from N5110 Library
    int y_range = y1-y0;  // calc range of y and x
    int x_range = x1-x0;
    int start,stop,step;

    // if dotted line, set step to 2, else step is 1
    step = (type==2) ? 2:1;

    // make sure we loop over the largest range to get the most pixels on the display
    // for instance, if drawing a vertical line (x_range = 0), we need to loop down the y pixels
    // or else we'll only end up with 1 pixel in the x column
    if ( abs(x_range) > abs(y_range) ) {

        // ensure we loop from smallest to largest or else for-loop won't run as expected
        start = x1>x0 ? x0:x1;
        stop =  x1>x0 ? x1:x0;
        // loop between x pixels
        for (int x = start; x<= stop ; x+=step) {
            // do linear interpolation
            int y = y0 + (y1-y0)*(x-x0)/(x1-x0);
            table[x][y]=0;  // set Table Cell to 0
        }
    } else {
        // ensure we loop from smallest to largest or else for-loop won't run as expected
        start = y1>y0 ? y0:y1;
        stop =  y1>y0 ? y1:y0;

        for (int y = start; y<= stop ; y+=step) {
            // do linear interpolation
            int x = x0 + (x1-x0)*(y-y0)/(y1-y0);
            table[x][y]=0;  // set Table Cell to 0
        }
    }
}