CnC_Remastered_Collection

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

COORD.CPP (34622B)


      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/COORD.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 : COORD.CPP                                                    *
     24  *                                                                                             *
     25  *                   Programmer : Joe L. Bostic                                                *
     26  *                                                                                             *
     27  *                   Start Date : September 10, 1993                                           *
     28  *                                                                                             *
     29  *                  Last Update : July 22, 1996 [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_Cell -- Convert a coordinate into a cell number.                                    *
     39  *   Coord_Move -- Moves a coordinate an arbitrary direction for an arbitrary distance         *
     40  *   Coord_Scatter -- Determines a random coordinate from an anchor point.                     *
     41  *   Coord_Spillage_List -- Calculate a spillage list for the dirty rectangle specified.       *
     42  *   Coord_Spillage_List -- Determines the offset list for cell spillage/occupation.           *
     43  *   Distance -- Determines the cell distance between two cells.                               *
     44  *   Distance -- Determines the lepton distance between two coordinates.                       *
     45  *   Distance -- Fetch distance between two target values.                                     *
     46  *   Fixed_To_Cardinal -- Converts a fixed point number into a cardinal number.                *
     47  *   Normal_Move_Point -- Moves point with tilt compensation.                                  *
     48  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     49 
     50 #include	"function.h"
     51 
     52 
     53 /***********************************************************************************************
     54  * Coord_Cell -- Convert a coordinate into a cell number.                                      *
     55  *                                                                                             *
     56  *    This routine will convert the specified coordinate value into a cell number. This is     *
     57  *    useful to determine the map index number into the cell array that corresponds to a       *
     58  *    particular coordinate.                                                                   *
     59  *                                                                                             *
     60  * INPUT:   coord -- The coordinate to convert into a cell number.                             *
     61  *                                                                                             *
     62  * OUTPUT:  Returns with the cell number that corresponds to the coordinate specified.         *
     63  *                                                                                             *
     64  * WARNINGS:   none                                                                            *
     65  *                                                                                             *
     66  * HISTORY:                                                                                    *
     67  *   06/17/1996 JLB : Created.                                                                 *
     68  *=============================================================================================*/
     69 CELL Coord_Cell(COORDINATE coord)
     70 {
     71 	CELL_COMPOSITE cell;
     72 	cell.Cell = 0;
     73 	cell.Sub.X = ((COORD_COMPOSITE &)coord).Sub.X.Sub.Cell;
     74 	cell.Sub.Y = ((COORD_COMPOSITE &)coord).Sub.Y.Sub.Cell;
     75 	return(cell.Cell);
     76 //	return(XY_Cell(((COORD_COMPOSITE)coord).Sub.X, ((COORD_COMPOSITE)composite).Sub.Y));
     77 }
     78 
     79 
     80 /***********************************************************************************************
     81  * Distance -- Fetch distance between two target values.                                       *
     82  *                                                                                             *
     83  *    This routine will determine the lepton distance between the two specified target         *
     84  *    values.                                                                                  *
     85  *                                                                                             *
     86  * INPUT:   target1  -- First target value.                                                    *
     87  *                                                                                             *
     88  *          target2  -- Second target value.                                                   *
     89  *                                                                                             *
     90  * OUTPUT:  Returns with the lepton distance between the two target values.                    *
     91  *                                                                                             *
     92  * WARNINGS:   Be sure that the targets are legal before calling this routine. Otherwise, the  *
     93  *             return value is meaningless.                                                    *
     94  *                                                                                             *
     95  * HISTORY:                                                                                    *
     96  *   06/17/1996 JLB : Created.                                                                 *
     97  *=============================================================================================*/
     98 int Distance(TARGET target1, TARGET target2)
     99 {
    100 	return(Distance(As_Coord(target1), As_Coord(target2)));
    101 }
    102 
    103 
    104 /***********************************************************************************************
    105  * Distance -- Determines the lepton distance between two coordinates.                         *
    106  *                                                                                             *
    107  *    This routine is used to determine the distance between two coordinates. It uses the      *
    108  *    Dragon Strike method of distance determination and thus it is very fast.                 *
    109  *                                                                                             *
    110  * INPUT:   coord1   -- First coordinate.                                                      *
    111  *                                                                                             *
    112  *          coord2   -- Second coordinate.                                                     *
    113  *                                                                                             *
    114  * OUTPUT:  Returns the lepton distance between the two coordinates.                           *
    115  *                                                                                             *
    116  * WARNINGS:   none                                                                            *
    117  *                                                                                             *
    118  * HISTORY:                                                                                    *
    119  *   05/27/1994 JLB : Created.                                                                 *
    120  *=============================================================================================*/
    121 int Distance(COORDINATE coord1, COORDINATE coord2)
    122 {
    123 	int	diff1, diff2;
    124 
    125 	diff1 = Coord_Y(coord1) - Coord_Y(coord2);
    126 	if (diff1 < 0) diff1 = -diff1;
    127 	diff2 = Coord_X(coord1) - Coord_X(coord2);
    128 	if (diff2 < 0) diff2 = -diff2;
    129 	if (diff1 > diff2) {
    130 		return(diff1 + ((unsigned)diff2 / 2));
    131 	}
    132 	return(diff2 + ((unsigned)diff1 / 2));
    133 }
    134 
    135 
    136 /***********************************************************************************************
    137  * Coord_Spillage_List -- Determines the offset list for cell spillage/occupation.             *
    138  *                                                                                             *
    139  *    This routine will take an arbitrary position and object size and return with a list of   *
    140  *    cell offsets from the current cell for all cells that are overlapped by the object. The  *
    141  *    first cell offset is always zero, so to just get the adjacent spill cell list, add one   *
    142  *    to the return pointer.                                                                   *
    143  *                                                                                             *
    144  * INPUT:   coord -- The coordinate to examine.                                                *
    145  *                                                                                             *
    146  *          maxsize -- The maximum width/height of the object (pixels).                        *
    147  *                                                                                             *
    148  * OUTPUT:  Returns with a pointer to a spillage list.                                         *
    149  *                                                                                             *
    150  * WARNINGS:   The algorithm is limited to working with a maxsize of 48 or less. Larger values *
    151  *             will generate an incomplete overlap list.                                       *
    152  *                                                                                             *
    153  * HISTORY:                                                                                    *
    154  *   11/06/1993 JLB : Created.                                                                 *
    155  *   03/25/1994 JLB : Added width optimization.                                                *
    156  *   04/29/1994 JLB : Converted to C.                                                          *
    157  *   06/03/1994 JLB : Converted to general purpose spillage functionality.                     *
    158  *   01/07/1995 JLB : Manually calculates spillage list for large objects.                     *
    159  *=============================================================================================*/
    160 short const * Coord_Spillage_List(COORDINATE coord, int maxsize)
    161 {
    162 	static short const _MoveSpillage[(int)FACING_COUNT+1][5] = {
    163 		{0, -MAP_CELL_W, REFRESH_EOL, 0, 0},						// N
    164 		{0, -MAP_CELL_W, 1, -(MAP_CELL_W-1), REFRESH_EOL},		// NE
    165 		{0, 1, REFRESH_EOL, 0, 0},										// E
    166 		{0, 1, MAP_CELL_W, MAP_CELL_W+1, REFRESH_EOL},			// SE
    167 		{0, MAP_CELL_W, REFRESH_EOL, 0, 0},							// S
    168 		{0, -1, MAP_CELL_W, MAP_CELL_W-1, REFRESH_EOL},			// SW
    169 		{0, -1, REFRESH_EOL, 0, 0},									// W
    170 		{0, -1, -MAP_CELL_W, -(MAP_CELL_W+1), REFRESH_EOL},	// NW
    171 		{0, REFRESH_EOL, 0, 0, 0}										// non-moving.
    172 	};
    173 	static short _manual[10];
    174 //;	00 = on axis
    175 //;	01 = below axis
    176 //;	10 = above axis
    177 //;	11 = undefined
    178 	static signed char const _SpillTable[16]	= {8,6,2,-1,0,7,1,-1,4,5,3,-1,-1,-1,-1,-1};
    179 	int	index=0;
    180 	int	x,y;
    181 
    182 	/*
    183 	**	For mondo-enourmo-gigundo objects, use a prebuilt mammoth table
    184 	**	that covers a 5x5 square region.
    185 	*/
    186 	if (maxsize > ICON_PIXEL_W * 2) {
    187 		static short const _gigundo[] = {
    188 			-((2*MAP_CELL_W)-2),-((2*MAP_CELL_W)-1),-((2*MAP_CELL_W)),-((2*MAP_CELL_W)+1),-((2*MAP_CELL_W)+2),
    189 			-((1*MAP_CELL_W)-2),-((1*MAP_CELL_W)-1),-((1*MAP_CELL_W)),-((1*MAP_CELL_W)+1),-((1*MAP_CELL_W)+2),
    190 			-((0*MAP_CELL_W)-2),-((0*MAP_CELL_W)-1),-((0*MAP_CELL_W)),-((0*MAP_CELL_W)+1),-((0*MAP_CELL_W)+2),
    191 			((1*MAP_CELL_W)-2),((1*MAP_CELL_W)-1),((1*MAP_CELL_W)),((1*MAP_CELL_W)+1),((1*MAP_CELL_W)+2),
    192 			+((2*MAP_CELL_W)-2),+((2*MAP_CELL_W)-1),+((2*MAP_CELL_W)),+((2*MAP_CELL_W)+1),+((2*MAP_CELL_W)+2),
    193 			REFRESH_EOL
    194 		};
    195 		return(&_gigundo[0]);
    196 	}
    197 
    198 	/*
    199 	**	For very large objects, build the overlap list by hand. This is time consuming, but
    200 	**	not nearly as time consuming as drawing even a single cell unnecessarily.
    201 	*/
    202 	if (maxsize > ICON_PIXEL_W) {
    203 		maxsize = min(maxsize, (ICON_PIXEL_W*2))/2;
    204 
    205 		x = (ICON_PIXEL_W * Coord_XLepton(coord)) / ICON_LEPTON_W;
    206 		y = (ICON_PIXEL_H * Coord_YLepton(coord)) / ICON_LEPTON_H;
    207 		int left = x-maxsize;
    208 		int right = x+maxsize;
    209 		int top = y-maxsize;
    210 		int bottom = y+maxsize;
    211 
    212 		_manual[index++] = 0;
    213 		if (left < 0) _manual[index++] = -1;
    214 		if (right >= ICON_PIXEL_W) _manual[index++] = 1;
    215 		if (top < 0) _manual[index++] = -MAP_CELL_W;
    216 		if (bottom >= ICON_PIXEL_H) _manual[index++] = MAP_CELL_W;
    217 		if (left < 0 && top < 0) _manual[index++] = -(MAP_CELL_W+1);
    218 		if (right >= ICON_PIXEL_W && bottom >= ICON_PIXEL_H) _manual[index++] = MAP_CELL_W+1;
    219 		if (left < 0 && bottom >= ICON_PIXEL_H) _manual[index++] = MAP_CELL_W-1;
    220 		if (right >= ICON_PIXEL_H && top < 0) _manual[index++] = -(MAP_CELL_W-1);
    221 		_manual[index] = REFRESH_EOL;
    222 		return(&_manual[0]);
    223 	}
    224 
    225 	/*
    226 	**	Determine the number of leptons "leeway" allowed this unit.
    227 	*/
    228 	int posval = Pixel2Lepton[(ICON_PIXEL_W-maxsize)/2];
    229 
    230 	x = Coord_XLepton(coord) - 0x0080;
    231 	y = Coord_YLepton(coord) - 0x0080;
    232 	if (y > posval) index |= 0x08;			// Spilling South.
    233 	if (y < -posval) index |= 0x04;			// Spilling North.
    234 	if (x > posval) index |= 0x02;			// Spilling East.
    235 	if (x < -posval) index |= 0x01;			// Spilling West.
    236 
    237 	return(&_MoveSpillage[_SpillTable[index]][0]);
    238 }
    239 
    240 
    241 /***********************************************************************************************
    242  * Coord_Spillage_List -- Calculate a spillage list for the dirty rectangle specified.         *
    243  *                                                                                             *
    244  *    Given a center coordinate and a dirty rectangle, calcuate a cell offset list for         *
    245  *    determining such things as overlap and redraw logic. Optionally, the center cell         *
    246  *    location will not be part of the list.                                                   *
    247  *                                                                                             *
    248  * INPUT:   coord -- The center coordinate that the dirty rectangle is based off of.           *
    249  *                                                                                             *
    250  *          rect  -- Reference to the dirty rectangle.                                         *
    251  *                                                                                             *
    252  *          nocenter -- If true, then the center cell offset will not be part of the spillage  *
    253  *                      list returned. This is handy when the center cell is known to be       *
    254  *                      processed by some other method and it can be safely and efficiently    *
    255  *                      ignored by the list generated.                                         *
    256  *                                                                                             *
    257  * OUTPUT:  Returns with a pointer to the spillage list that corresponds to the data           *
    258  *          specified. This is a pointer to a static buffer and as such it will only be valid  *
    259  *          until the next time that this routine is called.                                   *
    260  *                                                                                             *
    261  * WARNINGS:   none                                                                            *
    262  *                                                                                             *
    263  * HISTORY:                                                                                    *
    264  *   07/22/1996 JLB : Created.                                                                 *
    265  *=============================================================================================*/
    266 short const * Coord_Spillage_List(COORDINATE coord, Rect const & rect, bool nocenter)
    267 {
    268 	if (!rect.Is_Valid()) {
    269 		static short const _list[] = {REFRESH_EOL};
    270 		return(_list);
    271 	}
    272 
    273 	CELL coordcell = Coord_Cell(coord);
    274 	LEPTON x = Coord_X(coord);
    275 	LEPTON y = Coord_Y(coord);
    276 
    277 	/*
    278 	**	Add the rectangle values to the coordinate in order to normalize the start and end
    279 	**	corners of the rectangle. The values are now absolute to the real game world rather
    280 	**	than relative to the coordinate.
    281 	*/
    282 	LEPTON_COMPOSITE startx;
    283 	LEPTON_COMPOSITE starty;
    284 	LEPTON_COMPOSITE endx;
    285 	LEPTON_COMPOSITE endy;
    286 	startx.Raw = (int)x + (short)Pixel_To_Lepton(rect.X);
    287 	starty.Raw = (int)y + (short)Pixel_To_Lepton(rect.Y);
    288 	endx.Raw = startx.Raw + Pixel_To_Lepton(rect.Width-1);
    289 	endy.Raw = starty.Raw + Pixel_To_Lepton(rect.Height-1);
    290 
    291 	/*
    292 	**	Determine the upper left and lower right cell indexes. This is a simple conversion from
    293 	**	their lepton counterpart. These cells values are used to form the bounding box for the
    294 	**	map offset list.
    295 	*/
    296 	int cellx = startx.Sub.Cell;
    297 	int cellx2 = endx.Sub.Cell;
    298 	int celly = starty.Sub.Cell;
    299 	int celly2 = endy.Sub.Cell;
    300 
    301 	/*
    302 	**	Generate the spillage list by counting off the rows and colums of the cells
    303 	**	that are affected. This is easy since the upper left and lower right corner cells
    304 	**	are known.
    305 	*/
    306 	int count = 0;
    307 	static short _spillagelist[128];
    308 	short * ptr = _spillagelist;
    309 	for (int yy = celly; yy <= celly2; yy++) {
    310 		for (int xx = cellx; xx <= cellx2; xx++) {
    311 			short offset = (XY_Cell(xx, yy) - coordcell);
    312 			if (!nocenter || offset != 0) {
    313 				*ptr++ = offset;
    314 				count++;
    315 				if (count+2 >= ARRAY_SIZE(_spillagelist)) break;
    316 			}
    317 		}
    318 		if (count+2 >= ARRAY_SIZE(_spillagelist)) break;
    319 	}
    320 
    321 	/*
    322 	**	Cap the list with the end of list marker and then return a pointer
    323 	**	to the completed list.
    324 	*/
    325 	*ptr = REFRESH_EOL;
    326 	return(_spillagelist);
    327 }
    328 
    329 
    330 /***********************************************************************************************
    331  * Coord_Move -- Moves a coordinate an arbitrary direction for an arbitrary distance           *
    332  *                                                                                             *
    333  *    This function will move a coordinate in a using SIN and COS arithmetic.                  *
    334  *                                                                                             *
    335  * INPUT:   start    -- The starting coordinate.                                               *
    336  *                                                                                             *
    337  *          dir      -- The direction to move the coordinate.                                  *
    338  *                                                                                             *
    339  *          distance -- The distance to move the coordinate position (in leptons).             *
    340  *                                                                                             *
    341  * OUTPUT:  Returns the new coordinate position.                                               *
    342  *                                                                                             *
    343  * WARNINGS:   This routine uses multiplies -- use with caution.                               *
    344  *                                                                                             *
    345  * HISTORY:                                                                                    *
    346  *   05/27/1994 JLB : Created.                                                                 *
    347  *=============================================================================================*/
    348 COORDINATE Coord_Move(COORDINATE start, register DirType dir, unsigned short distance)
    349 {
    350 #ifdef NEVER
    351 	short x = Coord_X(start);
    352 	short y = Coord_Y(start);
    353 
    354 	Move_Point(x, y, dir, distance);
    355 	return(XY_Coord(x,y));
    356 #endif
    357 
    358 	Move_Point(*(short *)&start, *(((short *)&start)+1), dir, distance);
    359 	return(start);
    360 }
    361 
    362 
    363 /***********************************************************************************************
    364  * Coord_Scatter -- Determines a random coordinate from an anchor point.                       *
    365  *                                                                                             *
    366  *    This routine will perform a scatter algorithm on the specified                           *
    367  *    anchor point in order to return with another coordinate that is                          *
    368  *    randomly nearby the original. Typical use of this would be for                           *
    369  *    missile targeting.                                                                       *
    370  *                                                                                             *
    371  * INPUT:   coord    -- This is the anchor coordinate.                                         *
    372  *                                                                                             *
    373  *          distance -- This is the distance in pixels that the scatter                        *
    374  *                      should fall within.                                                    *
    375  *                                                                                             *
    376  *          lock     -- bool; Convert the new coordinate into a center                         *
    377  *                      cell based coordinate?                                                 *
    378  *                                                                                             *
    379  * OUTPUT:  Returns with a new coordinate that is nearby the original.                         *
    380  *                                                                                             *
    381  * WARNINGS:   Maximum pixel scatter distance is 255.                                          *
    382  *                                                                                             *
    383  * HISTORY:                                                                                    *
    384  *   02/01/1992 JLB : Created.                                                                 *
    385  *   05/13/1992 JLB : Only uses Random().                                                      *
    386  *=============================================================================================*/
    387 COORDINATE Coord_Scatter(COORDINATE coord, unsigned distance, bool lock)
    388 {
    389 	COORDINATE	newcoord;
    390 
    391 	newcoord = Coord_Move(coord, Random_Pick(DIR_N, DIR_MAX), distance);
    392 
    393 	if (newcoord & HIGH_COORD_MASK) newcoord = coord;
    394 
    395 	if (lock) {
    396 		newcoord = Coord_Snap(newcoord);
    397 	}
    398 
    399 	return(newcoord);
    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 #if (0)
    441 extern int calcx(signed short, short distance);
    442 #pragma aux calcx parm [ax] [bx] \
    443 	modify [eax dx] \
    444 	value [eax]		= 				\
    445 	"imul bx"						\
    446 	"shl	ax,1"						\
    447 	"rcl	dx,1"						\
    448 	"mov	al,ah"					\
    449 	"mov	ah,dl"					\
    450 	"cwd"								\
    451 //	"and	eax,0FFFFh";
    452 
    453 extern int calcy(signed short, short distance);
    454 #pragma aux calcy parm [ax] [bx] \
    455 	modify [eax dx] \
    456 	value [eax]		= 				\
    457 	"imul bx"						\
    458 	"shl	ax,1"						\
    459 	"rcl	dx,1"						\
    460 	"mov	al,ah"					\
    461 	"mov	ah,dl"					\
    462 	"cwd"								\
    463 	"neg	eax";
    464 //	"and	eax,0FFFFh"				\
    465 
    466 #endif
    467 
    468 void Move_Point(short &x, short &y, register DirType dir, unsigned short distance)
    469 {
    470 	static unsigned char const CosTable[256] = {
    471 		0x00,0x03,0x06,0x09,0x0c,0x0f,0x12,0x15,
    472 		0x18,0x1b,0x1e,0x21,0x24,0x27,0x2a,0x2d,
    473 		0x30,0x33,0x36,0x39,0x3b,0x3e,0x41,0x43,
    474 		0x46,0x49,0x4b,0x4e,0x50,0x52,0x55,0x57,
    475 		0x59,0x5b,0x5e,0x60,0x62,0x64,0x65,0x67,
    476 		0x69,0x6b,0x6c,0x6e,0x6f,0x71,0x72,0x74,
    477 		0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7b,
    478 		0x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7e,0x7e,
    479 
    480 		0x7f,0x7e,0x7e,0x7e,0x7e,0x7e,0x7d,0x7d,
    481 		0x7c,0x7b,0x7b,0x7a,0x79,0x78,0x77,0x76,
    482 		0x75,0x74,0x72,0x71,0x70,0x6e,0x6c,0x6b,
    483 		0x69,0x67,0x66,0x64,0x62,0x60,0x5e,0x5b,
    484 		0x59,0x57,0x55,0x52,0x50,0x4e,0x4b,0x49,
    485 		0x46,0x43,0x41,0x3e,0x3b,0x39,0x36,0x33,
    486 		0x30,0x2d,0x2a,0x27,0x24,0x21,0x1e,0x1b,
    487 		0x18,0x15,0x12,0x0f,0x0c,0x09,0x06,0x03,
    488 
    489 		0x00,0xfd,0xfa,0xf7,0xf4,0xf1,0xee,0xeb,
    490 		0xe8,0xe5,0xe2,0xdf,0xdc,0xd9,0xd6,0xd3,
    491 		0xd0,0xcd,0xca,0xc7,0xc5,0xc2,0xbf,0xbd,
    492 		0xba,0xb7,0xb5,0xb2,0xb0,0xae,0xab,0xa9,
    493 		0xa7,0xa5,0xa2,0xa0,0x9e,0x9c,0x9a,0x99,
    494 		0x97,0x95,0x94,0x92,0x91,0x8f,0x8e,0x8c,
    495 		0x8b,0x8a,0x89,0x88,0x87,0x86,0x85,0x85,
    496 		0x84,0x83,0x83,0x82,0x82,0x82,0x82,0x82,
    497 
    498 		0x82,0x82,0x82,0x82,0x82,0x82,0x83,0x83,
    499 		0x84,0x85,0x85,0x86,0x87,0x88,0x89,0x8a,
    500 		0x8b,0x8c,0x8e,0x8f,0x90,0x92,0x94,0x95,
    501 		0x97,0x99,0x9a,0x9c,0x9e,0xa0,0xa2,0xa5,
    502 		0xa7,0xa9,0xab,0xae,0xb0,0xb2,0xb5,0xb7,
    503 		0xba,0xbd,0xbf,0xc2,0xc5,0xc7,0xca,0xcd,
    504 		0xd0,0xd3,0xd6,0xd9,0xdc,0xdf,0xe2,0xe5,
    505 		0xe8,0xeb,0xee,0xf1,0xf4,0xf7,0xfa,0xfd,
    506 	};
    507 
    508 	static unsigned char const SinTable[256] = {
    509 		0x7f,0x7e,0x7e,0x7e,0x7e,0x7e,0x7d,0x7d,
    510 		0x7c,0x7b,0x7b,0x7a,0x79,0x78,0x77,0x76,
    511 		0x75,0x74,0x72,0x71,0x70,0x6e,0x6c,0x6b,
    512 		0x69,0x67,0x66,0x64,0x62,0x60,0x5e,0x5b,
    513 		0x59,0x57,0x55,0x52,0x50,0x4e,0x4b,0x49,
    514 		0x46,0x43,0x41,0x3e,0x3b,0x39,0x36,0x33,
    515 		0x30,0x2d,0x2a,0x27,0x24,0x21,0x1e,0x1b,
    516 		0x18,0x15,0x12,0x0f,0x0c,0x09,0x06,0x03,
    517 
    518 		0x00,0xfd,0xfa,0xf7,0xf4,0xf1,0xee,0xeb,
    519 		0xe8,0xe5,0xe2,0xdf,0xdc,0xd9,0xd6,0xd3,
    520 		0xd0,0xcd,0xca,0xc7,0xc5,0xc2,0xbf,0xbd,
    521 		0xba,0xb7,0xb5,0xb2,0xb0,0xae,0xab,0xa9,
    522 		0xa7,0xa5,0xa2,0xa0,0x9e,0x9c,0x9a,0x99,
    523 		0x97,0x95,0x94,0x92,0x91,0x8f,0x8e,0x8c,
    524 		0x8b,0x8a,0x89,0x88,0x87,0x86,0x85,0x85,
    525 		0x84,0x83,0x83,0x82,0x82,0x82,0x82,0x82,
    526 
    527 		0x82,0x82,0x82,0x82,0x82,0x82,0x83,0x83,
    528 		0x84,0x85,0x85,0x86,0x87,0x88,0x89,0x8a,
    529 		0x8b,0x8c,0x8e,0x8f,0x90,0x92,0x94,0x95,
    530 		0x97,0x99,0x9a,0x9c,0x9e,0xa0,0xa2,0xa5,
    531 		0xa7,0xa9,0xab,0xae,0xb0,0xb2,0xb5,0xb7,
    532 		0xba,0xbd,0xbf,0xc2,0xc5,0xc7,0xca,0xcd,
    533 		0xd0,0xd3,0xd6,0xd9,0xdc,0xdf,0xe2,0xe5,
    534 		0xe8,0xeb,0xee,0xf1,0xf4,0xf7,0xfa,0xfd,
    535 
    536 		0x00,0x03,0x06,0x09,0x0c,0x0f,0x12,0x15,
    537 		0x18,0x1b,0x1e,0x21,0x24,0x27,0x2a,0x2d,
    538 		0x30,0x33,0x36,0x39,0x3b,0x3e,0x41,0x43,
    539 		0x46,0x49,0x4b,0x4e,0x50,0x52,0x55,0x57,
    540 		0x59,0x5b,0x5e,0x60,0x62,0x64,0x65,0x67,
    541 		0x69,0x6b,0x6c,0x6e,0x6f,0x71,0x72,0x74,
    542 		0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7b,
    543 		0x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7e,0x7e,
    544 	};
    545 	distance = distance;		// Keep LINT quiet.
    546 
    547 #ifdef OBSOLETE
    548 	/*
    549 	**	Calculate and add in the X component of the move.
    550 	*/
    551 	_AX = CosTable[dir];
    552 	asm imul word ptr distance
    553 	asm shl ax,1
    554 	asm rcl dx,1
    555 	asm mov al,ah
    556 	asm mov ah,dl
    557 	_DX = _AX;
    558 	x += _DX;
    559 #else
    560 	//
    561 	// Have to declare table as unsigned otherwise MSVC complains, but we need to treat the actual values as signed.
    562 	//
    563 	static const char *_cos_table = (char*)&CosTable[0];
    564 	x += calcx(_cos_table[dir], distance);
    565 #endif
    566 //	asm add [word ptr start],ax
    567 
    568 #ifdef OBSOLETE
    569 	/*
    570 	**	Calculate and add in the Y component of the move.
    571 	*/
    572 	_AX = SinTable[dir];
    573 	asm imul word ptr distance
    574 	asm shl ax,1
    575 	asm rcl dx,1
    576 	asm mov al,ah
    577 	asm mov ah,dl
    578 	asm neg ax				// Subtraction needed because of inverted sine table.
    579 	_DX = _AX;
    580 	y += _DX;
    581 #else
    582 	//
    583 	// Have to declare table as unsigned otherwise MSVC complains, but we need to treat the actual values as signed.
    584 	//
    585 	static const char *_sin_table = (char*)&SinTable[0];
    586 	y += calcy(_sin_table[dir], distance);
    587 #endif
    588 //	asm add [word ptr start+2],ax
    589 
    590 }
    591 
    592 
    593 /***********************************************************************************************
    594  * Normal_Move_Point -- Moves point with tilt compensation.                                    *
    595  *                                                                                             *
    596  *    This routine will move the point in the direction and distance specified but it will     *
    597  *    take into account the tilt of the playing field. Typical use of this routine is to       *
    598  *    determine positioning as it relates to the playfield. Turrets are a good example of      *
    599  *    this.                                                                                    *
    600  *                                                                                             *
    601  * INPUT:   x,y   -- References to the coordinates to adjust.                                  *
    602  *                                                                                             *
    603  *          dir   -- The direction of the desired movement.                                    *
    604  *                                                                                             *
    605  *          distance -- The distance (in coordinate units) to move the point.                  *
    606  *                                                                                             *
    607  * OUTPUT:  none                                                                               *
    608  *                                                                                             *
    609  * WARNINGS:   none                                                                            *
    610  *                                                                                             *
    611  * HISTORY:                                                                                    *
    612  *   12/19/1995 JLB : Created.                                                                 *
    613  *=============================================================================================*/
    614 // Loss of precision in initializations (8 bits to 7 bits) warning. Hmmm.. can this be fixed?
    615 //lint -e569
    616 void Normal_Move_Point(short &x, short &y, register DirType dir, unsigned short distance)
    617 {
    618 	static unsigned char const CosTable[256] = {
    619 		0x00,0x03,0x06,0x09,0x0c,0x0f,0x12,0x15,
    620 		0x18,0x1b,0x1e,0x21,0x24,0x27,0x2a,0x2d,
    621 		0x30,0x33,0x36,0x39,0x3b,0x3e,0x41,0x43,
    622 		0x46,0x49,0x4b,0x4e,0x50,0x52,0x55,0x57,
    623 		0x59,0x5b,0x5e,0x60,0x62,0x64,0x65,0x67,
    624 		0x69,0x6b,0x6c,0x6e,0x6f,0x71,0x72,0x74,
    625 		0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7b,
    626 		0x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7e,0x7e,
    627 
    628 		0x7f,0x7e,0x7e,0x7e,0x7e,0x7e,0x7d,0x7d,
    629 		0x7c,0x7b,0x7b,0x7a,0x79,0x78,0x77,0x76,
    630 		0x75,0x74,0x72,0x71,0x70,0x6e,0x6c,0x6b,
    631 		0x69,0x67,0x66,0x64,0x62,0x60,0x5e,0x5b,
    632 		0x59,0x57,0x55,0x52,0x50,0x4e,0x4b,0x49,
    633 		0x46,0x43,0x41,0x3e,0x3b,0x39,0x36,0x33,
    634 		0x30,0x2d,0x2a,0x27,0x24,0x21,0x1e,0x1b,
    635 		0x18,0x15,0x12,0x0f,0x0c,0x09,0x06,0x03,
    636 
    637 		0x00,0xfd,0xfa,0xf7,0xf4,0xf1,0xee,0xeb,
    638 		0xe8,0xe5,0xe2,0xdf,0xdc,0xd9,0xd6,0xd3,
    639 		0xd0,0xcd,0xca,0xc7,0xc5,0xc2,0xbf,0xbd,
    640 		0xba,0xb7,0xb5,0xb2,0xb0,0xae,0xab,0xa9,
    641 		0xa7,0xa5,0xa2,0xa0,0x9e,0x9c,0x9a,0x99,
    642 		0x97,0x95,0x94,0x92,0x91,0x8f,0x8e,0x8c,
    643 		0x8b,0x8a,0x89,0x88,0x87,0x86,0x85,0x85,
    644 		0x84,0x83,0x83,0x82,0x82,0x82,0x82,0x82,
    645 
    646 		0x82,0x82,0x82,0x82,0x82,0x82,0x83,0x83,
    647 		0x84,0x85,0x85,0x86,0x87,0x88,0x89,0x8a,
    648 		0x8b,0x8c,0x8e,0x8f,0x90,0x92,0x94,0x95,
    649 		0x97,0x99,0x9a,0x9c,0x9e,0xa0,0xa2,0xa5,
    650 		0xa7,0xa9,0xab,0xae,0xb0,0xb2,0xb5,0xb7,
    651 		0xba,0xbd,0xbf,0xc2,0xc5,0xc7,0xca,0xcd,
    652 		0xd0,0xd3,0xd6,0xd9,0xdc,0xdf,0xe2,0xe5,
    653 		0xe8,0xeb,0xee,0xf1,0xf4,0xf7,0xfa,0xfd,
    654 	};
    655 
    656 	static unsigned char const SinTable[256] = {
    657 		0x7f,0x7e,0x7e,0x7e,0x7e,0x7e,0x7d,0x7d,
    658 		0x7c,0x7b,0x7b,0x7a,0x79,0x78,0x77,0x76,
    659 		0x75,0x74,0x72,0x71,0x70,0x6e,0x6c,0x6b,
    660 		0x69,0x67,0x66,0x64,0x62,0x60,0x5e,0x5b,
    661 		0x59,0x57,0x55,0x52,0x50,0x4e,0x4b,0x49,
    662 		0x46,0x43,0x41,0x3e,0x3b,0x39,0x36,0x33,
    663 		0x30,0x2d,0x2a,0x27,0x24,0x21,0x1e,0x1b,
    664 		0x18,0x15,0x12,0x0f,0x0c,0x09,0x06,0x03,
    665 
    666 		0x00,0xfd,0xfa,0xf7,0xf4,0xf1,0xee,0xeb,
    667 		0xe8,0xe5,0xe2,0xdf,0xdc,0xd9,0xd6,0xd3,
    668 		0xd0,0xcd,0xca,0xc7,0xc5,0xc2,0xbf,0xbd,
    669 		0xba,0xb7,0xb5,0xb2,0xb0,0xae,0xab,0xa9,
    670 		0xa7,0xa5,0xa2,0xa0,0x9e,0x9c,0x9a,0x99,
    671 		0x97,0x95,0x94,0x92,0x91,0x8f,0x8e,0x8c,
    672 		0x8b,0x8a,0x89,0x88,0x87,0x86,0x85,0x85,
    673 		0x84,0x83,0x83,0x82,0x82,0x82,0x82,0x82,
    674 
    675 		0x82,0x82,0x82,0x82,0x82,0x82,0x83,0x83,
    676 		0x84,0x85,0x85,0x86,0x87,0x88,0x89,0x8a,
    677 		0x8b,0x8c,0x8e,0x8f,0x90,0x92,0x94,0x95,
    678 		0x97,0x99,0x9a,0x9c,0x9e,0xa0,0xa2,0xa5,
    679 		0xa7,0xa9,0xab,0xae,0xb0,0xb2,0xb5,0xb7,
    680 		0xba,0xbd,0xbf,0xc2,0xc5,0xc7,0xca,0xcd,
    681 		0xd0,0xd3,0xd6,0xd9,0xdc,0xdf,0xe2,0xe5,
    682 		0xe8,0xeb,0xee,0xf1,0xf4,0xf7,0xfa,0xfd,
    683 
    684 		0x00,0x03,0x06,0x09,0x0c,0x0f,0x12,0x15,
    685 		0x18,0x1b,0x1e,0x21,0x24,0x27,0x2a,0x2d,
    686 		0x30,0x33,0x36,0x39,0x3b,0x3e,0x41,0x43,
    687 		0x46,0x49,0x4b,0x4e,0x50,0x52,0x55,0x57,
    688 		0x59,0x5b,0x5e,0x60,0x62,0x64,0x65,0x67,
    689 		0x69,0x6b,0x6c,0x6e,0x6f,0x71,0x72,0x74,
    690 		0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7b,
    691 		0x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7e,0x7e,
    692 	};
    693 	distance = distance;		// Keep LINT quiet.
    694 
    695 	//
    696 	// Have to declare table as unsigned otherwise MSVC complains, but we need to treat the actual values as signed.
    697 	//
    698 	static const char *_sin_table = (char*)&SinTable[0];
    699 	static const char *_cos_table = (char*)&CosTable[0];
    700 
    701 	x += calcx(_cos_table[dir], distance);
    702 
    703 	y += calcy(_sin_table[dir] / 2, distance);
    704 }