Selaa lähdekoodia

* window now works
* bugfix of keypressed and readkey

carl 27 vuotta sitten
vanhempi
commit
27bbe627c1
1 muutettua tiedostoa jossa 282 lisäystä ja 43 poistoa
  1. 282 43
      rtl/amiga/crt.pp

+ 282 - 43
rtl/amiga/crt.pp

@@ -1,7 +1,7 @@
 {
 {
     $Id$
     $Id$
     This file is part of the Free Pascal run time library.
     This file is part of the Free Pascal run time library.
-    Copyright (c) 1998 by Nils Sjoholm
+    Copyright (c) 1998 by Nils Sjoholm and Carl Eric Codere
 
 
     See the file COPYING.FPC, included in this distribution,
     See the file COPYING.FPC, included in this distribution,
     for details about the copyright.
     for details about the copyright.
@@ -13,8 +13,22 @@
  **********************************************************************}
  **********************************************************************}
 
 
 
 
-
 unit Crt;
 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
 Interface
 
 
 Const
 Const
@@ -75,25 +89,25 @@ Const
   Blink         = 128;
   Blink         = 128;
 
 
 {Other Defaults}
 {Other Defaults}
-
-  TextAttr   : Byte = $07;
   LastMode   : Word = 3;
   LastMode   : Word = 3;
   WindMin    : Word = $0;
   WindMin    : Word = $0;
   WindMax    : Word = $184f;
   WindMax    : Word = $184f;
+{ These don't change anything if they are modified }
+  CheckSnow  : Boolean = FALSE;
+  DirectVideo: Boolean = FALSE;
 var
 var
+  TextAttr : BYTE;
   { CheckBreak have to make this one to a function for Amiga }
   { CheckBreak have to make this one to a function for Amiga }
-  CheckEOF,
-  CheckSnow,
-  DirectVideo: Boolean;
+  CheckEOF : Boolean;
 
 
 Procedure AssignCrt(Var F: Text);
 Procedure AssignCrt(Var F: Text);
 Function  KeyPressed: Boolean;
 Function  KeyPressed: Boolean;
 Function  ReadKey: Char;
 Function  ReadKey: Char;
 Procedure TextMode(Mode: Integer);
 Procedure TextMode(Mode: Integer);
-Procedure Window(X1, Y1, X2, Y2: Integer);
-Procedure GoToXy(X: Integer; Y: Integer);
-Function  WhereX: Integer;
-Function  WhereY: Integer;
+Procedure Window(X1, Y1, X2, Y2: BYTE);
+Procedure GoToXy(X: byte; Y: byte);
+Function  WhereX: Byte;
+Function  WhereY: Byte;
 Procedure ClrScr;
 Procedure ClrScr;
 Procedure ClrEol;
 Procedure ClrEol;
 Procedure InsLine;
 Procedure InsLine;
@@ -121,8 +135,15 @@ Implementation
 {$i textrec.inc}
 {$i textrec.inc}
 {$i filerec.inc}
 {$i filerec.inc}
 
 
-Var
-  maxcols,maxrows : word;
+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
 Type
 
 
@@ -508,41 +529,56 @@ begin
    ConData := pos + 1;
    ConData := pos + 1;
 end;
 end;
 
 
-function WhereX : integer;
+function WhereX : Byte;
 begin
 begin
-   WhereX := ConData(CD_CURRX);
+   WhereX := Byte(ConData(CD_CURRX))-lo(windmin);
 end;
 end;
 
 
-function WhereY : integer;
+function realx: byte;
 begin
 begin
-   WhereY := ConData(CD_CURRY);
+   RealX := Byte(ConData(CD_CURRX));
 end;
 end;
 
 
-function maxx : integer;
+function realy: byte;
 begin
 begin
-   maxx := ConData(CD_MAXX);
+ RealY := Byte(ConData(CD_CURRY));
 end;
 end;
 
 
-function maxy : integer;
+function WhereY : Byte;
 begin
 begin
-   maxy := ConData(CD_MAXY);
+   WhereY := Byte(ConData(CD_CURRY))-hi(windmin);
 end;
 end;
 
 
-procedure GotoXY(x, y : integer);
-var
-   mx, my : integer;
+function screencols : integer;
 begin
 begin
-   mx := maxx;
-   my := maxy;
+   screencols := ConData(CD_MAXX);
+end;
 
 
-   if x < 1 then x := wherex
-   else if x > mx then x := mx;
+function screenrows : integer;
+begin
+   screenrows := ConData(CD_MAXY);
+end;
 
 
-   if y < 1 then y := wherey
-   else if y > my then y := my;
 
 
-   Write(CSI, y, ';', x, 'H');
-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;
 procedure CursorOff;
 begin
 begin
@@ -572,6 +608,12 @@ var
    idcmp, vanil   :  Longint;
    idcmp, vanil   :  Longint;
 begin
 begin
    key   := #0;
    key   := #0;
+   if KeyPress <> #0 then
+    Begin
+      ReadKey:=KeyPress;
+      KeyPress:=#0;
+      exit;
+    end;
    info  := OpenInfo;
    info  := OpenInfo;
 
 
    if info <> nil then begin
    if info <> nil then begin
@@ -585,7 +627,11 @@ begin
          msg   := WaitPort(win^.UserPort);
          msg   := WaitPort(win^.UserPort);
          imsg  := pIntuiMessage(GetMsg(win^.UserPort));
          imsg  := pIntuiMessage(GetMsg(win^.UserPort));
 
 
-         if (imsg^.Class_ = IDCMP_VANILLAKEY) or (imsg^.Class_ = IDCMP_RAWKEY) then key := char(imsg^.Code);
+         if (imsg^.Class_ = IDCMP_VANILLAKEY) then
+              key := char(imsg^.Code)
+         else
+         if (imsg^.Class_ = IDCMP_RAWKEY) then
+              key := char(imsg^.Code);
 
 
          ReplyMsg(pMessage(imsg));
          ReplyMsg(pMessage(imsg));
       until key <> #0;
       until key <> #0;
@@ -616,6 +662,7 @@ var
    idcmp, vanil   :  Longint;
    idcmp, vanil   :  Longint;
    ispressed : Boolean;
    ispressed : Boolean;
 begin
 begin
+   KeyPress := #0;
    ispressed := False;
    ispressed := False;
    info  := OpenInfo;
    info  := OpenInfo;
 
 
@@ -629,7 +676,11 @@ begin
       msg   := WaitPort(win^.UserPort);
       msg   := WaitPort(win^.UserPort);
       imsg  := pIntuiMessage(GetMsg(win^.UserPort));
       imsg  := pIntuiMessage(GetMsg(win^.UserPort));
 
 
-      if (imsg^.Class_ = IDCMP_VANILLAKEY) or (imsg^.Class_ = IDCMP_RAWKEY) then ispressed := true;
+      if (imsg^.Class_ = IDCMP_VANILLAKEY) or (imsg^.Class_ = IDCMP_RAWKEY) then
+      Begin
+        ispressed := true;
+        KeyPress := char(imsg^.Code)
+      end;
 
 
       ReplyMsg(pMessage(imsg));
       ReplyMsg(pMessage(imsg));
 
 
@@ -659,14 +710,19 @@ begin
    Write(CSI, '4', color, 'm');
    Write(CSI, '4', color, 'm');
 end;
 end;
 
 
-procedure window(X1,Y1,X2,Y2 : Integer);
-begin
+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;
+
+
 
 
-end;
 
 
-procedure assigncrt(var f : text);
-begin
-end;
 
 
 procedure DelLine;
 procedure DelLine;
 begin
 begin
@@ -721,20 +777,203 @@ end;
 
 
 procedure textmode(mode : integer);
 procedure textmode(mode : integer);
 begin
 begin
+       lastmode:=mode;
+       mode:=mode and $ff;
+       windmin:=0;
+       windmax:=(screencols-1) or ((screenrows-1) shl 8);
+       maxcols:=screencols;
+       maxrows:=screenrows;
 end;
 end;
 
 
 procedure normvideo;
 procedure normvideo;
 begin
 begin
 end;
 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
 Begin
+   old_exit:=exitproc;
+   exitproc:=@crt_exit;
    { load system variables to temporary variables to save time }
    { load system variables to temporary variables to save time }
-   maxcols:=maxy;
-   maxrows:=maxx;
+   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 }
    { set output window }
-   windmax:=((maxcols-1) shl 8) or (maxrows-1);
+   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.
 end.