// CED3D10Hook.cpp : Defines the exported functions for the DLL application. // #include "stdafx.h" using namespace std; map D3D10devices; PD3DHookShared shared=NULL; int insidehook=0; DXMessD3D10Handler *lastdevice; BOOL makeSnapshot=FALSE; //duplicate variable to be used as a hint that one of the devices is making a snapshot. (in case of multiple devices) //definitions struct SpriteVertex{ XMFLOAT3 Pos; XMFLOAT2 Tex; }; struct ConstantBuffer { D3DXMATRIX rotation; XMFLOAT2 originpoint; XMFLOAT2 translation; XMFLOAT2 scaling; FLOAT transparency; FLOAT garbage; //16 byte alignment crap }; void DXMessD3D10Handler::PrepareForSnapshot() //just clears the screen { if (!shared->progressiveSnapshot) //if this is true no erasing will be done { ID3D10RenderTargetView *currentrt=NULL; ID3D10DepthStencilView* currentds=NULL; FLOAT f[]={1.0f,0.0f,1.0f,1.0f}; if (!shared->alsoClearDepthBuffer) dev->OMGetRenderTargets(1, ¤trt, NULL); else dev->OMGetRenderTargets(1, ¤trt, ¤tds); if (currentrt) { dev->ClearRenderTargetView(currentrt, f); currentrt->Release(); } if (currentds) { dev->ClearDepthStencilView(currentds, D3D10_CLEAR_DEPTH, 1.0, 0); currentds->Release(); } } } void DXMessD3D10Handler::TakeSnapshot(char *functionname) { //alternate if only the backbuffer is requested : ID3D10Texture2D *backbuffer=NULL; if (SUCCEEDED(swapchain->GetBuffer(0, __uuidof(backbuffer), (void **)&backbuffer))) //problem is that that won't capture renders to textures. //Problem with capturing texture renders is that mouse coordinates are useless then ID3D10RenderTargetView *currentrt=NULL ; if (makeSnapshot) { dev->OMGetRenderTargets(1, ¤trt, NULL); if (currentrt) { ID3D10Texture2D *backbuffer=NULL; D3D10_TEXTURE2D_DESC texDesc; D3D10_RENDER_TARGET_VIEW_DESC backbufferdesc; ID3D10Resource *r=NULL; currentrt->GetDesc(&backbufferdesc); texDesc.Format=backbufferdesc.Format; currentrt->GetResource(&r); if (r) { BOOL isMultiSampled=FALSE; if (SUCCEEDED(r->QueryInterface(__uuidof(ID3D10Texture2D), (void **)&backbuffer))) { backbuffer->GetDesc(&texDesc); isMultiSampled=texDesc.SampleDesc.Count>1; texDesc.SampleDesc.Count=1; texDesc.SampleDesc.Quality=0; if (smallSnapshot && (isMultiSampled==FALSE)) { texDesc.BindFlags = 0; texDesc.CPUAccessFlags = D3D10_CPU_ACCESS_READ; texDesc.Usage = D3D10_USAGE_STAGING; } else { texDesc.CPUAccessFlags = 0; texDesc.Usage = D3D10_USAGE_DEFAULT; } ID3D10Texture2D *texture; if (SUCCEEDED(dev->CreateTexture2D(&texDesc, 0, &texture))) { BOOL savethis=FALSE; if (isMultiSampled) { dev->ResolveSubresource(texture, 0, r, 0, texDesc.Format); if (smallSnapshot) { ID3D10Texture2D *texture2; //temp storage for the new texture texDesc.BindFlags = 0; texDesc.CPUAccessFlags = D3D10_CPU_ACCESS_READ; texDesc.Usage = D3D10_USAGE_STAGING; if (SUCCEEDED(dev->CreateTexture2D(&texDesc, 0, &texture2))) { dev->CopyResource(texture2, texture); texture->Release(); //release the old one texture=texture2; } } } else dev->CopyResource(texture, r); if (smallSnapshot) { D3D10_MAPPED_TEXTURE2D mappedtexture; if (SUCCEEDED(texture->Map(0, D3D10_MAP_READ, 0, &mappedtexture))) { DWORD *color; int xpos, ypos; xpos=(int)floor(texDesc.Width * smallSnapshotPointRelative.x); ypos=(int)floor(texDesc.Height * smallSnapshotPointRelative.y); //check if the pixel at xpos,ypos is not 0xffff00ff color=(DWORD *)((UINT_PTR)mappedtexture.pData+mappedtexture.RowPitch*ypos+xpos*4); if ((*color & 0xffffff)!=0xff00ff) //pixels got changed savethis=TRUE; texture->Unmap(0); } } else savethis=TRUE; if (savethis) { char s[MAX_PATH]; HANDLE h; DWORD bw; int x; UINT64 stackbase=0; #ifdef _AMD64_ stackbase=(UINT64)&functionname; #else __asm { mov dword ptr [stackbase], ebp //sure, it's a bit too far, but close enough } #endif snapshotCounter++; sprintf_s(s, MAX_PATH, "%ssnapshot%d.ce3dsnapshot", shared->SnapShotDir, snapshotCounter); LPD3D10BLOB dest; h=CreateFileA(s, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); x=10; //dx10 WriteFile(h, &x, sizeof(x), &bw, NULL); if (shared->savePNGSeperateAsWell) { switch (shared->snapshotImageFormat) { case 0: strcat_s(s,MAX_PATH, ".BMP"); break; case 1: strcat_s(s,MAX_PATH, ".JPG"); break; case 3: strcat_s(s,MAX_PATH, ".PNG"); break; default: strcat_s(s,MAX_PATH, ".WTF"); break; } D3DX10SaveTextureToFileA(texture, (D3DX10_IMAGE_FILE_FORMAT)shared->snapshotImageFormat, s); } if (SUCCEEDED(D3DX10SaveTextureToMemory(texture, (D3DX10_IMAGE_FILE_FORMAT)shared->snapshotImageFormat, &dest, 0))) //weird. PNG has some information loss on certain things like text { x=shared->snapshotImageFormat; WriteFile(h, &x, sizeof(x), &bw, NULL); x=dest->GetBufferSize(); WriteFile(h, &x, sizeof(x), &bw, NULL); WriteFile(h, dest->GetBufferPointer(), x, &bw, NULL); dest->Release(); } else { x=0; WriteFile(h, &x, sizeof(x), &bw, NULL); WriteFile(h, &x, sizeof(x), &bw, NULL); } WriteFile(h, &stackbase, sizeof(stackbase), &bw, NULL); MEMORY_BASIC_INFORMATION mbi; int stacksize; if (VirtualQuery((void *)stackbase, &mbi, sizeof(mbi))==sizeof(mbi)) { stacksize=min(mbi.RegionSize- ((uintptr_t)stackbase-(uintptr_t)mbi.BaseAddress), 8192); WriteFile(h, &stacksize, sizeof(stacksize), &bw, NULL); WriteFile(h, (void *)stackbase, stacksize, &bw, NULL); } else { stacksize=0; stackbase=0; WriteFile(h, &stacksize, sizeof(stacksize), &bw, NULL); } ID3D10Buffer* c=NULL; //save the VS Constant buffers dev->VSGetConstantBuffers(0, 1, &c); int nocb=1; //if getting the constantbuffers fail this notifies that it has a length of 0 if (c) { ID3D10Buffer* c2=NULL; D3D10_BUFFER_DESC desc; c->GetDesc(&desc); desc.CPUAccessFlags=D3D10_CPU_ACCESS_READ; desc.BindFlags=0; desc.Usage=D3D10_USAGE_STAGING; dev->CreateBuffer(&desc, NULL, &c2); if (c2) { unsigned char *buf; dev->CopyResource(c2, c); if (SUCCEEDED(c2->Map(D3D10_MAP_READ, 0, (void **)&buf))) { int i=desc.ByteWidth; WriteFile(h, &i, sizeof(i), &bw, NULL); WriteFile(h, buf, desc.ByteWidth, &bw, NULL); nocb=0; c2->Unmap(); } c2->Release(); } c->Release(); } if (nocb) { int i=0; WriteFile(h, &i, sizeof(i), &bw, NULL); } if (functionname) { int i=strlen(functionname); WriteFile(h, &i, sizeof(i), &bw, NULL); WriteFile(h, functionname, i, &bw, NULL); } CloseHandle(h); } texture->Release(); } backbuffer->Release(); } r->Release(); } currentrt->Release(); } } } void DXMessD3D10Handler::SetupFontVertexBuffer(int count) { if (currentMaxCharacterCountRelease(); pFontVB=NULL; } ZeroMemory( &bd2d, sizeof(bd2d) ); bd2d.Usage = D3D10_USAGE_DYNAMIC; bd2d.ByteWidth = sizeof( SpriteVertex ) * 6 * count; //size of a vertex*verticel per char*charcount bd2d.BindFlags = D3D10_BIND_VERTEX_BUFFER; bd2d.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; hr = dev->CreateBuffer( &bd2d, NULL, &pFontVB ); if (SUCCEEDED(hr)) { currentMaxCharacterCount=count; } } } void DXMessD3D10Handler::DrawString(D3D10_VIEWPORT vp, PTextureData10 pFontTexture, char *s, int strlen) { if (pFontTexture) { if (strlen==0) return; SetupFontVertexBuffer(strlen); if (currentMaxCharacterCountDefinedFontMap->charheight*2) / vp.Height; float fRectLeft = 0; float fRectTop = 1.0f; fRectLeft = fRectLeft * 2.0f - 1.0f; fRectTop = fRectTop * 2.0f - 1.0f; float fOriginalLeft = fRectLeft; //0*2.0f-1.0f=-1.0f float fTexTop = 0.0f; float fTexBottom = 1.0f; //fill the FontVB with the sizes and texture coordinates SpriteVertex *vertices; if (SUCCEEDED(pFontVB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void **)&vertices))) { int i,j; for (j=0, i=0; i 127)) continue;//invalid char float fGlyphSizeX = (pFontTexture->DefinedFontMap->charinfo[s[i]-32].charwidth*2) / vp.Width; float fCharTexSizeX = pFontTexture->DefinedFontMap->charinfo[s[i]-32].charwidth / (pFontTexture->DefinedFontMap->fullwidth); //0.010526315f; float fRectRight = fRectLeft + fGlyphSizeX; float fRectBottom = fRectTop - fGlyphSizeY; float fTexLeft = pFontTexture->DefinedFontMap->charinfo[s[i]-32].offset / pFontTexture->DefinedFontMap->fullwidth; float fTexRight = fTexLeft + fCharTexSizeX; vertices[j*6+0].Pos=XMFLOAT3( fRectLeft, fRectTop, 1.0f ); vertices[j*6+0].Tex=XMFLOAT2( fTexLeft, fTexTop ); vertices[j*6+1].Pos=XMFLOAT3( fRectRight, fRectTop, 1.0f ); vertices[j*6+1].Tex=XMFLOAT2( fTexRight, fTexTop ); vertices[j*6+2].Pos=XMFLOAT3( fRectLeft, fRectBottom, 1.0f ); vertices[j*6+2].Tex=XMFLOAT2( fTexLeft, fTexBottom ); vertices[j*6+3].Pos=XMFLOAT3( fRectRight, fRectTop, 1.0f); vertices[j*6+3].Tex=XMFLOAT2( fTexRight, fTexTop ); vertices[j*6+4].Pos=XMFLOAT3( fRectRight, fRectBottom, 1.0f); vertices[j*6+4].Tex=XMFLOAT2( fTexRight, fTexBottom ); vertices[j*6+5].Pos=XMFLOAT3( fRectLeft, fRectBottom, 1.0f); vertices[j*6+5].Tex=XMFLOAT2( fTexLeft, fTexBottom ); j++; fRectLeft += fGlyphSizeX; } pFontVB->Unmap(); } //then render UINT stride = sizeof( SpriteVertex ); UINT offset = 0; dev->IASetVertexBuffers( 0, 1, &pFontVB, &stride, &offset ); dev->PSSetShaderResources( 0, 1, &pFontTexture->pTexture ); dev->Draw(6*strlen,0); } } BOOL DXMessD3D10Handler::UpdateTextures() { //call this each time the resolution changes (when the buffer changes) HRESULT hr; ID3D10Resource *test; ID3D10Texture2D *texturex; DXGI_SWAP_CHAIN_DESC desc; int i; int newTextureCount; WaitForSingleObject((HANDLE)(shared->TextureLock), INFINITE); if (shared->textureCount) { ZeroMemory(&desc, sizeof(desc)); hr=swapchain->GetDesc(&desc); if (FAILED(hr)) return hr; newTextureCount=shared->textureCount; if (shared->textureCount > TextureCount) { //update the textures if needed if (textures==NULL) //initial alloc textures=(TextureData10 *)malloc(sizeof(TextureData10)* shared->textureCount); else //realloc textures=(TextureData10 *)realloc(textures, sizeof(TextureData10)* shared->textureCount); //initialize the new entries to NULL for (i=TextureCount; itextureCount; i++) { textures[i].pTexture=NULL; textures[i].DefinedFontMap=NULL; } } for (i=0; iRelease(); textures[i].pTexture=NULL; //should always happen } if (textures[i].DefinedFontMap) { //already has a fontmap. Free the old one free(textures[i].DefinedFontMap); textures[i].DefinedFontMap=NULL; } hr=D3DX10CreateTextureFromMemory(dev, (void *)(tea[i].AddressOfTexture), tea[i].size, NULL, NULL, &test, NULL); if( FAILED( hr ) ) { OutputDebugStringA("Failure creating a texture"); return hr; } hr=test->QueryInterface(__uuidof(ID3D10Texture2D), (void **)(&texturex)); hr=dev->CreateShaderResourceView(test, NULL, &textures[i].pTexture); if( FAILED( hr ) ) return hr; test->Release(); texturex->Release(); if (tea[i].AddressOfFontmap) { int j; float currentOffset=0; textures[i].DefinedFontMap=(PFONTMAP)malloc(sizeof(FONTMAP)); //now parse the fontmap provided by ce and fill in the gaps WORD *cefontmap=(WORD *)(tea[i].AddressOfFontmap); textures[i].DefinedFontMap->charheight=(float)cefontmap[0]; for (j=0; j<96; j++) { textures[i].DefinedFontMap->charinfo[j].offset=currentOffset; textures[i].DefinedFontMap->charinfo[j].charwidth=(float)cefontmap[j+1]; currentOffset+=cefontmap[j+1]; } textures[i].DefinedFontMap->fullwidth=currentOffset; } tea[i].hasBeenUpdated=0; } } else { //It's NULL (cleanup) if (textures[i].pTexture) { textures[i].pTexture->Release(); textures[i].pTexture=NULL; } if (textures[i].DefinedFontMap) { free(textures[i].DefinedFontMap); textures[i].DefinedFontMap=NULL; } } } TextureCount=newTextureCount; } if (shared->texturelistHasUpdate) InterlockedExchange((volatile LONG *)&shared->texturelistHasUpdate,0); SetEvent((HANDLE)(shared->TextureLock)); return TRUE; } DXMessD3D10Handler::~DXMessD3D10Handler() { if (textures) { int i; for (i=0; iRelease(); } free(textures); } if (pFontVB) pFontVB->Release(); if (pSpriteVB) pSpriteVB->Release(); if (pPixelShaderNormal) pPixelShaderNormal->Release(); if (pVertexShader) pVertexShader->Release(); if (pVertexLayout) pVertexLayout->Release(); if (pSamplerLinear) pSamplerLinear->Release(); if (pSpriteRasterizer) pSpriteRasterizer->Release(); if (pTransparency) pTransparency->Release(); if (pDepthStencil) pDepthStencil->Release(); if (pRenderTargetView) pRenderTargetView->Release(); if (pDepthStencilView) pDepthStencilView->Release(); if (pConstantBuffer) pConstantBuffer->Release(); if (pWireframeRasterizer) pWireframeRasterizer->Release(); if (pDisabledDepthStencilState) pDisabledDepthStencilState->Release(); if (dev) dev->Release(); if (swapchain) swapchain->Release(); } DXMessD3D10Handler::DXMessD3D10Handler(ID3D10Device *dev, IDXGISwapChain *sc, PD3DHookShared shared) { HRESULT hr; int i; snapshotCounter=0; lastSnapshot=0; makeSnapshot=FALSE; smallSnapshot=FALSE; pPixelShaderNormal=NULL; pVertexShader=NULL; pVertexLayout=NULL; pSamplerLinear=NULL; pSpriteRasterizer=NULL; pTransparency=NULL; pDepthStencil=NULL; pRenderTargetView=NULL; pDepthStencilView=NULL; pConstantBuffer=NULL; pWireframeRasterizer=NULL; pDisabledDepthStencilState=NULL; pSpriteVB=NULL; pFontVB=NULL; TextureCount=0; textures=NULL; tea=NULL; Valid=FALSE; this->shared=shared; this->dev=dev; this->dev->AddRef(); this->swapchain=sc; this->swapchain->AddRef(); //create the shaders ID3DBlob* pBlob = NULL; ID3DBlob* pErrorBlob = NULL; char shaderfile[MAX_PATH]; sprintf_s(shaderfile,MAX_PATH, "%s%s", shared->CheatEngineDir,"overlay.fx"); //normal pixel shader pBlob = NULL; pErrorBlob = NULL; hr=D3DX10CompileFromFileA( shaderfile, NULL, NULL, "PSNormal", "ps_4_0", D3DCOMPILE_ENABLE_STRICTNESS, 0, NULL, &pBlob, &pErrorBlob, NULL ); if (pErrorBlob) { OutputDebugStringA((LPCSTR)pErrorBlob->GetBufferPointer()); pErrorBlob->Release(); } if( FAILED( hr ) ) { OutputDebugStringA("pixelshader compilation failed\n"); return; } hr = dev->CreatePixelShader( pBlob->GetBufferPointer(), pBlob->GetBufferSize(), &pPixelShaderNormal ); pBlob->Release(); if( FAILED( hr ) ) { OutputDebugStringA("CreatePixelShader failed\n"); return; } //vertex shader pBlob = NULL; pErrorBlob = NULL; hr=D3DX10CompileFromFileA( shaderfile, NULL, NULL, "VS", "vs_4_0", D3DCOMPILE_ENABLE_STRICTNESS, 0, NULL, &pBlob, &pErrorBlob, NULL ); if (pErrorBlob) { OutputDebugStringA((LPCSTR)pErrorBlob->GetBufferPointer()); pErrorBlob->Release(); } if( FAILED( hr ) ) { OutputDebugStringA("vertexshader compilation failed\n"); return; } hr = dev->CreateVertexShader( pBlob->GetBufferPointer(), pBlob->GetBufferSize(), &pVertexShader ); if( FAILED( hr ) ) { pBlob->Release(); OutputDebugStringA("CreatePixelShader failed\n"); return; } //and create a input layout D3D10_INPUT_ELEMENT_DESC layout[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0 }, }; UINT numElements = ARRAYSIZE( layout ); // Create the input layout hr = dev->CreateInputLayout( layout, numElements, pBlob->GetBufferPointer(), pBlob->GetBufferSize(), &pVertexLayout ); pBlob->Release(); //create rectangular vertex buffer for sprites SpriteVertex spriteVertices[] ={ {XMFLOAT3( 1.0f, 1.0f, 1.0f), XMFLOAT2( 1.0f, 0.0f ) }, {XMFLOAT3( 1.0f, -1.0f, 1.0f), XMFLOAT2( 1.0f, 1.0f )}, {XMFLOAT3(-1.0f, -1.0f, 1.0f), XMFLOAT2( 0.0f, 1.0f )}, {XMFLOAT3(-1.0f, -1.0f, 1.0f), XMFLOAT2( 0.0f, 1.0f )}, {XMFLOAT3(-1.0f, 1.0f, 1.0f), XMFLOAT2( 0.0f, 0.0f )}, {XMFLOAT3( 1.0f, 1.0f, 1.0f), XMFLOAT2( 1.0f, 0.0f )}, }; D3D10_BUFFER_DESC bd2d; ZeroMemory( &bd2d, sizeof(bd2d) ); bd2d.Usage = D3D10_USAGE_DYNAMIC; bd2d.ByteWidth = sizeof( SpriteVertex ) * 6; bd2d.BindFlags = D3D10_BIND_VERTEX_BUFFER; bd2d.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; D3D10_SUBRESOURCE_DATA InitData2d; ZeroMemory( &InitData2d, sizeof(InitData2d) ); InitData2d.pSysMem = spriteVertices; hr = dev->CreateBuffer( &bd2d, &InitData2d, &pSpriteVB ); if( FAILED( hr ) ) { OutputDebugStringA("Vertexbuffer creation failed\n"); return; } D3D10_SAMPLER_DESC sampDesc; ZeroMemory( &sampDesc, sizeof(sampDesc) ); sampDesc.Filter = D3D10_FILTER_MIN_MAG_MIP_LINEAR; sampDesc.AddressU = D3D10_TEXTURE_ADDRESS_WRAP; sampDesc.AddressV = D3D10_TEXTURE_ADDRESS_WRAP; sampDesc.AddressW = D3D10_TEXTURE_ADDRESS_WRAP; sampDesc.ComparisonFunc = D3D10_COMPARISON_NEVER; sampDesc.MinLOD = 0; sampDesc.MaxLOD = D3D10_FLOAT32_MAX; hr = dev->CreateSamplerState( &sampDesc, &pSamplerLinear ); if( FAILED( hr ) ) return; //rasterizer D3D10_RASTERIZER_DESC rasterizerdesc; ZeroMemory(&rasterizerdesc, sizeof(rasterizerdesc)); rasterizerdesc.FillMode = D3D10_FILL_SOLID; rasterizerdesc.CullMode = D3D10_CULL_NONE; rasterizerdesc.FrontCounterClockwise = false; rasterizerdesc.DepthBias = 0; rasterizerdesc.DepthBiasClamp = 0.0f; rasterizerdesc.DepthClipEnable = false; rasterizerdesc.AntialiasedLineEnable = false; rasterizerdesc.MultisampleEnable = false; rasterizerdesc.ScissorEnable = false; rasterizerdesc.SlopeScaledDepthBias = 0.0f; hr=dev->CreateRasterizerState(&rasterizerdesc, &pSpriteRasterizer); if( FAILED( hr ) ) return; rasterizerdesc.FillMode = D3D10_FILL_WIREFRAME; hr=dev->CreateRasterizerState(&rasterizerdesc, &pWireframeRasterizer); if( FAILED( hr ) ) pWireframeRasterizer=NULL; //no biggie D3D10_DEPTH_STENCIL_DESC dsDesc; ZeroMemory(&dsDesc, sizeof(dsDesc)); //everything 0, including DepthEnable hr= dev->CreateDepthStencilState(&dsDesc, &pDisabledDepthStencilState); if( FAILED( hr ) ) pDisabledDepthStencilState=NULL; D3D10_BLEND_DESC blend; ZeroMemory( &blend, sizeof(blend) ); blend.BlendEnable[0] = true; blend.SrcBlend = D3D10_BLEND_SRC_ALPHA ; blend.DestBlend = D3D10_BLEND_INV_SRC_ALPHA; blend.BlendOp = D3D10_BLEND_OP_ADD; blend.SrcBlendAlpha = D3D10_BLEND_SRC_ALPHA; blend.DestBlendAlpha = D3D10_BLEND_INV_SRC_ALPHA; blend.BlendOpAlpha = D3D10_BLEND_OP_ADD; blend.RenderTargetWriteMask[0] = D3D10_COLOR_WRITE_ENABLE_ALL; blend.AlphaToCoverageEnable=false; for (i=0; i<8; i++) blend.RenderTargetWriteMask[i]=D3D10_COLOR_WRITE_ENABLE_ALL; pTransparency=NULL; hr=dev->CreateBlendState(&blend, &pTransparency); if( FAILED( hr ) ) return; //create a rendertarget (I doubt this is needed) ID3D10Texture2D* pBackBuffer = NULL; hr = sc->GetBuffer( 0, __uuidof( ID3D10Texture2D ), ( LPVOID* )&pBackBuffer ); if( FAILED( hr ) ) return; hr = dev->CreateRenderTargetView( pBackBuffer, NULL, &pRenderTargetView ); pBackBuffer->Release(); if( FAILED( hr ) ) return; DXGI_SWAP_CHAIN_DESC scdesc; ZeroMemory(&scdesc,sizeof(scdesc)); sc->GetDesc(&scdesc); // Create depth stencil texture D3D10_TEXTURE2D_DESC descDepth; ZeroMemory( &descDepth, sizeof(descDepth) ); descDepth.Width = scdesc.BufferDesc.Width; descDepth.Height = scdesc.BufferDesc.Height; descDepth.MipLevels = 1; descDepth.ArraySize = 1; descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; descDepth.SampleDesc.Count = 1; descDepth.SampleDesc.Quality = 0; descDepth.Usage = D3D10_USAGE_DEFAULT; descDepth.BindFlags = D3D10_BIND_DEPTH_STENCIL; descDepth.CPUAccessFlags = 0; descDepth.MiscFlags = 0; hr = dev->CreateTexture2D( &descDepth, NULL, &pDepthStencil ); if( FAILED( hr ) ) return; // Create the depth stencil view D3D10_DEPTH_STENCIL_VIEW_DESC descDSV; ZeroMemory( &descDSV, sizeof(descDSV) ); descDSV.Format = descDepth.Format; descDSV.ViewDimension = D3D10_DSV_DIMENSION_TEXTURE2D; descDSV.Texture2D.MipSlice = 0; hr = dev->CreateDepthStencilView( pDepthStencil, &descDSV, &pDepthStencilView ); if( FAILED( hr ) ) return; //now load the textures tea=(PTextureEntry)((uintptr_t)shared+shared->texturelist); UpdateTextures(); // Create the constant buffer D3D10_BUFFER_DESC bd; ZeroMemory(&bd, sizeof(bd)); bd.Usage = D3D10_USAGE_DEFAULT; bd.ByteWidth = sizeof(ConstantBuffer); bd.BindFlags = D3D10_BIND_CONSTANT_BUFFER; bd.CPUAccessFlags = 0; hr = dev->CreateBuffer( &bd, NULL, &pConstantBuffer ); if( FAILED( hr ) ) return; //create a vertexbuffer to hold the characters currentMaxCharacterCount=0; SetupFontVertexBuffer(32); //init to 32 chars Valid=TRUE; } void DXMessD3D10Handler::RenderOverlay() { int i; if (Valid) { //render the overlay POINT clientMousepos; BOOL hasLock=FALSE; clientMousepos.x=-1; clientMousepos.y=-1; //check if the overlay has an update //if so, first update the texture DXGI_SWAP_CHAIN_DESC desc; swapchain->GetDesc(&desc); shared->lastHwnd=(DWORD)desc.OutputWindow; if (shared->texturelistHasUpdate) UpdateTextures(); UINT stride = sizeof( SpriteVertex ); UINT offset = 0; float blendFactor[] = {0.0f, 0.0f, 0.0f, 0.0f}; ID3D10VertexShader *oldvs=NULL; ID3D10PixelShader *oldps=NULL; ID3D10GeometryShader *oldgs=NULL; ID3D10SamplerState *oldPSSampler=NULL; ID3D10ShaderResourceView *oldPSShaderResource=NULL; ID3D10BlendState *oldBlendState=NULL; float oldblendFactor[4]; UINT oldblendsamplemask; ID3D10DepthStencilState *oldDepthStencilState=NULL; UINT oldstencilref; D3D10_PRIMITIVE_TOPOLOGY oldPrimitiveTopology; ID3D10InputLayout *oldInputLayout=NULL; ID3D10Buffer *oldIndexBuffer=NULL; DXGI_FORMAT oldIndexBufferFormat; UINT oldIndexBufferOffset; ID3D10Buffer *oldVertexBuffer=NULL; UINT oldVertexBufferStrides; UINT oldVertexBufferOffset; ID3D10RasterizerState *oldRastersizerState=NULL; ID3D10RenderTargetView *oldRenderTarget; ID3D10DepthStencilView *oldDepthStencilView=NULL; ID3D10Buffer *oldConstantBuffersVS=NULL; ID3D10Buffer *oldConstantBuffersPS=NULL; D3D10_VIEWPORT vp; UINT oldviewports=0; D3D10_VIEWPORT viewports[D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; //save state dev->VSGetShader( &oldvs); dev->VSGetConstantBuffers(0,1, &oldConstantBuffersVS); dev->GSGetShader(&oldgs); dev->PSGetShader( &oldps); dev->PSGetSamplers(0,1, &oldPSSampler); dev->PSGetShaderResources(0,1, &oldPSShaderResource); dev->PSGetConstantBuffers(0,1, &oldConstantBuffersPS); dev->OMGetRenderTargets(1, &oldRenderTarget, &oldDepthStencilView); dev->OMGetBlendState( &oldBlendState, oldblendFactor, &oldblendsamplemask); dev->OMGetDepthStencilState( &oldDepthStencilState, &oldstencilref); dev->IAGetPrimitiveTopology(&oldPrimitiveTopology); dev->IAGetInputLayout(&oldInputLayout); dev->IAGetIndexBuffer( &oldIndexBuffer, &oldIndexBufferFormat, &oldIndexBufferOffset); dev->IAGetVertexBuffers(0,1,&oldVertexBuffer, &oldVertexBufferStrides, &oldVertexBufferOffset); dev->RSGetState(&oldRastersizerState); dev->RSGetViewports(&oldviewports, NULL); dev->RSGetViewports(&oldviewports, viewports); //change state dev->GSSetShader(NULL); //not used dev->VSSetShader(pVertexShader); dev->PSSetShader(pPixelShaderNormal); dev->PSSetSamplers( 0, 1, &pSamplerLinear ); vp.Width = desc.BufferDesc.Width; vp.Height = desc.BufferDesc.Height; vp.MinDepth = 0.0f; vp.MaxDepth = 1.0f; vp.TopLeftX = 0; vp.TopLeftY = 0; dev->RSSetViewports( 1, &vp ); dev->OMSetRenderTargets(1, &pRenderTargetView, NULL); //pDepthStencilView); dev->ClearDepthStencilView( pDepthStencilView, D3D10_CLEAR_DEPTH, 1.0f, 0 ); dev->OMSetBlendState(pTransparency, blendFactor, 0xffffffff); dev->OMSetDepthStencilState(pDisabledDepthStencilState, 0);; dev->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); dev->IASetInputLayout( pVertexLayout ); // dev->IASetIndexBuffer( pSpriteIB, DXGI_FORMAT_R16_UINT, 0 ); dev->IASetIndexBuffer( NULL, DXGI_FORMAT_R16_UINT, 0 ); dev->RSSetState(pSpriteRasterizer); if (shared->UseCommandlistLock) hasLock=WaitForSingleObject((HANDLE)shared->CommandlistLock, INFINITE)==WAIT_OBJECT_0; i=0; while (shared->RenderCommands[i].Command) { switch (shared->RenderCommands[i].Command) { case rcDrawSprite: { if (shared->RenderCommands[i].sprite.textureidIASetVertexBuffers( 0, 1, &pSpriteVB, &stride, &offset ); dev->PSSetShader( pPixelShaderNormal); dev->PSSetSamplers( 0, 1, &pSamplerLinear ); dev->PSSetShaderResources( 0, 1, &textures[shared->RenderCommands[i].sprite.textureid].pTexture ); if (shared->RenderCommands[i].x==-1) //center { position.x=((float)vp.Width / 2.0f) - ((float)shared->RenderCommands[i].sprite.width / 2.0f); } else if (shared->RenderCommands[i].x==-2) //mouse { if (clientMousepos.x==-1) { //get the mouse position GetCursorPos(&clientMousepos); ScreenToClient((HWND)shared->lastHwnd, &clientMousepos); } position.x=(float)clientMousepos.x-((float)shared->RenderCommands[i].sprite.width / 2.0f); } else position.x=(float)shared->RenderCommands[i].x; if (shared->RenderCommands[i].y==-1) //center { position.y=((float)vp.Height / 2.0f) - ((float)shared->RenderCommands[i].sprite.height / 2.0f); } else if (shared->RenderCommands[i].y==-2) //mouse { if (clientMousepos.y==-1) { //get the mouse position GetCursorPos(&clientMousepos); ScreenToClient((HWND)shared->lastHwnd, &clientMousepos); } position.y=(float)clientMousepos.y-((float)shared->RenderCommands[i].sprite.height / 2.0f); } else position.y=(float)shared->RenderCommands[i].y; //truncate the position to an exact pixel position.x=(float)(int)position.x; position.y=(float)(int)position.y; ConstantBuffer cb; cb.transparency=shared->RenderCommands[i].alphablend; if (shared->RenderCommands[i].sprite.width==-1) cb.scaling.x=(float)vp.Width/(float)vp.Width; //1.0 else cb.scaling.x=(float)shared->RenderCommands[i].sprite.width/(float)vp.Width; cb.scaling.y=(float)shared->RenderCommands[i].sprite.height/(float)vp.Height; cb.originpoint.x=-1.0f+((float)shared->RenderCommands[i].centerX * 2)/(float)shared->RenderCommands[i].sprite.width; cb.originpoint.y=-1.0f+((float)shared->RenderCommands[i].centerY * 2)/(float)shared->RenderCommands[i].sprite.height; D3DXMatrixRotationZ(&cb.rotation, shared->RenderCommands[i].rotation); cb.translation.x=-1.0f+((float)(((float)position.x-(float)shared->RenderCommands[i].centerX) * 2)/(float)vp.Width); cb.translation.y=-1.0f+((float)(((float)position.y-(float)shared->RenderCommands[i].centerY) * 2)/(float)vp.Height); dev->UpdateSubresource( pConstantBuffer, 0, NULL, &cb, 0, 0 ); dev->VSSetConstantBuffers(0,1, &pConstantBuffer); dev->PSSetConstantBuffers(0,1, &pConstantBuffer); dev->Draw(6,0); } break; } case rcDrawFont: { int tid=shared->RenderCommands[i].font.fontid; if ((tidCommandlistLock, INFINITE)==WAIT_OBJECT_0; //fonts demand a lock (stringpointer) position.x=(float)shared->RenderCommands[i].x; position.y=(float)shared->RenderCommands[i].y; td=&textures[tid]; s=(char *)shared->RenderCommands[i].font.addressoftext; if (position.x==-1) { //horizontal center //calculate the width float maxwidth=0, width=0; int slen=strlen(s); int j; for (j=0; j=32) && (s[j]<(96+32))) width+=td->DefinedFontMap->charinfo[s[j]-32].charwidth; else if (s[j]=='\n') width=0; if (width>maxwidth) maxwidth=width; } position.x=((float)vp.Width / 2.0f) - ((float)maxwidth / 2.0f); } if (position.y==-1) { //vertical center position.y=((float)vp.Height / 2.0f) - ((float)td->DefinedFontMap->charheight / 2.0f); } //truncate the position to an exact pixel position.x=(float)(int)position.x; position.y=(float)(int)position.y; dev->PSSetShader( pPixelShaderNormal); dev->PSSetSamplers( 0, 1, &pSamplerLinear ); ConstantBuffer cb; cb.transparency=shared->RenderCommands[i].alphablend; cb.scaling.x=1.0f; cb.scaling.y=1.0f;//if you wish a bigger font, use a bigger font, don't scale (ugly) cb.originpoint.x=-1.0f; cb.originpoint.y=-1.0f; D3DXMatrixRotationZ(&cb.rotation, shared->RenderCommands[i].rotation); cb.translation.x=-1.0f+((float)((float)position.x * 2)/(float)vp.Width); cb.translation.y=-1.0f+((float)((float)position.y * 2)/(float)vp.Height); dev->UpdateSubresource( pConstantBuffer, 0, NULL, &cb, 0, 0 ); dev->VSSetConstantBuffers(0,1, &pConstantBuffer); dev->PSSetConstantBuffers(0,1, &pConstantBuffer); DrawString(vp, &textures[tid], s,strlen(s)); } break; } } i++; } if (hasLock) //release the lock if it was obtained SetEvent((HANDLE)shared->CommandlistLock); //restore dev->GSSetShader(oldgs); if (oldgs) oldgs->Release(); dev->VSSetShader(oldvs); if (oldvs) oldvs->Release(); dev->PSSetShader(oldps); if (oldps) oldps->Release(); dev->PSSetSamplers(0, 1, &oldPSSampler); if (oldPSSampler) oldPSSampler->Release(); dev->PSSetShaderResources(0,1, &oldPSShaderResource); if (oldPSShaderResource) oldPSShaderResource->Release(); dev->VSSetConstantBuffers(0,1, &oldConstantBuffersVS); if (oldConstantBuffersVS) oldConstantBuffersVS->Release(); dev->PSSetConstantBuffers(0,1, &oldConstantBuffersPS); if (oldConstantBuffersPS) oldConstantBuffersPS->Release(); dev->OMSetRenderTargets(1, &oldRenderTarget, oldDepthStencilView); if (oldRenderTarget) oldRenderTarget->Release(); if (oldDepthStencilView) oldDepthStencilView->Release(); dev->OMSetBlendState(oldBlendState, oldblendFactor, oldblendsamplemask); if (oldBlendState) oldBlendState->Release(); dev->OMSetDepthStencilState(oldDepthStencilState, oldstencilref); if (oldDepthStencilState) oldDepthStencilState->Release(); dev->IASetPrimitiveTopology(oldPrimitiveTopology); dev->IASetInputLayout(oldInputLayout); if (oldInputLayout) oldInputLayout->Release(); dev->IASetIndexBuffer(oldIndexBuffer, oldIndexBufferFormat, oldIndexBufferOffset); if (oldIndexBuffer) oldIndexBuffer->Release(); dev->IASetVertexBuffers(0,1,&oldVertexBuffer, &oldVertexBufferStrides, &oldVertexBufferOffset); if (oldVertexBuffer) oldVertexBuffer->Release(); dev->RSSetState(oldRastersizerState); if (oldRastersizerState) oldRastersizerState->Release(); dev->RSSetViewports(oldviewports, viewports); } } void __stdcall D3D10Hook_SwapChain_ResizeBuffers_imp(IDXGISwapChain *swapchain, ID3D10Device *device, PD3DHookShared s) { //release all buffers DXMessD3D10Handler *currentDevice=D3D10devices[device]; if (currentDevice) { D3D10devices[device]=NULL; lastdevice=NULL; device->ClearState(); delete(currentDevice); } } void __stdcall D3D10Hook_SwapChain_Present_imp(IDXGISwapChain *swapchain, ID3D10Device *device, PD3DHookShared s) { //look up the controller class for this device DXMessD3D10Handler *currentDevice=D3D10devices[device]; if (currentDevice==NULL) { currentDevice=new DXMessD3D10Handler(device, swapchain, s);//create a new devicehandler D3D10devices[device]=currentDevice; shared=s; } insidehook=1; //tell the draw hooks not to mess with the following draw operations lastdevice=currentDevice; currentDevice->RenderOverlay(); insidehook=0; //check if a snapshot key is down if (currentDevice->makeSnapshot) //possible threading issue if more than one render device { //notify CE that all render operations have completed shared->snapshotcount=currentDevice->snapshotCounter; shared->canDoSnapshot=0; SetEvent((HANDLE)shared->snapshotDone); currentDevice->makeSnapshot=FALSE; } if (shared->canDoSnapshot) { if ((shared->snapshotKey) && (GetTickCount()>currentDevice->lastSnapshot+250)) { SHORT ks=GetAsyncKeyState(shared->snapshotKey); currentDevice->makeSnapshot=((ks & 1) || (ks & (1 << 15))); currentDevice->smallSnapshot=FALSE; if (currentDevice->makeSnapshot) currentDevice->lastSnapshot=GetTickCount(); } if ((currentDevice->makeSnapshot==FALSE) && (shared->smallSnapshotKey) && (GetTickCount()>currentDevice->lastSnapshot+250) && (shared->lastHwnd)) { SHORT ks=GetAsyncKeyState(shared->smallSnapshotKey); currentDevice->makeSnapshot=((ks & 1) || (ks & (1 << 15))); if (currentDevice->makeSnapshot) { POINT p; currentDevice->smallSnapshot=TRUE; currentDevice->lastSnapshot=GetTickCount(); //get the pixel the mouse is hovering over GetCursorPos(&p); ScreenToClient((HWND)shared->lastHwnd, &p); currentDevice->smallSnapshotPoint=p; GetClientRect((HWND)shared->lastHwnd, ¤tDevice->smallSnapshotClientRect); //get the relative position (0.00 - 1.00) this position is in for the clientrect currentDevice->smallSnapshotPointRelative.x=(float)currentDevice->smallSnapshotPoint.x/(float)(currentDevice->smallSnapshotClientRect.right-currentDevice->smallSnapshotClientRect.left); currentDevice->smallSnapshotPointRelative.y=(float)currentDevice->smallSnapshotPoint.y/(float)(currentDevice->smallSnapshotClientRect.bottom-currentDevice->smallSnapshotClientRect.top); } } if (currentDevice->makeSnapshot) { ID3D10RenderTargetView *rt=NULL; makeSnapshot=TRUE; //once true, always true currentDevice->dev->OMGetRenderTargets(1, &rt, NULL); //clear the render target with a specific color if (rt) { FLOAT f[]={1.0f,0.0f,1.0f,1.0f}; currentDevice->dev->ClearRenderTargetView(rt, f); rt->Release(); } currentDevice->snapshotCounter=0; } } } HRESULT __stdcall D3D10Hook_DrawIndexed_imp(D3D10_DRAWINDEXED_ORIGINAL originalfunction, ID3D10Device *device, UINT IndexCount, UINT StartIndexLocation, INT BaseVertexLocation) { if (((shared) && ((shared->wireframe) || (shared->disabledzbuffer) || (makeSnapshot) ) && (insidehook==0))) { //setup for wireframe and/or zbuffer HRESULT hr; DXMessD3D10Handler *currentDevice=D3D10devices[device]; if (currentDevice==NULL) //this can happen in some situations when there is a layer inbetween { currentDevice=lastdevice; } if (currentDevice) { ID3D10DepthStencilState *oldDepthStencilState; ID3D10RasterizerState *oldRasterizerState; UINT stencilref; currentDevice->dev->OMGetDepthStencilState(&oldDepthStencilState, &stencilref); currentDevice->dev->RSGetState(&oldRasterizerState); if (shared->wireframe) currentDevice->dev->RSSetState(currentDevice->pWireframeRasterizer); if (shared->disabledzbuffer) currentDevice->dev->OMSetDepthStencilState(currentDevice->pDisabledDepthStencilState, 0);; if (currentDevice->makeSnapshot) currentDevice->PrepareForSnapshot(); hr=originalfunction(device, IndexCount, StartIndexLocation, BaseVertexLocation); currentDevice->dev->RSSetState(oldRasterizerState); currentDevice->dev->OMSetDepthStencilState(oldDepthStencilState, stencilref); if (currentDevice->makeSnapshot) currentDevice->TakeSnapshot("D3D10Hook_DrawIndexed_imp"); return hr; } } return originalfunction(device, IndexCount, StartIndexLocation, BaseVertexLocation); } HRESULT __stdcall D3D10Hook_Draw_imp(D3D10_DRAW_ORIGINAL originalfunction, ID3D10Device *device, UINT VertexCount, UINT StartVertexLocation) { if (((shared) && ((shared->wireframe) || (shared->disabledzbuffer) || (makeSnapshot) ) && (insidehook==0))) { //setup for wireframe and/or zbuffer HRESULT hr; DXMessD3D10Handler *currentDevice=D3D10devices[device]; if (currentDevice==NULL) //this can happen in some situations when there is a layer inbetween { currentDevice=lastdevice; } if (currentDevice) { ID3D10DepthStencilState *oldDepthStencilState; ID3D10RasterizerState *oldRasterizerState; UINT stencilref; currentDevice->dev->OMGetDepthStencilState(&oldDepthStencilState,&stencilref); currentDevice->dev->RSGetState(&oldRasterizerState); if (shared->wireframe) currentDevice->dev->RSSetState(currentDevice->pWireframeRasterizer); if (shared->disabledzbuffer) currentDevice->dev->OMSetDepthStencilState(currentDevice->pDisabledDepthStencilState, 0);; if (currentDevice->makeSnapshot) currentDevice->PrepareForSnapshot(); hr=originalfunction(device, VertexCount, StartVertexLocation); currentDevice->dev->RSSetState(oldRasterizerState); currentDevice->dev->OMSetDepthStencilState(oldDepthStencilState, stencilref); if (currentDevice->makeSnapshot) currentDevice->TakeSnapshot("D3D10Hook_Draw_imp"); return hr; } } return originalfunction(device, VertexCount, StartVertexLocation); } HRESULT __stdcall D3D10Hook_DrawIndexedInstanced_imp(D3D10_DRAWINDEXEDINSTANCED_ORIGINAL originalfunction, ID3D10Device *device, UINT IndexCountPerInstance, UINT InstanceCount, UINT StartIndexLocation, INT BaseVertexLocation, UINT StartInstanceLocation) { if (((shared) && ((shared->wireframe) || (shared->disabledzbuffer) || (makeSnapshot) ) && (insidehook==0))) { //setup for wireframe and/or zbuffer HRESULT hr; DXMessD3D10Handler *currentDevice=D3D10devices[device]; if (currentDevice==NULL) //this can happen in some situations when there is a layer inbetween { currentDevice=lastdevice; } if (currentDevice) { ID3D10DepthStencilState *oldDepthStencilState; ID3D10RasterizerState *oldRasterizerState; UINT stencilref=0; currentDevice->dev->OMGetDepthStencilState(&oldDepthStencilState, &stencilref); currentDevice->dev->RSGetState(&oldRasterizerState); if (shared->wireframe) currentDevice->dev->RSSetState(currentDevice->pWireframeRasterizer); if (shared->disabledzbuffer) currentDevice->dev->OMSetDepthStencilState(currentDevice->pDisabledDepthStencilState, 0);; if (currentDevice->makeSnapshot) currentDevice->PrepareForSnapshot(); hr=originalfunction(device, IndexCountPerInstance, InstanceCount, StartIndexLocation, BaseVertexLocation, StartInstanceLocation); currentDevice->dev->RSSetState(oldRasterizerState); currentDevice->dev->OMSetDepthStencilState(oldDepthStencilState, stencilref); if (currentDevice->makeSnapshot) currentDevice->TakeSnapshot("D3D10Hook_DrawIndexedInstanced_imp"); return hr; } } return originalfunction(device, IndexCountPerInstance, InstanceCount, StartIndexLocation, BaseVertexLocation, StartInstanceLocation); } HRESULT __stdcall D3D10Hook_DrawInstanced_imp(D3D10_DRAWINSTANCED_ORIGINAL originalfunction, ID3D10Device *device, UINT VertexCountPerInstance, UINT InstanceCount, UINT StartVertexLocation, UINT StartInstanceLocation) { if (((shared) && ((shared->wireframe) || (shared->disabledzbuffer) || (makeSnapshot) ) && (insidehook==0))) { //setup for wireframe and/or zbuffer HRESULT hr; DXMessD3D10Handler *currentDevice=D3D10devices[device]; if (currentDevice==NULL) //this can happen in some situations when there is a layer inbetween { currentDevice=lastdevice; } if (currentDevice) { ID3D10DepthStencilState *oldDepthStencilState; ID3D10RasterizerState *oldRasterizerState; UINT stencilref=0; currentDevice->dev->OMGetDepthStencilState(&oldDepthStencilState,&stencilref); currentDevice->dev->RSGetState(&oldRasterizerState); if (shared->wireframe) currentDevice->dev->RSSetState(currentDevice->pWireframeRasterizer); if (shared->disabledzbuffer) currentDevice->dev->OMSetDepthStencilState(currentDevice->pDisabledDepthStencilState, 0);; if (currentDevice->makeSnapshot) currentDevice->PrepareForSnapshot(); hr=originalfunction(device, VertexCountPerInstance, InstanceCount, StartVertexLocation, StartInstanceLocation); currentDevice->dev->RSSetState(oldRasterizerState); currentDevice->dev->OMSetDepthStencilState(oldDepthStencilState, stencilref); if (currentDevice->makeSnapshot) currentDevice->TakeSnapshot("D3D10Hook_DrawInstanced_imp"); return hr; } } return originalfunction(device, VertexCountPerInstance, InstanceCount, StartVertexLocation, StartInstanceLocation); } HRESULT __stdcall D3D10Hook_DrawAuto_imp(D3D10_DRAWAUTO_ORIGINAL originalfunction, ID3D10Device *device) { if (((shared) && ((shared->wireframe) || (shared->disabledzbuffer) || (makeSnapshot) ) && (insidehook==0))) { //setup for wireframe and/or zbuffer HRESULT hr; DXMessD3D10Handler *currentDevice=D3D10devices[device]; if (currentDevice==NULL) //this can happen in some situations when there is a layer inbetween { currentDevice=lastdevice; } if (currentDevice) { ID3D10DepthStencilState *oldDepthStencilState; ID3D10RasterizerState *oldRasterizerState; UINT stencilref=0; currentDevice->dev->OMGetDepthStencilState(&oldDepthStencilState,&stencilref); currentDevice->dev->RSGetState(&oldRasterizerState); if (shared->wireframe) currentDevice->dev->RSSetState(currentDevice->pWireframeRasterizer); if (shared->disabledzbuffer) currentDevice->dev->OMSetDepthStencilState(currentDevice->pDisabledDepthStencilState, 0);; if (currentDevice->makeSnapshot) currentDevice->PrepareForSnapshot(); hr=originalfunction(device); currentDevice->dev->RSSetState(oldRasterizerState); currentDevice->dev->OMSetDepthStencilState(oldDepthStencilState, stencilref); if (currentDevice->makeSnapshot) currentDevice->TakeSnapshot("D3D10Hook_DrawAuto_imp"); return hr; } } HRESULT br; br=originalfunction(device); return br; }