Simple vertical scrolling with status bar
Moderator: Moderators
Re: Simple vertical scrolling with status bar
There are no glitches when changing only the NT because $2000 writes only affect the temporary VRAM address register. Then, only at the start of hblank does the PPU copy the horizontal scroll bits to the actual address register. You don't have direct control over the active scroll through $2000 alone, so any changes you make are effectively delayed until hblank.
Re: Simple vertical scrolling with status bar
Correct. Changing bit 0 of $2000 (horizontal nametable select) is considered a coarse horizontal scroll and takes effect on the next scanline. Changing bit 1 of the same port is considered a vertical scroll and takes effect on the next frame. But for fine horizontal scrolling, you do need to take care of the timing yourself. The same is true of forced scrolling (the $2006-$2005-$2005-$2006).DRW wrote:Is this maybe a specific behavior of the NES, that scrolling can be changed anytime mid-frame and you have to take care of the timing yourself, while a name table switch automatically only takes place during the next hblank?
Re: Simple vertical scrolling with status bar
Interesting.
Is there a specific reason why this wasn't done for scrolling as well?
I mean, I cannot really imagine a situation where you do a mid-frame horizontal scrolling change and don't intend it to take place during hblank, but where you actually want the change to happen in the middle of the line.
In my previous game, where I created parallax scrolling with a sprite 0 split, I was able to circumvent the whole problem by creating the fog in a way, so that there's one continuous line of a single color above the highest possible platform: This way I could place the sprite 0 at the left side and didn't need to bother about timing.
But for a status bar with vertical scrolling in the new game, this would have posed a problem.
Either, I would have had to experiment with the timer to try to implement a counter that goes exactly to the end of the line, by the pixel. (A feat that not even professional games like "The Legend of Zelda" or "Journey to Silius" managed.)
Or I would have covered the rest of the line with black sprites.
Fortunately, since for dialog boxes only the name table is changed (since no scrolling is done when a dialog box is open) while the always on-screen status bar will be just a bunch of sprites, this is one less problem that I have to think about.
Is there a specific reason why this wasn't done for scrolling as well?
I mean, I cannot really imagine a situation where you do a mid-frame horizontal scrolling change and don't intend it to take place during hblank, but where you actually want the change to happen in the middle of the line.
In my previous game, where I created parallax scrolling with a sprite 0 split, I was able to circumvent the whole problem by creating the fog in a way, so that there's one continuous line of a single color above the highest possible platform: This way I could place the sprite 0 at the left side and didn't need to bother about timing.
But for a status bar with vertical scrolling in the new game, this would have posed a problem.
Either, I would have had to experiment with the timer to try to implement a counter that goes exactly to the end of the line, by the pixel. (A feat that not even professional games like "The Legend of Zelda" or "Journey to Silius" managed.)
Or I would have covered the rest of the line with black sprites.
Fortunately, since for dialog boxes only the name table is changed (since no scrolling is done when a dialog box is open) while the always on-screen status bar will be just a bunch of sprites, this is one less problem that I have to think about.
My game "City Trouble":
Gameplay video: https://youtu.be/Eee0yurkIW4
Download (ROM, manual, artworks): http://www.denny-r-walter.de/city.html
Gameplay video: https://youtu.be/Eee0yurkIW4
Download (ROM, manual, artworks): http://www.denny-r-walter.de/city.html
Re: Simple vertical scrolling with status bar
This sort of buffering was done for scrolling, but only coarse scrolling, not fine scrolling, and not forced scrolling.DRW wrote:Is there a specific reason why this wasn't done for scrolling as well?
As for why fine scroll ($2005 first write bits 2-0) wasn't buffered, here's my speculation: Extra registers for that would have cost money in three ways: engineering time to design and test, the die size to hold them, and risk of loss of first mover advantage while waiting for engineers to finish. Nintendo wanted to beat Sega to market, and price was consoles' primary advantages over home computers of the time. The workaround using blank lines between the status bar and the playfield was deemed an acceptable engineering compromise.
As for why forced scrolling ($2006-$2005-$2005-$2006) wasn't buffered, the correct write sequence for that wasn't even discovered during the NES's original commercial era (prior to 1997). I think it was discovered soon after loopy posted "The skinny on NES scrolling".
In Super Mario Bros., Vs. Super Mario Bros., and Super Mario Bros. 2 (J), the scanline between the status bar and the playfield was left blank for a similar reason. This is why the numbers in Vs. SMB and SMB2 (J) aren't as tall as the letters.In my previous game, where I created parallax scrolling with a sprite 0 split, I was able to circumvent the whole problem by creating the fog in a way, so that there's one continuous line of a single color above the highest possible platform
That's what you have to do if you want neither blank lines nor glitches. Use the forced scrolling sequence, and make sure that the last two writes come between x=256 (start of sprite fetch) and x=320 (start of next line's background fetch).experiment with the timer to try to implement a counter that goes exactly to the end of the line, by the pixel.
Re: Simple vertical scrolling with status bar
But it was... with the exception of the fine X scroll, all scroll bits are buffered (i.e. they go to the temporary address register), but due to the way that rendering works, only the horizontal bits are restored (i.e. copied from t to v) every scanline. The clean NT switch isn't necessarily a deliberate design decision, but more like a side effect of the way rendering and scrolling work. The horizontal NT bit just happens to be one of the bits that's copied from t to v every scanline.DRW wrote:Is there a specific reason why this wasn't done for scrolling as well?
Well, much like the Atari 2600 was originally designed for Pong and Combat, but ended up getting versions of Double Dragon and Ikari Warriors, which had to use the video hardware in unconventional ways to produce their visuals, Nintendo engineers certainly didn't put much thought into raster effects when designing the NES PPU. It barely has anything to help with timing effects (the sprite 0 hit is a joke) and almost everything you do to the PPU mid-screen screws up the picture.I mean, I cannot really imagine a situation where you do a mid-frame horizontal scrolling change and don't intend it to take place during hblank, but where you actually want the change to happen in the middle of the line.
It's impossible to align "by the pixel" on the NES. The exact point where the scroll change happens WILL vary over time, you just have to make sure that the variation is hidden between one scanline and the next (i.e. the first 21 or so cycles of hblank - that's equivalent to 64 pixels, which's plenty of space to hide glitches without the aid of sprites).I would have had to experiment with the timer to try to implement a counter that goes exactly to the end of the line, by the pixel. (A feat that not even professional games like "The Legend of Zelda" or "Journey to Silius" managed.)
Re: Simple vertical scrolling with status bar
By the way, this is exactly what I did now.Bregalad wrote:I know some (especially Tokumary) will disagree, but my personal opinion is that the "best way" is, by far, to do like 98% of the NES games out there : To ignore this non-issue. It is just an accepted standard to have some minour glitches on the sides of the screen, ESPECIALLY at the top and bottom.What are the best ways to do this?
What you can however do is to minimize the issue. By updating a name table row when the fine scroll is exactly 4 or 12, and an attribute table when the fine scroll is 8, you have on each side :Which is much less noticeable than what most games does (most of them have 8 pixels of wrong color AND wrong tile displayed on top and bottom).
- At maximum 4 pixels of wrong tile displayed
- At maximum 8 pixels of wrong color displayed
The scrolling is completely finished and I came to the conclusion that having four pixels of incorrect tiles and eight pixels of incorrect colors during vertical scrolling is sufficient. Doing timed code to switch the rendering on and off is not really worth the hassle, especially since I always scroll four pixels per frame anyway (i.e. the scrolling goes for one second) and it's screen-by-screen.
My game "City Trouble":
Gameplay video: https://youtu.be/Eee0yurkIW4
Download (ROM, manual, artworks): http://www.denny-r-walter.de/city.html
Gameplay video: https://youtu.be/Eee0yurkIW4
Download (ROM, manual, artworks): http://www.denny-r-walter.de/city.html