automatic cars

Applications, Games, Tools, User libs and useful stuff coded in PureBasic
Realizimo
User
User
Posts: 71
Joined: Sun Nov 25, 2012 5:27 pm
Location: Sweden

automatic cars

Post by Realizimo »

And with an simple trackeditor.
It is verry hard to drive it yourselves

Code: Select all

;3D-racing without any 3d 
;2012-04-14 v0.56 by Realizmo
;modified 2014-12-28 v0.60
;modified 2017-07-18 v0.66
;modified 2021-01-16 v0.69
;
;F2  : Vsync Or Not
;F3  : paus 0,2 sec
;F4  : fastBrake car
;F5  : Change view (static / dynamic)
;
;-/+ : toughness
;
;pad 7/1 : x-axis angle
;pad 8/2 : move camera in Y-direction
;pad 9/3 : move camera in z-direction
;pad 4/6 : roadspace
;
;page-up/down: move everything upp/down
;
;ins/del  : change perspectiv
;home/End : level of detail
;
;G/B : Change car
;
;M   : roadmap
;K   : Control (auto/manual)
;Arrows  : turn , trottle , brake (manual control)
;Joystick: turn , trottle , brake (manual control)
InitJoystick() 
InitSprite ()
InitKeyboard()
;InitMouse() 
#ant_spelare=7 ; max 15 (=16st)
Global.f sinybil,cosybil,sinxbil,cosxbil,sinzbil,coszbil,sinxbilm,cosxbilm
Global.i bil,roadmap,b2
Global.f Dim x(#ant_spelare,14),Dim y(#ant_spelare,14),Dim z(#ant_spelare,14);,Dim tangent(256)
Global.l Dim xx(16000) ,Dim zz(16000),Dim tx(6000) ,Dim tz(6000),Dim yy(16000),Dim xxx(550),Dim yyy(550)
Global.w Dim ang_ax_y(6000),Dim ang_ax_x(6000)
Global.i Dim z1(14), Dim x1(14), Dim y1(14),Dim ordning(38),Dim farg(#ant_spelare)
Global.f Dim sin512(511),Dim cos512(511)      ;4 decimal
Global.a Dim randomizee(127,100),flagg2,max_sc2      ;1 bytes integer
Global.i count1,count2,count3,count4
;Global.s SoundFileName$="blipmono2.wav"
Global.i sc2,flagg1,c4,t
#rad=180/#PI
#v512=256/#PI
#fram=20
#roadmap_x=30000
#roadmap_y=40000
#roadmapzoom=300
#pace="        "

For c1=0 To 511:sin512(c1)=Sin(c1/#v512):cos512(c1)=Cos(c1/#v512):Next c1
Declare course_choser()
Declare course_randomize()
Declare course_maker(x1,y1,v1,vv1,x2,y2,v2,vv2)
Declare course_addjust()
Declare course_hill_randomizee()
Declare course_hill_maker()
Declare calculate_angles()
Declare play()

Declare load_courses()
Declare save_courses()
Declare plot_3d(nx1,ny1,nz1,nx2,ny2,nz2,y_glid,camera_y,camera_z,dist,farg) 

load_courses()
For c1=1 To 14: Read.i t:z1(c1)=t*2 :Read.i t:x1(c1)=t*2 :Read.i t :y1(c1)=t*-2+30:Next c1
For c1=1 To 38:Read.i ordning(c1):Next c1
For c1=0 To #ant_spelare:Read.i farg(c1):Next c1
DataSection
  Data.i -30,-15,-15,10,-15,-15,10,-15,0,40,-15,0,-30,-15,15,60,-15,15;bil-positions
  Data.i -30, 15,-15,10, 15,-15,10, 15,0,40, 15,0,-30, 15,15,60, 15,15;bil-positions
  Data.i 0,0,-15,0,0,15                                               ;bil-positions
  Data.i 1,2,2,3,3,4,4,6,6,5,5,1  ,7,8,8,9,9,10,10,12,12,11,11,7 ,1,7,2,8,3,9,4,10,6,12,5,11 ,13,14;bil-streck
  Data.i $ffffff,$888888,$ff0000,$ffff00,$00ff00,$0000ff,$ff00ff,$00ffff                           ;bil-färger
  Data.i $88ff88,$555555,$ff8888,$888800,$008800,$008888,$880088,$88ffff                           ;bil-färger
EndDataSection
OpenScreen (1024, 768 , 32 , "test" , 0); [,RefreshRate ])
                                        ;SetFrameRate(60)
;- sound
;{
#a1=13
#a2=12
#a3=13
CAPTURECLOCK   = 11025                                      ; Sampling/Replay frequency in 'samples per second' 
BLKSIZE        = #a1*(#a2+#a3)                              ;312   ; Number of samples in capture/play block 
BytesPerSample = 2                                          ; Number of bytes needed for each sample 
Channels       = 1                                          ; Number of channels, 1 for mono, 2 for stereo.
BufSize        =  (BytesPerSample * Channels * BLKSIZE * Channels) ; Buffer to hold TWO blocks
*Header        =  AllocateMemory(BufSize + 12 + 24 + 8)            ; Memory for header and buffer
*P = *Header
;                                                         'RIFF' chunk descriptor - 12 bytes
PokeS(*P,"RIFF",4, #PB_Ascii)               : *P + 4        ; 00-03 Chunk ID                                     4
PokeL(*P,0)                                 : *P + 4        ; 04-07 Chunk data size (Place holder)               4
PokeS(*P,"WAVE",4, #PB_Ascii)               : *P + 4        ; 08-11 'RIFF type'                                  4

;                                                         'fmt' Subchunk          - 24 bytes
PokeS(*P,"fmt ",4, #PB_Ascii)               : *P+ 4         ; 12-15 'SubChunk ID'
PokeL(*P,16)                                : *P+ 4         ; 16-19 'Chunk data size'

PokeW(*P,1)                                 : *P+ 2         ; 20-21 'Compression code' 1=Non-compressed data PCM  2
PokeW(*P,Channels)                          : *P+ 2         ; 22-24 'Number of channels'                          2
PokeL(*P,CAPTURECLOCK)                      : *P+ 4         ; 24-27 'Sample rate'                                 4
PokeL(*P,Channels * BytesPerSample * CAPTURECLOCK) : *P+ 4  ; 28-31 'Average bytes per second'                    4
PokeW(*P,BytesPerSample * Channels)         : *P+ 2         ; 32-33 'Block align' Bytes per sample slice          2
PokeW(*P,8 * BytesPerSample )               : *P+ 2         ; 34-35 'Significant bits per sample'                 2

;                                                         'data' Subchunk          - 8 bytes (+Buffer)
PokeS(*P,"data",4, #PB_Ascii)               : *P + 4        ; 'SubChunk ID'                                      4
PokeL(*P,BufSize)                           : *P + 4        ; Length of my data      
PokeL(*P,BufSize)                           : *P + 4        ; Length of my data                                  4
FillMemory(*P,BufSize,0,#PB_Word)                           ; Clear the buffer

For b=1 To #a1
  For a=1 To #a2
    PokeW(*p,$0733) : *P + 2
  Next a
  For a=1 To #a3
    PokeW(*p,$F8CD) : *P + 2 
  Next a
Next b
InitSound()
CatchSound(0,*Header)
CatchSound(1,*Header)
SetSoundFrequency(0, 5500) 
SetSoundFrequency(1, 23500) 
;}
sc2=max_sc2
flagg1=1
course_choser()
Procedure course_choser()
  Repeat
    If flagg1=1 Or flagg1=8:course_randomize():course_addjust():course_hill_randomizee():EndIf
    If flagg1=16:course_hill_randomizee() :EndIf
    ClearScreen (RGB (0, 0, 0))
    StartDrawing (ScreenOutput())    
    For c1=0 To c4 Step 6
      xx= (xx(c1)+38000)/100:yy=(zz(c1)+38000)/100
      If xx>-1 And xx<1024 And yy>-1 And yy<768:Plot(xx,yy,$FFFFFF):EndIf            
      xx=(c1*60+38000)/100:yy=(yy(c1)+38000)/100
      Plot((xx-380)*0.3,400+yy*0.5,$F00FFF)
    Next c1          
    
    DrawText (5, 0, "Space=start    0-9🡩🡫=Track    F1=New End Track    F2=go To End Track    F3=randomize Track & slope    F4=randomize slope   S=Save   ESC=Exit")
    DrawText (50, 30, "Active Track: "+Str(sc2)+"   End Track: "+Str(max_sc2)+"   Tracklength: "+Str(c4))
    DrawText (50, 50,text$)
    If flagg1=1 : DrawText (50, 70,"Track "+Str(sc2)+" received"):EndIf ;numbers, M ,up,down
    If flagg1=8 : DrawText (50, 70,"Track "+Str(sc2)+" randomized"):EndIf ;F2              
    If flagg1=16 : DrawText (50, 70,"Track "+Str(sc2)+" Slopes randomized"):EndIf ;F3
    If flagg1=4 : DrawText (50, 70,"Track "+Str(max_sc2)+" Are last Track now"):EndIf ;F1
    If flagg1=5 : DrawText (50, 70,"All Tracks are saved on disk"):EndIf              ;S            
    StopDrawing():FlipBuffers():PlaySound(1):flagg1=0
    Repeat
      Delay(40)        
      ExamineKeyboard()
      t$=KeyboardInkey():time = ElapsedMilliseconds()
      If FindString("0123456789",t$,1)>0:text$+t$:oldtext$=text$:oldtime=time:flagg1=2:EndIf;ny siffra
      If Val(text$)>max_sc2:text$=Left(text$, Len(text$)-1):flagg1=0:EndIf                  ;om tal för stort
      If time-oldtime>500 And text$<>"":sc2=Abs(Val(text$)):text$="":flagg1=1:EndIf         ;hämta Track efter 500 ms
      If KeyboardPushed(#PB_Key_All)
        If KeyboardPushed(#PB_Key_Up) And sc2<max_sc2 :flagg1=1:sc2+1      :EndIf     ;receive Track
        If KeyboardPushed(#PB_Key_Down)And sc2>0      :flagg1=1:sc2-1      :EndIf     ;receive Track
        If KeyboardPushed(#PB_Key_F2)And sc2<max_sc2   :flagg1=1:sc2=max_sc2:EndIf    ;receive Track      
        If KeyboardPushed(#PB_Key_F3)                 :flagg1=8             :EndIf    ;randomize Track & slope           
        If KeyboardPushed(#PB_Key_F4)                 :flagg1=16             :EndIf   ;randomize slope  
        If KeyboardPushed(#PB_Key_Space)              :flagg1=1:calculate_angles():play()     :EndIf     ;play
        If KeyboardPushed(#PB_Key_F1)And flagg2=1 And sc2<100:max_sc2+1:flagg1=4:flagg2=0:EndIf          ;increase number of tracks
        If KeyboardPushed(#PB_Key_S) And flagg3=1     :flagg1=5:flagg3=0:save_courses()     :EndIf       ;Save
        If KeyboardPushed(#PB_Key_Escape):End                              :EndIf                        ;Exit
        If flagg1&24 :flagg3=1:If sc2=max_sc2 :flagg2=1:EndIf:EndIf     
      EndIf         
    Until flagg1<>0    
  ForEver
EndProcedure      
Procedure course_randomize()
  Protected.f axis_1 , axis_2 ,circel,x4,y4,x5,y5
  sc1=0:c4=0
  If flagg1<>1     
    randomizee(sc1+0,sc2)=Random(1) ;    åtta eller nolla
    randomizee(sc1+1,sc2)=Random(1) ;    ny axis
    randomizee(sc1+2,sc2)=Random(40);     ny axis
    randomizee(sc1+3,sc2)=Random(250);  åtta/nolla randomizee #radie
  EndIf
  otta=Int(randomizee(sc1,sc2)+1) ;2="8-image"   1="0-image"  
  circel=0
  x4= Sin(circel/#rad):y4= Cos(circel/#rad)  
  x3= x4*20000        :y3= y4*20000
  vv3=90
  v3= vv3+Int(randomizee(sc1+1,sc2)*2-1)*(randomizee(sc1+2,sc2)+50)    
  cc=randomizee(sc1+3,sc2)*32-4000
  sc1+4
  If otta=1: cc*3.5:EndIf
  x3=x3
  y3=y3+cc
  x2=x3:y2=y3:v2=v3:vv2=vv3
  Repeat    
    If flagg1<>1
      randomizee(sc1+0,sc2)=Random(25) ;    8/0 randomizee intervall      
      randomizee(sc1+1,sc2)=Random(1)  ;    new axis
      randomizee(sc1+2,sc2)=Random(40) ;     new axis
      randomizee(sc1+3,sc2)=Random(250);  8/0 randomizee radie
    EndIf    
    circel+25+randomizee(sc1+0,sc2)          
    x4= Sin(circel/#rad*otta)
    y4= Cos(circel/#rad)
    x5= Sin((circel+3)/#rad*otta)
    y5= Cos((circel+3)/#rad)    
    x1= x4*20000
    y1= y4*20000            
    vv1= ATan2(x5-x4,y4-y5)*#rad-90
    v1=vv1+Int(randomizee(sc1+1,sc2)*2-1)*(randomizee(sc1+2,sc2)+50)    
    axis_1=v1/#rad
    axis_2=v2/#rad
    cc=randomizee(sc1+3,sc2)*32-4000    
    sc1+4
    If otta=1: cc*3.5:EndIf
    x1+Cos(vv1/#rad)*cc
    y1-Sin(vv1/#rad)*cc
    If circel>350: x1=x3:y1=y3:v1=v3+180:vv1=vv3-180:EndIf                     ;
    
    course_maker (x1,y1,v1,vv1,x2,y2,v2,vv2);x=xposition    y=yposition   v=new axis    vv= axis        
    x2=x1:y2=y1:v2=v1-180:vv2=vv1-180          
  Until circel>350  
  c4-1  
EndProcedure        
Procedure course_maker(x1,y1,v1,vv1,x2,y2,v2,vv2)
  Protected.f  x1v1,x1v2,y1v1,y1v2,x2v1,x2v2,y2v1,y2v2,ang,axis_1,axis_2,vvv1,vvv2,a1f,b1f,a2f,xh,yh,hh
  
  axis_1=v1/#rad : axis_2=v2/#rad
  vvv1=vv1/#rad:vvv2=vv2/#rad 
  b1f=100/Sqr((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))  
  Repeat    
    x1_pos=x1    
    y1_pos=y1
    x2_pos=x2
    y2_pos=y2
    fl=0:a1f=0:a2f=0
    c1=0
    tx(c1+c4)=x2_pos
    tz(c1+c4)=y2_pos
    xxx(c1)=x1_pos
    yyy(c1)=y1_pos   
    Repeat      
      ang=-ATan2(y2_pos-y1_pos,x1_pos-x2_pos)      
      ;===============================================================
      a1f=a1f+b1f :If a1f>1 : a1f=1 :EndIf   
      x1v1=Sin(axis_1)
      x1v2=Sin(ang)
      y1v1=Cos(axis_1)
      y1v2=Cos(ang)      
      xh=x1v1*(1-a1f)+x1v2*a1f   
      yh=y1v1*(1-a1f)+y1v2*a1f   
      hh=Sqr(xh*xh+yh*yh);:If hh<0.8 :PlaySound(0): EndIf
      xh+Sin(vvv1)*(0.5-Abs(0.5-a1f))/(hh)
      yh+Cos(vvv1)*(0.5-Abs(0.5-a1f))/(hh)
      hh=Sqr(xh*xh+yh*yh)
      x1_pos=x1_pos+60*xh/hh 
      y1_pos=y1_pos+60*yh/hh      
      ;===============================================================            
      a2f=a2f+b1f :If a2f>1 : a2f=1 :EndIf        
      x2v1=Sin(axis_2)
      x2v2=Sin(ang-#PI)
      y2v1=Cos(axis_2)
      y2v2=Cos(ang-#PI)      
      xh=x2v1*(1-a2f)+x2v2*a2f   
      yh=y2v1*(1-a2f)+y2v2*a2f   
      hh=Sqr(xh*xh+yh*yh);:If hh<0.8 :PlaySound(0): EndIf
      xh+Sin(vvv2)*(0.5-Abs(0.5-a2f))/(hh)
      yh+Cos(vvv2)*(0.5-Abs(0.5-a2f))/(hh)
      hh=Sqr(xh*xh+yh*yh) ;:If hh<0.8 :PlaySound(1): EndIf
      x2_pos=x2_pos+60*xh/hh    
      y2_pos=y2_pos+60*yh/hh 
      ;================================================================================            
      tx(c1+c4)=x2_pos
      tz(c1+c4)=y2_pos
      xxx(c1+1)=x1_pos
      yyy(c1+1)=y1_pos
      c1+1
    Until Abs(x1_pos-x2_pos)<61 And Abs(y1_pos-y2_pos)<61 
    b1f=b1f+0.0001+(1-a1f)/200
  Until a1f=1 Or a1f>1  
  c3=c1-1 
  For c2=c3 To 0 Step-1    
    tx(c1+c4)=xxx(c2)    
    tz(c1+c4)=yyy(c2)    
    c1+1   :If c1+c4=6067:CallDebugger:EndIf
  Next  
  c4=c4+c1
EndProcedure
Procedure course_addjust()
  EnableExplicit
  Protected.i c1,c2,nyx,nyz,c5,c6
  Protected.f vx,vz,avst_x,avst_z,avst,avst2,avst_ny,avst_old
  ;Protected.s Dim fel(6000,2)
  #dens60=60
  c4+1
  tx(c4)=tx(0)
  tz(c4)=tz(0)
  c1=0:c2=1:avst=0
  xx(0)=tx(0):zz(0)=tz(0):
  Repeat  
    If avst=>#dens60
      xx(c2)=tx(c1-1)+vx*(#dens60-avst_old)
      zz(c2)=tz(c1-1)+vz*(#dens60-avst_old)
      avst-#dens60
      If avst<#dens60
        avst_old=avst
      Else
        avst_old-#dens60
      EndIf
      If avst_old>#dens60 : avst_old-#dens60:EndIf 
      c2+1
    Else            
      avst_x=tx(c1+1)-tx(c1)                      ;avst x        
      avst_z=tz(c1+1)-tz(c1)                      ;avst z 
                                                  ;avst_ny=Sqr(Pow(avst_x,2) + Pow(avst_z,2))  ;avst tot.
      avst_ny=Sqr(avst_x*avst_x + avst_z*avst_z)
      vx=avst_x/avst_ny                              ;riktn x
      vz=avst_z/avst_ny                              ;riktn z
      avst_old=avst
      avst+avst_ny
      c1+1
    EndIf
  Until c1=c4+1
  c4=c2-1
  DisableExplicit
EndProcedure
Procedure course_hill_randomizee()            
  Shared.i v1,v2,h1,h2,p1,p2;,c4 
  v2=0:v3=v2  
  h2=0:h3=h2
  p2=100
  sc1=64
  For c=0 To 6000:yy(c)=0:Next c
  For c=400 To c4-100 Step 300   
    v1=v2:h1=h2:p1=p2         
    If flagg1<>1
      randomizee(sc1,sc2)=Random(20);     ny axis      
      randomizee(sc1+1,sc2)=Random(200);    y      
    EndIf    
    v2= randomizee(sc1,sc2)    
    h2= (randomizee(sc1+1,sc2)-100)*50
    p2= c
    sc1+2
    course_hill_maker()
  Next c  
  v2=v3:h2=h3   
  course_hill_maker()
EndProcedure
Procedure course_hill_maker()
  Shared.i v1,v2,h1,h2,p1,p2
  Protected.i Dim avst_xz(150)
  Protected.f grad,avst,x1,x2,y1,y2,ha1,ha2,avst_yy
  c2=(p2-p1)/2 
  ha1=h1:ha2=h2
  For c1=0 To  c2
    grad=grad+0.006:If grad>1 : grad=1:PlaySound(0):EndIf
    yy(p1+c1)=ha1
    yy(p2-c1)=ha2
    avst_yy=yy(p1+c1)-yy(p2-c1)
    avst_xz=avst_xz(c1)
    y1=avst_yy/(c2-c1)
    ha1-y1*grad
    ha2+y1*grad
  Next c1
EndProcedure
Procedure calculate_angles()
  For c1=0 To c4
    c2=c1-1:c3=c1+1
    If c2<0: c2=c4:EndIf
    If c3>c4:c3=0:EndIf       
    xx=xx(c2)-xx(c3)
    zz=zz(c2)-zz(c3)
    ;z=Sqr(Pow(xx,2)+Pow(zz,2))
    z=Sqr(xx*xx+zz*zz)
    
    ang_ax_y(c1)=Int((ATan2(xx ,zz))* #v512)&511
    ang_ax_x(c1)=Int((ATan2(yy(c2)-yy(c3) ,z)-#PI/2)* #v512)&511
  Next c1  
EndProcedure  
Procedure play()
  EnableExplicit
  Protected.s Dim timelist(#ant_spelare), Dim timelist2(#ant_spelare)
  Protected.i car_nr,x3_axis,z3_axis,color,temp,kontr,bilyy,farg,fram,bilavst,bilbyt,bilbyt2,y_glid,camera_y,dist,rate
  Protected.i ang_ax_y,x4_axis,x5_axis
  Protected.i ElapsedTime,StartTime,mellanraceTime ,check,m_time_a,m_time_b
  Protected.i vg_br,detalj,dyn
  Protected.i b3,avst,avst1,avst2
  Protected.i nx,ny,nz,nx1,ny1,nz1,nx2,ny2,nz2,x1,y1,x2,y2
  Protected.i avst_x,avst_z,avst_y,y2old
  Protected.f sinx,cosx,cosy,siny,cosz,sinz
  Protected.f Dim y1_axis(#ant_spelare),Dim y2_axis(#ant_spelare)
  Protected.f riktn_x,riktn_z,riktn_y,a,b,c,z,y1_axis,Acceleration,camera_z
  Protected.f rx,rrx,rz,rrz,ry,rry
  Protected.i Dim car_pos(#ant_spelare), Dim car_pos2(#ant_spelare),Dim y3_axis(#ant_spelare)
  Protected.i Dim varv(#ant_spelare)  ,Dim s_time(#ant_spelare),Dim v_time(#ant_spelare), Dim s_list(#ant_spelare), Dim m_time_fl(#ant_spelare)
  Protected.f Dim speeed(#ant_spelare), Dim acc(#ant_spelare), Dim brake(#ant_spelare),Dim toughness(#ant_spelare),Dim steer_speed(#ant_spelare)
  Protected.f Dim avstold(#ant_spelare)
  
  Delay(300)
  For car_nr=0 To #ant_spelare
    varv(car_nr)=-1
    m_time_fl(car_nr)=1
    x(car_nr,0)=xx(c4-car_nr*10)
    y(car_nr,0)=yy(c4-car_nr*10)
    z(car_nr,0)=-zz(c4-car_nr*10)
    car_pos(car_nr)=c4-car_nr*10 : car_pos2(car_nr)=c4-car_nr*10+1
    y2_axis(car_nr)=ValF(Str(ang_ax_y(c4-car_nr*10)))
    s_time(car_nr) = ElapsedMilliseconds()
    
    toughness(car_nr)=54-car_nr*0.3
    acc(car_nr)=0.08+car_nr/200
    brake(car_nr)=-0.70+car_nr/80
    steer_speed(car_nr)=car_nr*2+4
  Next car_nr
  
  ;bil=1 
  y_glid=140
  camera_y=0
  x4_axis=60
  dist=256
  camera_z=-142
  vg_br=470
  detalj=1000:If detalj>c4/2:detalj=c4/2:EndIf;detalj=1860
                                              ;car_pos(bil)=bil:b2=bil:b3=bil
  m_time_a=c4/2:m_time_b=m_time_a+200   
  roadmap=1
  rate=60 :SetFrameRate(rate)
  ;-----loop 
  

  Global.i adr,len
  CreateSprite(1,1024, 768)
  StartDrawing(SpriteOutput(1))
  adr= DrawingBuffer()
  len= DrawingBufferPitch()*(768)
  StopDrawing()
  Repeat
    FlipBuffers()
    
    ElapsedTime = ElapsedMilliseconds()-StartTime 
    StartTime = ElapsedMilliseconds()             ; Get the actual value
    DisplaySprite(1 , 0 , 0)
;     StartDrawing (ScreenOutput())
    StartDrawing(SpriteOutput(1))
;     Box(0,0, 1024, 768,0)
    FillMemory(adr,len)
    DrawText (0, 0, "updatespeed (F2) ");+Str(rate)+ " " +Str(ElapsedTime))
    LineXY(0,18,ElapsedTime*10,18)
    DrawText (400, 20, "position "+Str(car_pos(bil)))
    DrawText (400, 35, "Maxnr  "+Str(c4))
    DrawText (520, 5, "Car-nr:  "+Str(bil))
    DrawText (520, 20, "Time:  "+StrF(Int(ElapsedMilliseconds()-s_time(bil))/1000,2))
    DrawText (520, 35, "speed:  "+Str(speeed(bil)*-3))
    ;   DrawText (520, 50, "count 1:  "+Str(count1))
    ;   DrawText (520, 70, "count 2:  "+Str(count2))
    ;   DrawText (520, 90, "count 3:  "+Str(count3))
    ;   DrawText (520, 110, "count 4:  "+Str(count4))
    
    
    DrawText (694, 0,"car     lap     Laptime      tough")
    For temp=0 To #ant_spelare;: DrawText (700, temp *20,timelist2(temp))
                   ;If s_list(temp)&8:bilbyt=temp:EndIf
      car_nr=s_list(temp)&15
      If car_nr=bil:bilbyt=temp:Circle(690,temp *20+27,3,farg(car_nr)):EndIf 
      DrawText (700, temp *20+20,Str(car_nr)+#pace+Str(varv(car_nr)) +#pace+timelist(car_nr)+#pace+StrF(toughness(car_nr),2) ,farg(car_nr))
      If temp<#ant_spelare:
        bilavst=car_pos(car_nr)-car_pos(s_list(temp+1)&15):If bilavst<0 :bilavst+c4:EndIf
        LineXY(700,temp *20+37,700+bilavst,temp *20+37)
      EndIf
    Next temp
    
    ExamineKeyboard()
    
    If KeyboardReleased(#PB_Key_F2) :rate!1000 : SetFrameRate(rate):EndIf
    If KeyboardReleased(#PB_Key_F5) :dyn!1             :EndIf      ;Change view (statisk/dynamisk)
    If KeyboardPushed(#PB_Key_All)
    If KeyboardPushed(#PB_Key_F3) :Delay(200)          :EndIf
    If KeyboardPushed(#PB_Key_F4) :speeed(bil)=-0.5    :EndIf      ;checkspeeed
    
    
    If KeyboardPushed(#PB_Key_Subtract):toughness(bil)-0.05:EndIf  ;drivers toughness                       
    If KeyboardPushed(#PB_Key_Add):toughness(bil)+0.05     :EndIf
    
    If KeyboardPushed(#PB_Key_Pad7) :x4_axis=(x4_axis + 1)&511 :EndIf ;camera angle
    If KeyboardPushed(#PB_Key_Pad1) :x4_axis=(x4_axis - 1)&511 :EndIf
    If KeyboardPushed(#PB_Key_Pad8) :camera_y +1           :EndIf     ;y-axis camera
    If KeyboardPushed(#PB_Key_Pad2) :camera_y -1           :EndIf
    If KeyboardPushed(#PB_Key_Pad3) :camera_z +(Abs(camera_z+dist)/100) +0.1:EndIf  ;camera dist
    If KeyboardPushed(#PB_Key_Pad9) :camera_z -(Abs(camera_z+dist)/100) -0.1:EndIf
    If KeyboardPushed(#PB_Key_Pad6) :vg_br=(vg_br +1)&1023  :EndIf    ;roadspace
    If KeyboardPushed(#PB_Key_Pad4) :vg_br=(vg_br -1)&1023  :EndIf      
    
    If KeyboardPushed(#PB_Key_PageDown) :y_glid +1       :EndIf       ;move everything upp/down
    If KeyboardPushed(#PB_Key_PageUp) : y_glid -1       :EndIf  
    
    If KeyboardPushed(#PB_Key_Insert):dist /1.01       :EndIf         ;perspektiv/avstånd
    If KeyboardPushed(#PB_Key_Delete):dist *1.01       :EndIf
    If KeyboardPushed(#PB_Key_Home):detalj +1          :EndIf         ;road
    If KeyboardPushed(#PB_Key_End):detalj -1           :EndIf
    EndIf
    
    If KeyboardReleased(#PB_Key_B) And bilbyt<#ant_spelare :bilbyt+1:bil=s_list(bilbyt)&15:kontr=0:EndIf        ;change bil
    If KeyboardReleased(#PB_Key_G) And bilbyt>0            :bilbyt-1:bil=s_list(bilbyt)&15:kontr=0:EndIf  
    
    If KeyboardReleased(#PB_Key_M):roadmap=(roadmap+1)&3:EndIf        ;roadmap 
    If KeyboardReleased(#PB_Key_K):kontr!1              :EndIf        ;steer manual or auto
                                                                      ;-car physics 
                                                                      ;{ ----cars
    For car_nr =0 To #ant_spelare                                                ; 0-7 ---- 8 st cars
      x3_axis=ang_ax_x(car_pos(car_nr)) 
      If kontr=1 And car_nr=bil ;manual control  
        If KeyboardPushed(#PB_Key_Left) :y1_axis(bil) -0.35 :EndIf ;turn axis y-axis
        If KeyboardPushed(#PB_Key_Right):y1_axis(bil) +0.35 :EndIf  
        If KeyboardPushed(#PB_Key_Down) :speeed(bil)+0.5 :If speeed(bil)>0:speeed(bil)=0:EndIf:EndIf     ; Brake
        If KeyboardPushed(#PB_Key_Up  ) :speeed(bil)-0.5        :EndIf                                   ; trottle
        If ExamineJoystick(0)      
          If JoystickAxisX(0)=-1 :y1_axis(bil) -0.25    :EndIf ;turn L
          If JoystickAxisX(0)=1:y1_axis(bil) +0.25      :EndIf ;turn R
          If JoystickButton(0, 4) :speeed(bil)-0.4        :EndIf                    ; trottle
          If JoystickButton(0, 3)   :speeed(bil)+0.5 :If speeed(bil)>0:speeed(bil)=0:EndIf:EndIf ; Brake
        EndIf
        y1_axis(bil)*0.9
        y2_axis(bil)+y1_axis(bil)
      Else
        ;- car turn
        fram=car_pos(car_nr)-speeed(car_nr)/3+2;3+7
        If fram>c4 :fram-c4:EndIf
        nx= -xx(fram)+x(car_nr,6):nz= zz(fram)+z(car_nr,6):avst1=Sqr(nx*nx+nz*nz)
        ;     plot_3d(-xx(fram),yy(fram),zz(fram),-x(car_nr,6),y(car_nr,6),-z(car_nr,6),y_glid,camera_y,camera_z,dist,0) 
        nx= -xx(fram)+x(car_nr,12):nz= zz(fram)+z(car_nr,12):avst2=Sqr(nx*nx+nz*nz)
        ;    plot_3d(-xx(fram),yy(fram),zz(fram),-x(car_nr,12),y(car_nr,12),-z(car_nr,12),y_glid,camera_y,camera_z,dist,0) 
        y1_axis=(avst2-avst1)/steer_speed(car_nr)
        If Abs(y1_axis)>2.35 :y1_axis=2.35*Sign(y1_axis):EndIf
        y2_axis(car_nr)+y1_axis
        
        ;- car speed
        fram=car_pos(car_nr)+Abs(speeed(car_nr))
        If fram>c4 :fram-c4:EndIf
        nx=((ang_ax_y(fram)-ang_ax_y(car_pos(car_nr))+256)&511-256)
        ;plot_3d(-xx(fram),yy(fram),zz(fram),-xx(car_pos(car_nr)),yy(car_pos(car_nr)),zz(car_pos(car_nr)),y_glid,camera_y,camera_z,dist,0) 
        Acceleration=(toughness(car_nr)-Abs(nx))/150; toughness(car_nr) högre = snabbare (48)
        If Acceleration>Acc(car_nr) : Acceleration=Acc(car_nr): EndIf
        If Acceleration<brake(car_nr) : Acceleration=brake(car_nr): EndIf
        
        speeed(car_nr)-Acceleration
      EndIf
      y3_axis(car_nr)=Int(y2_axis(car_nr))&511
      
      ;-x & z axis-axis      
      temp=(y3_axis(car_nr)-ang_ax_y(car_pos(car_nr)))&511      
      If x3_axis>256: x3_axis-512:EndIf
      z3_axis=Int(x3_axis*sin512(temp))&511
      x3_axis=Int(x3_axis*cos512(511-temp))&511  
      
      sinx=sin512(x3_axis);12
      cosx=Cos512(x3_axis);12
      siny=-sin512(y3_axis(car_nr));13
      cosy=-cos512(y3_axis(car_nr));13
      sinz=sin512(z3_axis)         ;13
      cosz=cos512(z3_axis)         ;13
      If car_nr=bil                ;camera
        sinxbilm=sin512(x4_axis)   ;12
        cosxbilm=Cos512(x4_axis)   ;12
        sinybil=siny:cosybil=cosy:sinzbil=sinz:coszbil=cosz
        If dyn:sinxbil=0:cosxbil=1 :Else :sinxbil=sinx:cosxbil=cosx : EndIf
      EndIf
      z(car_nr,0) +speeed(car_nr)*siny
      x(car_nr,0) -speeed(car_nr)*cosy
      ; set the car in y-pos
      avst_x=(xx(car_pos(car_nr))-x(car_nr,0))
      avst_x* avst_x
      avst_z=(zz(car_pos(car_nr))+z(car_nr,0))
      avst_z*avst_z
      a =Sqr(avst_x+ avst_z)   
      avst_x=(xx(car_pos2(car_nr))-x(car_nr,0))
      avst_x*avst_x
      avst_z=(zz(car_pos2(car_nr))+z(car_nr,0))
      avst_z*avst_z
      b =Sqr(avst_x+ avst_z)
      avst_x=(xx(car_pos(car_nr))-xx(car_pos2(car_nr)))
      avst_x*avst_x+30
      avst_z=(zz(car_pos(car_nr))-zz(car_pos2(car_nr)))
      avst_z*avst_z+30
      c =Sqr(avst_x+ avst_z)
      z=(-b*b+c*c+a*a)/(2*c)/#dens60; Marcus formula
      avst_y = yy(car_pos(car_nr)) - yy(car_pos2(car_nr))
      y(car_nr,0) = yy(car_pos(car_nr)) - (avst_y)* z
      
      ;-play loop start 
      avstold(car_nr)=1100
      For b3=car_pos(car_nr)-1 To car_pos(car_nr)+3
        b2=b3
        ; when car passing start
        If b3>c4 :b2=b3-c4:EndIf
        If b3<0 :b2=b3+c4:EndIf
        ; new car-positions                    
        nx= -xx(b2)+x(car_nr,0)
        ny= yy(b2)-y(car_nr,0)
        nz= zz(b2)+z(car_nr,0)
        avst=Sqr(nx*nx+nz*nz+ny*ny); distance to each point without rotation  
        If avst<avstold(car_nr)        
          car_pos2(car_nr)  = car_pos(car_nr)        
          avstold(car_nr) = avst        
          car_pos(car_nr)= b2        
        EndIf      
      Next b3
      ; -collision wall
      If avstold(car_nr)>vg_br
        nx1=-xx(car_pos(car_nr))+x(car_nr,0)
        nz1= zz(car_pos(car_nr))+z(car_nr,0)
        x(car_nr,0)-nx1/100
        z(car_nr,0)-nz1/100
        speeed(car_nr)*0.9:PlaySound(0):
        If kontr=0 Or car_nr<>bil:toughness(car_nr)-0.03:EndIf
      EndIf
      
      For temp= 1 To 14; angled car-positions   
        rx =   cosz * x1(temp) + sinz * y1(temp); z-axis
        ry =  -sinz * x1(temp) + cosz * y1(temp); z-axis
        rry =  cosx * ry - sinx * z1(temp)      ; x-axis
        rz =   sinx * ry + cosx * z1(temp)      ; x-axis
        rrx =   siny * rx + cosy * rz           ; y-axis
        rrz =   cosy * rx - siny * rz           ; y-axis
        z(car_nr,temp)= z(car_nr,0)+rrz
        x(car_nr,temp)= x(car_nr,0)+rrx
        y(car_nr,temp)= y(car_nr,0)-rry
      Next temp
      ;--check gool    
      If car_pos(car_nr)<3
        ;If car_pos(car_nr)<1:End:EndIf
        ;If car_pos(car_nr)>0
        If  m_time_fl(car_nr)
          varv(car_nr)=varv(car_nr)+1:m_time_fl(car_nr)=0
          v_time(car_nr) = ElapsedMilliseconds()-s_time(car_nr):PlaySound(1)  
          s_time(car_nr) = ElapsedMilliseconds() :timelist(car_nr)= " "+StrF(v_time(car_nr)/1000,2);: bil "+Str(car_nr)
          ;CopyArray(timelist(),timelist2()):SortArray(timelist2(),#PB_Sort_Ascending)
        EndIf
        ;EndIf
      EndIf
      
      ;--check half track
      If m_time_fl(car_nr)=0 And car_pos(car_nr)>m_time_a And car_pos(car_nr)<m_time_b :m_time_fl(car_nr)=1:PlaySound(1):EndIf;mellanraceTime = ElapsedMilliseconds()-s_time(car_nr) :   :PlaySound(1) 
      ;--sortlist  cars
      s_list(car_nr)=varv(car_nr)*131072+car_pos(car_nr)*16+car_nr
    Next car_nr                          
    SortArray(s_list(),#PB_Sort_Descending)
    ;}
    ;-plot track
    FrontColor($FF0000) 
    For b3=car_pos(bil)+detalj To car_pos(bil)-detalj Step-1
      b2=b3
      If b3>c4 :b2=b3-c4-1:EndIf; when passing start
      If b3<0 :b2=b3+c4+1:EndIf ; when passing start
      ang_ax_y=(ang_ax_y(b2)+128)&511 ; 90 degree road-direction
      nx1= -xx(b2)+cos512(ang_ax_y)*(vg_br+30) ;make road spacious
                                               ;ny1= yy(b2)
      nz1= zz(b2)-sin512(ang_ax_y)*(vg_br+30)  
      nx2= -xx(b2)-cos512(ang_ax_y)*(vg_br+30) 
      ;ny2= yy(b2)
      nz2= zz(b2)+sin512(ang_ax_y)*(vg_br+30)  
      
      If b2&63=0: FrontColor($008800) : EndIf      ;darkgreen 
      If b2&63=32: FrontColor($FF0000) : EndIf     ; blue
      plot_3d(nx1,yy(b2),nz1,nx2,yy(b2),nz2,y_glid,camera_y,camera_z,dist,roadmap)   
      
      If b3&4 And roadmap=1:Plot((xx(b2)+#roadmap_x)/#roadmapzoom,(zz(b2)+#roadmap_y)/#roadmapzoom):EndIf                  ;roadmap       
    Next b3
    If roadmap = 3
      For b3=0 To c4
        If b3&63=0: FrontColor($008800) : EndIf      ;darkgreen  
        If b3&63=32: FrontColor($FF0000) : EndIf     ;blue
        If b3 & 4 
          Plot((xx(b3)+#roadmap_x)/#roadmapzoom,(zz(b3)+#roadmap_y)/#roadmapzoom)
        EndIf
      Next b3
    EndIf
    ;--plot_cars
    For car_nr =0 To #ant_spelare
      FrontColor(farg(car_nr))
      If roadmap :Circle (  (x(car_nr,0)+#roadmap_x)/#roadmapzoom, (-z(car_nr,0)+#roadmap_y)/#roadmapzoom,1):EndIf; bilar på karta
      
      For temp= 1 To 38 Step 2 ; plot all car-lines  
        nx1= -x(car_nr,ordning(temp))   
        ny1= y(car_nr,ordning(temp)); 
        nz1= -z(car_nr,ordning(temp))  
        nx2= -x(car_nr,ordning(temp+1)) 
        ny2= y(car_nr,ordning(temp+1))
        nz2= -z(car_nr,ordning(temp+1))    
        plot_3d(nx1,ny1,nz1,nx2,ny2,nz2,y_glid,camera_y,camera_z,dist,0)        
      Next temp
    Next car_nr
    
    StopDrawing() 
  Until KeyboardReleased(#PB_Key_Escape)
EndProcedure

Procedure plot_3d(nx1,ny1,nz1,nx2,ny2,nz2,y_glid,camera_y,camera_z,dist,roadmap)
  Protected.l rx,rrx,ry,rry,rz,rrz,ry2,rrx2,rz2
  Protected.l nx,ny,nz
  Protected.l x1,y1,x2,y2
  nx= nx1+x(bil,0)
  ny= ny1-y(bil,0)
  nz= nz1+z(bil,0) 
  ;+++++++++++++++++-- anglade positions   (position 1)
  rx =   sinybil * nx + cosybil * nz; y-axis
  rz =  -cosybil * nx + sinybil * nz; y-axis
  ry =   cosxbil * ny - sinxbil * rz; x-axis
  rrz =  sinxbil * ny + cosxbil * rz; x-axis
  rrx =  coszbil * rx - sinzbil * ry; z-axis
  rry =  sinzbil * rx + coszbil * ry; z-axis
  ry =   cosxbilm * rry - sinxbilm * rrz +camera_y;x-axis-manual
  rz =   sinxbilm * rry + cosxbilm * rrz +camera_z;x-axis-manual
  If dist + rz > 0                                ;if point front of camera
                                                  ;+++++++++++++------2D & zoom
    nx= nx2+x(bil,0)
    ny= ny2-y(bil,0)
    nz= nz2+z(bil,0)
    ;+++++++++++++++++- anglade positions   (position 2)
    rx =   sinybil * nx + cosybil * nz; y-axis
    rz2 = -cosybil * nx + sinybil * nz; y-axis
    ry2 =  cosxbil * ny - sinxbil * rz2; x-axis
    rrz =  sinxbil * ny + cosxbil * rz2 ; x-axis
    rrx2 = coszbil * rx - sinzbil * ry2; z-axis
    rry =  sinzbil * rx + coszbil * ry2 ; z-axis
    ry2 =  cosxbilm * rry - sinxbilm * rrz +camera_y;x-axis-manual
    rz2 =  sinxbilm * rry + cosxbilm * rrz +camera_z;x-axis-manual
    If dist + rz2 > 0                                ;if point front of camera 
                                                     ;+++++++++++++------2D & zoom
      y1= dist* ry  / (dist + rz) +768-y_glid
      y2= dist* ry2 / (dist + rz2)+768-y_glid
      If y1<768 Or y2<768
        If y1>20 Or y2>20
          x1= dist* rrx  / (dist + rz) +512
          x2= dist* rrx2 / (dist + rz2)+512
          If x1>0 Or x2>0 
            If x1<1024 Or x2<1024
              If b2:LineXY (  x1,y1,x2,y2):Else:LineXY (  x1,y1,x2,y2,255):EndIf
              If roadmap=2 : Plot((xx(b2)+#roadmap_x)/#roadmapzoom,(zz(b2)+#roadmap_y)/#roadmapzoom):EndIf 
              ;   Else :count4+1    
            EndIf
            ;  Else :count3+1    
          EndIf
          ; Else :count2+1    
        EndIf
        ;Else :count1+1    
      EndIf
    EndIf
  EndIf
EndProcedure
DisableExplicit
Procedure load_courses()
  If ReadFile(0, "courses_data.txt")  
    max_sc2=ReadByte(0):flagg2=ReadByte(0):For c2=3 To 16:ReadByte(0):Next c2
    For c2=0 To 100:For c1=0 To 127
        randomizee(c1,c2)=ReadByte(0)
    Next c1:Next c2
    CloseFile(0)             
  Else
    MessageRequester("Information","Couldn't open the file!")
  EndIf
EndProcedure
Procedure save_courses() 
  If CreateFile(0, "courses_data.txt")         
    WriteByte(0,max_sc2):WriteByte(0,flagg2):For c2=3 To 16:WriteByte(0,0):Next c2
    For c2=0 To 100:For c1=0 To 127
        WriteByte(0,randomizee(c1,c2))
    Next c1:Next c2
    CloseFile(0)                  
  Else
    MessageRequester("Information","may not create the file!")
  EndIf  
EndProcedure