505 lines
35 KiB
NASM
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
|
|
|