333 lines
20 KiB
Plaintext
333 lines
20 KiB
Plaintext
;********************************************************************************************************
|
|
; MODULE: TRIMAP32.ASM DATE: FEBRUARY 11, 1999
|
|
; AUTHOR: SEAN M. KESSLER
|
|
; TARGET: 32 BIT TARGET
|
|
; FUNCTION : TEXTURE MAPPING TRIANGLES
|
|
;********************************************************************************************************
|
|
SMART
|
|
.386
|
|
.MODEL FLAT
|
|
.DATA
|
|
bmData@@mSrcWidth DD ?
|
|
bmData@@mSrcHeight DD ?
|
|
bmData@@mSrcExtent DD ?
|
|
bmData@@mlpSrcPtr DD ?
|
|
bmData@@mDstWidth DD ?
|
|
bmData@@mDstPitch DD ?
|
|
bmData@@mDstHeight DD ?
|
|
bmData@@mDstExtent DD ?
|
|
bmData@@mlpDstPtr DD ?
|
|
bmData@@mlpDstIndexPtr DD ?
|
|
.LALL
|
|
INCLUDE ..\COMMON\COMMON.INC
|
|
INCLUDE ..\DDRAW\TRIMAP32.INC
|
|
INCLUDE ..\DDRAW\UTIL32.INC
|
|
.CODE
|
|
|
|
roundEAX MACRO
|
|
LOCAL @@return
|
|
mov edx,eax ; copy eax to edx
|
|
and edx,7FFh ; get remainder to edx register
|
|
shr eax,0Bh ; get whole number to eax register
|
|
cmp edx,400h ; if remainder>1024 then increment eax
|
|
jle @@return ; ... otherwise return
|
|
inc eax ; increment value in eax
|
|
@@return:
|
|
ENDM
|
|
|
|
scanline MACRO
|
|
mov ecx,[esi].DirectTriEdge@@mxRight ; move mxRight into ecx
|
|
sub ecx,[esi].DirectTriEdge@@mxLeft ; subtract out mxLeft, this is dx
|
|
cmp ecx,0000h ; compare dx to zero
|
|
je @@scanlineLoopEnd ; if dx is zero then don't scan the line
|
|
mov eax,[esi].DirectTriEdge@@muRight ; move muRight into eax
|
|
sub eax,[esi].DirectTriEdge@@muLeft ; subtract out muLeft
|
|
shl eax,0Bh ; multiply this by 2048
|
|
divide eax,ecx ; divide by dx, this is du
|
|
mov du,eax ; store du into local variable
|
|
mov eax,[esi].DirectTriEdge@@mvRight ; move mvRight into eax
|
|
sub eax,[esi].DirectTriEdge@@mvLeft ; subtract out mvLeft
|
|
shl eax,0Bh ; multiply this by 2048
|
|
divide eax,ecx ; divide by dx, this is dv
|
|
mov dv,eax ; store dv into local variable
|
|
mov eax,[esi].DirectTriEdge@@muLeft ; move muLeft into eax
|
|
mov ui,eax ; muLeft is initial value for ui
|
|
mov eax,[esi].DirectTriEdge@@mvLeft ; move mvLeft into eax
|
|
mov vi,eax ; mvLeft is initial value for vi
|
|
mov eax,[esi].DirectTriEdge@@mxLeft ; move mxLeft into eax
|
|
mov x,eax ; mxLeft is initial value for x
|
|
@@scanlineLoop: ; scanline loop sync address
|
|
mov eax,[esi].DirectTriEdge@@mxRight ; move mxRight into eax
|
|
cmp x,eax ; compare x to mxRight
|
|
jg @@scanlineLoopEnd ; if x>mxRight then we're done with the scanline
|
|
getSrcDataByte ; get source byte at [ui][vi] to cl register
|
|
setDstDataByte ; set destination byte at [x][y],cl
|
|
incrementScan ; advance along the scanline
|
|
jmp @@scanlineLoop ; continue execution
|
|
@@scanlineLoopEnd: ; end scanline sync address
|
|
ENDM
|
|
|
|
incrementScan MACRO ; advance along the scanline
|
|
mov eax,ui ; move ui to eax
|
|
shl eax,0Bh ; multiply by 2048
|
|
add eax,du ; add in du
|
|
shr eax,0Bh ; divide by 2048
|
|
mov ui,eax ; update ui
|
|
mov eax,vi ; move vi to eax
|
|
shl eax,0Bh ; multiply by 2048
|
|
add eax,dv ; add in dv
|
|
shr eax,0Bh ; divide by 2048
|
|
mov vi,eax ; update vi
|
|
inc x ; increment x
|
|
ENDM
|
|
|
|
increment MACRO
|
|
mov eax,[esi].DirectTriEdge@@mxLeft ; move mxLeft into eax
|
|
shl eax,0Bh ; multiply by 2048
|
|
add eax,[esi].DirectTriEdge@@mDXLeft ; add in the delta
|
|
roundEAX ; adjust and round the value
|
|
mov [esi].DirectTriEdge@@mxLeft,eax ; this is new mxLeft
|
|
mov eax,[esi].DirectTriEdge@@mxRight ; move mxRight into eax
|
|
shl eax,0Bh ; multiply by 2048
|
|
add eax,[esi].DirectTriEdge@@mDXRight ; add in the delta
|
|
roundEAX ; adjust and round the value
|
|
mov [esi].DirectTriEdge@@mxRight,eax ; this is new mxRight
|
|
mov eax,[esi].DirectTriEdge@@muLeft ; move muLeft into eax
|
|
shl eax,0Bh ; multiply by 2048
|
|
add eax,[esi].DirectTriEdge@@mDULeft ; add in the delta
|
|
roundEAX ; adjust and round the value
|
|
mov [esi].DirectTriEdge@@muLeft,eax ; this is new muLeft
|
|
mov eax,[esi].DirectTriEdge@@muRight ; move muRight into eax
|
|
shl eax,0Bh ; multiply by 2048
|
|
add eax,[esi].DirectTriEdge@@mDURight ; add in the delta
|
|
roundEAX ; adjust and round the value
|
|
mov [esi].DirectTriEdge@@muRight,eax ; this is new muRight
|
|
mov eax,[esi].DirectTriEdge@@mvLeft ; move mvLeft into eax
|
|
shl eax,0Bh ; multiply by 2048
|
|
add eax,[esi].DirectTriEdge@@mDVLeft ; add in the delta
|
|
roundEAX ; adjust and round the value
|
|
mov [esi].DirectTriEdge@@mvLeft,eax ; this is new mvLeft
|
|
mov eax,[esi].DirectTriEdge@@mvRight ; move mvRight into eax
|
|
shl eax,0Bh ; multiply by 2048
|
|
add eax,[esi].DirectTriEdge@@mDVRight ; add in the delta
|
|
roundEAX ; adjust and round the value
|
|
mov [esi].DirectTriEdge@@mvRight,eax ; this is new mvRight
|
|
inc y ; increment y
|
|
ENDM
|
|
|
|
initialize MACRO
|
|
mov eax,[esi].DirectTriEdge@@my2 ; move my2 into eax
|
|
sub eax,[esi].DirectTriEdge@@my0 ; eax has (y2-y0)
|
|
mov [esi].DirectTriEdge@@mDY,eax ; move (y2-y0) into mDY variable
|
|
mov eax,[esi].DirectTriEdge@@mx2 ; move x2 into eax
|
|
sub eax,[esi].DirectTriEdge@@mx0 ; eax has (x2-x0)
|
|
shl eax,0Bh ; multiply result by 2048 for precision
|
|
divide eax,[esi].DirectTriEdge@@mDY ; eax has (x2-x0)/(y2-y0)
|
|
mov [esi].DirectTriEdge@@mDXLeft,eax ; this is mDXLeft
|
|
mov eax,[esi].DirectTriEdge@@mx1 ; move x1 into eax
|
|
sub eax,[esi].DirectTriEdge@@mx0 ; eax has (x1-x0)
|
|
shl eax,0Bh ; multiply result by 2048 for precision
|
|
divide eax,[esi].DirectTriEdge@@mDY ; eax has (x1-x0)/(y2-y0)
|
|
mov [esi].DirectTriEdge@@mDXRight,eax ; this is mDXRight
|
|
mov eax,[esi].DirectTriEdge@@mu2 ; move u2 into eax
|
|
sub eax,[esi].DirectTriEdge@@mu0 ; eax has (u2-u0)
|
|
shl eax,0Bh ; multiply result by 2048 for precision
|
|
divide eax,[esi].DirectTriEdge@@mDY ; eax has (u2-u0)/(y2-y0)
|
|
mov [esi].DirectTriEdge@@mDULeft,eax ; this is mDULeft
|
|
mov eax,[esi].DirectTriEdge@@mu1 ; move u1 into eax
|
|
sub eax,[esi].DirectTriEdge@@mu0 ; eax has (u1-u0)
|
|
shl eax,0Bh ; multiply result by 2048 for precision
|
|
divide eax,[esi].DirectTriEdge@@mDY ; eax has (u1-u0)/(y2-y0)
|
|
mov [esi].DirectTriEdge@@mDURight,eax ; this is mDURight
|
|
mov eax,[esi].DirectTriEdge@@mv2 ; move v2 into eax
|
|
sub eax,[esi].DirectTriEdge@@mv0 ; eax has (v2-v0)
|
|
shl eax,0Bh ; multiply result by 2048 for precision
|
|
divide eax,[esi].DirectTriEdge@@mDY ; eax has (v2-v0)/(y2-y0)
|
|
mov [esi].DirectTriEdge@@mDVLeft,eax ; this is mDVLeft
|
|
mov eax,[esi].DirectTriEdge@@mv1 ; move v1 into eax
|
|
sub eax,[esi].DirectTriEdge@@mv0 ; eax has (v1-v0)
|
|
shl eax,0Bh ; multiply result by 2048 for precision
|
|
divide eax,[esi].DirectTriEdge@@mDY ; eax has (v1-v0)/(y2-y0)
|
|
mov [esi].DirectTriEdge@@mDVRight,eax ; this is mDVRight
|
|
mov eax,[esi].DirectTriEdge@@mx0 ; move x0 into eax
|
|
mov [esi].DirectTriEdge@@mxLeft,eax ; mxLeft=x0
|
|
mov [esi].DirectTriEdge@@mxRight,eax ; mxRight=x0
|
|
mov eax,[esi].DirectTriEdge@@mu0 ; move u0 into eax
|
|
mov [esi].DirectTriEdge@@muLeft,eax ; muLeft=u0
|
|
mov [esi].DirectTriEdge@@muRight,eax ; muRight=u0
|
|
mov eax,[esi].DirectTriEdge@@mv0 ; move v0 into eax
|
|
mov [esi].DirectTriEdge@@mvLeft,eax ; mvLeft=v0
|
|
mov [esi].DirectTriEdge@@mvRight,eax ; mvRight=v0
|
|
ENDM
|
|
|
|
if 0
|
|
initialize MACRO
|
|
mov eax,[esi].DirectTriEdge@@my2 ; move my2 into eax
|
|
sub eax,[esi].DirectTriEdge@@my0 ; eax has (y2-y0)
|
|
mov [esi].DirectTriEdge@@mDY,eax ; move (y2-y0) into mDY variable
|
|
mov eax,[esi].DirectTriEdge@@mx2 ; move x2 into eax
|
|
sub eax,[esi].DirectTriEdge@@mx0 ; eax has (x2-x0)
|
|
shl eax,0Bh ; multiply result by 2048 for precision
|
|
divide eax,[esi].DirectTriEdge@@mDY ; eax has (x2-x0)/(y2-y0)
|
|
mov [esi].DirectTriEdge@@mDXLeft,eax ; this is mDXLeft
|
|
mov eax,[esi].DirectTriEdge@@mx1 ; move x1 into eax
|
|
sub eax,[esi].DirectTriEdge@@mx0 ; eax has (x1-x0)
|
|
shl eax,0Bh ; multiply result by 2048 for precision
|
|
divide eax,[esi].DirectTriEdge@@mDY ; eax has (x1-x0)/(y2-y0)
|
|
mov [esi].DirectTriEdge@@mDXRight,eax ; this is mDXRight
|
|
mov eax,[esi].DirectTriEdge@@mu2 ; move u2 into eax
|
|
sub eax,[esi].DirectTriEdge@@mu0 ; eax has (u2-u0)
|
|
shl eax,0Bh ; multiply result by 2048 for precision
|
|
divide eax,[esi].DirectTriEdge@@mDY ; eax has (u2-u0)/(y2-y0)
|
|
mov [esi].DirectTriEdge@@mDULeft,eax ; this is mDULeft
|
|
mov eax,[esi].DirectTriEdge@@mu1 ; move u1 into eax
|
|
sub eax,[esi].DirectTriEdge@@mu0 ; eax has (u1-u0)
|
|
shl eax,0Bh ; multiply result by 2048 for precision
|
|
divide eax,[esi].DirectTriEdge@@mDY ; eax has (u1-u0)/(y2-y0)
|
|
mov [esi].DirectTriEdge@@mDURight,eax ; this is mDURight
|
|
mov eax,[esi].DirectTriEdge@@mv2 ; move v2 into eax
|
|
sub eax,[esi].DirectTriEdge@@mv0 ; eax has (v2-v0)
|
|
shl eax,0Bh ; multiply result by 2048 for precision
|
|
divide eax,[esi].DirectTriEdge@@mDY ; eax has (v2-v0)/(y2-y0)
|
|
mov [esi].DirectTriEdge@@mDVLeft,eax ; this is mDVLeft
|
|
mov eax,[esi].DirectTriEdge@@mv1 ; move v1 into eax
|
|
sub eax,[esi].DirectTriEdge@@mv0 ; eax has (v1-v0)
|
|
shl eax,0Bh ; multiply result by 2048 for precision
|
|
divide eax,[esi].DirectTriEdge@@mDY ; eax has (v1-v0)/(y2-y0)
|
|
mov [esi].DirectTriEdge@@mDVRight,eax ; this is mDVRight
|
|
mov eax,[esi].DirectTriEdge@@mx0 ; move x0 into eax
|
|
mov [esi].DirectTriEdge@@mxLeft,eax ; mxLeft=x0
|
|
mov [esi].DirectTriEdge@@mxRight,eax ; mxRight=x0
|
|
mov eax,[esi].DirectTriEdge@@mu0 ; move u0 into eax
|
|
mov [esi].DirectTriEdge@@muLeft,eax ; muLeft=u0
|
|
mov [esi].DirectTriEdge@@muRight,eax ; muRight=u0
|
|
mov eax,[esi].DirectTriEdge@@mv0 ; move v0 into eax
|
|
mov [esi].DirectTriEdge@@mvLeft,eax ; mvLeft=v0
|
|
mov [esi].DirectTriEdge@@mvRight,eax ; mvRight=v0
|
|
ENDM
|
|
endif
|
|
|
|
|
|
getSrcDataByte MACRO ; BYTE getSrcDataByte (ui,vi)
|
|
LOCAL @@continue
|
|
mov ebx,vi ; move column into ebx
|
|
cmp ebx,bmData@@mSrcWidth ; compare column to width
|
|
jge @@continue ; if column greater than width, return
|
|
mov eax,ui ; move row into eax
|
|
cmp eax,bmData@@mSrcHeight ; compare row to height
|
|
jge @@continue ; if row greater than height, return
|
|
imul eax,bmData@@mSrcWidth ; multiply (row*width)->eax
|
|
add eax,bmData@@mSrcWidth ; add in the width
|
|
mov edx,bmData@@mSrcExtent ; move bitmap extent to edx
|
|
sub edx,eax ; subtract (row*width)+width from extent
|
|
add edx,vi ; now add in the column
|
|
mov ebx,bmData@@mlpSrcPtr ; move bitmap pointer into ebx
|
|
mov cl,byte ptr[ebx+edx] ; set the byte
|
|
@@continue:
|
|
ENDM
|
|
if 0
|
|
setDstDataByte MACRO ; setDstDataByte x,y,cl
|
|
mov ebx,y ; move column into ebx
|
|
cmp ebx,bmData@@mDstWidth ; compare column to width
|
|
jge @@continue ; if column greater than width, return
|
|
mov eax,x ; move row into eax
|
|
cmp eax,bmData@@mDstHeight ; compare row to height
|
|
jge @@continue ; if row greater than height, return
|
|
imul eax,bmData@@mDstWidth ; multiply (row*width)->eax
|
|
add eax,bmData@@mDstWidth ; add in the width
|
|
mov edx,bmData@@mDstExtent ; move bitmap extent to edx
|
|
sub edx,eax ; subtract (row*width)+width from extent
|
|
add edx,y ; now add in the column
|
|
mov ebx,bmData@@mlpDstPtr ; move bitmap pointer into ebx
|
|
mov byte ptr[ebx+edx],cl ; set the byte
|
|
@@continue:
|
|
ENDM
|
|
endif
|
|
|
|
setDstDataByte MACRO ; setDstDataByte x,y,cl
|
|
mov ebx,x ; move column into ebx
|
|
cmp ebx,bmData@@mDstWidth ; compare column to width
|
|
jge @@continue ; if column greater than width, return
|
|
mov eax,y ; move row into eax
|
|
cmp eax,bmData@@mDstHeight ; compare row to height
|
|
jge @@continue ; if row greater than height, return
|
|
imul eax,bmData@@mDstWidth ; multiply (row*width)->eax
|
|
add eax,bmData@@mDstWidth ; add in the width
|
|
mov edx,bmData@@mDstExtent ; move bitmap extent to edx
|
|
sub edx,eax ; subtract (row*width)+width from extent
|
|
add edx,x ; now add in the column
|
|
mov ebx,bmData@@mlpDstPtr ; move bitmap pointer into ebx
|
|
mov byte ptr[ebx+edx],cl ; set the byte
|
|
@@continue:
|
|
ENDM
|
|
|
|
|
|
|
|
_directTriSetSrcBitmapInfo 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 eax,dword ptr[ebp+08h] ; move width into eax register
|
|
mov bmData@@mSrcWidth,eax ; move width into bmData@@mSrcWidth
|
|
mov ebx,dword ptr[ebp+0Ch] ; move height into ebx register
|
|
mov bmData@@mSrcHeight,ebx ; move height into ebx register
|
|
imul eax,ebx ; multiply width*height, result to eax
|
|
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
|
|
_directTriSetSrcBitmapInfo endp
|
|
_directTriSetDstBitmapInfo proc near ; void setDstBitmapInfo(WORD width,WORD height,WORD pitch,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 eax,dword ptr[ebp+10h] ; move pitch into eax register
|
|
mov bmData@@mDstPitch,eax ; move pitch into mDstPitch
|
|
mov eax,dword ptr[ebp+08h] ; move width into eeax register
|
|
mov bmData@@mDstWidth,eax ; move width into mDstWidth
|
|
mov ebx,dword ptr[ebp+0Ch] ; move height into ebx register
|
|
mov bmData@@mDstHeight,ebx ; move height into mDstHeight
|
|
imul eax,ebx ; multiply width*height, result to eax
|
|
mov bmData@@mDstExtent,eax ; move (width*height) into mDstExtent
|
|
push dword ptr[ebp+14h] ; 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
|
|
_directTriSetDstBitmapInfo endp
|
|
|
|
_directTriMapTexture proc near ; void directTriMapTexture(DirectTriEdge *pEdge)
|
|
LOCAL y:DWORD,x:DWORD,du:DWORD,dv:DWORD,ui:DWORD,vi:DWORD=LocalLength ; local variables for proc
|
|
push ebp ; save prior stack frame
|
|
mov ebp,esp ; create new frame
|
|
sub esp,LocalLength ; make room for local variables
|
|
pushad ; save all general purpose registers
|
|
mov esi,[ebp+08h] ; move pEdge to esi register
|
|
initialize ; initialize the edge
|
|
mov eax,[esi].DirectTriEdge@@my0 ; move y0 into eax
|
|
mov y,eax ; initialize y with y0
|
|
@@verticalLoop: ; beginning of vertical loop
|
|
mov ecx,[esi].DirectTriEdge@@my1 ; move y1 into ecx
|
|
cmp y,ecx ; compare y to y1
|
|
jg @@verticalLoopEnd ; if y>y1 then we're done
|
|
scanline ; perform scanline on the horizontal
|
|
increment ; increment along the vertical
|
|
jmp @@verticalLoop ; continue execution
|
|
@@verticalLoopEnd: ; end loop sync address
|
|
popad ; restore all general purpose registers
|
|
add esp,LocalLength ; remove local variables from frame
|
|
pop ebp ; restore prior stack frame
|
|
retn ; return near to caller
|
|
_directTriMapTexture endp
|
|
|
|
public _directTriSetSrcBitmapInfo
|
|
public _directTriSetDstBitmapInfo
|
|
public _directTriMapTexture
|
|
END
|