;REM.
;REM. ****************|******************************************************************************
;REM. * | *
;REM. * Routine | (24) Plot *
;REM. * | *
;REM. * Purpose | Plots a raw 32bpp bitmap (or 'sprite') *
;REM. * | *
;REM. * Entry params | dispVars, bmAddr, bmW, bmH, bmX, bmY *
;REM. * | *
;REM. * Example | SYS GFXLIB_Plot, dispVars{}, ballspr%, 32, 32, ballx%, bally% *
;REM. * | *
;REM. * Notes | Black pixels (i.e. those of value &xx000000) are ignored (i.e. not plotted) *
;REM. * | *
;REM. ****************|******************************************************************************
;REM.
.GFXLIB_Plot
;
; SYS GFXLIB_Plot, dispVars, bmAddr, bmW, bmH, bmX, bmY
;
pushad
;REM. ESP+36 = dispVars
;REM. ESP+40 = bmAddr
;REM. ESP+44 = bmW
;REM. ESP+48 = bmH
;REM. ESP+52 = bmX
;REM. ESP+56 = bmY
;REM. --------------------------------------------------------------
;REM. Setup the entry calling params for the bitmap clipping routine
;REM. --------------------------------------------------------------
mov eax, [esp+36] ; EAX = ptr to params blk
cmp dword [eax+28], TRUE
jne near label%(24,0) ; .GFXLIB_Plot__exit
;REM. copy GFXLIB_Plot's entry vars from the stack to varsblk (makes life somewhat easier)
mov ebx,[esp+40] : mov [varsblk+64],ebx ; varsblk+64 = bmAddr
mov ebx,[esp+44] : mov [varsblk+68],ebx ; varsblk+68 = bmW
mov ebx,[esp+48] : mov [varsblk+72],ebx ; varsblk+72 = bmH
mov ebx,[esp+52] : mov [varsblk+76],ebx ; varsblk+76 = bmX
mov ebx,[esp+56] : mov [varsblk+80],ebx ; varsblk+80 = bmY
;REM. Call the clipping routine (GFXLIB_clip) after PUSHing the required vars onto the stack
;REM. SYS GFXLIB_clip, dispVars, bmW, bmH, bmX, bmY, clipValsBlk
push (varsblk+128) ; ptr to clipValsBlk
push dword [varsblk+80] ; bmY
push dword [varsblk+76] ; bmX
push dword [varsblk+72] ; bmH
push dword [varsblk+68] ; bmW
push eax ; ptr to params blk
call GFXLIB_clip
;REM.
;REM. clipValsBlk
;REM.
;REM. +128 plotFlag (TRUE or FALSE) - if FALSE, do not attempt to plot/display bitmap
;REM. +132 clipFlag (TRUE or FALSE) - if TRUE then clipping is required
;REM. +136 startX
;REM. +140 startY
;REM. +144 numRows
;REM. +148 rowLen
;REM. +152 skipRows
;REM. +156 skipPxls
;REM.
cmp [varsblk+128], dword TRUE ; check plotFlag
jne label%(24,0) ; GFXLIB_Plot__exit ; exit if plotFlag=FALSE
;REM.
;REM. bmBuffO% = bmBuffAddr% + 4*(params.bmBuffW%*clipvals.startY% + clipvals.startX%)
;REM. bmW4% = 4*bmW%
;REM. bmBuffW4% = 4*bmBuffW%
;REM. bmAddr% += 4*(clipvals.skipRows% + clipvals.skipPxls%)
;REM.
;REM. FOR Y%=clipvals.numRows%-1 TO 0 STEP -1
;REM. FOR X%=clipvals.rowLen%-1 TO 0 STEP -1
;REM. bmBuffO%!(4*X%) = bmAddr%!(4*X%)
;REM. NEXT X%
;REM. bmAddr% += bmW4%
;REM. bmBuffO% += bmBuffW4%
;REM. NEXT Y%
;REM.
;----*----*----*----*----*----*----*----|
; compute initial/starting offset into the 'bmp buffer' (bmBuffO)
; EAX = ptr to params blk
mov ebx, [eax + 0] ; load base addr of 'bmp buffer' (bmpBuffAddr)
mov ecx, [varsblk + 140] ; startY
imul ecx, [eax + 4] ; = startY*bmpBuffW
add ecx, [varsblk + 136] ; = startY*bmpBuffW + startX
shl ecx, 2 ; = 4*(startY*bmpBuffW + startX)
add ecx, ebx ; = bmpBuffAddr + 4*(startY*bmpBuffW + startX)
mov edi, [varsblk + 64] ; bmAddr
mov ebx, [varsblk + 152] ; skipRows
add ebx, [varsblk + 156] ; skipRows+skipPxls
shl ebx, 2 ; 4*(skipRows + skipPxls)
add edi, ebx ; bmAddr += 4*(skipRows + skipPxls)
mov ebp, [varsblk + 68] ; bmW
shl ebp, 2 ; = 4*bmW
mov eax, [eax + 4] ; bmBuffW
shl eax, 2 ; = 4*bmBuffW
mov esi, [varsblk + 144] ; numRows (Y-loop counter)
dec esi ; numRows -= 1
.label%(24,1) ; .GFXLIB_Plot__yloop
push esi ; preserve ESI (Y-loop counter)
mov esi, [varsblk + 148] ; rowLen (X-loop counter)
dec esi ; rowLen -= 1
.label%(24,2) ; .GFXLIB_Plot__xloop
mov edx, [edi + 4*esi] ; load dword from source bitmap
test edx, &00FFFFFF ; is it 0 ?
jz label%(24,3) ; GFXLIB_Plot__next_pxl ; skip (i.e. don't plot) if so
mov [ecx + 4*esi], edx ; write dword to destination bitmap buffer
.label%(24,3) ; .GFXLIB_Plot__next_pxl
dec esi ; X -= 1
jge label%(24,2) ; GFXLIB_Plot__xloop ; loop if X >= 0
add edi, ebp ; bmAddr += 4*bmW
add ecx, eax ; bmBuffAddr += 4*bmBuffW
pop esi ; recover numRows (Y-loop)
dec esi ; Y -= 1
jge label%(24,1) ; GFXLIB_Plot__yloop ; loop if Y >= 0
.label%(24,0) ; .GFXLIB_Plot__exit
popad
ret (6*4)