CnC_Remastered_Collection

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

COORD.CPP (26762B)


      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:   F:\projects\c&c\vcs\code\coord.cpv   2.18   16 Oct 1995 16:51:24   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 : COORD.CPP                                                    *
     24  *                                                                                             *
     25  *                   Programmer : Joe L. Bostic                                                *
     26  *                                                                                             *
     27  *                   Start Date : September 10, 1993                                           *
     28  *                                                                                             *
     29  *                  Last Update : January 7, 1995 [JLB]                                        *
     30  *                                                                                             *
     31  * Support code to handle the coordinate system is located in this module.                     *
     32  * Routines here will be called QUITE frequently during play and must be                       *
     33  * as efficient as possible.                                                                   *
     34  *                                                                                             *
     35  *---------------------------------------------------------------------------------------------*
     36  * Functions:                                                                                  *
     37  *   Cardinal_To_Fixed -- Converts cardinal numbers into a fixed point number.                 *
     38  *   Coord_Move -- Moves a coordinate an arbitrary direction for an arbitrary distance         *
     39  *   Coord_Scatter -- Determines a random coordinate from an anchor point.                     *
     40  *   Coord_Spillage_List -- Determines the offset list for cell spillage/occupation.           *
     41  *   Fixed_To_Cardinal -- Converts a fixed point number into a cardinal number.                *
     42  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     43 
     44 #include	"function.h"
     45 
     46 
     47 /***********************************************************************************************
     48  * Coord_Spillage_List -- Determines the offset list for cell spillage/occupation.             *
     49  *                                                                                             *
     50  *    This routine will take an arbitrary position and object size and return with a list of   *
     51  *    cell offsets from the current cell for all cells that are overlapped by the object. The  *
     52  *    first cell offset is always zero, so to just get the adjacent spill cell list, add one   *
     53  *    to the return pointer.                                                                   *
     54  *                                                                                             *
     55  * INPUT:   coord -- The coordinate to examine.                                                *
     56  *                                                                                             *
     57  *          maxsize -- The maximum width/height of the object (pixels).                        *
     58  *                                                                                             *
     59  * OUTPUT:  Returns with a pointer to a spillage list.                                         *
     60  *                                                                                             *
     61  * WARNINGS:   The algorithm is limited to working with a maxsize of 48 or less. Larger values *
     62  *             will generate an incomplete overlap list.                                       *
     63  *                                                                                             *
     64  * HISTORY:                                                                                    *
     65  *   11/06/1993 JLB : Created.                                                                 *
     66  *   03/25/1994 JLB : Added width optimization.                                                *
     67  *   04/29/1994 JLB : Converted to C.                                                          *
     68  *   06/03/1994 JLB : Converted to general purpose spillage functionality.                     *
     69  *   01/07/1995 JLB : Manually calculates spillage list for large objects.                     *
     70  *=============================================================================================*/
     71 short const * Coord_Spillage_List(COORDINATE coord, int maxsize)
     72 {
     73 	static short const _MoveSpillage[(int)FACING_COUNT+1][5] = {
     74 		{0, -MAP_CELL_W, REFRESH_EOL, 0, 0},						// N
     75 		{0, -MAP_CELL_W, 1, -(MAP_CELL_W-1), REFRESH_EOL},		// NE
     76 		{0, 1, REFRESH_EOL, 0, 0},										// E
     77 		{0, 1, MAP_CELL_W, MAP_CELL_W+1, REFRESH_EOL},			// SE
     78 		{0, MAP_CELL_W, REFRESH_EOL, 0, 0},							// S
     79 		{0, -1, MAP_CELL_W, MAP_CELL_W-1, REFRESH_EOL},			// SW
     80 		{0, -1, REFRESH_EOL, 0, 0},									// W
     81 		{0, -1, -MAP_CELL_W, -(MAP_CELL_W+1), REFRESH_EOL},	// NW
     82 		{0, REFRESH_EOL, 0, 0, 0}										// non-moving.
     83 //		{0, -MAP_CELL_W, -(MAP_CELL_W-1), 1, MAP_CELL_W+1, MAP_CELL_W, MAP_CELL_W-1, -1, -(MAP_CELL_W+1), REFRESH_EOL}
     84 	};
     85 	static short _manual[10];
     86 //;	00 = on axis
     87 //;	01 = below axis
     88 //;	10 = above axis
     89 //;	11 = undefined
     90 	static char const _SpillTable[16]	= {8,6,2,-1,0,7,1,-1,4,5,3,-1,-1,-1,-1,-1};
     91 	int	index=0;
     92 	int	x,y;
     93 
     94 	/*
     95 	**	For mondo-enourmo-gigundo objects, use a prebuilt mammoth table
     96 	**	that covers a 5x5 square region.
     97 	*/
     98 	if (maxsize > ICON_PIXEL_W * 2) {
     99 		static short const _gigundo[] = {
    100 			-((2*MAP_CELL_W)-2),-((2*MAP_CELL_W)-1),-((2*MAP_CELL_W)),-((2*MAP_CELL_W)+1),-((2*MAP_CELL_W)+2),
    101 			-((1*MAP_CELL_W)-2),-((1*MAP_CELL_W)-1),-((1*MAP_CELL_W)),-((1*MAP_CELL_W)+1),-((1*MAP_CELL_W)+2),
    102 			-((0*MAP_CELL_W)-2),-((0*MAP_CELL_W)-1),-((0*MAP_CELL_W)),-((0*MAP_CELL_W)+1),-((0*MAP_CELL_W)+2),
    103 			((1*MAP_CELL_W)-2),((1*MAP_CELL_W)-1),((1*MAP_CELL_W)),((1*MAP_CELL_W)+1),((1*MAP_CELL_W)+2),
    104 			+((2*MAP_CELL_W)-2),+((2*MAP_CELL_W)-1),+((2*MAP_CELL_W)),+((2*MAP_CELL_W)+1),+((2*MAP_CELL_W)+2),
    105 			REFRESH_EOL
    106 		};
    107 		return(&_gigundo[0]);
    108 	}
    109 
    110 	/*
    111 	**	For very large objects, build the overlap list by hand. This is time consuming, but
    112 	**	not nearly as time consuming as drawing even a single cell unnecessarily.
    113 	*/
    114 	if (maxsize > ICON_PIXEL_W) {
    115 		maxsize = MIN(maxsize, (ICON_PIXEL_W*2))/2;
    116 
    117 		x = Fixed_To_Cardinal(ICON_PIXEL_W, Coord_XLepton(coord));
    118 		y = Fixed_To_Cardinal(ICON_PIXEL_H, Coord_YLepton(coord));
    119 		int left = x-maxsize;
    120 		int right = x+maxsize;
    121 		int top = y-maxsize;
    122 		int bottom = y+maxsize;
    123 
    124 		_manual[index++] = 0;
    125 		if (left < 0) _manual[index++] = -1;
    126 		if (right >= ICON_PIXEL_W) _manual[index++] = 1;
    127 		if (top < 0) _manual[index++] = -MAP_CELL_W;
    128 		if (bottom >= ICON_PIXEL_H) _manual[index++] = MAP_CELL_W;
    129 		if (left < 0 && top < 0) _manual[index++] = -(MAP_CELL_W+1);
    130 		if (right >= ICON_PIXEL_W && bottom >= ICON_PIXEL_H) _manual[index++] = MAP_CELL_W+1;
    131 		if (left < 0 && bottom >= ICON_PIXEL_H) _manual[index++] = MAP_CELL_W-1;
    132 		if (right >= ICON_PIXEL_H && top < 0) _manual[index++] = -(MAP_CELL_W-1);
    133 		_manual[index] = REFRESH_EOL;
    134 		return(&_manual[0]);
    135 	}
    136 
    137 	/*
    138 	**	Determine the number of leptons "leeway" allowed this unit.
    139 	*/
    140 	int posval = Pixel2Lepton[(ICON_PIXEL_W-maxsize)/2];
    141 
    142 	x = Coord_XLepton(coord) - 0x0080;
    143 	y = Coord_YLepton(coord) - 0x0080;
    144 	if (y > posval) index |= 0x08;			// Spilling South.
    145 	if (y < -posval) index |= 0x04;			// Spilling North.
    146 	if (x > posval) index |= 0x02;			// Spilling East.
    147 	if (x < -posval) index |= 0x01;			// Spilling West.
    148 
    149 	return(&_MoveSpillage[_SpillTable[index]][0]);
    150 }
    151 
    152 
    153 /***********************************************************************************************
    154  * Coord_Move -- Moves a coordinate an arbitrary direction for an arbitrary distance           *
    155  *                                                                                             *
    156  *    This function will move a coordinate in a using SIN and COS arithmetic.                  *
    157  *                                                                                             *
    158  * INPUT:   start    -- The starting coordinate.                                               *
    159  *                                                                                             *
    160  *          dir      -- The direction to move the coordinate.                                  *
    161  *                                                                                             *
    162  *          distance -- The distance to move the coordinate position (in leptons).             *
    163  *                                                                                             *
    164  * OUTPUT:  Returns the new coordinate position.                                               *
    165  *                                                                                             *
    166  * WARNINGS:   This routine uses multiplies -- use with caution.                               *
    167  *                                                                                             *
    168  * HISTORY:                                                                                    *
    169  *   05/27/1994 JLB : Created.                                                                 *
    170  *=============================================================================================*/
    171 COORDINATE Coord_Move(COORDINATE start, register DirType dir, unsigned short distance)
    172 {
    173 	short x = Coord_X(start);
    174 	short y = Coord_Y(start);
    175 
    176 	Move_Point(x, y, dir, distance);
    177 	return(XY_Coord(x,y));
    178 #ifdef NEVER
    179 	static char const CosTable[256] = {
    180 		0x00,0x03,0x06,0x09,0x0c,0x0f,0x12,0x15,
    181 		0x18,0x1b,0x1e,0x21,0x24,0x27,0x2a,0x2d,
    182 		0x30,0x33,0x36,0x39,0x3b,0x3e,0x41,0x43,
    183 		0x46,0x49,0x4b,0x4e,0x50,0x52,0x55,0x57,
    184 		0x59,0x5b,0x5e,0x60,0x62,0x64,0x65,0x67,
    185 		0x69,0x6b,0x6c,0x6e,0x6f,0x71,0x72,0x74,
    186 		0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7b,
    187 		0x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7e,0x7e,
    188 
    189 		0x7f,0x7e,0x7e,0x7e,0x7e,0x7e,0x7d,0x7d,
    190 		0x7c,0x7b,0x7b,0x7a,0x79,0x78,0x77,0x76,
    191 		0x75,0x74,0x72,0x71,0x70,0x6e,0x6c,0x6b,
    192 		0x69,0x67,0x66,0x64,0x62,0x60,0x5e,0x5b,
    193 		0x59,0x57,0x55,0x52,0x50,0x4e,0x4b,0x49,
    194 		0x46,0x43,0x41,0x3e,0x3b,0x39,0x36,0x33,
    195 		0x30,0x2d,0x2a,0x27,0x24,0x21,0x1e,0x1b,
    196 		0x18,0x15,0x12,0x0f,0x0c,0x09,0x06,0x03,
    197 
    198 		0x00,0xfd,0xfa,0xf7,0xf4,0xf1,0xee,0xeb,
    199 		0xe8,0xe5,0xe2,0xdf,0xdc,0xd9,0xd6,0xd3,
    200 		0xd0,0xcd,0xca,0xc7,0xc5,0xc2,0xbf,0xbd,
    201 		0xba,0xb7,0xb5,0xb2,0xb0,0xae,0xab,0xa9,
    202 		0xa7,0xa5,0xa2,0xa0,0x9e,0x9c,0x9a,0x99,
    203 		0x97,0x95,0x94,0x92,0x91,0x8f,0x8e,0x8c,
    204 		0x8b,0x8a,0x89,0x88,0x87,0x86,0x85,0x85,
    205 		0x84,0x83,0x83,0x82,0x82,0x82,0x82,0x82,
    206 
    207 		0x82,0x82,0x82,0x82,0x82,0x82,0x83,0x83,
    208 		0x84,0x85,0x85,0x86,0x87,0x88,0x89,0x8a,
    209 		0x8b,0x8c,0x8e,0x8f,0x90,0x92,0x94,0x95,
    210 		0x97,0x99,0x9a,0x9c,0x9e,0xa0,0xa2,0xa5,
    211 		0xa7,0xa9,0xab,0xae,0xb0,0xb2,0xb5,0xb7,
    212 		0xba,0xbd,0xbf,0xc2,0xc5,0xc7,0xca,0xcd,
    213 		0xd0,0xd3,0xd6,0xd9,0xdc,0xdf,0xe2,0xe5,
    214 		0xe8,0xeb,0xee,0xf1,0xf4,0xf7,0xfa,0xfd,
    215 	};
    216 
    217 	static char const SinTable[256] = {
    218 		0x7f,0x7e,0x7e,0x7e,0x7e,0x7e,0x7d,0x7d,
    219 		0x7c,0x7b,0x7b,0x7a,0x79,0x78,0x77,0x76,
    220 		0x75,0x74,0x72,0x71,0x70,0x6e,0x6c,0x6b,
    221 		0x69,0x67,0x66,0x64,0x62,0x60,0x5e,0x5b,
    222 		0x59,0x57,0x55,0x52,0x50,0x4e,0x4b,0x49,
    223 		0x46,0x43,0x41,0x3e,0x3b,0x39,0x36,0x33,
    224 		0x30,0x2d,0x2a,0x27,0x24,0x21,0x1e,0x1b,
    225 		0x18,0x15,0x12,0x0f,0x0c,0x09,0x06,0x03,
    226 
    227 		0x00,0xfd,0xfa,0xf7,0xf4,0xf1,0xee,0xeb,
    228 		0xe8,0xe5,0xe2,0xdf,0xdc,0xd9,0xd6,0xd3,
    229 		0xd0,0xcd,0xca,0xc7,0xc5,0xc2,0xbf,0xbd,
    230 		0xba,0xb7,0xb5,0xb2,0xb0,0xae,0xab,0xa9,
    231 		0xa7,0xa5,0xa2,0xa0,0x9e,0x9c,0x9a,0x99,
    232 		0x97,0x95,0x94,0x92,0x91,0x8f,0x8e,0x8c,
    233 		0x8b,0x8a,0x89,0x88,0x87,0x86,0x85,0x85,
    234 		0x84,0x83,0x83,0x82,0x82,0x82,0x82,0x82,
    235 
    236 		0x82,0x82,0x82,0x82,0x82,0x82,0x83,0x83,
    237 		0x84,0x85,0x85,0x86,0x87,0x88,0x89,0x8a,
    238 		0x8b,0x8c,0x8e,0x8f,0x90,0x92,0x94,0x95,
    239 		0x97,0x99,0x9a,0x9c,0x9e,0xa0,0xa2,0xa5,
    240 		0xa7,0xa9,0xab,0xae,0xb0,0xb2,0xb5,0xb7,
    241 		0xba,0xbd,0xbf,0xc2,0xc5,0xc7,0xca,0xcd,
    242 		0xd0,0xd3,0xd6,0xd9,0xdc,0xdf,0xe2,0xe5,
    243 		0xe8,0xeb,0xee,0xf1,0xf4,0xf7,0xfa,0xfd,
    244 
    245 		0x00,0x03,0x06,0x09,0x0c,0x0f,0x12,0x15,
    246 		0x18,0x1b,0x1e,0x21,0x24,0x27,0x2a,0x2d,
    247 		0x30,0x33,0x36,0x39,0x3b,0x3e,0x41,0x43,
    248 		0x46,0x49,0x4b,0x4e,0x50,0x52,0x55,0x57,
    249 		0x59,0x5b,0x5e,0x60,0x62,0x64,0x65,0x67,
    250 		0x69,0x6b,0x6c,0x6e,0x6f,0x71,0x72,0x74,
    251 		0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7b,
    252 		0x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7e,0x7e,
    253 	};
    254 	distance = distance;		// Keep LINT quiet.
    255 
    256 	/*
    257 	**	Calculate and add in the X component of the move.
    258 	*/
    259 	_AX = CosTable[dir];
    260 	asm imul word ptr distance
    261 	asm shl ax,1
    262 	asm rcl dx,1
    263 	asm mov al,ah
    264 	asm mov ah,dl
    265 	_DX = _AX;
    266 	*((int*)&start) += _DX;
    267 //	asm add [word ptr start],ax
    268 
    269 	/*
    270 	**	Calculate and add in the Y component of the move.
    271 	*/
    272 	_AX = SinTable[dir];
    273 	asm imul word ptr distance
    274 	asm shl ax,1
    275 	asm rcl dx,1
    276 	asm mov al,ah
    277 	asm mov ah,dl
    278 	asm neg ax				// Subtraction needed because of inverted sine table.
    279 	_DX = _AX;
    280 	*(((int*)&start)+1) += _DX;
    281 //	asm add [word ptr start+2],ax
    282 
    283 	return(start);
    284 #endif
    285 }
    286 
    287 #ifdef OBSOLETE
    288 //BG: Note, this routine is replaced by assembly in COORDA.ASM
    289 /***********************************************************************************************
    290  * Cardinal_To_Fixed -- Converts cardinal numbers into a fixed point number.                   *
    291  *                                                                                             *
    292  *    This utility function will convert cardinal numbers into a fixed point fraction. The     *
    293  *    use of fixed point numbers occurs throughout the product -- since it is a convenient     *
    294  *    tool. The fixed point number is based on the formula:                                    *
    295  *                                                                                             *
    296  *       result = cardinal / base                                                              *
    297  *                                                                                             *
    298  *    The accuracy of the fixed point number is limited to 1/256 as the lowest and up to       *
    299  *    256 as the largest.                                                                      *
    300  *                                                                                             *
    301  * INPUT:   base     -- The key number to base the fraction about.                             *
    302  *                                                                                             *
    303  *          cardinal -- The other number (hey -- what do you call it?)                         *
    304  *                                                                                             *
    305  * OUTPUT:  Returns with the fixed point number of the "cardinal" parameter as it relates      *
    306  *          to the "base" parameter.                                                           *
    307  *                                                                                             *
    308  * WARNINGS:   none                                                                            *
    309  *                                                                                             *
    310  * HISTORY:                                                                                    *
    311  *   05/27/1994 JLB : Created.                                                                 *
    312  *=============================================================================================*/
    313 unsigned Cardinal_To_Fixed(unsigned base, unsigned cardinal)
    314 {
    315 	long	temp = 0;
    316 
    317 	if (base) {
    318 		*(unsigned*)(((char*)&temp)+1) = cardinal;		// Shift up by 8 bits.
    319 		_DX = FP_SEG(temp);
    320 		_AX = FP_OFF(temp);
    321 		asm div word ptr base
    322 		return(_AX);
    323 	}
    324 	return(0xFFFF);
    325 }
    326 #endif
    327 
    328 #ifdef OBSOLETE
    329 //BG: Note, this routine is replaced by assembly in COORDA.ASM
    330 /***********************************************************************************************
    331  * Fixed_To_Cardinal -- Converts a fixed point number into a cardinal number.                  *
    332  *                                                                                             *
    333  *    Use this routine to convert a fixed point number into a cardinal number.                 *
    334  *                                                                                             *
    335  * INPUT:   base     -- The base number that the original fixed point number was created from. *
    336  *                                                                                             *
    337  *          fixed    -- The fixed point number to convert.                                     *
    338  *                                                                                             *
    339  * OUTPUT:  Returns with the reconverted number.                                               *
    340  *                                                                                             *
    341  * WARNINGS:   none                                                                            *
    342  *                                                                                             *
    343  * HISTORY:                                                                                    *
    344  *   05/27/1994 JLB : Created.                                                                 *
    345  *=============================================================================================*/
    346 unsigned Fixed_To_Cardinal(unsigned base, unsigned fixed)
    347 {
    348 	unsigned long temp;
    349 
    350 	_AX = base;
    351 	asm mul word ptr fixed
    352 	_CX = _AX;
    353 	temp = ((unsigned long)MK_FP(_DX, _CX)) + 0x80;
    354 	if ( *((char*)&temp+3) ) {
    355 		return(0xFFFF);
    356 	}
    357 	return(*(unsigned*)(((char*)&temp)+1));
    358 }
    359 #endif
    360 
    361 
    362 /***********************************************************************************************
    363  * Coord_Scatter -- Determines a random coordinate from an anchor point.                       *
    364  *                                                                                             *
    365  *    This routine will perform a scatter algorithm on the specified                           *
    366  *    anchor point in order to return with another coordinate that is                          *
    367  *    randomly nearby the original. Typical use of this would be for                           *
    368  *    missile targeting.                                                                       *
    369  *                                                                                             *
    370  * INPUT:   coord    -- This is the anchor coordinate.                                         *
    371  *                                                                                             *
    372  *          distance -- This is the distance in pixels that the scatter                        *
    373  *                      should fall within.                                                    *
    374  *                                                                                             *
    375  *          lock     -- bool; Convert the new coordinate into a center                         *
    376  *                      cell based coordinate?                                                 *
    377  *                                                                                             *
    378  * OUTPUT:  Returns with a new coordinate that is nearby the original.                         *
    379  *                                                                                             *
    380  * WARNINGS:   Maximum pixel scatter distance is 255.                                          *
    381  *                                                                                             *
    382  * HISTORY:                                                                                    *
    383  *   02/01/1992 JLB : Created.                                                                 *
    384  *   05/13/1992 JLB : Only uses Random().                                                      *
    385  *=============================================================================================*/
    386 COORDINATE Coord_Scatter(COORDINATE coord, unsigned distance, bool lock)
    387 {
    388 	COORDINATE	newcoord;
    389 
    390 	newcoord = Coord_Move(coord, Random_Pick(DIR_N, DIR_MAX), distance);
    391 
    392 	if (newcoord & 0xC000C000L) newcoord = coord;
    393 
    394 	if (lock) {
    395 		newcoord = Coord_Snap(newcoord);
    396 	}
    397 
    398 	return(newcoord);
    399 }
    400 
    401 
    402 
    403 int __cdecl calcx(signed short param1, short distance)
    404 {
    405 	__asm {
    406 				  
    407 //#pragma aux calcx parm [ax] [bx] \
    408 	
    409 		movzx	eax, [param1]
    410 		mov	bx, [distance]
    411 		imul 	bx
    412 		shl	ax,1
    413 		rcl	dx,1
    414 		mov	al,ah
    415 		mov	ah,dl
    416 		cwd
    417 	}
    418 }
    419 
    420 
    421 int __cdecl calcy(signed short param1, short distance)
    422 {
    423 	__asm {
    424 				  
    425 //#pragma aux calcy parm [ax] [bx] \
    426 	
    427 		movzx	eax, [param1]
    428 		mov	bx, [distance]
    429 		imul bx
    430 		shl	ax,1
    431 		rcl	dx,1
    432 		mov	al,ah
    433 		mov	ah,dl
    434 		cwd
    435 		neg	eax
    436 	}
    437 }
    438 
    439 
    440 
    441 
    442 #if (0)
    443 extern int calcx(signed short, short distance);
    444 #pragma aux calcx parm [ax] [bx] \
    445 	modify [eax dx] \
    446 	value [eax]		= 				\
    447 	"imul bx"						\
    448 	"shl	ax,1"						\
    449 	"rcl	dx,1"						\
    450 	"mov	al,ah"					\
    451 	"mov	ah,dl"					\
    452 	"cwd"								\
    453 //	"and	eax,0FFFFh";
    454 
    455 extern int calcy(signed short, short distance);
    456 #pragma aux calcy parm [ax] [bx] \
    457 	modify [eax dx] \
    458 	value [eax]		= 				\
    459 	"imul bx"						\
    460 	"shl	ax,1"						\
    461 	"rcl	dx,1"						\
    462 	"mov	al,ah"					\
    463 	"mov	ah,dl"					\
    464 	"cwd"								\
    465 	"neg	eax";
    466 //	"and	eax,0FFFFh"				
    467 #endif
    468 
    469 
    470 
    471 void Move_Point(short &x, short &y, register DirType dir, unsigned short distance)
    472 {
    473 //	static char const CosTable[256] = {
    474 	static unsigned char const CosTable[256] = {
    475 		0x00,0x03,0x06,0x09,0x0c,0x0f,0x12,0x15,
    476 		0x18,0x1b,0x1e,0x21,0x24,0x27,0x2a,0x2d,
    477 		0x30,0x33,0x36,0x39,0x3b,0x3e,0x41,0x43,
    478 		0x46,0x49,0x4b,0x4e,0x50,0x52,0x55,0x57,
    479 		0x59,0x5b,0x5e,0x60,0x62,0x64,0x65,0x67,
    480 		0x69,0x6b,0x6c,0x6e,0x6f,0x71,0x72,0x74,
    481 		0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7b,
    482 		0x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7e,0x7e,
    483 
    484 		0x7f,0x7e,0x7e,0x7e,0x7e,0x7e,0x7d,0x7d,
    485 		0x7c,0x7b,0x7b,0x7a,0x79,0x78,0x77,0x76,
    486 		0x75,0x74,0x72,0x71,0x70,0x6e,0x6c,0x6b,
    487 		0x69,0x67,0x66,0x64,0x62,0x60,0x5e,0x5b,
    488 		0x59,0x57,0x55,0x52,0x50,0x4e,0x4b,0x49,
    489 		0x46,0x43,0x41,0x3e,0x3b,0x39,0x36,0x33,
    490 		0x30,0x2d,0x2a,0x27,0x24,0x21,0x1e,0x1b,
    491 		0x18,0x15,0x12,0x0f,0x0c,0x09,0x06,0x03,
    492 
    493 		0x00,0xfd,0xfa,0xf7,0xf4,0xf1,0xee,0xeb,
    494 		0xe8,0xe5,0xe2,0xdf,0xdc,0xd9,0xd6,0xd3,
    495 		0xd0,0xcd,0xca,0xc7,0xc5,0xc2,0xbf,0xbd,
    496 		0xba,0xb7,0xb5,0xb2,0xb0,0xae,0xab,0xa9,
    497 		0xa7,0xa5,0xa2,0xa0,0x9e,0x9c,0x9a,0x99,
    498 		0x97,0x95,0x94,0x92,0x91,0x8f,0x8e,0x8c,
    499 		0x8b,0x8a,0x89,0x88,0x87,0x86,0x85,0x85,
    500 		0x84,0x83,0x83,0x82,0x82,0x82,0x82,0x82,
    501 
    502 		0x82,0x82,0x82,0x82,0x82,0x82,0x83,0x83,
    503 		0x84,0x85,0x85,0x86,0x87,0x88,0x89,0x8a,
    504 		0x8b,0x8c,0x8e,0x8f,0x90,0x92,0x94,0x95,
    505 		0x97,0x99,0x9a,0x9c,0x9e,0xa0,0xa2,0xa5,
    506 		0xa7,0xa9,0xab,0xae,0xb0,0xb2,0xb5,0xb7,
    507 		0xba,0xbd,0xbf,0xc2,0xc5,0xc7,0xca,0xcd,
    508 		0xd0,0xd3,0xd6,0xd9,0xdc,0xdf,0xe2,0xe5,
    509 		0xe8,0xeb,0xee,0xf1,0xf4,0xf7,0xfa,0xfd,
    510 	};
    511 
    512 //	static char const SinTable[256] = {
    513 	static unsigned char const SinTable[256] = {
    514 		0x7f,0x7e,0x7e,0x7e,0x7e,0x7e,0x7d,0x7d,
    515 		0x7c,0x7b,0x7b,0x7a,0x79,0x78,0x77,0x76,
    516 		0x75,0x74,0x72,0x71,0x70,0x6e,0x6c,0x6b,
    517 		0x69,0x67,0x66,0x64,0x62,0x60,0x5e,0x5b,
    518 		0x59,0x57,0x55,0x52,0x50,0x4e,0x4b,0x49,
    519 		0x46,0x43,0x41,0x3e,0x3b,0x39,0x36,0x33,
    520 		0x30,0x2d,0x2a,0x27,0x24,0x21,0x1e,0x1b,
    521 		0x18,0x15,0x12,0x0f,0x0c,0x09,0x06,0x03,
    522 
    523 		0x00,0xfd,0xfa,0xf7,0xf4,0xf1,0xee,0xeb,
    524 		0xe8,0xe5,0xe2,0xdf,0xdc,0xd9,0xd6,0xd3,
    525 		0xd0,0xcd,0xca,0xc7,0xc5,0xc2,0xbf,0xbd,
    526 		0xba,0xb7,0xb5,0xb2,0xb0,0xae,0xab,0xa9,
    527 		0xa7,0xa5,0xa2,0xa0,0x9e,0x9c,0x9a,0x99,
    528 		0x97,0x95,0x94,0x92,0x91,0x8f,0x8e,0x8c,
    529 		0x8b,0x8a,0x89,0x88,0x87,0x86,0x85,0x85,
    530 		0x84,0x83,0x83,0x82,0x82,0x82,0x82,0x82,
    531 
    532 		0x82,0x82,0x82,0x82,0x82,0x82,0x83,0x83,
    533 		0x84,0x85,0x85,0x86,0x87,0x88,0x89,0x8a,
    534 		0x8b,0x8c,0x8e,0x8f,0x90,0x92,0x94,0x95,
    535 		0x97,0x99,0x9a,0x9c,0x9e,0xa0,0xa2,0xa5,
    536 		0xa7,0xa9,0xab,0xae,0xb0,0xb2,0xb5,0xb7,
    537 		0xba,0xbd,0xbf,0xc2,0xc5,0xc7,0xca,0xcd,
    538 		0xd0,0xd3,0xd6,0xd9,0xdc,0xdf,0xe2,0xe5,
    539 		0xe8,0xeb,0xee,0xf1,0xf4,0xf7,0xfa,0xfd,
    540 
    541 		0x00,0x03,0x06,0x09,0x0c,0x0f,0x12,0x15,
    542 		0x18,0x1b,0x1e,0x21,0x24,0x27,0x2a,0x2d,
    543 		0x30,0x33,0x36,0x39,0x3b,0x3e,0x41,0x43,
    544 		0x46,0x49,0x4b,0x4e,0x50,0x52,0x55,0x57,
    545 		0x59,0x5b,0x5e,0x60,0x62,0x64,0x65,0x67,
    546 		0x69,0x6b,0x6c,0x6e,0x6f,0x71,0x72,0x74,
    547 		0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7b,
    548 		0x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7e,0x7e,
    549 	};
    550 	distance = distance;		// Keep LINT quiet.
    551 
    552 #ifdef OBSOLETE
    553 	/*
    554 	**	Calculate and add in the X component of the move.
    555 	*/
    556 	_AX = CosTable[dir];
    557 	asm imul word ptr distance
    558 	asm shl ax,1
    559 	asm rcl dx,1
    560 	asm mov al,ah
    561 	asm mov ah,dl
    562 	_DX = _AX;
    563 	x += _DX;
    564 #else
    565 	//
    566 	// Have to declare table as unsigned otherwise MSVC complains, but we need to treat the actual values as signed.
    567 	//
    568 	// ST - 1/10/2019 11:20AM
    569 	//
    570 	char *cos_table = (char*)&CosTable[0];
    571 	x += calcx(cos_table[dir], distance);
    572 #endif
    573 //	asm add [word ptr start],ax
    574 
    575 #ifdef OBSOLETE
    576 	/*
    577 	**	Calculate and add in the Y component of the move.
    578 	*/
    579 	_AX = SinTable[dir];
    580 	asm imul word ptr distance
    581 	asm shl ax,1
    582 	asm rcl dx,1
    583 	asm mov al,ah
    584 	asm mov ah,dl
    585 	asm neg ax				// Subtraction needed because of inverted sine table.
    586 	_DX = _AX;
    587 	y += _DX;
    588 #else
    589 	//
    590 	// Have to declare table as unsigned otherwise MSVC complains, but we need to treat the actual values as signed.
    591 	//
    592 	// ST - 1/10/2019 11:20AM
    593 	//
    594 	char *sin_table = (char*)&SinTable[0];
    595 	y += calcy(sin_table[dir], distance);
    596 #endif
    597 //	asm add [word ptr start+2],ax
    598 
    599 }