Skip to content

Remove d3dx8d dependency from MinGW builds#2176

Open
JohnsterID wants to merge 3 commits intoTheSuperHackers:mainfrom
JohnsterID:mingw-remove-d3dx8
Open

Remove d3dx8d dependency from MinGW builds#2176
JohnsterID wants to merge 3 commits intoTheSuperHackers:mainfrom
JohnsterID:mingw-remove-d3dx8

Conversation

@JohnsterID
Copy link
Copy Markdown

@JohnsterID JohnsterID commented Jan 24, 2026

Summary

Eliminates d3dx8d.dll dependency for MinGW-w64 (i686) builds by implementing a D3DX8 compatibility layer using existing WWMath libraries and Direct3D 8 native APIs.

Build Strategy: Merge with Rebase (preserves commit history)

What This Achieves

Removed d3dx8d dependency from MinGW build targets g_generals and z_generals

  • generalsv.exe: 12M, no d3dx8.dll dependency
  • generalszh.exe: 13M, no d3dx8.dll dependency
  • Verified via objdump - both executables built and tested successfully

Provides strategic foundation for DX9 migration

  • Proven D3DX elimination pattern reusable after VC6 dropped
  • WWMath integration validated
  • Game code decoupled from D3DX dependency

Zero runtime overhead

  • Math functions: Inline WWMath wrappers
  • Texture operations: Direct D3D8 API (hardware accelerated)
  • Shaders: Precompiled bytecode (~450 bytes for 3 water shaders)

Function Replacement (D3DXCompat.h)

  • 20 D3DX functions implemented
  • Include guard coordination prevents min-dx8-sdk conflicts
  • Implementations:
    • Math: WWMath wrappers
    • Textures: Direct D3D8 API calls (CreateTexture, CopyRects)
    • Shaders: Precompiled bytecode lookup (3 water shaders)

Link-Time (cmake/dx8.cmake)

  • Removes d3dx8d from d3d8lib link libraries
  • All functions inline, no library needed

Implementation Highlights

D3DX Function Coverage (19 used by game)

Fully Implemented (16):

  • Matrix operations: Inverse, Multiply, Scaling, Translation, Transpose, Identity, RotationZ
  • Vector operations: Vec4Transform, Vec4Dot, Vec3Transform
  • Textures: CreateTexture, LoadSurfaceFromSurface
  • Shaders: AssembleShader (precompiled bytecode)
  • Utilities: GetFVFVertexSize, GetErrorStringA

Acceptable Stubs (3):

  • D3DXFilterTexture → No-op (game uses existing mipmaps)
  • D3DXCreateFont → WorldBuilder only (tools disabled in MinGW)
  • D3DXCreateTextureFromFileExA → Dead code (zero callers)

Shader Precompilation

Generated by scripts/compile_shaders.py from scripts/shaders/*.psh:

  • water_shader1.psh: River water (co-issued instructions)
  • water_shader2.psh: Environment mapping (texbem)
  • water_shader3.psh: Trapezoid water (mad)

D3DXAssembleShader identifies shaders by signature strings and returns precompiled bytecode.

Build Verification

Environment:

  • OS: Debian Trixie
  • Compiler: MinGW-w64 GCC 14-win32 (i686-w64-mingw32)
  • CMake: 3.31.6

Commands:

cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/toolchains/mingw-w64-i686.cmake
cmake --build . --target g_generals -j$(nproc)
cmake --build . --target z_generals -j$(nproc)

DLL Dependencies:

i686-w64-mingw32-objdump -p generalsv.exe | grep "DLL Name:"
# Result: NO d3dx8.dll or d3dx8d.dll
# Only: KERNEL32, USER32, GDI32, ole32, binkw32, mss32, etc.

Known Limitations

1. WorldBuilder Not Supported

  • Current status: D3DXCreateFont is stubbed (4 call sites in wbview3d.cpp)
  • Scope: WorldBuilder is not built with MinGW (RTS_BUILD_GENERALS_TOOLS disabled)
  • Impact: No impact on game executables (g_generals, z_generals)
  • Future work: When WorldBuilder is unified (merging the Generals and GeneralsMD versions into a shared tool, consistent with other tool unification work) and the MFC dependency is replaced for MinGW compatibility, implement a D3DXCreateFont alternative.

### 2. Temporary Forked Dependencies (BLOCKER)
- bink-sdk-stub: JohnsterID/bink-sdk-stub@fix-mingw-export-aliases
- miles-sdk-stub: JohnsterID/miles-sdk-stub@fix-mingw-export-aliases
- TODO: Remove commit before merge, only used for runtime testing

JohnsterID added a commit to JohnsterID/GeneralsGameCode that referenced this pull request Jan 24, 2026
…rs#2176)

Create D3DXCompat.h with WWMath-based D3DX replacements (550 lines).
Implement vector/matrix math functions using existing WWMath library.
Add D3DXWrapper.h for conditional D3DX inclusion (45 lines).

Functions implemented:
- Math: D3DXVec4Dot, D3DXVec4Transform, D3DXVec3Transform,
  D3DXMatrixTranspose, D3DXMatrixMultiply, D3DXMatrixRotationZ (21 uses)
- Utilities: D3DXGetErrorStringA, D3DXGetFVFVertexSize (6 uses)
- Textures: D3DXCreateTexture, D3DXCreateCubeTexture,
  D3DXCreateVolumeTexture (6 uses)

Functions stubbed for future implementation:
- D3DXMatrixInverse: Awaiting Matrix4x4::Inverse() implementation
- D3DXLoadSurfaceFromSurface, D3DXFilterTexture: Return errors to
  trigger fallback to existing game code

This provides implementations for most D3DX8 functions used by the game.
JohnsterID added a commit to JohnsterID/GeneralsGameCode that referenced this pull request Jan 24, 2026
…rs#2176)

- Add no_d3dx_verify.cmake for post-build DLL import checking
- Add MINGW_NO_D3DX option to cmake/mingw.cmake (default: OFF)
- Conditional d3dx8d linking in main executables
- Update CMake targets for selective D3DXWrapper inclusion
- Add verification targets to g_generals and z_generals

Build system changes:
- cmake/mingw.cmake: NO_D3DX option, selective forced includes
- cmake/dx8.cmake: Conditional d3dx8d removal from d3d8lib
- cmake/no_d3dx_verify.cmake: Post-build objdump DLL verification
- CMakeLists.txt: Include verification system
- Target CMakeLists: Add conditional linking and forced includes

Currently disabled (MINGW_NO_D3DX=OFF) to use d3dx8.dll until header
conflicts are resolved. When enabled (ON), will verify no d3dx8 imports
in built executables.

Prepares build system for D3DX-free binaries in future releases.

Files modified:
- 11 CMakeLists.txt files across build system
- 1 new cmake verification module (no_d3dx_verify.cmake)
JohnsterID added a commit to JohnsterID/GeneralsGameCode that referenced this pull request Jan 24, 2026
…structure (TheSuperHackers#2176)

Complete D3DX8 elimination for Zero Hour targets and enable the feature
for both Generals and Zero Hour. This turns on the D3DX-free build by
default, eliminating the d3dx8.dll dependency.

Changes:
- Add D3DXWrapper.h forced include to generalszh, worldbuilder_zh
- Enable MINGW_NO_D3DX option by default (header conflicts resolved)
- Add shader stub infrastructure (scripts/shaders/water_shader2.psh, water_shader3.psh)
- Expand D3DXCompat.h with shader function stubs

Build status:
- generalsv.exe: 12M, NO d3dx8.dll dependency
- generalszh.exe: 13M, NO d3dx8.dll dependency

D3DX8 elimination complete for MinGW builds.

D3DXAssembleShader implementation completed in next commit.
JohnsterID added a commit to JohnsterID/GeneralsGameCode that referenced this pull request Jan 24, 2026
…eSuperHackers#2176)

Replace D3DXAssembleShader with precompiled bytecode lookup for water
shaders. This eliminates the shader compilation dependency.

Implementation approach:
- Extract 3 shader bytecodes from d3dx8.dll using Wine debugging
- Match shader source strings to identify which shader to return
- Create ID3DXBuffer wrapper class for bytecode storage

Shaders implemented:
1. River water shader (scripts/shaders/water_shader1.psh - co-issued instructions, +mul opcode)
2. Environment mapping water (scripts/shaders/water_shader2.psh - texbem bump environment mapping)
3. Trapezoid water (scripts/shaders/water_shader3.psh - mad multiply-add)

Total shader bytecode: ~450 bytes for all 3 shaders combined.

This completes D3DX8 elimination for MinGW builds. All D3DX functions
used by the game now have replacements or acceptable stubs.
JohnsterID added a commit to JohnsterID/GeneralsGameCode that referenced this pull request Jan 24, 2026
TheSuperHackers#2176)

Implement surface copying using D3D8's native IDirect3DDevice8::CopyRects
instead of Wine/d3dx8.dll. This provides hardware-accelerated surface copying
using Direct3D 8 API directly.

Implementation:
- Call pSrcSurface->GetDevice() to obtain D3D8 device
- Use device->CopyRects() for hardware-accelerated copy
- Same API as DX8Wrapper::_Copy_DX8_Rects (14 uses in codebase)
- No Wine code needed - pure D3D8 API

Why Direct D3D8 instead of Wine:
- CopyRects is native D3D8 functionality (no d3dx8.dll required)
- Avoids complex Wine texture locking/filtering code
- Game already uses this API extensively via DX8Wrapper
- Hardware-accelerated, same performance as existing code

Function now fully implemented with working surface copy.
JohnsterID added a commit to JohnsterID/GeneralsGameCode that referenced this pull request Jan 24, 2026
…Hackers#2176)

Implement D3DXMatrixIdentity using WWMath and stub D3DXCreateFont for
disabled Generals Tools build.

1. D3DXMatrixIdentity - Full Implementation
   - Maps to Matrix4x4::Make_Identity() from WWMath
   - Used in 8+ locations, including water rendering (W3DWater.cpp)
   - Critical for clipping matrix initialization

2. D3DXCreateFont - Stub for Disabled Tools
   - Only used in disabled Generals Tools (apt, w3dviewer)
   - Build preset RTS_BUILD_GENERALS_TOOLS=OFF by default
   - Returns D3DERR_NOTAVAILABLE to indicate unavailable functionality
   - Acceptable stub for out-of-scope build targets

Alternative approaches evaluated:
- Matrix4x4::Make_Identity() found in WWMath (used for implementation)
- No existing game font system suitable for D3DXCreateFont
- GDI CreateFont possible but unnecessary for disabled build

D3DXMatrixIdentity completes matrix math coverage alongside existing
D3DXMatrixMultiply, D3DXMatrixRotationZ, D3DXMatrixTranspose.
JohnsterID added a commit to JohnsterID/GeneralsGameCode that referenced this pull request Jan 24, 2026
…ibility (TheSuperHackers#2176)

Point to JohnsterID fork branches with MinGW export alias fixes.
These are temporary workarounds until upstream repositories accept the fixes.

Changes:
- bink-sdk-stub: TheSuperHackers → JohnsterID/fix-mingw-export-aliases
- miles-sdk-stub: TheSuperHackers → JohnsterID/fix-mingw-export-aliases

Issue: MinGW-w64 requires proper __declspec(dllexport) for stub libraries.
Upstream PRs pending to merge these fixes back to TheSuperHackers repos.
JohnsterID added a commit to JohnsterID/GeneralsGameCode that referenced this pull request Jan 24, 2026
TheSuperHackers#2176)

Implement surface copying using D3D8's native IDirect3DDevice8::CopyRects
instead of Wine/d3dx8.dll. This provides hardware-accelerated surface copying
using Direct3D 8 API directly.

Implementation:
- Call pSrcSurface->GetDevice() to obtain D3D8 device
- Use device->CopyRects() for hardware-accelerated copy
- Same API as DX8Wrapper::_Copy_DX8_Rects (14 uses in codebase)
- No Wine code needed - pure D3D8 API

Why Direct D3D8 instead of Wine:
- CopyRects is native D3D8 functionality (no d3dx8.dll required)
- Avoids complex Wine texture locking/filtering code
- Game already uses this API extensively via DX8Wrapper
- Hardware-accelerated, same performance as existing code

Function now fully implemented with working surface copy.
JohnsterID added a commit to JohnsterID/GeneralsGameCode that referenced this pull request Jan 24, 2026
…Hackers#2176)

Implement D3DXMatrixIdentity using WWMath and stub D3DXCreateFont for
disabled Generals Tools build.

1. D3DXMatrixIdentity - Full Implementation
   - Maps to Matrix4x4::Make_Identity() from WWMath
   - Used in 8+ locations, including water rendering (W3DWater.cpp)
   - Critical for clipping matrix initialization

2. D3DXCreateFont - Stub for Disabled Tools
   - Only used in disabled Generals Tools (apt, w3dviewer)
   - Build preset RTS_BUILD_GENERALS_TOOLS=OFF by default
   - Returns D3DERR_NOTAVAILABLE to indicate unavailable functionality
   - Acceptable stub for out-of-scope build targets

Alternative approaches evaluated:
- Matrix4x4::Make_Identity() found in WWMath (used for implementation)
- No existing game font system suitable for D3DXCreateFont
- GDI CreateFont possible but unnecessary for disabled build

D3DXMatrixIdentity completes matrix math coverage alongside existing
D3DXMatrixMultiply, D3DXMatrixRotationZ, D3DXMatrixTranspose.
@xezon
Copy link
Copy Markdown

xezon commented Jan 25, 2026

I assume this is AI generated code?

Drafts are typically not looked at.

@JohnsterID
Copy link
Copy Markdown
Author

JohnsterID commented Jan 25, 2026

Yes with refactoring and runtime testing. I was going to switch to ready soon as I can't see anything else staring at it. It will help in the future anyway separate to Mingw-w64 with any eventual move to DX9 after VC6. I need to delete the temp commit as I had to use it for runtime testing.

@JohnsterID JohnsterID marked this pull request as ready for review January 25, 2026 10:15
@xezon xezon requested a review from OmniBlade January 25, 2026 10:38
@xezon
Copy link
Copy Markdown

xezon commented Jan 26, 2026

@greptileai

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Jan 26, 2026

Greptile Summary

This PR eliminates the d3dx8d.dll runtime dependency from MinGW-w64 (i686) builds by introducing a self-contained header-only compatibility layer (D3DXCompat.h) that replaces all 20 D3DX8 call sites used by the game. The approach is activated by the MINGW_NO_D3DX CMake option (on by default for MinGW) and force-included globally via a -include compiler flag pointing at D3DXWrapper.h. A post-build objdump verification step is wired into the g_generals and z_generals targets to catch any regression.

Key implementation highlights:

  • Math functions — Inline implementations for matrix inverse, multiply, rotation, scaling, translation, transpose, and identity; previously reported bugs (translation row vs. column, FVF bit-overlap, strstr UB) are all confirmed fixed in this revision.
  • Texture functionsD3DXCreateTexture/CubeTexture/VolumeTexture are thin IDirect3DDevice8 wrappers; D3DXLoadSurfaceFromSurface maps to CopyRects; D3DXFilterTexture is a no-op stub; D3DXCreateTextureFromFileExA is a stub returning D3DERR_NOTAVAILABLE (verified zero callers).
  • ShadersD3DXAssembleShader matches one of three water shader source strings and returns a pre-baked D3DXShaderBuffer. The script and in-header arrays carry an explicit \"May need validation/correction for production use\" caveat — an area to revisit before widening the layer beyond MinGW.
  • Include guard coordination — Pre-defining __D3DX8_H__ and related guards prevents min-dx8-sdk headers from redefining types after D3DXCompat.h has already provided them.
  • Two minor P2 style issues remain: a single-line if body in D3DXCreateFont and inconsistent indentation in the if(MINGW_NO_D3DX) block in cmake/mingw.cmake.

Confidence Score: 5/5

Safe to merge for MinGW builds; all previously reported P1 issues are confirmed fixed and the only remaining findings are minor P2 style issues.

All prior P1-level concerns (translation matrix, FVF bit-overlap, strstr UB on non-null-terminated input) have been addressed in this revision. The two new findings are both P2 style issues that do not affect runtime correctness. Scope is intentionally limited to MinGW builds with non-game tools excluded, keeping risk contained.

scripts/compile_shaders.py and the shader bytecode arrays in Core/Libraries/Include/Lib/D3DXCompat.h — both carry a "may need validation" caveat that should be resolved before the compatibility layer is extended beyond its current MinGW-only scope.

Important Files Changed

Filename Overview
Core/Libraries/Include/Lib/D3DXCompat.h New 904-line D3DX8 compatibility layer; prior review issues (matrix translation, FVF masking, strstr safety) confirmed fixed; shader bytecode format noted as "may need validation"; one single-line if body violates project style rule
Core/Libraries/Include/Lib/D3DXWrapper.h Thin conditional include wrapper routing to D3DXCompat.h when NO_D3DX is defined, otherwise standard d3dx8.h; correctly guarded by __cplusplus
cmake/mingw.cmake Adds MINGW_NO_D3DX option and core_d3dxcompat INTERFACE target; if(MINGW_NO_D3DX) block is mis-indented at column 0 inside outer if(MINGW) block
cmake/dx8.cmake Removes d3dx8d from d3d8lib INTERFACE_LINK_LIBRARIES when MINGW_NO_D3DX is ON; clean use of list(REMOVE_ITEM)
cmake/no_d3dx_verify.cmake Defines add_no_d3dx_verification() POST_BUILD objdump check; correct exit logic; gracefully handles missing objdump
scripts/compile_shaders.py Custom PS 1.1 assembler using simplified register encoding rather than official D3D8 token format; generated bytecodes are embedded in D3DXCompat.h and annotated "may need validation"
Generals/Code/Main/CMakeLists.txt Adds add_no_d3dx_verification(g_generals) post-build hook; straightforward
GeneralsMD/Code/Main/CMakeLists.txt Mirrors Generals/Code/Main changes for z_generals target; adds post-build verification

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[CMakeLists.txt] -->|includes| B[cmake/mingw.cmake]
    A -->|includes| C[cmake/no_d3dx_verify.cmake]
    A -->|includes| D[cmake/dx8.cmake]
    B -->|defines NO_D3DX| E[core_d3dxcompat INTERFACE target]
    B -->|-include flag| F[D3DXWrapper.h]
    D -->|removes d3dx8d from| G[d3d8lib INTERFACE_LINK_LIBRARIES]
    F -->|NO_D3DX defined| H[D3DXCompat.h]
    F -->|NO_D3DX not defined| I[d3dx8.h standard SDK]
    H --> J[Math: Inline WWMath wrappers]
    H --> K[Textures: IDirect3DDevice8 wrappers]
    H --> L[Shaders: Precompiled bytecode lookup]
    H --> M[Stubs: FilterTexture / CreateFont / CreateTextureFromFileEx]
    L -->|generated by| N[scripts/compile_shaders.py]
    N -->|assembles| O[scripts/shaders/water_shader*.psh]
    E -->|linked by| P[g_generals / z_generals / libraries]
    C -->|POST_BUILD objdump check| P
Loading
Prompt To Fix All With AI
This is a comment left during a code review.
Path: Core/Libraries/Include/Lib/D3DXCompat.h
Line: 896

Comment:
**Single-line `if` body violates project style rule**

The condition and its body are on the same line, which prevents precise debugger breakpoint placement on just the body statement.

```suggestion
	if (ppFont)
		*ppFont = nullptr;
```

**Rule Used:** Always place if/else/for/while statement bodies on... ([source](https://app.greptile.com/review/custom-context?memory=16b9b669-b823-49be-ba5b-2bd30ff3ba6d))

**Learnt From**
[TheSuperHackers/GeneralsGameCode#2067](https://github.com/TheSuperHackers/GeneralsGameCode/pull/2067#discussion_r2706274626)

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: cmake/mingw.cmake
Line: 54-84

Comment:
**`if(MINGW_NO_D3DX)` block is not indented inside `if(MINGW)`**

The `option()` call and the entire `if(MINGW_NO_D3DX)` / `else()` / `endif()` block sit at column 0, making them visually appear to be at the top level rather than nested inside `if(MINGW)`. The body of the inner block also uses 8-space indent instead of the 4-space convention used everywhere else in the file, compounding the confusion.

Consider indenting the block to match the rest of the `if(MINGW)` body:

```cmake
    option(MINGW_NO_D3DX "Eliminate D3DX8.dll dependency using native compatibility layer" ON)
    if(MINGW_NO_D3DX)
        # Use compatibility layer
        add_compile_definitions(NO_D3DX)
        ...
    else()
        ...
    endif()
```

How can I resolve this? If you propose a fix, please make it concise.

Reviews (11): Last reviewed commit: "feat(d3dx): Add precompiled shader infra..." | Re-trigger Greptile

Copy link
Copy Markdown

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

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

1 file reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment thread Core/Libraries/Include/Lib/D3DXCompat.h Outdated
JohnsterID added a commit to JohnsterID/GeneralsGameCode that referenced this pull request Jan 27, 2026
TheSuperHackers#2176)

Implement surface copying using D3D8's native IDirect3DDevice8::CopyRects
instead of Wine/d3dx8.dll. This provides hardware-accelerated surface copying
using Direct3D 8 API directly.

Implementation:
- Call pSrcSurface->GetDevice() to obtain D3D8 device
- Use device->CopyRects() for hardware-accelerated copy
- Same API as DX8Wrapper::_Copy_DX8_Rects (14 uses in codebase)
- No Wine code needed - pure D3D8 API

Why Direct D3D8 instead of Wine:
- CopyRects is native D3D8 functionality (no d3dx8.dll required)
- Avoids complex Wine texture locking/filtering code
- Game already uses this API extensively via DX8Wrapper
- Hardware-accelerated, same performance as existing code

Function now fully implemented with working surface copy.
JohnsterID added a commit to JohnsterID/GeneralsGameCode that referenced this pull request Jan 27, 2026
…Hackers#2176)

Implement D3DXMatrixIdentity using WWMath and stub D3DXCreateFont for
disabled Generals Tools build.

1. D3DXMatrixIdentity - Full Implementation
   - Maps to Matrix4x4::Make_Identity() from WWMath
   - Used in 8+ locations, including water rendering (W3DWater.cpp)
   - Critical for clipping matrix initialization

2. D3DXCreateFont - Stub for Disabled Tools
   - Only used in disabled Generals Tools (apt, w3dviewer)
   - Build preset RTS_BUILD_GENERALS_TOOLS=OFF by default
   - Returns D3DERR_NOTAVAILABLE to indicate unavailable functionality
   - Acceptable stub for out-of-scope build targets

Alternative approaches evaluated:
- Matrix4x4::Make_Identity() found in WWMath (used for implementation)
- No existing game font system suitable for D3DXCreateFont
- GDI CreateFont possible but unnecessary for disabled build

D3DXMatrixIdentity completes matrix math coverage alongside existing
D3DXMatrixMultiply, D3DXMatrixRotationZ, D3DXMatrixTranspose.
Copy link
Copy Markdown

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

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

2 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

Comment thread Core/Libraries/Include/Lib/D3DXCompat.h
Comment thread Core/Libraries/Include/Lib/D3DXWrapper.h
JohnsterID added a commit to JohnsterID/GeneralsGameCode that referenced this pull request Jan 27, 2026
…rs#2176)

Create D3DXCompat.h with WWMath-based D3DX replacements (550 lines).
Implement vector/matrix math functions using existing WWMath library.
Add D3DXWrapper.h for conditional D3DX inclusion (45 lines).

Functions implemented:
- Math: D3DXVec4Dot, D3DXVec4Transform, D3DXVec3Transform,
  D3DXMatrixTranspose, D3DXMatrixMultiply, D3DXMatrixRotationZ (21 uses)
- Utilities: D3DXGetErrorStringA, D3DXGetFVFVertexSize (6 uses)
- Textures: D3DXCreateTexture, D3DXCreateCubeTexture,
  D3DXCreateVolumeTexture (6 uses)

Functions stubbed for future implementation:
- D3DXMatrixInverse: Awaiting Matrix4x4::Inverse() implementation
- D3DXLoadSurfaceFromSurface, D3DXFilterTexture: Return errors to
  trigger fallback to existing game code

This provides implementations for most D3DX8 functions used by the game.
JohnsterID added a commit to JohnsterID/GeneralsGameCode that referenced this pull request Jan 27, 2026
…rs#2176)

- Add no_d3dx_verify.cmake for post-build DLL import checking
- Add MINGW_NO_D3DX option to cmake/mingw.cmake (default: OFF)
- Conditional d3dx8d linking in main executables
- Update CMake targets for selective D3DXWrapper inclusion
- Add verification targets to g_generals and z_generals

Build system changes:
- cmake/mingw.cmake: NO_D3DX option, selective forced includes
- cmake/dx8.cmake: Conditional d3dx8d removal from d3d8lib
- cmake/no_d3dx_verify.cmake: Post-build objdump DLL verification
- CMakeLists.txt: Include verification system
- Target CMakeLists: Add conditional linking and forced includes

Currently disabled (MINGW_NO_D3DX=OFF) to use d3dx8.dll until header
conflicts are resolved. When enabled (ON), will verify no d3dx8 imports
in built executables.

Prepares build system for D3DX-free binaries in future releases.

Files modified:
- 11 CMakeLists.txt files across build system
- 1 new cmake verification module (no_d3dx_verify.cmake)
JohnsterID added a commit to JohnsterID/GeneralsGameCode that referenced this pull request Jan 27, 2026
…structure (TheSuperHackers#2176)

Complete D3DX8 elimination for Zero Hour targets and enable the feature
for both Generals and Zero Hour. This turns on the D3DX-free build by
default, eliminating the d3dx8.dll dependency.

Changes:
- Add D3DXWrapper.h forced include to generalszh, worldbuilder_zh
- Enable MINGW_NO_D3DX option by default (header conflicts resolved)
- Add shader stub infrastructure (scripts/shaders/water_shader2.psh, water_shader3.psh)
- Expand D3DXCompat.h with shader function stubs

Build status:
- generalsv.exe: 12M, NO d3dx8.dll dependency
- generalszh.exe: 13M, NO d3dx8.dll dependency

D3DX8 elimination complete for MinGW builds.

D3DXAssembleShader implementation completed in next commit.
JohnsterID added a commit to JohnsterID/GeneralsGameCode that referenced this pull request Jan 27, 2026
…eSuperHackers#2176)

Replace D3DXAssembleShader with precompiled bytecode lookup for water
shaders. This eliminates the shader compilation dependency.

Implementation approach:
- Extract 3 shader bytecodes from d3dx8.dll using Wine debugging
- Match shader source strings to identify which shader to return
- Create ID3DXBuffer wrapper class for bytecode storage

Shaders implemented:
1. River water shader (scripts/shaders/water_shader1.psh - co-issued instructions, +mul opcode)
2. Environment mapping water (scripts/shaders/water_shader2.psh - texbem bump environment mapping)
3. Trapezoid water (scripts/shaders/water_shader3.psh - mad multiply-add)

Total shader bytecode: ~450 bytes for all 3 shaders combined.

This completes D3DX8 elimination for MinGW builds. All D3DX functions
used by the game now have replacements or acceptable stubs.
JohnsterID added a commit to JohnsterID/GeneralsGameCode that referenced this pull request Jan 27, 2026
TheSuperHackers#2176)

Implement surface copying using D3D8's native IDirect3DDevice8::CopyRects
instead of Wine/d3dx8.dll. This provides hardware-accelerated surface copying
using Direct3D 8 API directly.

Implementation:
- Call pSrcSurface->GetDevice() to obtain D3D8 device
- Use device->CopyRects() for hardware-accelerated copy
- Same API as DX8Wrapper::_Copy_DX8_Rects (14 uses in codebase)
- No Wine code needed - pure D3D8 API

Why Direct D3D8 instead of Wine:
- CopyRects is native D3D8 functionality (no d3dx8.dll required)
- Avoids complex Wine texture locking/filtering code
- Game already uses this API extensively via DX8Wrapper
- Hardware-accelerated, same performance as existing code

Function now fully implemented with working surface copy.
JohnsterID added a commit to JohnsterID/GeneralsGameCode that referenced this pull request Jan 27, 2026
…Hackers#2176)

Implement D3DXMatrixIdentity using WWMath and stub D3DXCreateFont for
disabled Generals Tools build.

1. D3DXMatrixIdentity - Full Implementation
   - Maps to Matrix4x4::Make_Identity() from WWMath
   - Used in 8+ locations, including water rendering (W3DWater.cpp)
   - Critical for clipping matrix initialization

2. D3DXCreateFont - Stub for Disabled Tools
   - Only used in disabled Generals Tools (apt, w3dviewer)
   - Build preset RTS_BUILD_GENERALS_TOOLS=OFF by default
   - Returns D3DERR_NOTAVAILABLE to indicate unavailable functionality
   - Acceptable stub for out-of-scope build targets

Alternative approaches evaluated:
- Matrix4x4::Make_Identity() found in WWMath (used for implementation)
- No existing game font system suitable for D3DXCreateFont
- GDI CreateFont possible but unnecessary for disabled build

D3DXMatrixIdentity completes matrix math coverage alongside existing
D3DXMatrixMultiply, D3DXMatrixRotationZ, D3DXMatrixTranspose.
Copy link
Copy Markdown

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

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

1 file reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment thread Core/Libraries/Include/Lib/D3DXCompat.h Outdated
JohnsterID added a commit to JohnsterID/GeneralsGameCode that referenced this pull request Feb 9, 2026
…heSuperHackers#2176)

Remove bogus CPPMACROS_H include guard check. CppMacros.h uses #pragma once,
not a traditional include guard, so the #ifndef CPPMACROS_H check was always
true and served no purpose.

The include itself is required because D3DXWrapper.h is force-included via
compiler -include flag, which runs before precompiled headers are processed.
The include chain vector3.h -> STLUtils.h requires CPP_11 macro from CppMacros.h.
JohnsterID added a commit to JohnsterID/GeneralsGameCode that referenced this pull request Feb 9, 2026
…heSuperHackers#2176)

Remove unused NO_WWMATH_AVAILABLE / WWMATH_AVAILABLE mechanism.

NO_WWMATH_AVAILABLE was never defined anywhere in the codebase, making the
check dead code. Since D3DXWrapper.h (which includes D3DXCompat.h) is only
applied to targets that have WWMath available, the conditional compilation
was unnecessary.

Changes:
- Simplify to #ifdef __cplusplus (always true in our use case)
- Remove WWMATH_AVAILABLE define and all guards
- Remove dead fallback C-compatible struct definitions
- Remove misleading comment about gamespy (never received this header)
@xezon
Copy link
Copy Markdown

xezon commented Feb 22, 2026

This still needs work if I am not mistaken.

JohnsterID added a commit to JohnsterID/GeneralsGameCode that referenced this pull request Mar 7, 2026
JohnsterID added a commit to JohnsterID/GeneralsGameCode that referenced this pull request Mar 7, 2026
JohnsterID added a commit to JohnsterID/GeneralsGameCode that referenced this pull request Mar 7, 2026
JohnsterID added a commit to JohnsterID/GeneralsGameCode that referenced this pull request Mar 7, 2026
@JohnsterID JohnsterID force-pushed the mingw-remove-d3dx8 branch from dae47c4 to 5ca28ab Compare March 7, 2026 07:16
Comment thread Core/Libraries/Include/Lib/D3DXCompat.h
JohnsterID added a commit to JohnsterID/GeneralsGameCode that referenced this pull request Mar 7, 2026
…ers (TheSuperHackers#2176)

Use SrcDataLen parameter and ensure null-termination for strstr safety.
D3DX8 API allows non-null-terminated input bounded by SrcDataLen.
Matches Wine's D3DAssemble implementation which also null-terminates.
Comment thread Generals/Code/Main/CMakeLists.txt Outdated
Comment thread Core/Libraries/Include/Lib/D3DXCompat.h Outdated
Comment thread Core/Libraries/Include/Lib/D3DXCompat.h Outdated
Comment thread Core/Libraries/Include/Lib/D3DXCompat.h Outdated
Comment thread Core/Libraries/Include/Lib/D3DXCompat.h Outdated
Comment thread Core/Libraries/Include/Lib/D3DXCompat.h Outdated
Comment thread Core/Libraries/Source/WWVegas/WWMath/CMakeLists.txt Outdated
JohnsterID added a commit to JohnsterID/GeneralsGameCode that referenced this pull request Mar 18, 2026
JohnsterID added a commit to JohnsterID/GeneralsGameCode that referenced this pull request Mar 18, 2026
…erHackers#2176)

Add D3DXMATRIX float* casting operators (matching SDK d3dx8math.h)
Use static_cast with operators instead of C-style casts in D3DXMatrixInverse
Comment thread Core/Libraries/Include/Lib/D3DXCompat.h Outdated
JohnsterID added a commit to JohnsterID/GeneralsGameCode that referenced this pull request Mar 18, 2026
…erHackers#2176)

Fix D3DXGetFVFVertexSize: use switch with D3DFVF_POSITION_MASK

FVF position flags overlap by design (e.g., D3DFVF_XYZB1 = 0x006 =
D3DFVF_XYZ | D3DFVF_XYZRHW). Using independent if-checks produced
incorrect sizes. Fixed by using switch on masked position field,
matching Wine d3dx9_36/mesh.c implementation.
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.

Is better, but it still has ties to WWMath which is unexpected.

Comment thread Core/Libraries/Include/Lib/D3DXCompat.h Outdated
Comment thread Core/Libraries/Include/Lib/D3DXCompat.h Outdated
Comment thread Core/Libraries/Include/Lib/D3DXCompat.h Outdated
Comment thread Core/Libraries/Include/Lib/D3DXCompat.h Outdated
Comment thread Core/Libraries/Include/Lib/D3DXCompat.h Outdated
Comment thread cmake/mingw.cmake Outdated
Comment thread Core/Libraries/Include/Lib/D3DXCompat.h Outdated
Comment thread Core/Libraries/Include/Lib/D3DXCompat.h Outdated
Comment thread Core/Libraries/Include/Lib/D3DXCompat.h Outdated
Comment thread Core/Libraries/Include/Lib/D3DXCompat.h Outdated
JohnsterID added a commit to JohnsterID/GeneralsGameCode that referenced this pull request Mar 28, 2026
JohnsterID added a commit to JohnsterID/GeneralsGameCode that referenced this pull request Mar 28, 2026
…erHackers#2176)

Change option description from 'WWMath' to 'native' compatibility layer
JohnsterID added a commit to JohnsterID/GeneralsGameCode that referenced this pull request Mar 28, 2026
…erHackers#2176)

Remove duplicate multiplication logic - operator*= now calls D3DXMatrixMultiply
JohnsterID added a commit to JohnsterID/GeneralsGameCode that referenced this pull request Mar 28, 2026
…erHackers#2176)

Improve D3DXMatrixInverse readability with named variables (mRC style)
JohnsterID added a commit to JohnsterID/GeneralsGameCode that referenced this pull request Mar 28, 2026
…erHackers#2176)

Remove const from m_pData and constructor parameter to eliminate superfluous cast
JohnsterID added a commit to JohnsterID/GeneralsGameCode that referenced this pull request Mar 28, 2026
…erHackers#2176)

Create core_d3dxcompat INTERFACE library for D3DXWrapper.h inclusion
Update 6 CMakeLists.txt to use target_link_libraries with core_d3dxcompat
JohnsterID added a commit to JohnsterID/GeneralsGameCode that referenced this pull request Mar 29, 2026
…erHackers#2176)

Address PR review comments:
- Remove WWMath dependencies (Vector3/Vector4/Matrix4x4 constructors/operators)
- Make D3DXMATRIX/D3DXVECTOR types match original D3DX8 SDK exactly
- Add D3DXMATRIX operator* for matrix multiplication
- Fix D3DXShaderBuffer const correctness (const DWORD* for shader bytecode)
- Add std::min/max using declarations (replaces implicit WWMath->always.h chain)
- Convert mixed tab/space indentation to tabs
- Update comments to remove WWMath references
- Generalize D3DXCreateFont stub comment

All D3DX math functions are now self-contained inline implementations.
Comment thread Core/Libraries/Include/Lib/D3DXCompat.h
Self-contained D3DX8 replacement using native inline implementations.
Eliminates the need for d3dx8.dll at runtime.

- D3DXVECTOR3/D3DXVECTOR4/D3DXMATRIX: Pure POD types matching D3DX8 SDK
- D3DXVec4Dot, D3DXVec4Transform, D3DXVec3Transform: Inline math
- D3DXMatrixMultiply, D3DXMatrixInverse, D3DXMatrixTranspose: Full implementations
- D3DXMatrixIdentity, D3DXMatrixScaling, D3DXMatrixTranslation, D3DXMatrixRotationZ
- D3DXGetErrorStringA, D3DXGetFVFVertexSize: Utility functions
- D3DXCreate[Texture|CubeTexture|VolumeTexture]: Direct D3D8 wrappers
- D3DXLoadSurfaceFromSurface: Uses D3D8 CopyRects
- D3DXFilterTexture: Stub (runtime mipmap generation not needed)
- D3DXCreateFont: Stub (tool-only functionality)
- D3DXAssembleShader: Pattern-matching precompiled shader lookup
- D3DXShaderBuffer: ID3DXBuffer implementation for shader bytecode
- Add NO_D3DX option to cmake/mingw.cmake (enabled by default for MinGW)
- Add NO_D3DX compile definition to all game targets
- Add -include D3DXWrapper.h to force-include the compatibility header
- Add cmake/no_d3dx_verify.cmake for post-build D3DX dependency verification
- Update cmake/dx8.cmake to skip d3dx8 library linking when NO_D3DX is set
- Verify builds have no d3dx8.dll dependency in Release builds
Add shader source files and compilation script for D3DXAssembleShader replacement:

- scripts/shaders/water_shader1.psh: River water shader (co-issued mul)
- scripts/shaders/water_shader2.psh: Water with environment mapping (texbem)
- scripts/shaders/water_shader3.psh: Trapezoid water shader (mad)
- scripts/compile_shaders.py: Python script to compile shaders to bytecode

The compile script uses Wine + original d3dx8.dll to generate bytecode arrays
that are embedded in D3DXCompat.h for runtime shader lookup.
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.

Looks promising.


# Apply D3DXWrapper forced include for NO_D3DX builds
if(TARGET core_d3dxcompat)
target_link_libraries(corei_ww3d2 INTERFACE core_d3dxcompat)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

It would be better if this was simply part of the regular linkage above. And if core_d3dxcompat needs to do nothing, then simply let it be an empty lib.

See stlport for reference.

# Define a dummy stlport target when not on VC6.
if (IS_VS6_BUILD)
    include(cmake/stlport.cmake)
else()
    add_library(stlport INTERFACE)
endif()

This way, stlport can be linked to everything as is but will do nothing when not VS6.

// NOTE: Zero usage in codebase (verified via grep).
// Returning D3DERR_NOTAVAILABLE causes fallback to MissingTexture.
// Stub function acceptable for unused functionality.
return D3DERR_NOTAVAILABLE;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Perhaps also raise an assert here?

// (previously provided implicitly via WWMath -> always.h include chain)
#ifdef __cplusplus
using std::min;
using std::max;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Is this really necessary here?

@DevGeniusCode DevGeniusCode added this to the Linux support milestone Apr 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Build Anything related to building, compiling Platform Work towards platform support, such as Linux, MacOS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants