;************************************************************************************* ; 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