It is currently Thu Dec 13, 2018 4:23 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 10 posts ] 
Author Message
 Post subject: Sprite wackyness
PostPosted: Thu Oct 11, 2018 6:04 pm 
Offline
User avatar

Joined: Wed Sep 05, 2018 11:13 am
Posts: 152
Location: Colorado
So I've been messing around working on an Asteroids game, and I'm getting some sprite wackyness when I fire more than a single bullet at a time. I'm stepping through my NMI code and looking at the OAM data and everything looks like it's ok to me. I'm guessing I'm doing something stupid/simple that I'm just not aware of.

If anyone is willing to take a quick look I'd appreciate it. I've attached the .nes and the Messen debug .dbg file (which I had to change to a .txt to get it to upload).

Thanks


Attachments:
File comment: Nesteroids Label File (change to .dbg)
nesteroids.nes.dbg.txt [118.05 KiB]
Downloaded 71 times
File comment: Failing Nesteroids
nesteroids.nes [40.02 KiB]
Downloaded 83 times

_________________
A few of my web games
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com
Top
 Profile  
 
 Post subject: Re: Sprite wackyness
PostPosted: Thu Oct 11, 2018 7:07 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 10:59 pm
Posts: 1440
When I ran it in my emulator, I got a totally blank screen, likely because your Sprite DMA is being done too close to the end of VBlank (it starts at the beginning of scanline 259 and then ends in the middle of scanline 1) - when I switched to PAL mode, everything worked great (likely because I'm not emulating the extra OAM refreshing that the PAL PPU does to prevent the memory from decaying).

_________________
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.


Top
 Profile  
 
 Post subject: Re: Sprite wackyness
PostPosted: Thu Oct 11, 2018 7:31 pm 
Offline
User avatar

Joined: Wed Sep 05, 2018 11:13 am
Posts: 152
Location: Colorado
Quietust wrote:
When I ran it in my emulator, I got a totally blank screen, likely because your Sprite DMA is being done too close to the end of VBlank (it starts at the beginning of scanline 259 and then ends in the middle of scanline 1) - when I switched to PAL mode, everything worked great (likely because I'm not emulating the extra OAM refreshing that the PAL PPU does to prevent the memory from decaying).


Part of my confusion in this new world of NES Dev, is I don't fully understand what I should be doing in the NMI and what I should be doing in the main game loop.

I'm also not clear on how much I can do in the NMI vs. the main game loop

Any suggestions?

Thanks

_________________
A few of my web games
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com


Top
 Profile  
 
 Post subject: Re: Sprite wackyness
PostPosted: Thu Oct 11, 2018 8:26 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20867
Location: NE Indiana, USA (NTSC)
In vblank, you have 2270 cycles. To make the best use of them, you'll need to buffer the changes to sprites and backgrounds and push them to the PPU before you start calculating the changes for the next frame. There are a few video memory buffer libraries floating around; I wrote one called Popslide.

As for how NMI relates to vblank, there are 3 different ways to divide the tasks associated with every frame: everything in NMI, everything in main, or calculate updates in main and apply them in NMI. Each approach has its pros and cons.

Everything in main

NMI:
1. Increment a variable

Main:
1. Read the controller
2. Move the game objects
3. Calculate new sprite display list and background and palette updates
4. Wait for NMI handler to increment the variable
5. If a new sprite display list is ready, push it to OAM
6. If background and palette updates are ready, push them to video memory
7. Run music as many times as the variable was incremented

Everything in NMI

NMI:
1. If a new sprite display list is ready, push it to OAM
2. If background and palette updates are ready, push them to video memory
3. Run music
4. If in a lag frame, return
5. Read the controller
6. Move the game objects
7. Calculate new sprite display list and background and palette updates

Main:
1. Goto 1

Split responsibility

NMI:
1. If a new sprite display list is ready, push it to OAM
2. If background and palette updates are ready, push them to video memory
3. Run music (bank switching for this can prove tricky)
4. Increment a variable

Main:
1. Read the controller
2. Move the game objects
3. Calculate new sprite display list and background and palette updates
4. Wait for NMI handler to increment the variable

See also tokumaru's explanation


Top
 Profile  
 
 Post subject: Re: Sprite wackyness
PostPosted: Thu Oct 11, 2018 8:30 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 11011
Location: Rio de Janeiro - Brazil
Even thought I've been ninja'd by tepples (who even linked to a previous explanation I did on this subject, which I totally forgot BTW), I'm still gonna post my reply because I took the time to write it:

The main thing to keep in mind is that PPU updates must take place during vblank, and never spill into the visible frame, otherwise Bad Things (tm) will happen. As for *how* exactly you can make it so this rule is respected is up to you. There are 3 main possible structures for an NES program:

1- Everything in the main loop: Do your game logic first (buffering all PPU updates along the way), and wait for vblank by polling a flag modified by the NMI handler (all the NMI does is change this flag). When the flag changes, you know you're in vblank and you have about 2273 CPU cycles to carry out the buffered PPU updates. Then you can do sound. Repeat. This is a very simple structure, but has poor handling of lag frames (music will slow down, raster effects will break, etc.).

2- Everything in the NMI handler: This is more versatile, as long as you don't disable NMIs while doing game logic. As soon as the NMI fires, you're in vblank, so you have to carry out any buffered PPU updates. Normally there'll be one or more flags indicating what updates must be performed. Then comes the audio, and finally the game logic, during which PPU updates for the next frame will be buffered. The advantage this method has over the last one is that if an NMI fires before the previous frame's game logic is done, you can still handle the things that must keep working at 60Hz even when the gameplay lags, such as music and raster effects (status bar, parallax layers, etc.).

3- Game logic in the main loop, PPU updates in the NMI handler: this works much like the last method, only with better separation between the game logic and the PPU update code. This structure makes it easier to have multiple game logic loops scattered around your ROM, but they're all interrupted by the same NMI handler when vblank starts. This works very well if your PPU update system is generic enough to work with all game modules, but if you really need it, you can have different sets of PPU update logic. The same system of flags is used here, so the PPU code knows which operations can and can't be done.


Top
 Profile  
 
 Post subject: Re: Sprite wackyness
PostPosted: Fri Oct 12, 2018 7:08 am 
Offline
User avatar

Joined: Sat Jan 09, 2016 9:21 pm
Posts: 518
Location: Central Illinois, USA
And in case you feel overwhelmed by the 3 options and pros/cons, keep in mind that if you're doing a small simple project for the sake of learning the NES, most likely any of these 3 methods will be JUST FINE.

Quote:
The main thing to keep in mind is that PPU updates must take place during vblank, and never spill into the visible frame, otherwise Bad Things (tm) will happen. As for *how* exactly you can make it so this rule is respected is up to you.


This is the important part. As long as all PPU updates happen during vblank, you'll generally be ok for a simple project.

_________________
My games: http://www.bitethechili.com


Top
 Profile  
 
 Post subject: Re: Sprite wackyness
PostPosted: Fri Oct 12, 2018 9:33 am 
Offline
User avatar

Joined: Wed Sep 05, 2018 11:13 am
Posts: 152
Location: Colorado
Thanks for the explanation. Does it make sense to double buffer the oam data? Or is there a more efficient way to do all my sprite calculations in the game loop so I can just move the data over in the nmi code?

Thanks

_________________
A few of my web games
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com


Top
 Profile  
 
 Post subject: Re: Sprite wackyness
PostPosted: Fri Oct 12, 2018 9:42 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 11011
Location: Rio de Janeiro - Brazil
gauauu wrote:
keep in mind that if you're doing a small simple project for the sake of learning the NES, most likely any of these 3 methods will be JUST FINE.

Just NEVER do what Nerdy Nights does in the first few lessons (I think), which's everything in the NMI with the game logic first. That just wastes your precious vblank time with things that don't need it.


Top
 Profile  
 
 Post subject: Re: Sprite wackyness
PostPosted: Fri Oct 12, 2018 9:59 am 
Offline
User avatar

Joined: Wed Sep 05, 2018 11:13 am
Posts: 152
Location: Colorado
@clearvus set me straight. I didn't realize that the OAM data was being copied during a DMA and not somehow shared with the PPU. So double buffering makes no sense.

Thanks everyone for setting me straight on this stuff... hopefully I get this part now.

_________________
A few of my web games
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com


Top
 Profile  
 
 Post subject: Re: Sprite wackyness
PostPosted: Fri Oct 12, 2018 10:24 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 11011
Location: Rio de Janeiro - Brazil
Yeah, the memory page where you write OAM data to is already a buffer, the actual OAM inside the PPU remains unchanged until you do a sprite DMA. Actually, it will decay if PPU rendering is off for too long, but under normal circumstances, just skipping a DMA if the buffer isn't ready will cause the previous frame's sprites to be displayed again.


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

All times are UTC - 7 hours


Who is online

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