05 May 2023, 01:00 | #1 |
Registered User
Join Date: May 2022
Location: Canada
Posts: 139
|
Blitter for masking sprite
Hello Amiga coders!
Recently I wanted to mask sprites in order to make them "walk behind" a portion of the background bitmap. I managed to do it but not using a single blitter pass, so I wondered if you could help me figure it out. Here are example specifications: Suppose the source sprite data is a 4 colors (2 bitplane interleaved), 16 pixel wide, by 32 pixel tall. Modulo will be 0. The destination is to copy this sprite into sprite dma, so exactly same specs as source, modulo 0. The mask is a 16x32 1bpp mask, modulo 0. Questiion 1: I assume each bitplane must be done as a separate pass? I figured that if I repeated the mask twice, basically as if it was 32x32 of two copies, it could mask the two bitplanes of my sprite in one pass, however requiring twice the memory for the mask. Is that accurate? Question 2: I want to shift the mask since the sprite will not always be perfectly aligned on a 16-pixel grid. Using the A or B channel I can shift by 0 to 15 bits, but that will not fetch the remaining bits of the mask. It is as if a wanted to tell the blitter to load two words for channel A, but keep it to 1 word for B and D. That seems impossible to do in a single pass? My current solution is to do a first pass to build the shifted mask into a 32x32 temporary destination; after that, blit the sprite using that "preshifted" mask. One thing I noticed is that by doing a regular blit, I was not able to get my mask correctly built. I had to do a reverse blit. It seems to me that this is because the blitter shifts to the right instead of to the left. I was (and still am) very confused about why it shifts in that direction, since the next word that is fetched is won't enter from the correct side of the barrel shifter. Perhaps it is in fact in the correct shift direction for a regular blit, but when building a mask, it is not? I am feeling I will confuse more people if I keep writing so I'll wait for a wiser sage to teach the ways of the blitter. |
05 May 2023, 03:04 | #2 |
Registered User
Join Date: Jun 2016
Location: europe
Posts: 1,043
|
1. Yes, if you have a single bitplane (non-interleaved) mask you have to blit each bitplane separately.
2. In ascending mode, blitter works to the right and downward. In descending mode, it works to the left and upward. If you want to shift to the left you either have to use descending mode, or start a word earlier (and typically with +1 to horizontal size) and shift to the right by 16-x. If you want to be efficiient (blitsize as small as possible), change mode as needed. How does your mask look like, 1=visible or 1=hidden? If 1=visible, then you don't have to worry about it because shifting will bring in zeroes, and they will mask out the sprite data. If 1=hidden, then you could simply invert the mask (and minterm). I don't see the need for 32-bit wide blits (unless interleaved), but maybe I don't understand the problem correctly... |
05 May 2023, 13:42 | #3 |
Registered User
Join Date: May 2022
Location: Canada
Posts: 139
|
Ah yes sorry I forgot to explain properly: the mask is going to be larger than the sprite.
For example, here's the mask of a tree: It is 80 pixel wide (i.e.: 5 words), while the sprite is 16 pixel (1 word) wide. Here on this screenshot, I am showing the sprite (the purple elipse) with alphablending just to illustrate the portion that will be masked off by the tree. The sprite is at position x=4, which means the mask bits must be shifted 4 bits to the left. I can see that the blit size must be 2 words x 32 lines in order to fetch the mask and shift it; however since the source and destination are only 1 word wide (and to my knowledge, sprite dma data must remain organized this way: there is no modulo for sprite dma fetch?), can you help me figure out if this operation cannot be done in one pass? |
05 May 2023, 15:32 | #4 |
Registered User
Join Date: Jun 2016
Location: europe
Posts: 1,043
|
OK, I understand the problem now.
If you invert the mask (0= visible, 1=hidden) and adjust minterms accordingly, you could then use source A for the mask and clip the right half of the mask with BLTAFWM/$dff044. Blit would be 2 words wide, but it would be a single blit per bitplane. E.g. looking at the picture, sprite is 4 pixels to the right from the mask edge, so you have to shift the mask to the left by 4 pixels (descending mode: right to left, and upwards), you set $dff044 to $ffff<<(16-4) (and BLTALWM/$dff046 is always $ffff), so the lowest 12 bits are all 0 and the top 4 are shifted to the next word which then masks the correct sprite bitplane while the other bitplane is masked with all 0s (=visible) and remains unchanged. |
05 May 2023, 15:35 | #5 |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,479
|
Yes, you cannot do this operation in one pass (I think you need three..).
1) extract mask from 2 word and right align data (so you don't need descending mode) 2) copy the right part to the left part 3) cut the sprite data from the first and second bitplane I try to think if it can be done with fewer steps, but since the mask must be duplicated and applied in an object with a fixed width and without a modulo, I don't know if there are alternatives.. (I hope I understood correctly and that by sprite you mean hardware sprites) |
06 May 2023, 19:25 | #6 |
German Translator
Join Date: Aug 2018
Location: Drübeck / Germany
Age: 49
Posts: 187
|
the mask ist the shadow of the tree and the sprite shall not be visible behind the tree.
the spritedata is in memory twice, once unchanged and once changend by blitter. you have to work on the sprite data in chip-ram -copy the original sprite data (the original, unchanged data) to the working sprite -make the blitt on the working sprite (erase the bits with the blitter mask) -move the sprite to the new position -a part (or all) of the sprite is now behind the object (tree, background etc.) -next frame: copy the original sprite data back and repeat the procedure -if the mask has no '1', you can skip the blitter part and leave the sprite unchanged (All this is not necesseray if you use the BPLCON2 possibilities, when the screen is eg set for dual-playfield mode) |
07 May 2023, 05:27 | #7 |
Registered User
Join Date: May 2022
Location: Canada
Posts: 139
|
It works! Thanks everyone for your input and suggestions.
Although I only succeeded using a reverse blit, here's a screenshot and a short video [ Show youtube player ] showing the character walking in front and back of various elements. (Note: it runs at 50/60 fps, but my video capture was set to 30 fps). The game is running in HAM mode (6 bitplanes) and the player is a 4 color sprite. (i.e.: it is still my same game engine as the previous 'remgame' tech demo, I was trying how HAM would fare on a potential exterior forest/town map. There is a small bit of fringing visible but overall it works very well). Was this technique of masking sprites used in Amiga games? |
07 May 2023, 09:07 | #8 |
Registered User
Join Date: May 2020
Location: Figueira da Foz
Posts: 394
|
Most impressive!
|
07 May 2023, 09:07 | #9 |
Registered User
Join Date: Nov 2015
Location: Italy
Posts: 191
|
Instead of blitter, wouldn't it be worth trying to do it with cpu instead. Read a LONGWORD from mask (which may be in fast ram) once, shift it, use it to AND WORD every plane of sprite. Repeat for each sprite line.
|
07 May 2023, 10:15 | #10 | |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,479
|
Quote:
You could give it a try with 020+. |
|
07 May 2023, 11:31 | #11 | |
HOL/FTP busy bee
Join Date: Sep 2006
Location: Germany
Age: 46
Posts: 31,735
|
Quote:
|
|
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 |
wait for blitter vs immediate blitter | jotd | support.WinUAE | 1 | 08 September 2020 04:14 |
Kefrens converter, image masking | fstarred | support.Apps | 0 | 21 August 2018 20:31 |
Blitz Basic 2 med channel masking | leathered | Coders. Blitz Basic | 2 | 31 May 2014 17:50 |
Blitter busy flag with blitter DMA off? | NorthWay | Coders. Asm / Hardware | 9 | 23 February 2014 21:05 |
|
|