mirror of
https://github.com/gwdevhub/gMod.git
synced 2026-07-15 23:19:30 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2705ceda7b | |||
| 2b2a817c15 | |||
| 9b809519f8 | |||
| c57a527b68 |
@@ -0,0 +1,2 @@
|
||||
# Shell scripts must stay LF or bash on the CI runner chokes on \r.
|
||||
*.sh text eol=lf
|
||||
@@ -0,0 +1,28 @@
|
||||
# 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."
|
||||
@@ -0,0 +1,245 @@
|
||||
# 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
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
#!/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."
|
||||
@@ -0,0 +1,66 @@
|
||||
# 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."
|
||||
@@ -16,9 +16,15 @@ 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
|
||||
@@ -46,7 +52,28 @@ 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
@@ -10,9 +10,9 @@ if(NOT(CMAKE_SIZEOF_VOID_P EQUAL 4))
|
||||
endif()
|
||||
|
||||
set(VERSION_MAJOR 1)
|
||||
set(VERSION_MINOR 9)
|
||||
set(VERSION_MINOR 10)
|
||||
set(VERSION_PATCH 0)
|
||||
set(VERSION_TWEAK 3)
|
||||
set(VERSION_TWEAK 0)
|
||||
|
||||
set(VERSION_RC "${CMAKE_CURRENT_BINARY_DIR}/version.rc")
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/version.rc.in" "${VERSION_RC}" @ONLY)
|
||||
|
||||
@@ -0,0 +1,305 @@
|
||||
#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();
|
||||
};
|
||||
@@ -0,0 +1,127 @@
|
||||
#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);
|
||||
@@ -0,0 +1,69 @@
|
||||
#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_;
|
||||
};
|
||||
@@ -0,0 +1,536 @@
|
||||
#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); }
|
||||
@@ -357,6 +357,11 @@ 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
|
||||
|
||||
@@ -0,0 +1,212 @@
|
||||
#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); }
|
||||
@@ -0,0 +1,166 @@
|
||||
#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); }
|
||||
+11
-6
@@ -2,6 +2,7 @@
|
||||
#include <Psapi.h>
|
||||
#include "MinHook.h"
|
||||
#include "D3D9Hooks.h"
|
||||
#include "D3D9Wrappers.h"
|
||||
#include <atomic>
|
||||
|
||||
import TextureClient;
|
||||
@@ -148,9 +149,11 @@ IDirect3D9* APIENTRY Direct3DCreate9(UINT SDKVersion)
|
||||
|
||||
creating_d3d9 = false;
|
||||
|
||||
// Hook the vtable and hand the game back the real object untouched.
|
||||
InstallD3D9Hooks(pIDirect3D9_orig, false);
|
||||
return pIDirect3D9_orig;
|
||||
// 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;
|
||||
}
|
||||
|
||||
HRESULT APIENTRY Direct3DCreate9Ex(UINT SDKVersion, IDirect3D9Ex** ppD3D)
|
||||
@@ -172,9 +175,11 @@ HRESULT APIENTRY Direct3DCreate9Ex(UINT SDKVersion, IDirect3D9Ex** ppD3D)
|
||||
if (ret != S_OK)
|
||||
return ret;
|
||||
|
||||
// Hook the vtable (CreateDevice + CreateDeviceEx) and return the real object untouched.
|
||||
InstallD3D9Hooks(pIDirect3D9Ex_orig, true);
|
||||
*ppD3D = pIDirect3D9Ex_orig;
|
||||
// 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;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user