Files
Meck/examples
pelgraine 3647bdcc88 GBC emulator: full speed, 1.5x dithered picture, live keys, ghosting control
Follow-up to the initial Game Boy emulator commit (T-Deck Max).

SPEED (GBCEmulatorScreen.cpp)
- Pacing keeps its deficit: a frame that finishes late is paid back by
  running the next ones back-to-back instead of resetting the deadline
  and forgiving the lost time, which held Pokemon Gold at 0.96x. Only a
  stall of more than 250 ms resyncs. Now measures 1.00x on every 5 s
  window. A 1 ms yield every 30 undelayed frames keeps the idle task
  (and the task watchdog) fed.
- The core context (49952 bytes) is allocated from internal RAM for
  the duration of a game and freed on quit, with PSRAM as the fallback
  if no internal block is free; the launch log says which it got.
- Speed line printed to serial every 5 s (window fps, average, ratio to
  real time).

INPUT (GBCEmulatorScreen.cpp, GxEPDDisplay.h)
- GxEPDDisplay::setBusyCallback() exposes GxEPD2's busy-wait hook. The
  emulator registers a keyboard poll on it while a game runs, so key
  presses and releases are seen through the ~650 ms panel refresh
  instead of waiting for it to finish.

PICTURE (GBCEmulatorScreen.cpp, UITask.cpp, GxEPDDisplay.{h,cpp})
- 1.5x nearest-neighbour scale to 240x216, the full panel width,
  centred; title line removed, quit hint kept.
- Ordered 4x4 Bayer dithering replaces the single threshold: the four
  Game Boy shades map to 0, 6, 11 and 16 dark pixels in 16, so
  sprites with mid-tone colours are no longer flattened to white or
  black. The pattern is fixed to panel position so it does not crawl
  between refreshes.
- UITask: the 800 ms minimum interval between e-ink refreshes is
  lifted while a game runs, so pictures follow at the panel's own
  partial-refresh rate (about 0.7 s).
- GxEPDDisplay::requestFullRefresh(): the next endFrame() uses the
  full black/white waveform regardless of frame change. The emulator
  requests one every 45 pictures (about 30 s) and once on quit, to
  clear the residue that continuous partial refreshes leave on the
  game screen and the home screen after it. No other screen calls it.

Files: examples/companion_radio/ui-new/GBCEmulatorScreen.{h,cpp},
examples/companion_radio/ui-new/UITask.cpp,
src/helpers/ui/GxEPDDisplay.{h,cpp}
2026-09-13 01:23:02 +10:00
..