crt.pp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 by Nils Sjoholm and Carl Eric Codere
  4. See the file COPYING.FPC, included in this distribution,
  5. for details about the copyright.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9. **********************************************************************}
  10. unit Crt;
  11. {--------------------------------------------------------------------}
  12. { LEFT TO DO: }
  13. {--------------------------------------------------------------------}
  14. { o Write special characters are not recognized }
  15. { o Write does not take care of window coordinates yet. }
  16. { o Read does not recognize the special editing characters }
  17. { o Read does not take care of window coordinates yet. }
  18. { o Readkey extended scancode is not correct yet }
  19. { o Color mapping only works for 4 colours }
  20. { o ClrScr, DeleteLine, InsLine do not work with window coordinates }
  21. {--------------------------------------------------------------------}
  22. Interface
  23. Const
  24. { Controlling consts }
  25. Flushing=false; {if true then don't buffer output}
  26. ScreenWidth = 80;
  27. ScreenHeight = 25;
  28. {$i crth.inc}
  29. Implementation
  30. var
  31. maxcols,maxrows : longint;
  32. CONST
  33. { This is used to make sure that readkey returns immediately }
  34. { if keypressed was used beforehand. }
  35. KeyPress : char = #0;
  36. _LVODisplayBeep = -96;
  37. Type
  38. pInfoData = ^tInfoData;
  39. tInfoData = packed record
  40. id_NumSoftErrors : Longint; { number of soft errors on disk }
  41. id_UnitNumber : Longint; { Which unit disk is (was) mounted on }
  42. id_DiskState : Longint; { See defines below }
  43. id_NumBlocks : Longint; { Number of blocks on disk }
  44. id_NumBlocksUsed : Longint; { Number of block in use }
  45. id_BytesPerBlock : Longint;
  46. id_DiskType : Longint; { Disk Type code }
  47. id_VolumeNode : Longint; { BCPL pointer to volume node }
  48. id_InUse : Longint; { Flag, zero if not in use }
  49. end;
  50. { * List Node Structure. Each member in a list starts with a Node * }
  51. pNode = ^tNode;
  52. tNode = packed Record
  53. ln_Succ, { * Pointer to next (successor) * }
  54. ln_Pred : pNode; { * Pointer to previous (predecessor) * }
  55. ln_Type : Byte;
  56. ln_Pri : Shortint; { * Priority, for sorting * }
  57. ln_Name : PChar; { * ID string, null terminated * }
  58. End; { * Note: Integer aligned * }
  59. { normal, full featured list }
  60. pList = ^tList;
  61. tList = packed record
  62. lh_Head : pNode;
  63. lh_Tail : pNode;
  64. lh_TailPred : pNode;
  65. lh_Type : Byte;
  66. l_pad : Byte;
  67. end;
  68. pMsgPort = ^tMsgPort;
  69. tMsgPort = packed record
  70. mp_Node : tNode;
  71. mp_Flags : Byte;
  72. mp_SigBit : Byte; { signal bit number }
  73. mp_SigTask : Pointer; { task to be signalled (TaskPtr) }
  74. mp_MsgList : tList; { message linked list }
  75. end;
  76. pMessage = ^tMessage;
  77. tMessage = packed record
  78. mn_Node : tNode;
  79. mn_ReplyPort : pMsgPort; { message reply port }
  80. mn_Length : Word; { message len in bytes }
  81. end;
  82. pIOStdReq = ^tIOStdReq;
  83. tIOStdReq = packed record
  84. io_Message : tMessage;
  85. io_Device : Pointer; { device node pointer }
  86. io_Unit : Pointer; { unit (driver private)}
  87. io_Command : Word; { device command }
  88. io_Flags : Byte;
  89. io_Error : Shortint; { error or warning num }
  90. io_Actual : Longint; { actual number of bytes transferred }
  91. io_Length : Longint; { requested number bytes transferred}
  92. io_Data : Pointer; { points to data area }
  93. io_Offset : Longint; { offset for block structured devices }
  94. end;
  95. pIntuiMessage = ^tIntuiMessage;
  96. tIntuiMessage = packed record
  97. ExecMessage : tMessage;
  98. IClass : Longint;
  99. Code : Word;
  100. Qualifier : Word;
  101. IAddress : Pointer;
  102. MouseX,
  103. MouseY : Word;
  104. Seconds,
  105. Micros : Longint;
  106. IDCMPWindow : Pointer;
  107. SpecialLink : pIntuiMessage;
  108. end;
  109. pWindow = ^tWindow;
  110. tWindow = packed record
  111. NextWindow : pWindow; { for the linked list in a screen }
  112. LeftEdge,
  113. TopEdge : Integer; { screen dimensions of window }
  114. Width,
  115. Height : Integer; { screen dimensions of window }
  116. MouseY,
  117. MouseX : Integer; { relative to upper-left of window }
  118. MinWidth,
  119. MinHeight : Integer; { minimum sizes }
  120. MaxWidth,
  121. MaxHeight : Word; { maximum sizes }
  122. Flags : Longint; { see below for defines }
  123. MenuStrip : Pointer; { the strip of Menu headers }
  124. Title : PChar; { the title text for this window }
  125. FirstRequest : Pointer; { all active Requesters }
  126. DMRequest : Pointer; { double-click Requester }
  127. ReqCount : Integer; { count of reqs blocking Window }
  128. WScreen : Pointer; { this Window's Screen }
  129. RPort : Pointer; { this Window's very own RastPort }
  130. BorderLeft,
  131. BorderTop,
  132. BorderRight,
  133. BorderBottom : Shortint;
  134. BorderRPort : Pointer;
  135. FirstGadget : Pointer;
  136. Parent,
  137. Descendant : pWindow;
  138. Pointer_ : Pointer; { sprite data }
  139. PtrHeight : Shortint; { sprite height (not including sprite padding) }
  140. PtrWidth : Shortint; { sprite width (must be less than or equal to 16) }
  141. XOffset,
  142. YOffset : Shortint; { sprite offsets }
  143. IDCMPFlags : Longint; { User-selected flags }
  144. UserPort,
  145. WindowPort : pMsgPort;
  146. MessageKey : pIntuiMessage;
  147. DetailPen,
  148. BlockPen : Byte; { for bar/border/gadget rendering }
  149. CheckMark : Pointer;
  150. ScreenTitle : PChar; { if non-null, Screen title when Window is active }
  151. GZZMouseX : Integer;
  152. GZZMouseY : Integer;
  153. GZZWidth : Integer;
  154. GZZHeight : Word;
  155. ExtData : Pointer;
  156. UserData : Pointer; { general-purpose pointer to User data extension }
  157. WLayer : Pointer;
  158. IFont : Pointer;
  159. MoreFlags : Longint;
  160. end;
  161. const
  162. M_LNM = 20; { linefeed newline mode }
  163. PMB_ASM = M_LNM + 1; { internal storage bit for AS flag }
  164. PMB_AWM = PMB_ASM + 1; { internal storage bit for AW flag }
  165. MAXTABS = 80;
  166. IECLASS_MAX = $15;
  167. type
  168. pKeyMap = ^tKeyMap;
  169. tKeyMap = packed record
  170. km_LoKeyMapTypes : Pointer;
  171. km_LoKeyMap : Pointer;
  172. km_LoCapsable : Pointer;
  173. km_LoRepeatable : Pointer;
  174. km_HiKeyMapTypes : Pointer;
  175. km_HiKeyMap : Pointer;
  176. km_HiCapsable : Pointer;
  177. km_HiRepeatable : Pointer;
  178. end;
  179. pConUnit = ^tConUnit;
  180. tConUnit = packed record
  181. cu_MP : tMsgPort;
  182. { ---- read only variables }
  183. cu_Window : Pointer; { (WindowPtr) intuition window bound to this unit }
  184. cu_XCP : Integer; { character position }
  185. cu_YCP : Integer;
  186. cu_XMax : Integer; { max character position }
  187. cu_YMax : Integer;
  188. cu_XRSize : Integer; { character raster size }
  189. cu_YRSize : Integer;
  190. cu_XROrigin : Integer; { raster origin }
  191. cu_YROrigin : Integer;
  192. cu_XRExtant : Integer; { raster maxima }
  193. cu_YRExtant : Integer;
  194. cu_XMinShrink : Integer; { smallest area intact from resize process }
  195. cu_YMinShrink : Integer;
  196. cu_XCCP : Integer; { cursor position }
  197. cu_YCCP : Integer;
  198. { ---- read/write variables (writes must must be protected) }
  199. { ---- storage for AskKeyMap and SetKeyMap }
  200. cu_KeyMapStruct : tKeyMap;
  201. { ---- tab stops }
  202. cu_TabStops : Array [0..MAXTABS-1] of Word;
  203. { 0 at start, -1 at end of list }
  204. { ---- console rastport attributes }
  205. cu_Mask : Shortint;
  206. cu_FgPen : Shortint;
  207. cu_BgPen : Shortint;
  208. cu_AOLPen : Shortint;
  209. cu_DrawMode : Shortint;
  210. cu_AreaPtSz : Shortint;
  211. cu_AreaPtrn : Pointer; { cursor area pattern }
  212. cu_Minterms : Array [0..7] of Byte; { console minterms }
  213. cu_Font : Pointer; { (TextFontPtr) }
  214. cu_AlgoStyle : Byte;
  215. cu_TxFlags : Byte;
  216. cu_TxHeight : Word;
  217. cu_TxWidth : Word;
  218. cu_TxBaseline : Word;
  219. cu_TxSpacing : Word;
  220. { ---- console MODES and RAW EVENTS switches }
  221. cu_Modes : Array [0..(PMB_AWM+7) div 8 - 1] of Byte;
  222. { one bit per mode }
  223. cu_RawEvents : Array [0..(IECLASS_MAX+7) div 8 - 1] of Byte;
  224. end;
  225. const
  226. CD_CURRX = 1;
  227. CD_CURRY = 2;
  228. CD_MAXX = 3;
  229. CD_MAXY = 4;
  230. CSI = chr($9b);
  231. SIGBREAKF_CTRL_C = 4096;
  232. function AllocVec( size, reqm : Longint ): Pointer;
  233. begin
  234. asm
  235. MOVE.L A6,-(A7)
  236. MOVE.L size,d0
  237. MOVE.L reqm,d1
  238. MOVE.L _ExecBase, A6
  239. JSR -684(A6)
  240. MOVE.L (A7)+,A6
  241. MOVE.L d0,@RESULT
  242. end;
  243. end;
  244. function DoPkt(ID : pMsgPort;
  245. Action, Param1, Param2,
  246. Param3, Param4, Param5 : Longint) : Longint;
  247. begin
  248. asm
  249. MOVEM.L d2/d3/d4/d5/d6/d7/a6,-(A7)
  250. MOVE.L ID,d1
  251. MOVE.L Action,d2
  252. MOVE.L Param1,d3
  253. MOVE.L Param2,d4
  254. MOVE.L Param3,d5
  255. MOVE.L Param4,d6
  256. MOVE.L Param5,d7
  257. MOVE.L _DOSBase,A6
  258. JSR -240(A6)
  259. MOVEM.L (A7)+,d2/d3/d4/d5/d6/d7/a6
  260. MOVE.L d0,@RESULT
  261. end;
  262. end;
  263. procedure FreeVec( memory : Pointer );
  264. begin
  265. asm
  266. MOVE.L A6,-(A7)
  267. MOVE.L memory,a1
  268. MOVE.L _ExecBase,A6
  269. JSR -690(A6)
  270. MOVE.L (A7)+,A6
  271. end;
  272. end;
  273. function GetConsoleTask : pMsgPort;
  274. begin
  275. asm
  276. MOVE.L A6,-(A7)
  277. MOVE.L _DOSBase,A6
  278. JSR -510(A6)
  279. MOVE.L (A7)+,A6
  280. MOVE.L d0,@RESULT
  281. end;
  282. end;
  283. function GetMsg(port : pMsgPort): pMessage;
  284. begin
  285. asm
  286. MOVE.L A6,-(A7)
  287. MOVE.L port,a0
  288. MOVE.L _ExecBase,A6
  289. JSR -372(A6)
  290. MOVE.L (A7)+,A6
  291. MOVE.L d0,@RESULT
  292. end;
  293. end;
  294. function ModifyIDCMP(window : pWindow;
  295. IDCMPFlags : Longint) : Boolean;
  296. begin
  297. asm
  298. MOVE.L A6,-(A7)
  299. MOVE.L window,a0
  300. MOVE.L IDCMPFlags,d0
  301. MOVE.L _IntuitionBase,A6
  302. JSR -150(A6)
  303. MOVE.L (A7)+,A6
  304. TST.L d0
  305. bne @success
  306. bra @end
  307. @success:
  308. move.b #1,d0
  309. @end:
  310. move.b d0,@RESULT
  311. end;
  312. end;
  313. procedure ReplyMsg(mess : pMessage);
  314. begin
  315. asm
  316. MOVE.L A6,-(A7)
  317. MOVE.L mess,a1
  318. MOVE.L _ExecBase,A6
  319. JSR -378(A6)
  320. MOVE.L (A7)+,A6
  321. end;
  322. end;
  323. function WaitPort(port : pMsgPort): pMessage;
  324. begin
  325. asm
  326. MOVE.L A6,-(A7)
  327. MOVE.L port,a0
  328. MOVE.L _ExecBase,A6
  329. JSR -384(A6)
  330. MOVE.L (A7)+,A6
  331. MOVE.L d0,@RESULT
  332. end;
  333. end;
  334. procedure Delay_(ticks : Longint);
  335. begin
  336. asm
  337. MOVE.L A6,-(A7)
  338. MOVE.L ticks,d1
  339. MOVE.L _DOSBase,A6
  340. JSR -198(A6)
  341. MOVE.L (A7)+,A6
  342. end;
  343. end;
  344. function SetSignal(newSignals, signalMask : Longint) : Longint;
  345. begin
  346. asm
  347. MOVE.L A6,-(A7)
  348. MOVE.L newSignals,d0
  349. MOVE.L signalMask,d1
  350. MOVE.L _ExecBase,A6
  351. JSR -306(A6)
  352. MOVE.L (A7)+,A6
  353. MOVE.L d0,@RESULT
  354. end;
  355. end;
  356. function OpenInfo : pInfoData;
  357. var
  358. port : pMsgPort;
  359. info : pInfoData;
  360. bptr, d4, d5, d6, d7 : Longint;
  361. begin
  362. info := pInfoData(AllocVec(SizeOf(tInfoData), 1));
  363. if info <> nil then begin
  364. port := GetConsoleTask;
  365. bptr := Longint(info) shr 2;
  366. if port <> nil then begin
  367. if DoPkt(port, $19, bptr, d4, d5, d6, d7) <> 0 then info := pInfoData(bptr shl 2)
  368. else port := nil;
  369. end;
  370. if port = nil then begin
  371. FreeVec(info);
  372. info := nil;
  373. end;
  374. end;
  375. OpenInfo := info;
  376. end;
  377. procedure CloseInfo(var info : pInfoData);
  378. begin
  379. if info <> nil then begin
  380. FreeVec(info);
  381. info := nil;
  382. end;
  383. end;
  384. function ConData(modus : byte) : integer;
  385. var
  386. info : pInfoData;
  387. theunit : pConUnit;
  388. pos : Longint;
  389. begin
  390. pos := 1;
  391. info := OpenInfo;
  392. if info <> nil then begin
  393. theunit := pConUnit((pIoStdReq(info^.id_InUse))^.io_Unit);
  394. case modus of
  395. CD_CURRX : pos := theunit^.cu_XCP;
  396. CD_CURRY : pos := theunit^.cu_YCP;
  397. CD_MAXX : pos := theunit^.cu_XMax;
  398. CD_MAXY : pos := theunit^.cu_YMax;
  399. end;
  400. CloseInfo(info);
  401. end;
  402. ConData := pos + 1;
  403. end;
  404. function WhereX : tcrtcoord;
  405. begin
  406. WhereX := Byte(ConData(CD_CURRX))-lo(windmin);
  407. end;
  408. function realx: byte;
  409. begin
  410. RealX := Byte(ConData(CD_CURRX));
  411. end;
  412. function realy: byte;
  413. begin
  414. RealY := Byte(ConData(CD_CURRY));
  415. end;
  416. function WhereY : tcrtcoord;
  417. begin
  418. WhereY := Byte(ConData(CD_CURRY))-hi(windmin);
  419. end;
  420. function screencols : integer;
  421. begin
  422. screencols := ConData(CD_MAXX);
  423. end;
  424. function screenrows : integer;
  425. begin
  426. screenrows := ConData(CD_MAXY);
  427. end;
  428. procedure Realgotoxy(x,y : integer);
  429. begin
  430. Write(CSI, y, ';', x, 'H');
  431. end;
  432. procedure gotoxy(x,y : tcrtcoord);
  433. begin
  434. if (x<1) then
  435. x:=1;
  436. if (y<1) then
  437. y:=1;
  438. if y+hi(windmin)-2>=hi(windmax) then
  439. y:=hi(windmax)-hi(windmin)+1;
  440. if x+lo(windmin)-2>=lo(windmax) then
  441. x:=lo(windmax)-lo(windmin)+1;
  442. Write(CSI, y+hi(windmin), ';', x+lo(windmin), 'H');
  443. end;
  444. procedure CursorOff;
  445. begin
  446. Write(CSI,'0 p');
  447. end;
  448. procedure CursorOn;
  449. begin
  450. Write(CSI,'1 p');
  451. end;
  452. procedure ClrScr;
  453. begin
  454. Write(Chr($0c));
  455. end;
  456. function ReadKey : char;
  457. const
  458. IDCMP_VANILLAKEY = $00200000;
  459. IDCMP_RAWKEY = $00000400;
  460. var
  461. info : pInfoData;
  462. win : pWindow;
  463. imsg : pIntuiMessage;
  464. msg : pMessage;
  465. key : char;
  466. idcmp, vanil : Longint;
  467. begin
  468. key := #0;
  469. if KeyPress <> #0 then
  470. Begin
  471. ReadKey:=KeyPress;
  472. KeyPress:=#0;
  473. exit;
  474. end;
  475. info := OpenInfo;
  476. if info <> nil then begin
  477. win := pWindow(pConUnit((pIoStdReq(info^.id_InUse))^.io_Unit)^.cu_Window);
  478. idcmp := win^.IDCMPFlags;
  479. vanil := IDCMP_VANILLAKEY or IDCMP_RAWKEY;
  480. ModifyIDCMP(win, (idcmp or vanil));
  481. repeat
  482. msg := WaitPort(win^.UserPort);
  483. imsg := pIntuiMessage(GetMsg(win^.UserPort));
  484. if (imsg^.IClass = IDCMP_VANILLAKEY) then
  485. key := char(imsg^.Code)
  486. else
  487. if (imsg^.IClass = IDCMP_RAWKEY) then
  488. key := char(imsg^.Code);
  489. ReplyMsg(pMessage(imsg));
  490. until key <> #0;
  491. repeat
  492. msg := GetMsg(win^.UserPort);
  493. if msg <> nil then ReplyMsg(msg);
  494. until msg = nil;
  495. ModifyIDCMP(win, idcmp);
  496. CloseInfo(info);
  497. end;
  498. ReadKey := key;
  499. end;
  500. function KeyPressed : Boolean;
  501. const
  502. IDCMP_VANILLAKEY = $00200000;
  503. IDCMP_RAWKEY = $00000400;
  504. var
  505. info : pInfoData;
  506. win : pWindow;
  507. imsg : pIntuiMessage;
  508. msg : pMessage;
  509. idcmp, vanil : Longint;
  510. ispressed : Boolean;
  511. begin
  512. KeyPress := #0;
  513. ispressed := False;
  514. info := OpenInfo;
  515. if info <> nil then begin
  516. win := pWindow(pConUnit((pIoStdReq(info^.id_InUse))^.io_Unit)^.cu_Window);
  517. idcmp := win^.IDCMPFlags;
  518. vanil := IDCMP_VANILLAKEY or IDCMP_RAWKEY;
  519. ModifyIDCMP(win, (idcmp or vanil));
  520. msg := WaitPort(win^.UserPort);
  521. imsg := pIntuiMessage(GetMsg(win^.UserPort));
  522. if (imsg^.IClass = IDCMP_VANILLAKEY) or (imsg^.IClass = IDCMP_RAWKEY) then
  523. Begin
  524. ispressed := true;
  525. KeyPress := char(imsg^.Code)
  526. end;
  527. ReplyMsg(pMessage(imsg));
  528. repeat
  529. msg := GetMsg(win^.UserPort);
  530. if msg <> nil then ReplyMsg(msg);
  531. until msg = nil;
  532. ModifyIDCMP(win, idcmp);
  533. CloseInfo(info);
  534. end;
  535. KeyPressed := ispressed;
  536. end;
  537. procedure TextColor(color : byte);
  538. begin
  539. TextAttr := (TextAttr and $70) or color;
  540. Write(CSI, '3', color, 'm');
  541. end;
  542. procedure TextBackground(color : byte);
  543. begin
  544. Textattr:=(textattr and $8f) or ((color and $7) shl 4);
  545. Write(CSI, '4', color, 'm');
  546. end;
  547. procedure Window(X1,Y1,X2,Y2: Byte);
  548. begin
  549. if (x1<1) or (x2>screencols) or (y2>screenrows) or
  550. (x1>x2) or (y1>y2) then
  551. exit;
  552. windmin:=(x1-1) or ((y1-1) shl 8);
  553. windmax:=(x2-1) or ((y2-1) shl 8);
  554. gotoxy(1,1);
  555. end;
  556. procedure DelLine;
  557. begin
  558. Write(CSI,'X');
  559. end;
  560. procedure ClrEol;
  561. begin
  562. Write(CSI,'K');
  563. end;
  564. procedure InsLine;
  565. begin
  566. Write(CSI,'1 L');
  567. end;
  568. procedure cursorbig;
  569. begin
  570. end;
  571. procedure lowvideo;
  572. begin
  573. end;
  574. procedure highvideo;
  575. begin
  576. end;
  577. procedure nosound;
  578. begin
  579. end;
  580. procedure sound(hz : word);
  581. begin
  582. end;
  583. procedure delay(DTime : Word);
  584. var
  585. dummy : Longint;
  586. begin
  587. dummy := trunc((real(DTime) / 1000.0) * 50.0);
  588. Delay_(dummy);
  589. end;
  590. function CheckBreak : boolean;
  591. begin
  592. if (SetSignal(0, 0) and SIGBREAKF_CTRL_C) = SIGBREAKF_CTRL_C then
  593. CheckBreak := true
  594. else
  595. CheckBreak := false;
  596. end;
  597. procedure textmode(mode : integer);
  598. begin
  599. lastmode:=mode;
  600. mode:=mode and $ff;
  601. windmin:=0;
  602. windmax:=(screencols-1) or ((screenrows-1) shl 8);
  603. maxcols:=screencols;
  604. maxrows:=screenrows;
  605. end;
  606. procedure normvideo;
  607. begin
  608. end;
  609. function GetTextBackground : byte;
  610. var
  611. info : pInfoData;
  612. pen : byte;
  613. begin
  614. pen := 1;
  615. info := OpenInfo;
  616. if info <> nil then begin
  617. pen := pConUnit((pIoStdReq(info^.id_InUse))^.io_Unit)^.cu_BgPen;
  618. CloseInfo(info);
  619. end;
  620. GetTextBackground := pen;
  621. end;
  622. function GetTextColor : byte;
  623. var
  624. info : pInfoData;
  625. pen : byte;
  626. begin
  627. pen := 1;
  628. info := OpenInfo;
  629. if info <> nil then begin
  630. pen := pConUnit((pIoStdReq(info^.id_InUse))^.io_Unit)^.cu_FgPen;
  631. CloseInfo(info);
  632. end;
  633. GetTextColor := pen;
  634. end;
  635. {*****************************************************************************
  636. Read and Write routines
  637. *****************************************************************************}
  638. { Problem here: Currently all these routines are not implemented because of how }
  639. { the console device works. Because w low level write is required to change the }
  640. { position of the cursor, and since the CrtWrite is assigned as the standard }
  641. { write routine, a recursive call will occur }
  642. { How to fix this: }
  643. { At startup make a copy of the Output handle, and then use this copy to make }
  644. { low level positioning calls. This does not seem to work yet. }
  645. Function CrtWrite(var f : textrec):integer;
  646. var
  647. i,col,row : longint;
  648. c : char;
  649. buf: array[0..1] of char;
  650. begin
  651. col:=realx;
  652. row:=realy;
  653. inc(row);
  654. inc(col);
  655. for i:=0 to f.bufpos-1 do
  656. begin
  657. c:=f.buffer[i];
  658. case ord(c) of
  659. 10 : begin
  660. inc(row);
  661. end;
  662. 13 : begin
  663. col:=lo(windmin)+1;
  664. end;
  665. 8 : if col>lo(windmin)+1 then
  666. begin
  667. dec(col);
  668. end;
  669. 7 : begin
  670. { beep }
  671. asm
  672. move.l a6,d6 { save base pointer }
  673. move.l _IntuitionBase,a6 { set library base }
  674. sub.l a0,a0
  675. jsr _LVODisplayBeep(a6)
  676. move.l d6,a6 { restore base pointer }
  677. end;
  678. end;
  679. else
  680. begin
  681. buf[0]:=c;
  682. realgotoxy(row,col);
  683. do_write(f.handle,longint(@buf[0]),1);
  684. inc(col);
  685. end;
  686. end;
  687. if col>lo(windmax)+1 then
  688. begin
  689. col:=lo(windmin)+1;
  690. inc(row);
  691. end;
  692. while row>hi(windmax)+1 do
  693. begin
  694. delline;
  695. dec(row);
  696. end;
  697. end;
  698. f.bufpos:=0;
  699. realgotoxy(row-1,col-1);
  700. CrtWrite:=0;
  701. end;
  702. Function CrtClose(Var F: TextRec): Integer;
  703. Begin
  704. F.Mode:=fmClosed;
  705. CrtClose:=0;
  706. End;
  707. Function CrtOpen(Var F: TextRec): Integer;
  708. Begin
  709. If F.Mode = fmOutput Then
  710. CrtOpen:=0
  711. Else
  712. CrtOpen:=5;
  713. End;
  714. Function CrtRead(Var F: TextRec): Integer;
  715. Begin
  716. f.bufend:=do_read(f.handle,longint(f.bufptr),f.bufsize);
  717. f.bufpos:=0;
  718. CrtRead:=0;
  719. End;
  720. Function CrtInOut(Var F: TextRec): Integer;
  721. Begin
  722. Case F.Mode of
  723. fmInput: CrtInOut:=CrtRead(F);
  724. fmOutput: CrtInOut:=CrtWrite(F);
  725. End;
  726. End;
  727. procedure assigncrt(var f : text);
  728. begin
  729. { TextRec(F).Mode:=fmClosed;
  730. TextRec(F).BufSize:=SizeOf(TextBuf);
  731. TextRec(F).BufPtr:=@TextRec(F).Buffer;
  732. TextRec(F).BufPos:=0;
  733. TextRec(F).OpenFunc:=@CrtOpen;
  734. TextRec(F).InOutFunc:=@CrtInOut;
  735. TextRec(F).FlushFunc:=@CrtInOut;
  736. TextRec(F).CloseFunc:=@CrtClose;
  737. TextRec(F).Name[0]:='.';
  738. TextRec(F).Name[1]:=#0;}
  739. end;
  740. var
  741. old_exit : pointer;
  742. procedure crt_exit;
  743. begin
  744. { Restore default colors }
  745. write(CSI,'0m');
  746. exitproc:=old_exit;
  747. end;
  748. Begin
  749. old_exit:=exitproc;
  750. exitproc:=@crt_exit;
  751. { load system variables to temporary variables to save time }
  752. maxcols:=screencols;
  753. maxrows:=screenrows;
  754. { Set the initial text attributes }
  755. { Text background }
  756. Textattr:=(textattr and $8f) or ((GetTextBackGround and $7) shl 4);
  757. { Text foreground }
  758. TextAttr := (TextAttr and $70) or GetTextColor;
  759. { set output window }
  760. windmax:=(maxcols-1) or (( maxrows-1) shl 8);
  761. { Get a copy of the standard }
  762. { output handle, and when using }
  763. { direct console calls, use this }
  764. { handle instead. }
  765. { assigncrt(Output);
  766. TextRec(Output).mode:=fmOutput;}
  767. end.