%begin
%include "irg:imgraph.inc"
%integer or,r,i,x,y,ox,oy,orx,ory
%byte c,b

%routine pp(%integer x,y)
  *move.l d0,d2
  *lsl.l #7,d1
  *andi.l #16_FFFFFFF0,d0
  *lsr.l #3,d0
  *add.l d0,d1
  *lea   frame,a1
  *lea   0(a1,d1.l),a1
  *andi.l #15,d2
  *eor.l  #15,d2
  *clr.l  d1
  *bset   d2,d1
  *move.w d1,(a1)
%end

%integerfunction sign(%integer n)
%integer r
  %if n=0 %then r=0
  %if n<0 %then r=-1
  %if n>0 %then r=1
  %result=r
%end

%routine drawline(%integer x1,y1,x2,y2)
%integer i,x,y,dx,dy,s1,s2,temp,interchange,e
%label l1,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11
!x=x1
    *MOVE.L  D0,x                 
!y=y1
    *MOVE.L  D1,y                 
!dx=|x2-x1|
    *SUB.L   x1,D2                
    *BGE     l1
    *NEG.L   D2                   
L1: *MOVE.L  D2,dx                
!dy=|y2-y1|
    *SUB.L   y1,D3                
    *BGE     l2                   
    *NEG.L   D3                   
L2: *MOVE.L  D3,dy                
!s1=sign(x2-x1)
    *MOVE.L  x2,D0                
    *SUB.L   x1,D0                
    *BSR     sign                 
    *MOVE.L  D0,s1                
!s2=sign(y2-y1)
    *MOVE.L  y2,D0                
    *SUB.L   y1,D0                
    *BSR     sign                 
    *MOVE.L  D0,s2                
!interchange=0
    *CLR.L   interchange          
!%if dy>dx %start
    *MOVE.L  dy,D1                
    *CMP.L   dx,D1                
    *BLE     L3                   
!temp=dx
    *MOVE.L  dx,temp              
!dx=dy
    *MOVE.L  D1,dx                
!dy=temp
    *MOVE.L  temp,dy              
!interchange=1
    *MOVEQ   #1,D2                
    *MOVE.L  D2,interchange       
!%finish
L3:
!e=dy<<1-dx
    *MOVE.L  dy,D1                
    *LSL.L   #1,D1                
    *SUB.L   dx,D1                
    *MOVE.L  D1,e                 
!%for i=1,1,dx %cycle
    *CLR.L   i                    
L4: *MOVE.L  i,D0                 
    *CMP.L   dx,D0                
    *BEQ     l5
    *ADDQ.L  #1,i                 
pp(x,y)
!%while (e>=0) %cycle
L9: *MOVE.L  e,D0                 
    *BLT     L6                   
!%if interchange=1 %then x=x+s1 %else y=y+s2
    *MOVEQ   #1,D1                
    *CMP.L   interchange,D1       
    *BNE     L7                   
    *MOVE.L  s1,D2                
    *ADD.L   D2,x                 
    *BRA     L8                   
L7: *MOVE.L  s2,D2                
    *ADD.L   D2,y                 
L8:
!e=e-dx<<1
    *MOVE.L  dx,D2                
    *LSL.L   #1,D2                
    *SUB.L   D2,e                 
!%repeat
    *BRA     L9                   
L6:
!%if interchange=1 %then y=y+s2 %else x=x+s1
    *MOVEQ   #1,D1                
    *CMP.L   interchange,D1       
    *BNE     L10                   
    *MOVE.L  s2,D2                
    *ADD.L   D2,y                 
    *BRA     L11                   
L10:*MOVE.L  s1,D2                
    *ADD.L   D2,x                 
L11:
!e=e+dy<<1
    *MOVE.L  dy,D2                
    *LSL.L   #1,D2                
    *ADD.L   D2,e                 
!%repeat
    *BRA     L4                   
L5:
%end

!%routine drawline(%integer x1,y1,x2,y2)
!%integer i,x,y,dx,dy,s1,s2,temp,interchange,e
!x=x1
!y=y1
!dx=|x2-x1|
!dy=|y2-y1|
!s1=sign(x2-x1)
!s2=sign(y2-y1)
!interchange=0
!%if dy>dx %start
!  temp=dx
!  dx=dy
!  dy=temp
!  interchange=1
!%finish
!e=dy<<1-dx
!%for i=1,1,dx %cycle
!  plot(x,y)
!  %while (e>=0) %cycle
!    %if interchange=1 %then x=x+s1 %else y=y+s2
!    e=e-dx<<1
!  %repeat
!  %if interchange=1 %then y=y+s2 %else x=x+s1
!  e=e+dy<<1
!%repeat
!%end

!%routine drawcircle(%integer x,y,r)
!%label l1,l2,l3,l10,l20,l30,l4
!%integer xi,yi,di,limit,delta,deltad
!
!xi=0;yi=r;di=(1-r)<<1;limit=0
!l1: plot(x+xi,y+yi)
!    plot(x+xi,y-yi)
!    plot(x-xi,y+yi)
!    plot(x-xi,y-yi)
!    %if yi<=limit %then ->l4
!    %if di<0 %then ->l2 %else %if di>0 %then ->l3 %else ->l20
!l2: delta=di<<1+yi<<1-1
!    %if delta<=0 %then ->l10 %else ->l20
!l3: deltad=di<<1-xi<<1-1
!    %if deltad<=0 %then ->l20 %else ->l30
!l10:xi=xi+1
!    di=di+xi<<1+1
!    ->l1
!l20:xi=xi+1
!    yi=yi-1
!    di=di+xi<<1-yi<<1+2
!    ->l1
!l30:yi=yi-1
!    di=di-yi<<1+1
!    ->l1
!l4:
!%end

%routine drawcircle(%integer x,y,r)
%label l1,l2,l3,l10,l20,l30,l4
%integer xi,yi,di,limit,delta,deltad
!xi=0;yi=r;di=(1-r)<<1;limit=0
    *CLR.L   xi     
    *MOVE.L  D2,yi  
    *MOVEQ   #1,D3                
    *SUB.L   r,D3                 
    *LSL.L   #1,D3                
    *MOVE.L  D3,di                
    *CLR.L   limit                
l1: pp(x+xi,y+yi)
    pp(x+xi,y-yi)
    pp(x-xi,y+yi)
    pp(x-xi,y-yi)
!%if yi<=limit %then ->l4
    *MOVE.L  yi,D0                
    *CMP.L   limit,D0             
    *BLE     l4                   
!%if di<0 %then ->l2 %else %if di>0 %then ->l3 %else ->l20
    *MOVE.L  di,D1                
    *BLT     l2                   
    *BGT     l3                   
    *BRA     l20                  
l2:! delta=di<<1+yi<<1-1
    *MOVE.L  di,D0        
    *LSL.L   #1,D0        
    *MOVE.L  yi,D1        
    *LSL.L   #1,D1        
    *ADD.L   D1,D0        
    *SUBQ.L  #1,D0        
    *MOVE.L  D0,delta     
!%if delta<=0 %then ->l10 %else ->l20
    *BLE     l10          
    *BRA     l20          
l3:! deltad=di<<1-xi<<1-1
    *MOVE.L  di,D0        
    *LSL.L   #1,D0        
    *MOVE.L  xi,D1        
    *LSL.L   #1,D1        
    *SUB.L   D1,D0        
    *SUBQ.L  #1,D0        
    *MOVE.L  D0,deltad    
!%if deltad<=0 %then ->l20 %else ->l30
    *BLE     l20          
    *BRA     l30          
l10:!xi=xi+1
    *ADDQ.L  #1,xi      
!di=di+xi<<1+1
    *MOVE.L  xi,D0 
    *LSL.L   #1,D0 
    *ADD.L   di,D0 
    *ADDQ.L  #1,D0 
    *MOVE.L  D0,di 
!->l1
    *BRA     l1    
l20:!xi=xi+1
    *ADDQ.L  #1,xi
!yi=yi-1
    *SUBQ.L  #1,yi       
!di=di+xi<<1-yi<<1+2
    *MOVE.L  xi,D0   
    *LSL.L   #1,D0   
    *ADD.L   di,D0   
    *MOVE.L  yi,D1   
    *LSL.L   #1,D1   
    *SUB.L   D1,D0   
    *ADDQ.L  #2,D0   
    *MOVE.L  D0,di   
!->l1
    *BRA     l1    
l30:!yi=yi-1
    *SUBQ.L  #1,yi 
!di=di-yi<<1+1
    *MOVE.L  di,D0 
    *MOVE.L  yi,D1 
    *LSL.L   #1,D1 
    *SUB.L   D1,D0 
    *ADDQ.L  #1,D0 
    *MOVE.L  D0,di 
!->l1
    *BRA     l1  
l4:
%end

clear
%for i=0,5,500 %cycle
  drawline(75,300,i,i)
%repeat
x=100;y=100;mousex=x;mousey=y;ox=x;oy=y
%cycle
colour(red)
%cycle
  x=mousex;y=mousey
  getbuttons(b,25)
  plot(x,y)
%repeatuntil b#0
orx=x;ory=y
mousex=orx;mousey=ory
ox=x;oy=y;or=1
wait(100)
%cycle
    x=mousex;y=mousey
    getbuttons(b,25)
    %if x#ox %or y#oy %start
      setcolour(black)
      drawcircle(orx,ory,or)
      setcolour(red)
      r=int(sqrt(|x-orx|*|x-orx|+|y-ory|*|y-ory|))
      drawcircle(orx,ory,r)
      ox=x;oy=y;or=r
    %finish
%repeatuntil b#0
setcolour(green)
drawcircle(orx,ory,or)
%repeat
%endofprogram
