crt.pp 12 KB

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