How does Wizards and Warriors 3 manage to have a status bar at the bottom of a vertically scrolling screen without the help of an MMC3? It looks like there's a sprite in the bottom row of the graphics, but how can you guarantee a sprite 0 hit when the background scrolls in all directions?
Dwedit wrote:
how can you guarantee a sprite 0 hit when the background scrolls in all directions?
One way is by drawing an opaque tile at the bottom left corner of the playfield.
The Guardian Legend uses the same trick, and it's quite visible too.
But in fact, the bottom
right corner is slightly less visible because the NES picture is offset two pixels to the right.
NES Scrolling Test by Lasse Öörni (Cadaver) displays the technique, but it's slightly glitchy on Nintendulator because like the NES, Nintendulator doesn't recognize sprite 0 overlaps in column 255.
I just watched the name table viewer carefully... It copies the original tile graphics to a specific tile number, changes the tile number for the lower-left corner, and plots a single PIXEL in that special tile. That single pixel collides with a single pixel sprite. Wow.
Since you make sure you never have 8 consecutives BG color pixels in the playfield, it will cause no problems to have a sprite zero hit with some 8 pixel tolerance (anyway, the tolerance so that the hit check loop is larger then
.
I think the best way is to make sure to never have 4 horizontal consecutive BG color in your whole tileset.
I think Big Nose Freaks Out also places a solid tile, by the right bottom corner.
I think you have to be really careful with that trick, because even if you make sure the sprite hit will happen, you must also be sure that game logic will never go beyond the place where the hit is to happen.
I was planning on turning the screen off early for a project, by having a sprite 0 hit on the last scanline, but am afraid that the calculations during the frame may take too long.
You're right, however there are game engines especially designed to be fast (Konami games ?).
However, in your case, that would just wait until the hit in the next frame, causing a slowdown that would happen anyways.
Bregalad wrote:
that would just wait until the hit in the next frame, causing a slowdown that would happen anyways.
Worse than the slowdown is the fact that the bottom part, that should be hidden, will be displayed for a frame, causing flicker and possibly exposing undesired/incorrect tiles/attributes.
Yeah... at least the game wouldn't frezee.
tokumaru wrote:
you must also be sure that game logic will never go beyond the place where the hit is to happen.
I was planning on turning the screen off early for a project, by having a sprite 0 hit on the last scanline, but am afraid that the calculations during the frame may take too long.
If you aren't using DPCM sound, you could borrow its IRQ for timing the sprite 0 hit. Start a DPCM playback in the vblank NMI, with a length such that it finishes a few scanlines before sprite 0. Then wait for sprite 0 inside the IRQ handler and do the PPUSCROLL/PPUADDR magic. But then you have to use an emulator that supports the game
Fire Hawk if you want any accuracy.
How to do this without hearing sound glitches ?
Hey, this has gotten me an alternate idea. Before the screen loads, wait a given number of cylces and write the value #$80 to $4017 to enable IRQ and use 4-step sequcne.
Then the interrupt will continue to reliably happen each frame when the game logic goes on. Unfrotuntaly, I think the frequencey is a very bit shorter than the 60Hz framerate, so something to compensate this is needed (re-write to $4017 after wait the difference of time between screen and APU).
Bregalad wrote:
How to do this without hearing sound glitches?
Use a DMC sample that's all $00 bytes and write 0 to $4011 at startup.
Quote:
Hey, this has gotten me an alternate idea. Before the screen loads, wait a given number of cylces and write the value #$80 to $4017 to enable IRQ and use 4-step sequcne. Then the interrupt will continue to reliably happen each frame when the game logic goes on. Unfrotuntaly, I think the frequencey is a very bit shorter than the 60Hz framerate, so something to compensate this is needed (re-write to $4017 after wait the difference of time between screen and APU).
Yeah, I tried to work this approach out a while back but was foiled by the APU's frame rate being slightly lower than the PPU's. If it were the other way around, it'd work out since you could reschedule the interrupt for the next frame slightly before the current scanline, after you had found a sprite #0 hit at the exact moment. Oh well.
Quote:
Yeah, I tried to work this approach out a while back but was foiled by the APU's frame rate being slightly lower than the PPU's. If it were the other way around, it'd work out since you could reschedule the interrupt for the next frame slightly before the current scanline, after you had found a sprite #0 hit at the exact moment. Oh well.
Sorry, I was really thinking it was the other way arround for some reason. That's a lame.
blargg wrote:
Yeah, I tried to work this approach out a while back but was foiled by the APU's frame rate being slightly lower than the PPU's. If it were the other way around, it'd work out since you could reschedule the interrupt for the next frame slightly before the current scanline, after you had found a sprite #0 hit at the exact moment. Oh well.
But on PAL...
Well, it would be ONLY on PAL, and I'm afraid I don't want to use stuff that works only on PAL systems.
Also, would the lenght of the DPCM sample should be changed from NTSC to PAL from your above example ?
DMA is done in some division of the main clock, so it shouldn't change the lenght, but since DPCM period values aren't the same in PAL than NTSC, it would still have to be corrected.