Skip to content

bugfix(dx8): Improve display mode transition reliability#2539

Merged
xezon merged 3 commits intoTheSuperHackers:mainfrom
githubawn:fix/setdisplaymode-tiny-bugs
Apr 7, 2026
Merged

bugfix(dx8): Improve display mode transition reliability#2539
xezon merged 3 commits intoTheSuperHackers:mainfrom
githubawn:fix/setdisplaymode-tiny-bugs

Conversation

@githubawn
Copy link
Copy Markdown

This PR addresses stability issues in the resolution switching logic.
These changes particularly improve stability when running under Wine but also resolve rare race conditions on native Windows.

  • Defer Render2D resolution update until after successful D3D reset
  • Snapshot current mode before Set_Device_Resolution for correct rollback
  • Fix fullscreen window failing to cover desktop by removing SWP_NOSIZE/NOMOVE
  • Remove dead D3DInterface release block in Shutdown

- Defer Render2D resolution update until after successful D3D reset
- Snapshot current mode before Set_Device_Resolution for correct rollback
- Fix fullscreen window failing to cover desktop by removing SWP_NOSIZE/NOMOVE
- Remove dead D3DInterface release block in Shutdown
@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Apr 5, 2026

Greptile Summary

Fixes four related bugs in the display mode transition path that caused incorrect rollback state, a renderer resolution mismatch on D3D reset failure, a silent no-op SetWindowPos call, and a dead double-release of D3DInterface during shutdown. All changes are mirrored identically across Generals/ and GeneralsMD/.

Confidence Score: 5/5

This PR is safe to merge; all four changes are correct, targeted bug fixes with no regressions introduced.

No P0 or P1 findings. The snapshot fix provably prevents stale rollback state, the Render2D deferral guards against incorrect resolution on D3D reset failure, the SetWindowPos flag removal fixes a silent no-op that was preventing fullscreen sizing, and the dead-code removal in Shutdown is provably safe since D3DInterface is already nulled earlier in the same function. Changes are consistently mirrored across both game directories.

No files require special attention.

Important Files Changed

Filename Overview
Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp Snapshots pre-change resolution values before calling Set_Device_Resolution to ensure rollback uses correct original state on failure
Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp Defers Render2D resolution update to after successful D3D reset; fixes SetWindowPos silently discarding size/position via SWP_NOSIZE
GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp Mirrors Generals fix: snapshots pre-change resolution values to fix incorrect rollback on failed mode switch
GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp Mirrors Generals fix: defers Render2D update, fixes SetWindowPos flags, removes dead D3DInterface release in Shutdown

Sequence Diagram

sequenceDiagram
    participant WD as W3DDisplay
    participant WW3D as WW3D
    participant DX8 as DX8Wrapper
    participant R2D as Render2DClass
    participant WIN as Win32 SetWindowPos

    WD->>WD: Snapshot oldWidth/Height/BitDepth/Windowed
    WD->>WW3D: Set_Device_Resolution(xres, yres, ...)
    WW3D->>DX8: Set_Render_Device(...)
    DX8->>WIN: SetWindowPos(HWND_TOPMOST, 0, 0, w, h, flags=0)
    Note over WIN: SWP_NOSIZE|SWP_NOMOVE removed — size+position now applied
    DX8->>DX8: Reset_Device() / Create_Device()
    alt D3D reset succeeds (ret=true)
        DX8->>R2D: Set_Screen_Resolution(w, h)
        DX8-->>WW3D: ret=true
        WW3D-->>WD: WW3D_ERROR_OK
        WD->>R2D: Set_Screen_Resolution(xres, yres)
        WD->>WD: Display::setDisplayMode(xres, yres)
        WD-->>WD: return TRUE
    else D3D reset fails (ret=false)
        Note over DX8: Render2D NOT updated (deferred guard)
        DX8-->>WW3D: ret=false
        WW3D-->>WD: error
        WD->>WW3D: Set_Device_Resolution(oldWidth, oldHeight, ...)
        WD->>R2D: Set_Screen_Resolution(oldWidth, oldHeight)
        WD->>WD: Display::setDisplayMode(oldWidth, oldHeight)
        WD-->>WD: return FALSE
    end
Loading

Reviews (3): Last reviewed commit: "unfancied const" | Re-trigger Greptile

@xezon xezon added Bug Something is not working right, typically is user facing Rendering Is Rendering related labels Apr 5, 2026
Copy link
Copy Markdown

@Skyaero42 Skyaero42 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me

Copy link
Copy Markdown

@xezon xezon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks ok.

So this change fixes 4 issues. The title is not so clear about what this fixes. It is unclear what "corner rendering" refers to. Can it be clearer?

@githubawn githubawn changed the title bugfix(dx8): Fix corner rendering and resolution switching rollback bugfix(dx8): Improve display mode transition reliability Apr 6, 2026
@githubawn
Copy link
Copy Markdown
Author

Changed the title to "bugfix(dx8): Improve display mode transition reliability" and switched to standard styling

@xezon xezon added the Minor Severity: Minor < Major < Critical < Blocker label Apr 7, 2026
@xezon xezon merged commit ff1baff into TheSuperHackers:main Apr 7, 2026
23 checks passed
@githubawn githubawn deleted the fix/setdisplaymode-tiny-bugs branch April 7, 2026 17:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug Something is not working right, typically is user facing Minor Severity: Minor < Major < Critical < Blocker Rendering Is Rendering related

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants