crt.pp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731
  1. {
  2. $Id$
  3. Copyright (c) 1999-2001 by the Free Pascal development team.
  4. Borland Pascal 7 Compatible CRT Unit for Netware, tested with
  5. Netware 4.11 and 5.1
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {At initialization time, AutoScreenDestructionMode is set to true so after program termination
  13. no "press any key to close screen" is displayed. Also check for ctrl-c in readkey is disabled.
  14. To enable ctrl-c check, set CheckBreak to true before calling ReadKey.
  15. 2001/04/13 armin: first version for netware, compilable, completely untested
  16. 2001/04/14 armin: tested, seems to work
  17. TextMode, Sound and NoSound are dummys, don't know how to
  18. implement that for netware
  19. }
  20. unit crt;
  21. interface
  22. const
  23. { CRT modes }
  24. BW40 = 0; { 40x25 B/W on Color Adapter }
  25. CO40 = 1; { 40x25 Color on Color Adapter }
  26. BW80 = 2; { 80x25 B/W on Color Adapter }
  27. CO80 = 3; { 80x25 Color on Color Adapter }
  28. Mono = 7; { 80x25 on Monochrome Adapter }
  29. Font8x8 = 256; { Add-in for ROM font }
  30. { Mode constants for 3.0 compatibility }
  31. C40 = CO40;
  32. C80 = CO80;
  33. { Foreground and background color constants }
  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. { Foreground color constants }
  43. DarkGray = 8;
  44. LightBlue = 9;
  45. LightGreen = 10;
  46. LightCyan = 11;
  47. LightRed = 12;
  48. LightMagenta = 13;
  49. Yellow = 14;
  50. White = 15;
  51. { Add-in for blinking }
  52. Blink = 128;
  53. var
  54. { Interface variables }
  55. CheckBreak: Boolean; { Enable Ctrl-Break, supported on Netware }
  56. CheckEOF: Boolean; { Enable Ctrl-Z, supported on Netware }
  57. DirectVideo: Boolean; { Enable direct video addressing }
  58. CheckSnow: Boolean; { Enable snow filtering }
  59. LastMode: Word; { Current text mode }
  60. TextAttr: Byte; { Current text attribute }
  61. WindMin: Word; { Window upper left coordinates }
  62. WindMax: Word; { Window lower right coordinates }
  63. Const
  64. ScreenHeight : longint=25;
  65. ScreenWidth : longint=80;
  66. ConsoleMaxX=80;
  67. ConsoleMaxY=25;
  68. { Interface procedures }
  69. procedure AssignCrt(var F: Text);
  70. function KeyPressed: Boolean;
  71. function ReadKey: Char;
  72. procedure TextMode(Mode: Integer); {dummy function}
  73. procedure Window(X1,Y1,X2,Y2: Byte);
  74. procedure GotoXY(X,Y: Byte);
  75. function WhereX: Byte;
  76. function WhereY: Byte;
  77. procedure ClrScr;
  78. procedure ClrEol;
  79. procedure InsLine;
  80. procedure DelLine;
  81. procedure TextColor(Color: Byte);
  82. procedure TextBackground(Color: Byte);
  83. procedure LowVideo;
  84. procedure HighVideo;
  85. procedure NormVideo;
  86. procedure Delay(MS: Word);
  87. procedure Sound(Hz: Word); {dummy function}
  88. procedure NoSound; {dummy function}
  89. {Extra Functions}
  90. procedure cursoron;
  91. procedure cursoroff;
  92. procedure cursorbig;
  93. implementation
  94. {$I nwsys.inc}
  95. {$ASMMODE ATT}
  96. var
  97. DelayCnt,
  98. // ScreenWidth,
  99. // ScreenHeight : longint;
  100. VidSeg : Word;
  101. {
  102. definition of textrec is in textrec.inc
  103. }
  104. {$i textrec.inc}
  105. {****************************************************************************
  106. Low level Routines
  107. ****************************************************************************}
  108. procedure setscreenmode(mode : byte);
  109. begin
  110. end;
  111. function GetScreenHeight : longint;
  112. VAR Height, Width : WORD;
  113. begin
  114. _GetSizeOfScreen (Height,Width);
  115. GetScreenHeight := Height;
  116. end;
  117. function GetScreenWidth : longint;
  118. VAR Height, Width : WORD;
  119. begin
  120. _GetSizeOfScreen (Height,Width);
  121. GetScreenWidth := Width;
  122. end;
  123. procedure GetScreenCursor(var x,y : longint);
  124. begin
  125. x := _wherex+1;
  126. y := _wherey+1;
  127. end;
  128. {****************************************************************************
  129. Helper Routines
  130. ****************************************************************************}
  131. Function WinMinX: Longint;
  132. {
  133. Current Minimum X coordinate
  134. }
  135. Begin
  136. WinMinX:=(WindMin and $ff)+1;
  137. End;
  138. Function WinMinY: Longint;
  139. {
  140. Current Minimum Y Coordinate
  141. }
  142. Begin
  143. WinMinY:=(WindMin shr 8)+1;
  144. End;
  145. Function WinMaxX: Longint;
  146. {
  147. Current Maximum X coordinate
  148. }
  149. Begin
  150. WinMaxX:=(WindMax and $ff)+1;
  151. End;
  152. Function WinMaxY: Longint;
  153. {
  154. Current Maximum Y coordinate;
  155. }
  156. Begin
  157. WinMaxY:=(WindMax shr 8) + 1;
  158. End;
  159. Function FullWin:boolean;
  160. {
  161. Full Screen 80x25? Window(1,1,80,25) is used, allows faster routines
  162. }
  163. begin
  164. FullWin:=(WinMinX=1) and (WinMinY=1) and
  165. (WinMaxX=ScreenWidth) and (WinMaxY=ScreenHeight);
  166. end;
  167. {****************************************************************************
  168. Public Crt Functions
  169. ****************************************************************************}
  170. procedure textmode(mode : integer);
  171. begin
  172. Window (1,1,byte(ScreenWidth),byte(ScreenHeight));
  173. ClrScr;
  174. end;
  175. Procedure TextColor(Color: Byte);
  176. {
  177. Switch foregroundcolor
  178. }
  179. Begin
  180. TextAttr:=(Color and $f) or (TextAttr and $70);
  181. If (Color>15) Then TextAttr:=TextAttr Or Blink;
  182. End;
  183. Procedure TextBackground(Color: Byte);
  184. {
  185. Switch backgroundcolor
  186. }
  187. Begin
  188. TextAttr:=((Color shl 4) and ($f0 and not Blink)) or (TextAttr and ($0f OR Blink) );
  189. End;
  190. Procedure HighVideo;
  191. {
  192. Set highlighted output.
  193. }
  194. Begin
  195. TextColor(TextAttr Or $08);
  196. End;
  197. Procedure LowVideo;
  198. {
  199. Set normal output
  200. }
  201. Begin
  202. TextColor(TextAttr And $77);
  203. End;
  204. Procedure NormVideo;
  205. {
  206. Set normal back and foregroundcolors.
  207. }
  208. Begin
  209. TextColor(7);
  210. TextBackGround(0);
  211. End;
  212. Procedure GotoXy(X: Byte; Y: Byte);
  213. {
  214. Go to coordinates X,Y in the current window.
  215. }
  216. Begin
  217. If (X>0) and (X<=WinMaxX- WinMinX+1) and
  218. (Y>0) and (Y<=WinMaxY-WinMinY+1) Then
  219. Begin
  220. X := X + WinMinX - 1;
  221. Y := Y + WinMinY - 1;
  222. _GotoXY (x-1,y-1);
  223. End;
  224. End;
  225. Procedure Window(X1, Y1, X2, Y2: Byte);
  226. {
  227. Set screen window to the specified coordinates.
  228. }
  229. Begin
  230. if (X1>X2) or (X2>ScreenWidth) or
  231. (Y1>Y2) or (Y2>ScreenHeight) then
  232. exit;
  233. WindMin:=((Y1-1) Shl 8)+(X1-1);
  234. WindMax:=((Y2-1) Shl 8)+(X2-1);
  235. GoToXY(1,1);
  236. End;
  237. Procedure ClrScr;
  238. {
  239. Clear the current window, and set the cursor on 1,1
  240. }
  241. var
  242. fil : word;
  243. y : longint;
  244. p : pointer;
  245. rowlen,rows: longint;
  246. begin
  247. fil:=32 or (textattr shl 8);
  248. if FullWin then
  249. begin
  250. _clrscr; {seems to swich cursor off}
  251. _DisplayInputCursor;
  252. end else
  253. begin
  254. rowlen := WinMaxX-WinMinX+1;
  255. rows := WinMaxY-WinMinY+1;
  256. GetMem (p, rows * rowlen * 2);
  257. FillWord (p^, rows * rowlen, fil);
  258. _CopyToScreenMemory (word(rows),word(rowlen),p,WinMinX-1,WinMinY-1);
  259. FreeMem (p, rows * rowlen * 2);
  260. end;
  261. Gotoxy(1,1);
  262. end;
  263. Procedure ClrEol;
  264. {
  265. Clear from current position to end of line.
  266. }
  267. var
  268. x,y : longint;
  269. fil : word;
  270. rowlen : word;
  271. p : pointer;
  272. Begin
  273. GetScreenCursor(x,y);
  274. fil:=32 or (textattr shl 8);
  275. if x<WinMaxX then
  276. begin
  277. rowlen := WinMaxX-x+1;
  278. GetMem (p, rowlen * 2);
  279. FillWord (p^, rowlen, fil);
  280. _CopyToScreenMemory (1,rowlen,p,x-1,y-1);
  281. FreeMem (p, rowlen * 2);
  282. end;
  283. End;
  284. Function WhereX: Byte;
  285. {
  286. Return current X-position of cursor.
  287. }
  288. var
  289. x,y : longint;
  290. Begin
  291. GetScreenCursor(x,y);
  292. WhereX:=x-WinMinX+1;
  293. End;
  294. Function WhereY: Byte;
  295. {
  296. Return current Y-position of cursor.
  297. }
  298. var
  299. x,y : longint;
  300. Begin
  301. GetScreenCursor(x,y);
  302. WhereY:=y-WinMinY+1;
  303. End;
  304. {*************************************************************************
  305. Keyboard
  306. *************************************************************************}
  307. var
  308. is_last : boolean;
  309. function readkey : char;
  310. var
  311. char1 : char;
  312. begin
  313. if is_last then
  314. begin
  315. is_last:=false;
  316. readkey:=_getch;
  317. end else
  318. begin
  319. _SetCtrlCharCheckMode (CheckBreak);
  320. char1 := _getch;
  321. if char1 = #0 then is_last := true;
  322. readkey:=char1;
  323. end;
  324. end;
  325. function keypressed : boolean;
  326. begin
  327. if is_last then
  328. begin
  329. keypressed:=true;
  330. exit;
  331. end else
  332. keypressed := (_kbhit <> 0);
  333. end;
  334. {*************************************************************************
  335. Delay
  336. *************************************************************************}
  337. procedure Delay(MS: Word);
  338. begin
  339. _delay (MS);
  340. end;
  341. procedure sound(hz : word);
  342. begin
  343. _RingTheBell;
  344. end;
  345. procedure nosound;
  346. begin
  347. end;
  348. {****************************************************************************
  349. HighLevel Crt Functions
  350. ****************************************************************************}
  351. procedure removeline(y : longint);
  352. var
  353. fil : word;
  354. rowlen : word;
  355. p : pointer;
  356. begin
  357. fil:=32 or (textattr shl 8);
  358. rowlen:=WinMaxX-WinMinX+1;
  359. GetMem (p, rowlen*2);
  360. y:=WinMinY+y-1;
  361. While (y<=WinMaxY) do
  362. begin
  363. _CopyFromScreenMemory (1,rowlen,p,WinMinX-1,word(y));
  364. _CopyToScreenMemory (1,rowlen,p,WinMinX-1,word(y-1));
  365. inc(y);
  366. end;
  367. FillWord (p^,rowlen,fil);
  368. _CopyToScreenMemory (1,rowlen,p,WinMinX-1,WinMaxY-1);
  369. FreeMem (p, rowlen*2);
  370. end;
  371. procedure delline;
  372. begin
  373. removeline(wherey);
  374. end;
  375. procedure insline;
  376. var
  377. my : longint;
  378. y : word;
  379. fil : word;
  380. rowlen : word;
  381. p : pointer;
  382. begin
  383. fil:=32 or (textattr shl 8);
  384. y:=WhereY-1;
  385. my:=WinMaxY-WinMinY;
  386. rowlen := WinMaxX-WinMinX+1;
  387. GetMem (p, rowlen*2);
  388. while (my>=y) do
  389. begin
  390. _CopyFromScreenMemory (1,rowlen,p,WinMinX-1,word(my));
  391. _CopyToScreenMemory (1,rowlen,p,WinMinX-1,word(my+1));
  392. dec(my);
  393. end;
  394. FillWord (p^,rowlen,fil);
  395. _CopyToScreenMemory (1,rowlen,p,WinMinX-1,y);
  396. FreeMem (p, rowlen*2);
  397. end;
  398. {****************************************************************************
  399. Extra Crt Functions
  400. ****************************************************************************}
  401. procedure cursoron;
  402. begin
  403. if _IsColorMonitor <> 0 then
  404. _SetCursorShape (9,$A)
  405. else
  406. _SetCursorShape ($B,$D);
  407. _DisplayInputCursor;
  408. end;
  409. procedure cursoroff;
  410. begin
  411. _HideInputCursor;
  412. end;
  413. procedure cursorbig;
  414. begin
  415. _SetCursorShape (1,$A);
  416. _DisplayInputCursor;
  417. end;
  418. {*****************************************************************************
  419. Read and Write routines
  420. *****************************************************************************}
  421. var
  422. CurrX,CurrY : longint;
  423. Procedure WriteChar(c:char);
  424. var
  425. w : word;
  426. begin
  427. case c of
  428. #10 : inc(CurrY);
  429. #13 : CurrX:=WinMinX;
  430. #8 : begin
  431. if CurrX>WinMinX then
  432. dec(CurrX);
  433. end;
  434. #7 : begin { beep }
  435. _RingTheBell;
  436. end;
  437. else
  438. begin
  439. w:=(textattr shl 8) or byte(c);
  440. _CopyToScreenMemory (1,1,@w,CurrX-1,CurrY-1);
  441. inc(CurrX);
  442. end;
  443. end;
  444. if CurrX>WinMaxX then
  445. begin
  446. CurrX:=WinMinX;
  447. inc(CurrY);
  448. end;
  449. while CurrY>WinMaxY do
  450. begin
  451. removeline(1);
  452. dec(CurrY);
  453. end;
  454. end;
  455. Function CrtWrite(var f : textrec):integer;
  456. var
  457. i : longint;
  458. begin
  459. GetScreenCursor(CurrX,CurrY);
  460. for i:=0 to f.bufpos-1 do
  461. WriteChar(f.buffer[i]); { ad: may be better to use a buffer but i think it's fast enough }
  462. _GotoXY (CurrX-1,CurrY-1);
  463. f.bufpos:=0;
  464. CrtWrite:=0;
  465. end;
  466. Function CrtRead(Var F: TextRec): Integer;
  467. procedure BackSpace;
  468. begin
  469. if (f.bufpos>0) and (f.bufpos=f.bufend) then
  470. begin
  471. WriteChar(#8);
  472. WriteChar(' ');
  473. WriteChar(#8);
  474. dec(f.bufpos);
  475. dec(f.bufend);
  476. end;
  477. end;
  478. var
  479. ch : Char;
  480. Begin
  481. GetScreenCursor(CurrX,CurrY);
  482. f.bufpos:=0;
  483. f.bufend:=0;
  484. repeat
  485. if f.bufpos>f.bufend then
  486. f.bufend:=f.bufpos;
  487. _GotoXY (CurrX-1,CurrY-1);
  488. ch:=readkey;
  489. case ch of
  490. #0 : case readkey of
  491. #71 : while f.bufpos>0 do
  492. begin
  493. dec(f.bufpos);
  494. WriteChar(#8);
  495. end;
  496. #75 : if f.bufpos>0 then
  497. begin
  498. dec(f.bufpos);
  499. WriteChar(#8);
  500. end;
  501. #77 : if f.bufpos<f.bufend then
  502. begin
  503. WriteChar(f.bufptr^[f.bufpos]);
  504. inc(f.bufpos);
  505. end;
  506. #79 : while f.bufpos<f.bufend do
  507. begin
  508. WriteChar(f.bufptr^[f.bufpos]);
  509. inc(f.bufpos);
  510. end;
  511. end;
  512. ^S,
  513. #8 : BackSpace;
  514. ^Y,
  515. #27 : begin
  516. f.bufpos:=f.bufend;
  517. while f.bufend>0 do
  518. BackSpace;
  519. end;
  520. #13 : begin
  521. WriteChar(#13);
  522. WriteChar(#10);
  523. f.bufptr^[f.bufend]:=#13;
  524. f.bufptr^[f.bufend+1]:=#10;
  525. inc(f.bufend,2);
  526. break;
  527. end;
  528. #26 : if CheckEOF then
  529. begin
  530. f.bufptr^[f.bufend]:=#26;
  531. inc(f.bufend);
  532. break;
  533. end;
  534. else
  535. begin
  536. if f.bufpos<f.bufsize-2 then
  537. begin
  538. f.buffer[f.bufpos]:=ch;
  539. inc(f.bufpos);
  540. WriteChar(ch);
  541. end;
  542. end;
  543. end;
  544. until false;
  545. f.bufpos:=0;
  546. _GotoXY (CurrX-1,CurrY-1);
  547. CrtRead:=0;
  548. End;
  549. Function CrtReturn(Var F: TextRec): Integer;
  550. Begin
  551. CrtReturn:=0;
  552. end;
  553. Function CrtClose(Var F: TextRec): Integer;
  554. Begin
  555. F.Mode:=fmClosed;
  556. CrtClose:=0;
  557. End;
  558. Function CrtOpen(Var F: TextRec): Integer;
  559. Begin
  560. If F.Mode=fmOutput Then
  561. begin
  562. TextRec(F).InOutFunc:=@CrtWrite;
  563. TextRec(F).FlushFunc:=@CrtWrite;
  564. end
  565. Else
  566. begin
  567. F.Mode:=fmInput;
  568. TextRec(F).InOutFunc:=@CrtRead;
  569. TextRec(F).FlushFunc:=@CrtReturn;
  570. end;
  571. TextRec(F).CloseFunc:=@CrtClose;
  572. CrtOpen:=0;
  573. End;
  574. procedure AssignCrt(var F: Text);
  575. begin
  576. Assign(F,'');
  577. TextRec(F).OpenFunc:=@CrtOpen;
  578. end;
  579. var
  580. x,y : longint;
  581. begin
  582. { Load startup values }
  583. ScreenWidth:=GetScreenWidth;
  584. ScreenHeight:=GetScreenHeight;
  585. lastmode := CO80;
  586. TextMode (lastmode);
  587. GetScreenCursor(x,y);
  588. if screenheight>25 then
  589. lastmode:=lastmode or $100;
  590. TextColor (LightGray);
  591. TextBackground (Black);
  592. { Redirect the standard output }
  593. assigncrt(Output);
  594. Rewrite(Output);
  595. TextRec(Output).Handle:=StdOutputHandle;
  596. assigncrt(Input);
  597. Reset(Input);
  598. TextRec(Input).Handle:=StdInputHandle;
  599. CheckBreak := FALSE;
  600. CheckEOF := FALSE;
  601. _SetCtrlCharCheckMode (CheckBreak);
  602. _SetAutoScreenDestructionMode (TRUE);
  603. end.