My implementation of VT100 ESC-sequence utility

Dependents:   test_vt100 maze_vt100_MMA8451Q funcgen test_MAG3110 ... more

vt100.cpp

Committer:
Rhyme
Date:
2015-08-02
Revision:
2:b7229a9eae1c
Parent:
0:94253645a02a

File content as of revision 2:b7229a9eae1c:

#include "serial_api.h"
#include "vt100.h"
#include "mbed.h"

#define BLACK   0
#define RED     1
#define GREEN   2
#define YELLOW  3
#define BLUE    4
#define PURPLE  5
#define CIAN    6
#define WHITE   7

char ESC = '\033' ;

vt100::vt100(int baud)
{
   extern serial_t stdio_uart ;
   serial_baud(&stdio_uart, baud) ;
}

vt100::~vt100()
{
}

void vt100::cls(void)
{
    printf("%c[2J", ESC) ;
    locate(1,1) ;
}

void vt100::locate(int x, int y)
{
    printf("%c[%d;%dH",ESC,y,x) ;
}

void vt100::putChar(int x, int y, char c)
{
    locate(x,y) ;
    printf("%c",c) ;
}

void vt100::putStr(int x, int y, char *str)
{
    locate(x,y) ;
    printf("%s", str) ;
}

void vt100::line(int x1, int y1, int x2, int y2, char c) 
{
    int x, y, dx, dy, w, h, step ;
    dx = x2 - x1 ;
    dy = y2 - y1 ;
    w = (dx >= 0)? dx : -dx ;
    h = (dy >= 0)? dy : -dy ;

    if (dx == 0) { /* vertical line */
        step = (dy >= 0) ? 1 : -1 ;
        for (y = 0 ; y <= h ; y++) {
            putChar(x1, y1 + (step * y), c) ;
        }
    } else if (dy == 0) { /* Horizontal line */
        step = (dx >= 0) ? 1 : -1 ;
        for (x = 0 ; x <= w ; x++) {
            putChar(x1 + (step * x), y1, c) ;
        }
    } else {
        if (w >= h) { /* use x as step */
            step = (dx >= 0) ? 1 : -1 ;
            for (x = 0 ; x <= w ; x++ ) {
                putChar( x1 + step*x, y1 + ((2*x+1) * dy)/(2 * w), c) ;
            }
        } else { /* use y as step */
            step = (dy >= 0) ? 1 : -1 ;
            for (y = 0 ; y <= h ; y++ ) {
                putChar( x1 + ((2*y+1) * dx)/(2*h), y1 + step*y,  c) ;
            }
        }
    }
}

/****************************************************
 *  frame(x1, y1, x2, y2)
 *  draw textual frame
 *  (x1,y1)                    (x2,y1)
 *     +--------------------------+
 *     |                          |
 *     +--------------------------+
 *  (x1,y2)                    (x2,y2)
 */
void vt100::frame(int x1, int y1, int x2, int y2)
{
    int tmp ;
    if (x1 > x2) {
        tmp = x1 ;
        x1 = x2 ;
        x2 = tmp ;
    }
    if (y1 > y2) {
        tmp = y1 ;
        y1 = y2 ;
        y2 = tmp ;
    }
    putChar(x1, y1, '+') ;
    line(x1+1,y1,x2-1,y1, '-') ; 
    putChar(x2, y1, '+') ; 
    line(x2,y1+1,x2,y2-1, '|') ; 
    putChar(x2, y2, '+') ; 
    line(x2-1,y2,x1+1,y2, '-') ; 
    putChar(x1, y2, '+') ; 
    line(x1,y2-1,x1,y1+1, '|') ; 
}

/***************************************************
 *  circle(x, y, r, c) 
 *  Based on Jack Elton Bresenham's
 *  Midpoint circle algorithm.
 *  http://en.wikipedia.org/wiki/Midpoint_circle_algorithm
  */
void vt100::circle(int x0, int y0, int r, char c) 
{
    int f = 1 - r ;
    int dFx = 1 ;
    int dFy = -2 * r ;
    int x = 0 ;
    int y = r ;
    
    putChar(x0, y0 + r, c) ; 
    putChar(x0, y0 - r, c) ; 
    putChar(x0 + 2*r, y0, c) ; 
    putChar(x0 - 2*r, y0, c) ; 
    
    while(x < y) {
        if (f >= 0) {
            y-- ;
            dFy += 2 ;
            f += dFy ;
        }
        x++ ;
        dFx += 2 ;
        f += dFx ;
        putChar(x0 + 2*x, y0 + y, c) ; 
        putChar(x0 - 2*x, y0 + y, c) ; 
        putChar(x0 + 2*x, y0 - y, c) ; 
        putChar(x0 - 2*x, y0 - y, c) ; 
        putChar(x0 + 2*y, y0 + x, c) ; 
        putChar(x0 - 2*y, y0 + x, c) ; 
        putChar(x0 + 2*y, y0 - x, c) ; 
        putChar(x0 - 2*y, y0 - x, c) ; 
    }
}

int vt100::setFG(int newFG)
{
    int oldFG = foreground ;
    printf("\033[3%dm", newFG) ;
    foreground = newFG ;
    return( oldFG ) ;
}

int vt100::getFG()
{
    return( foreground ) ;
}

int vt100::setBG(int newBG)
{
    int oldBG = background ;
    printf("\033[4%dm", newBG) ;
    return( oldBG ) ;
}

int vt100::getBG()
{
    return( background ) ;
}
    
void vt100::black()
{
    setFG( BLACK ) ;
}

void vt100::red()
{
    setFG( RED ) ;
}

void vt100::green()
{
    setFG( GREEN ) ;
}

void vt100::yellow()
{
    setFG( YELLOW ) ;
}

void vt100::blue()
{
    setFG( BLUE ) ;
}

void vt100::purple()
{
    setFG( PURPLE ) ;
}

void vt100::cian()
{
    setFG( CIAN ) ;
}

void vt100::white()
{
    setFG( WHITE ) ;
}