Question about graphical glitch when changing screens

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

Post Reply
User avatar
NeverCameBack
Posts: 41
Joined: Mon Feb 24, 2020 12:22 am

Question about graphical glitch when changing screens

Post by NeverCameBack » Sat Aug 15, 2020 9:58 pm

In my prototype game, whenever I go to a new screen, or open the text box by pressing B, I get a one frame flash of the last BG screen, moved down by about half. Through trial and error I found out it is because of this bit:

LDA #%00010110
STA $2001

Which is the bit to enable / disable sprite rendering.

If I turn it off before loading the BG graphics into the PPU, I get the one frame glitch flash when changing screens.
If I leave it on, I get garbled BG graphics.

Anyone know what is wrong here?

When a new BG is to be drawn, I first load the BG pointers with the address of the BG to be loaded. Then go to a forever loop. Next NMI, the NMI, BG rendering, and sprite rendering are disabled. The PPU status is read to reset the latches, then the $2007 bus is loaded with the 1024 bytes of BG data. After this, NMI, BG and sprite rendering are re-enabled, and we go back to the forever loop. Next time an NMI hits, it will skip the above unless a new BG is being called for.
Attachments
Incandesant_Gaze_v0_41.asm
(123.79 KiB) Downloaded 17 times
Incandesant_Gaze_v0_41.nes
(64.02 KiB) Downloaded 19 times

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

Re: Question about graphical glitch when changing screens

Post by tokumaru » Sat Aug 15, 2020 10:09 pm

That's probably because you're enabling rendering mid-screen, as soon as you're finished copying the data, causing the picture to be drawn lower down the screen for a frame. To fix this you have to wait until vblank to turn rendering back on, so that the following frame is drawn in full.

It's not recommended that you poll the vblank flag in $2002 though, as that doesn't work very reliably. The best option is to not write to $2001 directly, but write the value to a variable instead, and at the end of your NMI handler (which should run every vblank) you write the buffered value to the actual $2001 register.

User avatar
NeverCameBack
Posts: 41
Joined: Mon Feb 24, 2020 12:22 am

Re: Question about graphical glitch when changing screens

Post by NeverCameBack » Sat Aug 15, 2020 10:43 pm

You've done it again, It looks like that worked. I made it so that at after loading up the PPU with BG data, I only renable the NMI, not the rendering. Next NMI, the first thing that is done is enable the BG and Sprite rendering. I'm still writing to $2001 directly though - Were you suggesting to do something like load a variable with #%00100000 and add it to $2001 at some point?

The only problem I have now, which I'll look into is a quick black screen flashes when my "text box" appears. Which is fine when moving to a new screen, but I've probably seen other games pull up a text box without having this flash. The way I'm doing the text box is that when it's called to appear, the PPU is loaded up with 1024 bytes again. Only this time, about halfway through the loading of the BG bytes to $2007, a second loop comes in and loads the remainder of the screen with the "text box" BG data. Then a third loop comes in and loads the attributes of the current BG.

Do you think games usually pull this off using sprite 0, or maybe loading the PPU with some data somewhere in the middle of the stack? I can't think of how to do that, or if it can be done - since we can only write to the $2007 bus, and the PPU increments it self automatically. There seems no way to write to a specific BG tile in the ppu without reloading the whole thing.

calima
Posts: 1186
Joined: Tue Oct 06, 2015 10:16 am

Re: Question about graphical glitch when changing screens

Post by calima » Sat Aug 15, 2020 11:51 pm

They use a buffer that is written there during vblank. See set_vram_update in neslib.

It's all good to do these things manually for your own learning, but eventually you want to use neslib or similar.

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

Re: Question about graphical glitch when changing screens

Post by tokumaru » Sun Aug 16, 2020 12:09 am

NeverCameBack wrote:
Sat Aug 15, 2020 10:43 pm
I'm still writing to $2001 directly though - Were you suggesting to do something like load a variable with #%00100000 and add it to $2001 at some point?
Yes, this is a simple way to guarantee that $2001 will only be written during vblank. I don't know much about how your code is structured though, so if you think you can guarantee that some other way, that's probably OK too. I personally don't like to turn NMIs on and off, since there are side effects to writing to $2000 mid-frame (i.e. the infamous glitchy line in SMB) and you can't keep the sound going during load time if NMIs are off. I keep NMIs enabled at all times, and selectively do tasks based on flags (e.g. I don't touch any PPU registers if the respective flag doesn't say it's safe to do that).
The way I'm doing the text box is that when it's called to appear, the PPU is loaded up with 1024 bytes again. Only this time, about halfway through the loading of the BG bytes to $2007, a second loop comes in and loads the remainder of the screen with the "text box" BG data. Then a third loop comes in and loads the attributes of the current BG.
Well, 1024 bytes is a lot of data, way more than can be transferred during vblank... you can do around 200 bytes with reasonably optimized code, any more than that and you have to turn rendering off and lose a frame. What you can do is see if you can squeeze just the updates for the text box itself in a single vblank. Another option is to make use of the alternate name table (i.e. the part of the name tables that are not visible), drawing the new screen progressively across multiple vblanks and switching to it when it's ready, or drawing only the text box and using a scroll split to display it.
Do you think games usually pull this off using sprite 0, or maybe loading the PPU with some data somewhere in the middle of the stack?
Debugging the name tables in FCEUX or Mesen should give you a clue as to how different games do it. Games where these boxes smoothly scroll in certainly use scroll splits and the off-screen name table.
I can't think of how to do that, or if it can be done - since we can only write to the $2007 bus, and the PPU increments it self automatically. There seems no way to write to a specific BG tile in the ppu without reloading the whole thing.
You don't need to update the whole thing, you can start from anywhere in the name table, and go sequentially from there.

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

Re: Question about graphical glitch when changing screens

Post by tokumaru » Sun Aug 16, 2020 12:11 am

calima wrote:
Sat Aug 15, 2020 11:51 pm
They use a buffer that is written there during vblank. See set_vram_update in neslib.

It's all good to do these things manually for your own learning, but eventually you want to use neslib or similar.
He's using ASM though, right...?

User avatar
NeverCameBack
Posts: 41
Joined: Mon Feb 24, 2020 12:22 am

Re: Question about graphical glitch when changing screens

Post by NeverCameBack » Sun Aug 16, 2020 1:18 am

Yes ASM., and NESASM3 as the compiler. The Nerdy Nights "suite" of tools. This is my first programming language, aside from some industrial stuff. It sounds like the tools in nsdlib-master are for use with a higher level language? I can't make heads or tails of anything inside of the folders.

Eventually I will try like you said, loading the text box onto the second name table (off screen) and then scrolling that portion over, or up, using sprite 0. My main goal now is to add in all the boundaries, and most importantly come up with some music to put in it!

Speaking of that, my plan is to write music in Famitracker, and then piece by piece copy it over to the format that the Nerdy Nights sound engine I'm using would read it. It sounds like there is no other sound engine written for NESASM3 that would read an exported Famitracker track. Know of anything?

Pokun
Posts: 1511
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: Question about graphical glitch when changing screens

Post by Pokun » Sun Aug 16, 2020 4:24 pm

NeverCameBack wrote:
Sun Aug 16, 2020 1:18 am
Speaking of that, my plan is to write music in Famitracker, and then piece by piece copy it over to the format that the Nerdy Nights sound engine I'm using would read it. It sounds like there is no other sound engine written for NESASM3 that would read an exported Famitracker track. Know of anything?
I think there are too many differences between the sound engines for that to be practical and might not even be possible. If you want to make music using a tracker you probably either have to stick with a Famitracker engine or make a tracker for the engine you want to use (which isn't very easy since you don't know any other programming languages). And there is none for the Nerdy Nights sound engine AFAIK, you make music in an MML-like language in that.

tepples
Posts: 22049
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Question about graphical glitch when changing screens

Post by tepples » Sun Aug 16, 2020 5:41 pm

an MML-like language
NovaSquirrel managed to make ft2pently to convert a FamiTracker text export to a score in an MML-like language, which in turn compiles to Pently bytecode (which is documented). Is there any analogous documentation for the bytecode accepted by the Nerdy Nights driver, other than the entirety of the tutorial itself?

User avatar
NeverCameBack
Posts: 41
Joined: Mon Feb 24, 2020 12:22 am

Re: Question about graphical glitch when changing screens

Post by NeverCameBack » Sun Aug 16, 2020 8:13 pm

[/quote]If you want to make music using a tracker
[/quote]

Do you mean there is another way to generate NES music data to be used in a game other than a tracker program? All I could think would be composing your own music the old fashioned way, writing the notes out, and inputing it one note at time into your code.

User avatar
NeverCameBack
Posts: 41
Joined: Mon Feb 24, 2020 12:22 am

Re: Question about graphical glitch when changing screens

Post by NeverCameBack » Sun Aug 16, 2020 8:16 pm

Is there any analogous documentation for the bytecode accepted by the Nerdy Nights driver, other than the entirety of the tutorial itself?
I actually did not finish the audio tutorial - so I should probably hold back on asking. They may detail how to input your music into the sound engine. Jumping ahead, I put some of the notes from one of the sample songs into Famitracker and got a similar tune... So either way it'll be a matter of time before I can figure out the format to feed the data to the Nerdy Nights sound engine.

User avatar
Bregalad
Posts: 7951
Joined: Fri Nov 12, 2004 2:49 pm
Location: Chexbres, VD, Switzerland

Re: Question about graphical glitch when changing screens

Post by Bregalad » Mon Aug 17, 2020 2:52 am

Just as a side note, commercial, Nintendo-licenced games who display a glitchy frame when enabling the screen back are common :)
tokumaru wrote:
Sat Aug 15, 2020 10:09 pm
It's not recommended that you poll the vblank flag in $2002 though, as that doesn't work very reliably.
It's not recommended during gameplay, but for enabling back the screen there's no consequence if a frame is randomly missed so polling $2002.7 is just fine, if NMI was disabled.
Useless, lumbering half-wits don't scare us.

Pokun
Posts: 1511
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: Question about graphical glitch when changing screens

Post by Pokun » Mon Aug 17, 2020 9:53 am

tepples wrote:
Sun Aug 16, 2020 5:41 pm
an MML-like language
NovaSquirrel managed to make ft2pently to convert a FamiTracker text export to a score in an MML-like language, which in turn compiles to Pently bytecode (which is documented). Is there any analogous documentation for the bytecode accepted by the Nerdy Nights driver, other than the entirety of the tutorial itself?
I don't think so. It's more of a tutorial for teaching beginners how you can code a sound engine rather than a complete sound engine. It's actually incomplete, but it's still very sophisticated and by far good enough to make music and sound effects in a game with. Many people started with it and built it into a more complete sound engine though, and maybe some of those are documented.
You probably don't need to read the whole tutorial. The actual sound engine building starts in week 4 "sound engine skeleton". Everything before that are just the basics.


NeverCameBack wrote:
Sun Aug 16, 2020 8:13 pm
Do you mean there is another way to generate NES music data to be used in a game other than a tracker program? All I could think would be composing your own music the old fashioned way, writing the notes out, and inputting it one note at time into your code.
The two main ways that professional developers use are MML (Music Macro Language) and tracker. Writing music in an MML is basically like writing notes the traditional way, but by using characters on the keyboard. If you in a typical BASIC/MML interpreter enter: PLAY "CDEF" it will play notes C, D, E and F in that order for the currently selected octave, tempo and volume settings. There may be special symbols like R for rest notes and # for the sharp symbol for example. In other words, it's very similar to how you are composing music for the Nerdy Nights sound tutorial sound engine. The tutorial uses labels for all the notes that you can use in a very MML-like fashion. You could probably relatively quite easily code your own MML-interpreter that is compatible with that sound engine.

This forum is dominated by trackers so that's what you hear about a lot here, but some people (like me) greatly prefers MML (or anything that isn't a tracker). It might have something to do with what you grew up with. Commodore BASIC and Spectrum's BASIC both lacked both an MML and a video macro language for a long time while MSX BASIC had both from day 1 (MSX1 was also a later computer than C64 though). Trackers were a popular alternative on those computers at that time. That might be why Commodore-dominated countries (like USA) generally prefer trackers, while MSX-dominated countries like south America, south/east Europe and parts of Asia (especially Japan) generally prefers an MML. This is just my theory, it might be totally wrong. I'm Swedish, and Sweden was Commodore- and Nintendo-dominated in the '80s, just like USA (although MSX1 and ZX Spectrum also both certainly had a presence in Scandinavia), but I only had a NES at that time so I wouldn't know (I also have an MSX2+ now BTW).

Both MSX BASIC and Family BASIC were commonly used for professional game development of NES games, since the MSX PSG is quite similar to the NES APU it was possible to use the MSX MML for prototyping the music with. Family BASIC was great because it allows you to use an MML directly on the real hardware and play it instantly, and I'm pretty sure at least Koji Kondo used it a lot when composing music for games.

For modern MML solutions for NES, there are ppMCK (made for NESASM, but mostly for making NSFs with) and NSD.Lib made for ca65. And as Tepples said, his sound engine Pently has some kind of MML-like alternative.

tepples
Posts: 22049
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Question about graphical glitch when changing screens

Post by tepples » Mon Aug 17, 2020 11:41 am

Users of Frescobaldi, an editor for sheet music scores in the LilyPond language, may also prefer MML because of its conceptual similarity to LilyPond. This similarity led me to borrow from both when designing the Pently score language (example).

Post Reply