Skip to navigation

Maths (Geometry): GetHorizontalDelta

Name: GetHorizontalDelta [Show more] Type: Subroutine Category: Maths (Geometry) Summary: Calculate the difference in the x-axis and z-axis between two objects, as both signed and absolute deltas
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * GetObjectAngles calls GetHorizontalDelta

This routine calculates the following: xDelta(Hi Lo) = x-coordinate of object #Y - x-coordinate of object #X - xTitleOffset xDeltaAbsoluteHi = |xDeltaHi| zDelta(Hi Lo) = z-coordinate of object #Y - z-coordinate of object #X zDeltaAbsoluteHi = |zDeltaHi| So this calculates the difference (the "delta") in both the x-coordinate and z-coordinate between the two objects, which are the differences along the left-right x-axis and the z-axis the goes into the screen. Note that xTitleOffset is zero during gameplay, and is only non-zero when we are drawing large 3D text on the title screen.
Arguments: X The number of the first object Y The number of the second object
.GetHorizontalDelta \ The x-coordinates for each object are stored as 8-bit \ signed integers, with the x-coordinate for object #X \ in xObject+X and for object #Y in xObject+Y \ \ We want to calculate the deltas in 16-bit accuracy, \ where the low byte is effectively a fractional part, \ so we convert these x-coordinates into 16-bit numbers \ like this: \ \ * x-coordinate for object #X = (xObject+X 0) \ \ * x-coordinate for object #Y = (xObject+Y 0) \ \ and we then do a multi-byte subtraction to get the \ delta, with the title offset included in the \ calculation as (xTitleOffset 0) LDA #0 \ Calculate the following: STA xDeltaLo \ \ xDelta(Hi Lo) = (xObject+Y 0) - (xObject,X 0) \ - (xTitleOffset 0) \ \ starting with the low byte (which we know will be \ zero) SEC \ And then subtracting the high bytes LDA xObject,Y SBC xObject,X SEC SBC xTitleOffset STA xDeltaHi BPL delt1 \ If the high byte of the result is positive, jump to \ delt1 as the result in A is already correct for the \ absolute value (i.e. A = xDeltaHi = |xDeltaHi|) SEC \ The high byte is negative, so set: LDA #0 \ SBC xDeltaHi \ A = 0 - xDeltaHi \ = -xDeltaHi \ = |xDeltaHi| .delt1 STA xDeltaAbsoluteHi \ Set xDeltaAbsoluteHi = |xDeltaHi| \ \ So we now have the absolute x-axis length in: \ \ (xDeltaAbsoluteHi xDeltaLo) \ \ and the original high byte of the signed x-axis length \ is still in xDeltaHi \ We now do the same thing, but with the z-coordinates \ \ There is no title delta to include for the z-axis \ calculation LDA #0 \ Calculate the following: STA zDeltaLo \ \ zDelta(Hi Lo) = (zObject+Y 0) - (zObject,X 0) \ \ starting with the low byte (which we know will be \ zero) SEC \ And then subtracting the high bytes LDA zObject,Y SBC zObject,X STA zDeltaHi BPL delt2 \ If the high byte of the result is positive, jump to \ delt2 as the result in A is already correct for the \ absolute value (i.e. A = zDeltaHi = |zDeltaHi|) SEC \ The high byte is negative, so set: LDA #0 \ SBC zDeltaHi \ A = 0 - zDeltaHi \ = -zDeltaHi \ = |zDeltaHi| .delt2 STA zDeltaAbsoluteHi \ Set zDeltaAbsoluteHi = |zDeltaHi| \ \ So we now have the absolute z-axis length in: \ \ (zDeltaAbsoluteHi zDeltaLo) \ \ and the original high byte of the signed z-axis length \ is still in zDeltaHi RTS \ Return from the subroutine