Skip to content

Fix brightness tables: identity mapping for palette columns D/E/F#337

Closed
jonathanpeppers wants to merge 2 commits intomainfrom
fix/brightness-table-columns-DEF
Closed

Fix brightness tables: identity mapping for palette columns D/E/F#337
jonathanpeppers wants to merge 2 commits intomainfrom
fix/brightness-table-columns-DEF

Conversation

@jonathanpeppers
Copy link
Copy Markdown
Owner

Problem

Palette colors in NES columns D/E/F (e.g. $0D dark blue, $3D light blue) display as wrong colors at runtime. The universal background color shows $0F (black) instead of the intended $0D.

Root Cause

The brightness lookup tables (palBrightTable4-7) used the old clbr/neslib values that map columns D/E/F to "safe" alternatives:

Color Old (dotnes) New (reference)
$0D $0F $0D
$1D $00 $1D
$2D $10 $2D
$3D $20 $3D
$0E $0F $0E
$0F $0F $0F

The reference crypto ROM uses full identity mapping for these columns. Verified by dumping brightness table bytes at runtime via Mesen2 headless test runner.

Fix

Updated palBrightTable4-7 in NESLib.cs to use identity mapping for columns D/E/F, matching the reference ROM. Updated 38 verified.bin snapshots (only the 8 brightness table bytes change in each ROM).

All 586 tests pass.

The old clbr/neslib brightness tables mapped NES color columns D, E, F
to 'safe' values (e.g. 0x0D->0x0F, 0x1D->0x00, 0x3D->0x20). The
reference crypto ROM uses full identity mapping for these columns at
each brightness level, which is what modern neslib versions use.

This caused palette colors like 0x0D (dark blue) and 0x3D (light blue)
to display as wrong colors at runtime. Verified by dumping brightness
tables from the reference ROM via Mesen2 and comparing byte-for-byte.

Fixes #315

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 22, 2026 22:28
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes incorrect palette rendering for NES palette columns D/E/F by updating the built-in palette brightness lookup tables to use identity mappings, aligning runtime behavior with the reference ROM.

Changes:

  • Updated palBrightTable4palBrightTable7 to map colors $xD/$xE/$xF to themselves rather than “safe” substitutes.
  • Updated transpiler snapshot outputs (*.verified.bin) to reflect the new ROM bytes for the brightness tables.

Reviewed changes

Copilot reviewed 1 out of 39 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/neslib/NESLib.cs Adjusts palette brightness tables 4–7 to use identity mappings for columns D/E/F.
src/dotnes.tests/TranspilerTests.Write.transtable.verified.bin Snapshot updated to match new ROM bytes (brightness table data).
src/dotnes.tests/TranspilerTests.Write.tileset1.verified.bin Snapshot updated to match new ROM bytes (brightness table data).
src/dotnes.tests/TranspilerTests.Write.shoot2.verified.bin Snapshot updated to match new ROM bytes (brightness table data).
src/dotnes.tests/TranspilerTests.Write.monobitmap.verified.bin Snapshot updated to match new ROM bytes (brightness table data).
src/dotnes.tests/TranspilerTests.Write.hello.verified.bin Snapshot updated to match new ROM bytes (brightness table data).

@jonathanpeppers
Copy link
Copy Markdown
Owner Author

Closing -- the current values are correct

The brightness tables on main match the original clbr/neslib by Shiru byte-for-byte. I verified this by fetching the upstream source directly from https://github.com/clbr/neslib/blob/master/neslib.sinc:

\\�sm
palBrightTable4: ,,...,,,,\ ;normal colors
palBrightTable5: ,,...,,,,
palBrightTable6: ,,...,,,,\ ;\ because \ is the same as
palBrightTable7: ,,...,,,,
\\

The remapping of columns D/E/F is intentional -- Shiru's neslib avoids these colors because \ is the blacker than black color that causes display artifacts on real NES CRT hardware. This is a well-known safety convention in the NES homebrew community (documented on NESdev wiki, nesdoug, etc.).

The reference crypto ROM compared against uses modified brightness tables that diverge from the standard neslib. dotnes should match the original upstream, not a modified fork.

Closing issue #315 as well -- see comment there for full rationale.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants