Skip to navigation

Elite on the BBC Micro and NES

Drawing ships: SHPPT

[NES version, Bank 1]

Name: SHPPT [Show more] Type: Subroutine Category: Drawing ships Summary: Draw a distant ship as a point rather than a full wireframe
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * LL9 (Part 2 of 12) calls SHPPT
.SHPPT JSR PROJ ; Project the ship onto the screen, returning: ; ; * K3(1 0) = the screen x-coordinate ; * K4(1 0) = the screen y-coordinate ; * A = K4+1 ORA K3+1 ; If either of the high bytes of the screen coordinates BNE nono ; are non-zero, jump to nono as the ship is off-screen LDY K4 ; Set Y = the y-coordinate of the dot CPY #Y*2-2 ; If the y-coordinate is bigger than the y-coordinate of BCS nono ; the bottom of the screen, jump to nono as the ship's ; dot is off the bottom of the space view ; The C flag is clear at this point as we just passed ; through a BCS, so we call Shpt with the C flag clear JSR Shpt ; Call Shpt to draw a horizontal 4-pixel dash for the ; first row of the dot (i.e. a four-pixel dash) INY ; Increment Y to the next row (so this is the second row ; of the two-pixel-high dot) CLC ; Cleat the C flag to pass to Shpt JSR Shpt ; Call Shpt to draw a horizontal 4-pixel dash for the ; second row of the dot (i.e. a four-pixel dash) BIT XX1+31 ; If bit 6 of the ship's byte #31 is clear, then there BVC nono ; are no lasers firing, so jump to nono to record that ; we didn't draw anything and return from the subroutine LDA XX1+31 ; Clear 6 in the ship's byte #31 to denote that there AND #%10111111 ; are no lasers firing (bit 6), as we are about to draw STA XX1+31 ; the laser line and this will ensure it flickers off in ; the next iteration ; We now draw the laser line, from the ship dot at ; (X1, Y1), as set in the call to Shpt, to a point on ; the edge of the screen LDX #1 ; Set X = 1 to use as the x-coordinate for the end of ; the laser line for when z_lo < 128 (so the ship fires ; to our left) LDA XX1+6 ; Set A = z_lo BPL shpt1 ; If z_lo < 128, jump to shpt1 to leave X = 1 LDX #255 ; Set X = 255 to use as the x-coordinate for the end of ; the laser line for when z_lo >= 128 (so the ship fires ; to our left) ; ; This makes the ship fire to our left and right as it ; gets closer to us, as z_lo reduces from 255 to 0 for ; each reduction in z_hi .shpt1 STX X2 ; Set X2 to the x-coordinate of the end of the laser ; line AND #63 ; Set Y2 = z_lo, reduced to the range 0 to 63, plus 32 ADC #32 ; STA Y2 ; So the end of the laser line moves up and down the ; edge of the screen (between y-coordinate 32 and 95) as ; the ship gets closer to us, as z_lo reduces from 255 ; to 0 for each reduction in z_hi JSR LOIN ; Draw the laser line from (X1, Y1) to (X2, Y2) .nono LDA #%11110111 ; Clear bit 3 of the ship's byte #31 to record that AND XX1+31 ; nothing is being drawn on-screen for this ship STA XX1+31 RTS ; Return from the subroutine .Shpt ; This routine draws a horizontal 4-pixel dash, for ; either the top or the bottom of the ship's dot ; ; We always call this routine with the C flag clear LDA K3 ; Set A = screen x-coordinate of the ship dot STA X1 ; Set X1 to the screen x-coordinate of the ship dot ADC #3 ; Set A = screen x-coordinate of the ship dot + 3 ; (this works because we know the C flag is clear) BCS shpt2 ; If the addition overflowed, jump to shpt2 to return ; from the subroutine without drawing the dash STA X2 ; Store the x-coordinate of the ship dot in X1, as this ; is where the dash starts STY Y1 ; Store Y in both y-coordinates, as this is a horizontal STY Y2 ; dash at y-coordinate Y JMP LOIN ; Draw the dash from (X1, Y1) to (X2, Y2), returning ; from the subroutine using a tail call .shpt2 PLA ; Pull the return address from the stack, so the RTS PLA ; below actually returns from the subroutine that called ; LL9 (as we called SHPPT from LL9 with a JMP) JMP nono ; Jump to nono to record that we didn't draw anything ; and return from the subroutine