Skip to content

feat(system): Load Uniscribe at runtime - #3241

Open
OmarAglan wants to merge 1 commit into
TheSuperHackers:mainfrom
OmarAglan:feature/usp10-loader
Open

feat(system): Load Uniscribe at runtime#3241
OmarAglan wants to merge 1 commit into
TheSuperHackers:mainfrom
OmarAglan:feature/usp10-loader

Conversation

@OmarAglan

Copy link
Copy Markdown

Adds a small Windows-only loader for the five Uniscribe functions required by the complex-text renderer.

The loader resolves the functions from the system usp10.dll at runtime and reports failure to callers when Uniscribe is unavailable. This allows #3231 to retain the existing per-character renderer as its fallback while removing the compile-time dependency on usp10.h and usp10.lib, which are missing from the VC6 SDK.

Cross-platform text shaping remains outside this focused compatibility change.

The stacked result was validated with:

  • Visual Studio 2022 x86 Release builds of Generals and Zero Hour
  • The repository’s exact portable VC6 toolchain for Generals and Zero Hour
  • Verification that the resulting executables do not statically import usp10.dll
  • git diff --check

The change was developed with AI assistance, then manually reviewed against the nearby runtime-loader pattern and the official Windows SDK function declarations.

@OmarAglan
OmarAglan marked this pull request as ready for review August 31, 2026 20:18
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Load required Uniscribe APIs dynamically on Windows

✨ Enhancement 🕐 10-20 Minutes

Grey Divider

AI Description

• Loads five Uniscribe APIs dynamically from Windows’ system usp10.dll.
• Reports unavailable libraries or exports so renderers can retain existing fallbacks.
• Provides SDK-independent declarations compatible with the portable VC6 toolchain.
Diagram

graph TD
    Renderer["Text renderer"] --> Loader["Usp10 loader"] --> Attempt{"First attempt?"}
    Attempt -->|Yes| DLL["System usp10.dll"] --> Exports["Five exports"] --> Status["Cached status"]
    Attempt -->|No| Status
Loading
High-Level Assessment

The runtime-loader approach is appropriate for this compatibility-focused change: it avoids unavailable VC6 SDK headers and import libraries, prevents a static usp10.dll dependency, loads only from the Windows system directory, and exposes failure for the renderer’s existing fallback. Static linking and linker delay-loading were considered but would retain toolchain or import-table dependencies, while a general-purpose loader abstraction would add unnecessary scope for five tightly related APIs.

Files changed (3) +184 / -0

Enhancement (2) +182 / -0
Usp10Loader.cppResolve and wrap Uniscribe exports at runtime +111/-0

Resolve and wrap Uniscribe exports at runtime

• Implements thread-safe, one-time loading of 'usp10.dll' from the Windows system directory and resolves five required exports. Wrapper methods return 'E_FAIL' or 'nullptr' when the DLL or any required function is unavailable, allowing callers to fall back safely.

Core/Libraries/Source/WWVegas/WWLib/Usp10Loader.cpp

Usp10Loader.hDeclare SDK-independent Uniscribe wrappers +71/-0

Declare SDK-independent Uniscribe wrappers

• Defines the minimal opaque types, flags, function signatures, and loader state required by the complex-text renderer without including 'usp10.h'. The public static API mirrors the required Uniscribe calls while hiding dynamic-resolution details.

Core/Libraries/Source/WWVegas/WWLib/Usp10Loader.h

Other (1) +2 / -0
CMakeLists.txtBuild the Uniscribe loader on Windows +2/-0

Build the Uniscribe loader on Windows

• Adds the loader implementation and header to WWLib’s Windows-only source list, keeping non-Windows builds unaffected.

Core/Libraries/Source/WWVegas/WWLib/CMakeLists.txt

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider

Great, no issues found!

Qodo reviewed your code and found no material issues that require review

Grey Divider

Tip of the day
💡 Did you know, you can type 'qodo, fix this' on a finding and the fix lands right on your PR

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

@greptile-apps

greptile-apps Bot commented Aug 31, 2026

Copy link
Copy Markdown

Greptile Summary

The PR adds a Windows-only runtime loader for five Uniscribe functions, avoiding a compile-time dependency on usp10.h and usp10.lib.

  • Registers the loader implementation with the Windows WWLib source set.
  • Loads usp10.dll from the Windows system directory.
  • Resolves and caches the required exports, returning failure when loading or symbol resolution fails.

Confidence Score: 5/5

The PR appears safe to merge because no blocking failure remains.

No blocking failure remains.

Important Files Changed

Filename Overview
Core/Libraries/Source/WWVegas/WWLib/Usp10Loader.cpp Implements synchronized, process-lifetime loading and fail-closed dispatch for five Uniscribe exports.
Core/Libraries/Source/WWVegas/WWLib/Usp10Loader.h Defines the loader interface, opaque Uniscribe types, constants, and function-pointer signatures.
Core/Libraries/Source/WWVegas/WWLib/CMakeLists.txt Adds the loader files to the Windows-only WWLib source set.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    Caller[Complex-text renderer] --> Wrapper[Usp10Loader wrapper]
    Wrapper --> Cached{Load already attempted?}
    Cached -->|No| SystemPath[Build system-directory DLL path]
    SystemPath --> Load[Load usp10.dll]
    Load --> Resolve[Resolve five Uniscribe exports]
    Resolve -->|All available| Invoke[Invoke requested function]
    Resolve -->|Missing export| Failure[Return E_FAIL or nullptr]
    Load -->|Load fails| Failure
    Cached -->|Yes and loaded| Invoke
    Cached -->|Yes and unavailable| Failure
Loading

Reviews (2): Last reviewed commit: "feat(system): Load Uniscribe at runtime" | Re-trigger Greptile

Comment thread Core/Libraries/Source/WWVegas/WWLib/Usp10Loader.cpp Outdated
Comment thread Core/Libraries/Source/WWVegas/WWLib/Usp10Loader.cpp Outdated
Comment thread Core/Libraries/Source/WWVegas/WWLib/Usp10Loader.h Outdated
Comment thread Core/Libraries/Source/WWVegas/WWLib/Usp10Loader.cpp Outdated

private:

static bool load();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The current model does not allow to unload it. Is this acceptable?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

well its intentional be desigin, usp10.dll is loaded on first use and retained until process exit.
adding unload or reference counting would introduce lifecycle and synchronization risks without a practical benefit for the game, i only added comment to clerify!

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

In principle the permanent lifetime is ok, but technically it is a handle leak. HMODULE Module is never freed so Windows will log this as a leaked handle at program termination. It would be cleaner to free it on shutdown.

It will not race because there is a CriticalSection to use.

Comment thread Core/Libraries/Source/WWVegas/WWLib/Usp10Loader.cpp Outdated
@OmarAglan

Copy link
Copy Markdown
Author

@codex

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Breezy!

Reviewed commit: 68a4beb2f0

ℹ️ 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@OmarAglan
OmarAglan force-pushed the feature/usp10-loader branch from 68a4beb to 370c8ed Compare September 2, 2026 17:58
@OmarAglan
OmarAglan requested a review from xezon September 2, 2026 18:02
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.

2 participants