Skip to navigation

Elite on the BBC Micro and NES

Flight: DOCKIT

[BBC Master version]

Name: DOCKIT [Show more] Type: Subroutine Category: Flight Summary: Apply docking manoeuvres to the ship in INWK Deep dive: The docking computer
Context: See this subroutine in context in the source code Variations: See code variations for this subroutine in the different versions References: This subroutine is called as follows: * DOKEY calls DOCKIT * TACTICS (Part 3 of 7) calls DOCKIT
.DOCKIT LDA #6 \ Set RAT2 = 6, which is the threshold below which we STA RAT2 \ don't apply pitch and roll to the ship (so a lower \ value means we apply pitch and roll more often, and a \ value of 0 means we always apply them). The value is \ compared with double the high byte of sidev . XX15, \ where XX15 is the vector from the ship to the station LSR A \ Set RAT = 2, which is the magnitude we set the pitch STA RAT \ or roll counter to in part 7 when turning a ship \ towards a vector (a higher value giving a longer \ turn) LDA #29 \ Set CNT2 = 29, which is the maximum angle beyond which STA CNT2 \ a ship will slow down to start turning towards its \ prey (a lower value means a ship will start to slow \ down even if its angle with the enemy ship is large, \ which gives a tighter turn) LDA SSPR \ If we are inside the space station safe zone, skip the BNE P%+5 \ next instruction .GOPLS JMP GOPL \ Jump to GOPL to make the ship head towards the planet JSR VCSU1 \ If we get here then we are in the space station safe \ zone, so call VCSU1 to calculate the following, where \ the station is at coordinates (station_x, station_y, \ station_z): \ \ K3(2 1 0) = (x_sign x_hi x_lo) - station_x \ \ K3(5 4 3) = (y_sign y_hi z_lo) - station_y \ \ K3(8 7 6) = (z_sign z_hi z_lo) - station_z \ \ so K3 contains the vector from the station to the ship LDA K3+2 \ If any of the top bytes of the K3 results above are ORA K3+5 \ non-zero (after removing the sign bits), jump to GOPL ORA K3+8 \ via GOPLS to make the ship head towards the planet, as AND #%01111111 \ this will aim the ship in the general direction of the BNE GOPLS \ station (it's too far away for anything more accurate) JSR TA2 \ Call TA2 to calculate the length of the vector in K3 \ (ignoring the low coordinates), returning it in Q LDA Q \ Store the value of Q in K, so K now contains the STA K \ distance between station and the ship JSR TAS2 \ Call TAS2 to normalise the vector in K3, returning the \ normalised version in XX15, so XX15 contains the unit \ vector pointing from the station to the ship LDY #10 \ Call TAS4 to calculate: JSR TAS4 \ \ (A X) = nosev . XX15 \ \ where nosev is the nose vector of the space station, \ so this is the dot product of the station to ship \ vector with the station's nosev (which points straight \ out into space, out of the docking slot), and because \ both vectors are unit vectors, the following is also \ true: \ \ (A X) = cos(t) \ \ where t is the angle between the two vectors \ \ If the dot product is positive, that means the vector \ from the station to the ship and the nosev sticking \ out of the docking slot are facing in a broadly \ similar direction (so the ship is essentially heading \ for the slot, which is facing towards the ship), and \ if it's negative they are facing in broadly opposite \ directions (so the station slot is on the opposite \ side of the station as the ship approaches) BMI PH1 \ If the dot product is negative, i.e. the station slot \ is on the opposite side, jump to PH1 to fly towards \ the ideal docking position, some way in front of the \ slot CMP #35 \ If the dot product < 35, jump to PH1 to fly towards BCC PH1 \ the ideal docking position, some way in front of the \ slot, as there is a large angle between the vector \ from the station to the ship and the station's nosev, \ so the angle of approach is not very optimal \ \ Specifically, as the unit vector length is 96 in our \ vector system, \ \ (A X) = cos(t) < 35 / 96 \ \ so: \ \ t > arccos(35 / 96) = 68.6 degrees \ \ so the ship is coming in from the side of the station \ at an angle between 68.6 and 90 degrees off the \ optimal entry angle \ If we get here, the slot is on the same side as the \ ship and the angle of approach is less than 68.6 \ degrees, so we're heading in pretty much the correct \ direction for a good approach to the docking slot LDY #10 \ Call TAS3 to calculate: JSR TAS3 \ \ (A X) = nosev . XX15 \ \ where nosev is the nose vector of the ship, so this is \ the dot product of the station to ship vector with the \ ship's nosev, and is a measure of how close to the \ station the ship is pointing, with negative meaning it \ is pointing at the station, and positive meaning it is \ pointing away from the station CMP #&A2 \ If the dot product is in the range 0 to -34, jump to BCS PH3 \ PH3 to refine our approach, as we are pointing towards \ the station \ If we get here, then we are not pointing straight at \ the station, so check how close we are LDA K \ Fetch the distance to the station into A \BEQ PH10 \ This instruction is commented out in the original \ source CMP #157 \ If A < 157, jump to PH2 to turn away from the station, BCC PH2 \ as we are too close LDA TYPE \ Fetch the ship type into A BMI PH3 \ If bit 7 is set, then that means the ship type was set \ to -96 in the DOKEY routine when we switched on our \ docking computer, so this is us auto-docking our \ Cobra, so jump to PH3 to refine our approach \ \ Otherwise this is an NPC trying to dock, so keep going \ to turn away from the station .PH2 \ If we get here then we turn away from the station and \ slow right down, effectively aborting this approach \ attempt JSR TAS6 \ Call TAS6 to negate the vector in XX15 so it points in \ the opposite direction, away from the station and \ towards the ship JSR TA151 \ Call TA151 to make the ship head in the direction of \ XX15, which makes the ship turn away from the station .PH22 \ If we get here then we slam on the brakes and slow \ right down LDX #0 \ Set the acceleration in byte #28 to 0 STX INWK+28 INX \ Set the speed in byte #28 to 1 STX INWK+27 RTS \ Return from the subroutine .PH1 \ If we get here then the slot is on the opposite side \ of the station to the ship, or it's on the same side \ and the approach angle is not optimal, so we just fly \ towards the station, aiming for the ideal docking \ position some distance in front of the slot JSR VCSU1 \ Call VCSU1 to set K3 to the vector from the station to \ the ship JSR DCS1 \ Call DCS1 twice to calculate the vector from the ideal JSR DCS1 \ docking position to the ship, where the ideal docking \ position is straight out of the docking slot at a \ distance of 8 unit vectors from the centre of the \ station JSR TAS2 \ Call TAS2 to normalise the vector in K3, returning the \ normalised version in XX15 JSR TAS6 \ Call TAS6 to negate the vector in XX15 so it points in \ the opposite direction JMP TA151 \ Call TA151 to make the ship head in the direction of \ XX15, which makes the ship turn towards the ideal \ docking position, and return from the subroutine using \ a tail call .TN11 \ If we get here, we accelerate and apply a full \ clockwise roll (which matches the space station's \ roll) INC INWK+28 \ Increment the acceleration in byte #28 LDA #%01111111 \ Set the roll counter to a positive (clockwise) roll STA INWK+29 \ with no damping, to match the space station's roll BNE TN13 \ Jump down to TN13 (this BNE is effectively a JMP as \ A will never be zero) .PH3 \ If we get here, we refine our approach using pitch and \ roll to aim for the station LDX #0 \ Set RAT2 = 0 STX RAT2 STX INWK+30 \ Set the pitch counter to 0 to stop any pitching LDA TYPE \ If this is not our ship's docking computer, but is an BPL PH32 \ NPC ship trying to dock, jump to PH32 \ In the following, ship_x and ship_y are the x and \ y-coordinates of XX15, the vector from the station to \ the ship EOR XX15 \ A is negative, so this sets the sign of A to the same EOR XX15+1 \ as -XX15 * XX15+1, or -ship_x * ship_y ASL A \ Shift the sign bit into the C flag, so the C flag has \ the following sign: \ \ * Positive if ship_x and ship_y have different signs \ * Negative if ship_x and ship_y have the same sign LDA #2 \ Set A = +2 or -2, giving it the sign in the C flag, ROR A \ and store it in byte #29, the roll counter, so that STA INWK+29 \ the ship rolls towards the station LDA XX15 \ If |ship_x * 2| >= 12, i.e. |ship_x| >= 6, then jump ASL A \ to PH22 to slow right down and return from the CMP #12 \ subroutine, as the station is not in our sights BCS PH22 LDA XX15+1 \ Set A = +2 or -2, giving it the same sign as ship_y, ASL A \ and store it in byte #30, the pitch counter, so that LDA #2 \ the ship pitches towards the station ROR A STA INWK+30 LDA XX15+1 \ If |ship_y * 2| >= 12, i.e. |ship_y| >= 6, then jump ASL A \ to PH22 to slow right down and return from the CMP #12 \ subroutine, as the station is not in our sights BCS PH22 .PH32 \ If we get here, we try to match the station roll STX INWK+29 \ Set the roll counter to 0 to stop any pitching LDA INWK+22 \ Set XX15 = sidev_x_hi STA XX15 LDA INWK+24 \ Set XX15+1 = sidev_y_hi STA XX15+1 LDA INWK+26 \ Set XX15+2 = sidev_z_hi STA XX15+2 \ \ so XX15 contains the sidev vector of the ship LDY #16 \ Call TAS4 to calculate: JSR TAS4 \ \ (A X) = roofv . XX15 \ \ where roofv is the roof vector of the space station. \ To dock with the slot horizontal, we want roofv to be \ pointing off to the side, i.e. parallel to the ship's \ sidev vector, which means we want the dot product to \ be large (it can be positive or negative, as roofv can \ point left or right - it just needs to be parallel to \ the ship's sidev) ASL A \ If |A * 2| >= 66, i.e. |A| >= 33, then the ship is CMP #66 \ lined up with the slot, so jump to TN11 to accelerate BCS TN11 \ and roll clockwise (a positive roll) before jumping \ down to TN13 to check if we're docked yet JSR PH22 \ Call PH22 to slow right down, as we haven't yet \ matched the station's roll .TN13 \ If we get here, we check to see if we have docked LDA K3+10 \ If K3+10 is non-zero, skip to TNRTS, to return from BNE TNRTS \ the subroutine \ \ I have to say I have no idea what K3+10 contains, as \ it isn't mentioned anywhere in the whole codebase \ apart from here, but it does share a location with \ XX2+10, so it will sometimes be non-zero (specifically \ when face #10 in the ship we're drawing is visible, \ which probably happens quite a lot). This would seem \ to affect whether an NPC ship can dock, as that's the \ code that gets skipped if K3+10 is non-zero, but as \ to what this means... that's not yet clear ASL NEWB \ Set bit 7 of the ship's NEWB flags to indicate that SEC \ the ship has now docked, which only has meaning if ROR NEWB \ this is an NPC trying to dock .TNRTS RTS \ Return from the subroutine