home *** CD-ROM | disk | FTP | other *** search
- {Enhanced Graphics Adapter toolbox in Turbo pascal:
-
- Authors: Frank Guenther (Compuserve 76545,666)
- Steve Olson
-
- Date : Dec 2 1985
-
- Contact at "The Programmers Toolbox"
- (301) 540-7230 (data)
-
- ******************************
- These procedures and functions
- are in the public domain.
- ******************************
-
- }
- program ega;
-
- type
- regpak=
- record AX,BX,CX,DX,BP,SI,DI,DS,ES,FLAGS:INTeger END;
- str80=string[80];
- pstr80=^str80;
- coltype=array[0..15] of byte;
-
- const defcol:coltype=($0,$1,$2,$3,$4,$5,$14,$7,
- $38,$39,$3A,$3B,$3C,$3D,$3E,$3F);
-
- var stemp:str80;
- x,y,color,bakcolor,ega_mode,ega_mem,ega_feature,ega_switch:integer;
- setcolors:array[0..15] of integer;
-
- function get_key:integer;
- var r:regpak;
- begin
- r.ax:=0;
- intr($16,r);
- if lo(r.ax)=0 then get_key:=hi(r.ax)+256
- else get_key:=lo(r.ax);
- end;
-
- procedure writestr(wstr:str80;wx,wy:integer;wcolor:byte);
- var
- wr:regpak;
- begin
- if (wx<0) or (wx>79) or (wy<0) or (wy>24) then exit;
- with wr do begin
- ES:=seg(wstr[1]);
- BP:=ofs(wstr[1]);
- BX:=wcolor;
- CX:=length(wstr);
- DX:=(wy shl 8)+wx;
- AX:=$1301;
- intr(16,wr);
- end;
- end;
-
- procedure egaset(eset:byte);
- var er:regpak;
- begin
- er.AX:=eset;
- intr(16,er);
- end;
-
- procedure setmode(smode:byte);
- begin
- port[$3CE]:=5;
- port[$3CF]:=smode;
- end;
-
- procedure setpalette(spalnum,spalcolor:byte);
- var sr:regpak;
- begin
- sr.AX:=$1000;
- sr.BX:=(spalcolor shl 8)+spalnum;
- intr(16,sr);
- end;
-
- procedure egainfo;
- var er:regpak;
- begin
- er.AX:=$1200;
- er.BX:=$10;
- intr(16,er);
- ega_mode:=hi(er.BX);
- ega_mem:=lo(er.BX);
- ega_feature:=hi(er.CX);
- ega_switch:=lo(er.CX);
- end;
-
- procedure hrpixel(hx,hy:integer;hcol:byte);
- var loc,i:integer;
- bmask:byte;
- begin
- if (hx<0) or (hx>639) or (hy<0) or (hy>349) then exit;
- loc:=hy*80+(hx shr 3);
- i:=7-(hx mod 8);
- bmask:=(1 shl i);
- setmode(2);
- port[$3CE]:=8;
- port[$3CF]:=bmask;
- i:=mem[$A000:loc];
- mem[$A000:loc]:=hcol;
- setmode(0);
- port[$3CE]:=8;
- port[$3CF]:=$FF;
- end;
-
- function getpixval(hx,hy:integer):integer;
- var loc,i:integer;
- bmask:byte;
- begin
- getpixval:=-1;
- if (hx<0) or (hx>639) or (hy<0) or (hy>349) then exit;
- loc:=hy*80+(hx shr 3);
- i:=7-(hx mod 8);
- bmask:=(1 shl i);
- i:=3;hx:=0;
- repeat
- port[$3CE]:=4;
- port[$3CF]:=i;
- hy:=mem[$A000:loc];
- hx:=hx shl 1;
- if (hy and bmask)>0 then hx:=hx+1;
- i:=i-1;
- until i=-1;
- getpixval:=hx;
- end;
-
- function readpix(hx,hy:integer;hcol:byte):integer;
- var loc,i,j:integer;
- bmask:byte;
- begin
- readpix:=0;
- if (hx<0) or (hx>639) or (hy<0) or (hy>349) then exit;
- loc:=hy*80+(hx shr 3);
- i:=7-(hx mod 8);
- bmask:=(1 shl i);
- setmode(8);
- port[$3CE]:=2;
- port[$3CF]:=hcol;
- hy:=mem[$A000:loc];
- readpix:=(bmask shl 8)+(hy and $FF);
- end;
-
- function testpix(hx,hy:integer;hcol:byte):boolean;
- var pixval,bmask:integer;
- begin
- testpix:=false;
- pixval:=readpix(hx,hy,hcol);
- bmask:=hi(pixval);
- pixval:=lo(pixval);
- if (bmask and pixval)>0 then testpix:=true;
- end;
-
- function findpix(hx,hy:integer;hcol:byte):integer;
- var pixval,bmask,tmask,result,count:integer;
- begin
- findpix:=-99;
- pixval:=readpix(hx,hy,hcol);
- if (lo(pixval)=0) then exit;
- bmask:=hi(pixval);
- pixval:=lo(pixval);
- result:=99;tmask:=bmask;count:=0;
- while (tmask>0) and (result=99) do begin
- if (tmask and pixval)>0 then result:=count;
- count:=count+1;
- tmask:=(bmask shr count);
- end;
- tmask:=(bmask shl 1);count:=1;
- while (tmask<256) and (result>0) do begin
- if (tmask and pixval)>0 then result:=-count;
- count:=count+1;
- tmask:=(bmask shl count);
- end;
- findpix:=result;
- end;
-
- procedure hrclear(ccolor:byte);
- var i:integer;
- begin
- for i:=0 to 7 do hrpixel(i,0,ccolor);
- setmode(1);
- i:=mem[$A000:0000];
- i:=0;
- repeat
- memw[$A000:i]:=ccolor;
- i:=i+2;
- until i=28000;
- setmode(0);
- end;
-
- procedure hrline(xstr,ystr,xend,yend:integer;lcolor:byte);
-
- procedure regline(xs,ys,xe,ye:integer);
- var ii,jj:integer;
- begin
- ii:=((xe-xs) div 2)+xs;
- jj:=((ye-ys) div 2)+ys;
- if ((ii=xs) and (jj=ys)) then exit;
- hrpixel(ii,jj,lcolor);
- regline(xs,ys,ii,jj);
- regline(ii,jj,xe,ye);
- end;
-
- begin
- regline(xstr,ystr,xend,yend);
- hrpixel(xstr,ystr,lcolor);
- hrpixel(xend,yend,lcolor);
- end;
-
- procedure drawbox(xstr,ystr,xend,yend,boxcolor:integer);
- begin
- hrline(xstr,ystr,xend,ystr,boxcolor);
- hrline(xend,ystr,xend,yend,boxcolor);
- hrline(xend,yend,xstr,yend,boxcolor);
- hrline(xstr,yend,xstr,ystr,boxcolor);
- end;
-
- procedure fillbox(xstr,ystr,xend,yend,boxcolor:integer);
- var i,ii,j,jj,k,l:integer;
- begin
- if xend<xstr then begin
- i:=xstr;
- xstr:=xend;
- xend:=i;
- end;
- if yend<ystr then begin
- i:=ystr;
- ystr:=yend;
- yend:=i;
- end;
- k:=xstr div 8;
- l:=xend div 8;
- if (xend mod 8)>0 then l:=l+1;
- for ii:=xstr to xend do hrpixel(ii,ystr,boxcolor);
- setmode(1);
- for i:=ystr+1 to yend do
- for ii:=k to l do begin
- j:=(i-1)*80+ii;
- jj:=mem[$A000:j];
- j:=j+80;
- mem[$A000:j]:=boxcolor;
- end;
- setmode(0);
- end;
-
- procedure xorbox(xstr,ystr,xend,yend,xorval:integer);
- var xs,xe,i,j,k,loc:integer;
- begin
- port[$3CE]:=3;
- port[$3CF]:=$18;
- xs:=xstr div 8;
- xe:=xend div 8;
- setmode(2);
- port[$3CE]:=8;
- port[$3CF]:=$FF;
- for j:=ystr to yend do
- for i:=xs to xe do begin
- if i=xs then begin
- for k:=xstr to xstr+7-(xstr mod 8) do hrpixel(k,j,xorval);
- setmode(2);
- end else if i=xe then begin
- for k:=xe*8 to xend do hrpixel(k,j,xorval);
- setmode(2);
- end else begin
- loc:=j*80+i;
- k:=mem[$A000:loc];
- mem[$A000:loc]:=xorval;
- end;
- end;
- setmode(0);
- port[$3CE]:=3;
- port[$3CF]:=0;
- end;
-
- procedure xorstring(hx,hy,hlength:integer);
- var i,j:integer;
- begin
- hx:=hx*8;
- i:=hx+(hlength*8)-1;
- hy:=hy*14;
- j:=hy+13;
- xorbox(hx,hy,i,j,$F);
- end;
-
- procedure drawcircle(xs,ys,rad,dcolor:integer;flg:byte);
- var
- i,ma,mb,mc,md,aa,bb,cc,dd,ee,ff,gg,hh,incr2 : integer;
- r1,r2,x,y,temp,incr,fixrad:real;
- flgs:array[1..8] of boolean;
-
- begin
- incr:=Pi/(3.1*rad);
- incr2:=round(10000*incr); {integer incr; speed up loop}
- r1:=sin(incr);
- r2:=cos(incr); {close to 1; ignore in calculations}
- fixrad:=0.8*rad;
- for i:=0 to 7 do {Precalculate to speed up loop}
- if (flg and (1 shl i))>0 then flgs[i+1]:=true
- else flgs[i+1]:=false;
- i:=0;x:=1;y:=0;
- while i<=7854 do begin
- ma:=round(rad*x);
- mb:=round(fixrad*y);
- mc:=round(rad*y);
- md:=round(fixrad*x);
- aa:=xs+ma;
- bb:=ys+mb;
- cc:=ys-mb;
- dd:=xs-ma;
- ee:=xs+mc;
- ff:=ys+md;
- gg:=ys-md;
- hh:=xs-mc;
- if flgs[8] then hrpixel(aa,bb,dcolor);
- if flgs[1] then hrpixel(aa,cc,dcolor);
- if flgs[5] then hrpixel(dd,bb,dcolor);
- if flgs[4] then hrpixel(dd,cc,dcolor);
- if flgs[7] then hrpixel(ee,ff,dcolor);
- if flgs[2] then hrpixel(ee,gg,dcolor);
- if flgs[6] then hrpixel(hh,ff,dcolor);
- if flgs[3] then hrpixel(hh,gg,dcolor);
- temp:=y;
- y:=y+x*r1;
- x:=x-temp*r1;
- i:=i+incr2;
- end;
- end;
-
- procedure palette;
- var col,pixcol,row,i,j,k:integer;
- begin
- for i:=0 to 15 do begin
- row:=(i div 4);
- col:=(i mod 4);
- row:=row*80+20;
- col:=col*20+5;
- pixcol:=col*8;
- j:=row-1;
- k:=pixcol-1;
- fillbox(pixcol,row,pixcol+79,row+39,i);
- drawbox(k,j,k+81,j+41,0);
- end;
- end;
-
- procedure interact;
- var i,ii,j,jj,k:integer;
-
- procedure dbox(dpal,dcol:integer);
- var di,dj:integer;
- begin
- di:=dpal div 4;
- dj:=dpal mod 4;
- di:=di*80+20-5;
- dj:=(dj*20+5)*8-5;
- drawbox(dj,di,dj+89,di+49,dcol);
- end;
-
- begin
- writestr('Press ESC to QUIT.',0,23,5);
- xorstring(0,23,18);
- for i:=0 to 15 do setcolors[i]:=defcol[i];
- i:=0;j:=defcol[0];
- ii:=i;
- dbox(i,1);
- repeat
- repeat until keypressed;
- k:=get_key;
- case k of
- 27:exit;
- 328:j:=j+1;
- 336:j:=j-1;
- 331:i:=i-1;
- 333:i:=i+1;
- else writeln(chr(7));
- end;
- if i>15 then i:=0;
- if i<0 then i:=15;
- if j>63 then j:=0;
- if j<0 then j:=63;
- if i<>ii then begin
- dbox(ii,bakcolor);
- dbox(i,1);
- ii:=i;
- j:=setcolors[i];
- jj:=j;
- end;
- if j<>jj then begin
- setpalette(i,j);
- setcolors[i]:=j;
- jj:=j;
- end;
- until i=16;
- end;
-
- begin
- clrscr;
- bakcolor:=$3;
- egaset(16);
- setmode(0);
- hrclear(bakcolor);
- egainfo;
- palette;
- interact;
- egaset(3);
- for x:=0 to 15 do writeln('Palette ',x :2,'= ',setcolors[x]);
- end.
-