Flylib.com

Books Software

 
 
 

Graphics 101 -- Clipping Blit

Graphics 101 Clipping Blit

image from book
Figure 19-7: 2D bitmap on left with 2-bit clipping plane on right

The same trick of using inverse logic can be used for expanding image clipping planes.

In the image on the left, no matter how it's encoded (8/16/24/32 bits), only a single bit in the clipping plane image on the right would be needed to represent a single pixel. If black=0 and white=1, then a sprite object could appear to pass in front of the fence as well as behind it but in front of the distant background. This could be done in a variety of ways. One would be to use masks where both the sprite pixel and the background pixel are masked so only one has a non-zero value. The resulting color is written to the destination buffer.

; esi = sprite image pointer
; ebx = clipping plane
; ebp = background image pointer
; edi = destination image buffer pointer
   
        mov    edx,[ebx]         ; Get clipping plane
        mov    ch,32             ; 32 pixels at a time
   
$L1:    mov    al,[esi]          ; Source sprite image
        inc    esi               ; Next sprite pixel pointer
        mov    cl,[ebp]          ; Source background image
        inc    ebp               ; Next src background pixel
   
        test   al,tcolor         ; transparent color
        je     $T1               ; Jump if transparent pixel
   
        shr    edx,1             ; Get a masking bit into carry
        setnc  ah                ; 1=background 0=foreground
        dec    ah                ; 00=background ff=foreground
        and    cl,ah             ; ff=keep bgnd 00=kill it
        not    ah                ; Flip masking bits
        and    al,ah             ; ff=keep sprite 00=kill it
        or     cl,al             ; (XOR type) Blend pixels
$T1:    mov    [edi],cl          ; Save new pixel to destination
        inc    edi               ; Next dst working pixel
        dec    ch                ; 1 less pixel in run
        jnz    $L1               ; Loop

Chapter 20: MASM vs. NASM vs. TASM vs. WASM

Overview

This chapter reminds me of the old Batman and Robin show where in a fight scene we see sound effect words flash on screen such as "OOF," "KABONG," "ZING," "MASM," "ZOT," "TASM," "ZANG," "WASM," and "POW." These, by an amazing coincidence , are the war cry of the assembly language programmer. Wars have started for far less than trying to get one of these programmers to use a different C/C++ compiler or assembler. At one company I spent almost two years writing a good portion of the application core libraries and all the documentation for their SDK that allowed internal and external programmers to write online computer games using dedicated game servers. For the last year and a half there I worked on their Win32 Network API SDK (not to be confused with Microsoft's GameSDK). For the first four months there I wrote the DOS SDK, which uses 16-bit and various forms of 32-bit Extended DOS. It was a mix and match of C/C++ compilers, assemblers, linkers, and DOS extenders. It seemed every company had their own flavor. They had gotten used to their favorite combination and nothing was better! So every now and then I had to create libraries for that new flavor to entice new clients . Some of the code I currently write also uses the High C/C++ compiler with MASM or Pharlap's 386ASM. I do not use it these days, but there is also the Watcom C/C++ with their WASM Assembler. Occasionally on software I write today, I get inquiries if my libraries are compatible with the Borland TASM Assembler. I have used all of these and a few others, and to date my favorite is MASM by Microsoft.

There is a form of assembly that we should not forget: in-line assembly. Some people swear by it. I, on the other hand, swear at it! I rarely use it and only for some specific type of data conversion that I need to be fast without the penalty of a stack call to call a pure assembly function. It is akin to programming with one arm tied behind one's back. A lot of macro assembler functions are not available.

I have read book reviews in which advocates of non-MASM assemblers indicate a book could have been a lot better if the author had used TASM instead of MASM. Again, a personal bias! Although I have a few apprehensions about MASM, I have a personal bias for it. In writing this book I have tried to appease the critics by keeping the examples as generic as possible, and if this was not good enough for you, " L RASPBERRIES! J " MASM is only available separately by download but it's built into the Visual C++ 6 and VC .NET compilers.

You should always use the latest and greatest version of your favorite assembler because if you do not, your version could have bugs (I find them all the time) or be too old to support some of the newer instructions. Back when MMX first came out I had to use the IAMMX.INC by Intel with the MASM as a workaround just to support MMX instructions. Since then it has been built into MASM. Now for SSE3 support you need to either get the latest VC .NET or download the ia_pni.inc file to get assembly instruction macro emulation. With one other company's assembler I had to hand-code the opcodes to make sure I had the appropriate JMP instruction. There was a bug and the jump instruction that I had coded in assembly code was not the jump instruction being encoded into machine code. A bug was being introduced into compiled code because of a bug in the assembler itself!

With the latest instruction sets there seem to be two assemblers at the forefront with recently introduced assembly instructions: MASM and NASM. No matter whose assembler you're using, I use the following as placeholders for the arguments being passed into the example code used in this book:

arg1    equ     8          ; Argument #1
arg2    equ     (arg1+4)   ; Argument #2
arg3    equ     (arg2+4)   ; Argument #3
arg4    equ     (arg3+4)   ; Argument #4
arg5    equ     (arg4+4)   ; Argument #5
arg6    equ     (arg5+4)   ; Argument #6
arg7    equ     (arg6+4)   ; Argument #7
arg8    equ     (arg7+4)   ; Argument #8
   
   
; void unzip(byte *pRaw, byte *pZip, uint nWidth);
   
        public    unzip
unzip   proc      near
        push      ebp
        mov       ebp,esp
        push      ebx
        push      esi
        push      edi
   
        mov       esi,[ebp+arg1]  ; pRaw
        mov       edi,[ebp+arg2]  ; pZip
        mov       ecx,[ebp+arg3]  ; nWidth
   
       ;
       ;
       ;
   
        pop       edi
        pop       esi
        pop       ebx
        pop       ebp
        ret
unzip   endp

You will note that I used arg1 instead of 8 as shown below:

mov     eax,[ebp+8]

As an alternative to the arg1 you could use a define to make the argument name make more sense.

pRaw = arg1 
mov    eax,[ebp+pRaw]

The following information is a brief overview and you should refer to your assembler's documentation for specific information.