01 November 2019, 21:12 | #1 |
This cat is no more
Join Date: Dec 2004
Location: FRANCE
Age: 52
Posts: 8,246
|
blitter dumb questions
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 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(); } |
01 November 2019, 21:21 | #2 |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,476
|
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 Last edited by ross; 01 November 2019 at 21:27. |
01 November 2019, 21:27 | #3 |
This cat is no more
Join Date: Dec 2004
Location: FRANCE
Age: 52
Posts: 8,246
|
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; |
01 November 2019, 21:28 | #4 |
ex. demoscener "Bigmama"
Join Date: Jun 2012
Location: Fyn / Denmark
Posts: 1,624
|
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. |
01 November 2019, 21:36 | #5 |
This cat is no more
Join Date: Dec 2004
Location: FRANCE
Age: 52
Posts: 8,246
|
with the same exact code, one image is okay the other has this buggy effect
80 wide: bad 168 wide: okay |
02 November 2019, 01:07 | #6 |
Registered User
Join Date: Jun 2016
Location: europe
Posts: 1,039
|
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. |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Immediate Blitter & Wait for Blitter... | volvo_0ne | support.WinUAE | 32 | 18 September 2022 09:52 |
Blitter busy flag with blitter DMA off? | NorthWay | Coders. Asm / Hardware | 9 | 23 February 2014 21:05 |
Help this dumb Yankee... | ghost_of_war | New to Emulation or Amiga scene | 7 | 16 November 2013 19:38 |
Questions on C2P using blitter only | neoman | Coders. General | 2 | 21 July 2013 22:14 |
Probably a really dumb question... | BumpyCarrot | New to Emulation or Amiga scene | 3 | 28 February 2003 02:04 |
|
|