Page 2 of 2
Posted: Sun May 27, 2012 9:02 am
by MottZilla
tokumaru wrote:
Sprite 0 hits suck when you use scrolling. For completely arbitrary splits, it's impossible to always have solid pixels overlap the sprite unless you specifically erase/draw a solid tile at the proper NT location every frame.
Makes you wonder why Nintendo went with the whole sprite/background collision and didn't just trigger the flag when the first non transparent pixel of sprite 0 was drawn instead. There really is no reason to have it only happen when the background and sprite are non transparent unless the hardware implementation of this somehow wouldn't work the same.
Posted: Sun May 27, 2012 9:08 am
by 3gengames
I'm working on a zapper game that uses sprite 0 to determine the object pointed at since at minimum 8 scanlines inbetween them. It's not working, but my solution I decided to go with was to make the background always use solid colors for background. On places where you have to scroll you can always keep a line of solid pixels with good graphic design, although I agree it should have been as soon as a sprite 0 non-zero pixel was hit any background tile.
Posted: Sun May 27, 2012 10:31 am
by Drag
tokumaru wrote:Sprite 0 hits suck when you use scrolling. For completely arbitrary splits, it's impossible to always have solid pixels overlap the sprite unless you specifically erase/draw a solid tile at the proper NT location every frame.
TMNT 1.
Posted: Sun May 27, 2012 10:37 am
by digilogistist
tokumaru wrote:Since those sprites are transparent and have priority over all others, no sprites will be visible up there. The sprite overflow flag, which will be set at the same time every frame, is used for detecting the end of VBlank, so that I can wait for the end of the blanked area and enable background rendering at the correct time.
Ah, I see how your solution works now... if your initial sprite usage in the frame can guarantee that there will be no lines with 8 or more sprites on it, up until you deliberately intend to set the flag with 9 sprites all on 1 line, then this can be a practical solution to depend on the overflow flag's timing for, quite possibly for even establishing a top-screen status bar + horizontal split (provided less than 8 sprites/scanline (or no sprites at all) are used in the status bar). I suppose that overflow flag timing then just depends on which sprites you occupy in OAM to trip the flag (it just makes sense to always use 9 sequential sprite records to trip the overflow).
Of course, this makes using the overflow flag for timing out of the question for any scanlines following any playfield sprite activity that may introduce 8 or more sprites on one line, but just for the fact that you've given me a really neat idea that allows me to save the Sprite 0 hit for something later, really shows me how wrong I was to think the sprite overflow was useless. It may be a waste of 9 sprites, but ideally, those sprites could be used to display tiles like a power meter, or score digits (even those these sprites will hang down into the active part of the playfield- a small aesthetic price to pay, to get some use out of the rarely-used sprite overflow flag).
Very nice, tokumaru

Posted: Sun May 27, 2012 11:05 am
by digilogistist
MottZilla wrote:Makes you wonder why Nintendo went with the whole sprite/background collision and didn't just trigger the flag when the first non transparent pixel of sprite 0 was drawn instead. There really is no reason to have it only happen when the background and sprite are non transparent unless the hardware implementation of this somehow wouldn't work the same.
Opinion: Nintendo was just taking what had already been developed by other companies, and just built on those designs to make their PPU.
Case example: The Colecovision video processor TMS9928A (a Texas Instruments device with official available documentation) is sort of like a stripped-down version of the 2C02 (with a 4 sprite per scanline limit, if you can believe it!), but it did have something in it's status register called the "Coincidence flag", which would simply be set if 2 sprites overlapped the same location on the screen.
Interestingly enough, the TMS9928A also had a 5th Sprite Flag, which would get set when the processor would find more than 4 sprites on one scanline (and apparently, the processor would actually load the sprite record index value of the 5th sprite that sets the sprite overflow flag into another status register- kinda interesting).
It is odd though, why Nintendo's PPU designers demanded a coincidence between sprite 0, and the playfield, because while it is inconvenient for an NES developer to make sure that there is a non-transparent PF pixel underneath sprite 0 (as has been brought up when working with bottom screen status bars), it is equally a pain-in-the-ass to deal with in accurate PPU emulation... Gotta love the NES, man!

Posted: Sun May 27, 2012 11:12 am
by tepples
It was also the fashion in arcade games of the time to have a top status bar.
Posted: Sun May 27, 2012 11:40 am
by MottZilla
Still other than being lazy/copying, I haven't heard any good reason why it shouldn't just be a Sprite Zero Pixel has been drawn flag. I know some emulators change behavior to that for Battletoads to avoid the possibility of a deadlock since the sprite 0 is usually just 1 pixel and under certain conditions without correct timing or ppu behavior you won't get a sprite hit and the game is stuck forever.
Posted: Sun May 27, 2012 1:41 pm
by bunnyboy
There is no back way to manually clear the sprite overflow flag, correct?
Posted: Sun May 27, 2012 5:12 pm
by digilogistist
In addition to discussing the paradigm behind the PPU's Sprite 0 hit depending on the playfield pixels being solid, some attention has to be paid to the 2A03 audio hardware, most notably the sweep units.
If you look at the size of the silicon real-estate that the 2A03 consumes for it's audio unit compared to the 6502 section (thanks, Q), and THEN consider the fact that the sweep unit is only updated at a sluggish 240 times/sec (why not just use 6502 code calculations to update the wavelength register for a channel anyway, instead of using hardware to do this for a slow shift & add calc?), a serious question comes to mind:
** Why waste hardware resources on a chip to perform functions that can be efficiently implemented in software, with some thoughtful planning? (By the MMC5's time, Nintendo knew the sweep hardware was a waste of silicon, albeit some 8 years after the fact.) **
That answer has to be because hardware engineers, as innovative as they are, can not foresee how future software predicaments will challenge their idea of how current hardware implementations should be managed, which is at best, always based on at least 1 previous generation of implemented and exercised knowledge.
I've personally designed hardware projects that have ended up back at the drawing board, because of software requirements that I did not think of at the time of hardware design, and I doubt that this is an engineering mistake that is unique to a hobbyist or tinkerer.
Posted: Sun May 27, 2012 5:59 pm
by tokumaru
MottZilla wrote:Makes you wonder why Nintendo went with the whole sprite/background collision and didn't just trigger the flag when the first non transparent pixel of sprite 0 was drawn instead.
Yeah, it would have been much more useful that way.
MottZilla wrote:There really is no reason to have it only happen when the background and sprite are non transparent unless the hardware implementation of this somehow wouldn't work the same.
Maybe the logic for the hit is hidden in the priority circuit and really depends on solid pixels in both layers... Maybe some day we'll find out (possibly with the decapping of the chip), but it won't change the way things are.
digilogistist wrote:if your initial sprite usage in the frame can guarantee that there will be no lines with 8 or more sprites on it, up until you deliberately intend to set the flag with 9 sprites all on 1 line, then this can be a practical solution to depend on the overflow flag's timing for
Yup, that's right. The disadvantage (besides wasting 9 sprites - but I've seen even more being wasted) is that you might need to burn a few scanlines with timed code, but you can always minimize that by doing constant-timed tasks (reading the controllers, initializing variables, clearing arrays, etc) instead of just waiting. But like you said, if you use this for status bars, you even have sprite 0 free for effects further down the screen.
bunnyboy wrote:There is no back way to manually clear the sprite overflow flag, correct?
As far as I know, only the end of VBlank can do it, just like it is with the sprite 0 hit flag.
Posted: Mon May 28, 2012 1:06 am
by Bregalad
You are right that Nintendo wasted silicon on things that can be done in software.
For the sweep unit I disagree, in fact it's useful if your sound engine updates at only 50/60Hz, having the sound sweep with a resolution of 196Hz or 240hz really helps for sound effects, and sometimes even for music.
It can also make sound engine's code smaller as you don't have to implement sweep in software.
What is completely useless is the length counters and decay envelopes. Both can be done in software easily, and the resolution of 50/60Hz is not really a problem.
The worse thing is that 6 years later when Nintendo released the GameBoy with a similar audio hardware in it, they made it impossible to do volume envelope entierely in software without reseting the phase of the square wave, therefore games have to use the hardware envelope. This was really another poor design choice.
On the other hand, there is many really good design choices Nintendo made. The controllers were very ergonomic for their time. The tiles, attributes and palette system is very clever and done in a way that is more efficient as for example the C64.
And even if the serial interface to communicate between the CPU and PPU via $2007 is confusing when you start programming the NES for the first time, it's in fact better than shared memory like on the C64, where they had to divide the cloth of both teh CPU and the video device to have them interleave access to RAM.