! Shape drawing package

%externalintegerfnspec heapget(%integer bytes)
%externalroutinespec paint %alias "fred_graphics_paint"-
 (%integername pattern, %integer x0,y0,x1,y1,offset,stride)

%recordformat shape(%integer w,h,i,n,%integerarray a(1:*))

%externalrecord(shape)%map makeshape(%integer w,h)
%record(shape)%name s
%integer i,b
  i = (w+31)>>5<<2; !bytes per scan line
  b = i*h;          !bytes for array
  s == record(heapget(b+16))
  s_w = w; s_h = h
  s_i = i;          !byte stride for paint
  s_n = b>>2;       !number of array elements
  s_a(i) = 0 %for i = 1,1,s_n
  *move.l s,d0
  %result == s
%end

%externalrecord(shape)%map readshape
%record(shape)%name s
%integer w,h,i

  %integerfn readlong
  %integer k
    k = readsymbol<<8
    k = (readsymbol+k)<<8
    k = (readsymbol+k)<<8
    %result = readsymbol+k
  %end

  w = readlong; h = readlong
  s == makeshape(w,h)
  s_a(i) = readlong %for i = 1,1,s_n
  *move.l s,d0
  %result == s
%end

%externalroutine drawshape(%record(shape)%name s,%integer x,y)
  paint(s_a(1),x,y,x+s_w-1,y+s_h-1,0,s_i)
%end

%integermap shapedot(%record(shape)%name s,%integer x,y,
  %integername bit)
  bit = 1<<(x&31)
  %result == s_a(s_i>>2*y+x>>5)
%end

%externalroutine setdot(%record(shape)%name s,%integer x,y)
%integer bit
%integername word
  word == shape dot(s,x,y,bit); word = word!bit
%end

%externalroutine cleardot(%record(shape)%name s,%integer x,y)
%integer bit
%integername word
  word == shape dot(s,x,y,bit); word = word&(\bit)
%end

%externalpredicate dotset(%record(shape)%name s,%integer x,y)
%integer bit
%integername word
  word == shape dot(s,x,y,bit)
  %trueif word&bit#0; %false
%end

