This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

Demo of Sprites covering glitches

Demo of Sprites covering glitches
by on (#174392)
I made this today. I thought I would share it, because I haven't seen any such code anywhere.

Basically, I'm creating a glitch by doing a X/Y scroll split mid-screen. And, I'm using a series of sprites to cover them.

At startup, they are not in place. Press 'Down' for a little bit to line them up.

Works on real hardware.

If you're wondering what the grey squares are, I'm testing the alignment of the second nametable post split, and making sure there is no jitter.

(file removed, see later post for newer version).
Re: Demo of Sprites covering glitches
by on (#174395)
Instead of covering it with sprites, couldn't you just finish the scroll split within hblank and not have any visible glitch?

I mean, I know commercial-era games didn't manage that, but we have cycle accurate emulators now, and it can be done.
Re: Demo of Sprites covering glitches
by on (#174398)
rainwarrior wrote:
Instead of covering it with sprites, couldn't you just finish the scroll split within hblank and not have any visible glitch?

I second this. Why waste sprites hiding something that can be completely avoided in the first place? A full scroll change requires only 4 PPU writes ($2006, $2005, $2005, $2006), out of which only the last 2 need to happen during hblank so there are no glitches. That's less then 8 cycles you have to fit in a ~21 cycle window, so there's A LOT of wiggle room to get the timing right.
Re: Demo of Sprites covering glitches
by on (#174406)
tokumaru wrote:
less then 8 cycles you have to fit in a ~21 cycle window, so there's A LOT of wiggle room to get the timing right.
Specifically, 5 cycles. (Write Load_Opcode Load_Lo Load_Hi Write).

I guess on 2A07+2C07 it's probably a 19 cycle window ((64 pixels - 2 for jitter) ÷3.2, round down). Still, 14 cycles of slop means you don't need to do anything special, ordinary IRQ or sprite 0 polling is precise enough.
Re: Demo of Sprites covering glitches
by on (#174407)
lidnariq wrote:
Specifically, 5 cycles. (Write Load_Opcode Load_Lo Load_Hi Write).

Yeah, only the last cycle of the first write has to land on hblank, because that's when the write effectively happens.

Quote:
I guess on 2A07+2C07 it's probably a 19 cycle window ((64 pixels - 2 for jitter) ÷3.2, round down).

Oh yeah, I wasn't considering PAL consoles, sorry.
Re: Demo of Sprites covering glitches
by on (#174414)
What if you were using a mapper without scanline counter, and you were using the sprite zero hit elsewhere, and you couldn't be certain of exactly where the hblank was...and, you could only narrow it down to about a 16 pixel window. Glitch.

Then sprites can cover the glitch.

The main thing I'm testing here is..."CAN you cover a glitch with sprites?" And the anwer is yes.

I feel like this is also a good test of emulators of PPU behavior, since half of the emulators I tested didn't look the same as real NES.

I might try again, see if I can hide it in the hblank (again, without a MMC3 scanline counter). I haven't had great success with that, yet.

The idea is that, in a game, you should be able to do logic before and after the split, so, perfectly timed code only helps in a demo like this.
Re: Demo of Sprites covering glitches
by on (#174418)
You may also get more jitter if you attempt more than one split using a CPU cycle counting interval timer such as that in the FME-7. There's a delay of 1 to 7 cycles after /IRQ goes low to complete the processing of the current instruction, and unless you use the mod 256 trick (keeping the cycle counter going while writing only the high byte), this variability compounds.
Re: Demo of Sprites covering glitches
by on (#174427)
dougeff wrote:
What if you were using a mapper without scanline counter, and you were using the sprite zero hit elsewhere, and you couldn't be certain of exactly where the hblank was...

But if you were this lost, you'd need a lot of sprites to be absolute sure the glitch would be covered, wouldn't you?

Quote:
The main thing I'm testing here is..."CAN you cover a glitch with sprites?" And the anwer is yes.

Well, yeah... but is it practical? If the area affected by the glitch isn't just a flat color, you'll still be losing details by covering it with a flat line. You also have to make sure that you have the necessary color available somewhere in your sprite palettes. Also, depending on how large the area affected by the glitch is, the sprites you use could greatly increase sprite flickering near the split.

Quote:
I feel like this is also a good test of emulators of PPU behavior, since half of the emulators I tested didn't look the same as real NES.

Yeah, every time I tried to align things to hblank, emulators would disagree. Nestopia used to give me the most consistent results compared to the real hardware, but it's been a while since I needed this kind of precise timing.

Quote:
I might try again, see if I can hide it in the hblank (again, without a MMC3 scanline counter). I haven't had great success with that, yet.

Make sure to do most of the work beforehand, and have the values for the last 2 writes ready and loaded into different registers so that the last 2 writes can be performed as quickly as possible. Then you just move the whole code using NOPs until there are no more glitches. I used this code in the past, and once it was properly aligned to hblank there were no glitches at all.

Quote:
The idea is that, in a game, you should be able to do logic before and after the split, so, perfectly timed code only helps in a demo like this.

Again, if you're that lost, it's not a few sprites that will give you a steady split. If your timing is really off you can even end up with the part after the split jumping up and down, in case you can't guarantee that the split happens always before or always after the PPU automatically increments the vertical scroll.

If you don't have mapper IRQs, there are 3 basic ways to time raster effects: sprite 0 hits, sprite overflow, and timed code. There's also the DMC IRQ, but that's a totally different beast. Anyway, none of these 3 synchronization techniques introduces enough jitter to make landing a 5-cycle sequence in a 19-cycle window impossible. They can add a delay of 7 or 8 cycles, which still leaves you with 6 or 7 cycles of padding.

What other synchronization techniques are you thinking of that are not precise enough to allow syncing with hblank but will still result in a predictable amount of glitches that can be covered with sprites?
Re: Demo of Sprites covering glitches
by on (#174428)
I'm actually working on a project that has a HUD at the bottom (sometimes)... a bit like Dizzy.

Regular game play for the first 180 -ish lines. Sprite zero hit, rendering off for about 8 lines, X and Y scroll changed, rendering back on...HUD displayed for 32 lines, then rendering off to the bottom of the screen.

Anyway, I was getting glitches, and jitter, and I was testing if I can cover the glitches with sprites.

BTW, did you notice Dizzy has jitter and glitches? Maybe that's just in the YouTube video I watched...I've never played it on a real NES.
Re: Demo of Sprites covering glitches
by on (#174430)
dougeff wrote:
Regular game play for the first 180 -ish lines. Sprite zero hit

OK...

Quote:
rendering off for about 8 lines

Is this for writing something to VRAM? If you can make this take a constant amount of time, you won't lose any precision after the sprite 0 hit.

Quote:
X and Y scroll changed, rendering back on...HUD displayed for 32 lines

If you have rendering disabled, you can actually change the scroll at any time, and the only thing that will matter is when you turn rendering on (i.e. 1 cycle in a 19-cycle window).

Quote:
then rendering off to the bottom of the screen.

This should be easy if the HUD is followed by at least one blank scanline, so you can turn rendering off at any point in that scanline.

Quote:
BTW, did you notice Dizzy has jitter and glitches?

I've never played any Dizzy games, but I'm not surprised. Many commercial games have split glitches... The worst offender IMO is Mega Man 3, which mangles over half of the scanline every time there's a split, in addition to shifting the background up. Look at what happens when the game starts splitting the screen (right before the boss shows up): https://youtu.be/M1UkE9h2zJg?t=58m56s
Re: Demo of Sprites covering glitches
by on (#174431)
Quote:
Is this for writing something to VRAM?


It's just a way to get 8 lines of black without having to put them somewhere in the VRAM.

The same reason I'm turning rendering off just below the HUD, to make the rest of the scanlines black.
Re: Demo of Sprites covering glitches
by on (#174434)
I was just suggesting the hblank thing in case you hadn't considered it, not trying to argue you out of the sprites approach.

The other alternative for covering a jittery split is to just have a solid colour on the pixels that will appear in the artifact area (part of both lines involved). This is what most commercial-era games that actually have clean splits did. Battletoads, as always, has some good examples, like its Volkmire's Inferno stage.

I use sprites to cover some background problems myself (e.g. annoying attribute palette limitations), though I try not to do it often because I don't want the background to be subject to sprite flicker; it sends a false signal that it might be an "object". To cover jitter you need three or four sprites on the same horizontal line, which really makes flicker hard to avoid. Depends on where your characters can go onscreen, of course, but might be an undesirable effect.

You might consider vertical displacement on the covering sprites to mitigate this; only one line from the sprite needs to cover the jitter region, so it can be the top of one and the bottom of another, etc.


As far as robustness among emulators, if you do what commercial-era games did (i.e. split during the visible scanline) you'll get the most consistent results. If you split in hblank, I think some emulators will end up off by one line, unfortunately. You might find a timing that works on most popular emulators, if you're lucky, but I don't have any good advice on this front.
Re: Demo of Sprites covering glitches
by on (#174435)
I was able to make a version without any sprites that is glitch free, using tokumaru's suggesion of writing the first $2006, $2005 lines first, during rendering...then the final $2005, $2006 write during Hblank. And, avoiding any writes to $2001.


I also made a change to the actual project I'm working on that also has no glitches (and does involve $2001 writes, as I described). I didn't test it on real NES yet, but works in emulators.
Re: Demo of Sprites covering glitches
by on (#174436)
dougeff wrote:
I was able to make a version without any sprites that is glitch free

Cool!

Quote:
I also made a change to the actual project I'm working on that also has no glitches (and does involve $2001 writes, as I described).

For normal scroll updates done during vblank, it's still better to use $2005 and $2001. when you need to change only the horizontal scroll mid-screen, $2005 and $2001 work just fine too. If you need to freely modify the vertical scroll though, then the $2006/5/5/6 combo is the best way.

Quote:
I didn't test it on real NES yet, but works in emulators.

Hopefully you'll be able to make it work consistently across most emulators and the real console.
Re: Demo of Sprites covering glitches
by on (#174437)
dougeff wrote:
I also made a change to the actual project I'm working on that also has no glitches (and does involve $2001 writes, as I described). I didn't test it on real NES yet, but works in emulators.

Let me know if you need someone to test it on actual hardware.
Re: Demo of Sprites covering glitches
by on (#174442)
I have an NTSC NES + PowerPak. This means I too can perform tests that don't involve PAL, power-up state, or open bus.
Re: Demo of Sprites covering glitches
by on (#174443)
dougeff wrote:
Regular game play for the first 180 -ish lines. Sprite zero hit, rendering off for about 8 lines, X and Y scroll changed, rendering back on...HUD displayed for 32 lines, then rendering off to the bottom of the screen

When your sprite0-check is at the bottom of the screen, you must make sure that your main game loop does not take too much time, right? Or do you have a trick to avoid this need?
Re: Demo of Sprites covering glitches
by on (#174444)
I know of two ways to keep a bottom status bar rock solid on a mapper without a PIT:

  • Estimation
    For each actor handler, estimate how long it will take in the worst case, using data from an emulator instrumented as a profiler. Add the estimated time of all actor handlers to a counter. If the next actor's handler won't fit, spill the remaining computation over to the next frame and wait for sprite 0. I think Gradius uses this.
  • DMC as timer
    Don't play sampled drums or sound effects. During the NMI handler, start a silent sample on DMC timed to finish just above your status bar, and have it fire an IRQ on completion. Wait for sprite 0 in an IRQ handler. I think Time Lord uses this.
Re: Demo of Sprites covering glitches
by on (#174445)
Yes, ok, I know of the DMC timer. (which is probably the way to go)
For a game like Gradius, the estimation code could count the amount of enemies and bullets. Intersting idea, but painful... :)
Re: Demo of Sprites covering glitches
by on (#174446)
Re-uploading all the demos. All were tested in emulators and real NES. All are stable.

Demo 1. Midscreen X/Y scroll split, producing glitches. Press 'start' to hide glitch with sprites. I reduced the sprite count to 3.

Demo 2. Midscreen X/Y scroll split, no glitches. Timed with a sprite zero hit. Split occurs during Hblank to avoid glitches. Up/Down moves the sprite zero position.

Demo 3. Midscreen rendering off for several lines, then midscreen X/Y scroll split, no glitches. Timed with a sprite zero hit. Split occurs during Hblank to avoid glitches. Up/Down moves the sprite zero position.
Re: Demo of Sprites covering glitches
by on (#174447)
Interesting side-note. There is a slight audible buzzing sound (Powerpak to NES) when the sprite zero was in a certain range on the screen. I'd say between scanlines 210-230.
Re: Demo of Sprites covering glitches
by on (#174448)
Quote:
When your sprite0-check is at the bottom of the screen, you must make sure that your main game loop does not take too much time, right? Or do you have a trick to avoid this need?


In the current project I'm working on, there is too much logic that occurs before sprite zero hits, and also not enough V-blank time to do all the PPU updates I need, so I've dropped down to 30 fps, and I do half the things each frame.

V-blank - half of the PPU updates
top screen - half of the game logic
sprite zero hit - screen split
a little more logic at the bottom

V-blank - second half of PPU updates
top screen - second half of game logic
sprite zero hit - screen split
a litte more logic at the bottom

And I update sprite movements every frame, so it still runs as smooth as 60 fps.
Re: Demo of Sprites covering glitches
by on (#174449)
dougeff wrote:
Interesting side-note. There is a slight audible buzzing sound (Powerpak to NES) when the sprite zero was in a certain range on the screen. I'd say between scanlines 210-230.

Most likely you're hearing the video signal as audio, as it tends to bleed into the audio channel a bit. Example: https://www.youtube.com/watch?v=hsxxeJlmn1U

Other stuff can interfere with the audio signal too, but crosstalk from the PPU is a common culprit.
Re: Demo of Sprites covering glitches
by on (#174450)
Yeah, that was the buzzing sound, but not so loud, and only sometimes. I'm using the coaxial cable output from NES. I should probably go get an RCA cord.