# Track geometry: GetTrackSegment (Part 1 of 3)

```       Name: GetTrackSegment (Part 1 of 3)                           [Show more]
Type: Subroutine
Category: Track geometry
Summary: Set up the next track segment in the track segment buffer
Deep dive: Building a 3D track from sections and segments
Data structures for the track calculations
Corner markers
Context: See this subroutine in context in the source code
References: This subroutine is called as follows:
* PlaceCarsOnTrack calls GetTrackSegment
* TurnPlayerAround calls GetTrackSegment

This routine calculates the coordinates, flags and cornering data for the next
track segment. It does this in three parts:

1. Initialise up the new track segment, and fetch the segment vector for the
new track segment

2. Set the flags for the new track segment

3. Add the segment vector from part 1 to the coordinates for the current
track segment to get the coordinates for the next track segment

This part does the following:

* Move the index on to the next track segment

* Initialise the new track segment if we are entering a new track section

* Set pastHalfway

* Set (SS T), (TT U) and (UU V) to the xTrackSegmentI, yTrackSegmentI and
zTrackSegmentI vectors

.GetTrackSegment

LDA frontSegmentIndex  \ Set A to the index * 3 of the front track segment in
\ the track segment buffer

STA prevSegmentIndex   \ Store A in prevSegmentIndex, as we are about to move
\ on to the next track segment

CLC                    \ Set A = frontSegmentIndex + 3
\ to move on to the next track segment ahead of the
\ current front segment in the track segment buffer,
\ which will become the new front segment

CMP #120               \ If A < 120, then we haven't reached the end of the
BCC gets1              \ track segment buffer, so jump to gets1 to store the
\ updated value

LDA #0                 \ We just reached the end of the track segment buffer,
\ so set A = 0 to wrap round to the start

.gets1

STA frontSegmentIndex  \ Set frontSegmentIndex to the index * 3 of the new
\ front track segment

LDX #23                \ Set X to 23, the object number we use to store the
\ front segment of the track segment buffer

LDA directionFacing    \ If our car is facing backwards, jump to gets3
BMI gets3

LDA trackSectionCount  \ Set A to half the total number of track sections * 4
LSR A

AND #%11111000         \ Reduce A to the nearest multiple of 8

CMP objTrackSection,X  \ If A <> number of the track section * 8 for the front
BNE gets2              \ segment, then we are not halfway through all the track

\ If we get here then the front segment is at the
\ halfway point round the track in terms of track
\ section numbers

LDA #1                 \ Set pastHalfway = 1, to denote that the front segment
STA pastHalfway        \ is in the second half of the track

.gets2

JSR MoveObjectForward  \ Move the front segment forwards by one segment,
\ setting the C flag if this moves the driver into the
\ next track section

BCC gets4              \ If the front segment is still in the same track

JSR GetFirstSegment    \ Otherwise we just moved into a new track section, so
\ get the track section coordinates and flags from the
\ track data and populate the first track segment,
\ setting thisVectorNumber to the number of the segment
\ vector for the new track segment

JMP gets13             \ Jump to gets13 to finish setting up the track segment,
\ skipping the part that sets the coordinates and flags,
\ as those have just been set when creating the entry
\ for the new track section

.gets3

\ If we get here then our car is facing backwards

LDA objTrackSection+23 \ Set sectionBehind to the number * 8 of the track
STA sectionBehind      \ section for the front segment

JSR MoveObjectBack     \ Move the front segment backwards along the track,
\ setting the C flag if this moves the driver into the
\ next track section

BCC gets4              \ If the front segment is still in the same track

JSR GetFirstSegment    \ Otherwise we just moved into a new track section, so
\ get the track section coordinates and flags from the
\ track data and populate the first track segment,
\ setting thisVectorNumber to the number of the segment
\ vector for the new track segment

.gets4

LDY thisVectorNumber   \ Set Y to the number of the segment vector for the new
\ track segment

JSR GetSegmentVector   \ Set (SS T), (TT U) and (UU V) to the coordinates of
\ the segment vector for the new track segment, so:
\
\   [ (SS T) ]   [ xTrackSegmentI ]
\   [ (TT U) ] = [ yTrackSegmentI ]
\   [ (UU V) ]   [ zTrackSegmentI ]
\
\ In other words, they contain the vector that we need
\ to add to the previous track segment's coordinates in
\ order to get the coordinates for the new track segment
\
\ Or, even simpler, they contain the vector from the
\ previous track segment's coordinates to the new one
```