mirror of
https://github.com/imjasonh/nescript
synced 2026-07-08 08:55:38 +00:00
platformer: stabilise sprite-0 HUD by splitting below the HUD row
The previous commit parked the sprite-0 hit anchor on top of the visible HUD coin at NT col 2, row 1 — the hit therefore fired at dot 19 of scanline 15 (the HUD's last scanline) and jsnes's PPU model applied the scroll change to the rest of that same scanline, smearing the bottom row of every HUD glyph as `camera_x` drifted. The score "0"/"2" digit, the heart, and the lives "3" each flickered a handful of different pixel patterns per frame as the scroll shifted. An in-harness check for unique HUD states across the 180-frame window saw ~20-40 distinct states. Fix: move both anchors off the HUD row entirely. - `TILE_SPRITE0_ANCHOR` still has its single opaque pixel at row 7, col 3, but now draws at OAM `(248, 8)` so the pixel lands at screen `(251, 16)` — the first scanline of the playfield. - New `TILE_BG_ANCHOR` (tile 28) mirrors it with a single opaque pixel at row 0, col 3; the map pre-paints it at NT `(col 31, row 2)` via the new `a` legend entry. Its one opaque pixel lands at the same `(251, 16)`, so the PPU's sprite-0 hit fires there instead. - An explicit `scroll(0, 0)` right before `sprite_0_split` defensively re-latches scroll to zero in case jsnes has carried stale `$2005` state over from the previous frame. With the hit on scanline 16, `$2005` writes in HBLANK of scanline 16 (or thereabouts) only affect scanline 17 onward; rows 8-15 all render at scroll=0 and the HUD glyphs stay pixel-stable. The unique-state count across the 180-frame harness drops from ~40 to 4 — and those 4 correspond to the legitimate score / lives transitions (initial title, post- stomp-1, post-stomp-2, etc.), not per-frame jitter. Column 31 and OAM x=248 both sit inside jsnes's right-edge overscan so the anchor pixels are invisible in the committed golden. Goldens + gif refreshed.
This commit is contained in:
parent
c5b04c2065
commit
615490fbe5
6 changed files with 93 additions and 42 deletions
|
|
@ -367,18 +367,22 @@ aaaaaaaa
|
|||
...aa...
|
||||
........",
|
||||
},
|
||||
// Sprite-0 hit anchor — a single opaque pixel at row 7, col 3,
|
||||
// everything else transparent. Sits behind the HUD row's coin
|
||||
// tile as OAM slot 0 in every `on frame`; its one opaque pixel
|
||||
// aligns with column 3 of the coin's row 7 (`...bb...`), so
|
||||
// the PPU sets the sprite-0 hit flag at scanline 15 — the
|
||||
// last scanline of the HUD row. Writing `$2005` the moment
|
||||
// that flag sets means the horizontal scroll flip takes
|
||||
// effect at scanline 16 (the PPU latches horizontal scroll at
|
||||
// the next HBLANK), which pins NT rows 0-1 at scroll=0 and
|
||||
// lets scanlines 16+ render at `camera_x`. A sprite that
|
||||
// hit on its *top* row (e.g. using the coin as sprite 0)
|
||||
// would flip the scroll mid-HUD-row and smear the glyphs.
|
||||
// Sprite-0 hit pair — two single-pixel tiles whose one opaque
|
||||
// pixel sits at row 7 col 3 (sprite side) and row 0 col 3 (bg
|
||||
// side). OAM slot 0 gets `Sprite 0 anchor` at (248, 8) and NT
|
||||
// (col 31, row 2) gets `BG anchor`, so both opaque pixels
|
||||
// land at screen (251, 16) — the first scanline of the
|
||||
// playfield, one scanline below the HUD row. The PPU's
|
||||
// sprite-0 hit fires at dot 251 of scanline 16, `$2005`
|
||||
// writes from `sprite_0_split` land in HBLANK, and the
|
||||
// horizontal-scroll reload for scanline 17 latches the
|
||||
// playfield's `camera_x` without touching scanlines 8-15
|
||||
// (where the HUD glyphs live). A hit on scanline 15 itself
|
||||
// would smear the bottom row of every HUD glyph across the
|
||||
// split in jsnes. Both tiles are transparent everywhere
|
||||
// except that one pixel, so the only BG footprint is a
|
||||
// single dot at (251, 16) — inside jsnes's right-edge
|
||||
// overscan, invisible in the committed golden.
|
||||
Tile {
|
||||
name: "Sprite 0 anchor",
|
||||
art: "\
|
||||
|
|
@ -391,6 +395,18 @@ aaaaaaaa
|
|||
........
|
||||
...c....",
|
||||
},
|
||||
Tile {
|
||||
name: "BG anchor",
|
||||
art: "\
|
||||
...c....
|
||||
........
|
||||
........
|
||||
........
|
||||
........
|
||||
........
|
||||
........
|
||||
........",
|
||||
},
|
||||
];
|
||||
|
||||
// ── Named CHR tile indices used by the nametable layout below ──
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue