Controlled sprite flicker
Moderator: Moderators
- battagline
- Posts: 152
- Joined: Wed Sep 05, 2018 11:13 am
- Location: Colorado
- Contact:
Controlled sprite flicker
I've been thinking about how to display more than 8 sprites on a single scanline. My understanding is you make them flicker in and out by setting the priority bit in byte 2 of the oam to be behind the background. What I'm not sure is if there is some sort of scanline collision detection that would somehow determine if there are more than 8 sprites on a single line, or if the sprites should be set to randomly flicker at different times to just decrease the likelyhood of them all showing at the same time on the same scanline.
What kind of strategies are generally used? I tried googling this, but didn't really come up with anything.
Thanks
What kind of strategies are generally used? I tried googling this, but didn't really come up with anything.
Thanks
A few of my web games
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com
Re: Controlled sprite flicker
A search gave me this https://forums.nesdev.com/viewtopic.php?f=2&t=10591
https://twitter.com/bitinkstudios <- Follow me on twitter! Thanks!
https://www.patreon.com/bitinkstudios <- Support me on Patreon!
https://www.patreon.com/bitinkstudios <- Support me on Patreon!
- battagline
- Posts: 152
- Joined: Wed Sep 05, 2018 11:13 am
- Location: Colorado
- Contact:
Re: Controlled sprite flicker
Not sure why that didn't come up for me.nesrocks wrote:A search gave me this https://forums.nesdev.com/viewtopic.php?f=2&t=10591
Thanks
A few of my web games
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com
Re: Controlled sprite flicker
The BG bit does nothing to help BTW. Lower sprites in memory always have priority over the higher ones, regardless of the BG bit.
- rainwarrior
- Posts: 8734
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: Controlled sprite flicker
No, the priority bit will not help with this. That only draws that sprite behind the background, but it does not move it to a separate pass, so it will still interfere with other sprites on the same scanline even if they're not behind the background.battagline wrote:I've been thinking about how to display more than 8 sprites on a single scanline. My understanding is you make them flicker in and out by setting the priority bit in byte 2 of the oam to be behind the background. What I'm not sure is if there is some sort of scanline collision detection that would somehow determine if there are more than 8 sprites on a single line, or if the sprites should be set to randomly flicker at different times to just decrease the likelyhood of them all showing at the same time on the same scanline.
The way to deal with this is to change the order of the sprites within the OAM buffer.
The first step is not to put any particular character in a location. A lot of games hard-code sprites like this, but it makes flicker impossible. When you start a frame, set an "OAM index" to 0, every time you add a new sprite, put it at the index location, and add 4 to that index. To finish the frame, fill the rest of the OAM Y coordinates with $FF to hide any unused sprites.
Once you have a system like that in place, cycling the sprite order can be achieved by drawing your sprites in a different order each frame. You might try going through your object list forwards and backwards on different frames, or cycling thruogh them, or maybe have a few different orders.
Simple example:
Code: Select all
jsr oam_begin ; set index to 0
inc order_sequence
lda order_sequence
and #3
bne @order1
@order0:
jsr draw_player
jsr draw_enemies
jsr draw_bullets
jmp @order_end
@order1:
cmp #1
bne @order2:
jsr draw_bullets
jsr draw_enemies
jsr draw_player
jmp @order_end
@order2:
cmp #2
bne @order3:
jsr draw_enemies
jsr draw_player
jsr draw_bullets
jmp @order_end
@order3:
jsr draw_player
jsr draw_bullets
jsr draw_enemies
@order_end:
jsr oam_finish ; fill unused sprite Ys
Though a lot of older games did things in pairs of frames one off, one on, I'd recommend against a sequence with only two steps if you're making a new game, otherwise you'll get the "Mega Man disappears when hit" thing when YouTube or Twitch shows the video at 30fps. Use sequences of 3 frames or longer to ensure that the flickering is still comprehensible at half framerate.
One more general recommendation: don't try to detect overlap, it's easier just keep changing the order every frame. (Technically the sprite overflow flag in $2002 is supposed to detect this in a limited way, but its implementation was broken and it reports false positives. Not very useful.)
Re: Controlled sprite flicker
Note: Ninja'd by a lot of people, but I didn't write a reply for nothing so I'm posting anyway.
What you're looking for is called OAM cycling, and it has nothing to do with the priority bit.
Priorities between sprites is dictated by their order in OAM. Sprite 0 has the highest priority, sprite 63 the lowest. If more than 8 are present in any given scanline, only the 8 with the highest priorities will be rendered.
OAM cycling typically means randomizing the order of the sprites every frame, effectively randomizing their priorities, so that different sprites are dropped each frame.
You don't need to know when more than 8 sprites are sharing scanlines for this to work, because all sprites will be displayed when there are 8 or less, regardless of their priorities. The PPU does have a flag that indicates when sprites are dropped, but it only gets set once per frame (so you don't know which sprites are the problematic ones), and a bug in this flag's logic may report false positives.
What you're looking for is called OAM cycling, and it has nothing to do with the priority bit.
Priorities between sprites is dictated by their order in OAM. Sprite 0 has the highest priority, sprite 63 the lowest. If more than 8 are present in any given scanline, only the 8 with the highest priorities will be rendered.
OAM cycling typically means randomizing the order of the sprites every frame, effectively randomizing their priorities, so that different sprites are dropped each frame.
You don't need to know when more than 8 sprites are sharing scanlines for this to work, because all sprites will be displayed when there are 8 or less, regardless of their priorities. The PPU does have a flag that indicates when sprites are dropped, but it only gets set once per frame (so you don't know which sprites are the problematic ones), and a bug in this flag's logic may report false positives.
- battagline
- Posts: 152
- Joined: Wed Sep 05, 2018 11:13 am
- Location: Colorado
- Contact:
Re: Controlled sprite flicker
Ok, so I need to look around for OAM cycling for more information. I wasn't sure what it was called so googling things like "NES intentional sprite flickering" didn't return what I was looking for.
Thanks for your help
Thanks for your help
A few of my web games
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com
Re: Controlled sprite flicker
Strictly speaking, all sprite flickering is intentional. The PPU itself never flickers sprites, it just doesn't draw the ones with lower priority when it finds too many of them.
- battagline
- Posts: 152
- Joined: Wed Sep 05, 2018 11:13 am
- Location: Colorado
- Contact:
Re: Controlled sprite flicker
So I've attached a little flickering test I wrote. I'm not sure it looks right. Opinions are appreciated.
Thanks
Thanks
- Attachments
-
- starter.nes
- Flickering Text
- (40.02 KiB) Downloaded 287 times
A few of my web games
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com
Re: Controlled sprite flicker
It appears that you have two sprites for each letter and you're moving them outside the screen? You only should have one sprite for each letter and you don't have to move them at all. You cycle their address in memory so they alternate who's first in memory.
https://twitter.com/bitinkstudios <- Follow me on twitter! Thanks!
https://www.patreon.com/bitinkstudios <- Support me on Patreon!
https://www.patreon.com/bitinkstudios <- Support me on Patreon!
- battagline
- Posts: 152
- Joined: Wed Sep 05, 2018 11:13 am
- Location: Colorado
- Contact:
Re: Controlled sprite flicker
Actually what I'm doing is alternating the direction I write to oam, so on odd frames it writes from lowest to highest bytes and on even frames in writes from highest to lowest. I'm thinking since you move the whole block of OAM memory with the DMA no matter much it shouldn't matter that the used sprites alternate from one side of oam to the other, but if that's a problem for some reason, please let me know.nesrocks wrote:It appears that you have two sprites for each letter and you're moving them outside the screen? You only should have one sprite for each letter and you don't have to move them at all. You cycle their address in memory so they alternate who's first in memory.
Thanks
A few of my web games
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com
Re: Controlled sprite flicker
This subject comes just at the right time, when I'm considering how to approach it myself ^^;;;
I guess it depends on your system that you have implemented and how complicated is your engine. For example, I'm not doing sprite cycle at the moment (but must find how) and how I manage my sprites is that I add to a buffer a list of meta sprites with their information on every frame. Once everything is added to this buffer, I convert that buffer to OAM data.
I guess in my case, what I could do is on every odd frame I parse the buffer forward and even one backward and it could creates some very basic sprite cycling but it will still be depend on the order things are put inside, which for now it quite basic (player, bullets then soon entities, in that order).
Would it be enough, good question, but I guess I will know soon ^^;;; Is it a bad approach? I don't want to give some advice that are ill advised in the first place but I thought it was the right place to talk about it, instead of creating a new thread.
I guess it depends on your system that you have implemented and how complicated is your engine. For example, I'm not doing sprite cycle at the moment (but must find how) and how I manage my sprites is that I add to a buffer a list of meta sprites with their information on every frame. Once everything is added to this buffer, I convert that buffer to OAM data.
I guess in my case, what I could do is on every odd frame I parse the buffer forward and even one backward and it could creates some very basic sprite cycling but it will still be depend on the order things are put inside, which for now it quite basic (player, bullets then soon entities, in that order).
Would it be enough, good question, but I guess I will know soon ^^;;; Is it a bad approach? I don't want to give some advice that are ill advised in the first place but I thought it was the right place to talk about it, instead of creating a new thread.
- rainwarrior
- Posts: 8734
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: Controlled sprite flicker
In cases where you have more than 16 sprites on a line, alternating direction will still leave the ones in the middle unseen, but that's maybe an extreme case.battagline wrote:but if that's a problem for some reason, please let me know.
Maybe a more minor issue is the middle ground where you have 9-15 sprites on a line: in this case only the low and high sprites will be flickering, but the ones in between will be solid. This gives very uneven looking flickering, as only some of the sprite tiles will participate in it. That's pretty normal for NES flickering, though, so this might be acceptable.
The other problem I mentioned above, alternating frames means that on YouTube or streams or some other common situations where there's a reduction to 30fps will leave people seeing only one of the two versions. Though, you could deal with that easily by reversing every 2 frames instead of every frame, or doing some pattern like 01001011.
- battagline
- Posts: 152
- Joined: Wed Sep 05, 2018 11:13 am
- Location: Colorado
- Contact:
Re: Controlled sprite flicker
My thought was I would like to design the game to try and avoid any flickering at all, and the flickering would only happen in cases where things went further than I had intended... just a thought, it may not end up working out but doing it this way doesn't spend many cycles and is pretty easy to implementrainwarrior wrote: Maybe a more minor issue is the middle ground where you have 9-15 sprites on a line: in this case only the low and high sprites will be flickering, but the ones in between will be solid. This gives very uneven looking flickering, as only some of the sprite tiles will participate in it. That's pretty normal for NES flickering, though, so this might be acceptable.
The other problem I mentioned above, alternating frames means that on YouTube or streams or some other common situations where there's a reduction to 30fps will leave people seeing only one of the two versions. Though, you could deal with that easily by reversing every 2 frames instead of every frame, or doing some pattern like 01001011.
A few of my web games
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com
Re: Controlled sprite flicker
I'd consider leaving a sprite invisible for more than one successive frame much more detrimental than a 30hz flicker rate.rainwarrior wrote: Though, you could deal with that easily by reversing every 2 frames instead of every frame, or doing some pattern like 01001011.
If I'm making an NES game, I'm designing it for a CRT, not for YouTube, and a sprite disappearing for a single frame on a CRT will not flicker as clearly, and usually just appear like it goes partly transparent. Lose it for two frames in a row, and the flickering will be much more apparent.
I noticed this effect in my Donkey Kong port. Playing on emulator, a lot of people had issues with the frequent flickering. But playing it on a CRT it's nowhere near as noticeable.
Of course, I realise that most people will probably be playing your game on an emulator, or an LCD TV, but even on those, I think losing a sprite for two frames in a row will look off-putting when it's not intended as an effect (like Mega Man's invincibility frames)
Did anyone ever reverse engineer Dynamite Batman/Return of the Joker? I'd love to know which method they used.