crt.pp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 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. IClass : 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. const
  244. M_LNM = 20; { linefeed newline mode }
  245. PMB_ASM = M_LNM + 1; { internal storage bit for AS flag }
  246. PMB_AWM = PMB_ASM + 1; { internal storage bit for AW flag }
  247. MAXTABS = 80;
  248. IECLASS_MAX = $15;
  249. type
  250. pKeyMap = ^tKeyMap;
  251. tKeyMap = packed record
  252. km_LoKeyMapTypes : Pointer;
  253. km_LoKeyMap : Pointer;
  254. km_LoCapsable : Pointer;
  255. km_LoRepeatable : Pointer;
  256. km_HiKeyMapTypes : Pointer;
  257. km_HiKeyMap : Pointer;
  258. km_HiCapsable : Pointer;
  259. km_HiRepeatable : Pointer;
  260. end;
  261. pConUnit = ^tConUnit;
  262. tConUnit = packed record
  263. cu_MP : tMsgPort;
  264. { ---- read only variables }
  265. cu_Window : Pointer; { (WindowPtr) intuition window bound to this unit }
  266. cu_XCP : Integer; { character position }
  267. cu_YCP : Integer;
  268. cu_XMax : Integer; { max character position }
  269. cu_YMax : Integer;
  270. cu_XRSize : Integer; { character raster size }
  271. cu_YRSize : Integer;
  272. cu_XROrigin : Integer; { raster origin }
  273. cu_YROrigin : Integer;
  274. cu_XRExtant : Integer; { raster maxima }
  275. cu_YRExtant : Integer;
  276. cu_XMinShrink : Integer; { smallest area intact from resize process }
  277. cu_YMinShrink : Integer;
  278. cu_XCCP : Integer; { cursor position }
  279. cu_YCCP : Integer;
  280. { ---- read/write variables (writes must must be protected) }
  281. { ---- storage for AskKeyMap and SetKeyMap }
  282. cu_KeyMapStruct : tKeyMap;
  283. { ---- tab stops }
  284. cu_TabStops : Array [0..MAXTABS-1] of Word;
  285. { 0 at start, -1 at end of list }
  286. { ---- console rastport attributes }
  287. cu_Mask : Shortint;
  288. cu_FgPen : Shortint;
  289. cu_BgPen : Shortint;
  290. cu_AOLPen : Shortint;
  291. cu_DrawMode : Shortint;
  292. cu_AreaPtSz : Shortint;
  293. cu_AreaPtrn : Pointer; { cursor area pattern }
  294. cu_Minterms : Array [0..7] of Byte; { console minterms }
  295. cu_Font : Pointer; { (TextFontPtr) }
  296. cu_AlgoStyle : Byte;
  297. cu_TxFlags : Byte;
  298. cu_TxHeight : Word;
  299. cu_TxWidth : Word;
  300. cu_TxBaseline : Word;
  301. cu_TxSpacing : Word;
  302. { ---- console MODES and RAW EVENTS switches }
  303. cu_Modes : Array [0..(PMB_AWM+7) div 8 - 1] of Byte;
  304. { one bit per mode }
  305. cu_RawEvents : Array [0..(IECLASS_MAX+7) div 8 - 1] of Byte;
  306. end;
  307. const
  308. CD_CURRX = 1;
  309. CD_CURRY = 2;
  310. CD_MAXX = 3;
  311. CD_MAXY = 4;
  312. CSI = chr($9b);
  313. SIGBREAKF_CTRL_C = 4096;
  314. function AllocVec( size, reqm : Longint ): Pointer;
  315. begin
  316. asm
  317. MOVE.L A6,-(A7)
  318. MOVE.L size,d0
  319. MOVE.L reqm,d1
  320. MOVE.L _ExecBase, A6
  321. JSR -684(A6)
  322. MOVE.L (A7)+,A6
  323. MOVE.L d0,@RESULT
  324. end;
  325. end;
  326. function DoPkt(ID : pMsgPort;
  327. Action, Param1, Param2,
  328. Param3, Param4, Param5 : Longint) : Longint;
  329. begin
  330. asm
  331. MOVEM.L d2/d3/d4/d5/d6/d7/a6,-(A7)
  332. MOVE.L ID,d1
  333. MOVE.L Action,d2
  334. MOVE.L Param1,d3
  335. MOVE.L Param2,d4
  336. MOVE.L Param3,d5
  337. MOVE.L Param4,d6
  338. MOVE.L Param5,d7
  339. MOVE.L _DOSBase,A6
  340. JSR -240(A6)
  341. MOVEM.L (A7)+,d2/d3/d4/d5/d6/d7/a6
  342. MOVE.L d0,@RESULT
  343. end;
  344. end;
  345. procedure FreeVec( memory : Pointer );
  346. begin
  347. asm
  348. MOVE.L A6,-(A7)
  349. MOVE.L memory,a1
  350. MOVE.L _ExecBase,A6
  351. JSR -690(A6)
  352. MOVE.L (A7)+,A6
  353. end;
  354. end;
  355. function GetConsoleTask : pMsgPort;
  356. begin
  357. asm
  358. MOVE.L A6,-(A7)
  359. MOVE.L _DOSBase,A6
  360. JSR -510(A6)
  361. MOVE.L (A7)+,A6
  362. MOVE.L d0,@RESULT
  363. end;
  364. end;
  365. function GetMsg(port : pMsgPort): pMessage;
  366. begin
  367. asm
  368. MOVE.L A6,-(A7)
  369. MOVE.L port,a0
  370. MOVE.L _ExecBase,A6
  371. JSR -372(A6)
  372. MOVE.L (A7)+,A6
  373. MOVE.L d0,@RESULT
  374. end;
  375. end;
  376. function ModifyIDCMP(window : pWindow;
  377. IDCMPFlags : Longint) : Boolean;
  378. begin
  379. asm
  380. MOVE.L A6,-(A7)
  381. MOVE.L window,a0
  382. MOVE.L IDCMPFlags,d0
  383. MOVE.L _IntuitionBase,A6
  384. JSR -150(A6)
  385. MOVE.L (A7)+,A6
  386. TST.L d0
  387. bne @success
  388. bra @end
  389. @success:
  390. move.b #1,d0
  391. @end:
  392. move.b d0,@RESULT
  393. end;
  394. end;
  395. procedure ReplyMsg(mess : pMessage);
  396. begin
  397. asm
  398. MOVE.L A6,-(A7)
  399. MOVE.L mess,a1
  400. MOVE.L _ExecBase,A6
  401. JSR -378(A6)
  402. MOVE.L (A7)+,A6
  403. end;
  404. end;
  405. function WaitPort(port : pMsgPort): pMessage;
  406. begin
  407. asm
  408. MOVE.L A6,-(A7)
  409. MOVE.L port,a0
  410. MOVE.L _ExecBase,A6
  411. JSR -384(A6)
  412. MOVE.L (A7)+,A6
  413. MOVE.L d0,@RESULT
  414. end;
  415. end;
  416. procedure Delay_(ticks : Longint);
  417. begin
  418. asm
  419. MOVE.L A6,-(A7)
  420. MOVE.L ticks,d1
  421. MOVE.L _DOSBase,A6
  422. JSR -198(A6)
  423. MOVE.L (A7)+,A6
  424. end;
  425. end;
  426. function SetSignal(newSignals, signalMask : Longint) : Longint;
  427. begin
  428. asm
  429. MOVE.L A6,-(A7)
  430. MOVE.L newSignals,d0
  431. MOVE.L signalMask,d1
  432. MOVE.L _ExecBase,A6
  433. JSR -306(A6)
  434. MOVE.L (A7)+,A6
  435. MOVE.L d0,@RESULT
  436. end;
  437. end;
  438. function OpenInfo : pInfoData;
  439. var
  440. port : pMsgPort;
  441. info : pInfoData;
  442. bptr, d4, d5, d6, d7 : Longint;
  443. begin
  444. info := pInfoData(AllocVec(SizeOf(tInfoData), 1));
  445. if info <> nil then begin
  446. port := GetConsoleTask;
  447. bptr := Longint(info) shr 2;
  448. if port <> nil then begin
  449. if DoPkt(port, $19, bptr, d4, d5, d6, d7) <> 0 then info := pInfoData(bptr shl 2)
  450. else port := nil;
  451. end;
  452. if port = nil then begin
  453. FreeVec(info);
  454. info := nil;
  455. end;
  456. end;
  457. OpenInfo := info;
  458. end;
  459. procedure CloseInfo(var info : pInfoData);
  460. begin
  461. if info <> nil then begin
  462. FreeVec(info);
  463. info := nil;
  464. end;
  465. end;
  466. function ConData(modus : byte) : integer;
  467. var
  468. info : pInfoData;
  469. theunit : pConUnit;
  470. pos : Longint;
  471. begin
  472. pos := 1;
  473. info := OpenInfo;
  474. if info <> nil then begin
  475. theunit := pConUnit((pIoStdReq(info^.id_InUse))^.io_Unit);
  476. case modus of
  477. CD_CURRX : pos := theunit^.cu_XCP;
  478. CD_CURRY : pos := theunit^.cu_YCP;
  479. CD_MAXX : pos := theunit^.cu_XMax;
  480. CD_MAXY : pos := theunit^.cu_YMax;
  481. end;
  482. CloseInfo(info);
  483. end;
  484. ConData := pos + 1;
  485. end;
  486. function WhereX : Byte;
  487. begin
  488. WhereX := Byte(ConData(CD_CURRX))-lo(windmin);
  489. end;
  490. function realx: byte;
  491. begin
  492. RealX := Byte(ConData(CD_CURRX));
  493. end;
  494. function realy: byte;
  495. begin
  496. RealY := Byte(ConData(CD_CURRY));
  497. end;
  498. function WhereY : Byte;
  499. begin
  500. WhereY := Byte(ConData(CD_CURRY))-hi(windmin);
  501. end;
  502. function screencols : integer;
  503. begin
  504. screencols := ConData(CD_MAXX);
  505. end;
  506. function screenrows : integer;
  507. begin
  508. screenrows := ConData(CD_MAXY);
  509. end;
  510. procedure Realgotoxy(x,y : integer);
  511. begin
  512. Write(CSI, y, ';', x, 'H');
  513. end;
  514. procedure gotoxy(x,y : byte);
  515. begin
  516. if (x<1) then
  517. x:=1;
  518. if (y<1) then
  519. y:=1;
  520. if y+hi(windmin)-2>=hi(windmax) then
  521. y:=hi(windmax)-hi(windmin)+1;
  522. if x+lo(windmin)-2>=lo(windmax) then
  523. x:=lo(windmax)-lo(windmin)+1;
  524. Write(CSI, y+hi(windmin), ';', x+lo(windmin), 'H');
  525. end;
  526. procedure CursorOff;
  527. begin
  528. Write(CSI,'0 p');
  529. end;
  530. procedure CursorOn;
  531. begin
  532. Write(CSI,'1 p');
  533. end;
  534. procedure ClrScr;
  535. begin
  536. Write(Chr($0c));
  537. end;
  538. function ReadKey : char;
  539. const
  540. IDCMP_VANILLAKEY = $00200000;
  541. IDCMP_RAWKEY = $00000400;
  542. var
  543. info : pInfoData;
  544. win : pWindow;
  545. imsg : pIntuiMessage;
  546. msg : pMessage;
  547. key : char;
  548. idcmp, vanil : Longint;
  549. begin
  550. key := #0;
  551. if KeyPress <> #0 then
  552. Begin
  553. ReadKey:=KeyPress;
  554. KeyPress:=#0;
  555. exit;
  556. end;
  557. info := OpenInfo;
  558. if info <> nil then begin
  559. win := pWindow(pConUnit((pIoStdReq(info^.id_InUse))^.io_Unit)^.cu_Window);
  560. idcmp := win^.IDCMPFlags;
  561. vanil := IDCMP_VANILLAKEY or IDCMP_RAWKEY;
  562. ModifyIDCMP(win, (idcmp or vanil));
  563. repeat
  564. msg := WaitPort(win^.UserPort);
  565. imsg := pIntuiMessage(GetMsg(win^.UserPort));
  566. if (imsg^.IClass = IDCMP_VANILLAKEY) then
  567. key := char(imsg^.Code)
  568. else
  569. if (imsg^.IClass = IDCMP_RAWKEY) then
  570. key := char(imsg^.Code);
  571. ReplyMsg(pMessage(imsg));
  572. until key <> #0;
  573. repeat
  574. msg := GetMsg(win^.UserPort);
  575. if msg <> nil then ReplyMsg(msg);
  576. until msg = nil;
  577. ModifyIDCMP(win, idcmp);
  578. CloseInfo(info);
  579. end;
  580. ReadKey := key;
  581. end;
  582. function KeyPressed : Boolean;
  583. const
  584. IDCMP_VANILLAKEY = $00200000;
  585. IDCMP_RAWKEY = $00000400;
  586. var
  587. info : pInfoData;
  588. win : pWindow;
  589. imsg : pIntuiMessage;
  590. msg : pMessage;
  591. idcmp, vanil : Longint;
  592. ispressed : Boolean;
  593. begin
  594. KeyPress := #0;
  595. ispressed := False;
  596. info := OpenInfo;
  597. if info <> nil then begin
  598. win := pWindow(pConUnit((pIoStdReq(info^.id_InUse))^.io_Unit)^.cu_Window);
  599. idcmp := win^.IDCMPFlags;
  600. vanil := IDCMP_VANILLAKEY or IDCMP_RAWKEY;
  601. ModifyIDCMP(win, (idcmp or vanil));
  602. msg := WaitPort(win^.UserPort);
  603. imsg := pIntuiMessage(GetMsg(win^.UserPort));
  604. if (imsg^.IClass = IDCMP_VANILLAKEY) or (imsg^.IClass = IDCMP_RAWKEY) then
  605. Begin
  606. ispressed := true;
  607. KeyPress := char(imsg^.Code)
  608. end;
  609. ReplyMsg(pMessage(imsg));
  610. repeat
  611. msg := GetMsg(win^.UserPort);
  612. if msg <> nil then ReplyMsg(msg);
  613. until msg = nil;
  614. ModifyIDCMP(win, idcmp);
  615. CloseInfo(info);
  616. end;
  617. KeyPressed := ispressed;
  618. end;
  619. procedure TextColor(color : byte);
  620. begin
  621. TextAttr := (TextAttr and $70) or color;
  622. Write(CSI, '3', color, 'm');
  623. end;
  624. procedure TextBackground(color : byte);
  625. begin
  626. Textattr:=(textattr and $8f) or ((color and $7) shl 4);
  627. Write(CSI, '4', color, 'm');
  628. end;
  629. procedure Window(X1,Y1,X2,Y2: Byte);
  630. begin
  631. if (x1<1) or (x2>screencols) or (y2>screenrows) or
  632. (x1>x2) or (y1>y2) then
  633. exit;
  634. windmin:=(x1-1) or ((y1-1) shl 8);
  635. windmax:=(x2-1) or ((y2-1) shl 8);
  636. gotoxy(1,1);
  637. end;
  638. procedure DelLine;
  639. begin
  640. Write(CSI,'X');
  641. end;
  642. procedure ClrEol;
  643. begin
  644. Write(CSI,'K');
  645. end;
  646. procedure InsLine;
  647. begin
  648. Write(CSI,'1 L');
  649. end;
  650. procedure cursorbig;
  651. begin
  652. end;
  653. procedure lowvideo;
  654. begin
  655. end;
  656. procedure highvideo;
  657. begin
  658. end;
  659. procedure nosound;
  660. begin
  661. end;
  662. procedure sound(hz : word);
  663. begin
  664. end;
  665. procedure delay(DTime : Word);
  666. var
  667. dummy : Longint;
  668. begin
  669. dummy := trunc((real(DTime) / 1000.0) * 50.0);
  670. Delay_(dummy);
  671. end;
  672. function CheckBreak : boolean;
  673. begin
  674. if (SetSignal(0, 0) and SIGBREAKF_CTRL_C) = SIGBREAKF_CTRL_C then
  675. CheckBreak := true
  676. else
  677. CheckBreak := false;
  678. end;
  679. procedure textmode(mode : integer);
  680. begin
  681. lastmode:=mode;
  682. mode:=mode and $ff;
  683. windmin:=0;
  684. windmax:=(screencols-1) or ((screenrows-1) shl 8);
  685. maxcols:=screencols;
  686. maxrows:=screenrows;
  687. end;
  688. procedure normvideo;
  689. begin
  690. end;
  691. function GetTextBackground : byte;
  692. var
  693. info : pInfoData;
  694. pen : byte;
  695. begin
  696. pen := 1;
  697. info := OpenInfo;
  698. if info <> nil then begin
  699. pen := pConUnit((pIoStdReq(info^.id_InUse))^.io_Unit)^.cu_BgPen;
  700. CloseInfo(info);
  701. end;
  702. GetTextBackground := pen;
  703. end;
  704. function GetTextColor : byte;
  705. var
  706. info : pInfoData;
  707. pen : byte;
  708. begin
  709. pen := 1;
  710. info := OpenInfo;
  711. if info <> nil then begin
  712. pen := pConUnit((pIoStdReq(info^.id_InUse))^.io_Unit)^.cu_FgPen;
  713. CloseInfo(info);
  714. end;
  715. GetTextColor := pen;
  716. end;
  717. {*****************************************************************************
  718. Read and Write routines
  719. *****************************************************************************}
  720. { Problem here: Currently all these routines are not implemented because of how }
  721. { the console device works. Because w low level write is required to change the }
  722. { position of the cursor, and since the CrtWrite is assigned as the standard }
  723. { write routine, a recursive call will occur }
  724. { How to fix this: }
  725. { At startup make a copy of the Output handle, and then use this copy to make }
  726. { low level positioning calls. This does not seem to work yet. }
  727. Function CrtWrite(var f : textrec):integer;
  728. var
  729. i,col,row : longint;
  730. c : char;
  731. buf: array[0..1] of char;
  732. begin
  733. col:=realx;
  734. row:=realy;
  735. inc(row);
  736. inc(col);
  737. for i:=0 to f.bufpos-1 do
  738. begin
  739. c:=f.buffer[i];
  740. case ord(c) of
  741. 10 : begin
  742. inc(row);
  743. end;
  744. 13 : begin
  745. col:=lo(windmin)+1;
  746. end;
  747. 8 : if col>lo(windmin)+1 then
  748. begin
  749. dec(col);
  750. end;
  751. 7 : begin
  752. { beep }
  753. asm
  754. move.l a6,d6 { save base pointer }
  755. move.l _IntuitionBase,a6 { set library base }
  756. sub.l a0,a0
  757. jsr _LVODisplayBeep(a6)
  758. move.l d6,a6 { restore base pointer }
  759. end;
  760. end;
  761. else
  762. begin
  763. buf[0]:=c;
  764. realgotoxy(row,col);
  765. do_write(f.handle,longint(@buf[0]),1);
  766. inc(col);
  767. end;
  768. end;
  769. if col>lo(windmax)+1 then
  770. begin
  771. col:=lo(windmin)+1;
  772. inc(row);
  773. end;
  774. while row>hi(windmax)+1 do
  775. begin
  776. delline;
  777. dec(row);
  778. end;
  779. end;
  780. f.bufpos:=0;
  781. realgotoxy(row-1,col-1);
  782. CrtWrite:=0;
  783. end;
  784. Function CrtClose(Var F: TextRec): Integer;
  785. Begin
  786. F.Mode:=fmClosed;
  787. CrtClose:=0;
  788. End;
  789. Function CrtOpen(Var F: TextRec): Integer;
  790. Begin
  791. If F.Mode = fmOutput Then
  792. CrtOpen:=0
  793. Else
  794. CrtOpen:=5;
  795. End;
  796. Function CrtRead(Var F: TextRec): Integer;
  797. Begin
  798. f.bufend:=do_read(f.handle,longint(f.bufptr),f.bufsize);
  799. f.bufpos:=0;
  800. CrtRead:=0;
  801. End;
  802. Function CrtInOut(Var F: TextRec): Integer;
  803. Begin
  804. Case F.Mode of
  805. fmInput: CrtInOut:=CrtRead(F);
  806. fmOutput: CrtInOut:=CrtWrite(F);
  807. End;
  808. End;
  809. procedure assigncrt(var f : text);
  810. begin
  811. { TextRec(F).Mode:=fmClosed;
  812. TextRec(F).BufSize:=SizeOf(TextBuf);
  813. TextRec(F).BufPtr:=@TextRec(F).Buffer;
  814. TextRec(F).BufPos:=0;
  815. TextRec(F).OpenFunc:=@CrtOpen;
  816. TextRec(F).InOutFunc:=@CrtInOut;
  817. TextRec(F).FlushFunc:=@CrtInOut;
  818. TextRec(F).CloseFunc:=@CrtClose;
  819. TextRec(F).Name[0]:='.';
  820. TextRec(F).Name[1]:=#0;}
  821. end;
  822. var
  823. old_exit : pointer;
  824. procedure crt_exit;
  825. begin
  826. { Restore default colors }
  827. write(CSI,'0m');
  828. exitproc:=old_exit;
  829. end;
  830. Begin
  831. old_exit:=exitproc;
  832. exitproc:=@crt_exit;
  833. { load system variables to temporary variables to save time }
  834. maxcols:=screencols;
  835. maxrows:=screenrows;
  836. { Set the initial text attributes }
  837. { Text background }
  838. Textattr:=(textattr and $8f) or ((GetTextBackGround and $7) shl 4);
  839. { Text foreground }
  840. TextAttr := (TextAttr and $70) or GetTextColor;
  841. { set output window }
  842. windmax:=(maxcols-1) or (( maxrows-1) shl 8);
  843. { Get a copy of the standard }
  844. { output handle, and when using }
  845. { direct console calls, use this }
  846. { handle instead. }
  847. { assigncrt(Output);
  848. TextRec(Output).mode:=fmOutput;}
  849. end.
  850. $Log$
  851. Revision 1.3 2002-09-07 16:01:16 peter
  852. * old logs removed and tabs fixed
  853. }