FineX, FineY and zero hit

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
FineX, FineY and zero hit
by on (#160304)
Hello everybody, it's been a while since my last post!
It's been a lot of changes in the O-Nes-sama emulator, pretty exciting.

The reason for this post is to ask details about fineX and fineY.
Right now i have a predictive algorithm for the zero hit calculation. It doesn't "render" or process each pixel from the BG, neither compares it with the sprite zero pixels.
Right now the algorithm "works". it surprisingly passes all the zero hit tests, but it fail to trigger like in Total recall just after you press start, Maniac Mansion hangs at "twenty years ago today...", and Double Dragon at the second level, and many others.

Right now i want to re-implement the zero hit algorithm, what i'm planning to do is to predict what scanlines the sprite zero will be and then try to "render" pixel-accurately the BG pixels so i could compare the sprite zero pixels with it.

So if you guys could solve my doubts i will be very grateful! :mrgreen:

1) When rendering has started, oams can't move right? if you try to change the position it will corrupt the oams right?

2) If i understand correctly fineX is used to know what pixel to pick from current tile. fineY is the line of current tile.

Lets say fineX is 4, and we are at tick 1 of a given scanline. the first pixel that will pick is number 4 then 5, 6, 7 and then 01234567 from next tile right?
What if i change fineX as soon as possible? will the shift registers could be empty some time? Talking about ticks how soon can you change fineX?

Thanks in advance!
Re: FineX, FineY and zero hit
by on (#160308)
aLaix wrote:
Right now i want to re-implement the zero hit algorithm, what i'm planning to do is to predict what scanlines the sprite zero will be and then try to "render" pixel-accurately the BG pixels so i could compare the sprite zero pixels with it.

The most accurate way is to actually calculate sprite 0 hit while you're rendering. If this is too slow for your intended application, such as if you're trying to run an emulator on a sub-GHz ARM or in fast forward, then perhaps you can calculate while rendering only on scanlines where sprite 0 is in range. Perhaps that's what you're trying to do here.

Quote:
1) When rendering has started, oams can't move right? if you try to change the position it will corrupt the oams right?

OAM can't move unless $2004 is written. And yes, it's easy to trigger OAM corruption bugs if you do anything out of the ordinary. But Bigfoot does rewrite OAM mid-screen.

Quote:
2) If i understand correctly fineX is used to know what pixel to pick from current tile. fineY is the line of current tile.

Lets say fineX is 4, and we are at tick 1 of a given scanline. the first pixel that will pick is number 4 then 5, 6, 7 and then 01234567 from next tile right?

Yes.

Quote:
What if i change fineX as soon as possible? will the shift registers could be empty some time?

No. The fine X is actually the selector for a multiplexer on the output of a set of four serial-to-parallel shift registers used as a 4-bit-wide, 8-bit-deep delay line. Mid-scanline changes to fine X just pick a different tap off this delay line.
Re: FineX, FineY and zero hit
by on (#160342)
Thanks for the quick reply Tepples!
I read it at the very moment you posted it, but I didn't understand it, so that's why it took me so long to reply, sorry. I didn't want to sound noob by asking something that is documented already or something already explained..

Quote:
The most accurate way is to actually calculate sprite 0 hit while you're rendering. If this is too slow for your intended application, such as if you're trying to run an emulator on a sub-GHz ARM or in fast forward, then perhaps you can calculate while rendering only on scanlines where sprite 0 is in range. Perhaps that's what you're trying to do here.

Yes this is what i WAS trying to do. now i'm planning to render everything "pixel-accurately"

Quote:
OAM can't move unless $2004 is written. And yes, it's easy to trigger OAM corruption bugs if you do anything out of the ordinary. But Bigfoot does rewrite OAM mid-screen.

So is there some place where this writing-OAM-mid-screen behaviour is documented?
The wiki says:
Quote:
For emulation purposes, it is probably best to completely ignore writes during rendering.


Quote:
No. The fine X is actually the selector for a multiplexer on the output of a set of four serial-to-parallel shift registers used as a 4-bit-wide, 8-bit-deep delay line. Mid-scanline changes to fine X just pick a different tap off this delay line.

So lets say the last shift register is an array of 8 elements and each element is 2 bit: (i know, C only support 8bit elements minimum)
Code:
unsigned 2bit last_shift_register[8];


So what fineX does is:
Code:
while(this_scanline_is_rendering)
{
    pixel_to_be_draw = last_shift_register[fine_x];
    shift_registers();

    draw(pixel_to_be_draw);
}

So fineX only select one element (2bit element in this example) from the current parallel shift register, right?
fineX never increments by one each tick, neither determines whether a new tile is loaded into the shift registers, right?

Thanks in advance.
Re: FineX, FineY and zero hit
by on (#160364)
aLaix wrote:
So is there some place where this writing-OAM-mid-screen behaviour is documented?

The wiki says:
Quote:
For emulation purposes, it is probably best to completely ignore writes during rendering.



Games which do this certainly disable rendering via $2001 before touching OAM. I think Tepples point was that you can't expect OAM to remain untouched for the duration of the entire frame.

Note that the wiki also says this:

"Writes to OAMDATA during rendering (on the pre-render line and the visible lines 0-239, provided either sprite or background rendering is enabled) do not modify values in OAM, but do perform a glitchy increment of OAMADDR, bumping only the high 6 bits (i.e., it bumps the [n] value in PPU sprite evaluation - it's plausible that it could bump the low bits instead depending on the current status of sprite evaluation)."

So:
- mid-render writes to OAMDATA do not change OAM
- but they do mess up OAMADDR as described

Quote:
So fineX only select one element (2bit element in this example) from the current parallel shift register, right?
fineX never increments by one each tick, neither determines whether a new tile is loaded into the shift registers, right?


Correct.
Re: FineX, FineY and zero hit
by on (#160371)
Thank you so much Disch!

Ok my doubt about the oams it's cleared. but I will need to check that glitchy behavior further because right now i couldn't understand it, XD

I started implementing this fineX and fineY thingy and so far i could get it work! (i'm missing the palette shift registers right now, though)

Now that I think i understand how the fineX and FineY works now I can ask about zero hit.

Actual rendering starts at tick 1, as far as i know. so pixel 0 is rendered at tick 1, but it seems if zero hit happens at the very first pixel, (pixel 0 in this example) it won't trigger until tick 3, is this right? or is it tick 2?
What could be the reason for this delay??? :shock:
Re: FineX, FineY and zero hit
by on (#160372)
The reason for the delay is that pixel processing in the PPU is pipelined, and sprite 0 processing happens at a later pipeline stage than production of background pixels.
Re: FineX, FineY and zero hit
by on (#160512)
Finally!

Thank you guys, finally i could get through all the rendering stuff and the zero hit finally is working too!
Even i could run battletoads! I'm so impressed!! :D

Thank you you all guys, for your support. :beer:

Now the thing is that if i use 2 ticks of delay Bart vs space mutants shakes the status bar, but battletoads passes second level.
If i use 3 ticks of delay bart wont shake, but battletoads will hang. :?
both values passes all blargg tests.

Have you guys happened to see something similar? Any Ideas?

I found this http://forums.nesdev.com/viewtopic.php?f=3&t=12683&hilit=bart+shake&start=15 but these guys are not using cycle-accurate emulator. May be O_Nes_Sama is not that accurate. XD