Skip to navigation

Revs on the BBC Micro

Track geometry: GetSegmentAngles (Part 1 of 3)

Name: GetSegmentAngles (Part 1 of 3) [Show more] Type: Subroutine Category: Track geometry Summary: Get the yaw and pitch angles for the inner or outer track segments Deep dive: Data structures for the track calculations The track verges
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * GetTrackAndMarkers calls GetSegmentAngles

This routine works through track segments, starting from distant segments and working backwards towards the player, calculating the angles and verge data for each segment as we go, up to a maximum of 16 segments (which is the capacity of the track segment list).
Arguments: A The index of the first segment to update in the track segment list, starting at 6 for the first entry in list of right segments, and 46 for the first entry in the list of left segments X The offset from xSegmentCoordILo of the segment's 3D coordinates, i.e. the segment number * 3, with: * X for inner track segment coordinates * X + 120 for outer track segment coordinates segmentOffset The offset to use for this segment: * 0 when our car is facing in the same direction * 120 when our car is facing the opposite direction segmentDirection The relative direction of our car: * 0 when our car is facing in the same direction * 1 when our car is facing the opposite direction
Returns: xVergeRight Updated yaw angles for the entries in the track segment list (i.e. indexes 6 to 21) for the right verge yVergeLeft Updated pitch angles for the entries in the track segment list (i.e. indexes 6 to 21) for the left verge edgeDistance The distance between the player's car and the nearest track edge edgeSegmentNumber The number of the segment within the track segment list that is closest to the player's car edgeSegmentPointer The index of the segment within track verge buffer that is closest to the player's car edgeYawAngle The yaw angle of the segment that is closest to the player's car xVergeRight Entries in the second part of the track segment list for the coordinates of the outside of the right track verge (i.e. indexes 22 to 37, which correspond to the yaw angles in the track segment list in indexes 6 to 21) xVergeLeft Entries in the second part of the track segment list for the coordinates of the outside of the left track verge (i.e. indexes 22 to 37, which correspond to the yaw angles in the track segment list in indexes 6 to 21) yVergeRight Pitch angles for the entries in the track segment list (i.e. indexes 6 to 21) for the right verge yVergeLeft Pitch angles for the entries in the track segment list (i.e. indexes 6 to 21) for the left verge xMarker Distance in the x-axis between the track edge and the corner marker for this segment (if there is one) vergeDataRight Data (such as colour) for this segment's right verge vergeDataLeft Data (such as colour) for this segment's left verge
.GetSegmentAngles STA segmentListPointer \ Set segmentListPointer to the index passed in A LDA #0 \ Set segmentCounter = 0, to use to count visible STA segmentCounter \ segments over the course of the following routine \ We now run the rest of the routine for each segment \ in turn, looping back to here while segments are \ visible .gseg1 JSR GetSegmentYawAngle \ Calculate the yaw angle and distance between the \ player's car and the track segment specified in X, and \ store the results in the track segment list at the \ segment list pointer \ \ Also set (A K) = (L K) = the distance between the car \ and the track segment \ We now check to see if this is the closest track \ segment we've come across in this iteration of the \ main loop, and if it is, we set a bunch of variables \ with the details of the track edge CMP edgeDistanceHi \ If A < edgeDistanceHi, then we know that (A K) and BCC gseg2 \ therefore (L K) < (edgeDistanceHi edgeDistanceLo), \ so jump to gseg2 to set (L K) as the new minimum \ distance to the verge BNE gseg3 \ If A <> edgeDistanceHi, i.e. A > edgeDistanceHi, \ then (L K) > (edgeDistanceHi edgeDistanceLo), so \ jump to gseg3 as (L K) is not a new minimum verge \ distance \ We now compare the high bytes LDA edgeDistanceLo \ If edgeDistanceLo < K, then we know that CMP K \ (L K) > (edgeDistanceHi edgeDistanceLo), so jump to BCC gseg3 \ gseg3 as (L K) is not a new minimum verge distance .gseg2 \ If we get here then we know that \ (L K) <= (edgeDistanceHi edgeDistanceLo), so we now \ set (L K) as the new minimum distance to the verge, \ and set a number of variables so we can refer to this \ nearest track edge in places like the crash routine LDA L \ Set (edgeDistanceHi edgeDistanceLo) = (L K) STA edgeDistanceHi LDA K STA edgeDistanceLo LDA segmentCounter \ Set edgeSegmentNumber = segmentCounter STA edgeSegmentNumber \ \ So edgeSegmentNumber contains the number of the \ segment within the track segment list that is closest \ to the player's car LDY segmentListPointer \ Set edgeSegmentPointer = segmentListPointer STY edgeSegmentPointer \ \ So edgeSegmentPointer contains the index of the \ segment within the track verge buffer (i.e. from \ xVergeRight) that is closest to the player's car LDA xVergeRightHi,Y \ Set edgeYawAngle = the segment's entry in STA edgeYawAngle \ xVergeRightHi \ \ So edgeYawAngle contains the yaw angle of the segment \ that is closest to the player's car, from the point of \ view of the car .gseg3 JSR GetObjPitchAngle-2 \ Calculate the segment's pitch angle, from the \ point of view of the player, returning it in A and LL \ \ If the segment is not visible on-screen, the C flag is \ set, otherwise it will be clear BCS gseg4 \ If the segment is not visible on-screen, jump to gseg4 BPL gseg10 \ If the pitch angle is positive, jump to gseg10