This commit is contained in:
2024-08-07 09:16:27 -04:00
parent fdfadd5c7e
commit 5f971cf684
5200 changed files with 731717 additions and 0 deletions

589
engine/TMAP16.ASM Normal file
View File

@@ -0,0 +1,589 @@
;*************************************************************************************
; 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