Initial commit of original Tiberian Dawn and Red Alert source code converted to build as DLLs, and compatible with the release version of Command & Conquer Remastered.
458 lines
15 KiB
C
458 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#33 $
|
|
;***************************************************************************
|
|
;** 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
|