CnC_Remastered_Collection/TIBERIANDAWN/WIN32LIB/FACINGFF.h
PG-SteveT 7d496e8a63 September 24th Hotfix
Fixed some problematic harvester behavior
Implemented 10% build time reduction for Turkey
Neutral structures are capturable in multiplayer again (except for STRUCT_V01)
Other misc. fixes
2020-09-24 10:20:58 -07:00

459 lines
15 KiB
C

//
// 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#138 $
;***************************************************************************
;** 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