home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / vp21beta.zip / ARTLSRC.RAR / CRT.PAS < prev    next >
Pascal/Delphi Source File  |  2000-08-15  |  13KB  |  561 lines

  1. //█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█
  2. //█                                                       █
  3. //█      Virtual Pascal Runtime Library.  Version 2.1.    █
  4. //█      CRT Interface unit for OS/2 & Win32              █
  5. //█      ─────────────────────────────────────────────────█
  6. //█      Copyright (C) 1995-2000 vpascal.com              █
  7. //█                                                       █
  8. //▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  9.  
  10. {$S-,R-,Q-,I-,X+,T-,Cdecl-,OrgName-,AlignRec-,Use32+}
  11.  
  12. unit Crt;
  13.  
  14. interface
  15.  
  16. const
  17.  
  18. { CRT modes }
  19.  
  20.   BW40          = 0;            { 40x25 B/W on Color Adapter   }
  21.   CO40          = 1;            { 40x25 Color on Color Adapter }
  22.   BW80          = 2;            { 80x25 B/W on Color Adapter   }
  23.   CO80          = 3;            { 80x25 Color on Color Adapter }
  24.   Mono          = 7;            { 80x25 on Monochrome Adapter  }
  25.   Font8x8       = 256;          { Add-in for 8x8 font          }
  26.  
  27.   MON1          = $FE;          { Monochrome, ASCII chars only }
  28.   MON2          = $FD;          { Monochrome, graphics chars   }
  29.   COL1          = $FC;          { Color, ASCII chars only      }
  30.   COL2          = $FB;          { Color, graphics chars        }
  31.  
  32. { Foreground and background color constants }
  33.  
  34.   Black         = 0;
  35.   Blue          = 1;
  36.   Green         = 2;
  37.   Cyan          = 3;
  38.   Red           = 4;
  39.   Magenta       = 5;
  40.   Brown         = 6;
  41.   LightGray     = 7;
  42.  
  43. { Foreground color constants }
  44.  
  45.   DarkGray      = 8;
  46.   LightBlue     = 9;
  47.   LightGreen    = 10;
  48.   LightCyan     = 11;
  49.   LightRed      = 12;
  50.   LightMagenta  = 13;
  51.   Yellow        = 14;
  52.   White         = 15;
  53.  
  54. { Add-in for blinking }
  55.  
  56.   Blink         = 128;
  57.  
  58. { Interface variables }
  59.  
  60. const
  61.   CheckBreak: Boolean = True;   { Enable Ctrl-Break      }
  62.   CheckEOF: Boolean = False;    { Allow Ctrl-Z for EOF?  }
  63.   TextAttr: Byte = LightGray;   { Current text attribute }
  64.  
  65. var
  66.   LastMode: Word;               { Current text mode }
  67.   WindMin: Word;                { Window upper left coordinates }
  68.   WindMax: Word;                { Window lower right coordinates }
  69.  
  70. { The following interface variables are not used (for compatibility only) }
  71.  
  72. const
  73.   DirectVideo: Boolean = False; { Enable direct video addressing }
  74.   CheckSnow: Boolean = True;    { Enable snow filtering }
  75.  
  76. { Interface procedures }
  77.  
  78. procedure AssignCrt(var F: Text);
  79. function KeyPressed: Boolean;
  80. function ReadKey: Char;
  81. procedure TextMode(Mode: Integer);
  82. procedure Window(X1,Y1,X2,Y2: Byte);
  83. procedure GotoXY(X,Y: Byte);
  84. function WhereX: Byte;
  85. function WhereY: Byte;
  86. procedure ClrScr;
  87. procedure ClrEol;
  88. procedure InsLine;
  89. procedure DelLine;
  90. procedure TextColor(Color: Byte);
  91. procedure TextBackground(Color: Byte);
  92. procedure LowVideo;
  93. procedure HighVideo;
  94. procedure NormVideo;
  95. procedure Delay(MS: Longint);
  96.  
  97. { The following procedures are not implemented
  98.  
  99. procedure Sound(Hz: Word);
  100. procedure NoSound;
  101.  
  102. use new procedure PlaySound instead
  103.  
  104. }
  105. {$IFDEF DPMI32}
  106. procedure Sound(Hz: Word);
  107. procedure NoSound;
  108. {$ENDIF}
  109.  
  110. procedure PlaySound(Freq,Duration: Longint);
  111.  
  112. implementation
  113.  
  114. uses Dos, vpsyslow;
  115.  
  116. { Private variables }
  117.  
  118. var
  119.   NormAttr: Byte;
  120.   DelayCount: Longint;
  121.   PrevXcptProc: Pointer;
  122.   ScreenSize: tSysPoint;
  123.  
  124. { Determines if a key has been pressed on the keyboard and returns True }
  125. { if a key has been pressed                                             }
  126.  
  127. function KeyPressed: Boolean;
  128. begin
  129.   KeyPressed := SysKeyPressed;
  130. end;
  131.  
  132. { Reads a character from the keyboard and returns a character or an     }
  133. { extended scan code.                                                   }
  134.  
  135. function ReadKey: Char;
  136. begin
  137.   ReadKey := SysReadKey;
  138. end;
  139.  
  140. { Reads normal character attribute }
  141.  
  142. procedure ReadNormAttr;
  143. begin
  144.   NormAttr := SysReadAttributesAt(WhereX-1, WhereY-1);
  145.   NormVideo;
  146. end;
  147.  
  148. { Setups window coordinates }
  149.  
  150. procedure SetWindowPos;
  151. begin
  152.   WindMin := 0;
  153.   WindMax := ScreenSize.x - 1 + (ScreenSize.y - 1) shl 8;
  154. end;
  155.  
  156. { Stores current video mode in LastMode }
  157.  
  158. procedure GetLastMode;
  159. begin
  160.   LastMode := SysTvGetScrMode( @ScreenSize );
  161. end;
  162.  
  163. { Selects a specific text mode. The valid text modes are:               }
  164. {   BW40: 40x25 Black and white                                         }
  165. {   CO40  40x25 Color                                                   }
  166. {   BW80  80x25 Black and white                                         }
  167. {   CO80  80x25 Color                                                   }
  168. {   Mono  80x25 Black and white                                         }
  169. {   Font8x8 (Add-in) 43-/50-line mode                                   }
  170.  
  171. procedure TextMode(Mode: Integer);
  172. begin
  173.   TextAttr := LightGray;
  174.   SysTvSetScrMode( Mode );
  175.   GetLastMode;
  176.   NormVideo;
  177.   SetWindowPos;
  178.   ClrScr;
  179. end;
  180.  
  181. { Defines a text window on the screen.                                  }
  182.  
  183. procedure Window(X1,Y1,X2,Y2: Byte);
  184. begin
  185.   if (X1 <= X2) and (Y1 <= Y2) then
  186.   begin
  187.     Dec(X1);
  188.     Dec(Y1);
  189.     if (X1 >= 0) and (Y1 >= 0) then
  190.     begin
  191.       Dec(X2);
  192.       Dec(Y2);
  193.       if (X2 < ScreenSize.x) and (Y2 < ScreenSize.y) then
  194.       begin
  195.         WindMin := X1 + Y1 shl 8;
  196.         WindMax := X2 + Y2 shl 8;
  197.         GotoXY(1,1);
  198.       end;
  199.     end;
  200.   end;
  201. end;
  202.  
  203. { Moves the cursor to the given coordinates within the screen.          }
  204.  
  205. procedure GotoXY(X,Y: Byte);
  206. var
  207.   X1,Y1: Word;
  208. begin
  209.   if (X > 0) and (Y > 0) then
  210.   begin
  211.     X1 := X - 1 + Lo(WindMin);
  212.     Y1 := Y - 1 + Hi(WindMin);
  213.     if (X1 <= Lo(WindMax)) and (Y1 <= Hi(WindMax)) then
  214.       SysTVSetCurPos( X1, Y1 );
  215.   end;
  216. end;
  217.  
  218. { Returns the X coordinate of the current cursor location.              }
  219.  
  220. function WhereX: Byte;
  221. var
  222.   X,Y: SmallWord;
  223. begin
  224.   SysGetCurPos(X, Y);
  225.   WhereX := X - Lo(WindMin) + 1;
  226. end;
  227.  
  228. { Returns the Y coordinate of the current cursor location.              }
  229.  
  230. function WhereY: Byte;
  231. var
  232.   X,Y: SmallWord;
  233. begin
  234.   SysGetCurPos(X,Y);
  235.   WhereY := Y - Hi(WindMin) + 1;
  236. end;
  237.  
  238. { Clears the screen and returns the cursor to the upper-left corner.    }
  239.  
  240. procedure ClrScr;
  241. begin
  242.   SysScrollUp( Lo(WindMin), Hi(WindMin), Lo(WindMax), Hi(WindMax), Hi(WindMax)-Hi(WindMin)+1, Ord( ' ' ) + TextAttr shl 8 );
  243.   GotoXY(1,1);
  244. end;
  245.  
  246. { Clears all characters from the cursor position to the end of the line }
  247. { without moving the cursor.                                            }
  248.  
  249. procedure ClrEol;
  250. var
  251.   X,Y, Len: SmallWord;
  252.   Buffer: Array[0..255] of char;
  253. begin
  254.   SysGetCurPos(X, Y);
  255.   Len := succ(Lo(WindMax)-X);
  256.   fillchar(Buffer, Len, ' ');
  257.   SysWrtCharStrAtt(@Buffer, Len, X, Y, TextAttr);
  258. end;
  259.  
  260. { Inserts an empty line at the cursor position.                         }
  261.  
  262. procedure InsLine;
  263. var
  264.   Cell,X,Y: SmallWord;
  265. begin
  266.   Cell := Ord(' ') + TextAttr shl 8;
  267.   SysGetCurPos(X,Y);
  268.   SysScrollDn(Lo(WindMin),Y,Lo(WindMax),Hi(WindMax),1,Cell);
  269. end;
  270.  
  271. { Deletes the line containing the cursor.                               }
  272.  
  273. procedure DelLine;
  274. var
  275.   Cell,X,Y: SmallWord;
  276. begin
  277.   Cell := Ord(' ') + TextAttr shl 8;
  278.   SysGetCurPos(X,Y);
  279.   SysScrollUp(Lo(WindMin),Y,Lo(WindMax),Hi(WindMax),1,Cell);
  280. end;
  281.  
  282. { Selects the foreground character color.                               }
  283.  
  284. procedure TextColor(Color: Byte);
  285. begin
  286.   if Color > White then Color := (Color and $0F) or $80;
  287.   TextAttr := (TextAttr and $70) or Color;
  288. end;
  289.  
  290. { Selects the background color.                                         }
  291.  
  292. procedure TextBackground(Color: Byte);
  293. begin
  294.   TextAttr := (TextAttr and $8F) or ((Color and $07) shl 4);
  295. end;
  296.  
  297. { Selects low intensity characters.                                     }
  298.  
  299. procedure LowVideo;
  300. begin
  301.   TextAttr := TextAttr and $F7;
  302. end;
  303.  
  304. { Selects normal intensity characters.                                  }
  305.  
  306. procedure NormVideo;
  307. begin
  308.   TextAttr := NormAttr;
  309. end;
  310.  
  311. { Selects high-intensity characters.                                    }
  312.  
  313. procedure HighVideo;
  314. begin
  315.   TextAttr := TextAttr or $08;
  316. end;
  317.  
  318. { Delays a specified number of milliseconds. }
  319.  
  320. procedure Delay(MS: Longint);
  321. begin
  322.   SysCtrlSleep( MS );
  323. end;
  324.  
  325. { Plays sound of a specified frequency and duration.                    }
  326.  
  327. procedure PlaySound(Freq,Duration: Longint);
  328. begin
  329.   SysBeepEx(Freq, Duration);
  330. end;
  331.  
  332. {$IFDEF DPMI32}
  333. procedure Sound(Hz: Word);
  334. begin
  335.   SysSound(Hz);
  336. end;
  337.  
  338. procedure NoSound;
  339. begin
  340.   SysNoSound;
  341. end;
  342. {$ENDIF}
  343.  
  344. { Do line feed operation }
  345.  
  346. procedure LineFeed;
  347. var
  348.   Cell: SmallWord;
  349. begin
  350.   Cell := Ord(' ') + TextAttr shl 8;
  351.   SysScrollUp(Lo(WindMin),Hi(WindMin),Lo(WindMax),Hi(WindMax),1,Cell);
  352. end;
  353.  
  354. { Outputs packed string to the CRT device }
  355.  
  356. type
  357.   PWin32Cell = ^TWin32Cell;
  358.   TWin32Cell = record
  359.     Ch:     SmallWord;
  360.     Attr:   SmallWord;
  361.   end;
  362.  
  363. procedure WritePackedString(S: PChar; Len: Longint);
  364. var
  365.   Buf: array[1..256] of Char;
  366.   I,BufChars: Integer;
  367.   X,Y:        SmallWord;
  368.   X1,Y1:      Longint;
  369.   C:          Char;
  370.  
  371.   procedure FlushBuffered;
  372.   begin
  373.     If BufChars > 0 then
  374.     begin
  375.       SysWrtCharStrAtt(@Buf, BufChars, X1, Y1, TextAttr);
  376.       BufChars := 0;
  377.       X1 := X;
  378.       Y1 := Y;
  379.     end;
  380.   end;
  381.  
  382. begin
  383.   SysGetCurPos(X, Y);
  384.   BufChars := 0;
  385.   X1 := X;
  386.   Y1 := Y;
  387.   for I := 0 to Len - 1 do
  388.   begin
  389.     C := S[I];
  390.     case C of
  391.       ^J:               { Line Feed }
  392.         begin
  393.           FlushBuffered;
  394.           {$IFDEF LINUX}
  395.           X := Lo(WindMin);
  396.           x1 := x;
  397.           {$ENDIF}
  398.           if Y >= Hi(WindMax) then LineFeed else Inc(Y);
  399.           y1 := y;
  400.         end;
  401.       {$IFNDEF LINUX}
  402.       ^M:               { Carriage return }
  403.         begin
  404.           FlushBuffered;
  405.           X := Lo(WindMin);
  406.           x1 := x;
  407.         end;
  408.       {$ENDIF}
  409.       ^H:               { Backspace }
  410.         begin
  411.           FlushBuffered;
  412.           if X > Lo(WindMin) then Dec(X);
  413.           if X1 > Lo(WindMin) then Dec(X1);
  414.         end;
  415.       ^G:               { Bell }
  416.         SysBeep;
  417.       else
  418.         Inc(BufChars);
  419.         Buf[BufChars] := C;
  420.         Inc(X);
  421.         if X > Lo(WindMax) then
  422.         begin
  423.           FlushBuffered;
  424.           X := Lo(WindMin);
  425.           X1 := X;
  426.           Inc(Y);
  427.           if Y > Hi(WindMax) then
  428.           begin
  429.             FlushBuffered;
  430.             LineFeed;
  431.             Y := Hi(WindMax);
  432.           end;
  433.           Y1 := Y;
  434.         end;
  435.     end;
  436.   end;
  437.   FlushBuffered;
  438.   SysTVSetCurPos(X, Y);
  439. end;
  440.  
  441. { CRT text file I/O functions }
  442.  
  443. function CrtRead(var F: Text): Longint;
  444. var
  445.   CurPos: Longint;
  446.   C: Char;
  447. begin
  448.   with TextRec(F) do
  449.   begin
  450.     CurPos := 0;
  451.     repeat
  452.       SysFlushKeyBuf;
  453.       C := ReadKey;
  454.       case C of
  455.         ^H:                     { Backspace }
  456.           if CurPos > 0 then
  457.           begin
  458.             WritePackedString(^H' '^H, 3);
  459.             Dec(CurPos);
  460.           end;
  461.         #27:                    { Escape }
  462.           while CurPos > 0 do
  463.           begin
  464.             WritePackedString(^H' '^H, 3);
  465.             Dec(CurPos);
  466.           end;
  467.         ' '..#255:
  468.           if CurPos < BufSize - 2 then
  469.           begin
  470.             BufPtr^[CurPos] := C;
  471.             Inc(CurPos);
  472.             WritePackedString(@C,1);
  473.           end;
  474.       end; { case }
  475.     until (C = ^M) or (CheckEOF and (C = ^Z));
  476.     BufPtr^[CurPos] := C;
  477.     Inc(CurPos);
  478.     if C = ^M then              { Carriage Return }
  479.     begin
  480.       BufPtr^[CurPos] := ^J;    { Line Feed }
  481.       Inc(CurPos);
  482.       WritePackedString(^M^J,2);
  483.     end;
  484.     BufPos := 0;
  485.     BufEnd := CurPos;
  486.   end;
  487.   CrtRead := 0;                 { I/O result = 0: success }
  488. end;
  489.  
  490. function CrtWrite(var F: Text): Longint;
  491. begin
  492.   with TextRec(F) do
  493.   begin
  494.     WritePackedString(PChar(BufPtr),BufPos);
  495.     BufPos := 0;
  496.   end;
  497.   CrtWrite := 0;                { I/O result = 0: success }
  498. end;
  499.  
  500. function CrtReturn(var F: Text): Longint;
  501. begin
  502.   CrtReturn := 0;               { I/O result = 0: success }
  503. end;
  504.  
  505. function CrtOpen(var F: Text): Longint;
  506. begin
  507.   with TextRec(F) do
  508.   begin
  509.     CloseFunc := @CrtReturn;
  510.     if Mode = fmInput then
  511.     begin
  512.       InOutFunc := @CrtRead;
  513.       FlushFunc := @CrtReturn;
  514.     end
  515.    else
  516.     begin
  517.       Mode := fmOutput;
  518.       InOutFunc := @CrtWrite;
  519.       FlushFunc := @CrtWrite;
  520.     end;
  521.   end;
  522.   CrtOpen := 0;                 { I/O result = 0: success }
  523. end;
  524.  
  525. { Associates a text file with CRT device.                               }
  526.  
  527. procedure AssignCrt(var F: Text);
  528. begin
  529.   with TextRec(F) do
  530.   begin
  531.     Handle := $FFFFFFFF;
  532.     Mode := fmClosed;
  533.     BufSize := SizeOf(Buffer);
  534.     BufPtr := @Buffer;
  535.     OpenFunc := @CrtOpen;
  536.     Name[0] := #0;
  537.   end;
  538. end;
  539.  
  540. { Signal Handler }
  541.  
  542. function CrtCtrlBreakHandler: Boolean;
  543. begin
  544.   CrtCtrlBreakHandler := not CheckBreak;
  545. end;
  546.  
  547. begin
  548.   SysTvInitCursor;
  549.   GetLastMode;
  550.   ReadNormAttr;
  551.   SetWindowPos;
  552.   AssignCrt(Input);  Reset(Input);
  553.   AssignCrt(Output); ReWrite(Output);
  554.   CtrlBreakHandler := CrtCtrlBreakHandler;
  555.   SysCtrlSetCBreakHandler;
  556.   {$IFDEF LINUX}
  557.   SysTvKbdInit;
  558.   {$ENDIF}
  559. end.
  560.  
  561.