[comp.sys.amiga.programmer] Problem with code to do arbitrary blit in C. HELP!

ttr1415@helios.TAMU.EDU (Thom Robertson) (06/10/91)

I'm trying to debug a piece of Lattice C code that a friend gave me
which is supposed to do an arbitrary blit using a mask.  My problem is
this;  when my offset from the left edge of the source plane is > 0,
the routine doesn't calculate either the size in words, or the LWM word
correctly.  I don't know which.  Maybe both.

Let me elucidate.  The line which calculates the LWM (let's assume an
acending blit for now) goes like this:

    *bltalwm = 0xFFFF << (15 - ((sx + sizex) &0x0F));

sx = offset in pixels from the left edge of the source
sizex = width in pixels of the blit to be performed

The lines to calculate the source modulo is:

     sxm = sx & 0x0F;
     dxm = dx & 0x0F;

    tmp = src->BytesPerRow - (2 * (sizex / 16) + 1);
    if (sxm != dxm) tmp--;
    *bltamod = tmp;
    *bltbmod = tmp;

dx = offset in pixels from the left edge of the destination plane
src = the source BitMap

Last, the blit size is done like this:

    size = ((sizey) * 64) + (sizex / 16 + 1);
    *bltsize = size;

sizey = hieght in pixels of the blit to be performed

What happenes is, say for this demonstration, I want to blit a graphic
which is 49 pixels wide onto the Workbench screen.

If I blit it all (again assuming for the sake of argument an
acending blit), sx = 0, and sizex = 49.  Let's also say dx = 165.

for my LWM, this gives me:

     = 0xFFFF << (15 - ((0 + 49) &0x0F));

     = %1100000000000000

for the modulo,:

     sxm = 0 & 0x0F;
     dxm = 165 & 0x0F;   /* = 5 in this case */

    tmp = src->BytesPerRow - (2 * (49 / 16) + 1);
        = 8 - (2 * 3 + 1)
        = 1
    if (sxm != dxm) tmp--;
    *bltamod = tmp;
    *bltbmod = tmp;
    0 = tmp;

and the size is:

    size = ((sizey) * 64) + (49 / 16 + 1);
         =                + 3 + 1

All of which is right.   NOW, when we make sx, say, 5, perhaps because
we want to clip from the left edge, we want to make sizex smaller by
5, so we don't run over the right edge.  However,

for the LWM, this gives:

     = 0xFFFF << (15 - ((5 + 44) &0x0F));

     = %1100000000000000

for the modulo,:

     sxm = 5 & 0x0F;
     dxm = 167 & 0x0F;   /* = 7 in this case */

    tmp = src->BytesPerRow - (2 * (44 / 16) + 1);
        = 8 - (2 * 2 + 1)
        = 3
    if (sxm != dxm) tmp--;
    *bltamod = tmp;
    *bltbmod = tmp;
    2 = tmp;

and the size is:

    size = ((sizey) * 64) + (44 / 16 + 1);
         =                + 2 + 1

So, even though I want 5 less pixels on the right edge of this blit, the
size and modulo are calculated one word less, while the LWM stays the
same, chopping off a whole 16 bits!

What am I doing wrong?  Can someone help?

Thanx,

Thom Robertson