RTS \ This instruction appears to be unused .GetObjectAngles STY objectToAnalyse \ Set objectToAnalyse to the number of the object being \ analysed LDA objectTypes,Y \ Set objTypeToAnalyse to the type of the object being STA objTypeToAnalyse \ analysed \ We start by calculating the difference (the delta) in \ all three axes between the viewer and the object we \ are analysing, to give us the 3D vector from the \ viewer to the object LDX viewingObject \ Set X to the object number of the viewer JSR GetHorizontalDelta \ Calculate the following: \ \ xDelta(Hi Lo) = x-coordinate of object #Y \ - x-coordinate of object #X \ - xTitleOffset \ \ xDeltaAbsoluteHi = |xDeltaAbsoluteHi| \ \ zDelta(Hi Lo) = z-coordinate of object #Y \ - z-coordinate of object #X \ \ zDeltaAbsoluteHi = |zDeltaHi| \ \ So this calculates the difference in both horizontal \ axes between object #X (the viewer) and object #Y (the \ object being analysed) \ \ Note that xTitleOffset is zero during gameplay, and is \ only non-zero when we are drawing large 3D text on the \ title screen JSR GetVerticalDelta \ Calculate the following: \ \ yDelta(Hi Lo) = y-coordinate of object #Y \ - y-coordinate of object #X \ \ So this calculates the difference in altitude between \ object #X (the viewer) and object #Y (the object being \ analysed) \ We now have deltas for all three axes, so we now can \ calculate the angle of the hypotenuse of the triangle \ formed by the x-axis and z-axis, which is the \ projection of the 3D vector from the viewer to the \ object down onto the ground plane (so imagine a light \ shining down from above, casting the vector's shadow \ onto the y = 0 plane - that's the hypotenuse) JSR GetHypotenuseAngle \ Calculate the angle of the hypotenuse in the triangle \ with the following non-hypotenuse sides: \ \ * xDelta(Hi Lo) \ \ * zDelta(Hi Lo) \ \ and return the angle in angle(Hi Lo), the tangent in \ angleTangent, the length of the longer side in \ a(Hi Lo) and the length of the shorter side in \ b(Hi Lo) \ The angle of the hypotenuse is the yaw angle of the \ 3D vector from the viewer to the object we are \ analysing \ \ We also subtract the following: \ \ * objectYawAngle,X from the high byte so the result \ is the relative yaw angle from object #X (the \ viewer's gaze) to the object \ \ * yawAdjustmentLo from the low byte so if we are \ drawing an object for updating, we include the \ correct yaw offset to enable the object to be \ drawn flush with the left edge of the screen \ buffer (see the DrawUpdatedObject routine) \ \ and add the following: \ \ * (10 0) to add half a screen width (as the screen \ is 20 yaw angles wide) \ \ So the result in objectViewYaw(Hi Lo) is the yaw angle \ delta from the viewer's gaze to the object, plus \ adjustments and half a screen, to give us the yaw \ angle relative to the view \ \ You can think of this as the screen x-coordinate of \ the object, or how far the object appears from the \ left edge of the screen LDX viewingObject \ Set X to the object number of the viewer LDA angleLo \ Set objectViewYaw(Hi Lo) = SEC \ angle(Hi Lo) - (0 yawAdjustmentLo) SBC yawAdjustmentLo \ - (objectYawAngle,X 0) STA objectViewYawLo \ + (10 0) LDA angleHi SBC objectYawAngle,X CLC ADC #10 STA objectViewYawHi LDY objectToAnalyse \ Set Y to the number of the object being analysed LDA #0 \ Set objectGazeYaw(Hi Lo) = SEC \ (objectYawAngle,Y 0) - angle(Hi Lo) SBC angleLo \ STA objectGazeYawLo \ This is the difference in yaw angles between the LDA objectYawAngle,Y \ hypotenuse (i.e. the viewer's gaze) and the direction SBC angleHi \ in which the object is facing (i.e. the object's gaze STA objectGazeYawHi \ to wherever it is looking), so that's the object's \ gaze relative to the viewer's gaze JSR GetHypotenuse \ Calculate the length of the hypotenuse in the triangle \ with side lengths of a(Hi Lo) and b(Hi Lo) and angle \ angleTangent, which the call to GetHypotenuseAngle set \ to the values for the projection of the 3D vector from \ the viewer to the object down onto the ground plane \ \ The hypotenuse length is returned in hypotenuse(Hi Lo) LDA viewType \ If viewType is non-zero then this is not the landscape BNE oang1 \ preview, so jump to oang1 to skip the following \ This is the landscape preview, so we rotate the object \ to face towards the back of the landscape, so the \ Sentinel and sentries all neatly look out of the \ screen in the preview LDA #128 \ Set objectGazeYaw(Hi Lo) = (128 0) STA objectGazeYawHi \ LDA #0 \ The degree system in the Sentinel looks like this: STA objectGazeYawLo \ \ 0 \ -32 | +32 Overhead view of object \ \ | / \ \ | / 0 = looking straight ahead \ \|/ +64 = looking sharp right \ -64 -----+----- +64 -64 = looking sharp left \ /|\ \ / | \ \ / | \ \ -96 | +96 \ 128 \ \ So this makes the object face directly out of the \ screen CPY #63 \ If we are analysing object #63, then this is either BEQ oang1 \ a block of 3D text or the Sentinel's tower, and the \ landscape preview doesn't use 3D text so it must be \ the Sentinel's tower, so jump to oang1 to skip the \ following \ \ This ensures that all objects apart from the tower \ are drawn at double size, so they stand out more \ clearly in the landscape preview (the tower is the \ biggest object by far, so doubling its size would \ make it too large) LSR hypotenuseHi \ Halve the hypotenuse length to make the object appear ROR hypotenuseLo \ to be half the distance away, so it is drawn at twice \ the size SEC \ Halve the object's altitude in yDelta(Hi Lo) for the ROR yDeltaHi \ same reason ROR yDeltaLo \ \ Because this is the landscape view, the viewer is very \ high above the landscape (as well as a long way in \ front of the front edge), so we know that \ yDelta(Hi Lo) will be negative, as it's calculated as \ the altitude of the object being analysed minus the \ altitude of the viewer, and the latter is higher than \ any object on the landscape \ \ So we can halve the value of yDelta(Hi Lo) by shifting \ a set bit into the top end of yDeltaHi, so we keep the \ sign correct LDA yDeltaLo \ Set yDelta(Hi Lo) = yDelta(Hi Lo) + 112 CLC \ ADC #112 \ Starting with the low bytes STA yDeltaLo BCC oang1 \ And then the high byte INC yDeltaHi \ \ This moves the Sentinel and sentries up so they stand \ out more clearly in the landscape preview, as \ otherwise they would appear to be sinking into the \ landscape rather than perching on top of it .oang1 LDA hypotenuseLo \ Set objectAdjacent(Hi Lo) to the length of the STA objectAdjacentLo \ hypotenuse, which is the length of the adjacent side LDA hypotenuseHi \ in the right-angled triangle with the vector from the STA objectAdjacentHi \ viewer to the object as the hypotenuse LDA yDeltaLo \ Set objectOpposite(Hi Lo) to the height of the object STA objectOppositeLo \ relative to the viewer, which is the length of the LDA yDeltaHi \ opposite side in the right-angled triangle with the STA objectOppositeHi \ vector from the viewer to the object as the hypotenuse RTS \ Return from the subroutineName: GetObjectAngles [Show more] Type: Subroutine Category: 3D objects Summary: Calculate the angles and distances of the vector from the viewer to a specific objectContext: See this subroutine in context in the source code References: This subroutine is called as follows: * CheckEnemyGaze (Part 1 of 2) calls GetObjectAngles * DrawObject calls GetObjectAngles * GetObjVisibility calls GetObjectAngles
This routine calculates the following for an object: 1. objTypeToAnalyse: Set to the type of the object we are analysing. 2. xDelta(Hi Lo), yDelta(Hi Lo), zDelta(Hi Lo): Calculate the difference (the delta) in all three axes between the viewer and the object we are analysing, to give us the 3D vector from the viewer to the object. 3. angle(Hi Lo): Calculate the angle of the hypotenuse of the triangle formed by the x-axis and z-axis, which is the projection of the 3D vector from the viewer to the object down onto the ground plane (so imagine a light shining down from above, casting the vector's shadow onto the y = 0 plane, and that's the hypotenuse). 4. hypotenuse(Hi Lo): Set to the length of the hypotenuse in the above triangle, so that's the length of the 3D vector from the viewer to the object when projected down onto the ground plane. 5. objectViewYaw(Hi Lo): The angle of the hypotenuse is the yaw angle of the 3D vector from the viewer to the object we are analysing. We subtract the viewer's yaw angle and the yaw adjustment, and add half a screen width to get the yaw angle delta from the viewer's gaze to the object, relative to the viewer's gaze, i.e. the screen). This gives us the yaw angle relative to the view. You can think of this as the screen x-coordinate of the object, or how far the object appears from the left edge of the screen. 6. objectGazeYaw(Hi Lo): Set to the object's gaze relative to the viewer's gaze. 7. If this is the landscape preview, rotate the object to face forwards and scale it so it looks good. 8. Set objectAdjacent(Hi Lo) to hypotenuse(Hi Lo) so it can be used as the length of the adjacent side in the vertical right-angled triangle with the projected vector along the bottom and the vector from the viewer to the object as the hypotenuse. 9. Set objectOpposite(Hi Lo) to the length of the opposite side in the vertical right-angled triangle with the projected vector along the bottom and the vector from the viewer to the object as the hypotenuse.
Arguments: Y The number of the object to be analysed viewType Landscape preview flag: * Zero = this is the landscape preview, so rotate all the objects in the preview to face the viewer * Non-zero = this is not the landscape preview, so leave the objects alone viewingObject The viewing object
[X]
Subroutine GetHorizontalDelta (category: Maths (Geometry))
Calculate the difference in the x-axis and z-axis between two objects, as both signed and absolute deltas
[X]
Subroutine GetHypotenuse (category: Maths (Geometry))
Calculate the hypotenuse from an angle and two triangle sides with one lookup and one multiplication (so without a square root)
[X]
Subroutine GetHypotenuseAngle (category: Maths (Geometry))
Calculate the angle of the hypotenuse in a right-angle triangle given the two non-hypotenuse sides (i.e. two orthogonal axes)
[X]
Subroutine GetVerticalDelta (category: Maths (Geometry))
Calculate the difference in the y-axis between two objects as a signed delta
[X]
Variable hypotenuseHi in workspace Zero page
The high byte of the hypotenuse of a triangle
[X]
Variable hypotenuseLo in workspace Zero page
The low byte of the hypotenuse of a triangle
[X]
Label oang1 is local to this routine
[X]
Variable objTypeToAnalyse in workspace Zero page
The type of the object being analysed in the GetObjectAngles routine
[X]
Variable objectAdjacentHi in workspace Main variable workspace
The distance of an object from the viewer, expressed as the length of the adjacent side in a triangle with the vector from the viewer to the object as the hypotenuse (high byte)
[X]
Variable objectAdjacentLo in workspace Main variable workspace
The distance of an object from the viewer, expressed as the length of the adjacent side in a triangle with the vector from the viewer to the object as the hypotenuse (low byte)
[X]
Variable objectGazeYawHi in workspace Zero page
The difference in the yaw angle of the viewer's gaze and the yaw angle (i.e. the gaze) of the object being analysed (low byte)
[X]
Variable objectGazeYawLo in workspace Zero page
The difference in the yaw angle of the viewer's gaze and the yaw angle (i.e. the gaze) of the object being analysed (low byte)
[X]
Variable objectOppositeHi in workspace Main variable workspace
The height of an object relative to the viewer, expressed as the length of the opposite side in a triangle with the vector from the viewer to the object as the hypotenuse (high byte)
[X]
Variable objectOppositeLo in workspace Main variable workspace
The height of an object relative to the viewer, expressed as the length of the opposite side in a triangle with the vector from the viewer to the object as the hypotenuse (low byte)
[X]
Variable objectToAnalyse in workspace Zero page
The number of the object to analyse in the GetObjectAngles routine
[X]
Variable objectTypes (category: 3D objects)
The object types table for up to 64 objects
[X]
Variable objectViewYawHi in workspace Main variable workspace
The yaw angle of the object being analysed, relative to the current viewer (high byte)
[X]
Variable objectViewYawLo in workspace Main variable workspace
The yaw angle of the object being analysed, relative to the current viewer (low byte)
[X]
Variable objectYawAngle (category: 3D objects)
The yaw angle for each object (i.e. the horizontal direction in which they are facing)
[X]
Variable viewType (category: Title screen)
Storage for the type of title view we are drawing in DrawTitleView (title screen or landscape preview)
[X]
Variable viewingObject in workspace Zero page
The number of the viewing object
[X]
Variable yawAdjustmentLo in workspace Zero page
A yaw adjustment to apply to the landscape drawing process so that when we update objects on-screen, we can yaw the viewer's gaze to the right to move the left edge of the object to the left edge of the screen so the object will fit into the screen buffer as efficiently as possible (low byte)