FACINGFF.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  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. /*;***************************************************************************
  15. ;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
  16. ;***************************************************************************
  17. ;* *
  18. ;* Project Name : Support Library *
  19. ;* *
  20. ;* File Name : FACINGFF.ASM *
  21. ;* *
  22. ;* Programmer : Joe L. Bostic *
  23. ;* *
  24. ;* Start Date : May 8, 1991 *
  25. ;* *
  26. ;* Last Update : February 6, 1995 [BWG] *
  27. ;* *
  28. ;*-------------------------------------------------------------------------*
  29. ;* Functions: *
  30. ;* Desired_Facing256 -- Determines facing to reach a position. *
  31. ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
  32. */
  33. #ifndef FACINGFF_H
  34. #define FACINGFF_H
  35. //IDEAL
  36. //P386
  37. //MODEL USE32 FLAT
  38. //GLOBAL C Desired_Facing256 :NEAR
  39. //; INCLUDE "wwlib.i"
  40. //INCLUDE "..\include\gbuffer.inc"
  41. // CODESEG
  42. /*
  43. ;***************************************************************************
  44. ;* Desired_Facing256 -- Desired facing algorithm 0..255 resolution. *
  45. ;* *
  46. ;* This is a desired facing algorithm that has a resolution of 0 *
  47. ;* through 255. *
  48. ;* *
  49. ;* INPUT: srcx,srcy -- Source coordinate. *
  50. ;* *
  51. ;* dstx,dsty -- Destination coordinate. *
  52. ;* *
  53. ;* OUTPUT: Returns with the desired facing to face the destination *
  54. ;* coordinate from the position of the source coordinate. North *
  55. ;* is 0, East is 64, etc. *
  56. ;* *
  57. ;* WARNINGS: This routine is slower than the other forms of desired *
  58. ;* facing calculation. Use this routine when accuracy is *
  59. ;* required. *
  60. ;* *
  61. ;* HISTORY: *
  62. ;* 12/24/1991 JLB : Adapted. *
  63. ;*=========================================================================*/
  64. int __cdecl Desired_Facing256(LONG srcx, LONG srcy, LONG dstx, LONG dsty);
  65. #if (0)
  66. PROC Desired_Facing256 C near
  67. USES ebx, ecx, edx
  68. ARG srcx:DWORD
  69. ARG srcy:DWORD
  70. ARG dstx:DWORD
  71. ARG dsty:DWORD
  72. xor ebx,ebx ; Facing number.
  73. ; Determine absolute X delta and left/right direction.
  74. mov ecx,[dstx]
  75. sub ecx,[srcx]
  76. jge short ??xnotneg
  77. neg ecx
  78. mov ebx,11000000b ; Set bit 7 and 6 for leftward.
  79. ??xnotneg:
  80. ; Determine absolute Y delta and top/bottom direction.
  81. mov eax,[srcy]
  82. sub eax,[dsty]
  83. jge short ??ynotneg
  84. xor ebx,01000000b ; Complement bit 6 for downward.
  85. neg eax
  86. ??ynotneg:
  87. ; Set DX=64 for quadrants 0 and 2.
  88. mov edx,ebx
  89. and edx,01000000b
  90. xor edx,01000000b
  91. ; Determine if the direction is closer to the Y axis and make sure that
  92. ; CX holds the larger of the two deltas. This is in preparation for the
  93. ; divide.
  94. cmp eax,ecx
  95. jb short ??gotaxis
  96. xchg eax,ecx
  97. xor edx,01000000b ; Closer to Y axis so make DX=64 for quad 0 and 2.
  98. ??gotaxis:
  99. ; If closer to the X axis then add 64 for quadrants 0 and 2. If
  100. ; closer to the Y axis then add 64 for quadrants 1 and 3. Determined
  101. ; add value is in DX and save on stack.
  102. push edx
  103. ; Make sure that the division won't overflow. Reduce precision until
  104. ; the larger number is less than 256 if it appears that an overflow
  105. ; will occur. If the high byte of the divisor is not zero, then this
  106. ; guarantees no overflow, so just abort shift operation.
  107. test eax,0FFFFFF00h
  108. jnz short ??nooverflow
  109. ??again:
  110. test ecx,0FFFFFF00h
  111. jz short ??nooverflow
  112. shr ecx,1
  113. shr eax,1
  114. jmp short ??again
  115. ??nooverflow:
  116. ; Make sure that the division won't underflow (divide by zero). If
  117. ; this would occur, then set the quotient to $FF and skip divide.
  118. or ecx,ecx
  119. jnz short ??nounderflow
  120. mov eax,0FFFFFFFFh
  121. jmp short ??divcomplete
  122. ; Derive a pseudo angle number for the octant. The angle is based
  123. ; on $00 = angle matches long axis, $00 = angle matches $FF degrees.
  124. ??nounderflow:
  125. xor edx,edx
  126. shld edx,eax,8 ; shift high byte of eax into dl
  127. shl eax,8
  128. div ecx
  129. ??divcomplete:
  130. ; Integrate the 5 most significant bits into the angle index. If DX
  131. ; is not zero, then it is 64. This means that the dividend must be negated
  132. ; before it is added into the final angle value.
  133. shr eax,3
  134. pop edx
  135. or edx,edx
  136. je short ??noneg
  137. dec edx
  138. neg eax
  139. ??noneg:
  140. add eax,edx
  141. add eax,ebx
  142. and eax,0FFH
  143. ret
  144. ENDP Desired_Facing256
  145. END
  146. #endif
  147. /*
  148. ;***************************************************************************
  149. ;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
  150. ;***************************************************************************
  151. ;* *
  152. ;* Project Name : Support Library *
  153. ;* *
  154. ;* File Name : FACING8.ASM *
  155. ;* *
  156. ;* Programmer : Joe L. Bostic *
  157. ;* *
  158. ;* Start Date : May 8, 1991 *
  159. ;* *
  160. ;* Last Update : February 6, 1995 [BWG] *
  161. ;* *
  162. ;*-------------------------------------------------------------------------*
  163. ;* Functions: *
  164. ;* Desired_Facing8 -- Determines facing to reach a position. *
  165. ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
  166. IDEAL
  167. P386
  168. MODEL USE32 FLAT
  169. GLOBAL C Desired_Facing8 :NEAR
  170. ; INCLUDE "wwlib.i"
  171. DATASEG
  172. ; 8 direction desired facing lookup table. Build the index according
  173. ; to the following bits:
  174. ;
  175. ; bit 3 = Is y2 < y1?
  176. ; bit 2 = Is x2 < x1?
  177. ; bit 1 = Is the ABS(x2-x1) < ABS(y2-y1)?
  178. ; bit 0 = Is the facing closer to a major axis?
  179. //NewFacing8 DB 1,2,1,0,7,6,7,0,3,2,3,4,5,6,5,4
  180. // CODESEG
  181. */
  182. /*
  183. ;***************************************************************************
  184. ;* DESIRED_FACING8 -- Determines facing to reach a position. *
  185. ;* *
  186. ;* This routine will return with the most desirable facing to reach *
  187. ;* one position from another. It is accurate to a resolution of 0 to *
  188. ;* 7. *
  189. ;* *
  190. ;* INPUT: x1,y1 -- Position of origin point. *
  191. ;* *
  192. ;* x2,y2 -- Position of target. *
  193. ;* *
  194. ;* OUTPUT: Returns desired facing as a number from 0..255 with an *
  195. ;* accuracy of 32 degree increments. *
  196. ;* *
  197. ;* WARNINGS: If the two coordinates are the same, then -1 will be *
  198. ;* returned. It is up to you to handle this case. *
  199. ;* *
  200. ;* HISTORY: *
  201. ;* 07/15/1991 JLB : Documented. *
  202. ;* 08/08/1991 JLB : Same position check. *
  203. ;* 08/14/1991 JLB : New algorithm *
  204. ;* 02/06/1995 BWG : Convert to 32-bit *
  205. ;*=========================================================================*
  206. */
  207. int __cdecl Desired_Facing8(long x1, long y1, long x2, long y2);
  208. #if (0)
  209. PROC Desired_Facing8 C near
  210. USES ebx, ecx, edx
  211. ARG x1:DWORD
  212. ARG y1:DWORD
  213. ARG x2:DWORD
  214. ARG y2:DWORD
  215. xor ebx,ebx ; Index byte (built).
  216. ; Determine Y axis difference.
  217. mov edx,[y1]
  218. mov ecx,[y2]
  219. sub edx,ecx ; DX = Y axis (signed).
  220. jns short ??absy
  221. inc ebx ; Set the signed bit.
  222. neg edx ; ABS(y)
  223. ??absy:
  224. ; Determine X axis difference.
  225. shl ebx,1
  226. mov eax,[x1]
  227. mov ecx,[x2]
  228. sub ecx,eax ; CX = X axis (signed).
  229. jns short ??absx
  230. inc ebx ; Set the signed bit.
  231. neg ecx ; ABS(x)
  232. ??absx:
  233. ; Determine the greater axis.
  234. cmp ecx,edx
  235. jb short ??dxisbig
  236. xchg ecx,edx
  237. ??dxisbig:
  238. rcl ebx,1 ; Y > X flag bit.
  239. ; Determine the closeness or farness of lesser axis.
  240. mov eax,edx
  241. inc eax ; Round up.
  242. shr eax,1
  243. cmp ecx,eax
  244. rcl ebx,1 ; Close to major axis bit.
  245. xor eax,eax
  246. mov al,[NewFacing8+ebx]
  247. ; Normalize to 0..FF range.
  248. shl eax,5
  249. ret
  250. ENDP Desired_Facing8
  251. END
  252. #endif
  253. /*
  254. ; $Header: //depot/Projects/Mobius/QA/Project/Run/SOURCECODE/TIBERIANDAWN/WIN32LIB/FACINGFF.h#139 $
  255. ;***************************************************************************
  256. ;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
  257. ;***************************************************************************
  258. ;* *
  259. ;* Project Name : Support Library *
  260. ;* *
  261. ;* File Name : FACING16.ASM *
  262. ;* *
  263. ;* Programmer : Joe L. Bostic *
  264. ;* *
  265. ;* Start Date : May 8, 1991 *
  266. ;* *
  267. ;* Last Update : February 6, 1995 [BWG] *
  268. ;* *
  269. ;*-------------------------------------------------------------------------*
  270. ;* Functions: *
  271. ;* Desired_Facing16 -- Converts coordinates into a facing number. *
  272. ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
  273. IDEAL
  274. P386
  275. MODEL USE32 FLAT
  276. GLOBAL C Desired_Facing16 :NEAR
  277. ; INCLUDE "wwlib.i"
  278. DATASEG
  279. ; 16 direction desired facing lookup table. Build the index according
  280. ; to the following bits:
  281. ;
  282. ; bit 4 = Is y2 < y1?
  283. ; bit 3 = Is x2 < x1?
  284. ; bit 2 = Is the ABS(x2-x1) < ABS(y2-y1)?
  285. ; bit 1 = Is the lesser absolute difference very close to zero?
  286. ; bit 0 = Is the lesser absolute difference very close to the greater dist?
  287. NewFacing16 DB 3, 2, 4,-1, 1, 2,0,-1
  288. DB 13,14,12,-1,15,14,0,-1
  289. DB 5, 6, 4,-1, 7, 6,8,-1
  290. DB 11,10,12,-1, 9,10,8,-1
  291. CODESEG
  292. ;***************************************************************************
  293. ;* DESIRED_FACING16 -- Converts coordinates into a facing number. *
  294. ;* *
  295. ;* This converts coordinates into a desired facing number that ranges *
  296. ;* from 0 to 15 (0 equals North and going clockwise). *
  297. ;* *
  298. ;* INPUT: x1,y1 -- Position of origin point. *
  299. ;* *
  300. ;* x2,y2 -- Position of target. *
  301. ;* *
  302. ;* OUTPUT: Returns desired facing as a number from 0 to 255 but *
  303. ;* accurate to 22.5 degree increments. *
  304. ;* *
  305. ;* WARNINGS: If the two coordinates are the same, then -1 will be *
  306. ;* returned. It is up to you to handle this case. *
  307. ;* *
  308. ;* HISTORY: *
  309. ;* 08/14/1991 JLB : Created. *
  310. ;*=========================================================================*
  311. */
  312. long __cdecl Desired_Facing16(long x1, long y1, long x2, long y2);
  313. #if (0)
  314. PROC Desired_Facing16 C near
  315. USES ebx, ecx, edx
  316. ARG x1:DWORD
  317. ARG y1:DWORD
  318. ARG x2:DWORD
  319. ARG y2:DWORD
  320. xor ebx,ebx ; Index byte (built).
  321. ; Determine Y axis difference.
  322. mov edx,[y1]
  323. mov ecx,[y2]
  324. sub edx,ecx ; DX = Y axis (signed).
  325. jns short ??absy
  326. inc ebx ; Set the signed bit.
  327. neg edx ; ABS(y)
  328. ??absy:
  329. ; Determine X axis difference.
  330. shl ebx,1
  331. mov eax,[x1]
  332. mov ecx,[x2]
  333. sub ecx,eax ; CX = X axis (signed).
  334. jns short ??absx
  335. inc ebx ; Set the signed bit.
  336. neg ecx ; ABS(x)
  337. ??absx:
  338. ; Determine the greater axis.
  339. cmp ecx,edx
  340. jb short ??dxisbig
  341. xchg ecx,edx
  342. ??dxisbig:
  343. rcl ebx,1 ; Y > X flag bit.
  344. ; Determine the closeness or farness of lesser axis.
  345. mov eax,edx
  346. inc eax ; Round up.
  347. shr eax,1
  348. inc eax ; Round up.
  349. shr eax,1 ; 1/4 of greater axis.
  350. cmp ecx,eax
  351. rcl ebx,1 ; Very close to major axis bit.
  352. sub edx,eax
  353. cmp edx,ecx
  354. rcl ebx,1 ; Very far from major axis bit.
  355. xor eax,eax
  356. mov al,[NewFacing16+ebx]
  357. ; Normalize to 0..FF range.
  358. shl eax,4
  359. ret
  360. ENDP Desired_Facing16
  361. END
  362. #endif
  363. #endif FACINGFF_H