Rogue pixels

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

User avatar
sailense
Posts: 9
Joined: Wed Mar 14, 2018 6:23 pm

Rogue pixels

Post by sailense »

Hi all :)

I've been banging my head against this problem for a few days with no luck, so I'm hoping one of you guys could help me out. I'm a newbie NES programmer and I'm using ASM6 and 6502 assembly.

So far, I've done the Nerdy Nights tutorials and am trying my hand at my own game. I've got everything pretty much working and I even managed to integrate the GGSound engine without too much trouble. I added the examples from the https://wiki.nesdev.com/w/index.php/The_frame_and_NMIs page but now I have rogue pixels at the top left of my screen and I can't figure out where they're coming from.

I've moved the scroll values around and tried turning off the background, palette, sprites, etc. Turning off the palette blanks the screen so it's hard to tell if it's still there.
screenshot
screenshot
rogue-41.png (3.25 KiB) Viewed 4029 times
You can see it as red, white, and grey pixels at the top left.

Here's the basics of my code. Let me know if you need to see more. It's really just a framework with some custom and placeholder sprites.
Attachments
subroutines.asm
subroutines
(6.26 KiB) Downloaded 122 times
rogue.asm
main file
(5.25 KiB) Downloaded 120 times
User avatar
Kasumi
Posts: 1293
Joined: Wed Apr 02, 2008 2:09 pm

Re: Rogue pixels

Post by Kasumi »

Does it still happen when you render the background, but not sprites? My first guess is "sprites.spr" is not long enough, or has errors.

My second guess is something similar with rogue.nam.

The longshot:

Behold, the way to draw all the colors on the screen at once: https://wiki.nesdev.com/w/index.php/Full_palette_demo
Normally, the PPU displays the palette byte from $3F00 as the background color. When rendering is disabled and the PPU address is in the $3F00-$3FFF range, the PPU displays the palette byte at that address.
But the only way I can see that happening in the code you posted is if the sound engine wasn't set up to use unique RAM.

Another potential issue is a negative scroll value for Y, but similarly I can't see anything that would cause that except RAM collisions here.
User avatar
rainwarrior
Posts: 8732
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Rogue pixels

Post by rainwarrior »

If you would post an NES ROM as well, it would be very easy to tell what is causing any visual element that appears with a good debugging emulator (Mesen, FCEUX, Nintendulator, etc.)

The assembly files are helpful as well for diagnosing a problem, but it's much easier to just check what the ROM is actually doing than either try to reason about what a bunch of code does.
Last edited by rainwarrior on Mon Mar 19, 2018 11:16 pm, edited 1 time in total.
User avatar
dougeff
Posts: 3079
Joined: Fri May 08, 2015 7:17 pm

Re: Rogue pixels

Post by dougeff »

Top left is usually sprites that haven't been properly pushed off the screen (by setting a y value >= $f0).

If a sprite entry is left as 0,0,0,0 it will draw the #0 tile at position 0,0 (top left) using palette #0.

I'm guessing you have video settings at the default with top and bottom 8 pixels hidden.

Sprites show up 1 pixel lower on the screen, which is why you would see the bottom 8x1 slice of the sprite only. (top 8 pixels hidden, sprites shifted down 1 = 7 hidden and 1 visible).
nesdoug.com -- blog/tutorial on programming for the NES
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Rogue pixels

Post by tokumaru »

Also, as a developer, it's a good idea to configure your emulators to display all 240 scanlines (some emulators hide the top and bottom 8 scanlines by default, because some games have glitches in those areas and real TVs tend to hide some of those scanlines too), so you can see the whole picture your code is producing and detect problems that maybe you wouldn't notice otherwise.
User avatar
Sumez
Posts: 919
Joined: Thu Sep 15, 2016 6:29 am
Location: Denmark (PAL)

Re: Rogue pixels

Post by Sumez »

dougeff wrote:Top left is usually sprites that haven't been properly pushed off the screen (by setting a y value >= $f0).

If a sprite entry is left as 0,0,0,0 it will draw the #0 tile at position 0,0 (top left) using palette #0.
There's almost a 100% chance this is it. There is actually not a lot of newbie-friendly documentation out there about how to "disable" sprites, even though it should be obvious once you think about it. The NES hardware always renders 64 sprites, wether you want it or not. You can use invisible tiles, etc. for sprites you don't want the player to see, but by far the best and easiest solution is to simply push every unused sprite out of the visible area by setting the Y coordinate to something higher than 240 pixels (where you don't have to worry about the 8 sprites on a scanline limit either).

I'm assuming you're copying a full object table from a "sprite buffer" every NMI, so a good cause of this issue could be that you simply have a bunch of zeroes in your unused part of the RAM buffer, which places sprites in the top left corner like dougeff describes. A lazy way to initialize your sprite buffer if just to write $ff to every byte, but you also want to clear out unused sprites every single frame, so you don't leave old garbage ones hanging around.
User avatar
Bregalad
Posts: 8056
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

Re: Rogue pixels

Post by Bregalad »

Sumez wrote:by far the best and easiest solution is to simply push every unused sprite out of the visible area by setting the Y coordinate to something higher than 240 pixels (where you don't have to worry about the 8 sprites on a scanline limit either).
Actually using 239 ($ef) or 240 ($f0) works too. (239 works because sprites are one pixel lower than the coordinate which is used in OAM).
User avatar
sailense
Posts: 9
Joined: Wed Mar 14, 2018 6:23 pm

Re: Rogue pixels

Post by sailense »

You guys were totally right. You guys are awesome. Cheers! :beer:

I had originally zero filled my sprite table thinking that was the way to go. I went back and replaced everything but the onscreen sprites with $EF and that fixed it. And now I realize why just turning off my sprite drawing routine was also causing the error since the PPU memory would still be zero when I turned sprites on.

I've included the fixed rom file and source if anyone wants to check it out. :) Deconstructing source and rom has really helped me fill in the gaps between the tutorials and actually making a game so I'm hoping someone finds it useful.

You've also cleared up why setting my initial yscroll value to #$08 was the only way to get the screen to show properly.

I've been using FCEUX as an emulator. Is there any way to see the PPU memory values?

Next up is actually figuring out how to store, unpack, and display levels. :|
Attachments
rogue.zip
(19.13 KiB) Downloaded 118 times
rogue.nes
(40.02 KiB) Downloaded 131 times
User avatar
rainwarrior
Posts: 8732
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Rogue pixels

Post by rainwarrior »

FCEUX has an OAM (sprite memory) page in the hex editor, but it's not in the last release version (have to use a development build).

You can also use LUA scripts to help visualize where the sprites are (see included "sprites.lua", though tokumaru also wrote a really nice one).

However, Mesen and Nintendulator have dedicated OAM viewer tools which do a much better job of this, with good visual display of information.


FWIW, a lot of commercial era NES games put a value of "-8" into the Y scroll for more convenient alignment with the commonly visible picture. You could do this either with 232 (240-8) or 248 (256-8), though the latter causes garbage to appear in the extra row. You can see this in TMNT, for example, if you tell your emulator to show you the whole picture instead of cropping lines from the top and bottom.
User avatar
sailense
Posts: 9
Joined: Wed Mar 14, 2018 6:23 pm

Re: Rogue pixels

Post by sailense »

rainwarrior wrote:FCEUX has an OAM (sprite memory) page in the hex editor, but it's not in the last release version (have to use a development build).

You can also use LUA scripts to help visualize where the sprites are (see included "sprites.lua", though tokumaru also wrote a really nice one).

However, Mesen and Nintendulator have dedicated OAM viewer tools which do a much better job of this, with good visual display of information.
Great suggestions. I've downloaded both of them and the tools work great. One question though: the palette colors look way different from FCEUX. I know simulating CRT rendering isn't exact, but are there different approaches to approximating it?

rainwarrior wrote:FWIW, a lot of commercial era NES games put a value of "-8" into the Y scroll for more convenient alignment with the commonly visible picture. You could do this either with 232 (240-8) or 248 (256-8), though the latter causes garbage to appear in the extra row. You can see this in TMNT, for example, if you tell your emulator to show you the whole picture instead of cropping lines from the top and bottom.
I'm still trying to wrap my head around this. Do you mean treating y-scroll value as a signed int? Or wrapping around?


BTW: I loved Lizard :)
User avatar
rainwarrior
Posts: 8732
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Rogue pixels

Post by rainwarrior »

sailense wrote:I'm still trying to wrap my head around this. Do you mean treating y-scroll value as a signed int? Or wrapping around?
Sort of both. Yes, wrapping around, but in two's complement representation, a signed byte -8 is the same as an unsigned byte 256-8 (248).

The NES picture also wraps to the next screen at Y=240, though, so it has two wrapping points, which is weird. (It's supposed to skip over 240-255, where the attribute data is stored, but if you start inside that range it will render a few lines of garbage data from it.)
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Rogue pixels

Post by tokumaru »

Yeah, a Y scroll of 248 or 232 will result in the same picture from scanline 8 onwards, but scanlines 0-7 will be different: 248 will show garbage (attribute table data interpreted as name table data), 232 will show the bottom row of the name table.
User avatar
sailense
Posts: 9
Joined: Wed Mar 14, 2018 6:23 pm

Re: Rogue pixels

Post by sailense »

I think I get :) This thread helped alot too viewtopic.php?f=10&t=17014

Right now I'm resetting scoll values in all my subroutines where I write to $2006. Is that the best way to go? And when is the best time to read from controller? Every NMI or during the main loop?
User avatar
rainwarrior
Posts: 8732
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Rogue pixels

Post by rainwarrior »

sailense wrote:Right now I'm resetting scoll values in all my subroutines where I write to $2006. Is that the best way to go? And when is the best time to read from controller? Every NMI or during the main loop?
I can think of theoretical situations where someone might want to read and use input in the NMI, but in general there's no reason to read the controller more often than you do something with those read values, so probably I'd suggest main loop.
User avatar
sailense
Posts: 9
Joined: Wed Mar 14, 2018 6:23 pm

Re: Rogue pixels

Post by sailense »

rainwarrior wrote:
sailense wrote:Right now I'm resetting scoll values in all my subroutines where I write to $2006. Is that the best way to go? And when is the best time to read from controller? Every NMI or during the main loop?
I can think of theoretical situations where someone might want to read and use input in the NMI, but in general there's no reason to read the controller more often than you do something with those read values, so probably I'd suggest main loop.
Perfect. Thanks so much. :)
Post Reply