Set Display Mode 800,600,32
Sync On: Sync Rate 0: CLS 0: Sync
AutoCam Off
Set Camera Range 1.0, 100000.0
Hide Mouse
 
Gosub Setup
Do
  CX#=Camera Angle X(): CY#=Camera Angle Y(): CZ#=Camera Angle Z()
  CY#=Wrapvalue(CY#+mousemovex())
  CX#=Wrapvalue(CX#+mousemovey())
  Rotate Camera CX#,CY#,CZ#
  If MouseClick()=1 Then Move Camera 10
  If MouseClick()=2 Then Move Camera -10
 
  If Scancode() Then RaceStarted=1
 
  IF RaceStarted=1
    For N=1 To 6
      Move Object N,Speed#(N)
      Gh# = Get Ground Height(1,Object Position X(N),Object Position Z(N))+5
      If Object Position Y(N) > Gh# Then Position Object N,Object Position X(N),Gh#,Object Position Z(N)
      If Speed#(N) < TopSpeed#(N) Then Speed#(N)=Speed#(N)+Accell#(N)
      Dist# = CarDistance(N)
      If Dist# < 10.0
        CurrentWayPoint(N)=CurrentWayPoint(N)+1: If CurrentWayPoint(N) = 180 Then CurrentWayPoint(N) = 0
        Point Object N,Waypoints#(N,CurrentWayPoint(N),0),Gh#,Waypoints#(N,CurrentWayPoint(N),1)
      Else
        Point Object N,Waypoints#(N,CurrentWayPoint(N),0),Gh#,Waypoints#(N,CurrentWayPoint(N),1)
      Endif
    Next N
  Endif
  Sync
Loop
 
 
Rem **************************************************
Rem                  Smooth Matrix
Rem **************************************************
Smooth:
  Rem Averages matrix heights to remove jagged edges
  for Z=0 to 70
    for X=0 to 70
      P0#=Get Matrix Height(1,X,Z):     Rem Current point height
      Rem Get 4 adjoining points heights (if they exist)
      If Z-1>=0
        P1#=Get Matrix Height(1,X,Z-1)
      Else
        P1#=P0#
      Endif
      If X+1<=TilesX
        P2#=Get Matrix Height(1,X+1,Z)
      Else
        P2#=P0#
      Endif
      If Z+1<=TilesZ
        P3#=Get Matrix Height(1,X,Z+1)
      Else
        P3#=P0#
      Endif
      If X-1>=0
        P4#=Get Matrix Height(1,X-1,Z)
      Else
        P4#=P0#
      Endif
      Average#=(P0#+P1#+P2#+P3#+P4#)/5: Rem Av height of other points
      RHeight#=Average#
      Set Matrix Height 1,x,z,RHeight#
    Next x
  Next z
  Update Matrix 1
Return
 
Setup:
  Dim Waypoints#(6,180,1)
  Dim CurrentWayPoint(6)
  Dim Speed#(6)
  Dim TopSpeed#(6)
  Dim Accell#(6)
 
  Create Bitmap 1,1024,1024
  Rem ****************************
  Rem    Create SkyBox Textures
  Rem ****************************
  CLS 0
  For N=0 To 128
    Ink RGB(0,N,255-N),0
    Line 0,N,256,N
  Next N
  Get Image 1001,0,0,256,256: Rem Sides
  CLS 0: Get Image 1002,0,0,256,256: Rem Bottom
  CLS RGB(0,0,255): Get Image 1003,0,0,256,256: Rem Top
  Rem *******************
  Rem    Create SkyBox
  Rem *******************
  MakeLimbCube(1001,1000.0)
  rem SET OBJECT Object Number, Wireframe, Transparency, Cull, Filter, Light, Fog, Ambient
  Set Object           1001,        1,            1,       0,    1,      0,    1,     1
  Texture Limb 1001,1,1001: Rem Back
  Texture Limb 1001,2,1001: Rem Left
  Texture Limb 1001,3,1001: Rem Front
  Texture Limb 1001,4,1001: Rem Right
  Texture Limb 1001,5,1002: Rem Bottom
  Texture Limb 1001,6,1003: Rem Top
  Scale Object 1001,1000,1000,1000
  Position Object 1001,3500,-200,3500: Rem Sky Box
 
  Rem ********************
  Rem  Large Track Sprite
  Rem ********************
  CLS 0
  CircleRad=18
  Ink RGB(150,150,150),0
  For N=1 To CircleRad
    Circle CircleRad,CircleRad,N
    Circle CircleRad,CircleRad+1,N
  Next N
  Sync
  Get Image 1,0,0,CircleRad*2+2,CircleRad*2+2
  Sprite 1,-200,-200,1
 
  Rem ********************
  Rem  Small Track Sprite
  Rem ********************
  CLS 0: Ink RGB(100,100,100),0
  CircleRad=12
  For N=1 To CircleRad
    Circle CircleRad,CircleRad,N
    Circle CircleRad,CircleRad+1,N
  Next N
  Sync
  Get Image 2,0,0,CircleRad*2+2,CircleRad*2+2
  Sprite 2,-200,-200,2
 
  Rem ********************
  Rem    Matrix Texture
  Rem ********************
  Ink RGB(0,130,0),0
  Box 0,0,1023,1023
  For N=1 To 5000
    Ink RGB(0,Rnd(250)+50,0),0
    Dot Rnd(1024),Rnd(1024)
  Next N
  Blur Bitmap 1,2
  Sync
  xcenter=512: ycenter=512: radiusx=400: radiusy=200
  Ratio#=7000.0/1024.0
  for a=0 to 180
    x=cos(a*2)*radiusx
    y=sin(a*2)*radiusy
    Paste Sprite 1,x+xcenter-19,y+ycenter-19
  next a
  Sync
  for a=0 to 180
    x=cos(a*2)*radiusx
    y=sin(a*2)*radiusy
    Paste Sprite 2,x+xcenter-13,y+ycenter-13
  next a
  Blur Bitmap 1,4
  Get Image 100,0,0,1024,1024
  rem Sync
  Rem ********************
  Rem      WayPoints
  Rem ********************
  radiusx=390: radiusy=190
  for car=1 to 6
    for a=0 to 180
      x=cos(a*2)*radiusx
      y=sin(a*2)*radiusy
      Waypoints#(car,a,0) = (x+xcenter)*Ratio#
      Waypoints#(car,a,1) = (y+ycenter)*Ratio#
    next a
    Inc radiusx,3
    Inc radiusy,3
  next car
 
  Rem ********************
  Rem       Matrix
  Rem ********************
  Make Matrix 1,7000,7000,70,70: Rem 1 Tile = 100
  Prepare Matrix Texture 1,100,70,70
  Randomize Matrix 1,2000.0
  For N=1 To 140
    X=Rnd(66)+2: Z=Rnd(66)+2
    Set Matrix Height 1,X,Z,3000.0
  Next N
  For N=1 To 20
    Gosub Smooth
  Next N
  Rem Skirt
  For N=0 To 70
    Set Matrix Height 1,0,N,Rnd(100)+400
    Set Matrix Height 1,70,N,Rnd(100)+400
    Set Matrix Height 1,N,0,Rnd(100)+400
    Set Matrix Height 1,N,70,Rnd(100)+400
  Next N
  Normalise(1)
  t=1
  For z=69 to 0 Step -1
    For x=0 to 69
      Set Matrix Tile 1,x,z,t
      Inc t
    Next x
  Next z
  Update Matrix 1
 
  Set Current Bitmap 0
  Delete Bitmap 1
 
  Rem ********************
  Rem       Cars
  Rem ********************
  For N=-4 To 1
    MakeCars(N+5)
    Gh# = Get Ground Height(1,Waypoints#(N+5,N+5,0)+((N+5)*10),Waypoints#(N+5,N+5,1)-140)+5
    Position Object N+5,Waypoints#(N+5,N+5,0)+((N+5)*10),Gh#,Waypoints#(N+5,N+5,1)-140
    CurrentWayPoint(N+5)=N+5
  Next N
 
  Color Object 1,RGB(255,0,0)
  Color Object 2,0
  Color Object 3,RGB(0,255,0)
  Color Object 4,RGB(255,255,0)
  Color Object 5,RGB(0,0,255)
  Color Object 6,RGB(255,255,255)
 
  For N=1 To 6
    Speed#(N) = 0.0
    Accell#(N) = (Rnd(5)+10)/100.0
    TopSpeed#(N) = 10.0
  Next N
 
  CGh# = Get Ground Height(1,Waypoints#(4,0,0),Waypoints#(4,0,1)-120)+85
  Position Camera Waypoints#(4,0,0),CGh#,Waypoints#(4,0,1)-120
  Point Camera Waypoints#(4,0,0),Gh#,Waypoints#(4,0,1)
Return
 
 
Rem *********************************************************
Rem ***                   FUNCTIONS                       ***
Rem *********************************************************
 
Function MakeCars(CarNum)
  Make Object Box CarNum,10,5,20
EndFunction
 
Function CarDistance(CarNum)
  Dx# = Object Position X(CarNum)-Waypoints#(CarNum,CurrentWayPoint(CarNum),0)
  rem Dy# = Object Position Y(CarNum)-5.0
  Dz# = Object Position Z(CarNum)-Waypoints#(CarNum,CurrentWayPoint(CarNum),1)
  Dist# = Sqrt((Dx#*Dx#)+0+(Dz#*Dz#))
EndFunction Dist#
 
Function Normalise(MatNum)
  Rem By Lee Bamber From DB Example - Adds shaded areas to matrix to give depth
  For z=1 to 70
    For x=1 to 70
      h8#=get matrix height(MatNum,x,z-1)
      h4#=get matrix height(MatNum,x-1,z)
      h#=get matrix height(MatNum,x,z)
      h2#=get matrix height(MatNum,x,z)
      x1#=(x-1)*25.0
      y1#=h#
      x2#=(x+0)*25.0
      y2#=h4#
      dx#=x2#-x1#
      dy#=y2#-y1#
      ax#=atanfull(dx#,dy#)
      ax#=wrapvalue(90-ax#)
      z1#=(z-1)*25.0
      y1#=h2#
      z2#=(z+0)*25.0
      y2#=h8#
      dz#=z2#-z1#
      dy#=y2#-y1#
      az#=atanfull(dz#,dy#)
      az#=wrapvalue(90-az#)
      nx#=sin(ax#)
      ny#=cos(ax#)
      nz#=sin(az#)
      Set matrix normal MatNum,x,z,nx#,ny#,nz#
    next x
  next z
  Update Matrix MatNum
EndFunction
 
Function MakeLimbCube(ObjNum,Size#)
  Offset#=Size#/2.0: MeshNum=2000: PlainNum=2000
  Make Object Cube ObjNum,Size#
  Make Object Plain PlainNum,Size#,Size#
  Make Mesh From Object MeshNum,PlainNum
  ADD LIMB ObjNum,1,2000: Offset Limb ObjNum,1,0,0,0.0-Offset#: Rem Cube Side 1 (Front)
  ADD LIMB ObjNum,2,2000: Rotate Limb ObjNum,2,0,90,0: Offset Limb ObjNum,2,0.0-Offset#,0,0: Rem Cube Side 2 (Left)
  ADD LIMB ObjNum,3,2000: Rotate Limb ObjNum,3,0,180,0: Offset Limb ObjNum,3,0,0,Offset#:  Rem Cube Side 3 (Back)
  ADD LIMB ObjNum,4,2000: Rotate Limb ObjNum,4,0,270,0: Offset Limb ObjNum,4,Offset#,0,0:  Rem Cube Side 4 (Right)
  ADD LIMB ObjNum,5,2000: Rotate Limb ObjNum,5,270,0,0: Offset Limb ObjNum,5,0,0.0-Offset#,0: Rem Cube Side 5 (Bottom)
  ADD LIMB ObjNum,6,2000: Rotate Limb ObjNum,6,90,0,0: Offset Limb ObjNum,6,0,Offset#,0: Rem Cube Side 6 (Top)
  Delete Mesh MeshNum
  Delete Object PlainNum
  Hide Limb ObjNum,0
EndFunction