CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

FACE.CPP (10206B)


      1 //
      2 // Copyright 2020 Electronic Arts Inc.
      3 //
      4 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 
      5 // software: you can redistribute it and/or modify it under the terms of 
      6 // the GNU General Public License as published by the Free Software Foundation, 
      7 // either version 3 of the License, or (at your option) any later version.
      8 
      9 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 
     10 // in the hope that it will be useful, but with permitted additional restrictions 
     11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 
     12 // distributed with this program. You should have received a copy of the 
     13 // GNU General Public License along with permitted additional restrictions 
     14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
     15 
     16 /* $Header: /CounterStrike/FACE.CPP 1     3/03/97 10:24a Joe_bostic $ */
     17 /***********************************************************************************************
     18  ***              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               ***
     19  ***********************************************************************************************
     20  *                                                                                             *
     21  *                 Project Name : Command & Conquer                                            *
     22  *                                                                                             *
     23  *                    File Name : FACE.CPP                                                     *
     24  *                                                                                             *
     25  *                   Programmer : Joe L. Bostic                                                *
     26  *                                                                                             *
     27  *                   Start Date : 03/08/96                                                     *
     28  *                                                                                             *
     29  *                  Last Update : March 8, 1996 [JLB]                                          *
     30  *                                                                                             *
     31  *---------------------------------------------------------------------------------------------*
     32  * Functions:                                                                                  *
     33  *   Desired_Facing8 -- Determines facing from one coordinate to another.                      *
     34  *   Desired_Facing256 -- Determines facing from one coordinate to another.                    *
     35  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     36 
     37 #include "function.h"
     38 
     39 
     40 /***********************************************************************************************
     41  * Desired_Facing8 -- Determines facing from one coordinate to another.                        *
     42  *                                                                                             *
     43  *    This routine will find the facing (compass direction) from one location to another.      *
     44  *    Typical use of this is in find path and other 'monster' movement logic.                  *
     45  *                                                                                             *
     46  * INPUT:   x1,y1    -- X and Y coordinates for the source location. The coordinate 0,0 is     *
     47  *                      presumed to be the northwest corner of the map.                        *
     48  *                                                                                             *
     49  *          x2,y2    -- X and Y coordinates for the destination (target) location.             *
     50  *                                                                                             *
     51  * OUTPUT:  Returns with the facing from the first coordinate to the second coordinate. The    *
     52  *          value returned will range from 0 being North, increasing clockwise until reaching  *
     53  *          255 which is just shy of North in a Westerly direction.                            *
     54  *                                                                                             *
     55  * WARNINGS:   This routine is only accurate to the 8 primary compass directions. It is much   *
     56  *             faster than the Desired_Facing256() function so it should be used where speed   *
     57  *             is more important than accuracy.                                                *
     58  *                                                                                             *
     59  * HISTORY:                                                                                    *
     60  *   03/08/1996 JLB : Created.                                                                 *
     61  *=============================================================================================*/
     62 DirType Desired_Facing8(int x1, int y1, int x2, int y2)
     63 {
     64 	int index = 0;				// Facing composite value.
     65 
     66 	/*
     67 	**	Figure the absolute X difference. This determines
     68 	**	if the facing is leftward or not.
     69 	*/
     70 	int xdiff = x2-x1;
     71 	if (xdiff < 0) {
     72 		index |= 0x00C0;
     73 		xdiff = -xdiff;
     74 	}
     75 
     76 	/*
     77 	**	Figure the absolute Y difference. This determines
     78 	**	if the facing is downward or not. This also clarifies
     79 	**	exactly which quadrant the facing lies.
     80 	*/
     81 	int ydiff = y1-y2;
     82 	if (ydiff < 0) {
     83 		index ^= 0x0040;
     84 		ydiff = -ydiff;
     85 	}
     86 
     87 	/*
     88 	**	Determine which of the two direction offsets it bigger. The
     89 	**	offset direction that is bigger (X or Y) will indicate which
     90 	**	orthogonal direction the facing is closer to.
     91 	*/
     92 	unsigned bigger;
     93 	unsigned smaller;
     94 	if (xdiff < ydiff) {
     95 		smaller = xdiff;
     96 		bigger = ydiff;
     97 	} else {
     98 		smaller = ydiff;
     99 		bigger = xdiff;
    100 	}
    101 
    102 	/*
    103 	**	If on the diagonal, then incorporate this into the facing
    104 	**	and then bail. The facing is known.
    105 	*/
    106 	if (((bigger+1)/2) <= smaller) {
    107 		index += 0x0020;
    108 		return(DirType(index));
    109 	}
    110 
    111 	/*
    112 	**	Determine if the facing is closer to the Y axis or
    113 	**	the X axis.
    114 	*/
    115 	int adder = (index & 0x0040);
    116 	if (xdiff == bigger) {
    117 		adder ^= 0x0040;
    118 	}
    119 	index += adder;
    120 
    121 	return(DirType(index));
    122 }
    123 
    124 
    125 /***********************************************************************************************
    126  * Desired_Facing256 -- Determines facing from one coordinate to another.                      *
    127  *                                                                                             *
    128  *    This routine will figure the facing from the source coordinate toward the destination    *
    129  *    coordinate. Typically, this routine is used for movement and other 'monster' logic. It   *
    130  *    is more accurate than the corresponding Desired_Facing8() function, but is slower.       *
    131  *                                                                                             *
    132  * INPUT:   srcx, srcy  -- The source coordinate to determine the facing from.                 *
    133  *                                                                                             *
    134  *          dstx, dsty  -- The destination (or target) coordinate to determine the facing      *
    135  *                         toward.                                                             *
    136  *                                                                                             *
    137  * OUTPUT:  Returns with the facing from the source coordinate toward the destination          *
    138  *          coordinate with 0 being North increasing in a clockwise direction. 64 is East,     *
    139  *          128 is South, etc.                                                                 *
    140  *                                                                                             *
    141  * WARNINGS:   The coordinate 0,0 is presumed to be in the Northwest corner of the map.        *
    142  *             Although this routine is fast, it is not as fast as Desired_Facing8().          *
    143  *                                                                                             *
    144  * HISTORY:                                                                                    *
    145  *   03/08/1996 JLB : Created.                                                                 *
    146  *=============================================================================================*/
    147 DirType Desired_Facing256(int srcx, int srcy, int dstx, int dsty)
    148 {
    149 	int composite=0;		// Facing built from intermediate calculations.
    150 
    151 	/*
    152 	**	Fetch the absolute X difference. This also gives a clue as
    153 	**	to which hemisphere the direction lies.
    154 	*/
    155 	int xdiff = dstx - srcx;
    156 	if (xdiff < 0) {
    157 		composite |= 0x00C0;
    158 		xdiff = -xdiff;
    159 	}
    160 
    161 	/*
    162 	**	Fetch the absolute Y difference. This clarifies the exact
    163 	**	quadrant that the direction lies.
    164 	*/
    165 	int ydiff = srcy - dsty;
    166 	if (ydiff < 0) {
    167 		composite ^= 0x0040;
    168 		ydiff = -ydiff;
    169 	}
    170 
    171 	/*
    172 	**	Bail early if the coordinates are the same. This check also
    173 	**	has the added bonus of ensuring that checking for division
    174 	**	by zero is not needed in the following section.
    175 	*/
    176 	if (xdiff == 0 && ydiff == 0) return(DirType(0xFF));
    177 
    178 	/*
    179 	**	Determine which of the two direction offsets it bigger. The
    180 	**	offset direction that is bigger (X or Y) will indicate which
    181 	**	orthogonal direction the facing is closer to.
    182 	*/
    183 	unsigned bigger;
    184 	unsigned smaller;
    185 	if (xdiff < ydiff) {
    186 		smaller = xdiff;
    187 		bigger = ydiff;
    188 	} else {
    189 		smaller = ydiff;
    190 		bigger = xdiff;
    191 	}
    192 
    193 	/*
    194 	**	Now that the quadrant is known, we need to determine how far
    195 	**	from the orthogonal directions, the facing lies. This value
    196 	**	is calculated as a ratio from 0 (matches orthogonal) to 31
    197 	**	(matches diagonal).
    198 	*/
    199 	//lint -e414		Division by zero cannot occur here.
    200 	int frac = (smaller * 32U) / bigger;
    201 
    202 	/*
    203 	**	Given the quadrant and knowing whether the facing is closer
    204 	**	to the X or Y axis, we must make an adjustment toward the
    205 	**	subsequent quadrant if necessary.
    206 	*/
    207 	int adder = (composite & 0x0040);
    208 	if (xdiff > ydiff) {
    209 		adder ^= 0x0040;
    210 	}
    211 	if (adder) {
    212 		frac = (adder - frac)-1;
    213 	}
    214 
    215 	/*
    216 	**	Integrate the fraction value into the quadrant.
    217 	*/
    218 	composite += frac;
    219 
    220 	/*
    221 	**	Return with the final facing value.
    222 	*/
    223 	return(DirType(composite & 0x00FF));
    224 }