This is a version of vga640x480g customized to work well with MbedConsole
Fork of vga640x480g by
vga640x480g_functions.h@0:821e34a87609, 2011-07-27 (annotated)
- Committer:
- gertk
- Date:
- Wed Jul 27 19:43:07 2011 +0000
- Revision:
- 0:821e34a87609
0.1
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
gertk | 0:821e34a87609 | 1 | #include "vga_font.h" |
gertk | 0:821e34a87609 | 2 | #define FRAMEBUFFERMAX 32000 |
gertk | 0:821e34a87609 | 3 | #define EXTENSIONMAX 6400 |
gertk | 0:821e34a87609 | 4 | #define VGA_HEIGHT 400 |
gertk | 0:821e34a87609 | 5 | #define VGA_WIDTH 640 |
gertk | 0:821e34a87609 | 6 | #include "mbed.h" |
gertk | 0:821e34a87609 | 7 | |
gertk | 0:821e34a87609 | 8 | extern unsigned char *framebuffer; |
gertk | 0:821e34a87609 | 9 | extern unsigned char *framebuffer2; |
gertk | 0:821e34a87609 | 10 | |
gertk | 0:821e34a87609 | 11 | static const unsigned char rmask[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe}; |
gertk | 0:821e34a87609 | 12 | static const unsigned char smask[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; |
gertk | 0:821e34a87609 | 13 | |
gertk | 0:821e34a87609 | 14 | // clear the screen |
gertk | 0:821e34a87609 | 15 | void vga_cls() { |
gertk | 0:821e34a87609 | 16 | memset(framebuffer,0,FRAMEBUFFERMAX); |
gertk | 0:821e34a87609 | 17 | memset(framebuffer2,0,EXTENSIONMAX); |
gertk | 0:821e34a87609 | 18 | } |
gertk | 0:821e34a87609 | 19 | |
gertk | 0:821e34a87609 | 20 | // scroll the screen one text line up |
gertk | 0:821e34a87609 | 21 | void vga_scroll() { |
gertk | 0:821e34a87609 | 22 | // move first part up |
gertk | 0:821e34a87609 | 23 | memcpy(framebuffer,framebuffer+(FONTHEIGHT*80),FRAMEBUFFERMAX-80*(FONTHEIGHT)); |
gertk | 0:821e34a87609 | 24 | // copy top line of second part into bottom of first part |
gertk | 0:821e34a87609 | 25 | memcpy(framebuffer+FRAMEBUFFERMAX-80*(FONTHEIGHT),framebuffer2,FONTHEIGHT*80); |
gertk | 0:821e34a87609 | 26 | // move bottom part up |
gertk | 0:821e34a87609 | 27 | memcpy(framebuffer2,framebuffer2+(FONTHEIGHT*80),EXTENSIONMAX-80*(FONTHEIGHT)); |
gertk | 0:821e34a87609 | 28 | // clear bottom row of second part |
gertk | 0:821e34a87609 | 29 | memset(framebuffer2+EXTENSIONMAX-80*(FONTHEIGHT),0,FONTHEIGHT*80); |
gertk | 0:821e34a87609 | 30 | } |
gertk | 0:821e34a87609 | 31 | |
gertk | 0:821e34a87609 | 32 | // set or reset a single pixel on screen |
gertk | 0:821e34a87609 | 33 | void vga_plot(int x,int y,char color) { |
gertk | 0:821e34a87609 | 34 | unsigned char *ad; |
gertk | 0:821e34a87609 | 35 | |
gertk | 0:821e34a87609 | 36 | ad=framebuffer+80*y+((x/8)^1); // calculate offset |
gertk | 0:821e34a87609 | 37 | if (ad>=framebuffer+FRAMEBUFFERMAX) { // first test for end of framebuffer |
gertk | 0:821e34a87609 | 38 | ad=framebuffer2+80*(y-400)+((x/8)^1); // calculate offset in framebuffer2 |
gertk | 0:821e34a87609 | 39 | if (ad>framebuffer2+EXTENSIONMAX) return; // clip if exceeded |
gertk | 0:821e34a87609 | 40 | } |
gertk | 0:821e34a87609 | 41 | *ad &= rmask[x%8]; // clear the bit |
gertk | 0:821e34a87609 | 42 | if (color) *ad |= smask[x%8]; // if color != 0 set the bit |
gertk | 0:821e34a87609 | 43 | |
gertk | 0:821e34a87609 | 44 | } |
gertk | 0:821e34a87609 | 45 | |
gertk | 0:821e34a87609 | 46 | // put a character from the vga font on screen |
gertk | 0:821e34a87609 | 47 | void vga_putchar(int x,int y,int ch, char color) { |
gertk | 0:821e34a87609 | 48 | int n,m; |
gertk | 0:821e34a87609 | 49 | for (n=0; n<FONTHEIGHT; n++) { |
gertk | 0:821e34a87609 | 50 | for (m=0; m<FONTWIDTH; m++) { |
gertk | 0:821e34a87609 | 51 | if (vga_font8x16[ch*FONTHEIGHT+n] & (1<<(7-m))) vga_plot(x+m,y+n, color); |
gertk | 0:821e34a87609 | 52 | else vga_plot(x+m,y+n,0); |
gertk | 0:821e34a87609 | 53 | } |
gertk | 0:821e34a87609 | 54 | } |
gertk | 0:821e34a87609 | 55 | } |
gertk | 0:821e34a87609 | 56 | |
gertk | 0:821e34a87609 | 57 | // put a string on screen |
gertk | 0:821e34a87609 | 58 | void vga_putstring(int x,int y, char *s, char color) { |
gertk | 0:821e34a87609 | 59 | while (*s) { |
gertk | 0:821e34a87609 | 60 | vga_putchar(x,y,*(s++),color); |
gertk | 0:821e34a87609 | 61 | x+=FONTWIDTH; |
gertk | 0:821e34a87609 | 62 | } |
gertk | 0:821e34a87609 | 63 | } |
gertk | 0:821e34a87609 | 64 | |
gertk | 0:821e34a87609 | 65 | // Bresenham line routine |
gertk | 0:821e34a87609 | 66 | void vga_line(int x0, int y0, int x1, int y1,char color) { |
gertk | 0:821e34a87609 | 67 | |
gertk | 0:821e34a87609 | 68 | char steep=1; |
gertk | 0:821e34a87609 | 69 | int li,dx,dy,le; |
gertk | 0:821e34a87609 | 70 | int sx,sy; |
gertk | 0:821e34a87609 | 71 | |
gertk | 0:821e34a87609 | 72 | // if same coordinates |
gertk | 0:821e34a87609 | 73 | if (x0==x1 && y0==y1) { |
gertk | 0:821e34a87609 | 74 | vga_plot(x0,y0,color); |
gertk | 0:821e34a87609 | 75 | return; |
gertk | 0:821e34a87609 | 76 | } |
gertk | 0:821e34a87609 | 77 | |
gertk | 0:821e34a87609 | 78 | dx = abs(x1-x0); |
gertk | 0:821e34a87609 | 79 | sx = ((x1 - x0) >0) ? 1 : -1; |
gertk | 0:821e34a87609 | 80 | dy=abs(y1-y0); |
gertk | 0:821e34a87609 | 81 | sy = ((y1 - y0) >0) ? 1 : -1; |
gertk | 0:821e34a87609 | 82 | |
gertk | 0:821e34a87609 | 83 | if (dy > dx) { |
gertk | 0:821e34a87609 | 84 | steep=0; |
gertk | 0:821e34a87609 | 85 | // swap X0 and Y0 |
gertk | 0:821e34a87609 | 86 | x0=x0 ^ y0; |
gertk | 0:821e34a87609 | 87 | y0=x0 ^ y0; |
gertk | 0:821e34a87609 | 88 | x0=x0 ^ y0; |
gertk | 0:821e34a87609 | 89 | |
gertk | 0:821e34a87609 | 90 | // swap DX and DY |
gertk | 0:821e34a87609 | 91 | dx=dx ^ dy; |
gertk | 0:821e34a87609 | 92 | dy=dx ^ dy; |
gertk | 0:821e34a87609 | 93 | dx=dx ^ dy; |
gertk | 0:821e34a87609 | 94 | |
gertk | 0:821e34a87609 | 95 | // swap SX and SY |
gertk | 0:821e34a87609 | 96 | sx=sx ^ sy; |
gertk | 0:821e34a87609 | 97 | sy=sx ^ sy; |
gertk | 0:821e34a87609 | 98 | sx=sx ^ sy; |
gertk | 0:821e34a87609 | 99 | } |
gertk | 0:821e34a87609 | 100 | |
gertk | 0:821e34a87609 | 101 | le = (dy << 1) - dx; |
gertk | 0:821e34a87609 | 102 | |
gertk | 0:821e34a87609 | 103 | for (li=0; li<=dx; li++) { |
gertk | 0:821e34a87609 | 104 | if (steep) { |
gertk | 0:821e34a87609 | 105 | vga_plot(x0,y0,color); |
gertk | 0:821e34a87609 | 106 | } else { |
gertk | 0:821e34a87609 | 107 | vga_plot(y0,x0,color); |
gertk | 0:821e34a87609 | 108 | } |
gertk | 0:821e34a87609 | 109 | while (le >= 0) { |
gertk | 0:821e34a87609 | 110 | y0 += sy; |
gertk | 0:821e34a87609 | 111 | le -= (dx << 1); |
gertk | 0:821e34a87609 | 112 | } |
gertk | 0:821e34a87609 | 113 | x0 += sx; |
gertk | 0:821e34a87609 | 114 | le += (dy << 1); |
gertk | 0:821e34a87609 | 115 | } |
gertk | 0:821e34a87609 | 116 | } |
gertk | 0:821e34a87609 | 117 | |
gertk | 0:821e34a87609 | 118 | // draw an outline box |
gertk | 0:821e34a87609 | 119 | void vga_box(int x0, int y0, int x1, int y1,char color) { |
gertk | 0:821e34a87609 | 120 | vga_line(x0,y0,x1,y0,color); |
gertk | 0:821e34a87609 | 121 | vga_line(x1,y0,x1,y1,color); |
gertk | 0:821e34a87609 | 122 | vga_line(x1,y1,x0,y1,color); |
gertk | 0:821e34a87609 | 123 | vga_line(x0,y1,x0,y0,color); |
gertk | 0:821e34a87609 | 124 | } |
gertk | 0:821e34a87609 | 125 | |
gertk | 0:821e34a87609 | 126 | // draw a filled box |
gertk | 0:821e34a87609 | 127 | void vga_filledbox(int x0, int y0, int x1, int y1,char color) { |
gertk | 0:821e34a87609 | 128 | int n,dn; |
gertk | 0:821e34a87609 | 129 | |
gertk | 0:821e34a87609 | 130 | if (y1>y0) dn=1; |
gertk | 0:821e34a87609 | 131 | else dn=-1; |
gertk | 0:821e34a87609 | 132 | |
gertk | 0:821e34a87609 | 133 | for (n=abs(y1-y0); n>=0; n--) { |
gertk | 0:821e34a87609 | 134 | vga_line(x0,y0,x1,y0,color); |
gertk | 0:821e34a87609 | 135 | y0+=dn; |
gertk | 0:821e34a87609 | 136 | } |
gertk | 0:821e34a87609 | 137 | } |
gertk | 0:821e34a87609 | 138 | |
gertk | 0:821e34a87609 | 139 | // Bresenham circle routine |
gertk | 0:821e34a87609 | 140 | void vga_circle(int x0,int y0, int radius, char color) { |
gertk | 0:821e34a87609 | 141 | |
gertk | 0:821e34a87609 | 142 | int cf = 1 - radius; |
gertk | 0:821e34a87609 | 143 | int dx = 1; |
gertk | 0:821e34a87609 | 144 | int dy = -2 * radius; |
gertk | 0:821e34a87609 | 145 | int cx = 0; |
gertk | 0:821e34a87609 | 146 | int py = radius; |
gertk | 0:821e34a87609 | 147 | |
gertk | 0:821e34a87609 | 148 | vga_plot(x0, y0 + radius,color); |
gertk | 0:821e34a87609 | 149 | vga_plot(x0, y0 - radius,color); |
gertk | 0:821e34a87609 | 150 | vga_plot(x0 + radius, y0,color); |
gertk | 0:821e34a87609 | 151 | vga_plot(x0 - radius, y0,color); |
gertk | 0:821e34a87609 | 152 | |
gertk | 0:821e34a87609 | 153 | while (cx < py) { |
gertk | 0:821e34a87609 | 154 | if (cf >= 0) { |
gertk | 0:821e34a87609 | 155 | py--; |
gertk | 0:821e34a87609 | 156 | dy += 2; |
gertk | 0:821e34a87609 | 157 | cf += dy; |
gertk | 0:821e34a87609 | 158 | } |
gertk | 0:821e34a87609 | 159 | cx++; |
gertk | 0:821e34a87609 | 160 | dx += 2; |
gertk | 0:821e34a87609 | 161 | cf += dx; |
gertk | 0:821e34a87609 | 162 | vga_plot(x0 + cx, y0 + py,color); |
gertk | 0:821e34a87609 | 163 | vga_plot(x0 - cx, y0 + py,color); |
gertk | 0:821e34a87609 | 164 | vga_plot(x0 + cx, y0 - py,color); |
gertk | 0:821e34a87609 | 165 | vga_plot(x0 - cx, y0 - py,color); |
gertk | 0:821e34a87609 | 166 | vga_plot(x0 + py, y0 + cx,color); |
gertk | 0:821e34a87609 | 167 | vga_plot(x0 - py, y0 + cx,color); |
gertk | 0:821e34a87609 | 168 | vga_plot(x0 + py, y0 - cx,color); |
gertk | 0:821e34a87609 | 169 | vga_plot(x0 - py, y0 - cx,color); |
gertk | 0:821e34a87609 | 170 | } |
gertk | 0:821e34a87609 | 171 | } |