Skip to navigation

Revs on the BBC Micro

3D objects: MoveObjectForward

Name: MoveObjectForward [Show more] Type: Subroutine Category: 3D objects Summary: Move a specified object forwards along the track by one segment
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * GetTrackSegment (Part 1 of 3) calls MoveObjectForward * MoveCars (Part 1 of 2) calls MoveObjectForward * MovePlayer calls MoveObjectForward * PlaceCarsOnTrack calls MoveObjectForward

Moves object X forwards by one segment, updating the section number if we cross into a new section. Also updates the lap number and lap time, but only if this is a driver and bit 7 of updateLapTimes is clear.
Arguments: X Driver number (0-23) updateLapTimes If bit 7 is set, the call to UpdateLaps has no effect, so we do not update the lap number or lap time
Returns: C flag Whether the driver has moved into a new section: * Clear if the driver is still within the same track section as before * Set if the driver has now moved into the next track section
.MoveObjectForward LDY objTrackSection,X \ Set Y to the track section number * 8 for object X LDA objSectionSegmt,X \ Set A = objSectionSegmt + 1 CLC \ ADC #1 \ This increments the section segment counter, which \ keeps track of the object's segment number in the \ current track section, so it moves forward one segment CMP trackSectionSize,Y \ If A < Y-th trackSectionSize, then the object is still PHP \ within the current track section, so clear the C flag \ and store it on the stack, otherwise the object has \ now reached the end of the current section, so set the \ C flag and store it on the stack BCC fore2 \ If A < Y-th trackSectionSize, then the object is still \ within the current track section, so jump to fore2 to \ update the track section counter with the new value TYA \ Set A = Y + 8 CLC \ ADC #8 \ So A contains the track section number * 8 of the next \ track section CMP trackSectionCount \ If A < trackSectionCount then this isn't the last BCC fore1 \ section before we wrap round to zero again, so jump to \ fore1 to skip the following instruction LDA #0 \ Set A = 0, so the track section number wraps round to \ zero when we reach the last section .fore1 STA objTrackSection,X \ Update the object's track section number to the new \ one that they just moved into LDA #0 \ The object just entered a new track section, so we \ need to zero the section counter, which keeps track of \ how far through the current section the object is, so \ set A to 0 to set as its new value below .fore2 STA objSectionSegmt,X \ Set the track section counter to the new value \ We now need to increment the object's segment number \ in (objectSegmentHi objectSegmentLo) INC objectSegmentLo,X \ Increment (objectSegmentHi objectSegmentLo) for object \ X, starting with the low byte BNE fore3 \ And then the high byte, if the low byte overflows INC objectSegmentHi,X .fore3 LDA objectSegmentLo,X \ If objectSegment <> trackLength, then the object has CMP trackLength \ not yet reached the end of the track, so jump to fore4 BNE fore4 \ to return from the subroutine as we are done LDA objectSegmentHi,X CMP trackLength+1 BNE fore4 LDA #0 \ The object has just reached the end of the track, so STA objectSegmentLo,X \ set (objectSegmentHi objectSegmentLo) = 0 to wrap STA objectSegmentHi,X \ round to the start again JSR UpdateLaps \ Increment the lap number and lap times for object X, \ for when this object is a car .fore4 PLP \ Retrieve the C flag from the stack so we can return it \ from the subroutine, so it is clear if the driver is \ still within the same track section, set otherwise RTS \ Return from the subroutine