Hey guys, I was going to be writing a small tutorial on split-screen scrolling based on using sprite zero hit detection. I've used it in demos before, but not anything CPU-intensive. I've always figured I'd use an IRQ if it came to that, so I hadn't given it much consideration before. But most people are using NROM, UNROM, etc. for their games, and there's enough interest in my GTROM board, so I figured this would be a good time to show how to use mid-frame nametable banking for 8-way scrolling.
My first thought is that having a status bar at the top of the screen is going to be easier than using the bottom of the screen. The big concern is if you have code that's complex enough that it might take more than one frame to complete. The top status bar is rendered not long after vblank, so I think it would make sense to have the NMI routine do the sprite zero polling before it returns. Before sprite zero polling begins, the user can run some portion of their game logic, music or whatever, as long as it can never take longer than waiting for the sprite zero hit.
Does it sound like I'm on the right track, or does anyone have any alternative approaches? It seems like every example I've looked at in the past either do the sprite zero polling in the main loop, or they do it in the NMI, and don't even have a mainloop (infinite JMP loop). Neither of those methods will work when the code runs longer than a frame.
As for a bottom status bar, I'm not sure how that could be handled. Seems like you would have to be sure the program never takes too long. I'm thinking of recommending against using a bottom status bar, unless your program is really simple it's probably better to avoid that whole mess.
Sounds about right to me.
Quote:
As for a bottom status bar, I'm not sure how that could be handled. Seems like you would have to be sure the program never takes too long. I'm thinking of recommending against using a bottom status bar, unless your program is really simple it's probably better to avoid that whole mess.
Yeah, status bars on the bottom of the screen with sprite 0 hit are problematic. That's why I'm surprised every time I see a game (without mapper IRQ) that has it. Some that come to mind: TMNT, Addams Family, Ghostbusters 2, Legend of Prince Valiant, Gradius
Every single one of those games can also exhibit problems like shaky status bars because of that decision, so it's hard to recommend it. Another problem with a status bar on bottom with sprite 0 hit is the need to ensure that there's a solid pixel in the game's background in the correct place. Addams Family is an example of a game where lack of solid pixels in some background tiles causes the status bar to shake one pixel up/down depending on the Y scroll (in some levels).
You are on the right track Memblers. However it's possible for example to use DMC interrupt that will trigger at an approximate time before the sprite zero hit, and wait for it within the DMC IRQ. Of course this monopolizes the DMC channel and prevents to use it for music or effects while the status bar is here, it also will cause emulator compatibility issues.
Quote:
Another problem with a status bar on bottom with sprite 0 hit is the need to ensure that there's a solid pixel in the game's background in the correct place.
This can be indeed a problem depending on your graphic style used for the playfield.
I would definitely recommend against a bottom status bar if you don't have scanline IRQs. Big Nose Freaks out draws a solid background tile at the correct location to ensure a sprite hit, but that's just ugly, programatically and visually.
As for top status bars, I always recommend handling them in the NMI routine, so that the screen doesn't jump on lag frames. To me it makes sense to have the NMI handler take care of PPU updates first, then call the sound engine, and finally wait for the sprite 0 hit in order to change the scroll. The PPU updates should be skipped in lag frames, but the rest should still happen. You must obviously make sure the music engine fits in the number of scanlines taken by the status bar. That's actually a nice way to make use of that time instead of letting it go to waste.
Another important point of combining a top status bar with vertical scrolling is that you have to use the $2006/5/5/6 trick to change the scroll after the status bar. That can be complicated for a beginner to understand... but so is 8-way scrolling.
Wizards and warriors III draws a copy of the tile that would be there, except with a specific pixel set. You can see that the bottom-left visible pixel is always black, sprite zero is a black pixel, and is guaranteed to collide with the specific pixel that's set.
Visually, that's pretty clean, but having to waste VBlank time making a copy of a tile is a major nuisance, IMO.
IIRC, Addams Family uses sprites to draw spider webs on the corners of the screen, hiding any glitches in the place where the sprite hit happens.
I can see this being quite a problem back in the day. The $2006/5/5/6 trick wasn't known, so having the status bar at the top in a game with vertical scrolling wasn't an option, and people had to jump through hoops to get a sprite 0 hit to work at the bottom of the screen.
thefox wrote:
That's why I'm surprised every time I see a game (without mapper IRQ) that has it. Some that come to mind: TMNT, Addams Family, Ghostbusters 2, Legend of Prince Valiant, Gradius
There's one argument for having a status bar at the bottom (came up at #nesdev), especially given the limited knowledge of the system at the time commercial games were developed: if the game scrolls vertically, it's usually easier to set the scroll to the status bar at the bottom of the screen, because it's (usually) at a known position. If status bar is at the top, game would have to do complicated 2005/2006 writes to set the playfield scroll after the status bar if the game scrolls vertically.
EDIT: Didn't notice until now that tokumaru made the exact same point. Oh well.