It is currently Tue Jun 19, 2018 7:44 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 19 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Rogue pixels
PostPosted: Mon Mar 19, 2018 9:26 pm 
Offline
User avatar

Joined: Wed Mar 14, 2018 6:23 pm
Posts: 9
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.

Attachment:
File comment: screenshot
rogue-41.png
rogue-41.png [ 3.25 KiB | Viewed 1065 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:
File comment: subroutines
subroutines.asm [6.26 KiB]
Downloaded 27 times
File comment: main file
rogue.asm [5.25 KiB]
Downloaded 23 times
Top
 Profile  
 
 Post subject: Re: Rogue pixels
PostPosted: Mon Mar 19, 2018 10:15 pm 
Offline
User avatar

Joined: Wed Apr 02, 2008 2:09 pm
Posts: 1149
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
Quote:
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.

_________________
https://kasumi.itch.io/indivisible


Top
 Profile  
 
 Post subject: Re: Rogue pixels
PostPosted: Mon Mar 19, 2018 11:05 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 6342
Location: Canada
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.

Top
 Profile  
 
 Post subject: Re: Rogue pixels
PostPosted: Mon Mar 19, 2018 11:12 pm 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 2091
Location: DIGDUG
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


Top
 Profile  
 
 Post subject: Re: Rogue pixels
PostPosted: Tue Mar 20, 2018 12:02 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10513
Location: Rio de Janeiro - Brazil
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.


Top
 Profile  
 
 Post subject: Re: Rogue pixels
PostPosted: Tue Mar 20, 2018 3:05 am 
Offline
User avatar

Joined: Thu Sep 15, 2016 6:29 am
Posts: 613
Location: Denmark (PAL)
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.


Top
 Profile  
 
 Post subject: Re: Rogue pixels
PostPosted: Tue Mar 20, 2018 4:09 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7436
Location: Chexbres, VD, Switzerland
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).


Top
 Profile  
 
 Post subject: Re: Rogue pixels
PostPosted: Tue Mar 20, 2018 4:36 pm 
Offline
User avatar

Joined: Wed Mar 14, 2018 6:23 pm
Posts: 9
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 20 times
rogue.nes [40.02 KiB]
Downloaded 29 times
Top
 Profile  
 
 Post subject: Re: Rogue pixels
PostPosted: Tue Mar 20, 2018 4:49 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 6342
Location: Canada
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.


Top
 Profile  
 
 Post subject: Re: Rogue pixels
PostPosted: Tue Mar 20, 2018 5:16 pm 
Offline
User avatar

Joined: Wed Mar 14, 2018 6:23 pm
Posts: 9
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 :)


Top
 Profile  
 
 Post subject: Re: Rogue pixels
PostPosted: Tue Mar 20, 2018 5:32 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 6342
Location: Canada
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.)


Top
 Profile  
 
 Post subject: Re: Rogue pixels
PostPosted: Tue Mar 20, 2018 6:31 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10513
Location: Rio de Janeiro - Brazil
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.


Top
 Profile  
 
 Post subject: Re: Rogue pixels
PostPosted: Tue Mar 20, 2018 7:36 pm 
Offline
User avatar

Joined: Wed Mar 14, 2018 6:23 pm
Posts: 9
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?


Top
 Profile  
 
 Post subject: Re: Rogue pixels
PostPosted: Tue Mar 20, 2018 7:46 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 6342
Location: Canada
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.


Top
 Profile  
 
 Post subject: Re: Rogue pixels
PostPosted: Tue Mar 20, 2018 7:53 pm 
Offline
User avatar

Joined: Wed Mar 14, 2018 6:23 pm
Posts: 9
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. :)


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 19 posts ]  Go to page 1, 2  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 4 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