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.
390 lines
12 KiB
390 lines
12 KiB
page ,132
|
|
;------------------------------Module-Header----------------------------;
|
|
; Module Name: str.asm
|
|
;
|
|
; Same format, no translation stretch blt inner loop
|
|
;
|
|
; Created: 17-Oct-1994
|
|
; Author: Mark Enstrom
|
|
;
|
|
; Copyright (c) 1994-1999 Microsoft Corporation
|
|
;-----------------------------------------------------------------------;
|
|
|
|
|
|
.386
|
|
.model small,c
|
|
|
|
assume cs:FLAT,ds:FLAT,es:FLAT,ss:FLAT
|
|
assume fs:nothing,gs:nothing
|
|
|
|
.xlist
|
|
include callconv.inc
|
|
include gdii386.inc
|
|
;
|
|
; stack based params and local variables
|
|
;
|
|
|
|
sp_TempXFrac equ 000H
|
|
sp_YCarry equ 004H
|
|
sp_LeftCase equ 008H
|
|
sp_RightCase equ 00CH
|
|
sp_pjSrcScan equ 010H
|
|
sp_SrcIntStep equ 014H
|
|
sp_DstStride equ 018H
|
|
sp_XCount equ 01CH
|
|
sp_ebp equ 020H
|
|
sp_esi equ 024H
|
|
sp_edi equ 028H
|
|
sp_ebx equ 02CH
|
|
sp_RetAddr equ 030H
|
|
sp_pSTR_BLT equ 034H
|
|
|
|
.list
|
|
|
|
;------------------------------------------------------------------------------;
|
|
|
|
.code
|
|
|
|
|
|
_TEXT$01 SEGMENT DWORD USE32 PUBLIC 'CODE'
|
|
ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
|
|
|
|
|
|
;------------------------------------------------------------------------------;
|
|
|
|
;------------------------------------------------------------------------------;
|
|
; vDirectStretch8
|
|
;
|
|
; Stretcg 8 to 8
|
|
;
|
|
; Entry:
|
|
;
|
|
; pSTR_BLT - pointer to stretch blt parameter block
|
|
;
|
|
; Returns:
|
|
; none
|
|
; Registers Destroyed:
|
|
; all
|
|
; Calls:
|
|
; None
|
|
; History:
|
|
;
|
|
; WARNING This routine uses EBP as a general variable.
|
|
; Also, if parameters are changed, the ret statement must
|
|
; also be fixed
|
|
;
|
|
;------------------------------------------------------------------------------;
|
|
|
|
public vDirectStretch8@4
|
|
|
|
vDirectStretch8@4 proc near
|
|
|
|
;
|
|
; use ebp as general register, use esp for parameter and local access
|
|
; save ebp,ebx,esi,edi
|
|
|
|
push ebx
|
|
push edi
|
|
push esi
|
|
push ebp
|
|
|
|
sub esp,8 * 4
|
|
|
|
mov ebp,[esp].sp_pSTR_BLT ; load pSTR_BLT into ebp
|
|
|
|
;
|
|
; calc starting addressing parameters
|
|
;
|
|
|
|
mov esi,[ebp].str_pjSrcScan ; load src DIB pointer
|
|
add esi,[ebp].str_XSrcStart ; add strarting Src Pixel
|
|
mov edi,[ebp].str_pjDstScan ; load dst DIB pointer
|
|
add edi,[ebp].str_XDstStart ; add strarting Dst Pixel
|
|
mov [esp].sp_pjSrcScan,esi ; save scan line start pointer
|
|
mov eax,[ebp].str_ulYDstToSrcIntCeil ; number of src scan lines to step
|
|
mul dword ptr [ebp].str_lDeltaSrc ; calc scan line int lines to step
|
|
mov [esp].sp_SrcIntStep,eax ; save int portion of Y src step
|
|
mov eax,edi ; make copy of pjDst
|
|
and eax,3 ; calc left edge case
|
|
mov edx,4 ; calc left bytes = (4 - LeftCase) & 0x03
|
|
sub edx,eax ; 4 - LeftCase
|
|
and edx,3 ; left edge bytes
|
|
mov [esp].sp_LeftCase,edx ; save left edge case pixels (4-LeftCase)&0x03
|
|
mov eax,[ebp].str_pjDstScan ; make copy
|
|
mov ecx,[ebp].str_XDstEnd ; load x end
|
|
add eax,ecx ; ending dst addr
|
|
and eax,3 ; calc right edge case
|
|
mov [esp].sp_RightCase,eax ; save right edge case
|
|
sub ecx,[ebp].str_XDstStart ; calc x count
|
|
mov ebx,[ebp].str_lDeltaDst ; dst scan line stride
|
|
sub ebx,ecx ; distance from end of one line to start of next
|
|
mov [esp].sp_DstStride,ebx ; save dst scan line stride
|
|
sub ecx,eax ; sub right edge from XCount
|
|
sub ecx,edx ; sub left edge from XCount
|
|
shr ecx,2 ; convert from byte to DWORD count
|
|
mov [esp].sp_XCount,ecx ; save DWORD count
|
|
mov ebx,[ebp].str_ulXDstToSrcFracCeil ; get x frac
|
|
mov [esp].sp_TempXFrac,ebx ; save x frac to a esp based location
|
|
|
|
LoopTop::
|
|
|
|
;
|
|
; can 2 scan dst lines be drawn from 1 src?
|
|
;
|
|
|
|
xor ebx,ebx ; zero ebx
|
|
mov eax,[ebp].str_ulYFracAccumulator ; get .32 part of Y pointer
|
|
add eax,[ebp].str_ulYDstToSrcFracCeil ; add in fractional step
|
|
adc ebx,0
|
|
mov [esp].sp_YCarry,ebx ; save carry for end of loop
|
|
mov [ebp].str_ulYFracAccumulator,eax ; save Y accumulator
|
|
|
|
cmp [esp].sp_SrcIntStep,0 ; int step must be zero
|
|
jne SingleLoop
|
|
|
|
cmp ebx,0 ; carry must be zero
|
|
jne SingleLoop
|
|
|
|
cmp [ebp].str_YDstCount,2 ; y count must be at least 2
|
|
jl SingleLoop
|
|
|
|
;
|
|
; there was no carry, draw 2 dst scan lines. Add 1 extra y Frac, and subtract
|
|
; one extra Y Count
|
|
;
|
|
|
|
add eax,[ebp].str_ulYDstToSrcFracCeil ; add in fractional step
|
|
adc ebx,0 ; get new carry
|
|
mov [esp].sp_YCarry,ebx ; save carry for end of loop
|
|
mov [ebp].str_ulYFracAccumulator,eax ; save Y accumulator
|
|
dec dword ptr [ebp].str_YDstCount ; dec y count
|
|
|
|
;
|
|
; Draw 2 Dst scan lines from 1 src scan
|
|
;
|
|
|
|
mov eax,[ebp].str_ulXDstToSrcIntCeil ; get src integer step for step in dst
|
|
mov edx,[ebp].str_ulXFracAccumulator ; put it in edx as tmp
|
|
|
|
mov ebx,[ebp].str_lDeltaDst ; Get Dst Scan line delta
|
|
mov ebp,edi ; get dst pointer to ebp (ebp uses ss:)
|
|
|
|
;
|
|
; Can't directly access pSTR_BLT variables through ebp
|
|
;
|
|
|
|
mov edi,edx ; get accumulator where we want it
|
|
mov ecx,[esp].sp_LeftCase
|
|
|
|
; esi = pointer to source pixel
|
|
; ebp = pointer to dest pixel
|
|
; ecx = Left edge case
|
|
; eax = integer step in source
|
|
; ebx = Dst scan line delta
|
|
; edi = fractional accumulator
|
|
; edx = free for pixel data
|
|
|
|
;
|
|
; first do the left side to align dwords
|
|
;
|
|
|
|
cmp ecx,0
|
|
je DualDwordAligned
|
|
|
|
DualLeftEdge:
|
|
|
|
mov dl,[esi] ; fetch pixel
|
|
mov [ebp],dl ; write it out
|
|
mov [ebp+ebx],dl ; write it out to next scan line
|
|
add edi,[esp].sp_tempXFrac ; step fraction
|
|
adc esi,eax ; add in integer and possible carry
|
|
inc ebp ; step 1 in dest
|
|
dec ecx ; dec and repeat for left edge
|
|
jne DualLeftEdge
|
|
|
|
DualDwordAligned:
|
|
|
|
mov ecx,[esp].sp_XCount ; get run length
|
|
|
|
@@:
|
|
mov dl,[esi] ; get a source pixel edx = ???0
|
|
add edi,[esp].sp_tempXFrac ; step fraction
|
|
adc esi,eax ; add integer and carry
|
|
|
|
add edi,[esp].sp_tempXFrac ; step fraction
|
|
mov dh,[esi] ; get source pixel edx = ??10
|
|
adc esi,eax ; add integer and carry
|
|
|
|
shl edx,16 ; edx = 10??
|
|
|
|
add edi,[esp].sp_tempXFrac ; step fraction
|
|
mov dl,[esi] ; get a source pixel edx = 10?2
|
|
adc esi,eax ; add integer and carry
|
|
|
|
add edi,[esp].sp_tempXFrac ; step fraction
|
|
mov dh,[esi] ; get source pixel edx = 0132
|
|
adc esi,eax ; add integer and carry
|
|
|
|
ror edx,16 ; edx = 3210
|
|
|
|
mov [ebp],edx ; write everything to dest
|
|
mov [ebp+ebx],edx ; write everything to dest plus 1 scan line
|
|
|
|
add ebp,4 ; increment dest pointer by 2 dwords
|
|
dec ecx ; decrement count
|
|
jnz @b ; do more pixels
|
|
|
|
DualRightEdge:
|
|
|
|
;
|
|
; now do the right side trailing bytes
|
|
;
|
|
|
|
mov ecx,[esp].sp_RightCase
|
|
cmp ecx,0
|
|
je DualAddScanLine
|
|
|
|
@@:
|
|
mov dl,[esi] ; fetch pixel
|
|
mov [ebp],dl ; write it out
|
|
mov [ebp+ebx],dl ; write it out to next scan line
|
|
add edi,[esp].sp_tempXFrac ; step fraction
|
|
adc esi,eax ; add in integer and possible carry
|
|
inc ebp ; step 1 in dest
|
|
dec ecx
|
|
jne @B
|
|
|
|
;
|
|
; add one extra lDeltaDst (ebx) tp ebp for the
|
|
; extra dst scan line
|
|
;
|
|
|
|
DualAddScanLine:
|
|
|
|
add ebp,ebx
|
|
|
|
jmp EndScanLine ; skip to end
|
|
|
|
;
|
|
; Expand and draw 1 scan line
|
|
;
|
|
|
|
SingleLoop:
|
|
|
|
mov eax,[ebp].str_ulXDstToSrcIntCeil ; get src integer step for step in dst
|
|
mov ebx,[ebp].str_ulXDstToSrcFracCeil ; get src frac step for step in dst
|
|
mov edx,[ebp].str_ulXFracAccumulator ; put it in edx as tmp
|
|
|
|
mov ebp,edi ; get dst pointer to ebp (ebp uses ss:)
|
|
|
|
;
|
|
; Can't directly access pSTR_BLT variables through ebp
|
|
;
|
|
|
|
mov edi,edx ; get accumulator where we want it
|
|
mov ecx,[esp].sp_LeftCase
|
|
|
|
; esi = pointer to source pixel
|
|
; ebp = pointer to dest pixel
|
|
; ecx = Left edge case
|
|
; eax = integer step in source
|
|
; ebx = fractional step in source
|
|
; edi = fractional accumulator
|
|
; edx = free for pixel data
|
|
|
|
;
|
|
; first do the left side to align dwords
|
|
;
|
|
|
|
cmp ecx,0
|
|
je DwordAligned
|
|
|
|
@@:
|
|
mov dl,[esi] ; fetch pixel
|
|
mov [ebp],dl ; write it out
|
|
add edi,ebx ; step fraction
|
|
adc esi,eax ; add in integer and possible carry
|
|
inc ebp ; step 1 in dest
|
|
dec ecx ; dec left count
|
|
jne @B ; repeat until done
|
|
|
|
DwordAligned:
|
|
|
|
mov ecx,[esp].sp_XCount ; get run length
|
|
|
|
@@:
|
|
mov dl,[esi] ; get a source pixel edx = ???0
|
|
add edi,ebx ; step fraction
|
|
adc esi,eax ; add integer and carry
|
|
|
|
add edi,ebx ; step fraction
|
|
mov dh,[esi] ; get source pixel edx = ??10
|
|
adc esi,eax ; add integer and carry
|
|
|
|
shl edx,16 ; edx = 10??
|
|
|
|
add edi,ebx ; step fraction
|
|
mov dl,[esi] ; get a source pixel edx = 10?2
|
|
adc esi,eax ; add integer and carry
|
|
|
|
add edi,ebx ; step fraction
|
|
mov dh,[esi] ; get source pixel edx = 0132
|
|
adc esi,eax ; add integer and carry
|
|
|
|
ror edx,16 ; edx = 3210
|
|
|
|
mov [ebp],edx ; write everything to dest
|
|
|
|
add ebp,4 ; increment dest pointer by 1 dword
|
|
dec ecx ; decrement count
|
|
jnz @b ; do more pixels
|
|
|
|
;
|
|
; now do the right side trailing bytes
|
|
;
|
|
|
|
mov ecx,[esp].sp_RightCase
|
|
cmp ecx,0
|
|
je EndScanLine
|
|
|
|
@@:
|
|
|
|
mov dl,[esi] ; fetch pixel
|
|
mov ss:[ebp],dl ; write it out
|
|
add edi,ebx ; step fraction
|
|
adc esi,eax ; add in integer and possible carry
|
|
inc ebp ; step 1 in dest
|
|
dec ecx ; dec right count
|
|
jnz @b ; repeat until done
|
|
|
|
EndScanLine:
|
|
|
|
mov edi,ebp ; get dst pointer back
|
|
mov ebp,[esp].sp_pSTR_BLT ; load pSTR_BLT into ebp
|
|
|
|
mov esi,[esp].sp_pjSrcScan ; load src scan start addr
|
|
cmp [esp].sp_YCarry,1 ; is there a carry
|
|
jne @f ; no additional int step
|
|
|
|
add esi,[ebp].str_lDeltaSrc ; step one extra in src
|
|
@@:
|
|
add esi,[esp].sp_SrcIntStep ; step int part
|
|
mov [esp].sp_pjSrcScan,esi ; save starting scan addr
|
|
add edi,[esp].sp_DstStride ; step to next scan in dst
|
|
dec dword ptr [ebp].str_YDstCount
|
|
jnz LoopTop
|
|
|
|
|
|
add esp,8*4
|
|
pop ebp
|
|
pop esi
|
|
pop edi
|
|
pop ebx
|
|
|
|
ret 4
|
|
|
|
vDirectStretch8@4 endp
|
|
|
|
_TEXT$01 ends
|
|
|
|
end
|