From 47668c2998f77f8116a8fa8252d73befe8a34cd4 Mon Sep 17 00:00:00 2001 From: costin-alupului <23552514+costin-alupului@users.noreply.github.com> Date: Fri, 17 Jul 2026 17:39:22 +0300 Subject: [PATCH] bugfix: Re-assert FP mode in mouse pick to fix wrong click location with audio active screenToTerrain() and pickDrawable() perform screen->world ray/coordinate math without setting the FPU mode the engine relies on (GameLogic::update() calls setFPMode() every frame for its fast float->int conversions). On macOS/ARM the audio thread leaves the floating-point environment in a state that skews these conversions, so clicks resolve to the wrong world tile whenever audio is active. Call setFPMode() at the top of both pick functions. Fixes #215 AI-assisted: change authored with Claude; verified in-game by me (clicks and camera-jump freeze fixed with audio on, tested on three displays at native fullscreen). Co-Authored-By: Claude Opus 4.8 (1M context) --- .../Source/W3DDevice/GameClient/W3DView.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp index cfd8e75a3f9..b2e7e119ba8 100644 --- a/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp +++ b/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp @@ -68,6 +68,7 @@ #include "GameLogic/AI.h" ///< For AI debug (yes, I'm cheating for now) #include "GameLogic/AIPathfind.h" ///< For AI debug (yes, I'm cheating for now) #include "GameLogic/ExperienceTracker.h" +#include "GameLogic/FPUControl.h" ///< GeneralsX @bugfix costin-alupului 10/07/2026 setFPMode() to guard screen->world pick math against audio-thread FP env leaks #include "GameLogic/GameLogic.h" #include "GameLogic/Module/AIUpdate.h" #include "GameLogic/Module/BodyModule.h" @@ -2520,6 +2521,9 @@ Drawable *W3DView::pickDrawable( const ICoord2D *screen, Bool forceAttack, PickT if( screen == nullptr ) return nullptr; + // GeneralsX @bugfix costin-alupului 10/07/2026 Re-assert FP mode before the pick ray math (see screenToTerrain). + setFPMode(); + // don't pick a drawable if there is a window under the cursor GameWindow *window = nullptr; if (TheWindowManager) @@ -2575,6 +2579,14 @@ Bool W3DView::screenToTerrain( const ICoord2D *screen, Coord3D *world ) if( screen == nullptr || world == nullptr || TheTerrainRenderObject == nullptr ) return false; + // GeneralsX @bugfix costin-alupului 10/07/2026 The screen->world ray/intersection math below + // relies on a consistent FP rounding/environment (same reason GameLogic::update() calls + // setFPMode()). On macOS/ARM the audio backend thread can leave the FP environment in a state + // that skews the fast float->int coordinate conversion, causing clicks to resolve to the wrong + // world tile (move/build fail unless the camera is moved/zoomed to force a recompute). Re-assert + // the engine's FP mode here so picks are correct regardless of audio-thread activity. + setFPMode(); + if (m_cameraHasMovedSinceRequest) { m_locationRequests.clear(); m_cameraHasMovedSinceRequest = false;