[Back to SAVESCRN SWAG index] [Back to Main SWAG index] [Original]
{
: Is there a way to save the current text screen so you can call it
: up later? (ie: Either save the screen so you can display something else
: in text, then bring back the first page, or to display graphics, then
: bring back the old text screen.) Also, is there a way to dumb the screen
: to disk?
Here's the stuff i use... (It works from TP 4.0 and up)
}
Type
ScreenRecord =
Record
X, Y: Byte; {x,y coord. of cursor}
Screen: Pointer
End;
Var
OriginalScreen: ScreenRecord;
Function QueryAdapterType: AdapterType;
Var
Code: Byte;
Regs: Registers;
Begin
Regs.AH := $1A; { Attempt to call VGA Identify Adapter Function }
Regs.AL := $00; { Must clear AL to 0 ... }
Intr($10, Regs);
If Regs.AL = $1A then { ...so that If $1A comes back in AL... }
Begin { ...we know a PS/2 video BIOS is out there. }
Case Regs.BL of { Code comes back in BL }
$00:
QueryAdapterType := None;
$01:
QueryAdapterType := MDA;
$02:
QueryAdapterType := CGA;
$04:
QueryAdapterType := EGAColor;
$05:
QueryAdapterType := EGAMono;
$07:
QueryAdapterType := VGAMono;
$08:
QueryAdapterType := VGAColor;
$0A, $0C:
QueryAdapterType := MCGAColor;
$0B:
QueryAdapterType := MCGAMono
else
QueryAdapterType := CGA
End { Case }
End
else
{ Next we have to check for the presence of an EGA BIOS: }
Begin
Regs.AH := $12; { Select Alternate Function service }
Regs.BX := $10; { BL=$10 means return EGA information }
Intr($10, Regs); { Call BIOS VIDEO }
If Regs.BX <> $10 then { BX unchanged means EGA is NOT there...}
Begin
Regs.AH := $12; { Once we know Alt Function exists... }
Regs.BL := $10; { ...we call it again to see If it's... }
Intr($10, Regs); { ...EGA color or EGA monochrome. }
If Regs.BH = 0 then
QueryAdapterType := EGAColor
else
QueryAdapterType := EGAMono
End
else { Now we know we have an EGA or MDA: }
Begin
Intr($11, Regs); { Equipment determination service }
Code := (Regs.AL and $30) Shr 4;
Case Code of
1:
QueryAdapterType := CGA;
2:
QueryAdapterType := CGA;
3:
QueryAdapterType := MDA
else
QueryAdapterType := CGA
End { Case }
End
End
End;
Function DeterminePoints: Integer;
Var
Regs: Registers;
Begin
Case QueryAdapterType of
CGA:
DeterminePoints := 8;
MDA:
DeterminePoints := 14;
EGAMono, { These adapters may be using any of }
EGAColor, { several different font cell heights, }
VGAMono, { so we need to query the BIOS to find }
VGAColor, { out which is currently in use. }
MCGAMono, MCGAColor:
Begin
With Regs do
Begin
AH := $11; { EGA/VGA Information Call }
AL := $30;
BL := 0
End;
Intr($10, Regs);
DeterminePoints := Regs.CX
End
End { Case }
End;
Procedure SaveScreen(Var StashPtr: Pointer);
Type
VidPtr = ^VidSaver;
VidSaver =
Record
Base, Size: Word;
BufStart: Byte
End;
Var
VidVector: VidPtr;
StashBuf: VidSaver;
VidBuffer: Pointer;
Adapter: AdapterType;
Begin
Adapter := QueryAdapterType;
With StashBuf do
Begin
Case Adapter of
MDA, EGAMono, VGAMono, MCGAMono:
Base := $B000
else
Base := $B800
End; { Case }
Case DeterminePoints of
8:
Case Adapter of
CGA:
Size := 4000; { 25-line screen }
EGAMono, EGAColor:
Size := 6880 { 43-line screen }
else
Size := 8000 { 50-line screen }
End; { Case }
14:
Case Adapter of
EGAMono, EGAColor:
Size := 4000; { 25-line screen }
else
Size := 4320 { 27-line screen }
End; { Case }
16:
Size := 4000
End; { Case }
VidBuffer := Ptr(Base, 0)
End;
{ Allocate heap for whole shebang }
GetMem(StashPtr, StashBuf.Size + 16);
{ Here we move *ONLY* the VidSaver Record (5 bytes) to the heap: }
Move(StashBuf, StashPtr^, Sizeof(StashBuf));
{ This casts StashPtr, a generic pointer, to a pointer to a VidSaver: }
VidVector := StashPtr;
{ Now we move the video buffer itself to the heap. The vide data is
written starting at the BufStart byte in the VidSaver Record, and
goes on for Size bytes to fit the whole buffer. Messy but hey,
this is PC land! }
Move(VidBuffer^, VidVector^.BufStart, StashBuf.Size);
End;
Procedure RestoreScreen(StashPtr: Pointer);
Type
VidPtr = ^VidSaver;
VidSaver =
Record
Base, Size: Word;
BufStart: Byte
End;
Var
DataSize: Word;
VidVector: VidPtr;
VidBuffer: Pointer;
Begin
VidVector := StashPtr; { Cast generic pointer onto VidSaver pointer }
DataSize := VidVector^.Size;
{ Create a pointer to the base of the video buffer: }
VidBuffer := Ptr(VidVector^.Base, 0);
{ Move the buffer portion of the data on the heap to the video buffer: }
Move(VidVector^.BufStart, VidBuffer^, VidVector^.Size);
FreeMem(StashPtr, DataSize + 16)
End;
(*
Here's how you save a screen...
With OriginalScreen do
Begin
X := WhereX; {save the x,y cursor positions...}
Y := WhereY - 1;
SaveScreen(Screen) {then the screen}
End;
Here's how you restore a screen...
With OriginalScreen do
Begin
RestoreScreen(Screen); {restore the screen}
GotoXY(X, Y) {go back to the orig. cursor position}
End;
: While we're at it, I might as well get all my questions out of my
: system :) First, is there a way to stop the program from crashing if
: someone enters a character instead of an integer (or any incompatible
: data types?) I've been looking around but havn't found anything...
The best way is to read the number in as a string (characters), then use
the procedure Val(), to convert it from a character string to numeric.
: And lastly, how do you stop the program from crashing if a user enters
: a filename to load, and it doesn't exist? I think this has something
: to do with the doserror (is that the function name? Don't recall offhand)
: but I couldn't get it to work.
Check to see if the file exists, before you open it (Reset)... Here's a
quick function..
Function Exists(FileName: String): Boolean;
Begin
Exists := FSearch(FileName, '') <> ''
End;
*)
[Back to SAVESCRN SWAG index] [Back to Main SWAG index] [Original]