639 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			639 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
 | 
						|
{-----------------------------------------------------------------------+
 | 
						|
|                                                                       |
 | 
						|
|       Racer game                                                      |
 | 
						|
|                                                                       |
 | 
						|
+-----------------------------------------------------------------------}
 | 
						|
 | 
						|
gcl0x
 | 
						|
 | 
						|
{
 | 
						|
Ideas for after ROMv1:
 | 
						|
XXX Less drift or lower max speed
 | 
						|
XXX Make time red in last 30 seconds
 | 
						|
XXX Readability of GET READY and GAME OVER messages
 | 
						|
XXX Obstacles? Other cars / bicycles?
 | 
						|
XXX Freeze time display for the first 2 seconds after completing a lap
 | 
						|
XXX Increase minimum speed when completing a lap
 | 
						|
XXX Car crash sequence when hitting curb? Easy to make it scatter...
 | 
						|
XXX Add breaking sound
 | 
						|
XXX Add tire screech sound
 | 
						|
XXX Move car forward when going faster
 | 
						|
XXX Finish line?
 | 
						|
XXX Background music score?
 | 
						|
XXX Crash sound effect?
 | 
						|
XXX Sprite acceleration?
 | 
						|
XXX Image compression?
 | 
						|
 | 
						|
 Many ideas here come from Lou's Pseudo 3d page at
 | 
						|
 http://www.extentofthejam.com/pseudo/
 | 
						|
}
 | 
						|
 | 
						|
[def {QPrintChar -- Pos Color Char
 | 
						|
 | 
						|
  Draw a 5x8 character on screen with the built-in font.
 | 
						|
  `Char' must be in the 32-127 range (this is not checked)
 | 
						|
}
 | 
						|
  {Map ASCII code to offset in font table}
 | 
						|
  82- [if<0 50+ i= \font32up
 | 
						|
       else     i= \font82up] fontData= {Select low or high page}
 | 
						|
  i 2<< i+             {Multiply by 5}
 | 
						|
  fontData+ fontData=  {Add to page address to reach bitmap data for Char}
 | 
						|
 | 
						|
  {Draw 6 vertical slices: 5 using font data, the last with all-zeros}
 | 
						|
  BgColor \sysArgs0.
 | 
						|
  Color   \sysArgs1.
 | 
						|
  Pos     \sysArgs4:
 | 
						|
  \SYS_VDrawBits_134 \sysFn:
 | 
						|
  $fb i= [do
 | 
						|
    fontData 0? fontData<++ \sysArgs2. 134!!
 | 
						|
    \sysArgs4<++
 | 
						|
    i<++ i if<>0loop]
 | 
						|
  Pos ret
 | 
						|
] QPrintChar=
 | 
						|
 | 
						|
[def {ControlRaceCar}
 | 
						|
  {Update time with actual elapsed frames}
 | 
						|
  \frameCount, LastFrame- 255& \sysArgs7. Time+ [if<0 $7fff] Time=
 | 
						|
  \frameCount, LastFrame=
 | 
						|
 | 
						|
  {Car drift and horizon shift are proportional to speed}
 | 
						|
  Speed>, [do if>0 i=
 | 
						|
    CarX DriftX- CarX=
 | 
						|
    HorizonX HorizonDX+ HorizonX=
 | 
						|
    i 1- loop]
 | 
						|
 | 
						|
  {Steering}
 | 
						|
  0 Steer=
 | 
						|
  \serialRaw, $01& {buttonRight} [if=0  $200 CarX+ CarX= +1 Steer=]
 | 
						|
  \serialRaw, $02& {buttonLeft}  [if=0 -$200 CarX+ CarX= -1 Steer=]
 | 
						|
 | 
						|
  {Speed control}
 | 
						|
  \serialRaw, $80& {buttonA} [if=0 {Accelerating}
 | 
						|
    Speed $10+ Speed= {At 15 fps $10 means ~1s to reach the next speed level}
 | 
						|
    $5ff Speed- [if<0 $5ff Speed=]
 | 
						|
   else
 | 
						|
    -$108 Speed+ [if>=0 Speed 8- Speed=] {Slowly drop to very low speed}
 | 
						|
  ]
 | 
						|
  \serialRaw, $40& {buttonB} [if=0 Speed $40- [if<0 0] Speed=] {Braking}
 | 
						|
  ret
 | 
						|
] ControlRaceCar=
 | 
						|
 | 
						|
 | 
						|
{-----------------------------------------------------------------------+
 | 
						|
|}\vLR>++ ret{          RAM page 3                                      |
 | 
						|
+-----------------------------------------------------------------------}
 | 
						|
$0300:
 | 
						|
 | 
						|
[def $47# $69# $67# $61# $74# $72# $6f# $6e# 0# ] GigatronText=
 | 
						|
 | 
						|
[def { Wait -- Wait Delay number of frames (range 1..255) }
 | 
						|
  \frameCount, Delay+ 255& tmp=
 | 
						|
  [do \frameCount, tmp- if<>0loop]
 | 
						|
  ret
 | 
						|
] Wait=
 | 
						|
 | 
						|
[def {
 | 
						|
  DrawPixels -- Write a single line of pixels on two correspinding
 | 
						|
                road scanlines (light and dark). Remove previous
 | 
						|
                pixels, if any.
 | 
						|
                XXX This is probably better done as a SYS call
 | 
						|
}
 | 
						|
  {Setup page reference for write pointers}
 | 
						|
  Video, 254&  p>. 1| q>. Video<++
 | 
						|
 | 
						|
  {Find segment to clear from position p[0] to position q[0]}
 | 
						|
  0 p<. q<.
 | 
						|
  p, i= q, i- i=        {i = q[0] - p[0]}
 | 
						|
  p, p<. q<.            {p,q = p+p[0], q+p[0]}
 | 
						|
 | 
						|
  {Clear previous object}
 | 
						|
  {XXX Only clear pixels outside new area?}
 | 
						|
  [do
 | 
						|
    21 p. q.            {Clear pixel on both lines}
 | 
						|
    p<++ q<++
 | 
						|
    i 1- i=
 | 
						|
    if>0loop]
 | 
						|
 | 
						|
  {Set low bytes of p and q, to turn them into pixel write pointers}
 | 
						|
  Sprite s=             {Pixel read pointer}
 | 
						|
  0 p<.                 {First let p point to start of page}
 | 
						|
  Video, X+ X= s, X+    {First byte in pixel data is offset}
 | 
						|
  p.                    {Remember starting point}
 | 
						|
  p<. q<.               {Set low bytes}
 | 
						|
 | 
						|
  {Draw actual pixels}
 | 
						|
  s<++
 | 
						|
  [do
 | 
						|
     p, 21^ Collision+ Collision=
 | 
						|
     s,
 | 
						|
     p. p<++
 | 
						|
     q. q<++
 | 
						|
     s<++ s, if<>0loop]
 | 
						|
 | 
						|
  {Remember end point for later removal}
 | 
						|
  0 q<. p<, q.
 | 
						|
 | 
						|
  Video 3+ Video=
 | 
						|
  ret
 | 
						|
] DrawPixels=
 | 
						|
 | 
						|
[def {PlayEngineSound}
 | 
						|
 | 
						|
  {High key is Speed[7:14]}
 | 
						|
  $01fd {keyH} p= Speed Speed+ \vACH,
 | 
						|
  p. p>++ p. p>++ p. p>++ p. {Sound channel 1-4}
 | 
						|
 | 
						|
  {Low key is Speed[0:6]}
 | 
						|
  $01fc {keyL} p= Speed 127&
 | 
						|
  p. p>++ p. p>++ p. p>++ p. {Sound channel 1-4}
 | 
						|
 | 
						|
  10 \soundTimer. {Keep sound on a bit longer}
 | 
						|
 | 
						|
  ret
 | 
						|
] PlayEngineSound=
 | 
						|
 | 
						|
{-----------------------------------------------------------------------+
 | 
						|
|}\vLR>++ ret{          RAM page 4                                      |
 | 
						|
+-----------------------------------------------------------------------}
 | 
						|
$0400:
 | 
						|
 | 
						|
[def
 | 
						|
  push
 | 
						|
  $2080 Pos=
 | 
						|
 | 
						|
  0 Width= {(Half) road width}
 | 
						|
  [do
 | 
						|
    Width 1+ Width=
 | 
						|
 | 
						|
    {Even lines are dark}
 | 
						|
    63 {White}        CurbColor=
 | 
						|
    12 {Bright Green} GrassColor=
 | 
						|
    SetupSegment!
 | 
						|
    Pos>++
 | 
						|
 | 
						|
    {Odd lines are bright}
 | 
						|
    3 {Bright Red}    CurbColor=
 | 
						|
    8 {Green}         GrassColor=
 | 
						|
    SetupSegment!
 | 
						|
    Pos>++
 | 
						|
 | 
						|
    Pos if>=0loop]
 | 
						|
 | 
						|
  {Setup undo infomation for last lines (for car sprite)}
 | 
						|
  $7400 [do \POKE# \vAC# \vAC>++ if>0loop]
 | 
						|
 | 
						|
  pop ret
 | 
						|
] SetupRoad=
 | 
						|
 | 
						|
[def
 | 
						|
  {Draw road segment}
 | 
						|
  Pos p=
 | 
						|
  Width [do tmp=
 | 
						|
    21 p. p<++
 | 
						|
    tmp 1- if>0loop]
 | 
						|
 | 
						|
  {Draw curb}
 | 
						|
  p q=
 | 
						|
  Width [do 8- [if>0 tmp=
 | 
						|
      q 1- q=
 | 
						|
      CurbColor q.
 | 
						|
      tmp loop]]
 | 
						|
 | 
						|
  {Draw grass}
 | 
						|
  [do
 | 
						|
    GrassColor p. p<++
 | 
						|
    p<, if<>0loop]
 | 
						|
 | 
						|
  {Draw mirror image}
 | 
						|
  [do
 | 
						|
    p 255^ peek p. p<++
 | 
						|
    p<, 128^ if<>0loop]
 | 
						|
 | 
						|
  ret
 | 
						|
] SetupSegment=
 | 
						|
 | 
						|
[def {
 | 
						|
  PrintTime -- Render elapsed time (in frams) as M:SS.s -- Value Radix
 | 
						|
              Skip unchanged digits
 | 
						|
}
 | 
						|
  push
 | 
						|
  {Note we have 3599 instead of 3600. Assuming a 6.25MHz clock, 200 cycles per
 | 
						|
   scanline and 521 scanlines per frame, the Gigatron runs at 59.98 frames per
 | 
						|
   second and that is ~3599 frames per minute. With this single correction the
 | 
						|
   overall timekeeping error is within the tolerances of the crystal itself.}
 | 
						|
  3599 Radix= ExtractDigit!
 | 
						|
       {\sysArgs7, $30+ Char= {Show frame speed for debugging}}
 | 
						|
       Prev3 Char^ [if<>0 Char Prev3= QPrintChar! else Pos] 12+ Pos=
 | 
						|
   600 Radix= ExtractDigit!
 | 
						|
       Prev2 Char^ [if<>0 Char Prev2= QPrintChar! else Pos]  6+ Pos=
 | 
						|
    60 Radix= ExtractDigit!
 | 
						|
       Prev1 Char^ [if<>0 Char Prev1= QPrintChar! else Pos] 12+ Pos=
 | 
						|
     6 Radix= ExtractDigit! QPrintChar!
 | 
						|
  pop ret
 | 
						|
] PrintTime=
 | 
						|
 | 
						|
{-----------------------------------------------------------------------+
 | 
						|
|}\vLR>++ ret{          RAM page 5                                      |
 | 
						|
+-----------------------------------------------------------------------}
 | 
						|
$0500:
 | 
						|
 | 
						|
[def {ExtractDigit -- Value Radix}
 | 
						|
  $30 Char=
 | 
						|
  Value Radix- [if>=0
 | 
						|
    [do
 | 
						|
      Value=
 | 
						|
      Char<++
 | 
						|
      Radix-
 | 
						|
      if>=0loop]
 | 
						|
  ]
 | 
						|
  Char
 | 
						|
  ret
 | 
						|
] ExtractDigit=
 | 
						|
 | 
						|
[def {
 | 
						|
  PrintText(Text,Pos)
 | 
						|
 | 
						|
  Draw a zero-terminated text string to the screen.
 | 
						|
  There is no check for running off screen.
 | 
						|
}
 | 
						|
  push
 | 
						|
  Text=
 | 
						|
  [do
 | 
						|
    Text, Char= {Next character to be printed}
 | 
						|
    if<>0       {Zero termination}
 | 
						|
      Text<++   {Advance text pointer}
 | 
						|
      QPrintChar! 6+ Pos=
 | 
						|
      loop]
 | 
						|
  pop ret
 | 
						|
] PrintText=
 | 
						|
 | 
						|
[def {DrawRoad}
 | 
						|
  $74d0 p=                      {array[48], in display memory but out of view}
 | 
						|
  0 X=
 | 
						|
  DX0 DX=
 | 
						|
 | 
						|
  NextTurn Distance- tmp=
 | 
						|
  tmp+ tmp=
 | 
						|
  \invTable tmp+ 53? tmp=       {59 .. 11}
 | 
						|
 | 
						|
  {Debug marker}
 | 
						|
  {tmp+ 10+ z>. 192 z<. NextDDX z. z>++ z.}
 | 
						|
 | 
						|
  {Road curvature for bottom segment}
 | 
						|
  197 tmp+ i=                   {(byte)-47 .. (byte)-1}
 | 
						|
  [do
 | 
						|
    X>, p. p<++
 | 
						|
    DX DDX+ DX=
 | 
						|
    X+ X=
 | 
						|
    i<++ i if<>0loop]
 | 
						|
 | 
						|
  {Road curvature for top segment}
 | 
						|
  [do
 | 
						|
    X>, p. p<++
 | 
						|
    DX NextDDX+ DX=
 | 
						|
    X+ X=
 | 
						|
    p<, if<>0loop]
 | 
						|
 | 
						|
  {Update video table low bytes for road}
 | 
						|
 | 
						|
  {Prepare SYS call}
 | 
						|
  $01ed           \sysArgs0: {"p"}
 | 
						|
  $74d1           \sysArgs2: {"q"}
 | 
						|
 {$74d0} 1-  peek \sysArgs4: {"X"}
 | 
						|
 | 
						|
  HorizonX>, tmp=                    {Pivot 12px from bottom (front of car)}
 | 
						|
  $74d5 peek 48+ tmp- tmp=
 | 
						|
 | 
						|
  {Update DX0 based on overall curvature in bottom part of screen}
 | 
						|
  $74d4 peek DX0=
 | 
						|
  $74ec peek DX0- 255& 128^ 128- DX0=
 | 
						|
 | 
						|
  $0111 s=                           {Video table: start of sky}
 | 
						|
 | 
						|
  {Sync with video loop}
 | 
						|
  [do \videoY, 1& if=0loop]
 | 
						|
 | 
						|
  {Set top of horizon}
 | 
						|
  HorizonX>, s.
 | 
						|
 | 
						|
  {Copy to video table. This is most timing-critical for a smooth road update}
 | 
						|
  \SYS_RacerUpdateVideoX_40 \sysFn: 40!!
 | 
						|
  {This SYS call self-repeats for a total of 47 times and is equivalent to:
 | 
						|
    [do
 | 
						|
      q, X- p. p 4- p=
 | 
						|
      q, X= q<++
 | 
						|
      q<, if<>0loop]
 | 
						|
  }
 | 
						|
  \sysArgs0; s= {$0131 bottom of sky (horizon)}
 | 
						|
  \sysArgs4; X=
 | 
						|
 | 
						|
  {Set bottom of sky}
 | 
						|
  tmp X- s.
 | 
						|
 | 
						|
  ret
 | 
						|
] DrawRoad=
 | 
						|
 | 
						|
{-----------------------------------------------------------------------+
 | 
						|
|}\vLR>++ ret{          RAM page 6                                      |
 | 
						|
+-----------------------------------------------------------------------}
 | 
						|
$0600:
 | 
						|
 | 
						|
[def {Play a single game until the end }
 | 
						|
  push
 | 
						|
 | 
						|
  {Run game loop}
 | 
						|
  0 Collision=
 | 
						|
  Prev3= Prev2= Prev1=
 | 
						|
  [do
 | 
						|
    AdvanceCar!
 | 
						|
 | 
						|
    {See if we have reached the finish}
 | 
						|
    Distance
 | 
						|
    [if<0
 | 
						|
      Time BestTime- [if<0 Time BestTime=]
 | 
						|
 | 
						|
      15 {Yellow} PrintBestTime!
 | 
						|
 | 
						|
      {New lap}
 | 
						|
      0 Time= Random=
 | 
						|
      $7400 Distance= NextTurn=
 | 
						|
    ]
 | 
						|
 | 
						|
    {See if we have reached the next turn}
 | 
						|
    {Distance} NextTurn-
 | 
						|
    [if>0
 | 
						|
      Random NextTurn+ 109^ Random=     {Circuit formula}
 | 
						|
      31& 40+ NextTurn+ NextTurn=       {40..71 units until next turn}
 | 
						|
      Random>, 3& 1+ i= i+ i+ 1<< i=    {Bending magnitude 6,12,18,24}
 | 
						|
      NextDDX DDX=                      {Shift to next segment}
 | 
						|
     {DDX} [if<0  i+                    {Adjust bending of road}
 | 
						|
      else [if>0  i-
 | 
						|
      else {if=0} Random [if>=0 i else 0 i-]
 | 
						|
      ]]
 | 
						|
      NextDDX=
 | 
						|
    ]
 | 
						|
 | 
						|
    {Draw bending of the road}
 | 
						|
    DrawRoad!
 | 
						|
 | 
						|
    {Drift and horizon movement}
 | 
						|
    DDX 3<< HorizonDX= 1<< DriftX=
 | 
						|
 | 
						|
    {Car "physics" and driver input}
 | 
						|
    ControlRaceCar!
 | 
						|
 | 
						|
    {Update pitch of engine sound}
 | 
						|
    PlayEngineSound!
 | 
						|
 | 
						|
    {Draw race car}
 | 
						|
    DrawRaceCar!
 | 
						|
 | 
						|
    {Update the perspective illusion}
 | 
						|
    DrawGrass!
 | 
						|
 | 
						|
    {Force end of game after 5m00s}
 | 
						|
    -17995 Time+ [if>0 Collision=]
 | 
						|
 | 
						|
    {Draw current time}
 | 
						|
    Time Value= $801 Pos= 63 Color= PrintTime!
 | 
						|
 | 
						|
    Collision if=0loop]
 | 
						|
  pop ret
 | 
						|
] PlayGame=
 | 
						|
 | 
						|
{
 | 
						|
  Car sprite. Black is 0 but also the teminator, therfore use 64 for black.
 | 
						|
  XXX Reduce footprint by bringing all lines under one 'def'
 | 
						|
}
 | 
						|
[def 2#         64# 64# 64# 40# 60# 60# 40# 64# 64# 64#         0#] Car0=
 | 
						|
[def 3#             40# 20# 20# 63# 63# 20# 20# 40#             0#] Car1=
 | 
						|
[def 2#         40# 20# 20# 20# 40# 40# 20# 20# 20# 40#         0#] Car2=
 | 
						|
 | 
						|
{-----------------------------------------------------------------------+
 | 
						|
|}$08a0 \vLR: ret{      RAM page 8                                      |
 | 
						|
+-----------------------------------------------------------------------}
 | 
						|
$08a0:
 | 
						|
 | 
						|
[def 0# 64# 64# 64# 64# 40# 20# 20# 20# 20# 40# 64# 64# 64# 64# 0#] Car3=
 | 
						|
[def 0# 64# 64# 64# 64# 21# 21# 21# 21# 21# 21# 64# 64# 64# 64# 0#] Car4=
 | 
						|
 | 
						|
[def
 | 
						|
  {Update video table high bytes for road width and color scheme}
 | 
						|
  {We do this part last because any timing delays here don't really
 | 
						|
   cause visible problems.}
 | 
						|
 | 
						|
  {Original version}
 | 
						|
{
 | 
						|
  $0130 p=              {Video table top of road, at horizon}
 | 
						|
  $20 SegmentY=         {Start with smallest segment}
 | 
						|
  \invTable q=
 | 
						|
  [do
 | 
						|
    q 21?               {Y to Z depth mapping for perspective. The offset
 | 
						|
                         of 21 reduces aliasing effects near the horizon.}
 | 
						|
    Distance+ 4&        {Vertical scrolling Distance}
 | 
						|
    [if<>0 1] tmp=
 | 
						|
    SegmentY 254& tmp+ p.
 | 
						|
    p<++ p<++
 | 
						|
    SegmentY<++
 | 
						|
    q<++
 | 
						|
    p<, 240^ if<>0loop]
 | 
						|
}
 | 
						|
 | 
						|
  {Accelerated version}
 | 
						|
  $012e \sysArgs0: {"p"}
 | 
						|
  $20   \sysArgs2. {"SegmentY"}
 | 
						|
  \invTable q=
 | 
						|
  \SYS_RacerUpdateVideoY_40 \sysFn:
 | 
						|
  [do
 | 
						|
    q 8?
 | 
						|
    Distance+ \sysArgs3. 40!!
 | 
						|
    q<++
 | 
						|
    if<>0loop]
 | 
						|
 | 
						|
  ret
 | 
						|
] DrawGrass=
 | 
						|
 | 
						|
{-----------------------------------------------------------------------+
 | 
						|
|}\vLR>++ ret{          RAM page 9                                      |
 | 
						|
+-----------------------------------------------------------------------}
 | 
						|
$09a0:
 | 
						|
 | 
						|
[def
 | 
						|
  {Clear progress indicator in title bar}
 | 
						|
  $0bf7 Indicator=
 | 
						|
  $0c6b Tracking=
 | 
						|
  [do 0 {Black} Tracking. Tracking<++ Tracking<, $76^ if<>0loop]
 | 
						|
  ret
 | 
						|
] SetupIndicator=
 | 
						|
 | 
						|
[def
 | 
						|
  {Update progress indicator}
 | 
						|
  0 Tracking.
 | 
						|
  Distance>, Indicator+ Tracking= 60 Tracking.
 | 
						|
 | 
						|
  {Advance car along track}
 | 
						|
  Speed>, Distance+ Distance=
 | 
						|
 | 
						|
  ret
 | 
						|
] AdvanceCar=
 | 
						|
 | 
						|
{-----------------------------------------------------------------------+
 | 
						|
|}\vLR>++ ret{          RAM page 10                                     |
 | 
						|
+-----------------------------------------------------------------------}
 | 
						|
$0aa0:
 | 
						|
 | 
						|
[def
 | 
						|
  push
 | 
						|
  $01d9 peek 255^ X=
 | 
						|
  CarX>, X+ X=
 | 
						|
  $01d8 Video=
 | 
						|
  Car0 Sprite= DrawPixels!
 | 
						|
  Car1 Sprite= DrawPixels!
 | 
						|
  X Steer- X=
 | 
						|
  Car2 Sprite= DrawPixels!
 | 
						|
  Car3 Sprite= DrawPixels!
 | 
						|
  Car4 Sprite= DrawPixels!
 | 
						|
  pop ret
 | 
						|
] DrawRaceCar=
 | 
						|
 | 
						|
{-----------------------------------------------------------------------+
 | 
						|
|}\vLR>++ ret{          RAM page 12                                     |
 | 
						|
+-----------------------------------------------------------------------}
 | 
						|
$0ba0:
 | 
						|
 | 
						|
[def {
 | 
						|
  Intro
 | 
						|
}
 | 
						|
  push
 | 
						|
 | 
						|
  {Display welcome tekst}
 | 
						|
  48 BgColor=
 | 
						|
 | 
						|
  BgColor \sysArgs0. \sysArgs1.
 | 
						|
  $800    \sysArgs4:
 | 
						|
  \SYS_VDrawBits_134 \sysFn:
 | 
						|
  [do
 | 
						|
    134!!
 | 
						|
    \sysArgs4<++
 | 
						|
    \sysArgs4, 160^ if<>0loop]
 | 
						|
 | 
						|
  63 Color=
 | 
						|
 | 
						|
  $807 Pos= $3a QPrintChar!
 | 
						|
   18+ Pos= $2e QPrintChar!
 | 
						|
   31+ Pos= GigatronText PrintText!
 | 
						|
  60 Delay= Wait!
 | 
						|
 | 
						|
  pop ret
 | 
						|
] Intro=
 | 
						|
 | 
						|
{-----------------------------------------------------------------------+
 | 
						|
|}\vLR>++ ret{          RAM page 13                                     |
 | 
						|
+-----------------------------------------------------------------------}
 | 
						|
$0ca0:
 | 
						|
 | 
						|
[def {PrintBestTime}
 | 
						|
  Color=
 | 
						|
  BestTime Value=
 | 
						|
  1+ [if<0 ret] {No best time set yet}
 | 
						|
  push
 | 
						|
  $87c Pos=
 | 
						|
  3599 Radix= ExtractDigit! QPrintChar! 6+ Pos=
 | 
						|
                        $3a QPrintChar! 6+ Pos=
 | 
						|
   600 Radix= ExtractDigit! QPrintChar! 6+ Pos=
 | 
						|
    60 Radix= ExtractDigit! QPrintChar! 6+ Pos=
 | 
						|
                        $2e QPrintChar! 6+ Pos=
 | 
						|
     6 Radix= ExtractDigit! QPrintChar!
 | 
						|
  pop ret
 | 
						|
] PrintBestTime=
 | 
						|
 | 
						|
{-----------------------------------------------------------------------+
 | 
						|
|}\vLR>++ ret{          RAM page 14                                     |
 | 
						|
+-----------------------------------------------------------------------}
 | 
						|
$0da0:
 | 
						|
 | 
						|
[def
 | 
						|
  push
 | 
						|
 | 
						|
  {"GAME OVER" message}
 | 
						|
  $1435 Pos=
 | 
						|
  [def
 | 
						|
    $47# $41# $4d# $45# $20# $4f# $56# $45# $52# 0# {GAME OVER}
 | 
						|
  ] PrintText!
 | 
						|
 | 
						|
  $111 s=
 | 
						|
  $20+ t=
 | 
						|
  1 Delay=
 | 
						|
  s, 128& [if=0 +1 else -1] i= {Scroll direction}
 | 
						|
  [do Wait!
 | 
						|
    t, i- t.
 | 
						|
    s, i+ s.
 | 
						|
    255& if<>0loop]
 | 
						|
 | 
						|
  30 Delay= Wait!
 | 
						|
 | 
						|
  pop ret
 | 
						|
] GameOver=
 | 
						|
 | 
						|
{-----------------------------------------------------------------------+
 | 
						|
|}\vLR>++ ret{          RAM page 15                                     |
 | 
						|
+-----------------------------------------------------------------------}
 | 
						|
$0ea0:
 | 
						|
 | 
						|
[def {SetupHorizon}
 | 
						|
  push
 | 
						|
 | 
						|
  \zippedRacerHorizon p= $1000 q=
 | 
						|
  [def p<, 250^ [if<>0 1 else 6] p+ p= ret] tmp= {"next p"}
 | 
						|
  [do
 | 
						|
    p 0? \sysArgs0. tmp!
 | 
						|
      0? \sysArgs1. tmp!
 | 
						|
      0? \sysArgs2. tmp! \SYS_Unpack_56 \sysFn: 56!!
 | 
						|
      q \sysArgs4: 4+ q= \SYS_Draw4_30  \sysFn: 30!!
 | 
						|
    q>, $20^ if<>0loop]
 | 
						|
 | 
						|
  pop ret
 | 
						|
] SetupHorizon=
 | 
						|
 | 
						|
{-----------------------------------------------------------------------+
 | 
						|
|}\vLR>++ ret{          RAM page 16                                     |
 | 
						|
+-----------------------------------------------------------------------}
 | 
						|
$0fa0:
 | 
						|
 | 
						|
{--- Run ---}
 | 
						|
Intro!
 | 
						|
 | 
						|
{--- Main loop ---}
 | 
						|
[do
 | 
						|
  {Setup new game}
 | 
						|
  $7400 Distance= NextTurn=
 | 
						|
 | 
						|
  $7fff BestTime=
 | 
						|
  0 Time= Value= HorizonX= DriftX= Speed=
 | 
						|
  Random= DX0= DDX= NextDDX= DrawRoad!
 | 
						|
  DrawGrass!
 | 
						|
  SetupHorizon!
 | 
						|
  $1435 Pos=
 | 
						|
  [def
 | 
						|
   $47# $45# $54# $20# $52# $45# $41# $44# $59# 0# {GET READY}
 | 
						|
  ] PrintText!
 | 
						|
  SetupRoad!
 | 
						|
  SetupHorizon! {To delete the GET READY message}
 | 
						|
  SetupIndicator!
 | 
						|
 | 
						|
  $7900 CarX=
 | 
						|
 | 
						|
  {Play game until finished}
 | 
						|
  \frameCount, LastFrame=
 | 
						|
  PlayGame!
 | 
						|
  GameOver!
 | 
						|
  63 {White} PrintBestTime!
 | 
						|
 | 
						|
 loop]
 | 
						|
 | 
						|
{-----------------------------------------------------------------------+
 | 
						|
|       End                                                             |
 | 
						|
+-----------------------------------------------------------------------}
 | 
						|
 |