`Racing Challenge by Ric
 
detail=40
 
`display settings
if check display mode(1024,768,32)=1 then set display mode 1024,768,32
sync on
sync rate 50
hide mouse
 
autocam off
hide light 0
color backdrop 0
set ambient light 0
make light 1
set light range 1,3
`set initial value for image numbers
global image_seed
image_seed=1000000
 
create bitmap 1,screen width(),screen height()
 
position light 1,0,0,-1
set light range 1,2
 
make object sphere 1,1,100,100
set object specular power 1,20
set object specular 1,rgb(255,255,255)
position camera 0,0,-2
sync
sun=free_image()
get image sun,screen width()/4,screen height()/4,screen width()*.75,screen height()*.75,1
set object light 1,0
sync
flare1=free_image()
get image flare1,screen width()/4,screen height()/4,screen width()*.75,screen height()*.75,1
delete object 1
 
delete bitmap 1
text 0,0,"Please wait ......"
sync
 
`camera and light settings
 
set camera range 0.01,10000
position camera 64,0,64
color backdrop 0
set ambient light 20
 
 
`set size of terrain
global matrixsize
matrixsize=128
 
`fog settings
fog on
fog color rgb(200,200,200)
fog distance matrixsize
 
`set initial value for object numbers
global object_seed
object_seed=1000000
 
 
 
`position light for world illumination
position light 1,200,30,200
set light range 1,100000
make object cube 2000,1
hide object 2000
position object 2000,light position x(1),light position y(1),light position z(1)
 
global skyimage
create_sky()
 
 
global height#
global rows
global columns
global terrainimage
`set size of terrain
rows=detail
columns=detail
global peaksoff
global peaksoff2
global dim peakx(100)
global dim peakz(100)
global dim peakh(100)
global dim peakx2(100)
global dim peakz2(100)
global dim peakh2(100)
terraform()
create_trench()
Matrix_to_Object(1000,1,128,128,rows,rows,rows,rows,rows,rows)
 
 
ink rgb(255,255,255),0
 
gosub calculate_shadows
delete object 1000
set current bitmap 0
 
global sphere1
global sphere2
global sphere3
create_skysphere()
 
sunplane=free_object()
make object plain sunplane,160*4/3.0,160
set object fog sunplane,0
texture object sunplane,sun
set object light sunplane,0
ghost object on sunplane,2
set object transparency sunplane,2
flareplane1=free_object()
make object plain flareplane1,0.3*4/3.0,0.3
texture object flareplane1,flare1
set object light flareplane1,0
set alpha mapping on flareplane1,20
position object flareplane1,0,-0.5,0
`reference object for distant light source
dummy=free_object()
make object cube dummy,1
hide object dummy
point object dummy,light position x(1),light position y(1),light position z(1)
move object dummy,10000
 
 
 
position camera 64,height#+2+get ground height(1,64,64),64
 
`boaty and watery stuff
 
 
`set mouse position to centre
position mouse 0.5*screen width(),0
 
 camdist#=4 `cam distance
 camheight#=2 `cam height
 smoothness=50 `chasecam smoothness
 
 
 `wavegenerator1 x,z coordinates:
 a=15
 b=10
 
 `wavegenerator2 x,z coordinates:
 c=35
 d=40
 
 `wave characteristics
 elasticity#=0.001 `determines wave speed
 damping#=0.992 `determines the decay of the wave height
 amplitude#=2.5  `the wave height at the generator points
 frequency#=2.0   `how quickly the generator points move up and down
 current#=0.01  `how much the wave slope affects the jetski
 
`******************
 
`***jetski motion properties***
 
friction#=0.975 `1=no friction - slides all over the place
               `0=big friction - like moving through concrete
 
power#=0.007    `controls the acceleration of the jetski
 
 
dim tile(rows+10,columns+10)
dim v#(rows*2,columns*2)
 
make matrix 2,rows*4,columns*4,rows,columns
 
 
`give every tile of the matrix a coordinate - tile(x,z)
for x=1 to rows
for z=1 to columns
tile(x,z)=tile
tile=tile+1
next z
next x
 
`fix the wave generator points
dim fixed(rows*columns*2)
fixed(tile(a,b))=1
fixed(tile(c,d))=1
 
create bitmap 1,10,10
ink rgb(0,0,255),0
box 0,0,10,10
`ink rgb(0,0,180),0
`box 0,0,9,9
get image 1,0,0,10,10,1
prepare matrix texture 2,1,1,1
ghost matrix on 2,3
 
 
`Make a simple jetski - object number 1
  make object cube 1,0.1
  make object box 2,2,1,4
  make mesh from object 1,2
  delete object 2
  make object cone 3,2
  scale object 3,100,200,100
  xrotate object 3,90
  make mesh from object 2,3
  delete object 3
  make object sphere 4,2
  make mesh from object 3,4
  delete object 4
  add limb 1,1,1
  add limb 1,2,2
  offset limb 1,2,0,0,2
  add limb 1,3,3
  ink rgb(250,0,50),0
  box 0,0,10,10
  get image 2,0,0,10,10
  set current bitmap 0
  texture object 1,2
  ink rgb(255,255,255),0
  scale object 1,20,20,20
 
`*****************************************************
 
 
 
`*******initial positions and speeds *********
 
 
number=50  `number of floating boxes
dim x#(number)
dim y#(number)
dim z#(number)
dim frontspeed#(number)
dim sidespeed#(number)
 
x#(1)=64  `initial x position of jetski
z#(1)=96  `initial z position of jetski
 
for object=2 to number
 
make object cube object,5
hide object object
 
x#(object)=rnd(500)  `initial x position of boxes
z#(object)=rnd(500)  `initial z position of boxes
 
next object
 
`**********************************
 
 
`main program loop
do
 
position object sunplane,camera position x(),camera position y(),camera position z()
point object sunplane,object position x(dummy),object position y(dummy),object position z(dummy)
move object sunplane,128*7
point object sunplane,camera position x(),camera position y(),camera position z()
 
gosub wave
 
gosub control
 
gosub get_wave_slope
 
gosub chasecam
 
text 0,0,str$(screen fps())
 
sync
loop
 
`****************************************
 
`functions
 
function terraform
 
`create terrain
make matrix 1,matrixsize,matrixsize,columns,rows
set matrix 1,0,0,0,2,1,1,0
 
for peak=1 to 50
peakh(peak)=rnd(5)+5
peakx(peak)=rnd(rows-8)+4
peakz(peak)=rnd(rows-8)+4
set matrix height 1,peakx(peak),peakz(peak),peakh(peak)
next peak
update matrix 1
 
 
for times=1 to 120
if times>=90 then peaksoff=1
smooth_matrix(1,rows,rows)
next times
peaksoff=0
 
 
endfunction
 
function create_trench()
 
data$="663663222222222222121477441114788888889698744444478998888963336666"
x=20
z=30
length=len(data$)
for n=1 to length
check$=right$(left$(data$,n),1)
if check$="1" then dec x:dec z
if check$="2" then dec z
if check$="3" then inc x:dec z
if check$="4" then dec x
if check$="6" then inc x
if check$="7" then inc z:dec x
if check$="8" then inc z
if check$="9" then inc z:inc x
 
for u=-1 to 1
for v=-1 to 1
set matrix height 1,x+u,z+v,-2
next v
next u
next n
 
 
`fill with water
water=free_object()
make object plain water,4000,4000
xrotate object water,-90
ghost object on water,3
set object fog water,0
position object water,0,-1.8,0
color object water,rgb(0,0,255)
 
 
water2=free_object()
make object plain water2,4000,4000
xrotate object water2,-90
`ghost object on water2,3
set object fog water2,0
position object water2,0,-2.85,0
color object water2,rgb(0,0,255)
 
 
endfunction
 
 
function smooth_matrix(matnum,tilex,tilez)
 
for x=2 to tilex-2
for z=2 to tilez-2
b=-get matrix height(matnum,x,z)+get matrix height(matnum,x,z+1)
d=-get matrix height(matnum,x,z)+get matrix height(matnum,x+1,z)
f=-get matrix height(matnum,x,z)+get matrix height(matnum,x,z-1)
h=-get matrix height(matnum,x,z)+get matrix height(matnum,x-1,z)
total=b+d+f+h
 
set matrix height matnum,x,z,get matrix height(matnum,x,z)+total*0.1
 
next z
next x
 
 
 
for peak=1 to 100
`peakh(peak)=peakh(peak)*0.999
if matnum=1
  if peaksoff=0 then set matrix height 1,peakx(peak),peakz(peak),peakh(peak)
endif
if matnum=2
  if peaksoff=0 then set matrix height 2,peakx2(peak),peakz2(peak),peakh2(peak)
endif
next peak
 
update matrix matnum
endfunction
 
function free_object
 
object=object_seed
repeat
inc object
until object exist(object)=0
 
endfunction object
 
function check_free_object_number
 
object=object_seed
repeat
inc object
until object exist(object)=0
 
endfunction object
 
function free_image
 
image=image_seed
repeat
inc image
until image exist(image)=0
 
endfunction image
 
 
 
function create_skysphere
 
`get image for sphere by taking snapshot of terrain
terrainimage=free_image()
set camera fov 90
fog off
position camera matrixsize/2.0,3,-matrixsize*0.3
sync
get image terrainimage,0,0,screen width(),screen height()
fog on
fog color rgb(200,200,200)
fog distance matrixsize
set camera fov 60
 
 
sphere2=free_object()
make object sphere sphere2,matrixsize*10
set object collision off sphere2
xrotate object sphere2,180
`yrotate object sphere2,30
set object cull sphere2,0
texture object sphere2,terrainimage
set object texture sphere2,2,0
scale object texture sphere2,8,2.6
set object fog sphere2,0
set object transparency sphere2,2
ghost object on sphere2,5
set alpha mapping on sphere2,20
set object emissive sphere2,rgb(80,60,100)
`set object specular power sphere2,100
`fade object sphere2,200
`set object light sphere2,0
position object sphere2,matrixsize/2,-135,matrixsize/2
 
`sphere 3 (sky) - a third, outer sphere for the sky
sphere3=free_object()
make object sphere sphere3,matrixsize*20
set object collision off sphere3
set object cull sphere3,0
texture object sphere3,skyimage
scale object texture sphere3,1,1.8
set object light sphere3,0
set object fog sphere3,0
position object sphere3,matrixsize/2,0,matrixsize/2
 
endfunction
 
function create_sky()
`creates a dark to light bluish gradient
cls
for n=0 to 250
  ink rgb(n,n-20,n-40),0
  line 0,n,250,n
next n
 
skyimage=free_image()
get image skyimage,0,0,250,250
 
endfunction
 
 
 
 
 
 
 
function move_camera
 
control camera using arrowkeys 0,0.2,3
position camera camera position x(),height#+.2+get ground height(1,camera position x(),camera position z()),camera position z()
if inkey$()="a" then inc height#,1
if inkey$()="z" then dec height#,1
endfunction
 
calculate_shadows:
undim pixelshaded1(128,128)
undim pixelshaded2(128,128)
dim pixelshaded1(128,128)
dim pixelshaded2(128,128)
`if light1>0
create bitmap 1,128,128
set current bitmap 1
ink rgb(20,155,0),0
box 0,0,128,128
for n=0 to 5000
tone=rnd(100)+150
ink rgb(tone/10,tone+15,tone/15),0
dot rnd(128),rnd(128)
next n
ink rgb(10,10,10),0
for y=0 to 128
for x=0 to 128
 
 
`shadows cast by terrain - matrix converted to object 1000
ray2#=intersect object(1000,x,get ground height(1,x,y)+0.1,y,light position x(1),light position y(1),light position z(1))
if ray2#=0 then ray2#=1000
if ray2#<0 then ray2#=1
if ray2#<=100
  tone=40+ray2#*8
 
  `if pixelshaded2(x,y)=1 or pixelshaded1(x,y)=1 then tone=tone/1.5
  if tone>155 then tone=155
  ink rgb(20,tone,0),0
  dot x,128-y
  `pixelshaded1(x,y)=1
endif
 
 
next x
next y
blur bitmap 1,3
shadowmap=5000000
get image shadowmap,0,0,128,128
 
delete bitmap 1
`set light mapping on 2,shadowmap
 `(light1 exist)
 
`texture matrix
prepare matrix texture 1,shadowmap,rows,columns
tile=1
for x=rows-1 to 0 step -1
for z=0 to columns-1
set matrix tile 1,z,x,tile
inc tile
next z
next x
`endif
update matrix 1
 
return
 
function Matrix_to_Object( object, matrixnum, matxsize#, matzsize#, matxsegs, matzsegs, tilex, tilez, limbx, limbz )
   `safety in case limbx and limbz is smaller than the texture x and z
   a = 0
   if limbx < tilex then limbx = tilex : a = 1
   if limbz < tilez then limbz = tilez : a = 1
   if a > 0
      sync
      print "limbx or limbz was less than tilex or tilez : Error corrected"
      print "Press any key to continue."
      sync
      wait key
   endif
   `safety in case matxsegs and matzsegs is not evenly divisible by tilex and tilez
   if matxsegs mod tilex > 0
      EXIT PROMPT "Number of matrix xsegs not evenly divisible by tilex", "Texture tilex error"
      end
   endif
   if matzsegs mod tilez > 0
      EXIT PROMPT "Number of matrix zsegs not evenly divisible by tilez", "Texture tilez error"
      end
   endif
   `safety in case matxsegs and matzsegs is not evenly divisible by tilex and tilez
   if matxsegs mod limbx > 0
      EXIT PROMPT "Number of matrix xsegs not evenly divisible by limbx", "Texture tilex error"
      end
   endif
   if matzsegs mod limbz > 0
      EXIT PROMPT "Number of matrix zsegs not evenly divisible by limbz", "Texture tilez error"
      end
   endif
 
   `calc the number of polys in the matrix
   num_mat_polys = (matxsegs*matzsegs)*2
   `make array to store vert info
   `storage indexs = poly number, vert number, x/y/z vert pos/norm/uv
   `polys are numbered starting from left to right, front to
   `back, one row at a time (with 2 polys per tile)
   dim vert_store#(num_mat_polys,2,7)
 
   `calc the width and depth of each tile on the matrix
   `formula size#/number
   mat_x_wide# = matxsize#/matxsegs
   mat_z_deep# = matzsize#/matzsegs
 
 
`******************************************************************************
   `get vert position data
   `placeholder variable for poly numbers
   a = 1
   `one row at a time (front to back)
   for j = 0 to matzsegs - 1
      `one tile at a time (left to right)
      for i = 0 to matxsegs - 1
 
         `tile top left poly info
 
         `bottom left vert (x,y,z)
         vert_store#(a,0,0) = i*mat_x_wide#
         vert_store#(a,0,1) = GET MATRIX HEIGHT(matrixnum, i, j)
         vert_store#(a,0,2) = j*mat_z_deep#
         `top left vert (x,y,z)
         vert_store#(a,1,0) = i*mat_x_wide#
         vert_store#(a,1,1) = GET MATRIX HEIGHT(matrixnum, i, j+1)
         vert_store#(a,1,2) = (j+1)*mat_z_deep#
         `top right vert (x,y,z)
         vert_store#(a,2,0) = (i+1)*mat_x_wide#
         vert_store#(a,2,1) = GET MATRIX HEIGHT(matrixnum, i+1, j+1)
         vert_store#(a,2,2) = (j+1)*mat_z_deep#
         inc a, 1
 
         `tile bottom right poly info
 
         `bottom left vert (x,y,z)
         vert_store#(a,0,0) = i*mat_x_wide#
         vert_store#(a,0,1) = GET MATRIX HEIGHT(matrixnum, i, j)
         vert_store#(a,0,2) = j*mat_z_deep#
         `top right vert (x,y,z)
         vert_store#(a,1,0) = (i+1)*mat_x_wide#
         vert_store#(a,1,1) = GET MATRIX HEIGHT(matrixnum, i+1, j+1)
         vert_store#(a,1,2) = (j+1)*mat_z_deep#
         `bottom right vert (x,y,z)
         vert_store#(a,2,0) = (i+1)*mat_x_wide#
         vert_store#(a,2,1) = GET MATRIX HEIGHT(matrixnum, i+1, j)
         vert_store#(a,2,2) = j*mat_z_deep#
         inc a, 1
      next i
   next j
`******************************************************************************
 
 
`******************************************************************************
   `calc normals for polys
   `Thanks to ADR for posting this code on the DBP forums :)
   for i = 1 to num_mat_polys
      `acuire vert positions
      P1X# = vert_store#(i,0,0)
      P1Y# = vert_store#(i,0,1)
      P1Z# = vert_store#(i,0,2)
      P2X# = vert_store#(i,1,0)
      P2Y# = vert_store#(i,1,1)
      P2Z# = vert_store#(i,1,2)
      P3X# = vert_store#(i,2,0)
      P3Y# = vert_store#(i,2,1)
      P3Z# = vert_store#(i,2,2)
 
      null = make vector3(1)
      null = make vector3(2)
      null = make vector3(3)
 
      ` -- calculate the two directional vectors for the adj and opp edges...
      set vector3 1, P1X#, P1Y#, P1Z#
      set vector3 2, P2X#, P2Y#, P2Z#
      set vector3 3, P3X#, P3Y#, P3Z#
      subtract vector3 2, 2, 1
      subtract vector3 3, 3, 1   ` -- vector 3 and 1 are now directional vectors
      normalize vector3 2,2      ` -- normalize em
      normalize vector3 3,3
      cross product vector3 1, 2,3  ` -- use the origin vector (1) to store the face normal
      normalize vector3 1,1
 
      `save normals (all 3 verts have same normals)
      vert_store#(i,0,3) = x vector3(1)
      vert_store#(i,0,4) = y vector3(1)
      vert_store#(i,0,5) = z vector3(1)
      vert_store#(i,1,3) = vert_store#(i,0,3)
      vert_store#(i,1,4) = vert_store#(i,0,4)
      vert_store#(i,1,5) = vert_store#(i,0,5)
      vert_store#(i,2,3) = vert_store#(i,0,3)
      vert_store#(i,2,4) = vert_store#(i,0,4)
      vert_store#(i,2,5) = vert_store#(i,0,5)
 
      null = delete vector3(1)
      null = delete vector3(2)
      null = delete vector3(3)
   next i
`******************************************************************************
 
 
`******************************************************************************
   `calc UV data for polys
 
   `save current x tile number
   xtiles = 1
   `save current z tile number
   ztiles = 1
   `calc how much to step each u data per tile
   stepu# = (1.0/tilex)
   `calc how much to step each v data per tile
   stepv# = (1.0/tilez)
   `set base u data for new set of tiles
   baseu# = 0
   `set base v data for new set of tiles
   basev# = 1-stepv#
   `poly number placeholder variable
   i = 1
   `from front to back
   for k = 1 to matzsegs
      `reset the number of x tiles to 1 and the u base to 0
      `at the beginning of each row
      xtiles = 1
      baseu# = 0
      `from left to right
      for l = 1 to matxsegs
         `2 polys per tile
         for m = 1 to 2
            `write all 3 verts of each matrix poly
            for j = 0 to 2
               `select which formula to apply depending on polygon side
               `and vert number (0 to 2)
               `j selects the vert number
               `m selects the polygon side (back/left or front right : 1 or 2)
               select j
                  case 0
                     if m = 1
                        testu# = baseu#
                        testv# = basev#+stepv#
                     else
                        testu# = baseu#
                        testv# = basev#+stepv#
                     endif
                  endcase
                  case 1
                     if m = 1
                        testu# = baseu#
                        testv# = basev#
                     else
                        testu# = baseu#+stepu#
                        testv# = basev#
                     endif
                  endcase
                  case 2
                     if m = 1
                        testu# = baseu#+stepu#
                        testv# = basev#
                     else
                        testu# = baseu#+stepu#
                        testv# = basev#+stepv#
                     endif
                  endcase
               endselect
               `store calculated data for each vert of each poly
               `u data
               vert_store#(i,j,6) = testu#
               `v data
               vert_store#(i,j,7) = testv#
            next j
            inc i, 1
         `next polygon side of this tile
         next m
         `update u data and xtiles place holder
         inc baseu#, stepu#
         inc xtiles, 1
         `reset data when texture tile width has been reached
         if xtiles > tilex
            baseu# = 0
            xtiles = 1
         endif
      `next x tile
      next l
      `update v data and ztiles place holder
      dec basev#, stepv#
      inc ztiles, 1
      `reset data when texture depth has been reached
      if ztiles > tilez
         basev# = 1-stepv#
         ztiles = 1
      endif
   `next z tile
   next k
`******************************************************************************
 
 
`******************************************************************************
   `make object from matrix verts
 
   `calc number of memblocks needed
   tempx = matxsegs/limbx
   tempz = matzsegs/limbz
   tempmem = tempx * tempz
   `make arrays to store memblock positions and memblock numbers
   dim membhold(tempx, tempz)
   dim mempos(tempmem)
   `enter memblock numbers for each texture tile based on the x and z limbs to use
   a = 1
   for i = 1 to tempz
      for j = 1 to tempx
         membhold(j, i) = a
         inc a, 1
      next j
   next i
   `calc the memblock size
   `formula is 12 byte header + ((( 32 bytes per vert * limb x segs)*(limb z segs * 2 polys))* 3 verts per poly)
   mat_mem_size = 12+(((32*limbx)*(limbz*2))*3)
   `make memblocks and write headers for each memblock and set the beginning
   `position for vert data to 12
   for i = 1 to tempmem
      make memblock i, mat_mem_size
      `write objects fvf format as 274
      write memblock dword i, 0, 274
      `write bytes per vert as 32 (8 floats xpos#,ypos#,zpos#,xnorm#,ynorm#,znorm#,u#,v#)
      write memblock dword i, 4, 32
      `write number of verts in matrix (polys*3)
      write memblock dword i, 8, ((limbx*limbz)*2)*3
      `set beginning position for vert data after header(0-8)+4 = 12
      mempos(i) = 12
   next i
 
   `image tile, row, and memblock placeholders
   xtile = 1
   ztile = 1
   xrow = 1
   xmem = 1
   zmem = 1
   `polygon placeholders (b=2 is 1 tile complete)
   b = 1
   `enter all polys' verts to memblock
   for i = 1 to num_mat_polys
      `select memblock number to write to use current x and z limb tile to pick
      tempmemnum = membhold(xmem, zmem)
      `write all 3 verts of each matrix poly
      for j = 0 to 2
         `xpos
         write memblock float tempmemnum, mempos(tempmemnum), vert_store#(i,j,0)
         `increment the current memblock position
         inc mempos(tempmemnum), 4
         `ypos
         write memblock float tempmemnum, mempos(tempmemnum), vert_store#(i,j,1)
         inc mempos(tempmemnum), 4
         `zpos
         write memblock float tempmemnum, mempos(tempmemnum), vert_store#(i,j,2)
         inc mempos(tempmemnum), 4
         `xnorm
         write memblock float tempmemnum, mempos(tempmemnum), vert_store#(i,j,3)
         inc mempos(tempmemnum), 4
         `ynorm
         write memblock float tempmemnum, mempos(tempmemnum), vert_store#(i,j,4)
         inc mempos(tempmemnum), 4
         `znorm
         write memblock float tempmemnum, mempos(tempmemnum), vert_store#(i,j,5)
         inc mempos(tempmemnum), 4
         `u data
         write memblock float tempmemnum, mempos(tempmemnum), vert_store#(i,j,6)
         inc mempos(tempmemnum), 4
         `v data
         write memblock float tempmemnum, mempos(tempmemnum), vert_store#(i,j,7)
         inc mempos(tempmemnum), 4
      next j
      `after each poly increase b by 1
      inc b, 1
      `after 2 polys have been completed 1 tile has been entered
      if b > 2
         `reset poly count to 1
         b = 1
         `move to next x tile
         inc xtile, 1
         `if at the next limb
         if xtile > limbx
            `reseet the x tile to 1
            xtile = 1
            `update the tile count to know when to move to the next row
            inc xrow, limbx
            `inc the xmem selector placeholder
            inc xmem, 1
            `if at the last xmem wide then start back at the begining
            if xmem > tempx
               xmem = 1
            endif
         endif
         `when at the end of the row
         if xrow > matxsegs
            `go back to the far left
            xrow = 1
            `update the number of rows done
            inc ztile, 1
            `when the number of rows done is > the preset depth
            if ztile > limbz
               `reset row count back to 1
               ztile = 1
               `move to the next zmem selector placeholder
               inc zmem, 1
               `if row count overlaps predetermined number
               if zmem > tempz
                  `wrap to 1
                  zmem = 1
               endif
            endif
         endif
      endif
   next i
   `undim arrays when done with them
   undim vert_store#(0,0,0)
   undim membhold(0, 0)
   undim mempos(0)
   `set the mesh number to use (can be replaced with a findfreemesh function)
   mesh = 1
   `make object and limbs from data setup
   for i = 1 to tempmem
      `make temp mesh from info
      make mesh from memblock mesh, i
      `delete temp memblock
      delete memblock i
      `if it is the first memblock mesh, use it as the base object
      if i = 1
         `make temp object for NGC
         make object object, mesh, 0
      `else turn each memblock mesh into limbs
      else
         add limb object, i-1, mesh
      endif
      `delete temp mesh
      delete mesh mesh
   next i
`******************************************************************************
endfunction
 
 
 
function check_free_image_number()
 
`this functionworks in the same way as the check_free_object function,
`except it works for images.
 
image=image_seed
repeat
inc image
until image exist(image)=0
 
endfunction image
 
 
wave:
 
`****move the generator points up and down****
 
y#=amplitude#*sin(theta#)
theta#=theta#+frequency#
 
if fixed(tile(a,b))=1
set matrix height 2,a,b,y#
endif
if fixed(tile(c,d))=1
set matrix height 2,c,d,y#
endif
 
`********************************************
 
`****make wave propogate through matrix******
 
for x=1+1 to rows-1
for z=1+1 to columns-1
 
`check x+1 height
if x<rows
distxp1#=get matrix height(2,x+1,z)-get matrix height (2,x,z)
endif
 
 
`check x-1 height
if x>1
distxm1#=get matrix height(2,x-1,z)-get matrix height (2,x,z)
endif
 
`check z+1 height
if z<columns
distzp1#=get matrix height(2,x,z+1)-get matrix height (2,x,z)
endif
 
`check z-1 height
if z>1
distzm1#=get matrix height(2,x,z-1)-get matrix height (2,x,z)
endif
 
`calculate vector some of heights adjacent to tile
`and make this proportional to the tile's acceleration
vectorsum#=distxp1#+distxm1#+distzp1#+distzm1#
a#=vectorsum#*elasticity#
`increase tile's velocity by it's acceleration amount
v#(tile(x,z))=v#(tile(x,z))+a#
if fixed(tile(x,z))=0
`reposition tile
set matrix height 2,x,z,get matrix height(2,x,z)+v#(tile(x,z))
v#(tile(x,z))=v#(tile(x,z))*damping#
endif
 
next z
next x
 
update matrix 2
 
`****************************************************
 
return
 
 
get_wave_slope:
 
for object=1 to number
 
   y#(object)=get ground height(2,x#(object),z#(object))
   yfront#=get ground height(2,newxvalue(x#(object),angle#,1),newzvalue(z#(object),angle#,1))
   yside#=get ground height(2,newxvalue(x#(object),angle#+90,1),newzvalue(z#(object),angle#+90,1))
 
   frontspeed#(object)=frontspeed#(object)+(y#(object)-yfront#)*current#
   sidespeed#(object)=sidespeed#(object)+(y#(object)-yside#)*current#
 
   x#(object)=newxvalue(x#(object),angle#,frontspeed#(object))
   z#(object)=newzvalue(z#(object),angle#,frontspeed#(object))
 
   x#(object)=newxvalue(x#(object),angle#+90,sidespeed#(object))
   z#(object)=newzvalue(z#(object),angle#+90,sidespeed#(object))
 
position object object,x#(object),y#(object),z#(object)
 
next object
 
return
 
control:
 
`***steering****
 
 
if mousex()>0.5*screen width() then polarity=1
if mousex()<0.5*screen width() then polarity=-1
`the square function is so that the steering is less sensitive
`in the middle and more sensitive for extreme turns
`note: squaring makes the mouse position always positive,
`hence the need for a polarity.
turn#=(((mousex()-(0.5*screen width()))^2)/10000)*polarity
if turn#>1 then turn#=1
if turn#<-1 then turn#=-1
yrotate object 1,object angle y(1)+turn#
direction#=wrapvalue(direction#+turn#)
rotate limb 1,1,0,0,-turn#*20 `roll the jetski body according to turn amount
 
`***************
 
`*****speed*****
 
if upkey()=1 then frontspeed#(1)=frontspeed#(1)+(power#*cos(direction#)):sidespeed#(1)=sidespeed#(1)+(power#*sin(direction#))
if downkey()=1 then frontspeed#(1)=frontspeed#(1)-(power#*cos(direction#)):sidespeed#(1)=sidespeed#(1)-(power#*sin(direction#))
 
for object=1 to number
frontspeed#(object)=frontspeed#(object)*friction#
sidespeed#(object)=sidespeed#(object)*friction#
next object
 
`***************
 
return
 
chasecam:
 
yrotate camera curveangle(direction#,camera angle y(),smoothness)
position camera object position x(1),object position y(1)+camheight#,object position z(1)
move camera -camdist#
point camera object position x(1),object position y(1)+camheight#,object position z(1)
 
return
 
`********have a nice day*************