It is currently Mon Oct 15, 2018 10:33 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 7 posts ] 
Author Message
PostPosted: Tue Aug 21, 2018 11:36 pm 
Offline

Joined: Tue Aug 21, 2018 11:23 pm
Posts: 2
I'm following the nerdy nights series. I created / finished the pong game. When the game finishes, I display GAME OVER using background tiles.
The user can press Start to restart the game. When they do, I overwrite the GAME OVER tiles with a solid tile (ie: no letter).
However, for some reason, the screen briefly displays a bunch of zeros (Tile #$00) on half the screen before looking normal again.

I'm new to NES programming (but not to programming in general).
Has anyone else seen this before?

Thanks!

TriForced


Top
 Profile  
 
PostPosted: Wed Aug 22, 2018 12:17 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10892
Location: Rio de Janeiro - Brazil
It could be that you're writing to VRAM while the PPU is trying to use that same VRAM to render the image, and the VRAM can't be written to and read from at the same time, so you get visual glitches.

Whenever you have to redraw large portions of the screen, an operation that takes a lot of time, you have to disable rendering so the PPU won't touch the video memory, and you have full access to it. When you're done, turn rendering back on.

Small updates can be done with rendering on, as long as they're done during vblank, a time during which the PPU doesn't touch VRAM. That's how games that scroll work, they draw only the new parts of the background right before they scroll into view.


Top
 Profile  
 
PostPosted: Wed Aug 22, 2018 12:38 am 
Offline

Joined: Tue Aug 21, 2018 11:23 pm
Posts: 2
That worked tokumaru; thanks for the response!
Out of curiosity: how many background tiles can I update without having to disable rendering?


Top
 Profile  
 
PostPosted: Wed Aug 22, 2018 1:02 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10892
Location: Rio de Janeiro - Brazil
In NTSC, vblank lasts 20 scanlines, or 2273 CPU cycles. Different types of loops will execute at different speeds, so there's not a definitive answer to your question... Writing to VRAM can be as fast as 6 cycles per byte (example A), as slow as 17 cycles per byte (example B), or even slower.

Example A:
Code:
  lda #$00 ;2 cycles
  sta $2007 ;4 cycles
  lda #$05
  sta $2007
  (...)


Example B:
Code:
  ldy Start
CopyByte:
  lda (Pointer), y ;5 cycles
  sta $2007 ;4 cycles
  iny ;2 cycles
  cpy End ;3 cycles
  bne CopyByte ;3 cycles


You also have to consider all the other operations that may take place during vblank, such as the sprite DMA, setting the scroll, and so on. In most cases, you should be able to update at least 100 bytes of VRAM, but you can do better than that with more optimized code.

Avoid single-byte loops like in example B like the plague if you're going for speed! Avoid indirect addressing (keep your update buffer under 256 bytes and use absolute/indexed addressing). If using indices/counters, count down instead of up and avoid the CPX/CPY. Unroll loops whenever possible, even if partially.


Top
 Profile  
 
PostPosted: Wed Aug 22, 2018 11:23 am 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3629
Location: Mountain View, CA
Another possibility isn't the amount of data being transferred during NMI/VBlank, but that PPU scroll aren't "reset" before the start of the next drawing cycle, e.g. lda #$00 / sta $2005 / sta $2005 may be needed at end of NMI routine to ensure "junk" isn't printed on the screen when the PPU begins drawing again. Most recent thread we have about that: viewtopic.php?f=10&t=17680


Top
 Profile  
 
PostPosted: Wed Aug 22, 2018 12:09 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10892
Location: Rio de Janeiro - Brazil
That's right. To completely avoid these kinds of glitches, you have to be sure to only manipulate the PPU during vblank (even turning rendering on/off should be done during vblank to avoid the drawing of misaligned partial frames), and always set the scroll after you're done manipulating the PPU but before rendering starts.


Top
 Profile  
 
PostPosted: Wed Aug 22, 2018 12:31 pm 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7546
Location: Chexbres, VD, Switzerland
koitsu wrote:
Another possibility isn't the amount of data being transferred during NMI/VBlank, but that PPU scroll aren't "reset" before the start of the next drawing cycle, e.g. lda #$00 / sta $2005 / sta $2005 may be needed at end of NMI routine to ensure "junk" isn't printed on the screen when the PPU begins drawing again

*cough cough* Final Fantasy II *cough cough*


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: Google Adsense [Bot] and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group