www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1999/01/03/08:14:40

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
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 <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, &regs);
}

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, &regs);
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, &regs);
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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019