11 March 2016 - Forum Rules

Main Menu

NES glitches that i dont understand

Started by tigrou, January 17, 2013, 05:34:55 AM

Previous topic - Next topic


When playing SMB3 on FCEUX, i noticed that the tiles near right border of the screen have always wrong palette :

Is it a emulator glitch / error, something specific to that game, or due to how nes hardware (PPU) works ?

I remember not having this problem when playing on a real TV, maybe its because this region is not visible ? (has it something to do with HBLANK?)

Also, something strange : setting 0xCF (mario vertical velocity) to 0x80 (-128) and 0xBD (horizontal velocity) to 0x7F (128) will make player "fly" to the right full speed. It will also force game to scroll level horizontally at maximum possible speed (higher than what is possible when playing game normally) and  most tiles will have wrong palette :

What i think is that tiles palette is set at a precise moment and if level is scrolled too fast that moment is "missed". Anyway, no matter scroll speed, tile indexes are always set correctly, why would palette be set separately than tiles indexes (PPU limitation) ?


The 1st error is "specific to that game". The fact is, the NES was designed only scroll horizontally or vertically. Games can scroll in both direction, but then data that exists through the left borders enters immediately to the right border ("horizontal mirroring") OR data that texits through the bottom border enters immediately to the top border ("vertical mirroring").

The NES defines maps with 8x8 tiles and 16x16 colour blocks. So you'll be getting up to 8 pixels with the wrong tile and 16 pixels with the wrong colour while scrolling (either horizontally or vertically).

The left 8 pixels can be hidden easily (just by setting the $2001 register appropriately), so many games could hide the 8 pixels with the wrong tile under that solid bar at the left. What remains is 8 pixels with the wrong colour, which is what you're seeing here.

As for the scrolling, it's probably just a glitch with the game. Normally the scrolling speed was bounded, and the game just assumes it never increase this much. The scrolling engine apparently is not working as expected if the scrolling is too fast. This is not surprising, considering the VRAM update bandwith is limited on the NES, therefore it's impossible to scroll TOO fast (but it's still possible to do up to 8 pixels per frame easily, which is already very fast if you ask me).


Well, it works that way on the Nester emulator too, so yes, that's probably a hardware limitation. I don't quite understand the finer points of old 8-bit programming and palette swapping, but I do know that various NES games from that era had some amusing screen-edge glitches in them that a player could sometimes exploit to his advantage.

For instance, Ninja Gaiden had what I called the "Incredible Disappearing Enemy" trick by which, if you carefully scrolled the screen forward while an enemy on a platform near the edge was stepping backwards, you could sometimes watch the enemy vanish off the platform altogether. (This was especially handy on Level 6, where there wasn't much of anywhere for you to stand otherwise.) At the same time, one of the more frustrating effects of this same glitch had to do with enemies rapidly re-spawning every time you destroyed them, especially the bird that consumed three (!) of your hit points every time it struck you.

Incidentally, yes, the edges of the screen would often be invisible to someone playing the game on the original console hooked up to an old Fullscreen CRT TV. When playing a DVD on one of those old televisions, I noticed that although the movie had black bars on its left and right due to being made with a European ratio (5:3) instead of an American one (4:3 or 16:9), these were cut off on the TV itself. Apparently, those old TVs shave anywhere from about 20-60 pixels off every edge. That's why the old game consoles could get away with so many of these shenanigans.


QuoteThe NES defines maps with 8x8 tiles and 16x16 colour blocks.

i didn't know that  :P

thanks for the answers and info, its clear now.


Quote from: Bregalad on January 17, 2013, 07:17:46 AM
The 1st error is "specific to that game". The fact is, the NES was designed only scroll horizontally or vertically. Games can scroll in both direction, but then data that exists through the left borders enters immediately to the right border ("horizontal mirroring") OR data that texits through the bottom border enters immediately to the top border ("vertical mirroring").

Don't forget, SMB3 scrolls in both directions AND has a graphics HUD. That adds an additional layer of complexity the NES probably wasn't meant to support. (see also Little Nemo, another popular game that suffers from similar glitches)
"My watch says 30 chickens" Google, 2018


If I remember correctly, Mario 3 uses the NES's hardware feature to disable the 8 leftmost pixels.  Because of horizontal mirroring, without disabling the 8 leftmost pixels, the glitch would also cause you to see the wrong *tile* on one side or the other.  The only reason that the palette is affected is because the NES selects palettes in 16x16 blocks rather than per-tile.  The second-leftmost tile's palette must equal the rightmost tile's palette in certain scrolling situations.  (Specifically, when the X scroll value mod 16 is between 9 and 15, inclusive.)

This Mario 3 glitch could be overcome with an MMC5, but that didn't exist at the time.  With an MMC5, you can disable the mirroring effect entirely, allowing you to not only fix the right side's palette glitching, but also remove the need to disable the 8 leftmost pixels.  Also, the MMC5 allows you to select the palette on a per-tile basis, a second way to solve the problem.


I actually tried out a demo somebody posted on NESDev that shows that the attribute artifacts in this game could theoretically be reduced to 3 or four pixels on either side of the screen, which is comparatively unnoticeable. Look.

The other thing that could have been done is to have the artifacts show up on the trailing side of the screen, rather than on the leading edge where your eyes are pointed. I think Kirby's Adventure does it this way.

I guess the reason they didn't do anything to mitigate the problem is because the way they programmed it was the simplest way, and it didn't stop it from being a great game or hurt sales.


Also, at the time most people were using CRTs that would hide the edges anyways so it probably seemed like a large effort to fix a problem of little noticeable effect.
"My watch says 30 chickens" Google, 2018


It might be cool to make an MMC5 hack for this game that fixes the problem. =^-^=


QuoteWith an MMC5, you can disable the mirroring effect entirely
This is actually wrong, but the rest of what you said is true.
The MMC5 can make you have memory for 3 screens instead of 2, but since there is 4 screens in total, you still have to "mirror" at least one of them. In the case of a game with a status bar it's possible to place the status bar in one screen, and two gameplay screen in the others, so that no glitches ever happens.

I considered doing a SMB3 that does it like in my demo (almost hiding the glitches - but in the real game) but I got quickly discouraged when I saw how the scrolling engine was coded. I don't remember clearly what discouraged me but there was certainly a good reason.


The limitations of the NES has been discussed thoroughly already, but I'll address the max velocity "bug" regarding the palette not updating. This isn't so much a limitation of the NES as it is a math problem.  If Mario is moving at 15 pixels per frame or slower, you won't get this issue.

During the update, it detects the right edge of the screen within a level by column of the tile map. It grabs that block and updates the character value and updates the palette accordingly (it only checks for a position within a 16 pixel range, makes sense, reduces execution time). In this is situation, you get your normal artifact situation. If you move faster than 16 pixels, you begin to skip entire blocks, thus, if your screen's ridge edge is on block 4, next frame it's on block 6. The game never updates the palette in relation to block 5 because the right edge's value was never within block 5's range.

Regarding solving this glitch, there's a much simpler way that the game already uses for the maps: sacrifice a few sprites with the highest priority and use them as a border on the right side.


Now that you said it, that was exactly why I have given up on doing a hack that would (partially) solve this glitch.

If you look at the source code of my demo, the scrolling engine works with a completely different approach as Mario 3's, and it's hard to hack another "approach" in a game engine.

My demo looks for the exact pixel position of the camera, compare with the old camera value, and updates all tiles and colours values that should be updated. It does not have the "block" approach, therefore the precision and why the glitches are more hidden.


I forget who (Hyper Hacker?), but years and years ago on acmlm, a user posted a simple fix for this glitch. Either someone goofted on the scrolling code, or it was poorly optimized. I forget the specifics, but it was a relatively short, simple edit that fixed the issue.

(This really belies a larger issue I've been concerned with not only with romhacking, but with humanity in general: it's too easy for good things to be lost as if they've never existed at all)