Skip to navigation

Revs on the BBC Micro

Drawing objects: DrawObjectEdges

Name: DrawObjectEdges [Show more] Type: Subroutine Category: Drawing objects Summary: Draw all the parts of an object by drawing edges into the screen buffer Deep dive: Creating objects from edges
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * DrawObject calls DrawObjectEdges

This routine is used to draw road signs, corner markers and cars. They are drawn as edges - specifically the left and right edges - into the screen buffer in the dash data blocks.
Arguments: MM The index of the first entry in the object data tables for this this object (i.e. the index of the data for the object's first part) xPixelCoord The pixel x-coordinate of the centre of the object yPixelCoord The object's y-coordinate (for the centre of the object) in terms of track lines, so 80 is the top of the track view and 0 is the bottom of the track view lowestTrackLine Hide any part of the object that's below the specified track line (typically used to stop an object from being drawn below the horizon) * 0 = draw the whole object * Non-zero = only draw the part of the object that's above this track line
.DrawObjectEdges LDY MM \ Set Y to the index of this object data in the object \ data tables \ We now work our way through the data for this object, \ drawing one part at a time, using thisObjectIndex and \ Y as the loop counter as we loop through each part \ \ Note that most object parts are defined by one set of \ object data, so they correspond to two edges (left and \ right), but object types 2 and 4 contain four-edge \ object parts, which are defined by two sets of data, \ and therefore two loop iterations .drob1 LDA colourPalette \ Set rightOfEdge to logical colour 0 in the standard STA rightOfEdge \ colour palette, so the fill colour to the left of the \ first edge is set to a default of black when we call \ DrawObjectEdge below LDA #0 \ Set prevEdgeInByte = 0 to indicate that the first edge STA prevEdgeInByte \ is not sharing a pixel byte with the previous edge (as \ there isn't a previous edge) STA edgePixelMask \ Set edgePixelMask = 0 to pass to DrawObjectEdge below \ as there is no previous edge, so there should be no \ mask for the previous edge in the same pixel byte LDX objectTop,Y \ Set A to the scaled scaffold for the top of this part LDA scaledScaffold,X \ of the object CLC \ Set A = A + yPixelCoord ADC yPixelCoord \ \ so A is now the track line of the top of the object BMI drob9 \ If A > 128, then the top of this object part is well \ above the track view, so jump to drob9 to move on to \ the next object part as this one doesn't fit on-screen CMP #80 \ If A >= 80, set A = 79, as the maximum track line at BCC drob2 \ the very top of the track view is 79 LDA #79 .drob2 STA topTrackLine \ Store A in N as the number of the top track line, to \ send to DrawObjectEdge below LDX objectBottom,Y \ Set A to the scaled scaffold for the bottom of this LDA scaledScaffold,X \ part of the object CLC \ Set A = A + yPixelCoord ADC yPixelCoord \ \ so A is now the track line of the bottom of the object BMI drob3 \ If A < 0, then the bottom of this object part is lower \ than the bottom of the track view, so jump to drob3 to \ set A = lowestTrackLine, so we only draw the object \ down to the lowest line allowed CMP lowestTrackLine \ If A >= lowestTrackLine, jump to drob4 to skip the BCS drob4 \ following .drob3 \ If we get here then either the bottom track line in A \ is negative or A < lowestTrackLine, both of which are \ below the lowest level that we want to draw, so we \ cut off the bottom of the object to fit LDA lowestTrackLine \ Set A = lowestTrackLine, so the minimum track line \ number is set to lowestTrackLine and we only draw the \ object down to the lowest line allowed NOP \ These instructions have no effect - presumably they NOP \ are left over from changes during development .drob4 CMP topTrackLine \ If A >= N, then the bottom track line for this object BCS drob9 \ in A is higher than the top track line in N, so jump \ to drob9 to move on to the next object part as there \ is nothing to draw for this part \ We now set up the parameters to pass to DrawObjectEdge \ below, to draw the left and right edges STA bottomTrackLine \ Set bottomTrackLine = A as the bottom track line LDX objectLeft,Y \ Set thisEdge to the scaled scaffold for the left edge LDA scaledScaffold,X \ of this part of the object, to pass to DrawObjectEdge STA thisEdge LDX objectRight,Y \ Set nextEdge to the scaled scaffold for the right LDA scaledScaffold,X \ edge of this part of the object, to pass to STA nextEdge \ DrawObjectEdge LDA objectColour,Y \ Set A to the colour data for this object part STA colourData \ Set colourData to the colour data for this object part STY thisObjectIndex \ Store the current index into the object data in \ thisObjectIndex LDY #1 \ Draw the left edge of this object part JSR DrawObjectEdge .drob5 BIT colourData \ If bit 7 is set in the colour data for this object BMI drob10 \ part, then this is a four-edge object part, so \ jump to drob10 to draw the extra two edges before \ returning here (with bit 7 of colourData clear) to \ draw the fourth edge LDA #0 \ Set A = 0 to send to DrawObjectEdge as the fill colour \ to the right, as there is no fill to the right of the \ object LDY #2 \ Draw the right edge of this object part JSR DrawObjectEdge BIT colourData \ If bit 6 is set in the colour data for this object BVS drob7 \ part, then this indicates that this is the last part \ of this object, so jump to drob7 to return from the \ subroutine as we have now drawn the whole object LDY thisObjectIndex \ Otherwise we need to move on to the next part, so set \ Y to the loop counter .drob6 INY \ Increment the loop counter to point to the data for \ the next object part JMP drob1 \ Loop back to drob1 to process the next object part .drob7 RTS \ Return from the subroutine .drob8 \ We get here when we come across data that forms the \ second and third stages of a four-edge object part, \ so we now need to skip that data as we have already \ processed it AND #%01000000 \ If bit 6 of A is set, i.e. 64 + x, jump to drob7 to BNE drob7 \ return from the subroutine, as we have just drawn the \ last part of the object we wanted to draw INY \ Increment the loop counter to point to the data for \ the next object part .drob9 LDA objectColour,Y \ Set A to the colour data for this object part BMI drob8 \ If bit 7 of A is set, i.e. 128 + x, jump to drob8 to \ skip this bit of data and move on to the next, as this \ contains the data for the second and third edges of a \ four-edge object part, and this will already have \ been processed in drob10 AND #%01000000 \ If bit 6 of A is set, i.e. 64 + x, jump to drob7 to BNE drob7 \ return from the subroutine, as we have just drawn the \ last part of the object we wanted to draw BEQ drob6 \ Jump to drob6 to move on to the next object part (this \ BEQ is effectively a JMP as we just passed through a \ BNE) .drob10 \ If we get here then the colour data for this object \ part has bit 7 set, so this is a four-edge object \ part and we need to draw the second and third edges \ \ The second and third edges are defined in the next bit \ of object data, as follows: \ \ * Second edge: nextEdge = objectLeft \ colourData = objectRight \ \ * Third edge: nextEdge = objectTop \ colourData = objectColour LDY thisObjectIndex \ Set Y to the loop counter INY \ Increment the loop counter to point to the next bit of STY thisObjectIndex \ object data (which contains the data for the second \ and third edges) LDX objectLeft,Y \ Set nextEdge to the scaled data from objectLeft for LDA scaledScaffold,X \ this object part, to pass to DrawObjectEdge STA nextEdge LDA objectRight,Y \ Set colourData to the data from objectRight for this STA colourData \ object part, to pass to DrawObjectEdge LDY #0 \ Draw the second edge of the four-edge object part JSR DrawObjectEdge LDY thisObjectIndex \ Set Y to the index into the object data LDX objectTop,Y \ Set nextEdge to the scaled data from objectTop for LDA scaledScaffold,X \ this object part, to pass to DrawObjectEdge STA nextEdge LDA objectColour,Y \ Set colourData to the data from objectColour for this STA colourData \ object part, to pass to DrawObjectEdge LDY #0 \ Draw the third edge of the four-edge object part JSR DrawObjectEdge JMP drob5 \ Loop back to drob5 to draw the fourth edge, with \ colourData set to the colour data from the third edge, \ which does not have bit 7 set