!
! Fractals Program - lets you read in a fractal picture plus its
! data file, and then window off a small portion to be reevaluated.
! 
!
%begin
%include "ng"

%half %array CM (0:255)
%half %name CMp == CM(0)
%byte Clr, Doing, MB, Fixed
%const %byte True = 1, False = 0
%integer MaxCol, Infinity
%byte Type
%integer i,j,k
%short XOff, YOff, wid, ht, OX,OY,MX,MY, PX, PY, P2X, P2Y, NX, NY
%const %half Wh = 31<<10 ! 31<<5 ! 31
%string (255) File,As,Bs
%real p,q,XMin, YMin, XMax, YMax, Xr, Yr, XYRatio
%real X1,x2,y1,y2,t

%shortfn Get Short
%byte a,b
   Read Symbol (a); Read Symbol (b)
   %result = a<<8 ! b
%end

%byte %fn Get Mouse
%byte M,N
%integer i
   %cycle
      M = MsButtons
      N = MsButtons %for i = 1,1,2000
   %repeat %until M = N
   %result = M
%end

%routine Convert
   OX = MX; OY = MY
   MX = Rem((MouseX //3) & 1023,wid)
   MX = MX + wid %if MX < 0
   MX=MX+XOff
   MY = Rem((MouseY //3) & 1023,ht)
   MY = MY + ht %if MY < 0
   MY=MY+YOff
%end

%routine Box (%short X1,Y1,X2,Y2)
   Line (X1,Y1,X1,Y2)
   Line (X1,Y2,X2,Y2)
   Line (X2,Y2,X2,Y1)
   Line (X2,Y1,X1,Y1)
%end

%routine Erase
   Enable (128)
   Colour (127)
   At (OX-8,OY-10)
   Show Symbol (129)
%end

%routine Cursor
   Enable (128)
   Colour (128)
   At (MX-8,MY-10)
   Show Symbol (129)
   Enable (255)
%end

%routine EraseBox
   Enable (128)
   Colour (127)
   Box (PX,PY,OX,OY)
%end

%routine DrawBox
   Enable (128)
   Colour (128)
   Box (PX,PY,MX,MY)
   Enable (255)
%end


%routine Give Coords (%integer Num)
   PrintSymbol (13); PrintSymbol (27); PrintSymbol('t')
   NX = MX-XOff; NY = MY-YOff
   %if Num = 1 %start
      Print(Xmin+NX*Xr,2,7 ); Print(Ymin+NY*Yr,2,7)
   %else
      Print(XMin+P2X*Xr,2,7); Print(YMin+P2Y*Yr,2,7)
      PrintString (" -> ")
      Print(Xmin+NX*Xr,2,7); Print(Ymin+NY*Yr,2,7)
   %finish
%end

%on %event 9 %start
   %if Doing = True %start
      PrintString ("Input Ended at PixelX = ");Write(i,0)
      PrintString (", PixelY = ");Write(j,0);Newline
   %finish
   -> Finished
%finish

Setup; VClear
Hi Font = 128
Append Font ("Pr_1:Cursors")

File = Cliparam
Prompt("File : ") %and Readline (File) %if File = ""

Open input (1,File)
Select Input (0)

   Select input (1)
   wid = Get Short
   ht = Get Short
   Select input (0)
   Newline
   PrintString ("File is ");Write(wid,0)
   PrintString (" by ");Write(ht,0)
   PrintString (" pixels.");Newlines(2)

CM(i) = Wh %for i = 0,1,255
CM(128) = Wh
   Select input (1)
   CM(i) = Get Short %for i = 0,1,127
   CMp == CM(0)
   Update Colour Map (CMp)
   CM(i) = Get Short %for i = 128,1,255
   Select input (0)
Prompt ("Clear Screen? (Y/N) : ")
Readsymbol (Clr) %and Clr = Clr & 95 %until Clr = 'Y' %or Clr = 'N'
Clear %if Clr = 'Y'

XOff = 0
XOff = (688-Wid)>>1 %if Wid < 688
YOff = 0
YOff = (512-Ht)>>1 %if Ht < 512

Doing = True
Select input (1)
%for i = 0,1,wid-1 %cycle
   %for j = 0,1,ht-1 %cycle
      readsymbol(k)
      colour (k&127);plot(i+XOff,j+YOff)
   %repeat
%repeat
Finished:
Close input
Select input (0)

Prompt ("Data File : "); Read (File)
%if File -> As.(".").Bs %then File = As.".".Bs %else File = File.".Dat"
Open Input (3,file)
Select Input (3)
%cycle
   SkipSymbol %while Next Symbol = ' ' %or Next Symbol = NL
   %exit %unless Next Symbol = '!'
   SkipSymbol %until Next Symbol = NL
%repeat
Read (type)
Read (infinity)
Read (maxcol)
Read (XMin)
Read (XMax)
Xr = (xMax - xMin)/wid
Read (yMin)
Read (yMax)
Yr = (yMax - yMin)/ht
%if Type = 1 %start
   Read (p)
   Read (q)
%finish

XYRatio = Xr/Yr
Close Input
Select Input (0)
PrintString ("X Values : ");Print(Xmin,2,7);Print(Xmax,2,7);Newline
PrintString ("Y Values : ");Print(ymin,2,7);Print(ymax,2,7);Newline

MX = 0; MY = 0
Fixed = False
%cycle
   Convert
   MB = Get Mouse
   %if Fixed = False %start
      %if OX # MX %or OY # MY %start
         Erase
         Give Coords (1)
         Cursor %if MB = MsNone
      %else
         Erase %if MB # MsNone
      %finish
      %if MB # MsNone %start
         PX = MX; PY = MY
         P2X = PX-XOff
         P2Y = PY-YOff
      %finish
   %else
      %if OX # MX %or OY # MY %start
         EraseBox
         Give Coords (2)
         %if MB = MsNone %then DrawBox
      %else
         %continue %if MB = MsNone
         %if MB = MsLMR %then EraseBox %elsestart
            Give Coords (2)
            %cycle; %repeat %until MsButtons = MsNone
            %cycle; %repeat %until TestSymbol = -1
            Newlines(2)
            Prompt ("Output File : ");ReadLine (File)
%if File -> As.(".").Bs %then File = As.".".Bs %else File = File.".Dat"
            %if File # "" %start
               Open Output (3,File)
               Select Output (3)
               Write(Type,0);Newline
               Write(Infinity,0);Newline
               Write(MAxcol,0);Newline
               X1 = XMin+P2X*Xr; Y1 = YMin+P2Y*Yr
               X2 = XMin+(MX-XOff)*Xr; Y2 = YMin+(MY-YOff)*Yr
               t = X1 %and X1 = X2 %and X2 = t %if X2 < X1
               t = Y1 %and Y1 = Y2 %and Y2 = t %if Y2 < Y1
               Print(X1,4,7);Print(X2,4,7);Newline
               Print(Y1,4,7);Print(Y2,4,7);Newline
               %if Type = 1 %start
                  Print(p,4,7);Print(q,4,7);Newline
               %finish
               Close Output
               Select Output (0)
            %finish
            EraseBox
            MB = MsButtons %until MB # MsNone
         %finish      
      %finish
   %finish
   %if MB # MsNone %start
      Fixed = 1 - Fixed
      %cycle; %repeat %until MsButtons = MsNone
   %finish
%repeat

%endofprogram
