English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Asm / Hardware

 
 
Thread Tools
Old 05 May 2023, 01:00   #1
remz
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.
remz is offline  
Old 05 May 2023, 03:04   #2
a/b
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...
a/b is offline  
Old 05 May 2023, 13:42   #3
remz
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?
Attached Thumbnails
Click image for larger version

Name:	mask_blitter.png
Views:	455
Size:	25.4 KB
ID:	78875  
remz is offline  
Old 05 May 2023, 15:32   #4
a/b
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.
a/b is offline  
Old 05 May 2023, 15:35   #5
ross
Defendit numerus
 
ross's Avatar
 
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)
ross is offline  
Old 06 May 2023, 19:25   #6
Rock'n Roll
German Translator
 
Rock'n Roll's Avatar
 
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)
Rock'n Roll is offline  
Old 07 May 2023, 05:27   #7
remz
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?

Attached Thumbnails
Click image for larger version

Name:	Screenshot 2023-05-06 231135.png
Views:	379
Size:	733.4 KB
ID:	78901  
remz is offline  
Old 07 May 2023, 09:07   #8
pixie
Registered User
 
pixie's Avatar
 
Join Date: May 2020
Location: Figueira da Foz
Posts: 394
Most impressive!
pixie is offline  
Old 07 May 2023, 09:07   #9
aros-sg
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.
aros-sg is offline  
Old 07 May 2023, 10:15   #10
ross
Defendit numerus
 
ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,479
Quote:
Originally Posted by aros-sg View Post
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.
For a simple 68k this is too much (not having a barrel shifter).
You could give it a try with 020+.
ross is offline  
Old 07 May 2023, 11:31   #11
TCD
HOL/FTP busy bee

 
TCD's Avatar
 
Join Date: Sep 2006
Location: Germany
Age: 46
Posts: 31,733
Quote:
Originally Posted by remz View Post
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).

Wow, that looks great Looking forward to see how it actually plays!
TCD is offline  
 


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

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


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

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.08855 seconds with 16 queries