sync on
sync rate 60
autocam off
hide mouse
randomize timer()
`load image "Grass.bmp",1
ink rgb(0,255,0),0
box 0,0,100,100
get image 1,0,0,100,100
make matrix 1, 1000, 1000, 60, 60
prepare matrix texture 1, 1, 1, 1
smooth_matrix(1,2,60,60)
update matrix 1
color backdrop 0
make light 1
hide light 0
lightz=0
light=0
 
DO
   if light=0
   if lightz<50
   lightz=lightz+1
   else light=1
   endif
   endif
   if light=1
   lightz=lightz-1
   if lightz<2
   light=0
   endif
   endif
   position light 1,0,0,lightz
   shadow(1,2,10,30,30)
   shadow(3,4,50,100,100)
 
   gosub camera_stuff
   sync
LOOP
 
function smooth_matrix(number as integer, iter as integer, xsegs as integer, zsegs as integer)
 
   dim heights#(xsegs, zsegs)
 
   rem store original heights
   for z = 0 to zsegs
      for x = 0 to xsegs
         heights#(x,z) = get matrix height(number,x,z)
      next x
   next z
 
   for t = 1 to iter
      for z = 0 to zsegs
         for x = 0 to xsegs
            count = 0
            h1# = 0
            h2# = 0
            h3# = 0
            h4# = 0
            h5# = 0
            h6# = 0
            h7# = 0
            h8# = 0
 
           if z < zsegs
               if x > 0 then h1# = heights#(x-1,z+1) : inc count
               h2# = heights#(x,z+1) : inc count
               if x < xsegs then h3# = heights#(x+1,z+1) : inc count
            endif
 
            if x > 0 then h4# = heights#(x-1,z) : inc count
            if x < xsegs then h5# = heights#(x+1,z) : inc count
 
            if z > 0
               if x > 0 then h6# = heights#(x-1,z-1) : inc count
               h7# = heights#(x,z-1) : inc count
               if x < xsegs then h8# = heights#(x+1,z-1) : inc count
            endif
 
            avg# = (h1#+h2#+h3#+h4#+h5#+h6#+h7#+h8#) / count
 
            set matrix height number,x,z,avg#
            heights#(x,z) = avg#
 
         next x
      next z
   next t
 
   rem delete array
   undim heights#()
 
endfunction
 
camera_stuff:
  oldcx#=cx#
  oldcz#=cz#
  speed# = 5
 
  if shiftkey() then speed# = 10
  if upkey()=1
    cx#=newxvalue(cx#,a#,speed#)
    cz#=newzvalue(cz#,a#,speed#)
  endif
  if downkey()=1
    cx#=newxvalue(cx#,a#,-speed#)
    cz#=newzvalue(cz#,a#,-speed#)
  endif
  if leftkey()=1
    cx#=newxvalue(cx#,wrapvalue(a#-90.0),speed#)
    cz#=newzvalue(cz#,wrapvalue(a#-90.0),speed#)
  endif
  if rightkey()=1
    cx#=newxvalue(cx#,wrapvalue(a#+90.0),speed#)
    cz#=newzvalue(cz#,wrapvalue(a#+90.0),speed#)
  endif
 
   `if shiftkey() then inc cy#, 2
   `if controlkey() then dec cy#, 2
 
  a#=wrapvalue(a#+(mousemovex()/3.0))
  cxa#=cxa#+(mousemovey()/3.0)
  if cxa#<-90.0 then cxa#=-90.0
  if cxa#>90.0 then cxa#=90.0
  cy# = get ground height(1,cx#,cz#)
  position camera cx#,cy#+50,cz#
  rotate camera wrapvalue(cxa#),a#,0
RETURN
 
 
function shadow(objnum,shadownum,objsize,xpos,ypos)
if object exist(objnum)=0
make object sphere objnum,objsize
ypos=get ground height(1,xpos,ypos)
position object objnum,xpos,ypos+objsize/2,xpos
endif
if object exist(shadownum)=0
make object sphere shadownum,objsize
endif
litpos=light position z(1)
objsize=object size(objnum)
objposz=object position z(objnum)
objposy=object position y(objnum)
objposx=object position x(objnum)
scale object shadownum,100,10,160
set object ambient shadownum,0
yrotate object shadownum,litpos*1.5
position object shadownum,objposx+litpos*.18*objsize*.1,objposy-objsize,objposz+objsize*1.2-litpos*.12*objsize*.2
color object shadownum,RGB(0,0,0)
sync
endfunction