Mail Archives: djgpp/1999/01/03/08:14:40
On Sat, 02 Jan 1999 01:38:05 -0800, Alex Lowe <ayin AT 2xtreme DOT net>
wrote:
>Hello all,
>
>I am searching for a SMALL (ironically in big letters) graphics library.
>The smaller the better, just a few graphics modes (at least 640x480x16
>colors) and a putpixel... A Vesa library is nice, if it is SMALL, I
>don't want to make a VESA library.
I often needed that myself... I picked up the following VESA-code from
the Internet about a year ago. It didn't do bank-switching right, so I
fixed it. It's a *small* demo-program and it has setmode, putpixel,
rectangle and circle. It only works with VESA-modes 0x101
(640x480x256), 0x103 (800x600x256), and 0x105 (1024x768x256). When
running the program just input the hex-values without the leading 0x:
101, 103 or 105. I hope this is of some help!
------------------------ vesa.c --------------------------
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<assert.h>
#include<go32.h>
#include<dos.h>
#include<dpmi.h>
#include<sys/farptr.h>
#define MODEINFO_SIZE 256
#define ADDR_TAB_SIZE 256
#define WRITE_WINDOW 0
unsigned char modeinfo[MODEINFO_SIZE];
#define ModeAttributes (*(unsigned short*)(modeinfo))
#define WinAAttributes (*(unsigned char *)(modeinfo+2))
#define WinBAttributes (*(unsigned char *)(modeinfo+3))
#define WinGranularity (*(unsigned short*)(modeinfo+4))
#define WinSize (*(unsigned short*)(modeinfo+6))
#define WinASegment (*(unsigned short*)(modeinfo+8))
#define WinBSegment (*(unsigned short*)(modeinfo+10))
#define WinFuncPtr (*(unsigned long *)(modeinfo+12))
#define BytesPerScanLine (*(unsigned short*)(modeinfo+16))
unsigned short mode=0x101;
unsigned long phys_base;
unsigned short win_sizegran_prop;
unsigned short res_tab[8][2] =
{ { 640,400}, { 640,480}, { 800, 600}, { 800, 600},
{1024,768}, {1024,768}, {1280,1024}, {1280,1024}
};
unsigned int addr_tab[ADDR_TAB_SIZE];
void init_mode(unsigned short mode)
{
__dpmi_regs regs;
regs.x.ax = 0x4F02;
regs.x.bx = mode;
__dpmi_int(0x10, ®s);
}
unsigned char VBE_getmodeinfo(unsigned short mode, char *modeinfo)
{
__dpmi_regs regs;
assert(MODEINFO_SIZE < _go32_info_block.size_of_transfer_buffer);
regs.x.ax = 0x4F01;
regs.x.cx = mode;
regs.x.di = __tb & 0x0F;
regs.x.es = (__tb >> 4) & 0xFFFF;
__dpmi_int(0x10, ®s);
dosmemget(__tb, MODEINFO_SIZE, modeinfo);
return regs.h.ah;
}
unsigned short curbank = -1;
void setbank(unsigned short bank, unsigned short rw)
{
__dpmi_regs regs;
unsigned short win_gran = bank * win_sizegran_prop;
regs.x.ax = 0x4F05;
regs.x.bx = rw;
regs.x.dx = win_gran;
__dpmi_int(0x10, ®s);
curbank=bank;
}
void putpixel(short x, short y, char c)
{
int addr = y * BytesPerScanLine + x;
int bank = addr/addr_tab[1];
if (bank != curbank)
setbank (bank, WRITE_WINDOW);
_farpokeb(_dos_ds, phys_base + (addr-addr_tab[curbank]), c);
}
void line(short x, short y, short x2, short y2, char c)
{
int i, steep = 0, sx, sy, dx, dy, e;
dx = abs(x2 - x);
sx = ((x2 - x) > 0) ? 1 : -1;
dy = abs(y2 - y);
sy = ((y2 - y) > 0) ? 1 : -1;
if(dy > dx)
{ steep = 1;
x ^= y; y ^= x; x ^= y;
dx ^= dy; dy ^= dx; dx ^= dy;
sx ^= sy; sy ^= sx; sx ^= sy;
}
e = (dy << 1) - dx;
for(i = 0;i <= dx; i++)
{ if (steep)
putpixel(y, x, c);
else
putpixel(x, y, c);
while(e >= 0)
{ y += sy;
e -= dx << 1;
}
x += sx;
e += dy << 1;
}
}
void rectangle(short x1, short y1, short x2, short y2, char c)
{
short x, y;
for (x=x1; x<=x2; x++)
putpixel(x, y1, c);
for (x=x1; x<=x2; x++)
putpixel(x, y2, c);
for (y=y1; y<=y2; y++)
{ putpixel(x1, y, c);
putpixel(x2, y, c);
}
}
void circle(short xc, short yc, short r, char c)
{
int x = 0, y = r, d = (1 - r) << 1;
while(y >= 0)
{ putpixel(xc + x, yc + y, c);
putpixel(xc + x, yc - y, c);
putpixel(xc - x, yc + y, c);
putpixel(xc - x, yc - y, c);
if(d + y > 0)
{ y -= 1;
d -= (y << 1) - 1;
}
if(x > d)
{ x += 1;
d += (x << 1) + 1;
}
}
return;
}
void make_addr_tab()
{
int i, base=0, win = WinSize*1024;
for (i=0; i<ADDR_TAB_SIZE; i++)
{ addr_tab[i] = base;
base+=win;
}
}
int main(void)
{
short x, y;
double t, yxprop;
short c;
int xres, yres;
printf("Enter the VESA mode you wanna use (ex. 0x101):");
scanf("%hx",&mode);
if (mode < 0x100 || mode > 0x107)
{ fprintf (stderr, "\nMode %hx is not a VBE 1.0 graphics mode\n",
mode);
exit (1);
}
if (VBE_getmodeinfo(mode, modeinfo))
{ fprintf (stderr, "\nMode %hx not available\n", mode);
exit (2);
}
init_mode (mode);
phys_base = WinASegment*16;
win_sizegran_prop = WinSize/WinGranularity;
make_addr_tab();
xres=res_tab[mode-0x100][0];
yres=res_tab[mode-0x100][1];
for (y=0; y < yres; y++)
{ c = y/(yres/256.0);
for (x=0; x < xres; x++)
putpixel(x, y, c);
}
yxprop=yres/(double)xres;
for (c=0; c<xres>>4; c++)
rectangle(c, c*yxprop, xres-c, yres-c*yxprop, c/(xres/256.0)+16);
for(t=0; t<360; t+=.05)
{ x=sin(t)*(xres>>2);
y=cos(t)*(xres>>2);
line (xres >> 1, yres >> 1, (xres>>1) + x, (yres>>1) + y, x+16);
}
for(t=0; t<xres>>4; t++)
circle(xres>>1, yres>>1, t, t+16);
getkey();
init_mode(0x3);
return 0;
}
------------------------ vesa.c --------------------------
- Raw text -