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