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
```