Repository navigation
refactor(ww3d2): Replace Vector3 reference casts with explicit field copies - #3580
Conversation
…copies Dazzle read TPoint3D<float> values through Vector3 references and wrote whole Vector3 values over the x member of its vertices. Recolor(unsigned&) and W3DAssetManager::Recolor_Vertices recolored the RGB part of a Vector4 through a Vector3 reference. These accesses go through an unrelated type. Build Vector3 values from the point members, store the vertex x, y and z fields one by one, and recolor an RGB copy whose result is written back with the original alpha. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
No actionable comments were generated in the recent review. ℹ️ Recent review info
WalkthroughThe changes replace vector reinterpret casts in color and dazzle code. Recoloring now handles RGB separately while preserving alpha. Dazzle configuration and quad positions use explicit component assignments. ChangesRGB and Dazzle Vector Handling
Priority: Estimated code review effort: 2 (Simple) | ~10 minutes Change: Refactor Suggested reviewers: Merge Risk:
|
[Medium impact] The PR appears safe to merge; no actionable issues were found.
|
Yes but most of them need special care (See #3605), I will be making follow up prs for those as i get some closed |
…copies (TheSuperHackers#3580) Dazzle read TPoint3D<float> values through Vector3 references and wrote whole Vector3 values over the x member of its vertices. Recolor(unsigned&) and W3DAssetManager::Recolor_Vertices recolored the RGB part of a Vector4 through a Vector3 reference. These accesses go through an unrelated type. Build Vector3 values from the point members, store the vertex x, y and z fields one by one, and recolor an RGB copy whose result is written back with the original alpha.
Some WW3D2 code reads or writes a
Vector4orTPoint3D<float>through aVector3reference. Accessing an object through a reference to an unrelated type is undefined behavior, the same problem #3521 tracks for float/integer casts. #3532 fixed those casts withstd::bit_cast, butbit_castcan't fix these sites.Vector3andVector4have user-provided copy constructors that aren't trivially copyable, and aVector4is larger than aVector3. This PR copies the fields instead.Changes
Init_From_INIin both games read 5TPoint3D<float>values throughVector3references. It now buildsVector3(tp.X,tp.Y,tp.Z).Render_Dazzlein both games wrote a wholeVector3oververtex->xat 8 places. It now storesx,yandzseparately.Recolor(unsigned&)incolorspace.hrecolored the RGB part of aVector4through aVector3reference. It now recolors aVector3copy and converts it with the original alpha.W3DAssetManager::Recolor_Verticesin both games had the same cast. It now recolors a copy and writes the RGB back withrgba.Set, which keeps alpha, before the existing clamp.DX8Wrapper::Convert_Color(const Vector4&)andConvert_Color_Clamphave the same cast and stay as they are for now. On VC6,Convert_Color(const Vector3&, float)is inline assembly that reads through the reference. A temporaryVector3there adds a stack copy of three floats to every call, including per-vertex loops, so that change needs its own PR.The
DazzleINIClassdowncast inInit_From_INIalso stays.ww3d.cpppasses a plainINIClass, so changing the cast wouldn't fix it.Testing
Generals and Zero Hour, with tools, build with VS 2026 and VC6 in Release and Debug.
I compared the disassembly of every rebuilt object against a build of
main.Init_From_INIloads the three floats before storing them.Recolor(unsigned&)converts alpha after the RGB call instead of before it.Copy_Image_Generate_MipmapinlinesRecolor. The arithmetic and the stored values are the same.Render_DazzleandRecolor_Verticescompile to the same code.RecolorandConvert_Color(unsigned)into the texture copy functions inbitmaphandler.cppandddsfile.cpp. In the GeneralsRender_Dazzle, twoMatrix4x4temporaries now share a stack slot, and the vertex stores keep the same structure. VC6 copies the newVector3temporaries inInit_From_INIthrough the x87 stack. That would quiet a signaling NaN, but these values come from INI text, which can't produce one.AI Disclosure
Claude Opus 5.5 was used to aid in implementation and to compare the disassembly.