Elite on the BBC Micro and NES

# Version analysis of PROJ

This code appears in the following versions (click to see it in the source code):

Code variations between these versions are shown below.

```       Name: PROJ
Type: Subroutine
Category: Maths (Geometry)
Summary: Project the current ship or planet onto the screen
Deep dive: Extended screen coordinates

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

```

Code variation 1 of 3A variation in the comments only

Tap on a block to expand it, and tap it again to revert.

```Cassette, Flight, 6502SP, MasterElectron This is to cater for ships (and, more likely, planets and suns) whose centres
are off-screen but whose edges may still be visible.
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

```

Code variation 2 of 3A variation in the comments only

This variation is blank in the Cassette, Disc (flight), 6502 Second Processor and Master versions.

```Electron 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

```

Code variation 3 of 3A variation in the labels only

This variation is blank in the Cassette, Disc (flight), 6502 Second Processor and Master versions.

```Electron.RTS2
```
``` RTS                    \ Return from the subroutine

```