This is a version of vga640x480g customized to work well with MbedConsole

Dependents:   MbedConsole

Fork of vga640x480g by Gert van der Knokke

vga640x480g_functions.h

Committer:
earlz
Date:
2012-09-28
Revision:
3:be212d7dbb60
Parent:
0:821e34a87609

File content as of revision 3:be212d7dbb60:

#include "vga_font.h"
#define FRAMEBUFFERMAX 32000
#define EXTENSIONMAX 6400
#define VGA_HEIGHT 400
#define VGA_WIDTH 640
#include "mbed.h"

extern unsigned char *framebuffer;
extern unsigned char *framebuffer2;

static const unsigned char rmask[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
static const unsigned char smask[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};

// clear the screen
void vga_cls() {
    memset(framebuffer,0,FRAMEBUFFERMAX);
    memset(framebuffer2,0,EXTENSIONMAX);
}

// scroll the screen one text line up
void vga_scroll() {
    // move first part up
    memcpy(framebuffer,framebuffer+(FONTHEIGHT*80),FRAMEBUFFERMAX-80*(FONTHEIGHT));
    // copy top line of second part into bottom of first part
    memcpy(framebuffer+FRAMEBUFFERMAX-80*(FONTHEIGHT),framebuffer2,FONTHEIGHT*80);
    // move bottom part up
    memcpy(framebuffer2,framebuffer2+(FONTHEIGHT*80),EXTENSIONMAX-80*(FONTHEIGHT));
    // clear bottom row of second part
    memset(framebuffer2+EXTENSIONMAX-80*(FONTHEIGHT),0,FONTHEIGHT*80);
}

// set or reset a single pixel on screen
void vga_plot(int x,int y,char color) {
    unsigned char *ad;

    ad=framebuffer+80*y+((x/8)^1);                      // calculate offset
    if (ad>=framebuffer+FRAMEBUFFERMAX) {               // first test for end of framebuffer
        ad=framebuffer2+80*(y-400)+((x/8)^1);                // calculate offset in framebuffer2
        if (ad>framebuffer2+EXTENSIONMAX) return;            // clip if exceeded
    }
    *ad &= rmask[x%8];             // clear the bit
    if (color) *ad |= smask[x%8]; // if color != 0 set the bit

}

// put a character from the vga font on screen
void vga_putchar(int x,int y,int ch, char color) {
    int n,m;
    for (n=0; n<FONTHEIGHT; n++) {
        for (m=0; m<FONTWIDTH; m++) {
            if (vga_font8x16[ch*FONTHEIGHT+n] & (1<<(7-m))) vga_plot(x+m,y+n, color);
            else vga_plot(x+m,y+n,0);
        }
    }
}

// put a string on screen
void vga_putstring(int x,int y, char *s, char color) {
    while (*s) {
        vga_putchar(x,y,*(s++),color);
        x+=FONTWIDTH;
    }
}

// Bresenham line routine
void vga_line(int x0, int y0, int x1, int y1,char color) {

    char steep=1;
    int li,dx,dy,le;
    int sx,sy;

    // if same coordinates
    if (x0==x1 && y0==y1) {
        vga_plot(x0,y0,color);
        return;
    }

    dx = abs(x1-x0);
    sx = ((x1 - x0) >0) ? 1 : -1;
    dy=abs(y1-y0);
    sy = ((y1 - y0) >0) ? 1 : -1;

    if (dy > dx) {
        steep=0;
        // swap X0 and Y0
        x0=x0 ^ y0;
        y0=x0 ^ y0;
        x0=x0 ^ y0;

        // swap DX and DY
        dx=dx ^ dy;
        dy=dx ^ dy;
        dx=dx ^ dy;

        // swap SX and SY
        sx=sx ^ sy;
        sy=sx ^ sy;
        sx=sx ^ sy;
    }

    le = (dy << 1) - dx;

    for (li=0; li<=dx; li++) {
        if (steep) {
            vga_plot(x0,y0,color);
        } else {
            vga_plot(y0,x0,color);
        }
        while (le >= 0) {
            y0 += sy;
            le -= (dx << 1);
        }
        x0 += sx;
        le += (dy << 1);
    }
}

// draw an outline box
void vga_box(int x0, int y0, int x1, int y1,char color) {
    vga_line(x0,y0,x1,y0,color);
    vga_line(x1,y0,x1,y1,color);
    vga_line(x1,y1,x0,y1,color);
    vga_line(x0,y1,x0,y0,color);
}

// draw a filled box
void vga_filledbox(int x0, int y0, int x1, int y1,char color) {
    int n,dn;

    if (y1>y0) dn=1;
    else dn=-1;

    for (n=abs(y1-y0); n>=0; n--) {
        vga_line(x0,y0,x1,y0,color);
        y0+=dn;
    }
}

// Bresenham circle routine
void vga_circle(int x0,int y0, int radius, char color) {

    int cf = 1 - radius;
    int dx = 1;
    int dy = -2 * radius;
    int cx = 0;
    int py = radius;

    vga_plot(x0, y0 + radius,color);
    vga_plot(x0, y0 - radius,color);
    vga_plot(x0 + radius, y0,color);
    vga_plot(x0 - radius, y0,color);

    while (cx < py) {
        if (cf >= 0) {
            py--;
            dy += 2;
            cf += dy;
        }
        cx++;
        dx += 2;
        cf += dx;
        vga_plot(x0 + cx, y0 + py,color);
        vga_plot(x0 - cx, y0 + py,color);
        vga_plot(x0 + cx, y0 - py,color);
        vga_plot(x0 - cx, y0 - py,color);
        vga_plot(x0 + py, y0 + cx,color);
        vga_plot(x0 - py, y0 + cx,color);
        vga_plot(x0 + py, y0 - cx,color);
        vga_plot(x0 - py, y0 - cx,color);
    }
}