Skip to navigation

Aviator on the BBC Micro

The Theme: CheckAlienWeakSpot

Name: CheckAlienWeakSpot [Show more] Type: Subroutine Category: The Theme Summary: Check whether an object is close enough to an alien's weak spot to be hitting it Deep dive: Detecting alien hits
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * CheckIfAlienIsHit (Part 2 of 2) calls CheckAlienWeakSpot

If the object is hitting the alien's weak spot, the routine returns to the caller of the caller - in other words, it returns from the original call to the CheckIfAlienIsHit routine, in part 6 of the main loop. This is called HITS in the original source code.
Arguments: Y The bullet trail to be calculated: * 216 = object 0, which we set to points along the bullet trail at 1/32 intervals * 228 = the trailing end of the left bullet trail * 230 = the trailing end of the right bullet trail
.CheckAlienWeakSpot LDX #2 \ Set a counter in X to iterate through the three axes .spot1 TYA \ Point Y to the next axis (xObject, yObject, zObject) CLC \ ADC #nextAxis \ The routine is called is with Y = 216, 228 or 230, so TAY \ this bumps X onto 256, 268 or 260, which gets \ truncated in the 8-bit register to 0, 12 or 14, so \ this moves X through the xObject, yObject and zObject \ values for object 0 (when called with X = 216), object \ 12 (when called with X = 228) or object 14 (when \ called with X = 230) \ \ Objects 12 and 14 are the trailing ends of the two \ bullet trails, so the following checks whether the \ trailing end is within the weak spot, rather than the \ bullets themselves LDA xObjectLo,Y \ Set (A T) = (xObjectHi xObjectLo) - (I+X W+X) SEC \ SBC W,X \ starting with the low bytes STA T LDA xObjectHi,Y \ And then the high bytes SBC I,X \ So we now have: \ \ (A T) = xObject - (I W) \ \ where xObject is the coordinate of the bullet, and \ (I W) is the coordinate of the alien's weak spot \ \ In other words, (A T) is the distance between the \ bullet and the alien's weak spot BNE spot2 \ If the high byte in A is non-zero, then the bullet is \ too far from the weak spot to do any damage, so jump \ to spot2 to return from the subroutine LDA T \ If the low byte in T is >= the corresponding value in CMP PP,X \ PP, QQ or RR (for the z, y and x-axes respectively), BCS spot2 \ then the bullet is too far away from the weak spot to \ do any damage, so jump to spot2 to return from the \ subroutine DEX \ Otherwise the bullet is close enough to the weak spot \ to cause damage in this axis, so decrement X to point \ to the next axis BPL spot1 \ Loop back until we have checked all three axes \ If we get here then the bullet is close enough to the \ weak spot in all three axes, so we have a hit LDA objectId \ Store the object ID of the hit alien in hitObjectId STA hitObjectId TSX \ Remove two bytes from the top of the stack, so the INX \ RTS below returns us to the JSR CheckIfAlienIsHit in INX \ part 6 of the main loop TXS LDA #27 \ Set the hitTimer to 27 to start the explosion counter STA hitTimer .spot2 RTS \ Return from the subroutine