| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458 |
- //
- // Copyright 2020 Electronic Arts Inc.
- //
- // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free
- // software: you can redistribute it and/or modify it under the terms of
- // the GNU General Public License as published by the Free Software Foundation,
- // either version 3 of the License, or (at your option) any later version.
- // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
- // in the hope that it will be useful, but with permitted additional restrictions
- // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
- // distributed with this program. You should have received a copy of the
- // GNU General Public License along with permitted additional restrictions
- // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
- /*;***************************************************************************
- ;** 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 **
- ;***************************************************************************
- ;* *
- ;* Project Name : Support Library *
- ;* *
- ;* File Name : FACINGFF.ASM *
- ;* *
- ;* Programmer : Joe L. Bostic *
- ;* *
- ;* Start Date : May 8, 1991 *
- ;* *
- ;* Last Update : February 6, 1995 [BWG] *
- ;* *
- ;*-------------------------------------------------------------------------*
- ;* Functions: *
- ;* Desired_Facing256 -- Determines facing to reach a position. *
- ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
- */
- #ifndef FACINGFF_H
- #define FACINGFF_H
- //IDEAL
- //P386
- //MODEL USE32 FLAT
- //GLOBAL C Desired_Facing256 :NEAR
- //; INCLUDE "wwlib.i"
- //INCLUDE "..\include\gbuffer.inc"
- // CODESEG
- /*
- ;***************************************************************************
- ;* Desired_Facing256 -- Desired facing algorithm 0..255 resolution. *
- ;* *
- ;* This is a desired facing algorithm that has a resolution of 0 *
- ;* through 255. *
- ;* *
- ;* INPUT: srcx,srcy -- Source coordinate. *
- ;* *
- ;* dstx,dsty -- Destination coordinate. *
- ;* *
- ;* OUTPUT: Returns with the desired facing to face the destination *
- ;* coordinate from the position of the source coordinate. North *
- ;* is 0, East is 64, etc. *
- ;* *
- ;* WARNINGS: This routine is slower than the other forms of desired *
- ;* facing calculation. Use this routine when accuracy is *
- ;* required. *
- ;* *
- ;* HISTORY: *
- ;* 12/24/1991 JLB : Adapted. *
- ;*=========================================================================*/
- int __cdecl Desired_Facing256(LONG srcx, LONG srcy, LONG dstx, LONG dsty);
- #if (0)
- PROC Desired_Facing256 C near
- USES ebx, ecx, edx
- ARG srcx:DWORD
- ARG srcy:DWORD
- ARG dstx:DWORD
- ARG dsty:DWORD
- xor ebx,ebx ; Facing number.
- ; Determine absolute X delta and left/right direction.
- mov ecx,[dstx]
- sub ecx,[srcx]
- jge short ??xnotneg
- neg ecx
- mov ebx,11000000b ; Set bit 7 and 6 for leftward.
- ??xnotneg:
- ; Determine absolute Y delta and top/bottom direction.
- mov eax,[srcy]
- sub eax,[dsty]
- jge short ??ynotneg
- xor ebx,01000000b ; Complement bit 6 for downward.
- neg eax
- ??ynotneg:
- ; Set DX=64 for quadrants 0 and 2.
- mov edx,ebx
- and edx,01000000b
- xor edx,01000000b
- ; Determine if the direction is closer to the Y axis and make sure that
- ; CX holds the larger of the two deltas. This is in preparation for the
- ; divide.
- cmp eax,ecx
- jb short ??gotaxis
- xchg eax,ecx
- xor edx,01000000b ; Closer to Y axis so make DX=64 for quad 0 and 2.
- ??gotaxis:
- ; If closer to the X axis then add 64 for quadrants 0 and 2. If
- ; closer to the Y axis then add 64 for quadrants 1 and 3. Determined
- ; add value is in DX and save on stack.
- push edx
- ; Make sure that the division won't overflow. Reduce precision until
- ; the larger number is less than 256 if it appears that an overflow
- ; will occur. If the high byte of the divisor is not zero, then this
- ; guarantees no overflow, so just abort shift operation.
- test eax,0FFFFFF00h
- jnz short ??nooverflow
- ??again:
- test ecx,0FFFFFF00h
- jz short ??nooverflow
- shr ecx,1
- shr eax,1
- jmp short ??again
- ??nooverflow:
- ; Make sure that the division won't underflow (divide by zero). If
- ; this would occur, then set the quotient to $FF and skip divide.
- or ecx,ecx
- jnz short ??nounderflow
- mov eax,0FFFFFFFFh
- jmp short ??divcomplete
- ; Derive a pseudo angle number for the octant. The angle is based
- ; on $00 = angle matches long axis, $00 = angle matches $FF degrees.
- ??nounderflow:
- xor edx,edx
- shld edx,eax,8 ; shift high byte of eax into dl
- shl eax,8
- div ecx
- ??divcomplete:
- ; Integrate the 5 most significant bits into the angle index. If DX
- ; is not zero, then it is 64. This means that the dividend must be negated
- ; before it is added into the final angle value.
- shr eax,3
- pop edx
- or edx,edx
- je short ??noneg
- dec edx
- neg eax
- ??noneg:
- add eax,edx
- add eax,ebx
- and eax,0FFH
- ret
- ENDP Desired_Facing256
- END
- #endif
- /*
- ;***************************************************************************
- ;** 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 **
- ;***************************************************************************
- ;* *
- ;* Project Name : Support Library *
- ;* *
- ;* File Name : FACING8.ASM *
- ;* *
- ;* Programmer : Joe L. Bostic *
- ;* *
- ;* Start Date : May 8, 1991 *
- ;* *
- ;* Last Update : February 6, 1995 [BWG] *
- ;* *
- ;*-------------------------------------------------------------------------*
- ;* Functions: *
- ;* Desired_Facing8 -- Determines facing to reach a position. *
- ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
- IDEAL
- P386
- MODEL USE32 FLAT
- GLOBAL C Desired_Facing8 :NEAR
- ; INCLUDE "wwlib.i"
- DATASEG
- ; 8 direction desired facing lookup table. Build the index according
- ; to the following bits:
- ;
- ; bit 3 = Is y2 < y1?
- ; bit 2 = Is x2 < x1?
- ; bit 1 = Is the ABS(x2-x1) < ABS(y2-y1)?
- ; bit 0 = Is the facing closer to a major axis?
- //NewFacing8 DB 1,2,1,0,7,6,7,0,3,2,3,4,5,6,5,4
- // CODESEG
- */
- /*
- ;***************************************************************************
- ;* DESIRED_FACING8 -- Determines facing to reach a position. *
- ;* *
- ;* This routine will return with the most desirable facing to reach *
- ;* one position from another. It is accurate to a resolution of 0 to *
- ;* 7. *
- ;* *
- ;* INPUT: x1,y1 -- Position of origin point. *
- ;* *
- ;* x2,y2 -- Position of target. *
- ;* *
- ;* OUTPUT: Returns desired facing as a number from 0..255 with an *
- ;* accuracy of 32 degree increments. *
- ;* *
- ;* WARNINGS: If the two coordinates are the same, then -1 will be *
- ;* returned. It is up to you to handle this case. *
- ;* *
- ;* HISTORY: *
- ;* 07/15/1991 JLB : Documented. *
- ;* 08/08/1991 JLB : Same position check. *
- ;* 08/14/1991 JLB : New algorithm *
- ;* 02/06/1995 BWG : Convert to 32-bit *
- ;*=========================================================================*
- */
- int __cdecl Desired_Facing8(long x1, long y1, long x2, long y2);
- #if (0)
- PROC Desired_Facing8 C near
- USES ebx, ecx, edx
- ARG x1:DWORD
- ARG y1:DWORD
- ARG x2:DWORD
- ARG y2:DWORD
- xor ebx,ebx ; Index byte (built).
- ; Determine Y axis difference.
- mov edx,[y1]
- mov ecx,[y2]
- sub edx,ecx ; DX = Y axis (signed).
- jns short ??absy
- inc ebx ; Set the signed bit.
- neg edx ; ABS(y)
- ??absy:
- ; Determine X axis difference.
- shl ebx,1
- mov eax,[x1]
- mov ecx,[x2]
- sub ecx,eax ; CX = X axis (signed).
- jns short ??absx
- inc ebx ; Set the signed bit.
- neg ecx ; ABS(x)
- ??absx:
- ; Determine the greater axis.
- cmp ecx,edx
- jb short ??dxisbig
- xchg ecx,edx
- ??dxisbig:
- rcl ebx,1 ; Y > X flag bit.
- ; Determine the closeness or farness of lesser axis.
- mov eax,edx
- inc eax ; Round up.
- shr eax,1
- cmp ecx,eax
- rcl ebx,1 ; Close to major axis bit.
- xor eax,eax
- mov al,[NewFacing8+ebx]
- ; Normalize to 0..FF range.
- shl eax,5
- ret
- ENDP Desired_Facing8
- END
- #endif
- /*
- ; $Header: //depot/Projects/Mobius/QA/Project/Run/SOURCECODE/TIBERIANDAWN/WIN32LIB/FACINGFF.h#139 $
- ;***************************************************************************
- ;** 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 **
- ;***************************************************************************
- ;* *
- ;* Project Name : Support Library *
- ;* *
- ;* File Name : FACING16.ASM *
- ;* *
- ;* Programmer : Joe L. Bostic *
- ;* *
- ;* Start Date : May 8, 1991 *
- ;* *
- ;* Last Update : February 6, 1995 [BWG] *
- ;* *
- ;*-------------------------------------------------------------------------*
- ;* Functions: *
- ;* Desired_Facing16 -- Converts coordinates into a facing number. *
- ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
- IDEAL
- P386
- MODEL USE32 FLAT
- GLOBAL C Desired_Facing16 :NEAR
- ; INCLUDE "wwlib.i"
- DATASEG
- ; 16 direction desired facing lookup table. Build the index according
- ; to the following bits:
- ;
- ; bit 4 = Is y2 < y1?
- ; bit 3 = Is x2 < x1?
- ; bit 2 = Is the ABS(x2-x1) < ABS(y2-y1)?
- ; bit 1 = Is the lesser absolute difference very close to zero?
- ; bit 0 = Is the lesser absolute difference very close to the greater dist?
- NewFacing16 DB 3, 2, 4,-1, 1, 2,0,-1
- DB 13,14,12,-1,15,14,0,-1
- DB 5, 6, 4,-1, 7, 6,8,-1
- DB 11,10,12,-1, 9,10,8,-1
- CODESEG
- ;***************************************************************************
- ;* DESIRED_FACING16 -- Converts coordinates into a facing number. *
- ;* *
- ;* This converts coordinates into a desired facing number that ranges *
- ;* from 0 to 15 (0 equals North and going clockwise). *
- ;* *
- ;* INPUT: x1,y1 -- Position of origin point. *
- ;* *
- ;* x2,y2 -- Position of target. *
- ;* *
- ;* OUTPUT: Returns desired facing as a number from 0 to 255 but *
- ;* accurate to 22.5 degree increments. *
- ;* *
- ;* WARNINGS: If the two coordinates are the same, then -1 will be *
- ;* returned. It is up to you to handle this case. *
- ;* *
- ;* HISTORY: *
- ;* 08/14/1991 JLB : Created. *
- ;*=========================================================================*
- */
- long __cdecl Desired_Facing16(long x1, long y1, long x2, long y2);
-
- #if (0)
- PROC Desired_Facing16 C near
- USES ebx, ecx, edx
- ARG x1:DWORD
- ARG y1:DWORD
- ARG x2:DWORD
- ARG y2:DWORD
- xor ebx,ebx ; Index byte (built).
- ; Determine Y axis difference.
- mov edx,[y1]
- mov ecx,[y2]
- sub edx,ecx ; DX = Y axis (signed).
- jns short ??absy
- inc ebx ; Set the signed bit.
- neg edx ; ABS(y)
- ??absy:
- ; Determine X axis difference.
- shl ebx,1
- mov eax,[x1]
- mov ecx,[x2]
- sub ecx,eax ; CX = X axis (signed).
- jns short ??absx
- inc ebx ; Set the signed bit.
- neg ecx ; ABS(x)
- ??absx:
- ; Determine the greater axis.
- cmp ecx,edx
- jb short ??dxisbig
- xchg ecx,edx
- ??dxisbig:
- rcl ebx,1 ; Y > X flag bit.
- ; Determine the closeness or farness of lesser axis.
- mov eax,edx
- inc eax ; Round up.
- shr eax,1
- inc eax ; Round up.
- shr eax,1 ; 1/4 of greater axis.
- cmp ecx,eax
- rcl ebx,1 ; Very close to major axis bit.
- sub edx,eax
- cmp edx,ecx
- rcl ebx,1 ; Very far from major axis bit.
- xor eax,eax
- mov al,[NewFacing16+ebx]
- ; Normalize to 0..FF range.
- shl eax,4
- ret
- ENDP Desired_Facing16
- END
- #endif
- #endif FACINGFF_H
|