From: sjoerd DOT s DOT bakker AT tip DOT nl (sjoerd DOT s DOT bakker AT tip DOT nl) Newsgroups: comp.os.msdos.djgpp Subject: Re: small graphics library Date: Sun, 03 Jan 1999 13:09:13 GMT Organization: WorldOnline News server Lines: 244 Message-ID: <3692676b.560489@news.worldonline.nl> References: <368DE8FD DOT E94FFF21 AT 2xtreme DOT net> NNTP-Posting-Host: vp240-100.worldonline.nl Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Trace: news.worldonline.nl 915368780 4552 195.241.240.100 (3 Jan 1999 13:06:20 GMT) X-Complaints-To: abuse AT worldonline DOT nl NNTP-Posting-Date: 3 Jan 1999 13:06:20 GMT X-Newsreader: Forte Agent 1.5/32.451 To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com On Sat, 02 Jan 1999 01:38:05 -0800, Alex Lowe 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 #include #include #include #include #include #include #include #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 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>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>4; t++) circle(xres>>1, yres>>1, t, t+16); getkey(); init_mode(0x3); return 0; } ------------------------ vesa.c --------------------------