Challenge: 
Winner?: 
No
Code Snippet: 
set display mode 1024,768,32
sync on

backdrop on
color backdrop 0
hide mouse
randomize timer()
set camera range 1, 18000


grass()
get image 1, 0,0,128,128

cloud()
get image 2, 0,0,50,50

cls
ink rgb(0,255,0),0
fern(512,668,7,90,7,50,150)
   fern(511,668,7,90,7,50,150)
   fern(513,668,7,90,7,50,150)
   fern(510,668,7,90,7,50,150)
   fern(514,668,7,90,7,50,150)
   line 512,668,512,768
   box 510,668,514,768
   blur bitmap 0,4

get image 3, 346,376,714,767


#constant N1 = 3
#constant N2 = 4
#constant N3 = 5
#constant N4 = 6

for t = 1 to 6
   null = make vector3(t)
next t


global cStart = 10
global cCount = 400

global fStart = 600
global fCount = 600



for t = cStart to cStart+cCount
   make object plain t, 1000+rnd(1000),1000+rnd(1000)
   position object t, rnd(18000)-7000,rnd(100)+4000,rnd(18000)-7000
   xrotate object t, 90
   texture object t, 2
   ghost object on t, 0
   disable object zwrite t
   set object light t,0
   set object fog t, 0
next t



REM fern
tempObject = 599
make object plain tempObject,50,100
offset limb tempObject,0,0,50,0
texture object tempObject,3
set object transparency tempObject, 1
set object cull tempObject, 0

rem populate ferns
for t = fStart to fStart+fCount step 3
   instance object t,tempObject
   instance object t+1,tempObject
   instance object t+2,tempObject
   x = rnd(4000)
   z = rnd(4000)
   position object t, x, 0, z
   position object t+1, x, 0, z
   position object t+2, x, 0, z

   yrotate object t+1,120 : fix object pivot t+1
   yrotate object t+2,240 : fix object pivot t+2

   x = wrapvalue(rnd(150)-75)
   y = rnd(360)
   z = wrapvalue(rnd(150)-75)
   rotate object t,x,y,z
   rotate object t+1,x,y,z
   rotate object t+2,x,y,z
next t


tx = 100
tz = 100
tsx# = 3000.0/tx
tsz# = 3000.0/tz

mSize = 4000

dim heights#(tx,tz)



make matrix 1, mSize, mSize,tx,tz
`set matrix 1, 0, 0, 1, 1, 1, 1, 1
prepare matrix texture 1,1,1,1


rem water plane
make object plain 2, 18500, 18500
`make object plain 2, 5000,5000

set object fog 2,0
`set object light 2,0
`set object ambient 2, 0
position object 2, 2000,10,2000
xrotate object 2, 270
color object 2, rgb(30,60,250)

rem sky sphere
make object sphere 3, 18000
set object light 3,0
position object 3, 2000,0,2000
set object cull 3, 0
color object 3, rgb(60,120,250)


position camera 0,300,0
point camera 500,100,500


make light 1
`set point light 0,2000,3000,2000
set light range 1, 4000

fog on
fog distance 4000
fog color rgb(230,230,250)



DO


   gosub camera_stuff



   if inkey$()="f" and flag=0
      flag = 1
      x1 = rnd(mSize)
      y1 = rnd(mSize)
      x2 = rnd(mSize)
      y2 = rnd(mSize)
      gosub _calc_matrix
   endif

   if inkey$()="s" and flag2=0
      flag2 = 1
      gosub _smooth_matrix
   endif

   if inkey$()="r" and flag3=0
      flag3=1
      gosub _randomize_matrix
   endif

   if inkey$()="n" and flag4=0 then gosub calc_normals : flag4=1

   if inkey$()="p" and flag5=0 then repopulateFerns() : flag5=1

   if inkey$()<>"f" then flag = 0
   if inkey$()<>"s" then flag2 = 0
   if inkey$()<>"r" then flag3 = 0
   if inkey$()<>"n" then flag4 = 0
   if inkey$()<>"p" then flag5 = 0

   moveClouds()

   set cursor 0,0
   print "FPS: ",screen fps()
   print "X: ",cx#
   print "Z: ",cz#



   angle# = wrapvalue(angle#+0.1)
   lx# = 2000+sin(angle#)*2000
   lz# = 2000+cos(angle#)*2000
   set point light 1, lx#,get ground height(1,lx#,lz#)+1000,lz#




   sync
LOOP



_randomize_matrix:
   for z = 1 to tz-1
      for x = 1 to tx-1
         h# = rnd(50)
         set matrix height 1,x,z,heights#(x,z)+h#
         heights#(x,z) = heights#(x,z)+h#
      next x
   next z
   update matrix 1
RETURN


_calc_matrix:

   h0# = 50
   h1# = 20

   for z = 1 to tz-1
      for x = 1 to tx-1
         px# = x*tsx#
         pz# = z*tsz#
         if point_line(px#,pz#,x1,y1,x2,y2) >= 0
            h# = get matrix height(1,x,z)+h0#
            set matrix height 1, x, z, h#
         else
            h# = get matrix height(1,x,z)-h1#
            set matrix height 1, x, z, h#
         endif
         heights#(x,z) = h#
      next x
   next z

   update matrix 1
RETURN



_smooth_matrix:

   for z = 1 to tz-1
      for x = 1 to tx-1
         count = 0
         h1# = 0
         h2# = 0
         h3# = 0
         h4# = 0
         h5# = 0
         h6# = 0
         h7# = 0
         h8# = 0
         if z < tz
            if x > 0 then h1# = heights#(x-1,z+1) : inc count
            h2# = heights#(x,z+1) : inc count
            if x < tx then h3# = heights#(x+1,z+1) : inc count
         endif

         if x > 0 then h4# = heights#(x-1,z) : inc count
         if x < tx 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 < tx then h8# = heights#(x+1,z-1) : inc count
         endif

         `count=count+5 : h1#=h1#+(5.0*heights#(x,z))

         avg# = (h1#+h2#+h3#+h4#+h5#+h6#+h7#+h8#) / count

         set matrix height 1,x,z,avg#
      next x
   next z

   update matrix 1

   for z = 0 to tz
      for x = 0 to tx
         heights#(x,z) = get matrix height(1,x,z)
      next x
   next z

RETURN



calc_normals2:
   for z = 0 to tz
      for x = 0 to tx
         aa# = rnd(360)
         nx#=0.0 : ny#=(sin(aa#)+1.0)/2.0 : nz#=0.0
         set matrix normal 1, x, z, nx#, ny#, nz#
      next x
   next z
RETURN



calc_normals:
   for z = 1 to tz-1
      for x = 1 to tx-1

         rem upper right
         set vector3 1,x*tsx#,get matrix height(1,x,z+1),(z+1)*tsz#
         set vector3 2,(x+1)*tsx#,get matrix height(1,x+1,z),z*tsz#
         cross product vector3 N1,1,2
         normalize vector3 N1, 1

         rem upper left
         set vector3 1,x*tsx#,get matrix height(1,x,z+1),(z+1)*tsz#
         set vector3 2,(x-1)*tsx#,get matrix height(1,x-1,z),z*tsz#
         cross product vector3 N2,1,2
         normalize vector3 N2, 1

         rem lower left
         set vector3 1,x*tsx#,get matrix height(1,x,z-1),(z-1)*tsz#
         set vector3 2,(x-1)*tsx#,get matrix height(1,x-1,z),z*tsz#
         cross product vector3 N3,1,2
         normalize vector3 N3, 1

         rem lower right
         set vector3 1,x*tsx#,get matrix height(1,x,z-1),(z-1)*tsz#
         set vector3 2,(x+1)*tsx#,get matrix height(1,x+1,z),z*tsz#
         cross product vector3 N4,1,2
         normalize vector3 N4, 1

         rem average 4 normals
         add vector3 N1,N1,N2
         add vector3 N1,N1,N3
         add vector3 N1,N1,N4
         divide vector3 N1,4
         normalize vector3 N1, N1

         nx# = x vector3(N1)
         ny# = y vector3(N1)
         nz# = z vector3(N1)
         set matrix normal 1, x, z, nx#, ny#, nz#
      next x
   next z
   update matrix 1

RETURN





camera_stuff:
  oldcx#=cx#
  oldcz#=cz#
  speed# = 5
  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#+100,cz#
  rotate camera wrapvalue(cxa#),a#,0
RETURN



function point_line(px#,py#, x1#,y1#,x2#,y2#)
   dp# = (x2# - x1#) * (py# - y1#) - (px# - x1#) * (y2# - y1#)
endfunction dp#


function moveClouds()
   for t = cStart to cStart+cCount
      hh# = (object position y(t) - 4000) / 100
      if hh# < 2 then hh# = 0.04
      hh# = (1.04 - hh#)
      position object t, object position x(t),object position y(t),object position z(t)-hh#
      if object position z(t) < -8000 then position object t, rnd(18000)-7000,rnd(100)+4000,11000+rnd(1000)
   next t
endfunction



function grass()
   cls
   ink rgb(30,150,0),0
   box 0,0,128,128
   for t = 1 to 1000
      x = rnd(128)
      y = rnd(128)
      g = rnd(200)+55
      r = rnd(50)+65
      if r > g then r = g
      ink rgb(r,g,rnd(50)),0
      box x,y,x+4,y+4
   next t
   blur bitmap 0,4
endfunction



function cloud()
   cls
   ink rgb(255,255,200),0
   for x=1 to 1000
      ang=rnd(360)
      rad=rnd(20)
      box 25+sin(ang)*rad,25+cos(ang)*rad,rnd(3)+25+sin(ang)*rad,rnd(3)+25+cos(ang)*rad
   next x
   blur bitmap 0,4
endfunction


REM ====== FERN FRACTAL =======
REM X,Y         - starting position for fern, root of first stem
REM passes      - number of iterations
REM startAngle  - angle to start drawing on this pass
REM bendAngle   - overall bending angle of the whole leaf
REM branchAngle - angle to branch off each stem at
REM height      - starting height
function fern(x as float, y as float, passes as integer, startAngle as float, bendAngle as float, branchAngle as float, height as float)

   rootAngle# = wrapvalue(startAngle - bendAngle)

   x2 = x + cos(rootAngle#)*height
   y2 = y - sin(rootAngle#)*height
   line x,y,x2,y2

   height = height*0.5

   x3 = x + cos(wrapvalue(rootAngle#+branchAngle))*height
   y3 = y - sin(wrapvalue(rootAngle#+branchAngle))*height
   line x,y,x3,y3

   x4 = x + cos(wrapvalue(rootAngle#-branchAngle))*height
   y4 = y - sin(wrapvalue(rootAngle#-branchAngle))*height
   line x,y,x4,y4

   if passes > 1
      fern(x2,y2,passes-1, rootAngle#, bendAngle, branchAngle, height)
      fern(x3,y3,passes-1, wrapvalue(rootAngle#+branchAngle), bendAngle, branchAngle, height)
      fern(x4,y4,passes-1, wrapvalue(rootAngle#-branchAngle), bendAngle, branchAngle, height)
   endif

endfunction



function repopulateFerns()
   for t = fStart to fStart+fCount step 3
      x = rnd(4000)
      z = rnd(4000)
      position object t, x, get ground height(1,x,z), z
      position object t+1, x, get ground height(1,x,z), z
      position object t+2, x, get ground height(1,x,z), z

      x = wrapvalue(rnd(90)-45)
      y = rnd(360)
      z = wrapvalue(rnd(90)-45)
      rotate object t,x,y,z
      rotate object t+1,x,y,z
      rotate object t+2,x,y,z
   next t
endfunction