{** A HARMONOGRAPH program **}
{** PR August 84           **}

%begin
   %include "inc:util.imp"
   %include "level1:graphinc.imp"
   %include "inc:random.imp"
   %include "Inc:Maths.Imp"

   %const %integer C=255,                 {** Must be a power of 2 minus 1 **}
                   Q=C//4,
                   OffX=160,
                   OffY=256,
                   X=343+OffX,
                   Y=256+OffY,
                   A=160,
                   Value=5000

   %integer R1,R2,R3,R4,A1,A2,A3,A4,B,I
 
   %integer Old X, Old Y, New X, New Y
   %byte Col

   %integer T1, T2, T3, T4

   %real F1, F2, X1, X2, X3, X4, Y1, Y2, Y3, Y4

   %real %array SN (0:C)

   %routine Set Up
   %integer i
   %integer z = 0
     %on 0 %start
       Print line ("Software requires a graphics system")
       %stop
     %finish
     Offset (0,0)
     enable(16_FF)
     colour (White)
     %for i = 0, 16, 240 %cycle
        Colour Map (0+i)  = z
        Colour Map (1+i)  = 31
        Colour Map (2+i)  = 31<<5
        Colour Map (3+i)  = 31<<5+31
        Colour Map (4+i)  = 31<<10
        Colour Map (5+i) = 31<<10+31
        Colour Map (6+i) = 31<<10+31<<5
        Colour Map (7+i) = 31<<10+31<<5+31
        Colour Map (8+i) = 31<<10+31<<5+31
        Colour Map (9+i) = 31<<10+31<<5
        Colour Map (10+i) = 31<<10+31
        Colour Map (11+i) = 31<<10
        Colour Map (12+i) = 31<<5+31
        Colour Map (13+i) = 31<<5
        Colour Map (14+i) = 31
        Colour Map (15+i) = z
     %repeat
   %end
   
   SetUp
   Clear
   Initialise Random

   PrintSymbol (27); PrintSymbol('v'); Newlines (3)
   Printline("Harmonograph Program"); Newline
   Printline("Hit any key for a new pattern")
   Printline("Ctrl-Y to exit program"); Newline

   OffSet (OffX,OffY)
   SN(I) = Sin (I*2*Pi/C) %for I = 0,1,C

   %cycle
      colour (Black)
      Col = Random Int (1,7)
      R1 = Random Int (1,C);        R2 = (R1 + Q) & C
      R3 = Random Int (1,C);        R4 = (R3 + Q) & C
      A1 = Random Int (1, A);       A2 = Random Int (1, A)
      A3 = Random Int (1, A);       A4 = Random Int (1, A)
      F1 = Random Real (0,1) * 7;   F2 = Random Real (0,1) * 9
      X1 = SN(R1) * A1;             X2 = SN(R2) * A2
      X3 = SN(R3) * A3;             X4 = SN(R4) * A4
      Y1 = SN((Q+R1)&C)*A1;      Y2 = SN((Q+R2)&C)*A2
      Y3 = SN((Q+R3)&C)*A3;      Y4 = SN((Q+R4)&C)*A4
      B = Random Int (1,C)
      Old X = X; Old Y = Y; New X = X; New Y = Y
      %for I = 0,1,Value %cycle
         T1 = Int (F1 * I) & C;     T2 = Int (B + F2 * I) & C
         T3 = Int (Q + T1) & C;     T4 = Int (Q + T2) & C
         New X = Int(X1 * SN(T1) + X2*SN(T3) + X3*SN(T2) + X4*SN(T4) + X)
         New Y = Int(Y1 * SN(T1) + Y2*SN(T3) + Y3*SN(T2) + Y4*SN(T4) + Y)
         Line (Old X, Old Y, New X, New Y)
         colour (Col)
         Old X = New X; Old Y = New Y
         %exit %if Test Symbol <> -1
      %repeat
      Clear
   %repeat
%endofprogram
