CnC_Remastered_Collection

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

SUPPORT.ASM (18218B)


      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 ; $Header:   F:\projects\c&c0\vcs\code\support.asv   5.0   11 Nov 1996 09:40:30   JOE_BOSTIC  $
     17 ;***************************************************************************
     18 ;**   C O N F I D E N T I A L --- W E S T W O O D    S T U D I O S        **
     19 ;***************************************************************************
     20 ;*                                                                         *
     21 ;*                 Project Name : Command & Conquer                        *
     22 ;*                                                                         *
     23 ;*                    File Name : SUPPORT.ASM                              *
     24 ;*                                                                         *
     25 ;*                   Programmer : Joe L. Bostic                            *
     26 ;*                                                                         *
     27 ;*                   Start Date : September 23, 1993                       *
     28 ;*                                                                         *
     29 ;*                  Last Update : May 10, 1994   [JLB]                     *
     30 ;*                                                                         *
     31 ;*-------------------------------------------------------------------------*
     32 ;* Functions:                                                              *
     33 ;*   strtrim -- Remove the trailing white space from a string.             *
     34 ;*   Fat_Put_Pixel -- Draws a fat pixel.                                   *
     35 ;*   Conquer_Build_Fading_Table -- Builds custom shadow/light fading table.*
     36 ;*   Remove_From_List -- Removes a pointer from a list of pointers.        *
     37 ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
     38 
     39 IDEAL
     40 P386
     41 MODEL USE32 FLAT
     42 
     43 INCLUDE "gbuffer.inc"
     44 	DISPLAY	"Command & Conquer assembly support routines."
     45 
     46 	CODESEG
     47 
     48 
     49 ;***************************************************************************
     50 ;* Fat_Put_Pixel -- Draws a fat pixel.                                     *
     51 ;*                                                                         *
     52 ;*    Use this routine to draw a "pixel" that is bigger than 1 pixel       *
     53 ;*    across.  This routine is faster than drawing a similar small shape   *
     54 ;*    and faster than calling Fill_Rect.                                   *
     55 ;*                                                                         *
     56 ;* INPUT:   x,y       -- Screen coordinates to draw the pixel's upper      *
     57 ;*                       left corner.                                      *
     58 ;*                                                                         *
     59 ;*          color     -- The color to render the pixel in.                 *
     60 ;*                                                                         *
     61 ;*          size      -- The number of pixels width of the big "pixel".    *
     62 ;*                                                                         *
     63 ;*          page      -- The pointer to a GraphicBuffer class or something *
     64 ;*                                                                         *
     65 ;* OUTPUT:  none                                                           *
     66 ;*                                                                         *
     67 ;* WARNINGS:   none                                                        *
     68 ;*                                                                         *
     69 ;* HISTORY:                                                                *
     70 ;*   03/17/1994 JLB : Created.                                             *
     71 ;*=========================================================================*
     72 ; VOID cdecl Fat_Put_Pixel(long x, long y, long color, long size, void *page)
     73 	GLOBAL	C Fat_Put_Pixel:NEAR
     74 	PROC	Fat_Put_Pixel C near
     75 	USES	eax, ebx, ecx, edx, edi, esi
     76 
     77 	ARG	x:DWORD		; X coordinate of upper left pixel corner.
     78 	ARG	y:DWORD		; Y coordinate of upper left pixel corner.
     79 	ARG	color:DWORD	; Color to use for the "pixel".
     80 	ARG	siz:DWORD	; Size of "pixel" to plot (square).
     81 	ARG	gpage:DWORD	; graphic page address to plot onto
     82 
     83 	cmp	[siz],0
     84 	je	short ??exit
     85 
     86 	; Set EDI to point to start of logical page memory.
     87 	;*===================================================================
     88 	; Get the viewport information and put bytes per row in ecx
     89 	;*===================================================================
     90 	mov	ebx,[gpage]				; get a pointer to viewport
     91 	mov	edi,[(GraphicViewPort ebx).GVPOffset]	; get the correct offset
     92 
     93 	; Verify the the Y pixel offset is legal.
     94 	mov	eax,[y]
     95 	cmp	eax,[(GraphicViewPort ebx).GVPHeight]	;YPIXEL_MAX
     96 	jae	short ??exit
     97 	mul	[(GraphicViewPort ebx).GVPWidth]
     98 	add	edi,eax
     99 
    100 	; Verify the the X pixel offset is legal.
    101 	mov	edx,[(GraphicViewPort ebx).GVPWidth]
    102 	cmp	edx,[x]
    103 	jbe	short ??exit
    104 	add	edi,[x]
    105 
    106 	; Write the pixel to the screen.
    107 	mov	ebx,[siz]		; Copy of pixel size.
    108 	sub	edx,ebx			; Modulo to reach start of next row.
    109 	mov	eax,[color]
    110 ??again:
    111 	mov	ecx,ebx
    112 	rep stosb
    113 	add	edi,edx			; EDI points to start of next row.
    114 	dec	[siz]
    115 	jnz	short ??again
    116 
    117 ??exit:
    118 	ret
    119 
    120 	ENDP	Fat_Put_Pixel
    121 
    122 
    123 if 0
    124 
    125 ;***************************************************************************
    126 ;* strtrim -- Remove the trailing white space from a string.               *
    127 ;*                                                                         *
    128 ;*    Use this routine to remove white space characters from the beginning *
    129 ;*    and end of the string.        The string is modified in place by     *
    130 ;*    this routine.                                                        *
    131 ;*                                                                         *
    132 ;* INPUT:   buffer   -- Pointer to the string to modify.                   *
    133 ;*                                                                         *
    134 ;* OUTPUT:     none                                                        *
    135 ;*                                                                         *
    136 ;* WARNINGS:   none                                                        *
    137 ;*                                                                         *
    138 ;* HISTORY:                                                                *
    139 ;*   10/07/1992 JLB : Created.                                             *
    140 ;*=========================================================================*
    141 ; VOID cdecl strtrim(BYTE *buffer);
    142 	GLOBAL	C strtrim :NEAR
    143 	PROC	strtrim C near
    144 	USES	ax, edi, esi
    145 
    146 	ARG	buffer:DWORD		; Pointer to string to modify.
    147 
    148 	cmp	[buffer],0
    149 	je	short ??fini
    150 
    151 	; Prepare for string scanning by loading pointers.
    152 	cld
    153 	mov	esi,[buffer]
    154 	mov	edi,esi
    155 
    156 	; Strip white space from the start of the string.
    157 ??looper:
    158 	lodsb
    159 	cmp	al,20h			; Space
    160 	je	short ??looper
    161 	cmp	al,9			; TAB
    162 	je	short ??looper
    163 	stosb
    164 
    165 	; Copy the rest of the string.
    166 ??gruntloop:
    167 	lodsb
    168 	stosb
    169 	or	al,al
    170 	jnz	short ??gruntloop
    171 	dec	edi
    172 	; Strip the white space from the end of the string.
    173 ??looper2:
    174 	mov	[edi],al
    175 	dec	edi
    176 	mov	ah,[edi]
    177 	cmp	ah,20h
    178 	je	short ??looper2
    179 	cmp	ah,9
    180 	je	short ??looper2
    181 
    182 ??fini:
    183 	ret
    184 
    185 	ENDP	strtrim
    186 
    187 
    188 ;***************************************************************************
    189 ;* Conquer_Build_Fading_Table -- Builds custom shadow/light fading table.  *
    190 ;*                                                                         *
    191 ;*    This routine is used to build a special fading table for C&C.  There *
    192 ;*    are certain colors that get faded to and cannot be faded again.      *
    193 ;*    With this rule, it is possible to draw a shadow multiple times and   *
    194 ;*    not have it get any lighter or darker.                               *
    195 ;*                                                                         *
    196 ;* INPUT:   palette  -- Pointer to the 768 byte IBM palette to build from. *
    197 ;*                                                                         *
    198 ;*          dest     -- Pointer to the 256 byte remap table.               *
    199 ;*                                                                         *
    200 ;*          color    -- Color index of the color to "fade to".             *
    201 ;*                                                                         *
    202 ;*          frac     -- The fraction to fade to the specified color        *
    203 ;*                                                                         *
    204 ;* OUTPUT:  Returns with pointer to the remap table.                       *
    205 ;*                                                                         *
    206 ;* WARNINGS:   none                                                        *
    207 ;*                                                                         *
    208 ;* HISTORY:                                                                *
    209 ;*   10/07/1992 JLB : Created.                                             *
    210 ;*=========================================================================*/
    211 ;VOID * cdecl Conquer_Build_Fading_Table(VOID *palette, VOID *dest, long color, long frac);
    212 	GLOBAL	C Conquer_Build_Fading_Table : NEAR
    213 	PROC	Conquer_Build_Fading_Table C near
    214 	USES	ebx, ecx, edi, esi
    215 
    216 	ARG	palette:DWORD
    217 	ARG	dest:DWORD
    218 	ARG	color:DWORD
    219 	ARG	frac:DWORD
    220 
    221 	LOCAL	matchvalue:DWORD	; Last recorded match value.
    222 	LOCAL	targetred:BYTE		; Target gun red.
    223 	LOCAL	targetgreen:BYTE	; Target gun green.
    224 	LOCAL	targetblue:BYTE		; Target gun blue.
    225 	LOCAL	idealred:BYTE
    226 	LOCAL	idealgreen:BYTE
    227 	LOCAL	idealblue:BYTE
    228 	LOCAL	matchcolor:BYTE		; Tentative match color.
    229 
    230 ALLOWED_COUNT	EQU	16
    231 ALLOWED_START	EQU	256-ALLOWED_COUNT
    232 
    233 	cld
    234 
    235 	; If the source palette is NULL, then just return with current fading table pointer.
    236 	cmp	[palette],0
    237 	je	??fini1
    238 	cmp	[dest],0
    239 	je	??fini1
    240 
    241 	; Fractions above 255 become 255.
    242 	mov	eax,[frac]
    243 	cmp	eax,0100h
    244 	jb	short ??ok
    245 	mov	[frac],0FFh
    246 ??ok:
    247 
    248 	; Record the target gun values.
    249 	mov	esi,[palette]
    250 	mov	ebx,[color]
    251 	add	esi,ebx
    252 	add	esi,ebx
    253 	add	esi,ebx
    254 	lodsb
    255 	mov	[targetred],al
    256 	lodsb
    257 	mov	[targetgreen],al
    258 	lodsb
    259 	mov	[targetblue],al
    260 
    261 	; Main loop.
    262 	xor	ebx,ebx			; Remap table index.
    263 
    264 	; Transparent black never gets remapped.
    265 	mov	edi,[dest]
    266 	mov	[edi],bl
    267 	inc	edi
    268 
    269 	; EBX = source palette logical number (1..255).
    270 	; EDI = running pointer into dest remap table.
    271 ??mainloop:
    272 	inc	ebx
    273 	mov	esi,[palette]
    274 	add	esi,ebx
    275 	add	esi,ebx
    276 	add	esi,ebx
    277 
    278 	mov	edx,[frac]
    279 	shr	edx,1
    280 	; new = orig - ((orig-target) * fraction);
    281 
    282 	lodsb				; orig
    283 	mov	dh,al			; preserve it for later.
    284 	sub	al,[targetred]		; al = (orig-target)
    285 	imul	dl			; ax = (orig-target)*fraction
    286 	shl	eax,1
    287 	sub	dh,ah			; dh = orig - ((orig-target) * fraction)
    288 	mov	[idealred],dh		; preserve ideal color gun value.
    289 
    290 	lodsb				; orig
    291 	mov	dh,al			; preserve it for later.
    292 	sub	al,[targetgreen]	; al = (orig-target)
    293 	imul	dl			; ax = (orig-target)*fraction
    294 	shl	eax,1
    295 	sub	dh,ah			; dh = orig - ((orig-target) * fraction)
    296 	mov	[idealgreen],dh		; preserve ideal color gun value.
    297 
    298 	lodsb				; orig
    299 	mov	dh,al			; preserve it for later.
    300 	sub	al,[targetblue]		; al = (orig-target)
    301 	imul	dl			; ax = (orig-target)*fraction
    302 	shl	eax,1
    303 	sub	dh,ah			; dh = orig - ((orig-target) * fraction)
    304 	mov	[idealblue],dh		; preserve ideal color gun value.
    305 
    306 	; Sweep through a limited set of existing colors to find the closest
    307 	; matching color.
    308 
    309 	mov	eax,[color]
    310 	mov	[matchcolor],al		; Default color (self).
    311 	mov	[matchvalue],-1		; Ridiculous match value init.
    312 	mov	ecx,ALLOWED_COUNT
    313 
    314 	mov	esi,[palette]		; Pointer to original palette.
    315 	add	esi,(ALLOWED_START)*3
    316 
    317 	; BH = color index.
    318 	mov	bh,ALLOWED_START
    319 ??innerloop:
    320 
    321 	xor	edx,edx			; Comparison value starts null.
    322 
    323 	; Build the comparison value based on the sum of the differences of the color
    324 	; guns squared.
    325 	lodsb
    326 	sub	al,[idealred]
    327 	mov	ah,al
    328 	imul	ah
    329 	add	edx,eax
    330 
    331 	lodsb
    332 	sub	al,[idealgreen]
    333 	mov	ah,al
    334 	imul	ah
    335 	add	edx,eax
    336 
    337 	lodsb
    338 	sub	al,[idealblue]
    339 	mov	ah,al
    340 	imul	ah
    341 	add	edx,eax
    342 	jz	short ??perfect		; If perfect match found then quit early.
    343 
    344 	cmp	edx,[matchvalue]
    345 	jae	short ??notclose
    346 	mov	[matchvalue],edx	; Record new possible color.
    347 	mov	[matchcolor],bh
    348 ??notclose:
    349 	inc	bh			; Checking color index.
    350 	loop	??innerloop
    351 	mov	bh,[matchcolor]
    352 ??perfect:
    353 	mov	[matchcolor],bh
    354 	xor	bh,bh			; Make BX valid main index again.
    355 
    356 	; When the loop exits, we have found the closest match.
    357 	mov	al,[matchcolor]
    358 	stosb
    359 	cmp	ebx,ALLOWED_START-1
    360 	jne	??mainloop
    361 
    362 	; Fill the remainder of the remap table with values
    363 	; that will remap the color to itself.
    364 	mov	ecx,ALLOWED_COUNT
    365 ??fillerloop:
    366 	inc	bl
    367 	mov	al,bl
    368 	stosb
    369 	loop	??fillerloop
    370 
    371 ??fini1:
    372 	mov	esi,[dest]
    373 	mov	eax,esi
    374 	ret
    375 
    376 	ENDP	Conquer_Build_Fading_Table
    377 
    378 
    379 ;***************************************************************************
    380 ;* Remove_From_List -- Removes a pointer from a list of pointers.          *
    381 ;*                                                                         *
    382 ;*    This low level routine is used to remove a pointer from a list of    *
    383 ;*    pointers.  The trailing pointers are moved downward to fill the      *
    384 ;*    hole.                                                                *
    385 ;*                                                                         *
    386 ;* INPUT:   list     -- Pointer to list of pointer.                        *
    387 ;*                                                                         *
    388 ;*          index    -- Pointer to length of pointer list.                 *
    389 ;*                                                                         *
    390 ;*          ptr      -- The pointer value to search for and remove.        *
    391 ;*                                                                         *
    392 ;* OUTPUT:  none                                                           *
    393 ;*                                                                         *
    394 ;* WARNINGS:   none                                                        *
    395 ;*                                                                         *
    396 ;* HISTORY:                                                                *
    397 ;*   04/11/1994 JLB : Created.                                             *
    398 ;*   04/22/1994 JLB : Convert to assembly language.                        *
    399 ;*   05/10/1994 JLB : Short pointers now.                                  *
    400 ;*=========================================================================*/
    401 ;VOID cdecl Remove_From_List(VOID **list, long *index, long ptr);
    402 	GLOBAL	C Remove_From_List:NEAR
    403 	PROC	Remove_From_List C near
    404 	USES	edi, esi, ecx, eax
    405 	ARG	list:DWORD		; Pointer to list.
    406 	ARG	index:DWORD		; Pointer to count.
    407 	ARG	element:DWORD		; Element to remove.
    408 
    409 	; Fetch the number of elements in the list.  If there are no
    410 	; elements, then just exit quickly.
    411 	mov	edi,[index]
    412 	mov	ecx,[edi]
    413 	jcxz	short ??fini2
    414 
    415 	; Fetch pointer to list.
    416 	cmp	[list],0
    417 	je	short ??fini2
    418 	mov	edi,[list]
    419 
    420 	; Loop through all elements searching for a match.
    421 	mov	eax,[element]
    422 	repne scasd
    423 	jne	short ??fini2		; No match found.
    424 
    425 	; Copy all remaining elements down.  If this is the
    426 	; last element in the list then nothing needs to be
    427 	; copied -- just decrement the list size.
    428 	jcxz	short ??nocopy		; No copy necessary.
    429 	mov	esi,edi
    430 	sub	edi,4
    431 	rep movsd
    432 
    433 	; Reduce the list count by one.
    434 ??nocopy:
    435 	mov	edi,[index]
    436 	dec	[DWORD PTR edi]
    437 
    438 ??fini2:
    439 	ret
    440 
    441 	ENDP	Remove_From_List
    442 
    443 
    444 ; long cdecl Get_EAX();
    445 	GLOBAL	C Get_EAX :NEAR
    446 	PROC	Get_EAX C near
    447 	ret
    448 
    449 	ENDP	Get_EAX
    450 endif
    451 
    452 
    453 	DATASEG
    454 
    455 TabA	DD 6949350
    456 	DD 4913933
    457 	DD 3474675
    458 	DD 2456966
    459 	DD 1737338
    460 	DD 1228483
    461 	DD 868669
    462 	DD 614242
    463 	DD 434334
    464 	DD 307121
    465 	DD 217167
    466 	DD 153560
    467 	DD 108584
    468 	DD 76780
    469 	DD 54292
    470 	DD 38390
    471 	DD 27146
    472 	DD 19195
    473 	DD 13573
    474 	DD 9598
    475 	DD 6786
    476 	DD 4799
    477 	DD 3393
    478 	DD 2399
    479 	DD 1697
    480 	DD 1200
    481 	DD 848
    482 	DD 600
    483 	DD 424
    484 	DD 300
    485 	DD 212
    486 	DD 150
    487 	DD 106
    488 
    489 TabB	DD 154
    490 	DD 218
    491 	DD 309
    492 	DD 437
    493 	DD 618
    494 	DD 874
    495 	DD 1236
    496 	DD 1748
    497 	DD 2472
    498 	DD 3496
    499 	DD 4944
    500 	DD 6992
    501 	DD 9888
    502 	DD 13983
    503 	DD 19775
    504 	DD 27967
    505 	DD 39551
    506 	DD 55933
    507 	DD 79101
    508 	DD 111866
    509 	DD 158203
    510 	DD 223732
    511 	DD 316405
    512 	DD 447465
    513 	DD 632811
    514 	DD 894929
    515 	DD 1265621
    516 	DD 1789859
    517 	DD 2531243
    518 	DD 3579718
    519 	DD 5062486
    520 	DD 7159436
    521 	DD 10124971
    522 
    523 	CODESEG
    524 
    525 ;***********************************************************************************************
    526 ;* Square_Root -- Finds the square root of the fixed pointer parameter.                        *
    527 ;*                                                                                             *
    528 ;* INPUT:   val   -- The fixed point (16:16) value to find the square root of.                 *
    529 ;*                                                                                             *
    530 ;* OUTPUT:  Returns with the square root of the fixed pointer parameter.                       *
    531 ;*                                                                                             *
    532 ;* WARNINGS:   none                                                                            *
    533 ;*                                                                                             *
    534 ;* HISTORY:                                                                                    *
    535 ;*   10/04/1995 JLB : Adapted.                                                                 *
    536 ;*=============================================================================================*/
    537 ;unsigned Square_Root(unsigned val);
    538 	GLOBAL	C Square_Root :NEAR
    539 	PROC	Square_Root C near
    540 	USES	ebx,edx
    541 
    542 	bsr ebx,eax
    543 	jz ??zero
    544 
    545 	mul [DWORD 4*ebx + OFFSET TabA]
    546 	shrd eax,edx,10h
    547 	add eax, [4*ebx + OFFSET TabB]
    548 ??zero:
    549 	ret
    550 
    551 	ENDP	Square_Root
    552 
    553 ;----------------------------------------------------------------------------
    554 
    555 	END
    556