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); }