Biblioteka graficzna VESA

    -- Sebastian Pawlak, 1997.


Prezentuję tu moją bibliotekę graficzną VESA, która przeznaczona jest dla kompilatora DJGPP.


Kod źródłowy pliku "VESA.c":

// *************************************************************************
// *************************************************************************
// ***                                                                   ***
// ***  BIBLIOTEKA GRAFICZNA                    DjGPP 2.0                ***
// ***                                          VESA 2.0, 640x480 8bit   ***
// *** vesa.c                                                       TrIx ***
// *************************************************************************
// *************************************************************************
#include "vesa.h"
#include <fcntl.h>
#include <sys/stat.h> // definicje trybu otwarcia pliku przez funkcje "open"
#include <unistd.h> // dla funkcji lseek do LoadPCX
#include <io.h> // filelength
#include <pc.h> // out port
#include <string.h>
#include <dos.h> // for mouse

// *************
// *  ZMIENNE  *
// *************

VBE_ModeInfo modeinfo;
SVGA_card_info cardinfo;
unsigned short _mode_4xxx,_mode_xxx;
short VESA_selector;
unsigned char *videoptr;
unsigned char *_VirtualScreenPointer; // wskaznik do ekranu wirtualnego
unsigned char *MouseMaskTMP;
short MouseX=0,MouseY=0,MouseXtmp=0,MouseYtmp=0,MouseXsize,MouseYsize;
char MouseBusy=0,MouseShow=0;
char *rom_char_set=(char *)0xffa6e;

// ***********************
// *  DEFINICJE FUNKCJI  *
// ***********************

// GraphError - funkcja lokalna biblioteki sygnalizuje bledy
//    error_text - wskaznik do komunikatu o bledzie
void GraphError (char *error_text)
{
 printf ("Graph Error: %s\n",error_text);
 exit (1);
}


// get_SVGA_card_info - funkcja lokalna biblioteki wypelnia strukture
//                      SVGA_card_info zadeklarowana w "vesa.h" informacjami
//                      o karcie graficznej
//    cardinfo - wskaznik do struktury na informacje o karcie
int get_SVGA_card_info (SVGA_card_info *cardinfo)
{
 __dpmi_regs regs;
  
 assert(sizeof(*cardinfo) < _go32_info_block.size_of_transfer_buffer);
 regs.x.ax=0x4F00;
 regs.x.di=__tb&0x0F;
 regs.x.es=(__tb>>4)&0xFFFF;
 __dpmi_int(0x10,&regs);
 dosmemget(__tb,sizeof(*cardinfo), cardinfo);
 if (regs.h.al!=0x4F) return (0); // bark VESA
  else return (-1);
}


// get_VBE_mode_info - funkcja lokalna biblioteki wypelnia strukture
//                      VBE_ModeInfo zadeklarowana w "vesa.h" informacjami
//                      o wskazanym przez zmienna _mode trybie graficznym
//    modeinfo - wskaznik do struktury na informacje o trybie graficznym
int get_VBE_mode_info (VBE_ModeInfo *modeinfo)
{
 __dpmi_regs regs;
  
 assert(sizeof(*modeinfo) < _go32_info_block.size_of_transfer_buffer);
 regs.x.ax=0x4F01;
 regs.x.cx=_mode_xxx;
 regs.x.di=__tb&0x0F;
 regs.x.es=(__tb>>4)&0xFFFF;
 __dpmi_int(0x10,&regs);
 dosmemget(__tb,sizeof(*modeinfo), modeinfo);
 if (regs.h.al!=0x4F) return (0); // brak VESA
  else if (modeinfo->tryb_jest==-1) return (1); // wszystko OK
   else return (-1); // VESA jest, ale nie ma trybu graficznego MODE
}


// InitGraph - funkcja inicjalizuje tryb graficzny wskazany przez zmienna
//             mode, moze wlaczac tryb zarowno 0x13 jak i SVGA
int InitGraph ()
{
 __dpmi_regs regs;
 regs.x.ax=0x4F02;
 regs.x.bx=_mode_4xxx;
 __dpmi_int(0x10,&regs);
 if(regs.h.ah==0) return 1; // tryb wlaczony
  else return 0; // blad
}


// go_VESA - glowna funkcja uruchamiajaca tryb VESA z linear buffer`em
//    mode - nr trybu graficznego poprzedzony 4 lub nie
//    parametr: 0 - nie wyswietla informacji
//              1 - wyswietla informacje
//              2 - wyswietla informacje i czeka na klawisz
void go_VESA (unsigned short mode,char parametr)
{
__dpmi_meminfo mi;

 if ((mode&0x4000)==0) {_mode_4xxx=mode+0x4000; _mode_xxx=mode;}
  else {_mode_4xxx=mode; _mode_xxx=mode-0x4000;}

printf ("---------------------------- Biblioteka graficzna ----------------------------\n");

if (!get_SVGA_card_info (&cardinfo)) GraphError ("Brak VESA !");
if (parametr!=0)
{

 printf ("Informacje o karcie graficznej ...\n");
 printf ("standard: %s    wersja: %d.%d\n",cardinfo.vesa,cardinfo.wersja2,cardinfo.wersja1);
 printf ("pamiec na karcie: %d kB\n",cardinfo.mem_size64kb*64);
 printf ("OEM wersja: %d.%d\n",cardinfo.OEM_software_version2,cardinfo.OEM_software_version1);
 if (cardinfo.wersja2*256+cardinfo.wersja1<0x200)
  GraphError ("Brak VBE 2.0 lub nowszego (polecam UNIVESA) !");
 if (cardinfo.mem_size64kb<16) GraphError ("Wymagany 1MB pamieci na karcie graficznej");
}

if (get_VBE_mode_info (&modeinfo)!=1) GraphError ("Brak trybu graficznego !");
if (parametr!=0)
{
 printf ("Informacje o trybie graficznym: 0x%x, 0x%x... \n",_mode_4xxx,_mode_xxx);
 printf ("rozdzielczosc,  pozioma: %d   pionowa: %d\n",modeinfo.Xmax,modeinfo.Ymax);
 printf ("bitow na piksel: %d\n",modeinfo.BitsPerPixel);
 if (modeinfo.BitsPerPixel!=8) GraphError ("Ten tryb nie jest obslugiwany przez te biblioteke!");
}

VESA_selector=__dpmi_allocate_ldt_descriptors (1);
if (VESA_selector==-1) GraphError ("Blad inicjalizacji selektora ""VESA_selector""");

mi.size=(unsigned long)(modeinfo.Xmax*modeinfo.Ymax);
mi.address=modeinfo.PhysBasePtr;
__dpmi_physical_address_mapping (&mi);

if (__dpmi_set_segment_base_address (VESA_selector,mi.address)==-1)
 GraphError ("Blad operacji na segmencie");
__dpmi_set_segment_limit(VESA_selector, mi.size|0xfff);
videoptr=(unsigned char *)mi.address;

printf ("Ustawianie bazy dla funkcji wyswietlania znakow\n");
__djgpp_nearptr_enable();
rom_char_set+=__djgpp_conventional_base;
__djgpp_nearptr_disable();


if (parametr==2)
{
 printf ("nacisnij dowolny klawisz ...\n");
 getkey();
}
 InitGraph ();
}


// Line - funkcja wyswietla linie w buforze. Ekran _VirtualScreenPointer.
//    x1,y1 - wspolrzedne poczatku
//    x2,y2 - wsporzedne konca
//    color - kolor linii
void Line (int x1,int y1,int x2,int y2,char color)
{
 int dx,dy,sdx,sdy,x,y,px,py;

 dx=x2-x1;
 dy=y2-y1;

 sdx=(dx<0)?-1:1;
 sdy=(dy<0)?-1:1;

 dx=sdx*dx+1;
 dy=sdy*dy+1;

 x=y=0;

 px=x1;
 py=y1;

 if (dx>=dy)
 {
  for (x=0;x<dx;x++)
  {
   _VirtualScreenPointer [(py<<9)+(py<<7)+px]=color;
   y+=dy;
   if (y>=dx) { y-=dx; py+=sdy; }
   px+=sdx;
  }
 }
 else
 {
  for (y=0;y<dy;y++)
  {
   _VirtualScreenPointer [(py<<9)+(py<<7)+px]=color;
    x+=dx;
    if (x>=dy) { x -= dy; px += sdx; }
    py+=sdy;
  }
 }
}


// LoadPCX - funkcja wczytuje obraz zapisany w formacie PCX 8-bit
//    FName - wskaznik do nazwy pliku z obrazem
//    Bufor - wskaznik do bufora w pamieci, do ktorego ma zostac zapisany plik
//    Pal - wskaznik do bufora w pamieci, do ktorego ma zostac zapisana paleta
void LoadPCX (char *FName,unsigned char *Bufor,unsigned char *Pal)
{
 int i;
 int file_handle;
 unsigned short int Xp=0,Yp=0,Xk=0,Yk=0;
 unsigned char byte_per_pixel;
 unsigned short szerok,wysok;
 unsigned long data_size;
 unsigned char *Buf;
 unsigned long Ofs1=0,Ofs2=0;
 unsigned char Color;
 unsigned char licznik;

 file_handle=open (FName,O_RDONLY|O_BINARY);
 if (file_handle==NULL) GraphError ("LoadPCX: Blad otwarcia pliku !");

 lseek (file_handle,3,SEEK_SET);
 read (file_handle,&byte_per_pixel,1);
 if (byte_per_pixel!=8) GraphError ("LoadPCX: Obraz nie jest 8-bitowy !");

 read (file_handle,&Xp,2);
 read (file_handle,&Xp,2);
 read (file_handle,&Xk,2);
 read (file_handle,&Yk,2);

 szerok=Xk-Xp;
 wysok=Yk-Yp;
 data_size=filelength (file_handle)-896;

 lseek (file_handle,filelength (file_handle)-768,SEEK_SET);
 if (read (file_handle,Pal,768)!=768)
  GraphError ("LoadPCX: Blad podczas odczytu palety z pliku !");
 for (i=0;i<=767;i++) *(Pal+i)=(*(Pal+i)&255) / 4;

 lseek (file_handle,128,SEEK_SET);
 Buf=(unsigned char *)malloc (data_size);
 if (Buf==NULL) GraphError ("LoadPCX: Brak pamieci na obraz");
 if (read (file_handle,Buf,data_size)!=data_size)
  GraphError ("LoadPCX: Blad podczas odczytu pliku !");

 close (file_handle);

 Ofs1=0,Ofs2=0;

 *Bufor++=(szerok)-(((szerok)/256)*256);
 *Bufor++=(szerok)/256;
 *Bufor++=(wysok)-(((wysok)/256)*256);
 *Bufor++=(wysok)/256;
 do
 {
 	Color=*(Buf+Ofs1); Ofs1++;

	 if ((Color&0x0c0)==0x0c0)
	 {
	  licznik=Color&0x03f;
	  Color=*(Buf+Ofs1); Ofs1++;
	 }
	 else licznik=1;

	 for (i=0;i<licznik;i++) *(Bufor++)=Color;
 } while (Ofs1<data_size);

 free (Buf);
}


// SetRGBblock - funkcja ustawia blok kolorow
//    pal - wskaznik do palety kolorow w formacie RGB
//    od_kol - nr pierwszego koloru
//    do_kol - ilosc kolorow
void SetRGBblock (unsigned char *pal,unsigned char od_kol,unsigned short int ilosc)
{
 int i;
 outportb (0x03c8,od_kol);
 for (i=0;i<ilosc;i++)
 {
 	outportb (0x03c9,*pal++);
 	outportb (0x03c9,*pal++);
 	outportb (0x03c9,*pal++);
 }
}


// SetRGBregister - funkcja ustawia skladowe RGB dla jednego koloru
//    color - nr koloru
//    r - skladowa czerwona
//    g - skladowa zielona
//    b - skladowa niebieska
void SetRGBregister (unsigned char color,char r,char g,char b)
{
 outportb (0x3c8,color);
 outportb (0x3c9,r);
 outportb (0x3c9,g);
 outportb (0x3c9,b);
}


// PutImage - funkcja wyswietla obraz w buforze. Ekran _VirtualScreenPointer.
//    x,y - wspolrzedne obraz
//    Bufor - bufor z obrazem
void PutImage (short int x,short int y,unsigned char *Bufor)
{
 unsigned short int szerok=*Bufor+*(Bufor+1)*256+1;
 unsigned short int wysok=*(Bufor+2)+*(Bufor+3)*256+1;
 short xp=0,yp=0,xk=szerok,yk=wysok;
 unsigned int Ofs1;
 short _st_ixszerok;
 char widocznosc=1; // boolean
 int i,j;

// obcinanie obrazu, ktory jest poza obszarem ekranu
 if (x<0) { xp=(-1)*x; x=0; if (xp>=szerok) widocznosc=0; }
 if (y<0) { yp=(-1)*y; y=0; if (yp>=wysok) widocznosc=0; }
 if (x+szerok>modeinfo.Xmax) { xk=modeinfo.Xmax-x; if (xk<=0) widocznosc=0; }
 if (y+wysok>modeinfo.Ymax) { yk=modeinfo.Ymax-y; if (yk<=0) widocznosc=0; }

 Ofs1=y*modeinfo.Xmax+x;

 if (widocznosc==1)
  for (i=yp;i<yk;i++)
  {
   memcpy (_VirtualScreenPointer+Ofs1,Bufor+4+i*szerok+xp,xk-xp);
   Ofs1+=modeinfo.Xmax;
  }
}


// GetImage - funkcja pobiera obraz do buforze. Ekran _VirtualScreenPointer.
//    x1,y1 - wspolrzedne 1 rogu obrazu
//    x2,y2 - wspolrzedne 2 rogu obrazu
//    Bufor - bufor na obraz
void GetImage (short x1,short y1,short x2,short y2,unsigned char *Bufor)
{
 unsigned short int szerok=abs (x2-x1)+1;
 unsigned short int wysok=abs (y2-y1)+1;
 short xp=0,yp=0,xk=szerok,yk=wysok;
 unsigned int Ofs1;
 short _st_ixszerok;
 char widocznosc=1; // boolean
 int i,j;

 // czyszczenie bufora
 memset (Bufor+4,0,(szerok+0)*(wysok+0));
 szerok--;
 wysok--;
 *(Bufor+1)=szerok/256;
 *(Bufor+0)=szerok-(szerok/256)*256;
 *(Bufor+3)=wysok/256;
 *(Bufor+2)=wysok-(wysok/256)*256;
 szerok++;
 wysok++;

// obcinanie obrazu, ktory jest poza obszarem ekranu
 if (x1<0) { xp=(-1)*x1; x1=0; if (xp>=szerok) widocznosc=0; }
 if (y1<0) { yp=(-1)*y1; y1=0; if (yp>=wysok) widocznosc=0; }
 if (x1+szerok>modeinfo.Xmax) { xk=modeinfo.Xmax-x1; if (xk<=0) widocznosc=0; }
 if (y1+wysok>modeinfo.Ymax) { yk=modeinfo.Ymax-y1; if (yk<=0) widocznosc=0; }

 Ofs1=y1*modeinfo.Xmax+x1;

 if (widocznosc==1)
  for (i=yp;i<yk;i++)
  {
   memcpy (Bufor+4+i*szerok+xp,_VirtualScreenPointer+Ofs1,xk-xp);
   Ofs1+=modeinfo.Xmax;
  }
}


// PutSprite - funkcja wyswietla sprite`a w buforze. Ekran _VirtualScreenPointer.
//    x,y - wspolrzedne obraz
//    Bufor - bufor z obrazem
//    transparent - kolor przezroczystosci
void PutSprite (short int x,short int y,unsigned char *Bufor,unsigned char transparent)
{
 unsigned short int szerok=*Bufor+*(Bufor+1)*256+1;
 unsigned short int wysok=*(Bufor+2)+*(Bufor+3)*256+1;
 short xp=0,yp=0,xk=szerok,yk=wysok;
 unsigned int Ofs1;
 short _st_ixszerok;
 char widocznosc=1; // boolean
 int i,j;

// obcinanie obrazu, ktory jest poza obszarem ekranu
 if (x<0) { xp=(-1)*x; x=0; if (xp>=szerok) widocznosc=0; }
 if (y<0) { yp=(-1)*y; y=0; if (yp>=wysok) widocznosc=0; }
 if (x+szerok>modeinfo.Xmax) { xk=modeinfo.Xmax-x; if (xk<=0) widocznosc=0; }
 if (y+wysok>modeinfo.Ymax) { yk=modeinfo.Ymax-y; if (yk<=0) widocznosc=0; }

 Ofs1=y*modeinfo.Xmax+x;

 if (widocznosc==1)
  for (i=yp;i<yk;i++)
  {
   _st_ixszerok=i*szerok;
   for (j=xp;j<xk;j++)
   {
	 if (*(Bufor+4+_st_ixszerok+j)!=transparent)
     *(_VirtualScreenPointer+Ofs1+j-xp)=*(Bufor+4+_st_ixszerok+j);
	}
   Ofs1+=modeinfo.Xmax;
  }
}


// MakeSpriteN - funkcja konwertuje bitmape do formatu dla funkcji PutSpriteN
//    Bufor_source_we - bufor z bitmapa
//    Bufor_dest_wy - bufor na przetworzony format
//    transparent - kolor przezroczystosci
int MakeSpriteN (unsigned char *Bufor_source_we,
                 unsigned char *Bufor_dest_we,unsigned char transparent)
{
 int i,j;
 unsigned dlugosc=4;
 unsigned ofs1,ofs2;
 unsigned char *Bufor_dest=Bufor_dest_we;
 unsigned char *Bufor_source=Bufor_source_we;
 unsigned short int szerok=*Bufor_source+*(Bufor_source+1)*256;
 unsigned short int wysok=*(Bufor_source+2)+*(Bufor_source+3)*256;

 *(Bufor_dest++)=(szerok)-(((szerok)/256)*256);
 *(Bufor_dest++)=(szerok)/256;
 *(Bufor_dest++)=(wysok)-(((wysok)/256)*256);
 *(Bufor_dest++)=(wysok)/256;

 szerok++;
 wysok++;

 for (i=0;i<wysok;i++)
 {
  ofs2=0;
  ofs1=0;
  do
  {
   if (*(Bufor_source+4+i*szerok+ofs1)==transparent)  // transparent
   {
    *(Bufor_dest++)=0; dlugosc++;
    for (j=ofs1;j<szerok;j++) if (*(Bufor_source+4+i*szerok+j)!=transparent) break;
    *(Bufor_dest++)=j-ofs1;  dlugosc++;
    ofs1=j;
   }
   else
   {
    for (j=ofs1;j<szerok;j++) if (*(Bufor_source+4+i*szerok+j)==transparent) break;
    *(Bufor_dest++)=j-ofs1;  dlugosc++;
    memcpy (Bufor_dest,Bufor_source+4+i*szerok+ofs1,j-ofs1);
    Bufor_dest+=j-ofs1;  dlugosc+=j-ofs1;
    ofs1=j;
   }
  } while (ofs1<szerok);
 }
 return (dlugosc);
}

// PutSpriteN - funkcja wyswietla innego sprite`a w buforze. Ekran _VirtualScreenPointer.
//    x,y - wspolrzedne obraz
//    Bufor - bufor z obrazem
void PutSpriteN (short int x,short int y,unsigned char *Bufor)
{
 unsigned short int szerok=*Bufor+*(Bufor+1)*256+1;
 unsigned short int wysok=*(Bufor+2)+*(Bufor+3)*256+1;
 short yp,yk=wysok;
 int Ofs1=y*modeinfo.Xmax+x,_Ofs1=0,_Ofs2=0;
 char widocznosc=1; // boolean
 int sz,prz;
 int i,j;

// obcinanie obrazu, ktory jest poza obszarem ekranu
 if (x<0) {   if ((-1)*x>=szerok) widocznosc=0; }
 if (y<0) { yp=(-1)*y;  if ((-1)*y>=wysok) widocznosc=0; }
 if (modeinfo.Xmax-x<=0) widocznosc=0;
 if (y+wysok>modeinfo.Ymax) { yk=modeinfo.Ymax-y; if (yk<=0) widocznosc=0; }

 _Ofs2=0;
if (widocznosc==1)
 for (i=0;i<yk;i++)
 {
  _Ofs1=0;
  do
  {
   if (*(Bufor+4+_Ofs2)==0) { _Ofs1+=*(Bufor+4+_Ofs2+1); _Ofs2+=2; }
   else
   { if (x+_Ofs1+*(Bufor+4+_Ofs2)>modeinfo.Xmax) sz=modeinfo.Xmax-(x+_Ofs1);
      else sz=*(Bufor+4+_Ofs2);
     if (x+_Ofs1<0) { sz=sz+(x+_Ofs1); prz=(-1)*(x+_Ofs1); } else prz=0;
     if ((i>=yp)&&(sz>0)) memcpy (_VirtualScreenPointer+Ofs1+_Ofs1+prz,Bufor+4+_Ofs2+1+prz,sz);
     _Ofs1+=*(Bufor+4+_Ofs2);
     _Ofs2+=*(Bufor+4+_Ofs2); _Ofs2+=1;
   }
  } while (_Ofs1<szerok);
  Ofs1+=modeinfo.Xmax;
 }
}


// GetImageWidth - zwraca szerokosc bitmapy
//    Bufor - bufor z obrazem
int GetImageWidth (unsigned char *Bufor)
{
 unsigned short int szerok=*Bufor+*(Bufor+1)*256;
 unsigned short int wysok=*(Bufor+2)+*(Bufor+3)*256;
 return (szerok+1);
}


// GetImageHeight - zwraca wysokosc bitmapy
//    Bufor - bufor z obrazem
int GetImageHeight (unsigned char *Bufor)
{
 unsigned short int szerok=*Bufor+*(Bufor+1)*256;
 unsigned short int wysok=*(Bufor+2)+*(Bufor+3)*256;
 return (wysok+1);
}


// oczekiwanie na powrot pionowy
void WaitVideo ()
{
 asm ("movl $0x3da,%edx
    wait_start:
       inb %dx,%al
       and $0x8,%al
       jnz wait_start
    wait_end:
       in %dx,%al
       and $0x8,%al
       jz wait_end");
}


// wewnetrzna funkcja obslugi myszki (zakladana na przerwanie)
void MouseFunction()
{
 unsigned char i,j;
 asm("cli; pusha");
 if ((MouseBusy==0)&&(MouseShow==1))
 {
  MouseBusy=1;
 // Wyswietla zapamietane wczesniej tlo
 PutImage (MouseXtmp,MouseYtmp,MouseMaskTMP);

 MouseX=GetMouseX();
 MouseY=GetMouseY();
 // Zapamietanie tla pod myszka
 GetImage (MouseX,MouseY,MouseX+MouseXsize,MouseY+MouseYsize,MouseMaskTMP);

 // Wyswietla myszke
 PutSprite (MouseX,MouseY,MouseMask,255);

 MouseXtmp=MouseX;
 MouseYtmp=MouseY;
 MouseBusy=0;
 }
 asm("popa; sti");
}

// funkcja inicjalizujaca myszke
void InitMouse()
{
 union REGS r;
 __dpmi_regs re;
 static _go32_dpmi_seginfo mouse_seginfo;
 static _go32_dpmi_registers mouse_regs;

 r.h.ah  = 0x00;                     /* <- goto graphics mode */
 r.h.al  = 16;
 int86 (0x10,&r,&r);
 r.x.ax=0x00;                   /* <- set Mikeys/pixel-ratio */
 int86(0x33,&r,&r);

 r.x.ax=7;
 r.x.cx=0;
 r.x.dx=639;
 int86(0x33,&r,&r);
 r.x.ax=8;
 r.x.cx=0;
 r.x.dx=479;
 int86(0x33,&r,&r);

 r.x.ax=0x000F;                   /* <- set Mikeys/pixel-ratio */
 r.x.cx=5;
 r.x.dx=5;
 int86(0x33,&r,&r);

 r.x.ax = 0x001A;                   /* <- set mouse sensitivity */
 r.x.bx = 50;
 r.x.cx = 50;
 int86(0x33,&r,&r);

 MouseXsize=GetImageWidth (MouseMask);
 MouseYsize=GetImageHeight (MouseMask);
 MouseMaskTMP=(char *)malloc ((MouseXsize+1)*(MouseYsize+1)+4);
 GetImage (MouseX,MouseY,MouseX+MouseXsize,MouseY+MouseYsize,MouseMaskTMP);

 mouse_seginfo.pm_offset = (int)MouseFunction;
 mouse_seginfo.pm_selector = _my_cs();
 _go32_dpmi_allocate_real_mode_callback_retf(&mouse_seginfo, &mouse_regs);

 re.x.ax = 0x0C;
 re.x.cx = 0x7f;
 re.x.dx = mouse_seginfo.rm_offset;
 re.x.es = mouse_seginfo.rm_segment;
 __dpmi_int(0x33, &re);            /* install callback */

 r.x.ax=0x001c;                   /* <- set Mikeys/pixel-ratio */
 r.x.bx=1;
 int86(0x33,&r,&r);
 MouseShow=0;
}


// funkcja usuwajaca myszke
void RemoveMouse()
{
 __dpmi_regs re;

 re.x.ax = 0x0C;
 re.x.cx = 0;
 re.x.dx = 0;
 re.x.es = 0;
 __dpmi_int(0x33, &re);         /* install NULL callback */
 MouseShow=0;
 free (MouseMaskTMP);
}


// funkcja uaktywniajaca wyswietlanie kursora myszki}
void ShowMouse()
{
 union REGS r;
 r.x.ax = 0x01;
 int86(0x33, &r, &r);
 GetImage (MouseXtmp,MouseYtmp,MouseXtmp+MouseXsize,MouseYtmp+MouseYsize,MouseMaskTMP);
 MouseShow=1;
 if (MouseBusy==0) MouseFunction();
}

// funkcja dezaktywujaca wyswietlanie kursora myszki}
void HideMouse()
{
 union REGS r;
 r.x.ax = 0x02;
 int86(0x33, &r, &r);
 MouseShow=0;
 PutImage (MouseX,MouseY,MouseMaskTMP);
 MouseXtmp=MouseX;
 MouseYtmp=MouseY;
}

// funkcja zwracajaca stan przyciskow myszki}
unsigned short GetMouseButton()
{
 union REGS r,rout;
 r.x.ax = 0x03;
 int86(0x33, &r, &rout);
 return (rout.x.bx);
}

// funkcja zwracajaca pozycje kursora myszki w osi X}
unsigned short GetMouseX()
{
 union REGS r,rout;
 r.x.ax = 0x03;
 int86(0x33, &r, &rout);
 return (rout.x.cx);
}

// funkcja zwracajaca pozycje kursora myszki w osi Y}
unsigned short GetMouseY()
{
 union REGS r,rout;
 r.x.ax = 0x03;
 int86(0x33, &r, &rout);
 return (rout.x.dx*2);
}


// funkcja wyswietla znak 8x8 z matrycy pod adresem f000:fa6e
//    buf - bufor docelowy
void charXY(unsigned char *buf,int x,int y,int color,unsigned char c)
{
 int offset,x2,y2;
 char *work_char;
 unsigned char bit_mask=0x80;

__djgpp_nearptr_enable();

 work_char=rom_char_set+c*8;
 offset=(y<<8)+(y<<6)+x;

 for (y2=0;y2<8;y2++)
 {
  bit_mask=0x80;
  for (x2=0;x2<8;x2++)
  {
   if (*work_char&bit_mask) buf[offset+x2] = color;
   bit_mask=(bit_mask>>1);
  }
  offset+=modeinfo.Xmax;
  work_char++;
 }
__djgpp_nearptr_disable();
}


// funkcja wyswietla tekst korzystajac z funkcji chatXY
//    buf - bufor docelowy
void textXY(unsigned char *buf,int x,int y,int color,char *string)
{
 int index;
 for (index=0;string[index]!=0;index++)
      charXY(buf,x+(index<<3),y,color,string[index]);
}

Kod źródłowy pliku "VESA.h":

// *************************************************************************
// *************************************************************************
// ***                                                                   ***
// ***  BIBLIOTEKA GRAFICZNA                    DjGPP 2.0                ***
// ***                                          VESA 2.0, 640x480 8bit   ***
// *** vesa.h                                                       TrIx ***
// *************************************************************************
// *************************************************************************
#include <dpmi.h>
#include <go32.h>
#include <assert.h>
#include <sys/nearptr.h>

// **********************************************************
// *  STRUKTURY NA INFORMACJE O KARCIE I TRYBIE GRAFICZNYM  *
// **********************************************************

// Informacje dotyczace karty graficznej
#pragma pack (1)
typedef struct
{
 char vesa [4];  //Napis VESA
 unsigned char wersja1;
 unsigned char wersja2;
 char *firma;
 char zarezerwowane [4];
 char *tryby;  //wskaznik do listy dostepnych trybow
 unsigned short int mem_size64kb; // pamiec na karcie, trzeba pomnozyc przez 64
 // --- VBE v2.0 ---
 unsigned char OEM_software_version1;
 unsigned char OEM_software_version2;
 char *Pointer_to_vendor_name;
 char *Pointer_to_product_name;
 char *Pointer_to_product_revision_string;
 char OEM_scratchpad [256];
} SVGA_card_info;
#pragma pack ()

// Informacje dotyczace trybu graficznego
#pragma pack (1)
typedef struct
{
 // atrybuty trybu
 short int tryb_jest :1;
 short int jest_inf_dodatkowa :1;
 short int bios_piksel :1;
 short int kolor :1;
 short int grafika :1;
 short int rez_tryb :11;
 unsigned char WinAAttributes; // atrybuty okna A ; 8 bitow
 unsigned char WinBAttributes; // atrybuty okna B ; 8 bitow
 unsigned short int WinGranularity; // minimalny odstep miedzy bankami
 unsigned short int WinSize; // rozmiar okna kB
 unsigned short int WinASegment; // segment adresu okna A
 unsigned short int WinBSegment; // segment adresu okna B
 void *WinFuncPtr; // wskaznik do funkcji przelaczajacej banki w V86
 unsigned short int BytesPerScanLine; // ilosc bajtow w linii logicznej
 unsigned short int Xmax; // rozmiar ekranu w poziomie
 unsigned short int Ymax; // rozmiar ekranu w pionie
 unsigned char XCharSize; // szerokosc matrycy znaku
 unsigned char YCharSize; // wysokosc ...
 unsigned char NumberOfPlanes; // liczba platow
 unsigned char BitsPerPixel; // liczba bitow na piksel
 unsigned char NumberOfBanks; // liczba bankow
 unsigned char typ_ekranu; // organizacja ekranu  5-256kolorow
 unsigned char BankSize;  // rozmiar banku w kB
 unsigned char NumberOfImagePages; // liczba stron
 unsigned char reserved;
 // VESA 1.2
 unsigned char r_size; // liczba bitow na skladowa R
 unsigned char RedFieldPosition; // pozycja skladowej R
 unsigned char g_size; // liczba bitow na skladowa G
 unsigned char GreenFieldPosition; // pozycja skladowej G
 unsigned char b_size; // liczba bitow na skladowa B
 unsigned char BlueFieldPosition; // pozycja skladowej B
 unsigned char RsvdMaskSize; // liczba bitow na skladowa dodatkowa
 unsigned char RsvdFieldPosition; // liczba bitow na skladowa dodatkowa
 unsigned char DirectColorModeInfo; // Direct color mode attributes
 // VESA 2.0
 unsigned long PhysBasePtr; // physical address for flat frame buffer
 unsigned long OffScreenMemOffset; // pointer to start of off screen memory
 unsigned short int OffScreenMemSize; // wielkosc obszaru poza obrazem w kB
 char res2[206];    // Pad to 256 byte block size
} VBE_ModeInfo;
#pragma pack ()


// **********************
// *  ZMIENNE GLOBALNE  *
// **********************
short VESA_selector;
unsigned char *videoptr;//0x0;
unsigned char *_VirtualScreenPointer; // wskaznik do ekranu wirtualnego
unsigned char *MouseMask;

// ***********************
// *  PROTOTYPY FUNKCJI  *
// ***********************
#define PutScreen(buf) (movedata (_my_ds(),(int)buf,VESA_selector,(int)0,640*480));
#define PutPixelScreen(x,y,c) (videoptr [((y)<<9)+((y)<<7)+(x)+__djgpp_conventional_base]=c);
#define PutPixel(buf,x,y,c) (buf [((y)<<9)+((y)<<7)+(x)]=c);
//#define WaitVideo while (inportb (0x3da)&8!=1);
void ustaw_VESA (short int);
void Line (int,int,int,int,char);
void LoadPCX (char *,unsigned char *,unsigned char *);
void SetRGBblock (unsigned char *pal,unsigned char od_kol,unsigned short int ilosc);
void SetRGBregister (unsigned char,char,char,char);
void PutImage (short int,short int,unsigned char *);
void PutSprite (short int,short int,unsigned char *,unsigned char);
int MakeSpriteN (unsigned char *,unsigned char *,unsigned char);
void PutSpriteN (short int,short int,unsigned char *);
int GetImageWidth (unsigned char *);
int GetImageHeight (unsigned char *);
void WaitVideo ();
void MouseFunction();
void InitMouse();
void RemoveMouse();
void ShowMouse();
void HideMouse();
unsigned short GetMouseButton();
unsigned short GetMouseX();
unsigned short GetMouseY();
void charXY(unsigned char *buf,int x,int y,int color,unsigned char c);
void textXY(unsigned char *buf,int x,int y,int color,char *string);

Kod źródłowy pliku "main.c":

#include <conio.h>
#include <stdlib.h>
#include <pc.h>
#include "vesa.h"

unsigned char bufor [640*480+640];

void main (int ilosc_parametrow,char *lista_parametrow[])
{
 int i,j,k;
 __dpmi_regs regs;

 _VirtualScreenPointer=bufor;
 go_VESA (0x4101,2);

 for(i = 0; i < 640 * 480 ; i++)
   bufor[i] = i%640;

 k = 0;
 while(!kbhit()) {
  k+=4;
  if(k>637)
   k = 0;
  WaitVideo();
  PutScreen (bufor+k);
 }

 getch();
 k=0;
 while(!kbhit()) {
  k+=1;
  if(k>=360)
   k = 0;
  WaitVideo();
  PutScreen (bufor+sin(k*3.1415/180.0)*150);
 }


 regs.x.ax=3;
 __dpmi_int(0x10,&regs);
}
w3cw3c
automatyka przemysłowa