home *** CD-ROM | disk | FTP | other *** search
- Unit CVGA256;
-
-
- interface
-
- uses crt;
-
- type GrCh = Array[1..8] of Byte;
-
- Const VGA = $A000;
- Alpha : Array[1..41] of GrCh =
- ((0,8,20,34,65,127,65,65), (0,63,65,65,63,65,65,63), (0,28,34,1,1,65,34,28),
- (0,63,97,65,65,65,97,63), (0,127,1,1,31,1,1,127), (0,127,1,1,31,1,1,1),
- (0,60,66,1,1,113,65,62), (0,65,65,65,127,65,65,65),(0,127,8,8,8,8,8,127),
- (0,127,8,8,8,9,9,6), (0,65,33,17,15,17,33,65), (0,1,1,1,1,1,65,127),
- (0,65,99,85,73,65,65,65), (0,65,67,69,73,81,97,65), (0,28,34,65,65,65,34,28),
- (0,63,65,65,63,1,1,1), (0,28,34,65,65,113,34,92),(0,63,65,65,63,9,17,33),
- (0,127,65,1,127,64,65,127),(0,127,8,8,8,8,8,8), (0,65,65,65,65,65,65,62),
- (0,65,65,65,65,34,20,8), (0,65,65,65,73,73,73,54), (0,65,34,20,8,20,34,65),
- (0,65,34,20,8,8,8,8), (0,127,32,16,8,4,2,127), (0,0,0,0,0,0,0,0),
- (0,62,97,81,73,69,67,62), (0,8,12,10,8,8,8,127), (0,62,65,32,16,8,4,127),
- (0,62,65,64,32,64,65,62), (0,17,17,17,127,16,16,16),(0,127,1,1,63,64,64,63),
- (0,60,2,1,63,65,65,62), (0,127,65,64,32,16,8,8), (0,62,65,65,62,65,65,62),
- (0,62,65,65,126,64,32,28), (0,0,0,0,0,16,16,8), (0,0,0,0,0,0,24,24),
- (0,67,35,16,8,4,98,97), (0,0,0,0,127,0,0,0));
-
- type VirtualP = Array [1..64000] of byte; { The size of our Virtual Screen }
- VirtPtr = ^VirtualP; { Pointer to the virtual screen }
- RGB256 = Array[0..255,1..3] of byte;
- DataPicLine = array[0..319] of Byte;
-
- var VirScr: VirtPtr; { Global }
- Vaddr: Word;
-
- procedure StartGraphics;
- procedure StartText;
- procedure Cls (Col : Byte; Where:word);
- procedure Putpixel (X,Y : Integer; Col : Byte; where:word);
- procedure PutpixelClip (X,Y : Integer; Col : Byte; where:word);
- procedure WaitRetrace;
- procedure SetColor(Col,R,G,B : Byte);
- procedure GetColor(Col : Byte; Var R,G,B : Byte);
- procedure GetAllRGB (var Pal: RGB256);
- procedure SetAllRGB (var Pal: RGB256);
- procedure ResetPalette (var Pal: RGB256; Col: Byte);
- procedure ResetScreenPalette (Col: Byte);
- procedure FadeOut (Time: Byte);
- procedure FadeIn (Pal: RGB256;Time: byte);
- procedure CycleColors (var Pal: RGB256; Start,Finish: Byte; Forw: Boolean);
- procedure SetUpVirtual;
- procedure ShutDown;
- procedure Flip(source,dest:Word);
- procedure WriteGraphString (s: string; x,y: word; color: byte; where: word);
- procedure WriteGraphStringCentered (s: string; y: word; color: byte; where: word);
- procedure Line(a,b,c,d:integer;col:byte;where:word);
- procedure LineClip(a,b,c,d:integer;col:byte;where:word);
- procedure LoadPic (Filename: String; Xoffs, Yoffs, Where: Word; var Pal: RGB256);
- procedure Circle (X,Y,Radius: Word; Color: Byte; Where: Word);
- procedure Rectangle (X1,Y1,X2,Y2: Word; Color: Byte; Where: Word);
- procedure Hline (x1,x2,y:word;col:byte;where:word);
- procedure DrawPoly(x1,y1,x2,y2,x3,y3,x4,y4:integer;color:byte;where:word);
-
-
- implementation
-
- Procedure StartGraphics; assembler;
- asm
- mov ax,0013h
- int 10h
- end;
-
- Procedure StartText; assembler;
- asm
- mov ax,0003h
- int 10h
- end;
-
-
-
- Procedure Cls (Col : Byte; Where:word); assembler;
- asm
- push es
- mov cx, 32000;
- mov es,[where]
- xor di,di
- mov al,[col]
- mov ah,al
- rep stosw
- pop es
- end;
-
-
- Procedure Putpixel (X,Y : Integer; Col : Byte; where:word); assembler;
- Asm
- push ds
- push es
- mov ax,[where]
- mov es,ax
- mov bx,[X]
- mov dx,[Y]
- push bx {; and this again for later}
- mov bx, dx {; bx = dx}
- mov dh, dl {; dx = dx * 256}
- xor dl, dl
- shl bx, 6
- add dx, bx {; dx = dx + bx (ie y*320)}
- pop bx {; get back our x}
- add bx, dx {; finalise location}
- mov di, bx
- xor al,al
- mov ah, [Col]
- mov es:[di],ah
- pop es
- pop ds
- end;
-
- procedure PutpixelClip (X,Y : Integer; Col : Byte; where:word);
- begin
- if (Abs (X-160) < 160) and (Abs (Y-100) < 100) then PutPixel (X,Y,Col,Where);
- end;
-
-
- procedure WaitRetrace; assembler;
- { This waits for a vertical retrace to reduce snow on the screen }
- label
- l1, l2;
- asm
- mov dx,3DAh
- l1:
- in al,dx
- and al,08h
- jnz l1
- l2:
- in al,dx
- and al,08h
- jz l2
- end;
-
-
- procedure SetColor(Col,R,G,B : Byte);
- Begin
- asm
- mov dx,3c8h
- mov al,[col]
- out dx,al
- inc dx
- mov al,[r]
- out dx,al
- mov al,[g]
- out dx,al
- mov al,[b]
- out dx,al
- end;
- End;
-
- Procedure GetColor(Col : Byte; Var R,G,B : Byte);
- Var
- rr,gg,bb : Byte;
- Begin
- asm
- mov dx,3c7h
- mov al,col
- out dx,al
- add dx,2
- in al,dx
- mov [rr],al
- in al,dx
- mov [gg],al
- in al,dx
- mov [bb],al
- end;
- r := rr;
- g := gg;
- b := bb;
- end;
-
- procedure GetAllRGB (var Pal: RGB256);
- var i: byte;
- begin
- for i := 0 to 255 do
- GetColor (i,Pal[i,1],Pal[i,2],Pal[i,3]);
- end;
-
-
- procedure SetAllRGB (var Pal: RGB256);
- var i: byte;
- begin
- WaitRetrace;
- for i := 0 to 85 do
- SetColor (i,Pal[i,1],Pal[i,2],Pal[i,3]);
- WaitRetrace;
- for i := 86 to 170 do
- SetColor (i,Pal[i,1],Pal[i,2],Pal[i,3]);
- WaitRetrace;
- for i := 171 to 255 do
- SetColor (i,Pal[i,1],Pal[i,2],Pal[i,3]);
- end;
-
- procedure ResetPalette (var Pal: RGB256; Col: Byte);
- var i: byte;
- begin
- for i := 0 to 255
- do begin
- Pal[i,1] := Col;
- Pal[i,2] := Col;
- Pal[i,3] := Col;
- end;
- end;
-
- procedure ResetScreenPalette (Col: Byte);
- var i: byte;
- begin
- for i := 0 to 255 do
- SetColor (i,Col,Col,Col);
- end;
-
-
- procedure FadeOut (Time: Byte);
- var i,
- j: byte;
- FadeOutPal: RGB256;
- begin
- GetAllRGB (FadeOutPal);
- for i := 0 to 63 do
- begin
- for j := 0 to 255 do
- begin
- If FadeOutPal[j,1] > 0 then dec(FadeOutPal[j,1]);
- If FadeOutPal[j,2] > 0 then dec(FadeOutPal[j,2]);
- If FadeOutPal[j,3] > 0 then dec(FadeOutPal[j,3]);
- end;
- delay(Time);
- SetAllRGB (FadeOutPal);
- end;
- end;
-
- procedure FadeIn (Pal: RGB256; Time: byte);
- var
- TempPal: RGB256;
- i,
- j: byte;
-
- begin
- ResetPalette(TempPal,0);
- for i := 0 to 63 do
- begin
- for j := 0 to 255 do
- begin
- If TempPal[j,1]+1 < Pal[j,1] then inc (TempPal[j,1],2);
- If TempPal[j,2]+1 < Pal[j,2] then inc (TempPal[j,2],2);
- If TempPal[j,3]+1 < Pal[j,3] then inc (TempPal[j,3],2);
- end;
- delay(Time);
- SetAllRGB (TempPal);
- end;
- SetAllRGB (Pal);
- end;
-
- procedure CycleColors (var Pal: RGB256; Start,Finish: Byte; Forw: Boolean);
- var i,R,G,B: byte;
- begin
- if Forw then
- begin
- R := Pal[start,1];
- G := Pal[start,2];
- B := Pal[start,3];
- for i := Start to Finish - 1
- do Pal[i] := Pal[i+1];
- Pal[finish,1] := R;
- Pal[finish,2] := B;
- Pal[finish,3] := G;
- end
- else
- begin
- R := Pal[finish,1];
- G := Pal[finish,2];
- B := Pal[finish,3];
- for i := Finish downto start + 1
- do Pal[i] := Pal[i-1];
- Pal[start,1] := R;
- Pal[start,2] := B;
- Pal[start,3] := G;
- end
- end;
-
-
- Procedure SetUpVirtual;
- BEGIN
- GetMem (VirScr,64000);
- vaddr := seg (virscr^);
- END;
-
- Procedure ShutDown;
- BEGIN
- FreeMem (VirScr,64000);
- END;
-
-
- procedure flip(source,dest:Word);
- { This copies the entire screen at "source" to destination }
- begin
- asm
- push ds
- mov ax, [Dest]
- mov es, ax
- mov ax, [Source]
- mov ds, ax
- xor si, si
- xor di, di
- mov cx, 32000
- rep movsw
- pop ds
- end;
- end;
-
-
- procedure WriteGraphCh (Ch: GrCh; Color:Byte; X,Y: word; Where: Word);
- var i: byte;
- begin
- for i := 1 to 8 do
- begin
- if (ch[i] and $01<>0) then PutPixelClip(x ,y+i-1,Color,Where);
- if (ch[i] and $02<>0) then PutPixelClip(x+1,y+i-1,Color,Where);
- if (ch[i] and $04<>0) then PutPixelClip(x+2,y+i-1,Color,Where);
- if (ch[i] and $08<>0) then PutPixelClip(x+3,y+i-1,Color,Where);
- if (ch[i] and $10<>0) then PutPixelClip(x+4,y+i-1,Color,Where);
- if (ch[i] and $20<>0) then PutPixelClip(x+5,y+i-1,Color,Where);
- if (ch[i] and $40<>0) then PutPixelClip(x+6,y+i-1,Color,Where);
- if (ch[i] and $80<>0) then PutPixelClip(x+7,y+i-1,Color,Where);
- end;
- end;
-
- procedure ConvertString(var S: String);
- var i: byte;
- begin
- for i := 1 to length(s) do
- case S[i] of
- 'A'..'Z': S[i] := chr(ord(S[i]) - 64);
- 'a'..'z': S[i] := chr(ord(S[i]) - 96);
- #32: S[i] := chr(27);
- #48..#57: S[i] := chr(ord(S[i]) - 20);
- ',':S[i] := chr(38);
- '.':S[i] := chr(39);
- '%':S[i] := chr(40);
- '-':S[i] := chr(41);
- else s[i] := chr(27);
- end;
- end;
-
- procedure WriteGraphString (s: string; x,y: word; color: byte; where: word);
- var i: byte;
- begin
- convertstring(s);
- for i := 1 to length(S)
- do writeGraphCh ((Alpha[ord(s[i])]),Color,X+i*8-1,Y,Where);
- end;
-
- procedure WriteGraphStringCentered (s: string; y: word; color: byte; where: word);
- var i: byte;
- begin
- convertstring(s);
- for i := 1 to length(S)
- do writeGraphCh (Alpha[ord(S[i])],Color,round((160-(length(S)/2)*8)+i*8-1),Y,Where);
- end;
-
- Procedure Line(a,b,c,d:integer;col:byte;where:word);
- { This draws a solid line from a,b to c,d in colour col }
- function sgn(a:real):integer;
- begin
- if a>0 then sgn:=+1;
- if a<0 then sgn:=-1;
- if a=0 then sgn:=0;
- end;
- var i,s,d1x,d1y,d2x,d2y,u,v,m,n:integer;
- begin
- u:= c - a;
- v:= d - b;
- d1x:= SGN(u);
- d1y:= SGN(v);
- d2x:= SGN(u);
- d2y:= 0;
- m:= ABS(u);
- n := ABS(v);
- IF NOT (M>N) then
- BEGIN
- d2x := 0 ;
- d2y := SGN(v);
- m := ABS(v);
- n := ABS(u);
- END;
- s := m shr 1;
- FOR i := 0 TO m DO
- BEGIN
- putpixel(a,b,col,where);
- s := s + n;
- IF not (s<m) THEN
- BEGIN
- s := s - m;
- a:= a + d1x;
- b := b + d1y;
- END
- ELSE
- BEGIN
- a := a + d2x;
- b := b + d2y;
- END;
- end;
- END;
-
- Procedure LineClip(a,b,c,d:integer;col:byte;where:word);
- { This draws a solid line from a,b to c,d in colour col }
- function sgn(a:real):integer;
- begin
- if a>0 then sgn:=+1;
- if a<0 then sgn:=-1;
- if a=0 then sgn:=0;
- end;
- var i,s,d1x,d1y,d2x,d2y,u,v,m,n:integer;
- begin
- u:= c - a;
- v:= d - b;
- d1x:= SGN(u);
- d1y:= SGN(v);
- d2x:= SGN(u);
- d2y:= 0;
- m:= ABS(u);
- n := ABS(v);
- IF NOT (M>N) then
- BEGIN
- d2x := 0 ;
- d2y := SGN(v);
- m := ABS(v);
- n := ABS(u);
- END;
- s := m shr 1;
- FOR i := 0 TO m DO
- BEGIN
- if (abs(a-160) < 160) and (abs(b-100) < 100) then
- putpixel(a,b,col,where);
- s := s + n;
- IF not (s<m) THEN
- BEGIN
- s := s - m;
- a:= a + d1x;
- b := b + d1y;
- END
- ELSE
- BEGIN
- a := a + d2x;
- b := b + d2y;
- END;
- end;
- END;
-
- procedure LoadPic ( Filename: String;
- Xoffs,
- Yoffs,
- Where: Word;
- var Pal: RGB256);
-
- var F: File of DataPicLine;
- D: DataPicLine;
- I,J: Word;
- begin
- Assign (F,Filename);
- reset(F);
- for J := 1 to 3 do
- begin
- read(F,D);
- for I := 1 to 256 do Pal[I,J] := D[i];
- end;
- For j := 0 to 200 do
- begin
- read(f,d);
- For i := 0 to 319 do
- PutPixel (i,j,d[i],Where);
- end;
- close(f);
- end;
-
- procedure Circle (X,Y,Radius: Word; Color: Byte; Where: Word);
- var i: byte;
- begin
- for i := 1 to 30 do
- LineClip ( Round(X+Sin(I*Pi/15)*Radius),
- Round(Y+Cos(I*Pi/15)*Radius),
- Round(X+Sin((I+1)*pi/15)*Radius),
- Round(Y+Cos((I+1)*pi/15)*Radius),
- Color,Where);
- end;
-
- procedure Rectangle (X1,Y1,X2,Y2: Word; Color: Byte; Where: Word);
- begin
- line (x1,y1,x2,y1,Color,Where);
- line (x2,y2,x2,y1,Color,Where);
- line (x1,y1,x1,y2,Color,Where);
- line (x2,y2,x1,y2,Color,Where);
- end;
-
- Procedure Hline (x1,x2,y:word;col:byte;where:word); assembler;
- { This draws a horizontal line from x1 to x2 on line y in color col }
- asm
- mov ax,where
- mov es,ax
- mov ax,y
- mov di,ax
- shl ax,8
- shl di,6
- add di,ax
- add di,x1
-
- mov al,col
- mov ah,al
- mov cx,x2
- sub cx,x1
- shr cx,1
- jnc @start
- stosb
- @Start :
- rep stosw
- end;
-
-
- Procedure DrawPoly(x1,y1,x2,y2,x3,y3,x4,y4:integer;color:byte;where:word);
- { Muck of this procedure I can credit Asphixia }
- var
- x:integer;
- mny,mxy:integer;
- mnx,mxx,yc:integer;
- mul1,div1,
- mul2,div2,
- mul3,div3,
- mul4,div4:integer;
- begin
- mny:=y1; mxy:=y1;
- if y2<mny then mny:=y2;
- if y2>mxy then mxy:=y2;
- if y3<mny then mny:=y3;
- if y3>mxy then mxy:=y3;
- if y4<mny then mny:=y4;
- if y4>mxy then mxy:=y4;
-
- if mny<0 then mny:=0;
- if mxy>199 then mxy:=199;
- if mny>199 then exit;
- if mxy<0 then exit; { Verticle range checking }
-
- mul1:=x1-x4; div1:=y1-y4;
- mul2:=x2-x1; div2:=y2-y1;
- mul3:=x3-x2; div3:=y3-y2;
- mul4:=x4-x3; div4:=y4-y3; { Constansts needed for intersection calc }
-
- for yc:=mny to mxy do
- begin
- mnx:=320;
- mxx:=-1;
- if (y4>=yc) or (y1>=yc) then
- if (y4<=yc) or (y1<=yc) then { Check that yc is between y1 and y4 }
- if not(y4=y1) then
- begin
- x:=(yc-y4)*mul1 div div1+x4; { Point of intersection on x axis }
- if x<mnx then
- mnx:=x;
- if x>mxx then
- mxx:=x; { Set point as start or end of horiz line }
- end;
- if (y1>=yc) or (y2>=yc) then
- if (y1<=yc) or (y2<=yc) then { Check that yc is between y1 and y2 }
- if not(y1=y2) then
- begin
- x:=(yc-y1)*mul2 div div2+x1; { Point of intersection on x axis }
- if x<mnx then
- mnx:=x;
- if x>mxx then
- mxx:=x; { Set point as start or end of horiz line }
- end;
- if (y2>=yc) or (y3>=yc) then
- if (y2<=yc) or (y3<=yc) then { Check that yc is between y2 and y3 }
- if not(y2=y3) then
- begin
- x:=(yc-y2)*mul3 div div3+x2; { Point of intersection on x axis }
- if x<mnx then
- mnx:=x;
- if x>mxx then
- mxx:=x; { Set point as start or end of horiz line }
- end;
- if (y3>=yc) or (y4>=yc) then
- if (y3<=yc) or (y4<=yc) then { Check that yc is between y3 and y4 }
- if not(y3=y4) then
- begin
- x:=(yc-y3)*mul4 div div4+x3; { Point of intersection on x axis }
- if x<mnx then
- mnx:=x;
- if x>mxx then
- mxx:=x; { Set point as start or end of horiz line }
- end;
- if mnx<0 then
- mnx:=0;
- if mxx>319 then
- mxx:=319; { Range checking on horizontal line }
- if mnx<=mxx then
- hline (mnx,mxx,yc,color,where); { Draw the horizontal line }
- end;
- end;
-
- end.