Compare commits

..

1 Commits

Author SHA1 Message Date
Marc 34dd80388f Merge dev: emulation re-JIT flush, unhook fallthrough, teardown safety (v1.9.0.3)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 18:06:00 +00:00
15 changed files with 9 additions and 1848 deletions
-2
View File
@@ -1,2 +0,0 @@
# Shell scripts must stay LF or bash on the CI runner chokes on \r.
*.sh text eol=lf
-28
View File
@@ -1,28 +0,0 @@
# Pre-configure SimplySign Desktop for unattended use:
# - auto-show the login dialog on launch (so the TOTP keystrokes have a target)
# - cache the smart-card PIN in the CSP, so signtool signs without a per-call
# PIN prompt, and forget it again when the session disconnects.
# Mirrors the settings used by the blinkdisk / docuscope CI signing setups.
$ErrorActionPreference = "Stop"
$RegistryPath = "HKCU:\Software\Certum\SimplySign"
$settings = [ordered]@{
ShowLoginDialogOnStart = 1
ShowLoginDialogOnAppRequest = 1
RememberLastUserName = 0
Autostart = 0
UnregisterCertificatesOnDisconnect = 0
RememberPINinCSP = 1
ForgetPINinCSPonDisconnect = 1
LangID = 9
}
Write-Host "=== Configuring SimplySign Desktop registry ==="
New-Item -Path $RegistryPath -Force | Out-Null
foreach ($name in $settings.Keys) {
Set-ItemProperty -Path $RegistryPath -Name $name -Value $settings[$name] -Type DWord
Write-Host " $name = $($settings[$name])"
}
Write-Host "Done."
-245
View File
@@ -1,245 +0,0 @@
# Authenticate SimplySign Desktop non-interactively.
#
# Certum's SimplySign cloud has no headless login: the certificate only reaches
# the Windows store after the GUI client authenticates. So we generate the
# current TOTP from the otpauth:// secret (CERTUM_OTP_URI) and paste the
# credentials into the login dialog. This needs an interactive desktop session,
# which GitHub-hosted Windows runners provide.
#
# Based on https://www.devas.life/how-to-automate-signing-your-windows-app-with-certum/
# and the refinements in blinkdisk's connect-simplysign.ps1.
param(
[string]$OtpUri = $env:CERTUM_OTP_URI,
[string]$UserId = $env:CERTUM_USERID,
[string]$ExePath = $env:CERTUM_EXE_PATH
)
if (-not $OtpUri) { Write-Host "ERROR: CERTUM_OTP_URI not provided"; exit 1 }
if (-not $UserId) { Write-Host "ERROR: CERTUM_USERID not provided"; exit 1 }
if (-not $ExePath) {
$ExePath = "C:\Program Files\Certum\SimplySign Desktop\SimplySignDesktop.exe"
}
Write-Host "=== SimplySign Desktop TOTP authentication ==="
if (-not (Test-Path $ExePath)) {
Write-Host "ERROR: SimplySign Desktop not found at $ExePath"
exit 1
}
# --- Parse the otpauth:// URI (works on PowerShell 5.1 and 7+) ---------------
$uri = [Uri]$OtpUri
try {
$q = [System.Web.HttpUtility]::ParseQueryString($uri.Query)
} catch {
$q = @{}
foreach ($part in $uri.Query.TrimStart('?') -split '&') {
$kv = $part -split '=', 2
if ($kv.Count -eq 2) { $q[$kv[0]] = [Uri]::UnescapeDataString($kv[1]) }
}
}
$Base32 = $q['secret']
$Digits = if ($q['digits']) { [int]$q['digits'] } else { 6 }
$Period = if ($q['period']) { [int]$q['period'] } else { 30 }
$Algorithm = if ($q['algorithm']) { $q['algorithm'].ToUpper() } else { 'SHA256' }
if (-not $Base32) { Write-Host "ERROR: otpauth URI has no 'secret'"; exit 1 }
if ($Algorithm -notin @('SHA1', 'SHA256', 'SHA512')) {
Write-Host "ERROR: unsupported TOTP algorithm: $Algorithm"
exit 1
}
# --- TOTP generator (RFC 6238), inline C# so there are no dependencies --------
Add-Type -Language CSharp @"
using System;
using System.Security.Cryptography;
public static class Totp
{
private const string B32 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
private static byte[] Base32Decode(string s)
{
s = s.TrimEnd('=').ToUpperInvariant();
byte[] bytes = new byte[s.Length * 5 / 8];
int bitBuffer = 0, bitsLeft = 0, idx = 0;
foreach (char c in s)
{
int val = B32.IndexOf(c);
if (val < 0) throw new ArgumentException("Invalid Base32 char: " + c);
bitBuffer = (bitBuffer << 5) | val;
bitsLeft += 5;
if (bitsLeft >= 8) { bytes[idx++] = (byte)(bitBuffer >> (bitsLeft - 8)); bitsLeft -= 8; }
}
return bytes;
}
private static HMAC Hmac(string algorithm, byte[] key)
{
switch (algorithm.ToUpper())
{
case "SHA1": return new HMACSHA1(key);
case "SHA256": return new HMACSHA256(key);
case "SHA512": return new HMACSHA512(key);
default: throw new ArgumentException("Unsupported algorithm: " + algorithm);
}
}
public static string Now(string secret, int digits, int period, string algorithm)
{
byte[] key = Base32Decode(secret);
long counter = DateTimeOffset.UtcNow.ToUnixTimeSeconds() / period;
byte[] cnt = BitConverter.GetBytes(counter);
if (BitConverter.IsLittleEndian) Array.Reverse(cnt);
byte[] hash;
using (var h = Hmac(algorithm, key)) { hash = h.ComputeHash(cnt); }
int offset = hash[hash.Length - 1] & 0x0F;
int binary =
((hash[offset] & 0x7F) << 24) |
((hash[offset + 1] & 0xFF) << 16) |
((hash[offset + 2] & 0xFF) << 8) |
(hash[offset + 3] & 0xFF);
int otp = binary % (int)Math.Pow(10, digits);
return otp.ToString(new string('0', digits));
}
}
"@
function Find-UiByName($el, $walker, $name) {
$c = $walker.GetFirstChild($el)
while ($c) {
if ($c.Current.Name -eq $name) { return $c }
$r = Find-UiByName $c $walker $name
if ($r) { return $r }
$c = $walker.GetNextSibling($c)
}
return $null
}
# An outdated SimplySign build pops a modal "New version found - download?" box
# over the login form, which swallows the credential keystrokes. Decline it by
# clicking "No" (Invoke / legacy default action / click the element's point).
function Dismiss-UpdatePrompt {
try { Add-Type -AssemblyName UIAutomationClient, UIAutomationTypes -ErrorAction Stop } catch { return $false }
if (-not ('Win32Mouse' -as [type])) {
Add-Type @"
using System;
using System.Runtime.InteropServices;
public static class Win32Mouse {
[DllImport("user32.dll")] static extern bool SetCursorPos(int x, int y);
[DllImport("user32.dll")] static extern void mouse_event(uint f, uint x, uint y, uint d, int e);
public static void Click(int x, int y){ SetCursorPos(x,y); mouse_event(0x02,0,0,0,0); mouse_event(0x04,0,0,0,0); }
}
"@
}
$procIds = @((Get-Process -Name '*SimplySign*' -ErrorAction SilentlyContinue).Id)
$walker = [System.Windows.Automation.TreeWalker]::ControlViewWalker
$top = $walker.GetFirstChild([System.Windows.Automation.AutomationElement]::RootElement)
while ($top) {
if ($procIds -contains $top.Current.ProcessId) {
$no = Find-UiByName $top $walker "No"
if ($no) {
Write-Host "Update prompt detected; declining (clicking 'No')."
try { ($no.GetCurrentPattern([System.Windows.Automation.InvokePattern]::Pattern)).Invoke(); return $true } catch {}
try { ($no.GetCurrentPattern([System.Windows.Automation.LegacyIAccessiblePattern]::Pattern)).DoDefaultAction(); return $true } catch {}
try { $pt = $no.GetClickablePoint(); [Win32Mouse]::Click([int]$pt.X, [int]$pt.Y); return $true } catch { Write-Host "Click 'No' failed: $($_.Exception.Message)" }
}
}
$top = $walker.GetNextSibling($top)
}
return $false
}
# Start from a clean slate so a stale window/session can't swallow the keystrokes.
if ($existing = Get-Process -Name "SimplySignDesktop" -ErrorAction Ignore) {
Write-Host "Killing existing SimplySignDesktop process..."
$existing | Stop-Process -Force
Start-Sleep -Seconds 1
}
Write-Host "Launching SimplySign Desktop..."
$proc = Start-Process -FilePath $ExePath -PassThru
Start-Sleep -Seconds 3
$wshell = New-Object -ComObject WScript.Shell
Write-Host "Focusing the login window..."
$focused = $wshell.AppActivate($proc.Id)
if (-not $focused) { $focused = $wshell.AppActivate('SimplySign Desktop') }
for ($i = 0; (-not $focused) -and ($i -lt 10); $i++) {
Start-Sleep -Milliseconds 500
$focused = $wshell.AppActivate($proc.Id) -or $wshell.AppActivate('SimplySign Desktop')
}
if (-not $focused) {
Write-Host "ERROR: could not bring SimplySign Desktop to the foreground"
exit 1
}
# Decline the "new version available" modal if it's covering the login form.
if (Dismiss-UpdatePrompt) { Start-Sleep -Milliseconds 800 }
# Re-assert focus: dismissing the dialog can move the foreground window, and
# keystrokes sent to the wrong window are silently dropped.
$wshell.AppActivate($proc.Id) | Out-Null
$wshell.AppActivate('SimplySign Desktop') | Out-Null
Start-Sleep -Milliseconds 400
# Paste rather than type: SendKeys mangles characters like + ^ % ( ) and can
# drop characters; pasting delivers the exact string. Falls back to typing if
# the clipboard is unavailable.
function Set-Field([string]$text) {
try {
Set-Clipboard -Value $text -ErrorAction Stop
Start-Sleep -Milliseconds 150
$wshell.SendKeys("^v")
} catch {
Write-Host "Clipboard unavailable ($($_.Exception.Message)); typing instead."
$wshell.SendKeys($text)
}
Start-Sleep -Milliseconds 250
}
Write-Host "Injecting credentials..."
Set-Field $UserId
$wshell.SendKeys("{TAB}")
Start-Sleep -Milliseconds 200
# Generate the code right before sending it so it can't expire while we focus.
$otp = [Totp]::Now($Base32, $Digits, $Period, $Algorithm)
Set-Field $otp
Start-Sleep -Milliseconds 200
$wshell.SendKeys("{ENTER}")
# Don't leave the OTP / username sitting on the clipboard afterwards.
try { Set-Clipboard -Value " " -ErrorAction Stop } catch {}
Write-Host "Waiting for authentication to settle..."
Start-Sleep -Seconds 5
if (-not (Get-Process -Id $proc.Id -ErrorAction SilentlyContinue)) {
Write-Host "ERROR: SimplySign Desktop exited - authentication failed."
exit 1
}
# Confirm the login actually mounted the signing certificate into the store.
$thumb = if ($env:CERTUM_CERT_SHA1) { ($env:CERTUM_CERT_SHA1 -replace '\s', '').ToUpperInvariant() } else { $null }
Write-Host "Verifying the signing certificate reached the store..."
$deadline = (Get-Date).AddSeconds(60)
$found = $false
do {
$certs = Get-ChildItem Cert:\CurrentUser\My, Cert:\LocalMachine\My -ErrorAction SilentlyContinue
if ($thumb) { $found = [bool]($certs | Where-Object { $_.Thumbprint -eq $thumb }) }
else { $found = [bool]($certs | Where-Object { $_.Subject -like '*Certum*' -or $_.Issuer -like '*Certum*' }) }
if ($found) { break }
Start-Sleep -Seconds 3
} while ((Get-Date) -lt $deadline)
if ($found) {
Write-Host "=== Authentication complete: signing certificate is available. ==="
} else {
Write-Host "ERROR: signing certificate did not appear after authentication."
exit 1
}
-46
View File
@@ -1,46 +0,0 @@
#!/bin/bash
# Install Certum SimplySign Desktop on the (ephemeral) Windows runner.
# SimplySign Desktop is what mounts the cloud signing certificate as a virtual
# smart card into the Windows certificate store; signtool then selects it by
# thumbprint. The version + checksum are pinned for reproducibility.
set -euo pipefail
VERSION="9.3.4.72"
URL="https://files.certum.eu/software/SimplySignDesktop/Windows/${VERSION}/SimplySignDesktop-${VERSION}-64-bit-en.msi"
EXPECTED_SHA256="bd51ebbaaac20fc7d59ab7103b5ed532b7800586df4e31f6999d03a394f9c515"
INSTALLER="SimplySignDesktop.msi"
INSTALL_DIR="/c/Program Files/Certum/SimplySign Desktop"
echo "=== Installing Certum SimplySign Desktop ${VERSION} ==="
# Idempotent: a cached/pre-provisioned image may already have it.
if [ -d "$INSTALL_DIR" ]; then
echo "Already installed at: $INSTALL_DIR"
exit 0
fi
echo "Downloading installer..."
curl -L "$URL" -o "$INSTALLER" --fail --max-time 600
ACTUAL_SHA256=$(sha256sum "$INSTALLER" | awk '{print $1}')
if [ "$EXPECTED_SHA256" != "$ACTUAL_SHA256" ]; then
echo "ERROR: checksum mismatch"
echo " expected: $EXPECTED_SHA256"
echo " actual: $ACTUAL_SHA256"
exit 1
fi
echo "Checksum verified."
echo "Running msiexec (silent)..."
# Start-Process inherits this CWD, so the relative installer path resolves here.
powershell -Command "Start-Process msiexec.exe -ArgumentList '/i','${INSTALLER}','/quiet','/norestart','/l*v','install.log','ALLUSERS=1','REBOOT=ReallySuppress' -Wait -NoNewWindow"
if [ ! -d "$INSTALL_DIR" ]; then
echo "ERROR: installation directory not found after install"
echo "Last 20 lines of install.log:"
tail -20 install.log 2>/dev/null || echo "(no install.log)"
exit 1
fi
echo "SimplySign Desktop installed."
-66
View File
@@ -1,66 +0,0 @@
# Sign the given files with the Certum cloud certificate (selected by SHA1
# thumbprint from the store) and verify each signature. Assumes SimplySign
# Desktop has already authenticated (connect-simplysign.ps1).
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[string[]]$Files,
[string]$CertSha1 = $env:CERTUM_CERT_SHA1,
[string]$TimestampUrl = "http://time.certum.pl"
)
$ErrorActionPreference = "Stop"
if (-not $CertSha1) { throw "CERTUM_CERT_SHA1 not provided." }
$thumb = ($CertSha1 -replace '\s', '').ToUpperInvariant()
# Resolve the newest signtool.exe from the installed Windows SDK(s).
$kitsBin = "C:\Program Files (x86)\Windows Kits\10\bin"
$signtool = Get-ChildItem -Path $kitsBin -Recurse -Filter signtool.exe -File -ErrorAction SilentlyContinue |
Where-Object { $_.FullName -like '*\x64\*' } |
Sort-Object { [version]$_.Directory.Parent.Name } |
Select-Object -Last 1 -ExpandProperty FullName
if (-not $signtool) { throw "signtool.exe not found under $kitsBin" }
Write-Host "Using signtool: $signtool"
# The SimplySign virtual smart card registers in the store a moment after the
# desktop client authenticates; poll for our certificate before signing.
Write-Host "Waiting for certificate $thumb to appear in the store..."
$deadline = (Get-Date).AddSeconds(120)
$cert = $null
$elapsed = 0
do {
$cert = Get-ChildItem Cert:\CurrentUser\My, Cert:\LocalMachine\My -ErrorAction SilentlyContinue |
Where-Object { $_.Thumbprint -eq $thumb } | Select-Object -First 1
if ($cert) { break }
Start-Sleep -Seconds 3
$elapsed += 3
Write-Host " ...still waiting (${elapsed}s)"
} while ((Get-Date) -lt $deadline)
if (-not $cert) {
Write-Host "Certificate not found. CurrentUser\My + LocalMachine\My contents:"
Get-ChildItem Cert:\CurrentUser\My, Cert:\LocalMachine\My -ErrorAction SilentlyContinue |
Select-Object Thumbprint, Subject, HasPrivateKey | Format-Table -AutoSize | Out-String | Write-Host
Write-Host "SimplySign processes:"
Get-Process -Name '*SimplySign*' -ErrorAction SilentlyContinue |
Select-Object Name, Id, Responding, MainWindowTitle | Format-Table -AutoSize | Out-String | Write-Host
throw "Certificate $thumb not found in the store - SimplySign authentication likely failed (see dump above)."
}
Write-Host "Found signing certificate: $($cert.Subject)"
$failed = @()
foreach ($file in $Files) {
if (-not (Test-Path $file)) { throw "File to sign not found: $file" }
Write-Host "=== Signing $file ==="
& $signtool sign /sha1 $thumb /fd sha256 /td sha256 /tr $TimestampUrl /v $file
if ($LASTEXITCODE -ne 0) { $failed += $file; continue }
& $signtool verify /pa /v $file
if ($LASTEXITCODE -ne 0) { $failed += $file }
}
if ($failed.Count -gt 0) {
throw "Signing/verification failed for: $($failed -join ', ')"
}
Write-Host "All binaries signed and verified."
+1 -28
View File
@@ -16,15 +16,9 @@ jobs:
runs-on: windows-2025-vs2026
permissions:
contents: write
env:
Configuration: Release
Actions_Allow_Unsecure_Commands: true
CERTUM_OTP_URI: ${{ secrets.CERTUM_OTP_URI }}
CERTUM_USERID: ${{ secrets.CERTUM_USERID }}
CERTUM_CERT_SHA1: ${{ secrets.CERTUM_CERT_SHA1 }}
steps:
- name: Checkout
@@ -52,28 +46,7 @@ jobs:
- name: Build binaries
run: cmake --build build --config Release
# Signing only runs when the Certum secrets are present (i.e. on the real
# repo, not forks); without them the build still produces unsigned binaries.
- name: Set up Certum SimplySign
if: env.CERTUM_OTP_URI != ''
shell: bash
run: |
chmod +x ./.github/scripts/install-simplysign.sh
./.github/scripts/install-simplysign.sh
powershell -ExecutionPolicy Bypass -File "./.github/scripts/configure-simplysign.ps1"
- name: Authenticate Certum SimplySign
if: env.CERTUM_OTP_URI != ''
shell: bash
run: powershell -ExecutionPolicy Bypass -File "./.github/scripts/connect-simplysign.ps1"
- name: Sign release binaries
if: env.CERTUM_OTP_URI != ''
shell: pwsh
run: |
./.github/scripts/sign-certum.ps1 -Files @(".\bin\Release\gMod.dll", ".\bin\Release\TpfConvert.exe")
- name: Retrieve version
id: set_version
run: |
+2 -2
View File
@@ -10,9 +10,9 @@ if(NOT(CMAKE_SIZEOF_VOID_P EQUAL 4))
endif()
set(VERSION_MAJOR 1)
set(VERSION_MINOR 10)
set(VERSION_MINOR 9)
set(VERSION_PATCH 0)
set(VERSION_TWEAK 0)
set(VERSION_TWEAK 3)
set(VERSION_RC "${CMAKE_CURRENT_BINARY_DIR}/version.rc")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/version.rc.in" "${VERSION_RC}" @ONLY)
-305
View File
@@ -1,305 +0,0 @@
#pragma once
#include <d3d9.h>
#include <atomic>
class TextureClient;
// Wraps a real IDirect3DDevice9 so CreateTexture/CreateVolumeTexture/CreateCubeTexture/
// UpdateTexture/BeginScene/SetTexture/GetTexture/Release are intercepted via ordinary
// compiled virtual dispatch instead of a MinHook-patched vtable slot (unstable under
// ARM64 emulation). Every other method is a pure forward to the real device.
class WrappedDirect3DDevice9 : public IDirect3DDevice9 {
public:
explicit WrappedDirect3DDevice9(IDirect3DDevice9* real);
IDirect3DDevice9* RealDevice() const { return real_; }
TextureClient* Client() const { return client_; }
void SetClient(TextureClient* client) { client_ = client; }
STDMETHOD(QueryInterface)(REFIID riid, void** ppvObj) override;
STDMETHOD_(ULONG, AddRef)() override;
STDMETHOD_(ULONG, Release)() override;
STDMETHOD(TestCooperativeLevel)() override;
STDMETHOD_(UINT, GetAvailableTextureMem)() override;
STDMETHOD(EvictManagedResources)() override;
STDMETHOD(GetDirect3D)(IDirect3D9** ppD3D9) override;
STDMETHOD(GetDeviceCaps)(D3DCAPS9* pCaps) override;
STDMETHOD(GetDisplayMode)(UINT iSwapChain, D3DDISPLAYMODE* pMode) override;
STDMETHOD(GetCreationParameters)(D3DDEVICE_CREATION_PARAMETERS* pParameters) override;
STDMETHOD(SetCursorProperties)(UINT XHotSpot, UINT YHotSpot, IDirect3DSurface9* pCursorBitmap) override;
STDMETHOD_(void, SetCursorPosition)(int X, int Y, DWORD Flags) override;
STDMETHOD_(BOOL, ShowCursor)(BOOL bShow) override;
STDMETHOD(CreateAdditionalSwapChain)(D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DSwapChain9** pSwapChain) override;
STDMETHOD(GetSwapChain)(UINT iSwapChain, IDirect3DSwapChain9** pSwapChain) override;
STDMETHOD_(UINT, GetNumberOfSwapChains)() override;
STDMETHOD(Reset)(D3DPRESENT_PARAMETERS* pPresentationParameters) override;
STDMETHOD(Present)(const RECT* pSourceRect, const RECT* pDestRect, HWND hDestWindowOverride, const RGNDATA* pDirtyRegion) override;
STDMETHOD(GetBackBuffer)(UINT iSwapChain, UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface9** ppBackBuffer) override;
STDMETHOD(GetRasterStatus)(UINT iSwapChain, D3DRASTER_STATUS* pRasterStatus) override;
STDMETHOD(SetDialogBoxMode)(BOOL bEnableDialogs) override;
STDMETHOD_(void, SetGammaRamp)(UINT iSwapChain, DWORD Flags, const D3DGAMMARAMP* pRamp) override;
STDMETHOD_(void, GetGammaRamp)(UINT iSwapChain, D3DGAMMARAMP* pRamp) override;
STDMETHOD(CreateTexture)(UINT Width, UINT Height, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DTexture9** ppTexture, HANDLE* pSharedHandle) override;
STDMETHOD(CreateVolumeTexture)(UINT Width, UINT Height, UINT Depth, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DVolumeTexture9** ppVolumeTexture, HANDLE* pSharedHandle) override;
STDMETHOD(CreateCubeTexture)(UINT EdgeLength, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DCubeTexture9** ppCubeTexture, HANDLE* pSharedHandle) override;
STDMETHOD(CreateVertexBuffer)(UINT Length, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer9** ppVertexBuffer, HANDLE* pSharedHandle) override;
STDMETHOD(CreateIndexBuffer)(UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer9** ppIndexBuffer, HANDLE* pSharedHandle) override;
STDMETHOD(CreateRenderTarget)(UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, BOOL Lockable, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle) override;
STDMETHOD(CreateDepthStencilSurface)(UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, BOOL Discard, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle) override;
STDMETHOD(UpdateSurface)(IDirect3DSurface9* pSourceSurface, const RECT* pSourceRect, IDirect3DSurface9* pDestinationSurface, const POINT* pDestPoint) override;
STDMETHOD(UpdateTexture)(IDirect3DBaseTexture9* pSourceTexture, IDirect3DBaseTexture9* pDestinationTexture) override;
STDMETHOD(GetRenderTargetData)(IDirect3DSurface9* pRenderTarget, IDirect3DSurface9* pDestSurface) override;
STDMETHOD(GetFrontBufferData)(UINT iSwapChain, IDirect3DSurface9* pDestSurface) override;
STDMETHOD(StretchRect)(IDirect3DSurface9* pSourceSurface, const RECT* pSourceRect, IDirect3DSurface9* pDestSurface, const RECT* pDestRect, D3DTEXTUREFILTERTYPE Filter) override;
STDMETHOD(ColorFill)(IDirect3DSurface9* pSurface, const RECT* pRect, D3DCOLOR color) override;
STDMETHOD(CreateOffscreenPlainSurface)(UINT Width, UINT Height, D3DFORMAT Format, D3DPOOL Pool, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle) override;
STDMETHOD(SetRenderTarget)(DWORD RenderTargetIndex, IDirect3DSurface9* pRenderTarget) override;
STDMETHOD(GetRenderTarget)(DWORD RenderTargetIndex, IDirect3DSurface9** ppRenderTarget) override;
STDMETHOD(SetDepthStencilSurface)(IDirect3DSurface9* pNewZStencil) override;
STDMETHOD(GetDepthStencilSurface)(IDirect3DSurface9** ppZStencilSurface) override;
STDMETHOD(BeginScene)() override;
STDMETHOD(EndScene)() override;
STDMETHOD(Clear)(DWORD Count, const D3DRECT* pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil) override;
STDMETHOD(SetTransform)(D3DTRANSFORMSTATETYPE State, const D3DMATRIX* pMatrix) override;
STDMETHOD(GetTransform)(D3DTRANSFORMSTATETYPE State, D3DMATRIX* pMatrix) override;
STDMETHOD(MultiplyTransform)(D3DTRANSFORMSTATETYPE, const D3DMATRIX*) override;
STDMETHOD(SetViewport)(const D3DVIEWPORT9* pViewport) override;
STDMETHOD(GetViewport)(D3DVIEWPORT9* pViewport) override;
STDMETHOD(SetMaterial)(const D3DMATERIAL9* pMaterial) override;
STDMETHOD(GetMaterial)(D3DMATERIAL9* pMaterial) override;
STDMETHOD(SetLight)(DWORD Index, const D3DLIGHT9*) override;
STDMETHOD(GetLight)(DWORD Index, D3DLIGHT9*) override;
STDMETHOD(LightEnable)(DWORD Index, BOOL Enable) override;
STDMETHOD(GetLightEnable)(DWORD Index, BOOL* pEnable) override;
STDMETHOD(SetClipPlane)(DWORD Index, const float* pPlane) override;
STDMETHOD(GetClipPlane)(DWORD Index, float* pPlane) override;
STDMETHOD(SetRenderState)(D3DRENDERSTATETYPE State, DWORD Value) override;
STDMETHOD(GetRenderState)(D3DRENDERSTATETYPE State, DWORD* pValue) override;
STDMETHOD(CreateStateBlock)(D3DSTATEBLOCKTYPE Type, IDirect3DStateBlock9** ppSB) override;
STDMETHOD(BeginStateBlock)() override;
STDMETHOD(EndStateBlock)(IDirect3DStateBlock9** ppSB) override;
STDMETHOD(SetClipStatus)(const D3DCLIPSTATUS9* pClipStatus) override;
STDMETHOD(GetClipStatus)(D3DCLIPSTATUS9* pClipStatus) override;
STDMETHOD(GetTexture)(DWORD Stage, IDirect3DBaseTexture9** ppTexture) override;
STDMETHOD(SetTexture)(DWORD Stage, IDirect3DBaseTexture9* pTexture) override;
STDMETHOD(GetTextureStageState)(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD* pValue) override;
STDMETHOD(SetTextureStageState)(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value) override;
STDMETHOD(GetSamplerState)(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD* pValue) override;
STDMETHOD(SetSamplerState)(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value) override;
STDMETHOD(ValidateDevice)(DWORD* pNumPasses) override;
STDMETHOD(SetPaletteEntries)(UINT PaletteNumber, const PALETTEENTRY* pEntries) override;
STDMETHOD(GetPaletteEntries)(UINT PaletteNumber, PALETTEENTRY* pEntries) override;
STDMETHOD(SetCurrentTexturePalette)(UINT PaletteNumber) override;
STDMETHOD(GetCurrentTexturePalette)(UINT* PaletteNumber) override;
STDMETHOD(SetScissorRect)(const RECT* pRect) override;
STDMETHOD(GetScissorRect)(RECT* pRect) override;
STDMETHOD(SetSoftwareVertexProcessing)(BOOL bSoftware) override;
STDMETHOD_(BOOL, GetSoftwareVertexProcessing)() override;
STDMETHOD(SetNPatchMode)(float nSegments) override;
STDMETHOD_(float, GetNPatchMode)() override;
STDMETHOD(DrawPrimitive)(D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount) override;
STDMETHOD(DrawIndexedPrimitive)(D3DPRIMITIVETYPE, INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount) override;
STDMETHOD(DrawPrimitiveUP)(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, const void* pVertexStreamZeroData, UINT VertexStreamZeroStride) override;
STDMETHOD(DrawIndexedPrimitiveUP)(D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex, UINT NumVertices, UINT PrimitiveCount, const void* pIndexData, D3DFORMAT IndexDataFormat, const void* pVertexStreamZeroData, UINT VertexStreamZeroStride) override;
STDMETHOD(ProcessVertices)(UINT SrcStartIndex, UINT DestIndex, UINT VertexCount, IDirect3DVertexBuffer9* pDestBuffer, IDirect3DVertexDeclaration9* pVertexDecl, DWORD Flags) override;
STDMETHOD(CreateVertexDeclaration)(const D3DVERTEXELEMENT9* pVertexElements, IDirect3DVertexDeclaration9** ppDecl) override;
STDMETHOD(SetVertexDeclaration)(IDirect3DVertexDeclaration9* pDecl) override;
STDMETHOD(GetVertexDeclaration)(IDirect3DVertexDeclaration9** ppDecl) override;
STDMETHOD(SetFVF)(DWORD FVF) override;
STDMETHOD(GetFVF)(DWORD* pFVF) override;
STDMETHOD(CreateVertexShader)(const DWORD* pFunction, IDirect3DVertexShader9** ppShader) override;
STDMETHOD(SetVertexShader)(IDirect3DVertexShader9* pShader) override;
STDMETHOD(GetVertexShader)(IDirect3DVertexShader9** ppShader) override;
STDMETHOD(SetVertexShaderConstantF)(UINT StartRegister, const float* pConstantData, UINT Vector4fCount) override;
STDMETHOD(GetVertexShaderConstantF)(UINT StartRegister, float* pConstantData, UINT Vector4fCount) override;
STDMETHOD(SetVertexShaderConstantI)(UINT StartRegister, const int* pConstantData, UINT Vector4iCount) override;
STDMETHOD(GetVertexShaderConstantI)(UINT StartRegister, int* pConstantData, UINT Vector4iCount) override;
STDMETHOD(SetVertexShaderConstantB)(UINT StartRegister, const BOOL* pConstantData, UINT BoolCount) override;
STDMETHOD(GetVertexShaderConstantB)(UINT StartRegister, BOOL* pConstantData, UINT BoolCount) override;
STDMETHOD(SetStreamSource)(UINT StreamNumber, IDirect3DVertexBuffer9* pStreamData, UINT OffsetInBytes, UINT Stride) override;
STDMETHOD(GetStreamSource)(UINT StreamNumber, IDirect3DVertexBuffer9** ppStreamData, UINT* pOffsetInBytes, UINT* pStride) override;
STDMETHOD(SetStreamSourceFreq)(UINT StreamNumber, UINT Setting) override;
STDMETHOD(GetStreamSourceFreq)(UINT StreamNumber, UINT* pSetting) override;
STDMETHOD(SetIndices)(IDirect3DIndexBuffer9* pIndexData) override;
STDMETHOD(GetIndices)(IDirect3DIndexBuffer9** ppIndexData) override;
STDMETHOD(CreatePixelShader)(const DWORD* pFunction, IDirect3DPixelShader9** ppShader) override;
STDMETHOD(SetPixelShader)(IDirect3DPixelShader9* pShader) override;
STDMETHOD(GetPixelShader)(IDirect3DPixelShader9** ppShader) override;
STDMETHOD(SetPixelShaderConstantF)(UINT StartRegister, const float* pConstantData, UINT Vector4fCount) override;
STDMETHOD(GetPixelShaderConstantF)(UINT StartRegister, float* pConstantData, UINT Vector4fCount) override;
STDMETHOD(SetPixelShaderConstantI)(UINT StartRegister, const int* pConstantData, UINT Vector4iCount) override;
STDMETHOD(GetPixelShaderConstantI)(UINT StartRegister, int* pConstantData, UINT Vector4iCount) override;
STDMETHOD(SetPixelShaderConstantB)(UINT StartRegister, const BOOL* pConstantData, UINT BoolCount) override;
STDMETHOD(GetPixelShaderConstantB)(UINT StartRegister, BOOL* pConstantData, UINT BoolCount) override;
STDMETHOD(DrawRectPatch)(UINT Handle, const float* pNumSegs, const D3DRECTPATCH_INFO* pRectPatchInfo) override;
STDMETHOD(DrawTriPatch)(UINT Handle, const float* pNumSegs, const D3DTRIPATCH_INFO* pTriPatchInfo) override;
STDMETHOD(DeletePatch)(UINT Handle) override;
STDMETHOD(CreateQuery)(D3DQUERYTYPE Type, IDirect3DQuery9** ppQuery) override;
protected:
IDirect3DDevice9* real_;
std::atomic<ULONG> ref_count_;
TextureClient* client_;
// Shared by Release() here and by WrappedDirect3DDevice9Ex::Release(); deletes
// client_ exactly as h_DeviceRelease does, via TextureClient::CurrentClient().
void TeardownTextureClient();
};
// Adds IDirect3DDevice9Ex's own methods via ordinary forwards, plus CreateDeviceEx-style
// interception is one level up (in WrappedDirect3D9Ex); this class only needs to override
// the base's virtuals once (inherited) and add the Ex-only ones.
class WrappedDirect3DDevice9Ex : public IDirect3DDevice9Ex {
public:
explicit WrappedDirect3DDevice9Ex(IDirect3DDevice9Ex* real);
IDirect3DDevice9Ex* RealDeviceEx() const { return real_; }
TextureClient* Client() const { return client_; }
void SetClient(TextureClient* client) { client_ = client; }
STDMETHOD(QueryInterface)(REFIID riid, void** ppvObj) override;
STDMETHOD_(ULONG, AddRef)() override;
STDMETHOD_(ULONG, Release)() override;
STDMETHOD(TestCooperativeLevel)() override;
STDMETHOD_(UINT, GetAvailableTextureMem)() override;
STDMETHOD(EvictManagedResources)() override;
STDMETHOD(GetDirect3D)(IDirect3D9** ppD3D9) override;
STDMETHOD(GetDeviceCaps)(D3DCAPS9* pCaps) override;
STDMETHOD(GetDisplayMode)(UINT iSwapChain, D3DDISPLAYMODE* pMode) override;
STDMETHOD(GetCreationParameters)(D3DDEVICE_CREATION_PARAMETERS* pParameters) override;
STDMETHOD(SetCursorProperties)(UINT XHotSpot, UINT YHotSpot, IDirect3DSurface9* pCursorBitmap) override;
STDMETHOD_(void, SetCursorPosition)(int X, int Y, DWORD Flags) override;
STDMETHOD_(BOOL, ShowCursor)(BOOL bShow) override;
STDMETHOD(CreateAdditionalSwapChain)(D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DSwapChain9** pSwapChain) override;
STDMETHOD(GetSwapChain)(UINT iSwapChain, IDirect3DSwapChain9** pSwapChain) override;
STDMETHOD_(UINT, GetNumberOfSwapChains)() override;
STDMETHOD(Reset)(D3DPRESENT_PARAMETERS* pPresentationParameters) override;
STDMETHOD(Present)(const RECT* pSourceRect, const RECT* pDestRect, HWND hDestWindowOverride, const RGNDATA* pDirtyRegion) override;
STDMETHOD(GetBackBuffer)(UINT iSwapChain, UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface9** ppBackBuffer) override;
STDMETHOD(GetRasterStatus)(UINT iSwapChain, D3DRASTER_STATUS* pRasterStatus) override;
STDMETHOD(SetDialogBoxMode)(BOOL bEnableDialogs) override;
STDMETHOD_(void, SetGammaRamp)(UINT iSwapChain, DWORD Flags, const D3DGAMMARAMP* pRamp) override;
STDMETHOD_(void, GetGammaRamp)(UINT iSwapChain, D3DGAMMARAMP* pRamp) override;
STDMETHOD(CreateTexture)(UINT Width, UINT Height, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DTexture9** ppTexture, HANDLE* pSharedHandle) override;
STDMETHOD(CreateVolumeTexture)(UINT Width, UINT Height, UINT Depth, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DVolumeTexture9** ppVolumeTexture, HANDLE* pSharedHandle) override;
STDMETHOD(CreateCubeTexture)(UINT EdgeLength, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DCubeTexture9** ppCubeTexture, HANDLE* pSharedHandle) override;
STDMETHOD(CreateVertexBuffer)(UINT Length, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer9** ppVertexBuffer, HANDLE* pSharedHandle) override;
STDMETHOD(CreateIndexBuffer)(UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer9** ppIndexBuffer, HANDLE* pSharedHandle) override;
STDMETHOD(CreateRenderTarget)(UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, BOOL Lockable, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle) override;
STDMETHOD(CreateDepthStencilSurface)(UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, BOOL Discard, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle) override;
STDMETHOD(UpdateSurface)(IDirect3DSurface9* pSourceSurface, const RECT* pSourceRect, IDirect3DSurface9* pDestinationSurface, const POINT* pDestPoint) override;
STDMETHOD(UpdateTexture)(IDirect3DBaseTexture9* pSourceTexture, IDirect3DBaseTexture9* pDestinationTexture) override;
STDMETHOD(GetRenderTargetData)(IDirect3DSurface9* pRenderTarget, IDirect3DSurface9* pDestSurface) override;
STDMETHOD(GetFrontBufferData)(UINT iSwapChain, IDirect3DSurface9* pDestSurface) override;
STDMETHOD(StretchRect)(IDirect3DSurface9* pSourceSurface, const RECT* pSourceRect, IDirect3DSurface9* pDestSurface, const RECT* pDestRect, D3DTEXTUREFILTERTYPE Filter) override;
STDMETHOD(ColorFill)(IDirect3DSurface9* pSurface, const RECT* pRect, D3DCOLOR color) override;
STDMETHOD(CreateOffscreenPlainSurface)(UINT Width, UINT Height, D3DFORMAT Format, D3DPOOL Pool, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle) override;
STDMETHOD(SetRenderTarget)(DWORD RenderTargetIndex, IDirect3DSurface9* pRenderTarget) override;
STDMETHOD(GetRenderTarget)(DWORD RenderTargetIndex, IDirect3DSurface9** ppRenderTarget) override;
STDMETHOD(SetDepthStencilSurface)(IDirect3DSurface9* pNewZStencil) override;
STDMETHOD(GetDepthStencilSurface)(IDirect3DSurface9** ppZStencilSurface) override;
STDMETHOD(BeginScene)() override;
STDMETHOD(EndScene)() override;
STDMETHOD(Clear)(DWORD Count, const D3DRECT* pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil) override;
STDMETHOD(SetTransform)(D3DTRANSFORMSTATETYPE State, const D3DMATRIX* pMatrix) override;
STDMETHOD(GetTransform)(D3DTRANSFORMSTATETYPE State, D3DMATRIX* pMatrix) override;
STDMETHOD(MultiplyTransform)(D3DTRANSFORMSTATETYPE, const D3DMATRIX*) override;
STDMETHOD(SetViewport)(const D3DVIEWPORT9* pViewport) override;
STDMETHOD(GetViewport)(D3DVIEWPORT9* pViewport) override;
STDMETHOD(SetMaterial)(const D3DMATERIAL9* pMaterial) override;
STDMETHOD(GetMaterial)(D3DMATERIAL9* pMaterial) override;
STDMETHOD(SetLight)(DWORD Index, const D3DLIGHT9*) override;
STDMETHOD(GetLight)(DWORD Index, D3DLIGHT9*) override;
STDMETHOD(LightEnable)(DWORD Index, BOOL Enable) override;
STDMETHOD(GetLightEnable)(DWORD Index, BOOL* pEnable) override;
STDMETHOD(SetClipPlane)(DWORD Index, const float* pPlane) override;
STDMETHOD(GetClipPlane)(DWORD Index, float* pPlane) override;
STDMETHOD(SetRenderState)(D3DRENDERSTATETYPE State, DWORD Value) override;
STDMETHOD(GetRenderState)(D3DRENDERSTATETYPE State, DWORD* pValue) override;
STDMETHOD(CreateStateBlock)(D3DSTATEBLOCKTYPE Type, IDirect3DStateBlock9** ppSB) override;
STDMETHOD(BeginStateBlock)() override;
STDMETHOD(EndStateBlock)(IDirect3DStateBlock9** ppSB) override;
STDMETHOD(SetClipStatus)(const D3DCLIPSTATUS9* pClipStatus) override;
STDMETHOD(GetClipStatus)(D3DCLIPSTATUS9* pClipStatus) override;
STDMETHOD(GetTexture)(DWORD Stage, IDirect3DBaseTexture9** ppTexture) override;
STDMETHOD(SetTexture)(DWORD Stage, IDirect3DBaseTexture9* pTexture) override;
STDMETHOD(GetTextureStageState)(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD* pValue) override;
STDMETHOD(SetTextureStageState)(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value) override;
STDMETHOD(GetSamplerState)(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD* pValue) override;
STDMETHOD(SetSamplerState)(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value) override;
STDMETHOD(ValidateDevice)(DWORD* pNumPasses) override;
STDMETHOD(SetPaletteEntries)(UINT PaletteNumber, const PALETTEENTRY* pEntries) override;
STDMETHOD(GetPaletteEntries)(UINT PaletteNumber, PALETTEENTRY* pEntries) override;
STDMETHOD(SetCurrentTexturePalette)(UINT PaletteNumber) override;
STDMETHOD(GetCurrentTexturePalette)(UINT* PaletteNumber) override;
STDMETHOD(SetScissorRect)(const RECT* pRect) override;
STDMETHOD(GetScissorRect)(RECT* pRect) override;
STDMETHOD(SetSoftwareVertexProcessing)(BOOL bSoftware) override;
STDMETHOD_(BOOL, GetSoftwareVertexProcessing)() override;
STDMETHOD(SetNPatchMode)(float nSegments) override;
STDMETHOD_(float, GetNPatchMode)() override;
STDMETHOD(DrawPrimitive)(D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount) override;
STDMETHOD(DrawIndexedPrimitive)(D3DPRIMITIVETYPE, INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount) override;
STDMETHOD(DrawPrimitiveUP)(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, const void* pVertexStreamZeroData, UINT VertexStreamZeroStride) override;
STDMETHOD(DrawIndexedPrimitiveUP)(D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex, UINT NumVertices, UINT PrimitiveCount, const void* pIndexData, D3DFORMAT IndexDataFormat, const void* pVertexStreamZeroData, UINT VertexStreamZeroStride) override;
STDMETHOD(ProcessVertices)(UINT SrcStartIndex, UINT DestIndex, UINT VertexCount, IDirect3DVertexBuffer9* pDestBuffer, IDirect3DVertexDeclaration9* pVertexDecl, DWORD Flags) override;
STDMETHOD(CreateVertexDeclaration)(const D3DVERTEXELEMENT9* pVertexElements, IDirect3DVertexDeclaration9** ppDecl) override;
STDMETHOD(SetVertexDeclaration)(IDirect3DVertexDeclaration9* pDecl) override;
STDMETHOD(GetVertexDeclaration)(IDirect3DVertexDeclaration9** ppDecl) override;
STDMETHOD(SetFVF)(DWORD FVF) override;
STDMETHOD(GetFVF)(DWORD* pFVF) override;
STDMETHOD(CreateVertexShader)(const DWORD* pFunction, IDirect3DVertexShader9** ppShader) override;
STDMETHOD(SetVertexShader)(IDirect3DVertexShader9* pShader) override;
STDMETHOD(GetVertexShader)(IDirect3DVertexShader9** ppShader) override;
STDMETHOD(SetVertexShaderConstantF)(UINT StartRegister, const float* pConstantData, UINT Vector4fCount) override;
STDMETHOD(GetVertexShaderConstantF)(UINT StartRegister, float* pConstantData, UINT Vector4fCount) override;
STDMETHOD(SetVertexShaderConstantI)(UINT StartRegister, const int* pConstantData, UINT Vector4iCount) override;
STDMETHOD(GetVertexShaderConstantI)(UINT StartRegister, int* pConstantData, UINT Vector4iCount) override;
STDMETHOD(SetVertexShaderConstantB)(UINT StartRegister, const BOOL* pConstantData, UINT BoolCount) override;
STDMETHOD(GetVertexShaderConstantB)(UINT StartRegister, BOOL* pConstantData, UINT BoolCount) override;
STDMETHOD(SetStreamSource)(UINT StreamNumber, IDirect3DVertexBuffer9* pStreamData, UINT OffsetInBytes, UINT Stride) override;
STDMETHOD(GetStreamSource)(UINT StreamNumber, IDirect3DVertexBuffer9** ppStreamData, UINT* pOffsetInBytes, UINT* pStride) override;
STDMETHOD(SetStreamSourceFreq)(UINT StreamNumber, UINT Setting) override;
STDMETHOD(GetStreamSourceFreq)(UINT StreamNumber, UINT* pSetting) override;
STDMETHOD(SetIndices)(IDirect3DIndexBuffer9* pIndexData) override;
STDMETHOD(GetIndices)(IDirect3DIndexBuffer9** ppIndexData) override;
STDMETHOD(CreatePixelShader)(const DWORD* pFunction, IDirect3DPixelShader9** ppShader) override;
STDMETHOD(SetPixelShader)(IDirect3DPixelShader9* pShader) override;
STDMETHOD(GetPixelShader)(IDirect3DPixelShader9** ppShader) override;
STDMETHOD(SetPixelShaderConstantF)(UINT StartRegister, const float* pConstantData, UINT Vector4fCount) override;
STDMETHOD(GetPixelShaderConstantF)(UINT StartRegister, float* pConstantData, UINT Vector4fCount) override;
STDMETHOD(SetPixelShaderConstantI)(UINT StartRegister, const int* pConstantData, UINT Vector4iCount) override;
STDMETHOD(GetPixelShaderConstantI)(UINT StartRegister, int* pConstantData, UINT Vector4iCount) override;
STDMETHOD(SetPixelShaderConstantB)(UINT StartRegister, const BOOL* pConstantData, UINT BoolCount) override;
STDMETHOD(GetPixelShaderConstantB)(UINT StartRegister, BOOL* pConstantData, UINT BoolCount) override;
STDMETHOD(DrawRectPatch)(UINT Handle, const float* pNumSegs, const D3DRECTPATCH_INFO* pRectPatchInfo) override;
STDMETHOD(DrawTriPatch)(UINT Handle, const float* pNumSegs, const D3DTRIPATCH_INFO* pTriPatchInfo) override;
STDMETHOD(DeletePatch)(UINT Handle) override;
STDMETHOD(CreateQuery)(D3DQUERYTYPE Type, IDirect3DQuery9** ppQuery) override;
STDMETHOD(SetConvolutionMonoKernel)(UINT width, UINT height, float* rows, float* columns) override;
STDMETHOD(ComposeRects)(IDirect3DSurface9* pSrc, IDirect3DSurface9* pDst, IDirect3DVertexBuffer9* pSrcRectDescs, UINT NumRects, IDirect3DVertexBuffer9* pDstRectDescs, D3DCOMPOSERECTSOP Operation, int Xoffset, int Yoffset) override;
STDMETHOD(PresentEx)(const RECT* pSourceRect, const RECT* pDestRect, HWND hDestWindowOverride, const RGNDATA* pDirtyRegion, DWORD dwFlags) override;
STDMETHOD(GetGPUThreadPriority)(INT* pPriority) override;
STDMETHOD(SetGPUThreadPriority)(INT Priority) override;
STDMETHOD(WaitForVBlank)(UINT iSwapChain) override;
STDMETHOD(CheckResourceResidency)(IDirect3DResource9** pResourceArray, UINT32 NumResources) override;
STDMETHOD(SetMaximumFrameLatency)(UINT MaxLatency) override;
STDMETHOD(GetMaximumFrameLatency)(UINT* pMaxLatency) override;
STDMETHOD(CheckDeviceState)(HWND hDestinationWindow) override;
STDMETHOD(CreateRenderTargetEx)(UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, BOOL Lockable, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle, DWORD Usage) override;
STDMETHOD(CreateOffscreenPlainSurfaceEx)(UINT Width, UINT Height, D3DFORMAT Format, D3DPOOL Pool, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle, DWORD Usage) override;
STDMETHOD(CreateDepthStencilSurfaceEx)(UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, BOOL Discard, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle, DWORD Usage) override;
STDMETHOD(ResetEx)(D3DPRESENT_PARAMETERS* pPresentationParameters, D3DDISPLAYMODEEX* pFullscreenDisplayMode) override;
STDMETHOD(GetDisplayModeEx)(UINT iSwapChain, D3DDISPLAYMODEEX* pMode, D3DDISPLAYROTATION* pRotation) override;
private:
IDirect3DDevice9Ex* real_;
std::atomic<ULONG> ref_count_;
TextureClient* client_;
void TeardownTextureClient();
};
-127
View File
@@ -1,127 +0,0 @@
#pragma once
#include <d3d9.h>
#include <atomic>
class TextureClient;
// Wraps a real IDirect3D*Texture9 so every method is ordinary compiled virtual dispatch
// instead of a MinHook-patched vtable slot. See D3D9DeviceWrapper.h for why this matters.
class WrappedTexture9 : public IDirect3DTexture9 {
public:
explicit WrappedTexture9(IDirect3DTexture9* real);
IDirect3DTexture9* RealTexture() const { return real_; }
STDMETHOD(QueryInterface)(REFIID riid, void** ppvObj) override;
STDMETHOD_(ULONG, AddRef)() override;
STDMETHOD_(ULONG, Release)() override;
STDMETHOD(GetDevice)(IDirect3DDevice9** ppDevice) override;
STDMETHOD(SetPrivateData)(REFGUID refguid, const void* pData, DWORD SizeOfData, DWORD Flags) override;
STDMETHOD(GetPrivateData)(REFGUID refguid, void* pData, DWORD* pSizeOfData) override;
STDMETHOD(FreePrivateData)(REFGUID refguid) override;
STDMETHOD_(DWORD, SetPriority)(DWORD PriorityNew) override;
STDMETHOD_(DWORD, GetPriority)() override;
STDMETHOD_(void, PreLoad)() override;
STDMETHOD_(D3DRESOURCETYPE, GetType)() override;
STDMETHOD_(DWORD, SetLOD)(DWORD LODNew) override;
STDMETHOD_(DWORD, GetLOD)() override;
STDMETHOD_(DWORD, GetLevelCount)() override;
STDMETHOD(SetAutoGenFilterType)(D3DTEXTUREFILTERTYPE FilterType) override;
STDMETHOD_(D3DTEXTUREFILTERTYPE, GetAutoGenFilterType)() override;
STDMETHOD_(void, GenerateMipSubLevels)() override;
STDMETHOD(GetLevelDesc)(UINT Level, D3DSURFACE_DESC* pDesc) override;
STDMETHOD(GetSurfaceLevel)(UINT Level, IDirect3DSurface9** ppSurfaceLevel) override;
STDMETHOD(LockRect)(UINT Level, D3DLOCKED_RECT* pLockedRect, const RECT* pRect, DWORD Flags) override;
STDMETHOD(UnlockRect)(UINT Level) override;
STDMETHOD(AddDirtyRect)(const RECT* pDirtyRect) override;
private:
IDirect3DTexture9* real_;
std::atomic<ULONG> ref_count_;
};
class WrappedVolumeTexture9 : public IDirect3DVolumeTexture9 {
public:
explicit WrappedVolumeTexture9(IDirect3DVolumeTexture9* real);
IDirect3DVolumeTexture9* RealTexture() const { return real_; }
STDMETHOD(QueryInterface)(REFIID riid, void** ppvObj) override;
STDMETHOD_(ULONG, AddRef)() override;
STDMETHOD_(ULONG, Release)() override;
STDMETHOD(GetDevice)(IDirect3DDevice9** ppDevice) override;
STDMETHOD(SetPrivateData)(REFGUID refguid, const void* pData, DWORD SizeOfData, DWORD Flags) override;
STDMETHOD(GetPrivateData)(REFGUID refguid, void* pData, DWORD* pSizeOfData) override;
STDMETHOD(FreePrivateData)(REFGUID refguid) override;
STDMETHOD_(DWORD, SetPriority)(DWORD PriorityNew) override;
STDMETHOD_(DWORD, GetPriority)() override;
STDMETHOD_(void, PreLoad)() override;
STDMETHOD_(D3DRESOURCETYPE, GetType)() override;
STDMETHOD_(DWORD, SetLOD)(DWORD LODNew) override;
STDMETHOD_(DWORD, GetLOD)() override;
STDMETHOD_(DWORD, GetLevelCount)() override;
STDMETHOD(SetAutoGenFilterType)(D3DTEXTUREFILTERTYPE FilterType) override;
STDMETHOD_(D3DTEXTUREFILTERTYPE, GetAutoGenFilterType)() override;
STDMETHOD_(void, GenerateMipSubLevels)() override;
STDMETHOD(GetLevelDesc)(UINT Level, D3DVOLUME_DESC* pDesc) override;
STDMETHOD(GetVolumeLevel)(UINT Level, IDirect3DVolume9** ppVolumeLevel) override;
STDMETHOD(LockBox)(UINT Level, D3DLOCKED_BOX* pLockedVolume, const D3DBOX* pBox, DWORD Flags) override;
STDMETHOD(UnlockBox)(UINT Level) override;
STDMETHOD(AddDirtyBox)(const D3DBOX* pDirtyBox) override;
private:
IDirect3DVolumeTexture9* real_;
std::atomic<ULONG> ref_count_;
};
class WrappedCubeTexture9 : public IDirect3DCubeTexture9 {
public:
explicit WrappedCubeTexture9(IDirect3DCubeTexture9* real);
IDirect3DCubeTexture9* RealTexture() const { return real_; }
STDMETHOD(QueryInterface)(REFIID riid, void** ppvObj) override;
STDMETHOD_(ULONG, AddRef)() override;
STDMETHOD_(ULONG, Release)() override;
STDMETHOD(GetDevice)(IDirect3DDevice9** ppDevice) override;
STDMETHOD(SetPrivateData)(REFGUID refguid, const void* pData, DWORD SizeOfData, DWORD Flags) override;
STDMETHOD(GetPrivateData)(REFGUID refguid, void* pData, DWORD* pSizeOfData) override;
STDMETHOD(FreePrivateData)(REFGUID refguid) override;
STDMETHOD_(DWORD, SetPriority)(DWORD PriorityNew) override;
STDMETHOD_(DWORD, GetPriority)() override;
STDMETHOD_(void, PreLoad)() override;
STDMETHOD_(D3DRESOURCETYPE, GetType)() override;
STDMETHOD_(DWORD, SetLOD)(DWORD LODNew) override;
STDMETHOD_(DWORD, GetLOD)() override;
STDMETHOD_(DWORD, GetLevelCount)() override;
STDMETHOD(SetAutoGenFilterType)(D3DTEXTUREFILTERTYPE FilterType) override;
STDMETHOD_(D3DTEXTUREFILTERTYPE, GetAutoGenFilterType)() override;
STDMETHOD_(void, GenerateMipSubLevels)() override;
STDMETHOD(GetLevelDesc)(UINT Level, D3DSURFACE_DESC* pDesc) override;
STDMETHOD(GetCubeMapSurface)(D3DCUBEMAP_FACES FaceType, UINT Level, IDirect3DSurface9** ppCubeMapSurface) override;
STDMETHOD(LockRect)(D3DCUBEMAP_FACES FaceType, UINT Level, D3DLOCKED_RECT* pLockedRect, const RECT* pRect, DWORD Flags) override;
STDMETHOD(UnlockRect)(D3DCUBEMAP_FACES FaceType, UINT Level) override;
STDMETHOD(AddDirtyRect)(D3DCUBEMAP_FACES FaceType, const RECT* pDirtyRect) override;
private:
IDirect3DCubeTexture9* real_;
std::atomic<ULONG> ref_count_;
};
// Real texture pointer -> wrapper, for the D3D9 calls that only ever hand back real
// pointers (e.g. IDirect3DDevice9::GetTexture) so they can be turned back into the
// wrapper identity the game must see. Populated by each wrapper's constructor, erased
// in its destructor/Release.
IDirect3DBaseTexture9* FindWrapperForRealTexture(IDirect3DBaseTexture9* real);
void RegisterWrapperForRealTexture(IDirect3DBaseTexture9* real, IDirect3DBaseTexture9* wrapper);
void UnregisterWrapperForRealTexture(IDirect3DBaseTexture9* real);
-69
View File
@@ -1,69 +0,0 @@
#pragma once
#include <d3d9.h>
#include <atomic>
// Wraps a real IDirect3D9 so CreateDevice is intercepted via ordinary compiled virtual
// dispatch instead of a MinHook-patched vtable slot (unstable under ARM64 emulation).
// Every other method is a pure forward to the real object.
class WrappedDirect3D9 : public IDirect3D9 {
public:
explicit WrappedDirect3D9(IDirect3D9* real);
STDMETHOD(QueryInterface)(REFIID riid, void** ppvObj) override;
STDMETHOD_(ULONG, AddRef)() override;
STDMETHOD_(ULONG, Release)() override;
STDMETHOD(RegisterSoftwareDevice)(void* pInitializeFunction) override;
STDMETHOD_(UINT, GetAdapterCount)() override;
STDMETHOD(GetAdapterIdentifier)(UINT Adapter, DWORD Flags, D3DADAPTER_IDENTIFIER9* pIdentifier) override;
STDMETHOD_(UINT, GetAdapterModeCount)(UINT Adapter, D3DFORMAT Format) override;
STDMETHOD(EnumAdapterModes)(UINT Adapter, D3DFORMAT Format, UINT Mode, D3DDISPLAYMODE* pMode) override;
STDMETHOD(GetAdapterDisplayMode)(UINT Adapter, D3DDISPLAYMODE* pMode) override;
STDMETHOD(CheckDeviceType)(UINT Adapter, D3DDEVTYPE DevType, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, BOOL bWindowed) override;
STDMETHOD(CheckDeviceFormat)(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat) override;
STDMETHOD(CheckDeviceMultiSampleType)(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat, BOOL Windowed, D3DMULTISAMPLE_TYPE MultiSampleType, DWORD* pQualityLevels) override;
STDMETHOD(CheckDepthStencilMatch)(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, D3DFORMAT RenderTargetFormat, D3DFORMAT DepthStencilFormat) override;
STDMETHOD(CheckDeviceFormatConversion)(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SourceFormat, D3DFORMAT TargetFormat) override;
STDMETHOD(GetDeviceCaps)(UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9* pCaps) override;
STDMETHOD_(HMONITOR, GetAdapterMonitor)(UINT Adapter) override;
STDMETHOD(CreateDevice)(UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice9** ppReturnedDeviceInterface) override;
protected:
IDirect3D9* real_;
std::atomic<ULONG> ref_count_;
};
class WrappedDirect3D9Ex : public IDirect3D9Ex {
public:
explicit WrappedDirect3D9Ex(IDirect3D9Ex* real);
STDMETHOD(QueryInterface)(REFIID riid, void** ppvObj) override;
STDMETHOD_(ULONG, AddRef)() override;
STDMETHOD_(ULONG, Release)() override;
STDMETHOD(RegisterSoftwareDevice)(void* pInitializeFunction) override;
STDMETHOD_(UINT, GetAdapterCount)() override;
STDMETHOD(GetAdapterIdentifier)(UINT Adapter, DWORD Flags, D3DADAPTER_IDENTIFIER9* pIdentifier) override;
STDMETHOD_(UINT, GetAdapterModeCount)(UINT Adapter, D3DFORMAT Format) override;
STDMETHOD(EnumAdapterModes)(UINT Adapter, D3DFORMAT Format, UINT Mode, D3DDISPLAYMODE* pMode) override;
STDMETHOD(GetAdapterDisplayMode)(UINT Adapter, D3DDISPLAYMODE* pMode) override;
STDMETHOD(CheckDeviceType)(UINT Adapter, D3DDEVTYPE DevType, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, BOOL bWindowed) override;
STDMETHOD(CheckDeviceFormat)(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat) override;
STDMETHOD(CheckDeviceMultiSampleType)(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat, BOOL Windowed, D3DMULTISAMPLE_TYPE MultiSampleType, DWORD* pQualityLevels) override;
STDMETHOD(CheckDepthStencilMatch)(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, D3DFORMAT RenderTargetFormat, D3DFORMAT DepthStencilFormat) override;
STDMETHOD(CheckDeviceFormatConversion)(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SourceFormat, D3DFORMAT TargetFormat) override;
STDMETHOD(GetDeviceCaps)(UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9* pCaps) override;
STDMETHOD_(HMONITOR, GetAdapterMonitor)(UINT Adapter) override;
STDMETHOD(CreateDevice)(UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice9** ppReturnedDeviceInterface) override;
STDMETHOD_(UINT, GetAdapterModeCountEx)(UINT Adapter, const D3DDISPLAYMODEFILTER* pFilter) override;
STDMETHOD(EnumAdapterModesEx)(UINT Adapter, const D3DDISPLAYMODEFILTER* pFilter, UINT Mode, D3DDISPLAYMODEEX* pMode) override;
STDMETHOD(GetAdapterDisplayModeEx)(UINT Adapter, D3DDISPLAYMODEEX* pMode, D3DDISPLAYROTATION* pRotation) override;
STDMETHOD(CreateDeviceEx)(UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, D3DDISPLAYMODEEX* pFullscreenDisplayMode, IDirect3DDevice9Ex** ppReturnedDeviceInterface) override;
STDMETHOD(GetAdapterLUID)(UINT Adapter, LUID* pLUID) override;
private:
IDirect3D9Ex* real_;
std::atomic<ULONG> ref_count_;
};
-536
View File
@@ -1,536 +0,0 @@
#include "Main.h"
#include "D3D9DeviceWrapper.h"
#include "D3D9TextureWrappers.h"
import TextureClient;
namespace {
// Unwraps a WrappedTexture9/WrappedVolumeTexture9/WrappedCubeTexture9 to the real
// pointer the real device needs; passes non-wrapper (or null) pointers through as-is.
IDirect3DBaseTexture9* Unwrap(IDirect3DBaseTexture9* texture)
{
if (texture == nullptr) return nullptr;
switch (texture->GetType()) {
case D3DRTYPE_TEXTURE: return static_cast<WrappedTexture9*>(texture)->RealTexture();
case D3DRTYPE_VOLUMETEXTURE: return static_cast<WrappedVolumeTexture9*>(texture)->RealTexture();
case D3DRTYPE_CUBETEXTURE: return static_cast<WrappedCubeTexture9*>(texture)->RealTexture();
default: return texture;
}
}
}
// ---- WrappedDirect3DDevice9 ----------------------------------------------
WrappedDirect3DDevice9::WrappedDirect3DDevice9(IDirect3DDevice9* real) : real_(real), ref_count_(1), client_(nullptr)
{
real_->AddRef();
}
HRESULT WrappedDirect3DDevice9::QueryInterface(REFIID riid, void** ppvObj)
{
if (riid == IID_IUnknown || riid == IID_IDirect3DDevice9) {
AddRef();
*ppvObj = this;
return S_OK;
}
// Unrecognized-but-successful QueryInterface hands back an unwrapped real pointer.
return real_->QueryInterface(riid, ppvObj);
}
ULONG WrappedDirect3DDevice9::AddRef()
{
return ++ref_count_;
}
void WrappedDirect3DDevice9::TeardownTextureClient()
{
if (auto* client = TextureClient::CurrentClient())
delete client;
}
ULONG WrappedDirect3DDevice9::Release()
{
const ULONG count = --ref_count_;
if (count == 0) {
TeardownTextureClient();
real_->Release();
delete this;
return 0;
}
return count;
}
HRESULT WrappedDirect3DDevice9::TestCooperativeLevel() { return real_->TestCooperativeLevel(); }
UINT WrappedDirect3DDevice9::GetAvailableTextureMem() { return real_->GetAvailableTextureMem(); }
HRESULT WrappedDirect3DDevice9::EvictManagedResources() { return real_->EvictManagedResources(); }
HRESULT WrappedDirect3DDevice9::GetDirect3D(IDirect3D9** ppD3D9) { return real_->GetDirect3D(ppD3D9); }
HRESULT WrappedDirect3DDevice9::GetDeviceCaps(D3DCAPS9* pCaps) { return real_->GetDeviceCaps(pCaps); }
HRESULT WrappedDirect3DDevice9::GetDisplayMode(UINT iSwapChain, D3DDISPLAYMODE* pMode) { return real_->GetDisplayMode(iSwapChain, pMode); }
HRESULT WrappedDirect3DDevice9::GetCreationParameters(D3DDEVICE_CREATION_PARAMETERS* pParameters) { return real_->GetCreationParameters(pParameters); }
HRESULT WrappedDirect3DDevice9::SetCursorProperties(UINT XHotSpot, UINT YHotSpot, IDirect3DSurface9* pCursorBitmap) { return real_->SetCursorProperties(XHotSpot, YHotSpot, pCursorBitmap); }
void WrappedDirect3DDevice9::SetCursorPosition(int X, int Y, DWORD Flags) { real_->SetCursorPosition(X, Y, Flags); }
BOOL WrappedDirect3DDevice9::ShowCursor(BOOL bShow) { return real_->ShowCursor(bShow); }
HRESULT WrappedDirect3DDevice9::CreateAdditionalSwapChain(D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DSwapChain9** pSwapChain) { return real_->CreateAdditionalSwapChain(pPresentationParameters, pSwapChain); }
HRESULT WrappedDirect3DDevice9::GetSwapChain(UINT iSwapChain, IDirect3DSwapChain9** pSwapChain) { return real_->GetSwapChain(iSwapChain, pSwapChain); }
UINT WrappedDirect3DDevice9::GetNumberOfSwapChains() { return real_->GetNumberOfSwapChains(); }
HRESULT WrappedDirect3DDevice9::Reset(D3DPRESENT_PARAMETERS* pPresentationParameters) { return real_->Reset(pPresentationParameters); }
HRESULT WrappedDirect3DDevice9::Present(const RECT* pSourceRect, const RECT* pDestRect, HWND hDestWindowOverride, const RGNDATA* pDirtyRegion) { return real_->Present(pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion); }
HRESULT WrappedDirect3DDevice9::GetBackBuffer(UINT iSwapChain, UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface9** ppBackBuffer) { return real_->GetBackBuffer(iSwapChain, iBackBuffer, Type, ppBackBuffer); }
HRESULT WrappedDirect3DDevice9::GetRasterStatus(UINT iSwapChain, D3DRASTER_STATUS* pRasterStatus) { return real_->GetRasterStatus(iSwapChain, pRasterStatus); }
HRESULT WrappedDirect3DDevice9::SetDialogBoxMode(BOOL bEnableDialogs) { return real_->SetDialogBoxMode(bEnableDialogs); }
void WrappedDirect3DDevice9::SetGammaRamp(UINT iSwapChain, DWORD Flags, const D3DGAMMARAMP* pRamp) { real_->SetGammaRamp(iSwapChain, Flags, pRamp); }
void WrappedDirect3DDevice9::GetGammaRamp(UINT iSwapChain, D3DGAMMARAMP* pRamp) { real_->GetGammaRamp(iSwapChain, pRamp); }
HRESULT WrappedDirect3DDevice9::CreateTexture(UINT Width, UINT Height, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DTexture9** ppTexture, HANDLE* pSharedHandle)
{
IDirect3DTexture9* real_texture = nullptr;
const HRESULT hr = real_->CreateTexture(Width, Height, Levels, Usage, Format, Pool, &real_texture, pSharedHandle);
if (FAILED(hr) || real_texture == nullptr) {
if (ppTexture) *ppTexture = nullptr;
return hr;
}
const auto wrapped = new WrappedTexture9(real_texture);
real_texture->Release(); // the wrapper holds its own AddRef'd reference
if (client_) client_->OnCreateTexture(wrapped, TexType::Tex2D);
*ppTexture = wrapped;
return hr;
}
HRESULT WrappedDirect3DDevice9::CreateVolumeTexture(UINT Width, UINT Height, UINT Depth, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DVolumeTexture9** ppVolumeTexture, HANDLE* pSharedHandle)
{
IDirect3DVolumeTexture9* real_texture = nullptr;
const HRESULT hr = real_->CreateVolumeTexture(Width, Height, Depth, Levels, Usage, Format, Pool, &real_texture, pSharedHandle);
if (FAILED(hr) || real_texture == nullptr) {
if (ppVolumeTexture) *ppVolumeTexture = nullptr;
return hr;
}
const auto wrapped = new WrappedVolumeTexture9(real_texture);
real_texture->Release();
if (client_) client_->OnCreateTexture(wrapped, TexType::Volume);
*ppVolumeTexture = wrapped;
return hr;
}
HRESULT WrappedDirect3DDevice9::CreateCubeTexture(UINT EdgeLength, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DCubeTexture9** ppCubeTexture, HANDLE* pSharedHandle)
{
IDirect3DCubeTexture9* real_texture = nullptr;
const HRESULT hr = real_->CreateCubeTexture(EdgeLength, Levels, Usage, Format, Pool, &real_texture, pSharedHandle);
if (FAILED(hr) || real_texture == nullptr) {
if (ppCubeTexture) *ppCubeTexture = nullptr;
return hr;
}
const auto wrapped = new WrappedCubeTexture9(real_texture);
real_texture->Release();
if (client_) client_->OnCreateTexture(wrapped, TexType::Cube);
*ppCubeTexture = wrapped;
return hr;
}
HRESULT WrappedDirect3DDevice9::CreateVertexBuffer(UINT Length, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer9** ppVertexBuffer, HANDLE* pSharedHandle) { return real_->CreateVertexBuffer(Length, Usage, FVF, Pool, ppVertexBuffer, pSharedHandle); }
HRESULT WrappedDirect3DDevice9::CreateIndexBuffer(UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer9** ppIndexBuffer, HANDLE* pSharedHandle) { return real_->CreateIndexBuffer(Length, Usage, Format, Pool, ppIndexBuffer, pSharedHandle); }
HRESULT WrappedDirect3DDevice9::CreateRenderTarget(UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, BOOL Lockable, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle) { return real_->CreateRenderTarget(Width, Height, Format, MultiSample, MultisampleQuality, Lockable, ppSurface, pSharedHandle); }
HRESULT WrappedDirect3DDevice9::CreateDepthStencilSurface(UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, BOOL Discard, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle) { return real_->CreateDepthStencilSurface(Width, Height, Format, MultiSample, MultisampleQuality, Discard, ppSurface, pSharedHandle); }
HRESULT WrappedDirect3DDevice9::UpdateSurface(IDirect3DSurface9* pSourceSurface, const RECT* pSourceRect, IDirect3DSurface9* pDestinationSurface, const POINT* pDestPoint) { return real_->UpdateSurface(pSourceSurface, pSourceRect, pDestinationSurface, pDestPoint); }
HRESULT WrappedDirect3DDevice9::UpdateTexture(IDirect3DBaseTexture9* pSourceTexture, IDirect3DBaseTexture9* pDestinationTexture)
{
const HRESULT hr = real_->UpdateTexture(Unwrap(pSourceTexture), Unwrap(pDestinationTexture));
if (SUCCEEDED(hr) && client_)
client_->OnUpdateTexture(pSourceTexture, pDestinationTexture); // re-hash by wrapper identity
return hr;
}
HRESULT WrappedDirect3DDevice9::GetRenderTargetData(IDirect3DSurface9* pRenderTarget, IDirect3DSurface9* pDestSurface) { return real_->GetRenderTargetData(pRenderTarget, pDestSurface); }
HRESULT WrappedDirect3DDevice9::GetFrontBufferData(UINT iSwapChain, IDirect3DSurface9* pDestSurface) { return real_->GetFrontBufferData(iSwapChain, pDestSurface); }
HRESULT WrappedDirect3DDevice9::StretchRect(IDirect3DSurface9* pSourceSurface, const RECT* pSourceRect, IDirect3DSurface9* pDestSurface, const RECT* pDestRect, D3DTEXTUREFILTERTYPE Filter) { return real_->StretchRect(pSourceSurface, pSourceRect, pDestSurface, pDestRect, Filter); }
HRESULT WrappedDirect3DDevice9::ColorFill(IDirect3DSurface9* pSurface, const RECT* pRect, D3DCOLOR color) { return real_->ColorFill(pSurface, pRect, color); }
HRESULT WrappedDirect3DDevice9::CreateOffscreenPlainSurface(UINT Width, UINT Height, D3DFORMAT Format, D3DPOOL Pool, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle) { return real_->CreateOffscreenPlainSurface(Width, Height, Format, Pool, ppSurface, pSharedHandle); }
HRESULT WrappedDirect3DDevice9::SetRenderTarget(DWORD RenderTargetIndex, IDirect3DSurface9* pRenderTarget) { return real_->SetRenderTarget(RenderTargetIndex, pRenderTarget); }
HRESULT WrappedDirect3DDevice9::GetRenderTarget(DWORD RenderTargetIndex, IDirect3DSurface9** ppRenderTarget) { return real_->GetRenderTarget(RenderTargetIndex, ppRenderTarget); }
HRESULT WrappedDirect3DDevice9::SetDepthStencilSurface(IDirect3DSurface9* pNewZStencil) { return real_->SetDepthStencilSurface(pNewZStencil); }
HRESULT WrappedDirect3DDevice9::GetDepthStencilSurface(IDirect3DSurface9** ppZStencilSurface) { return real_->GetDepthStencilSurface(ppZStencilSurface); }
HRESULT WrappedDirect3DDevice9::BeginScene()
{
if (client_) client_->OnBeginScene();
return real_->BeginScene();
}
HRESULT WrappedDirect3DDevice9::EndScene() { return real_->EndScene(); }
HRESULT WrappedDirect3DDevice9::Clear(DWORD Count, const D3DRECT* pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil) { return real_->Clear(Count, pRects, Flags, Color, Z, Stencil); }
HRESULT WrappedDirect3DDevice9::SetTransform(D3DTRANSFORMSTATETYPE State, const D3DMATRIX* pMatrix) { return real_->SetTransform(State, pMatrix); }
HRESULT WrappedDirect3DDevice9::GetTransform(D3DTRANSFORMSTATETYPE State, D3DMATRIX* pMatrix) { return real_->GetTransform(State, pMatrix); }
HRESULT WrappedDirect3DDevice9::MultiplyTransform(D3DTRANSFORMSTATETYPE state, const D3DMATRIX* matrix) { return real_->MultiplyTransform(state, matrix); }
HRESULT WrappedDirect3DDevice9::SetViewport(const D3DVIEWPORT9* pViewport) { return real_->SetViewport(pViewport); }
HRESULT WrappedDirect3DDevice9::GetViewport(D3DVIEWPORT9* pViewport) { return real_->GetViewport(pViewport); }
HRESULT WrappedDirect3DDevice9::SetMaterial(const D3DMATERIAL9* pMaterial) { return real_->SetMaterial(pMaterial); }
HRESULT WrappedDirect3DDevice9::GetMaterial(D3DMATERIAL9* pMaterial) { return real_->GetMaterial(pMaterial); }
HRESULT WrappedDirect3DDevice9::SetLight(DWORD Index, const D3DLIGHT9* light) { return real_->SetLight(Index, light); }
HRESULT WrappedDirect3DDevice9::GetLight(DWORD Index, D3DLIGHT9* light) { return real_->GetLight(Index, light); }
HRESULT WrappedDirect3DDevice9::LightEnable(DWORD Index, BOOL Enable) { return real_->LightEnable(Index, Enable); }
HRESULT WrappedDirect3DDevice9::GetLightEnable(DWORD Index, BOOL* pEnable) { return real_->GetLightEnable(Index, pEnable); }
HRESULT WrappedDirect3DDevice9::SetClipPlane(DWORD Index, const float* pPlane) { return real_->SetClipPlane(Index, pPlane); }
HRESULT WrappedDirect3DDevice9::GetClipPlane(DWORD Index, float* pPlane) { return real_->GetClipPlane(Index, pPlane); }
HRESULT WrappedDirect3DDevice9::SetRenderState(D3DRENDERSTATETYPE State, DWORD Value) { return real_->SetRenderState(State, Value); }
HRESULT WrappedDirect3DDevice9::GetRenderState(D3DRENDERSTATETYPE State, DWORD* pValue) { return real_->GetRenderState(State, pValue); }
HRESULT WrappedDirect3DDevice9::CreateStateBlock(D3DSTATEBLOCKTYPE Type, IDirect3DStateBlock9** ppSB) { return real_->CreateStateBlock(Type, ppSB); }
HRESULT WrappedDirect3DDevice9::BeginStateBlock() { return real_->BeginStateBlock(); }
HRESULT WrappedDirect3DDevice9::EndStateBlock(IDirect3DStateBlock9** ppSB) { return real_->EndStateBlock(ppSB); }
HRESULT WrappedDirect3DDevice9::SetClipStatus(const D3DCLIPSTATUS9* pClipStatus) { return real_->SetClipStatus(pClipStatus); }
HRESULT WrappedDirect3DDevice9::GetClipStatus(D3DCLIPSTATUS9* pClipStatus) { return real_->GetClipStatus(pClipStatus); }
HRESULT WrappedDirect3DDevice9::GetTexture(DWORD Stage, IDirect3DBaseTexture9** ppTexture)
{
const HRESULT hr = real_->GetTexture(Stage, ppTexture);
if (FAILED(hr) || !ppTexture || !*ppTexture) return hr;
// The real call only ever returns real pointers; recover the wrapper identity.
auto* wrapper = FindWrapperForRealTexture(*ppTexture);
if (wrapper == nullptr) {
// Not one of ours (created before hooks/pass-through path) - nothing to translate.
return hr;
}
(*ppTexture)->Release(); // drop the real ref the runtime handed back
IDirect3DBaseTexture9* result = wrapper;
if (client_) {
if (auto* original = client_->ResolveOriginalFromFake(wrapper)) {
original->AddRef();
result = original;
}
else {
wrapper->AddRef();
}
}
else {
wrapper->AddRef();
}
*ppTexture = result;
return hr;
}
HRESULT WrappedDirect3DDevice9::SetTexture(DWORD Stage, IDirect3DBaseTexture9* pTexture)
{
IDirect3DBaseTexture9* bind = client_ ? client_->ResolveBinding(pTexture) : pTexture;
return real_->SetTexture(Stage, Unwrap(bind));
}
HRESULT WrappedDirect3DDevice9::GetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD* pValue) { return real_->GetTextureStageState(Stage, Type, pValue); }
HRESULT WrappedDirect3DDevice9::SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value) { return real_->SetTextureStageState(Stage, Type, Value); }
HRESULT WrappedDirect3DDevice9::GetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD* pValue) { return real_->GetSamplerState(Sampler, Type, pValue); }
HRESULT WrappedDirect3DDevice9::SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value) { return real_->SetSamplerState(Sampler, Type, Value); }
HRESULT WrappedDirect3DDevice9::ValidateDevice(DWORD* pNumPasses) { return real_->ValidateDevice(pNumPasses); }
HRESULT WrappedDirect3DDevice9::SetPaletteEntries(UINT PaletteNumber, const PALETTEENTRY* pEntries) { return real_->SetPaletteEntries(PaletteNumber, pEntries); }
HRESULT WrappedDirect3DDevice9::GetPaletteEntries(UINT PaletteNumber, PALETTEENTRY* pEntries) { return real_->GetPaletteEntries(PaletteNumber, pEntries); }
HRESULT WrappedDirect3DDevice9::SetCurrentTexturePalette(UINT PaletteNumber) { return real_->SetCurrentTexturePalette(PaletteNumber); }
HRESULT WrappedDirect3DDevice9::GetCurrentTexturePalette(UINT* PaletteNumber) { return real_->GetCurrentTexturePalette(PaletteNumber); }
HRESULT WrappedDirect3DDevice9::SetScissorRect(const RECT* pRect) { return real_->SetScissorRect(pRect); }
HRESULT WrappedDirect3DDevice9::GetScissorRect(RECT* pRect) { return real_->GetScissorRect(pRect); }
HRESULT WrappedDirect3DDevice9::SetSoftwareVertexProcessing(BOOL bSoftware) { return real_->SetSoftwareVertexProcessing(bSoftware); }
BOOL WrappedDirect3DDevice9::GetSoftwareVertexProcessing() { return real_->GetSoftwareVertexProcessing(); }
HRESULT WrappedDirect3DDevice9::SetNPatchMode(float nSegments) { return real_->SetNPatchMode(nSegments); }
float WrappedDirect3DDevice9::GetNPatchMode() { return real_->GetNPatchMode(); }
HRESULT WrappedDirect3DDevice9::DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount) { return real_->DrawPrimitive(PrimitiveType, StartVertex, PrimitiveCount); }
HRESULT WrappedDirect3DDevice9::DrawIndexedPrimitive(D3DPRIMITIVETYPE type, INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount) { return real_->DrawIndexedPrimitive(type, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount); }
HRESULT WrappedDirect3DDevice9::DrawPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, const void* pVertexStreamZeroData, UINT VertexStreamZeroStride) { return real_->DrawPrimitiveUP(PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride); }
HRESULT WrappedDirect3DDevice9::DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex, UINT NumVertices, UINT PrimitiveCount, const void* pIndexData, D3DFORMAT IndexDataFormat, const void* pVertexStreamZeroData, UINT VertexStreamZeroStride) { return real_->DrawIndexedPrimitiveUP(PrimitiveType, MinVertexIndex, NumVertices, PrimitiveCount, pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride); }
HRESULT WrappedDirect3DDevice9::ProcessVertices(UINT SrcStartIndex, UINT DestIndex, UINT VertexCount, IDirect3DVertexBuffer9* pDestBuffer, IDirect3DVertexDeclaration9* pVertexDecl, DWORD Flags) { return real_->ProcessVertices(SrcStartIndex, DestIndex, VertexCount, pDestBuffer, pVertexDecl, Flags); }
HRESULT WrappedDirect3DDevice9::CreateVertexDeclaration(const D3DVERTEXELEMENT9* pVertexElements, IDirect3DVertexDeclaration9** ppDecl) { return real_->CreateVertexDeclaration(pVertexElements, ppDecl); }
HRESULT WrappedDirect3DDevice9::SetVertexDeclaration(IDirect3DVertexDeclaration9* pDecl) { return real_->SetVertexDeclaration(pDecl); }
HRESULT WrappedDirect3DDevice9::GetVertexDeclaration(IDirect3DVertexDeclaration9** ppDecl) { return real_->GetVertexDeclaration(ppDecl); }
HRESULT WrappedDirect3DDevice9::SetFVF(DWORD FVF) { return real_->SetFVF(FVF); }
HRESULT WrappedDirect3DDevice9::GetFVF(DWORD* pFVF) { return real_->GetFVF(pFVF); }
HRESULT WrappedDirect3DDevice9::CreateVertexShader(const DWORD* pFunction, IDirect3DVertexShader9** ppShader) { return real_->CreateVertexShader(pFunction, ppShader); }
HRESULT WrappedDirect3DDevice9::SetVertexShader(IDirect3DVertexShader9* pShader) { return real_->SetVertexShader(pShader); }
HRESULT WrappedDirect3DDevice9::GetVertexShader(IDirect3DVertexShader9** ppShader) { return real_->GetVertexShader(ppShader); }
HRESULT WrappedDirect3DDevice9::SetVertexShaderConstantF(UINT StartRegister, const float* pConstantData, UINT Vector4fCount) { return real_->SetVertexShaderConstantF(StartRegister, pConstantData, Vector4fCount); }
HRESULT WrappedDirect3DDevice9::GetVertexShaderConstantF(UINT StartRegister, float* pConstantData, UINT Vector4fCount) { return real_->GetVertexShaderConstantF(StartRegister, pConstantData, Vector4fCount); }
HRESULT WrappedDirect3DDevice9::SetVertexShaderConstantI(UINT StartRegister, const int* pConstantData, UINT Vector4iCount) { return real_->SetVertexShaderConstantI(StartRegister, pConstantData, Vector4iCount); }
HRESULT WrappedDirect3DDevice9::GetVertexShaderConstantI(UINT StartRegister, int* pConstantData, UINT Vector4iCount) { return real_->GetVertexShaderConstantI(StartRegister, pConstantData, Vector4iCount); }
HRESULT WrappedDirect3DDevice9::SetVertexShaderConstantB(UINT StartRegister, const BOOL* pConstantData, UINT BoolCount) { return real_->SetVertexShaderConstantB(StartRegister, pConstantData, BoolCount); }
HRESULT WrappedDirect3DDevice9::GetVertexShaderConstantB(UINT StartRegister, BOOL* pConstantData, UINT BoolCount) { return real_->GetVertexShaderConstantB(StartRegister, pConstantData, BoolCount); }
HRESULT WrappedDirect3DDevice9::SetStreamSource(UINT StreamNumber, IDirect3DVertexBuffer9* pStreamData, UINT OffsetInBytes, UINT Stride) { return real_->SetStreamSource(StreamNumber, pStreamData, OffsetInBytes, Stride); }
HRESULT WrappedDirect3DDevice9::GetStreamSource(UINT StreamNumber, IDirect3DVertexBuffer9** ppStreamData, UINT* pOffsetInBytes, UINT* pStride) { return real_->GetStreamSource(StreamNumber, ppStreamData, pOffsetInBytes, pStride); }
HRESULT WrappedDirect3DDevice9::SetStreamSourceFreq(UINT StreamNumber, UINT Setting) { return real_->SetStreamSourceFreq(StreamNumber, Setting); }
HRESULT WrappedDirect3DDevice9::GetStreamSourceFreq(UINT StreamNumber, UINT* pSetting) { return real_->GetStreamSourceFreq(StreamNumber, pSetting); }
HRESULT WrappedDirect3DDevice9::SetIndices(IDirect3DIndexBuffer9* pIndexData) { return real_->SetIndices(pIndexData); }
HRESULT WrappedDirect3DDevice9::GetIndices(IDirect3DIndexBuffer9** ppIndexData) { return real_->GetIndices(ppIndexData); }
HRESULT WrappedDirect3DDevice9::CreatePixelShader(const DWORD* pFunction, IDirect3DPixelShader9** ppShader) { return real_->CreatePixelShader(pFunction, ppShader); }
HRESULT WrappedDirect3DDevice9::SetPixelShader(IDirect3DPixelShader9* pShader) { return real_->SetPixelShader(pShader); }
HRESULT WrappedDirect3DDevice9::GetPixelShader(IDirect3DPixelShader9** ppShader) { return real_->GetPixelShader(ppShader); }
HRESULT WrappedDirect3DDevice9::SetPixelShaderConstantF(UINT StartRegister, const float* pConstantData, UINT Vector4fCount) { return real_->SetPixelShaderConstantF(StartRegister, pConstantData, Vector4fCount); }
HRESULT WrappedDirect3DDevice9::GetPixelShaderConstantF(UINT StartRegister, float* pConstantData, UINT Vector4fCount) { return real_->GetPixelShaderConstantF(StartRegister, pConstantData, Vector4fCount); }
HRESULT WrappedDirect3DDevice9::SetPixelShaderConstantI(UINT StartRegister, const int* pConstantData, UINT Vector4iCount) { return real_->SetPixelShaderConstantI(StartRegister, pConstantData, Vector4iCount); }
HRESULT WrappedDirect3DDevice9::GetPixelShaderConstantI(UINT StartRegister, int* pConstantData, UINT Vector4iCount) { return real_->GetPixelShaderConstantI(StartRegister, pConstantData, Vector4iCount); }
HRESULT WrappedDirect3DDevice9::SetPixelShaderConstantB(UINT StartRegister, const BOOL* pConstantData, UINT BoolCount) { return real_->SetPixelShaderConstantB(StartRegister, pConstantData, BoolCount); }
HRESULT WrappedDirect3DDevice9::GetPixelShaderConstantB(UINT StartRegister, BOOL* pConstantData, UINT BoolCount) { return real_->GetPixelShaderConstantB(StartRegister, pConstantData, BoolCount); }
HRESULT WrappedDirect3DDevice9::DrawRectPatch(UINT Handle, const float* pNumSegs, const D3DRECTPATCH_INFO* pRectPatchInfo) { return real_->DrawRectPatch(Handle, pNumSegs, pRectPatchInfo); }
HRESULT WrappedDirect3DDevice9::DrawTriPatch(UINT Handle, const float* pNumSegs, const D3DTRIPATCH_INFO* pTriPatchInfo) { return real_->DrawTriPatch(Handle, pNumSegs, pTriPatchInfo); }
HRESULT WrappedDirect3DDevice9::DeletePatch(UINT Handle) { return real_->DeletePatch(Handle); }
HRESULT WrappedDirect3DDevice9::CreateQuery(D3DQUERYTYPE Type, IDirect3DQuery9** ppQuery) { return real_->CreateQuery(Type, ppQuery); }
// ---- WrappedDirect3DDevice9Ex ---------------------------------------------
WrappedDirect3DDevice9Ex::WrappedDirect3DDevice9Ex(IDirect3DDevice9Ex* real) : real_(real), ref_count_(1), client_(nullptr)
{
real_->AddRef();
}
HRESULT WrappedDirect3DDevice9Ex::QueryInterface(REFIID riid, void** ppvObj)
{
if (riid == IID_IUnknown || riid == IID_IDirect3DDevice9 || riid == IID_IDirect3DDevice9Ex) {
AddRef();
*ppvObj = this;
return S_OK;
}
// Unrecognized-but-successful QueryInterface hands back an unwrapped real pointer.
return real_->QueryInterface(riid, ppvObj);
}
ULONG WrappedDirect3DDevice9Ex::AddRef()
{
return ++ref_count_;
}
void WrappedDirect3DDevice9Ex::TeardownTextureClient()
{
if (auto* client = TextureClient::CurrentClient())
delete client;
}
ULONG WrappedDirect3DDevice9Ex::Release()
{
const ULONG count = --ref_count_;
if (count == 0) {
TeardownTextureClient();
real_->Release();
delete this;
return 0;
}
return count;
}
HRESULT WrappedDirect3DDevice9Ex::TestCooperativeLevel() { return real_->TestCooperativeLevel(); }
UINT WrappedDirect3DDevice9Ex::GetAvailableTextureMem() { return real_->GetAvailableTextureMem(); }
HRESULT WrappedDirect3DDevice9Ex::EvictManagedResources() { return real_->EvictManagedResources(); }
HRESULT WrappedDirect3DDevice9Ex::GetDirect3D(IDirect3D9** ppD3D9) { return real_->GetDirect3D(ppD3D9); }
HRESULT WrappedDirect3DDevice9Ex::GetDeviceCaps(D3DCAPS9* pCaps) { return real_->GetDeviceCaps(pCaps); }
HRESULT WrappedDirect3DDevice9Ex::GetDisplayMode(UINT iSwapChain, D3DDISPLAYMODE* pMode) { return real_->GetDisplayMode(iSwapChain, pMode); }
HRESULT WrappedDirect3DDevice9Ex::GetCreationParameters(D3DDEVICE_CREATION_PARAMETERS* pParameters) { return real_->GetCreationParameters(pParameters); }
HRESULT WrappedDirect3DDevice9Ex::SetCursorProperties(UINT XHotSpot, UINT YHotSpot, IDirect3DSurface9* pCursorBitmap) { return real_->SetCursorProperties(XHotSpot, YHotSpot, pCursorBitmap); }
void WrappedDirect3DDevice9Ex::SetCursorPosition(int X, int Y, DWORD Flags) { real_->SetCursorPosition(X, Y, Flags); }
BOOL WrappedDirect3DDevice9Ex::ShowCursor(BOOL bShow) { return real_->ShowCursor(bShow); }
HRESULT WrappedDirect3DDevice9Ex::CreateAdditionalSwapChain(D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DSwapChain9** pSwapChain) { return real_->CreateAdditionalSwapChain(pPresentationParameters, pSwapChain); }
HRESULT WrappedDirect3DDevice9Ex::GetSwapChain(UINT iSwapChain, IDirect3DSwapChain9** pSwapChain) { return real_->GetSwapChain(iSwapChain, pSwapChain); }
UINT WrappedDirect3DDevice9Ex::GetNumberOfSwapChains() { return real_->GetNumberOfSwapChains(); }
HRESULT WrappedDirect3DDevice9Ex::Reset(D3DPRESENT_PARAMETERS* pPresentationParameters) { return real_->Reset(pPresentationParameters); }
HRESULT WrappedDirect3DDevice9Ex::Present(const RECT* pSourceRect, const RECT* pDestRect, HWND hDestWindowOverride, const RGNDATA* pDirtyRegion) { return real_->Present(pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion); }
HRESULT WrappedDirect3DDevice9Ex::GetBackBuffer(UINT iSwapChain, UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface9** ppBackBuffer) { return real_->GetBackBuffer(iSwapChain, iBackBuffer, Type, ppBackBuffer); }
HRESULT WrappedDirect3DDevice9Ex::GetRasterStatus(UINT iSwapChain, D3DRASTER_STATUS* pRasterStatus) { return real_->GetRasterStatus(iSwapChain, pRasterStatus); }
HRESULT WrappedDirect3DDevice9Ex::SetDialogBoxMode(BOOL bEnableDialogs) { return real_->SetDialogBoxMode(bEnableDialogs); }
void WrappedDirect3DDevice9Ex::SetGammaRamp(UINT iSwapChain, DWORD Flags, const D3DGAMMARAMP* pRamp) { real_->SetGammaRamp(iSwapChain, Flags, pRamp); }
void WrappedDirect3DDevice9Ex::GetGammaRamp(UINT iSwapChain, D3DGAMMARAMP* pRamp) { real_->GetGammaRamp(iSwapChain, pRamp); }
HRESULT WrappedDirect3DDevice9Ex::CreateTexture(UINT Width, UINT Height, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DTexture9** ppTexture, HANDLE* pSharedHandle)
{
IDirect3DTexture9* real_texture = nullptr;
const HRESULT hr = real_->CreateTexture(Width, Height, Levels, Usage, Format, Pool, &real_texture, pSharedHandle);
if (FAILED(hr) || real_texture == nullptr) {
if (ppTexture) *ppTexture = nullptr;
return hr;
}
const auto wrapped = new WrappedTexture9(real_texture);
real_texture->Release();
if (client_) client_->OnCreateTexture(wrapped, TexType::Tex2D);
*ppTexture = wrapped;
return hr;
}
HRESULT WrappedDirect3DDevice9Ex::CreateVolumeTexture(UINT Width, UINT Height, UINT Depth, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DVolumeTexture9** ppVolumeTexture, HANDLE* pSharedHandle)
{
IDirect3DVolumeTexture9* real_texture = nullptr;
const HRESULT hr = real_->CreateVolumeTexture(Width, Height, Depth, Levels, Usage, Format, Pool, &real_texture, pSharedHandle);
if (FAILED(hr) || real_texture == nullptr) {
if (ppVolumeTexture) *ppVolumeTexture = nullptr;
return hr;
}
const auto wrapped = new WrappedVolumeTexture9(real_texture);
real_texture->Release();
if (client_) client_->OnCreateTexture(wrapped, TexType::Volume);
*ppVolumeTexture = wrapped;
return hr;
}
HRESULT WrappedDirect3DDevice9Ex::CreateCubeTexture(UINT EdgeLength, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DCubeTexture9** ppCubeTexture, HANDLE* pSharedHandle)
{
IDirect3DCubeTexture9* real_texture = nullptr;
const HRESULT hr = real_->CreateCubeTexture(EdgeLength, Levels, Usage, Format, Pool, &real_texture, pSharedHandle);
if (FAILED(hr) || real_texture == nullptr) {
if (ppCubeTexture) *ppCubeTexture = nullptr;
return hr;
}
const auto wrapped = new WrappedCubeTexture9(real_texture);
real_texture->Release();
if (client_) client_->OnCreateTexture(wrapped, TexType::Cube);
*ppCubeTexture = wrapped;
return hr;
}
HRESULT WrappedDirect3DDevice9Ex::CreateVertexBuffer(UINT Length, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer9** ppVertexBuffer, HANDLE* pSharedHandle) { return real_->CreateVertexBuffer(Length, Usage, FVF, Pool, ppVertexBuffer, pSharedHandle); }
HRESULT WrappedDirect3DDevice9Ex::CreateIndexBuffer(UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer9** ppIndexBuffer, HANDLE* pSharedHandle) { return real_->CreateIndexBuffer(Length, Usage, Format, Pool, ppIndexBuffer, pSharedHandle); }
HRESULT WrappedDirect3DDevice9Ex::CreateRenderTarget(UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, BOOL Lockable, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle) { return real_->CreateRenderTarget(Width, Height, Format, MultiSample, MultisampleQuality, Lockable, ppSurface, pSharedHandle); }
HRESULT WrappedDirect3DDevice9Ex::CreateDepthStencilSurface(UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, BOOL Discard, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle) { return real_->CreateDepthStencilSurface(Width, Height, Format, MultiSample, MultisampleQuality, Discard, ppSurface, pSharedHandle); }
HRESULT WrappedDirect3DDevice9Ex::UpdateSurface(IDirect3DSurface9* pSourceSurface, const RECT* pSourceRect, IDirect3DSurface9* pDestinationSurface, const POINT* pDestPoint) { return real_->UpdateSurface(pSourceSurface, pSourceRect, pDestinationSurface, pDestPoint); }
HRESULT WrappedDirect3DDevice9Ex::UpdateTexture(IDirect3DBaseTexture9* pSourceTexture, IDirect3DBaseTexture9* pDestinationTexture)
{
const HRESULT hr = real_->UpdateTexture(Unwrap(pSourceTexture), Unwrap(pDestinationTexture));
if (SUCCEEDED(hr) && client_)
client_->OnUpdateTexture(pSourceTexture, pDestinationTexture);
return hr;
}
HRESULT WrappedDirect3DDevice9Ex::GetRenderTargetData(IDirect3DSurface9* pRenderTarget, IDirect3DSurface9* pDestSurface) { return real_->GetRenderTargetData(pRenderTarget, pDestSurface); }
HRESULT WrappedDirect3DDevice9Ex::GetFrontBufferData(UINT iSwapChain, IDirect3DSurface9* pDestSurface) { return real_->GetFrontBufferData(iSwapChain, pDestSurface); }
HRESULT WrappedDirect3DDevice9Ex::StretchRect(IDirect3DSurface9* pSourceSurface, const RECT* pSourceRect, IDirect3DSurface9* pDestSurface, const RECT* pDestRect, D3DTEXTUREFILTERTYPE Filter) { return real_->StretchRect(pSourceSurface, pSourceRect, pDestSurface, pDestRect, Filter); }
HRESULT WrappedDirect3DDevice9Ex::ColorFill(IDirect3DSurface9* pSurface, const RECT* pRect, D3DCOLOR color) { return real_->ColorFill(pSurface, pRect, color); }
HRESULT WrappedDirect3DDevice9Ex::CreateOffscreenPlainSurface(UINT Width, UINT Height, D3DFORMAT Format, D3DPOOL Pool, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle) { return real_->CreateOffscreenPlainSurface(Width, Height, Format, Pool, ppSurface, pSharedHandle); }
HRESULT WrappedDirect3DDevice9Ex::SetRenderTarget(DWORD RenderTargetIndex, IDirect3DSurface9* pRenderTarget) { return real_->SetRenderTarget(RenderTargetIndex, pRenderTarget); }
HRESULT WrappedDirect3DDevice9Ex::GetRenderTarget(DWORD RenderTargetIndex, IDirect3DSurface9** ppRenderTarget) { return real_->GetRenderTarget(RenderTargetIndex, ppRenderTarget); }
HRESULT WrappedDirect3DDevice9Ex::SetDepthStencilSurface(IDirect3DSurface9* pNewZStencil) { return real_->SetDepthStencilSurface(pNewZStencil); }
HRESULT WrappedDirect3DDevice9Ex::GetDepthStencilSurface(IDirect3DSurface9** ppZStencilSurface) { return real_->GetDepthStencilSurface(ppZStencilSurface); }
HRESULT WrappedDirect3DDevice9Ex::BeginScene()
{
if (client_) client_->OnBeginScene();
return real_->BeginScene();
}
HRESULT WrappedDirect3DDevice9Ex::EndScene() { return real_->EndScene(); }
HRESULT WrappedDirect3DDevice9Ex::Clear(DWORD Count, const D3DRECT* pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil) { return real_->Clear(Count, pRects, Flags, Color, Z, Stencil); }
HRESULT WrappedDirect3DDevice9Ex::SetTransform(D3DTRANSFORMSTATETYPE State, const D3DMATRIX* pMatrix) { return real_->SetTransform(State, pMatrix); }
HRESULT WrappedDirect3DDevice9Ex::GetTransform(D3DTRANSFORMSTATETYPE State, D3DMATRIX* pMatrix) { return real_->GetTransform(State, pMatrix); }
HRESULT WrappedDirect3DDevice9Ex::MultiplyTransform(D3DTRANSFORMSTATETYPE state, const D3DMATRIX* matrix) { return real_->MultiplyTransform(state, matrix); }
HRESULT WrappedDirect3DDevice9Ex::SetViewport(const D3DVIEWPORT9* pViewport) { return real_->SetViewport(pViewport); }
HRESULT WrappedDirect3DDevice9Ex::GetViewport(D3DVIEWPORT9* pViewport) { return real_->GetViewport(pViewport); }
HRESULT WrappedDirect3DDevice9Ex::SetMaterial(const D3DMATERIAL9* pMaterial) { return real_->SetMaterial(pMaterial); }
HRESULT WrappedDirect3DDevice9Ex::GetMaterial(D3DMATERIAL9* pMaterial) { return real_->GetMaterial(pMaterial); }
HRESULT WrappedDirect3DDevice9Ex::SetLight(DWORD Index, const D3DLIGHT9* light) { return real_->SetLight(Index, light); }
HRESULT WrappedDirect3DDevice9Ex::GetLight(DWORD Index, D3DLIGHT9* light) { return real_->GetLight(Index, light); }
HRESULT WrappedDirect3DDevice9Ex::LightEnable(DWORD Index, BOOL Enable) { return real_->LightEnable(Index, Enable); }
HRESULT WrappedDirect3DDevice9Ex::GetLightEnable(DWORD Index, BOOL* pEnable) { return real_->GetLightEnable(Index, pEnable); }
HRESULT WrappedDirect3DDevice9Ex::SetClipPlane(DWORD Index, const float* pPlane) { return real_->SetClipPlane(Index, pPlane); }
HRESULT WrappedDirect3DDevice9Ex::GetClipPlane(DWORD Index, float* pPlane) { return real_->GetClipPlane(Index, pPlane); }
HRESULT WrappedDirect3DDevice9Ex::SetRenderState(D3DRENDERSTATETYPE State, DWORD Value) { return real_->SetRenderState(State, Value); }
HRESULT WrappedDirect3DDevice9Ex::GetRenderState(D3DRENDERSTATETYPE State, DWORD* pValue) { return real_->GetRenderState(State, pValue); }
HRESULT WrappedDirect3DDevice9Ex::CreateStateBlock(D3DSTATEBLOCKTYPE Type, IDirect3DStateBlock9** ppSB) { return real_->CreateStateBlock(Type, ppSB); }
HRESULT WrappedDirect3DDevice9Ex::BeginStateBlock() { return real_->BeginStateBlock(); }
HRESULT WrappedDirect3DDevice9Ex::EndStateBlock(IDirect3DStateBlock9** ppSB) { return real_->EndStateBlock(ppSB); }
HRESULT WrappedDirect3DDevice9Ex::SetClipStatus(const D3DCLIPSTATUS9* pClipStatus) { return real_->SetClipStatus(pClipStatus); }
HRESULT WrappedDirect3DDevice9Ex::GetClipStatus(D3DCLIPSTATUS9* pClipStatus) { return real_->GetClipStatus(pClipStatus); }
HRESULT WrappedDirect3DDevice9Ex::GetTexture(DWORD Stage, IDirect3DBaseTexture9** ppTexture)
{
const HRESULT hr = real_->GetTexture(Stage, ppTexture);
if (FAILED(hr) || !ppTexture || !*ppTexture) return hr;
auto* wrapper = FindWrapperForRealTexture(*ppTexture);
if (wrapper == nullptr) {
return hr;
}
(*ppTexture)->Release();
IDirect3DBaseTexture9* result = wrapper;
if (client_) {
if (auto* original = client_->ResolveOriginalFromFake(wrapper)) {
original->AddRef();
result = original;
}
else {
wrapper->AddRef();
}
}
else {
wrapper->AddRef();
}
*ppTexture = result;
return hr;
}
HRESULT WrappedDirect3DDevice9Ex::SetTexture(DWORD Stage, IDirect3DBaseTexture9* pTexture)
{
IDirect3DBaseTexture9* bind = client_ ? client_->ResolveBinding(pTexture) : pTexture;
return real_->SetTexture(Stage, Unwrap(bind));
}
HRESULT WrappedDirect3DDevice9Ex::GetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD* pValue) { return real_->GetTextureStageState(Stage, Type, pValue); }
HRESULT WrappedDirect3DDevice9Ex::SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value) { return real_->SetTextureStageState(Stage, Type, Value); }
HRESULT WrappedDirect3DDevice9Ex::GetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD* pValue) { return real_->GetSamplerState(Sampler, Type, pValue); }
HRESULT WrappedDirect3DDevice9Ex::SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value) { return real_->SetSamplerState(Sampler, Type, Value); }
HRESULT WrappedDirect3DDevice9Ex::ValidateDevice(DWORD* pNumPasses) { return real_->ValidateDevice(pNumPasses); }
HRESULT WrappedDirect3DDevice9Ex::SetPaletteEntries(UINT PaletteNumber, const PALETTEENTRY* pEntries) { return real_->SetPaletteEntries(PaletteNumber, pEntries); }
HRESULT WrappedDirect3DDevice9Ex::GetPaletteEntries(UINT PaletteNumber, PALETTEENTRY* pEntries) { return real_->GetPaletteEntries(PaletteNumber, pEntries); }
HRESULT WrappedDirect3DDevice9Ex::SetCurrentTexturePalette(UINT PaletteNumber) { return real_->SetCurrentTexturePalette(PaletteNumber); }
HRESULT WrappedDirect3DDevice9Ex::GetCurrentTexturePalette(UINT* PaletteNumber) { return real_->GetCurrentTexturePalette(PaletteNumber); }
HRESULT WrappedDirect3DDevice9Ex::SetScissorRect(const RECT* pRect) { return real_->SetScissorRect(pRect); }
HRESULT WrappedDirect3DDevice9Ex::GetScissorRect(RECT* pRect) { return real_->GetScissorRect(pRect); }
HRESULT WrappedDirect3DDevice9Ex::SetSoftwareVertexProcessing(BOOL bSoftware) { return real_->SetSoftwareVertexProcessing(bSoftware); }
BOOL WrappedDirect3DDevice9Ex::GetSoftwareVertexProcessing() { return real_->GetSoftwareVertexProcessing(); }
HRESULT WrappedDirect3DDevice9Ex::SetNPatchMode(float nSegments) { return real_->SetNPatchMode(nSegments); }
float WrappedDirect3DDevice9Ex::GetNPatchMode() { return real_->GetNPatchMode(); }
HRESULT WrappedDirect3DDevice9Ex::DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount) { return real_->DrawPrimitive(PrimitiveType, StartVertex, PrimitiveCount); }
HRESULT WrappedDirect3DDevice9Ex::DrawIndexedPrimitive(D3DPRIMITIVETYPE type, INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount) { return real_->DrawIndexedPrimitive(type, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount); }
HRESULT WrappedDirect3DDevice9Ex::DrawPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, const void* pVertexStreamZeroData, UINT VertexStreamZeroStride) { return real_->DrawPrimitiveUP(PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride); }
HRESULT WrappedDirect3DDevice9Ex::DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex, UINT NumVertices, UINT PrimitiveCount, const void* pIndexData, D3DFORMAT IndexDataFormat, const void* pVertexStreamZeroData, UINT VertexStreamZeroStride) { return real_->DrawIndexedPrimitiveUP(PrimitiveType, MinVertexIndex, NumVertices, PrimitiveCount, pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride); }
HRESULT WrappedDirect3DDevice9Ex::ProcessVertices(UINT SrcStartIndex, UINT DestIndex, UINT VertexCount, IDirect3DVertexBuffer9* pDestBuffer, IDirect3DVertexDeclaration9* pVertexDecl, DWORD Flags) { return real_->ProcessVertices(SrcStartIndex, DestIndex, VertexCount, pDestBuffer, pVertexDecl, Flags); }
HRESULT WrappedDirect3DDevice9Ex::CreateVertexDeclaration(const D3DVERTEXELEMENT9* pVertexElements, IDirect3DVertexDeclaration9** ppDecl) { return real_->CreateVertexDeclaration(pVertexElements, ppDecl); }
HRESULT WrappedDirect3DDevice9Ex::SetVertexDeclaration(IDirect3DVertexDeclaration9* pDecl) { return real_->SetVertexDeclaration(pDecl); }
HRESULT WrappedDirect3DDevice9Ex::GetVertexDeclaration(IDirect3DVertexDeclaration9** ppDecl) { return real_->GetVertexDeclaration(ppDecl); }
HRESULT WrappedDirect3DDevice9Ex::SetFVF(DWORD FVF) { return real_->SetFVF(FVF); }
HRESULT WrappedDirect3DDevice9Ex::GetFVF(DWORD* pFVF) { return real_->GetFVF(pFVF); }
HRESULT WrappedDirect3DDevice9Ex::CreateVertexShader(const DWORD* pFunction, IDirect3DVertexShader9** ppShader) { return real_->CreateVertexShader(pFunction, ppShader); }
HRESULT WrappedDirect3DDevice9Ex::SetVertexShader(IDirect3DVertexShader9* pShader) { return real_->SetVertexShader(pShader); }
HRESULT WrappedDirect3DDevice9Ex::GetVertexShader(IDirect3DVertexShader9** ppShader) { return real_->GetVertexShader(ppShader); }
HRESULT WrappedDirect3DDevice9Ex::SetVertexShaderConstantF(UINT StartRegister, const float* pConstantData, UINT Vector4fCount) { return real_->SetVertexShaderConstantF(StartRegister, pConstantData, Vector4fCount); }
HRESULT WrappedDirect3DDevice9Ex::GetVertexShaderConstantF(UINT StartRegister, float* pConstantData, UINT Vector4fCount) { return real_->GetVertexShaderConstantF(StartRegister, pConstantData, Vector4fCount); }
HRESULT WrappedDirect3DDevice9Ex::SetVertexShaderConstantI(UINT StartRegister, const int* pConstantData, UINT Vector4iCount) { return real_->SetVertexShaderConstantI(StartRegister, pConstantData, Vector4iCount); }
HRESULT WrappedDirect3DDevice9Ex::GetVertexShaderConstantI(UINT StartRegister, int* pConstantData, UINT Vector4iCount) { return real_->GetVertexShaderConstantI(StartRegister, pConstantData, Vector4iCount); }
HRESULT WrappedDirect3DDevice9Ex::SetVertexShaderConstantB(UINT StartRegister, const BOOL* pConstantData, UINT BoolCount) { return real_->SetVertexShaderConstantB(StartRegister, pConstantData, BoolCount); }
HRESULT WrappedDirect3DDevice9Ex::GetVertexShaderConstantB(UINT StartRegister, BOOL* pConstantData, UINT BoolCount) { return real_->GetVertexShaderConstantB(StartRegister, pConstantData, BoolCount); }
HRESULT WrappedDirect3DDevice9Ex::SetStreamSource(UINT StreamNumber, IDirect3DVertexBuffer9* pStreamData, UINT OffsetInBytes, UINT Stride) { return real_->SetStreamSource(StreamNumber, pStreamData, OffsetInBytes, Stride); }
HRESULT WrappedDirect3DDevice9Ex::GetStreamSource(UINT StreamNumber, IDirect3DVertexBuffer9** ppStreamData, UINT* pOffsetInBytes, UINT* pStride) { return real_->GetStreamSource(StreamNumber, ppStreamData, pOffsetInBytes, pStride); }
HRESULT WrappedDirect3DDevice9Ex::SetStreamSourceFreq(UINT StreamNumber, UINT Setting) { return real_->SetStreamSourceFreq(StreamNumber, Setting); }
HRESULT WrappedDirect3DDevice9Ex::GetStreamSourceFreq(UINT StreamNumber, UINT* pSetting) { return real_->GetStreamSourceFreq(StreamNumber, pSetting); }
HRESULT WrappedDirect3DDevice9Ex::SetIndices(IDirect3DIndexBuffer9* pIndexData) { return real_->SetIndices(pIndexData); }
HRESULT WrappedDirect3DDevice9Ex::GetIndices(IDirect3DIndexBuffer9** ppIndexData) { return real_->GetIndices(ppIndexData); }
HRESULT WrappedDirect3DDevice9Ex::CreatePixelShader(const DWORD* pFunction, IDirect3DPixelShader9** ppShader) { return real_->CreatePixelShader(pFunction, ppShader); }
HRESULT WrappedDirect3DDevice9Ex::SetPixelShader(IDirect3DPixelShader9* pShader) { return real_->SetPixelShader(pShader); }
HRESULT WrappedDirect3DDevice9Ex::GetPixelShader(IDirect3DPixelShader9** ppShader) { return real_->GetPixelShader(ppShader); }
HRESULT WrappedDirect3DDevice9Ex::SetPixelShaderConstantF(UINT StartRegister, const float* pConstantData, UINT Vector4fCount) { return real_->SetPixelShaderConstantF(StartRegister, pConstantData, Vector4fCount); }
HRESULT WrappedDirect3DDevice9Ex::GetPixelShaderConstantF(UINT StartRegister, float* pConstantData, UINT Vector4fCount) { return real_->GetPixelShaderConstantF(StartRegister, pConstantData, Vector4fCount); }
HRESULT WrappedDirect3DDevice9Ex::SetPixelShaderConstantI(UINT StartRegister, const int* pConstantData, UINT Vector4iCount) { return real_->SetPixelShaderConstantI(StartRegister, pConstantData, Vector4iCount); }
HRESULT WrappedDirect3DDevice9Ex::GetPixelShaderConstantI(UINT StartRegister, int* pConstantData, UINT Vector4iCount) { return real_->GetPixelShaderConstantI(StartRegister, pConstantData, Vector4iCount); }
HRESULT WrappedDirect3DDevice9Ex::SetPixelShaderConstantB(UINT StartRegister, const BOOL* pConstantData, UINT BoolCount) { return real_->SetPixelShaderConstantB(StartRegister, pConstantData, BoolCount); }
HRESULT WrappedDirect3DDevice9Ex::GetPixelShaderConstantB(UINT StartRegister, BOOL* pConstantData, UINT BoolCount) { return real_->GetPixelShaderConstantB(StartRegister, pConstantData, BoolCount); }
HRESULT WrappedDirect3DDevice9Ex::DrawRectPatch(UINT Handle, const float* pNumSegs, const D3DRECTPATCH_INFO* pRectPatchInfo) { return real_->DrawRectPatch(Handle, pNumSegs, pRectPatchInfo); }
HRESULT WrappedDirect3DDevice9Ex::DrawTriPatch(UINT Handle, const float* pNumSegs, const D3DTRIPATCH_INFO* pTriPatchInfo) { return real_->DrawTriPatch(Handle, pNumSegs, pTriPatchInfo); }
HRESULT WrappedDirect3DDevice9Ex::DeletePatch(UINT Handle) { return real_->DeletePatch(Handle); }
HRESULT WrappedDirect3DDevice9Ex::CreateQuery(D3DQUERYTYPE Type, IDirect3DQuery9** ppQuery) { return real_->CreateQuery(Type, ppQuery); }
HRESULT WrappedDirect3DDevice9Ex::SetConvolutionMonoKernel(UINT width, UINT height, float* rows, float* columns) { return real_->SetConvolutionMonoKernel(width, height, rows, columns); }
HRESULT WrappedDirect3DDevice9Ex::ComposeRects(IDirect3DSurface9* pSrc, IDirect3DSurface9* pDst, IDirect3DVertexBuffer9* pSrcRectDescs, UINT NumRects, IDirect3DVertexBuffer9* pDstRectDescs, D3DCOMPOSERECTSOP Operation, int Xoffset, int Yoffset) { return real_->ComposeRects(pSrc, pDst, pSrcRectDescs, NumRects, pDstRectDescs, Operation, Xoffset, Yoffset); }
HRESULT WrappedDirect3DDevice9Ex::PresentEx(const RECT* pSourceRect, const RECT* pDestRect, HWND hDestWindowOverride, const RGNDATA* pDirtyRegion, DWORD dwFlags) { return real_->PresentEx(pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion, dwFlags); }
HRESULT WrappedDirect3DDevice9Ex::GetGPUThreadPriority(INT* pPriority) { return real_->GetGPUThreadPriority(pPriority); }
HRESULT WrappedDirect3DDevice9Ex::SetGPUThreadPriority(INT Priority) { return real_->SetGPUThreadPriority(Priority); }
HRESULT WrappedDirect3DDevice9Ex::WaitForVBlank(UINT iSwapChain) { return real_->WaitForVBlank(iSwapChain); }
HRESULT WrappedDirect3DDevice9Ex::CheckResourceResidency(IDirect3DResource9** pResourceArray, UINT32 NumResources) { return real_->CheckResourceResidency(pResourceArray, NumResources); }
HRESULT WrappedDirect3DDevice9Ex::SetMaximumFrameLatency(UINT MaxLatency) { return real_->SetMaximumFrameLatency(MaxLatency); }
HRESULT WrappedDirect3DDevice9Ex::GetMaximumFrameLatency(UINT* pMaxLatency) { return real_->GetMaximumFrameLatency(pMaxLatency); }
HRESULT WrappedDirect3DDevice9Ex::CheckDeviceState(HWND hDestinationWindow) { return real_->CheckDeviceState(hDestinationWindow); }
HRESULT WrappedDirect3DDevice9Ex::CreateRenderTargetEx(UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, BOOL Lockable, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle, DWORD Usage) { return real_->CreateRenderTargetEx(Width, Height, Format, MultiSample, MultisampleQuality, Lockable, ppSurface, pSharedHandle, Usage); }
HRESULT WrappedDirect3DDevice9Ex::CreateOffscreenPlainSurfaceEx(UINT Width, UINT Height, D3DFORMAT Format, D3DPOOL Pool, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle, DWORD Usage) { return real_->CreateOffscreenPlainSurfaceEx(Width, Height, Format, Pool, ppSurface, pSharedHandle, Usage); }
HRESULT WrappedDirect3DDevice9Ex::CreateDepthStencilSurfaceEx(UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, BOOL Discard, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle, DWORD Usage) { return real_->CreateDepthStencilSurfaceEx(Width, Height, Format, MultiSample, MultisampleQuality, Discard, ppSurface, pSharedHandle, Usage); }
HRESULT WrappedDirect3DDevice9Ex::ResetEx(D3DPRESENT_PARAMETERS* pPresentationParameters, D3DDISPLAYMODEEX* pFullscreenDisplayMode) { return real_->ResetEx(pPresentationParameters, pFullscreenDisplayMode); }
HRESULT WrappedDirect3DDevice9Ex::GetDisplayModeEx(UINT iSwapChain, D3DDISPLAYMODEEX* pMode, D3DDISPLAYROTATION* pRotation) { return real_->GetDisplayModeEx(iSwapChain, pMode, pRotation); }
-5
View File
@@ -357,11 +357,6 @@ void InstallD3D9Hooks(IDirect3D9* d3d9, const bool is_ex)
bool RegisterExistingDevice(IDirect3DDevice9* device)
{
if (device == nullptr) return false;
// Already active, whether registered via this path before or already wrapped by the
// cold Direct3DCreate9(Ex) path (D3D9Wrappers.cpp) - that path never touches g_devices,
// so without this check we'd double-hook the wrapper's own vtable and construct a second
// TextureClient, hitting its single-instance ASSERT.
if (TextureClient::CurrentClient() != nullptr) return false;
{
std::lock_guard lk(g_devices_mutex);
if (g_devices.contains(device)) return false; // already known
-212
View File
@@ -1,212 +0,0 @@
#include "Main.h"
#include "D3D9TextureWrappers.h"
#include <mutex>
#include <unordered_map>
import TextureClient;
namespace {
std::mutex g_real_to_wrapper_mutex;
std::unordered_map<IDirect3DBaseTexture9*, IDirect3DBaseTexture9*> g_real_to_wrapper;
}
IDirect3DBaseTexture9* FindWrapperForRealTexture(IDirect3DBaseTexture9* real)
{
if (real == nullptr) return nullptr;
std::lock_guard lk(g_real_to_wrapper_mutex);
const auto it = g_real_to_wrapper.find(real);
return it != g_real_to_wrapper.end() ? it->second : nullptr;
}
void RegisterWrapperForRealTexture(IDirect3DBaseTexture9* real, IDirect3DBaseTexture9* wrapper)
{
std::lock_guard lk(g_real_to_wrapper_mutex);
g_real_to_wrapper[real] = wrapper;
}
void UnregisterWrapperForRealTexture(IDirect3DBaseTexture9* real)
{
std::lock_guard lk(g_real_to_wrapper_mutex);
g_real_to_wrapper.erase(real);
}
// ---- WrappedTexture9 ----------------------------------------------------
WrappedTexture9::WrappedTexture9(IDirect3DTexture9* real) : real_(real), ref_count_(1)
{
real_->AddRef();
RegisterWrapperForRealTexture(real_, this);
}
HRESULT WrappedTexture9::QueryInterface(REFIID riid, void** ppvObj)
{
if (riid == IID_IUnknown || riid == IID_IDirect3DTexture9) {
AddRef();
*ppvObj = this;
return S_OK;
}
// Unrecognized-but-successful QueryInterface hands back an unwrapped real pointer.
return real_->QueryInterface(riid, ppvObj);
}
ULONG WrappedTexture9::AddRef()
{
return ++ref_count_;
}
ULONG WrappedTexture9::Release()
{
const ULONG count = --ref_count_;
if (count == 0) {
if (auto* client = TextureClient::CurrentClient())
client->OnReleaseTexture(this);
UnregisterWrapperForRealTexture(real_);
real_->Release();
delete this;
return 0;
}
return count;
}
HRESULT WrappedTexture9::GetDevice(IDirect3DDevice9** ppDevice) { return real_->GetDevice(ppDevice); }
HRESULT WrappedTexture9::SetPrivateData(REFGUID refguid, const void* pData, DWORD SizeOfData, DWORD Flags) { return real_->SetPrivateData(refguid, pData, SizeOfData, Flags); }
HRESULT WrappedTexture9::GetPrivateData(REFGUID refguid, void* pData, DWORD* pSizeOfData) { return real_->GetPrivateData(refguid, pData, pSizeOfData); }
HRESULT WrappedTexture9::FreePrivateData(REFGUID refguid) { return real_->FreePrivateData(refguid); }
DWORD WrappedTexture9::SetPriority(DWORD PriorityNew) { return real_->SetPriority(PriorityNew); }
DWORD WrappedTexture9::GetPriority() { return real_->GetPriority(); }
void WrappedTexture9::PreLoad() { real_->PreLoad(); }
D3DRESOURCETYPE WrappedTexture9::GetType() { return real_->GetType(); }
DWORD WrappedTexture9::SetLOD(DWORD LODNew) { return real_->SetLOD(LODNew); }
DWORD WrappedTexture9::GetLOD() { return real_->GetLOD(); }
DWORD WrappedTexture9::GetLevelCount() { return real_->GetLevelCount(); }
HRESULT WrappedTexture9::SetAutoGenFilterType(D3DTEXTUREFILTERTYPE FilterType) { return real_->SetAutoGenFilterType(FilterType); }
D3DTEXTUREFILTERTYPE WrappedTexture9::GetAutoGenFilterType() { return real_->GetAutoGenFilterType(); }
void WrappedTexture9::GenerateMipSubLevels() { real_->GenerateMipSubLevels(); }
HRESULT WrappedTexture9::GetLevelDesc(UINT Level, D3DSURFACE_DESC* pDesc) { return real_->GetLevelDesc(Level, pDesc); }
HRESULT WrappedTexture9::GetSurfaceLevel(UINT Level, IDirect3DSurface9** ppSurfaceLevel) { return real_->GetSurfaceLevel(Level, ppSurfaceLevel); }
HRESULT WrappedTexture9::LockRect(UINT Level, D3DLOCKED_RECT* pLockedRect, const RECT* pRect, DWORD Flags) { return real_->LockRect(Level, pLockedRect, pRect, Flags); }
HRESULT WrappedTexture9::UnlockRect(UINT Level) { return real_->UnlockRect(Level); }
HRESULT WrappedTexture9::AddDirtyRect(const RECT* pDirtyRect) { return real_->AddDirtyRect(pDirtyRect); }
// ---- WrappedVolumeTexture9 -----------------------------------------------
WrappedVolumeTexture9::WrappedVolumeTexture9(IDirect3DVolumeTexture9* real) : real_(real), ref_count_(1)
{
real_->AddRef();
RegisterWrapperForRealTexture(real_, this);
}
HRESULT WrappedVolumeTexture9::QueryInterface(REFIID riid, void** ppvObj)
{
if (riid == IID_IUnknown || riid == IID_IDirect3DVolumeTexture9) {
AddRef();
*ppvObj = this;
return S_OK;
}
// Unrecognized-but-successful QueryInterface hands back an unwrapped real pointer.
return real_->QueryInterface(riid, ppvObj);
}
ULONG WrappedVolumeTexture9::AddRef()
{
return ++ref_count_;
}
ULONG WrappedVolumeTexture9::Release()
{
const ULONG count = --ref_count_;
if (count == 0) {
if (auto* client = TextureClient::CurrentClient())
client->OnReleaseTexture(this);
UnregisterWrapperForRealTexture(real_);
real_->Release();
delete this;
return 0;
}
return count;
}
HRESULT WrappedVolumeTexture9::GetDevice(IDirect3DDevice9** ppDevice) { return real_->GetDevice(ppDevice); }
HRESULT WrappedVolumeTexture9::SetPrivateData(REFGUID refguid, const void* pData, DWORD SizeOfData, DWORD Flags) { return real_->SetPrivateData(refguid, pData, SizeOfData, Flags); }
HRESULT WrappedVolumeTexture9::GetPrivateData(REFGUID refguid, void* pData, DWORD* pSizeOfData) { return real_->GetPrivateData(refguid, pData, pSizeOfData); }
HRESULT WrappedVolumeTexture9::FreePrivateData(REFGUID refguid) { return real_->FreePrivateData(refguid); }
DWORD WrappedVolumeTexture9::SetPriority(DWORD PriorityNew) { return real_->SetPriority(PriorityNew); }
DWORD WrappedVolumeTexture9::GetPriority() { return real_->GetPriority(); }
void WrappedVolumeTexture9::PreLoad() { real_->PreLoad(); }
D3DRESOURCETYPE WrappedVolumeTexture9::GetType() { return real_->GetType(); }
DWORD WrappedVolumeTexture9::SetLOD(DWORD LODNew) { return real_->SetLOD(LODNew); }
DWORD WrappedVolumeTexture9::GetLOD() { return real_->GetLOD(); }
DWORD WrappedVolumeTexture9::GetLevelCount() { return real_->GetLevelCount(); }
HRESULT WrappedVolumeTexture9::SetAutoGenFilterType(D3DTEXTUREFILTERTYPE FilterType) { return real_->SetAutoGenFilterType(FilterType); }
D3DTEXTUREFILTERTYPE WrappedVolumeTexture9::GetAutoGenFilterType() { return real_->GetAutoGenFilterType(); }
void WrappedVolumeTexture9::GenerateMipSubLevels() { real_->GenerateMipSubLevels(); }
HRESULT WrappedVolumeTexture9::GetLevelDesc(UINT Level, D3DVOLUME_DESC* pDesc) { return real_->GetLevelDesc(Level, pDesc); }
HRESULT WrappedVolumeTexture9::GetVolumeLevel(UINT Level, IDirect3DVolume9** ppVolumeLevel) { return real_->GetVolumeLevel(Level, ppVolumeLevel); }
HRESULT WrappedVolumeTexture9::LockBox(UINT Level, D3DLOCKED_BOX* pLockedVolume, const D3DBOX* pBox, DWORD Flags) { return real_->LockBox(Level, pLockedVolume, pBox, Flags); }
HRESULT WrappedVolumeTexture9::UnlockBox(UINT Level) { return real_->UnlockBox(Level); }
HRESULT WrappedVolumeTexture9::AddDirtyBox(const D3DBOX* pDirtyBox) { return real_->AddDirtyBox(pDirtyBox); }
// ---- WrappedCubeTexture9 -------------------------------------------------
WrappedCubeTexture9::WrappedCubeTexture9(IDirect3DCubeTexture9* real) : real_(real), ref_count_(1)
{
real_->AddRef();
RegisterWrapperForRealTexture(real_, this);
}
HRESULT WrappedCubeTexture9::QueryInterface(REFIID riid, void** ppvObj)
{
if (riid == IID_IUnknown || riid == IID_IDirect3DCubeTexture9) {
AddRef();
*ppvObj = this;
return S_OK;
}
// Unrecognized-but-successful QueryInterface hands back an unwrapped real pointer.
return real_->QueryInterface(riid, ppvObj);
}
ULONG WrappedCubeTexture9::AddRef()
{
return ++ref_count_;
}
ULONG WrappedCubeTexture9::Release()
{
const ULONG count = --ref_count_;
if (count == 0) {
if (auto* client = TextureClient::CurrentClient())
client->OnReleaseTexture(this);
UnregisterWrapperForRealTexture(real_);
real_->Release();
delete this;
return 0;
}
return count;
}
HRESULT WrappedCubeTexture9::GetDevice(IDirect3DDevice9** ppDevice) { return real_->GetDevice(ppDevice); }
HRESULT WrappedCubeTexture9::SetPrivateData(REFGUID refguid, const void* pData, DWORD SizeOfData, DWORD Flags) { return real_->SetPrivateData(refguid, pData, SizeOfData, Flags); }
HRESULT WrappedCubeTexture9::GetPrivateData(REFGUID refguid, void* pData, DWORD* pSizeOfData) { return real_->GetPrivateData(refguid, pData, pSizeOfData); }
HRESULT WrappedCubeTexture9::FreePrivateData(REFGUID refguid) { return real_->FreePrivateData(refguid); }
DWORD WrappedCubeTexture9::SetPriority(DWORD PriorityNew) { return real_->SetPriority(PriorityNew); }
DWORD WrappedCubeTexture9::GetPriority() { return real_->GetPriority(); }
void WrappedCubeTexture9::PreLoad() { real_->PreLoad(); }
D3DRESOURCETYPE WrappedCubeTexture9::GetType() { return real_->GetType(); }
DWORD WrappedCubeTexture9::SetLOD(DWORD LODNew) { return real_->SetLOD(LODNew); }
DWORD WrappedCubeTexture9::GetLOD() { return real_->GetLOD(); }
DWORD WrappedCubeTexture9::GetLevelCount() { return real_->GetLevelCount(); }
HRESULT WrappedCubeTexture9::SetAutoGenFilterType(D3DTEXTUREFILTERTYPE FilterType) { return real_->SetAutoGenFilterType(FilterType); }
D3DTEXTUREFILTERTYPE WrappedCubeTexture9::GetAutoGenFilterType() { return real_->GetAutoGenFilterType(); }
void WrappedCubeTexture9::GenerateMipSubLevels() { real_->GenerateMipSubLevels(); }
HRESULT WrappedCubeTexture9::GetLevelDesc(UINT Level, D3DSURFACE_DESC* pDesc) { return real_->GetLevelDesc(Level, pDesc); }
HRESULT WrappedCubeTexture9::GetCubeMapSurface(D3DCUBEMAP_FACES FaceType, UINT Level, IDirect3DSurface9** ppCubeMapSurface) { return real_->GetCubeMapSurface(FaceType, Level, ppCubeMapSurface); }
HRESULT WrappedCubeTexture9::LockRect(D3DCUBEMAP_FACES FaceType, UINT Level, D3DLOCKED_RECT* pLockedRect, const RECT* pRect, DWORD Flags) { return real_->LockRect(FaceType, Level, pLockedRect, pRect, Flags); }
HRESULT WrappedCubeTexture9::UnlockRect(D3DCUBEMAP_FACES FaceType, UINT Level) { return real_->UnlockRect(FaceType, Level); }
HRESULT WrappedCubeTexture9::AddDirtyRect(D3DCUBEMAP_FACES FaceType, const RECT* pDirtyRect) { return real_->AddDirtyRect(FaceType, pDirtyRect); }
-166
View File
@@ -1,166 +0,0 @@
#include "Main.h"
#include "D3D9Wrappers.h"
#include "D3D9DeviceWrapper.h"
import TextureClient;
namespace {
// Constructs the device wrapper + its TextureClient. The client must be built with
// the wrapper pointer (not the real device) so DirectX::CreateDDSTextureFromMemoryEx's
// internal CreateTexture call re-enters the wrapper's intercepted CreateTexture, which
// is what makes loading_fake-gated registration (see TextureClient::OnCreateTexture)
// see that call at all.
template <class Wrapper, class Real>
Wrapper* WrapDevice(Real* real_device)
{
const auto wrapper = new Wrapper(real_device);
const auto client = new TextureClient(wrapper);
wrapper->SetClient(client);
client->Initialize();
return wrapper;
}
}
WrappedDirect3D9::WrappedDirect3D9(IDirect3D9* real) : real_(real), ref_count_(1)
{
real_->AddRef();
}
HRESULT WrappedDirect3D9::QueryInterface(REFIID riid, void** ppvObj)
{
if (riid == IID_IUnknown || riid == IID_IDirect3D9) {
AddRef();
*ppvObj = this;
return S_OK;
}
// Unrecognized-but-successful QueryInterface hands back an unwrapped real pointer.
return real_->QueryInterface(riid, ppvObj);
}
ULONG WrappedDirect3D9::AddRef()
{
return ++ref_count_;
}
ULONG WrappedDirect3D9::Release()
{
const ULONG count = --ref_count_;
if (count == 0) {
real_->Release();
delete this;
return 0;
}
return count;
}
HRESULT WrappedDirect3D9::RegisterSoftwareDevice(void* pInitializeFunction) { return real_->RegisterSoftwareDevice(pInitializeFunction); }
UINT WrappedDirect3D9::GetAdapterCount() { return real_->GetAdapterCount(); }
HRESULT WrappedDirect3D9::GetAdapterIdentifier(UINT Adapter, DWORD Flags, D3DADAPTER_IDENTIFIER9* pIdentifier) { return real_->GetAdapterIdentifier(Adapter, Flags, pIdentifier); }
UINT WrappedDirect3D9::GetAdapterModeCount(UINT Adapter, D3DFORMAT Format) { return real_->GetAdapterModeCount(Adapter, Format); }
HRESULT WrappedDirect3D9::EnumAdapterModes(UINT Adapter, D3DFORMAT Format, UINT Mode, D3DDISPLAYMODE* pMode) { return real_->EnumAdapterModes(Adapter, Format, Mode, pMode); }
HRESULT WrappedDirect3D9::GetAdapterDisplayMode(UINT Adapter, D3DDISPLAYMODE* pMode) { return real_->GetAdapterDisplayMode(Adapter, pMode); }
HRESULT WrappedDirect3D9::CheckDeviceType(UINT Adapter, D3DDEVTYPE DevType, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, BOOL bWindowed) { return real_->CheckDeviceType(Adapter, DevType, AdapterFormat, BackBufferFormat, bWindowed); }
HRESULT WrappedDirect3D9::CheckDeviceFormat(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat) { return real_->CheckDeviceFormat(Adapter, DeviceType, AdapterFormat, Usage, RType, CheckFormat); }
HRESULT WrappedDirect3D9::CheckDeviceMultiSampleType(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat, BOOL Windowed, D3DMULTISAMPLE_TYPE MultiSampleType, DWORD* pQualityLevels) { return real_->CheckDeviceMultiSampleType(Adapter, DeviceType, SurfaceFormat, Windowed, MultiSampleType, pQualityLevels); }
HRESULT WrappedDirect3D9::CheckDepthStencilMatch(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, D3DFORMAT RenderTargetFormat, D3DFORMAT DepthStencilFormat) { return real_->CheckDepthStencilMatch(Adapter, DeviceType, AdapterFormat, RenderTargetFormat, DepthStencilFormat); }
HRESULT WrappedDirect3D9::CheckDeviceFormatConversion(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SourceFormat, D3DFORMAT TargetFormat) { return real_->CheckDeviceFormatConversion(Adapter, DeviceType, SourceFormat, TargetFormat); }
HRESULT WrappedDirect3D9::GetDeviceCaps(UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9* pCaps) { return real_->GetDeviceCaps(Adapter, DeviceType, pCaps); }
HMONITOR WrappedDirect3D9::GetAdapterMonitor(UINT Adapter) { return real_->GetAdapterMonitor(Adapter); }
HRESULT WrappedDirect3D9::CreateDevice(UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice9** ppReturnedDeviceInterface)
{
IDirect3DDevice9* real_device = nullptr;
const HRESULT hr = real_->CreateDevice(Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, &real_device);
if (FAILED(hr) || real_device == nullptr) {
if (ppReturnedDeviceInterface) *ppReturnedDeviceInterface = nullptr;
return hr;
}
const auto wrapped = WrapDevice<WrappedDirect3DDevice9>(real_device);
real_device->Release(); // the wrapper holds its own AddRef'd reference
*ppReturnedDeviceInterface = wrapped;
return hr;
}
// ---- WrappedDirect3D9Ex ---------------------------------------------------
WrappedDirect3D9Ex::WrappedDirect3D9Ex(IDirect3D9Ex* real) : real_(real), ref_count_(1)
{
real_->AddRef();
}
HRESULT WrappedDirect3D9Ex::QueryInterface(REFIID riid, void** ppvObj)
{
if (riid == IID_IUnknown || riid == IID_IDirect3D9 || riid == IID_IDirect3D9Ex) {
AddRef();
*ppvObj = this;
return S_OK;
}
// Unrecognized-but-successful QueryInterface hands back an unwrapped real pointer.
return real_->QueryInterface(riid, ppvObj);
}
ULONG WrappedDirect3D9Ex::AddRef()
{
return ++ref_count_;
}
ULONG WrappedDirect3D9Ex::Release()
{
const ULONG count = --ref_count_;
if (count == 0) {
real_->Release();
delete this;
return 0;
}
return count;
}
HRESULT WrappedDirect3D9Ex::RegisterSoftwareDevice(void* pInitializeFunction) { return real_->RegisterSoftwareDevice(pInitializeFunction); }
UINT WrappedDirect3D9Ex::GetAdapterCount() { return real_->GetAdapterCount(); }
HRESULT WrappedDirect3D9Ex::GetAdapterIdentifier(UINT Adapter, DWORD Flags, D3DADAPTER_IDENTIFIER9* pIdentifier) { return real_->GetAdapterIdentifier(Adapter, Flags, pIdentifier); }
UINT WrappedDirect3D9Ex::GetAdapterModeCount(UINT Adapter, D3DFORMAT Format) { return real_->GetAdapterModeCount(Adapter, Format); }
HRESULT WrappedDirect3D9Ex::EnumAdapterModes(UINT Adapter, D3DFORMAT Format, UINT Mode, D3DDISPLAYMODE* pMode) { return real_->EnumAdapterModes(Adapter, Format, Mode, pMode); }
HRESULT WrappedDirect3D9Ex::GetAdapterDisplayMode(UINT Adapter, D3DDISPLAYMODE* pMode) { return real_->GetAdapterDisplayMode(Adapter, pMode); }
HRESULT WrappedDirect3D9Ex::CheckDeviceType(UINT Adapter, D3DDEVTYPE DevType, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, BOOL bWindowed) { return real_->CheckDeviceType(Adapter, DevType, AdapterFormat, BackBufferFormat, bWindowed); }
HRESULT WrappedDirect3D9Ex::CheckDeviceFormat(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat) { return real_->CheckDeviceFormat(Adapter, DeviceType, AdapterFormat, Usage, RType, CheckFormat); }
HRESULT WrappedDirect3D9Ex::CheckDeviceMultiSampleType(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat, BOOL Windowed, D3DMULTISAMPLE_TYPE MultiSampleType, DWORD* pQualityLevels) { return real_->CheckDeviceMultiSampleType(Adapter, DeviceType, SurfaceFormat, Windowed, MultiSampleType, pQualityLevels); }
HRESULT WrappedDirect3D9Ex::CheckDepthStencilMatch(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, D3DFORMAT RenderTargetFormat, D3DFORMAT DepthStencilFormat) { return real_->CheckDepthStencilMatch(Adapter, DeviceType, AdapterFormat, RenderTargetFormat, DepthStencilFormat); }
HRESULT WrappedDirect3D9Ex::CheckDeviceFormatConversion(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SourceFormat, D3DFORMAT TargetFormat) { return real_->CheckDeviceFormatConversion(Adapter, DeviceType, SourceFormat, TargetFormat); }
HRESULT WrappedDirect3D9Ex::GetDeviceCaps(UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9* pCaps) { return real_->GetDeviceCaps(Adapter, DeviceType, pCaps); }
HMONITOR WrappedDirect3D9Ex::GetAdapterMonitor(UINT Adapter) { return real_->GetAdapterMonitor(Adapter); }
HRESULT WrappedDirect3D9Ex::CreateDevice(UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice9** ppReturnedDeviceInterface)
{
IDirect3DDevice9* real_device = nullptr;
const HRESULT hr = real_->CreateDevice(Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, &real_device);
if (FAILED(hr) || real_device == nullptr) {
if (ppReturnedDeviceInterface) *ppReturnedDeviceInterface = nullptr;
return hr;
}
const auto wrapped = WrapDevice<WrappedDirect3DDevice9>(real_device);
real_device->Release();
*ppReturnedDeviceInterface = wrapped;
return hr;
}
UINT WrappedDirect3D9Ex::GetAdapterModeCountEx(UINT Adapter, const D3DDISPLAYMODEFILTER* pFilter) { return real_->GetAdapterModeCountEx(Adapter, pFilter); }
HRESULT WrappedDirect3D9Ex::EnumAdapterModesEx(UINT Adapter, const D3DDISPLAYMODEFILTER* pFilter, UINT Mode, D3DDISPLAYMODEEX* pMode) { return real_->EnumAdapterModesEx(Adapter, pFilter, Mode, pMode); }
HRESULT WrappedDirect3D9Ex::GetAdapterDisplayModeEx(UINT Adapter, D3DDISPLAYMODEEX* pMode, D3DDISPLAYROTATION* pRotation) { return real_->GetAdapterDisplayModeEx(Adapter, pMode, pRotation); }
HRESULT WrappedDirect3D9Ex::CreateDeviceEx(UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, D3DDISPLAYMODEEX* pFullscreenDisplayMode, IDirect3DDevice9Ex** ppReturnedDeviceInterface)
{
IDirect3DDevice9Ex* real_device = nullptr;
const HRESULT hr = real_->CreateDeviceEx(Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, pFullscreenDisplayMode, &real_device);
if (FAILED(hr) || real_device == nullptr) {
if (ppReturnedDeviceInterface) *ppReturnedDeviceInterface = nullptr;
return hr;
}
const auto wrapped = WrapDevice<WrappedDirect3DDevice9Ex>(real_device);
real_device->Release();
*ppReturnedDeviceInterface = wrapped;
return hr;
}
HRESULT WrappedDirect3D9Ex::GetAdapterLUID(UINT Adapter, LUID* pLUID) { return real_->GetAdapterLUID(Adapter, pLUID); }
+6 -11
View File
@@ -2,7 +2,6 @@
#include <Psapi.h>
#include "MinHook.h"
#include "D3D9Hooks.h"
#include "D3D9Wrappers.h"
#include <atomic>
import TextureClient;
@@ -149,11 +148,9 @@ IDirect3D9* APIENTRY Direct3DCreate9(UINT SDKVersion)
creating_d3d9 = false;
// Hand the game a wrapper object instead of the real one: CreateDevice is intercepted
// via ordinary virtual dispatch, so nothing here is ever patched (see D3D9Wrappers.h).
const auto wrapped = new WrappedDirect3D9(pIDirect3D9_orig);
pIDirect3D9_orig->Release(); // the wrapper holds its own AddRef'd reference
return wrapped;
// Hook the vtable and hand the game back the real object untouched.
InstallD3D9Hooks(pIDirect3D9_orig, false);
return pIDirect3D9_orig;
}
HRESULT APIENTRY Direct3DCreate9Ex(UINT SDKVersion, IDirect3D9Ex** ppD3D)
@@ -175,11 +172,9 @@ HRESULT APIENTRY Direct3DCreate9Ex(UINT SDKVersion, IDirect3D9Ex** ppD3D)
if (ret != S_OK)
return ret;
// Hand the game a wrapper object instead of the real one: CreateDevice/CreateDeviceEx
// are intercepted via ordinary virtual dispatch, so nothing here is ever patched.
const auto wrapped = new WrappedDirect3D9Ex(pIDirect3D9Ex_orig);
pIDirect3D9Ex_orig->Release(); // the wrapper holds its own AddRef'd reference
*ppD3D = wrapped;
// Hook the vtable (CreateDevice + CreateDeviceEx) and return the real object untouched.
InstallD3D9Hooks(pIDirect3D9Ex_orig, true);
*ppD3D = pIDirect3D9Ex_orig;
return ret;
}