259 lines
14 KiB
Plaintext
259 lines
14 KiB
Plaintext
;*************************************************************************************
|
|
; MODULE: UTIL.ASM DATE: MAY 15, 1998
|
|
; AUTHOR: SEAN M. KESSLER
|
|
; TARGET: 32 BIT TARGET
|
|
; FUNCTION : RESAMPLE FUNCTIONS
|
|
;*************************************************************************************
|
|
SMART
|
|
.386
|
|
.MODEL FLAT
|
|
.DATA
|
|
.CODE
|
|
LOCALS
|
|
INCLUDE ..\COMMON\COMMON.INC
|
|
INCLUDE ..\COMMON\MATH.INC
|
|
setByte MACRO ; setByte, see _lineWINGBlt, see _line
|
|
LOCAL @@return,@@chkCol,@@endChk ; locals
|
|
mov esi,imageBase ; move imageBase to source index register
|
|
mov eax,yRunning ; move yRunning to eax register
|
|
sar eax,10h ; adjust yRunning, this is row
|
|
jl @@return ; if less than zero then we're done
|
|
mov ebx,xRunning ; move xRunning to ebx register
|
|
sar ebx,10h ; adjust xRunning, this is col
|
|
jl @@return ; if less than zero then we're done
|
|
cmp eax,[ebp+18h] ; compare row to height
|
|
jge @@return ; if row is greater equal height then we're done here
|
|
cmp ebx,[ebp+14h] ; compare column to width
|
|
jge @@return ; if column is greater equal width then we're done here
|
|
mov edx,[ebp+14h] ; move width into bx register
|
|
imul eax,edx ; multiply row*width
|
|
sub esi,eax ; lpImage-=(row*width)
|
|
add esi,edx ; add the width back in, so (row*width)+width
|
|
add esi,ebx ; now subtract out the column
|
|
mov bl,byte ptr[ebp+1Ch] ; get fill value from stack
|
|
mov byte ptr[esi],bl ; move value into bitmap data
|
|
@@return:
|
|
ENDM
|
|
_resampleClip proc near ; short resampleClip(char *lpIn,char *lpOut,DWORD inLen,DWORD outLen,DWORD outClamp)
|
|
LOCAL sampleFactor:DWORD,runningFactor:DWORD=LocalLength
|
|
push ebp ; save stack frame
|
|
mov ebp,esp ; create new stack frame
|
|
sub esp,LocalLength ; adjust stack for local
|
|
push esi ; save source index register
|
|
push edi ; save destination
|
|
push ebx ; save ebx register
|
|
mov eax,[ebp+10h] ; move inLen to eax register
|
|
cmp eax,0000h ; compare inLen to zero
|
|
jle @@errorExit ; if it's less or equal then exit
|
|
mov ebx,[ebp+14h] ; move outLen to ebx register
|
|
cmp ebx,0000h ; compare outLen to zero
|
|
jle @@errorExit ; if it's less or equal then exit
|
|
dec eax ; decrement inLen
|
|
shl eax,10h ; multiply inLen by 65536L
|
|
divide eax,ebx ; divide ((inLen-1L)*65536L)/outLen
|
|
mov sampleFactor,eax ; store the factor
|
|
dec ebx ; ebx has (outLen-1)
|
|
mov ecx,ebx ; copy (outLen-1) to ecx
|
|
mov eax,dword [ebp+18h] ; move outClip to eax register
|
|
sub ebx,eax ; subtract (outLen-1L)-outClip, this is clipping region
|
|
mov edi,[ebp+0Ch] ; move lpOut to destination index register
|
|
add edi,ecx ; edi=lpOut+(outLen-1L)
|
|
mov esi,[ebp+08h] ; move lpIn to source index register
|
|
multiply ecx,sampleFactor ; multiply (outLen-1)*sampleFactor
|
|
mov runningFactor,eax ; save this into runningFactor
|
|
@@loopControl: ; loop control sync address
|
|
cmp ecx,0000h ; make sure we're within boundary
|
|
jl @@exit ; if not then we exit
|
|
cmp ecx,ebx ; compare ecx to clipping region
|
|
je @@exit ; if it's equal then we're done
|
|
mov eax,runningFactor ; move last running factor into eax
|
|
round ; round it off
|
|
mov dl,byte ptr[esi+eax] ; move source byte to dl register
|
|
mov byte ptr[edi],dl ; move source byte to destination address
|
|
mov eax,sampleFactor ; move sampleFactor into eax register
|
|
sub runningFactor,eax ; subtract from running factor
|
|
dec ecx ; decrement counter
|
|
dec edi ; advance (backwards) along lpOut array
|
|
jmp @@loopControl ; continue processing
|
|
@@errorExit: ; error exit return sync address
|
|
xor ax,ax ; clear ax register on error
|
|
jmp @@endProcedure ; jump to end procedure
|
|
@@exit: ; exit sync address
|
|
mov ax,01h ; set ax register on success
|
|
@@endProcedure: ; end procedure sync address
|
|
pop ebx ; restore ebx register
|
|
pop edi ; restore destination index register
|
|
pop esi ; restore source index register
|
|
add esp,LocalLength ; remove locals off stack
|
|
pop ebp ; restore previous stack frame
|
|
retn ; return near to caller
|
|
_resampleClip endp
|
|
_lineWINGBlt proc near ; void lineWINGBLT(DWORD lpWINGData,Point *lpFirstPoint,Point *lpSecondPoint,DWORD width,DWORD height,WORD value)
|
|
LOCAL xRunning:DWORD,yRunning:DWORD,xDelta:DWORD,yDelta:DWORD,xDir:WORD,yDir:WORD, \
|
|
imageExtent:DWORD,imageBase:DWORD,steps:DWORD=LocalLength
|
|
push ebp ; save stack frame
|
|
mov ebp,esp ; create new frame
|
|
sub esp,LocalLength ; storage for local symbols
|
|
pushad ; save all general purpose registers
|
|
mov eax,[ebp+18h] ; move height into eax register
|
|
imul eax,[ebp+14h] ; multiply width*height, this is imageExtent
|
|
mov imageExtent,eax ; store extent into imageExtent
|
|
mov esi,[ebp+08h] ; move wingData into source index register
|
|
add esi,imageExtent ; add in imageExtent
|
|
mov imageBase,esi ; this is our new imageBase
|
|
mov esi,[ebp+0Ch] ; move lpFirstPoint to esi
|
|
mov edi,[ebp+10h] ; move lpSecondPoint to edi
|
|
mov ax,[esi].Point@@x ; pFirstPoint->x to eax
|
|
cmp ax,[edi].Point@@x ; is firstPoint.x == secondPoint.x
|
|
jne @@xne ; if x's are not equal then keep going
|
|
mov ax,[esi].Point@@y ; pFirstPoint->y to ax
|
|
cmp ax,[edi].Point@@y ; is firstPoint.y==secondPoint.y
|
|
je @@endLine ; if points are equal no need to draw the line
|
|
@@xne:
|
|
movsx eax,[esi].Point@@x ; move lpFirstPoint->x to eax
|
|
shl eax,10h ; shift into high word
|
|
mov xRunning,eax ; this is xRunning
|
|
movsx ebx,[esi].Point@@y ; move lpFirstPoint->y to eax
|
|
shl ebx,10h ; shift into high word
|
|
mov yRunning,ebx ; this is yRunning
|
|
mov xDir,01h ; initialize x-direction
|
|
mov yDir,01h ; initialize y-direction
|
|
movzx eax,[edi].Point@@x ; move secondPoint.x to ax
|
|
cmp ax,[esi].Point@@x ; compare secondPoint.x to firstPoint.x
|
|
jge @@noxDirChange ; no direction change required
|
|
neg xDir ; change line direction along x
|
|
@@noxDirChange: ; noxDirChange sync address
|
|
movzx ebx,[edi].Point@@y ; move secondPoint.y to ax
|
|
cmp bx,[esi].Point@@y ; compare secondPoint.y to firstPoint.y
|
|
jge @@noyDirChange ; no direction change requires
|
|
neg yDir ; change line direction along y
|
|
@@noyDirChange: ; noyDirChange sync address
|
|
sub ax,[esi].Point@@x ; move secondPoint.x-firstPoint.x to ax
|
|
movsx eax,ax ; adjust sign
|
|
mov xDelta,eax ; store difference into xDelta
|
|
sub bx,[esi].Point@@y ; move secondPoint.y-firstPoint.y to bx
|
|
movsx ebx,bx ; adjust sign
|
|
mov yDelta,ebx ; store difference into yDelta
|
|
cmp xDelta,00000000h ; is xDelta less than zero
|
|
jl @@posxDelta ; if yes then we must adjust xDelta for magnitude
|
|
jmp @@skipxFix ; otherwise no adjustment is necessary
|
|
@@posxDelta: ; posxDelta sync address
|
|
neg xDelta ; make xDelta positive
|
|
@@skipxFix: ; skipxFix sync address
|
|
cmp yDelta,00000000h ; is yDelta less than zero
|
|
jl @@posyDelta ; if yes then we must adjust yDelta for magnitude
|
|
jmp @@skipyFix ; otherwise no adjustment is necessary
|
|
@@posyDelta: ; posyDelta sync address
|
|
neg yDelta ; make yDelta positive
|
|
@@skipyFix: ; skipyFix sync address
|
|
mov eax,xDelta ; move xDelta into eax register
|
|
cmp eax,yDelta ; compare xDelta to yDelta
|
|
jge @@xGEy ; handle xDelta>=yDelta
|
|
shl eax,10h ; shift xDelta left 16 positions
|
|
cmp yDelta,00000000h ; compare yDelta to zero
|
|
je @@yEQz ; jump to sync address
|
|
divide eax,yDelta ; divide xDelta by yDelta
|
|
mov xDelta,eax ; save new xDelta value to xDelta
|
|
jmp @@yCMPs ; jump over to sync address
|
|
@@yEQz: ; yEQz sync address
|
|
mov xDelta,00000001h ; if yDelta is zero then assign one to xDelta
|
|
@@yCMPs: ; yCMPs sync address
|
|
mov eax,yDelta ; move yDelta to eax register
|
|
mov steps,eax ; move yDelta to steps
|
|
mov yDelta,10000h ; move 10000h to yDelta
|
|
jmp @@startLineDraw ; we're ready to start drawing the line
|
|
@@xGEy: ; xGEy sync address
|
|
mov eax,yDelta ; move yDelta to eax register
|
|
shl eax,10h ; shift left 10h
|
|
cmp xDelta,00000000h ; is xDelta zero
|
|
jne @@xNEz ; handle xDelta not equal to zero
|
|
mov yDelta,00000001h ; if xDelta is zero then yDelta equals one
|
|
jmp @@xCMPs ; jump over to sync address
|
|
@@xNEz: ; xNEzs sync address
|
|
divide eax,xDelta ; divide yDelta by xDelta
|
|
mov yDelta,eax ; replace yDelta with new value
|
|
@@xCMPs: ; xCMPs sync address
|
|
mov eax,xDelta ; move xDelta value into eax register
|
|
mov steps,eax ; move xDelta to steps
|
|
mov xDelta,10000h ; move 10000h to xDelta
|
|
@@startLineDraw: ; startLineDraw sync address
|
|
mov ecx,steps ; move steps into ecx register
|
|
cmp xDir,0FFFFh ; is xDir negative
|
|
je @@checkYDir ; yes it is, now check yDir
|
|
cmp yDir,0FFFFh ; is yDir negative
|
|
je @@posxDirAndNegyDir ; xDir is positive and yDir is negative
|
|
jmp @@posxDirAndPosyDir ; xDir is positive and yDir is positive
|
|
@@checkYDir: ; xDir is negative on entry
|
|
cmp yDir,0FFFFh ; is yDir negative
|
|
je @@negxDirAndNegyDir ; xDir is negative and yDir is negative
|
|
@@negxDirAndPosyDir: ; xDir is negative and yDir is positive
|
|
setByte ; set the byte
|
|
mov eax,xDelta ; move xDelta into eax register
|
|
sub xRunning,eax ; xRunning-=xDelta
|
|
mov eax,yDelta ; move yDelta into eax register
|
|
add yRunning,eax ; yRunning+=yDelta
|
|
dec cx ; decrement cx register
|
|
jnz @@negxDirAndPosyDir ; if (cx) continue
|
|
jmp @@endLine ; we're done
|
|
@@negxDirAndNegyDir: ; xDir==-1&&yDir==-1 sync address
|
|
setByte ; set the byte
|
|
mov eax,xDelta ; move xDelta into eax register
|
|
sub xRunning,eax ; xRunning-=xDelta
|
|
mov eax,yDelta ; move yDelta into eax register
|
|
sub yRunning,eax ; yRunning-=yDelta
|
|
dec cx ; decrement cx register
|
|
jnz @@negxDirAndNegyDir ; if (cx) continue
|
|
jmp @@endLine ; we're done
|
|
@@posxDirAndNegyDir: ; xDir==1&&yDir==-1 sync address
|
|
setByte ; set the byte
|
|
mov eax,xDelta ; move xDelta into eax register
|
|
add xRunning,eax ; xRunning+=xDelta
|
|
mov eax,yDelta ; move yDelta into eax register
|
|
sub yRunning,eax ; yRunning-=yDelta
|
|
dec cx ; decrement cx register
|
|
jnz @@posxDirAndNegyDir ; if (cx) continue
|
|
jmp @@endLine ; we're done here
|
|
@@posxDirAndPosyDir: ; xDir==1&&yDir==1
|
|
setByte ; set the byte
|
|
mov eax,xDelta ; move xDelta into eax register
|
|
add xRunning,eax ; xRunning+=xDelta
|
|
mov eax,yDelta ; move yDelta into eax
|
|
add yRunning,eax ; yRunning+=yDelta
|
|
dec cx ; decrement cx register
|
|
jnz @@posxDirAndPosyDir ; if (cx) continue;
|
|
@@endLine: ; we're done here
|
|
popad ; restore all general purpose registers
|
|
add esp,LocalLength ; remove local storage frame
|
|
pop ebp ; restore stack frame
|
|
retn ; return near to caller
|
|
_lineWINGBlt endp
|
|
_clearBitmap proc near ; void clearBitmap(DWORD lpBitmapData,DWORD imageExtent)
|
|
push edi ; save destination index register
|
|
xor eax,eax ; clear eax register
|
|
mov edi,[esp+08h] ; move lpBitmapData to esi
|
|
mov ecx,[esp+0Ch] ; move bitmap extent to ecx
|
|
shr ecx,02h ; divide bitmap extent by sizeof(long)
|
|
rep stosd ; clear out the bitmap in chunks of sizeof(long)
|
|
pop edi ; restore destination index register
|
|
retn ; return near to caller
|
|
_clearBitmap endp
|
|
_setBits proc near ; void setBits(DWORD lpBitmapData,DWORD imageExtent,BYTE setBit)
|
|
push edi ; save destination index register
|
|
mov eax,[esp+10h] ; move filler byte into eax register (actually al register)
|
|
mov ah,al ; copy filler into high byte
|
|
mov cx,ax ; save word at ax into bx
|
|
shl eax,10h ; move low word into high word
|
|
mov ax,cx ; copy word back into ax
|
|
mov edi,[esp+08h] ; move lpBitmapData to esi
|
|
mov ecx,[esp+0Ch] ; move bitmap extent to ecx
|
|
shr ecx,02h ; divide bitmap extent by sizeof(long)
|
|
rep stosd ; clear out the bitmap in chunks of sizeof(long)
|
|
pop edi ; restore destination index register
|
|
retn ; return near to caller
|
|
_setBits endp
|
|
public _resampleClip
|
|
public _lineWINGBlt
|
|
public _clearBitmap
|
|
public _setBits
|
|
END
|