Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 17:57 17 Jul 2026 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : CMM2: Outrun game

     Page 2 of 2    
Author Message
Martin H.

Guru

Joined: 04/06/2022
Location: Germany
Posts: 1479
Posted: 03:53pm 18 May 2026
Copy link to clipboard 
Print this post

Hello Leo,
On Sunday, I took a look at Jake Gordon’s explanation and recreated it in MM-Basic (with help from  Gemini).
I haven't done any speed tests on the Pico yet but it runs quite smoothly on MMB4W and should work just as well on the CMM2.



This could form the framework for the game.
' =========================================================================
' 2.5D Testloop Martin H. 2026
' MM-Basic Version based on the description by Jake Gordon
' https://jakesgordon.com/writing/javascript-racer-v3-hills/
' =========================================================================
Option Explicit
Option Default Integer
mode 7
' Bildschirm-Modus (z.B. 640x480)
Const SCREEN_WIDTH  = mm.hres
Const SCREEN_HEIGHT = mm.vres
'

' Konstanten für die Straße und Kamera
Const ROAD_WIDTH     = 2000
Const SEGMENT_LENGTH = 200
Const DRAW_DISTANCE  = 100

' Globale Variablen mit DIM deklarieren
Dim Float fieldOfView  = 100
Dim Float cameraHeight = 1500
Dim Float cameraDepth  = 1 / Tan((fieldOfView / 2) * Pi / 180)
Dim Float playerZ      = cameraHeight * cameraDepth
Dim Float resolution   = SCREEN_HEIGHT / 480

Dim Float position = 0
Dim Float playerX  = 0  
Dim Float speed    = 75


' Input values for the projection
Dim Float prj_wy, prj_wz
Dim Float prj_px, prj_py
Dim Float prj_camz, prj_xoff
Dim prj_looped

' Ausgabewerte der Projektion
Dim prj_sx, prj_sy, prj_sw
' Temporary auxiliary variables for the calculation (declared globally)
Dim Float prj_tx, prj_ty, prj_tz, prj_scale
' Two separate arrays of integers for the X and Y coordinates of the four corners
Dim xpoly%(3)
Dim ypoly%(3)

' =========================================================================
' The road network (global arrays)
' =========================================================================
Const MAX_SEGMENTS = 3000
Dim integer seg_count = 0
Page write 1
' The parallel arrays hold the route data
Dim Float seg_world_y(MAX_SEGMENTS)
Dim Float seg_world_z(MAX_SEGMENTS)
Dim Float seg_curve(MAX_SEGMENTS)
Dim seg_color(MAX_SEGMENTS)

' Subroutine to be added: Variables in the header are automatically local,
' no internal variables are redimensioned.
Sub Add_Segment(curve As Float, y As Float)
 If seg_count >= (MAX_SEGMENTS-100) Then Exit Sub
   seg_world_y(seg_count) = y
 seg_world_z(seg_count) = seg_count * SEGMENT_LENGTH
 seg_curve(seg_count)   = curve
   If Int(seg_count / 3) MOD 2 Then
   seg_color(seg_count) = 1
 Else
   seg_color(seg_count) = 0
 EndIf
   inc seg_count
End Sub

Function EaseInOut(a As Float, b As Float, pct As Float) As Float
 EaseInOut = a + (b - a) * ((-Cos(pct * Pi) / 2) + 0.5)
End Function

'Here we use LOCAL for the loop variable
Sub Build_Track
 seg_count = 0 'Reset to restart'
' Parameter description for Add_Road:

 ' Inlet, Hold, Outlet, Curve strength (- for left, + for right), Hill height  
 ' --- OUTRUN LEVEL 1: COCONUT BEACH ---
 ' Start & Erste Hügel
 Add_Road 100, 100, 100, 0, 8
 Add_Road 20, 20, 20, 0, 8
 Add_Road 10, 10, 100, -5, 8
 Add_Road 20, 50, 20, 30, 7
 
 ' First big left-hand bend & straight
 Add_Road 100, 100, 100, -1.5, 0
 Add_Road 26, 26, 26, 0, 7
 
 ' A right-hand bend that leads into a hill
 Add_Road 100, 100, 5, 1.5, 0
 Add_Road 0, 100, 0, 1.5, 20
 Add_Road 0, 50, 100, 1.5, -10
 
 ' Hügelige Gerade
 Add_Road 40, 40, 40, 0, 20
 Add_Road 30, 60, 0, 0, -15
 
 ' Long left-hand bend, straight, sharper left-hand bend
 Add_Road 20, 170, 85, -1.5, 0
 Add_Road 50, 50, 50, 0, 0
 Add_Road 60, 60, 60, -3.0, 0
 Add_Road 70, 70, 70, 0, 0
 
 ' A combination of S-bends and hills
 Add_Road 20, 20, 20, 3.0, 0
 Add_Road 25, 25, 25, 0, -10
 Add_Road 20, 40, 0, -3.0, 10
 Add_Road 0, 80, 0, -3.0, -5
 Add_Road 0, 70, 0, -3.0, 15
 
 ' Outward-sweeping left-hand bend & long straight
 Add_Road 0, 50, 20, -3.0, 0
 Add_Road 100, 100, 100, 0, 0
 Add_Road 30, 30, 30, -3.0, 0
 Add_Road 30, 30, 30, 0, 0
 Add_Road 30, 30, 30, 0, 0
 
 'The bumpy finish before the fork in the track'
 Add_Road 20, 20, 20, -3.5, 0
 Add_Road 10, 60, 10, 3.5, 20
 Add_Road 10, 90, 10, -3.5, 25
 Add_Road 10, 10, 10, 0, 0
 Add_Road 50, 50, 50, 0, 0
 Add_Road 10, 10, 10, 0, 5
 Add_Road 10, 10, 10, 0, -5
 Add_Road 10, 10, 10, 0, 5
 Add_Downhill_To_End 150

End Sub

Build_Track
Dim Float trackLength = seg_count * SEGMENT_LENGTH
Sub Add_Downhill_To_End num_segments
 Local startY, n
 Local Float hillPerSegment
 
 If seg_count = 0 Then Exit Sub
 
 ' Determine the current altitude at the end of the OutRun track
 startY = seg_world_y(seg_count - 1)
   ' Calculate how much we need to decrease/increase per segment to end up at 0
 ' (Taper off as a negative slope)
 hillPerSegment = -startY / (num_segments * SEGMENT_LENGTH)
 
 ' Add the run-out straight, which gently takes us to the finish line
 ' We use a slight left-hand bend (-1.0) to visually signal the finish line
 Add_Road Int(num_segments/3), Int(num_segments/3), Int(num_segments/3), -1.0, hillPerSegment
End Sub
Sub Project
 ' 1. Transformieren
 prj_tx = (prj_px * ROAD_WIDTH) - prj_xoff
 prj_ty = prj_py + cameraHeight
 prj_tz = prj_wz - prj_camz
 
 ' 2. Runden-Loop prüfen
 If prj_looped Then
   inc prj_tz , trackLength
 EndIf
 
 ' 3. Division durch Null verhindern
 If prj_tz <= 0 Then
   prj_tz = 1
 EndIf
 
 ' 4. Skalieren und Projizieren
 prj_scale = cameraDepth / prj_tz
 
 ' 5. Ergebnis in die Ausgangsvariablen schreiben
 prj_sx = (SCREEN_WIDTH / 2) + (prj_scale * prj_tx * SCREEN_WIDTH / 2)
 prj_sy = (SCREEN_HEIGHT / 2) - (prj_scale * (prj_wy - prj_ty) * SCREEN_HEIGHT / 2)
 prj_sw = prj_scale * ROAD_WIDTH * SCREEN_WIDTH / 2
End Sub

' =========================================================================
' Render-Engine
' =========================================================================

Sub Render_Road
 Local baseSeg, s_idx, looped, n, maxy
 Local Float basePct, playerY, p1_y, p2_y
 Local Float r_x, r_dx
 
 ' Werte für das aktuelle Segment berechnen
 baseSeg = Int(position / SEGMENT_LENGTH) MOD seg_count
 basePct = (position MOD SEGMENT_LENGTH) / SEGMENT_LENGTH
 
 p1_y = seg_world_y(baseSeg)
 p2_y = seg_world_y((baseSeg + 1) MOD seg_count)
 playerY = p1_y + (p2_y - p1_y) * basePct
 
 maxy = SCREEN_HEIGHT
 r_x = 0
 r_dx = - (seg_curve(baseSeg) * basePct)
 
 ' Lokale Speicher für die projizierten Punkte
 Local p1_sx, p1_sy, p1_sw
 Local p2_sx, p2_sy, p2_sw
 
 For n = 0 To DRAW_DISTANCE - 1
     if n=Draw_DISTANCE - 1 then Box 0,0,SCREEN_WIDTH,p1_sy+1,,rgb(Cyan),rgb(Cyan)
   s_idx = (baseSeg + n) MOD seg_count
   looped = (s_idx < baseSeg)
   
   ' --- PROJEKTION PUNKT 1 (p1) ---
   ' Daten übergeben
   prj_wy = seg_world_y(s_idx)
   prj_wz = seg_world_z(s_idx)
   prj_px = playerX
   prj_py = playerY
   prj_camz = position
   prj_looped = looped
   prj_xoff = r_x
   
   Project ' Berechnen
   
   ' Ergebnisse sichern
   p1_sx = prj_sx : p1_sy = prj_sy : p1_sw = prj_sw
   
   ' --- PROJEKTION PUNKT 2 (p2) ---
   ' Daten übergeben (Nächstes Segment)
   prj_wy = seg_world_y((s_idx + 1) MOD seg_count)
   prj_wz = seg_world_z((s_idx + 1) MOD seg_count)
   prj_xoff = r_x + r_dx
   
   Project ' Berechnen
   
   ' Ergebnisse sichern
   p2_sx = prj_sx : p2_sy = prj_sy : p2_sw = prj_sw
   
   ' Kurven-Akkumulation
   r_x = r_x + r_dx
   r_dx = r_dx + seg_curve(s_idx)

   ' Clipping prüfen
   If p2_sy >= p1_sy Or p2_sy >= maxy Then
     Continue For
   EndIf

   ' Zeichnen aufrufen (Variablenübergabe via Globals oder kurze Liste)
   Draw_Segment_Trapezoid p1_sx, p1_sy, p1_sw, p2_sx, p2_sy, p2_sw, seg_color(s_idx)
   
   maxy = p1_sy
 Next n
End Sub
Sub Add_Road enter_seg, hold_seg, leave_seg, curve As Float, hillY As Float
 Local startY, endY, total, n
 Local Float c_val, y_val
 
 startY = 0
 If seg_count > 0 Then
   startY = seg_world_y(seg_count - 1)
 EndIf
 
 ' hill-Y wird hier als direkte Neigung pro Segment interpretiert,
 ' das verhindert mathematische Rundungsfehler bei schnellen Wechseln
 total = enter_seg + hold_seg + leave_seg
 endY = startY + (hillY * total)
 ' curve
 ' 1. Ease In
 For n = 0 To enter_seg - 1
   c_val = EaseInOut(0, curve, n / enter_seg)
   y_val = EaseInOut(startY, endY, n / total)
   Add_Segment c_val, y_val
 Next n
 
 ' 2. Hold
 For n = 0 To hold_seg - 1
   c_val = curve
   y_val = EaseInOut(startY, endY, (enter_seg + n) / total)
   Add_Segment c_val, y_val
 Next n
 
 ' 3. Ease Out
 For n = 0 To leave_seg - 1
   c_val = EaseInOut(curve, 0, n / leave_seg)
   y_val = EaseInOut(startY, endY, (enter_seg + hold_seg + n) / total)
   Add_Segment c_val, y_val
 Next n
End Sub


Sub Draw_Segment_Trapezoid x1, y1, w1, x2, y2, w2, colorType
 Local c_road, c_grass,n
 
 If colorType = 0 Then
   c_road = RGB(0, 0, 255)  
   c_grass = RGB(0, 170, 0)    
 Else
   c_road = RGB(0, 85,255)    
   c_grass = RGB(0, 255, 0)    
 EndIf
 
if y2>SCREEN_HEIGHT then y2=SCREEN_HEIGHT
 ' Fill in X-coordinates (integer assignment)
 xpoly%(0) = Int(x1 - w1)
 xpoly%(1) = Int(x2 - w2)
 xpoly%(2) = Int(x2 + w2)
 xpoly%(3) = Int(x1 + w1)
  For n = 0 To 3
  if xpoly%(n)> SCREEN_WIDTH then xpoly%(n)= SCREEN_WIDTH
  next
 ' Fill in Y-coordinates (integer assignment)
 ypoly%(0) = Int(y1)
 ypoly%(1) = Int(y2)
 ypoly%(2) = Int(y2)
 ypoly%(3) = Int(y1)
 'Grass baseline
 box 0, y1, SCREEN_WIDTH, y2-y1,, c_grass,c_grass
 'Road segment
 POLYGON 4, xpoly%(), ypoly%(), c_road, c_road
End Sub
' =========================================================================
' (Game Loop)
' =========================================================================
CLS 0
Dim k$

DO
 inc position,speed
 If  position >= trackLength Then inc position, - trackLength
 
 ' Keypress?
 k$ = INKEY$
 If k$ = "a" Or k$ = "A" Then playerX = playerX - 0.05
 If k$ = "d" Or k$ = "D" Then playerX = playerX + 0.05
 If k$ = chr$(27) then end
 'start Render-Engine
 Render_Road

 TEXT 10, 10, "SPEED: " + Str$(speed)
 page copy 1,0
'  PAUSE 30
LOOP

Cheers
Martin
Edited 2026-05-19 20:14 by Martin H.
'no comment
 
Martin H.

Guru

Joined: 04/06/2022
Location: Germany
Posts: 1479
Posted: 03:40pm 03 Jul 2026
Copy link to clipboard 
Print this post

Background graphics for Outrun all 15 stages
Hello,
in case anyone’s interested: I’ve revamped the background graphics for all 15 levels of the game.
To do this, I ripped the graphics from the Sega Mega Drive/Genesis version. These are originally 640 pixels wide. To save on resources, I’ve compressed them horizontally (C64-style, It doesn’t look as bad as it sounds, and it’s just the background on the horizon, where you can’t make out much anyway )
PNG for CMM2 Windows, BMP for Pico RGB 121

MegaBG.zip

I’ve also included a small sample programme so you can take a look at the backgrounds on Windows or on the Pico.
'Test / Demo for Outrun backgrounds
Pico=1
If Pico Then
 MODE 2
 FRAMEBUFFER create f
Else
 MODE 7
End If
CLS
If Pico  Then FRAMEBUFFER write f :Else :page write 1:EndIf
Dim FN$(14)LENGTH 2 =("01","2A","2B","3A","3B","3C","4A","4B","4C","4D","5A","5B","5C","5D","5E")
grass%=RGB(0,85,0)
Dim Integer s=1 'Scrollspeed 1-8
Do
 For N=0 To 14
   If Pico  Then FRAMEBUFFER write f :Else :page write 1:EndIf
   LN$=FN$(N)
   If Pico Then
     Load image LN$+".BMP"
     'Save compressed image LN$+".BMP",0,0,312,80
   Else
     Load png LN$+".png"
   End If
   sky%=Pixel(0,0)
   If Pico  Then FRAMEBUFFER write n :Else :page write 0:EndIf
   Box 0,0,320,80,,Sky%,sky%
   Box 0,80,320,160,,grass%,grass%
   If Pico  Then FRAMEBUFFER write f :Else :page write 1:EndIf
   For f=0 To 320
     'Scroll Left
     Blit 0,0,312,0,s,80:Blit s,0,0,0,312,80
     If Pico Then
       Blit Resize f,n,0,0,160,80,0,80,320,80
     Else
       page write 0
       image resize 0,0,160,80,0,80,320,80,1
       page write 1
     End If
     Pause 20
   Next
   For f=0 To 320
     'Scroll Right
     Blit 0,0,s,0,312,80:Blit 312,0,0,0,s,80
     If Pico Then
       Blit Resize f,n,0,0,160,80,0,80,320,80
     Else
       page write 0
       image resize 0,0,160,80,0,80,320,80,1
       page write 1
     End If
     Pause 20
   Next
 Next
Loop

Perhaps someone will find the time to give it a go.
Edited 2026-07-04 01:42 by Martin H.
'no comment
 
LeoNicolas

Guru

Joined: 07/10/2020
Location: Canada
Posts: 590
Posted: 01:19am 04 Jul 2026
Copy link to clipboard 
Print this post

Thank you, Martin.

​I haven't given up on developing the game. I just needed to take a break due to some personal issues.

​I hope to restart development over the next few months.
 
Martin H.

Guru

Joined: 04/06/2022
Location: Germany
Posts: 1479
Posted: 07:12pm 05 Jul 2026
Copy link to clipboard 
Print this post

Hi Leo,
Good to hear from you. I summarized all of this today and combined the two approaches.
This is now Picomite 2 running at 378 MHz, but unfortunately it’s only managing 18–22 fps so far.Video
I still need to find a less resource-intensive approach for drawing the roads; it worked much faster in my other attempt, after all.
Cheers
Martin
'no comment
 
Martin H.

Guru

Joined: 04/06/2022
Location: Germany
Posts: 1479
Posted: 12:19pm 15 Jul 2026
Copy link to clipboard 
Print this post

Hi Leo and everyone,
Here’s a quick update.

Outrun.zip
Over the last two days, I’ve been working on the programme behind the high score screen

It’s more or less finished, but you can’t enter your details yet – after all, you haven’t achieved a score yet.
In the game, I’m still trying to increase my speed by improving my driving technique. The tracks are already in the txt folder, but I haven’t achieved anything worth showing off yet. It’s too hot to think straight at the moment, anyway.That’s why I’ve spent more of my free time tweaking pixels and music than programming.

It’s running well, but unfortunately still only at about 22 fps at 378 kHz (I’m working on it, see above).
The music tracks are included as MOD files. Except for “Last Wave”, the jazzy high-score track – I’ve kept that as a FLAC file for the sake of simplicity. Sound effects haven’t been integrated yet.
Just giving it a go.
 Cheers
   Martin
Edited 2026-07-15 22:32 by Martin H.
'no comment
 
Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 5991
Posted: 01:12pm 15 Jul 2026
Copy link to clipboard 
Print this post

Hi Martin,

Tried this on RP2040VGA V60300.
I get "out of heap memory" in line 72.

Tried to limit max segments to 1000 (from 3500) but get the same error message.
Are you running a 2350 ? Or an older MMBasic (6.02.01 ? ).

Regards,

Volhout
PicomiteVGA PETSCII ROBOTS
 
PilotPirx

Senior Member

Joined: 03/11/2020
Location: Germany
Posts: 126
Posted: 01:14pm 15 Jul 2026
Copy link to clipboard 
Print this post

It looks damn good—I can't wait to try it out.
Hopefully there will be a CMM2 version later on, too!!
Edited 2026-07-15 23:21 by PilotPirx
 
Martin H.

Guru

Joined: 04/06/2022
Location: Germany
Posts: 1479
Posted: 01:33pm 15 Jul 2026
Copy link to clipboard 
Print this post

  Volhout said  Hi Martin,

Tried this on RP2040VGA V60300.
I get "out of heap memory" in line 72.

Tried to limit max segments to 1000 (from 3500) but get the same error message.
Are you running a 2350 ? Or an older MMBasic (6.02.01 ? ).

Regards,

Volhout

Hi Harm,
Thank you for testing. Yes, you’re right, I’m currently working on a 2350 (HDMI), but the aim is to move on to the Pico 2040 VGA as well.
At the moment, the route data array takes up a lot of space, but that will change with the new method; I plan to load only the part of the route data that’s currently needed – essentially streaming the route. It is, of course, in the nature of things that the file is only ever read in one direction; this makes it possible to keep the file open in read-only mode and only read the necessary (future) data.

Please have a go at testing whether the ".Highscore.Bas" file works for you.
Cheers
 Martin
'no comment
 
Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 5991
Posted: 02:46pm 15 Jul 2026
Copy link to clipboard 
Print this post

Hi Martin,

Yes Highscore.bas works (after I corrected a spurious character in line 100).
With the cursor keys you can highlight characters, there is a countdown clock running right top.
But I could not really edit something.

Regards,

Volhout
PicomiteVGA PETSCII ROBOTS
 
Martin H.

Guru

Joined: 04/06/2022
Location: Germany
Posts: 1479
Posted: 02:59pm 15 Jul 2026
Copy link to clipboard 
Print this post

  PilotPirx said  It looks damn good—I can't wait to try it out.
Hopefully there will be a CMM2 version later on, too!!


Leo is working on the CMM2 version, but I think it would help if he could take over some of the components I’ve already programmed. My plan is as follows:

I broke down a video of all the arcade levels into individual frames and analyzed them frame by frame to see exactly what happens and when.

The game starts with an intro animation that is simply played and can then be purged from memory. At the start, the player is driving slowly; a drop in the frame rate wouldn’t be noticeable here, which gives the system a great opportunity to run garbage collection and load the next objects in the background. At this stage, only the absolutely necessary sprites are kept in memory. Elements like spectators or the start banner are no longer needed later on, so that memory is freed up again. Once the player reaches the first hill, the next set of sprites—like waves and surfers—can be loaded, and so on. In principle, new sprites are constantly replacing old ones, meaning all the "decorations" can be streamed.

Forked paths always occur on flat ground, so there is no need to calculate the height separately at that moment. There are also no roadside decorations at any of these junctions. Once the player has chosen a direction, this gives the game enough time to load the new background first, followed by the sprites for the new level (bit by bit, so as not to cause visible lag). The next piece of scenery is the "Checkpoint" sign—and here, too, there are no other decorations along the road. Since those only appear after a few frames, I suspect they are loaded into sprite memory at that exact moment. From there, the actual level really gets going.

To sum up: whenever the scene looks calm to the player, the hardware (Pico/CMM2) is actually working flat out in the background.
Edited 2026-07-16 03:22 by Martin H.
'no comment
 
Martin H.

Guru

Joined: 04/06/2022
Location: Germany
Posts: 1479
Posted: 08:04pm 15 Jul 2026
Copy link to clipboard 
Print this post

  Volhout said  Hi Martin,

Yes Highscore.bas works (after I corrected a spurious character in line 100).
With the cursor keys you can highlight characters, there is a countdown clock running right top.
But I could not really edit something.

Regards,

Volhout

Hi Harm,
After the INC command, that often happens on my Pico – for some inexplicable reason, ‘ghost characters’ suddenly appear.I don’t know if it’s down to the SD card.

I did write that you can’t edit anything yet; that’s the GUI first of all.  
But for my taste, it’s pretty close to the original.
I’m going to create a pseudo-score to implement the input and sorting. The little animation where the little cars drag the text across the screen is also missing.
To make up for this, I’ve animated the headings (colour fade) – it just seemed like the right thing to do, even though it isn’t in the original.
I handle the fade-in and fade-out in the same way as with Petscii Robots, but there’s a reason for that too. Once the high score is displayed, or rather once you get to the point of entering the high score, the game is over; after entering it, the main programme can be restarted.
By using the fade-in and fade-out effect, I conceal the fact that it’s a different programme. For the Pico, this means it has a fresh system for every new round.
Have a lovely evening
Cheers
Martin..
PS: Is it just as warm in the Netherlands at the moment?
'no comment
 
Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 5991
Posted: 08:27pm 15 Jul 2026
Copy link to clipboard 
Print this post

Yes, too warm to do difficult tasks.
Most of pico work happens in the evenings, when it cools down, sitting in our garden...
Under the tree.

Really looking forward to this game Martin. It sounds like there is a lot sequencing needed to balance the CPU load. Are you planning on using a state machine to do this (since in essence each level has a fixed start point, and a fixed end point, although you can select different roads to get there).??

Volhout
Edited 2026-07-16 16:38 by Volhout
PicomiteVGA PETSCII ROBOTS
 
LeoNicolas

Guru

Joined: 07/10/2020
Location: Canada
Posts: 590
Posted: 11:12am 16 Jul 2026
Copy link to clipboard 
Print this post

Hi Martin

I'm traveling to visit family. I will be back home in August. I
I will restart working on the project as soon as I'm back
 
Martin H.

Guru

Joined: 04/06/2022
Location: Germany
Posts: 1479
Posted: 03:35pm 16 Jul 2026
Copy link to clipboard 
Print this post

  Volhout said  Are you planning on using a state machine to do this (since in essence each level has a fixed start point, and a fixed end point, although you can select different roads to get there).??

I’m not sure what you mean by state machine.
Technically speaking, all stages work in the same way.
The only differences are the scenery, the route, the colour scheme and the background. I have the distribution of bends and elevation profiles in the CSV file. The individual stages simply have different start and end points.
Here is a list of the start and end points for each stage in the CSV file.

  Quote  route A :
 stage 1  >   stage 2  >   stage 3     >   stage 4    >   stage 5     >  stage 50
(6-235)   >  (237-481) >  (483-717)    >  (719-963)   >  (965-1239)

route B :
stage 1   >  stage 6    >   stage 7    >   stage 8    >   stage 9     >  stage 90
(6-235)   > (1240-1505) >  (1507-1772) >  (1774-1980) >  (1982-2257)

route C :
stage 1   >   stage 6   >   stage 10   >   stage 11   >   stage 12    >  stage 120
(6-235)   > (1240-1505) >  (2306-2509) >  (2511-2760) >  (2762-3047)

route D :
stage 1   >   stage 6   >   stage 10   >   stage 13   >   stage 14    >  stage 140  
(6-235)   > (1240-1505) >  (2306-2569) >  (3049-3308) >  (3310-3584)

route E :
stage 1   >  stage 6    >   stage 10   >   stage 13   >   stage 15    >  stage 150
(6-235)   > (1240-1505) >  (2306-2569) >  (3105-3370) >  (3586-3878)
The list is not complete, but the line numbers are correct
The 50, 150, etc. stages are the end points.
They are simply reference points for the programme; they do not have specific line numbers.

I found much of those data in a CPC Outrun version in QB, but the programme isn’t really transferable.
However, the stage list can be expanded without any problems; each entry in the "route.csv" represents a section of the road valzes of. There you’ll find details on curves, elevation changes, decoration and so on. One only need at least 8 (preferably 12) of these in memory. At least, that’s my planThat’s nothing compared to the 3,000 Line field my test programme currently uses. And I can easily add, for example, instructions for reloading new graphics to ensure the timing is correct.
Cheers
Martin
Edited 2026-07-17 01:56 by Martin H.
'no comment
 
     Page 2 of 2    
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2026