Skip to navigation

BBC Micro Elite

Drawing ships: LL9 (Part 3 of 11)

Name: LL9 (Part 3 of 11) [View in context] Type: Subroutine Category: Drawing ships Summary: Draw ship: Set up orientation vector, ship coordinate variables
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 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 in the cassette version, but this \ allows us to force a vertex to always be visible by \ associating it with face 15 (see the blueprints for \ the Cobra Mk III at SHIP5 and asteroid at SHIP10 for \ examples) 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