Guest User

Micah

a guest
Feb 13th, 2009
1,026
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.20 KB | None | 0 0
  1. using System;
  2. using System.Runtime.InteropServices;
  3.  
  4. namespace MyDirect3D9
  5. {
  6.     public unsafe class IDirect3D9 : IDisposable
  7.     {
  8.         // A pointer to the native IDirect3D9 object that we are providing overrides for.
  9.         public Win32.D3D9.IDirect3D9* NativeIDirect3D9
  10.         {
  11.             get;
  12.             private set;
  13.         }
  14.         // A pointer to the original array of virtual functions.  We keep this around so we can call the originals.
  15.         private IntPtr* OriginalVFTable = null;
  16.        
  17.         #region Construction
  18.         // For the case where we already have a native IDirect3D9 object and we want to override some of it's functions.
  19.         public unsafe IDirect3D9(Win32.D3D9.IDirect3D9* InNativeIDirect3D9)
  20.         {
  21.             NativeIDirect3D9 = InNativeIDirect3D9;
  22.            
  23.             // Override the functions in NativeIDirect3D9 with our own.
  24.             OverrideFunctions();
  25.         }
  26.        
  27.         // For the case where we don't have a native IDirect3D object so we want one created for us.
  28.         public IDirect3D9(ushort SdkVersion)
  29.         {
  30.             // Create the real IDirect3D9 object.
  31.             NativeIDirect3D9 = Win32.D3D9.Direct3DCreate9(SdkVersion);
  32.            
  33.             // Override the functions in NativeIDirect3D9 with our own.
  34.             OverrideFunctions();
  35.         }
  36.         #endregion
  37.        
  38.         #region Destruction
  39.         ~IDirect3D9()
  40.         {
  41.             Dispose(true);
  42.         }
  43.        
  44.         public void Dispose()
  45.         {
  46.             Dispose(false);
  47.         }
  48.        
  49.         // Cleanup resources.  Destructing == true means we are getting garbage collected so don't reference any managed resources.
  50.         private void Dispose(bool Destructing)
  51.         {
  52.             if (OriginalVFTable != null)
  53.             {
  54.                 Win32.Kernel32.HeapFree(Win32.Kernel32.GetProcessHeap(), 0, *OriginalVFTable);
  55.                 OriginalVFTable = null;
  56.             }
  57.         }
  58.         #endregion
  59.        
  60.         #region Virtual Function Table Management
  61.         // Backup the original native virtual function table and overwrite the pointer to it with our own (which is a copy of the original).
  62.         private void InitializeVFTable()
  63.         {
  64.             // If we don't have a real IDirect3D9 object yet then do nothing.
  65.             if (NativeIDirect3D9 == null) return;
  66.            
  67.             // Save off the original VFTable (only if it really is the original).
  68.             if (OriginalVFTable == null) OriginalVFTable = NativeIDirect3D9->VFTable;
  69.            
  70.             // IDirect3D9 has 17 members.
  71.             UInt32 VFTableLength = 17;
  72.             // Allocate space for our new VFTable.
  73.             IntPtr* NewVFTable = (IntPtr*)Win32.Kernel32.HeapAlloc(Win32.Kernel32.GetProcessHeap(), 0, (UIntPtr)(VFTableLength * sizeof(IntPtr)));
  74.            
  75.             // Copy all of the original function pointers into our new VFTable.
  76.             for (int i = 0; i < VFTableLength; i++)
  77.             {
  78.                 NewVFTable[i] = OriginalVFTable[i];
  79.             }
  80.            
  81.             // Set the Real IDirect3D9 implementation's VFTable to point at our custom one.
  82.             NativeIDirect3D9->VFTable = NewVFTable;
  83.         }
  84.        
  85.         // Reset the native virtual function table to point back at the original.
  86.         private void ResetVFTable()
  87.         {
  88.             // If the original table is not defined do nothing.
  89.             if (OriginalVFTable == null) return;
  90.             // If the original table points to the same place as the current one do nothing.
  91.             if (OriginalVFTable == NativeIDirect3D9->VFTable) return;
  92.             // Cleanup memory allocated for our custom VFTable.
  93.             Win32.Kernel32.HeapFree(Win32.Kernel32.GetProcessHeap(), 0, *NativeIDirect3D9->VFTable);
  94.             // Set the VFTable back to the original.
  95.             NativeIDirect3D9->VFTable = OriginalVFTable;
  96.             // Set the original VFTable back to null.
  97.             OriginalVFTable = null;
  98.         }
  99.        
  100.         private void OverrideFunctions()
  101.         {
  102.             InitializeVFTable();
  103.            
  104.             // #0: STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE;
  105.             // #1: STDMETHOD_(ULONG,AddRef)(THIS) PURE;
  106.             // #2: STDMETHOD_(ULONG,Release)(THIS) PURE;
  107.             // TODO: Override this and Dispose this object if it is going to return 0.
  108.             // #3: STDMETHOD(RegisterSoftwareDevice)(THIS_ void* pInitializeFunction) PURE;
  109.             // #4: STDMETHOD_(UINT, GetAdapterCount)(THIS) PURE;
  110.             DelegateGetAdapterCount MyAdapterCount = new DelegateGetAdapterCount(GetAdapterCount);
  111.             IntPtr PointerToMyAdapterCount = Marshal.GetFunctionPointerForDelegate(MyAdapterCount);
  112.             NativeIDirect3D9->VFTable[4] = PointerToMyAdapterCount;
  113.             // #5: STDMETHOD(GetAdapterIdentifier)(THIS_ UINT Adapter,DWORD Flags,D3DADAPTER_IDENTIFIER9* pIdentifier) PURE;
  114.             // #6: STDMETHOD_(UINT, GetAdapterModeCount)(THIS_ UINT Adapter,D3DFORMAT Format) PURE;
  115.             // #7: STDMETHOD(EnumAdapterModes)(THIS_ UINT Adapter,D3DFORMAT Format,UINT Mode,D3DDISPLAYMODE* pMode) PURE;
  116.             // #8: STDMETHOD(GetAdapterDisplayMode)(THIS_ UINT Adapter,D3DDISPLAYMODE* pMode) PURE;
  117.             // #9: STDMETHOD(CheckDeviceType)(THIS_ UINT Adapter,D3DDEVTYPE DevType,D3DFORMAT AdapterFormat,D3DFORMAT BackBufferFormat,BOOL bWindowed) PURE;
  118.             // #10: STDMETHOD(CheckDeviceFormat)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,DWORD Usage,D3DRESOURCETYPE RType,D3DFORMAT CheckFormat) PURE;
  119.             // #11: STDMETHOD(CheckDeviceMultiSampleType)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SurfaceFormat,BOOL Windowed,D3DMULTISAMPLE_TYPE MultiSampleType,DWORD* pQualityLevels) PURE;
  120.             // #12: STDMETHOD(CheckDepthStencilMatch)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,D3DFORMAT RenderTargetFormat,D3DFORMAT DepthStencilFormat) PURE;
  121.             // #13: STDMETHOD(CheckDeviceFormatConversion)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SourceFormat,D3DFORMAT TargetFormat) PURE;
  122.             // #14: STDMETHOD(GetDeviceCaps)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DCAPS9* pCaps) PURE;
  123.             // #15: STDMETHOD_(HMONITOR, GetAdapterMonitor)(THIS_ UINT Adapter) PURE;
  124.             // #16: STDMETHOD(CreateDevice)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,HWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DDevice9** ppReturnedDeviceInterface) PURE;
  125.         }
  126.         #endregion
  127.        
  128.         #region IDirect3D9 Interface Function Implementations
  129.         public delegate uint DelegateGetAdapterCount(Win32.D3D9.IDirect3D9* This);
  130.         public uint GetAdapterCount(Win32.D3D9.IDirect3D9* This)
  131.         {
  132.             DelegateGetAdapterCount RealGetAdapterCount = (DelegateGetAdapterCount)Marshal.GetDelegateForFunctionPointer(OriginalVFTable[4], typeof(DelegateGetAdapterCount));
  133.             uint AdapterCount = RealGetAdapterCount(This);
  134.             // TODO: Send the AdapterCount to the profiling application via remoting.
  135.             return AdapterCount;
  136.         }
  137.         #endregion
  138.     }
  139. }
Advertisement
Add Comment
Please, Sign In to add comment