Repository navigation
Conversation
721a696 to
c53497d
Compare
|
#2259 changes the same stub and host path from the other side. When frames run a little longer than a vsync (55–59 fps), the game's step is taken from the measured frame time. It's on by default, uses state page +0x38 (float seconds) and +0x3c (the stub's mark), and leaves |
|
I've had a port of this in my fork since Nov 9 (M3 Max, 120 Hz screen). Porting it and going over it, I found four things that may be worth fixing before it lands. Line numbers are on main 1. The present thread declares a one-tick period. 2. The vsync event stays at 60 Hz. With the event at 120, the game's half-rate mode needs a look too. When bit 0 of the framework's +0x24f is set (read at main+0x6e6cc0), the base in s1 is 30 and calc runs twice per drawn frame (#2071). On the passes with both bits set, the frame end (main+0x40cd20 → main+0x40ced0) sleeps 1/60 s from its last mark instead of waiting for the event, so at 120 that mode no longer paces as it does at 60. I haven't checked how that mode looks at 120 in play. In my port the stub also stores s1 in a spare state word, and the host caps at 60 while that word is 30, which puts the event back at 60 Hz for that mode. 3. 4. The floor makes the game run slightly fast. The step is max(base / cap, mean of the last 8 intervals × base). Where the game holds 120, frames follow the link's ticks, so the true mean is one tick. The present call's jitter moves the 8-interval mean above and below that, and the floor lifts the low windows while keeping the high ones. Here is game time against real time, simulated with this PR's rule (frames locked to 120 Hz ticks, Gaussian work jitter, 36,000 frames per run):
The test's mode 1 alternates 7.0 and 9.67 ms. Every window of 8 then has a mean of exactly 8.33 ms, so the floor never binds and the test can't see this. My fix keeps an I have the With these changes, five scripted unlocked runs on my fork (about 30 minutes in all, from five saves) ran at 58-85 fps in the 30 s windows after each area loaded. Game time was 0.996-1.001 of real time in every window except the five with the area load (0.98-0.99 there, where stalls past the 0.1 s bound are dropped), and nothing crashed. My fork has many other changes, so take that as a sanity check, not an A/B of this PR. |
Ocarina's frame-ratio division cannot express arbitrary high-rate simulation through the existing whole-vsync contract. This extracts the experimental fractional path from #1663 and adapts it to current main without overwriting the newer dynamic-resolution control.
DM_EXPERIMENTAL_FRACTIONAL=1, restricted to NSO builde0f3ccfaf50065ae4ea01eb5aeb13b1a. Normal rewrites retain upstream's whole-vsync timing. Function matching still supplies the existing dynamic-resolution patch.FPS_FRACTIONAL=2relocates the override to +0x44, preserving DRS at +0x40. Legacy contract 1 is rejected with a rewrite instruction.DM_FPS_TARGET=120requests the high-rate path; existing screen, movie and thermal caps remain. Deterministic clocks and disabled elapsed-time correction reject high-rate mode. This does not unlock 85 Hz displays or establish compatibility with other titles.Evidence and validation
Historical campaign chat, 2026-11-08 02:22 UTC: a short forest run averaged 85.7 FPS and measured simulation speed within 0.06% of the 60 FPS reference. A later combined timing/compute run at 02:49 UTC averaged 93.7 FPS, median GPU 9.84 ms, with three presentation discards and GPU p95 above 12.5 ms. These used the older integration branch; they are not fresh A/B results for this adaptation and do not establish sustained 120 FPS.
Current extraction: 265 NVN checks, 84 frame-step checks, seven ARM64 execution/build-gating tests and 11 documentation tests pass. The execution test verifies preserved registers/NZCV and that +0x40 is untouched; the gating test checks DRS remains called. Loader syntax and modified Python compilation pass.
Outstanding validation: renewed full gameplay, audio/movie/hitch checks, full graphics suite, CI lint/tidy and multi-game regression remain pending. Impact analysis reaches module loading/rewriting and NVN presentation. Selected regression coverage is Ocarina (new contract), Breath of the Wild and Tears of the Kingdom (whole-vsync stubs), Pokémon Scarlet (ordinary NVN presentation), and Hades (non-Ocarina host loading). Only Ocarina assets are available locally. No full shader rebuild or game restart was performed for this extraction.
Front-ends: this is an experimental rewrite opt-in requiring the matching host and rewritten module; do not reuse contract-1 modules. Keep the ordinary frame-rate path as the default. A 120 FPS request is not a guaranteed rate.
Regression attempt
The selected five-game quick/no-smoke check stopped during asset discovery, before builds or game runs:
This is incomplete validation, not a regression pass.
Reproducible evidence
Tested extraction:
721a69655b6ac31feda2e0fa403e56dfdac6e90f. Test source at that commit; game note at that commit. Run on an Apple-silicon Mac with the repository's build dependencies configured:Saved local test-output excerpt (not a new test run or a CI result):
Historical A/B figures above describe the older combined branch. They are not fresh performance validation of this extracted commit. The remaining gameplay/regression limitations above still apply.
Rebase validation — 2026-11-09
Current head:
c53497d1a3a2751b2c7fe1a80ae2a5ac9e616b57, one commit above upstream9983d659e6101867215e4afe5dd6287ad8e0d4a3.Full graphics check list: 125 test targets plus the two Python check targets passed. The fractional timing, matcher, patch registry, and FPS Python tests passed 63 tests; the C frame-step fixture passed 84 checks. Rebase resolution retained upstream function-address matching and the opt-in/build gate. The internal build constant was renamed to satisfy the patch-table registry.
Mac fixtures were tested before the final upstream iOS-linker-only commit; verified that
dm/ios/tools/gen_build.pyis the sole subsequent file difference. Impact analysis was also run. No new gameplay A/B performance claim: historical figures above still describe the combined branch. Full current-chain game rebuild and gameplay regression remain pending; only Ocarina assets are locally available, and other titles/iOS are untested. The installed app andcodex/ocarina-playabilitywere preserved.