2
0

crt.pp 12 KB

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