home *** CD-ROM | disk | FTP | other *** search
- page ,132
- TITLE FAST32.ASM
- ;---------------------------------------------------------------------------;
- ; FAST.ASM
- ;
- ; 32 bit asm routines for doing a "sprite" bitblt
- ;
- ; TransCopyDIBBits - copy DIB bits with a transparent color
- ; CopyDIBBits - copy DIB bits without a transparent color
- ;
- ; (C) Copyright 1994 Microsoft Corp. All rights reserved.
- ;
- ; You have a royalty-free right to use, modify, reproduce and
- ; distribute the Sample Files (and/or any modified version) in
- ; any way you find useful, provided that you agree that
- ; Microsoft has no warranty obligations or liability for any
- ; Sample Application Files which are modified.
- ;
- ;---------------------------------------------------------------------------;
-
- ;
- ; 32 bit code segment version of FAST16.ASM
- ;
- ; NOTE! cmacro32.inc needs MASM 5.1 compatibility
- ; Run MASM 6 specifying option: /Zm (provides MASM 5.1 compatibility)
- ;
- .xlist
- include cmacro32.inc
- .list
-
- ;
- ; NOTE!!!! because we are generating USE32 code this must NOT
- ; be located in a code segment with USE16 code, so we put it into
- ; it's own little segment....
- ;
-
- ifndef SEGNAME
- SEGNAME equ <FAST_TEXT32>
- endif
-
- createSeg %SEGNAME, CodeSeg, dword, use32, CODE
-
- sBegin Data
- sEnd Data
-
- sBegin CodeSeg
- assumes cs,CodeSeg
- assumes ds,nothing
- assumes es,nothing
-
- ;-------------------------------------------------------
- ;
- ; TransCopyDIBBits
- ;
- ; Copy a block with transparency
- ;
- ;-------------------------------------------------------
-
- cProc TransCopyDIBBits,<FAR, PASCAL, PUBLIC>,<>
- ParmW DestSelector ; dest 48bit pointer
- ParmD DestOffset
- ParmD pSource ; source pointer
- ParmD dwWidth ; width pixels
- ParmD dwHeight ; height pixels
- ParmD dwScanD ; width bytes dest
- ParmD dwScanS ; width bytes source
- ParmB bTranClr ; transparent color
- cBegin
- push ds
- push esi
- push edi
-
- mov ecx, dwWidth
- or ecx,ecx
- jz tcdb_nomore ; test for silly case
-
- mov edx, dwHeight ; EDX is line counter
- mov ah, bTranClr ; AL has transparency color
-
- xor esi, esi
- lds si, pSource ; DS:[ESI] point to source
-
- mov es, DestSelector ; es:[edi] point to dest
- mov edi, DestOffset
-
- sub dwScanD,ecx ; bias these
- sub dwScanS,ecx
-
- mov ebx,ecx ; save this for later
-
- align 4
-
- tcdb_morelines:
- mov ecx, ebx ; ECX is pixel counter
- shr ecx,2
- jz short tcdb_nextscan
-
- ;
- ; The idea here is to not branch very often so we unroll the loop by four
- ; and try to not branch when a whole run of pixels is either transparent
- ; or not transparent.
- ;
- ; There are two loops. One loop is for a run of pixels equal to the
- ; transparent color, the other is for runs of pixels we need to store.
- ;
- ; When we detect a "bad" pixel we jump to the same position in the
- ; other loop.
- ;
- ; Here is the loop we will stay in as long as we encounter a "transparent"
- ; pixel in the source.
- ;
-
- align 4
-
- tcdb_same:
- mov al, ds:[esi]
- cmp al, ah
- jne short tcdb_diff0
-
- tcdb_same0:
- mov al, ds:[esi+1]
- cmp al, ah
- jne short tcdb_diff1
-
- tcdb_same1:
- mov al, ds:[esi+2]
- cmp al, ah
- jne short tcdb_diff2
-
- tcdb_same2:
- mov al, ds:[esi+3]
- cmp al, ah
- jne short tcdb_diff3
-
- tcdb_same3:
- add edi,4
- add esi,4
- dec ecx
- jnz short tcdb_same
- jz short tcdb_nextscan
-
- ;
- ; Here is the loop we will stay in as long as
- ; we encounter a "non transparent" pixel in the source.
- ;
-
- align 4
-
- tcdb_diff:
- mov al, ds:[esi]
- cmp al, ah
- je short tcdb_same0
-
- tcdb_diff0:
- mov es:[edi],al
- mov al, ds:[esi+1]
- cmp al, ah
- je short tcdb_same1
-
- tcdb_diff1:
- mov es:[edi+1],al
- mov al, ds:[esi+2]
- cmp al, ah
- je short tcdb_same2
-
- tcdb_diff2:
- mov es:[edi+2],al
- mov al, ds:[esi+3]
- cmp al, ah
- je short tcdb_same3
-
- tcdb_diff3:
- mov es:[edi+3],al
-
- add edi,4
- add esi,4
- dec ecx
- jnz short tcdb_diff
- jz short tcdb_nextscan
-
- ;
- ; We are at the end of a scan, check for odd leftover pixels to do
- ; and go to the next scan.
- ;
-
- align 4
-
- tcdb_nextscan:
- mov ecx,ebx
- and ecx,11b
- jnz short tcdb_oddstuff
- ; move on to the start of the next line
-
- tcdb_nextscan1:
- add esi, dwScanS
- add edi, dwScanD
-
- dec edx ; line counter
- jnz short tcdb_morelines
- jz short tcdb_nomore
-
- ;
- ; If the width is not a multiple of 4 we will come here to clean up
- ; the last few pixels
- ;
-
- tcdb_oddstuff:
- inc ecx
- tcdb_oddloop:
- dec ecx
- jz short tcdb_nextscan1
- mov al, ds:[esi]
- inc esi
- inc edi
- cmp al, ah
- je short tcdb_oddloop
- mov es:[edi-1],al
- jmp short tcdb_oddloop
-
- tcdb_nomore:
- pop edi
- pop esi
- pop ds
- cEnd
-
- ;-----------------------------------------------------------------------------;
- ;
- ; CopyDIBBits
- ;
- ; Copy a block without transparency
- ;
- ;-----------------------------------------------------------------------------;
-
- cProc CopyDIBBits,<FAR, PASCAL, PUBLIC>,<>
- ParmD pDest ; dest pointer
- ParmD pSource ; source pointer
- ParmD dwWidth ; width pixels
- ParmD dwHeight ; height pixels
- ParmD dwScanD ; width bytes dest
- ParmD dwScanS ; width bytes source
- cBegin
- push ds
- push esi
- push edi
-
- mov ecx, dwWidth
- or ecx,ecx
- jz cdb_nomore ; test for silly case
-
- mov edx, dwHeight ; EDX is line counter
- or edx,edx
- jz cdb_nomore ; test for silly case
-
- xor esi, esi
- lds si, pSource ; DS:[ESI] point to source
-
- xor edi, edi
- les di, pDest ; ES:[EDI] point to dest
-
- sub dwScanD,ecx ; bias these
- sub dwScanS,ecx
-
- mov ebx,ecx
- shr ebx,2
-
- mov eax,ecx
- and eax,11b
-
- align 4
-
- cdb_loop:
- mov ecx, ebx
- rep movs dword ptr es:[edi], dword ptr ds:[esi]
- mov ecx,eax
- rep movs byte ptr es:[edi], byte ptr ds:[esi]
-
- add esi, dwScanS
- add edi, dwScanD
- dec edx ; line counter
- jnz short cdb_loop
-
- cdb_nomore:
- pop edi
- pop esi
- pop ds
- cEnd
-
-
-
- sEnd CodeSeg
- end
-