remstart
   ==============================================================
   =  Title  : Matrix Waypoint Creator
   =  Author : latch grapple
   =  Date   : 07/07/2007
   =  Update :
   =  Version: v.01
   ==============================================================
   Comments    Create waypoints for something to travel on
               on a matrix by clicking the grid squares on
               the green grid.  You can see the path that is traveled
               on the map (blue grid) and the camera will move on
               the matrix in the camera window.
   ==============================================================
remend
 
rem =============================================================
rem = SET UP DISPLAY
rem =============================================================
   autocam off
   set display mode 800,600,32
   sync on
   sync rate 80
 
rem =============================================================
rem = MAIN
rem =============================================================
   gosub _init
   gosub _make_grids
   count=0                 : rem this is the number of set waypoints
   do
      gosub _set_waypoint
      gosub _map
      gosub _move_camera
 
      rem run through the waypoints
      gosub _run_through_waypoints
 
      rem clear grids and reset
      text 5,560,"Right Click to Reset Camera on new map"
      if mouseclick()=2
         delete matrix 1
         gosub _make_grids
         count=0
      endif
 
      text 600,60,"FPS  : "+str$(screen fps())
 
      sync
   loop
 
   end
 
rem =============================================================
rem = SUBROUTINES - PROCEDURES
rem =============================================================
   _init:
      randomize timer()
 
      rem matrix size
      matx=10000
      matz=10000
      tilex=25
      tilez=25
      xpertile#=matx/tilex
      zpertile#=matz/tilez
 
      rem way point grid size (use tilex and tilez for number of cells)
      xpos=0
      ypos=0
      xsize=10
      ysize=10
 
      rem array to hold all 625 (25x25) matrix locations x and z
      dim cell(625,1)
      n=0
      for z=1 to tilez
         for x=1 to tilex
            inc n
            rem centers of cells
            cell(n,0)=(x*xpertile#)-(xpertile#/2)
            cell(n,1)=(z*zpertile#)-(zpertile#/2)
         next x
      next z
 
      rem array to hold the waypoints.  Cells can be repeated
      rem dimension this to the maximum waypoints to record
      maxway=2000
      dim waypoints(maxway)
 
      rem get matrix textures
      gosub _textures
 
      gosub _lighting
 
   return
`-----------------------------------------------------------------
   _textures:
      rem create two bitmaps to draw textures on
      create bitmap 3,screen width(),screen height()
      create bitmap 4,screen width(),screen height()
      rem stone tile
      tiles=100
      while image exist(tiles)=1
         inc stone
      endwhile
      grid(0,0,1,1,128,128,rgb(255,255,255),rgb(100,100,100))
      for n=1 to 5
         blur bitmap 4,3
      next n
      get image tiles,0,0,274,137
 
      rem grass
      set current bitmap 3
      grass=tiles
      while image exist(grass)
         inc grass
      endwhile
      cls rgb(0,32,0)
      for n=0 to 10000
         ink rgb(20,rnd(80)+20,10),0
      dot rnd(137),rnd(137)
      next n
      blur bitmap 3,2
      get image grass,0,0,137,137
      set current bitmap 4
      paste image grass,137,0
      rem matrix textures
      get image tiles,0,0,274,137
 
      rem cleanup
      delete bitmap 3
      delete bitmap 4
      for n=1 to 51
      read a
      a$=a$+chr$(a)
      next n
      paste image tiles,0,0
 
   return
`-----------------------------------------------------------------
   _make_grids:
      rem matrix and camera
      `set camera view 281,1,790,511
      make matrix 1,matx,matz,tilex,tilez
      prepare matrix texture 1,tiles,2,1
      fill matrix 1,0,2
      randomize matrix 1,1000
 
      rem put in tiled walkway
      for x=11 to 13
         for z=0 to tilez-1
            set matrix tile 1,x,z,1
            set matrix height 1,x+1,z,0
            set matrix height 1,x,z,0
            set matrix height 1,x,z+1,0
            set matrix height 1,x+1,z+1,0
         next z
      next x
      for x=0 to tilex-1
         for z=11 to 13
            set matrix tile 1,x,z,1
            set matrix height 1,x+1,z,0
            set matrix height 1,x,z,0
            set matrix height 1,x,z+1,0
            set matrix height 1,x+1,z+1,0
         next z
      next x
      update matrix 1
      calc_mat_normals(1,tilex,tilez,matx/50.0,matz/50.0)
 
      color backdrop 0
 
      rem overhead map
      camy#=camera position y()
      position camera camera position x(),8700,camera position z()
      rotate camera 90,0,0
      set camera view 0,0,screen width(),screen height()
      fog off
      sync
      overhead=200
      get image overhead,110,12,701,600
      sprite overhead,0,0,overhead
      size sprite overhead,280,279
      set sprite overhead,0,0
      hide sprite overhead
      sync
      cls
      set camera view 281,1,790,511
      position camera camera position x(),camy#,camera position z()
      rotate camera 0,0,0
      fog on
 
      rem green grid
      grid(0,0,tilex,tilez,xsize,ysize,rgb(0,255,0),0)
 
      rem create a blue grid on bitmap 1
      create bitmap 1,276,276
      cls
      grid(0,0,tilex,tilez,xsize,ysize,255,0)
      overlay=overhead+1
      while image exist(overlay)=1
         inc overlay
      endwhile
      get image overlay,0,0,276,276
      sync
      sprite overlay,0,280,overlay
      hide sprite overlay
      set sprite overlay,0,1
      cls
      sync
      paste sprite overhead,0,0
      set current bitmap 0
 
      rem create a green grid on bitmap 2 for cell selection
      create bitmap 2,276,276
      cls
      grid(0,0,tilex,tilez,xsize,ysize,rgb(0,255,0),0)
      set current bitmap 0
 
      rem yellow border around camera window
      grid(280,0,1,1,510,510,RGB(255,255,0),0)
 
   return
`----------------------------------------------------------------
   _map:
      rem show movement path
      set current bitmap 1
      ink RGB(128,255,255),0
      mapx#=camera position x()/(matx/275)
      mapy#=275-(camera position z()/(matz/275))
      dot mapx#,mapy#
      get image 1,0,0,276,276
      set current bitmap 0
      paste image 1,0,280
 
      rem put overlay grid ontop of map
      text 381,560,"Press [CTRL] to toggle overlay grid on map"
      ink rgb(32,32,32),0
      text 0,580,a$
      ink RGB(128,255,255),0
      if controlkey()=1 then ctoggle=1-ctoggle
      repeat
         rem wait for control key to be released
      until controlkey()=0
      if ctoggle = 1
         paste sprite overlay,0,280
      endif
   return
`----------------------------------------------------------------
   _move_camera:
      curyang#=camera angle y()
      cy#=get ground height(1,camera position x(),camera position z())
      position camera camera position x(),cy#+50,camera position z()
      if upkey()=1 then move camera 10
      if leftkey()=1 then curyang#=wrapvalue(curyang#-2)
      if rightkey()=1 then curyang#=wrapvalue(curyang#+2)
      yrotate camera curyang#
   return
`----------------------------------------------------------------
   _set_waypoint:
      rem check for a way point
      wayset=mouse_cell(tilex,tilez,xsize,ysize)
      rem add the cell number to the list of waypoints
      if wayset > 0
         inc count
         if count > maxway then return
         waypoints(count)=wayset
      endif
 
   return
`------------------------------------------------------------------
   _run_through_waypoints:
      rem run through the waypoints
      text 381,520,"Press [ENTER] to move camera through waypoints"
      text 381,540,"Press [SPACE] to halt camera"
      if returnkey()=1
         if count > 0
            wayflag=0
            for n=1 to count
 
               repeat
                  rem get angle for smooth camera turning
                  cangy#=camera angle y()
                  point camera cell(waypoints(n),0),camera position y(),cell(waypoints(n),1)
                  newcangy#=camera angle y()
                  yrotate camera cangy#
                  cy#=get ground height(1,camera position x(),camera position z())
                  position camera camera position x(),cy#+50,camera position z()
 
                  wx=cell(waypoints(n),0)
                  wz=cell(waypoints(n),1)
                  rem is the camera within 50 units of the waypoint?
                  if camera position x() >= wx-25 and camera position x() <= wx+25
                     if camera position z() >= wz-25 and camera position z() <= wz+25
                        wayflag=1
                     endif
                  endif
                  rem start angle interpolation
                  final#=curveangle(newcangy#,cangy#,30)
                  yrotate camera final#
                  move camera 5
                  gosub _map
                  sync
 
                  rem check for space key to stop
                  if spacekey()=1 then return
 
               until wayflag=1
               wayflag=0
            next n
         endif
      endif
   return
`----------------------------------------------------------------
   _lighting:
      set ambient light 0
      set directional light 0,1,-1,1
      fog distance 8000
      fog on
      fog color RGB(32,32,64)
      set camera range 1,20000
   return
`----------------------------------------------------------------
 
`----------------------------------------------------------------
rem =============================================================
rem = FUNCTIONS
rem =============================================================
   Function Grid(XPosition,YPosition,Columns,Rows,XSize,YSize,CellColourF,CellColourB)
      Ink CellColourB,0
      Box XPosition,YPosition,XPosition+(Columns*(XSize+1)),YPosition+(Rows*(YSize+1))
      Ink CellColourF,0
      For N=0 To Rows
         Line XPosition,  N*(YSize+1)+YPosition,  Columns*(XSize+1)+XPosition,  N*(YSize+1)+YPosition
      Next N
      For N=0 To Columns
         Line N*(XSize+1)+XPosition,  YPosition,  N*(XSize+1)+XPosition,  Rows*(YSize+1)+YPosition
      Next N
   Endfunction
`----------------------------------------------------------------
   function mouse_cell(horz,vert,cellsizex,cellsizey)
      result=0
      rem find actual cell
      cellx=int(mousex()/(cellsizex+1))+1
      celly=int(mousey()/(cellsizey+1))+1
      celly=(vert-celly)+1
      if (cellx > horz or cellx < 1) or (celly > vert or celly < 1)
         cellx=0
         celly=0
      endif
      curcell=((celly-1)*horz)+cellx
      if curcell <= 0 then curcell=0
      text 281,0,"Left Click Green Grid to set waypoint at:"
      text 600,0,"Horizontal cell # :"+str$(cellx)
      text 600,20,"Vertical cell #: "+str$(celly)
      `text 500,40,"Current Cell in grid: "+str$((horz*(celly-1))+cellx)
      text 600,40,"Current Cell in grid: "+str$(curcell)
 
      rem selected cell red
      if mouseclick()=1 and curcell > 0
         if point(mousex(),mousey())=rgb(255,0,0) or point(mousex(),mousey())=rgb(192,192,192)
            ink RGB(192,192,192),0
         else
            ink RGB(255,0,0),0
         endif
         set current bitmap 2
         box (cellx-1)*(cellsizex+1)+1,(celly-1)*(cellsizey+1)+1,((cellx-1)*(cellsizex+1)+1)+cellsizex-1,((celly-1)*(cellsizey+1)+1)+cellsizey-1
         flip bitmap 2
         get image 2,0,0,276,276
         flip bitmap 2
         set current bitmap 0
         paste image 2,0,0
         ink RGB(128,255,255),0
         repeat
            rem wait for mouse click release
         until mouseclick()=0
         result=curcell
      endif
   endfunction result
`----------------------------------------------------------------
   function calc_mat_normals(mat,tilex,tilez,sizex#,sizez#)
   Rem By Lee Bamber From DB Example - Adds shaded areas to matrix to give depth
   rem added tile and tile size factor for normal depth adjustment - latch
      for z=1 to tilez
         for x=1 to tilex
 
            rem Get matrix heights
            h8#=get matrix height(mat,x,z-1)
            h4#=get matrix height(mat,x-1,z)
            h#=get matrix height(mat,x,z)
            h2#=get matrix height(mat,x,z)
 
            rem Calculate projected angle X using heights
            x1#=(x-1)*sizex# : y1#=h#
            x2#=(x+0)*sizex# : y2#=h4#
            dx#=x2#-x1#
            dy#=y2#-y1#
            ax#=atanfull(dx#,dy#)
            ax#=wrapvalue(90-ax#)
 
            rem Calculate projected angle Z using heights
            z1#=(z-1)*sizez# : y1#=h2#
            z2#=(z+0)*sizez# : y2#=h8#
            dz#=z2#-z1#
            dy#=y2#-y1#
            az#=atanfull(dz#,dy#)
            az#=wrapvalue(90-az#)
 
            rem Make normal from projected angle
            nx#=sin(ax#)
            ny#=cos(ax#)
            nz#=sin(az#)
 
            rem Setting matrix normal for smoothness
            set matrix normal mat,x,z,nx#,ny#,nz#
 
         next x
      next z
      update matrix mat
   EndFunction
 
rem =============================================================
rem = DATA STATEMENTS
rem =============================================================
data 77,97,116,114,105,120,32,87,97,121,112,111,105
data 110,116,32,68,101,109,111,32,45,32,67,111,112
data 121,114,105,103,104,116,32,50,48,48,55,32,76
data 97,116,99,104,32,71,114,97,112,112,108,101