home *** CD-ROM | disk | FTP | other *** search
-
- {These constants for the portion of memory where picture bits are
- stored. Bits for odd lines on the screen are stored at a different
- location than even lines. See the IBM technical manual for an
- explanation.}
-
- Const
- SegEven = $b800; {Starting segment for even lines on screen }
- SegOdd = $ba00; {Starting segment for odd lines on screen }
- LineBytes = $50; {Bytes per line }
- MaxArray = 3000; {Maximum array -- increase for larger figures}
-
- {The array Storage is a memory area used by both GET and PUT. GET
- stores the old bits in the array. PUT removes them and places them
- at the new memory location. The 3000 byte array used here may be
- more or less than you need for a particular figure. If memory is
- tight and you must conserve it, you can multiply the length of the
- moved block by its width, then divide by four for medium resolution
- or eight for high resolution. Change MaxArray to this number.
- However, if you are using several figures, the array will be the
- same for all. This might be wasteful of memory, but...you can wait
- for the next release. }
-
- Type
- Strng = String[14]; {Allows you to use type String in a parameter.}
- Storage = Record
- Pixels : Array[1..MaxArray] of Byte;
- StoreHeight : Integer;
- StoreWidth : Integer;
- end;
-
- {This procedure Gets the bytes that define a figure and places them
- either in memory and, optionally, in a file. One limitation is
- that the procedure gets whole bytes. If your figure starts or ends
- midway through the byte, then the additional bits before or after
- will also be captured. You can see this when you move something
- with the NOT parameter. The next version may solve this problem.}
-
- Procedure Get(StartWidth, StartHeight, Width, Height : Integer;
- var AName : Storage;
- FName : Strng);
- Label Exit;
-
- Var
- HeightLoop, WidthLoop,
- StartWidthByte, EndWidthByte,
- EndHeight, WidthBytes,
- Segment, OffSet,
- Divisor, Counter, Size : Integer;
- FileName : String[14];
- Destination : File;
-
- {Adjusts for two bits per pixel in medium resolution or one bit per
- pixel in high resolution. Also adjusts Y coordinates for aspect.
- This procedure is used by both Get and Put. }
-
- Procedure Adjust;
- begin
- If ResolutionHigh then Divisor := 8 else Divisor := 4;
- StartHeight := Round(StartHeight * Scrunch);
- Height := Round(Height * Scrunch);
- end;
-
- {Move the bytes of the figure to a file. }
-
- Procedure FileWrite;
- begin
- FileName := FName;
- Assign(Destination,FileName);
- Rewrite(Destination);
- Size := (Counter * 8) div 128; {Find the number of blocks. }
- BlockWrite(Destination, AName, Size);
- Close(Destination);
- end;
-
- begin
- Adjust;
- If Width * Height div Divisor > MaxArray then
- begin
- Write(#7); {Error and quit if array too small. }
- Goto Exit;
- end;
- AName.StoreHeight := Height; {Store the width and height. }
- AName.StoreWidth := Width;
- HeightLoop := StartHeight; {Set the loops and the starting... }
- EndHeight := StartHeight + Height; {...and ending points for the loops.}
- StartWidthByte := StartWidth div Divisor;
- WidthBytes := (Width div divisor) + 1;
- Counter := 1;
- While HeightLoop <= EndHeight do {Store each line, alternating... }
- begin {...segments for even and odd. }
- If Odd(HeightLoop) then Segment := SegOdd else Segment := SegEven;
- Offset := ((HeightLoop div 2) * LineBytes) + StartWidthByte;
- Move(mem[Segment:Offset], AName.Pixels[Counter], WidthBytes);
- Counter := Counter + WidthBytes;
- HeightLoop := HeightLoop + 1; {Increment counter and loop. }
- end;
- If FName <> '' then FileWrite; {If file exists, write bits to it. }
- Exit : end;
-
- {Constants to indicate how intersecting figures will be treated
- when new bits are put on old bits. }
-
- Const
- A = 1; {New picture bits AND old picture bits}
- O = 2; {New picture bits OR old picture bits}
- X = 3; {New picture bits XOR old picture bits}
- N = 4; { NOT new picture bits}
- E = 5; { EQUAL new picture bits}
- B = 6; { New bits BLANK old picture bits}
-
- {This procedure Puts the bytes stored with Get onto the screen.
- Notice that the procedure for the EQU and BLANK operators is
- completely different than the one for the other operators. Because
- whole bytes are being moved unchanged with EQUAL and BLANK, the
- Turbo MOVE procedure is used to move a whole line at a time. It
- works considerable faster than combining the old and new bytes one
- at time as with the other operators.
-
- This gives you two choices for animation. If you want to move a
- ball accross the screen, you can BLANK the old figure and EQU the
- new figure at the new location. Or you can XOR the old figure to
- erase it and XOR the new figure to draw it. Try it and see which
- is faster.}
-
- Procedure Put(var AName : Storage; Startwidth, StartHeight : Integer;
- Operator : Byte;
- FName : Strng);
- var
- HeightLoop, WidthLoop,
- StartWidthByte, EndWidthByte, WidthBytes,
- Height, Width, EndHeight,
- Segment, OffSet,
- Divisor, Counter, Size : Integer;
- OldValue, NewValue : Byte;
- FileName : String[14];
- Source : File;
- Blank : Array[0..LineBytes] of Byte;
-
- {Adjusts for two bits per pixel in medium resolution or one bit
- per pixel in medium resolution. Also adjusts Y coordinates for
- aspect. This procedure is used by both Get and Put. }
-
- Procedure Adjust;
- begin
- If ResolutionHigh then Divisor := 8 else Divisor := 4;
- StartHeight := Round(StartHeight * Scrunch);
- Height := Round(Height * Scrunch);
- end;
-
- Procedure DrawThing; {Mixes old and new bytes one at a time. }
- begin
- OldValue := AName.Pixels[Counter];
- NewValue := mem[Segment:Offset];
- Case Operator of
- 1 : Mem[Segment:Offset] := NewValue AND OldValue;
- 2 : Mem[Segment:Offset] := NewValue OR OldValue;
- 3 : Mem[Segment:Offset] := NewValue XOR OldValue;
- 4 : Mem[Segment:Offset] := NOT OldValue;
- end;
- Offset := Offset + 1; {Increment the loops. }
- Counter := Counter + 1;
- WidthLoop := WidthLoop + 1;
- end;
-
- Procedure Movething; {Moves a whole line of bytes at a time. }
- begin
- If Operator = 5 then {Move in new values for EQU. }
- Move(AName.Pixels[Counter], mem[Segment:Offset], WidthBytes)
- else {Move in blanks (zeros) for BLANK. }
- Move(Blank[0], mem[Segment:Offset], WidthBytes);
- Counter := Counter + Widthbytes;
- end;
-
- Procedure FileRead; {Reads bytes from a file. }
- begin
- FileName := FName;
- Assign(Source, FileName);
- Reset(Source);
- Size := FileSize(Source);
- BlockRead(Source, AName, Size);
- Close(Source);
- end;
-
- begin
- If FName <> '' then FileRead; {If file exists, then read bits. }
- Adjust;
- Width := AName.StoreWidth; {Get height and width from record. }
- Height := AName.StoreHeight;
- HeightLoop := StartHeight; {Set the loops and the starting... }
- EndHeight := StartHeight + Height; {...and ending points for loops. }
- StartWidthByte := StartWidth div Divisor;
- WidthBytes := (Width div Divisor) + 1;
- EndWidthByte := StartWidthByte + (Width div Divisor);
- If Operator = 6 then {If BLANK then fill array with 0. }
- For Counter := 0 to WidthBytes do Blank[Counter] := 0;
- Counter := 1;
- While HeightLoop <= EndHeight do
- begin {Set loops and segments. }
- if Odd(HeightLoop) then Segment := SegOdd else Segment := SegEven;
- Offset := ((HeightLoop div 2) * LineBytes) + StartWidthByte;
- WidthLoop := StartWidthByte;
- If operator > 4 then Movething {Move or draw depending on operator.}
- else While WidthLoop <= EndWidthByte do Drawthing;
- HeightLoop := HeightLoop + 1;
- end;
- end;
-
- {Before using GET, you must declare a variable of type Storage that
- you will use to name the figure you want to move. Later you will
- use the same name to get the figure. For example:
-
- Var
- Box : Storage;
-
- Get(1,1,50,50,Box,'');
- Put(Box,150,150,e,'');
-
- This gets a square 50 by 50 starting at 1,1. It stores the figure
- in Box. Then Put takes the figure out of Box and puts it onto the
- screen at 150,150. The operator "e" indicates that the new figure
- overwrites anything that was there before. The empty set indicates
- that the whole process takes place in memory.
-
- If you wanted Box to be saved in a file, you could do it like this:
-
- Var
- Box : Storage;
-
- Get(1,1,50,50,Box,'BOX.FIG');
-
- Then you could get the figure from the file even after booting (or
- from another program) with this command:
-
- Var
- Box : Storage;
-
- Put(Box,150,150,e,'BOX.FIG');
-
- You can declare several different figures and move them all in different
- combinations.
-
- Var
- Box : Storage;
- Circle : Storage;
-
- Get(1,1,50,50,Box,'');
- Get(1,1,50,150,Circle,'');
- Put(Circle,150,150,x,'');
- Put(Box,150,150,x,'');
-
- }
-
-