crt.pp 14 KB

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