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