How to hide vertical scrolling updates with no status bar?

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

Moderator: Moderators

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

Re: How to hide vertical scrolling updates with no status ba

Post by tokumaru »

Bregalad wrote:I don't understand why people would be bothered by glitches on the background, but not on the sprites.
Most homebrewers use 8x8 sprites, so the problem isn't so severe at the top of the screen, and the left side can just be hidden by the PPU.
Attributes clashes on a scrolling BG are also "so brief" and "near the edge of the screen", yet people seems to find them unacceptable.
With the background the artifacts span an entire side of the screen (much larger), they are periodic (like a blinking light, draws more attention), and they happen on static objects. A sprite is most likely going to be a moving object, so when it "pops" and your peripheral vision draws your attention to it, it does indeed find a moving object that needs your attention (like an enemy). When colors "pop" on the background you are deceived, there's nothing there that needs your attention.

I try to make scrolling cleaner on sprites as well, but that's not a priority for me.
this is noticeable, and probably moreso than 3 pixel attributes clashes on a horizontal scrolling BG using horizontal mirroring such as in my demo.
I completely disagree, for the reasons I listed above.
User avatar
GradualGames
Posts: 1106
Joined: Sun Nov 09, 2008 9:18 pm
Location: Pennsylvania, USA
Contact:

Re: How to hide vertical scrolling updates with no status ba

Post by GradualGames »

Tokumaru, have you tried the DMC IRQ technique mentioned a couple of times in this thread? To me, this sounds almost ideal. With an IRQ, I can avoid doing any waiting for a bit transition and let my sound engine run (I mention this because I update all sound at end of vblank in the new engine). I was also thinking, I wonder if it is possible to set up DMC IRQ for raster effects like this:

-set it up at start of vblank, but tweak the timing to fire an IRQ AFTER vblank is done and a frame has begun rendering, preferably far enough down to hide updates at top

-once the first irq fires, set it up immediately to fire again near the bottom of the screen.

If this is possible, this seems absolutely ideal for my present setup because it would require no new hardware, would not eat up very much cpu time (waiting for anything), and would hide updates very gracefully. I guess I'd have to tweak the timing for NTSC and PAL builds, though, but it doesn't sound so bad.

I guess the primary disadvantage is you can't use DMC for sound. I made the decision early on in this project to not use DMC for sound. Hmm, if I use DMC at all though, will that introduce the controller read bug?
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: How to hide vertical scrolling updates with no status ba

Post by tokumaru »

GradualGames wrote:Tokumaru, have you tried the DMC IRQ technique mentioned a couple of times in this thread?
The DMC IRQ isn't as useful as you'd like. The precision is far from ideal and the APU works at a pace you cannot mess with. This means that even you start playing a (silent) sample at the same time every frame, the IRQ will fire at different times, with errors of several scanlines. What was suggested in this thread (IIRC) was to have the IRQ fire a little before the position of sprite 0, so you wouldn't miss the hit.

A while ago tepples had an idea to make DMC IRQs more useful, which involved counting how long it takes for one IRQ to fire and use that time to compensate for the error in subsequent IRQs. I experimented with this a bit too, but never got something as stable as I wanted. Tepples released some demos using this technique... try searching for them.
Hmm, if I use DMC at all though, will that introduce the controller read bug?
If you read the controller between the time you start playing the sample and when the IRQ fires, yes.
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: How to hide vertical scrolling updates with no status ba

Post by tepples »

tokumaru wrote:A while ago tepples had an idea to make DMC IRQs more useful, which involved counting how long it takes for one IRQ to fire and use that time to compensate for the error in subsequent IRQs. I experimented with this a bit too, but never got something as stable as I wanted. Tepples released some demos using this technique... try searching for them.
The demo was DPCM Letterbox, and the topic was this one. the demo is for NTSC and shows a scrolling window about 160 lines tall. One advantage of blanking so much is that in the era of widescreen TVs, zooming in won't cover anything important.
tokumaru wrote:
GradualGames wrote:Hmm, if I use DMC at all though, will that introduce the controller read bug?
If you read the controller between the time you start playing the sample and when the IRQ fires, yes.
If you read the controller immediately after getting an IRQ, you shouldn't get the bug.
Sik
Posts: 1589
Joined: Thu Aug 12, 2010 3:43 am

Re: How to hide vertical scrolling updates with no status ba

Post by Sik »

Bregalad wrote:I don't understand why people would be bothered by glitches on the background, but not on the sprites.
Sprites vanishing like that horizontally can be hidden with the left column blanking, and in most games sprites vanishing vertically are sprites that are moving in that direction anyway so you probably want to pay attention to them.
User avatar
GradualGames
Posts: 1106
Joined: Sun Nov 09, 2008 9:18 pm
Location: Pennsylvania, USA
Contact:

Re: How to hide vertical scrolling updates with no status ba

Post by GradualGames »

Here's a "before and after" video of my first attempt at hiding scrolling glitches.

Cycle timed scrolling glitch hiding

Advantages:
-Was pretty easy to implement, mainly because my vblank routines are pretty linear and easy to cycle-pad (just blasting buffers to ppu, very few branches)
-Does not use up any sprites
-No extra hardware required
-May encourage me to try to optimize other parts of my engine because of the wasted cpu time

Disadvantages:
-Uses up a lot of cpu cycles just to hide graphical glitches. I may try putting some stable portions of sound update and controller reading (as suggested here in this thread!) in the padded part.
-Need to tweak timing for PAL separately from NTSC if I choose to support PAL systems.
-Hard to get absolutely right. You can see a few bouncy pixels on the bottom scanline of the artificial hidden area. Probably due to taken or untaken branches not accounted for in the padding.

I'm pretty happy with this, for now. My new game is a hybrid between full scrolling "overworld" areas and single-screen dungeon type of areas---it is possible I may not need to find a better approach that doesn't eat up CPU cycles. But I really like getting the clean scrolling out of this.

*edit* oops, I just saw a bug in that video. Can you spot it? Have to fix that...
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: How to hide vertical scrolling updates with no status ba

Post by tokumaru »

So you're keeping sprites enabled to avoid the different dot crawl and using timed code to enable background rendering? Sounds like a good compromise to me, sprite popping doesn't bother me nearly as much as background glitches.
GradualGames wrote:-Uses up a lot of cpu cycles just to hide graphical glitches. I may try putting some stable portions of sound update and controller reading (as suggested here in this thread!) in the padded part.
Yeah, put as much constant-timed code as you can in there.
-Need to tweak timing for PAL separately from NTSC if I choose to support PAL systems.
That's pretty easy though. There are several ways to detect whether the system is NTSC, PAL or DENDY on start up, and then you can time the wait based on that detection. You can just wait the amount of time necessary to make the trick work in NTSC/DENDY and then check whether you need to wait any longer for PAL.
User avatar
MottZilla
Posts: 2835
Joined: Wed Dec 06, 2006 8:18 pm

Re: How to hide vertical scrolling updates with no status ba

Post by MottZilla »

Looks like you solved it well. Just hope you really don't need that extra CPU time. Though you can put some of it to use you'll probably not be able to utilize all of it.
User avatar
GradualGames
Posts: 1106
Joined: Sun Nov 09, 2008 9:18 pm
Location: Pennsylvania, USA
Contact:

Re: How to hide vertical scrolling updates with no status ba

Post by GradualGames »

tokumaru wrote: Good luck with the cycle counting, I'm sure you'll regret that choice! =)
You weren't kidding! I spent the whole weekend on this thing and I think I've finally got it tweaked right. My first attempt, shown in the video, wasn't quite correct because the padding was a bit rough and sometimes the graphic hiding logic (turn bg off...wait....turn on) would start near the end of vblank rather than at the start of a new frame. I got some weird scrolling glitches as a result (only on real hardware...!). So, I had to come up with a better way to cycle-pad my column and row vblank routine. I came up with this:

Code: Select all

  ;cycle pad this ppu upload routine for the artificial scroll
  ;update hiding bar (see the main module)
  lda #0
  sta cycle_pad_lut_index
  lda column_ready
  ror
  rol cycle_pad_lut_index
  lda #0
  sta column_ready

  lda row_ready
  ror
  rol cycle_pad_lut_index
  lda #0
  sta row_ready

  ldx cycle_pad_lut_index
  lda cycle_pad_lut1,x
  tax
: dex
  bne :-
  ldx cycle_pad_lut_index
  lda cycle_pad_lut2,x
  tax
: dex
  bne :-
It accounts for all four combinations of "please upload a row," "please upload a column," that can be passed into this routine. The luts have values that I just played with until I could see the graphics hiding bar start just a few pixels from the top left part of the screen (for all directions, up/down, left/right, and diagonals). So, I basically moved the "bouncy pixels" artifact to the top left, which is great for NTSC. As an unexpected and cool side effect, the bottom right of the graphics hiding bar is no longer bouncy. I wonder if it is disappearing into hblank at that point?
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: How to hide vertical scrolling updates with no status ba

Post by tokumaru »

GradualGames wrote:I wonder if it is disappearing into hblank at that point?
HBlank is 28.33 cycles on NTSC and 26.5625 cycles on PAL, so you have a little room to accommodate small timing variations.
Bisqwit
Posts: 248
Joined: Fri Oct 14, 2011 1:09 am

Re: How to hide vertical scrolling updates with no status ba

Post by Bisqwit »

If you use sprite-0-hits, you can use the clearing of the sprite-0-hit flag to figure out the beginning of rendering (top of screen). This takes out the PAL/NTSC difference from the equation.

To force that sprite-0-hit flag is triggered at the bottom of the screen with minimal impact, you can duplicate the trick that Solar Jetman uses. Solar Jetman does some serious magic to ensure that there is _always_ a visible tile in the bottom left corner of the play area, and that when there is not supposed to be one, there still is one and it looks like just one pixel. It helps getting away with it, that the background has stars, which also look like singular pixels. This minimal-impact method is doable only on VRAM.

Personally, I would say run with it. Simon's Quest does 4-way scrolling with vertical mirroring. It updates 8-pixel tall/wide columns/rows at once on the edges of the screen, and it updates attribute tables at 16-pixel intervals. (I.e. finest grained possible in each direction.) Obviously this means that there can be 0-7 pixels of garbage tiles on the top of the screen, and 0-15 pixels of wrong colors at the top of the screen, if the television displays the full 240 scanlines. Not too bothersome. Way less bothersome, in my opinion, than what SMB3 has going on in the right edge of the screen.
Post Reply