Skip to content

refactor(w3ddevice): Swap silhouette edge indices with std::swap instead of an Int cast - #3635

Open
CryoTheRenegade wants to merge 2 commits into
TheSuperHackers:mainfrom
CryoTheRenegade:refactor/silhouette-edge-swap
Open

CryoTheRenegade wants to merge 2 commits into
TheSuperHackers:mainfrom
CryoTheRenegade:refactor/silhouette-edge-swap

Conversation

@CryoTheRenegade

@CryoTheRenegade CryoTheRenegade commented Oct 30, 2026 •

Copy link
Copy Markdown

Follow-up to #3580, #3605, #3617, #3628 and #3630. The shadow volume code swaps two silhouette edges by reading and writing their Short indices through an Int pointer. Accessing a Short array through an Int is undefined behavior, the same problem as #3521.

Summary

silhouetteIndices stores each edge as a start and end index. constructVolume and constructVolumeVB in both games move the edge that connects to the current one next to it. They now swap the start and end with std::swap:

 				//swap the two edges
-				Int tempIndex=*(Int *)(&silhouetteIndices[i+2]);
-				*(Int *)&silhouetteIndices[i+2]=*(Int *)&silhouetteIndices[k];
-				*(Int *)&silhouetteIndices[k]=tempIndex;
+				std::swap(silhouetteIndices[i+2], silhouetteIndices[k]);
+				std::swap(silhouetteIndices[i+3], silhouetteIndices[k+1]);

i and k both step by 2, so i+2 and k are always the start of an edge. When k is i+2, both versions leave the edge as it is.

Evidence

  • Disassembly: I compared both games' W3DVolumetricShadow objects against a build of main.
    • VS 2026 (ClangCL) Release: only constructVolume and constructVolumeVB changed. Each swap now uses four 16-bit loads and stores instead of two 32-bit ones. The other differences are register choice and block order. The float instructions and calls are the same.
    • VC6 Release: the same two functions changed, in the same way, plus stack slot and alignment padding changes. The rest of the object differs only in renumbered labels.

AI Disclosure

Claude Opus 5.5 was used to aid in implementation and to compare the disassembly.

CryoTheRenegade and others added 2 commits October 23, 2026 16:54
…f one Int

constructVolume and constructVolumeVB swapped a pair of Short silhouette
indices by reading and writing both through an Int pointer. Swap the two
Short values of each edge directly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ⚠️ Failed 2026-10-30T00:22:33.701015Z
We couldn’t complete this review. Comment @codex review to try again.
19523c9 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Walkthrough

Both game variants replace packed integer access with individual index swaps in the silhouette-edge ordering logic of constructVolume and constructVolumeVB. The edge-pair ordering logic and connection-search condition remain unchanged.

Changes

Volumetric shadow index swaps

Layer / File(s) Summary
Replace packed silhouette-index swaps
Generals/.../W3DVolumetricShadow.cpp, GeneralsMD/.../W3DVolumetricShadow.cpp
Both functions in each game variant now swap the two edge indices individually instead of accessing them through a casted Int pointer.

Priority: Low

Estimated code review effort: 2 (Simple) | ~8 minutes

Change: Refactor

Possibly related PRs

Suggested labels: Refactor, Minor, Rendering, Gen, ZH

Suggested reviewers: xezon, skyaero42

Merge Risk: Minimal · up to 19523

This narrowly scoped refactor preserves volumetric-shadow index behavior with no established merge-blocking risk.

Pre-merge checks: Passed 4
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main change: replacing the Int cast with std::swap for silhouette edge indices.
Description check Passed The description directly explains the undefined-behavior fix, the affected functions and games, the swap behavior, and the reported disassembly evidence.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[Low impact] The PR appears safe to merge; the new swaps preserve the existing edge ordering.

Summary

Replaces four edge swaps through Int pointers with paired std::swap calls in both games.

  • Shadow-volume builders swap silhouette-edge endpoints one index at a time.

Reviews (1) · Last reviewed commit: "refactor(w3ddevice): Swap the silhouette..." · Reviewed by Greptile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant