crt.pp 24 KB

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