home *** CD-ROM | disk | FTP | other *** search
- (****************************************************************************)
- (* *)
- (* SCREEN.PAS - Copyright 1985 Ridgely C. Evers - No Rights Reserved *)
- (* Attendant file: SCREEN.SCR *)
- (* *)
- (* This program is designed to produce and maintain screen image files *)
- (* for use with TURBO Pascal and other languages that can directly access *)
- (* the Video buffer for either the monochrome or color display cards. *)
- (* The program works directly with the video cards (Page 0 only on color *)
- (* systems, although it would be simple to adapt it to use the other *)
- (* pages as well). *)
- (* *)
- (* It works with two types of images, either "2K" or "4K" in size. *)
- (* Both are full screen images, but the 4K images consist of both the *)
- (* character and attribute values, while the 2K images are made up of *)
- (* character values only. *)
- (* Where possible, I recommend that you work with 4K images, since the *)
- (* programming requirements are so much simpler, and you have complete *)
- (* control over individual screen attributes such as color, intensity, *)
- (* underlining, reverse video, and blink. The only reason to use 2K *)
- (* images is if disk space is at a real premium. *)
- (* Programming techniques within TURBO for loading the screen images *)
- (* may be found within the program below. Generally, however, the *)
- (* recommended method is as follows: *)
- (* *)
- (* 1. You will need a TYPE statement to declare a screen array: *)
- (* => TYPE ScrnData = Array [0..4095] of Byte; *)
- (* *)
- (* 2. Set up a variable for each display your program will use: *)
- (* => VAR MonoBuf : ScrnData ABSOLUTE $B000:000 {monochrome} *)
- (* ColrBuf : ScrnData ABSOLUTE $B800:000 {color} *)
- (* *)
- (* 3. Set up a variable for the screen image file itself, and *)
- (* a variable to hold the screen images from the file: *)
- (* => VAR FileVar : File of ScrnData *)
- (* Screen : ScrnData *)
- (* *)
- (* 4. Determine which display you are using, if you will be using *)
- (* more than one, using the Intr procedure and an integer *)
- (* variable. This program uses the variable "Card" for this *)
- (* purpose, and uses the procedure "Get_Display" to set Card *)
- (* to the appropriate value ($B000 for the monochrome display, *)
- (* $B800 for color). If you will be using only one display, *)
- (* the process is simpler, since you can eliminate the need *)
- (* for this step, but doing so will mean that your program will *)
- (* not run on systems with the other type of display. Since *)
- (* very little overhead is involved in adding the flexibility *)
- (* to use both display types. *)
- (* *)
- (* 5. Records within the file are numbered starting with 0. To *)
- (* call up a specific screen, use the following procedure: *)
- (* => Seek (FileVar,{screen number you want}); *)
- (* Read (FileVar,Screen); *)
- (* If Card = $B000 *)
- (* Then MonoBuf := Screen *)
- (* Else ColrBuf := Screen; *)
- (* *)
- (* That's all there is to it! Once you have tried this, you will find *)
- (* that you won't ever be happy with any other kind of screen interface, *)
- (* and your users will not only be stunned, they'll be grateful. *)
- (* *)
- (* Use of the program is quite straightforward. When you call up the *)
- (* program, it will first display its help screen (which is in fact a *)
- (* screen image created with this program). Press F7 to begin. *)
- (* You will be presented with a blank screen. You may then "paint" *)
- (* your screen using the full IBM character set (use the Alt key with *)
- (* the number pad to enter characters 128..255). The Function keys, *)
- (* as well as several of the Alt+Alpha keys, control attributes, file *)
- (* saving and loading, and insert/delete functions. The cursor keys *)
- (* move you around on the screen. At any time, you can call up the *)
- (* Help screen by pressing F7. *)
- (* *)
- (* Note: when you call up Help, the bottom of the screen will show *)
- (* you several things. On the left side, it will show you *)
- (* where you are (Col/Row), and what character/attribute *)
- (* is at the cursor position. On the right side, it will *)
- (* show you the "F1" value. This is the character/attribute *)
- (* that you will get when you press the F1 key, which is the *)
- (* repeat function. You can repeat in any direction (up/down/ *)
- (* left/right) by using F1 in conjunction with the Ctrl, Shift, *)
- (* and Alt keys. This is particularly valuable for drawing *)
- (* boxes and borders using the Extended Character set (128..255). *)
- (* *)
- (* Note for super-zoombo use: you can speed things up even more, at *)
- (* the expense of memory, by loading all of your screen images into *)
- (* an array of ScrnData. For example, if your program has 7 screens, *)
- (* create a variable array as follows: *)
- (* => VAR ScreenArray : Array [0..6] of ScrnData; *)
- (* *)
- (* At the beginning of your program, read the entire screen image *)
- (* file into this array. Then, when you want to fire an image to the *)
- (* screen, use the following code: *)
- (* => If Card = $B000 *)
- (* Then MonoBuf := ScreenArray[{# of screen image}] *)
- (* Else ColrBuf := ScreenArray[{# of screen image}]; *)
- (* *)
- (* For those of you who want to use 2K images, see the code below for *)
- (* saving and loading 2K images. *)
- (* *)
- (* Play with the program. The best way to learn it is to use it. I *)
- (* welcome your comments and suggestions as to how to improve this *)
- (* program in any way. Please leave them on the TechMail BBS, to my *)
- (* attention. *)
- (* *)
- (****************************************************************************)
-
- TYPE
- ScrnData = Array [0..4095] of Byte;
- SmallScrnData = Array [0..2047] of Byte;
- RegPack = Record
- AX,BX,CX,DX,BP,SI,DI,Flags : Integer;
- End;
-
- VAR
- MonoBuf : ScrnData Absolute $B000:0000;
- ColrBuf : ScrnData Absolute $B800:0000;
- SmallScreen : SmallScrnData;
- SmallFileVar : File of SmallScrnData;
- Screen, HelpScrn : ScrnData;
- FileVar, HelpFile: File of ScrnData;
- FileName : String[30];
- RecPack : RegPack;
- Card,
- i, RecNum,
- CharCode,
- ScanCode,
- CharValue,
- Attribute : Integer;
- Ch : Char;
- Row, Col,
- ScrnSub : Integer;
- Altered, OK,
- LastCol,
- Finished, First : Boolean;
-
-
-
- Procedure Get_Character;
- Begin
- RecPack.AX := 0;
- Intr ($16,RecPack);
- With RecPack do begin
- CharCode := AX mod 256;
- ScanCode := AX shr 8;
- End {of With};
- End {of Procedure Get_Character};
-
- Procedure Check (VAR OK_To_Quit : Boolean);
- Begin
- OK_To_Quit := True;
- If Altered Then Begin
- GoToXY (1,25); ClrEol; Write ('Screen NOT Saved! Proceed? (Y/N) ');
- Repeat
- Get_Character; If CharCode > 90 Then CharCode := CharCode - 32;
- Until Chr(CharCode) in ['N','Y'];
- If Chr(CharCode) = 'N' Then OK_To_Quit := False;
- End;
- End;
-
- Procedure Give_Help;
- Begin
- If Card = $B000
- Then MonoBuf := HelpScrn
- Else ColrBuf := HelpScrn;
- LowVideo;
- If First Then Begin
- TextColor (9); GoToXY (1,24); ClrEol; GoToXY (1,25); ClrEol;
- GoToXY (32,25);
- Write ('Press F7 to Start'); TextColor (7);
- For i := 0 to 3999 do Screen[i] := 0;
- End
- Else Begin
- GoToXY (14,25); Write (Col:2);
- GoToXY (22,25); Write (Row:2);
- GoToXY (31,25); Write (Screen[ScrnSub]:3);
- GoToXY (35,25); Write (Chr(Screen[ScrnSub]));
- GoToXY (43,25); Write (Screen[ScrnSub+1]:3);
- GoToXY (65,25); Write (CharValue:3);
- GoToXY (69,25); Write (Chr(CharValue));
- GoToXY (77,25); Write (Attribute:3);
- GoToXY (1,24);
- If Card = $B000
- Then Begin
- MonoBuf[3931] := Screen[ScrnSub+1];
- MonoBuf[3999] := Attribute;
- End
- Else Begin
- ColrBuf[3931] := Screen[ScrnSub+1];
- ColrBuf[3999] := Attribute;
- End;
- End;
- Repeat Get_Character Until ScanCode = 65;
- If Card = $B000
- Then MonoBuf := Screen
- Else ColrBuf := Screen;
- End {of Give_Help};
-
- Procedure Get_Display;
- Begin
- Intr ($11,RecPack);
- If RecPack.AX AND 48 = 48
- Then Card := $B000
- Else Card := $B800;
- End {of Procedure Get_Display};
-
-
- Begin
- LowVideo; ClrScr; Finished := False; Row := 1; Col := 1;
- Attribute := 7; CharValue := 32;
- Assign (HelpFile,'SCREEN.SCR'); ReSet (HelpFile);
- Seek (HelpFile,0); Read (HelpFile,HelpScrn);
- Close (HelpFile);
-
- Get_Display;
- First := True; Give_Help; First := False; Altered := False;
-
- While NOT Finished do Begin
- If Col = 81 Then Begin
- LastCol := True; Col := 80;
- End
- Else LastCol := False;
- GoToXY (Col,Row); Get_Character;
- If Card = $B000
- Then Screen := MonoBuf
- Else Screen := ColrBuf;
- ScrnSub := ((Row-1)*160) + ((Col-1)*2);
-
- If CharCode = 0 Then Begin {to process Extended Code};
-
- Case ScanCode of
- 15: Begin {to Tab back}
- Col := ((Col-8) div 8) * 8;
- If Col < 1 Then Col := 1;
- End {of Shift Tab};
- 18: Begin {Attribute to EOL}
- i := ScrnSub;
- While i < Row*160 do begin
- If Card = $B000
- Then MonoBuf[i+1] := Attribute
- Else ColrBuf[i+1] := Attribute;
- i := i + 2;
- End;
- End;
- 23: InsLine; {Insert}
- 32: DelLine; {Delete}
- 38: Begin {Attribute Whole Line}
- i := (Row-1)*160;
- While i < Row*160 do begin
- If Card = $B000
- Then MonoBuf[i+1] := Attribute
- Else ColrBuf[i+1] := Attribute;
- i := i + 2;
- End;
- End;
- 46: ClrScr; {Clear Screen}
-
- 59,84,94,104: Begin {to repeat last character}
- If ScanCode = 84 Then Col := Col - 2
- Else If ScanCode = 94 Then Begin
- Row := Row - 1; If NOT LastCol Then Col := Col - 1;
- End
- Else If ScanCode = 104 Then Begin
- Row := Row + 1; If NOT LastCol Then Col := Col - 1;
- End;
- If Col < 1 Then Col := 1 Else
- If Col > 80 Then Col := 80 Else
- If Row < 1 Then Row := 1 Else
- If Row > 25 Then Row := 25;
- ScrnSub := ((Row-1)*160) + ((Col-1)*2);
- If Card = $B000 Then Begin
- MonoBuf[ScrnSub] := CharValue;
- MonoBuf[ScrnSub+1] := Attribute;
- End
- Else Begin
- ColrBuf[ScrnSub] := CharValue;
- ColrBuf[ScrnSub+1] := Attribute;
- End;
- Col := Col + 1; If Col > 81 Then Col := 81;
- End {of Repeat last character};
-
- 60: Attribute := Attribute xor 8; {toggle intensity}
- 61: Attribute := Attribute xor 119; {toggle reverse}
- 62: Attribute := Attribute xor 128; {toggle blink}
- 63: Attribute := Attribute xor 6; {toggle underline}
- 65: Give_Help;
-
- 66: Begin {to load a 4K file}
- Check (OK);
- If OK Then Begin
- GoToXY (1,25); ClrEol; Write ('4K FileName to Load from: ');
- Read (FileName); Assign (FileVar,FileName);
- {$I-}
- ReSet (FileVar);
- If IOResult <> 0
- Then Begin
- Write (^G,' Can''t find file!');
- Read (Kbd,Ch);
- End {of Then}
- Else Begin
- Write (' Record Number [0..',
- FileSize(FileVar)-1,']: ');
- Read (RecNum);
- Seek (FileVar,RecNum); Read (FileVar,Screen);
- If IOResult <> 0
- Then Write (^G,' Read Error!')
- Else Altered := False;
- Close (FileVar);
- End {of Else};
- {$I+}
- End {of If OK};
- If Card = $B000
- Then MonoBuf := Screen
- Else ColrBuf := Screen;
- End {of Load};
-
- 67: Begin {to save to a 4K file}
- GoToXY (1,25); ClrEol; Write ('4K FileName for Saving: ');
- Read (FileName); Assign (FileVar,FileName);
- {$I-}
- ReSet (FileVar);
- If IOResult <> 0
- Then Begin
- Write (^G,' Can''t Find File! Create? [Y/N] ');
- Repeat Read (KBD,Ch) Until UpCase (Ch) in ['Y','N'];
- If UpCase (Ch) = 'Y'
- Then ReWrite (FileVar)
- Else FileName := '';
- End {of If IOResult is a bust};
- {$I+}
- If FileName <> '' Then Begin
- GoToXY (1,25); ClrEol;
- Write (' Record Number [0..',
- FileSize(FileVar),']: ');
- Repeat
- Read (RecNum)
- Until RecNum <= FileSize(FileVar);
- Seek (FileVar,RecNum);
- Write (FileVar,Screen);
- Close (FileVar);
- Altered := False;
- End {of ok to Save};
- If Card = $B000
- Then MonoBuf := Screen
- Else ColrBuf := Screen;
- End {of Save};
-
- 68: Begin
- Check (OK);
- If OK Then Finished := True;
- If Card = $B000
- Then MonoBuf := Screen
- Else ColrBuf := Screen;
- End;
-
- 71: Col := 1; {Home}
- 72: If Row > 1 Then Row := Row - 1; {Up Arrow}
- 73: Row := 1; {PgUp}
- 75: If Col > 1 Then Col := Col - 1; {Left Arrow}
- 77: If Col < 80 Then Col := Col + 1; {Right Arrow}
- 79: Col := 80; {End}
- 80: If Row < 25 Then Row := Row + 1; {Down Arrow}
- 81: Row := 25; {PgDn}
-
- 82: Begin {Ins char}
- For i := (Row*160)-2 downto (ScrnSub+2) do If Card = $B000
- Then MonoBuf[i] := MonoBuf[i-2]
- Else ColrBuf[i] := ColrBuf[i-2];
- If Card = $B000
- Then MonoBuf[ScrnSub] := 32
- Else ColrBuf[ScrnSub] := 32;
- End {of Ins Character};
-
- 83: Begin {Del char}
- For i := ScrnSub to (Row*160)-2 do If Card = $B000
- Then MonoBuf[i] := MonoBuf[i+2]
- Else ColrBuf[i] := ColrBuf[i+2];
- If Card = $B000
- Then MonoBuf[(Row*160)-2] := 32
- Else ColrBuf[(Row*160)-2] := 32;
- End {of Del Character};
-
- 111: Begin {to load a 2K file}
- Check (OK);
- If OK Then Begin
- GoToXY (1,25); ClrEol; Write ('2K FileName to Load from: ');
- Read (FileName); Assign (SmallFileVar,FileName);
- {$I-}
- ReSet (SmallFileVar);
- If IOResult <> 0
- Then Begin
- Write (^G,' Can''t find file!');
- Read (Kbd,Ch);
- End {of Then}
- Else Begin
- Write (' Record Number [0..',
- FileSize(SmallFileVar)-1,']: ');
- Read (RecNum);
- Seek (SmallFileVar,RecNum);
- Read (SmallFileVar,SmallScreen);
- If IOResult <> 0
- Then Write (^G,' Read Error!')
- Else Altered := False;
- Close (SmallFileVar);
- End {of Else};
- {$I+}
- End {of If OK};
- LowVideo; ClrScr; Altered := False;
- For i := 0 to 2047 do If Card = $B000
- Then MonoBuf[i*2] := SmallScreen[i]
- Else ColrBuf[i*2] := SmallScreen[i];
- End {of Load};
-
- 112: Begin {to save to a 2K file}
- GoToXY (1,25); ClrEol; Write ('2K FileName for Saving: ');
- Read (FileName); Assign (SmallFileVar,FileName);
- {$I-}
- ReSet (SmallFileVar);
- If IOResult <> 0
- Then Begin
- Write (^G,' Can''t Find File! Create? [Y/N] ');
- Repeat Read (KBD,Ch) Until UpCase (Ch) in ['Y','N'];
- If UpCase (Ch) = 'Y'
- Then ReWrite (SmallFileVar)
- Else FileName := '';
- End {of If IOResult is a bust};
- {$I+}
- If FileName <> '' Then Begin
- GoToXY (1,25); ClrEol;
- Write (' Record Number [0..',
- FileSize(SmallFileVar),']: ');
- Repeat
- Read (RecNum)
- Until RecNum <= FileSize(SmallFileVar);
- Seek (SmallFileVar,RecNum);
- i := 0;
- For i := 0 to 2047 do
- SmallScreen[i] := Screen[i*2];
- Write (SmallFileVar,SmallScreen);
- Close (SmallFileVar);
- Altered := False;
- End {of ok to Save};
- If Card = $B000
- Then MonoBuf := Screen
- Else ColrBuf := Screen;
- End {of Save};
- End {of Case ScanCode};
-
- End {of If CharCode = 0}
-
- Else {if CharCode <> 0 Then} Begin
- If (CharCode=9) And (ScanCode=15) Then {Real Tab}
- Begin {to Tab over}
- Col := ((Col+8) div 8) * 8;
- If Col > 80 Then Col := 80;
- End {of Real Tab}
- Else Begin
- If Card = $B000 Then Begin
- MonoBuf[ScrnSub] := CharCode;
- MonoBuf[ScrnSub+1] := Attribute;
- End
- Else Begin
- ColrBuf[ScrnSub] := CharCode;
- ColrBuf[ScrnSub+1] := Attribute;
- End;
- CharValue := CharCode; Altered := True;
- End;
- If Col < 81 Then Col := Col + 1;
- End {of Else};
- End {of While Not Finished};
- ClrScr;
-
- End.