CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

FACINGFF.ASM (6370B)


      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 ;IDEAL
     37 ;P386
     38 ;MODEL USE32 FLAT
     39 
     40 GLOBAL	C Desired_Facing256	:NEAR
     41 ;	INCLUDE	"wwlib.i"
     42 INCLUDE "..\include\gbuffer.inc"
     43 
     44 	CODESEG
     45 
     46 ;***************************************************************************
     47 ;* Desired_Facing256 -- Desired facing algorithm 0..255 resolution.        *
     48 ;*                                                                         *
     49 ;*    This is a desired facing algorithm that has a resolution of 0        *
     50 ;*    through 255.                                                         *
     51 ;*                                                                         *
     52 ;* INPUT:   srcx,srcy   -- Source coordinate.                              *
     53 ;*                                                                         *
     54 ;*          dstx,dsty   -- Destination coordinate.                         *
     55 ;*                                                                         *
     56 ;* OUTPUT:  Returns with the desired facing to face the destination        *
     57 ;*          coordinate from the position of the source coordinate.  North  *
     58 ;*          is 0, East is 64, etc.                                         *
     59 ;*                                                                         *
     60 ;* WARNINGS:   This routine is slower than the other forms of desired      *
     61 ;*             facing calculation.  Use this routine when accuracy is      *
     62 ;*             required.                                                   *
     63 ;*                                                                         *
     64 ;* HISTORY:                                                                *
     65 ;*   12/24/1991 JLB : Adapted.                                             *
     66 ;*=========================================================================*/
     67 ; LONG cdecl Desired_Facing256(LONG srcx, LONG srcy, LONG dstx, LONG dsty)
     68 	PROC	Desired_Facing256 C near
     69 	USES	ebx, ecx, edx
     70 
     71 	ARG	srcx:DWORD
     72 	ARG	srcy:DWORD
     73 	ARG	dstx:DWORD
     74 	ARG	dsty:DWORD
     75 
     76 	xor	ebx,ebx			; Facing number.
     77 
     78 	; Determine absolute X delta and left/right direction.
     79 	mov	ecx,[dstx]
     80 	sub	ecx,[srcx]
     81 	jge	short ??xnotneg
     82 	neg	ecx
     83 	mov	ebx,11000000b		; Set bit 7 and 6 for leftward.
     84 ??xnotneg:
     85 
     86 	; Determine absolute Y delta and top/bottom direction.
     87 	mov	eax,[srcy]
     88 	sub	eax,[dsty]
     89 	jge	short ??ynotneg
     90 	xor	ebx,01000000b		; Complement bit 6 for downward.
     91 	neg	eax
     92 ??ynotneg:
     93 
     94 	; Set DX=64 for quadrants 0 and 2.
     95 	mov	edx,ebx
     96 	and	edx,01000000b
     97 	xor	edx,01000000b
     98 
     99 	; Determine if the direction is closer to the Y axis and make sure that
    100 	; CX holds the larger of the two deltas.  This is in preparation for the
    101 	; divide.
    102 	cmp	eax,ecx
    103 	jb	short ??gotaxis
    104 	xchg	eax,ecx
    105 	xor	edx,01000000b		; Closer to Y axis so make DX=64 for quad 0 and 2.
    106 ??gotaxis:
    107 
    108 	; If closer to the X axis then add 64 for quadrants 0 and 2.  If
    109 	; closer to the Y axis then add 64 for quadrants 1 and 3.  Determined
    110 	; add value is in DX and save on stack.
    111 	push	edx
    112 
    113 	; Make sure that the division won't overflow.  Reduce precision until
    114 	; the larger number is less than 256 if it appears that an overflow
    115 	; will occur.  If the high byte of the divisor is not zero, then this
    116 	; guarantees no overflow, so just abort shift operation.
    117 	test	eax,0FFFFFF00h
    118 	jnz	short ??nooverflow
    119 ??again:
    120 	test	ecx,0FFFFFF00h
    121 	jz	short ??nooverflow
    122 	shr	ecx,1
    123 	shr	eax,1
    124 	jmp	short ??again
    125 ??nooverflow:
    126 
    127 	; Make sure that the division won't underflow (divide by zero).  If
    128 	; this would occur, then set the quotient to $FF and skip divide.
    129 	or	ecx,ecx
    130 	jnz	short ??nounderflow
    131 	mov	eax,0FFFFFFFFh
    132 	jmp	short ??divcomplete
    133 
    134 	; Derive a pseudo angle number for the octant.  The angle is based
    135 	; on $00 = angle matches long axis, $00 = angle matches $FF degrees.
    136 ??nounderflow:
    137 	xor	edx,edx
    138 	shld	edx,eax,8	; shift high byte of eax into dl
    139 	shl	eax,8
    140 	div	ecx
    141 ??divcomplete:
    142 
    143 	; Integrate the 5 most significant bits into the angle index.  If DX
    144 	; is not zero, then it is 64.  This means that the dividend must be negated
    145 	; before it is added into the final angle value.
    146 	shr	eax,3
    147 	pop	edx
    148 	or	edx,edx
    149 	je	short ??noneg
    150 	dec	edx
    151 	neg	eax
    152 ??noneg:
    153 	add	eax,edx
    154 	add	eax,ebx
    155 	and	eax,0FFH
    156 	ret
    157 
    158 	ENDP	Desired_Facing256
    159 
    160 
    161 
    162 	END