Here is the complete code.
<code>
rem title pcgamercc
rem author : dbs-LB
rem date* date : 16th sat-sun sept 2000
rem circuit challenge v1.02
rem for pv gamer
rem 19/09/2000
rem by dbs-lb
set camera range 100,10000
backdrop off
autocam off
hide mouse
sync on
rem checked=888888888888888888888888888888888888888888888888888888888888
rem Data structure for car
dim x#(4)
dim y#(4)
dim z#(4)
dim speed#(4)
dim ix#(4)
dim iz#(4)
dim a#(4)
dim tilt#(4)
dim wpi(4)
dim onbridge(4)
dim nextcheckpoint(4)
dim currentlap(4)
dim currentime(4)
dim fuel#(4)
dim damage#(4)
dim gear#(4)
dim gearstep(4)
dim freezepenalty(4)
dim dronespeed#(4)
dim toofarcount(4)
dim timemu(4)
dim timest(4)
dim timesu(4)
dim timese(4)
dim hiname$(4,10)
dim hitime(4,10)
dim hiscoew(33)
dim wpx#(4,100)
dim wpz#(4,100)
dim checkpointsx(20)
dim checkpointsz(20)
dim segmap(400)
dim segtype(400)
rem Segment Type Data structure
dim segzones(50,10)
dim bridgezones(4,10)
restore segmenttypedata
read segtypemax
for segtype=1 to segtypemax
read segzonesmax
segzones(segtype,0)=segzonesmax
for zone=1 to segzonesmax
read segzone
segzones(segtype,zone)=segzone
next zone
if segtype=7
for car=1 to 4
for zone=0 to segzonesmax
bridgezones(car,zone)=segzones(segtype,zone)
next zone
next car
endif
next segtype
rem Map zone structure
dim mapzonex(100,2)
dim mapzonez(100,2)
restore mapzonedata
read zonemax
for zone=1 to zonemax
read t,x1,z1,x2,z2
mapzonex(zone,1)=x1
mapzonez(zone,1)=z1
mapzonex(zone,2)=x2
mapzonez(zone,2)=z2
next zone
rem Temp arrays
dim tx#(10)
dim tz#(10)
rem Title bitmap
load bitmap "bits\title.bmp",1
load bitmap "bits\title.bmp",2 : fade bitmap 2,30
rem Make display images
load bitmap "bits\font.bmp",3
set current bitmap 3
for d=0 to 9
get image 100+d,(d*48),0,(d*48)+48,26
next d
for d=0 to 1
get image 110+d,(d*48),27,(d*48)+48,27+26
next d
get image 112,0,473,244,512
set text size 50
set text font "Arial"
cls rgb(255,255,0)
get image 120,0,0,32,32
cls rgb(255,0,0)
get image 121,0,0,32,32
cls 0
center text 160,8,"WINNER"
get image 122,0,0,320,64
for t=1 to 4
cls 0
center text 160,8,"PLAYER "+str$(t)
get image 122+t,0,0,320,64
next t
for t=1 to 4
if t=1 then t$="3"
if t=2 then t$="2"
if t=3 then t$="1"
if t=4 then t$="GO!"
cls 0
center text 160,8,t$
get image 127+t,0,0,320,64
next t
delete bitmap 3
set current bitmap 0
rem Make all decal objects
for plr=0 to 1
rem Make decals
for decal=11 to 22
if decal=22
make object plain decal+(plr*20),244,39
else
if decal>=19 and decal<=21
make object plain decal+(plr*20),24,14
else
if decal>=17 and decal<=18
make object plain decal+(plr*20),140,10
position object decal+(plr*20),70,-1,0
make mesh from object decal+(plr*20),decal+(plr*20)
delete object decal+(plr*20)
make object decal+(plr*20),decal+(plr*20),0
else
make object plain decal+(plr*20),24,14
endif : endif : endif
lock object on decal+(plr*20)
scale object decal+(plr*20),100,100,1000
set object decal+(plr*20),1,0,1,0
next decal
` rem Player decals offset
tptop=200
tpoffset=-160+(plr*320)
rem Place lap decals
for decal=11 to 12
position object decal+(plr*20),tpoffset+(((decal-11)*32)-106),tptop+30,400
next decal
rem Place time decals
for decal=13 to 16
position object decal+(plr*20),tpoffset+(((decal-13)*28)+20),tptop+30,400
next decal
rem Place fuel and damage decals
for decal=17 to 18
position object decal+(plr*20),tpoffset-35,tptop+((decal-17)*14)-7,400
texture object decal+(plr*20),120+(decal-17)
next decal
rem Place slash
decal=19
position object decal+(plr*20),tpoffset+((22)-106)-4,tptop+29,400
texture object decal+(plr*20),111
rem Place colons
for decal=20 to 21
position object decal+(plr*20),tpoffset+(((decal-20)*57)+43),tptop+31,400
texture object decal+(plr*20),110
next decal
rem Place status box
decal=22
position object decal+(plr*20),(tpoffset+30)-30,tptop,400
texture object decal+(plr*20),112
next plr
rem Prompt Decal
for decal=50 to 51
make object plain decal,320,64
lock object on decal
scale object decal,100,100,1000
set object decal,1,0,1,0
position object decal,0,20-((decal-50)*40),400
texture object decal,122+(decal-50)
hide object decal
next decal
load sound "sound19.wav",131
rem Setup cars
for car=1 to 4
load object "car\newcar.x",car
set object rotation zyx car
load image "car\tex0"+str$(car)+".bmp",car
texture object car,car
rem sounds for cars **SND
load sound "sounds\car"+str$(car)+".wav",(car*10)+0
load sound "sounds\crash2.wav",(car*10)+1 : set sound speed (car*10)+1,9000
load sound "sounds\crash"+str$(1+rnd(2))+".wav",(car*10)+2 : set sound speed (car*10)+2,10000+rnd(2000)
load sound "sounds\revup.wav",(car*10)+3
load sound "sounds\lapping.wav",(car*10)+4
load sound "sounds\warp.wav",(car*10)+5
load sound "sounds\crowd.wav",(car*10)+6
load sound "sound19.wav",333
next car
rem Make a grid to track car locations
load object "track\ground.x",5
position object 5,0,-10,0
rem Place camera
position camera 0,1000,-50
point camera 0,0,0
rem Default settings
lapmax=3
difficulty=1
tracknumber=1
twoplayermode=0
titletimer=timer()
rem Play-game loop
rem do
rem sync
rem loop
rem Do title screen
gosub _title_screen
maketrack=0
tracknumber=3
if maketrack=1
rem Waypoint structure
restore waypointdata
read wpmax
for w=1 to wpmax
read x,z
for car=1 to 4
wpx#(car,w)=x : wpz#(car,w)=z
next car
next w
rem Checkpoint structure
restore checkpointdata
read checkpointmax
for cp=1 to checkpointmax
read sx,sz
checkpointsx(cp)=sx
checkpointsz(cp)=sz
next cp
rem Segment Map structure
restore segmentmapdata
for sz=0 to 19
for sx=0 to 19
read st
segaddress=sx+((19-sz)*20)
segmap(segaddress)=st
next sx
next sz
rem Save track
dim data#(10)
data#(1)=wpmax
data#(2)=checkpointmax
save array "data\track"+str$(tracknumber)+".dat",data#(0)
save array "data\trackwx"+str$(tracknumber)+".dat",wpx#(0)
save array "data\trackwz"+str$(tracknumber)+".dat",wpz#(0)
save array "data\trackcx"+str$(tracknumber)+".dat",checkpointsx(0)
save array "data\trackcz"+str$(tracknumber)+".dat",checkpointsz(0)
save array "data\tracks"+str$(tracknumber)+".dat",segmap(0)
undim data#(0)
else
rem Load track
dim data#(10)
load array "data\track"+str$(tracknumber)+".dat",data#(0)
load array "data\trackwx"+str$(tracknumber)+".dat",wpx#(0)
load array "data\trackwz"+str$(tracknumber)+".dat",wpz#(0)
load array "data\trackcx"+str$(tracknumber)+".dat",checkpointsx(0)
load array "data\trackcz"+str$(tracknumber)+".dat",checkpointsz(0)
load array "data\tracks"+str$(tracknumber)+".dat",segmap(0)
checkpointmax=data#(2)
wpmax=data#(1)
undim data#(0)
endif
rem Segment map zones creation
mapobjid=1000
for sz=0 to 19
for sx=0 to 19
segaddress=sx+(sz*20)
segmenttype=segmap(segaddress)
if segmenttype>0
if segmenttype>=1 and segmenttype<=16
load object "track\track"+right$(str$(100+segmenttype),2)+".x",mapobjid
endif
if segmenttype=22 then load object "track\tree01.x",mapobjid
if segmenttype=23 then load object "track\tree02.x",mapobjid
if segmenttype=24 then load object "track\gstand01.x",mapobjid
if segmenttype=25 then load object "track\gstand02.x",mapobjid
if segmenttype=26 then load object "track\build01.x",mapobjid
if segmenttype=27 then load object "track\build02.x",mapobjid
if segmenttype=28 then load object "track\hay01.x",mapobjid
position object mapobjid,(sx*1000)+500,0,(sz*1000)+500
if segmenttype=22 or segmenttype=23
scale object mapobjid,200,100,200
yrotate object mapobjid,rnd(359)
endif
inc mapobjid
if segzones(segmenttype,0)>0
for zi=1 to segzones(segmenttype,0)
zone=segzones(segmenttype,zi)
x1=mapzonex(zone,1)+(sx*1000)
z1=mapzonez(zone,1)+(sz*1000)
x2=mapzonex(zone,2)+(sx*1000)
z2=mapzonez(zone,2)+(sz*1000)
next zi
endif
endif
next sx
next sz
rem Setup cars for new game
for car=1 to 4
if car=1
x#(car)=(checkpointsx(1)*1000)-800
z#(car)=(checkpointsz(1)*1000)+650
endif
if car=2
x#(car)=(checkpointsx(1)*1000)-850
z#(car)=(checkpointsz(1)*1000)+365
wpi(car)=1
endif
if car=3
x#(car)=(checkpointsx(1)*1000)-500
z#(car)=(checkpointsz(1)*1000)+650
wpi(car)=1
endif
if car=4
x#(car)=(checkpointsx(1)*1000)-550
z#(car)=(checkpointsz(1)*1000)+365
wpi(car)=1
endif
a#(car)=90
y#(car)=0
position object car,x#(car),y#(car),z#(car)
yrotate object car,a#(car)
speed#(car)=0
ix#(car)=0
iz#(car)=0
tilt#(car)=0
onbridge(car)=0
freezepenalty(car)=0
nextcheckpoint(car)=2
currentlap(car)=1
currentime(car)=timer()
fuel#(car)=100.0
damage#(car)=0
loop sound (car*10)+0
play sound (car*10)+3 : set sound speed (car*10)+3,15000
next car
rem Hide panel 2
if twoplayermode=0
for decal=11 to 22
hide object decal+(1*20)
next decal
else
for decal=11 to 22
show object decal+(1*20)
next decal
endif
rem Setup new game
endgamecountdown=0
haveawinner=0
getready=4
getreadycount=0
rem Optional data
fueluse#=0.07/lapmax : if fueluse#>0.05 then fueluse#=0.05
for car=1 to 4
if difficulty=1 then dronespeed#(car)=2.0+(0.5)+(rnd(3)/10.0)
if difficulty=2 then dronespeed#(car)=2.0+(1.0)+(rnd(3)/10.0)
if difficulty=3 then dronespeed#(car)=2.0+(1.1)+(rnd(3)/10.0)
next car
rem In-game loop
`disable escapekey
do
rem CAR ENGINE
set cursor 0,0
for car=1 to 4
rem CAR CONTROLS AND MOVMENT
move=0
if getready<=1
if car=1
rem PLAYER ONE CONTROLS
if leftkey()=1 then a#(car)=wrapvalue(a#(car)-(2*speed#(car)))
if rightkey()=1 then a#(car)=wrapvalue(a#(car)+(2*speed#(car)))
if upkey()=1 then speed#(car)=speed#(car)+4.0 : move=1
if downkey()=1 then speed#(car)=speed#(car)-2.0 : move=1
else
if car=2 and twoplayermode=1
rem PLAYER TWO CONTROLS
if joystick left()=1 then a#(car)=wrapvalue(a#(car)-(2*speed#(car)))
if joystick right()=1 then a#(car)=wrapvalue(a#(car)+(2*speed#(car)))
if joystick up()=1 then speed#(car)=speed#(car)+3.0 : move=1
if joystick down()=1 then speed#(car)=speed#(car)-2.0 : move=1
else
rem A.I: WAYPOINT CONTROL
rem Head for waypoint
tdx#=wpx#(car,wpi(car))-x#(car)
tdz#=wpz#(car,wpi(car))-z#(car)
tdist#=sqrt(abs(tdx#*tdx#)+abs(tdz#*tdz#))
rem Next waypoint
if tdist#<250
wpi(car)=wpi(car)+1
if wpi(car)>wpmax then wpi(car)=1
endif
if tracknumber>=3 then agr#=15.0 else agr#=25.0
a#(car)=curveangle(wrapvalue(atanfull(tdx#,tdz#)),a#(car),agr#)
speed#(car)=speed#(car)+dronespeed#(car) : move=1
endif : endif
endif
rem Affect engine by fuel
if fuel#(car)<1.0 then speed#(car)=speed#(car)/2
rem Reduce engine speed
speed#(car)=speed#(car)/(2.0+(rnd(5)/10.0))
rem Engine and Gear sounds
if move=1
gear#(car)=gear#(car)+50
if gear#(car)>6000 and gearstep(car)<3 then gear#(car)=2000 : gearstep(car)=gearstep(car)+1
else
gear#(car)=gear#(car)-500
gearstep(car)=0
endif
if gear#(car)>10000 then gear#(car)=10000
if gear#(car)<0 then gear#(car)=0
set sound speed (car*10)+0,12000+(gearstep(car)*1000)+gear#(car)
tdist#=getdistance(x#(car),z#(car),x#(1),z#(1))
for snd=0 to 6
tv#=105-((20.0/5000.0)*tdist#)
tp#=(x#(car)-x#(1))*2.0
if tv#>100.0 then tv#=100.0
if tp#>10000.0 then tp#=10000.0
if tp#<-10000.0 then tp#=-10000.0
if snd=3 then set sound volume (car*10)+snd,95
if snd<>3 then set sound volume (car*10)+snd,tv#
if snd<>3 then set sound pan (car*10)+snd,tp#
next snd
rem Apply speed when move
if move=1 and freezepenalty(car)=0
ix#(car)=ix#(car)+newxvalue(0,a#(car),speed#(car))
iz#(car)=iz#(car)+newzvalue(0,a#(car),speed#(car))
endif
rem Reduce inertia of movement
ix#(car)=ix#(car)/1.1 : iz#(car)=iz#(car)/1.1
rem Apply inertia to position of car
x#(car)=x#(car)+ix#(car) : z#(car)=z#(car)+iz#(car)
rem Place car
position object car,x#(car),y#(car),z#(car)
set object rotation zyx car
xrotate object car,tilt#(car)
yrotate object car,a#(car)
rem CHECK CAR-vs-MAP COLLISION
rem Check whether car on bridge
sx=x#(car)/1000
sz=z#(car)/1000
segaddress=sx+(sz*20)
segtype=segmap(segaddress)
ttx#=x#(car)-(sx*1000)
ttz#=z#(car)-(sz*1000)
if onbridge(car)=0
if segtype=7
if ttz#>200 and ttz#<800
if ttx#<200 or ttx#>800
rem on bridge
onbridge(car)=1
bridgezones(car,0)=2
bridgezones(car,1)=6
bridgezones(car,2)=7
endif
endif
endif
rem Normal tilt
tilt#(car)=0
else
rem Control ascent over bridge
if ttx#<200
y#(car)=25+(ttx#/2.0)
tilt#(car)=360-25
else
if ttx#>800
y#(car)=(1000-ttx#)/2.0
tilt#(car)=25
else
y#(car)=125
tilt#(car)=0
endif
endif
if segtype<>7
rem off bridge
onbridge(car)=0
bridgezones(car,0)=6
bridgezones(car,1)=8
bridgezones(car,2)=9
y#(car)=0
endif
endif
rem Check corners with map collision zones
for t=1 to 5
rem Get corner points of car
tx#(1)=newxvalue(x#(car),wrapvalue(a#(car)+25),95)
tz#(1)=newzvalue(z#(car),wrapvalue(a#(car)+25),95) : rem collision for ogjects
tx#(2)=newxvalue(x#(car),wrapvalue(a#(car)+155),95)
tz#(2)=newzvalue(z#(car),wrapvalue(a#(car)+155),95)
tx#(3)=newxvalue(x#(car),wrapvalue(a#(car)+205),95)
tz#(3)=newzvalue(z#(car),wrapvalue(a#(car)+205),95)
tx#(4)=newxvalue(x#(car),wrapvalue(a#(car)-25),95)
tz#(4)=newzvalue(z#(car),wrapvalue(a#(car)-25),95)
tx#(5)=newxvalue(x#(car),wrapvalue(a#(car)),95)
tz#(5)=newzvalue(z#(car),wrapvalue(a#(car)),95)
if tx#(1)=5 and (x#car)=5 then play sound 131
if tz#(1)=5 and (z#car)=5 then play sound 131
rem Get zone list from segment
sx=tx#(t)/1000
sz=tz#(t)/1000
segaddress=sx+(sz*20)
segtype=segmap(segaddress)
if segtype>0
rem If segment has map zones
if segtype=7
segzonesmax=bridgezones(car,0)
else
segzonesmax=segzones(segtype,0)
endif
if segzonesmax>0
for zi=1 to segzonesmax
if segtype=7
zone=bridgezones(car,zi)
else
zone=segzones(segtype,zi)
endif
x1=mapzonex(zone,1)+(sx*1000)
z1=mapzonez(zone,1)+(sz*1000)
x2=mapzonex(zone,2)+(sx*1000)
z2=mapzonez(zone,2)+(sz*1000)
if tx#(t)>x1 and tx#(t)<x2
if tz#(t)>z1 and tz#(t)<z2
rem Align car to edge of map zone
txadjust=0 : tzadjust=0
if tx#(t)>x1 and x#(car)<x1 then txadjust=1
if tx#(t)<x2 and x#(car)>x2 then txadjust=2
if tz#(t)>z1 and z#(car)<z1 then tzadjust=3
if tz#(t)<z2 and z#(car)>z2 then tzadjust=4
rem Choose smallest adjustment (smoother)
xa#=abs(tx#(t)-x#(car))
za#=abs(tz#(t)-z#(car))
if txadjust>0 and tzadjust>0
if xa#>za# then txadjust=0 else tzadjust=0
endif
rem Make the adjustment
if txadjust=1 then x#(car)=x1-(tx#(t)-x#(car)) : ix#(car)=ix#(car)*-1
if txadjust=2 then x#(car)=x2-(tx#(t)-x#(car)) : ix#(car)=ix#(car)*-1
if tzadjust=3 then z#(car)=z1-(tz#(t)-z#(car)) : iz#(car)=iz#(car)*-1
if tzadjust=4 then z#(car)=z2-(tz#(t)-z#(car)) : iz#(car)=iz#(car)*-1
rem Assign damage
damage#(car)=damage#(car)+(speed#(car)/10.0)
if damage#(car)>100 then damage#(car)=100
if sound playing((car*10)+1)=0 then play sound (car*10)+1
if gearstep(car)>1 then gearstep(car)=gearstep(car)-1
endif
endif
next zi
endif
endif
next t
rem CHECK CAR-vs-CAR COLLISION
rem Check against all other cars
for othercar=1 to 4
rem Determine height collision first
heightmatch=0
if y#(car)=0 and y#(othercar)=0 then heightmatch=1
if y#(car)<>0 and y#(othercar)<>0 then heightmatch=1
rem Only check against higher numbered cars
if car<>othercar and heightmatch=1
rem Get temporary coords of the other car
tx#=x#(othercar)
tz#=z#(othercar)
ta#=a#(othercar)
rem Find centers of car collision spheres
for t=-50 to 50 step 33
rem Find car A collision centers
cxA#=newxvalue(x#(car),a#(car),t) : czA#=newzvalue(z#(car),a#(car),t)
rem Check against cars Bs collision centers
for tt=-50 to 50 step 33
rem Check for collision between car A and B
cxB#=newxvalue(tx#,ta#,tt) : czB#=newzvalue(tz#,ta#,tt)
cdist#=getdistance(cxA#,czA#,cxB#,czB#)
if cdist#<100
rem Transfer inertias over
tixA#=ix#(car)
tizA#=iz#(car)
tixB#=ix#(othercar)
tizB#=iz#(othercar)
ix#(othercar)=(ix#(othercar)+(tixA#/8))-(tixB#/8)
iz#(othercar)=(iz#(othercar)+(tizA#/8))-(tizB#/8)
ix#(car)=0:rem ix#(car)-(tixA#/8)--------------gheck**************
iz#(car)=0:rem iz#(car)-(tizA#/8------------------check****************
rem Update car positions
x#(car)=x#(car)+ix#(car) : z#(car)=z#(car)+iz#(car)
x#(othercar)=x#(othercar)+ix#(othercar)
z#(othercar)=z#(othercar)+iz#(othercar)
rem Ensure cars are NOT overlapping EVER
tries=0
repeat
rem Move them away from each other
tdx#=x#(car)-x#(othercar)
tdz#=z#(car)-z#(othercar)
ta#=wrapvalue(atanfull(tdx#,tdz#))
x#(car)=newxvalue(x#(car),ta#,10)
z#(car)=newzvalue(z#(car),ta#,10)
tdist#=getdistance(x#(car),z#(car),x#(othercar),z#(othercar))
inc tries
until tdist#>100 or tries>5
rem Assign damage
if sound playing((car*10)+2)=0
damage#(car)=damage#(car)+1
if damage#(car)>100 then damage#(car)=100
play sound (car*10)+2
endif
if gearstep(car)>1 then gearstep(car)=gearstep(car)-1
endif
next tt
next t
endif
next othercar
rem CHECK FOR CHECKPOINT CLEARANCE
if haveawinner=0
if move=1
fuel#(car)=fuel#(car)-fueluse#
if fuel#(car)<0.0 then fuel#(car)=0.0
endif
sx=x#(car)/1000
sz=z#(car)/1000
cp=nextcheckpoint(car)
if checkpointsx(cp)=sx and checkpointsz(cp)=sz
nextcheckpoint(car)=cp+1
if nextcheckpoint(car)=checkpointmax+1
nextcheckpoint(car)=2
currentlap(car)=currentlap(car)+1
if sound playing((car*10)+4)=0 then play sound (car*10)+4
if currentlap(car)=lapmax+1
rem This car wins
if sound playing((car*10)+2)=0 then play sound (car*10)+2
if sound playing((car*10)+6)=0 then play sound (car*10)+6
haveawinner=car
endgamecountdown=100
currentlap(car)=lapmax
time=(timer()-currentime(car))/100
timemu(car)=time/600 : time=time-(timemu(car)*600)
timest(car)=time/100 : time=time-(timest(car)*100)
timesu(car)=time/10 : time=time-(timesu(car)*10)
timese(car)=time
endif
endif
endif
endif
rem DAMAGE RESTART AT CHECKPOINT PENALTY
if damage#(car)=100
if sound playing((car*10)+5)=0 then play sound (car*10)+5
freezepenalty(car)=1
cp=nextcheckpoint(car)
x#(car)=(checkpointsx(cp)*1000)+500
z#(car)=(checkpointsz(cp)*1000)+500
endif
if freezepenalty(car)=1
damage#(car)=damage#(car)-2
if damage#(car)<=0 then damage#(car)=0 : freezepenalty(car)=0
endif
rem TOO FAR CHECK (2 player mode only)
if haveawinner=0 and twoplayermode=1
tx#=abs(x#(2)-x#(1))
tz#=abs(z#(2)-z#(1))
tdist#=sqrt((tx#*tx#)+(tz#*tz#))
if tdist#>2500
if car=1 then tcar=2 else tcar=1
tbehind=0
if currentlap(car)<currentlap(tcar) then tbehind=1
if currentlap(car)=currentlap(tcar) and nextcheckpoint(car)<nextcheckpoint(tcar) then tbehind=1
if currentlap(car)=currentlap(tcar) and nextcheckpoint(car)=nextcheckpoint(tcar)
cp=nextcheckpoint(car)
tsx#=(checkpointsx(cp)*1000)+500
tsz#=(checkpointsz(cp)*1000)+500
tx#=abs(x#(car)-tsx#)
tz#=abs(z#(car)-tsz#)
tdist1#=sqrt((tx#*tx#)+(tz#*tz#))
tx#=abs(x#(tcar)-tsx#)
tz#=abs(z#(tcar)-tsz#)
tdist2#=sqrt((tx#*tx#)+(tz#*tz#))
if tdist1#>tdist2# then tbehind=1
endif
if tbehind=1
toofarcount(car)=toofarcount(car)+1
if toofarcount(car)>50
nextcheckpoint(car)=nextcheckpoint(tcar)
a#(car)=a#(tcar)
x#(car)=newxvalue(x#(tcar),wrapvalue(a#(car)+90),125)
y#(car)=y#(tcar)
z#(car)=newzvalue(z#(tcar),wrapvalue(a#(car)+90),125)
endif
endif
else
toofarcount(car)=0
endif
endif
next car
rem CAMERA CONTROL
if twoplayermode=0
cx#=x#(1)
cy#=1500
cz#=z#(1)
else
cdx#=abs(x#(2)-x#(1))*4
cdz#=abs(z#(2)-z#(1))*4
cy#=curvevalue(sqrt((cdx#*cdx#)+(cdz#*cdz#))/3.5,cy#,25)
if cy#<1500 then cy#=1500
cx#=curvevalue(x#(1)+((x#(2)-x#(1))/2),cx#,10)
cz#=curvevalue(z#(1)+((z#(2)-z#(1))/2),cz#,10)
endif
rem Secret camera view
if inkey$()="C" and camview=0
camview=1
set camera range 5,10000
draw to back
endif
if camview=0
position camera cx#,cy#,cz#
point camera cx#,0,cz#
else
position camera x#(1),50+y+(1),z#(1)
rotate camera 0,a#(1),0
endif
rem STATS CONTROL
gosub _control_decals
rem GET-READY CONTROL
if getready>0
show object 51
texture object 51,128+(4-getready)
inc getreadycount
if getreadycount>20
getreadycount=0
dec getready
if getready=0
hide object 51
endif
endif
endif
rem GAME-END CONTROL
if endgamecountdown>0
for decal=50 to 51 : show object decal : next decal
texture object 51,122+haveawinner
dec endgamecountdown
if endgamecountdown=0
exit
endif
play sound 131
endif
rem Update screen
if inkey$()="f"
ffs=ffs+1 : if ffs>5 : ffs=0 : sync : endif
else
sync
endif
if object collision 1,5=1 then play sound 131
loop
rem Escape handling
while escapekey()=1 : endwhile
enable escapekey
draw to front
rem Hide prompt
for decal=50 to 51
hide object decal
next decal
for car=1 to 4
for t=0 to 6
stop sound (car*10)+t
next r
next car
rem Not terminated or escaped
if haveawinner<>-1
rem Hiscore System
if haveawinner=1 or (haveawinner=2 and twoplayermode=1)
rem Enter human player name
gosub _enter_hiscore
gosub _show_hiscore :rem check***********************************************88iougy
endif
endif
rem Delete map bits
for m=1000 to mapobjid-1
if object exist(m)=1 then delete object m
next m
rem End play-game loop
`loop
rem SUBROUTINES
_control_decals:
rem For both players
for plr=0 to 1
rem Decals for lap count
texture object 11+(plr*20),100+currentlap(1+plr)
texture object 12+(plr*20),100+lapmax
rem Decals for time count
if haveawinner=1+plr
timemu=timemu(haveawinner)
timest=timest(haveawinner)
timesu=timesu(haveawinner)
timese=timese(haveawinner)
else
time=(timer()-currentime(1+plr))/100
timemu=time/600 : time=time-(timemu*600)
timest=time/100 : time=time-(timest*100)
timesu=time/10 : time=time-(timesu*10)
timese=time
endif
texture object 13+(plr*20),100+timemu
texture object 14+(plr*20),100+timest
texture object 15+(plr*20),100+timesu
texture object 16+(plr*20),100+timese
rem Decals for fuel and damage
scale object 17+(plr*20),1+(fuel#(1+plr)),100,1000
scale object 18+(plr*20),1+(100-damage#(1+plr)),100,1000
next plr
return
_enter_hiscore:
rem Load music loop
if sound exist(99)=0
load sound "sounds\musichs.wav",99
endif
loop sound 99
rem Create hiscore if none exist
delete file "hiscore.dtn"
if file exist("hiscore.dtn")=0
for track=1 to 4
for item=1 to 10
hiname$(track,item)="---"
hitime(track,item)=18888
next item
next track
save array "hiscore.dtn",hiname$(0)
save array "hiscore.dtt",hitime(0)
endif
rem Load hiscore table
load array "hiscore.dtn",hiname$(0)
load array "hiscore.dtt",hitime(0)
rem Enter name in hiscore table
car=haveawinner
time=(timemu(car)*1000)
inc time,(timest(car)*100)
inc time,(timesu(car)*10)
inc time,(timese(car))
time=(time/lapmax*1.0)
inc time,10000
rem Is within table?
tinsert=0
for ti=1 to 10
if time<hitime(tracknumber,ti)
tinsert=ti : ti=11
endif
next ti
if tinsert>0
rem Shuffle lesser scores
for ti=0 to (9-tinsert)-1
tti=9-ti
hiname$(tracknumber,tti)=hiname$(tracknumber,tti-1)
hitime(tracknumber,tti)=hitime(tracknumber,tti-1)
next ti
rem Set text
set text font "Arial"
set text size 64
ink rgb(255,255,255),0
rem Accept name
sync rate 0
dim entry$(2)
entry$(1)=""
entry$(2)=""
do
i$=upper$(inkey$())
if i$<>""
` if keydown=0 or i$<>entry$(2)
sc=scancode()
if sc=14 or sc=28
` if sc=14 then entry$(1)=left$(entry$(1),len(entry$(1))-1)
if sc=28 then exit
else
` if len(entry$(1))<3
` entry$(1)=entry$(1)+i$
endif
endif
entry$(2)=i$
keydown=1
if secondstrikes=0
keyspeed=30
secondstrikes=1
else
keyspeed=10
endif
else
dec keyspeed
if keyspeed=0 then keydown=0
` endif
` else
keydown=0
secondstrikes=0
` endif
copy bitmap 2,0
center text 320,150,"ENTER YOUR NAME"
` center text 320,220,entry$(1)
sync
loop
` hiname$(tracknumber,tinsert)=entry$(1)
hitime(tracknumber,tinsert)=time
save array "hiscore.dtn",hiname$(0)
save array "hiscore.dtt",hitime(0)
` draw to back
sync rate 40
undim entry$(0)
`endif
return
_show_hiscore:
rem Load music loop
if sound exist(99)=0
load sound "sounds\musichs.wav",99
endif
loop sound 99
rem Set text
set text font "Arial"
ink rgb(255,255,255),0
rem Show hiscore
sync rate 0
`draw to front
showtime=timer()
do
copy bitmap 2,0
set text size 56
center text 320,20,"HISCORE FOR TRACK "+str$(tracknumber)
set text size 48
for item=1 to 10
if tinsert=item then ink rgb(255,255,rnd(255)),0 else ink rgb(255,255,255),0
text 120,48+(item*36),str$(item)+". "+hiname$(tracknumber,item)
s$=str$(hitime(tracknumber,item))
a$=mid$(s$,2) : b$=mid$(s$,3)
c$=mid$(s$,4) : d$=mid$(s$,5)
text 400,48+(item*36),a$+":"+b$+c$+":"+d$
next item
sync
if timer()-showtime>5000 then exit
loop
`draw to back
sync rate 40
rem Delete music loop
delete sound 99
return
_title_screen:
rem Load music loop
load sound "sounds\musictit.wav",99 : loop sound 99
rem Set text
set text font "Arial"
ink rgb(255,255,255),0
rem Intro pause
backpic=1
current=1
rem Show title
sync rate 0
`draw to front
showtime=timer()
do
if timer()-titletimer>2000 then backpic=2
copy bitmap backpic,0
if backpic=2
set text size 48
ink rgb(255,255,255),0
center text 320,50,"OPTIONS"
set text size 32
for t=1 to 6
if current=t then ink rgb(255,255,255),0 else ink rgb(155,155,155),0
if t=1 then t$="TRACK "+str$(tracknumber)
if t=2 then t$=str$(1+twoplayermode)+" HUMAN PLAYER(S)"
if t=3
t$="DIFFICULTY OF "
if difficulty=1 then t$=y$+"EASY"
if difficulty=2 then t$=y$+"MEDIUM"
if difficulty=3 then t$=y$+"HARD"
endif
if t=4 then t$=str$(lapmax)+" LAPS PER RACE"
if t=5 then t$="PLAY GAME"
if t=6 then t$="EXIT"
center text 320,100+(t*30),t$
next t
set text size 24
ink rgb(255,255,255),0
center text 320,350,"Player 1 = Cursor Keys Player 2 = Joystick"
endif
if keypress=0
if upkey()=1 and current>1 then dec current : keypress=5
if downkey()=1 and current<6 then inc current : keypress=5
if current=1
if leftkey()=1 and tracknumber>1 then dec tracknumber : keypress=5
if rightkey()=1 and tracknumber<4 then inc tracknumber : keypress=5
endif
if current=2
if leftkey()=1 and twoplayermode>0 then dec twoplayermode : keypress=5
if rightkey()=1 and twoplayermode<1 then inc twoplayermode : keypress=5
endif
if current=3
if leftkey()=1 and difficulty>1 then dec difficulty : keypress=5
if rightkey()=1 and difficulty<3 then inc difficulty : keypress=5
endif
if current=4
if leftkey()=1 and lapmax>3 then dec lapmax,2 : keypress=5
if rightkey()=1 and lapmax<7 then inc lapmax,2 : keypress=5
endif
if current=5
if returnkey()=1 then exit
endif
if current=6
if returnkey()=1 then end
endif
else
dec keypress
if upkey()=0 and downkey()=0 and leftkey()=0 and rightkey()=0
keypress=0
endif
endif
sync
loop
`draw to back
sync rate 40
rem Delete music
delete sound 99
return
endif
rem FUNCTIONS
function getdistance(x1#,z1#,x2#,z2#)
rem Using hypo calc for distance
dx#=abs(x2#-x1#)
dz#=abs(z2#-z1#)
dist#=sqrt((dx#*dx#)+(dz#*dz#))
endfunction dist#
rem DATA
rem Track One
`waypointdata:
data 6
data 12000,9700
data 12500,12000
data 10000,12250
data 9500,7100
data 7000,6500
data 6750,8950
`
`segmentmapdata:
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,23,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,03,01,01,04,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,28,02,14,13,02,12,00,00,00,00,00,00
data 00,00,00,00,00,00,28,27,22,02,11,14,02,00,00,00,00,00,00,00
data 00,00,00,00,00,00,03,09,01,07,01,01,05,00,00,00,00,00,00,00
data 00,00,00,00,00,00,02,24,24,02,22,23,26,00,00,00,00,00,00,00
data 00,00,00,00,00,11,02,00,23,02,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,22,06,01,01,05,23,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,23,00,22,11,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
`checkpointdata:
data 8
data 8,9
data 12,9
data 12,12
data 9,12
data 9,6
data 6,6
data 6,9
data 8,9
rem Track Two
`waypointdata:
data 4
data 12000,9500
data 12500,12000
data 7000,12500
data 6500,10000
`
`segmentmapdata:
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,11,00,22,23,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,03,01,01,15,01,15,04,00,00,00,00,00,00,00
data 00,00,00,00,00,00,16,00,28,22,23,00,02,12,00,00,00,00,00,00
data 00,00,00,00,00,00,02,27,22,00,00,22,16,00,00,00,00,00,00,00
data 00,00,00,00,00,00,06,09,01,01,01,01,05,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,24,24,00,22,23,26,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
`checkpointdata:
data 6
data 8,9
data 12,9
data 12,12
data 6,12
data 6,9
data 8,9
rem Track Three
`waypointdata:
data 13
data 9250,9500
data 9500,8000
data 6000,7500
data 5400,11000
data 4350,11750
data 5000,12500
data 6750,12500
data 7500,13450
data 8400,13000
data 9000,12500
data 9500,12000
data 6700,11250
data 6600,9900
`
`segmentmapdata:
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,22,23,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,23,00,11,03,04,22,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,03,15,01,05,06,04,00,00,00,00,00,00,00,00,00,00
data 00,00,00,22,06,04,03,01,15,05,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,16,02,27,22,23,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,12,02,06,09,01,04,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,16,23,24,26,16,12,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,06,01,01,15,05,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,23,11,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
`checkpointdata:
data 15
data 8,9
data 9,9
data 9,7
data 5,7
data 5,11
data 4,11
data 4,12
data 7,12
data 7,13
data 8,13
data 8,12
data 9,12
data 9,11
data 6,11
data 6,9
rem Track Four
`waypointdata:
data 12
data 9000,9500
data 9750,10250
data 11150,10250
data 11650,9600
data 12250,9500
data 12750,10250
data 15600,10500
data 15350,9300
data 14600,9500
data 14550,11200
data 6750,11300
data 6750,9750
`
`segmentmapdata:
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,11,22,23,00,22,00,22,00,00,00,00,00,00
data 00,00,00,00,00,22,03,15,01,15,01,15,01,15,04,27,00,00,00,00
data 00,00,00,00,00,26,02,27,00,03,01,04,03,01,07,04,00,00,00,00
data 00,00,00,00,00,23,06,09,01,05,23,06,05,11,06,05,23,00,00,00
data 00,00,00,00,00,00,00,24,00,26,00,00,00,00,00,22,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
`checkpointdata:
data 14
data 8,9
data 9,9
data 9,10
data 11,10
data 11,9
data 12,9
data 12,10
data 15,10
data 15,9
data 14,9
data 14,11
data 6,11
data 6,9
data 8,9
rem Track Three
waypointdata:
data 13
data 9250,9500
data 9500,8000
data 6000,7500
data 5400,11000
data 4350,11750
data 5000,12500
data 6750,12500
data 7500,13750
data 8400,13250
data 8900,12700
data 9400,12100
data 6700,11350
data 6600,9900
`
segmentmapdata:
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,22,23,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,23,00,11,03,04,22,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,03,15,01,05,06,04,00,00,00,00,00,00,00,00,00,00
data 00,00,00,22,06,04,03,01,15,05,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,16,02,27,22,23,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,12,02,06,09,01,04,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,16,23,24,26,16,12,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,06,01,01,15,05,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,23,11,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
data 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
checkpointdata:
data 16
data 8,9
data 9,9
data 9,7
data 5,7
data 5,11
data 4,11
data 4,12
data 7,12
data 7,13
data 8,13
data 8,12
data 9,12
data 9,11
data 6,11
data 6,9
data 8,9
segmenttypedata:
data 28
data 0
data 0
data 0
data 0
data 0
data 0
data 6,8,9,10,11,12,13
data 0
data 0
data 0
data 0
data 0
data 0
data 1,3
data 2,14,15
data 2,16,17
data 0
data 0
data 0
data 0
data 0
data 1,2
data 1,2
data 1,1
data 1,1
data 1,4
data 1,5
data 0
mapzonedata:
data 17
data 1,0,240,1000,740
data 2,450,450,550,550
data 3,100,100,900,900
data 4,300,400,700,600
data 5,400,400,600,600
data 6,0,0,1000,200
data 7,0,800,1000,1000
data 8,150,0,250,1000
data 9,750,0,850,1000
data 10,0,0,150,200
data 11,850,0,1000,200
data 12,0,800,150,1000
data 13,850,800,1000,1000
data 14,0,150,1000,250
data 15,0,750,1000,850
data 16,150,0,250,1000
data 17,750,0,850,1000
</code>
Mike