# Car geometry: MovePlayerSegment

```       Name: MovePlayerSegment                                       [Show more]
Type: Subroutine
Category: Car geometry
Summary: Move the player's car in the correct direction
Deep dive: Placing cars on the track
Context: See this subroutine in context in the source code
References: This subroutine is called as follows:
* MainDrivingLoop (Part 2 of 5) calls MovePlayerSegment

This routine checks whether the player has turned enough to be in a different
direction (i.e. pointing forwards to pointing backwards or vice versa), and if
so, it turns the player around by updating the track segment buffer for the
new direction, resetting the track section list, and updating all the
direction-related variables.

Otherwise it works out whether the player has moved into a new segment, and if
so, it updates the car's segment and section numbers accordingly.

.MovePlayerSegment

SEC                    \
SBC spinYawAngleTop    \ So A contains the new heading of the player's car,
\ once the current spin is added (i.e. it's the new

\ A is an angle that represents the new direction in
\ which our car will be facing, after applying spin,
\ with respect to the track, like this:
\
\            0
\      -32   |   +32         Overhead view of car
\         \  |  /
\          \ | /             0 = looking straight ahead
\           \|/              +64 = looking sharp right
\   -64 -----+----- +64      -64 = looking sharp left
\           /|\
\          / | \
\         /  |  \
\      -96   |   +96
\           128
\
\ An angle of 0 means our car is facing forwards along
\ the track, while an angle of +32 means we are facing
\ 45 degrees to the right of straight on, and an angle
\ of 128 means we are facing backwards along the track

BPL mpla1              \ If A is positive, jump to mpla1 to skip the following

EOR #&FF               \ Invert A, so this effectively reflects the angle into
\ the right half of the above diagram:
\
\            0
\            |   32
\            |  /
\            | /
\            |/
\            +----- 64
\            |\
\            | \
\            |  \
\            |   96
\           127

.mpla1

ASL A                  \ Set A = A << 1, so we now have:
\
\            0
\            |   64
\            |  /
\            | /
\            |/
\            +----- 128
\            |\
\            | \
\            |  \
\            |   192
\           254

CMP #128               \ Clear the C flag if A < 128 (i.e. top-right quadrant)
\ is set the C flag if A >= 128 (i.e. bottom-right

\ Note that bit 7 is similar, so we have:
\
\            0
\            |   64
\            |  /       <-- C flag and bit 7 clear
\            | /
\            |/
\            +----- 128
\            |\
\            | \
\            |  \       <-- C flag and bit 7 set
\            |   192
\           254

EOR directionFacing    \ If we are facing forwards, leave A alone, but if we
\ are currently facing backwards, flip bit 7 of A

BPL mpla3              \ If we are facing forwards and we are in the top-right
\ quadrant, or we are facing backwards and we are in the
\ bottom-right quadrant, then the direction we are
\ facing is still correct, so jump to mpla3 to get on
\ with moving the car
\
\ Otherwise we may now be facing in a different
\ direction to before, and bit 7 of A is set

BCC mpla2              \ If bit 7 of A was clear before the above EOR, then we
\ are in the top-right quadrant but are currently facing
\ instruction

EOR #%01111111         \ Bit 7 of A was set before the above EOR, so we are in
\ the bottom-right quadrant, but are currently facing
\ forwards, so flip bits 0-6 of A, changing the range of
\ the bottom-right quadrant from 128 to 254 to
\ 255 to 129

.mpla2

\ By this point, we are pointing in the opposite
\ direction to the setting of directionFacing, and the
\ angles are as follows:
\
\            0
\            |   64
\            |  /       <-- C flag and bit 7 clear
\            | /
\            |/_.- 127
\            +----- 255
\            |\-._ 252
\            | \
\            |  \       <-- C flag and bit 7 set
\            |   192
\           129
\
\ So 0 to 127 is in the top-right quadrant, while 255 to
\ 129 is the bottom-right quadrant

CMP #252               \ If A >= 252, then the new angle we are facing is in
BCS mpla3              \ the top sliver of the bottom-right quadrant, so jump
\ to mpla3 to get on with moving the car

\ If we get here then A < 252, which means we are either
\ now in the top-right quadrant, or we are in the bottom
\ part of the bottom-right quadrant, and we are facing
\ in a different direction to directionFacing
\
\ So we have now officially turned in the opposite
\ direction, and need to update all the various buffers
\ and variables

JSR ChangeDirection    \ Turn the player around by updating the track segment
\ buffer for the new direction, resetting the track
\ section list, and updating all the direction-related
\ variables

RTS                    \ Return from the subroutine

.mpla3

\ The GetSegmentAngles routine, which has already been
\ called by this point, sets up the track segment list
\ and sets edgeSegmentNumber to the entry number within
\ the track segment list that is closest to the player's
\ car
\
\ Entry 13 in the track segment list corresponds to the
\ segment that's 32 behind the front segment of the
\ track segment buffer, which is the position of the
\ player's car, so if edgeSegmentNumber does not equal
\ 13, then it means that the car has moved into a new
\ segment
\
\ Specifically, the values of edgeSegmentNumber mean
\ the following:
\
\   * 11 = player has moved forward two segments
\   * 12 = player has moved forward one segment
\   * 13 = player is still in the same segment
\   * 14 = player has moved back one segment
\   * 15 = player has moved back two segments
\
\ The player can't travel more than two segments in one
\ iteration of the main driving loop

LDA edgeSegmentNumber  \ If edgeSegmentNumber = 12, jump to mpla4 to move the
CMP #12                \ player forward by one segment
BEQ mpla4

BCS mpla5              \ If edgeSegmentNumber > 12, then the player is either
\ in the same segment, or has moved backwards, so jump
\ to mpla5

\ If we get here then edgeSegmentNumber < 12, so
\ edgeSegmentNumber must be 11, so we move the player
\ forwards by two segments

JSR MovePlayerForward  \ Move the player forwards by one segment

.mpla4

BIT playerPastSegment  \ If bit 0 of playerPastSegment is clear, then the
BPL mpla7              \ player has not yet gone past the closest segment, so
\ moving forward by this segment

JSR MovePlayerForward  \ Move the player forwards by one segment

RTS                    \ Return from the subroutine

.mpla5

\ If we get here then edgeSegmentNumber > 12

CMP #14                \ If edgeSegmentNumber < 14, i.e. edgeSegmentNumber is
BCC mpla7              \ 13, then the player has not changed segment, so jump
\ to mpla7 to return from the subroutine

BEQ mpla6              \ If edgeSegmentNumber = 14, jump to mpla6 to move the
\ player backwards by one segment

\ If we get here then edgeSegmentNumber > 14, so
\ edgeSegmentNumber must be 15, so we move the player
\ backward by two segments

JSR MovePlayerBack     \ Move the player backwards by one segment

.mpla6

JSR MovePlayerBack     \ Move the player backwards by one segment

.mpla7

RTS                    \ Return from the subroutine
```