Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

932 lines
45 KiB

;---------------------------Module-Header------------------------------;
; Module Name: stretch.asm
;
; Copyright (c) 1992 Microsoft Corporation
;-----------------------------------------------------------------------;
;-----------------------------------------------------------------------;
; INT vStretchBlt8bpp(PPDEV ppdev, PBYTE pSrc, LONG lSrcNext,
; PRECTL prclSrc, PRECTL prclDest, PRECTL prclDestClip,
; PULONG pulXlatVector)
; Input:
;
; Performs accelerated stretch blts from 8-bit DIBs to 256-color VGA
; display memory.
;-----------------------------------------------------------------------;
; Note: Does not handle source clipping.
;
; Note: Does not yet handle expansion, only shrinking.
;-----------------------------------------------------------------------;
comment $
***
Note: in the noxlat loop, EBX isn't altered, so it could be used for
something else, like the scan line count. This isn't done currently
because the scan-line loop is shared by the xlat and noxlat cases, and
the xlat cases do alter EBX; separate loops would be needed in order
to perform this optimization.
commend $
;-----------------------------------------------------------------------;
.386
ifndef DOS_PLATFORM
.model small,c
else
ifdef STD_CALL
.model small,c
else
.model small,pascal
endif; STD_CALL
endif; DOS_PLATFORM
assume cs:FLAT,ds:FLAT,es:FLAT,ss:FLAT
assume fs:nothing,gs:nothing
.xlist
include stdcall.inc ;calling convention cmacros
include i386\strucs.inc
include i386\driver.inc
.list
;-----------------------------------------------------------------------;
.data
;-----------------------------------------------------------------------;
.code
;-----------------------------------------------------------------------;
cProc vStretchBlt8bpp,28,< \
uses esi edi ebx, \
ppdev:ptr, \
pSrc:ptr, \
lSrcNext:dword, \
prclSrc:ptr, \
prclDest:ptr, \
prclDestClip:ptr, \
pulXlatVector:dword >
local pulDDAArray:dword ;pointer to array of n and n+1
; values generated by DDA, used to
; advance across source
local ulXStretchCount:dword ;# of pixels or pixel pair to copy to
; (pixel pairs except in narrow
; cases; doesn't include leading or
; trailing single pixels in pixel
; pair cases)
local ulDestNext:dword ;offset from last dest pixel on one
; scan to first on next
local ulSrcMinNext:dword ;offset from start of one source scan
; to start of next scan that's skipped
; to by minimum DDA advance (basically,
; skips over n scans when DDA advances
; either n or n+1 scans)
local lYErrorTerm:dword ;current error term for the DDA in Y
local ulYAdjUp:dword ;error term adjust up for advancing
; DDA in Y
local ulYAdjDown:dword ;error term adjust down for advancing
; DDA in Y
local ulDstTopScan:dword ;top scan of dest text rect in
; current bank
local ulDstBottomScan :dword ;bottom scan line of dest rectangle
local ulScanCount:dword ;# of scans to stretch in current
; bank
local pfnRowVector:dword ;pointer to routine to be used to
; stretch each row
local pfnStretchFn:dword ;pointer to routine to do a bank's
; worth of stretching
local ulSrcTopScan:dword ;top scan line of source from which
; to copy (after clipping, if needed)
local ulYMinStep:dword ;minimum # of scans to skip in source
; when advancing dest one scan
local lXDstRight:dword ;right edge of dest area to which to
; stretch, accounting for clipping
local lXDstLeft:dword ;left edge of dest area to which to
; stretch, accounting for clipping
local ulXAdjUp:dword ;X error term adjust up
local ulXMinStep:dword ;X minimum step per dest 1-pixel step
local ulXAdjDown:dword ;X error term adjust down
local lXSrcRight:dword ;right edge of source area from which
; to stretch, accounting for clipping
local lXSrcLeft:dword ;left edge of source area from which to
; stretch, accounting for clipping
local pvBuf:dword ;local copy of ppdev->pvTmpBuf ptr
;-----------------------------------------------------------------------;
mov esi,ppdev
mov edi,[esi].pdev_pvTmpBuf
mov pvBuf,edi
mov esi,prclSrc
mov edi,prclDest
mov eax,[esi].xRight
mov edx,[esi].xLeft
mov lXSrcLeft,edx
sub eax,edx ;EAX = source width
mov ecx,[edi].xRight
mov lXDstRight,ecx
mov edx,[edi].xLeft
mov lXDstLeft,edx
sub ecx,edx ;ECX = dest width
cmp eax,ecx ;shrink or stretch in X?
jge short x_shrink ;shrink
;stretch
;@@@
DoneFailed::
sub eax,eax ;@@@shouldn't have to return a value
jmp done
;The destination is narrower than the source
x_shrink::
mov pfnStretchFn,offset shrink_8bpp_loop
;-----------------------------------------------------------------------;
; Precalculate the DDA steps for X and store them in the temp buffer. We know
; these will fit in the temp buffer, because there are only, say, 2K steps
; max across the screen, and the temp buffer is guaranteed to be more than
; 2K*4 = 8K bytes long.
;
; At this point, EAX = source width, ECX = destination width
;-----------------------------------------------------------------------;
sub edx,edx ;prepare for division
div ecx ;SourceDeltaX / DestDeltaX
mov ulXMinStep,eax ;EAX = minimum step in source for 1 dest step
mov esi,edx ;set aside SourceDeltaX % DestDeltaX
add edx,edx ;scale up ulXAdjUp by 2 so we can handle a
; half-pixel advance
mov ulXAdjUp,edx ;ulXAdjUp = (SourceDeltaX % DestDeltaX)*2
;prestep source X coord and error term by 1/2
; a destination pixel, so we pick the source
; pixel that most closely matches the center
; of each destination pixel
;step by 1/2 the whole source pixel advance
; per destination step
shr eax,1 ;minimum step/2
jnc short @F ;odd
;even
add esi,ecx ;advance error term for 1/2 of the source
; pixel we just split (by DestDeltaX)
@@:
add lXSrcLeft,eax ;advance 1/2 minimum step in source
add ecx,ecx ;scale up DestDeltaX by 2 so we can handle a
; half-pixel advance
mov ulXAdjDown,ecx ;ulXAdjDown = DestDeltaX*2
sub esi,ecx ;initial error term = -(DestDeltaX*2) + 1/2
; normal error term step (for 1/2 pixel dest
; advance effect on error term; note that 1/2
; effect on whole source pixels has already
; been accounted for)
;-----------------------------------------------------------------------;
; Clip to the dest in X, if necessary.
;-----------------------------------------------------------------------;
mov ebx,prclDestClip
and ebx,ebx ;any clipping?
jz short x_clip_done ;no, all set
mov eax,[ebx].xRight ;right clip edge
cmp eax,lXDstRight ;is the right edge clipped?
jge short check_x_left_clip ;no
;right edge is clipped
mov lXDstRight,eax ;set the clipped right edge
check_x_left_clip:
mov eax,[ebx].xLeft ;left clip edge
cmp eax,lXDstLeft ;is the left edge clipped?
jle short check_x_not_fully_clipped ;no
;left edge is clipped
mov edx,lXDstLeft ;get the unclipped dest left edge
mov lXDstLeft,eax ;set the clipped dest left edge
;now figure out how many source pixels
; were clipped, and advance the error
; term appropriately
sub eax,edx ;# of dest pixels clipped
mov ecx,eax ;set aside # of dest pixels to skip
mul ulXAdjUp ;# of adjust ups in the course of the
; skipped pixels
add esi,eax ;EDX:ESI = error term after skipping
adc edx,-1 ;(the initial error term is negative;
; this stretches it to 64 bits)
jnc short check_x_not_fully_clipped ;didn't turn over even once
mov eax,esi ;EDX:EAX = error term after skipping
div ulXAdjDown ;EAX = # of times to adjust down
; while skipping pixels, minus 1
sub edx,ulXAdjDown ;do the last adjust down, to cross
; back into negative territory where
; the error term belongs
mov esi,edx ;error term at new, clipped dest left
; edge
inc eax ;count the last adjust down (# of times
; source error turned over while
; advancing to the clipped left edge)
imul ecx,ulXMinStep ;# of whole pixels skipped in source
; while advancing to dest clip left
; edge
add eax,ecx ;total # of pixels skipped in source
; while advancing to dest clip left
; edge
add lXSrcLeft,eax ;advance the source left edge to match
; advancing the destination left edge
; to the left edge of the clip
; rectangle
check_x_not_fully_clipped:
mov eax,lXDstLeft
cmp lXDstRight,eax ;is the destination fully x-clipped?
jle done ;yes, nothing to draw
x_clip_done:
;-----------------------------------------------------------------------;
; Now actually generate the (possibly clipped) X DDA skip array
;
; At this point, ESI = X error term for left edge (accounting for any
; X clipping that has occurred)
;-----------------------------------------------------------------------;
mov eax,ulXMinStep
mov edi,pvBuf ;we'll store the DDA steps in the temp
mov pulDDAArray,edi ; buffer
mov edx,ulXAdjUp
mov ebx,ulXAdjDown
mov ecx,lXDstRight
sub ecx,lXDstLeft ;ECX = # of pixels per dest scan
push ecx ;remember # of dest pixels across
push ebp ;preserve stack frame pointer
lea ebp,[eax+1] ;maximum step
;***stack frame unavailable***
x_shrink_set_dda_loop::
add esi,edx ;adjust the error term up
jnc short x_shrink_set_dda_min ;didn't turn over, so advance
; minimum step
x_shrink_set_dda_max::
sub esi,ebx ;turned over; adjust error term back down
mov [edi],ebp ;advance by maximum step
add edi,4 ;point to next DDA array storage location
dec ecx ;count down steps
jz short x_shrink_set_dda_done ;no more steps
add esi,edx ;adjust the error term up
jc x_shrink_set_dda_max ;did turn over, so advance maximum step
x_shrink_set_dda_min::
mov [edi],eax ;advance by minimum step
add edi,4 ;point to next DDA array storage location
dec ecx ;count down steps
jnz x_shrink_set_dda_loop
x_shrink_set_dda_done::
mov dword ptr [edi],0 ;mark the end of the DDA
pop ebp ;restore stack frame pointer
;***stack frame available***
pop ecx ;retrieve # of dest pixels across
mov edi,prclDest
cmp pulXlatVector,0 ;translation?
jz short x_shrink_noxlat ;no
;yes
cmp ecx,3 ;narrow case?
ja short @F ;no
mov pfnRowVector,offset shrink_xlat_8bpp_narrow ;narrow case
mov ulXStretchCount,ecx ;do all dest pixels one at a time
jmp check_y_shrink
@@: ;not narrow case; figure out which wide case,
; based on the need to perform as many word-
; aligned writes to display memory as possible
mov edx,ecx
test [edi].xLeft,1 ;starting at an odd destination address?
jnz short x_shrink_xlat_leading ;yes, need leading pixel
mov pfnRowVector,offset shrink_xlat_8bpp_nl_nt
;assume no leading or trailing pixels
shr edx,1 ;destination width in pixel pairs
mov ulXStretchCount,edx ;count of pixel pairs to draw
jnc short check_y_shrink ;no leading or trailing pixels
mov pfnRowVector,offset shrink_xlat_8bpp_nl_t
;no leading pixel, is a trailing pixel
jmp short check_y_shrink
x_shrink_xlat_leading: ;there is a leading pixel
mov pfnRowVector,offset shrink_xlat_8bpp_l_nt
;assume no trailing pixel
shr edx,1 ;destination width in pixel pairs
mov ulXStretchCount,edx ;count of pixel pairs to draw
jc short check_y_shrink ;no trailing pixel
mov pfnRowVector,offset shrink_xlat_8bpp_l_t
;both leading and trailing pixels
dec edx ;we'll do one pixel pair in the form
; of the leading/trailing pixel pair
mov ulXStretchCount,edx ;count of pixel pairs to draw
jmp short check_y_shrink
x_shrink_noxlat: ;no translation
cmp ecx,3 ;narrow case?
ja short @F ;no
mov pfnRowVector,offset shrink_noxlat_8bpp_narrow ;narrow case
mov ulXStretchCount,ecx ;do all dest pixels one at a time
jmp short check_y_shrink
@@: ;not narrow case; figure out which wide case,
; based on the need to perform as many word-
; aligned writes to display memory as possible
mov edx,ecx
test [edi].xLeft,1 ;starting at an odd destination address?
jnz short x_shrink_noxlat_leading ;yes, need leading pixel
mov pfnRowVector,offset shrink_noxlat_8bpp_nl_nt
;assume no leading or trailing pixels
shr edx,1 ;destination width in pixel pairs
mov ulXStretchCount,edx ;count of pixel pairs to draw
jnc short check_y_shrink ;no leading or trailing pixels
mov pfnRowVector,offset shrink_noxlat_8bpp_nl_t
;no leading pixel, is a trailing pixel
jmp short check_y_shrink
x_shrink_noxlat_leading: ;there is a leading pixel
mov pfnRowVector,offset shrink_noxlat_8bpp_l_nt
;assume no trailing pixel
shr edx,1 ;destination width in pixel pairs
mov ulXStretchCount,edx ;count of pixel pairs to draw
jc short check_y_shrink ;no trailing pixel
mov pfnRowVector,offset shrink_noxlat_8bpp_l_t
;both leading and trailing pixels
dec edx ;we'll do one pixel pair in the form
; of the leading/trailing pixel pair
mov ulXStretchCount,edx ;count of pixel pairs to draw
check_y_shrink::
mov esi,edi ;ESI->prclDest
mov edi,prclSrc ;EDI->prclSrc
mov eax,[edi].yBottom
mov ecx,[edi].yTop
mov ulSrcTopScan,ecx
sub eax,ecx ;EAX = source height
mov ecx,[esi].yBottom
mov ulDstBottomScan,ecx
mov edx,[esi].yTop
mov ulDstTopScan,edx
sub ecx,edx ;ECX = dest height
cmp eax,ecx ;shrink or stretch in Y?
jge short y_shrink ;shrink
;stretch
;@@@
sub eax,eax ;@@@shouldn't have to return a value
jmp done
;The destination is shorter than the source; calculate the error term values
; for advancing through the source on a per-dest-scan-line basis.
y_shrink::
sub edx,edx ;prepare for division
div ecx ;SourceDeltaY/DestDeltaY
mov ulYMinStep,eax ;EAX = minimum step in source for 1 dest step
mov ebx,edx ;set aside SourceDeltaY % DestDeltaY
add edx,edx ;scale up ulYAdjUp by 2 so we can handle a
; half-pixel advance
mov ulYAdjUp,edx ;ulYAdjUp = (SourceDeltaY % DestDeltaY)*2
imul lSrcNext ;(minimum step * source scan width in bytes)
mov ulSrcMinNext,eax ; = minimum offset by which to advance from
; one scan to the next
;prestep source X coord and error term by 1/2
; a destination pixel, so we pick the source
; pixel that most closely matches the center
; of each destination pixel
;step by 1/2 the whole source pixel advance
; per destination step
mov eax,ulYMinStep ;retrieve minimum step
shr eax,1 ;minimum step/2
jnc short @F ;odd
;even
add ebx,ecx ;advance error term for 1/2 of the source
; pixel we just split
@@:
add ulSrcTopScan,eax ;advance 1/2 minimum step in source
add ecx,ecx ;scale up DestDeltaY by 2 so we can handle a
; half-pixel advance
mov ulYAdjDown,ecx ;ulYAdjDown = DestDeltaY*2
sub ebx,ecx ;initial error term = -(DestDeltaY*2) + 1/2
; normal error term step (for 1/2 pixel dest
; advance effect on error term; note that 1/2
; effect on whole source pixels has already
; been accounted for)
mov lYErrorTerm,ebx
;-----------------------------------------------------------------------;
; Clip in Y, if necessary.
;-----------------------------------------------------------------------;
mov ebx,prclDestClip
and ebx,ebx ;any clipping?
jz short y_clip_done ;no, all set
mov eax,[ebx].yBottom ;yes, clipping
;see if the dest is clipped off the
; bottom
cmp ulDstBottomScan,eax ;is the bottom clipped?
jle short check_y_top_clip ;no, check the top
mov ulDstBottomScan,eax ;yes, set the new bottom
check_y_top_clip:
;see if the dest is clipped off the
; top
mov eax,[ebx].yTop
cmp ulDstTopScan,eax ;is the top clipped?
jge short check_y_not_fully_clipped ;no
;yes, so advance the top scan and the
; error term accordingly
mov ulDstTopScan,eax ;top of clipped destination rectangle
sub eax,[esi].yTop ;# of destination scans to skip
mov ecx,eax ;set aside # of dest scans to skip
mul ulYAdjUp ;# of adjust ups in the course of the
; skipped scans
add eax,lYErrorTerm ;EDX:EAX = error term after skipping
adc edx,-1 ;(the initial error term is negative;
; this stretches it to 64 bits)
jnc short check_y_not_fully_clipped ;didn't turn over even once
div ulYAdjDown ;EAX = # of times to adjust down
; while skipping scans, minus 1
sub edx,ulYAdjDown ;do the last adjust down, to cross
; back into negative territory where
; the error term belongs
mov lYErrorTerm,edx ;error term at new, clipped dest top
inc eax ;count the last adjust down (# of
; times source error has turned over)
imul ecx,ulYMinStep ;# of whole steps in source while
; advancing to dest clip top
add eax,ecx ;total # of scans skipped in source
; while advancing to dest clip top
add ulSrcTopScan,eax ;advance the source top edge to match
; advancing the destination top edge to
; the top of the clip rectangle
check_y_not_fully_clipped:
mov eax,ulDstTopScan
cmp ulDstBottomScan,eax ;is the destination fully y-clipped?
jle done ;yes, nothing to draw
y_clip_done:
;-----------------------------------------------------------------------;
; Calculate the offset of the initial destination pixel.
;-----------------------------------------------------------------------;
mov ebx,ppdev
mov eax,ulDstTopScan ;top scan line of text
mov esi,[ebx].pdev_lDeltaScreen
mul esi
mov edi,lXDstLeft
mov ecx,lXDstRight
sub ecx,edi ;dest width
sub esi,ecx ;dest width - width of a dest scan to stretch
mov ulDestNext,esi ;offset from end of one dest stretched
; scan to start of next
add edi,eax
;-----------------------------------------------------------------------;
; Map in the bank containing the top scan of the text, if it's not
; mapped in already.
;-----------------------------------------------------------------------;
mov eax,ulDstTopScan ;top scan line of text
cmp eax,[ebx].pdev_rcl1WindowClip.yTop ;is text top less than
; current bank?
jl short map_init_bank ;yes, map in proper bank
cmp eax,[ebx].pdev_rcl1WindowClip.yBottom ;text top greater than
; current bank?
jl short init_bank_mapped ;no, proper bank already mapped
map_init_bank::
; Map in the bank containing the top scan line of the destination.
; Preserves EBX, ESI, and EDI.
ptrCall <dword ptr [ebx].pdev_pfnBankControl>,<ebx,eax,JustifyTop>
init_bank_mapped::
add edi,[ebx].pdev_pvBitmapStart ;initial destination address
;-----------------------------------------------------------------------;
; Calculate the offset of the initial source pixel.
;-----------------------------------------------------------------------;
mov esi,prclSrc
mov eax,lSrcNext
imul ulSrcTopScan
mov esi,lXSrcLeft
add esi,eax
add esi,pSrc
;-----------------------------------------------------------------------;
; Main loop for processing stretch blt in each bank.
;
; At start of loop, EBX->ppdev, ESI->current src, EDI->current dst
;-----------------------------------------------------------------------;
bank_loop::
mov edx,ulDstBottomScan ;bottom of destination rectangle
cmp edx,[ebx].pdev_rcl1WindowClip.yBottom
;which comes first, the bottom of the
; text rect or the bottom of the
; current bank?
jl short @F ;text bottom comes first, so draw to
; that; this is the last bank in text
mov edx,[ebx].pdev_rcl1WindowClip.yBottom
;bank bottom comes first; draw to
; bottom of bank
@@:
sub edx,ulDstTopScan ;# of scans to draw in bank
mov ulScanCount,edx
call pfnStretchFn ;stretch the bitmap block that's in this bank
;-----------------------------------------------------------------------;
; See if there are more banks to draw.
;-----------------------------------------------------------------------;
mov ebx,ppdev
mov eax,[ebx].pdev_rcl1WindowClip.yBottom ;is the text bottom in
cmp ulDstBottomScan,eax ; the current bank?
jnle short do_next_bank ;no, map in the next bank and draw
mov eax,1 ;success
;@@@shouldn't return a value
done::
cRet vStretchBlt8bpp ;yes, so we're done
do_next_bank::
mov ulDstTopScan,eax
sub edi,[ebx].pdev_pvBitmapStart ;convert from address to offset
; within bitmap
ptrCall <dword ptr [ebx].pdev_pfnBankControl>,<ebx,eax,JustifyTop>
;map in the bank (call preserves
; EBX, ESI, and EDI)
add edi,[ebx].pdev_pvBitmapStart ;convert from offset within bitmap
; to address (bitmap start just
; moved)
jmp bank_loop ;we're ready to draw to the new
; bank
;-----------------------------------------------------------------------;
; Shrink in X and Y, xlat or noxlat, 8-bpp source, VGA dest
;
; On entry: ESI->first source pixel to copy from
; EDI->first dest pixel to copy to
; pulXlatVector = pointer to color translation array (xlat cases
; only)
; ulSrcMinNext = minimum offset from end of current source scan to
; start of next source scan to stretch
; lSrcNext = offset from start of one source scan to start of next
; ulDestNext = offset from end of current dest scan to start of
; next dest scan to stretch to
; pfnRowVector = pointer to routine to call to stretch one scan
; ulScanCount = # of scans to stretch
; lYErrorTerm, ulYAdjUp, ulYAdjDown = Y DDA error term components
;
; On exit: ESI->next source pixel to copy from
; EDI->next dest pixel to copy to
; lYErrorTerm advanced for next scan
;-----------------------------------------------------------------------;
shrink_8bpp_loop::
sub ebx,ebx ;prepare EBX=0 for xlat-case row-drawing
; routines
shrink_block_8bpp_loop::
mov edx,pulDDAArray ;point to array of skip values to use to scan
; across the source
mov ecx,ulXStretchCount ;# of pixels or pixel pairs to copy to
push esi ;preserve source pointer
call pfnRowVector ;stretch/shrink this row
pop esi ;restore source pointer
add esi,ulSrcMinNext ;point to start of next source row, assuming
; no extra row for error term turnover
mov eax,lYErrorTerm
add eax,ulYAdjUp ;advance the error term
jnc short @F ; didn't turn over (minimum step)
sub eax,ulYAdjDown ;turned over, adjust down and...
add esi,lSrcNext ; advance an extra scan (maximum step)
@@:
mov lYErrorTerm,eax ;remember the new error term
add edi,ulDestNext ;point to start of next destination row
dec ulScanCount ;count down scans
jnz shrink_block_8bpp_loop
retn
;-----------------------------------------------------------------------;
; Single-row optimizations, called out of main stretch loops.
;-----------------------------------------------------------------------;
;-----------------------------------------------------------------------;
; Shrink in X
; No xlat
; 8-bit source
; Writes a word at a time
;
; Input: ECX = number of pixel pairs to do, not counting leading and trailing
; single pixels (except in narrow case, where ECX = number of
; pixels, not pixel pairs)
; EDX = pointer to pre-computed skip array
; ESI = pointer to initial source pixel
; EDI = pointer to initial destination pixel
;
; Output: ESI = pointer after last source pixel processed
; EDI = pointer after last source pixel processed
;
; EBX and EBP are preserved
; The contents of EAX, ECX, and EDX may be destroyed
;-----------------------------------------------------------------------;
; No leading byte, no trailing byte.
shrink_noxlat_8bpp_nl_nt::
shrink_noxlat_8bpp_nl_nt_pixel_loop::
mov al,[esi] ;get first source pixel
add esi,[edx] ;point to next source pixel
mov ah,[esi] ;get second source pixel
add esi,[edx+4] ;point to next source pixel
add edx,8 ;point to next skip entry
mov [edi],ax ;write both pixels to the destination
add edi,2 ;point to next destination pixel
dec ecx ;count down pixel pairs
jnz shrink_noxlat_8bpp_nl_nt_pixel_loop
retn
; Leading byte, no trailing byte.
shrink_noxlat_8bpp_l_nt::
;do the leading pixel
mov al,[esi] ;get the current source pixel
add esi,[edx] ;point to next source pixel
add edx,4 ;point to next skip entry
mov [edi],al ;write the pixel to the destination
inc edi ;point to next destination pixel
;now do pixel pairs across the middle
shrink_noxlat_8bpp_l_nt_pixel_loop::
mov al,[esi] ;get first source pixel
add esi,[edx] ;point to next source pixel
mov ah,[esi] ;get second source pixel
add esi,[edx+4] ;point to next source pixel
add edx,8 ;point to next skip entry
mov [edi],ax ;write both pixels to the destination
add edi,2 ;point to next destination pixel
dec ecx ;count down pixel pairs
jnz shrink_noxlat_8bpp_l_nt_pixel_loop
retn
; Leading byte, trailing byte.
shrink_noxlat_8bpp_l_t::
;do the leading pixel
mov al,[esi] ;get current source pixel
add esi,[edx] ;point to next source pixel
add edx,4 ;point to next skip entry
mov [edi],al ;write the pixel to the destination
inc edi ;point to next destination pixel
;now do pixel pairs across the middle
shrink_noxlat_8bpp_l_t_pixel_loop::
mov al,[esi] ;get first source pixel
add esi,[edx] ;point to next source pixel
mov ah,[esi] ;get second source pixel
add esi,[edx+4] ;point to next source pixel
add edx,8 ;point to next skip entry
mov [edi],ax ;write both pixels to the destination
add edi,2 ;point to next destination pixel
dec ecx ;count down pixel pairs
jnz shrink_noxlat_8bpp_l_t_pixel_loop
;do the trailing pixel
mov al,[esi] ;get current source pixel
add esi,[edx] ;point to next source pixel
add edx,4 ;point to next skip entry
mov [edi],al ;write the pixel to the destination
inc edi ;point to next destination pixel
retn
; No leading byte, trailing byte.
shrink_noxlat_8bpp_nl_t::
shrink_noxlat_8bpp_nl_t_pixel_loop::
mov al,[esi] ;get first source pixel
add esi,[edx] ;point to next source pixel
mov ah,[esi] ;get second source pixel
add esi,[edx+4] ;point to next source pixel
add edx,8 ;point to next skip entry
mov [edi],ax ;write both pixels to the destination
add edi,2 ;point to next destination pixel
dec ecx ;count down pixel pairs
jnz shrink_noxlat_8bpp_nl_t_pixel_loop
;do the trailing pixel
mov al,[esi] ;get current source pixel
add esi,[edx] ;point to next source pixel
add edx,4 ;point to next skip entry
mov [edi],al ;write the pixel to the destination
inc edi ;point to next destination pixel
retn
; Narrow case, a byte at a time.
shrink_noxlat_8bpp_narrow::
shrink_noxlat_8bpp_narrow_pixel_loop::
mov al,[esi] ;get current source pixel
add esi,[edx] ;point to next source pixel
add edx,4 ;point to next skip entry
mov [edi],al ;write the pixel to the destination
inc edi ;point to next destination pixel
dec ecx ;count down pixels
jnz shrink_noxlat_8bpp_narrow_pixel_loop
retn
;-----------------------------------------------------------------------;
; Shrink in X
; Xlat
; 8-bit source
; Writes a word at a time
;
; Input: EBX upper three bytes = zero (0)
; ECX = number of pixel pairs to do, not counting leading and trailing
; single pixels (except in narrow case, where ECX = number of
; pixels, not pixel pairs)
; EDX = pointer to pre-computed skip array
; ESI = pointer to initial source pixel
; EDI = pointer to initial destination pixel
; pulXlatVector = pointer to color translation array
;
; Output: ESI = pointer after last source pixel processed
; EDI = pointer after last source pixel processed
;
; EBP is preserved
; The upper three bytes of EBX are preserved
; The contents of EAX, BL, ECX, and EDX may be destroyed
;-----------------------------------------------------------------------;
; No leading byte, no trailing byte.
shrink_xlat_8bpp_nl_nt::
push ebp ;***stack frame not available***
mov ebp,pulXlatVector ;point EBP to the translation table
shrink_xlat_8bpp_nl_nt_pixel_loop::
mov bl,[esi] ;get first source pixel
add esi,[edx] ;point to next source pixel
mov eax,[ebp+ebx*4] ;translate the pixel color
mov bl,[esi] ;get second source pixel
add esi,[edx+4] ;point to next source pixel
mov ah,[ebp+ebx*4] ;translate the pixel color
add edx,8 ;point to next skip entry
mov [edi],ax ;write both pixels to the destination
add edi,2 ;point to next destination pixel
dec ecx ;count down pixel pairs
jnz shrink_xlat_8bpp_nl_nt_pixel_loop
pop ebp ;***stack frame available***
retn
; Leading byte, no trailing byte.
shrink_xlat_8bpp_l_nt::
push ebp ;***stack frame not available***
mov ebp,pulXlatVector ;point EBP to the translation table
;do the leading pixel
mov bl,[esi] ;get first source pixel
add esi,[edx] ;point to next source pixel
mov eax,[ebp+ebx*4] ;translate the pixel color
add edx,4 ;point to next skip entry
mov [edi],al ;write the pixel to the destination
inc edi ;point to next destination pixel
;now do pixel pairs across the middle
shrink_xlat_8bpp_l_nt_pixel_loop::
mov bl,[esi] ;get first source pixel
add esi,[edx] ;point to next source pixel
mov eax,[ebp+ebx*4] ;translate the pixel color
mov bl,[esi] ;get second source pixel
add esi,[edx+4] ;point to next source pixel
mov ah,[ebp+ebx*4] ;translate the pixel color
add edx,8 ;point to next skip entry
mov [edi],ax ;write both pixels to the destination
add edi,2 ;point to next destination pixel
dec ecx ;count down pixel pairs
jnz shrink_xlat_8bpp_l_nt_pixel_loop
pop ebp ;***stack frame available***
retn
; Leading byte, trailing byte.
shrink_xlat_8bpp_l_t::
push ebp ;***stack frame not available***
mov ebp,pulXlatVector ;point EBP to the translation table
;do the leading pixel
mov bl,[esi] ;get first source pixel
add esi,[edx] ;point to next source pixel
mov eax,[ebp+ebx*4] ;translate the pixel color
add edx,4 ;point to next skip entry
mov [edi],al ;write the pixel to the destination
inc edi ;point to next destination pixel
;now do pixel pairs across the middle
shrink_xlat_8bpp_l_t_pixel_loop::
mov bl,[esi] ;get first source pixel
add esi,[edx] ;point to next source pixel
mov eax,[ebp+ebx*4] ;translate the pixel color
mov bl,[esi] ;get second source pixel
add esi,[edx+4] ;point to next source pixel
mov ah,[ebp+ebx*4] ;translate the pixel color
add edx,8 ;point to next skip entry
mov [edi],ax ;write both pixels to the destination
add edi,2 ;point to next destination pixel
dec ecx ;count down pixel pairs
jnz shrink_xlat_8bpp_l_t_pixel_loop
;do the trailing pixel
mov bl,[esi] ;get first source pixel
add esi,[edx] ;point to next source pixel
mov eax,[ebp+ebx*4] ;translate the pixel color
add edx,4 ;point to next skip entry
mov [edi],al ;write the pixel to the destination
inc edi ;point to next destination pixel
pop ebp ;***stack frame available***
retn
; No leading byte, trailing byte.
shrink_xlat_8bpp_nl_t::
push ebp ;***stack frame not available***
mov ebp,pulXlatVector ;point EBP to the translation table
shrink_xlat_8bpp_nl_t_pixel_loop::
mov bl,[esi] ;get first source pixel
add esi,[edx] ;point to next source pixel
mov eax,[ebp+ebx*4] ;translate the pixel color
mov bl,[esi] ;get second source pixel
add esi,[edx+4] ;point to next source pixel
mov ah,[ebp+ebx*4] ;translate the pixel color
add edx,8 ;point to next skip entry
mov [edi],ax ;write both pixels to the destination
add edi,2 ;point to next destination pixel
dec ecx ;count down pixel pairs
jnz shrink_xlat_8bpp_nl_t_pixel_loop
;do the trailing pixel
mov bl,[esi] ;get first source pixel
add esi,[edx] ;point to next source pixel
mov eax,[ebp+ebx*4] ;translate the pixel color
add edx,4 ;point to next skip entry
mov [edi],al ;write the pixel to the destination
inc edi ;point to next destination pixel
pop ebp ;***stack frame available***
retn
; Narrow case, a byte at a time.
shrink_xlat_8bpp_narrow::
push ebp ;***stack frame not available***
mov ebp,pulXlatVector ;point EBP to the translation table
shrink_xlat_8bpp_narrow_loop::
mov bl,[esi] ;get first source pixel
add esi,[edx] ;point to next source pixel
mov eax,[ebp+ebx*4] ;translate the pixel color
add edx,4 ;point to next skip entry
mov [edi],al ;write the pixel to the destination
inc edi ;point to next destination pixel
dec ecx ;count down pixels
jnz shrink_xlat_8bpp_narrow_loop
pop ebp ;***stack frame available***
retn
endProc vStretchBlt8bpp
public DoneFailed
public x_shrink
public check_y_shrink
public x_shrink_set_dda_loop
public x_shrink_set_dda_max
public x_shrink_set_dda_min
public x_shrink_set_dda_done
public y_shrink
public map_init_bank
public init_bank_mapped
public bank_loop
public done
public do_next_bank
public shrink_8bpp_loop
public shrink_block_8bpp_loop
public shrink_noxlat_8bpp_nl_nt
public shrink_noxlat_8bpp_nl_nt_pixel_loop
public shrink_noxlat_8bpp_l_nt
public shrink_noxlat_8bpp_l_nt_pixel_loop
public shrink_noxlat_8bpp_l_t
public shrink_noxlat_8bpp_l_t_pixel_loop
public shrink_noxlat_8bpp_nl_t
public shrink_noxlat_8bpp_nl_t_pixel_loop
public shrink_noxlat_8bpp_narrow
public shrink_noxlat_8bpp_narrow_pixel_loop
public shrink_xlat_8bpp_nl_nt
public shrink_xlat_8bpp_nl_nt_pixel_loop
public shrink_xlat_8bpp_l_nt
public shrink_xlat_8bpp_l_nt_pixel_loop
public shrink_xlat_8bpp_l_t
public shrink_xlat_8bpp_l_t_pixel_loop
public shrink_xlat_8bpp_nl_t
public shrink_xlat_8bpp_nl_t_pixel_loop
public shrink_xlat_8bpp_narrow
public shrink_xlat_8bpp_narrow_loop
end