3 This file is part of the Free Pascal run time library
.
4 Copyright (c
) 1999-2000 by Nils Sjoholm
and Carl Eric Codere
6 See the file COPYING
.FPC
, included
in this distribution
,
7 for details about the copyright
.
9 This program is distributed
in the hope that it will be useful
,
10 but WITHOUT ANY WARRANTY
; without even the implied warranty of
11 MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE
.
13 **********************************************************************}
18 {--------------------------------------------------------------------}
20 {--------------------------------------------------------------------}
21 { o Write special characters are
not recognized
}
22 { o Write does
not take care of window coordinates yet
. }
23 { o Read does
not recognize the special editing characters
}
24 { o Read does
not take care of window coordinates yet
. }
25 { o Readkey extended scancode is
not correct yet
}
26 { o Color mapping only works
for 4 colours
}
27 { o ClrScr
, DeleteLine
, InsLine
do not work with window coordinates
}
28 {--------------------------------------------------------------------}
35 { Controlling consts
}
36 Flushing
=false; {if true then don
't buffer output}
41 BW40 = 0; { 40x25 B/W on Color Adapter }
42 CO40 = 1; { 40x25 Color on Color Adapter }
43 BW80 = 2; { 80x25 B/W on Color Adapter }
44 CO80 = 3; { 80x25 Color on Color Adapter }
45 Mono = 7; { 80x25 on Monochrome Adapter }
46 Font8x8 = 256; { Add-in for ROM font }
48 { Mode constants for 3.0 compatibility }
53 When using this color constants on the Amiga
54 you can bet that they don't work as expected
.
55 You never know what color the user has on
56 his Amiga
. Perhaps we should
do a check of
57 the number of
bitplanes (for number of colors
)
59 The normal
4 first pens
for an Amiga are
68 { Foreground
and background color constants
}
69 Black
= 1; { normal pen
for amiga
}
70 Blue
= 3; { windowborder color
}
76 LightGray
= 0; { canvas color
}
78 { Foreground color constants
}
86 White
= 2; { third color on amiga
}
88 { Add-in
for blinking
}
94 WindMax
: Word
= $184f;
95 { These don
't change anything if they are modified }
96 CheckSnow : Boolean = FALSE;
97 DirectVideo: Boolean = FALSE;
100 { CheckBreak have to make this one to a function for Amiga }
103 Procedure AssignCrt(Var F: Text);
104 Function KeyPressed: Boolean;
105 Function ReadKey: Char;
106 Procedure TextMode(Mode: Integer);
107 Procedure Window(X1, Y1, X2, Y2: BYTE);
108 Procedure GoToXy(X: byte; Y: byte);
109 Function WhereX: Byte;
110 Function WhereY: Byte;
115 Procedure TextColor(Color: Byte);
116 Procedure TextBackground(Color: Byte);
120 Procedure Delay(DTime: Word);
121 Procedure Sound(Hz: Word);
128 Function CheckBreak: Boolean;
133 The definitions of TextRec and FileRec are in separate files.
139 maxcols,maxrows : longint;
142 { This is used to make sure that readkey returns immediately }
143 { if keypressed was used beforehand. }
144 KeyPress : char = #0;
145 _LVODisplayBeep = -96;
150 pInfoData = ^tInfoData;
151 tInfoData = packed record
152 id_NumSoftErrors : Longint; { number of soft errors on disk }
153 id_UnitNumber : Longint; { Which unit disk is (was) mounted on }
154 id_DiskState : Longint; { See defines below }
155 id_NumBlocks : Longint; { Number of blocks on disk }
156 id_NumBlocksUsed : Longint; { Number of block in use }
157 id_BytesPerBlock : Longint;
158 id_DiskType : Longint; { Disk Type code }
159 id_VolumeNode : Longint; { BCPL pointer to volume node }
160 id_InUse : Longint; { Flag, zero if not in use }
163 { * List Node Structure. Each member in a list starts with a Node * }
166 tNode = packed Record
167 ln_Succ, { * Pointer to next (successor) * }
168 ln_Pred : pNode; { * Pointer to previous (predecessor) * }
170 ln_Pri : Shortint; { * Priority, for sorting * }
171 ln_Name : PChar; { * ID string, null terminated * }
172 End; { * Note: Integer aligned * }
174 { normal, full featured list }
177 tList = packed record
185 pMsgPort = ^tMsgPort;
186 tMsgPort = packed record
189 mp_SigBit : Byte; { signal bit number }
190 mp_SigTask : Pointer; { task to be signalled (TaskPtr) }
191 mp_MsgList : tList; { message linked list }
194 pMessage = ^tMessage;
195 tMessage = packed record
197 mn_ReplyPort : pMsgPort; { message reply port }
198 mn_Length : Word; { message len in bytes }
201 pIOStdReq = ^tIOStdReq;
202 tIOStdReq = packed record
203 io_Message : tMessage;
204 io_Device : Pointer; { device node pointer }
205 io_Unit : Pointer; { unit (driver private)}
206 io_Command : Word; { device command }
208 io_Error : Shortint; { error or warning num }
209 io_Actual : Longint; { actual number of bytes transferred }
210 io_Length : Longint; { requested number bytes transferred}
211 io_Data : Pointer; { points to data area }
212 io_Offset : Longint; { offset for block structured devices }
215 pIntuiMessage = ^tIntuiMessage;
216 tIntuiMessage = packed record
217 ExecMessage : tMessage;
226 IDCMPWindow : Pointer;
227 SpecialLink : pIntuiMessage;
231 tWindow = packed record
232 NextWindow : pWindow; { for the linked list in a screen }
234 TopEdge : Integer; { screen dimensions of window }
236 Height : Integer; { screen dimensions of window }
238 MouseX : Integer; { relative to upper-left of window }
240 MinHeight : Integer; { minimum sizes }
242 MaxHeight : Word; { maximum sizes }
243 Flags : Longint; { see below for defines }
244 MenuStrip : Pointer; { the strip of Menu headers }
245 Title : PChar; { the title text for this window }
246 FirstRequest : Pointer; { all active Requesters }
247 DMRequest : Pointer; { double-click Requester }
248 ReqCount : Integer; { count of reqs blocking Window }
249 WScreen : Pointer; { this Window's Screen
}
250 RPort
: Pointer
; { this Window
's very own RastPort }
254 BorderBottom : Shortint;
255 BorderRPort : Pointer;
256 FirstGadget : Pointer;
258 Descendant : pWindow;
259 Pointer_ : Pointer; { sprite data }
260 PtrHeight : Shortint; { sprite height (not including sprite padding) }
261 PtrWidth : Shortint; { sprite width (must be less than or equal to 16) }
263 YOffset : Shortint; { sprite offsets }
264 IDCMPFlags : Longint; { User-selected flags }
266 WindowPort : pMsgPort;
267 MessageKey : pIntuiMessage;
269 BlockPen : Byte; { for bar/border/gadget rendering }
271 ScreenTitle : PChar; { if non-null, Screen title when Window is active }
277 UserData : Pointer; { general-purpose pointer to User data extension }
285 M_LNM = 20; { linefeed newline mode }
286 PMB_ASM = M_LNM + 1; { internal storage bit for AS flag }
287 PMB_AWM = PMB_ASM + 1; { internal storage bit for AW flag }
294 tKeyMap = packed record
295 km_LoKeyMapTypes : Pointer;
296 km_LoKeyMap : Pointer;
297 km_LoCapsable : Pointer;
298 km_LoRepeatable : Pointer;
299 km_HiKeyMapTypes : Pointer;
300 km_HiKeyMap : Pointer;
301 km_HiCapsable : Pointer;
302 km_HiRepeatable : Pointer;
307 pConUnit = ^tConUnit;
308 tConUnit = packed record
310 { ---- read only variables }
311 cu_Window : Pointer; { (WindowPtr) intuition window bound to this unit }
312 cu_XCP : Integer; { character position }
314 cu_XMax : Integer; { max character position }
316 cu_XRSize : Integer; { character raster size }
318 cu_XROrigin : Integer; { raster origin }
319 cu_YROrigin : Integer;
320 cu_XRExtant : Integer; { raster maxima }
321 cu_YRExtant : Integer;
322 cu_XMinShrink : Integer; { smallest area intact from resize process }
323 cu_YMinShrink : Integer;
324 cu_XCCP : Integer; { cursor position }
327 { ---- read/write variables (writes must must be protected) }
328 { ---- storage for AskKeyMap and SetKeyMap }
330 cu_KeyMapStruct : tKeyMap;
334 cu_TabStops : Array [0..MAXTABS-1] of Word;
335 { 0 at start, -1 at end of list }
337 { ---- console rastport attributes }
342 cu_AOLPen : Shortint;
343 cu_DrawMode : Shortint;
344 cu_AreaPtSz : Shortint;
345 cu_AreaPtrn : Pointer; { cursor area pattern }
346 cu_Minterms : Array [0..7] of Byte; { console minterms }
347 cu_Font : Pointer; { (TextFontPtr) }
352 cu_TxBaseline : Word;
355 { ---- console MODES and RAW EVENTS switches }
357 cu_Modes : Array [0..(PMB_AWM+7) div 8 - 1] of Byte;
359 cu_RawEvents : Array [0..(IECLASS_MAX+7) div 8 - 1] of Byte;
372 SIGBREAKF_CTRL_C = 4096;
374 function AllocVec( size, reqm : Longint ): Pointer;
388 function DoPkt(ID : pMsgPort;
389 Action, Param1, Param2,
390 Param3, Param4, Param5 : Longint) : Longint;
393 MOVEM.L d2/d3/d4/d5/d6/d7/a6,-(A7)
403 MOVEM.L (A7)+,d2/d3/d4/d5/d6/d7/a6
408 procedure FreeVec( memory : Pointer );
420 function GetConsoleTask : pMsgPort;
432 function GetMsg(port : pMsgPort): pMessage;
444 function ModifyIDCMP(window : pWindow;
445 IDCMPFlags : Longint) : Boolean;
451 MOVE.L _IntuitionBase,A6
464 procedure ReplyMsg(mess : pMessage);
476 function WaitPort(port : pMsgPort): pMessage;
488 procedure Delay_(ticks : Longint);
499 function SetSignal(newSignals, signalMask : Longint) : Longint;
512 function OpenInfo : pInfoData;
516 bptr, d4, d5, d6, d7 : Longint;
518 info := pInfoData(AllocVec(SizeOf(tInfoData), 1));
520 if info <> nil then begin
521 port := GetConsoleTask;
522 bptr := Longint(info) shr 2;
524 if port <> nil then begin
525 if DoPkt(port, $19, bptr, d4, d5, d6, d7) <> 0 then info := pInfoData(bptr shl 2)
529 if port = nil then begin
538 procedure CloseInfo(var info : pInfoData);
540 if info <> nil then begin
546 function ConData(modus : byte) : integer;
555 if info <> nil then begin
556 theunit := pConUnit((pIoStdReq(info^.id_InUse))^.io_Unit);
559 CD_CURRX : pos := theunit^.cu_XCP;
560 CD_CURRY : pos := theunit^.cu_YCP;
561 CD_MAXX : pos := theunit^.cu_XMax;
562 CD_MAXY : pos := theunit^.cu_YMax;
571 function WhereX : Byte;
573 WhereX := Byte(ConData(CD_CURRX))-lo(windmin);
576 function realx: byte;
578 RealX := Byte(ConData(CD_CURRX));
581 function realy: byte;
583 RealY := Byte(ConData(CD_CURRY));
586 function WhereY : Byte;
588 WhereY := Byte(ConData(CD_CURRY))-hi(windmin);
591 function screencols : integer;
593 screencols := ConData(CD_MAXX);
596 function screenrows : integer;
598 screenrows := ConData(CD_MAXY);
602 procedure Realgotoxy(x,y : integer);
604 Write(CSI, y, ';', x, 'H
');
608 procedure gotoxy(x,y : byte);
614 if y+hi(windmin)-2>=hi(windmax) then
615 y:=hi(windmax)-hi(windmin)+1;
616 if x+lo(windmin)-2>=lo(windmax) then
617 x:=lo(windmax)-lo(windmin)+1;
618 Write(CSI, y+hi(windmin), ';', x+lo(windmin), 'H
');
637 function ReadKey : char;
639 IDCMP_VANILLAKEY = $00200000;
640 IDCMP_RAWKEY = $00000400;
644 imsg : pIntuiMessage;
647 idcmp, vanil : Longint;
650 if KeyPress <> #0 then
658 if info <> nil then begin
659 win := pWindow(pConUnit((pIoStdReq(info^.id_InUse))^.io_Unit)^.cu_Window);
660 idcmp := win^.IDCMPFlags;
661 vanil := IDCMP_VANILLAKEY or IDCMP_RAWKEY;
663 ModifyIDCMP(win, (idcmp or vanil));
666 msg := WaitPort(win^.UserPort);
667 imsg := pIntuiMessage(GetMsg(win^.UserPort));
669 if (imsg^.IClass = IDCMP_VANILLAKEY) then
670 key := char(imsg^.Code)
672 if (imsg^.IClass = IDCMP_RAWKEY) then
673 key := char(imsg^.Code);
675 ReplyMsg(pMessage(imsg));
679 msg := GetMsg(win^.UserPort);
681 if msg <> nil then ReplyMsg(msg);
684 ModifyIDCMP(win, idcmp);
692 function KeyPressed : Boolean;
694 IDCMP_VANILLAKEY = $00200000;
695 IDCMP_RAWKEY = $00000400;
699 imsg : pIntuiMessage;
701 idcmp, vanil : Longint;
708 if info <> nil then begin
709 win := pWindow(pConUnit((pIoStdReq(info^.id_InUse))^.io_Unit)^.cu_Window);
710 idcmp := win^.IDCMPFlags;
711 vanil := IDCMP_VANILLAKEY or IDCMP_RAWKEY;
713 ModifyIDCMP(win, (idcmp or vanil));
715 msg := WaitPort(win^.UserPort);
716 imsg := pIntuiMessage(GetMsg(win^.UserPort));
718 if (imsg^.IClass = IDCMP_VANILLAKEY) or (imsg^.IClass = IDCMP_RAWKEY) then
721 KeyPress := char(imsg^.Code)
724 ReplyMsg(pMessage(imsg));
727 msg := GetMsg(win^.UserPort);
729 if msg <> nil then ReplyMsg(msg);
732 ModifyIDCMP(win, idcmp);
737 KeyPressed := ispressed;
740 procedure TextColor(color : byte);
742 TextAttr := (TextAttr and $70) or color;
743 Write(CSI, '3', color, 'm
');
746 procedure TextBackground(color : byte);
748 Textattr:=(textattr and $8f) or ((color and $7) shl 4);
749 Write(CSI, '4', color, 'm
');
752 procedure Window(X1,Y1,X2,Y2: Byte);
754 if (x1<1) or (x2>screencols) or (y2>screenrows) or
755 (x1>x2) or (y1>y2) then
757 windmin:=(x1-1) or ((y1-1) shl 8);
758 windmax:=(x2-1) or ((y2-1) shl 8);
797 procedure sound(hz : word);
801 procedure delay(DTime : Word);
805 dummy := trunc((real(DTime) / 1000.0) * 50.0);
809 function CheckBreak : boolean;
811 if (SetSignal(0, 0) and SIGBREAKF_CTRL_C) = SIGBREAKF_CTRL_C then
817 procedure textmode(mode : integer);
822 windmax:=(screencols-1) or ((screenrows-1) shl 8);
831 function GetTextBackground : byte;
839 if info <> nil then begin
840 pen := pConUnit((pIoStdReq(info^.id_InUse))^.io_Unit)^.cu_BgPen;
845 GetTextBackground := pen;
848 function GetTextColor : byte;
856 if info <> nil then begin
857 pen := pConUnit((pIoStdReq(info^.id_InUse))^.io_Unit)^.cu_FgPen;
866 {*****************************************************************************
867 Read and Write routines
868 *****************************************************************************}
869 { Problem here: Currently all these routines are not implemented because of how }
870 { the console device works. Because w low level write is required to change the }
871 { position of the cursor, and since the CrtWrite is assigned as the standard }
872 { write routine, a recursive call will occur }
875 { At startup make a copy of the Output handle, and then use this copy to make }
876 { low level positioning calls. This does not seem to work yet. }
880 Function CrtWrite(var f : textrec):integer;
885 buf: array[0..1] of char;
892 for i:=0 to f.bufpos-1 do
902 8 : if col>lo(windmin)+1 then
909 move.l a6,d6 { save base pointer }
910 move.l _IntuitionBase,a6 { set library base }
912 jsr _LVODisplayBeep(a6)
913 move.l d6,a6 { restore base pointer }
920 do_write(f.handle,longint(@buf[0]),1);
924 if col>lo(windmax)+1 then
929 while row>hi(windmax)+1 do
936 realgotoxy(row-1,col-1);
940 Function CrtClose(Var F: TextRec): Integer;
946 Function CrtOpen(Var F: TextRec): Integer;
948 If F.Mode = fmOutput Then
954 Function CrtRead(Var F: TextRec): Integer;
956 f.bufend:=do_read(f.handle,longint(f.bufptr),f.bufsize);
961 Function CrtInOut(Var F: TextRec): Integer;
964 fmInput: CrtInOut:=CrtRead(F);
965 fmOutput: CrtInOut:=CrtWrite(F);
969 procedure assigncrt(var f : text);
971 { TextRec(F).Mode:=fmClosed;
972 TextRec(F).BufSize:=SizeOf(TextBuf);
973 TextRec(F).BufPtr:=@TextRec(F).Buffer;
974 TextRec(F).BufPos:=0;
975 TextRec(F).OpenFunc:=@CrtOpen;
976 TextRec(F).InOutFunc:=@CrtInOut;
977 TextRec(F).FlushFunc:=@CrtInOut;
978 TextRec(F).CloseFunc:=@CrtClose;
979 TextRec(F).Name[0]:='.';
980 TextRec(F).Name[1]:=#0;}
989 { Restore default colors }
998 { load system variables to temporary variables to save time }
1000 maxrows:=screenrows;
1001 { Set the initial text attributes }
1003 Textattr:=(textattr and $8f) or ((GetTextBackGround and $7) shl 4);
1005 TextAttr := (TextAttr and $70) or GetTextColor;
1006 { set output window }
1007 windmax:=(maxcols-1) or (( maxrows-1) shl 8);
1010 { Get a copy of the standard }
1011 { output handle, and when using }
1012 { direct console calls, use this }
1014 { assigncrt(Output);
1015 TextRec(Output).mode:=fmOutput;}