COORD.CPP 33 KB

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