%begin
   %include "fmacs:frame"
   %const %integer max vertex = 128,
                   insert limit = 5
   %record %format edge(%integer x0, y0, x1, y1, slope, %record(edge) %name l)
   %record(edge) niledge
   %own %integer pp = 0, trace = 0
   %record(edge) %array edges(1:max vertex)

   %integer %function muldiv(%integer a, b, c)
      *muls d1,d0
      *divs d2,d0
      *extl d0
      *add.l #12,a7
      *rts
      %result = a*b//c
   %end

   %routine sort edges(%integer l, r)
      %record(edge) key
      %integer key y, lp, rp, i

      %return %unless l<r
      %while r-l>insert limit %cycle
         lp = l
         rp = r+1
         key = edges(l)
         key y = key_y0
         %cycle
            rp = rp-1 %until rp=lp %or key y>edges(rp)_y0 %or %c
                          (key y=edges(rp)_y0 %and key_x0>edges(rp)_x0) %or %c
                          (key y=edges(rp)_y0 %and key_x0=edges(rp)_x0 %and %c
                           key_slope>edges(rp)_slope)
            %exit %if lp=rp
            edges(lp) = edges(rp)
            lp = lp+1 %until rp=lp %or key y<edges(lp)_y0 %or %c
                          (key y=edges(lp)_y0 %and key_x0<=edges(lp)_x0) %or %c
                          (key y=edges(lp)_y0 %and key_x0=edges(lp)_x0 %and %c
                           key_slope<=edges(rp)_slope)
            %exit %if lp=rp
            edges(rp) = edges(lp)
         %repeat
         edges(lp) = key
         %if lp-l>r-rp %start
            sort edges(rp+1, r)
            r = lp-1
         %finish %else %start
            sort edges(l, lp-1)
            l = rp+1
         %finish
      %repeat
      %for rp = l+1, 1, r %cycle
         key = edges(rp)
         key y = key_y0
         lp = l
         lp = lp+1 %while lp#rp %and (key y>edges(lp)_y0 %or %c
                           (key y=edges(lp)_y0 %and key_x0>edges(lp)_x0) %or %c
                           (key y=edges(lp)_y0 %and key_x0=edges(lp)_x0 %and %c
                            key_slope>edges(lp)_slope))
         %for i = rp-1, -1, lp %cycle
            edges(i+1) = edges(i)
         %repeat
         edges(lp) = key
      %repeat
   %end

   %routine poly(%integer x, y)
      %signal 11, 1 %if pp=max vertex
      pp = pp+1
      edges(pp)_x0 = x
      edges(pp)_y0 = y
   %end

   %routine close poly
      %record %format hl(%integer x0, x1, y)
      %record(edge) %name el, ael, e0, e1, nilael, p, l, q, r, s
      %record(hl) top, btm
      %integer i, x0, x1, y0
      %record(edge) %name d

      %routine set ends(%record(edge)%name e, %integer x, y)
         %if e_y0<y %or (e_y0=y %and e_x0<=x) %start
            e_x1 = x
            e_y1 = y
         %finish %else %start
            e_x1 = e_x0
            e_y1 = e_y0
            e_x0 = x
            e_y0 = y
         %finish
         %if e_y0=e_y1 %start
            e_slope = 0
         %finish %else %start
            e_slope = (e_x1-e_x0)//(e_y1-e_y0)
         %finish
      %end

      %routine check top(%record(edge) %name e)
         %record(edge) %name p, l
         %if e_y1>top_y %start
            e_x0 = e_x0+muldiv(e_x1-e_x0, top_y-btm_y, e_y1-btm_y)
            e_y0 = top_y
            p == el
            %while %not p==niledge %and (p_y0<top_y %or %c
                       (p_y0=top_y %and p_x0<e_x0) %or %c
                       (p_y0=top_y %and p_x0=e_x0 %and p_slope<e_slope)) %cycle
               l == p
               p == p_l
            %repeat
            e_l == p
            %if p==el %then el == e %else l_l == e
         %finish %else %start
            e_x0 = e_x1
         %finish
      %end

      %return %if pp=0
      %if pp=1 %start
         plot(edges(1)_x0, edges(1)_y0)
      %finish %else %start
         e1 == edges(1)
         x0 = e1_x0
         y0 = e1_y0
         %for i = 1, 1, pp %cycle
            e0 == e1
            e1 == edges(i)
            set ends(e0, e1_x0, e1_y0)
         %repeat
         set ends(e1, x0, y0)
         sort edges(1, pp)
         e1 == edges(1)
         el == e1
         e0 == e1 %and e1 == edges(i) %and e0_l == e1 %for i = 2, 1, pp
         e1_l == niledge
 disable(7)
 x0=currentcolour
 set colour(8)
 line(edges(i)_x0, edges(i)_y0, edges(i)_x1, edges(i)_y1) %for i= 1, 1, pp
 disable(8)
 set colour(x0)

         %cycle
            ael == el
            btm_y =ael_y0
            x0 = ael_x0
            x1 = x0
            el == el_l %until el==niledge %or el_y0#btm_y
            nilael == el
            %cycle
               %while %not ael==nilael %and ael_y1=btm_y %and ael_x0<=x1 %cycle
                  x1 = ael_x1 %if x1<ael_x1
                  ael == ael_l
               %repeat
               %exit %if ael==nilael
               e0 == ael
               ael == ael_l
               %if e0_y1=btm_y %start
                  %exit %if ael==nilael
                  line(x0, btm_y, x1, btm_y) %unless x0=x1
                  x0 = ael_x0
                  x1 = x0
                  %continue
               %finish

               %while %not ael==nilael %and ael_y1=btm_y %cycle
                  x1 = ael_x1 %if x1<ael_x1
                  ael == ael_l
               %repeat
               e1 == ael
               ael == ael_l
               line(x0, btm_y, e0_x0, btm_y) %if x0<e0_x0 %and x0<x1
               x0 = e1_x0
               x1 = x0 %if x1<x0
               %if e0_y1<e1_y1 %start
                  top_y = e0_y1
               %finish %else %start
                  top_y = e1_y1
               %finish
               top_y = nilael_y0 %unless nilael==niledge %or top_y<nilael_y0
               btm_x0 = e0_x0
               check top(e0)
               top_x0 = e0_x0
               btm_x1 = e1_x0
               check top(e1)
               top_x1 = e1_x0
               trapeze(btm, top)
               p == el
               %while %not p==niledge %and p_y0<=top_y %cycle
                  %if p_y0=top_y %and p_y1=top_y %start
                     %if top_x0<=p_x0 %and p_x1<=top_x1 %start
                        %if p==el %start
                           el == p_l
                        %finish %else %start
                           l_l == p_l
                        %finish
                     %finish %else %if top_x0<=p_x1<=top_x1 %start
                        p_x1 = top_x0
                     %finish %else %if top_x0<=p_x0<=top_x1 %start
                        p_x0 = top_x1
                     %finish %else %if p_x0<=top_x0 %and top_x1<=p_x1 %start
                        pp = pp+1
                        q == edges(pp)
                        q_x0 = top_x1
                        q_y0 = top_y
                        q_x1 = p_x1
                        q_y1 = top_y
                        p_x1 = top_x0
                        r == p_l
                        %while %not r==niledge %and r_y0=top_y %and %c
                                                          r_x0<top_x1 %cycle
                           s == r
                           r == r_l
                        %repeat
                        q_l == r
                        %if r==p_l %then p_l == q %else s_l == q
                     %finish
                  %finish
                  l == p
                  p == p_l
               %repeat
            %repeat %until ael==nilael
            line(x0, btm_y, x1, btm_y) %unless x0=x1
         %repeat %until el==niledge
      %finish
      pp = 0
   %end

   setup
   clear
   set colour(red)

  poly(20, 20)
  poly(40, 20)
  poly(20, 10)
  poly(20, 20)
  poly(40, 10)
  poly(40, 20)
  close poly

  poly(60, 30)
  poly(80, 30)
  poly(80, 10)
  poly(100, 10)
  poly(100, 30)
  poly(120, 30)
  poly(120, 20)
  poly(60, 20)
  close poly

  poly(140, 10)
  poly(160, 10)
  poly(160, 30)
  poly(180, 30)
  poly(180, 10)
  poly(200, 10)
  poly(200, 20)
  poly(140, 20)
  close poly

  poly(220, 10)
  poly(240, 10)
  poly(240, 20)
  poly(220, 20)
  poly(280, 20)
  poly(260, 20)
  poly(260, 10)
  poly(280, 10)
  close poly

  poly(320, 10)
  poly(300, 20)
  poly(340, 40)
  poly(360, 30)
  close poly

  poly(380, 20)
  poly(400, 10)
  poly(420, 20)
  poly(440, 10)
  poly(460, 20)
  poly(480, 10)
  poly(500, 20)
  poly(500, 30)
  poly(380, 30)
  close poly

  poly(520, 20)
  poly(540, 10)
  poly(560, 30)
  poly(580, 10)
  poly(600, 30)
  poly(620, 10)
  poly(640, 20)
  poly(640, 30)
  poly(520, 30)
  close poly

  poly(660, 30)
  poly(680, 40)
  poly(720, 20)
  poly(700, 10)
  close poly

  poly(20, 70)
  poly(60, 50)
  poly(100, 70)
  poly(140, 50)
  poly(180, 70)
  poly(220, 50)
  poly(260, 70)
  poly(240, 80)
  poly(200, 60)
  poly(160, 80)
  poly(120, 60)
  poly(80, 80)
  poly(40, 60)
  close poly

  poly(260, 50)
  poly(300, 60)
  poly(340, 50)
  poly(320, 70)
  poly(340, 90)
  poly(300, 80)
  poly(260, 90)
  poly(280, 70)
  close poly

  poly(360, 60)
  poly(380, 50)
  poly(400, 60)
  poly(420, 50)
  poly(440, 60)
  poly(420, 70)
  poly(440, 80)
  poly(420, 90)
  poly(400, 80)
  poly(380, 90)
  poly(360, 80)
  poly(380, 70)
  close poly

  poly(500, 60)
  poly(520, 50)
  poly(540, 80)
  poly(560, 50)
  poly(580, 80)
  poly(600, 50)
  poly(620, 60)
  poly(620, 70)
  poly(500, 70)
  close poly

  poly(20, 100)
  poly(40, 140)
  poly(60, 100)
  poly(80, 140)
  poly(100, 100)
  poly(120, 140)
  poly(140, 100)
  poly(160, 100)
  poly(30, 110)
  poly(160, 120)
  poly(30, 130)
  poly(160, 140)
  poly(160, 150)
  poly(20, 150)
  close poly

! %cycle
!    %cycle
!       read(x)
!       %exit %if x<0
!       read(y)
!       %exit %if y<0
!       poly(x, y)
!    %repeat
!    close poly
! %repeat %until y<0
%end %of %program
