ppu: rebuild bg pair LUT after priority |= 64, fixes Mega Man 3 sprites
The pair LUT introduced in a502cea was built at the top of
RefreshLine, before the
Pal[0] |= 64;
Pal[4] |= 64;
Pal[8] |= 64;
Pal[0xC] |= 64;
block that follows. That OR sets the 0x40 "background priority"
marker on the universal-background entries of PALRAM (Pal is
`#define Pal (PALRAM)`), so that the framebuffer downstream of the
pputile.h tile expansion can distinguish BG-colour pixels from
true zero-pen pixels for sprite priority / sprite-0-hit testing.
The matching `Pal[i] &= 63` at the bottom of the function strips
the bit again after rendering.
Building the LUT before the |= 64 meant entries 0/4/8/0xC carried
the PALRAM value WITHOUT the priority bit, so every tile pixel that
expanded to one of those four indices wrote a plain palette index
to the framebuffer instead of (palette | 0x40). Sprite compositing
then could not tell which BG pixels were the universal background,
and broke priority for games that exercise Pal[0x04/0x08/0x0C] --
Mega Man 3 sprites were reported.
Fix: move the FCEU_BuildBgPairLUT() call to just after the
`Pal[i] |= 64` block. The LUT is now built with the priority bit
present in entries 0/4/8/0xC and bit-exactly matches what the
original eight-load scalar code reads from PALRAM during the
pputile.h includes. No second rebuild is needed before the
`Pal[i] &= 63` cleanup because the LUT is only consumed inside
the includes, which sit between the OR and the AND.
Mid-scanline RefreshLine entries via FCEUPPU_LineUpdate continue
to work: each entry walks the same |= 64 -> BuildLUT -> includes
-> &= 63 sequence, so any $3F00..$3F0F write the CPU made since
the previous span is folded into the LUT before the resumed tile
span renders.
Codegen unchanged: still one leaq fceu_bg_pair_lut at function
entry, 48 indexed LUT loads across the 12 pputile.h expansion
sites, one movq per site to P.
This commit is contained in:
committed by
U-DESKTOP-SPFP6AQ\twistedtechre
parent
01b7446a66
commit
6911042cf6
34
src/ppu.c
34
src/ppu.c
@@ -138,12 +138,16 @@ uint8_t UPALRAM[0x03];/* for 0x4/0x8/0xC addresses in palette, the ones in
|
||||
* emit four pair-lookups and a single 64-bit store instead of eight
|
||||
* serial nibble-load-store iterations.
|
||||
*
|
||||
* Rebuilt at the start of every RefreshLine call so that mid-frame
|
||||
* raster effects writing to $3F00-$3F0F see their pen changes on the
|
||||
* very next scanline. 256 entries x ~3 ops = ~768 ops per rebuild;
|
||||
* RefreshLine runs once per scanline plus the occasional mid-scanline
|
||||
* call from FCEUPPU_LineUpdate, so the worst-case rebuild cost is
|
||||
* well under 1% of frame budget. */
|
||||
* Rebuilt INSIDE RefreshLine just before the pputile.h includes, so
|
||||
* that:
|
||||
* (a) any PALRAM[0x00..0x0F] change since the previous RefreshLine
|
||||
* is reflected on the next tile span, and
|
||||
* (b) crucially, the 0x40 "background priority" bit that RefreshLine
|
||||
* OR's into Pal[0/4/8/0xC] right before rendering -- and ANDs
|
||||
* off again after -- is captured in the LUT. Without that the
|
||||
* sprite compositor cannot tell BG-color pixels apart from the
|
||||
* universal background, breaking sprite priority for any game
|
||||
* that hits Pal[0x04/0x08/0x0C] (e.g. Mega Man 3 sprites). */
|
||||
static uint16_t fceu_bg_pair_lut[256];
|
||||
|
||||
static void FCEU_BuildBgPairLUT(void)
|
||||
@@ -468,13 +472,6 @@ static void FASTAPASS(1) RefreshLine(int lastpixel) {
|
||||
|
||||
if (numtiles <= 0) return;
|
||||
|
||||
/* Rebuild the bg pair LUT once per RefreshLine call. This covers
|
||||
* both per-scanline calls from FCEUPPU_Loop and mid-scanline calls
|
||||
* from FCEUPPU_LineUpdate (raster effects); any PALRAM[0x00..0x0F]
|
||||
* change done since the previous RefreshLine is reflected for the
|
||||
* about-to-be-rendered tile span. */
|
||||
FCEU_BuildBgPairLUT();
|
||||
|
||||
P = Pline;
|
||||
|
||||
vofs = 0;
|
||||
@@ -512,6 +509,17 @@ static void FASTAPASS(1) RefreshLine(int lastpixel) {
|
||||
Pal[8] |= 64;
|
||||
Pal[0xC] |= 64;
|
||||
|
||||
/* Rebuild the bg pair LUT *after* the priority |= 64 modification
|
||||
* above so that the LUT entries for PALRAM[0/4/8/0xC] carry the
|
||||
* 0x40 bit while the pputile.h includes below run. The matching
|
||||
* Pal[i] &= 63 cleanup at the bottom of this function does NOT
|
||||
* require a second rebuild: the LUT is only consumed by the
|
||||
* pputile.h block, which runs between the |= 64 and the &= 63.
|
||||
* The LUT is also rebuilt at every mid-scanline RefreshLine call
|
||||
* via FCEUPPU_LineUpdate, picking up any $3F00..$3F0F write the
|
||||
* CPU made since the previous tile span. */
|
||||
FCEU_BuildBgPairLUT();
|
||||
|
||||
/* This high-level graphics MMC5 emulation code was written for MMC5 carts in "CL" mode.
|
||||
* It's probably not totally correct for carts in "SL" mode.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user