English Amiga Board

English Amiga Board (https://eab.abime.net/index.php)
-   Coders. Asm / Hardware (https://eab.abime.net/forumdisplay.php?f=112)
-   -   blitter dumb questions (https://eab.abime.net/showthread.php?t=99464)

jotd 01 November 2019 21:12

blitter dumb questions
 
1 Attachment(s)
I've written a blitter routine but I have issues with it.

- small objects aren't blitter properly. If width < 16 pixels it doesn't work.

How to blit small objects (like 8x8 objects) ? Is it even possible?

- shifting seems to work to some extent but with some images the end of the pic is drawn at the start (depending on the offset/shifting)

64: ok
70 & 72: shifted

Picture is 80 pixels wide

Attachment 65028

On other pictures it's OK. I don't know why on some it's okay and on some it's not.

My C code is trying to emulate SDL blit routine (with amiga raw bitplane format instead of the chunky pixels struct)

Code:

      {
        SDL_Amiga_Surface *amiga_source = (SDL_Amiga_Surface *)(source);
        SDL_Amiga_Surface *amiga_destination = (SDL_Amiga_Surface *)(destination);

        SDL_Rect source_rect = *src_rect;
   
        // safety
        if (source_rect.x + source_rect.w > source->w)
          {
            source_rect.w = source->w - source_rect.x;
          }
        if (source_rect.y + source_rect.h > source->h)
          {
            source_rect.h = source->h - source_rect.y;
          }
   
        // TEMP don't do anything
        if ((destination->w < source_rect.w) or (destination->h < source_rect.h))
          {
            return 0;
          }
   
        UBYTE *srcptr = (UBYTE *)amiga_source->pixels + (src_rect->x>>3);
        OwnBlitter();

        custom.dmacon = 0x8040;  // dirty enable blit

        // compute shift mask too
        custom.bltcon0 = 0x09f0 + ((dst_rect->x & 0xF) << 12);
        custom.bltcon1 = 0x0000;
        //move.l #$09f00000,bltcon0(a5)        ;A->D copy, no shifts, ascending mode
        custom.bltafwm = -1;
        //move.l #$ffffffff,bltafwm(a5)        ;no masking of first/last word
        custom.bltamod = 0;
        //move.w #0,bltamod(a5)                ;A modulo=bytes to skip between lines
        custom.bltdmod = (amiga_destination->w-amiga_source->w)>>3;


        UBYTE *dstptr = (UBYTE*)amiga_destination->pixels + (dst_rect->x>>3) + dst_rect->y*(amiga_destination->w>>3);

        auto asrcbw = amiga_source->w>>4;


        for (int i=0;i<NB_PLANES;i++)
          {
            custom.bltapt = srcptr;
            custom.bltdpt = dstptr;
            // BLTSIZE=height*64+width(words: so width divided by 16 and min 1)
            custom.bltsize = amiga_source->h*64+asrcbw;

            //move.l a0,bltapt(a5)        ;source graphic top left corner
            //move.l a3,bltdpt(a5)        ;destination top left corner
            //move.w #blith*64+blitw,bltsize(a5)        ;rectangle size, starts blit

            srcptr += amiga_source->plane_size;
            dstptr += amiga_destination->plane_size;
            wait_blit();
          }
        DisownBlitter();
      }


ross 01 November 2019 21:21

Hi jotd, from your code it doesn't seem you set a proper BLTAFWM and BLTALWM mask.

EDIT.
And of course you need a one more word to blit if you shift :)

jotd 01 November 2019 21:27

1 Attachment(s)
thanks. I forgot to set lwm because asm code treats both registers together, in the C code you need 2 different moves. I've changed it

Code:

        custom.bltafwm = 0xFFFF;
        custom.bltalwm = 0xFFFF;

The border is gone but still doesn't cut it

Attachment 65038

hooverphonique 01 November 2019 21:28

You can't blit less than 16 bit wide, so your source data width needs to be an even number of bytes. Height is in lines, so 8 lines high is not a problem.

Pointers and modulos are in bytes, but bit 0 is ignored, i.e. they must be even.

The shift effect you're experiencing is the data being shifted into the next word to the right, so you need to widen your blit by one word on the right-hand side to avoid it being shifted to the next line, or clip the blit using bltalwm, possibly using a smaller/negative source modulo to avoid having to widen your source data.

jotd 01 November 2019 21:36

1 Attachment(s)
with the same exact code, one image is okay the other has this buggy effect

80 wide: bad
168 wide: okay

Attachment 65039

a/b 02 November 2019 01:07

Maybe it looks OK because the last char (tm) has large enough blank area on its right side, and you can't see it on the very left.
Your blit doesn't fully take into account that you are shifting (one extra word needed), you have to adjust all modulos and size. Something like:
img_width = 80 => blit_width = 96, moda = (80-96)/8, last_word_mask = 0, modd = 96/8
Unless your image is pre-resized to 96 (blank 16 pix on the right side), in which case moda can be 0 and last_word_mask can be $ffff.


All times are GMT +2. The time now is 01:29.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.

Page generated in 0.04453 seconds with 11 queries