namespace XFEEDToolBox.Plugin; internal static unsafe partial class Navigation { private static nuint dockingZeroAxisRoot; private static ulong dockingZeroAxisVersion,dockingZeroAxisCommits,dockingZeroAxisRestoresSkipped; private static void RememberDockingZero(nuint root) {dockingZeroAxisRoot=root;dockingZeroAxisVersion++;dockingZeroAxisCommits++;} private static void RestoreOverlayAxis(nuint root,int axis,float previous,float written,ulong version) { // FSD can run inside an input-evaluation overlay. A durable original // zero must also survive restoration of that outer invocation. if(axis==0&&root==dockingZeroAxisRoot&&version!=dockingZeroAxisVersion) {dockingZeroAxisRestoresSkipped++;return;} var address=root+0x70+(nuint)axis*0x10; if(Read(address)==written)Write(address,previous); } // SetSpeedZero updates the original controller, but an SCA exit can leave // its last .75 value in the newly materialised ship's input buffer. Commit // the requested zero only after overlays have been released. The caller // has already checked the current main ship, owner, target and ATC grant. private static bool CommitOriginalDockingZeroAxis(nuint inputRoot,nuint controller,float sampledThrottle, bool originalInputConfirmed,bool inputLeaseReleased,out bool committed) { committed=false; if(!originalInputConfirmed||!inputLeaseReleased||inputRoot<0x10000||controller<0x10000 ||!float.IsFinite(sampledThrottle)||Math.Abs(sampledThrottle)>1.001f ||Pointer(inputRoot+0x2F8)!=controller||Read(controller+0x680)!=0)return false; var current=Read(inputRoot+0x70); if(current==0){RememberDockingZero(inputRoot);return true;} // A changed sample may be a player input. Never overwrite it. if(current!=sampledThrottle)return false; Write(inputRoot+0x70,0f); committed=Read(inputRoot+0x70)==0; if(committed)RememberDockingZero(inputRoot); return committed; } }