CnC_Remastered_Collection

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

SUPPORT.ASM (16213B)


      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&c\vcs\code\support.asv   2.13   16 Oct 1995 16:52: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 ;* strtrim -- Remove the trailing white space from a string.               *
     51 ;*                                                                         *
     52 ;*    Use this routine to remove white space characters from the beginning *
     53 ;*    and end of the string.        The string is modified in place by     *
     54 ;*    this routine.                                                        *
     55 ;*                                                                         *
     56 ;* INPUT:   buffer   -- Pointer to the string to modify.                   *
     57 ;*                                                                         *
     58 ;* OUTPUT:     none                                                        *
     59 ;*                                                                         *
     60 ;* WARNINGS:   none                                                        *
     61 ;*                                                                         *
     62 ;* HISTORY:                                                                *
     63 ;*   10/07/1992 JLB : Created.                                             *
     64 ;*=========================================================================*
     65 ; VOID cdecl strtrim(BYTE *buffer);
     66 	global C	strtrim :NEAR
     67 	PROC	strtrim C near
     68 	USES	ax, edi, esi
     69 
     70 	ARG	buffer:DWORD		; Pointer to string to modify.
     71 
     72 	cmp	[buffer],0
     73 	je	short ??fini
     74 
     75 	; Prepare for string scanning by loading pointers.
     76 	cld
     77 	mov	esi,[buffer]
     78 	mov	edi,esi
     79 
     80 	; Strip white space from the start of the string.
     81 ??looper:
     82 	lodsb
     83 	cmp	al,20h			; Space
     84 	je	short ??looper
     85 	cmp	al,9			; TAB
     86 	je	short ??looper
     87 	stosb
     88 
     89 	; Copy the rest of the string.
     90 ??gruntloop:
     91 	lodsb
     92 	stosb
     93 	or	al,al
     94 	jnz	short ??gruntloop
     95 	dec	edi
     96 	; Strip the white space from the end of the string.
     97 ??looper2:
     98 	mov	[edi],al
     99 	dec	edi
    100 	mov	ah,[edi]
    101 	cmp	ah,20h
    102 	je	short ??looper2
    103 	cmp	ah,9
    104 	je	short ??looper2
    105 
    106 ??fini:
    107 	ret
    108 
    109 	ENDP	strtrim
    110 
    111 
    112 ;***************************************************************************
    113 ;* Fat_Put_Pixel -- Draws a fat pixel.                                     *
    114 ;*                                                                         *
    115 ;*    Use this routine to draw a "pixel" that is bigger than 1 pixel       *
    116 ;*    across.  This routine is faster than drawing a similar small shape   *
    117 ;*    and faster than calling Fill_Rect.                                   *
    118 ;*                                                                         *
    119 ;* INPUT:   x,y       -- Screen coordinates to draw the pixel's upper      *
    120 ;*                       left corner.                                      *
    121 ;*                                                                         *
    122 ;*          color     -- The color to render the pixel in.                 *
    123 ;*                                                                         *
    124 ;*          size      -- The number of pixels width of the big "pixel".    *
    125 ;*                                                                         *
    126 ;*          page      -- The pointer to a GraphicBuffer class or something *
    127 ;*                                                                         *
    128 ;* OUTPUT:  none                                                           *
    129 ;*                                                                         *
    130 ;* WARNINGS:   none                                                        *
    131 ;*                                                                         *
    132 ;* HISTORY:                                                                *
    133 ;*   03/17/1994 JLB : Created.                                             *
    134 ;*=========================================================================*
    135 ; VOID cdecl Fat_Put_Pixel(long x, long y, long color, long size, void *page)
    136 	global C	Fat_Put_Pixel:NEAR
    137 	PROC	Fat_Put_Pixel C near
    138 	USES	eax, ebx, ecx, edx, edi, esi
    139 
    140 	ARG	x:DWORD		; X coordinate of upper left pixel corner.
    141 	ARG	y:DWORD		; Y coordinate of upper left pixel corner.
    142 	ARG	color:DWORD	; Color to use for the "pixel".
    143 	ARG	siz:DWORD	; Size of "pixel" to plot (square).
    144 	ARG	gpage:DWORD	; graphic page address to plot onto
    145 
    146 	cmp	[siz],0
    147 	je	short ??exit
    148 
    149 	; Set EDI to point to start of logical page memory.
    150 	;*===================================================================
    151 	; Get the viewport information and put bytes per row in ecx
    152 	;*===================================================================
    153 	mov	ebx,[gpage]				; get a pointer to viewport
    154 	mov	edi,[(GraphicViewPort ebx).GVPOffset]	; get the correct offset
    155 
    156 	; Verify the the Y pixel offset is legal.
    157 	mov	eax,[y]
    158 	cmp	eax,[(GraphicViewPort ebx).GVPHeight]	;YPIXEL_MAX
    159 	jae	short ??exit
    160 	mov	ecx,[(GraphicViewPort ebx).GVPWidth]
    161 	add	ecx,[(GraphicViewPort ebx).GVPXAdd]
    162 	add	ecx,[(GraphicViewPort ebx).GVPPitch]
    163 	mul	ecx
    164 	add	edi,eax
    165 
    166 	; Verify the the X pixel offset is legal.
    167 	
    168 	mov	edx,[(GraphicViewPort ebx).GVPWidth]
    169 	cmp	edx,[x]
    170 	mov	edx,ecx
    171 	jbe	short ??exit
    172 	add	edi,[x]
    173 
    174 	; Write the pixel to the screen.
    175 	mov	ebx,[siz]		; Copy of pixel size.
    176 	sub	edx,ebx			; Modulo to reach start of next row.
    177 	mov	eax,[color]
    178 ??again:
    179 	mov	ecx,ebx
    180 	rep stosb
    181 	add	edi,edx			; EDI points to start of next row.
    182 	dec	[siz]
    183 	jnz	short ??again
    184 
    185 ??exit:
    186 	ret
    187 
    188 	ENDP	Fat_Put_Pixel
    189 
    190 
    191 ;***************************************************************************
    192 ;* Conquer_Build_Fading_Table -- Builds custom shadow/light fading table.  *
    193 ;*                                                                         *
    194 ;*    This routine is used to build a special fading table for C&C.  There *
    195 ;*    are certain colors that get faded to and cannot be faded again.      *
    196 ;*    With this rule, it is possible to draw a shadow multiple times and   *
    197 ;*    not have it get any lighter or darker.                               *
    198 ;*                                                                         *
    199 ;* INPUT:   palette  -- Pointer to the 768 byte IBM palette to build from. *
    200 ;*                                                                         *
    201 ;*          dest     -- Pointer to the 256 byte remap table.               *
    202 ;*                                                                         *
    203 ;*          color    -- Color index of the color to "fade to".             *
    204 ;*                                                                         *
    205 ;*          frac     -- The fraction to fade to the specified color        *
    206 ;*                                                                         *
    207 ;* OUTPUT:  Returns with pointer to the remap table.                       *
    208 ;*                                                                         *
    209 ;* WARNINGS:   none                                                        *
    210 ;*                                                                         *
    211 ;* HISTORY:                                                                *
    212 ;*   10/07/1992 JLB : Created.                                             *
    213 ;*=========================================================================*/
    214 ;VOID * cdecl Conquer_Build_Fading_Table(VOID *palette, VOID *dest, long color, long frac);
    215 	global C	Conquer_Build_Fading_Table : NEAR
    216 	PROC	Conquer_Build_Fading_Table C near
    217 	USES	ebx, ecx, edi, esi
    218 
    219 	ARG	palette:DWORD
    220 	ARG	dest:DWORD
    221 	ARG	color:DWORD
    222 	ARG	frac:DWORD
    223 
    224 	LOCAL	matchvalue:DWORD	; Last recorded match value.
    225 	LOCAL	targetred:BYTE		; Target gun red.
    226 	LOCAL	targetgreen:BYTE	; Target gun green.
    227 	LOCAL	targetblue:BYTE		; Target gun blue.
    228 	LOCAL	idealred:BYTE
    229 	LOCAL	idealgreen:BYTE
    230 	LOCAL	idealblue:BYTE
    231 	LOCAL	matchcolor:BYTE		; Tentative match color.
    232 
    233 ALLOWED_COUNT	EQU	16
    234 ALLOWED_START	EQU	256-ALLOWED_COUNT
    235 
    236 	cld
    237 
    238 	; If the source palette is NULL, then just return with current fading table pointer.
    239 	cmp	[palette],0
    240 	je	??fini1
    241 	cmp	[dest],0
    242 	je	??fini1
    243 
    244 	; Fractions above 255 become 255.
    245 	mov	eax,[frac]
    246 	cmp	eax,0100h
    247 	jb	short ??ok
    248 	mov	[frac],0FFh
    249 ??ok:
    250 
    251 	; Record the target gun values.
    252 	mov	esi,[palette]
    253 	mov	ebx,[color]
    254 	add	esi,ebx
    255 	add	esi,ebx
    256 	add	esi,ebx
    257 	lodsb
    258 	mov	[targetred],al
    259 	lodsb
    260 	mov	[targetgreen],al
    261 	lodsb
    262 	mov	[targetblue],al
    263 
    264 	; Main loop.
    265 	xor	ebx,ebx			; Remap table index.
    266 
    267 	; Transparent black never gets remapped.
    268 	mov	edi,[dest]
    269 	mov	[edi],bl
    270 	inc	edi
    271 
    272 	; EBX = source palette logical number (1..255).
    273 	; EDI = running pointer into dest remap table.
    274 ??mainloop:
    275 	inc	ebx
    276 	mov	esi,[palette]
    277 	add	esi,ebx
    278 	add	esi,ebx
    279 	add	esi,ebx
    280 
    281 	mov	edx,[frac]
    282 	shr	edx,1
    283 	; new = orig - ((orig-target) * fraction);
    284 
    285 	lodsb				; orig
    286 	mov	dh,al			; preserve it for later.
    287 	sub	al,[targetred]		; al = (orig-target)
    288 	imul	dl			; ax = (orig-target)*fraction
    289 	shl	eax,1
    290 	sub	dh,ah			; dh = orig - ((orig-target) * fraction)
    291 	mov	[idealred],dh		; preserve ideal color gun value.
    292 
    293 	lodsb				; orig
    294 	mov	dh,al			; preserve it for later.
    295 	sub	al,[targetgreen]	; al = (orig-target)
    296 	imul	dl			; ax = (orig-target)*fraction
    297 	shl	eax,1
    298 	sub	dh,ah			; dh = orig - ((orig-target) * fraction)
    299 	mov	[idealgreen],dh		; preserve ideal color gun value.
    300 
    301 	lodsb				; orig
    302 	mov	dh,al			; preserve it for later.
    303 	sub	al,[targetblue]		; al = (orig-target)
    304 	imul	dl			; ax = (orig-target)*fraction
    305 	shl	eax,1
    306 	sub	dh,ah			; dh = orig - ((orig-target) * fraction)
    307 	mov	[idealblue],dh		; preserve ideal color gun value.
    308 
    309 	; Sweep through a limited set of existing colors to find the closest
    310 	; matching color.
    311 
    312 	mov	eax,[color]
    313 	mov	[matchcolor],al		; Default color (self).
    314 	mov	[matchvalue],-1		; Ridiculous match value init.
    315 	mov	ecx,ALLOWED_COUNT
    316 
    317 	mov	esi,[palette]		; Pointer to original palette.
    318 	add	esi,(ALLOWED_START)*3
    319 
    320 	; BH = color index.
    321 	mov	bh,ALLOWED_START
    322 ??innerloop:
    323 
    324 	xor	edx,edx			; Comparison value starts null.
    325 
    326 	; Build the comparison value based on the sum of the differences of the color
    327 	; guns squared.
    328 	lodsb
    329 	sub	al,[idealred]
    330 	mov	ah,al
    331 	imul	ah
    332 	add	edx,eax
    333 
    334 	lodsb
    335 	sub	al,[idealgreen]
    336 	mov	ah,al
    337 	imul	ah
    338 	add	edx,eax
    339 
    340 	lodsb
    341 	sub	al,[idealblue]
    342 	mov	ah,al
    343 	imul	ah
    344 	add	edx,eax
    345 	jz	short ??perfect		; If perfect match found then quit early.
    346 
    347 	cmp	edx,[matchvalue]
    348 	jae	short ??notclose
    349 	mov	[matchvalue],edx	; Record new possible color.
    350 	mov	[matchcolor],bh
    351 ??notclose:
    352 	inc	bh			; Checking color index.
    353 	loop	??innerloop
    354 	mov	bh,[matchcolor]
    355 ??perfect:
    356 	mov	[matchcolor],bh
    357 	xor	bh,bh			; Make BX valid main index again.
    358 
    359 	; When the loop exits, we have found the closest match.
    360 	mov	al,[matchcolor]
    361 	stosb
    362 	cmp	ebx,ALLOWED_START-1
    363 	jne	??mainloop
    364 
    365 	; Fill the remainder of the remap table with values
    366 	; that will remap the color to itself.
    367 	mov	ecx,ALLOWED_COUNT
    368 ??fillerloop:
    369 	inc	bl
    370 	mov	al,bl
    371 	stosb
    372 	loop	??fillerloop
    373 
    374 ??fini1:
    375 	mov	esi,[dest]
    376 	mov	eax,esi
    377 	ret
    378 
    379 	ENDP	Conquer_Build_Fading_Table
    380 
    381 
    382 ;***************************************************************************
    383 ;* Remove_From_List -- Removes a pointer from a list of pointers.          *
    384 ;*                                                                         *
    385 ;*    This low level routine is used to remove a pointer from a list of    *
    386 ;*    pointers.  The trailing pointers are moved downward to fill the      *
    387 ;*    hole.                                                                *
    388 ;*                                                                         *
    389 ;* INPUT:   list     -- Pointer to list of pointer.                        *
    390 ;*                                                                         *
    391 ;*          index    -- Pointer to length of pointer list.                 *
    392 ;*                                                                         *
    393 ;*          ptr      -- The pointer value to search for and remove.        *
    394 ;*                                                                         *
    395 ;* OUTPUT:  none                                                           *
    396 ;*                                                                         *
    397 ;* WARNINGS:   none                                                        *
    398 ;*                                                                         *
    399 ;* HISTORY:                                                                *
    400 ;*   04/11/1994 JLB : Created.                                             *
    401 ;*   04/22/1994 JLB : Convert to assembly language.                        *
    402 ;*   05/10/1994 JLB : Short pointers now.                                  *
    403 ;*=========================================================================*/
    404 ;VOID cdecl Remove_From_List(VOID **list, long *index, long ptr);
    405 	global C	Remove_From_List:NEAR
    406 	PROC	Remove_From_List C near
    407 	USES	edi, esi, ecx, eax
    408 	ARG	list:DWORD		; Pointer to list.
    409 	ARG	index:DWORD		; Pointer to count.
    410 	ARG	element:DWORD		; Element to remove.
    411 
    412 	; Fetch the number of elements in the list.  If there are no
    413 	; elements, then just exit quickly.
    414 	mov	edi,[index]
    415 	mov	ecx,[edi]
    416 	jcxz	short ??fini2
    417 
    418 	; Fetch pointer to list.
    419 	cmp	[list],0
    420 	je	short ??fini2
    421 	mov	edi,[list]
    422 
    423 	; Loop through all elements searching for a match.
    424 	mov	eax,[element]
    425 	repne scasd
    426 	jne	short ??fini2		; No match found.
    427 
    428 	; Copy all remaining elements down.  If this is the
    429 	; last element in the list then nothing needs to be
    430 	; copied -- just decrement the list size.
    431 	jcxz	short ??nocopy		; No copy necessary.
    432 	mov	esi,edi
    433 	sub	edi,4
    434 	rep movsd
    435 
    436 	; Reduce the list count by one.
    437 ??nocopy:
    438 	mov	edi,[index]
    439 	dec	[DWORD PTR edi]
    440 
    441 ??fini2:
    442 	ret
    443 
    444 	ENDP	Remove_From_List
    445 
    446 
    447 ; long cdecl Get_EAX();
    448 	global C	Get_EAX :NEAR
    449 	PROC	Get_EAX C near
    450 	ret
    451 
    452 	ENDP	Get_EAX
    453 
    454 ;----------------------------------------------------------------------------
    455 
    456 	END