Skip to navigation

Flight: WARP, Removed

[Elite Demonstration Disc]

Name: WARP, Removed [Show more] Type: Subroutine Category: Flight Summary: Perform an in-system jump Deep dive: A sense of scale
Context: See this subroutine in context in the source code References: No direct references to this subroutine in this source file

This is called when we press "J" during flight. The following checks are performed: * Make sure we don't have any ships or space stations in the vicinity * Make sure we are not in witchspace * If we are facing the planet, make sure we aren't too close * If we are facing the sun, make sure we aren't too close If the above checks are passed, then we perform an in-system jump by moving the sun and planet in the opposite direction to travel, so we appear to jump in space. This means that any asteroids, cargo canisters or escape pods get dragged along for the ride.
\ --- Mod: Code removed for Demonstration Disc: -------> \.WARP \ \IF _SOURCE_DISC \ \LDA MANY+AST \ Set X to the total number of asteroids, escape pods \CLC \ and cargo canisters in the vicinity \ADC MANY+ESC \CLC \ The second CLC instruction has no effect, as there is \ADC MANY+OIL \ no way that adding the number of asteroids and the \TAX \ number escape pods will cause a carry \ \ELIF _TEXT_SOURCES OR _STH_CASSETTE \ \LDA MANY+AST \ Set X to the total number of asteroids, escape pods \CLC \ and cargo canisters in the vicinity \ADC MANY+ESC \ \ADC MANY+OIL \ This code saves one byte of memory over the code in \TAX \ the source disc version. The second CLC is not needed \ \ as there is no way that adding the number of asteroids \ \ and the number of escape pods will cause a carry \ \ENDIF \ \LDA FRIN+2,X \ If the slot at FRIN+2+X is non-zero, then we have \ \ something else in the vicinity besides asteroids, \ \ escape pods and cargo canisters, so to check whether \ \ we can jump, we first grab the slot contents into A \ \ORA SSPR \ If there is a space station nearby, then SSPR will \ \ be non-zero, so OR'ing with SSPR will produce a \ \ non-zero result if either A or SSPR are non-zero \ \ORA MJ \ If we are in witchspace, then MJ will be non-zero, so \ \ OR'ing with MJ will produce a non-zero result if \ \ either A or SSPR or MJ are non-zero \ \BNE WA1 \ A is non-zero if we have either a ship or a space \ \ station in the vicinity, or we are in witchspace, in \ \ which case jump to WA1 to make a low beep to show that \ \ we can't do an in-system jump \ \LDY K%+8 \ Otherwise we can do an in-system jump, so now we fetch \ \ the byte at K%+8, which contains the z_sign for the \ \ first ship slot, i.e. the distance of the planet \ \BMI WA3 \ If the planet's z_sign is negative, then the planet \ \ is behind us, so jump to WA3 to skip the following \ \TAY \ Set A = Y = 0 (as we didn't BNE above) so the call \ \ to MAS2 measures the distance to the planet \ \JSR MAS2 \ Call MAS2 to set A to the largest distance to the \ \ planet in any of the three axes (we could also call \ \ routine m to do the same thing, as A = 0) \ \IF _SOURCE_DISC \ \CMP #2 \ If A < 2 then jump to WA1 to abort the in-system jump \BCC WA1 \ with a low beep, as we are facing the planet and are \ \ too close to jump in that direction \ \ELIF _TEXT_SOURCES OR _STH_CASSETTE \ \LSR A \ If A < 2 then jump to WA1 to abort the in-system jump \BEQ WA1 \ with a low beep, as we are facing the planet and are \ \ too close to jump in that direction \ \ \ \ These instructions between them save one byte of \ \ memory over the CMP-based code in the source disc \ \ version, as LSR A is a one-byte opcode, while CMP #2 \ \ takes up two bytes (though the code does exactly the \ \ same thing) \ \ENDIF \ \.WA3 \ \LDY K%+NI%+8 \ Fetch the z_sign (byte #8) of the second ship in the \ \ ship data workspace at K%, which is reserved for the \ \ sun or the space station (in this case it's the \ \ former, as we already confirmed there isn't a space \ \ station in the vicinity) \ \BMI WA2 \ If the sun's z_sign is negative, then the sun is \ \ behind us, so jump to WA2 to skip the following \ \LDY #NI% \ Set Y to point to the offset of the ship data block \ \ for the sun, which is NI% (as each block is NI% bytes \ \ long, and the sun is the second block) \ \JSR m \ Call m to set A to the largest distance to the sun \ \ in any of the three axes \ \IF _SOURCE_DISC \ \CMP #2 \ If A < 2 then jump to WA1 to abort the in-system jump \BCC WA1 \ with a low beep, as we are facing the planet and are \ \ too close to jump in that direction \ \ELIF _TEXT_SOURCES OR _STH_CASSETTE \ \LSR A \ If A < 2 then jump to WA1 to abort the in-system jump \BEQ WA1 \ with a low beep, as we are facing the planet and are \ \ too close to jump in that direction \ \ \ \ These instructions between them save one byte of \ \ memory over the CMP-based code in the source disc \ \ version, as LSR A is a one-byte opcode, while CMP #2 \ \ takes up two bytes (though the code does exactly the \ \ same thing) \ \ENDIF \ \.WA2 \ \ \ If we get here, then we can do an in-system jump, as \ \ we don't have any ships or space stations in the \ \ vicinity, we are not in witchspace, and if we are \ \ facing the planet or the sun, we aren't too close to \ \ jump towards it \ \ \ \ We do an in-system jump by moving the sun and planet, \ \ rather than moving our own local bubble (this is why \ \ in-system jumps drag asteroids, cargo canisters and \ \ escape pods along for the ride). Specifically, we move \ \ them in the z-axis by a fixed amount in the opposite \ \ direction to travel, thus performing a jump towards \ \ our destination \ \LDA #&81 \ Set R = R = P = &81 \STA S \STA R \STA P \ \LDA K%+8 \ Set A = z_sign for the planet \ \JSR ADD \ Set (A X) = (A P) + (S R) \ \ = (z_sign &81) + &8181 \ \ = (z_sign &81) - &0181 \ \ \ \ This moves the planet against the direction of travel \ \ by reducing z_sign by 1, as the above maths is: \ \ \ \ z_sign 00000000 \ \ + 00000000 10000001 \ \ - 00000001 10000001 \ \ \ \ or: \ \ \ \ z_sign 00000000 \ \ + 00000000 00000000 \ \ - 00000001 00000000 \ \ \ \ i.e. the high byte is z_sign - 1, making sure the sign \ \ is preserved \ \STA K%+8 \ Set the planet's z_sign to the high byte of the result \ \LDA K%+NI%+8 \ Set A = z_sign for the sun \ \JSR ADD \ Set (A X) = (A P) + (S R) \ \ = (z_sign &81) + &8181 \ \ = (z_sign &81) - &0181 \ \ \ \ which moves the sun against the direction of travel \ \ by reducing z_sign by 1 \ \STA K%+NI%+8 \ Set the planet's z_sign to the high byte of the result \ \LDA #1 \ Temporarily set the view type to a non-zero value, so \STA QQ11 \ the call to LOOK1 below clears the screen before \ \ switching to the space view \ \STA MCNT \ Set the main loop counter to 1, so the next iteration \ \ through the main loop will potentially spawn ships \ \ (see part 2 of the main game loop at me3) \ \LSR A \ Set EV, the extra vessels spawning counter, to 0 \STA EV \ (the LSR produces a 0 as A was previously 1) \ \LDX VIEW \ Set X to the current view (front, rear, left or right) \JMP LOOK1 \ and jump to LOOK1 to initialise that view, returning \ \ from the subroutine using a tail call \ \.WA1 \ \LDA #40 \ If we get here then we can't do an in-system jump, so \JMP NOISE \ call the NOISE routine with A = 40 to make a long, low \ \ beep and return from the subroutine using a tail call \ --- End of removed code ----------------------------->