Skip to navigation

Elite on the BBC Micro and NES

Maths (Geometry): PROJ

[Acorn Electron version]

Name: PROJ [Show more] Type: Subroutine Category: Maths (Geometry) Summary: Project the current ship or planet onto the screen Deep dive: Extended screen coordinates
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: * PLANET calls PROJ * SHPPT calls PROJ * CIRCLE calls via RTS2

Project the current ship's location or the planet onto the screen, either returning the screen coordinates of the projection (if it's on-screen), or returning an error via the C flag. In this context, "on-screen" means that the point is projected into the following range: centre of screen - 1024 < x < centre of screen + 1024 centre of screen - 1024 < y < centre of screen + 1024 This is to cater for ships (and, more likely, planets) whose centres are off-screen but whose edges may still be visible. The projection calculation is: K3(1 0) = #X + x / z K4(1 0) = #Y + y / z where #X and #Y are the pixel x-coordinate and y-coordinate of the centre of the screen.
Arguments: INWK The ship data block for the ship to project on-screen
Returns: K3(1 0) The x-coordinate of the ship's projection on-screen K4(1 0) The y-coordinate of the ship's projection on-screen C flag Set if the ship's projection doesn't fit on the screen, clear if it does project onto the screen A Contains K4+1, the high byte of the y-coordinate
Other entry points: RTS2 Contains an RTS
.PROJ LDA INWK \ Set P(1 0) = (x_hi x_lo) STA P \ = x LDA INWK+1 STA P+1 LDA INWK+2 \ Set A = x_sign JSR PLS6 \ Call PLS6 to calculate: \ \ (X K) = (A P) / (z_sign z_hi z_lo) \ = (x_sign x_hi x_lo) / (z_sign z_hi z_lo) \ = x / z BCS PL2-1 \ If the C flag is set then the result overflowed and \ the coordinate doesn't fit on the screen, so return \ from the subroutine with the C flag set (as PL2-1 \ contains an RTS) LDA K \ Set K3(1 0) = (X K) + #X ADC #X \ = #X + x / z STA K3 \ \ first doing the low bytes TXA \ And then the high bytes. #X is the x-coordinate of ADC #0 \ the centre of the space view, so this converts the STA K3+1 \ space x-coordinate into a screen x-coordinate LDA INWK+3 \ Set P(1 0) = (y_hi y_lo) STA P LDA INWK+4 STA P+1 LDA INWK+5 \ Set A = -y_sign EOR #%10000000 JSR PLS6 \ Call PLS6 to calculate: \ \ (X K) = (A P) / (z_sign z_hi z_lo) \ = -(y_sign y_hi y_lo) / (z_sign z_hi z_lo) \ = -y / z BCS PL2-1 \ If the C flag is set then the result overflowed and \ the coordinate doesn't fit on the screen, so return \ from the subroutine with the C flag set (as PL2-1 \ contains an RTS) LDA K \ Set K4(1 0) = (X K) + #Y ADC #Y \ = #Y - y / z STA K4 \ \ first doing the low bytes TXA \ And then the high bytes. #Y is the y-coordinate of ADC #0 \ the centre of the space view, so this converts the STA K4+1 \ space x-coordinate into a screen y-coordinate CLC \ Clear the C flag to indicate success .RTS2 RTS \ Return from the subroutine