Aviator on the BBC Micro

# Visibility: CheckObjDistance

```       Name: CheckObjDistance                                        [Show more]
Type: Subroutine
Category: Visibility
Summary: Check whether an object is within the visible distance for that
object, along just one axis
Deep dive: Visibility checks
Context: See this subroutine in context in the source code
References: This subroutine is called as follows:
* SetObjectCoords (Part 8 of 11) calls CheckObjDistance

We call this routine by passing in the distance from the plane to the object,
along the axis we are checking. We pass it as the top two bytes of a 24-bit
number, (A T x), containing the object's coordinate in the relevant axis. We
can ignore the low byte as it doesn't affect object visibility.

First we check the top byte in A to make sure it is either 0 or -1, as
otherwise the distance is definitely too far for the object to be visible.

Assuming the top byte is within range, we then check the high byte in T
against the maximum visible distance for the object in question. The object
is visible only if |T| < the object's maxObjDistance value, otherwise it is
too far away to be seen.

When called with K = 0, this routine will always return 0 to indicate that the
object is visible. This is used by the bullets, to ensure that they remain
visible, whatever their distance from the plane.

Arguments:

Y                    The object ID of the object to check

A                    The top byte of the object's coordinates in the axis we
want to check (i.e. the byte above xPointHi, yPointHi or
zPointHi)

T                    The high byte the object's coordinates in the axis we
want to check (i.e. xPointHi, yPointHi or zPointHi)

K                    The non-zero return value (see below), so setting this
to 0 will ensure that the object is always reported as
being visible

Returns:

A                    Contains the result as follows:

* 0 if the object is close enough to be visible

* K if the object is too far away to be visible

.CheckObjDistance

CMP #&FF               \ If A <> -1, jump to objd3 as the object is too far
BNE objd3              \ away to be visible

\ If we get here, then A = -1, so now we need to check
\ the middle byte against the object's maximum visible
\ distance, though we need to negate the middle byte
\ first, as the coordinate is negative and the values in
\ maxObjDistance are positive

LDA T                  \ Set A = ~T to negate it
EOR #&FF

JMP objd2              \ Jump to objd2 to check against the object's maximum
\ visible distance

.objd1

\ If we get here, then A is positive

BNE objd3              \ If A is non-zero, jump to objd3 as the object is too
\ far away to be visible

\ If we get here then A = 0, so now we need to check the
\ middle byte against the object's maximum visible
\ distance

LDA T                  \ Set A = T so we check the middle byte in the following

.objd2

CMP maxObjDistance,Y   \ If A >= the object's maximum visible distance, then
BCS objd3              \ the object is too far away to be visible, so jump to
\ objd3

\ If we get here then we want to return a "visible"
\ result

LDA #0                 \ Set A = 0 as the return value

RTS                    \ Return from the subroutine

.objd3

\ If we get here then we want to return a "not visible"
\ result

LDA K                  \ Set A = K as the return value

RTS                    \ Return from the subroutine
```