123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372 |
- {****************************************************************************
- Standard CRT unit.
- Free Pascal runtime library for OS/2.
- Copyright (c) 1997 Daniel Mantione.
- This file may be reproduced and modified under the same conditions
- as all other Free Pascal source code.
- ****************************************************************************}
- unit crt;
- interface
- {$INLINE ON}
- {$i crth.inc}
- procedure Window32 (X1, Y1, X2, Y2: dword);
- procedure GotoXY32 (X, Y: dword);
- function WhereX32: dword;
- function WhereY32: dword;
- var
- ScreenHeight, ScreenWidth: dword;
- (* API *)
- implementation
- {uses keyboard, video;}
- {$i textrec.inc}
- const
- VioHandle: word = 0;
- type
- TKbdKeyInfo = record
- CharCode, ScanCode: char;
- fbStatus, bNlsShift: byte;
- fsState: word;
- Time: longint;
- end;
- VioModeInfo = record
- cb: word; { length of the entire data
- structure }
- fbType, { bit mask of mode being set}
- Color: byte; { number of colors (power of 2) }
- Col, { number of text columns }
- Row, { number of text rows }
- HRes, { horizontal resolution }
- VRes: word; { vertical resolution }
- fmt_ID, { attribute format }
- Attrib: byte; { number of attributes }
- Buf_Addr, { physical address of
- videobuffer, e.g. $0b800}
- Buf_Length, { length of a videopage (bytes)}
- Full_Length, { total video-memory on video-
- card (bytes)}
- Partial_Length: longint; { ????? info wanted !}
- Ext_Data_Addr: pointer; { ????? info wanted !}
- end;
- TVioCursorInfo=record
- case boolean of
- false: (
- yStart: word; {Cursor start (top) scan line (0-based)}
- cEnd: word; {Cursor end (bottom) scan line}
- cx: word; {Cursor width (0=default width)}
- Attr: word); {Cursor colour attribute (-1=hidden)}
- true:(
- yStartInt: integer; {integer variants can be used to specify negative}
- cEndInt: integer; {negative values (interpreted as percentage by OS/2)}
- cxInt: integer;
- AttrInt: integer);
- end;
- PVioCursorInfo = ^TVioCursorInfo;
- function KbdCharIn (var AKeyRec: TKbdKeyInfo; Wait, KbdHandle: longint):
- word; cdecl;
- external 'EMXWRAP' index 204;
- function KbdPeek (var AKeyRec: TKbdKeyInfo; KbdHandle: longint): word; cdecl;
- external 'EMXWRAP' index 222;
- function DosSleep (Time: cardinal): word; cdecl;
- external 'DOSCALLS' index 229;
- function VioScrollUp (Top, Left, Bottom, Right, Lines: longint;
- var ScrEl: word; VioHandle: word): word; cdecl;
- external 'EMXWRAP' index 107;
- {$WARNING ScrEl as word not DBCS safe!}
- function VioScrollDn (Top, Left, Bottom, Right, Lines: longint;
- var ScrEl: word; VioHandle: word): word; cdecl;
- external 'EMXWRAP' index 147;
- function VioScrollRight (Top, Left, Bottom, Right, Columns: word;
- var ScrEl: word; VioHandle: word): word; cdecl;
- external 'EMXWRAP' index 112;
- {external 'VIOCALLS' index 12;}
- function VioGetCurPos (var Row, Column: word; VioHandle: word): word; cdecl;
- external 'EMXWRAP' index 109;
- function VioSetCurPos (Row, Column, VioHandle: word): word; cdecl;
- external 'EMXWRAP' index 115;
- function VioWrtCharStrAtt (S: PChar; Len, Row, Col: longint; var Attr: byte;
- VioHandle: word): word; cdecl;
- external 'EMXWRAP' index 148;
- function VioGetMode (var AModeInfo: VioModeInfo; VioHandle: word): word; cdecl;
- external 'EMXWRAP' index 121;
- function VioSetMode (var AModeInfo: VioModeInfo; VioHandle: word): word; cdecl;
- external 'EMXWRAP' index 122;
- function VioSetCurType (var CurData: TVioCursorInfo; VioHandle: word): word;
- cdecl;
- external 'EMXWRAP' index 132;
- {external 'VIOCALLS' index 32;}
- function VioGetCurType (var CurData: TVioCursorInfo; VioHandle: word): word;
- cdecl;
- external 'EMXWRAP' index 127;
- {external 'VIOCALLS' index 27;}
- function VioCreatePS (var VPS: word; Depth, Width, Format, Attrs: integer;
- Reserved: word): word; cdecl;
- external 'EMXWRAP' index 156;
- {external 'VIOCALLS' index 56;}
- function DosBeep (Freq, MS: cardinal): cardinal; cdecl;
- external 'DOSCALLS' index 286;
- procedure GetScreenCursor (var X, Y: dword);inline;
- (* Return current cursor postion - 0-based. *)
- var
- X0, Y0: word;
- begin
- X := 0;
- Y := 0;
- if VioGetCurPos (Y0, X0, VioHandle) = 0 then
- begin
- X := X0;
- Y := Y0;
- end;
- end;
- procedure SetScreenCursor (X, Y: dword); inline;
- (* Set current cursor postion - 0-based. *)
- begin
- VioSetCurPos (Y, X, VioHandle);
- end;
- procedure RemoveLines (Row: dword; Cnt: dword); inline;
- (* Remove Cnt lines from screen starting with (0-based) Row. *)
- var
- ScrEl: word;
- begin
- ScrEl := $20 or (TextAttr shl 8);
- VioScrollUp (Row + WindMinY, WindMinX, WindMaxY, WindMaxX, Cnt, ScrEl,
- VioHandle);
- end;
- procedure ClearCells (X, Y, Cnt: dword); inline;
- (* Clear Cnt cells in line Y (0-based) starting with position X (0-based). *)
- var
- ScrEl: word;
- begin
- ScrEl := $20 or (TextAttr shl 8);
- VioScrollRight (Y, X, Y, X + Pred (Cnt), Cnt, ScrEl, VioHandle);
- end;
- procedure InsLine;
- (* Inserts a line at cursor position. *)
- var
- ScrEl: word;
- begin
- ScrEl := $20 or (TextAttr shl 8);
- VioScrollDn (Pred (WhereY32) + WindMinY, WindMinX, WindMaxY, WindMaxX, 1,
- ScrEl, VioHandle);
- end;
- procedure SetScreenMode (Mode: word);
- var
- NewMode: VioModeInfo;
- begin
- NewMode.cb := 8;
- VioGetMode (NewMode, VioHandle);
- NewMode.fbType := 1; {Non graphics colour mode.}
- NewMode.Color := 4; {We want 16 colours, 2^4=16 - requests for BW ignored.}
- case Mode and $FF of
- BW40, CO40: NewMode.Col := 40;
- BW80, CO80: NewMode.Col := 80;
- else
- begin
- (* Keep current amount of columns! *)
- end;
- end;
- case Mode and $100 of
- 0: NewMode.Row := 25;
- $100: NewMode.Row := 50
- else
- begin
- (* Keep current amount of rows! *)
- end;
- end;
- VioSetMode (NewMode, VioHandle);
- ScreenWidth := NewMode.Col;
- ScreenHeight := NewMode.Row;
- end;
- procedure Delay (Ms: word);
- {Waits ms milliseconds.}
- begin
- DosSleep (Ms)
- end;
- procedure WriteNormal (C: char; X, Y: dword); inline;
- (* Write C to console at X, Y (0-based). *)
- begin
- VioWrtCharStrAtt (@C, 1, Y, X, TextAttr, VioHandle);
- end;
- procedure WriteBell; inline;
- (* Write character #7 - beep. *)
- begin
- DosBeep (800, 250);
- end;
- {****************************************************************************
- Extra Crt Functions
- ****************************************************************************}
- procedure CursorOn;
- var
- I: TVioCursorInfo;
- begin
- VioGetCurType (I, VioHandle);
- with I do
- begin
- yStartInt := -90;
- cEndInt := -100;
- Attr := 15;
- end;
- VioSetCurType (I, VioHandle);
- end;
- procedure CursorOff;
- var
- I: TVioCursorInfo;
- begin
- VioGetCurType (I, VioHandle);
- I.AttrInt := -1;
- VioSetCurType (I, VioHandle);
- end;
- procedure CursorBig;
- var
- I: TVioCursorInfo;
- begin
- VioGetCurType (I, VioHandle);
- with I do
- begin
- yStart := 0;
- cEndInt := -100;
- Attr := 15;
- end;
- VioSetCurType (I, VioHandle);
- end;
- (* Include common, platform independent part. *)
- {$I crt.inc}
- function KeyPressed: boolean;
- {Checks if a key is pressed.}
- var
- AKeyRec: TKbdKeyinfo;
- begin
- if SpecialKey or (ScanCode <> 0) then
- KeyPressed := true
- else
- KeyPressed := (KbdPeek (AKeyRec, 0) = 0)
- and ((AKeyRec.fbStatus and $40) <> 0);
- end;
- function ReadKey: char;
- {Reads the next character from the keyboard.}
- var
- AKeyRec: TKbdKeyInfo;
- C, S: char;
- begin
- if SpecialKey then
- begin
- SpecialKey := false;
- ReadKey := char (ScanCode);
- ScanCode := 0;
- end
- else
- if ScanCode <> 0 then
- begin
- ReadKey := char (ScanCode);
- ScanCode := 0;
- end
- else
- begin
- while ((KbdCharIn (AKeyRec, 1, 0) <> 0)
- or (AKeyRec.fbStatus and $41 <> $40)) and (ScanCode = 0) do
- DosSleep (5);
- if ScanCode = 0 then
- begin
- C := AKeyRec.CharCode;
- S := AKeyRec.ScanCode;
- if (C = #224) and (S <> #0) then
- C := #0;
- if C = #0 then
- begin
- SpecialKey := true;
- ScanCode := byte (S);
- end;
- ReadKey := C;
- end
- else
- begin
- ReadKey := char (ScanCode);
- ScanCode := 0;
- end;
- end;
- end;
- {Initialization.}
- var
- CurMode: VioModeInfo;
- begin
- if not (IsConsole) then
- VioCreatePS (VioHandle, 25, 80, 1, 1, 0);
- { InitVideo;}
- CurMode.cb := SizeOf (CurMode);
- VioGetMode (CurMode, VioHandle);
- ScreenWidth := CurMode.Col;
- ScreenHeight := CurMode.Row;
- LastMode := 0;
- case ScreenWidth of
- 40: LastMode := CO40;
- 80: LastMode := CO80
- else
- LastMode := 255
- end;
- case ScreenHeight of
- 50: LastMode := LastMode + $100
- else
- LastMode := LastMode + $FF00;
- end;
- CrtInit;
- end.
|