mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-11 12:58:11 +02:00
928 lines
23 KiB
ObjectPascal
928 lines
23 KiB
ObjectPascal
{
|
|
This file is part of the Free Pascal run time library.
|
|
Copyright (c) 1999-2000 by Nils Sjoholm and Carl Eric Codere
|
|
|
|
See the file COPYING.FPC, included in this distribution,
|
|
for details about the copyright.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
**********************************************************************}
|
|
|
|
|
|
unit Crt;
|
|
|
|
{--------------------------------------------------------------------}
|
|
{ LEFT TO DO: }
|
|
{--------------------------------------------------------------------}
|
|
{ o Write special characters are not recognized }
|
|
{ o Write does not take care of window coordinates yet. }
|
|
{ o Read does not recognize the special editing characters }
|
|
{ o Read does not take care of window coordinates yet. }
|
|
{ o Readkey extended scancode is not correct yet }
|
|
{ o Color mapping only works for 4 colours }
|
|
{ o ClrScr, DeleteLine, InsLine do not work with window coordinates }
|
|
{--------------------------------------------------------------------}
|
|
|
|
|
|
|
|
Interface
|
|
|
|
Const
|
|
{ Controlling consts }
|
|
Flushing=false; {if true then don't buffer output}
|
|
ScreenWidth = 80;
|
|
ScreenHeight = 25;
|
|
|
|
{$i crth.inc}
|
|
|
|
Implementation
|
|
|
|
{
|
|
The definitions of TextRec and FileRec are in separate files.
|
|
}
|
|
{$i textrec.inc}
|
|
{$i filerec.inc}
|
|
|
|
var
|
|
maxcols,maxrows : longint;
|
|
|
|
CONST
|
|
{ This is used to make sure that readkey returns immediately }
|
|
{ if keypressed was used beforehand. }
|
|
KeyPress : char = #0;
|
|
_LVODisplayBeep = -96;
|
|
|
|
|
|
Type
|
|
|
|
pInfoData = ^tInfoData;
|
|
tInfoData = packed record
|
|
id_NumSoftErrors : Longint; { number of soft errors on disk }
|
|
id_UnitNumber : Longint; { Which unit disk is (was) mounted on }
|
|
id_DiskState : Longint; { See defines below }
|
|
id_NumBlocks : Longint; { Number of blocks on disk }
|
|
id_NumBlocksUsed : Longint; { Number of block in use }
|
|
id_BytesPerBlock : Longint;
|
|
id_DiskType : Longint; { Disk Type code }
|
|
id_VolumeNode : Longint; { BCPL pointer to volume node }
|
|
id_InUse : Longint; { Flag, zero if not in use }
|
|
end;
|
|
|
|
{ * List Node Structure. Each member in a list starts with a Node * }
|
|
|
|
pNode = ^tNode;
|
|
tNode = packed Record
|
|
ln_Succ, { * Pointer to next (successor) * }
|
|
ln_Pred : pNode; { * Pointer to previous (predecessor) * }
|
|
ln_Type : Byte;
|
|
ln_Pri : Shortint; { * Priority, for sorting * }
|
|
ln_Name : PChar; { * ID string, null terminated * }
|
|
End; { * Note: Integer aligned * }
|
|
|
|
{ normal, full featured list }
|
|
|
|
pList = ^tList;
|
|
tList = packed record
|
|
lh_Head : pNode;
|
|
lh_Tail : pNode;
|
|
lh_TailPred : pNode;
|
|
lh_Type : Byte;
|
|
l_pad : Byte;
|
|
end;
|
|
|
|
pMsgPort = ^tMsgPort;
|
|
tMsgPort = packed record
|
|
mp_Node : tNode;
|
|
mp_Flags : Byte;
|
|
mp_SigBit : Byte; { signal bit number }
|
|
mp_SigTask : Pointer; { task to be signalled (TaskPtr) }
|
|
mp_MsgList : tList; { message linked list }
|
|
end;
|
|
|
|
pMessage = ^tMessage;
|
|
tMessage = packed record
|
|
mn_Node : tNode;
|
|
mn_ReplyPort : pMsgPort; { message reply port }
|
|
mn_Length : Word; { message len in bytes }
|
|
end;
|
|
|
|
pIOStdReq = ^tIOStdReq;
|
|
tIOStdReq = packed record
|
|
io_Message : tMessage;
|
|
io_Device : Pointer; { device node pointer }
|
|
io_Unit : Pointer; { unit (driver private)}
|
|
io_Command : Word; { device command }
|
|
io_Flags : Byte;
|
|
io_Error : Shortint; { error or warning num }
|
|
io_Actual : Longint; { actual number of bytes transferred }
|
|
io_Length : Longint; { requested number bytes transferred}
|
|
io_Data : Pointer; { points to data area }
|
|
io_Offset : Longint; { offset for block structured devices }
|
|
end;
|
|
|
|
pIntuiMessage = ^tIntuiMessage;
|
|
tIntuiMessage = packed record
|
|
ExecMessage : tMessage;
|
|
IClass : Longint;
|
|
Code : Word;
|
|
Qualifier : Word;
|
|
IAddress : Pointer;
|
|
MouseX,
|
|
MouseY : Word;
|
|
Seconds,
|
|
Micros : Longint;
|
|
IDCMPWindow : Pointer;
|
|
SpecialLink : pIntuiMessage;
|
|
end;
|
|
|
|
pWindow = ^tWindow;
|
|
tWindow = packed record
|
|
NextWindow : pWindow; { for the linked list in a screen }
|
|
LeftEdge,
|
|
TopEdge : Integer; { screen dimensions of window }
|
|
Width,
|
|
Height : Integer; { screen dimensions of window }
|
|
MouseY,
|
|
MouseX : Integer; { relative to upper-left of window }
|
|
MinWidth,
|
|
MinHeight : Integer; { minimum sizes }
|
|
MaxWidth,
|
|
MaxHeight : Word; { maximum sizes }
|
|
Flags : Longint; { see below for defines }
|
|
MenuStrip : Pointer; { the strip of Menu headers }
|
|
Title : PChar; { the title text for this window }
|
|
FirstRequest : Pointer; { all active Requesters }
|
|
DMRequest : Pointer; { double-click Requester }
|
|
ReqCount : Integer; { count of reqs blocking Window }
|
|
WScreen : Pointer; { this Window's Screen }
|
|
RPort : Pointer; { this Window's very own RastPort }
|
|
BorderLeft,
|
|
BorderTop,
|
|
BorderRight,
|
|
BorderBottom : Shortint;
|
|
BorderRPort : Pointer;
|
|
FirstGadget : Pointer;
|
|
Parent,
|
|
Descendant : pWindow;
|
|
Pointer_ : Pointer; { sprite data }
|
|
PtrHeight : Shortint; { sprite height (not including sprite padding) }
|
|
PtrWidth : Shortint; { sprite width (must be less than or equal to 16) }
|
|
XOffset,
|
|
YOffset : Shortint; { sprite offsets }
|
|
IDCMPFlags : Longint; { User-selected flags }
|
|
UserPort,
|
|
WindowPort : pMsgPort;
|
|
MessageKey : pIntuiMessage;
|
|
DetailPen,
|
|
BlockPen : Byte; { for bar/border/gadget rendering }
|
|
CheckMark : Pointer;
|
|
ScreenTitle : PChar; { if non-null, Screen title when Window is active }
|
|
GZZMouseX : Integer;
|
|
GZZMouseY : Integer;
|
|
GZZWidth : Integer;
|
|
GZZHeight : Word;
|
|
ExtData : Pointer;
|
|
UserData : Pointer; { general-purpose pointer to User data extension }
|
|
WLayer : Pointer;
|
|
IFont : Pointer;
|
|
MoreFlags : Longint;
|
|
end;
|
|
|
|
const
|
|
|
|
M_LNM = 20; { linefeed newline mode }
|
|
PMB_ASM = M_LNM + 1; { internal storage bit for AS flag }
|
|
PMB_AWM = PMB_ASM + 1; { internal storage bit for AW flag }
|
|
MAXTABS = 80;
|
|
IECLASS_MAX = $15;
|
|
|
|
type
|
|
|
|
pKeyMap = ^tKeyMap;
|
|
tKeyMap = packed record
|
|
km_LoKeyMapTypes : Pointer;
|
|
km_LoKeyMap : Pointer;
|
|
km_LoCapsable : Pointer;
|
|
km_LoRepeatable : Pointer;
|
|
km_HiKeyMapTypes : Pointer;
|
|
km_HiKeyMap : Pointer;
|
|
km_HiCapsable : Pointer;
|
|
km_HiRepeatable : Pointer;
|
|
end;
|
|
|
|
|
|
|
|
pConUnit = ^tConUnit;
|
|
tConUnit = packed record
|
|
cu_MP : tMsgPort;
|
|
{ ---- read only variables }
|
|
cu_Window : Pointer; { (WindowPtr) intuition window bound to this unit }
|
|
cu_XCP : Integer; { character position }
|
|
cu_YCP : Integer;
|
|
cu_XMax : Integer; { max character position }
|
|
cu_YMax : Integer;
|
|
cu_XRSize : Integer; { character raster size }
|
|
cu_YRSize : Integer;
|
|
cu_XROrigin : Integer; { raster origin }
|
|
cu_YROrigin : Integer;
|
|
cu_XRExtant : Integer; { raster maxima }
|
|
cu_YRExtant : Integer;
|
|
cu_XMinShrink : Integer; { smallest area intact from resize process }
|
|
cu_YMinShrink : Integer;
|
|
cu_XCCP : Integer; { cursor position }
|
|
cu_YCCP : Integer;
|
|
|
|
{ ---- read/write variables (writes must must be protected) }
|
|
{ ---- storage for AskKeyMap and SetKeyMap }
|
|
|
|
cu_KeyMapStruct : tKeyMap;
|
|
|
|
{ ---- tab stops }
|
|
|
|
cu_TabStops : Array [0..MAXTABS-1] of Word;
|
|
{ 0 at start, -1 at end of list }
|
|
|
|
{ ---- console rastport attributes }
|
|
|
|
cu_Mask : Shortint;
|
|
cu_FgPen : Shortint;
|
|
cu_BgPen : Shortint;
|
|
cu_AOLPen : Shortint;
|
|
cu_DrawMode : Shortint;
|
|
cu_AreaPtSz : Shortint;
|
|
cu_AreaPtrn : Pointer; { cursor area pattern }
|
|
cu_Minterms : Array [0..7] of Byte; { console minterms }
|
|
cu_Font : Pointer; { (TextFontPtr) }
|
|
cu_AlgoStyle : Byte;
|
|
cu_TxFlags : Byte;
|
|
cu_TxHeight : Word;
|
|
cu_TxWidth : Word;
|
|
cu_TxBaseline : Word;
|
|
cu_TxSpacing : Word;
|
|
|
|
{ ---- console MODES and RAW EVENTS switches }
|
|
|
|
cu_Modes : Array [0..(PMB_AWM+7) div 8 - 1] of Byte;
|
|
{ one bit per mode }
|
|
cu_RawEvents : Array [0..(IECLASS_MAX+7) div 8 - 1] of Byte;
|
|
end;
|
|
|
|
const
|
|
|
|
|
|
CD_CURRX = 1;
|
|
CD_CURRY = 2;
|
|
CD_MAXX = 3;
|
|
CD_MAXY = 4;
|
|
|
|
CSI = chr($9b);
|
|
|
|
SIGBREAKF_CTRL_C = 4096;
|
|
|
|
function AllocVec( size, reqm : Longint ): Pointer;
|
|
begin
|
|
asm
|
|
MOVE.L A6,-(A7)
|
|
MOVE.L size,d0
|
|
MOVE.L reqm,d1
|
|
MOVE.L _ExecBase, A6
|
|
JSR -684(A6)
|
|
MOVE.L (A7)+,A6
|
|
MOVE.L d0,@RESULT
|
|
end;
|
|
end;
|
|
|
|
|
|
function DoPkt(ID : pMsgPort;
|
|
Action, Param1, Param2,
|
|
Param3, Param4, Param5 : Longint) : Longint;
|
|
begin
|
|
asm
|
|
MOVEM.L d2/d3/d4/d5/d6/d7/a6,-(A7)
|
|
MOVE.L ID,d1
|
|
MOVE.L Action,d2
|
|
MOVE.L Param1,d3
|
|
MOVE.L Param2,d4
|
|
MOVE.L Param3,d5
|
|
MOVE.L Param4,d6
|
|
MOVE.L Param5,d7
|
|
MOVE.L _DOSBase,A6
|
|
JSR -240(A6)
|
|
MOVEM.L (A7)+,d2/d3/d4/d5/d6/d7/a6
|
|
MOVE.L d0,@RESULT
|
|
end;
|
|
end;
|
|
|
|
procedure FreeVec( memory : Pointer );
|
|
begin
|
|
asm
|
|
MOVE.L A6,-(A7)
|
|
MOVE.L memory,a1
|
|
MOVE.L _ExecBase,A6
|
|
JSR -690(A6)
|
|
MOVE.L (A7)+,A6
|
|
end;
|
|
end;
|
|
|
|
|
|
function GetConsoleTask : pMsgPort;
|
|
begin
|
|
asm
|
|
MOVE.L A6,-(A7)
|
|
MOVE.L _DOSBase,A6
|
|
JSR -510(A6)
|
|
MOVE.L (A7)+,A6
|
|
MOVE.L d0,@RESULT
|
|
end;
|
|
end;
|
|
|
|
|
|
function GetMsg(port : pMsgPort): pMessage;
|
|
begin
|
|
asm
|
|
MOVE.L A6,-(A7)
|
|
MOVE.L port,a0
|
|
MOVE.L _ExecBase,A6
|
|
JSR -372(A6)
|
|
MOVE.L (A7)+,A6
|
|
MOVE.L d0,@RESULT
|
|
end;
|
|
end;
|
|
|
|
function ModifyIDCMP(window : pWindow;
|
|
IDCMPFlags : Longint) : Boolean;
|
|
begin
|
|
asm
|
|
MOVE.L A6,-(A7)
|
|
MOVE.L window,a0
|
|
MOVE.L IDCMPFlags,d0
|
|
MOVE.L _IntuitionBase,A6
|
|
JSR -150(A6)
|
|
MOVE.L (A7)+,A6
|
|
TST.L d0
|
|
bne @success
|
|
bra @end
|
|
@success:
|
|
move.b #1,d0
|
|
@end:
|
|
move.b d0,@RESULT
|
|
end;
|
|
end;
|
|
|
|
procedure ReplyMsg(mess : pMessage);
|
|
begin
|
|
asm
|
|
MOVE.L A6,-(A7)
|
|
MOVE.L mess,a1
|
|
MOVE.L _ExecBase,A6
|
|
JSR -378(A6)
|
|
MOVE.L (A7)+,A6
|
|
end;
|
|
end;
|
|
|
|
|
|
function WaitPort(port : pMsgPort): pMessage;
|
|
begin
|
|
asm
|
|
MOVE.L A6,-(A7)
|
|
MOVE.L port,a0
|
|
MOVE.L _ExecBase,A6
|
|
JSR -384(A6)
|
|
MOVE.L (A7)+,A6
|
|
MOVE.L d0,@RESULT
|
|
end;
|
|
end;
|
|
|
|
procedure Delay_(ticks : Longint);
|
|
begin
|
|
asm
|
|
MOVE.L A6,-(A7)
|
|
MOVE.L ticks,d1
|
|
MOVE.L _DOSBase,A6
|
|
JSR -198(A6)
|
|
MOVE.L (A7)+,A6
|
|
end;
|
|
end;
|
|
|
|
function SetSignal(newSignals, signalMask : Longint) : Longint;
|
|
begin
|
|
asm
|
|
MOVE.L A6,-(A7)
|
|
MOVE.L newSignals,d0
|
|
MOVE.L signalMask,d1
|
|
MOVE.L _ExecBase,A6
|
|
JSR -306(A6)
|
|
MOVE.L (A7)+,A6
|
|
MOVE.L d0,@RESULT
|
|
end;
|
|
end;
|
|
|
|
function OpenInfo : pInfoData;
|
|
var
|
|
port : pMsgPort;
|
|
info : pInfoData;
|
|
bptr, d4, d5, d6, d7 : Longint;
|
|
begin
|
|
info := pInfoData(AllocVec(SizeOf(tInfoData), 1));
|
|
|
|
if info <> nil then begin
|
|
port := GetConsoleTask;
|
|
bptr := Longint(info) shr 2;
|
|
|
|
if port <> nil then begin
|
|
if DoPkt(port, $19, bptr, d4, d5, d6, d7) <> 0 then info := pInfoData(bptr shl 2)
|
|
else port := nil;
|
|
end;
|
|
|
|
if port = nil then begin
|
|
FreeVec(info);
|
|
info := nil;
|
|
end;
|
|
end;
|
|
|
|
OpenInfo := info;
|
|
end;
|
|
|
|
procedure CloseInfo(var info : pInfoData);
|
|
begin
|
|
if info <> nil then begin
|
|
FreeVec(info);
|
|
info := nil;
|
|
end;
|
|
end;
|
|
|
|
function ConData(modus : byte) : integer;
|
|
var
|
|
info : pInfoData;
|
|
theunit : pConUnit;
|
|
pos : Longint;
|
|
begin
|
|
pos := 1;
|
|
info := OpenInfo;
|
|
|
|
if info <> nil then begin
|
|
theunit := pConUnit((pIoStdReq(info^.id_InUse))^.io_Unit);
|
|
|
|
case modus of
|
|
CD_CURRX : pos := theunit^.cu_XCP;
|
|
CD_CURRY : pos := theunit^.cu_YCP;
|
|
CD_MAXX : pos := theunit^.cu_XMax;
|
|
CD_MAXY : pos := theunit^.cu_YMax;
|
|
end;
|
|
|
|
CloseInfo(info);
|
|
end;
|
|
|
|
ConData := pos + 1;
|
|
end;
|
|
|
|
function WhereX : Byte;
|
|
begin
|
|
WhereX := Byte(ConData(CD_CURRX))-lo(windmin);
|
|
end;
|
|
|
|
function realx: byte;
|
|
begin
|
|
RealX := Byte(ConData(CD_CURRX));
|
|
end;
|
|
|
|
function realy: byte;
|
|
begin
|
|
RealY := Byte(ConData(CD_CURRY));
|
|
end;
|
|
|
|
function WhereY : Byte;
|
|
begin
|
|
WhereY := Byte(ConData(CD_CURRY))-hi(windmin);
|
|
end;
|
|
|
|
function screencols : integer;
|
|
begin
|
|
screencols := ConData(CD_MAXX);
|
|
end;
|
|
|
|
function screenrows : integer;
|
|
begin
|
|
screenrows := ConData(CD_MAXY);
|
|
end;
|
|
|
|
|
|
procedure Realgotoxy(x,y : integer);
|
|
begin
|
|
Write(CSI, y, ';', x, 'H');
|
|
end;
|
|
|
|
|
|
procedure gotoxy(x,y : byte);
|
|
begin
|
|
if (x<1) then
|
|
x:=1;
|
|
if (y<1) then
|
|
y:=1;
|
|
if y+hi(windmin)-2>=hi(windmax) then
|
|
y:=hi(windmax)-hi(windmin)+1;
|
|
if x+lo(windmin)-2>=lo(windmax) then
|
|
x:=lo(windmax)-lo(windmin)+1;
|
|
Write(CSI, y+hi(windmin), ';', x+lo(windmin), 'H');
|
|
end;
|
|
|
|
|
|
procedure CursorOff;
|
|
begin
|
|
Write(CSI,'0 p');
|
|
end;
|
|
|
|
procedure CursorOn;
|
|
begin
|
|
Write(CSI,'1 p');
|
|
end;
|
|
|
|
procedure ClrScr;
|
|
begin
|
|
Write(Chr($0c));
|
|
end;
|
|
|
|
function ReadKey : char;
|
|
const
|
|
IDCMP_VANILLAKEY = $00200000;
|
|
IDCMP_RAWKEY = $00000400;
|
|
var
|
|
info : pInfoData;
|
|
win : pWindow;
|
|
imsg : pIntuiMessage;
|
|
msg : pMessage;
|
|
key : char;
|
|
idcmp, vanil : Longint;
|
|
begin
|
|
key := #0;
|
|
if KeyPress <> #0 then
|
|
Begin
|
|
ReadKey:=KeyPress;
|
|
KeyPress:=#0;
|
|
exit;
|
|
end;
|
|
info := OpenInfo;
|
|
|
|
if info <> nil then begin
|
|
win := pWindow(pConUnit((pIoStdReq(info^.id_InUse))^.io_Unit)^.cu_Window);
|
|
idcmp := win^.IDCMPFlags;
|
|
vanil := IDCMP_VANILLAKEY or IDCMP_RAWKEY;
|
|
|
|
ModifyIDCMP(win, (idcmp or vanil));
|
|
|
|
repeat
|
|
msg := WaitPort(win^.UserPort);
|
|
imsg := pIntuiMessage(GetMsg(win^.UserPort));
|
|
|
|
if (imsg^.IClass = IDCMP_VANILLAKEY) then
|
|
key := char(imsg^.Code)
|
|
else
|
|
if (imsg^.IClass = IDCMP_RAWKEY) then
|
|
key := char(imsg^.Code);
|
|
|
|
ReplyMsg(pMessage(imsg));
|
|
until key <> #0;
|
|
|
|
repeat
|
|
msg := GetMsg(win^.UserPort);
|
|
|
|
if msg <> nil then ReplyMsg(msg);
|
|
until msg = nil;
|
|
|
|
ModifyIDCMP(win, idcmp);
|
|
|
|
CloseInfo(info);
|
|
end;
|
|
|
|
ReadKey := key;
|
|
end;
|
|
|
|
function KeyPressed : Boolean;
|
|
const
|
|
IDCMP_VANILLAKEY = $00200000;
|
|
IDCMP_RAWKEY = $00000400;
|
|
var
|
|
info : pInfoData;
|
|
win : pWindow;
|
|
imsg : pIntuiMessage;
|
|
msg : pMessage;
|
|
idcmp, vanil : Longint;
|
|
ispressed : Boolean;
|
|
begin
|
|
KeyPress := #0;
|
|
ispressed := False;
|
|
info := OpenInfo;
|
|
|
|
if info <> nil then begin
|
|
win := pWindow(pConUnit((pIoStdReq(info^.id_InUse))^.io_Unit)^.cu_Window);
|
|
idcmp := win^.IDCMPFlags;
|
|
vanil := IDCMP_VANILLAKEY or IDCMP_RAWKEY;
|
|
|
|
ModifyIDCMP(win, (idcmp or vanil));
|
|
|
|
msg := WaitPort(win^.UserPort);
|
|
imsg := pIntuiMessage(GetMsg(win^.UserPort));
|
|
|
|
if (imsg^.IClass = IDCMP_VANILLAKEY) or (imsg^.IClass = IDCMP_RAWKEY) then
|
|
Begin
|
|
ispressed := true;
|
|
KeyPress := char(imsg^.Code)
|
|
end;
|
|
|
|
ReplyMsg(pMessage(imsg));
|
|
|
|
repeat
|
|
msg := GetMsg(win^.UserPort);
|
|
|
|
if msg <> nil then ReplyMsg(msg);
|
|
until msg = nil;
|
|
|
|
ModifyIDCMP(win, idcmp);
|
|
|
|
CloseInfo(info);
|
|
end;
|
|
|
|
KeyPressed := ispressed;
|
|
end;
|
|
|
|
procedure TextColor(color : byte);
|
|
begin
|
|
TextAttr := (TextAttr and $70) or color;
|
|
Write(CSI, '3', color, 'm');
|
|
end;
|
|
|
|
procedure TextBackground(color : byte);
|
|
begin
|
|
Textattr:=(textattr and $8f) or ((color and $7) shl 4);
|
|
Write(CSI, '4', color, 'm');
|
|
end;
|
|
|
|
procedure Window(X1,Y1,X2,Y2: Byte);
|
|
begin
|
|
if (x1<1) or (x2>screencols) or (y2>screenrows) or
|
|
(x1>x2) or (y1>y2) then
|
|
exit;
|
|
windmin:=(x1-1) or ((y1-1) shl 8);
|
|
windmax:=(x2-1) or ((y2-1) shl 8);
|
|
gotoxy(1,1);
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
procedure DelLine;
|
|
begin
|
|
Write(CSI,'X');
|
|
end;
|
|
|
|
procedure ClrEol;
|
|
begin
|
|
Write(CSI,'K');
|
|
end;
|
|
|
|
procedure InsLine;
|
|
begin
|
|
Write(CSI,'1 L');
|
|
end;
|
|
|
|
procedure cursorbig;
|
|
begin
|
|
end;
|
|
|
|
procedure lowvideo;
|
|
begin
|
|
end;
|
|
|
|
procedure highvideo;
|
|
begin
|
|
end;
|
|
|
|
procedure nosound;
|
|
begin
|
|
end;
|
|
|
|
procedure sound(hz : word);
|
|
begin
|
|
end;
|
|
|
|
procedure delay(DTime : Word);
|
|
var
|
|
dummy : Longint;
|
|
begin
|
|
dummy := trunc((real(DTime) / 1000.0) * 50.0);
|
|
Delay_(dummy);
|
|
end;
|
|
|
|
function CheckBreak : boolean;
|
|
begin
|
|
if (SetSignal(0, 0) and SIGBREAKF_CTRL_C) = SIGBREAKF_CTRL_C then
|
|
CheckBreak := true
|
|
else
|
|
CheckBreak := false;
|
|
end;
|
|
|
|
procedure textmode(mode : integer);
|
|
begin
|
|
lastmode:=mode;
|
|
mode:=mode and $ff;
|
|
windmin:=0;
|
|
windmax:=(screencols-1) or ((screenrows-1) shl 8);
|
|
maxcols:=screencols;
|
|
maxrows:=screenrows;
|
|
end;
|
|
|
|
procedure normvideo;
|
|
begin
|
|
end;
|
|
|
|
function GetTextBackground : byte;
|
|
var
|
|
info : pInfoData;
|
|
pen : byte;
|
|
begin
|
|
pen := 1;
|
|
info := OpenInfo;
|
|
|
|
if info <> nil then begin
|
|
pen := pConUnit((pIoStdReq(info^.id_InUse))^.io_Unit)^.cu_BgPen;
|
|
|
|
CloseInfo(info);
|
|
end;
|
|
|
|
GetTextBackground := pen;
|
|
end;
|
|
|
|
function GetTextColor : byte;
|
|
var
|
|
info : pInfoData;
|
|
pen : byte;
|
|
begin
|
|
pen := 1;
|
|
info := OpenInfo;
|
|
|
|
if info <> nil then begin
|
|
pen := pConUnit((pIoStdReq(info^.id_InUse))^.io_Unit)^.cu_FgPen;
|
|
|
|
CloseInfo(info);
|
|
end;
|
|
|
|
GetTextColor := pen;
|
|
end;
|
|
|
|
|
|
{*****************************************************************************
|
|
Read and Write routines
|
|
*****************************************************************************}
|
|
{ Problem here: Currently all these routines are not implemented because of how }
|
|
{ the console device works. Because w low level write is required to change the }
|
|
{ position of the cursor, and since the CrtWrite is assigned as the standard }
|
|
{ write routine, a recursive call will occur }
|
|
|
|
{ How to fix this: }
|
|
{ At startup make a copy of the Output handle, and then use this copy to make }
|
|
{ low level positioning calls. This does not seem to work yet. }
|
|
|
|
|
|
|
|
Function CrtWrite(var f : textrec):integer;
|
|
|
|
var
|
|
i,col,row : longint;
|
|
c : char;
|
|
buf: array[0..1] of char;
|
|
|
|
begin
|
|
col:=realx;
|
|
row:=realy;
|
|
inc(row);
|
|
inc(col);
|
|
for i:=0 to f.bufpos-1 do
|
|
begin
|
|
c:=f.buffer[i];
|
|
case ord(c) of
|
|
10 : begin
|
|
inc(row);
|
|
end;
|
|
13 : begin
|
|
col:=lo(windmin)+1;
|
|
end;
|
|
8 : if col>lo(windmin)+1 then
|
|
begin
|
|
dec(col);
|
|
end;
|
|
7 : begin
|
|
{ beep }
|
|
asm
|
|
move.l a6,d6 { save base pointer }
|
|
move.l _IntuitionBase,a6 { set library base }
|
|
sub.l a0,a0
|
|
jsr _LVODisplayBeep(a6)
|
|
move.l d6,a6 { restore base pointer }
|
|
end;
|
|
end;
|
|
else
|
|
begin
|
|
buf[0]:=c;
|
|
realgotoxy(row,col);
|
|
do_write(f.handle,longint(@buf[0]),1);
|
|
inc(col);
|
|
end;
|
|
end;
|
|
if col>lo(windmax)+1 then
|
|
begin
|
|
col:=lo(windmin)+1;
|
|
inc(row);
|
|
end;
|
|
while row>hi(windmax)+1 do
|
|
begin
|
|
delline;
|
|
dec(row);
|
|
end;
|
|
end;
|
|
f.bufpos:=0;
|
|
realgotoxy(row-1,col-1);
|
|
CrtWrite:=0;
|
|
end;
|
|
|
|
Function CrtClose(Var F: TextRec): Integer;
|
|
Begin
|
|
F.Mode:=fmClosed;
|
|
CrtClose:=0;
|
|
End;
|
|
|
|
Function CrtOpen(Var F: TextRec): Integer;
|
|
Begin
|
|
If F.Mode = fmOutput Then
|
|
CrtOpen:=0
|
|
Else
|
|
CrtOpen:=5;
|
|
End;
|
|
|
|
Function CrtRead(Var F: TextRec): Integer;
|
|
Begin
|
|
f.bufend:=do_read(f.handle,longint(f.bufptr),f.bufsize);
|
|
f.bufpos:=0;
|
|
CrtRead:=0;
|
|
End;
|
|
|
|
Function CrtInOut(Var F: TextRec): Integer;
|
|
Begin
|
|
Case F.Mode of
|
|
fmInput: CrtInOut:=CrtRead(F);
|
|
fmOutput: CrtInOut:=CrtWrite(F);
|
|
End;
|
|
End;
|
|
|
|
procedure assigncrt(var f : text);
|
|
begin
|
|
{ TextRec(F).Mode:=fmClosed;
|
|
TextRec(F).BufSize:=SizeOf(TextBuf);
|
|
TextRec(F).BufPtr:=@TextRec(F).Buffer;
|
|
TextRec(F).BufPos:=0;
|
|
TextRec(F).OpenFunc:=@CrtOpen;
|
|
TextRec(F).InOutFunc:=@CrtInOut;
|
|
TextRec(F).FlushFunc:=@CrtInOut;
|
|
TextRec(F).CloseFunc:=@CrtClose;
|
|
TextRec(F).Name[0]:='.';
|
|
TextRec(F).Name[1]:=#0;}
|
|
end;
|
|
|
|
|
|
var
|
|
old_exit : pointer;
|
|
|
|
procedure crt_exit;
|
|
begin
|
|
{ Restore default colors }
|
|
write(CSI,'0m');
|
|
exitproc:=old_exit;
|
|
end;
|
|
|
|
|
|
Begin
|
|
old_exit:=exitproc;
|
|
exitproc:=@crt_exit;
|
|
{ load system variables to temporary variables to save time }
|
|
maxcols:=screencols;
|
|
maxrows:=screenrows;
|
|
{ Set the initial text attributes }
|
|
{ Text background }
|
|
Textattr:=(textattr and $8f) or ((GetTextBackGround and $7) shl 4);
|
|
{ Text foreground }
|
|
TextAttr := (TextAttr and $70) or GetTextColor;
|
|
{ set output window }
|
|
windmax:=(maxcols-1) or (( maxrows-1) shl 8);
|
|
|
|
|
|
{ Get a copy of the standard }
|
|
{ output handle, and when using }
|
|
{ direct console calls, use this }
|
|
{ handle instead. }
|
|
{ assigncrt(Output);
|
|
TextRec(Output).mode:=fmOutput;}
|
|
end.
|