home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
BEEHIVE
/
UTILITYS
/
PUDD.ARC
/
PUDD-05.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1991-08-11
|
11KB
|
302 lines
{****************************************************************************}
{* Rightside will find the first high point to the right of the point *}
{* given by centerbyte and centerbit in the array bytelist. *}
{****************************************************************************}
function RightSide (centerbyte :integer;
centerbit :integer;
bytelist :scanline): integer;
var i,j,k :integer;
l :byte;
bitlist :Blist;
linelocal :scanline;
last :boolean; {.....signals last byte in array }
begin
last := false;
i := centerbyte +1;
j := 1;
linelocal := bytelist;
if linelocal[i] <> 0 then {....clear bits to the left of centerbit }
begin
k := 0;
repeat
clrbitB(7-k,linelocal[centerbyte+1]);
if k < centerbit then
k := k + 1;
until (k = centerbit);
end;
i := i-1;
repeat {.........start looking for a bit to the right }
if i = 80 then
last := true
else
i := i + 1;
until (last) or (linelocal[i] <> 0); {...until finding a bit with a high bit }
ReadByte(linelocal[i],bitlist);
FlipList(bitlist);
while copy(bitlist,j,1) <> '1' do
begin
j := j + 1;
if j = 9 then {...force out of loop }
begin {...by providing answer to while }
j := 8;
bitlist := '11111111';
end;
end;
if (Centerbit = 0) and (Centerbyte = 0) then
RightSide := 0
else
RightSide := ((i-1) * 8) + (j-1);
end;
{****************************************************************************}
{* LeftSide will find the first high point to the left of the point *}
{* given by centerbyte and centerbit in the array bytelist. *}
{****************************************************************************}
function LeftSide (centerbyte :integer;
centerbit :integer;
bytelist :scanline): integer;
var i,j,k :integer;
bitlist :Blist;
linelocal :scanline;
first :boolean; {.....signals first byte in array }
begin
first := false;
i := centerbyte+1;
j := 7;
linelocal := bytelist;
if linelocal[i] <> 0 then {....clear bits to the left of centerbit }
begin
k := 7;
repeat
clrbitB(7-k,linelocal[centerbyte+1]);
if k > centerbit then
k := k - 1;
until (k = centerbit);
end;
repeat {.........start looking for a bit to the left }
if i = 0 then {.....by finding the byte }
first := true
else
i := i - 1;
until (first) or (linelocal[i+1] <> 0); {...until finding a bit with a high bit }
ReadByte(linelocal[i+1],bitlist);
FlipList(bitlist);
while copy(bitlist,j+1,1) <> '1' do
begin
j := j - 1;
if j = 0 then {...force out of loop }
begin {...by providing answer to while }
bitlist := '11111111';
end;
end;
LeftSide := ((i) * 8) + (j);
end;
{****************************************************************************}
{* Fillone will fill the horz line specified by Y with the current fill *}
{* style etc. The fill is done from the LeftMost bit to the RightMost bit, *}
{* unless the point specified by CenterX is already lit then Continue is *}
{* set to false and no other action is pursued. *}
{****************************************************************************}
procedure FillOne(var CenterX :integer;
var Continue :boolean;
Y :integer);
var chunk :byte; {......a chunk of 8 bits}
bit :byte; {......the n'th bit}
LeftMost :integer;
RightMost :integer;
ThisLine :scanline;
begin
chunk := CenterX div 8;
bit := CenterX mod 8;
GetLine(Y,ThisLine);
RightMost := RightSide(chunk,bit,ThisLine);
LeftMost := LeftSide(chunk,bit,Thisline);
if (Rightmost = CenterX) or (LeftMost = CenterX) then {...nothing to fill}
begin
Continue := false;
end
else
begin
Fillhorz(Y,LeftMost,RightMost);
CenterX := LeftMost + ( (RightMost-LeftMost) div 2);
end;
end; {................fillone }
{****************************************************************************
* fillArea will use fillone with LeftMost and RightMost in order to fill *
* an area. The area must be defined by either the edges of the screen *
* or by a solid line. If there are any holes in the line that defines the *
* shape, the filling will proceed beyond the indended area *
* The idea.... *
* is simple and will fail to fill certain types of areas. The line *
* that the crosshair is on is filled and the center of the line is *
* found from the left and right limits. Next we look up one line and *
* fill that line. The center of the line is again calculated from the *
* limits. This continues until we run off the screen or else find a *
* lit pixel on the line above the center point. The procedure then *
* starts working its way down with the same idea. *
****************************************************************************}
procedure fillArea;
var continue :boolean;
centerX,Y :integer;
tempMode :DefTypes;
begin
centerX := xPoz;
Y := yPoz;
continue := true;
offXhair(size,xPoz,yPoz); {....the crosshair should not be in the picture }
TempMode := vWriteMode; {...save the writemode }
vWriteMode := 'Fill'; {...fill is logical 'or' }
SetTypes; {...set the mode }
while continue do {....now fill from yPoz up }
begin
fillone(centerX,continue,Y);
if (continue) and (Y < 239) then
begin
Y := Y + 1;
end
else
continue := false
end;
centerX := xPoz;
Y := yPoz-1;
if Y <> -1 then {....if we're on the screen }
continue := true; {......then reset continue }
while continue do {.......and fill from yPoz down }
begin
fillone(centerX,continue,Y);
if (continue) and (Y > 0) then
begin
Y := Y - 1;
end
else
continue := false
end;
vWriteMode := TempMode; {.....putting this stuff back }
SetTypes;
initXhair(size,xPoz,yPoz);
end; {............................fillArea}
{*****************************************************************************
* BoxMove uses polyline to create a box with the given corners. It is call *
* by the Block procedure *
*****************************************************************************}
procedure BoxMove(x1,y1,x2,y2:integer);
var listarray :pointlist;
begin
listarray[1] := x1;
listarray[2] := y1;
listarray[3] := x1;
listarray[4] := y2;
listarray[5] := x2;
listarray[6] := y2;
listarray[7] := x2;
listarray[8] := y1;
listarray[9] := x1;
listarray[10] := y1;
polyline(5,listarray);
end; {.........BoxMove }
{*****************************************************************************
* Block will either create and fill a rectangle or else erase the area *
* defined by a rectangle, depending on the logic of the parameter. Since *
* most of the work is the defining of the rectangle, both these functions *
* have been combined. The actual erasing or filling is done by the graphic *
* primitive FillBar. *
*****************************************************************************}
procedure Block(erase:boolean);
var Xlowleft,Ylowleft :integer; {...these are for moving around /}
Xupright,Yupright :integer; { / }
Xtemp,Ytemp :integer; { / }
Xcorner,Ycorner :integer; {____________________________/ }
TempMode :defTypes;{...these save the originals /}
TempStyle :defTypes;{ / }
TempLine :defTypes;{ / }
TempColor :defTypes;{____________________________/ }
begin
TempColor := vLineColor;
TempLine := vLineStyle;
vLineStyle := 'Solid';
vLineColor := 'White';
TempMode := vWriteMode;
vWriteMode := 'OverWrite';
SetTypes;
Xcorner := xPoz;
Ycorner := yPoz;
BoxMove(Xcorner,Ycorner,xPoz,yPoz);
repeat
Xtemp := xPoz;
Ytemp := yPoz;
read(kbd,response);
response := UpCase(response);
case response of
'S':SetSpeed(speed);
'5':SetSpeed(speed);
'1'..'9':begin
reInitXhair(size,xpoz,ypoz);
MoveCross(size,speed,response,xPoz,yPoz);
end;
end; {.....case }
BoxMove(Xcorner,Ycorner,Xtemp,Ytemp);
BoxMove(Xcorner,Ycorner,xPoz,yPoz);
until (response = 'B') or (response = 'E'); {..until the area is defined }
BoxMove(Xcorner,Ycorner,xPoz,yPoz);
if Xcorner < xPoz then {......now let's get the corners straight }
begin
Xlowleft := Xcorner;
Xupright := xPoz;
end
else
begin
Xlowleft := xPoz;
Xupright := Xcorner;
end;
if Ycorner < yPoz then
begin
Ylowleft := Ycorner;
Yupright := yPoz;
end
else
begin
Ylowleft := yPoz;
Yupright := Ycorner;
end;
vLineColor := TempColor;
vLineStyle := TempLine;
vWriteMode := TempMode;
SetTypes;
if erase then {......the erase must form an open area }
begin
TempStyle := vFillStyle;
vFillStyle := 'Hollow';
end;
SetTypes;
offXhair(size,xPoz,yPoz); {....take this out of the picture }
fillbar(Xlowleft,Ylowleft,Xupright,Yupright);
if erase then {.......then we must get rid of the border left by FillBar }
begin
vWriteMode := 'Replace';
TempLine := vLineStyle;
vLineStyle := 'Solid';
TempColor := vLineColor;
vLineColor := 'Black';
SetTypes;
BoxMove(Xcorner,Ycorner,xPoz,yPoz);
vLineStyle := TempLine;
vLineColor := TempColor;
vFillStyle := TempStyle;
vWriteMode := TempMode;
SetTypes;
end;
initXhair(size,xPoz,yPoz); {....putting it back in place }
end;