Skip to content

Decoupled game-speed pacing + widescreen room-cap/never-stretch/ambient fill - #168

Merged
999sian merged 2 commits into
masterfrom
feat/decoupled-pacing-widescreen
Jul 12, 2026
Merged

Decoupled game-speed pacing + widescreen room-cap/never-stretch/ambient fill#168
999sian merged 2 commits into
masterfrom
feat/decoupled-pacing-widescreen

Conversation

@999sian

@999sian 999sian commented Jul 11, 2026

Copy link
Copy Markdown
Owner

Two independent user-facing features, one commit each:

feat(pacing): decouple game logic from the render framerate

Game logic ticks on its own fixed clock (60 Hz, or GBA-exact 59.7275 Hz under Console-Parity); the Target FPS preset paces presentation only. Fixes the "world speed affected by fps limiter" class (#121) and answers the high-refresh request (#154): a 120 FPS preset no longer runs the game at 2x. Legacy behavior stays available (decouple_render off / TMC_LEGACY_PACING) and all capture/repro harnesses pin it, so parity tooling is unchanged. Fast-forward is now engine-bound (~13.5k tps headless). VSync's >60-FPS force-off now checks the real display refresh rate.

feat(widescreen): room-capped true-wide, never stretch, ambient fill

  • Rooms narrower than the monitor target but wider than 240px (256/272px — most dungeons) now render true-wide at their full room width instead of falling back to 240.
  • Fixed-canvas scenes (title, one-screen rooms, pause overlays) always present at correct 3:2 — never stretched. Port_Widescreen_ShouldStretch renamed Port_Widescreen_FallbackNative to match.
  • The bars the game can't fill default to the blurred ambient fill; the Native aspect stage now spans the window so fills actually render there (pixel-identical for black). Contributes to [Feature Request] Support for 16:10 aspect ratio #157 (16:10 → exact 256px view fills edge-to-edge in 256px rooms).

Verification

  • Headless captures (USA, widescreen_width=384): Link's house → native-240 undistorted; Deepwood 272px room → wide@272; overworld → wide@284; camera pan-probe repro PASS at viewW=384.
  • TMC_PACE_LOG boot: 60.0 tps / 60.0 fps decoupled; native-240 configure builds; multi-region build ok.
  • 20-agent adversarial review of the widescreen diff: no runtime defects.

🤖 Generated with Claude Code

999sian and others added 2 commits July 11, 2026 18:06
Game logic now ticks on its own fixed clock (60 Hz, or the GBA-exact
59.7275 Hz under Console-Parity) while the Target FPS preset paces only
how often frames are presented: above 60 the port re-presents between
ticks, below 60 it skips presents without slowing the game. The legacy
behavior (FPS cap paces the engine directly, so 120 FPS = 2x game speed)
remains available via the new decouple_render toggle (default on) and is
pinned by all capture/repro harnesses (TMC_LEGACY_PACING/TMC_PERFCAP/
TMC_ROOMCAP/TMC_CAPTURE_FRAME) so parity tooling is unaffected.

- Fast-forward no longer rasterizes every tick; presents throttle to a
  real-time cadence (~13,500 ticks/s headless vs render-bound before).
- LCD-persistence ghosting folds once per game tick instead of once per
  present (Port_PPU_SetPresentIsFirstOfTick), so decay is rate-independent;
  paused re-presents rewind the HBlank-DMA line clock correctly.
- VSync force-disable above 60 FPS now compares against the actual
  display refresh rate (Port_PPU_DisplayRefreshRate) instead of a
  hardcoded 60, so 75/90/120 targets on high-refresh panels keep VSync.
- Window title shows FPS and TPS; TMC_PACE_LOG=1 prints both per second;
  optional show_fps overlay config key.

Verified: headless boot 60.0 tps / 60.0 fps decoupled; fast-forward
uncapped headless ~13.5k tps; capture harnesses byte-identical under
pinned legacy pacing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…fill default

Three presentation changes driven by player feedback (stretched image in
Link's house and on the title screen):

- Room-capped widescreen: the effective view width is now
  min(window-aspect target, room width) instead of deactivating outright
  in rooms narrower than the target. 256/272px rooms — most dungeon rooms
  and larger interiors — render true-wide at their full room width.
  Port_Widescreen_ShouldStretch is renamed Port_Widescreen_FallbackNative
  to match its real semantics (1 = render/present the native 240 canvas).

- Never stretch: fixed-canvas scenes (title, file select, pause/storybook
  overlays, one-screen 240px rooms) present at their correct 3:2 aspect.
  Removes the presentation-stretch experiment; screenshots/bug reports
  capture the native canvas again.

- Ambient fill default: bg_fill defaults to the blurred "ambient" style,
  and the Native aspect mode's stage now spans the whole window (it was
  stage==frame, so fills never rendered there — pixel-identical for
  black). Every scene fills the monitor without distorting the game;
  configs that explicitly saved a bg_fill style keep their choice.

Verified headless (USA, widescreen_width=384): Link's house 0x22/0x10 ->
native-240 (240x160 capture, undistorted); Deepwood 0x48/0x00 (272px
room) -> wide at 272 with HUD on the wide edge; overworld 0x03/0x08 ->
wide at the 284 16:9 target; WaitForCameraTouchRoomBorder pan-probe
PASS at viewW=384; native-240 configure also builds. 20-agent
adversarial review of the diff found no runtime defects.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@999sian
999sian merged commit 3a9c604 into master Jul 12, 2026
8 checks passed
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.

1 participant