COORD.CPP 26 KB

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