Program Matrix;

uses CRT;

type MLine = record
       C: Char;
       LC: Char;
       X: Byte;
       Y: Byte;
       _Y: Byte;
       L: Byte;
       First: Boolean;
     end;

var
   MLines: array[0..255] of MLine;
   I, MCount, MSpeed: Byte;
   Key: Char;

procedure clearLine(X, F, T: Byte);
var Y: Byte;
begin

     for Y := F to T do
     begin
          if(Y > 24) then break;
          GotoXY(X, Y);
          Write(' ');
     end;

end;

procedure makeMLine(var Line: MLine);
begin
  Line.C := chr(Random(256));
  Line.X := Random(80)+1;
  Line.Y := Random(24)+1;
  Line._Y := Line.Y;
  Line.L := Random(24)+1;
  Line.First := True;
end;

procedure processMLine(var Line: MLine);
begin

  if(Line.Y - Line._Y >= Line.L) then
  begin
    GotoXY(Line.X, Line.Y - Line.L);
    Write(' ');
    GotoXY(1 ,1);
  end;

  if(Line.Y < 24 + Line.L) then
  begin

    if (not Line.First) and
       (Line.Y - 1 <= 24) and
       (Line.Y - 1 <> Line.Y - Line.L) then
    begin
      TextColor(GREEN);
      GotoXY(Line.X, Line.Y-1);
      Write(Line.LC);
    end;

    if(Line.Y <= 24) then
    begin
      TextColor(LIGHTGREEN);
      GotoXY(Line.X, Line.Y);
      Write(Line.C);
    end;

    Line.LC := Line.C;
    Line.C := Chr(Random(256));

    Line.First := False;

    Inc(Line.Y);
  end
  else makeMLine(Line);

  GotoXY(1, 1);

end;

begin

     ClrScr;
     Randomize;
     TextMode(CO80);
     TextBackground(BLACK);

     MCount := 0;
     MSpeed := 150;

     for i := 0 to 255 do
         makeMLine(MLines[i]);

     MLines[0].X := 40;
     MLines[0]._Y := 20;
     MLines[0].Y := 20;
     MLines[0].L := 24;

     while(true) do
     begin
         for i := 0 to MCount do
             processMline(MLines[i]);

         if(KeyPressed) then
         begin
           Key := ReadKey;
           If(Ord(Key) = 0) then Key := ReadKey;

           Case Ord(Key) of
           27: Break;
           80: if(MCount > 0) then
           begin
             clearLine(MLines[MCount].X, MLines[MCount]._Y, MLines[MCount].Y);
             Dec(MCount);
           end;
           72: if(MCount < 255) then Inc(MCount);
           77: if(MSpeed > 5) then Dec(MSpeed, 5);
           75: if(MSpeed < 255) then Inc(MSpeed, 5);
           end;

         end;

         Delay(MSpeed);
     end;

     ClrScr;

     While(KeyPressed) do Delay(1);

     TextColor(WHITE);
     GotoXY(35, 9);
     Write('Ü       Ü');
     GotoXY(34, 10);
     Write('ßßÜÛÛÛÛÛÜßß');
     GotoXY(35, 11);
     Write('ÛÛßÛÛÛßÛÛ');
     GotoXY(35, 12);
     Write('ßÛÛÛßÛÛÛß');
     GotoXY(37, 13);
     Write('ÛÛÛÛÛ');
     GotoXY(34, 14);
     Write('ßÛ ßÜßÜß Ûß');
     TextColor(YELLOW);
     GotoXY(35, 15);
     Write('Developed');
     GotoXY(35, 16);
     Write('By MrKoKa');
     GotoXY(1, 1);

     ReadKey;

end.
