589 lines
37 KiB
NASM
589 lines
37 KiB
NASM
;*************************************************************************************
|
||
; MODULE: TMAP16.ASM DATE: DECEMBER 28,1994
|
||
; AUTHOR: SEAN M. KESSLER
|
||
; TARGET: 16 BIT TARGET
|
||
; FUNCTION : TEXTURE MAPPING POLYGONS IN PERSPECTIVE
|
||
;*************************************************************************************
|
||
.MODEL LARGE C
|
||
.386
|
||
.DATA
|
||
bmData@@mSrcWidth DW 00h
|
||
bmData@@mSrcHeight DW 00h
|
||
bmData@@mlpSrcPtr DD 00h
|
||
bmData@@mDstWidth DW 00h
|
||
bmData@@mDstHeight DW 00h
|
||
bmData@@mlpDstPtr DD 00h
|
||
MINVALUE EQU -32767
|
||
MAXVALUE EQU 32767
|
||
MINVERTEX EQU 3
|
||
PRECISION EQU 16384
|
||
.CODE
|
||
LOCALS
|
||
INCLUDE ..\COMMON\COMMON.INC
|
||
INCLUDE ..\ENGINE\TMAP16.INC
|
||
round MACRO varOne
|
||
mov eax,varOne ; move varOne into eax register
|
||
mov ebx,eax ; move varOne into ebx register
|
||
and ebx,00003FFFh ; get remainder into ebx register
|
||
shr eax,14 ; get whole number to eax register
|
||
cmp ebx,8192 ; if remainder > 8192, increment eax
|
||
db 7Eh ; the next 2 bytes comprise "jle +2" (ie)
|
||
db 02h ; jump passed the increment eax instruction
|
||
inc eax ; increment value in eax
|
||
ENDM
|
||
multiply MACRO varOne,varTwo
|
||
push bx ; save bx register
|
||
mov ax,varOne ; move varOne into ax register
|
||
mov bx,varTwo ; move varTwo into bx register
|
||
imul bx ; perform the multiply result to dx:ax
|
||
push ax ; save ax register result
|
||
movzx eax,dx ; move dx register to eax zero extend
|
||
shl eax,16 ; shift eax left by a word
|
||
pop ax ; restore ax register result
|
||
pop bx ; restore bx register
|
||
ENDM
|
||
divide MACRO varOne,varTwo
|
||
push ebx ; save ebx register
|
||
mov ebx,varTwo ; move varTwo into ebx register
|
||
mov eax,varOne ; move varOne into eax register
|
||
cdq ; convert doubleword in eax to quadword at edx:eax
|
||
idiv ebx ; divide eax/ebx result to eax, remainder to edx
|
||
pop ebx ; restore ebx register
|
||
ENDM
|
||
getPoint MACRO segment,offset,index
|
||
push si ; save source index register
|
||
push ds ; save data segment register
|
||
push cx ; save cx register
|
||
push segment ; save segment on stack
|
||
pop ds ; restore to data segment
|
||
mov ax,index ; move index to ax register
|
||
shl ax,02h ; multiply ax by size of far pointer
|
||
mov si,offset ; now move offset address to si
|
||
add si,ax ; add in the increment value
|
||
xor eax,eax ; clear out eax register
|
||
mov ax,ds:[si].Point@@x ; get the x-value to ax register
|
||
xor ebx,ebx ; clear out ebx register
|
||
mov bx,ds:[si].Point@@y ; get the y-value to bx register
|
||
pop cx ; restore saved cx register
|
||
pop ds ; restore saved data segment
|
||
pop si ; restore save source index register
|
||
ENDM
|
||
_initEdge proc far ; void initEdge(short edgeType,PureEdge *lpEdge);
|
||
push bp ; save callers stack frame
|
||
mov bp,sp ; create new stack frame
|
||
push di ; save callers destination index register
|
||
mov es,[bp+10] ; move segment of data to extra segment
|
||
mov di,[bp+8] ; move offset of data to destination index register
|
||
assume es ; now assume extra segment for segment loads.
|
||
call _getMinMaxInfo ; find minimum and maximum vertexes
|
||
cmp ax,00h ; make sure previous call returned success
|
||
jne @@return ; if not then we should leave
|
||
push word ptr[bp+6] ; push edgeType (-1:leftEdge,1:rightEdge)
|
||
push [di].PureEdge@@mStartVertex ; push startVertex
|
||
call _setupEdge ; now setup the edge
|
||
add sp,04h ; readjust the stack
|
||
@@return:
|
||
assume @data ; assume old data segment for segment loads
|
||
pop di ; restore destination index register
|
||
pop bp ; restore callers stack frame
|
||
retf ; return to caller
|
||
_initEdge endp
|
||
_getMinMaxInfo proc near ; short getMinMaxInfo(void)
|
||
LOCAL yMin:WORD,yMax:WORD=LocalLength
|
||
push bp ; save callers stack frame
|
||
mov bp,sp ; create new frame
|
||
sub sp,LocalLength ; adjust stack to handle local variables
|
||
push cx ; save callers cx register
|
||
push si ; save callers source index register
|
||
push ds ; save callers data segment register
|
||
cmp [di].PureEdge@@mNumVertexes,MINVERTEX ; make sure have at least three vertexes
|
||
jl @@error ; otherwise we've got a problem
|
||
mov yMin,MINVALUE ; start yMin with some low value
|
||
mov yMax,MAXVALUE ; start yMax with some high value
|
||
xor cx,cx ; start at index 0
|
||
mov ds,[di].PureEdge@@mlpDstList ; segment address of (Point *) to extra segment register
|
||
mov si,[di].PureEdge@@mlpDstList+2 ; offset address of (Point *) to source index register
|
||
@@iterator: ; loop top
|
||
mov bx,ds:[si].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 equal condition
|
||
mov yMin,bx ; set yMin to bx register
|
||
mov [di].PureEdge@@mMinVertex,cx ; move index number of vertex to mMinVertex
|
||
jmp @@nexttest ; go perform next test
|
||
@@less: ; handle less equal condition
|
||
mov yMax,bx ; set yMax to bx register
|
||
mov [di].PureEdge@@mMaxVertex,cx ; update mMaxVertex with current index
|
||
@@looptest: ; falls through to loop
|
||
add si,04h ; add 2 bytes to si to bump to next (Point*)
|
||
inc cx ; increment cx
|
||
cmp cx,[di].PureEdge@@mNumVertexes ; have we reached the number of vertexes yet?
|
||
jl @@iterator ; still more vertexes
|
||
push [di].PureEdge@@mMaxVertex ; save mMaxVertex
|
||
pop [di].PureEdge@@mStartVertex ; restore it to mStartVertex
|
||
jmp @@ok ; ok we've got good number of vertexes
|
||
@@error: ; setup for error return code
|
||
mov ax,01h ; move 01h into ax to indicate error
|
||
jmp @@return ; jump to return label
|
||
@@ok: ; setup for success return code
|
||
xor ax,ax ; clear out ax register
|
||
@@return: ; return label
|
||
pop ds ; restore callers extra segment register
|
||
pop si ; restore callers source index register
|
||
pop cx ; restore callers cx register
|
||
add sp,LocalLength ; readjust stack for local variables
|
||
pop bp ; restore old frame
|
||
retn ; return to caller
|
||
_getMinMaxInfo endp
|
||
_setupEdge proc near ; short setupEdge(short edgeType,short startVertex)
|
||
LOCAL nextVertex:WORD,xDestWidth:WORD,yDestHeight:DWORD=LocalLength
|
||
push bp ; save old stack frame
|
||
mov bp,sp ; create new stack frame
|
||
sub sp,LocalLength ; make room for local variables
|
||
push si ; save source index register
|
||
push ds ; save data segment register
|
||
push word ptr[bp+6] ; save edgeType on stack
|
||
pop [di].PureEdge@@mEdgeDirection ; restore edgeType to mEdgeDirection
|
||
push word ptr[bp+4] ; save startVertex on stack
|
||
pop [di].PureEdge@@mStartVertex ; restore startVertex to mStartVertex
|
||
@@forever: ; forever loop label
|
||
mov bx,[di].PureEdge@@mStartVertex ; move mStartVertex to bx register
|
||
cmp bx,[di].PureEdge@@mMinVertex ; is mStartVertex same as mMinVertex ??
|
||
je @@error ; if yes then return error status
|
||
add bx,[di].PureEdge@@mEdgeDirection ; add edge direction to mStartVertex
|
||
mov nextVertex,bx ; move result to nextVertex
|
||
mov bx,[di].PureEdge@@mNumVertexes ; move number of vertexes to bx register
|
||
cmp nextVertex,bx ; compare nextVertex to number of vertexes
|
||
jge @@zervert ; nextVertex is greater eq number of vertexes
|
||
cmp nextVertex,00h ; compare nextVertex to zero
|
||
jl @@adjVert ; nextVertex is less than zero
|
||
jmp @@bypass ; nextVertex is fine
|
||
@@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:
|
||
getPoint [di].PureEdge@@mlpDstList,[di].PureEdge@@mlpDstList+2,nextVertex
|
||
push bx ; dstList[nextVertex].y() in bx , save it
|
||
getPoint [di].PureEdge@@mlpDstList,[di].PureEdge@@mlpDstList+2,[di].PureEdge@@mStartVertex
|
||
pop ax ; restore first x-point to ax
|
||
sub ax,bx ; now subtract second x-point
|
||
mov [di].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 [di].PureEdge@@mCurrentEdgeEnd ; restore it to mCurrentEdgeEnd
|
||
getPoint [di].PureEdge@@mlpSrcList+2,[di].PureEdge@@mlpSrcList,[di].PureEdge@@mStartVertex
|
||
multiply ax,PRECISION ; multiply mxSource by PRECISION
|
||
mov [di].PureEdge@@mxSource,eax ; move srcList[mStartVertex].x() to mxSource
|
||
multiply bx,PRECISION ; multiply mySource by PRECISION
|
||
mov [di].PureEdge@@mySource,eax ; move srcList[mStartVertex].y() to mySource
|
||
getPoint [di].PureEdge@@mlpSrcList+2,[di].PureEdge@@mlpSrcList,nextVertex ; get source point
|
||
multiply ax,PRECISION
|
||
mov ebx,[di].PureEdge@@mxSource ; mxSource to bx register
|
||
sub eax,ebx ; (ie) mlpSrcList[nextVertex].x-mxSource-->ax
|
||
divide eax,yDestHeight ; divide by yDestHeight, this is mxSourceStep
|
||
mov [di].PureEdge@@mxSourceStep,eax ; move eax register into mxSourceStep
|
||
getPoint [di].PureEdge@@mlpSrcList+2,[di].PureEdge@@mlpSrcList,nextVertex ; get source point
|
||
mov eax,ebx ; move point.y into ax register
|
||
multiply ax,PRECISION
|
||
mov ebx,[di].PureEdge@@mySource ; mySource to bx register
|
||
sub eax,ebx ; (ie) mlpSrcList[nextVertex].y-mySource-->ax
|
||
divide eax,yDestHeight ; divide by yDestHeight, this is mySourceStep
|
||
mov [di].PureEdge@@mySourceStep,eax ; move eax register into mySourceStep
|
||
getPoint [di].PureEdge@@mlpDstList,[di].PureEdge@@mlpDstList+2,[di].PureEdge@@mStartVertex
|
||
mov [di].PureEdge@@mxDestLocation,ax ; mxDestLocation=mDstList[mStartVertex].x()
|
||
getPoint [di].PureEdge@@mlpDstList,[di].PureEdge@@mlpDstList+2,nextVertex ; get dstList[nextVertex]
|
||
sub ax,[di].PureEdge@@mxDestLocation ; get the width of the segment
|
||
mov xDestWidth,ax ; move width into xDestWidth
|
||
cmp xDestWidth,00h ; is the direction negative (ie) left
|
||
jl @@negWidth ; yes, handle negative direction
|
||
mov [di].PureEdge@@mxDirection,01h ; set right direction indicator
|
||
mov [di].PureEdge@@mxErrorTerm,00h ; set mxErrorTerm to zero
|
||
movzx eax,xDestWidth ; move xDestWidth to eax zero extend
|
||
movzx ebx,[di].PureEdge@@mRemainingScanLines ; move mRemainingScanLines to ebx zero extend
|
||
divide eax,ebx ; eax=xDestWidth/mRemainingScanLines
|
||
mov [di].PureEdge@@mxStep,ax ; move result into mxStep
|
||
jmp @@syncOne ; jump over following handler
|
||
@@negWidth: ; handle negative direction
|
||
mov [di].PureEdge@@mxDirection,-1 ; set left direction indicator
|
||
neg xDestWidth ; negate the width (ie) make it positive
|
||
mov ax,01h ; move a 1 into ax register
|
||
sub ax,[di].PureEdge@@mRemainingScanLines ; subtract remaining scan lines from 1
|
||
mov [di].PureEdge@@mxErrorTerm,ax ; move result to mxErrorTerm
|
||
movzx eax,xDestWidth ; move xDestWidth to eax zero extend
|
||
movzx ebx,[di].PureEdge@@mRemainingScanLines ; move mRemainingScanLines to ebx zero extend
|
||
divide eax,ebx ; eax=xDestWidth/mRemainingScanLines
|
||
neg eax ; negate the result
|
||
mov [di].PureEdge@@mxStep,ax ; move result back into mxStep
|
||
@@syncOne: ; synchronization address
|
||
movzx eax,xDestWidth ; move xDestWidth into eax register, zero extend
|
||
movzx ebx,[di].PureEdge@@mRemainingScanLines ; move mRemainingScanLines into ebx register
|
||
divide eax,ebx ; divide xDestWidth/mRemainingScanLines
|
||
mov [di].PureEdge@@mxAdjustUp,dx ; move remainder into mxAdjustUp
|
||
push [di].PureEdge@@mRemainingScanLines ; save mRemainingScanLines
|
||
pop [di].PureEdge@@mxAdjustDown ; restore mRemainingScanLines into mxAdjustDown
|
||
jmp @@ok ; jump over forever loop
|
||
@@loopNext: ; forever loop address
|
||
push nextVertex ; save nextVertex on stack
|
||
pop [di].PureEdge@@mStartVertex ; restore to mStartVertex
|
||
jmp @@forever ; continue with loop
|
||
@@error: ; error handler
|
||
mov ax,01h ; set ax register to 01h to indicate failure
|
||
jmp @@return ; jump over to return label
|
||
@@ok: ; success handler
|
||
xor ax,ax ; clear out ax register to handle success
|
||
@@return: ; return label
|
||
pop ds ; restore data segment register
|
||
pop si ; restore source index register
|
||
add sp,LocalLength ; readjust stack for local variables
|
||
pop bp ; restore old stack frame
|
||
retn ; return to caller
|
||
_setupEdge endp
|
||
_increment proc near ; short increment(PureEdge *lpEdge)
|
||
push bp ; save callers stack frame
|
||
mov bp,sp ; create new stack frame
|
||
push es ; save extra segment register
|
||
push di ; save destination index register
|
||
mov es,[bp+6] ; move segment of data to extra segment
|
||
mov di,[bp+4] ; move offset of data to destination index register
|
||
assume es ; now assume extra segment for segment loads.
|
||
dec [di].PureEdge@@mRemainingScanLines ; decrement mRemainingScanLines
|
||
cmp [di].PureEdge@@mRemainingScanLines,00h ; compare mRemainingScanLines to zero
|
||
je @@newEdge ; no more scan lines, try to get to next edge
|
||
jmp @@syncOne ; more scan lines, keep going
|
||
@@newEdge: ; new edge handler
|
||
push [di].PureEdge@@mEdgeDirection ; save edgeDirection
|
||
push [di].PureEdge@@mCurrentEdgeEnd ; save currentEdge end (ie) nextEdge index
|
||
call _setupEdge ; attempt to setup new edge
|
||
add sp,04h ; readjust stack
|
||
cmp ax,01h ; did prior call fail?
|
||
je @@error ; yes, no more edges
|
||
jmp @@ok ; no, keep going
|
||
@@syncOne: ; synchronizing address
|
||
mov eax,[di].PureEdge@@mxSourceStep ; get mxSourceStep to eax register
|
||
add eax,[di].PureEdge@@mxSource ; add in mxSource
|
||
mov [di].PureEdge@@mxSource,eax ; replace mxSource with new value
|
||
mov eax,[di].PureEdge@@mySourceStep ; get mySourceStep into eax register
|
||
add eax,[di].PureEdge@@mySource ; add in mySource
|
||
mov [di].PureEdge@@mySource,eax ; replace mySource with new value
|
||
mov ax,[di].PureEdge@@mxDestLocation ; get mxDestLocation into ax register
|
||
add ax,[di].PureEdge@@mxStep ; add in mxStep
|
||
mov [di].PureEdge@@mxDestLocation,ax ; replace mxDestLocation with new value
|
||
mov ax,[di].PureEdge@@mxErrorTerm ; get mxErrorTerm to ax register
|
||
add ax,[di].PureEdge@@mxAdjustUp ; add in mxAdjustUp
|
||
mov [di].PureEdge@@mxErrorTerm,ax ; replace mxErrorTerm with new value
|
||
cmp ax,00h ; now compare result to 00h
|
||
jg @@adjTerm ; result is greater than zero
|
||
jmp @@ok ; result is less equal to zero, we're done
|
||
@@adjTerm:
|
||
mov ax,[di].PureEdge@@mxDestLocation ; get mxDestLocation to ax register
|
||
add ax,[di].PureEdge@@mxDirection ; add in mxDirection
|
||
mov [di].PureEdge@@mxDestLocation,ax ; replace mxDestLocation with new value
|
||
mov ax,[di].PureEdge@@mxErrorTerm ; move mxErrorTerm into ax register
|
||
sub ax,[di].PureEdge@@mxAdjustDown ; add in mxAdjustDown
|
||
mov [di].PureEdge@@mxErrorTerm,ax ; replace mxErrorTerm with new value
|
||
@@ok: ; ok handler address
|
||
xor ax,ax ; set 00h into ax register
|
||
jmp @@return ; jump passed next block
|
||
@@error: ; error handler address
|
||
mov ax,01h ; set 01h into ax register
|
||
@@return: ; return handler
|
||
assume @data ; assume old data segment for segment loads
|
||
pop di ; restore destination index register
|
||
pop es ; restore extra segment register
|
||
pop bp ; restore stack frame
|
||
retn ; return to caller
|
||
_increment endp
|
||
_mapTexture proc far ; void mapTexture(PureMap *lpTextureMap)
|
||
push bp ; save stack frame
|
||
mov bp,sp ; create new frame
|
||
push di ; save destination index register
|
||
push si ; save source index register
|
||
push ds ; save data segment register
|
||
mov es,word ptr[bp+8] ; move segment (PureMap*) to es register
|
||
mov di,word ptr[bp+6] ; move offset (PureMap*) to destination index register
|
||
push es:[di].PureMap@@mlpLeftEdge+2 ; save segment mlpLeftEdge
|
||
pop ds ; restore segment mlpLeftEdge to ds register
|
||
mov si,es:[di].PureMap@@mlpLeftEdge ; move offset mlpLeftEdge to si register
|
||
mov cx,ds:[si].PureEdge@@mMaxVertex ; move left edge max vertex to ax register
|
||
getPoint ds:[si].PureEdge@@mlpDstList,ds:[si].PureEdge@@mlpDstList+2,cx
|
||
mov es:[di].PureMap@@myValue,bx ; myValue=mLeftEdge[mLeftEdge.maxVertex()].y()
|
||
@@forever: ; while(TRUE)
|
||
push es ; push segment (PureMap*)
|
||
push di ; push offset (PureMap*)
|
||
call _scanOutputLine ; call scanOutputLine
|
||
add sp,04h ; readjust stack
|
||
push word ptr es:[di].PureMap@@mlpLeftEdge+2 ; push segment mlpLeftEdge
|
||
push word ptr es:[di].PureMap@@mlpLeftEdge ; push offset mlpLeftEdge
|
||
call _increment ; increment along left edge
|
||
add sp,04h ; readjust stack after call
|
||
cmp ax,00h ; check return code
|
||
jne @@return ; edge failed to increment, we're done
|
||
push word ptr es:[di].PureMap@@mlpRightEdge ; push segment mlpRightEdge
|
||
push word ptr es:[di].PureMap@@mlpRightEdge+2 ; push offset mlpRightEdge
|
||
call _increment ; increment along right edge
|
||
add sp,04h ; readjust stack after call
|
||
cmp ax,00h ; check return code
|
||
jne @@return ; edge failed to increment, we're done
|
||
inc es:[di].PureMap@@myValue ; increment y() position
|
||
jmp @@forever ; loop until all edges are completed
|
||
@@return: ; return address label
|
||
pop ds ; restore data segment register
|
||
pop si ; restore source index re
|
||
pop di ; restore destination index register
|
||
pop bp ; restore old frame
|
||
retf ; return to caller
|
||
_mapTexture endp
|
||
_scanOutputLine proc near
|
||
push bp ; save stack frame
|
||
mov bp,sp ; create new frame
|
||
push es ; save extra segment
|
||
push di ; save destination index register
|
||
push ds ; save data segment register
|
||
push si ; save source index register
|
||
mov es,word ptr[bp+6] ; move segment (PureMap*) to extra segment register
|
||
mov di,word ptr[bp+4] ; move offset (PureMap*) to destination index register
|
||
push es:[di].PureMap@@mlpLeftEdge+2 ; save segment mlpLeftEdge
|
||
pop ds ; restore segment mlpLeftEdge to data segment
|
||
mov si,es:[di].PureMap@@mlpLeftEdge ; move offset mlpLeftEdge to source index reg
|
||
mov eax,ds:[si].PureEdge@@mxSource ; move PureEdge::mxSource to eax register
|
||
mov es:[di].PureMap@@mxSource,eax ; move PureEdge::mxSource to PureMap::mxSource
|
||
mov eax,ds:[si].PureEdge@@mySource ; move PureEdge::mySource to eax register
|
||
mov es:[di].PureMap@@mySource,eax ; move PureEdge::mySource to PureMap::mySource
|
||
mov bx,ds:[si].PureEdge@@mxDestLocation ; move PureEdge::mxDestLocation to bx
|
||
mov es:[di].PureMap@@mxDest,bx ; move PureEdge::mxDestLocation to PureMap::mxDest
|
||
push word ptr es:[di].PureMap@@mlpRightEdge ; save segment mlpRightEdge
|
||
pop ds ; restore segment mlpRightEdge to ds
|
||
mov si,word ptr es:[di].PureMap@@mlpRightEdge+2 ; move offset mlpRightEdge to si
|
||
xor eax,eax ; to clear out the high word of eax
|
||
mov ax,ds:[si].PureEdge@@mxDestLocation ; move PureEdge.mxDestLocation to ax
|
||
mov es:[di].PureMap@@mxDestMax,ax ; move PureEdge.mxDestLocation to PureMap.mxDestMap
|
||
sub ax,bx ; mxDestMax-mxDest
|
||
cmp ax,00h ; check if width is zero
|
||
je @@return ; if width is zero just return
|
||
mov es:[di].PureMap@@mDestWidth,eax ; move width into PureMap::mDestWidth
|
||
mov eax,ds:[si].PureEdge@@mxSource ; move PureEdge::mxSource into eax
|
||
sub eax,es:[di].PureMap@@mxSource ; subtract out PureMap::mxSource
|
||
divide eax,es:[di].PureMap@@mDestWidth ; now divide by PureMap::mDestWidth
|
||
mov es:[di].PureMap@@mxSourceStep,eax ; move new value to PureMap@@mxSourceStep
|
||
mov eax,ds:[si].PureEdge@@mySource ; move PureEdge::mySource into eax
|
||
sub eax,es:[di].PureMap@@mySource ; subtract out PureMap::mySource
|
||
divide eax,es:[di].PureMap@@mDestWidth ; now divide by PureMap::mDestWidth
|
||
mov es:[di].PureMap@@mySourceStep,eax ; move new value to PureMap@@mySourceStep
|
||
@@xLoop: ; xLoop top
|
||
mov ax,es:[di].PureMap@@mxDest ; move mxDest to ax register
|
||
cmp ax,es:[di].PureMap@@mxDestMax ; compare mxDest to mxDestMax
|
||
jge @@return ; if its greater equal return
|
||
cmp es:[di].PureMap@@mxSource,00h ; compare mxSource to zero
|
||
jl @@xFix ; if mxSource is less than zero, fix
|
||
@@nxtChk: ; sync label to continue with checking
|
||
cmp es:[di].PureMap@@mySource,00h ; compare mySource to zero
|
||
jl @@yFix ; if mySource is less than zero, fix
|
||
jmp @@syncOne ; everything ok, jump over block
|
||
@@yFix: ; handle y-fixup
|
||
mov es:[di].PureMap@@mySource,00h ; move zero to mySource
|
||
jmp @@syncOne ; jump around next handler
|
||
@@xFix: ; handle x-fixup
|
||
mov es:[di].PureMap@@mxSource,00h ; move zero into mxSource
|
||
jmp @@nxtChk ; now look at y-value
|
||
@@syncOne: ; synchronization for conditionals
|
||
push es ; save extra segment register
|
||
mov eax,es:[di].PureMap@@mySource ; move PureMap@@mxSource to eax
|
||
round eax ; convert and round
|
||
push ax ; save result on stack
|
||
mov eax,es:[di].PureMap@@mxSource ; move PureMap@@mySource to eax
|
||
round eax ; convert and round
|
||
shl eax,16 ; now shift eax left by 16 bits
|
||
pop ax ; and restore yValue to low word
|
||
movzx ebx,es:[di].PureMap@@mxDest ; move PureMap::mxDest to eax
|
||
shl ebx,16 ; shift eax left 16 bits
|
||
mov bx,es:[di].PureMap@@myValue ; move PureMap::myValue to ax
|
||
call _putImageBits ; call put pixel handler
|
||
pop es ; restore extra segment register
|
||
mov eax,es:[di].PureMap@@mxSource ; move mxSource to eax register
|
||
add eax,es:[di].PureMap@@mxSourceStep ; add in mxSourceStep
|
||
mov es:[di].PureMap@@mxSource,eax ; move result to mxSource
|
||
mov eax,es:[di].PureMap@@mySource ; move mySource into eax register
|
||
add eax,es:[di].PureMap@@mySourceStep ; add in mySourceStep
|
||
mov es:[di].PureMap@@mySource,eax ; move result to mySource
|
||
inc es:[di].PureMap@@mxDest ; increment loop counter
|
||
jmp @@xLoop ; loop through xLoop
|
||
@@return: ; return sync label
|
||
pop si ; restore source index register
|
||
pop ds ; restore data segment register
|
||
pop di ; restore destination index register
|
||
pop es ; restore extra segment
|
||
pop bp ; restore old stack frame
|
||
retn ; return to caller
|
||
_scanOutputLine endp
|
||
_getSrcDataByte proc near ; BYTE getSrcDataByte(WORD row,WORD col)
|
||
LOCAL addValue:DWORD=LocalLength
|
||
push bp ; save old stack frame
|
||
mov bp,sp ; create new stack frame
|
||
sub sp,LocalLength ; adjust stack for local variable
|
||
push bx ; save bx register
|
||
push cx ; save cx register
|
||
push dx ; save dx register
|
||
push es ; save extra segment register
|
||
push di ; save destination index register
|
||
mov dx,word ptr[bp+04h] ; move row into dx register
|
||
cmp dx,bmData@@mSrcHeight ; is row greater than bitmap height
|
||
jge @@error ; if so then return
|
||
cmp dx,00h ; is row less than zero
|
||
jl @@error ; if so then return error
|
||
movzx ebx,word ptr[bp+06h] ; move col into bx register, zero extended
|
||
cmp bx,bmData@@mSrcWidth ; is col greater than bitmap width
|
||
jge @@error ; if so then return
|
||
cmp bx,00h ; is col less than zero
|
||
jl @@error ; is so then return error
|
||
movzx ecx,bmData@@mSrcWidth ; move width into cx register
|
||
mov ax,bmData@@mSrcHeight ; move height into ax register
|
||
push dx ; save dx register
|
||
multiply ax,cx ; multiply width*height result to eax
|
||
pop dx ; restore dx register
|
||
mov addValue,eax ; store result to addValue
|
||
multiply dx,cx ; multiply row*width result to eax
|
||
add eax,ecx ; add (row*width)+width
|
||
sub addValue,eax ; calculate addValue-subValue
|
||
movzx eax,word ptr[bp+06h] ; move col into bx register, zero extended
|
||
add addValue,eax ; now add the column number back in
|
||
mov dx,word ptr addValue+02h ; move high word addValue to dx register
|
||
mov ax,word ptr addValue ; move low word addValue to ax register
|
||
add ax,word ptr bmData@@mlpSrcPtr ; add low word mlpSrcPtr to low word addValue
|
||
adc dx,0000h ; add any carry to high word addValue (dx)
|
||
shl dx,03h ; multiply dx register by 8 (segment magic)
|
||
add dx,word ptr bmData@@mlpSrcPtr+02h ; now add in high word of mlpSrcData
|
||
mov es,dx ; move segment into extra segment register
|
||
mov di,ax ; move offset into destination index register
|
||
xor ax,ax ; clear out ax register
|
||
mov al,byte ptr es:[di] ; move byte value into al register
|
||
jmp @@return ; jump over error return code
|
||
@@error: ; error return label
|
||
mov ax,0FF00h ; error places 0FFh in al register
|
||
@@return: ; normal return label
|
||
pop di ; restore destination index register
|
||
pop es ; restore extra segment register
|
||
pop dx ; restore dx register
|
||
pop cx ; restore cx register
|
||
pop bx ; restore bx register
|
||
add sp,LocalLength ; adjust stack for local variable
|
||
pop bp ; restore stack frame
|
||
retn ; return near to caller
|
||
_getSrcDataByte endp
|
||
_setDstDataByte proc near ; void setDstDataByte(WORD row,WORD col,BYTE byteValue)
|
||
LOCAL addValue:DWORD=LocalLength
|
||
push bp ; save old stack frame
|
||
mov bp,sp ; create new stack frame
|
||
sub sp,LocalLength ; adjust stack for local variable
|
||
push ax ; save ax register
|
||
push bx ; save bx register
|
||
push cx ; save cx register
|
||
push dx ; save dx register
|
||
push es ; save extra segment register
|
||
push di ; save destination index register
|
||
mov dx,word ptr[bp+04h] ; move row into dx register
|
||
cmp dx,bmData@@mDstHeight ; is row greater than bitmap height
|
||
jge @@error ; if so then return
|
||
cmp dx,00h ; is row less than zero
|
||
jl @@error ; if so then return error
|
||
movzx ebx,word ptr[bp+06h] ; move col into bx register, zero extended
|
||
cmp bx,bmData@@mDstWidth ; is col greater than bitmap width
|
||
jge @@error ; if so then return
|
||
cmp bx,00h ; is col less than zero
|
||
jl @@error ; if so then return error
|
||
movzx ecx,bmData@@mDstWidth ; move width into cx register
|
||
mov ax,bmData@@mDstHeight ; move height into ax register
|
||
push dx ; save dx register
|
||
multiply ax,cx ; multiply width*height result to eax
|
||
pop dx ; restore dx register
|
||
mov addValue,eax ; store result to addValue
|
||
multiply dx,cx ; multiply row*width result to eax
|
||
add eax,ecx ; add (row*width)+width
|
||
sub addValue,eax ; calculate addValue-subValue
|
||
movzx eax,word ptr[bp+06h] ; move col into bx register, zero extended
|
||
add addValue,eax ; now add the column number back in
|
||
mov dx,word ptr addValue+02h ; move high word addValue to dx register
|
||
mov ax,word ptr addValue ; move low word addValue to ax register
|
||
add ax,word ptr bmData@@mlpDstPtr ; add low word mlpSrcPtr to low word addValue
|
||
adc dx,0000h ; add any carry to high word addValue (dx)
|
||
shl dx,03h ; multiply dx register by 8 (segment magic)
|
||
add dx,word ptr bmData@@mlpDstPtr+02h ; now add in high word of mlpSrcData
|
||
mov es,dx ; move segment into extra segment register
|
||
mov di,ax ; move offset into destination index register
|
||
mov ax,word ptr[bp+08h] ; move byteValue into ax register
|
||
mov byte ptr es:[di],al ; move byte value into mlpDstPtr
|
||
jmp @@return ; jump over error return code
|
||
@@error: ; error return label
|
||
mov ax,0FF00h ; error places 0FFh in al register
|
||
jmp @@return ; return
|
||
@@return: ; normal return label
|
||
pop di ; restore destination index register
|
||
pop es ; restore extra segment register
|
||
pop dx ; restore dx register
|
||
pop cx ; restore cx register
|
||
pop bx ; restore bx register
|
||
pop ax ; restore ax register
|
||
add sp,LocalLength ; adjust stack for local variable
|
||
pop bp ; restore stack frame
|
||
retn ; return near to caller
|
||
_setDstDataByte endp
|
||
_putImageBits proc near ; void putImageBits(eax dstPoints,ebx srcPoints)
|
||
mov cx,ax ; move low word eax to cx register
|
||
shr eax,16 ; move high word eax to ax
|
||
push ebx ; save ebx register
|
||
push ax ; save high word on stack
|
||
push cx ; save low word on stack
|
||
call _getSrcDataByte ; get source data byte result is in al
|
||
add sp,04h ; caller adjusts stack after return
|
||
pop ebx ; restore ebx register
|
||
cmp ah,0FFh ; check return code
|
||
je @@return ; if al==0xFFh call failed
|
||
push ax ; push data byte
|
||
mov cx,bx ; move low word destination to cx register
|
||
shr ebx,16 ; move high word destination to bx
|
||
push bx ; save high word on stack
|
||
push cx ; save low word on stack
|
||
call _setDstDataByte ; set destination data byte
|
||
add sp,06h ; caller adjusts stack after return
|
||
@@return: ; return label
|
||
retn ; return near to caller
|
||
_putImageBits endp
|
||
_setSrcBitmapInfo proc far ; void setSrcBitmapInfo(WORD width,WORD height,UHUGE *lpBitmapImage)
|
||
push bp ; save old stack frame
|
||
mov bp,sp ; create new stack frame
|
||
push dword ptr[bp+0Ah] ; push lpBitmapImage onto stack
|
||
pop bmData@@mlpSrcPtr ; resore into mlpSrcPtr
|
||
push word ptr[bp+08h] ; push srcBitmapHeight onto stack
|
||
pop bmData@@mSrcHeight ; restore into mSrcHeight
|
||
push word ptr[bp+06h] ; push srcBitmapWidth
|
||
pop bmData@@mSrcWidth ; restore into mSrcWidth
|
||
pop bp ; restore old stack frame
|
||
retf ; return far to caller
|
||
_setSrcBitmapInfo endp
|
||
_setDstBitmapInfo proc far ; void setSrcBitmapInfo(WORD width,WORD height,UHUGE *lpBitmapImage)
|
||
push bp ; save old stack frame
|
||
mov bp,sp ; create new stack frame
|
||
push dword ptr[bp+0Ah] ; push lpBitmapImage onto stack
|
||
pop bmData@@mlpDstPtr ; resore into mlpSrcPtr
|
||
push word ptr[bp+08h] ; push srcBitmapHeight onto stack
|
||
pop bmData@@mDstHeight ; restore into mSrcHeight
|
||
push word ptr[bp+06h] ; push srcBitmapWidth
|
||
pop bmData@@mDstWidth ; restore into mSrcWidth
|
||
pop bp ; restore old stack frame
|
||
retf ; return far to caller
|
||
_setDstBitmapInfo endp
|
||
public _initEdge
|
||
public _mapTexture
|
||
public _setSrcBitmapInfo
|
||
public _setDstBitmapInfo
|
||
end
|
||
|
||
|