Skip to content

v0.1.0 - DMG panel and speaker model

Latest

Choose a tag to compare

@kathoc kathoc released this 05 Aug 01:39

The DMG panel and speaker model from brickboy, running in hardware on an
Analogue Pocket. Not an independent implementation: the maths, the pass order
and the constants come from brickboy's src/display/ and
src/ui/speaker-model.ts.

DMG only. SGB and GBC were removed from the upstream core and the freed
resources went into the panel.

What's in it

The game is rendered at 4x — one Game Boy dot is a 4x4 block — and the whole
panel model runs at that resolution, in the order brickboy's shader chain runs
it.

  • Colour correction — palette, inter-pixel bleed, off-element tint, panel
    gamma, desaturation, warm tint, tone, black lift
  • Passive-matrix crosstalk — downward, along the row, edge-triggered, the
    weak upward bleed, and per-column gain variation
  • LCD persistence — asymmetric, because darkening is driven and fast while
    lightening is relaxation and slow
  • Dot structure — inter-pixel gaps, grid contrast, and a two-layer drop
    shadow (sharp umbra at 1.35 dots, broad penumbra at 3.24) for the air gap
    between the element plane and the reflector
  • Reflector grain — three bands: half a dot, one to three dots, and
    eighteen to thirty-six
  • Screen-space finish — the reflection gradient, corner vignette and matte
    grain
  • Dead electrode lines — the surveyed edge concentration, contiguous bands,
    contact-resistance gradient along each line, and the rare stuck-dark line
  • Speaker and case — a 28 Hz DC blocker and the sealed-box model as three
    RBJ biquads (420 Hz Q1.1 highpass, 7 kHz lowpass, 1.2 kHz Q2.5 +4 dB peak)
  • Pad — X/Y auto-fire at 15 Hz with a TURBO/REPEAT choice, and brickboy's
    four-way D-pad mode

Verified against brickboy itself

tools/bb_render.mjs drives brickboy's own renderfarm harness — the same
six-pass WebGL chain the app puts on screen — and renders frames at the Pocket's
4x. Those pixels are the reference; nothing here was checked against a
reimplementation.

Measured on flat fields:

shade   grid modulation        cell luminance
        brickboy  this core    brickboy       this core
  0       3.20%     1.98%      [178 166 115]  [176 164 112]
  1       5.46%     4.46%      [143 151  99]  [142 151  97]
  2      15.85%    15.42%      [112 123  79]  [106 119  74]
  3      31.39%    33.09%      [ 98 110  71]  [ 91 105  67]

The audio chain matches its float model to within 0.01 dB across the audible
band.

Dials

Fifteen menu entries. The panel trim, ink, grain, off-element tint and reflector
saturation dials are not part of the port — at their Normal positions the
pipeline is brickboy's, unchanged. They exist because the Pocket's LTPS LCD and
the phone OLED brickboy is authored against have different primaries, and
Analogue publishes no colorimetry for the panel. Guessing a correction into the
pipeline would corrupt the reference; a dial leaves it intact.

Known limitations

  • Dead-line flicker is not implemented. The layout is there; the marginal
    contact flicker is not.
  • Vinegar syndrome is out of scope.
  • The dark shades sit about 5.5% below brickboy's. Measured, understood as a
    real difference rather than a panel effect, and not yet resolved.
  • The internal LCD and HDMI cannot be given different colour. APF gives the
    core no way to know a dock is attached, so one set of dials serves both.

Installing

Copy Cores, Platforms and Assets to the root of the SD card. Put the Game
Boy BIOS in /Assets/gb/common as gb_bios.bin, and ROMs in the same folder.

Licence

GPL-3.0-or-later. The upstream core carries GPL-3.0-or-later files (the
OpenGateware audio filters) beside MIT ones, so the combined work is
GPL-3.0-or-later. Ported from
budude2/openfpga-GBC, itself from
Gameboy_MiSTer.

Support

This is free, and it stays free. But it was a lot of measuring against real
hardware to get right, and if any of it is useful to you, a little help would
genuinely make me happy.

Sponsor @kathoc

No pressure at all — a star or a bug report is welcome too.