home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / coders / jËzyki_programowania / pascal / wwg-crt / crt.p < prev    next >
Text File  |  1997-07-14  |  8KB  |  428 lines

  1. External;
  2.  
  3. {
  4.    Crt.p für PCQ-Pascal, um nützliche "Konsolen"-Funktionen und Prozeduren
  5.    auch ohne einen Konsolenparameter nutzen zu können;
  6.    Crt.p for PCQ-Pascal to use console functions and procedures without an
  7.    console parameter.
  8. }
  9.  
  10. {$I "include:exec/exec.i"}
  11. {$I "include:dos/dos.i"}
  12. {$I "include:dos/dosextens.i"}
  13. {$I "include:intuition/intuition.i"}
  14. {$I "include:Devices/ConUnit.i"}
  15. {$I "include:Utils/StringLib.i"}
  16.  
  17. const
  18.    CSI = chr($9b);
  19.    
  20.    CD_CURRX =  1;
  21.    CD_CURRY =  2;
  22.    CD_MAXX  =  3;
  23.    CD_MAXY  =  4;
  24.    
  25.    TEXT_BACKGROUND = -1;
  26.    
  27. { -- Interne Crt-Funktionen/Prozeduren; internals -- }
  28.  
  29. function OpenInfo : InfoDataPtr;
  30. var
  31.    port     :  MsgPortPtr;
  32.    info     :  InfoDataPtr;
  33.    bptr, d4, d5, d6, d7 :  integer;
  34. begin
  35.    info  := InfoDataPtr(AllocVec(SizeOf(InfoData), MEMF_PUBLIC));
  36.    
  37.    if info <> nil then begin
  38.       port  := GetConsoleTask;
  39.       bptr  := integer(info) shr 2;
  40.       
  41.       if port <> nil then begin
  42.          if DoPkt(port, ACTION_DISK_INFO, bptr, d4, d5, d6, d7) <> DOSFALSE then info := InfoDataPtr(bptr shl 2)
  43.          else port := nil;
  44.       end;
  45.       
  46.       if port = nil then begin   
  47.          FreeVec(info);
  48.          info := nil;
  49.       end;
  50.    end;
  51.  
  52.    OpenInfo := info;
  53. end;
  54.  
  55. procedure CloseInfo(var info : InfoDataPtr);
  56. begin
  57.    if info <> nil then begin
  58.       FreeVec(info);
  59.       info := nil;
  60.    end;
  61. end;
  62.  
  63. function ConData(modus : byte) : integer;
  64. var
  65.    info  :  InfoDataPtr;
  66.    unit  :  ConUnitPtr;
  67.    pos   :  integer;
  68. begin
  69.    pos   := 1;
  70.    info  := OpenInfo;
  71.    
  72.    if info <> nil then begin
  73.       unit  := ConUnitPtr((IoStdReqPtr(info^.id_InUse))^.io_Unit);
  74.  
  75.       case modus of
  76.          CD_CURRX :  pos   := unit^.cu_XCP;
  77.          CD_CURRY :  pos   := unit^.cu_YCP;
  78.          CD_MAXX  :  pos   := unit^.cu_XMax;
  79.          CD_MAXY  :  pos   := unit^.cu_YMax;
  80.       end;
  81.       
  82.       CloseInfo(info);
  83.    end;
  84.    
  85.    ConData := pos + 1;
  86. end;
  87.  
  88. { -- öffentliche Funktionen und Prozeduren; public functions and procedures -- }
  89.  
  90. { Cursorpositionen; cursor positions }
  91.  
  92. function WhereX : integer;
  93. begin
  94.    WhereX := ConData(CD_CURRX);
  95. end;
  96.  
  97. function WhereY : integer;
  98. begin
  99.    WhereY := ConData(CD_CURRY);
  100. end;
  101.  
  102. function MaxX : integer;
  103. begin
  104.    MaxX := ConData(CD_MAXX);
  105. end;
  106.  
  107. function MaxY : integer;
  108. begin
  109.    MaxY := ConData(CD_MAXY);
  110. end;
  111.  
  112. { Cursorpositionierungen; cursor positioning }
  113.  
  114. procedure GotoXY(x, y : integer);
  115. var
  116.    mx, my : integer;
  117. begin
  118.    mx := MaxX;
  119.    my := MaxY;
  120.    
  121.    if x < 1 then x := WhereX
  122.    else if x > mx then x := mx;
  123.    
  124.    if y < 1 then y := WhereY
  125.    else if y > my then y := my;
  126.    
  127.    Write(CSI, y, ";", x, "H");
  128. end;
  129.  
  130. procedure GotoX(x : integer);
  131. begin
  132.    GotoXY(x, 0);
  133. end;
  134.  
  135. procedure GotoY(y : integer);
  136. begin
  137.    GotoXY(0, y);
  138. end;
  139.  
  140. procedure GoUp(n : integer);
  141. begin
  142.    if (n > 1) and (n < WhereY) then Write(CSI, n, "A");
  143. end;
  144.  
  145. procedure GoDown(n : integer);
  146. begin
  147.    if (n > 0) and (n <= (MaxY - WhereY)) then Write(CSI, n, "B");
  148. end;
  149.  
  150. procedure GoLeft(n : integer);
  151. begin
  152.    if (n > 0) and (n < WhereX) then Write(CSI, n, "D");
  153. end;
  154.  
  155. procedure GoRight(n : integer);
  156. begin
  157.    if (n > 0) and (n <= (MaxX - WhereX)) then Write(CSI, n, "C");
  158. end;
  159.  
  160. { Cursordarstellungen; cursor display }
  161.  
  162. procedure CursorOff;
  163. begin
  164.    Write(CSI,"0 p");
  165. end;
  166.  
  167. procedure CursorOn;
  168. begin
  169.    Write(CSI,"1 p");
  170. end;
  171.  
  172. { Spezielle Consolen-Aktionen; special console procedures }
  173.  
  174. procedure Bell;
  175. begin
  176.    Write(Chr($07));
  177. end;
  178.  
  179. procedure ClrScr;
  180. begin
  181.    Write(Chr($0c));
  182. end;
  183.  
  184. procedure ConReset;
  185. begin
  186.    Write("\ec");
  187. end;
  188.  
  189. { Tastatureingaben; keyboard inputs }
  190.  
  191. function Break : boolean;
  192. begin
  193.    if (SetSignal(0, 0) and SIGBREAKF_CTRL_C) = SIGBREAKF_CTRL_C then
  194.       Break := true
  195.    else
  196.       Break := false;
  197. end;
  198.  
  199. function ReadKey : char;
  200. var
  201.    info  :  InfoDataPtr;
  202.    win   :  WindowPtr;
  203.    imsg  :  IntuiMessagePtr;
  204.    msg   :  MessagePtr;
  205.    key   :  char;
  206.    idcmp, vanil   :  integer;
  207. begin
  208.    key   := char(0);
  209.    info  := OpenInfo;
  210.    
  211.    if info <> nil then begin
  212.       win   := WindowPtr(ConUnitPtr((IoStdReqPtr(info^.id_InUse))^.io_Unit)^.cu_Window);
  213.       idcmp := win^.IDCMPFlags;
  214.       vanil := IDCMP_VANILLAKEY or IDCMP_RAWKEY;
  215.       
  216.       ModifyIDCMP(win, (idcmp or vanil));
  217.       
  218.       repeat
  219.          msg   := WaitPort(win^.UserPort);
  220.          imsg  := IntuiMessagePtr(GetMsg(win^.UserPort));
  221.          
  222.          if (imsg^.Class = IDCMP_VANILLAKEY) or (imsg^.Class = IDCMP_RAWKEY) then key := char(imsg^.Code);
  223.          
  224.          ReplyMsg(MessagePtr(imsg));
  225.       until key <> char(0);
  226.       
  227.       repeat
  228.          msg   := GetMsg(win^.UserPort);
  229.          
  230.          if msg <> nil then ReplyMsg(msg);
  231.       until msg = nil;
  232.       
  233.       ModifyIDCMP(win, idcmp);
  234.       
  235.       CloseInfo(info);
  236.    end;
  237.    
  238.    ReadKey := key;
  239. end;
  240.  
  241. { Farben; colors }
  242.  
  243. function GetTextColor : byte;
  244. var
  245.    info  :  InfoDataPtr;
  246.    pen   :  byte;
  247. begin
  248.    pen   := 1;
  249.    info  := OpenInfo;
  250.    
  251.    if info <> nil then begin
  252.       pen   := ConUnitPtr((IoStdReqPtr(info^.id_InUse))^.io_Unit)^.cu_FgPen;
  253.       
  254.       CloseInfo(info);
  255.    end;
  256.    
  257.    GetTextColor   := pen;
  258. end;
  259.  
  260. function GetTextBackground : byte;
  261. var
  262.    info  :  InfoDataPtr;
  263.    pen   :  byte;
  264. begin
  265.    pen   := 1;
  266.    info  := OpenInfo;
  267.    
  268.    if info <> nil then begin
  269.       pen   := ConUnitPtr((IoStdReqPtr(info^.id_InUse))^.io_Unit)^.cu_BgPen;
  270.       
  271.       CloseInfo(info);
  272.    end;
  273.    
  274.    GetTextBackground := pen;
  275. end;
  276.  
  277. procedure TextColor(fgpen : byte);
  278. begin
  279.    Write(CSI, '3', fgpen, 'm');
  280. end;
  281.  
  282. procedure TextBackground(bgpen : byte);
  283. begin
  284.    Write(CSI, '4', bgpen, 'm');
  285. end;
  286.  
  287. procedure ConBackground(bgpen : byte);
  288. begin
  289.    if bgpen = TEXT_BACKGROUND then bgpen := GetTextBackground;
  290.    
  291.    Write(CSI, '4', bgpen, ';>', bgpen, 'm');
  292. end;
  293.  
  294. { Textdarstellungen; text display }
  295.  
  296. procedure TextReset;
  297. begin
  298.    Write(CSI, "0;39;49m");
  299. end;
  300.  
  301. procedure TextStyle(style : byte);
  302. begin
  303.    Write(CSI, style, "m");
  304. end;
  305.  
  306. procedure TextMode(style, fgpen, bgpen : byte);
  307. begin
  308.    TextReset;
  309.    Write(CSI, style, ";3", fgpen, ";4", bgpen, "m");
  310. end;
  311.  
  312. { Text-Zentrierung; text line centering }
  313.  
  314. procedure CenterText(txt : string);
  315. begin
  316.    GotoX((MaxX - StrLen(txt))/2+1);
  317.    WriteLn(txt);
  318. end;
  319.  
  320. { Text-Grafiken; text graphics }
  321.  
  322. procedure TextLine(x1, y1, x2, y2 : Integer; c : Char);
  323. var
  324.    i, j, m, n, d, x, y, dy :  integer;
  325.    s, f  :  real;
  326.    
  327.    procedure Tausch(var a, b : integer);
  328.    begin
  329.       i := a;
  330.       a := b;
  331.       b := i;
  332.    end;
  333.    
  334.    procedure d_ermitteln;
  335.    begin
  336.       s  := s + f;
  337.       n  := trunc(s+0.5);
  338.       d  := n - m;
  339.       m  := n;
  340.    end;
  341. begin
  342.    
  343.    {  Grundsätzlich von links nach rechs zeichnen;
  344.       always draw from left to right }
  345.    if x2 < x1 then begin
  346.       Tausch(x1, x2);
  347.       Tausch(y1, y2);
  348.    end;
  349.    
  350.    GotoXY(x1, y1);
  351.    
  352.    {  Die vertikale Zeichenrichtung und die Abmessung in der Höhe ermitteln;
  353.       determine the vertical drawing direction and height }
  354.    if y1 < y2 then begin
  355.       y  := (y2-y1)+1;
  356.       dy := 1;
  357.    end else begin
  358.       y  := (y1-y2)+1;
  359.       dy := -1;
  360.    end;
  361.    
  362.    {  Die Breite in Zeichen ermitteln;
  363.       determine the count of chars in width }
  364.    x  := (x2-x1)+1;
  365.    
  366.    m  := 0;
  367.    s  := 0;
  368.    
  369.    if x >= y then begin
  370.       {  Die Diagonale bedeckt eine Fläche, die breiter ist, als sie hoch ist;
  371.          The diagonal is smaller in height than in width }
  372.       f  := x/y;
  373.       
  374.       for i := 1 to y do begin
  375.          d_ermitteln;
  376.          
  377.          for j := 1 to d do Write(c);
  378.          
  379.          if i < y then GotoY(WhereY+dy);
  380.       end;
  381.    end else begin
  382.       {  Die Diagonale bedeckt eine Fläche, die schmaler ist, als sie hoch ist;
  383.          The diagonal is smaller in width than in height }
  384.       f  := y/x;
  385.       
  386.       for i := 1 to x do begin
  387.          d_ermitteln;
  388.          
  389.          for j := 1 to d-1 do begin
  390.             Write(c);
  391.             GotoXY(WhereX-1, WhereY+dy);
  392.          end;
  393.          
  394.          Write(c);
  395.          
  396.          if i < x then GotoY(WhereY+dy);
  397.       end;
  398.    end;
  399. end;
  400.  
  401. procedure TextRectFill(x, y, w, h : Integer; c : Char);
  402. var
  403.    ox, oy, mx, my, i, j :  Integer;
  404. begin
  405.    ox := WhereX;
  406.    oy := WhereY;
  407.    
  408.    GotoXY(x, y);
  409.    
  410.    x  := WhereX;
  411.    y  := WhereY;
  412.    
  413.    if w < 0 then w := -w;
  414.    if h < 0 then h := -h;
  415.    
  416.    mx := MaxX;
  417.    my := MaxY;
  418.    
  419.    if (x+w) > mx then w := mx-x;
  420.    if (y+h) > my then h := my-y;
  421.    
  422.    for i := 1 to h do begin
  423.       for j := 1 to w do Write(c);
  424.       GotoXY(x, WhereY+1);
  425.    end;
  426.    
  427.    GotoXY(ox, oy);
  428. end;