COORD.CPP 34 KB

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