Initial
This commit is contained in:
504
engine/Tmap32.asm
Normal file
504
engine/Tmap32.asm
Normal file
@@ -0,0 +1,504 @@
|
||||
;*************************************************************************************
|
||||
; 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
|
||||
|
||||
Reference in New Issue
Block a user