| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556 |
- ;
- ; Copyright 2020 Electronic Arts Inc.
- ;
- ; TiberianDawn.DLL and RedAlert.dll and corresponding source code is free
- ; software: you can redistribute it and/or modify it under the terms of
- ; the GNU General Public License as published by the Free Software Foundation,
- ; either version 3 of the License, or (at your option) any later version.
- ; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
- ; in the hope that it will be useful, but with permitted additional restrictions
- ; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
- ; distributed with this program. You should have received a copy of the
- ; GNU General Public License along with permitted additional restrictions
- ; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>.
- ; $Header: F:\projects\c&c0\vcs\code\support.asv 5.0 11 Nov 1996 09:40:30 JOE_BOSTIC $
- ;***************************************************************************
- ;** 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 **
- ;***************************************************************************
- ;* *
- ;* Project Name : Command & Conquer *
- ;* *
- ;* File Name : SUPPORT.ASM *
- ;* *
- ;* Programmer : Joe L. Bostic *
- ;* *
- ;* Start Date : September 23, 1993 *
- ;* *
- ;* Last Update : May 10, 1994 [JLB] *
- ;* *
- ;*-------------------------------------------------------------------------*
- ;* Functions: *
- ;* strtrim -- Remove the trailing white space from a string. *
- ;* Fat_Put_Pixel -- Draws a fat pixel. *
- ;* Conquer_Build_Fading_Table -- Builds custom shadow/light fading table.*
- ;* Remove_From_List -- Removes a pointer from a list of pointers. *
- ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
- IDEAL
- P386
- MODEL USE32 FLAT
- INCLUDE "gbuffer.inc"
- DISPLAY "Command & Conquer assembly support routines."
- CODESEG
- ;***************************************************************************
- ;* Fat_Put_Pixel -- Draws a fat pixel. *
- ;* *
- ;* Use this routine to draw a "pixel" that is bigger than 1 pixel *
- ;* across. This routine is faster than drawing a similar small shape *
- ;* and faster than calling Fill_Rect. *
- ;* *
- ;* INPUT: x,y -- Screen coordinates to draw the pixel's upper *
- ;* left corner. *
- ;* *
- ;* color -- The color to render the pixel in. *
- ;* *
- ;* size -- The number of pixels width of the big "pixel". *
- ;* *
- ;* page -- The pointer to a GraphicBuffer class or something *
- ;* *
- ;* OUTPUT: none *
- ;* *
- ;* WARNINGS: none *
- ;* *
- ;* HISTORY: *
- ;* 03/17/1994 JLB : Created. *
- ;*=========================================================================*
- ; VOID cdecl Fat_Put_Pixel(long x, long y, long color, long size, void *page)
- GLOBAL C Fat_Put_Pixel:NEAR
- PROC Fat_Put_Pixel C near
- USES eax, ebx, ecx, edx, edi, esi
- ARG x:DWORD ; X coordinate of upper left pixel corner.
- ARG y:DWORD ; Y coordinate of upper left pixel corner.
- ARG color:DWORD ; Color to use for the "pixel".
- ARG siz:DWORD ; Size of "pixel" to plot (square).
- ARG gpage:DWORD ; graphic page address to plot onto
- cmp [siz],0
- je short ??exit
- ; Set EDI to point to start of logical page memory.
- ;*===================================================================
- ; Get the viewport information and put bytes per row in ecx
- ;*===================================================================
- mov ebx,[gpage] ; get a pointer to viewport
- mov edi,[(GraphicViewPort ebx).GVPOffset] ; get the correct offset
- ; Verify the the Y pixel offset is legal.
- mov eax,[y]
- cmp eax,[(GraphicViewPort ebx).GVPHeight] ;YPIXEL_MAX
- jae short ??exit
- mul [(GraphicViewPort ebx).GVPWidth]
- add edi,eax
- ; Verify the the X pixel offset is legal.
- mov edx,[(GraphicViewPort ebx).GVPWidth]
- cmp edx,[x]
- jbe short ??exit
- add edi,[x]
- ; Write the pixel to the screen.
- mov ebx,[siz] ; Copy of pixel size.
- sub edx,ebx ; Modulo to reach start of next row.
- mov eax,[color]
- ??again:
- mov ecx,ebx
- rep stosb
- add edi,edx ; EDI points to start of next row.
- dec [siz]
- jnz short ??again
- ??exit:
- ret
- ENDP Fat_Put_Pixel
- if 0
- ;***************************************************************************
- ;* strtrim -- Remove the trailing white space from a string. *
- ;* *
- ;* Use this routine to remove white space characters from the beginning *
- ;* and end of the string. The string is modified in place by *
- ;* this routine. *
- ;* *
- ;* INPUT: buffer -- Pointer to the string to modify. *
- ;* *
- ;* OUTPUT: none *
- ;* *
- ;* WARNINGS: none *
- ;* *
- ;* HISTORY: *
- ;* 10/07/1992 JLB : Created. *
- ;*=========================================================================*
- ; VOID cdecl strtrim(BYTE *buffer);
- GLOBAL C strtrim :NEAR
- PROC strtrim C near
- USES ax, edi, esi
- ARG buffer:DWORD ; Pointer to string to modify.
- cmp [buffer],0
- je short ??fini
- ; Prepare for string scanning by loading pointers.
- cld
- mov esi,[buffer]
- mov edi,esi
- ; Strip white space from the start of the string.
- ??looper:
- lodsb
- cmp al,20h ; Space
- je short ??looper
- cmp al,9 ; TAB
- je short ??looper
- stosb
- ; Copy the rest of the string.
- ??gruntloop:
- lodsb
- stosb
- or al,al
- jnz short ??gruntloop
- dec edi
- ; Strip the white space from the end of the string.
- ??looper2:
- mov [edi],al
- dec edi
- mov ah,[edi]
- cmp ah,20h
- je short ??looper2
- cmp ah,9
- je short ??looper2
- ??fini:
- ret
- ENDP strtrim
- ;***************************************************************************
- ;* Conquer_Build_Fading_Table -- Builds custom shadow/light fading table. *
- ;* *
- ;* This routine is used to build a special fading table for C&C. There *
- ;* are certain colors that get faded to and cannot be faded again. *
- ;* With this rule, it is possible to draw a shadow multiple times and *
- ;* not have it get any lighter or darker. *
- ;* *
- ;* INPUT: palette -- Pointer to the 768 byte IBM palette to build from. *
- ;* *
- ;* dest -- Pointer to the 256 byte remap table. *
- ;* *
- ;* color -- Color index of the color to "fade to". *
- ;* *
- ;* frac -- The fraction to fade to the specified color *
- ;* *
- ;* OUTPUT: Returns with pointer to the remap table. *
- ;* *
- ;* WARNINGS: none *
- ;* *
- ;* HISTORY: *
- ;* 10/07/1992 JLB : Created. *
- ;*=========================================================================*/
- ;VOID * cdecl Conquer_Build_Fading_Table(VOID *palette, VOID *dest, long color, long frac);
- GLOBAL C Conquer_Build_Fading_Table : NEAR
- PROC Conquer_Build_Fading_Table C near
- USES ebx, ecx, edi, esi
- ARG palette:DWORD
- ARG dest:DWORD
- ARG color:DWORD
- ARG frac:DWORD
- LOCAL matchvalue:DWORD ; Last recorded match value.
- LOCAL targetred:BYTE ; Target gun red.
- LOCAL targetgreen:BYTE ; Target gun green.
- LOCAL targetblue:BYTE ; Target gun blue.
- LOCAL idealred:BYTE
- LOCAL idealgreen:BYTE
- LOCAL idealblue:BYTE
- LOCAL matchcolor:BYTE ; Tentative match color.
- ALLOWED_COUNT EQU 16
- ALLOWED_START EQU 256-ALLOWED_COUNT
- cld
- ; If the source palette is NULL, then just return with current fading table pointer.
- cmp [palette],0
- je ??fini1
- cmp [dest],0
- je ??fini1
- ; Fractions above 255 become 255.
- mov eax,[frac]
- cmp eax,0100h
- jb short ??ok
- mov [frac],0FFh
- ??ok:
- ; Record the target gun values.
- mov esi,[palette]
- mov ebx,[color]
- add esi,ebx
- add esi,ebx
- add esi,ebx
- lodsb
- mov [targetred],al
- lodsb
- mov [targetgreen],al
- lodsb
- mov [targetblue],al
- ; Main loop.
- xor ebx,ebx ; Remap table index.
- ; Transparent black never gets remapped.
- mov edi,[dest]
- mov [edi],bl
- inc edi
- ; EBX = source palette logical number (1..255).
- ; EDI = running pointer into dest remap table.
- ??mainloop:
- inc ebx
- mov esi,[palette]
- add esi,ebx
- add esi,ebx
- add esi,ebx
- mov edx,[frac]
- shr edx,1
- ; new = orig - ((orig-target) * fraction);
- lodsb ; orig
- mov dh,al ; preserve it for later.
- sub al,[targetred] ; al = (orig-target)
- imul dl ; ax = (orig-target)*fraction
- shl eax,1
- sub dh,ah ; dh = orig - ((orig-target) * fraction)
- mov [idealred],dh ; preserve ideal color gun value.
- lodsb ; orig
- mov dh,al ; preserve it for later.
- sub al,[targetgreen] ; al = (orig-target)
- imul dl ; ax = (orig-target)*fraction
- shl eax,1
- sub dh,ah ; dh = orig - ((orig-target) * fraction)
- mov [idealgreen],dh ; preserve ideal color gun value.
- lodsb ; orig
- mov dh,al ; preserve it for later.
- sub al,[targetblue] ; al = (orig-target)
- imul dl ; ax = (orig-target)*fraction
- shl eax,1
- sub dh,ah ; dh = orig - ((orig-target) * fraction)
- mov [idealblue],dh ; preserve ideal color gun value.
- ; Sweep through a limited set of existing colors to find the closest
- ; matching color.
- mov eax,[color]
- mov [matchcolor],al ; Default color (self).
- mov [matchvalue],-1 ; Ridiculous match value init.
- mov ecx,ALLOWED_COUNT
- mov esi,[palette] ; Pointer to original palette.
- add esi,(ALLOWED_START)*3
- ; BH = color index.
- mov bh,ALLOWED_START
- ??innerloop:
- xor edx,edx ; Comparison value starts null.
- ; Build the comparison value based on the sum of the differences of the color
- ; guns squared.
- lodsb
- sub al,[idealred]
- mov ah,al
- imul ah
- add edx,eax
- lodsb
- sub al,[idealgreen]
- mov ah,al
- imul ah
- add edx,eax
- lodsb
- sub al,[idealblue]
- mov ah,al
- imul ah
- add edx,eax
- jz short ??perfect ; If perfect match found then quit early.
- cmp edx,[matchvalue]
- jae short ??notclose
- mov [matchvalue],edx ; Record new possible color.
- mov [matchcolor],bh
- ??notclose:
- inc bh ; Checking color index.
- loop ??innerloop
- mov bh,[matchcolor]
- ??perfect:
- mov [matchcolor],bh
- xor bh,bh ; Make BX valid main index again.
- ; When the loop exits, we have found the closest match.
- mov al,[matchcolor]
- stosb
- cmp ebx,ALLOWED_START-1
- jne ??mainloop
- ; Fill the remainder of the remap table with values
- ; that will remap the color to itself.
- mov ecx,ALLOWED_COUNT
- ??fillerloop:
- inc bl
- mov al,bl
- stosb
- loop ??fillerloop
- ??fini1:
- mov esi,[dest]
- mov eax,esi
- ret
- ENDP Conquer_Build_Fading_Table
- ;***************************************************************************
- ;* Remove_From_List -- Removes a pointer from a list of pointers. *
- ;* *
- ;* This low level routine is used to remove a pointer from a list of *
- ;* pointers. The trailing pointers are moved downward to fill the *
- ;* hole. *
- ;* *
- ;* INPUT: list -- Pointer to list of pointer. *
- ;* *
- ;* index -- Pointer to length of pointer list. *
- ;* *
- ;* ptr -- The pointer value to search for and remove. *
- ;* *
- ;* OUTPUT: none *
- ;* *
- ;* WARNINGS: none *
- ;* *
- ;* HISTORY: *
- ;* 04/11/1994 JLB : Created. *
- ;* 04/22/1994 JLB : Convert to assembly language. *
- ;* 05/10/1994 JLB : Short pointers now. *
- ;*=========================================================================*/
- ;VOID cdecl Remove_From_List(VOID **list, long *index, long ptr);
- GLOBAL C Remove_From_List:NEAR
- PROC Remove_From_List C near
- USES edi, esi, ecx, eax
- ARG list:DWORD ; Pointer to list.
- ARG index:DWORD ; Pointer to count.
- ARG element:DWORD ; Element to remove.
- ; Fetch the number of elements in the list. If there are no
- ; elements, then just exit quickly.
- mov edi,[index]
- mov ecx,[edi]
- jcxz short ??fini2
- ; Fetch pointer to list.
- cmp [list],0
- je short ??fini2
- mov edi,[list]
- ; Loop through all elements searching for a match.
- mov eax,[element]
- repne scasd
- jne short ??fini2 ; No match found.
- ; Copy all remaining elements down. If this is the
- ; last element in the list then nothing needs to be
- ; copied -- just decrement the list size.
- jcxz short ??nocopy ; No copy necessary.
- mov esi,edi
- sub edi,4
- rep movsd
- ; Reduce the list count by one.
- ??nocopy:
- mov edi,[index]
- dec [DWORD PTR edi]
- ??fini2:
- ret
- ENDP Remove_From_List
- ; long cdecl Get_EAX();
- GLOBAL C Get_EAX :NEAR
- PROC Get_EAX C near
- ret
- ENDP Get_EAX
- endif
- DATASEG
- TabA DD 6949350
- DD 4913933
- DD 3474675
- DD 2456966
- DD 1737338
- DD 1228483
- DD 868669
- DD 614242
- DD 434334
- DD 307121
- DD 217167
- DD 153560
- DD 108584
- DD 76780
- DD 54292
- DD 38390
- DD 27146
- DD 19195
- DD 13573
- DD 9598
- DD 6786
- DD 4799
- DD 3393
- DD 2399
- DD 1697
- DD 1200
- DD 848
- DD 600
- DD 424
- DD 300
- DD 212
- DD 150
- DD 106
- TabB DD 154
- DD 218
- DD 309
- DD 437
- DD 618
- DD 874
- DD 1236
- DD 1748
- DD 2472
- DD 3496
- DD 4944
- DD 6992
- DD 9888
- DD 13983
- DD 19775
- DD 27967
- DD 39551
- DD 55933
- DD 79101
- DD 111866
- DD 158203
- DD 223732
- DD 316405
- DD 447465
- DD 632811
- DD 894929
- DD 1265621
- DD 1789859
- DD 2531243
- DD 3579718
- DD 5062486
- DD 7159436
- DD 10124971
- CODESEG
- ;***********************************************************************************************
- ;* Square_Root -- Finds the square root of the fixed pointer parameter. *
- ;* *
- ;* INPUT: val -- The fixed point (16:16) value to find the square root of. *
- ;* *
- ;* OUTPUT: Returns with the square root of the fixed pointer parameter. *
- ;* *
- ;* WARNINGS: none *
- ;* *
- ;* HISTORY: *
- ;* 10/04/1995 JLB : Adapted. *
- ;*=============================================================================================*/
- ;unsigned Square_Root(unsigned val);
- GLOBAL C Square_Root :NEAR
- PROC Square_Root C near
- USES ebx,edx
- bsr ebx,eax
- jz ??zero
- mul [DWORD 4*ebx + OFFSET TabA]
- shrd eax,edx,10h
- add eax, [4*ebx + OFFSET TabB]
- ??zero:
- ret
- ENDP Square_Root
- ;----------------------------------------------------------------------------
- END
|