crt.pp 12 KB

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