/* VGA256.C The source file for the functions that render dots, circles, lines and text in VGA Mode 13H. The video mode capable of displaying 320x200 pixels in 256 colors. This was written by Gary Wilkerson Jr for use by the entire gaming community. This code is not copyrighted nor do I expect any of it to be copyrighted. This code is to be 'common knowledge' among the gaming community. You are free to use and modify it in any way as you see fit. Happy programming. */ #include "vga256.h" /* Include our header file */ unsigned char far *videoMem = (unsigned char far *)0xA0000000L; unsigned char far *cacheMem = NULL; unsigned int cacheSize = 0; unsigned int cacheLines = 0; unsigned char far *charSet = (unsigned char far *)0xF000FA6EL; void SetVideoMode(int mode) { union REGS regs; regs.x.ax = mode; int86(0x10, ®s, ®s); } void Circle(int x, int y, int radius, unsigned char color) { int a, b, d; int xx1, yy1, xx2, yy2; int xy1, yx1, xy2, yx2; int XX1, YY1, XX2, YY2; int XY1, YX1, XY2, YX2; a = 0; b = radius; d = (1 - radius) * 2; xx1 = x; yy1 = y + b; xx2 = x; yy2 = y - b; xy1 = x + b; yx1 = y; xy2 = x - b; yx2 = y; while (b >= a) { if (xx1 < 0) XX1 = 0; else if (xx1 >= ScreenWidth) XX1 = ScreenWidth - 1; else XX1 = xx1; if (yy1 < 0) YY1 = 0; else if (yy1 >= ScreenHeight) YY1 = ScreenHeight - 1; else YY1 = yy1; if (xx2 < 0) XX2 = 0; else if (xx2 >= ScreenWidth) XX2 = ScreenWidth - 1; else XX2 = xx2; if (yy2 < 0) YY2 = 0; else if (yy2 >= ScreenHeight) YY2 = ScreenHeight - 1; else YY2 = yy2; if (xy1 < 0) XY1 = 0; else if (xy1 >= ScreenWidth) XY1 = ScreenWidth - 1; else XY1 = xy1; if (yx1 < 0) YX1 = 0; else if (yx1 >= ScreenHeight) YX1 = ScreenHeight - 1; else YX1 = yx1; if (xy2 < 0) XY2 = 0; else if (xy2 >= ScreenWidth) XY2 = ScreenWidth - 1; else XY2 = xy2; if (yx2 < 0) YX2 = 0; else if (yx2 >= ScreenHeight) YX2 = ScreenHeight - 1; else YX2 = yx2; SetPixel(XX1, YY1, color); SetPixel(XX1, YY2, color); SetPixel(XX2, YY1, color); SetPixel(XX2, YY2, color); SetPixel(XY1, YX1, color); SetPixel(XY1, YX2, color); SetPixel(XY2, YX1, color); SetPixel(XY2, YX2, color); if (d + b > 0) { b--; d -= (b * 2) + 1; yy1--; yy2++; xy1--; xy2++; } if (a > d) { a++; d += (a * 2) + 1; xx1++; xx2--; yx1++; yx2--; } } } void Line(int x1, int y1, int x2, int y2, unsigned char color) { int dx, dy; int xIncr, yIncr; int error = 0, i; dx = x2 - x1; dy = y2 - y1; if (dx >= 0) xIncr = 1; else { xIncr = -1; dx = -dx; } if (dy >= 0) yIncr = 1; else { yIncr = -1; dy = -dy; } if (dx > dy) { for (i=0; i<=dx; i++) { if (x1 >= 0 && x1 < ScreenWidth && y1 >= 0 && y1 < ScreenHeight) SetPixel(x1, y1, color); error += dy; if (error>dx) { error -= dx; y1 += yIncr; } x1 += xIncr; } } else { for (i=0; i<=dy; i++) { if (x1 >= 0 && x1 < ScreenWidth && y1 >= 0 && y1 < ScreenHeight) SetPixel(x1, y1, color); error += dx; if (error>dy) { error -= dy; x1 += xIncr; } y1 += yIncr; } } } void CircleC(int x, int y, int radius, unsigned char color) { int a, b, d; int xx1, yy1, xx2, yy2; int xy1, yx1, xy2, yx2; int XX1, YY1, XX2, YY2; int XY1, YX1, XY2, YX2; a = 0; b = radius; d = (1 - radius) * 2; xx1 = x; yy1 = y + b; xx2 = x; yy2 = y - b; xy1 = x + b; yx1 = y; xy2 = x - b; yx2 = y; while (b >= a) { if (xx1 < 0) XX1 = 0; else if (xx1 >= ScreenWidth) XX1 = ScreenWidth - 1; else XX1 = xx1; if (yy1 < 0) YY1 = 0; else if (yy1 >= cacheLines) YY1 = cacheLines - 1; else YY1 = yy1; if (xx2 < 0) XX2 = 0; else if (xx2 >= ScreenWidth) XX2 = ScreenWidth - 1; else XX2 = xx2; if (yy2 < 0) YY2 = 0; else if (yy2 >= cacheLines) YY2 = cacheLines - 1; else YY2 = yy2; if (xy1 < 0) XY1 = 0; else if (xy1 >= ScreenWidth) XY1 = ScreenWidth - 1; else XY1 = xy1; if (yx1 < 0) YX1 = 0; else if (yx1 >= cacheLines) YX1 = cacheLines - 1; else YX1 = yx1; if (xy2 < 0) XY2 = 0; else if (xy2 >= ScreenWidth) XY2 = ScreenWidth - 1; else XY2 = xy2; if (yx2 < 0) YX2 = 0; else if (yx2 >= cacheLines) YX2 = cacheLines - 1; else YX2 = yx2; SetPixelC(XX1, YY1, color); SetPixelC(XX1, YY2, color); SetPixelC(XX2, YY1, color); SetPixelC(XX2, YY2, color); SetPixelC(XY1, YX1, color); SetPixelC(XY1, YX2, color); SetPixelC(XY2, YX1, color); SetPixelC(XY2, YX2, color); if (d + b > 0) { b--; d -= (b * 2) + 1; yy1--; yy2++; xy1--; xy2++; } if (a > d) { a++; d += (a * 2) + 1; xx1++; xx2--; yx1++; yx2--; } } } void LineC(int x1, int y1, int x2, int y2, unsigned char color) { int dx, dy; int xIncr, yIncr; int error = 0, i; dx = x2 - x1; dy = y2 - y1; if (dx >= 0) xIncr = 1; else { xIncr = -1; dx = -dx; } if (dy >= 0) yIncr = 1; else { yIncr = -1; dy = -dy; } if (dx > dy) { for (i=0; i<=dx; i++) { if (x1 >= 0 && x1 < ScreenWidth && y1 >= 0 && y1 < cacheLines) SetPixelC(x1, y1, color); error += dy; if (error>dx) { error -= dx; y1 += yIncr; } x1 += xIncr; } } else { for (i=0; i<=dy; i++) { if (x1 >= 0 && x1 < ScreenWidth && y1 >= 0 && y1 < cacheLines) SetPixelC(x1, y1, color); error += dx; if (error>dy) { error -= dy; x1 += xIncr; } y1 += yIncr; } } } void SetPaletteRegister(int index, struct RGB_Color *color) { /* Tell VGA card we're accessing a palette register */ outp(PALETTE_MASK, 0xFF); /* Tell VGA card which register is being written to */ outp(PALETTE_WRITE_REGISTER, index); /* Write the data */ outp(PALETTE_DATA, color->red); outp(PALETTE_DATA, color->green); outp(PALETTE_DATA, color->blue); } void GetPaletteRegister(int index, struct RGB_Color *color) { /* Tell VGA card we're accessing a palette register */ outp(PALETTE_MASK, 0xFF); /* Tell VGA card which register is being read */ outp(PALETTE_READ_REGISTER, index); /* Get the data */ color->red = inp(PALETTE_DATA); color->green = inp(PALETTE_DATA); color->blue = inp(PALETTE_DATA); } void Gputch(int x, int y, int c, int fc, int bc) { char far *workChar; unsigned char bit; int xOff, yOff; workChar = &charSet[(c & 0xFF) * CharHeight]; for (yOff=0; yOff= 0) SetPixel(x + xOff, y + yOff, bc); } bit >>= 1; } } workChar++; } } void Gputs(int x, int y, char *string, int fc, int bc) { int i; for (i=0; string[i]; i++) Gputch(x + (i << 3), y, string[i], fc, bc); } void GputchC(int x, int y, int c, int fc, int bc) { char far *workChar; unsigned char bit; int xOff, yOff; workChar = &charSet[(c & 255) * CharHeight]; for (yOff=0; yOff= 0) SetPixelC(x + xOff, y + yOff, bc); } bit >>= 1; } } workChar++; } } void GputsC(int x, int y, char *string, int fc, int bc) { int i; for (i=0; string[i]; i++) GputchC(x + (i << 3), y, string[i], fc, bc); } int InitCache(unsigned int numLines) { if (numLines > ScreenHeight) numLines = ScreenHeight; cacheSize = (numLines << 8) + (numLines << 6); if (cacheMem != NULL) farfree(cacheMem); if (cacheSize == 0) { cacheMem = NULL; cacheLines = 0; cacheSize = 0; return 1; } cacheMem = (unsigned char far *)farcalloc(cacheSize, sizeof(unsigned char)); if (cacheMem == NULL) { cacheSize = 0; cacheLines = 0; return 0; } cacheLines = numLines; return 1; } void DeleteCache(void) { if (cacheMem != NULL) farfree(cacheMem); cacheLines = 0; cacheSize = 0; cacheMem = NULL; } void WaitForVertRetrace(void) { while (inp(VGA_STATUS_1) & VGA_RETRACE_MASK); while (!(inp(VGA_STATUS_1) & VGA_RETRACE_MASK)); }