!****************************************************************
!*                                                              *
!*      IFF3D:  Take an IFF image and display it in pseudo-3D   *
!*                                                              *
!*                  Version 1.1 14 May 1987                     *
!*                                                              *
!****************************************************************

%begin
%include "inc:random.imp"
%include "level1:graphinc.imp"
%include "inc:util.imp"
%include "iffinc.imp"

%record (iffhdr fm) iffhdr
%integer widht,skip,rc
%integer linelength,ref,size,i,rlleft,rlno,xo,ys
%integer hptr,hlen,no,type,plen
%bytearray vala(0:511)
%integer vali,wid,ht
%string (255) vals
%half %array CM (0:255)
%half %name CMp

%routine newthing(%integer xl,yb,xr,yt,xo,ys,pp)
%integer i,j,x,y,b,zero,c
i=xl %and xl=xr %and xr=i %if xl > xr
i=yb %and yb=yt %and yt=i %if yb > yt
enable(255)


%begin
%integer p,q,x00,x01,x10,x11, y00,y01,edge,pu,pd,pl,pr
%integer origin x, origin y, xfact,xfact2,{yfact,}yfact2
%shortarray pointx(0:xr-xl, 0:yt-yb)
%shortarray pointy(0:yt-yb)
colour map(255) = 31<<10
colour(255)
fill(0,0,687,511)
!The *1024's and >>10's are scaling to avoid reals
xfact = int(640/(xr-xl)*1024) {10}
{yfact = 1}
xfact2 = int(384/(xr-xl)*1024) {6}
yfact2 = int(384/(yt-yb)*1024) {8}

origin x = 10 * 1024
origin y = 10 * 1024

!Set up a flat plane of points skewed to give isomorphic (3D) view
%for i=yt-yb,-1,0 %cycle
   pointy(i) =  origin y >>10+ i+yb-yt
   q=origin x
   %for j=0,1,xr-xl %cycle
      pointx(j,i) = q>>10
      q=q+xfact
   %repeat
   origin x = origin x + xfact2
   origin y = origin y + yfact2
%repeat

! xl,yb  --------- xr,yb      i ->
!   |    + + + + +   |
!   |    + + + + +   |        j            x00 x10
! xl,yt  --------- xr,yt      |            x01 x11
!                             v
!                      eye

!Draw a flat plane in the correct colours (testing)
%for j=0,1,yt-yb-1 %cycle
   %for i=0,1,xr-xl-1 %cycle
      x00=pointx(i,j)-xo; x10=pointx(i+1,j)-xo
      x01=pointx(i,j+1)-xo; x11=pointx(i+1,j+1)-xo
      y00=pointy(j)
      y01=pointy(j+1)
      %continue %if x00<0 %or x01<0
      %exit %if x00 > 687 %and x01>687
      p = byteinteger(pp+(j+yb)*iffhdr_wid+i+xl)
      colour(p)
      trapeze(x00, x10, y00, x01, x11, y01)
   %repeat
   %exit %if y01 < 0
%repeat

%for j=0,1,yt-yb-1 %cycle
   %for i=0,1,xr-xl-1 %cycle
      x00=pointx(i,j)-xo; x10=pointx(i+1,j)-xo
      x01=pointx(i,j+1)-xo; x11=pointx(i+1,j+1)-xo
      y00=pointy(j)
      y01=pointy(j+1)
      %continue %if x00<0 %or x01<0
      %exit %if x00 > 687 %and x01>687
      q = byteinteger(pp+(j+yb)*iffhdr_wid+i+xl); p=(q*ys)>>2
      colour(q)
      !Top of block
      trapeze(x00, x10, y00+p, x01, x11, y01+p)

      !Visible portion of front of block
!      %if q<128 %then c=q %else c=128+(j+yb)>>1
!      c=255 %if c>255
!      colour(c)
      fill (x01, y01, x11, y01+p)

      !Right face of block if visible
!      c=c+24; c=255 %if c>255
!      colour(c)
      
      pr = byteinteger(pp+(j+yb)*iffhdr_wid+i+xl+1)
      triangle(x11,y01, x11,y01+p, x10,y00+p) %if p>pr>>2
      triangle(x10,y00+p, x10,y00, x11,y01)   %if p>pr>>2
      

      %unless p=0 %start
         pl = byteinteger(pp+(j+yb)*iffhdr_wid+i+xl-1)
         pu = byteinteger(pp+(j+yb-1)*iffhdr_wid+i+xl)
         pd = byteinteger(pp+(j+yb+1)*iffhdr_wid+i+xl)
         colour(0)
         !Top edge of block if distinct from neighbours
         hline(x00, x10,y00+p) %unless p=pu>>2
         line(x10,y00+p, x11,y01+p) %unless p=pr>2
         hline(x11, x01,y01+p) %unless p=pd>>2
         line(x01,y01+p, x00,y00+p) %unless p=pl>>2
   
         !Vertical edges of block
         vline(x10,y00,y00+p)
         vline(x01,y01,y01+p)
         vline(x11,y01,y01+p)
      %finish

   %repeat
%repeat

%end
%end

%routine Set Up
%integer i
%integer zero = 0
  %on 0 %start
    Print String ("Software requires a graphics system")
    Newlines (2)
    %stop
  %finish
  Offset (0,0)
  enable(16_FF)
  Colour (White)
  %for i = 0, 8, 248 %cycle
     Colour Map (i) = zero
     Colour Map (i+1) = 31
     Colour Map (i+2) = 31<<5
     Colour Map (i+3) = 31<<5+31
     Colour Map (i+4) = 31<<10
     Colour Map (i+5) = 31<<10+31
     Colour Map (i+6) = 31<<10+31<<5
     Colour Map (i+7) = 31<<10+31<<5+31
  %repeat
  Set Terminal Mode (Nopage)
%end

%routine Mix Colour (%byte Col, %integer Red, Green, Blue)
   Colour Map(Col)=Red+Green<<5+Blue<<10
%end

%integer len,j,c,xl,xr,yb,yt,maplen,cval,max,xoff,yoff,ad

Setup
Clear

ad=0
rc = iff readin(cli param, iffhdr, ad)
iff show header(iffhdr, 0)
%if iffhdr_mapaddr = 0 %start
   !No colour map - construct grey scale
   %for i=0,1,255 %cycle; c = i>>3; CM(i) = (c<<5 + c)<<5 + c; %repeat
   update colour map(cm(0))
%else
   cmp == halfinteger(iffhdr_mapaddr)
   update colour map(cmp)
%finish

wid=iffhdr_wid; ht=iffhdr_ht
max=wid*ht
XOff = 0
XOff = (688-Wid)>>1 %if Wid < 688
YOff = 0
YOff = (512-Ht)>>1 %if Ht < 512
   
col fill(0, 0, wid-1, ht-1, byteinteger(ad))

%cycle
prompt("xl:"); read(xl)
prompt("yb:"); read(yb)
prompt("xr:"); read(xr)
prompt("yt:"); read(yt)
prompt("x_offset:"); read(xo)
prompt("y_scale:"); read(ys)

newthing(xl,yb,xr,yt,xo,ys,ad)
%repeat

test:
!!initialise random
!!%for i=0,1,max-1 %cycle; %for j=0,1,max-1 %cycle
!!   pic2(i,j) = {random int(0,255)} 191
!!%repeat; %repeat
!!
!!newthing(0,0,max-1,max-1,pic2)

%endofprogram
