Revs on the BBC Micro

# Track geometry: GetSectionAngles (Part 3 of 3)

```       Name: GetSectionAngles (Part 3 of 3)                          [Show more]
Type: Subroutine
Category: Track geometry
Summary: Calculate the yaw and pitch angles for the track section entry
that we want to update
Deep dive: Data structures for the track calculations
The track verges
Context: See this subroutine in context in the source code
References: No direct references to this subroutine in this source file

This part of the routine sets the yaw and pitch angles for this track section
in the xVergeRight/Left and yVergeRight/Left tables.

.gsec6

TAY                    \ Set Y = the section number * 8 that we calculated in
\ part 3

STY thisSectionNumber  \ Store the section number * 8 in thisSectionNumber, so
\ we can retrieve it below when looping back

LDX sectionListPointer \ Set X = sectionListPointer, to use as a counter in the
\ two loops below

\ We run the following section twice, once for the inner
\ track section coordinates with X = sectionListPointer,
\ and a second time for the outer track section
\ coordinates with X = sectionListPointer + 40

.gsec7

STX sectionCounter     \ Store the loop counter in sectionCounter

LDX #&FD               \ Copy the first trackSectionI coordinate for track
JSR GetSectionCoord    \ section Y into xCoord2, so xCoord2 is the 3D
\ coordinate of the inner track at the start of the
\ section (or, if this is the second loop where Y has
\ been incremented by 3, xCoord2 is the 3D coordinate
\ of the outer track)

JSR GetObjYawAngle-2   \ Calculate xCoord2's yaw angle, from the point of view
\ of the player, returning it in (JJ II)

LDY sectionCounter     \ Set Y to the loop counter

BIT directionFacing    \ If bit 7 of directionFacing is clear, then we are

TYA                    \ We are facing backwards, so flip Y between
EOR #40                \ sectionListPointer and sectionListPointer + 40 to do
TAY                    \ the inner and outer track sections in reverse order
\ (so we always do the right track verge first, then the
\ left track verge, where right and left are relative to
\ the direction we are facing)

.gsec8

JSR GetSectionYawAngle \ Set the following for the Y-th section, to calculate
\ the difference in yaw angle between the track section
\ and the player:
\
\   xVergeRight = (JJ II) - playerYawAngle
\
\ Also set (L K) to the distance between the track
\ section and the player's car

LDX sectionCounter     \ If the loop counter in X >= 40, then we are dealing
CPX #40                \ with the outer track section, so jump to gsec10 as we
BCS gsec10             \ don't need to repeat the pitch angle calculation (the
\ track is level from left to right, so the outer track
\ is the same pitch angle as the inner track)

LDX #&FD               \ Set X = &FD so the call to GetObjPitchAngle uses
\ xCoord2, which we set above to the 3D coordinate of
\ the inner track at the start of the section

JSR GetObjPitchAngle-2 \ Calculate xCoord2's pitch angle, from the point
\ of view of the player, returning it in A and LL

LDX sectionCounter     \ Set X to the loop counter, which we know is less than
\ 40 at this point (and which is therefore equal to
\ sectionListPointer)

LDA LL                 \ Set A to the pitch angle that we just calculated
\ for the track section

STA yVergeRight,X      \ Store the pitch angle in the X-th yVergeRight
\ entry, for this point on the right track section

STA yVergeLeft,X       \ Store the same pitch angle in the X-th yVergeLeft,
\ for this point on the left track section, which will
\ at the same pitch angle as the track is level from
\ left to right

CMP horizonLine        \ If A < horizonLine, then this track section is lower
BCC gsec10             \ than the current horizon, so jump to gsec10 to move on
\ to the outer track section, as this section will not
\ be obscuring the horizon

BNE gsec9              \ If A <> horizonLine, i.e. A > horizonLine, then this
\ means the track section is higher than the current
\ line to the pitch angle of this track section, as the
\ section is obscuring the horizon

\ If we get here, then A = horizonLine, so this section
\ is at the same pitch angle as the current horizon line

CPX horizonListIndex   \ If X < horizonListIndex, then this section has a lower
BCC gsec10             \ index than the current horizon section, so jump to
\ gsec10 as horizonListIndex already contains the higher
\ index, and a higher index is closer to the player, so
\ we don't need to change the horizon line details

.gsec9

\ If we get here then we want to update the horizon to
\ the pitch angle of the track section we are updating,
\ as it obscures the horizon

STA horizonLine        \ Set horizonLine to the pitch angle in A, so the
\ horizon is set to the pitch angle of this track
\ section

STX horizonListIndex   \ Store the index of this section in the track section
\ list in horizonListIndex

.gsec10

TXA                    \ Set A = X + 40
CLC                    \       = sectionListPointer + 40
\ So A now points to the outer track section coordinates
\ and is ready to be put into X (and, when we look back,
\ into sectionCounter) for the loop back to gcsec7 below

CMP #60                \ If A >= 60, we have done both inner and outer track

TAX                    \ Set X = A
\       = sectionListPointer + 40

LDA thisSectionNumber  \ Set Y = thisSectionNumber + 3
CLC                    \
ADC #3                 \ So when we loop back, the offset in Y points to the
TAY                    \ trackSectionO coordinates for the outer track section
\ instead of the inner coordinates in trackSectionI (as
\ the outer coordinates are 3 bytes after the inner ones
\ in the track data)

JMP gsec7              \ Loop back to gsec7 to process the outer track section

.gsec11

\ If we get here then we have updated this entry in the
\ track section list with both left and right angles, so
\ we now update the list pointers

LDX sectionListPointer \ Set X = sectionListPointer - 1
DEX

JSR SetSectionPointers \ Update the section list pointers to move down through
\ the track section list

LDA #7                 \ If prevHorizonIndex <= 7, then the previous call to
CMP prevHorizonIndex   \ GetTrackAndMarkers (on the last iteration of the main
BCS gsec12             \ driving loop) had the horizon on one of the sections
\ in the track section list, or the first entry in the
\ track segment list (as the list starts at index 6), so