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 }