Skip to navigation


Drawing ships: LL9 (Part 3 of 12)

[NES version, Bank 1]

Name: LL9 (Part 3 of 12) [Show more] Type: Subroutine Category: Drawing ships Summary: Draw ship: Set up orientation vector, ship coordinate variables Deep dive: Drawing ships
Context: See this subroutine in context in the source code References: No direct references to this subroutine in this source file

This part sets up the following variable blocks: * XX16 contains the orientation vectors, divided to normalise them * XX18 contains the ship's x, y and z coordinates in space
.LL17 LDX #5 ; First we copy the three orientation vectors into XX16, ; so set up a counter in X for the 6 bytes in each ; vector .LL15 LDA XX1+21,X ; Copy the X-th byte of sidev to the X-th byte of XX16 STA XX16,X LDA XX1+15,X ; Copy the X-th byte of roofv to XX16+6 to the X-th byte STA XX16+6,X ; of XX16+6 LDA XX1+9,X ; Copy the X-th byte of nosev to XX16+12 to the X-th STA XX16+12,X ; byte of XX16+12 DEX ; Decrement the counter BPL LL15 ; Loop back to copy the next byte of each vector, until ; we have the following: ; ; * XX16(1 0) = sidev_x ; * XX16(3 2) = sidev_y ; * XX16(5 4) = sidev_z ; ; * XX16(7 6) = roofv_x ; * XX16(9 8) = roofv_y ; * XX16(11 10) = roofv_z ; ; * XX16(13 12) = nosev_x ; * XX16(15 14) = nosev_y ; * XX16(17 16) = nosev_z LDA #197 ; Set Q = 197 STA Q LDY #16 ; Set Y to be a counter that counts down by 2 each time, ; starting with 16, then 14, 12 and so on. We use this ; to work through each of the coordinates in each of the ; orientation vectors .LL21 SETUP_PPU_FOR_ICON_BAR ; If the PPU has started drawing the icon bar, configure ; the PPU to use nametable 0 and pattern table 0 LDA XX16,Y ; Set A = the low byte of the vector coordinate, e.g. ; nosev_z_lo when Y = 16 ASL A ; Shift bit 7 into the C flag LDA XX16+1,Y ; Set A = the high byte of the vector coordinate, e.g. ; nosev_z_hi when Y = 16 ROL A ; Rotate A left, incorporating the C flag, so A now ; contains the original high byte, doubled, and without ; a sign bit, e.g. A = |nosev_z_hi| * 2 JSR LL28 ; Call LL28 to calculate: ; ; R = 256 * A / Q ; ; so, for nosev, this would be: ; ; R = 256 * |nosev_z_hi| * 2 / 197 ; = 2.6 * |nosev_z_hi| LDX R ; Store R in the low byte's location, so we can keep the STX XX16,Y ; old, unscaled high byte intact for the sign DEY ; Decrement the loop counter twice DEY BPL LL21 ; Loop back for the next vector coordinate until we have ; divided them all ; By this point, the vectors have been turned into ; scaled magnitudes, so we have the following: ; ; * XX16 = scaled |sidev_x| ; * XX16+2 = scaled |sidev_y| ; * XX16+4 = scaled |sidev_z| ; ; * XX16+6 = scaled |roofv_x| ; * XX16+8 = scaled |roofv_y| ; * XX16+10 = scaled |roofv_z| ; ; * XX16+12 = scaled |nosev_x| ; * XX16+14 = scaled |nosev_y| ; * XX16+16 = scaled |nosev_z| LDX #8 ; Next we copy the ship's coordinates into XX18, so set ; up a counter in X for 9 bytes .ll91 LDA XX1,X ; Copy the X-th byte from XX1 to XX18 STA XX18,X DEX ; Decrement the loop counter BPL ll91 ; Loop back for the next byte until we have copied all ; three coordinates ; So we now have the following: ; ; * XX18(2 1 0) = (x_sign x_hi x_lo) ; ; * XX18(5 4 3) = (y_sign y_hi y_lo) ; ; * XX18(8 7 6) = (z_sign z_hi z_lo) LDA #255 ; Set the 15th byte of XX2 to 255, so that face 15 is STA XX2+15 ; always visible. No ship definitions actually have this ; number of faces, but this allows us to force a vertex ; to always be visible by associating it with face 15 ; (see the ship blueprints for the Cobra Mk III at ; SHIP_COBRA_MK_3 and the asteroid at SHIP_ASTEROID for ; examples of vertices that are associated with face 15) LDY #12 ; Set Y = 12 to point to the ship blueprint byte #12, LDA XX1+31 ; If bit 5 of the ship's byte #31 is clear, then the AND #%00100000 ; ship is not currently exploding, so jump down to EE29 BEQ EE29 ; to skip the following ; Otherwise we fall through to set up the visibility ; block for an exploding ship