Skip to navigation

Aviator on the BBC Micro

The Theme: CheckIfAlienIsHit (Part 1 of 2)

Name: CheckIfAlienIsHit (Part 1 of 2) [Show more] Type: Subroutine Category: The Theme Summary: Extract the alien's feeding stage, ready for the hit calculations in part 2 Deep dive: Detecting alien hits
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * MainLoop (Part 6 of 15) calls CheckIfAlienIsHit

Arguments: Y The object ID of the alien to check (30 to 33) objectId The object ID of the alien to check (30 to 33)
.CheckIfAlienIsHit LDA #%01111101 \ Set QQ = %01111101, to hold the y-axis dimension of STA QQ \ the alien's weak spot (let's call this y-size), which \ we will scale down to match the alien's current size LDA #%01000000 \ Set Q = %01000000, to hold the low byte of the offset STA Q \ of the alien's weak spot from the alien's anchor point \ (the high byte is always 5), which we will scale down \ to match the alien's current size LDA #%10100000 \ Set RR = %10100000, to hold the x-axis dimension of STA RR \ the alien's weak spot (let's call this x-size), which \ we will scale down to match the alien's current size STA PP \ Set PP = %10100000, to hold the z-axis dimension of \ the alien's weak spot (let's call this z-size), which \ we will scale down to match the alien's current size CPY #31 \ If Y >= 31, jump to ahit1 BCS ahit1 \ If we get here then Y = 30, so this is a dormant alien LDA #4 \ Set A = 4, to set as the feeding stage in ahit5 (stage \ 4 is the dormant phase) LDX #3 \ Set X = 3, so ahit4 shifts right by 3 places BNE ahit4 \ Jump to ahit4 (this BNE is effectively a JMP as X is \ never zero) .ahit1 LDA #0 \ Set A = 0, so if this is the flying alien (Y = 33), we \ set the feeding stage to 0 in ahit5 (stage 0 is for \ fully fed aliens, and only fully fed aliens can fly) CPY #32 \ If Y >= 32, jump to ahit2 BCS ahit2 \ If we get here then Y = 31, so this is a feeding alien LDX #183 \ Set X = 183, to use as the object point ID BNE ahit3 \ Jump to ahit3 (this BNE is effectively a JMP as X is \ never zero) .ahit2 BNE ahit5 \ If Y <> 32, then Y = 33 and this is the flying alien, \ so jump to ahit5 to store the feeding stage and move \ on to the next part \ If we get here then Y = 32, so this is a feeding alien LDX #188 \ Set X = 188, to use as the object point ID .ahit3 \ If we get here then Y = 31 or 32 and X is the ID of \ the first object point for this alien, so now we \ extract the alien's current feeding stage from the \ scale of the object point' z-coordinate, which gets \ updated in ResizeFeedingAlien as the alien grows \ \ Note that the feeding stage goes from 4 (dormant) down \ to 0 (fully fed) as the alien feeds and grows bigger, \ so we need to invert the scale of the z-coordinate \ to get the correct value for the feeding stage LDA zObjectPoint,X \ Set A to the object point's z-coordinate EOR #%01110000 \ The z-coordinate contains scale information in bits 4 \ to 7, with the smallest feeding alien having a scale \ factor of 2^2, and the largest having a scale factor \ of 2^5 (there are four different sizes of feeding \ alien) \ \ This means that even at the largest scale, bit 7 of \ the scale will still be zero, so to invert the scale \ we only need to flip bits 4 to 6, as then: \ \ * If scale is %0010 (2^2), result is %0101 (5) \ * If scale is %0011 (2^3), result is %0100 (4) \ * If scale is %0100 (2^4), result is %0011 (3) \ * If scale is %0101 (2^5), result is %0010 (2) \ \ so this EOR inverts the alien's scale factor to the \ range 2 to 5, if we only consider the top nibble LSR A \ We now shift the top nibble down, so A contains the LSR A \ inverted scale factor (i.e. A is in the range 2 to 5) LSR A LSR A TAX \ Finally, we subtract 2 from the inverted scale factor, DEX \ so A is now in the range 0 to 3 and reflects the four DEX \ feeding stages: \ \ * 0 = large feeding alien (fully fed) \ * 1 = medium feeding alien \ * 2 = small feeding alien \ * 3 = smallest feeding alien TXA \ Copy the feeding stage into X BEQ ahit5 \ If X = 0, the alien is at its largest size, so jump to \ ahit5 to store the feeding stage and move on to the \ next part \ Otherwise we scale QQ, RR, PP and QQ right by the \ number of places given in X .ahit4 \ This loop shifts the following to the right by X \ places, where X > 0 LSR QQ \ Shift QQ, RR, PP and QQ right by one place LSR RR LSR PP LSR Q DEX \ Decrement the shift counter in X BNE ahit4 \ Loop back until we have shifted right by X places \ By the time we get here, the variables are set as \ follows: \ \ * Fully fed (stage 0) or flying alien: \ \ Q = %01000000, so (5 Q) = &540 = 1360 \ RR = %10100000, so x-size = 160 \ QQ = %01111101, so y-size = 125 \ PP = %10100000, so z-size = 160 \ \ * Medium feeding alien (stage 1): \ \ Q = %00100000, so (5 Q) = &520 = 1312 \ RR = %01010000, so x-size = 80 \ QQ = %00111110, so y-size = 62 \ PP = %01010000, so z-size = 80 \ \ * Small feeding alien (stage 2): \ \ Q = %00010000, so (5 Q) = &510 = 1296 \ RR = %00101000, so x-size = 40 \ QQ = %00011111, so y-size = 31 \ PP = %00101000, so z-size = 40 \ \ * Smallest feeding alien (stage 3) or dormant alien: \ \ Q = %00001000, so (5 Q) = &508 = 1288 \ RR = %00010100, so x-size = 20 \ QQ = %00001111, so y-size = 15 \ PP = %00010100, so z-size = 20 .ahit5 STA feedingStage \ Store the alien's feeding stage in feedingStage