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,®s);
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,®s);
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,®s);
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,®s);
}





