| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- //
- // Copyright 2020 Electronic Arts Inc.
- //
- // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free
- // software: you can redistribute it and/or modify it under the terms of
- // the GNU General Public License as published by the Free Software Foundation,
- // either version 3 of the License, or (at your option) any later version.
- // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
- // in the hope that it will be useful, but with permitted additional restrictions
- // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
- // distributed with this program. You should have received a copy of the
- // GNU General Public License along with permitted additional restrictions
- // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
- /* $Header: /CounterStrike/FACE.CPP 1 3/03/97 10:24a Joe_bostic $ */
- /***********************************************************************************************
- *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
- ***********************************************************************************************
- * *
- * Project Name : Command & Conquer *
- * *
- * File Name : FACE.CPP *
- * *
- * Programmer : Joe L. Bostic *
- * *
- * Start Date : 03/08/96 *
- * *
- * Last Update : March 8, 1996 [JLB] *
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * Desired_Facing8 -- Determines facing from one coordinate to another. *
- * Desired_Facing256 -- Determines facing from one coordinate to another. *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "function.h"
- /***********************************************************************************************
- * Desired_Facing8 -- Determines facing from one coordinate to another. *
- * *
- * This routine will find the facing (compass direction) from one location to another. *
- * Typical use of this is in find path and other 'monster' movement logic. *
- * *
- * INPUT: x1,y1 -- X and Y coordinates for the source location. The coordinate 0,0 is *
- * presumed to be the northwest corner of the map. *
- * *
- * x2,y2 -- X and Y coordinates for the destination (target) location. *
- * *
- * OUTPUT: Returns with the facing from the first coordinate to the second coordinate. The *
- * value returned will range from 0 being North, increasing clockwise until reaching *
- * 255 which is just shy of North in a Westerly direction. *
- * *
- * WARNINGS: This routine is only accurate to the 8 primary compass directions. It is much *
- * faster than the Desired_Facing256() function so it should be used where speed *
- * is more important than accuracy. *
- * *
- * HISTORY: *
- * 03/08/1996 JLB : Created. *
- *=============================================================================================*/
- DirType Desired_Facing8(int x1, int y1, int x2, int y2)
- {
- int index = 0; // Facing composite value.
- /*
- ** Figure the absolute X difference. This determines
- ** if the facing is leftward or not.
- */
- int xdiff = x2-x1;
- if (xdiff < 0) {
- index |= 0x00C0;
- xdiff = -xdiff;
- }
- /*
- ** Figure the absolute Y difference. This determines
- ** if the facing is downward or not. This also clarifies
- ** exactly which quadrant the facing lies.
- */
- int ydiff = y1-y2;
- if (ydiff < 0) {
- index ^= 0x0040;
- ydiff = -ydiff;
- }
- /*
- ** Determine which of the two direction offsets it bigger. The
- ** offset direction that is bigger (X or Y) will indicate which
- ** orthogonal direction the facing is closer to.
- */
- unsigned bigger;
- unsigned smaller;
- if (xdiff < ydiff) {
- smaller = xdiff;
- bigger = ydiff;
- } else {
- smaller = ydiff;
- bigger = xdiff;
- }
- /*
- ** If on the diagonal, then incorporate this into the facing
- ** and then bail. The facing is known.
- */
- if (((bigger+1)/2) <= smaller) {
- index += 0x0020;
- return(DirType(index));
- }
- /*
- ** Determine if the facing is closer to the Y axis or
- ** the X axis.
- */
- int adder = (index & 0x0040);
- if (xdiff == bigger) {
- adder ^= 0x0040;
- }
- index += adder;
- return(DirType(index));
- }
- /***********************************************************************************************
- * Desired_Facing256 -- Determines facing from one coordinate to another. *
- * *
- * This routine will figure the facing from the source coordinate toward the destination *
- * coordinate. Typically, this routine is used for movement and other 'monster' logic. It *
- * is more accurate than the corresponding Desired_Facing8() function, but is slower. *
- * *
- * INPUT: srcx, srcy -- The source coordinate to determine the facing from. *
- * *
- * dstx, dsty -- The destination (or target) coordinate to determine the facing *
- * toward. *
- * *
- * OUTPUT: Returns with the facing from the source coordinate toward the destination *
- * coordinate with 0 being North increasing in a clockwise direction. 64 is East, *
- * 128 is South, etc. *
- * *
- * WARNINGS: The coordinate 0,0 is presumed to be in the Northwest corner of the map. *
- * Although this routine is fast, it is not as fast as Desired_Facing8(). *
- * *
- * HISTORY: *
- * 03/08/1996 JLB : Created. *
- *=============================================================================================*/
- DirType Desired_Facing256(int srcx, int srcy, int dstx, int dsty)
- {
- int composite=0; // Facing built from intermediate calculations.
- /*
- ** Fetch the absolute X difference. This also gives a clue as
- ** to which hemisphere the direction lies.
- */
- int xdiff = dstx - srcx;
- if (xdiff < 0) {
- composite |= 0x00C0;
- xdiff = -xdiff;
- }
- /*
- ** Fetch the absolute Y difference. This clarifies the exact
- ** quadrant that the direction lies.
- */
- int ydiff = srcy - dsty;
- if (ydiff < 0) {
- composite ^= 0x0040;
- ydiff = -ydiff;
- }
- /*
- ** Bail early if the coordinates are the same. This check also
- ** has the added bonus of ensuring that checking for division
- ** by zero is not needed in the following section.
- */
- if (xdiff == 0 && ydiff == 0) return(DirType(0xFF));
- /*
- ** Determine which of the two direction offsets it bigger. The
- ** offset direction that is bigger (X or Y) will indicate which
- ** orthogonal direction the facing is closer to.
- */
- unsigned bigger;
- unsigned smaller;
- if (xdiff < ydiff) {
- smaller = xdiff;
- bigger = ydiff;
- } else {
- smaller = ydiff;
- bigger = xdiff;
- }
- /*
- ** Now that the quadrant is known, we need to determine how far
- ** from the orthogonal directions, the facing lies. This value
- ** is calculated as a ratio from 0 (matches orthogonal) to 31
- ** (matches diagonal).
- */
- //lint -e414 Division by zero cannot occur here.
- int frac = (smaller * 32U) / bigger;
- /*
- ** Given the quadrant and knowing whether the facing is closer
- ** to the X or Y axis, we must make an adjustment toward the
- ** subsequent quadrant if necessary.
- */
- int adder = (composite & 0x0040);
- if (xdiff > ydiff) {
- adder ^= 0x0040;
- }
- if (adder) {
- frac = (adder - frac)-1;
- }
- /*
- ** Integrate the fraction value into the quadrant.
- */
- composite += frac;
- /*
- ** Return with the final facing value.
- */
- return(DirType(composite & 0x00FF));
- }
|