home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Hack-Phreak Scene Programs
/
cleanhpvac.zip
/
cleanhpvac
/
GB_FMINT.ZIP
/
SRC
/
CVGA256.PAS
next >
Wrap
Pascal/Delphi Source File
|
1997-01-27
|
16KB
|
606 lines
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.