CnC_Remastered_Collection

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

MiscAsm.cpp (43117B)


      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 /*
     18 ** 
     19 **   Misc. assembly code moved from headers
     20 ** 
     21 ** 
     22 ** 
     23 ** 
     24 ** 
     25 */
     26 
     27 #include "FUNCTION.H"
     28 
     29 
     30 
     31 extern "C" void __cdecl Mem_Copy(void const *source, void *dest, unsigned long bytes_to_copy)
     32 {
     33 	memcpy(dest, source, bytes_to_copy);
     34 }			  
     35 
     36 
     37 /***********************************************************************************************
     38  * Distance -- Determines the lepton distance between two coordinates.                         *
     39  *                                                                                             *
     40  *    This routine is used to determine the distance between two coordinates. It uses the      *
     41  *    Dragon Strike method of distance determination and thus it is very fast.                 *
     42  *                                                                                             *
     43  * INPUT:   coord1   -- First coordinate.                                                      *
     44  *                                                                                             *
     45  *          coord2   -- Second coordinate.                                                     *
     46  *                                                                                             *
     47  * OUTPUT:  Returns the lepton distance between the two coordinates.                           *
     48  *                                                                                             *
     49  * WARNINGS:   none                                                                            *
     50  *                                                                                             *
     51  * HISTORY:                                                                                    *
     52  *   05/27/1994 JLB : Created.                                                                 *
     53  *=============================================================================================*/
     54 int Distance_Coord(COORDINATE coord1, COORDINATE coord2)
     55 {
     56 	__asm {
     57 		mov	eax,[coord1]
     58 		mov	ebx,[coord2]
     59 		mov	dx,ax			
     60 		sub	dx,bx			
     61 		jg	okx				
     62 		neg	dx				
     63 		okx:					
     64 		shr	eax,16			
     65 		shr	ebx,16			
     66 		sub	ax,bx			
     67 		jg	oky				
     68 		neg	ax				
     69 oky:					
     70 		cmp	ax,dx			
     71 		jg	ok				
     72 		xchg	ax,dx			
     73 ok:						
     74 		shr	dx,1				
     75 		add	ax,dx
     76 	}
     77 }			  
     78 
     79 
     80 
     81 
     82 /*
     83 ;***************************************************************************
     84 ;* DESIRED_FACING16 -- Converts coordinates into a facing number.          *
     85 ;*                                                                         *
     86 ;*      This converts coordinates into a desired facing number that ranges *
     87 ;*      from 0 to 15 (0 equals North and going clockwise).                 *
     88 ;*                                                                         *
     89 ;* INPUT:       x1,y1   -- Position of origin point.                       *
     90 ;*                                                                         *
     91 ;*              x2,y2   -- Position of target.                             *
     92 ;*                                                                         *
     93 ;* OUTPUT:      Returns desired facing as a number from 0 to 255 but       *
     94 ;*              accurate to 22.5 degree increments.                        *
     95 ;*                                                                         *
     96 ;* WARNINGS:    If the two coordinates are the same, then -1 will be       *
     97 ;*              returned.  It is up to you to handle this case.            *
     98 ;*                                                                         *
     99 ;* HISTORY:                                                                *
    100 ;*   08/14/1991 JLB : Created.                                             *
    101 ;*=========================================================================*
    102 */
    103 
    104 long __cdecl Desired_Facing16(long x1, long y1, long x2, long y2)
    105 {
    106 	static const char _new_facing16[] = {
    107 		3, 2, 4,-1, 1, 2,0,-1,
    108 		13,14,12,-1,15,14,0,-1,
    109 		5, 6, 4,-1, 7, 6,8,-1,
    110 		11,10,12,-1, 9,10,8,-1
    111 	};
    112 
    113 	
    114 	__asm {		  
    115 		xor	ebx,ebx			//; Index byte (built).
    116 
    117 		//; Determine Y axis difference.
    118 		mov	edx,[y1]
    119 		mov	ecx,[y2]
    120 		sub	edx,ecx			//; DX = Y axis (signed).
    121 		jns	short absy
    122 		inc	ebx			//; Set the signed bit.
    123 		neg	edx			//; ABS(y)
    124 absy:
    125 
    126 		//; Determine X axis difference.
    127 		shl	ebx,1
    128 		mov	eax,[x1]
    129 		mov	ecx,[x2]
    130 		sub	ecx,eax			//; CX = X axis (signed).
    131 		jns	short absx
    132 		inc	ebx			//; Set the signed bit.
    133 		neg	ecx			//; ABS(x)
    134 absx:
    135 
    136 		//; Determine the greater axis.
    137 		cmp	ecx,edx
    138 		jb	short dxisbig
    139 		xchg	ecx,edx
    140 dxisbig:
    141 		rcl	ebx,1			//; Y > X flag bit.
    142 
    143 		//; Determine the closeness or farness of lesser axis.
    144 		mov	eax,edx
    145 		inc	eax			//; Round up.
    146 		shr	eax,1
    147 		inc	eax			//; Round up.
    148 		shr	eax,1			//; 1/4 of greater axis.
    149 
    150 		cmp	ecx,eax
    151 		rcl	ebx,1			//; Very close to major axis bit.
    152 
    153 		sub	edx,eax
    154 		cmp	edx,ecx
    155 		rcl	ebx,1			//; Very far from major axis bit.
    156 
    157 		xor	eax,eax
    158 		mov	al,[_new_facing16+ebx]
    159 
    160 		//; Normalize to 0..FF range.
    161 		shl	eax,4
    162 
    163 //		ret
    164 	}
    165 }
    166 
    167 
    168 
    169 
    170 
    171 
    172 
    173 
    174 
    175 
    176 
    177 
    178 
    179 
    180 
    181 /*
    182 ;***************************************************************************
    183 ;* Desired_Facing256 -- Desired facing algorithm 0..255 resolution.        *
    184 ;*                                                                         *
    185 ;*    This is a desired facing algorithm that has a resolution of 0        *
    186 ;*    through 255.                                                         *
    187 ;*                                                                         *
    188 ;* INPUT:   srcx,srcy   -- Source coordinate.                              *
    189 ;*                                                                         *
    190 ;*          dstx,dsty   -- Destination coordinate.                         *
    191 ;*                                                                         *
    192 ;* OUTPUT:  Returns with the desired facing to face the destination        *
    193 ;*          coordinate from the position of the source coordinate.  North  *
    194 ;*          is 0, East is 64, etc.                                         *
    195 ;*                                                                         *
    196 ;* WARNINGS:   This routine is slower than the other forms of desired      *
    197 ;*             facing calculation.  Use this routine when accuracy is      *
    198 ;*             required.                                                   *
    199 ;*                                                                         *
    200 ;* HISTORY:                                                                *
    201 ;*   12/24/1991 JLB : Adapted.                                             *
    202 ;*=========================================================================*/
    203 
    204 int __cdecl Desired_Facing256(LONG srcx, LONG srcy, LONG dstx, LONG dsty)
    205 {
    206 	
    207 	__asm {
    208 			xor	ebx,ebx			//; Facing number.
    209 
    210 			////; Determine absolute X delta and left/right direction.
    211 			mov	ecx,[dstx]
    212 			sub	ecx,[srcx]
    213 			jge	short xnotneg
    214 			neg	ecx
    215 			mov	ebx,11000000b		//; Set bit 7 and 6 for leftward.
    216 xnotneg:
    217 
    218 			//; Determine absolute Y delta and top/bottom direction.
    219 			mov	eax,[srcy]
    220 			sub	eax,[dsty]
    221 			jge	short ynotneg
    222 			xor	ebx,01000000b		//; Complement bit 6 for downward.
    223 			neg	eax
    224 ynotneg:
    225 
    226 			//; Set DX=64 for quadrants 0 and 2.
    227 			mov	edx,ebx
    228 			and	edx,01000000b
    229 			xor	edx,01000000b
    230 
    231 			//; Determine if the direction is closer to the Y axis and make sure that
    232 			//; CX holds the larger of the two deltas.  This is in preparation for the
    233 			//; divide.
    234 			cmp	eax,ecx
    235 			jb	short gotaxis
    236 			xchg	eax,ecx
    237 			xor	edx,01000000b		//; Closer to Y axis so make DX=64 for quad 0 and 2.
    238 gotaxis:
    239 
    240 			//; If closer to the X axis then add 64 for quadrants 0 and 2.  If
    241 			//; closer to the Y axis then add 64 for quadrants 1 and 3.  Determined
    242 			//; add value is in DX and save on stack.
    243 			push	edx
    244 
    245 			//; Make sure that the division won't overflow.  Reduce precision until
    246 			//; the larger number is less than 256 if it appears that an overflow
    247 			//; will occur.  If the high byte of the divisor is not zero, then this
    248 			//; guarantees no overflow, so just abort shift operation.
    249 			test	eax,0FFFFFF00h
    250 			jnz	short nooverflow
    251 again:
    252 			test	ecx,0FFFFFF00h
    253 			jz	short nooverflow
    254 			shr	ecx,1
    255 			shr	eax,1
    256 			jmp	short again
    257 nooverflow:
    258 
    259 			//; Make sure that the division won't underflow (divide by zero).  If
    260 			//; this would occur, then set the quotient to $FF and skip divide.
    261 			or	ecx,ecx
    262 			jnz	short nounderflow
    263 			mov	eax,0FFFFFFFFh
    264 			jmp	short divcomplete
    265 
    266 			//; Derive a pseudo angle number for the octant.  The angle is based
    267 			//; on $00 = angle matches long axis, $00 = angle matches $FF degrees.
    268 nounderflow:
    269 			xor	edx,edx
    270 			shld	edx,eax,8	//; shift high byte of eax into dl
    271 			shl	eax,8
    272 			div	ecx
    273 divcomplete:
    274 
    275 			//; Integrate the 5 most significant bits into the angle index.  If DX
    276 			//; is not zero, then it is 64.  This means that the dividend must be negated
    277 			//; before it is added into the final angle value.
    278 			shr	eax,3
    279 			pop	edx
    280 			or	edx,edx
    281 			je	short noneg
    282 			dec	edx
    283 			neg	eax
    284 noneg:
    285 			add	eax,edx
    286 			add	eax,ebx
    287 			and	eax,0FFH
    288 //			ret
    289 	}
    290 }		 
    291 
    292 
    293 
    294 
    295 
    296 
    297 
    298 
    299 
    300 
    301 
    302 
    303 /*
    304 
    305 ;***************************************************************************
    306 ;**   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   **
    307 ;***************************************************************************
    308 ;*                                                                         *
    309 ;*                 Project Name : Support Library                          *
    310 ;*                                                                         *
    311 ;*                    File Name : FACING8.ASM                              *
    312 ;*                                                                         *
    313 ;*                   Programmer : Joe L. Bostic                            *
    314 ;*                                                                         *
    315 ;*                   Start Date : May 8, 1991                              *
    316 ;*                                                                         *
    317 ;*                  Last Update : February 6, 1995  [BWG]                  *
    318 ;*                                                                         *
    319 ;*-------------------------------------------------------------------------*
    320 ;* Functions:                                                              *
    321 ;*   Desired_Facing8 -- Determines facing to reach a position.             *
    322 ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
    323 
    324 
    325 IDEAL
    326 P386
    327 MODEL USE32 FLAT
    328 
    329 GLOBAL	 C Desired_Facing8	:NEAR
    330 ;	INCLUDE	"wwlib.i"
    331 
    332 	DATASEG
    333 
    334 ; 8 direction desired facing lookup table.  Build the index according
    335 ; to the following bits:
    336 ;
    337 ; bit 3 = Is y2 < y1?
    338 ; bit 2 = Is x2 < x1?
    339 ; bit 1 = Is the ABS(x2-x1) < ABS(y2-y1)?
    340 ; bit 0 = Is the facing closer to a major axis?
    341 //NewFacing8	DB	1,2,1,0,7,6,7,0,3,2,3,4,5,6,5,4
    342 
    343 //	CODESEG
    344 */
    345 
    346 /*
    347 ;***************************************************************************
    348 ;* DESIRED_FACING8 -- Determines facing to reach a position.               *
    349 ;*                                                                         *
    350 ;*    This routine will return with the most desirable facing to reach     *
    351 ;*    one position from another.  It is accurate to a resolution of 0 to   *
    352 ;*    7.                                                                   *
    353 ;*                                                                         *
    354 ;* INPUT:       x1,y1   -- Position of origin point.                       *
    355 ;*                                                                         *
    356 ;*              x2,y2   -- Position of target.                             *
    357 ;*                                                                         *
    358 ;* OUTPUT:      Returns desired facing as a number from 0..255 with an     *
    359 ;*              accuracy of 32 degree increments.                          *
    360 ;*                                                                         *
    361 ;* WARNINGS:    If the two coordinates are the same, then -1 will be       *
    362 ;*              returned.  It is up to you to handle this case.            *
    363 ;*                                                                         *
    364 ;* HISTORY:                                                                *
    365 ;*   07/15/1991 JLB : Documented.                                          *
    366 ;*   08/08/1991 JLB : Same position check.                                 *
    367 ;*   08/14/1991 JLB : New algorithm                                        *
    368 ;*   02/06/1995 BWG : Convert to 32-bit                                    *
    369 ;*=========================================================================*
    370 */
    371 int __cdecl Desired_Facing8(long x1, long y1, long x2, long y2)
    372 {
    373 	
    374 	static const char _new_facing8[] = {1,2,1,0,7,6,7,0,3,2,3,4,5,6,5,4};
    375 	
    376 	__asm {
    377 		
    378 		xor	ebx,ebx			//; Index byte (built).
    379 
    380 		//; Determine Y axis difference.
    381 		mov	edx,[y1]
    382 		mov	ecx,[y2]
    383 		sub	edx,ecx			//; DX = Y axis (signed).
    384 		jns	short absy
    385 		inc	ebx			//; Set the signed bit.
    386 		neg	edx			//; ABS(y)
    387 absy:
    388 
    389 		//; Determine X axis difference.
    390 		shl	ebx,1
    391 		mov	eax,[x1]
    392 		mov	ecx,[x2]
    393 		sub	ecx,eax			//; CX = X axis (signed).
    394 		jns	short absx
    395 		inc	ebx			//; Set the signed bit.
    396 		neg	ecx			//; ABS(x)
    397 absx:
    398 
    399 		//; Determine the greater axis.
    400 		cmp	ecx,edx
    401 		jb	short dxisbig
    402 		xchg	ecx,edx
    403 dxisbig:
    404 		rcl	ebx,1			//; Y > X flag bit.
    405 
    406 		//; Determine the closeness or farness of lesser axis.
    407 		mov	eax,edx
    408 		inc	eax			//; Round up.
    409 		shr	eax,1
    410 
    411 		cmp	ecx,eax
    412 		rcl	ebx,1			//; Close to major axis bit.
    413 
    414 		xor	eax,eax
    415 		mov	al,[_new_facing8+ebx]
    416 
    417 		//; Normalize to 0..FF range.
    418 		shl	eax,5
    419 
    420 //		ret
    421 
    422 	}
    423 	
    424 }
    425 
    426 
    427 
    428 #if (0)
    429 
    430 /*
    431 	; $Header: //depot/Projects/Mobius/QA/Project/Run/SOURCECODE/REDALERT/MiscAsm.cpp#139 $
    432 ;***************************************************************************
    433 ;**   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   **
    434 ;***************************************************************************
    435 ;*                                                                         *
    436 ;*                 Project Name : Support Library                          *
    437 ;*                                                                         *
    438 ;*                    File Name : FACING16.ASM                             *
    439 ;*                                                                         *
    440 ;*                   Programmer : Joe L. Bostic                            *
    441 ;*                                                                         *
    442 ;*                   Start Date : May 8, 1991                              *
    443 ;*                                                                         *
    444 ;*                  Last Update : February 6, 1995  [BWG]                  *
    445 ;*                                                                         *
    446 ;*-------------------------------------------------------------------------*
    447 ;* Functions:                                                              *
    448 ;*   Desired_Facing16 -- Converts coordinates into a facing number.        *
    449 ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
    450 
    451 
    452 IDEAL
    453 P386
    454 MODEL USE32 FLAT
    455 
    456 GLOBAL	 C Desired_Facing16	:NEAR
    457 ;	INCLUDE	"wwlib.i"
    458 
    459 	DATASEG
    460 
    461 ; 16 direction desired facing lookup table.  Build the index according
    462 ; to the following bits:
    463 ;
    464 ; bit 4 = Is y2 < y1?
    465 ; bit 3 = Is x2 < x1?
    466 ; bit 2 = Is the ABS(x2-x1) < ABS(y2-y1)?
    467 ; bit 1 = Is the lesser absolute difference very close to zero?
    468 ; bit 0 = Is the lesser absolute difference very close to the greater dist?
    469 NewFacing16	DB	 3, 2, 4,-1, 1, 2,0,-1
    470 		DB	13,14,12,-1,15,14,0,-1
    471 		DB	 5, 6, 4,-1, 7, 6,8,-1
    472 		DB	11,10,12,-1, 9,10,8,-1
    473 
    474 	CODESEG
    475 
    476 ;***************************************************************************
    477 ;* DESIRED_FACING16 -- Converts coordinates into a facing number.          *
    478 ;*                                                                         *
    479 ;*      This converts coordinates into a desired facing number that ranges *
    480 ;*      from 0 to 15 (0 equals North and going clockwise).                 *
    481 ;*                                                                         *
    482 ;* INPUT:       x1,y1   -- Position of origin point.                       *
    483 ;*                                                                         *
    484 ;*              x2,y2   -- Position of target.                             *
    485 ;*                                                                         *
    486 ;* OUTPUT:      Returns desired facing as a number from 0 to 255 but       *
    487 ;*              accurate to 22.5 degree increments.                        *
    488 ;*                                                                         *
    489 ;* WARNINGS:    If the two coordinates are the same, then -1 will be       *
    490 ;*              returned.  It is up to you to handle this case.            *
    491 ;*                                                                         *
    492 ;* HISTORY:                                                                *
    493 ;*   08/14/1991 JLB : Created.                                             *
    494 ;*=========================================================================*
    495 */
    496 long __cdecl Desired_Facing16(long x1, long y1, long x2, long y2)
    497 {
    498 	
    499 	__asm {
    500 			xor	ebx,ebx			; Index byte (built).
    501 
    502 			; Determine Y axis difference.
    503 			mov	edx,[y1]
    504 			mov	ecx,[y2]
    505 			sub	edx,ecx			//; DX = Y axis (signed).
    506 			jns	short absy
    507 			inc	ebx			//; Set the signed bit.
    508 			neg	edx			//; ABS(y)
    509 absy:
    510 
    511 			//; Determine X axis difference.
    512 			shl	ebx,1
    513 			mov	eax,[x1]
    514 			mov	ecx,[x2]
    515 			sub	ecx,eax			//; CX = X axis (signed).
    516 			jns	short absx
    517 			inc	ebx			//; Set the signed bit.
    518 			neg	ecx			//; ABS(x)
    519 absx:
    520 
    521 			//; Determine the greater axis.
    522 			cmp	ecx,edx
    523 			jb	short dxisbig
    524 			xchg	ecx,edx
    525 dxisbig:
    526 			rcl	ebx,1			//; Y > X flag bit.
    527 
    528 			//; Determine the closeness or farness of lesser axis.
    529 			mov	eax,edx
    530 			inc	eax			//; Round up.
    531 			shr	eax,1
    532 			inc	eax			//; Round up.
    533 			shr	eax,1			//; 1/4 of greater axis.
    534 
    535 			cmp	ecx,eax
    536 			rcl	ebx,1			//; Very close to major axis bit.
    537 
    538 			sub	edx,eax
    539 			cmp	edx,ecx
    540 			rcl	ebx,1			//; Very far from major axis bit.
    541 
    542 			xor	eax,eax
    543 			mov	al,[NewFacing16+ebx]
    544 
    545 			//; Normalize to 0..FF range.
    546 			shl	eax,4
    547 
    548 //			ret
    549 	}
    550 }
    551 		
    552 	
    553 			  
    554 	
    555 #if (0)
    556 	PROC	Desired_Facing16 C near
    557 	USES	ebx, ecx, edx
    558 
    559 	ARG	x1:DWORD
    560 	ARG	y1:DWORD
    561 	ARG	x2:DWORD
    562 	ARG	y2:DWORD
    563 
    564 	xor	ebx,ebx			; Index byte (built).
    565 
    566 	; Determine Y axis difference.
    567 	mov	edx,[y1]
    568 	mov	ecx,[y2]
    569 	sub	edx,ecx			; DX = Y axis (signed).
    570 	jns	short ??absy
    571 	inc	ebx			; Set the signed bit.
    572 	neg	edx			; ABS(y)
    573 ??absy:
    574 
    575 	; Determine X axis difference.
    576 	shl	ebx,1
    577 	mov	eax,[x1]
    578 	mov	ecx,[x2]
    579 	sub	ecx,eax			; CX = X axis (signed).
    580 	jns	short ??absx
    581 	inc	ebx			; Set the signed bit.
    582 	neg	ecx			; ABS(x)
    583 ??absx:
    584 
    585 	; Determine the greater axis.
    586 	cmp	ecx,edx
    587 	jb	short ??dxisbig
    588 	xchg	ecx,edx
    589 ??dxisbig:
    590 	rcl	ebx,1			; Y > X flag bit.
    591 
    592 	; Determine the closeness or farness of lesser axis.
    593 	mov	eax,edx
    594 	inc	eax			; Round up.
    595 	shr	eax,1
    596 	inc	eax			; Round up.
    597 	shr	eax,1			; 1/4 of greater axis.
    598 
    599 	cmp	ecx,eax
    600 	rcl	ebx,1			; Very close to major axis bit.
    601 
    602 	sub	edx,eax
    603 	cmp	edx,ecx
    604 	rcl	ebx,1			; Very far from major axis bit.
    605 
    606 	xor	eax,eax
    607 	mov	al,[NewFacing16+ebx]
    608 
    609 	; Normalize to 0..FF range.
    610 	shl	eax,4
    611 
    612 	ret
    613 
    614 	ENDP	Desired_Facing16
    615 
    616 	END
    617 #endif
    618 #endif
    619 
    620 
    621 
    622 
    623 
    624 
    625 
    626 
    627 
    628 
    629 
    630 
    631 
    632 
    633 
    634 
    635 /*
    636 ;***********************************************************************************************
    637 ;* Cardinal_To_Fixed -- Converts cardinal numbers into a fixed point number.                   *
    638 ;*                                                                                             *
    639 ;*    This utility function will convert cardinal numbers into a fixed point fraction. The     *
    640 ;*    use of fixed point numbers occurs throughout the product -- since it is a convenient     *
    641 ;*    tool. The fixed point number is based on the formula:                                    *
    642 ;*                                                                                             *
    643 ;*       result = cardinal / base                                                              *
    644 ;*                                                                                             *
    645 ;*    The accuracy of the fixed point number is limited to 1/65536 as the lowest and up to     *
    646 ;*    65536 as the largest.                                                                    *
    647 ;*                                                                                             *
    648 ;* INPUT:   base     -- The key number to base the fraction about.                             *
    649 ;*                                                                                             *
    650 ;*          cardinal -- The other number (hey -- what do you call it?)                         *
    651 ;*                                                                                             *
    652 ;* OUTPUT:  Returns with the fixed point number of the "cardinal" parameter as it relates      *
    653 ;*          to the "base" parameter.                                                           *
    654 ;*                                                                                             *
    655 ;* WARNINGS:   none                                                                            *
    656 ;*                                                                                             *
    657 ;* HISTORY:                                                                                    *
    658 ;*   02/17/1995 BWG : Created.                                                                 *
    659 ;*=============================================================================================*/
    660 
    661 unsigned int __cdecl Cardinal_To_Fixed(unsigned base, unsigned cardinal)
    662 {
    663 	__asm {
    664 		
    665 				mov	eax, 0FFFFFFFFh	//; establish default return value
    666 
    667 				mov	ebx,[base]
    668 				or		ebx, ebx
    669 				jz		retneg1		//; if base==0, return 4294967295
    670 
    671 				mov	eax,[cardinal]		//; otherwise, return (cardinal*65536)/base
    672 				shl	eax,16
    673 				xor	edx,edx
    674 				div	ebx
    675 
    676 retneg1:
    677 				//ret
    678 
    679 		  
    680 	}	
    681 }
    682 
    683 #if (0)
    684 	PROC	Cardinal_To_Fixed C near
    685 	USES	ebx, edx
    686 
    687 	ARG	base:DWORD
    688 	ARG	cardinal:DWORD
    689 
    690 	mov	eax,0FFFFh		; establish default return value
    691 
    692 	mov	ebx,[base]
    693 	or	ebx,ebx
    694 	jz	near ??retneg1		; if base==0, return 65535
    695 
    696 	mov	eax,[cardinal]		; otherwise, return (cardinal*256)/base
    697 	shl	eax,8
    698 	xor	edx,edx
    699 	div	ebx
    700 
    701 ??retneg1:
    702 	ret
    703 
    704 	ENDP	Cardinal_To_Fixed
    705 #endif
    706 
    707 /*
    708 ;***********************************************************************************************
    709 ;* Fixed_To_Cardinal -- Converts a fixed point number into a cardinal number.                  *
    710 ;*                                                                                             *
    711 ;*    Use this routine to convert a fixed point number into a cardinal number.                 *
    712 ;*                                                                                             *
    713 ;* INPUT:   base     -- The base number that the original fixed point number was created from. *
    714 ;*                                                                                             *
    715 ;*          fixed    -- The fixed point number to convert.                                     *
    716 ;*                                                                                             *
    717 ;* OUTPUT:  Returns with the reconverted number.                                               *
    718 ;*                                                                                             *
    719 ;* WARNINGS:   none                                                                            *
    720 ;*                                                                                             *
    721 ;* HISTORY:                                                                                    *
    722 ;*   02/17/1995 BWG : Created.                                                                 *
    723 ;*=============================================================================================*/
    724 
    725 unsigned int __cdecl Fixed_To_Cardinal(unsigned base, unsigned fixed)
    726 {
    727 //	PROC	Fixed_To_Cardinal C near
    728 //	USES	edx
    729 
    730 //	ARG	base:DWORD
    731 //	ARG	fixed:DWORD
    732 
    733 	__asm {
    734 		mov	eax,[base]
    735 		mul	[fixed]
    736 		add	eax,08000h		//; eax = (base * fixed) + 0x8000
    737 
    738 		shr	eax,16			//; return eax/65536
    739 		//ret
    740 	}
    741 
    742 
    743 #if (0)
    744 	mov	eax,[base]
    745 	mul	[fixed]
    746 	add	eax,080h		; eax = (base * fixed) + 0x80
    747 
    748 	test	eax,0FF000000h		; if high byte set, return FFFF
    749 	jnz	??rneg1
    750 	shr	eax,8			; else, return eax/256
    751 	ret
    752 ??rneg1	:
    753 	mov	eax,0FFFFh		; establish default return value
    754 	ret
    755 
    756 	ENDP	Fixed_To_Cardinal
    757 
    758 	END
    759 #endif
    760 
    761 
    762 }
    763 
    764 
    765 
    766 
    767 
    768 
    769 
    770 
    771 
    772 
    773 
    774 
    775 
    776 
    777 
    778 void __cdecl Set_Bit(void * array, int bit, int value)
    779 {
    780 	__asm {
    781 		mov	ecx, [bit]
    782 		mov	eax, [value]
    783 		mov	esi, [array]
    784 		mov	ebx,ecx					
    785 		shr	ebx,5					
    786 		and	ecx,01Fh				
    787 		btr	[esi+ebx*4],ecx		
    788 		or	eax,eax					
    789 		jz	ok						
    790 		bts	[esi+ebx*4],ecx		
    791 ok:
    792 	}
    793 }
    794 
    795 
    796 int __cdecl Get_Bit(void const * array, int bit)
    797 {
    798 	__asm {
    799 		mov	eax, [bit]
    800 		mov	esi, [array]
    801 		mov	ebx,eax					
    802 		shr	ebx,5					
    803 		and	eax,01Fh				
    804 		bt	[esi+ebx*4],eax		
    805 		setc	al
    806 	}
    807 }
    808 
    809 int __cdecl First_True_Bit(void const * array)
    810 {
    811 	__asm {
    812 		mov	esi, [array]
    813 		mov	eax,-32					
    814 again:							
    815 		add	eax,32					
    816 		mov	ebx,[esi]				
    817 		add	esi,4					
    818 		bsf	ebx,ebx					
    819 		jz	again					
    820 		add	eax,ebx
    821 	}
    822 }
    823 
    824 
    825 int __cdecl First_False_Bit(void const * array)
    826 {
    827 	__asm {
    828 		
    829 		mov	esi, [array]
    830 		mov	eax,-32					
    831 again:							
    832 		add	eax,32					
    833 		mov	ebx,[esi]				
    834 		not	ebx						
    835 		add	esi,4					
    836 		bsf	ebx,ebx					
    837 		jz	again					
    838 		add	eax,ebx
    839 	}
    840 }
    841 
    842 int __cdecl Bound(int original, int min, int max)
    843 {		
    844 	__asm {
    845 		mov	eax,[original]
    846 		mov	ebx,[min]
    847 		mov	ecx,[max]
    848 		cmp	ebx,ecx					
    849 		jl	okorder					
    850 		xchg	ebx,ecx					
    851 okorder: cmp	eax,ebx		
    852 		jg	okmin					
    853 		mov	eax,ebx					
    854 okmin: cmp	eax,ecx			
    855 		jl	okmax					
    856 		mov	eax,ecx					
    857 okmax:
    858 	}
    859 }
    860 
    861 
    862 
    863 
    864 
    865 
    866 
    867 /*
    868 
    869 CELL __cdecl Coord_Cell(COORDINATE coord)
    870 {
    871 	__asm {
    872 		mov	eax, coord
    873 		mov	ebx,eax
    874 		shr	eax,010h
    875 		xor	al,al
    876 		shr	eax,2
    877 		or		al,bh
    878 	}
    879 
    880 }
    881 
    882 
    883 
    884 */
    885 
    886 
    887 
    888 
    889 
    890 /*
    891 ;***********************************************************
    892 ; SHAKE_SCREEN
    893 ;
    894 ; VOID Shake_Screen(int shakes);
    895 ;
    896 ; This routine shakes the screen the number of times indicated.
    897 ;
    898 ; Bounds Checking: None
    899 ;
    900 ;*
    901 */ 
    902 void __cdecl Shake_Screen(int shakes)
    903 {
    904 	// PG_TO_FIX	
    905 	// Need a different solution for shaking the screen
    906 	shakes;
    907 }
    908 
    909 
    910 
    911 #if (0)
    912 GLOBAL	C Shake_Screen	:NEAR
    913 
    914 	CODESEG
    915 
    916 ;***********************************************************
    917 ; SHAKE_SCREEN
    918 ;
    919 ; VOID Shake_Screen(int shakes);
    920 ;
    921 ; This routine shakes the screen the number of times indicated.
    922 ;
    923 ; Bounds Checking: None
    924 ;
    925 ;*
    926 	PROC	Shake_Screen C near
    927 	USES	ecx, edx
    928 
    929 	ARG	shakes:DWORD
    930  ret
    931 
    932 	mov	ecx,[shakes]
    933 
    934 ;;; push es
    935 ;;; mov ax,40h
    936 ;;; mov es,ax
    937 ;;; mov dx,[es:63h]
    938 ;;; pop es
    939 	mov	eax,[0463h]		; get CRTC I/O port
    940 	mov	dx,ax
    941 	add	dl,6			; video status port
    942 
    943 ??top_loop:
    944 
    945 ??start_retrace:
    946 	in	al,dx
    947 	test	al,8
    948 	jz	??start_retrace
    949 
    950 ??end_retrace:
    951 	in	al,dx
    952 	test	al,8
    953 	jnz	??end_retrace
    954 
    955 	cli
    956 	sub	dl,6			; dx = 3B4H or 3D4H
    957 
    958 	mov	ah,01			; top word of start address
    959 	mov	al,0Ch
    960 	out	dx,al
    961 	xchg	ah,al
    962 	inc	dx
    963 	out	dx,al
    964 	xchg	ah,al
    965 	dec	dx
    966 
    967 	mov	ah,040h			; bottom word = 40 (140h)
    968 	inc	al
    969 	out	dx,al
    970 	xchg	ah,al
    971 	inc	dx
    972 	out	dx,al
    973 	xchg	ah,al
    974 
    975 	sti
    976 	add	dl,5
    977 
    978 ??start_retrace2:
    979 	in	al,dx
    980 	test	al,8
    981 	jz	??start_retrace2
    982 
    983 ??end_retrace2:
    984 	in	al,dx
    985 	test	al,8
    986 	jnz	??end_retrace2
    987 
    988 ??start_retrace3:
    989 	in	al,dx
    990 	test	al,8
    991 	jz	??start_retrace3
    992 
    993 ??end_retrace3:
    994 	in	al,dx
    995 	test	al,8
    996 	jnz	??end_retrace3
    997 
    998 	cli
    999 	sub	dl,6			; dx = 3B4H or 3D4H
   1000 
   1001 	mov	ah,0
   1002 	mov	al,0Ch
   1003 	out	dx,al
   1004 	xchg	ah,al
   1005 	inc	dx
   1006 	out	dx,al
   1007 	xchg	ah,al
   1008 	dec	dx
   1009 
   1010 	mov	ah,0
   1011 	inc	al
   1012 	out	dx,al
   1013 	xchg	ah,al
   1014 	inc	dx
   1015 	out	dx,al
   1016 	xchg	ah,al
   1017 
   1018 	sti
   1019 	add	dl,5
   1020 
   1021 	loop	??top_loop
   1022 
   1023 	ret
   1024 
   1025 	ENDP	Shake_Screen
   1026 
   1027 ;***********************************************************
   1028 
   1029 	END
   1030 
   1031 #endif
   1032 
   1033 
   1034 
   1035 
   1036 
   1037 
   1038 
   1039 
   1040 
   1041 
   1042 
   1043 
   1044 
   1045 
   1046 /*
   1047 
   1048 ;***************************************************************************
   1049 ;* Conquer_Build_Fading_Table -- Builds custom shadow/light fading table.  *
   1050 ;*                                                                         *
   1051 ;*    This routine is used to build a special fading table for C&C.  There *
   1052 ;*    are certain colors that get faded to and cannot be faded again.      *
   1053 ;*    With this rule, it is possible to draw a shadow multiple times and   *
   1054 ;*    not have it get any lighter or darker.                               *
   1055 ;*                                                                         *
   1056 ;* INPUT:   palette  -- Pointer to the 768 byte IBM palette to build from. *
   1057 ;*                                                                         *
   1058 ;*          dest     -- Pointer to the 256 byte remap table.               *
   1059 ;*                                                                         *
   1060 ;*          color    -- Color index of the color to "fade to".             *
   1061 ;*                                                                         *
   1062 ;*          frac     -- The fraction to fade to the specified color        *
   1063 ;*                                                                         *
   1064 ;* OUTPUT:  Returns with pointer to the remap table.                       *
   1065 ;*                                                                         *
   1066 ;* WARNINGS:   none                                                        *
   1067 ;*                                                                         *
   1068 ;* HISTORY:                                                                *
   1069 ;*   10/07/1992 JLB : Created.                                             *
   1070 ;*=========================================================================*/
   1071 
   1072 void * __cdecl Conquer_Build_Fading_Table(void const *palette, void *dest, int color, int frac)
   1073 {	
   1074 	/*
   1075 	global C	Conquer_Build_Fading_Table : NEAR
   1076 	PROC	Conquer_Build_Fading_Table C near
   1077 	USES	ebx, ecx, edi, esi
   1078 
   1079 	ARG	palette:DWORD
   1080 	ARG	dest:DWORD
   1081 	ARG	color:DWORD
   1082 	ARG	frac:DWORD
   1083 
   1084 	LOCAL	matchvalue:DWORD	; Last recorded match value.
   1085 	LOCAL	targetred:BYTE		; Target gun red.
   1086 	LOCAL	targetgreen:BYTE	; Target gun green.
   1087 	LOCAL	targetblue:BYTE		; Target gun blue.
   1088 	LOCAL	idealred:BYTE
   1089 	LOCAL	idealgreen:BYTE
   1090 	LOCAL	idealblue:BYTE
   1091 	LOCAL	matchcolor:BYTE		; Tentative match color.
   1092 	
   1093 ALLOWED_COUNT	EQU	16
   1094 ALLOWED_START	EQU	256-ALLOWED_COUNT
   1095 	*/
   1096 
   1097 #define	ALLOWED_COUNT	16
   1098 #define	ALLOWED_START	256-ALLOWED_COUNT
   1099 
   1100 	int matchvalue = 0;	//:DWORD	; Last recorded match value.
   1101 	unsigned char targetred = 0;		//BYTE		; Target gun red.
   1102 	unsigned char targetgreen = 0;	//BYTE		; Target gun green.
   1103 	unsigned char targetblue = 0;		//BYTE		; Target gun blue.
   1104 	unsigned char idealred = 0;		//BYTE	
   1105 	unsigned char idealgreen = 0;		//BYTE	
   1106 	unsigned char idealblue = 0;		//BYTE	
   1107 	unsigned char matchcolor = 0;		//:BYTE		; Tentative match color.
   1108 
   1109 	__asm {
   1110 	
   1111 			cld
   1112 
   1113 			; If the source palette is NULL, then just return with current fading table pointer.
   1114 			cmp	[palette],0
   1115 			je	fini1
   1116 			cmp	[dest],0
   1117 			je	fini1
   1118 
   1119 			; Fractions above 255 become 255.
   1120 			mov	eax,[frac]
   1121 			cmp	eax,0100h
   1122 			jb	short ok
   1123 			mov	[frac],0FFh
   1124 		ok:
   1125 
   1126 			; Record the target gun values.
   1127 			mov	esi,[palette]
   1128 			mov	ebx,[color]
   1129 			add	esi,ebx
   1130 			add	esi,ebx
   1131 			add	esi,ebx
   1132 			lodsb
   1133 			mov	[targetred],al
   1134 			lodsb
   1135 			mov	[targetgreen],al
   1136 			lodsb
   1137 			mov	[targetblue],al
   1138 
   1139 			; Main loop.
   1140 			xor	ebx,ebx			; Remap table index.
   1141 
   1142 			; Transparent black never gets remapped.
   1143 			mov	edi,[dest]
   1144 			mov	[edi],bl
   1145 			inc	edi
   1146 
   1147 			; EBX = source palette logical number (1..255).
   1148 			; EDI = running pointer into dest remap table.
   1149 		mainloop:
   1150 			inc	ebx
   1151 			mov	esi,[palette]
   1152 			add	esi,ebx
   1153 			add	esi,ebx
   1154 			add	esi,ebx
   1155 
   1156 			mov	edx,[frac]
   1157 			shr	edx,1
   1158 			; new = orig - ((orig-target) * fraction);
   1159 
   1160 			lodsb				; orig
   1161 			mov	dh,al			; preserve it for later.
   1162 			sub	al,[targetred]		; al = (orig-target)
   1163 			imul	dl			; ax = (orig-target)*fraction
   1164 			shl	eax,1
   1165 			sub	dh,ah			; dh = orig - ((orig-target) * fraction)
   1166 			mov	[idealred],dh		; preserve ideal color gun value.
   1167 
   1168 			lodsb				; orig
   1169 			mov	dh,al			; preserve it for later.
   1170 			sub	al,[targetgreen]	; al = (orig-target)
   1171 			imul	dl			; ax = (orig-target)*fraction
   1172 			shl	eax,1
   1173 			sub	dh,ah			; dh = orig - ((orig-target) * fraction)
   1174 			mov	[idealgreen],dh		; preserve ideal color gun value.
   1175 
   1176 			lodsb				; orig
   1177 			mov	dh,al			; preserve it for later.
   1178 			sub	al,[targetblue]		; al = (orig-target)
   1179 			imul	dl			; ax = (orig-target)*fraction
   1180 			shl	eax,1
   1181 			sub	dh,ah			; dh = orig - ((orig-target) * fraction)
   1182 			mov	[idealblue],dh		; preserve ideal color gun value.
   1183 
   1184 			; Sweep through a limited set of existing colors to find the closest
   1185 			; matching color.
   1186 
   1187 			mov	eax,[color]
   1188 			mov	[matchcolor],al		; Default color (self).
   1189 			mov	[matchvalue],-1		; Ridiculous match value init.
   1190 			mov	ecx,ALLOWED_COUNT
   1191 
   1192 			mov	esi,[palette]		; Pointer to original palette.
   1193 			add	esi,(ALLOWED_START)*3
   1194 
   1195 			; BH = color index.
   1196 			mov	bh,ALLOWED_START
   1197 		innerloop:
   1198 
   1199 			xor	edx,edx			; Comparison value starts null.
   1200 
   1201 			; Build the comparison value based on the sum of the differences of the color
   1202 			; guns squared.
   1203 			lodsb
   1204 			sub	al,[idealred]
   1205 			mov	ah,al
   1206 			imul	ah
   1207 			add	edx,eax
   1208 
   1209 			lodsb
   1210 			sub	al,[idealgreen]
   1211 			mov	ah,al
   1212 			imul	ah
   1213 			add	edx,eax
   1214 
   1215 			lodsb
   1216 			sub	al,[idealblue]
   1217 			mov	ah,al
   1218 			imul	ah
   1219 			add	edx,eax
   1220 			jz	short perfect		; If perfect match found then quit early.
   1221 
   1222 			cmp	edx,[matchvalue]
   1223 			jae	short notclose
   1224 			mov	[matchvalue],edx	; Record new possible color.
   1225 			mov	[matchcolor],bh
   1226 		notclose:
   1227 			inc	bh			; Checking color index.
   1228 			loop	innerloop
   1229 			mov	bh,[matchcolor]
   1230 		perfect:
   1231 			mov	[matchcolor],bh
   1232 			xor	bh,bh			; Make BX valid main index again.
   1233 
   1234 			; When the loop exits, we have found the closest match.
   1235 			mov	al,[matchcolor]
   1236 			stosb
   1237 			cmp	ebx,ALLOWED_START-1
   1238 			jne	mainloop
   1239 
   1240 			; Fill the remainder of the remap table with values
   1241 			; that will remap the color to itself.
   1242 			mov	ecx,ALLOWED_COUNT
   1243 		fillerloop:
   1244 			inc	bl
   1245 			mov	al,bl
   1246 			stosb
   1247 			loop	fillerloop
   1248 
   1249 		fini1:
   1250 			mov	esi,[dest]
   1251 			mov	eax,esi
   1252 			
   1253 			//ret
   1254 	}
   1255 }
   1256 
   1257 
   1258 
   1259 
   1260 
   1261 
   1262 extern "C" long __cdecl Reverse_Long(long number)
   1263 {
   1264 	__asm {
   1265 		mov	eax,dword ptr [number]
   1266 		xchg	al,ah
   1267 		ror	eax,16
   1268 		xchg	al,ah
   1269 	}
   1270 }
   1271 
   1272 
   1273 extern "C" short __cdecl Reverse_Short(short number)
   1274 {
   1275 	__asm {
   1276 		mov	ax,[number]
   1277 		xchg	ah,al
   1278 	}
   1279 }	
   1280 
   1281 
   1282 
   1283 extern "C" long __cdecl Swap_Long(long number)
   1284 {
   1285 	__asm {
   1286 		mov	eax,dword ptr [number]
   1287 		ror	eax,16
   1288 	}
   1289 }
   1290 
   1291 
   1292 
   1293 
   1294 
   1295 
   1296 
   1297 
   1298 /*
   1299 
   1300 
   1301 
   1302 ;***************************************************************************
   1303 ;* strtrim -- Remove the trailing white space from a string.               *
   1304 ;*                                                                         *
   1305 ;*    Use this routine to remove white space characters from the beginning *
   1306 ;*    and end of the string.        The string is modified in place by     *
   1307 ;*    this routine.                                                        *
   1308 ;*                                                                         *
   1309 ;* INPUT:   buffer   -- Pointer to the string to modify.                   *
   1310 ;*                                                                         *
   1311 ;* OUTPUT:     none                                                        *
   1312 ;*                                                                         *
   1313 ;* WARNINGS:   none                                                        *
   1314 ;*                                                                         *
   1315 ;* HISTORY:                                                                *
   1316 ;*   10/07/1992 JLB : Created.                                             *
   1317 ;*=========================================================================*
   1318 ; VOID cdecl strtrim(BYTE *buffer);
   1319 	global C	strtrim :NEAR
   1320 	PROC	strtrim C near
   1321 	USES	ax, edi, esi
   1322 
   1323 	ARG	buffer:DWORD		; Pointer to string to modify.
   1324 */
   1325 void __cdecl strtrim(char *buffer)
   1326 {
   1327 	__asm {		  
   1328 			cmp	[buffer],0
   1329 			je	short fini
   1330 
   1331 			; Prepare for string scanning by loading pointers.
   1332 			cld
   1333 			mov	esi,[buffer]
   1334 			mov	edi,esi
   1335 
   1336 			; Strip white space from the start of the string.
   1337 		looper:
   1338 			lodsb
   1339 			cmp	al,20h			; Space
   1340 			je	short looper
   1341 			cmp	al,9			; TAB
   1342 			je	short looper
   1343 			stosb
   1344 
   1345 			; Copy the rest of the string.
   1346 		gruntloop:
   1347 			lodsb
   1348 			stosb
   1349 			or	al,al
   1350 			jnz	short gruntloop
   1351 			dec	edi
   1352 			; Strip the white space from the end of the string.
   1353 		looper2:
   1354 			mov	[edi],al
   1355 			dec	edi
   1356 			mov	ah,[edi]
   1357 			cmp	ah,20h
   1358 			je	short looper2
   1359 			cmp	ah,9
   1360 			je	short looper2
   1361 
   1362 		fini:
   1363 			//ret
   1364 	}
   1365 }
   1366 
   1367 
   1368 /*
   1369 ;***************************************************************************
   1370 ;* Fat_Put_Pixel -- Draws a fat pixel.                                     *
   1371 ;*                                                                         *
   1372 ;*    Use this routine to draw a "pixel" that is bigger than 1 pixel       *
   1373 ;*    across.  This routine is faster than drawing a similar small shape   *
   1374 ;*    and faster than calling Fill_Rect.                                   *
   1375 ;*                                                                         *
   1376 ;* INPUT:   x,y       -- Screen coordinates to draw the pixel's upper      *
   1377 ;*                       left corner.                                      *
   1378 ;*                                                                         *
   1379 ;*          color     -- The color to render the pixel in.                 *
   1380 ;*                                                                         *
   1381 ;*          size      -- The number of pixels width of the big "pixel".    *
   1382 ;*                                                                         *
   1383 ;*          page      -- The pointer to a GraphicBuffer class or something *
   1384 ;*                                                                         *
   1385 ;* OUTPUT:  none                                                           *
   1386 ;*                                                                         *
   1387 ;* WARNINGS:   none                                                        *
   1388 ;*                                                                         *
   1389 ;* HISTORY:                                                                *
   1390 ;*   03/17/1994 JLB : Created.                                             *
   1391 ;*=========================================================================*
   1392 ; VOID cdecl Fat_Put_Pixel(long x, long y, long color, long size, void *page)
   1393 	global C	Fat_Put_Pixel:NEAR
   1394 	PROC	Fat_Put_Pixel C near
   1395 	USES	eax, ebx, ecx, edx, edi, esi
   1396 
   1397 	ARG	x:DWORD		; X coordinate of upper left pixel corner.
   1398 	ARG	y:DWORD		; Y coordinate of upper left pixel corner.
   1399 	ARG	color:DWORD	; Color to use for the "pixel".
   1400 	ARG	siz:DWORD	; Size of "pixel" to plot (square).
   1401 	ARG	gpage:DWORD	; graphic page address to plot onto
   1402 */
   1403 
   1404 void __cdecl Fat_Put_Pixel(int x, int y, int color, int siz, GraphicViewPortClass &gpage)
   1405 {
   1406 	__asm {
   1407 				  
   1408 			cmp	[siz],0
   1409 			je	short exit_label
   1410 
   1411 			; Set EDI to point to start of logical page memory.
   1412 			;*===================================================================
   1413 			; Get the viewport information and put bytes per row in ecx
   1414 			;*===================================================================
   1415 			mov	ebx,[gpage]				; get a pointer to viewport
   1416 			mov	edi,[ebx]GraphicViewPortClass.Offset	; get the correct offset
   1417 
   1418 			; Verify the the Y pixel offset is legal.
   1419 			mov	eax,[y]
   1420 			cmp	eax,[ebx]GraphicViewPortClass.Height	;YPIXEL_MAX
   1421 			jae	short exit_label
   1422 			mov	ecx,[ebx]GraphicViewPortClass.Width
   1423 			add	ecx,[ebx]GraphicViewPortClass.XAdd
   1424 			add	ecx,[ebx]GraphicViewPortClass.Pitch
   1425 			mul	ecx
   1426 			add	edi,eax
   1427 
   1428 			; Verify the the X pixel offset is legal.
   1429 	
   1430 			mov	edx,[ebx]GraphicViewPortClass.Width
   1431 			cmp	edx,[x]
   1432 			mov	edx,ecx
   1433 			jbe	short exit_label
   1434 			add	edi,[x]
   1435 
   1436 			; Write the pixel to the screen.
   1437 			mov	ebx,[siz]		; Copy of pixel size.
   1438 			sub	edx,ebx			; Modulo to reach start of next row.
   1439 			mov	eax,[color]
   1440 		again:
   1441 			mov	ecx,ebx
   1442 			rep stosb
   1443 			add	edi,edx			; EDI points to start of next row.
   1444 			dec	[siz]
   1445 			jnz	short again
   1446 
   1447 		exit_label:
   1448 			//ret
   1449 	}
   1450 }
   1451 
   1452 
   1453 
   1454 
   1455 
   1456 
   1457 
   1458 
   1459 
   1460 
   1461 
   1462 /*
   1463 ;***************************************************************************
   1464 ;**   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   **
   1465 ;***************************************************************************
   1466 ;*                                                                         *
   1467 ;*                 Project Name : Westwood Library                         *
   1468 ;*                                                                         *
   1469 ;*                    File Name : CRC.ASM                                  *
   1470 ;*                                                                         *
   1471 ;*                   Programmer : Joe L. Bostic                            *
   1472 ;*                                                                         *
   1473 ;*                   Start Date : June 12, 1992                            *
   1474 ;*                                                                         *
   1475 ;*                  Last Update : February 10, 1995 [BWG]                  *
   1476 ;*                                                                         *
   1477 ;*-------------------------------------------------------------------------*
   1478 ;* Functions:                                                              *
   1479 ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
   1480 
   1481 IDEAL
   1482 P386
   1483 MODEL USE32 FLAT
   1484 
   1485 GLOBAL	C Calculate_CRC	:NEAR
   1486 
   1487 	CODESEG
   1488 */
   1489 /*
   1490 extern "C" long __cdecl Calculate_CRC(void *buffer, long length)
   1491 {
   1492 	unsigned long crc;
   1493 
   1494 	unsigned long local_length = (unsigned long) length;
   1495 
   1496 	__asm {
   1497 			; Load pointer to data block.
   1498 			mov	[crc],0
   1499 			pushad
   1500 			mov	esi,[buffer]
   1501 			cld
   1502 
   1503 			; Clear CRC to default (NULL) value.
   1504 			xor	ebx,ebx
   1505 
   1506 			//; Fetch the length of the data block to CRC.
   1507 			
   1508 			mov	ecx,[local_length]
   1509 
   1510 			jecxz	short fini
   1511 
   1512 			; Prepare the length counters.
   1513 			mov	edx,ecx
   1514 			and	dl,011b
   1515 			shr	ecx,2
   1516 
   1517 			; Perform the bulk of the CRC scanning.
   1518 			jecxz	short remainder2
   1519 		accumloop:
   1520 			lodsd
   1521 			rol	ebx,1
   1522 			add	ebx,eax
   1523 			loop	accumloop
   1524 
   1525 			; Handle the remainder bytes.
   1526 		remainder2:
   1527 			or	dl,dl
   1528 			jz	short fini
   1529 			mov	ecx,edx
   1530 			xor	eax,eax
   1531 
   1532 			and 	ecx,0FFFFh
   1533 			push	ecx
   1534 		nextbyte:
   1535 			lodsb
   1536 			ror	eax,8
   1537 			loop	nextbyte
   1538 			pop	ecx
   1539 			neg	ecx
   1540 			add	ecx,4
   1541 			shl	ecx,3
   1542 			ror	eax,cl
   1543 
   1544 		;nextbyte:
   1545 		;	shl	eax,8
   1546 		;	lodsb
   1547 		;	loop	nextbyte
   1548 			rol	ebx,1
   1549 			add	ebx,eax
   1550 
   1551 		fini:
   1552 			mov	[crc],ebx
   1553 			popad
   1554 			mov	eax,[crc]
   1555 			//ret
   1556 	}
   1557 }
   1558 
   1559 
   1560 */
   1561 
   1562 
   1563 
   1564 extern "C" void __cdecl Set_Palette_Range(void *palette)
   1565 {
   1566 	if (palette == NULL) {
   1567 		return;
   1568 	}
   1569 
   1570 	memcpy(CurrentPalette, palette, 768);
   1571 	Set_DD_Palette(palette);
   1572 }