Getting extra VBLANK

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Getting extra VBLANK
by on (#115709)
I was thinking, to get some extra VBLANK I can disable the PPU at line 200 or whereabouts and effectively start an early VBLANK, right? What if I also want to start the next frame late like at line 16 or 32? Is that possible? I'm going for a letterbox effect.
Re: Getting extra VBLANK
by on (#115712)
Yes it's possible. However there is many disadvantages in doing so, but regardless, it's perfectly possible.

If you use a mapper that relies on a CPU cycle timer like Konami VRCs mapper, FME-7 or the Famicom Disk System it'll be relatively easy, otherwise it'll be a headache to get working.
Re: Getting extra VBLANK
by on (#115714)
It's NROM-256. Will it be too hard? :/ I'm prepared to do some trickery. Just nothing that prohibits doing other things... can you explain how you would do it? What are the disadvantages?
Re: Getting extra VBLANK
by on (#115716)
sonder wrote:
I was thinking, to get some extra VBLANK I can disable the PPU at line 200 or whereabouts and effectively start an early VBLANK, right?

Yes, but be careful when disabling rendering during an scanline that contains sprites, as that might result in corrupt sprites on the next frame. Apparently there's a certain window of time when it's safe to turn rendering off.

Quote:
What if I also want to start the next frame late like at line 16 or 32? Is that possible?

Yes, it's possible. But you have to find a way get the time exactly right every frame, or it will look "jumpy", and since rendering is off you can't use sprite 0 to help you with the timing... it will have to be pure cycle counting (or a mapper that does the cycle counting for you - scanline counters won't work, because they also need rendering to work). Also, if you make use of $2006/$2007 past the end of VBlank, you'll need to set the scroll with combined $2005/$2006 writes, instead of the usual $2005/$2000 writes.
Re: Getting extra VBLANK
by on (#115717)
sonder wrote:
It's NROM-256. Will it be too hard?

If you are not scrolling vertically, not so much, because you can use sprite 0 hits.

Quote:
can you explain how you would do it?

The simplest way to do it would be to set up a sprite 0 hit at the point where you want to turn rendering off. Once you do it, you are free to use the PPU as if VBlank had started. When you're done, wait for the sprite hit flag to clear - this will tell you when VBlank has ended, so you can start counting cycles in order to enable rendering at the correct point.

If you don't need to use $2006/$2007 after VBlank has ended, you can set the scroll normally before waiting for the frame to start, otherwise you will need to use the $2005/$2006 trick to set the scroll before enabling rendering.
Re: Getting extra VBLANK
by on (#115734)
tokumaru wrote:
Yes, but be careful when disabling rendering during an scanline that contains sprites, as that might result in corrupt sprites on the next frame. Apparently there's a certain window of time when it's safe to turn rendering off.


If you don't refresh the sprites the data may start to degrade, or even if you do an OAM DMA too early, but if you do the DMA after the true vblank begins you should be fine, AFAIK? Or is there another issue there besides the dynamic RAM problem?
Re: Getting extra VBLANK
by on (#115737)
The problem as I understand it is that the state of a pair of sprites is kept in the OAM refresh mechanism, and this state might be restored to the wrong sprites.
Re: Getting extra VBLANK
by on (#115738)
tokumaru wrote:
sonder wrote:
It's NROM-256. Will it be too hard?

If you are not scrolling vertically, not so much, because you can use sprite 0 hits.

The simplest way to do it would be to set up a sprite 0 hit at the point where you want to turn rendering off. Once you do it, you are free to use the PPU as if VBlank had started. When you're done, wait for the sprite hit flag to clear - this will tell you when VBlank has ended, so you can start counting cycles in order to enable rendering at the correct point.

If you don't need to use $2006/$2007 after VBlank has ended, you can set the scroll normally before waiting for the frame to start, otherwise you will need to use the $2005/$2006 trick to set the scroll before enabling rendering.


Well, we were going to use vertical scrolling, but we may use horizontal scrolling. I'm thinking we put black tiles at the bottom of the screen to help hide glitches since I read that Sprite 0 Hit is imprecise.

Sounds like the bottom black bar, aka early vblank, is the easy part. And honestly ~20 extra lines may be good enough. I think that rather than try to start rendering late, I'd use a split-screen technique - manipulate the scroll values to show the bottom black bar again. Perhaps we can show a black bar from the other nametable - and us it as a place to show text - though text is a thing we're thinking of abandoning since our CHR ROM is so precious (though I have a mind to beg mham to upgrade us to UxROM, but we're trying to see how far we can get with NROM)
Re: Getting extra VBLANK
by on (#115743)
sonder wrote:
Well, we were going to use vertical scrolling, but we may use horizontal scrolling.

What? Are you changing the design of your game? Anyway, you can still use vertical scrolling as long as you can guarantee that non-transparent pixels in sprite 0 will overlap non-transparent pixels in the background every frame. Sometimes vertical scrolling gets in the way of that, but not always. Depends on how you design your background.

Quote:
I'm thinking we put black tiles at the bottom of the screen to help hide glitches since I read that Sprite 0 Hit is imprecise.

You will definitely need a sprite 0 hit to put a black bar at the bottom of the screen, unless you are not scrolling vertically, in which case you can just put black tiles there. You will not be able to use that time for extra VRAM transfers, of course, since rendering will still be enabled.

Quote:
Sounds like the bottom black bar, aka early vblank, is the easy part.

Quite the opposite! Disabling rendering early can introduce the sprite glitches we talked about, and it's harder to synchronize with PPU after your game logic (needs sprite 0 hit or mapper IRQ). Blanking scanlines at the top of the screen is easier, because you have 2 possible sync points nearby (start and end of VBlank), so all you need is a bit of timed code to enable rendering at the correct scanline.

Quote:
I think that rather than try to start rendering late, I'd use a split-screen technique - manipulate the scroll values to show the bottom black bar again. Perhaps we can show a black bar from the other nametable

I think we need to know more about the type of scrolling you're using and why you need to display a letterboxed image in order to suggest the best approach.
Re: Getting extra VBLANK
by on (#115745)
Quote:
Anyway, you can still use vertical scrolling as long as you can guarantee that non-transparent pixels in sprite 0 will overlap non-transparent pixels in the background every frame.

Yes, but this has nothing to do with horizonal or vertical scrolling.

Quote:
Quite the opposite! Disabling rendering early can introduce the sprite glitches we talked about, and it's harder to synchronize with PPU after your game logic (needs sprite 0 hit or mapper IRQ). Blanking scanlines at the top of the screen is easier, because you have 2 possible sync points nearby (start and end of VBlank), so all you need is a bit of timed code to enable rendering at the correct scanline.

This, and I'd also say that extra VBlank is overrated in general. Not that it'd bad, but it's just not that good. Normal VBlank is enough for most applications, really. Unless you want to do something REALLY crazy like updating 20+ tiles every frame, there is no need for extra VBlank.
Re: Getting extra VBLANK
by on (#115746)
No, not changing the design of the game... just how the map is broken up. We have decided to create a top-down adventure. We are bouncing lots of ideas around at the moment so really it's going to be somewhat of a compromise between design and technical power. We are working hard on the R&D side of things to push the conventional boundary of what the NES is thought of being capable of. Well, really, just me. I'm an obsessive perfectionist.

The main reason for wanting to have more VBLANK right now is this http://slack.net/~ant/misc/nes-saw/

I want to use this trick to add an extra voice during non-interactive moments. But we also want to do time-of-day palette updates. The combo makes me think that the CPU will be taxed because of the IRQ so having more time to update the palette will help avoid glitches. Alternatively I've been thinking about using the IRQ to do more frequent music updates (better time resolution so more freedom with tempo). Maybe one or the other depending on the context.

As for which mirroring mode we'll use ... right now I'm not sure but we know that the map will be divided into "rooms" much like Zelda (rooms is just a term ... it may be mainly an outdoor overworld.) I was going to use vertical scrolling to create "big" rooms but Mike brought up horizontal scrolling "corridors" (like Metroid or Goonies) and I might like that better, but we'd have to rework the map format (which is just in the sketching stage). Or we might have no scrolling at all. But I think that having some scrolling would add more impact.
Re: Getting extra VBLANK
by on (#115748)
Bregalad wrote:
Yes, but this has nothing to do with horizonal or vertical scrolling.

Not directly, but since you need the hit to happen at the same scanline every frame, getting the scanline right is harder when the background is moving up and down (since the solid pixels you're supposed the hit against are moving away from the sprite). With horizontal scrolling it's much easier to provide a straight solid line.

Quote:
This, and I'd also say that extra VBlank is overrated in general. Not that it'd bad, but it's just not that good. Normal VBlank is enough for most applications, really.

Yeah, if you optimize the shit out of the code that writes data to VRAM you can do a lot in the standard 20 or so scanlines of VBlank. You can easily scroll in both directions at once while also updating the sprites and the palettes, which is enough for most games. What complicates things a bit are pattern animations... those can really eat a lot of your VBlank time, and is the only real excuse I can think of to need extra VBlank time.

sonder wrote:
But we also want to do time-of-day palette updates.

Palette updates are ridiculously quick if you pre-calculate all the data (as should be done with EVERY piece of data you write to VRAM). If you use code similar to this:

Code:
;set up the destination address (12 cycles)
lda #$3f
sta $2006
lda #$00
sta $2006

;prepare to reuse the background color (3 or 4 cycles)
ldx BackgroundColor

;write the first palette (25 or 28)
stx $2007
lda Palette0Color1
sta $2007
lda Palette0Color2
sta $2007
lda Palette0Color3
sta $2007

;now write the remaining 7 palettes in the same way...

It will take only 240 (colors loaded with absolute addressing) or 215 (colors loaded with ZP addressing) cycles to update all the colors... that's about 10% of the regular VBlank time, there's still enough time to update many other things. If your game is screen-by-screen, you definitely don't need any extra VBlank time unless you're animating several tiles in the pattern tables (which can't be the case since you're using CHR-ROM).

Quote:
Or we might have no scrolling at all. But I think that having some scrolling would add more impact.

No scrolling definitely helps with blanking portions of the screen. If you're only using scroll for "impact", quickly scrolling from one room to the next rather than smoothly following the player, I suggest you either drop the scrolling or do a very controlled/scripted one (like the vertical scroll in Mega Man 1, that does something purely visual before returning control to the horizontal scrolling engine) that won't get in the way of your letterboxing scheme.
Re: Getting extra VBLANK
by on (#115752)
To save ROM space I may do a combination of tables and calculation. But if all tables / unrolled loops would take a mere 10% then maybe it won't be so necessary to get extra vblank. I just figure that having a smaller viewport for the playfield is a decent price to pay just to have a little more technical freedom, and it could as a side effect give the game a more cinematic feel. Where can I read about the topic of extending vblank in more detail?
Re: Getting extra VBLANK
by on (#115859)
As no one seemed to mention it: Battletoads does keep rendering disabled for 20 or so (iirc) scanlines into the frame, showing that some commercial games did it at least (maybe lots of games did, but I only know of that one). This is what makes it tricky to emulate, as the current screen position needs to be within a certain interval when rendering is turned on for a sprite zero hit to happen. If that sprite zero hit does not happen, the game freezes.

As others have said, you'd need to set up the scroll yourself via $2006 writes before you turn on rendering if you keep rendering disabled on the pre-render line. The reason is that the "vert(v) = vert(t)" (copy vertical scrolling bits from t to v) operation in http://wiki.nesdev.com/w/images/4/4f/Ppu.svg does not happen with rendering disabled. If you turn off rendering near the end of the frame instead and turn it on before the pre-render line, you would not need to use $2006 writes.
Re: Getting extra VBLANK
by on (#115860)
ulfalizer wrote:
As no one seemed to mention it: Battletoads does keep rendering disabled for 20 or so (iirc) scanlines into the frame, showing that some commercial games did it at least (maybe lots of games did, but I only know of that one). This is what makes it tricky to emulate, as the current screen position needs to be within a certain interval when rendering is turned on for a sprite zero hit to happen. If that sprite zero hit does not happen, the game freezes.

As others have said, you'd need to set up the scroll yourself via $2006 writes before you turn on rendering if you keep rendering disabled on the pre-render line. The reason is that the "vert(v) = vert(t)" (copy vertical scrolling bits from t to v) operation in http://wiki.nesdev.com/w/images/4/4f/Ppu.svg does not happen with rendering disabled. If you turn off rendering near the end of the frame instead and turn it on before the pre-render line, you would not need to use $2006 writes.


Thanks for adding your explanation ... though despite that I admit I'm still a bit lost.

How does the sprite 0 hit factor into this? It would have to be used strictly to disable rendering at the bottom of the frame, right? So no splitscreen without scanline hardware of some kind, or tricky-as-hell cycle counting, right?

How does Battletoads know when to re-enable rendering at the right scanline? Scanline hardware?

Everyone keeps mentioning $2006 writes for setting up the scroll. How does that work? But it only matters if rendering hasn't been enabled by the "first" scanline (the pre-render scanline as you referred to it). If it's not a big deal to do the scroll through $2006 then that's not a detractor.

I still don't have a clear idea of what it will take to accomplish this in say, an NROM game. People say cycle counting but it seems to me like I could easily disable rendering at line 200 on sprite 0 hit and just make sure to re-enable it after my vblank routine. Anyone please confirm if my thinking's right on this or not though.
Re: Getting extra VBLANK
by on (#115861)
The vblank code in Battletoads does indeed use tricky-as-hell cycle counting. But there are other substitutes for a scanline counter, such as abuse of DMC IRQ.
Re: Getting extra VBLANK
by on (#115863)
tepples wrote:
The vblank code in Battletoads does indeed use tricky-as-hell cycle counting. But there are other substitutes for a scanline counter, such as abuse of DMC IRQ.


When I read about the existence of the DMC IRQ this was my immediate thought - maybe it could be used to count scanlines. Does it actually count as "abuse" though? I mean, I have no idea what the drawbacks are besides the hit to the CPU.
Re: Getting extra VBLANK
by on (#115865)
sonder wrote:
ulfalizer wrote:
As no one seemed to mention it: Battletoads does keep rendering disabled for 20 or so (iirc) scanlines into the frame, showing that some commercial games did it at least (maybe lots of games did, but I only know of that one). This is what makes it tricky to emulate, as the current screen position needs to be within a certain interval when rendering is turned on for a sprite zero hit to happen. If that sprite zero hit does not happen, the game freezes.

As others have said, you'd need to set up the scroll yourself via $2006 writes before you turn on rendering if you keep rendering disabled on the pre-render line. The reason is that the "vert(v) = vert(t)" (copy vertical scrolling bits from t to v) operation in http://wiki.nesdev.com/w/images/4/4f/Ppu.svg does not happen with rendering disabled. If you turn off rendering near the end of the frame instead and turn it on before the pre-render line, you would not need to use $2006 writes.


Thanks for adding your explanation ... though despite that I admit I'm still a bit lost.

How does the sprite 0 hit factor into this? It would have to be used strictly to disable rendering at the bottom of the frame, right? So no splitscreen without scanline hardware of some kind, or tricky-as-hell cycle counting, right?


Yeah, if you determine when to disable rendering through a sprite zero hit, it would make most sense if it was for extra VBlank time at the bottom of the frame.

For Battletoads, the sprite zero hit comes after rendering is re-enabled (as it would have to, as no sprite zero hits can happen with rendering disabled) and so is really unrelated to the extra VBlank time. It just happens that messing up the timing related to the extra VBlank time also messes up the sprite zero hit.

sonder wrote:
How does Battletoads know when to re-enable rendering at the right scanline? Scanline hardware?


Through tricky-as-hell cycle counting. :P

sonder wrote:
Everyone keeps mentioning $2006 writes for setting up the scroll. How does that work? But it only matters if rendering hasn't been enabled by the "first" scanline (the pre-render scanline as you referred to it). If it's not a big deal to do the scroll through $2006 then that's not a detractor.


http://wiki.nesdev.com/w/index.php/The_ ... _scrolling goes over it. Basically, the VRAM address register (often called loopy_v or just v, used for the address during $2007 reads/writes) gets reused during rendering to hold the current nametable position (if you check the red cells in the linked diagram, you can see it getting updated during rendering to move between tiles). On the pre-render line (which is the line before the first visible line), the starting position (which is held in loopy_t/t) is copied over to v, but only if rendering is enabled. If rendering is disabled, v never gets initialized to the starting position, and you have to do it yourself via $2006 writes before you turn on rendering.

sonder wrote:
I still don't have a clear idea of what it will take to accomplish this in say, an NROM game. People say cycle counting but it seems to me like I could easily disable rendering at line 200 on sprite 0 hit and just make sure to re-enable it after my vblank routine. Anyone please confirm if my thinking's right on this or not though.


I think that should work, unless there's complications related to OAM (which is very glitchy). If it does, it would be easier than adding extra VBlank at the top of the frame I think. You'd just have to make sure to re-enable rendering before the pre-render line.
Re: Getting extra VBLANK
by on (#115866)
sonder wrote:
How does the sprite 0 hit factor into this? It would have to be used strictly to disable rendering at the bottom of the frame, right? So no splitscreen without scanline hardware of some kind, or tricky-as-hell cycle counting, right?

In your case, yes. But you can also use it to detect the end of VBlank (the hit flag is cleared), for syncing up with the PPU at the top of the frame. Battletoads doesn't disable rendering early though, AFAIK, so it doesn't use sprite 0 with that purpose.

Quote:
How does Battletoads know when to re-enable rendering at the right scanline? Scanline hardware?

Battletoads uses a very simple discrete mapper (it provides only PRG bankswitching and single screen mirroring selection), meaning there's no help from the hardware. It mostly uses timed code.

Quote:
Everyone keeps mentioning $2006 writes for setting up the scroll. How does that work?

The normal way of setting the scroll (2 writes to $2005 and 1 write to $2000) only works if done during VBlank, and rendering is enabled at the start of the frame. If those conditions are not met, you need to write to $2005 and $2006 in a certain order to have the same amount of control over the scroll.

Quote:
If it's not a big deal to do the scroll through $2006 then that's not a detractor.

It's not exactly hard, but since the bits are all "scrambled" a lot of people get confused when preparing the values that need to be written and defining when each one needs to be written.

Quote:
People say cycle counting but it seems to me like I could easily disable rendering at line 200 on sprite 0 hit and just make sure to re-enable it after my vblank routine.

You are right about disabling rendering at scanline 200, but in order to enable it late you'll need timed code. If you simply re-enable rendering at the end of your VBlank handler rendering will start from the top of the screen. If you really want to blank scanlines at the top of the screen, you'll have to use timed code after detecting the end of VBlank (i.e. wait for the sprite hit flag to be cleared), set the scroll with $2005/$2006 and finally re-enable rendering.
Re: Getting extra VBLANK
by on (#115867)
DMC playback causes glitches on the controller lines. There are workarounds for standard controllers and the Four Score adapter, but these may not be compatible with some specialty controllers. It can cause problems with the Zapper and the Super NES Mouse, for instance, unless you read them only while playback is turned off. (On the other hand, the IRQ may make Zapper reading easier if you don't need Y precision down to the scanline.) It's also somewhat tricky to time the IRQ exactly, as its period is far greater than a scanline and its underlying timer can't be paused. But I have written a demo with stable blanking regions at the top and bottom of the screen: DPCM Letterbox.

(Two edit conflicts in a row?)
Re: Getting extra VBLANK
by on (#115870)
Ah, yeah, you'd have to use $2005 too along with $2006 to set the starting position. The reason is that $2006 can't be used to set the uppermost bit of the fine y scroll (for no good reason. The hardware changes to allow it would have been minimal).

So yeah, it's a bit messy. :|
Re: Getting extra VBLANK
by on (#115871)
tepples wrote:
DMC playback causes glitches on the controller lines. There are workarounds for standard controllers and the Four Score adapter, but these may not be compatible with some specialty controllers. It can cause problems with the Zapper and the Super NES Mouse, for instance, unless you read them only while playback is turned off. (On the other hand, the IRQ may make Zapper reading easier if you don't need Y precision down to the scanline.) It's also somewhat tricky to time the IRQ exactly, as its period is far greater than a scanline and its underlying timer can't be paused. But I have written a demo with stable blanking regions at the top and bottom of the screen: DPCM Letterbox.

(Two edit conflicts in a row?)


very interesting demo. thanks for sharing it!

we will just be using standard controllers. we don't care about anything else at the moment. regardless, the way you stuffed the polling code into a block of time that you knew was safe was damn clever and comes as a nice bonus.

so the manner in which this disables just background rendering, obviously we can't do OAM DMA during the top of the screen, but does it allow extended time to update nametables? or is it just visual? and same goes for the bottom "blanked" area?

(p.s.: urr? didn't understand your last statement)
Re: Getting extra VBLANK
by on (#115905)
sonder wrote:
but it seems to me like I could easily disable rendering at line 200 on sprite 0 hit and just make sure to re-enable it after my vblank routine. Anyone please confirm if my thinking's right on this or not though.

It's easy only if your game logic is guaranteed to be finished by the time you're supposed to start actively polling for the sprite 0 hit. If the game logic ends up taking more time, you miss the hit.

When blanking the top of the screen, you have a guaranteed interrupt, plus you can poll for the end of the vblank by waiting for sprite 0 hit flag to be cleared (just need to make sure that it gets set somewhere in the frame for this to work).

ulfalizer wrote:
As no one seemed to mention it: Battletoads does keep rendering disabled for 20 or so (iirc) scanlines into the frame

The amount of forced blanking it uses depends on the level.
Re: Getting extra VBLANK
by on (#115916)
Thought I'd mention another method for syncing up with the PPU that hasn't been mentioned yet (which you can use along with sprite 0 hits): the sprite overflow flag. Yes, its behavior is a bit mystic, but it seems to work reliably if you place 9 high priority sprites in the same scanline. The drawbacks of this technique are:

1- Wasting 9 sprites. Not such a big deal if you use 8x16 sprites but very wasteful for 8x8 ones.
2- Can't be reliably used to detect the bottom of the screen, because game objects might accidentally line up more than 8 sprites before that point.
3- If used at the top, the high priority sprites will hide any actual game objects that go up there.

I do use the sprite overflow flag to detect the top of the screen in my scrolling engine, so I have to deal with issue number 3. What I do is put the 9 sprites at the very top of the screen and use timed code to wait the whole height of the sprites (I can do useful things during that time, and long as these tasks take a constant number of cycles) before enabling background rendering, so that even though sprites are enabled, the high priority ones will mask any game objects that go up there. Since sprites are enabled the whole time, I don't have to set the scroll the "magical" way and I still visually hide sprites and background at the top of the screen.
Re: Getting extra VBLANK
by on (#115918)
tokumaru wrote:
T
1- Wasting 9 sprites. Not such a big deal if you use 8x16 sprites but very wasteful for 8x8 ones.

Huh ? I don't see how this makes a difference.

Quote:
3- If used at the top, the high priority sprites will hide any actual game objects that go up there.
[...] I still visually hide sprites and background at the top of the screen.

This is quite an elegant way to hide the top overscan area I have to admit.
Re: Getting extra VBLANK
by on (#115920)
Bregalad wrote:
tokumaru wrote:
1- Wasting 9 sprites. Not such a big deal if you use 8x16 sprites but very wasteful for 8x8 ones.

Huh ? I don't see how this makes a difference.

On the NES, sprites cover a relatively small portion of the screen. The remaining 55 sprites can still cover quite a lot if each one is 8x16... more than all 64 8x8 sprites actually:

64 x 8 x 8 = 4096 pixels;
55 x 8 x 16 = 7040 pixels;

Giving up 9 8x8 sprites will reduce even further the already small area of the screen you can cover with sprites that size, so the impact is significantly more negative than if you used 8x16 sprites, IMO.

Quote:
This is quite an elegant way to hide the top overscan area I have to admit.

I like it mainly because it doesn't mess with the rendering process, which means no different dot crawl (which doesn't always look good) and no $2005/$2006 tricks.
Re: Getting extra VBLANK
by on (#115924)
I'm still not sure what you mean. No matter the sprite size, you loose 9 sprites out of 64, with 55 remaining which means you loose 14% of your sprites. Them being 8x8 or 8x16 doesn't affect this. On the other side you loose twice the area with 8x16 sprites because you're loosing sprites twice as big (but you had more sprite to start with).

If what you mean is that in a game with the same graphics, you are less likely to hit the 64 sprites bar with 8x16 sprite than with 8x8 I agree, so of course this remain true when the bar is lowered to 55. Nothing new here. However, it's not as simple as a calulation of area. For example, if you want to draw a 4x4 pixel bullet, you'll have to use a full 8x16 sprite if you use 8x16 sprites.
Re: Getting extra VBLANK
by on (#115928)
Bregalad wrote:
I'm still not sure what you mean. No matter the sprite size, you loose 9 sprites out of 64, with 55 remaining which means you loose 14% of your sprites. Them being 8x8 or 8x16 doesn't affect this. On the other side you loose twice the area with 8x16 sprites because you're loosing sprites twice as big (but you had more sprite to start with).

If what you mean is that in a game with the same graphics, you are less likely to hit the 64 sprites bar with 8x16 sprite than with 8x8 I agree, so of course this remain true when the bar is lowered to 55. Nothing new here. However, it's not as simple as a calulation of area. For example, if you want to draw a 4x4 pixel bullet, you'll have to use a full 8x16 sprite if you use 8x16 sprites.


What he's saying is that, say you were using 8x8 sprites. You need 4 to make a 16x16 sprite, the smallest most common game character sprite size (you don't see 8x16 very often). With 8x16 sprites you only need 2. Therefore losing 9 sprites in 8x16 mode is less of an impact on your sprite budget.

I think it should be assumed, if you are using 8x16 mode that your sprites will generally take advantage of the available space as much as possible and you wouldn't be using 4x4 bullets very often in the first place.
Re: Getting extra VBLANK
by on (#115930)
Contra (and it's sqeuel Super C) among with Gradius games (Gradius, Lifefore and Gradius II) uses 8x16 sprites and draws 4x4 bullets everywhere all the time.
Re: Getting extra VBLANK
by on (#115932)
Bregalad wrote:
I'm still not sure what you mean. No matter the sprite size, you loose 9 sprites out of 64, with 55 remaining which means you loose 14% of your sprites.

Relatively, it's the same, yes.

Quote:
On the other side you loose twice the area with 8x16 sprites because you're loosing sprites twice as big (but you had more sprite to start with).

Exactly, the total area you're subtracting from is much bigger, so even after the subtraction you can still cover a larger area than you could with 8x8 sprites. IMO, this makes the sacrifice of 9 sprites much more acceptable. You might disagree.

Quote:
If what you mean is that in a game with the same graphics, you are less likely to hit the 64 sprites bar with 8x16 sprite than with 8x8 I agree, so of course this remain true when the bar is lowered to 55.

Wouldn't you say that this explain why the sacrifice of 9 sprites is more meaningful with one sprite size than the other?

Quote:
However, it's not as simple as a calulation of area. For example, if you want to draw a 4x4 pixel bullet, you'll have to use a full 8x16 sprite if you use 8x16 sprites.

Yes, you gain nothing with bullets and small particles, but you don't loose anything either, as 1 bullet = 1 sprite no matter the sprite size (what you lose is pattern table space, which is irrelevant in this case), but you can still save a lot of sprites on larger objects (and games that use 8x16 sprites often do, otherwise they'd use 8x8), so I maintain my opinion.

I'm not advocating that everyone should use 8x16 sprites (I like them that way, but I can understand if people prefer 8x8), I'm just pointing out that due to the fact that they can cover a larger area of the screen (bullets and small things aside) the sacrifice of 9 sprites is not as bad as if you were using 8x8. If you were to use all 55 8x16 sprites fully, you'd have the equivalent of 110 8x8 sprites. Even if you take all the bullets and partially used sprites out (the ones that are half empty), I'm sure you can pull off more than the equivalent of 64 8x8 sprites in most cases.
Re: Getting extra VBLANK
by on (#115940)
I still don't get your point. Of course you can cover more area with 8x16 sprites than with 8x8, and this is true no matter if your "limit" is 55 sprites or 64.

Therefore, scarifying 9 sprites is exactly the same in both cases, it's not a bigger sacrifice in one case than in another.

Quote:
and games that use 8x16 sprites often do, otherwise they'd use 8x8

I'm not that sure. Apparently Konami simply used 8x16 sprites in all their games without asking them too much questions. On the other side, Capcom always used 8x8 sprites in all their games. Only Nintendo actually switched between 8x8 and 8x16 for different games.
Re: Getting extra VBLANK
by on (#115948)
NES Play Action Football switched between 8x8 and 8x16 sprites at a scanline split. Yay TOSE programmers!
Re: Getting extra VBLANK
by on (#115952)
Bregalad wrote:
I still don't get your point. Of course you can cover more area with 8x16 sprites than with 8x8, and this is true no matter if your "limit" is 55 sprites or 64.

Therefore, scarifying 9 sprites is exactly the same in both cases, it's not a bigger sacrifice in one case than in another.


Not sure how you can't see the difference here Bregalad...

The limit is 64 sprites, you get to pick how big they are. The cost of this method is 9 sprites. Games using 8x8 sprites would presumably need more sprites since they're half as big.

Analogy:

You're painting a house. I'm giving you 64 cans of paint, you pick if they're 1 liter or 2 liter cans. After getting your paint you accidentally spill 9 of the cans, you have 55 cans left. You tell me which situtation that loss of 9 cans was a bigger loss/sacrafice.
Re: Getting extra VBLANK
by on (#115953)
Bregalad wrote:
I still don't get your point. Of course you can cover more area with 8x16 sprites than with 8x8, and this is true no matter if your "limit" is 55 sprites or 64.

Therefore, scarifying 9 sprites is exactly the same in both cases, it's not a bigger sacrifice in one case than in another.
Mario takes eight 8x8 sprites. Or he might take four 8x16 sprites. It only takes two (and a quarter) such 16x32 actors to make up for the loss of nine sprites to deliberately trigger the overflow flag.

On the other hand, something like tepples's "64 cans of sprite" demo would be different if it were "55 cans of sprite".

Regardless, it's clearly NOT the same.
Re: Getting extra VBLANK
by on (#115954)
Sprite overflow flag is really really easy to trigger unintentionally, especially with the PPU's bugs, so just never use it.
Re: Getting extra VBLANK
by on (#115955)
Dwedit wrote:
Sprite overflow flag is really really easy to trigger unintentionally, especially with the PPU's bugs, so just never use it.


I have seen this in lots of places. But I am using it for a project now to know when to flicker. It seems to work just fine, and it saves a lot of CPU since I don't have to manually keep track of when there are too many sprites on one scanline.
Re: Getting extra VBLANK
by on (#115956)
When there are more than 8 sprites on a line, it's very easy to have it fail, don't use it. I use it in one project to do 2 splits mid-frame without IRQ's, but you have to make sure the data after the 8 sprites that do the split don't make the data after it make it unclear the flag, as that happens.
Re: Getting extra VBLANK
by on (#115958)
The only way you could unintentionally trigger overflow is if you're using it for a mid- or bottom-screen split. Otherwise, if you keep sprites 1-9 eight lines above the top of the active playfield, and there's nothing above those sprites, those sprites are the only thing that could turn on the overflow flag. And you don't necessarily "lose" these 9 sprites; you can use them to display a status bar above the playfield.
Re: Getting extra VBLANK
by on (#115960)
Dwedit wrote:
Sprite overflow flag is really really easy to trigger unintentionally, especially with the PPU's bugs, so just never use it.

What tepples said. I use it at the very top of the screen before any game objects have a chance to accidentally trigger it. It's pretty safe in that situation.
Re: Getting extra VBLANK
by on (#116016)
Quote:
Not sure how you can't see the difference here Bregalad...

Well it depends.
We already established that the reducted area in precentage is absolutely the same in all cases.

Now if you look at the absolute area that is loss by wasting 9 tall sprites (or 9 2l paint cans in your analogy), the loose of area is BIGGER than if you choose short sprites (or 1l paint cans in your analogy).

The third way of looking as it, is the raw area that you can draw. Of course it's smaller with 55 short sprites (or 55 1l paint cans) than with 55 tall sprites (or 55 2l pain cans). But that's the case as well if you replace both 55s with 64s.

The last way to look at it, which makes me understand your point, is that if you need to draw some given area, your chances are bigger with 55 2l cans than with 55 1l cans. In this regard, the probability that you will *need* to use 2l cans instead of being satisfied with 1l is bigger.

In summary, it all depends in which angle you look at it. I don't think it's obvious the loss is more or less acceptable with small or tall sprites. In both cases it's a small loss that should be accounted for.

Quote:
What tepples said. I use it at the very top of the screen before any game objects have a chance to accidentally trigger it. It's pretty safe in that situation.

As long as you are 100% sure that the flag gets set, I think it's okay (used to detect the end of VBlank only, not to do any raster timing synchronisation).
Now if somehow the flag could remain clear because of some PPU glitch, then it would freeze your game.
Re: Getting extra VBLANK
by on (#116017)
Bregalad wrote:
Now if somehow the flag could remain clear because of some PPU glitch, then it would freeze your game.

We discussed timeout techniques for sprite 0 in that topic about occasional horizontal line glitches in SMB1. The same techniques would work for overflow: a momentary flicker is better than a freeze.
Code:
  lda #%00100000
loop:
  bit $2002
  bmi did_not_trigger
  beq loop
  ; at this point, we know the overflow triggered, so wait 8 scanlines,
  ; set sprite size to 8x16 if needed, and turn on bg rendering
  ; (omitted)

did_not_trigger:
  ; The PPU hit the bottom of the picture instead of the 9 sprites.
  ; Log this situation for debugging.  if there are too many
  ; glitches in a short time, assume something is broken, and
  ; disable raster effects so as not to trigger a seizure.
  inc glitch_count