Skip to navigation


Drawing objects: DrawObjectEdge (Part 4 of 5)

Name: DrawObjectEdge (Part 4 of 5) [Show more] Type: Subroutine Category: Drawing objects Summary: Draw the edge into the screen buffer, merging with any content already in the buffer Deep dive: Creating objects from edges
Context: See this subroutine in context in the source code References: No direct references to this subroutine in this source file
.draw19 \ By this point, we have the following: \ \ * A contains the pixel byte we need to use to draw \ this edge (incorporating the previous edge if it's \ close enough to be in the same pixel byte) \ \ * L contains a pixel mask containing set pixels for \ those pixels outside of the object and its fill, \ so to the left of the left edge, or to the right \ of the right edge, or to the left and right \ of pixel byte that contains two edges \ \ * (Q P) contains the address of the dash data block \ containing the edge we want to draw \ \ * blockOffset contains the dash data block offset \ for the bottom track line of the edge we want to \ draw \ \ * topTrackLine contains the number of the track line \ at the top of the edge we want to draw \ \ So now we actually draw the edge STA I \ Set I to the pixel byte for the edge we want to draw IF _ACORNSOFT OR _4TRACKS BNE draw20 \ If the pixel byte is non-zero, jump to draw20 to skip \ the following instruction LDA #&55 \ Set A = &55 to use as the value of WW below (&55 in \ the screen buffer represents colour 0, or black) .draw20 STA WW \ Set WW to the pixel byte (or &55 if the pixel byte is \ zero) LDA #0 \ Set edgePixelMask = 0, so the next call to STA edgePixelMask \ DrawObjectEdge ignores any edges from this call (as \ we are about to draw them on-screen) LDY blockOffset \ Set W to the current screen buffer byte at the bottom LDA (P),Y \ of the edge that we want to draw STA W LDA #&AA \ Replace the byte at the bottom of the edge with &AA, STA (P),Y \ to use as a marker LDY topTrackLine \ Set Y = topTrackLine, which is the number of the \ track line at the top of the object, which is the \ same as the offset into the dash data block for the \ top edge JMP draw24 \ Jump into the following loop at the entry point draw24 \ to draw the edge from the top byte to the bottom byte \ \ We jump into the loop with the following set: \ \ * Y contains the offset of the top of the edge we \ want to draw, which we now use as a loop counter \ to work our way from the top of the edge to the \ bottom (i.e. Y gets decremented as we draw each \ pixel byte) \ \ * The bottom track line of the edge contains the \ marker byte &AA \ \ * W contains the original byte that was in the \ marker's location .draw21 \ We loop back here if we fetch the next byte down from \ the screen buffer into A and find that it is non-zero CMP #&55 \ If the current byte is &55, then this represents black BNE draw22 \ (colour 0), so set A = 0 so it's the correct pixel LDA #0 \ byte for the current buffer contents .draw22 AND L \ The bit mask in L contains set pixels for those \ outside of the edge and its fill, and clear pixels for \ the edge and object fill, so this clears the pixels \ where we want to draw the edge and object fill ORA I \ Replace those cleared bits with the edge and fill that \ we want to draw BNE draw23 \ If the result is non-zero, then jump to draw23 to skip \ the following instruction LDA #&55 \ The result is zero, i.e. colour 0 (black), so set \ A = &55, which is the value we use to represent \ colour 0 (black) in the screen buffer .draw23 STA (P),Y \ Draw the resulting pixel byte into the screen buffer \ by writing it to the Y-th byte of the relevant dash \ data block DEY \ Decrement the track line counter in Y to move down to \ the next pixel line on-screen .draw24 \ This is the entry point for the loop, which is between \ draw21 and the loop's end logic at draw28 LDA (P),Y \ If the current byte in the screen buffer is non-zero, BNE draw28 \ then it is not empty, so jump to draw28 to merge the \ pixel byte with the non-empty byte that's already in \ the screen buffer .draw25 JSR GetColour \ The current byte in the screen buffer is zero, which \ means it should inherit the colour of the byte to the \ left, so call GetColour to work out what this byte's \ colour would be on-screen, and put it into A AND L \ The bit mask in L contains set pixels for those \ outside of the edge and its fill, and clear pixels for \ the edge and object fill, so this clears the pixels \ where we want to draw the edge and object fill ORA I \ Replace those cleared bits with the edge and fill that \ we want to draw BNE draw26 \ If the result is non-zero, then jump to draw23 to skip \ the following instruction LDA #&55 \ The result is zero, i.e. colour 0 (black), so set \ A = &55, which is the value we use to represent \ colour 0 (black) in the screen buffer .draw26 STA (P),Y \ Draw the resulting pixel byte into the screen buffer \ by writing it to the Y-th byte of the relevant dash \ data block DEY \ Decrement the track line counter in Y to move down to \ the next pixel line on-screen .draw27 LDX &3000,Y \ Set X to the Y-th byte in the screen buffer, which is \ the next byte down the screen after the one we just \ draw \ \ Gets modified at the start of part 2 as follows: \ \ LDX &3000,Y -> LDX #(Q P),Y \ \ In other words, we have modified the instruction to \ load the Y-th byte from the dash data block address \ for the edge we are drawing, i.e. load the Y-th byte \ of dash data block blockNumber BEQ draw26 \ If the next byte down the screen is zero, then loop \ back to draw26 to draw the edge in this byte as well, \ so we keep drawing the edge downwards while the \ existing contents of the screen buffer are empty TXA \ The next byte down the screen is non-zero, so copy the \ value into A .draw28 CMP #&AA \ If this is not the marker for the bottom of the edge, BNE draw21 \ loop back to draw21 to draw the next pixel byte over \ the top of this non-empty byte in the screen buffer \ We just reached a value that matches the marker at the \ bottom of the edge, which is either our marker or a \ valid entry in the screen buffer that happens to have \ this value LDA #0 \ Overwrite the &AA value with 0, though this appears to STA (P),Y \ have no effect, as if we loop back to draw25 in the \ following conditional, this value will be overwritten, \ and if we fall through to the LDA W below, it will \ be overwritten there CPY blockOffset \ If Y <> blockOffset then this can't be our marker, as BNE draw25 \ the marker is on line blockOffset, so jump back to \ draw25 to merge this byte with the correct background \ colour \ If we get here then we have reached our marker at the \ bottom of the edge LDA W \ Restore the entry in the dash data block that we STA (P),Y \ overwrote with the marker, whose original contents we \ stored in W LDX J \ If the edge type in J = 1, then we have just drawn the CPX #1 \ left edge, so jump to draw31 to return from the BEQ draw31 \ subroutine as we are done drawing \ If we get here then we have just drawn an extra or \ right edge, so we need to fill the next column to the \ right of the edge we just drew (i.e. in the next block \ along), so that the background colour is restored \ after the object INC blockNumber \ Fill the column to the right of the edge we just drew, JSR FillAfterObject \ so the correct background colour is shown to the right DEC blockNumber \ of the object part ELIF _SUPERIOR OR _REVSPLUS LDA #0 \ Set edgePixelMask = 0, so the next call to STA edgePixelMask \ DrawObjectEdge ignores any edges from this call (as \ we are about to draw them on-screen) LDY topTrackLine \ Set Y = topTrackLine, which is the number of the \ track line at the top of the object, which is the \ same as the offset into the dash data block for the \ top edge JMP sraw6 \ Jump into the following loop at the entry point sraw6 \ to draw the edge from the top byte to the bottom byte \ \ We jump into the loop with the following set: \ \ * Y contains the offset of the top of the edge we \ want to draw, which we now use as a loop counter \ to work our way from the top of the edge to the \ bottom (i.e. Y gets decremented as we draw each \ pixel byte) \ \ * The bottom track line of the edge contains the \ marker byte &AA \ \ * W contains the original byte that was in the \ marker's location .sraw1 LDA (P),Y \ If the current byte in the screen buffer is zero, then BEQ sraw2 \ jump to sraw2 to work out what colour it would be \ on-screen CMP #&55 \ If the current byte is not &55, then the current byte BNE sraw3 \ in the screen buffer contains something, so jump to \ sraw3 with the contents in A LDA I \ The current byte in the screen buffer is &55, or \ black, so set A to the pixel byte we want to draw BNE sraw5 \ If we want to draw something that isn't black (i.e. \ which is non-zero), jump to sraw5 to store it in the \ screen buffer BEQ sraw4 \ If we get here then we want to draw a black pixel \ byte, so jump to sraw4 to store &55 in the screen \ buffer (which is the screen buffer value for black) .sraw2 JSR GetColourSup \ The current byte in the screen buffer is zero, which \ means it should inherit the colour of the byte to the \ left, so call GetColourSup to work out what this \ byte's colour would be on-screen, and put it into A .sraw3 \ At this point A contains the byte in the screen \ buffer, converted into the byte it represents when \ the buffer is copied to the screen AND L \ The bit mask in L contains set pixels for those \ outside of the edge and its fill, and clear pixels for \ the edge and object fill, so this clears the pixels \ where we want to draw the edge and object fill ORA I \ Replace those cleared bits with the edge and fill that \ we want to draw BNE sraw5 \ If the result is non-zero, then jump to sraw5 to skip \ the following instruction .sraw4 LDA #&55 \ Set A = &55, which is the value we use to represent \ colour 0 (black) in the screen buffer .sraw5 STA (P),Y \ Draw the resulting pixel byte into the screen buffer \ by writing it to the Y-th byte of the relevant dash \ data block DEY \ Decrement the track line counter in Y to move down to \ the next pixel line on-screen .sraw6 \ This is the entry point for the loop, which is between \ sraw1 and the loop's end logic in the next instruction CPY blockOffset \ If Y <> blockOffset then this can't be our marker, as BNE sraw1 \ the marker is on line blockOffset, so jump back to \ sraw1 to merge this byte with the correct background \ colour LDX J \ If the edge type in J = 1, then we have just drawn the CPX #1 \ left edge, so jump to draw31 to return from the BEQ draw31 \ subroutine as we are done drawing \ If we get here then we have just drawn an extra or \ right edge, so we need to fill the next column to the \ right of the edge we just drew (i.e. in the next block \ along), so that the background colour is restored \ after the object INC blockNumber \ Fill the column to the right of the edge we just drew, JSR FillAfterObjectSup \ so the correct background colour is shown to the right DEC blockNumber \ of the object part ENDIF