question regarding darwing while scrolling

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
question regarding darwing while scrolling
by on (#184023)
I'm able to draw tiles vertically while initializing a scroll, the nametable address is always updated and drawn at the right location.

However, I have such a noticeable gap until the next vertical line is drawn.

What I do is I load my X scanline, perform an AND of #$07, and then I branch to the drawing routine.

Is there anyway to make this less noticeable on the rightmost portion of the screen?

Here is a video of my work to show what i'm talking about.

https://youtu.be/K26NbUwG0RA
Re: question regarding darwing while scrolling
by on (#184033)
I knew exactly what you meant before I saw the video. So, the obvious solution is draw new tiles further to the right, so that changes aren't apparent. (Also, draw the first column, or two, before the screen is turned on at the start).

[Note, typo in title. Only you can fix it]
Re: question regarding darwing while scrolling
by on (#184036)
That's a scroll seam. Normally you'd want to place that seam off screen, by keeping your scroll engine a bit ahead of the camera. The NES has 2 name tables you can use, so there's plenty of room where to hide that seam. That is, until you need to scroll diagonally, because with 2 name tables you can only have extra room in one axis, so unless you have extra name table memory (4-screen) or use clever tricks, there will be glitches.
Re: question regarding darwing while scrolling
by on (#184037)
The $2001 register has two bits that can be used to hide the left 8 pixels of the screen, which would be enough to solve your problem, at least until attributes get involved. A lot of games use this. (TMNT and Alfred Chicken even put a big black bar of sprites on the right hand side to hide another 8 pixels.)
Re: question regarding darwing while scrolling
by on (#184038)
rainwarrior wrote:
The $2001 register has two bits that can be used to hide the left 8 pixels of the screen, which would be enough to solve your problem, at least until attributes get involved.

If you're stuck with horizontal or 1-screen mirroring, you'll definitely want to this. Otherwise, you can try this for a quick fix, but the better option would be to use vertical mirroring (or 4-screen) and draw your updates in the vast off screen areas.

Quote:
(TMNT and Alfred Chicken even put a big black bar of sprites on the right hand side to hide another 8 pixels.)

Felix the Cat is another example.
Re: question regarding darwing while scrolling
by on (#184041)
I'm using horizontal mirroring for this test, I know of the $2001 bits for the leftmost part of the screen, i disabled it for the video. I realize I will get some visual of the next line being drawn, I was just hoping it would be like Mario 3 where it's maybe 3 pixels wide of the next line being drawn, and not like what you see in my video.
Re: question regarding darwing while scrolling
by on (#184042)
Mario 3 hides the left 8 pixels. As rainwarrior pointed out, you can entirely hide the tile errors behind those hidden 8 pixels, even though Mario 3 actually fails to hide them.

If you don't want to hide the leftmost 8 pixels, you just offset updates by half a tile. What this gets you is the new column not being updated until it's 3 or 4 pixels on screen. The left and right of the screen would share the error area.

I can't tell if you want the left 8 pixels hidden for the final or not, but regardless you can actually just brute force pixel offsets added to the code that checks for a new column to find the best solution. There are very few values to try.

Edit: GIFs! Linked because they're biggish.

This is a 4 way scrolling engine with horizontal mirroring and the left 8 pixels hidden: http://i.imgur.com/tvTgLtu.gif

You will never see a wrong tile on either side of the screen. Wrong palette stuff, sure.

This is the same 4 screen scrolling engine with horizontal mirroring and the left 8 pixels shown: http://i.imgur.com/fp550Az.gif

You'll notice that there are CONSTANTLY errors on the left side of the screen. That's why it's being hidden!

This is the same 4 screen scrolling engine with horizontal mirroring and the left 8 pixels shown, with tile updates offset by -4: http://i.imgur.com/HwHWYUj.gif

You'll see tile errors on both the right and left. You have to scroll a few pixels to get the new column in either direction. (-4 is not necessarily the right value for this or any other engine. This seems to have more errors on the left than right.) This was just a quick hack, though. A possible setback is left and right no longer want to update a similar tile. (I remember having trouble with something like that when I offset the attributes to split the error between left+right, but it has been a while.)

Anyway, I don't just mean to show, "Look what I can do!". But without seeing your code, all I can say is try to offset when the updates happen to accomplish whatever looks best for your goal (hide left 8 pixels vs show 8 pixels ). Maybe seeing the where the column updates happen in relation to the scroll position in the above gifs will give you an idea of how you need to offset for whatever you're doing.

Edit 2: The way to think about it (assuming you want to hide the pixels) is, you're at the very top left of the screen. The left 8 pixels of your level will NEVER be shown, so at that scroll position, you want columns 1 through 32 of it in the nametable, rather than 0 through 31. Then every 8 pixels, you draw a new column.

If you want to show the pixels, well, I don't have a good way to think about it because I've never done that.
Re: question regarding darwing while scrolling
by on (#184051)
The way a scrolling engine works depends on the name table layout. You should decide what type of name table mirroring you're gonna use, taking into consideration how you want your camera to move, and then code the actual drawing of the tiles.

With horizontal or single-screen mirroring it's impossible to get clean horizontal scrolling. The PPU can hide the leftmost 8 pixels so you can hide the updates there, but attribute updates need 16 pixels to be hidden, so unless you use a single background palette or hide another 8 pixels using sprites, like Alfred Chicken and Felix the Cat do, there will be color glitches.

Vertical mirroring will give you 100% glitch-free scrolling, because you get a 256-pixel wide area where to hide the updates. Capcom games such as The Little Mermaid or DuckTales take advantage of this by progressively updating large 32x32 metatiles, instead of thin columns of tiles. Look at those games in FCEUX's name table viewer as they scroll, it's fun to look at.

Things start to get really messy when you need 4/8-way scrolling, because then you have to choose where to put the glitches, or resort to complex tricks to hide all the nasty stuff. I once spent a lot of time designing an engine that would hide all the scrolling glitches, and the result was pretty convoluted... Then I resized that adding more name table RAM to a cartridge can be so trivial (if you're using CHR-RAM, at least) that I said "fuck it" and started working with 4 screens.
Re: question regarding darwing while scrolling
by on (#184118)
Ok I believe I've managed to make it so only 3 to 4 pixels appear on the rightmost side of the screen, before the new line is drawn. It looks pretty good in fluid motion.

My project is to use 8 way scrolling with horizontal mirroring, much like Mario 3. I draw vertically down from the $2000 Nametable, and into the $2800 Nametable till I reach just above the IRQ split at $2B00.

So right now I only have my code working while going to the right. But I just discovered another issue.

Theres going to be a point in my project, where my game is going to start within the $2800 Nametable. I went to perform a test of that, and the tiles are drawn, but for some reason the $2000 Nametable will pop up for a brief millisecond for some reason?

Here is a video of it. The video stars with the $2000 Nametable functioning normally. The 2nd half of the video will cut to the $2800 Nametable, showing the issue I have.

https://youtu.be/DLMWjdvG7Qo


EDIT
hmm, here is a diagonal scroll showing my $2800 Nametable going upwards to the $2000 Nametable. I get the glitches here too.

https://youtu.be/KA803Gdghug

Sorry if the videos don't do the glitch justice, its way more noticeable on my end then the video(s) are showing.
Re: question regarding darwing while scrolling
by on (#184121)
One potential cause is the writes taking too long.

But posting code would help us help you.
Re: question regarding darwing while scrolling
by on (#184122)
infidelity wrote:
I went to perform a test of that, and the tiles are drawn, but for some reason the $2000 Nametable will pop up for a brief millisecond for some reason?

Are you by any chance writing zeroes to $2006 before rendering starts? That would override the name table selection if done after the $2000 write which is normally used to select the starting name table.
Re: question regarding darwing while scrolling
by on (#184124)
Code:
LDX #$00
LDA $380      ;contains 20
STA $2006
LDA $381
STA $2006    ;contains 00
LDA $FF     ;current nametable
ORA #$04
STA $2000
LDA,x $382
STA $2007
LDA,x $383
STA $2007
LDA,x 384
STA $2007
LDA,x $385
STA $2007
LDA,X $386
STA $2007
INX
INX
INX
INX
INX
CPX #$1E
BNE #$D9 ;to LDA,x $382 (I don't write code, so I know this looks incorrect here)
LDA $380
ORA #$08
STA $2006
LDA $381
STA $2006
LDA,x $382
STA $2007
LDA,x $383
STA $2007
LDA,x $384
STA $2007
LDA,x $385
STA $2007
INX
INX
INX
INX
CPX #$36
BNE #$E0 (to LDA,x $382)
INC $381
LDA $381
CMP #$20
BNE #$05 (to LDA #$00 STA $2006)
LDA #$00
STA $381

for some reason, I"ve needed to include this so that when scrolling, there is no flucuation
LDA #$00
STA $2006


So that's the drawing routine
Re: question regarding darwing while scrolling
by on (#184144)
As I suspected, that last write to $2006 is most definitely clearing your name table bit (along with part of the vertical scroll, but you won't notice that if you're using a vertical scroll of 0), effectively selecting name table 0. I see a lot, and I mean A LOT of people writing to $2006 after their VRAM updates hoping to stabilize the scroll, but that's just WRONG. For some reason, even experienced coders in this very board keep suggesting that to beginners, probably because in some simple cases that does indeed work as a quick fix, but it's still the wrong way to set the scroll.

The registers meant for manipulating the scroll are $2000 and $2005. If you're not using forced blanking or doing mid-screen vertical scroll changes, you should stick to using $2006 exclusively for writing to (or reading from) VRAM, which is its intended purpose. The use of $2006 for scrolling is an exception, a hack, an exploit of the way the scroll works internally to do something the designers of the PPU didn't plan for.

Please try removing that $2006 write, and replace it with a proper $2000 write selecting the correct name table, followed by 2 $2005 writes defining the scroll values within the selected name table.

EDIT: Seriously, we have to find a way to stop people from using $2006 for scroll purposes without necessity. I partially blame "The Skinny on NES Scrolling" for this, because it's often presented in a way that suggests you HAVE to use the information in that document to have any scrolling at all in your programs, which isn't the case at all. If a newbie has doubts about scrolling, please don't point them to "The Skinny", that's NOT what they need. Emulator authors, sure, they have to know that stuff because they have to deal with all kinds of scroll exploits, but someone trying to make their first side scroller? Definitely not. Using $2006 for scrolling is not only harder than the official $2000/$2005 way, but it's also incomplete if you don't snuck in a $2005 to set the fine X scroll, which $2006 doesn't touch.
Re: question regarding darwing while scrolling
by on (#184145)
tokumaru wrote:
The registers meant for manipulating the scroll are $2000 and $2005. If you're not using forced blanking or doing mid-screen vertical scroll changes, you should use $2006 exclusively for writing to VRAM, which is its intended purpose. The use of $2006 for scrolling is an exception, a hack, an exploit of the way the scroll works internally to do something the designers of the PPU didn't plan for.

I'll have to disagree with you there. There is loopy T and loopy V, and fine X. Whatever method you use to set them is fine, as long as they are set correctly.
Re: question regarding darwing while scrolling
by on (#184146)
Dwedit wrote:
I'll have to disagree with you there. There is loopy T and loopy V, and fine X. Whatever method you use to set them is fine, as long as they are set correctly.

I agree that if you know how these work, they can be very useful for scroll manipulation and their use for this purpose is perfectly valid. However, this is not something you go blindly suggesting newbies use, because more often than not, they use it wrong. I don't blame them, this is fairly complex if you're not familiar with the process the PPU uses to render pictures. A lot of people just don't know WHY they're using $2006, they just tried it out of desperation because their screens were unstable. This is the kind of thing we shouldn't encourage.
Re: question regarding darwing while scrolling
by on (#184147)
tokumaru wrote:
we have to find a way to stop people from using $2006 for scroll purposes without necessity. I partially blame "The Skinny on NES Scrolling" for this, because it's often presented in a way that suggests you HAVE to use the information in that document to have any scrolling at all in your programs, which isn't the case at all. If a newbie has doubts about scrolling, please don't point them to "The Skinny", that's NOT what they need.

That's why the current iteration of "skinny" on the wiki spends a whole section, titled "The common case", on explaining that setting $2005 and $2000 as last thing in vblank is enough if you're not splitting.

Dwedit: It's about what method of setting T and X is easiest for a novice to understand. And for games that don't use a lot of splits, that's the $2005-$2005-$2000 sequence, not the $2006-$2005-$2005-$2006 sequence.
Re: question regarding darwing while scrolling
by on (#184148)
Do the Nerdy Nights tutorials use $2006 to clear the scroll? If so, that could definitely have an influence on the number of misguided uses of this register we come across on this board.

tepples wrote:
Dwedit: It's about what method of setting T and X is easiest for a novice to understand. And that's the $2005-$2005-$2000 sequence, not the $2006-$2005-$2005-$2006 sequence.

Precisely. One method is intuitive, the other can really only be understood if you know the little dirty secrets of the PPU.
Re: question regarding darwing while scrolling
by on (#184199)
tokumaru wrote:
Please try removing that $2006 write, and replace it with a proper $2000 write selecting the correct name table, followed by 2 $2005 writes defining the scroll values within the selected name table.


I'll do as you suggest later today. My project is only going to use an mmc3 Irq to display a stationary status bar.

I've already completed 1 custom game from scratch, but now my 2nd project I'm moving onto having the screen drawn while it moves either left or right. I'm hoping to develop a platformer, but I'm taking my goals one at a time. My Super Mario All-Stars NES project, demonstrates my beginnings of drawing vertically while the screen scrolls (when cycling through the game list).

I've been on some sort of mission to start coding my own games, I'm getting more and more fascinated in it, and look forward to sharing my latest work.

But I'm slowly working and learning on how to get my drawing and scrolling to coexist, once that's done, I'll need to figure out how to define certain blocks, like if it's air or solid or water or a ladder or breakable, etc.

EDIT

The suggested changes did the trick. :-)

https://youtu.be/NE4cm-wSboo