Skip to navigation


Tactics: GetSegmentSteering

Name: GetSegmentSteering [Show more] Type: Subroutine Category: Tactics Summary: Calculate the optimum steering to take for the current track segment Deep dive: Tactics of the non-player drivers
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * GetTrackSegment (Part 3 of 3) calls GetSegmentSteering

This routine populates segmentSteering for a track segment, depending on a large number of factors.
.GetSegmentSteering LDY objTrackSection+23 \ Set Y to the number * 8 of the track section for the \ front segment of the track segment buffer TYA \ Set X = Y / 8 LSR A \ LSR A \ So X contains the number of the track section for the LSR A \ front segment TAX LDA turnCounter \ If turnCounter is non-zero, then a turn is already in BNE rlin5 \ progress, so jump to rlin5 \ We get here if turnCounter is zero LDA thisSectionFlags \ If bit 0 of thisSectionFlags is set then this is a LSR A \ curved track section, so jump to rlin2 BCS rlin2 LDA objSectionSegmt+23 \ If the front segment's number within the track section CMP trackSectionTurn,Y \ is >= the trackSectionTurn for the section, jump to BCS rlin3 \ rlin3 to move on to the next track section \ If we get here, then: \ \ * turnCounter is zero \ \ * Bit 0 of thisSectionFlags is clear, so this is a \ straight track section \ \ * The front segment's number within the track \ section is less than the trackSectionTurn value \ for the section \ \ So we are not already turning from a previous call, we \ are on a straight, and we haven't yet reached the \ point at the end of the straight where we should be \ turning \ \ So now we keep on driving straight .rlin1 LDA sectionSteering,X \ Set A to the optimum steering for section X, with ORA #%01000000 \ bit 6 set, so we do not apply any steering in MoveCars \ but instead just apply acceleration or braking BNE rlin7 \ Jump to rlin7 to store A in segmentSteering for this \ section and return from the subroutine (this BNE is \ effectively a JMP as A is never zero) .rlin2 \ If we get here then this is a curved track section and \ turnCounter is zero LDA prevDriverSpeed7 \ If bit 7 of prevDriverSpeed7 is set, jump to rlin4 BMI rlin4 \ If we get here then this is a curved track section and \ turnCounter is zero, and bit 7 of prevDriverSpeed7 is \ clear .rlin3 \ If we jump here, then the front segment is past the \ trackSectionTurn point in this section, so we start \ looking at the next section for the optimum steering TYA \ Set Y = Y + 8 CLC \ ADC #8 \ So Y contains the number * 8 of the next track section TAY INX \ Increment X, so X contains the number of the next \ track section .rlin4 LDA trackSectionFlag,Y \ If bit 0 of the track section's flag byte is clear, AND #1 \ then this is a straight section, so jump to rlin1 to BEQ rlin1 \ disable steering in MoveCars and keep on driving \ straight LDA trackSectionTurn,Y \ Set turnCounter = track section's trackSectionTurn STA turnCounter BEQ rlin1 \ If the track section's trackSectionTurn is zero, jump \ to rlin1 to disable steering in MoveCars and keep on \ driving straight LDA trackDriverSpeed,Y \ Set prevDriverSpeed7 = track section's driver speed, STA prevDriverSpeed7 \ which we only use to check bit 7 AND #%01111111 \ Set prevDriverSpeed06 = bits 0-6 of the track STA prevDriverSpeed06 \ section's driver speed LDA sectionSteering,X \ Set A to the optimum steering for the track section STA previousSteering \ Set previousSteering to the optimum steering for the \ track section JMP rlin7 \ Jump to rlin7 to store A in segmentSteering for this \ section and return from the subroutine (this BNE is \ effectively a JMP as A is never zero) .rlin5 \ If we get here then turnCounter is non-zero, so a \ turn is already in progress DEC turnCounter \ Decrement the turn counter in turnCounter LDA turnCounter \ Set T = turnCounter / 8 LSR A LSR A LSR A STA T LDA turnCounter \ Set A = turnCounter - prevDriverSpeed06 SEC SBC prevDriverSpeed06 BCS rlin6 \ If the subtraction didn't underflow, i.e. \ \ turnCounter >= prevDriverSpeed06 \ \ then jump to rlin6 to set segmentSteering to \ previousSteering and return from the subroutine \ If we get here then turnCounter < prevDriverSpeed06 \ and A is negative ADC T \ Set A = A + T \ = turnCounter - prevDriverSpeed06 \ + turnCounter / 8 \ = (turnCounter * 1.125) - prevDriverSpeed06 LDA #0 \ Set A = 0 BCS rlin7 \ If the addition overflowed, then because A was \ negative, we must have the following: \ \ (turnCounter * 1.125) - prevDriverSpeed06 >= 0 \ \ So jump to rlin7 to store 0 in segmentSteering for \ this section and return from the subroutine \ \ Otherwise store previousSteering in segmentSteering \ for this section with bit 7 flipped, and return from \ the subroutine .rlin6 LDA previousSteering \ Set A = previousSteering BCS rlin7 \ If the C flag is clear, flip bit 7 of A EOR #%10000000 .rlin7 LDY frontSegmentIndex \ Set segmentSteering for the front segment in the track STA segmentSteering,Y \ segment buffer to A RTS \ Return from the subroutine