Files
Work/engine/Tmap32.asm
2024-08-07 09:16:27 -04:00

505 lines
35 KiB
NASM

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