mirror of
https://github.com/gwdevhub/gMod.git
synced 2026-07-21 01:49:31 +00:00
2b2a817c15
CreateDevice(Ex)/CreateTexture/CreateVolumeTexture/CreateCubeTexture/ UpdateTexture/BeginScene/SetTexture/GetTexture/Release are now intercepted via ordinary compiled virtual dispatch on wrapper objects returned from Direct3DCreate9(Ex), instead of MinHook patching the real object's vtable slots. Nothing is ever patched in this path, so it sidesteps every self-modifying-code/JIT-cache concern the ARM64 emulator (Windows-on-ARM's xtajit, or Wine on FEX-Emu/box64) has with inline code patching. The late-attach path (SetDevice/RegisterExistingDevice/D3D9Hooks.cpp) is unchanged: wrapping only works when gMod controls object creation from the start, so late-attach still needs MinHook and remains gated off under ARM64 emulation.
70 lines
4.9 KiB
C++
70 lines
4.9 KiB
C++
#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_;
|
|
};
|