| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600 |
- ;
- ; Command & Conquer Red Alert(tm)
- ; Copyright 2025 Electronic Arts Inc.
- ;
- ; This program 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.
- ;
- ; This program is distributed in the hope that it will be useful,
- ; but WITHOUT ANY WARRANTY; without even the implied warranty of
- ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ; GNU General Public License for more details.
- ;
- ; You should have received a copy of the GNU General Public License
- ; along with this program. If not, see <http://www.gnu.org/licenses/>.
- ;
- ;***************************************************************************
- ;** 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 : Westwood Library *
- ;* *
- ;* File Name : STAMP.ASM *
- ;* *
- ;* Programmer : Joe L. Bostic *
- ;* *
- ;* Start Date : August 23, 1993 *
- ;* *
- ;* Last Update : August 23, 1993 [JLB] *
- ;* *
- ;*-------------------------------------------------------------------------*
- ;* Functions: *
- ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
- IDEAL
- P386
- MODEL USE32 FLAT
- INCLUDE ".\drawbuff.inc"
- INCLUDE ".\gbuffer.inc"
- INCLUDE "stamp.inc"
- global C Init_Stamps:near
- global LastIconset:dword
- global MapPtr:dword
- global IconCount:dword
- global IconSize:dword
- global StampPtr:dword
- DATASEG
- LastIconset DD 0 ; Pointer to last iconset initialized.
- StampPtr DD 0 ; Pointer to icon data.
- IsTrans DD 0 ; Pointer to transparent icon flag table.
- MapPtr DD 0 ; Pointer to icon map.
- IconWidth DD 0 ; Width of icon in pixels.
- IconHeight DD 0 ; Height of icon in pixels.
- IconSize DD 0 ; Number of bytes for each icon data.
- IconCount DD 0 ; Number of icons in the set.
- EVEN
- CODESEG
- GLOBAL C Buffer_Draw_Stamp:near
- GLOBAL C Buffer_Draw_Stamp_Clip:near
- ; 256 color icon system.
- ;***********************************************************
- ; INIT_STAMPS
- ;
- ; VOID cdecl Init_Stamps(VOID *icondata);
- ;
- ; This routine initializes the stamp data.
- ; Bounds Checking: NONE
- ;
- ;*
- PROC Init_Stamps C near USES eax ebx edx edi
- ARG icondata:DWORD
- ; Verify legality of parameter.
- cmp [icondata],0
- je short ??fini
- ; Don't initialize if already initialized to this set (speed reasons).
- mov edi,[icondata]
- cmp [LastIconset],edi
- je short ??fini
- mov [LastIconset],edi
- ; Record number of icons in set.
- movzx eax,[(IControl_Type edi).Count]
- mov [IconCount],eax
- ; Record width of icon.
- movzx eax,[(IControl_Type edi).Width]
- mov [IconWidth],eax
- ; Record height of icon.
- movzx ebx,[(IControl_Type edi).Height]
- mov [IconHeight],ebx
- ; Record size of icon (in bytes).
- mul ebx
- mov [IconSize],eax
- ; Record hard pointer to icon map data.
- mov eax,[(IControl_Type edi).Map]
- add eax,edi
- mov [MapPtr],eax
- ??nomap:
- ; Record hard pointer to icon data.
- mov eax,edi
- add eax,[(IControl_Type edi).Icons]
- mov [StampPtr],eax
- ; Record the transparent table.
- mov eax,edi
- add eax,[(IControl_Type edi).TransFlag]
- mov [IsTrans],eax
- ??fini:
- ret
- ENDP Init_Stamps
- ;***********************************************************
- ;***********************************************************
- ; DRAW_STAMP
- ;
- ; VOID cdecl Buffer_Draw_Stamp(VOID *icondata, WORD icon, WORD x_pixel, WORD y_pixel, VOID *remap);
- ;
- ; This routine renders the icon at the given coordinate.
- ;
- ; The remap table is a 256 byte simple pixel translation table to use when
- ; drawing the icon. Transparency check is performed AFTER the remap so it is possible to
- ; remap valid colors to be invisible (for special effect reasons).
- ; This routine is fastest when no remap table is passed in.
- ;*
- PROC Buffer_Draw_Stamp C near
- ARG this_object:DWORD ; this is a member function
- ARG icondata:DWORD ; Pointer to icondata.
- ARG icon:DWORD ; Icon number to draw.
- ARG x_pixel:DWORD ; X coordinate of icon.
- ARG y_pixel:DWORD ; Y coordinate of icon.
- ARG remap:DWORD ; Remap table.
- LOCAL modulo:DWORD ; Modulo to get to next row.
- LOCAL iwidth:DWORD ; Icon width (here for speedy access).
- LOCAL doremap:BYTE ; Should remapping occur?
- pushad
- cmp [icondata],0
- je ??out
- ; Initialize the stamp data if necessary.
- mov eax,[icondata]
- cmp [LastIconset],eax
- je short ??noreset
- call Init_Stamps C,eax
- ??noreset:
- ; Determine if the icon number requested is actually in the set.
- ; Perform the logical icon to actual icon number remap if necessary.
- mov ebx,[icon]
- cmp [MapPtr],0
- je short ??notmap
- mov edi,[MapPtr]
- mov bl,[edi+ebx]
- ??notmap:
- cmp ebx,[IconCount]
- jae ??out
- mov [icon],ebx ; Updated icon number.
- ; If the remap table pointer passed in is NULL, then flag this condition
- ; so that the faster (non-remapping) icon draw loop will be used.
- cmp [remap],0
- setne [doremap]
- ; Get pointer to position to render icon. EDI = ptr to destination page.
- mov ebx,[this_object]
- mov edi,[(GraphicViewPort ebx).GVPOffset]
- mov eax,[(GraphicViewPort ebx).GVPWidth]
- add eax,[(GraphicViewPort ebx).GVPXAdd]
- add eax,[(GraphicViewPort ebx).GVPPitch]
- push eax ; save viewport full width for lower
- mul [y_pixel]
- add edi,eax
- add edi,[x_pixel]
- ; Determine row modulo for advancing to next line.
- pop eax ; retrieve viewport width
- sub eax,[IconWidth]
- mov [modulo],eax
- ; Setup some working variables.
- mov ecx,[IconHeight] ; Row counter.
- mov eax,[IconWidth]
- mov [iwidth],eax ; Stack copy of byte width for easy BP access.
- ; Fetch pointer to start of icon's data. ESI = ptr to icon data.
- mov eax,[icon]
- mul [IconSize]
- mov esi,[StampPtr]
- add esi,eax
- ; Determine whether simple icon draw is sufficient or whether the
- ; extra remapping icon draw is needed.
- cmp [BYTE PTR doremap],0
- je short ??istranscheck
- ;************************************************************
- ; Complex icon draw -- extended remap.
- ; EBX = Palette pointer (ready for XLAT instruction).
- ; EDI = Pointer to icon destination in page.
- ; ESI = Pointer to icon data.
- ; ECX = Number of pixel rows.
- ;;; mov edx,[remap]
- mov ebx,[remap]
- xor eax,eax
- ??xrowloop:
- push ecx
- mov ecx,[iwidth]
- ??xcolumnloop:
- lodsb
- ;;; mov ebx,edx
- ;;; add ebx,eax
- ;;; mov al,[ebx] ; New real color to draw.
- xlatb
- or al,al
- jz short ??xskip1 ; Transparency skip check.
- mov [edi],al
- ??xskip1:
- inc edi
- loop ??xcolumnloop
- pop ecx
- add edi,[modulo]
- loop ??xrowloop
- jmp short ??out
- ;************************************************************
- ; Check to see if transparent or generic draw is necessary.
- ??istranscheck:
- mov ebx,[IsTrans]
- add ebx,[icon]
- cmp [BYTE PTR ebx],0
- jne short ??rowloop
- ;************************************************************
- ; Fast non-transparent icon draw routine.
- ; ES:DI = Pointer to icon destination in page.
- ; DS:SI = Pointer to icon data.
- ; CX = Number of pixel rows.
- mov ebx,ecx
- shr ebx,2
- mov edx,[modulo]
- mov eax,[iwidth]
- shr eax,2
- ??loop1:
- mov ecx,eax
- rep movsd
- add edi,edx
- mov ecx,eax
- rep movsd
- add edi,edx
- mov ecx,eax
- rep movsd
- add edi,edx
- mov ecx,eax
- rep movsd
- add edi,edx
- dec ebx
- jnz ??loop1
- jmp short ??out
- ;************************************************************
- ; Transparent icon draw routine -- no extended remap.
- ; ES:DI = Pointer to icon destination in page.
- ; DS:SI = Pointer to icon data.
- ; CX = Number of pixel rows.
- ??rowloop:
- push ecx
- mov ecx,[iwidth]
- ??columnloop:
- lodsb
- or al,al
- jz short ??skip1 ; Transparency check.
- mov [edi],al
- ??skip1:
- inc edi
- loop ??columnloop
- pop ecx
- add edi,[modulo]
- loop ??rowloop
- ; Cleanup and exit icon drawing routine.
- ??out:
- popad
- ret
- ENDP Buffer_Draw_Stamp
- ;***********************************************************
- ; DRAW_STAMP_CLIP
- ;
- ; VOID cdecl MCGA_Draw_Stamp_Clip(VOID *icondata, WORD icon, WORD x_pixel, WORD y_pixel, VOID *remap, LONG min_x, LONG min_y, LONG max_x, LONG max_y);
- ;
- ; This routine renders the icon at the given coordinate.
- ;
- ; The remap table is a 256 byte simple pixel translation table to use when
- ; drawing the icon. Transparency check is performed AFTER the remap so it is possible to
- ; remap valid colors to be invisible (for special effect reasons).
- ; This routine is fastest when no remap table is passed in.
- ;*
- PROC Buffer_Draw_Stamp_Clip C near
- ARG this_object:DWORD ; this is a member function
- ARG icondata:DWORD ; Pointer to icondata.
- ARG icon:DWORD ; Icon number to draw.
- ARG x_pixel:DWORD ; X coordinate of icon.
- ARG y_pixel:DWORD ; Y coordinate of icon.
- ARG remap:DWORD ; Remap table.
- ARG min_x:DWORD ; Clipping rectangle boundary
- ARG min_y:DWORD ; Clipping rectangle boundary
- ARG max_x:DWORD ; Clipping rectangle boundary
- ARG max_y:DWORD ; Clipping rectangle boundary
- LOCAL modulo:DWORD ; Modulo to get to next row.
- LOCAL iwidth:DWORD ; Icon width (here for speedy access).
- LOCAL skip:DWORD ; amount to skip per row of icon data
- LOCAL doremap:BYTE ; Should remapping occur?
- pushad
- cmp [icondata],0
- je ??out2
- ; Initialize the stamp data if necessary.
- mov eax,[icondata]
- cmp [LastIconset],eax
- je short ??noreset2
- call Init_Stamps C,eax
- ??noreset2:
- ; Determine if the icon number requested is actually in the set.
- ; Perform the logical icon to actual icon number remap if necessary.
- mov ebx,[icon]
- cmp [MapPtr],0
- je short ??notmap2
- mov edi,[MapPtr]
- mov bl,[edi+ebx]
- ??notmap2:
- cmp ebx,[IconCount]
- jae ??out2
- mov [icon],ebx ; Updated icon number.
- ; Setup some working variables.
- mov ecx,[IconHeight] ; Row counter.
- mov eax,[IconWidth]
- mov [iwidth],eax ; Stack copy of byte width for easy BP access.
- ; Fetch pointer to start of icon's data. ESI = ptr to icon data.
- mov eax,[icon]
- mul [IconSize]
- mov esi,[StampPtr]
- add esi,eax
- ; Update the clipping window coordinates to be valid maxes instead of width & height
- ; , and change the coordinates to be window-relative
- mov ebx,[min_x]
- add [max_x],ebx
- add [x_pixel],ebx ; make it window-relative
- mov ebx,[min_y]
- add [max_y],ebx
- add [y_pixel],ebx ; make it window-relative
- ; See if the icon is within the clipping window
- ; First, verify that the icon position is less than the maximums
- mov ebx,[x_pixel]
- cmp ebx,[max_x]
- jge ??out2
- mov ebx,[y_pixel]
- cmp ebx,[max_y]
- jge ??out2
- ; Now verify that the icon position is >= the minimums
- add ebx,[IconHeight]
- cmp ebx,[min_y]
- jle ??out2
- mov ebx,[x_pixel]
- add ebx,[IconWidth]
- cmp ebx,[min_x]
- jle ??out2
- ; Now, clip the x, y, width, and height variables to be within the
- ; clipping rectangle
- mov ebx,[x_pixel]
- cmp ebx,[min_x]
- jge ??nominxclip
- ; x < minx, so must clip
- mov ebx,[min_x]
- sub ebx,[x_pixel]
- add esi,ebx ; source ptr += (minx - x)
- sub [iwidth],ebx ; icon width -= (minx - x)
- mov ebx,[min_x]
- mov [x_pixel],ebx
- ??nominxclip:
- mov eax,[IconWidth]
- sub eax,[iwidth]
- mov [skip],eax
- ; Check for x+width > max_x
- mov eax,[x_pixel]
- add eax,[iwidth]
- cmp eax,[max_x]
- jle ??nomaxxclip
- ; x+width is greater than max_x, so must clip width down
- mov eax,[iwidth] ; eax = old width
- mov ebx,[max_x]
- sub ebx,[x_pixel]
- mov [iwidth],ebx ; iwidth = max_x - xpixel
- sub eax,ebx
- add [skip],eax ; skip += (old width - iwidth)
- ??nomaxxclip:
- ; check if y < miny
- mov eax,[min_y]
- cmp eax,[y_pixel] ; if(miny <= y_pixel), no clip needed
- jle ??nominyclip
- sub eax,[y_pixel]
- sub ecx,eax ; height -= (miny - y)
- mul [IconWidth]
- add esi,eax ; icon source ptr += (width * (miny - y))
- mov eax,[min_y]
- mov [y_pixel],eax ; y = miny
- ??nominyclip:
- ; check if (y+height) > max y
- mov eax,[y_pixel]
- add eax,ecx
- cmp eax,[max_y] ; if (y + height <= max_y), no clip needed
- jle ??nomaxyclip
- mov ecx,[max_y] ; height = max_y - y_pixel
- sub ecx,[y_pixel]
- ??nomaxyclip:
- ; If the remap table pointer passed in is NULL, then flag this condition
- ; so that the faster (non-remapping) icon draw loop will be used.
- cmp [remap],0
- setne [doremap]
- ; Get pointer to position to render icon. EDI = ptr to destination page.
- mov ebx,[this_object]
- mov edi,[(GraphicViewPort ebx).GVPOffset]
- mov eax,[(GraphicViewPort ebx).GVPWidth]
- add eax,[(GraphicViewPort ebx).GVPXAdd]
- add eax,[(GraphicViewPort ebx).GVPPitch]
- push eax ; save viewport full width for lower
- mul [y_pixel]
- add edi,eax
- add edi,[x_pixel]
- ; Determine row modulo for advancing to next line.
- pop eax ; retrieve viewport width
- sub eax,[iwidth]
- mov [modulo],eax
- ; Determine whether simple icon draw is sufficient or whether the
- ; extra remapping icon draw is needed.
- cmp [BYTE PTR doremap],0
- je short ??istranscheck2
- ;************************************************************
- ; Complex icon draw -- extended remap.
- ; EBX = Palette pointer (ready for XLAT instruction).
- ; EDI = Pointer to icon destination in page.
- ; ESI = Pointer to icon data.
- ; ECX = Number of pixel rows.
- mov ebx,[remap]
- xor eax,eax
- ??xrowloopc:
- push ecx
- mov ecx,[iwidth]
- ??xcolumnloopc:
- lodsb
- xlatb
- or al,al
- jz short ??xskip1c ; Transparency skip check.
- mov [edi],al
- ??xskip1c:
- inc edi
- loop ??xcolumnloopc
- pop ecx
- add edi,[modulo]
- add esi,[skip]
- loop ??xrowloopc
- jmp short ??out2
- ;************************************************************
- ; Check to see if transparent or generic draw is necessary.
- ??istranscheck2:
- mov ebx,[IsTrans]
- add ebx,[icon]
- cmp [BYTE PTR ebx],0
- jne short ??rowloopc
- ;************************************************************
- ; Fast non-transparent icon draw routine.
- ; ES:DI = Pointer to icon destination in page.
- ; DS:SI = Pointer to icon data.
- ; CX = Number of pixel rows.
- mov ebx,ecx
- mov edx,[modulo]
- mov eax,[iwidth]
- ;
- ; Optimise copy by dword aligning the destination
- ;
- ??loop1c:
- push eax
- rept 3
- test edi,3
- jz ??aligned
- movsb
- dec eax
- jz ??finishedit
- endm
- ??aligned:
- mov ecx,eax
- shr ecx,2
- rep movsd
- mov ecx,eax
- and ecx,3
- rep movsb
- ??finishedit:
- add edi,edx
- add esi,[skip]
- pop eax
- dec ebx
- jnz ??loop1c
- jmp short ??out2
- ;************************************************************
- ; Transparent icon draw routine -- no extended remap.
- ; ES:DI = Pointer to icon destination in page.
- ; DS:SI = Pointer to icon data.
- ; CX = Number of pixel rows.
- ??rowloopc:
- push ecx
- mov ecx,[iwidth]
- ??columnloopc:
- lodsb
- or al,al
- jz short ??skip1c ; Transparency check.
- mov [edi],al
- ??skip1c:
- inc edi
- loop ??columnloopc
- pop ecx
- add edi,[modulo]
- add esi,[skip]
- loop ??rowloopc
- ; Cleanup and exit icon drawing routine.
- ??out2:
- popad
- ret
- ENDP Buffer_Draw_Stamp_Clip
- END
|