CnC_Remastered_Collection

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

2SUPPORT.ASM (18329B)


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