Flickering of different tiles within the same meta sprite

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems.

Moderator: Moderators

User avatar
tokumaru
Posts: 11766
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Flickering of different tiles within the same meta sprit

Post by tokumaru » Sun Feb 10, 2019 5:33 pm

DRW wrote:
tokumaru wrote:1 object = 1 metasprite, which isn't very flexible
Why is this not flexible? Or rather: Apart from my specific flickering issue, why would flexibility be even an issue here? What exactly can I not do with this setup?
In addition to allowing better flickering of large objects, like you seem to be needing right now, you can use it for decoration (e.g. things a character acquires that don't need separate objects, like a hat), customizable characters (like in Cocoron), or entities that are clusters of things that can move separately (such as the explosion when Mega Man dies).

There's probably a lot more things that can be done that I just can't think of right now, but it's just more versatile. And it's not like implementing this is any hard either: in my engines, each object has an update address (called in an specific order) and a draw address (called in random order each frame). Simple objects that don't need any special handling of metasprites can just point to a generic sprite rendering routine that will process a single metasprites and move on, but complex objects can have specialized routines that can modify the parameters and call the generic rendering routine as many times as necessary, to render multiple metasprites.

User avatar
Bregalad
Posts: 7890
Joined: Fri Nov 12, 2004 2:49 pm
Location: Chexbres, VD, Switzerland

Re: Flickering of different tiles within the same meta sprit

Post by Bregalad » Mon Feb 11, 2019 1:29 am

Is the order of tiles within a metasprite importnat (i.e. do you use sprite layering) ? If not, then you can just blit the sprites out of order.

Instead of doing something like, assuming shadow-OAM is at $200-$2FF

Code: Select all

BlitMetasprite:
  [some calculations here]
BlitMetasprite_loop:
  [some calculations here]
  sta $200,X       ;
  [some calculations here]
  sta $201,X
  [some calculations here]
  sta $202,X
  [some calculations here]
  sta $203,X
  inx
  inx
  inx
  inx
  beq OAM_full
  [some calculations here]
  bne Blit_metasprite_loop
OAM_Full:
  rts
You do something like :

Code: Select all

BlitMetasprite:
  [some calculations here]
BlitMetasprite_loop:
  [some calculations here]
  sta $200,X       ;
  [some calculations here]
  sta $201,X
  [some calculations here]
  sta $202,X
  [some calculations here]
  sta $203,X
  txa
  clc
  adc SpriteSpacingValue
  tax
  beq OAM_full
  [some calculations here]
  bne Blit_metasprite_loop
OAM_Full:
  rts
And SpriteSpacingValue can be any multiple of 4 which is not a multiple of 8, in order to blit the sprites out of order. A good idea is once per frame tie it to the pseudorandom-number generator, shift 3 times and add 4. This assures your sprites will be blitted in random order and makes it close to what Konami is doing in their games, which looks quite good in my opinion. Note that you still blit your metatiles in order, it's just that the individual sprites that are part of them are put in random order in OAM, so that the lower priority individual sprites who disapears are random. Another advantage is that sprite #0 remains always sprite #0, so it doesn't get in the way of sprite zero hit. However you can only use sprite layering if it doesn't rely on priorities (i.e. the non-used layer is "transparent").

User avatar
DRW
Posts: 1976
Joined: Sat Sep 07, 2013 2:59 pm

Re: Flickering of different tiles within the same meta sprit

Post by DRW » Sun Feb 17, 2019 11:16 am

rainwarrior wrote:A good shuffler should be changing the relative order of sprites. Changing the start position doesn't accomplish this very well. If you start on 2, you still have 2 before 3 before 4, etc... the only order you've changed by doing that is that 1 is now after things, but every other order relationship is intact.
That's why I used an offset and and order switch. Have a look again:

Code: Select all

Start with 1, go forward:  1 2 3 4 5 6
Start with 2, go backward: 2 1 6 5 4 3
Start with 3, go forward:  3 4 5 6 1 2
Start with 4, go backward: 4 3 2 1 6 5
Start with 5, go forward:  5 6 1 2 3 4
Start with 6, go backward: 6 5 4 3 2 1
So, would you say this is a good method or do you see any shortcomings?

This of course only shuffles the characters, but not the sprites within each character (which was my original reason I wrote this thread). But this other issue, I will talk about now.


Regarding the shuffling of the hardware sprites themselves:

Thanks for all your input.

There are two versions that fit my taste best:


Either I take gravelstudios' one byte randomizer.
However, it does have the shortcoming that I have to delete all sprites after every frame.
In the moment, my deletion is optimized: If the previous frame drew fewer sprites than the current one, no deletion is necessary at all.
And if the previous frame drew more spites, I only have to delete from the current maximum index to the previous maximum index.


Or I use FrankenGraphics round robin suggestion as an inspiration.
I don't know if I understood it correctly, but in any case, I would do it like this:

I would still read my meta sprite as usual (i.e. in the correct order). But for rendering, I would use a round robin offset that only refers to the sprites that I'm about to draw now.
So, if the character consists of 10 sprites, then I take the next 10 sprites of the gloabl sprite shadow copy and use a round robin method on these 10 sprites only, with an offset value that is stored and incremented per character.

This makes sure that the sprites within the same character are always drawn from a different start value.
And for the order between different characters, I still use my method that I described above. (Or have a look at rainwarrior's alternatives if he still says it's no good.)
My game "City Trouble": www.denny-r-walter.de/city.htm

User avatar
rainwarrior
Posts: 7824
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Flickering of different tiles within the same meta sprit

Post by rainwarrior » Sun Feb 17, 2019 11:57 am

DRW wrote:That's why I used an offset and and order switch. So, would you say this is a good method or do you see any shortcomings?
I didn't miss that. I acknowledged the reversing. It helps a little, but the shortcoming of not effectively shuffling the order still applies.

Here, imagine that sprites 5-6-7-8-9-10-11-12-13 are all on the same scanline, in your rotation with 16 sprites:

Code: Select all

 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 - drops 13
 2  1 16 15 14 13 12 11 10  9  8  7  6  5  4  3 - drops 5
 3  4  5  6  7  8  9 10 11 12 13 14 15 16  1  2 - drops 13
 4  3  2  1 16 15 14 13 12 11 10  9  8  7  6  5 - drops 5
 5  6  7  8  9 10 11 12 13 14 15 16  1  2  3  4 - drops 13
 6  5  4  3  2  1 16 15 14 13 12 11 10  9  8  7 - drops 7
 7  8  9 10 11 12 13 14 15 16  1  2  3  4  5  6 - drops 6
 8  7  6  5  4  3  2  1 16 15 14 13 12 11 10  9 - drops 9
 9 10 11 12 13 14 15 16  1  2  3  4  5  6  7  8 - drops 8
10  9  8  7  6  5  4  3  2  1 16 15 14 13 12 11 - drops 11
11 12 13 14 15 16  1  2  3  4  5  6  7  8  9 10 - drops 10
12 11 10  9  8  7  6  5  4  3  2  1 16 15 14 13 - drops 13
13 14 15 16  1  2  3  4  5  6  7  8  9 10 11 12 - drops 12
14 13 12 11 10  9  8  7  6  5  4  3  2  1 16 15 - drops 5
15 16  1  2  3  4  5  6  7  8  9 10 11 12 13 14 - drops 13
16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1 - drops 5
Do you see how this is not changing the order very well? For many frames in a row you are only managing to drop only either sprite 5 or 13. The rest of them only participate in a single frame of flicker. All of them should be participating equally here. (This is just one simple example, but it gets worse the more overlap there is.)

Merely changing the starting point in a linear list like that is like shuffling a deck of cards with a single cut. Yes, it's better than nothing, but nobody would accept that as a shuffled deck. Most of the relative orderings remain intact after a cut.

Like I said, if your list is small enough what you're doing is probably fine. It's not ideal though, and gets worse the larger your list is. There are better ways to do it, possibly with none or negligible performance difference.

User avatar
DRW
Posts: 1976
Joined: Sat Sep 07, 2013 2:59 pm

Re: Flickering of different tiles within the same meta sprit

Post by DRW » Sun Feb 17, 2019 12:19 pm

O.k., thanks for the description. I'll have a look for better shuffling mechanisms on the character level that I then use in conjunction with the round robin method on the sprites-per-character level.
My game "City Trouble": www.denny-r-walter.de/city.htm

Post Reply