My implementation of VT100 ESC-sequence utility

Files at this revision

API Documentation at this revision

Comitter:
Rhyme
Date:
Mon Dec 01 12:48:02 2014 +0000
Child:
1:62238d4d6032
Commit message:
The first version with comments;

Changed in this revision

vt100.cpp Show annotated file Show diff for this revision Revisions of this file
vt100.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vt100.cpp	Mon Dec 01 12:48:02 2014 +0000
@@ -0,0 +1,216 @@
+#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 ) ;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vt100.h	Mon Dec 01 12:48:02 2014 +0000
@@ -0,0 +1,145 @@
+#ifndef VT100_H
+#define VT100_H included
+
+/** vt100 class
+ * Utility for handling text/letter on a terminal
+ * which can handle VT100 escape command sequence.
+ *
+ * Example:
+ * @code
+ * #include "mbed.h"
+ * #include "vt100.h"
+ * 
+ * vt100 tty ;
+ * 
+ * int main() {
+ *   int count = 0 ;
+ *   tty.cls() ;
+ *   tty.black() ;
+ *   tty.frame(5, 5, 15, 9) ;
+ *   while(1) {
+ *       tty.locate(7, 7) ;
+ *       tty.setFG(count % 8) ;
+ *       printf("%d\r\n", count++) ;
+ *       wait(1.0) ;
+ *   }
+ * }
+ * @endcode
+ * 
+ * Note: I know there should be other libraries
+ *  with similar functions, but I could not help 
+ *  writing one for myself anyway.
+ */
+
+class vt100 {
+public:
+    /** constructor 
+     * @param baud baud rate
+     */
+    vt100(int baud = 115200) ;
+    
+    /** destructor */
+    ~vt100(void) ;
+    
+    /** clear screen */
+    void cls(void) ;
+    
+    /** move cursor to (x, y) 
+     * @param x start column of the next letter
+     * @param y start row of the next letter
+     * @note no value checking is performed.
+     */
+    void locate(int x, int y) ;
+    
+    /** print a letter c at (x,y)
+     * @param c the letter to be written 
+     * @param x column of the letter
+     * @param y row of the letter
+     */
+    void putChar(int x, int y, char c) ;
+    
+    /** print a string str from (x,y) 
+     * @param *str c-style string to be written
+     * @param x column of the first letter
+     * @param y row of the first letter
+     */
+    void putStr(int x, int y, char *str) ;
+    
+    /** print a line of char 
+     * @param c the letter to form the line
+     * @param x1 starting column
+     * @param y1 starting row
+     * @param x2 ending column
+     * @param y2 ending row
+     */
+    void line(int x1, int y1, int x2, int y2, char c='*') ;
+    
+    /** print a text frame 
+     * @param x1 left column
+     * @param y1 top row
+     * @param x2 right column
+     * @param y2 bottom row
+     */
+    void frame(int x1, int y1, int x2, int y2) ;
+    
+    /** print a text circle
+     * @c the letter to form the circle
+     * @param x0 center column
+     * @param y1 center row
+     * @param r radius
+     */
+    void circle(int x0, int y0, int r, char c='*') ;
+    
+    /** set foreground color
+     * @param newFG new foreground color
+     * @returns previous foreground color
+     * @note 0 BLACK
+     * @note 1 RED
+     * @note 2 GREEN
+     * @note 3 YELLOW
+     * @note 4 BLUE
+     * @note 5 PURPLE
+     * @note 6 CIAN
+     * @note 7 WHITE
+     */
+    int setFG(int newFG) ;
+    
+    /** get current foreground color 
+     * @returns current foreground color
+     */
+    int getFG(void) ;
+    
+    /** set background color
+     * @param newBG new background color
+     * @returns previous background color
+     */
+    int setBG(int newBG) ;
+    
+    /** get current background color 
+     * @returns current background color
+     */
+    int getBG(void) ;
+    /** set foreground color to black */
+    void black(void) ;
+    /** set foreground color to red */
+    void red(void) ;
+    /** set foreground color to green */
+    void green(void) ;
+    /** set foreground color to yellow */
+    void yellow(void) ;
+    /** set foreground color to blue */
+    void blue(void) ;
+    /** set foreground color to purple */
+    void purple(void) ;
+    /** set foreground color to cian */
+    void cian(void) ;
+    /** set foreground color to white */
+    void white(void) ;
+protected:
+private:
+    int foreground ;
+    int background ;
+
+} ;
+
+#endif /* VT100_H */
\ No newline at end of file