Skip to navigation

BBC Micro Elite

Drawing ships: LL9 (Part 10 of 11)

Name: LL9 (Part 10 of 11) [View in context] Type: Subroutine Category: Drawing ships Summary: Draw ship: Calculate the visibility of each of the ship's edges
This part calculates which edges are visible - in other words, which lines we should draw - and adds them to the ship line heap. When we get here, the heap at XX3 contains all the visible vertex screen coordinates.
.LL170 LDY #3 \ Fetch byte #3 of the ship's blueprint, which contains CLC \ the low byte of the offset to the edges data LDA (XX0),Y ADC XX0 \ Set V = low byte edges offset + XX0 STA V LDY #16 \ Fetch byte #16 of the ship's blueprint, which contains LDA (XX0),Y \ the high byte of the offset to the edges data ADC XX0+1 \ Set V+1 = high byte edges offset + XX0+1 STA V+1 \ \ So V(1 0) now points to the start of the edges data \ for this ship LDY #5 \ Fetch byte #5 of the ship's blueprint, which contains LDA (XX0),Y \ the maximum heap size for plotting the ship (which is STA T1 \ 1 + 4 * the maximum number of visible edges) and store \ it in T1 LDY XX17 \ Set Y to the edge counter in XX17 .LL75 LDA (V),Y \ Fetch byte #0 for this edge, which contains the \ visibility distance for this edge, beyond which the \ edge is not shown CMP XX4 \ If XX4 > the visibility distance, where XX4 contains BCC LL78 \ the ship's z-distance reduced to 0-31 (which we set in \ part 2), then this edge is too far away to be visible, \ so jump down to LL78 to move on to the next edge INY \ Increment Y to point to byte #1 LDA (V),Y \ Fetch byte #1 for this edge into A, so: \ \ A = %ffff ffff, where: \ \ * Bits 0-3 = the number of face 1 \ \ * Bits 4-7 = the number of face 2 INY \ Increment Y to point to byte #2 STA P \ Store byte #1 into P AND #%00001111 \ Extract the number of face 1 into X TAX LDA XX2,X \ If XX2+X is non-zero then we decided in part 5 that BNE LL79 \ face 1 is visible, so jump to LL79 LDA P \ Fetch byte #1 for this edge into A LSR A \ Shift right four times to extract the number of face 2 LSR A \ from bits 4-7 into X LSR A LSR A TAX LDA XX2,X \ If XX2+X is zero then we decided in part 5 that BEQ LL78 \ face 2 is hidden, so jump to LL78 .LL79 \ We now build the screen line for this edge, as \ follows: \ \ XX15(1 0) = start x-coordinate \ \ XX15(3 2) = start y-coordinate \ \ XX15(5 4) = end x-coordinate \ \ XX12(1 0) = end y-coordinate \ \ We can then pass this to the line clipping routine \ before storing the resulting line in the ship line \ heap LDA (V),Y \ Fetch byte #2 for this edge into X, which contains TAX \ the number of the vertex at the start of the edge INY \ Increment Y to point to byte #3 LDA (V),Y \ Fetch byte #3 for this edge into X, which contains STA Q \ the number of the vertex at the end of the edge LDA XX3+1,X \ Fetch the x_hi coordinate of the edge's start vertex STA XX15+1 \ from the XX3 heap into XX15+1 LDA XX3,X \ Fetch the x_lo coordinate of the edge's start vertex STA XX15 \ from the XX3 heap into XX15 LDA XX3+2,X \ Fetch the y_lo coordinate of the edge's start vertex STA XX15+2 \ from the XX3 heap into XX15+2 LDA XX3+3,X \ Fetch the y_hi coordinate of the edge's start vertex STA XX15+3 \ from the XX3 heap into XX15+3 LDX Q \ Set X to the number of the vertex at the end of the \ edge, which we stored in Q LDA XX3,X \ Fetch the x_lo coordinate of the edge's end vertex STA XX15+4 \ from the XX3 heap into XX15+4 LDA XX3+3,X \ Fetch the y_hi coordinate of the edge's end vertex STA XX12+1 \ from the XX3 heap into XX11+1 LDA XX3+2,X \ Fetch the y_lo coordinate of the edge's end vertex STA XX12 \ from the XX3 heap into XX12 LDA XX3+1,X \ Fetch the x_hi coordinate of the edge's end vertex STA XX15+5 \ from the XX3 heap into XX15+5 JSR LL147 \ Call LL147 to see if the new line segment needs to be \ clipped to fit on-screen, returning the clipped line's \ end-points in (X1, Y1) and (X2, Y2) BCS LL78 \ If the C flag is set then the line is not visible on \ screen, so jump to LL78 so we don't store this line \ in the ship line heap .LL80 LDY U \ Fetch the ship line heap pointer, which points to the \ next free byte on the heap, into Y LDA XX15 \ Add X1 to the end of the heap STA (XX19),Y INY \ Increment the heap pointer LDA XX15+1 \ Add Y1 to the end of the heap STA (XX19),Y INY \ Increment the heap pointer LDA XX15+2 \ Add X2 to the end of the heap STA (XX19),Y INY \ Increment the heap pointer LDA XX15+3 \ Add Y2 to the end of the heap STA (XX19),Y INY \ Increment the heap pointer STY U \ Store the updated ship line heap pointer in U CPY T1 \ If Y >= T1 then we have reached the maximum number of BCS LL81 \ edge lines that we can store in the ship line heap, so \ skip to LL81 so we don't loop back for the next edge .LL78 INC XX17 \ Increment the edge counter to point to the next edge LDY XX17 \ If Y >= XX20, which contains the number of edges in CPY XX20 \ the blueprint, jump to LL81 as we have processed all BCS LL81 \ the edges LDY #0 \ Set Y to point to byte #0 again, ready for the next \ edge LDA V \ Increment V by 4 so V(1 0) points to the data for the ADC #4 \ next edge STA V BCC ll81 \ If the above addition didn't overflow, jump to ll81 INC V+1 \ Otherwise increment the high byte of V(1 0), as we \ just moved the V(1 0) pointer past a page boundary .ll81 JMP LL75 \ Loop back to LL75 to process the next edge .^LL81 \ We have finished adding lines to the ship line heap, \ so now we need to set the first byte of the heap to \ the number of bytes stored there LDA U \ Fetch the ship line heap pointer from U into A, which \ points to the end of the heap, and therefore contains \ the heap size LDY #0 \ Store A as the first byte of the ship line heap, so STA (XX19),Y \ the heap is now correctly set up