Skip to navigation


Track geometry: GetSegmentAngles (Part 3 of 3)

Name: GetSegmentAngles (Part 3 of 3) [Show more] Type: Subroutine Category: Track geometry Summary: Process a visible segment 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
.gseg10 \ If we get here then the segment's pitch angle is \ positive and the segment is visible on-screen JSR GetVergeAndMarkers \ Get the details for this segment's corner markers and \ verge marks LDA segmentCounter \ If segmentCounter <= edgeSegmentNumber, jump to gseg13 CMP edgeSegmentNumber \ to keep checking segments, as we haven't yet gone past BEQ gseg13 \ the closest segment to the player BCC gseg13 \ If we get here then we have gone past the closest \ segment to the player, so we need to check whether the \ segment is within the 20-degree field of view, and \ stop when the segments become hidden from view LDY segmentListPointer \ Set Y to the segment list pointer LDA xVergeRightHi,Y \ Set A to the high byte of the yaw angle of the \ segment's right verge BPL gseg11 \ If the angle is negative, negate it, so we now have EOR #&FF \ A = |yaw angle| .gseg11 CMP #20 \ If A < 20, then the segment is within the 20-degree BCC gseg13 \ field of view, so jump to gseg13 to keep checking \ segments LDA xVergeRightHi-1,Y \ Set A to the high byte of the yaw angle of the \ previous segment's right verge BPL gseg12 \ If the angle is negative, negate it, so we now have EOR #&FF \ A = |yaw angle| .gseg12 CMP #20 \ If A >= 20, then the previous segment was also outside BCS gseg16 \ the 20-degree field of view, so jump to gseg16 to \ return from the subroutine JMP gseg4 \ If we get here then the current segment is outside the \ 20-degree field of view, but the previous one wasn't, \ so we jump to gseg4 to try processing a segment that's \ one-quarter of the size, in case that fits .gseg13 \ If we get here then we have successfully processed a \ visible segment STX prevSegmentOffset \ Store the offset from xSegmentCoordILo of this \ segment's 3D coordinates in prevSegmentOffset, to use \ in the next iteration if the next segment is not \ visible INC segmentListPointer \ Increment the segment list pointer to point to the \ next entry in the list INC segmentCounter \ Increment the segment counter to indicate that we have \ populated a visible segment (so this will become 1 if \ this is the first visible segment we have processed, \ 2 for the second visible segment, and so on) LDY segmentCounter \ Set Y to the number of visible segments we have \ populated so far CPY #18 \ If Y >= 18, i.e. Y > 17, then Y was > 16 before we BCS gseg16 \ incremented it, which means we have filled the track \ segment list with 16 visible segments, so we jump to \ gseg16 to return from the subroutine to stop \ processing segments LDA segmentStep,Y \ Set T to the segment step for segment number Y, so to STA T \ get the next segment, we step back T steps in the \ track segment buffer \ \ This makes us step a long way backwards for the first \ few segments, and then make shorter steps as we get \ closer to the player TXA \ Set A to the segment offset that's in X SEC \ Set A = A - segmentOffset SBC segmentOffset \ \ so A contains the number of the segment * 3 (as X \ contains the offset from xSegmentCoordILo, which will \ be 120 + X for the X-th outer segment coordinate, so \ subtracting segmentOffset brings the offset down to \ the number * 3, whether this is an inner or outer \ coordinate) CMP T \ If A >= T, jump to gseg14 to jump back T segments BCS gseg14 \ towards the player, for the next iteration \ If we get here then A < T, so we can't jump back T \ segments or we will jump past the beginning of the \ track segment buffer, so we need to add 120 to wrap \ around to the end of the buffer before we can jump \ back T segments TXA \ Set A to the segment offset that's in X CLC \ Set A = A + 120 to wrap around to the end of the track ADC #120 \ segment buffer JMP gseg15 \ Jump to gseg15 .gseg14 TXA \ Set A to the segment offset that's in X .gseg15 SEC \ Set X = A - T SBC T \ TAX \ So the next segment to be tested is T steps backwards \ in the track segment buffer, towards the player (so \ if T = 3, we step back one segment, or if T = 13 * 3, \ we step back 13 segments) JMP gseg1 \ Loop back to gseg1 to move on to the next segment .gseg16 RTS \ Return from the subroutine