;************************************************************************************* ; MODULE: TMAP32.ASM DATE: DECEMBER 28, 1994 ; AUTHOR: SEAN M. KESSLER JUNE 06, 1995 ; TARGET: 32 BIT TARGET ; FUNCTION : TEXTURE MAPPING POLYGONS IN PERSPECTIVE ;************************************************************************************* SMART .386 .MODEL FLAT .DATA .LALL INCLUDE ..\COMMON\COMMON.INC INCLUDE ..\ENGINE\TMAP32.INC bmData@@mSrcWidth DW 00h bmData@@mSrcHeight DW 00h bmData@@mSrcExtent DD 00h bmData@@mlpSrcPtr DD 00h bmData@@mDstWidth DW 00h bmData@@mDstHeight DW 00h bmData@@mDstExtent DD 00h bmData@@mlpDstPtr DD 00h bmData@@mlpDstIndexPtr DD 00h bmData@@mPrecision DW 4000h bmData@@mMaskValue DB 0FFh bmData@@mUseMask DB 00h MINVALUE EQU -32767 MAXVALUE EQU 32767 MINVERTEX EQU 3 .CODE LOCALS divide MACRO varOne,varTwo mov eax,varOne ; move varOne into eax register cdq ; convert doubleword in eax to quadword at edx:eax idiv varTwo ; divide eax/varTwo result to eax, remainder to edx ENDM multiply MACRO varOne,varTwo movzx eax,varOne ; move varOne into eax register movzx edx,varTwo ; move varTwo into ebx register imul eax,edx ; perform multiply, result to eax ENDM roundEBX MACRO varOne LOCAL @@return mov edx,varOne ; move value into edx register mov ebx,varOne ; move value into ebx register and edx,00003FFFh ; get remainder into edx register shr ebx,14 ; get whole number to ebx register cmp edx,8192 ; if remainder > 8192, increment ebx jle @@return ; otherwise return inc ebx ; increment value in ebx @@return: ENDM roundEAX MACRO varOne LOCAL @@return mov edx,varOne ; move value into edx register mov eax,varOne ; move value into eax register and edx,00003FFFh ; get remainder into edx register shr eax,14 ; get whole number to eax register cmp edx,8192 ; if remainder > 8192, increment ebx jle @@return ; otherwise return inc eax ; increment value in eax @@return: ENDM getPoint MACRO address,index movzx eax,index ; move index into eax register shl eax,02h ; multiply ax by size of far pointer add eax,address ; add in the address movzx ebx,[eax].Point@@y ; get the y value to bx register movzx eax,[eax].Point@@x ; get the x value to ax register ENDM newEdge MACRO ; (PureEdge*) in eax, sets edx=1=error, otherwise edx=0 movzx ebx,[eax].PureEdge@@mEdgeDirection ; save edgeDirection push ebx ; push edgeDirection push [eax].PureEdge@@mCurrentEdgeEnd ; push currentEdge end (ie) nextEdge index mov ecx,eax ; move (PureEdge*) to ecx register call _setupEdge ; attempt to setup new edge add esp,06h ; readjust the stack mov edx,eax ; move return code to edx register ENDM getSrcDataByte MACRO ; BYTE getSrcDataByte(eax=colRow) multiply ax,bmData@@mSrcWidth ; multiply (row*width)-> eax movzx edx,bmData@@mSrcWidth ; move width to edx register add eax,edx ; add in width (ie) (row*width)+width mov edx,bmData@@mSrcExtent ; move source bitmap extent to edx sub edx,eax ; sub result from source bmp extent add edx,ebx ; add column back in mov ebx,bmData@@mlpSrcPtr ; move mlpSrcPtr to ebx register mov cl,byte ptr[ebx+edx] ; get source byte at ebx+edx to cl ENDM setDstDataByte MACRO ; void setDstDataByte(cl=charByte) mov ebx,bmData@@mlpDstIndexPtr ; get scanline pointer to ebx mov byte ptr[ebx],cl ; move byte into frame bitmap inc bmData@@mlpDstIndexPtr ; increment scanline pointer ENDM setDstIndexPtr MACRO multiply [esi].PureMap@@myValue,bmData@@mDstWidth ; multiply row*width result to eax xor edx,edx ; clear edx register mov dx,bmData@@mDstWidth ; move width into dx register add eax,edx ; add (row*width)+width mov edx,bmData@@mDstExtent ; move (width*height) into ebx sub edx,eax ; calculate addValue-subValue mov [esi].PureMap@@mBitmapIndex,edx ; save offset into bitmap ENDM adjDstIndexPtr MACRO mov edx,[esi].PureMap@@mBitmapIndex ; retrieve offset into bitmap movzx ebx,[esi].PureMap@@mxDest ; move column into bx register add edx,ebx ; now add column number back in add edx,bmData@@mlpDstPtr ; offset index by start mov bmData@@mlpDstIndexPtr,edx ; store value into DstIndexPtr ENDM increment MACRO ; assumes (PureEdge*) is in eax register, sets carry on error LOCAL @@newEdge,@@adjTerm,@@error,@@success,@@return dec [eax].PureEdge@@mRemainingScanLines ; decrement mRemainingScanLines jz @@newEdge ; if no more scan lines, try to setup new edge mov ebx,[eax].PureEdge@@mxSourceStep ; get mxSourceStep to ebx register add ebx,[eax].PureEdge@@mxSource ; add in mxSource mov [eax].PureEdge@@mxSource,ebx ; replace mxSource with new value mov ebx,[eax].PureEdge@@mySourceStep ; get mySourceStep into ebx register add ebx,[eax].PureEdge@@mySource ; add in mySource mov [eax].PureEdge@@mySource,ebx ; replace mySource with new value mov bx,[eax].PureEdge@@mxDestLocation ; get mxDestLocation into ebx register add bx,[eax].PureEdge@@mxStep ; add in mxStep mov [eax].PureEdge@@mxDestLocation,bx ; replace mxDestLocation with new value mov bx,[eax].PureEdge@@mxErrorTerm ; get mxErrorTerm to bx register add bx,[eax].PureEdge@@mxAdjustUp ; add in mxAdjustUp mov [eax].PureEdge@@mxErrorTerm,bx ; replace mxErrorTerm with new value cmp bx,00h ; compare mxErrorTerm to zero jle @@success ; mxErrorTerm is less equal zero @@adjTerm: ; adjTerm sync address mov bx,[eax].PureEdge@@mxDestLocation ; get mxDestLocation to bx register add bx,[eax].PureEdge@@mxDirection ; add in mxDirection mov [eax].PureEdge@@mxDestLocation,bx ; replace mxDestLocation with new value mov bx,[eax].PureEdge@@mxErrorTerm ; move mxErrorTerm into bx register sub bx,[eax].PureEdge@@mxAdjustDown ; add in mxAdjustDown mov [eax].PureEdge@@mxErrorTerm,bx ; replace mxErrorTerm with new value jmp @@success ; we're done here @@newEdge: ; newEdge sync address newEdge ; attempt to create new edge cmp edx,0001h ; did prior call fail ? jne @@success ; no, we're done here @@error: ; error sync address stc ; error sets carry jmp @@return ; jump to return @@success: ; ok sync address clc ; success clears carry @@return: ; return sync address ENDM scanOutputLine MACRO ; void scanOutputLine(ecx=(PureEdge*)) LOCAL @@xLoop,@@skipImageBit,@@continue,@@return ; local label mov edi,[esi].PureMap@@mlpLeftEdge ; move (PureEdge*)lpLeftEdge to ecx register mov eax,[edi].PureEdge@@mxSource ; move PureEdge::mxSource to eax register mov [esi].PureMap@@mxSource,eax ; move PureEdge::mxSource to PureMap::mxSource mov eax,[edi].PureEdge@@mySource ; move PureEdge::mySource to eax register mov [esi].PureMap@@mySource,eax ; move PureEdge::mySource to PureMap::mySource mov dx,[edi].PureEdge@@mxDestLocation ; move PureEdge::mxDestLocation to ax mov [esi].PureMap@@mxDest,dx ; move PureEdge::mxDestLocation to PureMap::mxDest mov edi,[esi].PureMap@@mlpRightEdge ; move (PureEdge*)lpRightEdge to ecx register xor eax,eax ; clear out eax register mov ax,[edi].PureEdge@@mxDestLocation ; move PureEdge::mxDestLocation to ax register mov [esi].PureMap@@mxDestMax,ax ; move PureEdge::mxDestLocation to PureMap::mxDestMax sub ax,dx ; mxDestMax-mxDest jz @@return ; if width is zero then return mov [esi].PureMap@@mDestWidth,eax ; move width into PureMap::mDestWidth mov eax,[edi].PureEdge@@mxSource ; move PureEdge::mxSource into eax sub eax,[esi].PureMap@@mxSource ; subtract out PureMap::mxSource divide eax,[esi].PureMap@@mDestWidth ; now divide by PureMap::mDestWidth mov [esi].PureMap@@mxSourceStep,eax ; move new value to PureMap@@mxSourceStep mov eax,[edi].PureEdge@@mySource ; move PureEdge::mySource into eax sub eax,[esi].PureMap@@mySource ; subtract out PureMap::mySource divide eax,[esi].PureMap@@mDestWidth ; now divide by PureMap::mDestWidth mov [esi].PureMap@@mySourceStep,eax ; move new value to PureMap@@mySourceStep setDstIndexPtr ; set destination index pointer to row/col @@xLoop: ; xLoop test mov ax,[esi].PureMap@@mxDest ; move mxDest to ax register cmp ax,[esi].PureMap@@mxDestMax ; compare mxDest to ax register jge @@return ; if its greater equal return cmp ax,bmData@@mDstWidth ; is destination x greater than frame width? jge @@return ; yes, stop scanning this output line or ax,ax ; does mxDest extend too far left of frame buffer jl @@skipImageBit ; if it does then skip putImageBits adjDstIndexPtr ; adjust index to reflect changed mxDest @@continue: ; sync address roundEAX [esi].PureMap@@mySource ; round PureMap@@mySource -> eax (row) roundEBX [esi].PureMap@@mxSource ; round PureMap@@mxSource -> ebx (col) getSrcDataByte ; getSrcDataByte at eax=colRow, byteValue gets placed into cl setDstDataByte ; setDstDataByte at mlpDstIndexPtr,cl=byteValue @@skipImageBit: ; skipImageBit bypass address mov eax,[esi].PureMap@@mxSourceStep ; move mxSourceStep to eax add [esi].PureMap@@mxSource,eax ; add mxSouceStep to mxSource mov ebx,[esi].PureMap@@mySourceStep ; move mySourceStep to eax add [esi].PureMap@@mySource,ebx ; add mySourceStep to mySource inc [esi].PureMap@@mxDest ; increment loop counter jmp @@xLoop ; loop through xLoop @@return: ; return sync label ENDM scanOutputLineMask MACRO ; void scanOutputLineMask(ecx=(PureEdge*)) - uses mask settings LOCAL @@xLoop,@@skipImageBit,@@continue,@@return ; local label mov edi,[esi].PureMap@@mlpLeftEdge ; move (PureEdge*)lpLeftEdge to ecx register mov eax,[edi].PureEdge@@mxSource ; move PureEdge::mxSource to eax register mov [esi].PureMap@@mxSource,eax ; move PureEdge::mxSource to PureMap::mxSource mov eax,[edi].PureEdge@@mySource ; move PureEdge::mySource to eax register mov [esi].PureMap@@mySource,eax ; move PureEdge::mySource to PureMap::mySource mov dx,[edi].PureEdge@@mxDestLocation ; move PureEdge::mxDestLocation to ax mov [esi].PureMap@@mxDest,dx ; move PureEdge::mxDestLocation to PureMap::mxDest mov edi,[esi].PureMap@@mlpRightEdge ; move (PureEdge*)lpRightEdge to ecx register xor eax,eax ; clear out eax register mov ax,[edi].PureEdge@@mxDestLocation ; move PureEdge::mxDestLocation to ax register mov [esi].PureMap@@mxDestMax,ax ; move PureEdge::mxDestLocation to PureMap::mxDestMax sub ax,dx ; mxDestMax-mxDest jz @@return ; if width is zero then return mov [esi].PureMap@@mDestWidth,eax ; move width into PureMap::mDestWidth mov eax,[edi].PureEdge@@mxSource ; move PureEdge::mxSource into eax sub eax,[esi].PureMap@@mxSource ; subtract out PureMap::mxSource divide eax,[esi].PureMap@@mDestWidth ; now divide by PureMap::mDestWidth mov [esi].PureMap@@mxSourceStep,eax ; move new value to PureMap@@mxSourceStep mov eax,[edi].PureEdge@@mySource ; move PureEdge::mySource into eax sub eax,[esi].PureMap@@mySource ; subtract out PureMap::mySource divide eax,[esi].PureMap@@mDestWidth ; now divide by PureMap::mDestWidth mov [esi].PureMap@@mySourceStep,eax ; move new value to PureMap@@mySourceStep setDstIndexPtr ; set destination index pointer to row/col @@xLoop: ; xLoop test mov ax,[esi].PureMap@@mxDest ; move mxDest to ax register cmp ax,[esi].PureMap@@mxDestMax ; compare mxDest to ax register jge @@return ; if its greater equal return cmp ax,bmData@@mDstWidth ; is destination x greater than frame width? jge @@return ; yes, stop scanning this output line or ax,ax ; does mxDest extend too far left of frame buffer jl @@skipImageBit ; if it does then skip putImageBits adjDstIndexPtr ; adjust index to reflect changed mxDest @@continue: ; sync address roundEAX [esi].PureMap@@mySource ; round PureMap@@mySource -> eax (row) roundEBX [esi].PureMap@@mxSource ; round PureMap@@mxSource -> ebx (col) getSrcDataByte ; getSrcDataByte at eax=colRow, byteValue gets placed into cl cmp cl,bmData@@mMaskValue ; are we attempting to output a byte in our mask je @@skipImageBit ; if so then do not set the byte setDstDataByte ; setDstDataByte at mlpDstIndexPtr,cl=byteValue @@skipImageBit: ; skipImageBit bypass address mov eax,[esi].PureMap@@mxSourceStep ; move mxSourceStep to eax add [esi].PureMap@@mxSource,eax ; add mxSouceStep to mxSource mov ebx,[esi].PureMap@@mySourceStep ; move mySourceStep to eax add [esi].PureMap@@mySource,ebx ; add mySourceStep to mySource inc [esi].PureMap@@mxDest ; increment loop counter jmp @@xLoop ; loop through xLoop @@return: ; return sync label ENDM _mapTexture proc near ; void mapTexture(PureMap *lpTextureMap) push ebp ; save old stack frame mov ebp,esp ; create new stack frame pushad ; save all general purpose registers, required. mov esi,dword ptr[ebp+8] ; move (PureMap*) to esi register mov edx,[esi].PureMap@@mlpLeftEdge ; move PureMap->mlpLeftEdge to edx mov bx,[edx].PureEdge@@mMaxVertex ; move left edge mMaxVertex to bx register getPoint [edx].PureEdge@@mlpDstList,bx ; get point mov [esi].PureMap@@myValue,bx ; myValue=mLeftEdge[mLeft.maxVertex()].y() @@forever: ; (ie) while(TRUE) mov ax,[esi].PureMap@@myValue ; move myValue to ax register cmp ax,bmData@@mDstHeight ; is myValue greater than frame buffer height jge @@return ; if so then we're done mapping the texture cmp ax,00h ; is myValue within frame buffer at all jl @@skipOutputLine ; if not then skip this output line cmp bmData@@mUseMask,00h ; are we using mask settings jne @@scanMask ; if so then scan the output line, excluding masked bits scanOutputLine ; otherwise just scan the output line jmp @@skipOutputLine ; jump over the mask code @@scanMask: ; scanMask sync address scanOutputLineMask ; scan the output line, apply mask where appropriate @@skipOutputLine: ; skipOutputLine sync address mov eax,[esi].PureMap@@mlpLeftEdge ; move (PureEdge*) left edge to eax increment ; increment along left edge jc @@return ; if carry set, edge failed to increment, we're done mov eax,[esi].PureMap@@mlpRightEdge ; move (PureEdge*) right edge to eax increment ; increment along right edge jc @@return ; if carry set, edge failed to increment, we're done inc [esi].PureMap@@myValue ; increment y position jmp @@forever ; loop until all edges are completed @@return: ; return sync address popad ; restore all general purpose registers pop ebp ; restore old stack frame retn ; return near to caller _mapTexture endp _initEdge proc near ; void initEdge(long edgeType,PureEdge *lpEdge); push ebp ; save old stack frame mov ebp,esp ; create new stack frame push ebx ; save ebx register mov ecx,dword ptr[ebp+12] ; move edge ptr to ecx register call _getMinMaxInfo ; find minimum and maximum vertices cmp eax,0000h ; make sure previous call returned success jne @@return ; if not then return push dword ptr[ebp+8] ; push edge type (-1:leftEdge,1:rightEdge) push [ecx].PureEdge@@mStartVertex ; push startVertex call _setupEdge ; now setup the edge add esp,06h ; readjust the stack @@return: ; return label pop ebx ; restore ebx register pop ebp ; restore old stack frame retn ; return to caller _initEdge endp _setupEdge proc near ; long setupEge(long edgeType,int startVertex); LOCAL nextVertex:WORD,startVertex:WORD,xDestWidth:WORD,yDestHeight:DWORD=LocalLength push ebp ; save old stack frame mov ebp,esp ; create new stack frame sub esp,LocalLength ; make room for local variables mov bx,word ptr[ebp+10] ; move edge type to bx register mov [ecx].PureEdge@@mEdgeDirection,bx ; store edge direction in variable mov bx,word ptr[ebp+8] ; move startVertex to bx register mov [ecx].PureEdge@@mStartVertex,bx ; move startVertex into mStartVertex mov startVertex,bx ; move startVertex into startVertex @@forever: ; forever loop label mov bx,startVertex ; move startVertex to bx register cmp bx,[ecx].PureEdge@@mMinVertex ; is startVertex same as mMinVertex ? je @@error ; if so then we're all done here add bx,[ecx].PureEdge@@mEdgeDirection ; add edge direction to startVertex mov nextVertex,bx ; move result to nextVertex mov bx,[ecx].PureEdge@@mNumVertexes ; move number of vertexes to bx register cmp nextVertex,bx ; compare nextVertex to number of vertexes jge @@zervert ; next vertex is greater eq number of vertexes cmp nextVertex,00h ; compare nextVertex to zero jl @@adjvert ; nextVertex is less than zero jmp @@bypass ; jump over next conditonal @@zervert: ; handle nextVertex>=number of vertexes mov nextVertex,00h ; set nextVertex to zero jmp @@bypass ; jump over next conditional @@adjvert: ; handle nextVertex<0 dec bx ; decrement value count in bx register mov nextVertex,bx ; set nextVertex to (numVertex-1) @@bypass: ; bypass sync address getPoint [ecx].PureEdge@@mlpDstList,nextVertex ; get mlpDstList[nextVertex] push bx ; dstList[nextVertex].y() in bx, save it. getPoint [ecx].PureEdge@@mlpDstList,startVertex ; get mlpDstList[startVertex] pop ax ; restore first x point to ax sub ax,bx ; now subtract second x point mov [ecx].PureEdge@@mRemainingScanLines,ax ; result is mRemainingScanLines cmp ax,00h ; check scanlines==0 je @@loopNext ; if it's zero, continue mov yDestHeight,eax ; set yDestHeight push nextVertex ; save nextVertex value pop [ecx].PureEdge@@mCurrentEdgeEnd ; restore it to mCurrentEdgeEnd getPoint [ecx].PureEdge@@mlpSrcList,startVertex ; get mlpSrcList[startVertex] multiply ax,bmData@@mPrecision ; multiply mxSource by bmData@@mPrecision mov [ecx].PureEdge@@mxSource,eax ; move srcList[startVertex].x() to mxSource multiply bx,bmData@@mPrecision ; multiply mySource by bmData@@mPrecision mov [ecx].PureEdge@@mySource,eax ; move srcList[startVertex].y() to mySource getPoint [ecx].PureEdge@@mlpSrcList,nextVertex ; get mlpSrcList[nextVertex] multiply ax,bmData@@mPrecision ; ax by bmData@@mPrecision mov ebx,[ecx].PureEdge@@mxSource ; mxSource to bx register sub eax,ebx ; (ie) mlpSrcList[nextVertex].x-mxSource-->eax divide eax,yDestHeight ; divide by yDestHeight, this is mxSourceStep mov [ecx].PureEdge@@mxSourceStep,eax ; move eax register into mxSourceStep getPoint [ecx].PureEdge@@mlpSrcList,nextVertex ; get source point mov eax,ebx ; move point.y into eax register multiply ax,bmData@@mPrecision ; multiply by precision mov ebx,[ecx].PureEdge@@mySource ; mySource to bx register sub eax,ebx ; (ie) mlpSrcList[nextVertex].y-mySource-->eax divide eax,yDestHeight ; divide by yDestHeight, this is mySourceStep mov [ecx].PureEdge@@mySourceStep,eax ; move eax register into mySourceStep getPoint [ecx].PureEdge@@mlpDstList,startVertex ; get mlpDstList[startVertex] mov [ecx].PureEdge@@mxDestLocation,ax ; mxDestLocation=mDstList[startVertex].x() getPoint [ecx].PureEdge@@mlpDstList,nextVertex ; get dstList[nextVertex] sub ax,[ecx].PureEdge@@mxDestLocation ; get the width of the segment mov xDestWidth,ax ; move the width into xDestWidth cmp xDestWidth,00h ; is the direction negative (ie) left jl @@negWidth ; yes, handle negative direction mov [ecx].PureEdge@@mxDirection,01h ; set right direction indicator mov [ecx].PureEdge@@mxErrorTerm,00h ; set mxErrorTerm to zero movzx eax,xDestWidth ; move xDestWidth to eax zero extend movzx ebx,[ecx].PureEdge@@mRemainingScanLines ; move mRemainingScanLines to ebx divide eax,ebx ; eax=xDestWidth.mRemainingScanLines mov [ecx].PureEdge@@mxStep,ax ; move result into mxStep jmp @@syncOne ; jump over following handler @@negWidth: ; handle negative direction mov [ecx].PureEdge@@mxDirection,-1 ; set left direction indicator neg xDestWidth ; negate the width (ie) make it positive mov ax,01h ; move one into ax register sub ax,[ecx].PureEdge@@mRemainingScanLines ; subtract remaining scan lines from 1 mov [ecx].PureEdge@@mxErrorTerm,ax ; move result to mxErrorTerm movzx eax,xDestWidth ; move xDestWidth to eax zero extend movzx ebx,[ecx].PureEdge@@mRemainingScanLines ; move mRemainingScanLines to ebx divide eax,ebx ; eax=xDestWidth/mRemainingScanLines neg eax ; negate the result mov [ecx].PureEdge@@mxStep,ax ; move result back into mxStep @@syncOne: ; synchronization address mov [ecx].PureEdge@@mxAdjustUp,dx ; move remainder into mxAdjustUp push [ecx].PureEdge@@mRemainingScanLines ; save mRemainingScanLines pop [ecx].PureEdge@@mxAdjustDown ; restore mRemainingScanLines into mxAdjustDown jmp @@ok ; jump over forever loop @@loopNext: ; forever loop address push nextVertex ; save nextVertex on stack pop [ecx].PureEdge@@mStartVertex ; restore into mStartVertex push nextVertex ; save nextVertex on stack pop startVertex ; restore it to local copy of startVertex jmp @@forever ; continue with loop @@error: ; error handler mov eax,0001h ; set ax register to 01h to indicate failure jmp @@return ; jump over to return label @@ok: ; success handler xor eax,eax ; clear out eax register to handle success @@return: ; return label add esp,LocalLength ; remove local variables from stack pop ebp ; restore old stack frame retn ; return near to caller _setupEdge endp _getMinMaxInfo proc near ; long getMinMaxInfo(void) LOCAL yMin:WORD,yMax:WORD=LocalLength push ebp ; save old stack frame mov ebp,esp ; create new stack frame sub esp,LocalLength ; make room for local variables push ecx ; save callers ecx register mov edx,ecx ; move ecx into edx, edx has ptr to PureEdge cmp [edx].PureEdge@@mNumVertexes,MINVERTEX ; make sure have at least 3 vertexes jl @@error ; handle error condition mov yMin,MINVALUE ; start yMin with some low value mov yMax,MAXVALUE ; start yMax with some high value xor ecx,ecx ; start at index zero mov eax,[edx].PureEdge@@mlpDstList ; move address of (Point*) to ebx register @@iterator: ; loop top mov bx,[eax].Point@@y ; move point::y to bx register cmp bx,yMin ; compare with current yMin value jg @@greater ; point::y greater than current yMin @@nexttest: ; if I handle the greater condition, still need to do less cmp bx,yMax ; compare with current yMax value jl @@less ; point::y less than current yMax jmp @@looptest ; nuthin, continue with test @@greater: ; handle greater condition mov yMin,bx ; set yMin to bx register mov [edx].PureEdge@@mMinVertex,cx ; move index number of vertex to mMinVertex jmp @@nexttest ; go perform next test @@less: ; handle less condition mov yMax,bx ; set yMax to bx register mov [edx].PureEdge@@mMaxVertex,cx ; update mMaxVertex with current index @@looptest: ; falls through to loop add eax,04h ; add 4 bytes to eax to address next (Point*) inc cx ; increment cx register cmp cx,[edx].PureEdge@@mNumVertexes ; have we reeached the number of vertexes yet? jl @@iterator ; still more vertexes push [edx].PureEdge@@mMaxVertex ; save mMaxVertex pop [edx].PureEdge@@mStartVertex ; restore it to mStartVertex jmp @@ok ; error return sync address @@error: ; setup for error return code mov eax,0001h ; move 01h into ax to indicate error jmp @@return ; jump to return label @@ok: ; setup for success return code xor eax,eax ; clear out eax register @@return: ; return label pop ecx ; restore callers ecx register add esp,LocalLength ; pop local variables off stack pop ebp ; restore old stack frame retn ; return near to caller _getMinMaxInfo endp _setSrcBitmapInfo proc near ; void setSrcBitmapInfo(WORD width,WORD height,UHUGE *lpBitmapImage) push ebp ; save old stack frame mov ebp,esp ; create new stack frame push eax ; save eax register push ebx ; save ebx register mov ax,word ptr[ebp+08h] ; move width into ax register mov bmData@@mSrcWidth,ax ; move width into bmData@@mSrcWidth mov bx,word ptr[ebp+0Ch] ; move height into bx register mov bmData@@mSrcHeight,bx ; move height into bx register multiply ax,bx ; multiply (width*height) mov bmData@@mSrcExtent,eax ; (width*height) to mSrcExtent push dword ptr[ebp+10h] ; save lpBitmapImage on stack pop bmData@@mlpSrcPtr ; restore in mlpSrcPtr pop ebx ; restore ebx register pop eax ; restore eax register pop ebp ; restore old stack frame retn ; return near to caller _setSrcBitmapInfo endp _setDstBitmapInfo proc near ; void setDstBitmapInfo(WORD width,WORD height,UHUGE *lpBitmapImage) push ebp ; save old stack frame mov ebp,esp ; create new stack frame push eax ; save eax register push ebx ; save ebx register mov ax,word ptr[ebp+08h] ; move width into ax register mov bmData@@mDstWidth,ax ; move width into mDstWidth mov bx,word ptr[ebp+0Ch] ; move height into bx register mov bmData@@mDstHeight,bx ; move height into mDstHeight multiply ax,bx ; multiply (width*height) mov bmData@@mDstExtent,eax ; move (width*height) into mDstExtent push dword ptr[ebp+10h] ; save lpBitmapImage on stack pop bmData@@mlpDstPtr ; restore in mlpDstPtr pop ebx ; restore ebx register pop eax ; restore eax register pop ebp ; restore old stack frame retn ; return near to caller _setDstBitmapInfo endp _setMaskInfo proc near ; void setMaskInfo(WORD useMask,BYTE maskValue) push ebp ; save previous stack frame mov ebp,esp ; create new frame mov eax,[ebp+08h] ; move useMask into eax register mov bmData@@mUseMask,al ; move useMask into bmData@@mUseMask cmp eax,0000h ; check to see if we are using the mask je @@maskEndProc ; if we're not using mask, don't set mask value mov eax,[ebp+0Ch] ; move mask value into eax register mov bmData@@mMaskValue,al ; move mask value into bmData@@mMaskValue @@maskEndProc: ; end procedure sync address pop ebp ; restore previous stack frame retn ; return near to caller _setMaskInfo endp public _mapTexture public _initEdge public _setSrcBitmapInfo public _setDstBitmapInfo public _setMaskInfo end