GetAsyncKeyState can wedge "down" without a real press (Alt-Tab residue);
a phantom held Tab forwarded as held Y and killed the camera on both
keyboard and pad. Keys now count as held only after an observed up->down
since startup/focus gain.
KB+M's flight heartbeat only came from the main force step, which never
runs on the ground, keyboard flight controls were dead until takeoff.
Fire it from every state's provider: the alternate ground step (rolling)
plus the master updates and ground-state maintainer (standstill).
Config presets now run after the toml loads: the ac6_fix_* switches and
their scale gates finally honor user settings. The settings save persists
only user-set values, with toml escaping - no leaked presets, and a saved
Windows path can no longer void the whole config. Runtime-forced values
(performance mode) can no longer overwrite the user's saved choices.
Menu: wrapped tooltips, "(set by <cvar>)" on driven entries, a developer
toggle; AC6-added cvars grouped under the AC6 node as AC6/Fixes and
AC6/Enhancements, with true restart/live lifecycles.
The game now mounts straight from a .iso beside the exe (selected by
title id; the assets folder still wins, and loose files layer over the
image so mods need no extraction), and DLC mounts straight from raw
STFS containers in a dlc folder, any layout, title updates ignored.
Disc image device ported from Xenia (BSD); one log line per source.
Interacting with the overlays also drove the game (clicks fired
weapons, scroll cycled them, keys leaked), and hovering one silenced a real
pad. Input now follows window-manager rules, mouse to the window under the
cursor, keyboard to the focused window, real pads never suppressed, via
ImGui capture flags conjoined with overlay visibility, published as atomics.
The two effect managers share the dispatcher slot but not the draw slot
(CX360 0x820B25D0, CAce6 0x822B0AD8); the fix only knew the first, so a
CAce6EffectManager job silently fell through to the unfixed path - the
diagnosed cause of the one flicker that survived field testing. Dispatch
both explicitly; count and warn on any unmodelled slot. Same cvar gate,
inert while ac6_effect_mode_fix is off.
The effect update and effect draw are two async worker-pool jobs entering
through one vtable slot, told apart only by a shared mode word with no
per-job copy; a host stall lets both jobs read "draw", so the effect and
cloud passes are emitted twice for one frame. Snapshot the mode at submit
and dispatch from the snapshot. Gated behind ac6_effect_mode_fix, default off.
This reverts commit edcb6314f2b1b06e70dbb214674eb7c2325f8ab1. The fold was a mitigation: the doubling was never in the assets but came from the decoder dropping straddled-header frames, letting the premix streams drift and comb. With the decode fixed at the root, the full summing fold is clean and cutscenes regain centre and rear content.
AC6's cutscene mixer submits its 5.1 premix to all six speaker slots as decorrelated near-copies of one mix; six real speakers separate them acoustically, but the port's 6→2 fold sums them, combing speech into the long-reported doubled dialogue. While the demo sequencer ticks, fold only the fronts (verified lossless). audio_cutscene_downmix (default on).
A render hitch during an in-engine cutscene permanently desynced video from the audio, which is master and keeps playing. Weak-symbol wrappers around the two demo-manager Exec functions issue bounded catch-up ticks computed from the audio clients' consumed-sample clock (48 kHz, deficit threshold 2). Behind ac6_cutscene_resync (on); dev tooling default-off.
The cutscene DoF chain is authored for the 640×360 guest grid; at render scale > 1 its guest-granular blur kernels alias against host-granular content, visible as streaks and ghost outlines. Fix: snap the two CoC pre-blur passes to guest texel centers and densify the two 13-tap gather passes per axis. Hash-allowlisted, behind ac6_fix_dof (on), inert at 1x.
ac6_widescreen = true (default false), renders missions at the window's aspect ratio (hor+) by patching the game's per-camera aspect data, so FOV, culling and every camera follow. Menus, hangar, briefing and FMV revert to 16:9 and letterbox. The HUD is pre-squeezed at draw time to stay crisp, and marker art is squared without moving the aim points. ac6_widescreen_cinematics enables it in in-game cutscenes(default true, gated).
Keyboard/mouse state is injected at the guest XamInput wrapper boundary, so
every layer of the input stack sees KB+M exactly as a connected pad, and a
real pad keeps working alongside. Menu and flight key sets (AC7-style
defaults) switch automatically via a flight-sim heartbeat; the mouse steers
pitch/roll with a velocity model, or pans the camera while the camera-control
key is held. With no controller connected, a synthetic pad is presented on
slot 0. Bindings and mouse feel live in ac6_input.toml (auto-created on first
run, hot-reloaded ~1x/s). Everything is off unless ac6_kbm_enabled is set.
Guest swap thread blocks on real GPU delivery (NotifyGuestPresent feeds the delivery counter) + an absolute-deadline limiter at ac6_fps_target, not the vblank grid (no sub-harmonic staircase). dt-snap locks the sim delta to the exact target at steady rate (kills the shake). Guest vblank forced to free-run during gameplay so pacing needs zero config. ac6_unlock_fps is the single master switch, ON by default (folded in timing-hooks/vblank-auto/delta-precision/dt-snap-tolerance AND the flight-model framerate-independence fix).
FPS/frametime counters (avg 0.5s), two fixed-time-interval frametime graphs (fps-independent, spikes preserved), present-wait metric (rex/ui/present_stats.h). Guest stats provider wired in OnCreateDialogs. Removed the old inline F3-only build watermark (moves to a standalone always-on drawer in a later commit).
The game builds its per-frame sim delta as floor(elapsed * 3000) + 1, capped at
100. The floor plus the +1 guard bias the delta high by (1 - frac) every frame,
which is invisible at the native 30fps (the cap absorbs it) but becomes a
systematic speed-up once the unlock frees the frame rate: about +2% at 60fps
and +10% at 300fps.
Add a hook on the delta computation that carries the fractional remainder
across frames, so the summed integer deltas track real elapsed time exactly
instead of rounding up every frame. Gated by ac6_delta_precision (default on)
and only active while the unlock's divisor remap is.
With the unlock forcing single-vblank presents, frame-locked content (menus,
hangar, in-engine cutscenes) free-runs far too fast while only gameplay should.
Pace the guest vblank dynamically: free-run only while the 3D world is being
rendered, otherwise force the native 60Hz.
"World is rendering" is detected from the GPU side - the command processor
stamps a heartbeat (NotifyWorldCompositorDraw) whenever a draw uses the
world/effects compositor pixel shader (ucode 17e5e4ac3e713245), which runs
every frame of 3D but never in the 2D front-end. The present timing hook then
sets a guest-vblank Hz override via the new GraphicsSystem hook. Only engages
under the unlock; ac6_dynamic_vblank=false restores the plain always-on unlock.
The flight model's longitudinal force/speed-command accumulator and the
accel/brake trigger command are stepped by fixed per-frame constants with no
delta, so with ac6_unlock_fps active the plane accelerates and brakes
proportionally faster at higher frame rates.
Wrap the two flight-model functions (rex_sub_823046A0 force step,
rex_sub_82329B40 input shaping) and rescale each accumulator's net per-call
change by frame_time / 33.3ms, reproducing the native 30fps continuous-time
dynamics at any frame rate. Bit-exact pass-through at <=30fps; applies to
player and AI aircraft. Gated by ac6_fps_physics_fix (default on) and only
active while the unlock's timing hooks are (ac6::TimingHooksActive).
Upscale mosaic. At draw-resolution scale > 1, AC6's deferred
EDRAM restore passes do integer pixel-address math on the PsParamGen
position. Its leftover sub-guest-pixel fraction scrambles into an 8x8
mosaic. Floor the param-gen position (param_gen_integer_guest_position)
and re-add the host sub-pixel at the fetch (param_gen_host_subpixel_restore).
Inert at 1x.
De-swizzle scramble. Some AC6 restore/resample passes
manually de-swizzle the Xenos EDRAM sub-tile layout of their source, which
is only correct on tiled data. The emulator detiles everything to linear,
so the de-swizzle always scrambles, streaking the cloud/effects pipeline.
For allowlisted shader hashes (ac6_neutralize_deswizzle_hashes) the sample
coordinate is replaced with the identity host-texel UV (a 1:1 copy).
Suspend the FPS unlock while a demo-manager Exec (DD sub_82184460 / EM sub_821856F8) ticks, so the frame-locked IngameCinematics Sequencer plays at native ~30fps instead of double speed. Adds ac6_cutscene_clamp CVar (default on).
Recovers the Apr 23 hand-edit (lost in subsequent refactors) and re-wires
it as a TOML midasm hook so codegen regeneration can no longer drop it.
Hook fires immediately after the guest decompressor (bl 0x822CF510)
returns, reads the entry record via r11 (codec at +1, csize at +8,
usize at +12), source offset from *(r31+22888), entry tag from r10, and
calls Ac6DumpPacDecodedEntry with the decoded buffer at r4. With
AC6_DUMP_PAC_DECODED=1, all 800 compressed entries now drop as
FHM-magic'd entry_*_mode1_*.bin in out/ac6_pac_runtime_dump/.
Also adds streamer-worker dispatch probes (AC6_TRACE_PAC_WORK_ITEMS),
PPC stack walking on PAC reads (AC6_TRACE_PAC_STACKS), the AC6 PAC
index parser, the chunk-coalescing dump fallback, and a user-facing
walkthrough at docs/ac6_asset_extraction_walkthrough.txt.
Add guest primitive-type histograms and per-frame DrawStatsSnapshot to frame capture summary so AC6 debugging can correlate point-list draws (trails) and sampler churn with native graphics planning without extra tooling.
Made-with: Cursor
Run the native renderer every frame from AC6 present timing hooks with a visible runtime status overlay so migration progress is observable in-game. Also add a tracked CMake bootstrap include and migration mapping docs so fresh clones can configure before generated glue exists.
Made-with: Cursor
Remove backup/, build logs, .bak files, and other workspace artifacts
that should have been gitignored from the start. Working tree is now
clean for rebase.
- Resolve merge conflicts in CMakeLists.txt, .gitignore, and all src/ files,
keeping the HEAD (native renderer) versions throughout
- Remove stale SDK alternate-tree ref (rexglue-sdk~6e0ca2f) from index
- Drop scratch files: 'New Text Document.txt', *.bak
- Rewrite README with full setup instructions, prereqs table, build
preset table, run command, project layout overview, and Linux section