diff --git a/Include/dxwnd.h b/Include/dxwnd.h index 9672597..9e00921 100644 --- a/Include/dxwnd.h +++ b/Include/dxwnd.h @@ -181,6 +181,7 @@ #define EMULATEFLAGS (EMULATEBUFFER | EMULATESURFACE | LOCKEDSURFACE) #define HANDLEFPS (SHOWFPS | SHOWFPSOVERLAY | LIMITFPS | SKIPFPS) +#define TEXTUREMASK (TEXTUREHIGHLIGHT|TEXTUREDUMP|TEXTUREHACK|TEXTURETRANSP) // DxWnd host app data to be passed to the hook callback typedef struct TARGETMAP diff --git a/build/dxwnd.dll b/build/dxwnd.dll index 5c54bf3..dbf1421 100644 --- a/build/dxwnd.dll +++ b/build/dxwnd.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cb39f983940d6870059f12aedec119662e8fa477b9e6a8729cd11bdaea54899a -size 525824 +oid sha256:dbfe732ec7cba24e2a540fa0a0275293d8f65b1922afeb0a190e5c7c5678e53f +size 535552 diff --git a/build/dxwnd.exe b/build/dxwnd.exe index cfaddd5..6b38334 100644 --- a/build/dxwnd.exe +++ b/build/dxwnd.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e5527a66a62d88b1d8b752729337b257c6c83e74098f5a158893b92552a1fc0c +oid sha256:ef09812ea8000eca947a595d2c89257576af411f35834a2aecec9256e1c3a385 size 532992 diff --git a/build/dxwnd.ini b/build/dxwnd.ini index 62664c1..6ab9251 100644 --- a/build/dxwnd.ini +++ b/build/dxwnd.ini @@ -1,6 +1,6 @@ [window] -posx=50 -posy=50 +posx=1486 +posy=523 sizx=320 sizy=200 lang=automatic diff --git a/build/readme-relnotes.txt b/build/readme-relnotes.txt index cd3ebff..34a3b4c 100644 --- a/build/readme-relnotes.txt +++ b/build/readme-relnotes.txt @@ -671,3 +671,6 @@ fix: DxWnd window position save now works on multiscreen desktop v2.03.04 fix: changed surface capability policy so that "Risk II" works with identical surface pitches +v2.03.05 +add: texture dump for d3d8 & d3d9. Note: highlight & hack yet to be implemented. d3d10 & d3d11 yet to be implemented. Texture types not complete. +fix: handling of d3d10 (Assassin's Creed) \ No newline at end of file diff --git a/dll/d3dtexture.cpp b/dll/d3dtexture.cpp new file mode 100644 index 0000000..9e3006c --- /dev/null +++ b/dll/d3dtexture.cpp @@ -0,0 +1,527 @@ +#define _CRT_SECURE_NO_WARNINGS + +#include +#include "dxwnd.h" +#include "dxwcore.hpp" +#include "dxhook.h" +#include "dxhelper.h" +#include "syslibs.h" +#include "stdio.h" + +extern unsigned int HashSurface(BYTE *, int, int, int); + +char *ExplainD3DSurfaceFormat(DWORD dwFormat) +{ + char *s; + switch(dwFormat){ + case D3DFMT_UNKNOWN: s = "UNKNOWN"; break; + case D3DFMT_R8G8B8: s = "R8G8B8"; break; + case D3DFMT_A8R8G8B8: s = "A8R8G8B8"; break; + case D3DFMT_X8R8G8B8: s = "X8R8G8B8"; break; + case D3DFMT_R5G6B5: s = "R5G6B5"; break; + case D3DFMT_X1R5G5B5: s = "X1R5G5B5"; break; + case D3DFMT_A1R5G5B5: s = "A1R5G5B5"; break; + case D3DFMT_A4R4G4B4: s = "A4R4G4B4"; break; + case D3DFMT_R3G3B2: s = "R3G3B2"; break; + case D3DFMT_A8: s = "A8"; break; + case D3DFMT_A8R3G3B2: s = "A8R3G3B2"; break; + case D3DFMT_X4R4G4B4: s = "X4R4G4B4"; break; + case D3DFMT_A2B10G10R10: s = "A2B10G10R10"; break; + case D3DFMT_A8B8G8R8: s = "A8B8G8R8"; break; + case D3DFMT_X8B8G8R8: s = "X8B8G8R8"; break; + case D3DFMT_G16R16: s = "G16R16"; break; + case D3DFMT_A2R10G10B10: s = "A2R10G10B10"; break; + case D3DFMT_A16B16G16R16: s = "A16B16G16R16"; break; + case D3DFMT_A8P8: s = "A8P8"; break; + case D3DFMT_P8: s = "P8"; break; + case D3DFMT_L8: s = "L8"; break; + case D3DFMT_A8L8: s = "A8L8"; break; + case D3DFMT_A4L4: s = "A4L4"; break; + case D3DFMT_V8U8: s = "V8U8"; break; + case D3DFMT_L6V5U5: s = "L6V5U5"; break; + case D3DFMT_X8L8V8U8: s = "X8L8V8U8"; break; + case D3DFMT_Q8W8V8U8: s = "Q8W8V8U8"; break; + case D3DFMT_V16U16: s = "V16U16"; break; + case D3DFMT_A2W10V10U10: s = "A2W10V10U10"; break; + case D3DFMT_UYVY: s = "UYVY"; break; + case D3DFMT_R8G8_B8G8: s = "R8G8_B8G8"; break; + case D3DFMT_YUY2: s = "YUY2"; break; + case D3DFMT_G8R8_G8B8: s = "G8R8_G8B8"; break; + case D3DFMT_DXT1: s = "DXT1"; break; + case D3DFMT_DXT2: s = "DXT2"; break; + case D3DFMT_DXT3: s = "DXT3"; break; + case D3DFMT_DXT4: s = "DXT4"; break; + case D3DFMT_DXT5: s = "DXT5"; break; + case D3DFMT_D16_LOCKABLE: s = "D16_LOCKABLE"; break; + case D3DFMT_D32: s = "D32"; break; + case D3DFMT_D15S1: s = "D15S1"; break; + case D3DFMT_D24S8: s = "D24S8"; break; + case D3DFMT_D24X8: s = "D24X8"; break; + case D3DFMT_D24X4S4: s = "D24X4S4"; break; + case D3DFMT_D16: s = "D16"; break; + case D3DFMT_D32F_LOCKABLE: s = "D32F_LOCKABLE"; break; + case D3DFMT_D24FS8: s = "D24FS8"; break; + case D3DFMT_D32_LOCKABLE: s = "D32_LOCKABLE"; break; + case D3DFMT_S8_LOCKABLE: s = "S8_LOCKABLE"; break; + case D3DFMT_L16: s = "L16"; break; + case D3DFMT_VERTEXDATA: s = "VERTEXDATA"; break; + case D3DFMT_INDEX16: s = "INDEX16"; break; + case D3DFMT_INDEX32: s = "INDEX32"; break; + case D3DFMT_Q16W16V16U16: s = "Q16W16V16U16"; break; + case D3DFMT_MULTI2_ARGB8: s = "MULTI2_ARGB8"; break; + case D3DFMT_R16F: s = "R16F"; break; + case D3DFMT_G16R16F: s = "G16R16F"; break; + case D3DFMT_A16B16G16R16F: s = "A16B16G16R16F"; break; + case D3DFMT_R32F: s = "R32F"; break; + case D3DFMT_G32R32F: s = "G32R32F"; break; + case D3DFMT_A32B32G32R32F: s = "A32B32G32R32F"; break; + case D3DFMT_A1: s = "A1"; break; + case D3DFMT_A2B10G10R10_XR_BIAS: s = "A2B10G10R10_XR_BIAS"; break; + case D3DFMT_BINARYBUFFER: s = "BINARYBUFFER"; break; + default: s = "Unknown"; break; + } + return s; +} + +static WORD Melt_123(WORD c1, WORD c2) +{ + WORD r1, r2, g1, g2, b1, b2; + WORD r, g, b; + r1 = (c1 & 0xF800) >> 11; + r2 = (c2 & 0xF800) >> 11; + g1 = (c1 & 0x07E0) >> 5; + g2 = (c2 & 0x07E0) >> 5; + b1 = (c1 & 0x001F) >> 0; + b2 = (c2 & 0x001F) >> 0; + r = (((r2 * 2) + r1) / 3) & 0x1F; + g = (((g2 * 2) + g1) / 3) & 0x3F; + b = (((b2 * 2) + b1) / 3) & 0x1F; + return (r << 11) | (g << 5) | (b << 0); +} + +static DWORD Melt32_123(WORD c1, WORD c2) +{ + WORD r1, r2, g1, g2, b1, b2; + DWORD r, g, b; + r1 = (c1 & 0xF800) >> 11; + r2 = (c2 & 0xF800) >> 11; + g1 = (c1 & 0x07E0) >> 5; + g2 = (c2 & 0x07E0) >> 5; + b1 = (c1 & 0x001F) >> 0; + b2 = (c2 & 0x001F) >> 0; + r = (((r2 * 2) + r1) / 3) & 0x1F; + g = (((g2 * 2) + g1) / 3) & 0x3F; + b = (((b2 * 2) + b1) / 3) & 0x1F; + return (r << (16+3)) | (g << (8+2)) | (b << (0+3)); +} + +static DWORD Conv32(WORD c) +{ + DWORD r, g, b; + r = ((c & 0xF800) >> 11) & 0x1F; + g = ((c & 0x07E0) >> 5) & 0x3F; + b = ((c & 0x001F) >> 0) & 0x1F; + return (r << (16+3)) | (g << (8+2)) | (b << (0+3)); +} + +#define GRIDSIZE 16 + +void D3DTextureHighlight(D3DSURFACE_DESC Desc, D3DLOCKED_RECT LockedRect) +{ + switch (Desc.Format){ + case D3DFMT_X8R8G8B8: + case D3DFMT_A8R8G8B8: + { + DWORD *p; + DWORD color; + color=(DWORD)(rand() & 0x00FFFFFF); + for(UINT y=0; y> 2); + for(UINT x=0; x> 2); + for(UINT x=0; x>2); y+=2) + // memset((BYTE *)LockedRect.pBits + (y * LockedRect.Pitch), 0x00, LockedRect.Pitch); + default: + break; + } +} + +void D3DTextureDump(D3DSURFACE_DESC Desc, D3DLOCKED_RECT LockedRect) +{ + static BOOL DoOnce = TRUE; + static int MinTexX, MinTexY, MaxTexX, MaxTexY; + FILE *hf; + BITMAPFILEHEADER hdr; // bitmap file-header + BITMAPV4HEADER pbi; // bitmap info-header + int w, h; + int iSurfaceSize, iScanLineSize; + char pszFile[MAX_PATH]; + DWORD hash; + + if(DoOnce){ + char sProfilePath[MAX_PATH]; + extern char *GetDxWndPath(); + sprintf(sProfilePath, "%s\\dxwnd.ini", GetDxWndPath()); + MinTexX=GetPrivateProfileInt("Texture", "MinTexX", 0, sProfilePath); + MaxTexX=GetPrivateProfileInt("Texture", "MaxTexX", 0, sProfilePath); + MinTexY=GetPrivateProfileInt("Texture", "MinTexY", 0, sProfilePath); + MaxTexY=GetPrivateProfileInt("Texture", "MaxTexY", 0, sProfilePath); + OutTrace("TextureDump: size min=(%dx%d) max=(%dx%d)\n", MinTexX, MinTexY, MaxTexX, MaxTexY); + sprintf_s(pszFile, MAX_PATH, "%s\\texture.out", GetDxWndPath()); + CreateDirectory(pszFile, NULL); + DoOnce = FALSE; + } + + while (TRUE){ // fake loop 1 + w = Desc.Width; + h = Desc.Height; + if((MinTexX && (wMaxTexX)) || (MaxTexY && (h>MaxTexY))) { + OutTrace("TextureDump: SKIP big texture\n"); + break; + } + iSurfaceSize = Desc.Height * LockedRect.Pitch; + + // calculate the bitmap hash + hash = 0; + switch (Desc.Format){ + case D3DFMT_A4R4G4B4: + case D3DFMT_X4R4G4B4: + case D3DFMT_X8R8G8B8: + case D3DFMT_A8R8G8B8: + case D3DFMT_R5G6B5: + case D3DFMT_X1R5G5B5: + case D3DFMT_A1R5G5B5: + case D3DFMT_A8: + hash = HashSurface((BYTE *)LockedRect.pBits, LockedRect.Pitch, Desc.Width, Desc.Height); + break; + case D3DFMT_DXT1: + hash = HashSurface((BYTE *)LockedRect.pBits, LockedRect.Pitch / 6, Desc.Width / 6, Desc.Height); + break; + case D3DFMT_DXT2: + case D3DFMT_DXT3: + hash = HashSurface((BYTE *)LockedRect.pBits, LockedRect.Pitch / 4, Desc.Width / 4, Desc.Height); + break; + case D3DFMT_DXT4: + case D3DFMT_DXT5: + hash = HashSurface((BYTE *)LockedRect.pBits, LockedRect.Pitch / 4, Desc.Width / 4, Desc.Height); + break; + default: + char sMsg[80+1]; + static BOOL DoOnce = TRUE; + if(DoOnce){ + sprintf_s(sMsg, 80, "Unhandled texture type=%d(%s)", Desc.Format, ExplainD3DSurfaceFormat(Desc.Format)); + MessageBox(0, sMsg, "WARN", MB_OK | MB_ICONEXCLAMATION); + DoOnce = FALSE; + } + break; + } + + if(!hash) { + OutTrace("TextureDump: hash=NULL\n"); + break; // almost certainly, an empty black surface! + } + + dxw.dwTFlags = (hash == 0xEC2EE7CE) ? 0xFFFFFFFF : 0x00000000; + + // Create the .BMP file. + extern char *GetDxWndPath(); + sprintf_s(pszFile, MAX_PATH, "%s\\texture.out\\texture.%03d.%03d.%s.%08X.bmp", + GetDxWndPath(), Desc.Width, Desc.Height, ExplainD3DSurfaceFormat(Desc.Format), hash); + hf = fopen(pszFile, "wb"); + if(!hf) break; + + // set bmp invariant parameters + memset((void *)&pbi, 0, sizeof(BITMAPV4HEADER)); + pbi.bV4Size = sizeof(BITMAPV4HEADER); + pbi.bV4Width = Desc.Width; + pbi.bV4Height = Desc.Height; + pbi.bV4Planes = 1; + pbi.bV4V4Compression = BI_BITFIELDS; + pbi.bV4XPelsPerMeter = 1; + pbi.bV4YPelsPerMeter = 1; + pbi.bV4ClrUsed = 0; + pbi.bV4ClrImportant = 0; + pbi.bV4CSType = LCS_CALIBRATED_RGB; + hdr.bfType = 0x4d42; // 0x42 = "B" 0x4d = "M" + hdr.bfReserved1 = 0; + hdr.bfReserved2 = 0; + + switch (Desc.Format){ + case D3DFMT_X8R8G8B8: + case D3DFMT_A8R8G8B8: + case D3DFMT_DXT2: + case D3DFMT_DXT3: + case D3DFMT_DXT4: + case D3DFMT_DXT5: + case D3DFMT_A8: + pbi.bV4BitCount = 32; + pbi.bV4RedMask = 0x00FF0000; + pbi.bV4GreenMask = 0x0000FF00; + pbi.bV4BlueMask = 0x000000FF; + pbi.bV4AlphaMask = 0xFF000000; + break; + case D3DFMT_DXT1: + pbi.bV4BitCount = 16; + pbi.bV4RedMask = 0xF800; + pbi.bV4GreenMask = 0x07E0; + pbi.bV4BlueMask = 0x001F; + pbi.bV4AlphaMask = 0x0000; + break; + case D3DFMT_A4R4G4B4: // AoE III + case D3DFMT_X4R4G4B4: + pbi.bV4BitCount = 16; + pbi.bV4RedMask = 0x0F00; + pbi.bV4GreenMask = 0x00F0; + pbi.bV4BlueMask = 0x000F; + pbi.bV4AlphaMask = 0xF000; + break; + case D3DFMT_A1R5G5B5: // AoE III + case D3DFMT_X1R5G5B5: + pbi.bV4BitCount = 16; + pbi.bV4RedMask = 0x7C00; + pbi.bV4GreenMask = 0x03E0; + pbi.bV4BlueMask = 0x001F; + pbi.bV4AlphaMask = 0x8000; + break; + case D3DFMT_R5G6B5: + pbi.bV4BitCount = 16; + pbi.bV4RedMask = 0x7C00; + pbi.bV4GreenMask = 0x03E0; + pbi.bV4BlueMask = 0x001F; + pbi.bV4AlphaMask = 0x0000; + break; + } + + pbi.bV4SizeImage = ((pbi.bV4Width * pbi.bV4BitCount + 0x1F) & ~0x1F)/8 * pbi.bV4Height; + iScanLineSize = ((pbi.bV4Width * pbi.bV4BitCount + 0x1F) & ~0x1F)/8; + pbi.bV4Height = - pbi.bV4Height; + + // Compute the size of the entire file. + hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) + pbi.bV4Size + pbi.bV4ClrUsed * sizeof(RGBQUAD) + pbi.bV4SizeImage); + + // Compute the offset to the array of color indices. + hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + pbi.bV4Size + pbi.bV4ClrUsed * sizeof (RGBQUAD); + + // Copy the BITMAPFILEHEADER into the .BMP file. + fwrite((LPVOID)&hdr, sizeof(BITMAPFILEHEADER), 1, hf); + + // Copy the BITMAPINFOHEADER and RGBQUAD array into the file. + fwrite((LPVOID)&pbi, sizeof(BITMAPV4HEADER) + pbi.bV4ClrUsed * sizeof (RGBQUAD), 1, hf); + + switch (Desc.Format){ + case D3DFMT_X8R8G8B8: + case D3DFMT_A8R8G8B8: + case D3DFMT_A4R4G4B4: + case D3DFMT_X4R4G4B4: + case D3DFMT_A1R5G5B5: // AoE III + case D3DFMT_R5G6B5: // AoE III + case D3DFMT_X1R5G5B5: + { + // Copy the array of color indices into the .BMP file. + for(int y=0; y<(int)Desc.Height; y++) + fwrite((BYTE *)LockedRect.pBits + (y*LockedRect.Pitch), iScanLineSize, 1, hf); + } + break; + case D3DFMT_A8: + { + // Copy the array of color indices into the .BMP file. + BYTE *p = (BYTE *)LockedRect.pBits; + for(int y=0; y<(int)Desc.Height; y++) + for(int x=0; x<(int)Desc.Width; x++){ + DWORD pixel; + pixel = 0xFF000000 | *p | (*p << 8) | (*p << 16); // gray color + fwrite((BYTE *)&pixel, sizeof(DWORD), 1, hf); + p++; + } + } + break; + case D3DFMT_DXT1: + { + // Copy the array of color indices into the .BMP file. + WORD *bm; + WORD *c; + int bmsize; + c = (WORD *)LockedRect.pBits; + bmsize = Desc.Width * Desc.Height * sizeof(WORD); + bm = (WORD *)malloc(bmsize); + for(int y=0; y<(int)Desc.Height; y+=4){ + for(int x=0; x<(int)Desc.Width; x+=4){ + WORD color_0, color_1, color_2, color_3; + color_0 = *c++; + color_1 = *c++; + color_2 = Melt_123(color_1, color_0); + color_3 = Melt_123(color_0, color_1); + for(int n=0; n<2; n++){ + int dy; + WORD color_indexes = *c++; + WORD color; + for (int m=0; m<8; m++){ + switch (color_indexes & 0x3){ + case 0x00: color = color_0; break; + case 0x01: color = color_1; break; + case 0x02: color = color_2; break; + case 0x03: color = color_3; break; + } + dy = (m<4) ? 0 : 1; + color_indexes >>= 2; + int index = ((y+(2*n)+dy)*Desc.Width) + (x+(m%4)); + if(index < bmsize/2) bm[index]=color; + } + } + } + } + fwrite((BYTE *)bm, bmsize, 1, hf); + free(bm); + } + break; + case D3DFMT_DXT2: + case D3DFMT_DXT3: + { + // Copy the array of color indices into the .BMP file. + DWORD *bm; + WORD *c; + int bmsize; + c = (WORD *)LockedRect.pBits; + bmsize = Desc.Width * Desc.Height * sizeof(DWORD); + bm = (DWORD *)malloc(bmsize); + memset(bm, 0, bmsize); + for(int y=0; y<(int)Desc.Height; y+=4){ + for(int x=0; x<(int)Desc.Width; x+=4){ + WORD color_0, color_1; + DWORD dwcolor[4]; + BYTE alpha[16]; + WORD *pAlpha; + pAlpha = (WORD *)c; + for(int row=0; row<4; row++){ + WORD a = *c++; + for(int col=0; col<4; col++){ + alpha[(row<<2)+col] = (a & 0xF); + a >>= 4; + } + } + color_0 = *c++; + color_1 = *c++; + dwcolor[0] = Conv32(color_0); + dwcolor[1] = Conv32(color_1); + dwcolor[2] = Melt32_123(color_1, color_0); + dwcolor[3] = Melt32_123(color_0, color_1); + for(int n=0; n<2; n++){ + int dy; + WORD color_indexes = *c++; + DWORD color; + for (int m=0; m<8; m++){ + dy = (m<4) ? 0 : 1; + color = dwcolor[color_indexes & 0x3] & 0x00FFFFFF; + dy = (m<4) ? 0 : 1; + color_indexes >>= 2; + int index = ((y+(2*n)+dy)*Desc.Width) + (x+(m%4)); + int alpha_index = (((2*n) + dy)<<2) + (m % 4); + //if(index < bmsize/4) bm[index] = color | 0xFF000000; // uncomment to get rid of alpha channel + if(index < bmsize/4) bm[index] = color | (alpha[alpha_index]<<28); + } + } + } + } + fwrite((BYTE *)bm, bmsize, 1, hf); + free(bm); + } + break; + case D3DFMT_DXT4: + case D3DFMT_DXT5: + { + // Copy the array of color indices into the .BMP file. + DWORD *bm; + WORD *c; + int bmsize; + c = (WORD *)LockedRect.pBits; + bmsize = Desc.Width * Desc.Height * sizeof(DWORD); + bm = (DWORD *)malloc(bmsize); + memset(bm, 0, bmsize); + for(int y=0; y<(int)Desc.Height; y+=4){ + for(int x=0; x<(int)Desc.Width; x+=4){ + WORD color_0, color_1; + DWORD dwcolor[4]; + DWORD alpha[8]; + // alpha section (4 words) .... + alpha[1] = ((*c) >> 8) & 0xFF; + alpha[0] = (*c) & 0xFF; + c++; + if(alpha[0] > alpha[1]) + { + // 6 interpolated alpha values. + alpha[2] = ((6*alpha[0]) + (1*alpha[1])) / 7; // bit code 010 + alpha[3] = ((5*alpha[0]) + (2*alpha[1])) / 7; // bit code 011 + alpha[4] = ((4*alpha[0]) + (3*alpha[1])) / 7; // bit code 100 + alpha[5] = ((3*alpha[0]) + (4*alpha[1])) / 7; // bit code 101 + alpha[6] = ((2*alpha[0]) + (5*alpha[1])) / 7; // bit code 110 + alpha[7] = ((1*alpha[0]) + (6*alpha[1])) / 7; // bit code 111 + } + else + { + // 4 interpolated alpha values. + alpha[2] = ((4*alpha[0]) + (1*alpha[1])) / 5; // bit code 010 + alpha[3] = ((3*alpha[0]) + (2*alpha[1])) / 5; // bit code 011 + alpha[4] = ((2*alpha[0]) + (3*alpha[1])) / 5; // bit code 100 + alpha[5] = ((1*alpha[0]) + (4*alpha[1])) / 5; // bit code 101 + alpha[6] = 0x00; // bit code 110 (fully transparent) + alpha[7] = 0xFF; // bit code 111 (fully opaque) + } + BYTE *pAlpha = (BYTE *)c; + c += 3; + color_0 = *c++; + color_1 = *c++; + dwcolor[0] = Conv32(color_0); + dwcolor[1] = Conv32(color_1); + dwcolor[2] = Melt32_123(color_1, color_0); + dwcolor[3] = Melt32_123(color_0, color_1); + for(int n=0; n<2; n++){ + int dy; + DWORD dwAlpha_indexes = (*(pAlpha+0) & 0x0000FF) | ((*(pAlpha+1)<<8) & 0x00FF00) | ((*(pAlpha+2)<<16) & 0xFF0000); + pAlpha += 3; + DWORD alpha_color; + WORD color_indexes = *c++; + DWORD color; + for (int m=0; m<8; m++){ + alpha_color = (alpha[dwAlpha_indexes & 0x7] << 24) & 0xFF000000; + dy = (m<4) ? 0 : 1; + dwAlpha_indexes >>= 3; + color = dwcolor[color_indexes & 0x3] & 0x00FFFFFF; + dy = (m<4) ? 0 : 1; + color_indexes >>= 2; + int index = ((y+(2*n)+dy)*Desc.Width) + (x+(m%4)); + if(index < bmsize/4) bm[index] = color | alpha_color; + } + } + } + } + fwrite((BYTE *)bm, bmsize, 1, hf); + free(bm); + } + default: + break; + } + // Close the .BMP file. + if(hf) fclose(hf); + break; + } // end of fake loop 1 +} + +void D3DTextureHack(D3DSURFACE_DESC Desc, D3DLOCKED_RECT LockedRect) +{ +} + +void D3DTextureTransp(D3DSURFACE_DESC Desc, D3DLOCKED_RECT LockedRect) +{ +} diff --git a/dll/texv4handle.cpp b/dll/ddtexture.cpp similarity index 87% rename from dll/texv4handle.cpp rename to dll/ddtexture.cpp index 4e1ed94..0872c59 100644 --- a/dll/texv4handle.cpp +++ b/dll/ddtexture.cpp @@ -55,7 +55,7 @@ static unsigned int Hash(BYTE *buf, int len) return hash; } -static unsigned int HashSurface(BYTE *buf, int pitch, int width, int height) +unsigned int HashSurface(BYTE *buf, int pitch, int width, int height) { unsigned int b = 378551; unsigned int a = 63689; @@ -70,6 +70,50 @@ static unsigned int HashSurface(BYTE *buf, int pitch, int width, int height) return hash; } +static char *SurfaceType(DDPIXELFORMAT ddpfPixelFormat) +{ + static char sSurfaceType[81]; + char sColorType[21]; + DWORD mask; + int i, count; + strcpy(sSurfaceType, ""); + // red + mask=ddpfPixelFormat.dwRBitMask; + for (i=0, count=0; i<32; i++) { + if(mask & 0x1) count++; + mask >>= 1; + } + sprintf(sColorType, "R%d", count); + strcat(sSurfaceType, sColorType); + // green + mask=ddpfPixelFormat.dwGBitMask; + for (i=0, count=0; i<32; i++) { + if(mask & 0x1) count++; + mask >>= 1; + } + sprintf(sColorType, "G%d", count); + strcat(sSurfaceType, sColorType); + // blue + mask=ddpfPixelFormat.dwBBitMask; + for (i=0, count=0; i<32; i++) { + if(mask & 0x1) count++; + mask >>= 1; + } + sprintf(sColorType, "B%d", count); + strcat(sSurfaceType, sColorType); + // alpha channel + mask=ddpfPixelFormat.dwRGBAlphaBitMask; + if(mask){ + for (i=0, count=0; i<32; i++) { + if(mask & 0x1) count++; + mask >>= 1; + } + sprintf(sColorType, "A%d", count); + strcat(sSurfaceType, sColorType); + } + return sSurfaceType; +} + void TextureHighlight(LPDIRECTDRAWSURFACE s) { DDSURFACEDESC2 ddsd; @@ -150,6 +194,7 @@ static void TextureDump(LPDIRECTDRAWSURFACE s) HRESULT res; static int MinTexX, MinTexY, MaxTexX, MaxTexY; static BOOL DoOnce = TRUE; + char pszFile[MAX_PATH]; if(DoOnce){ char sProfilePath[MAX_PATH]; @@ -159,6 +204,8 @@ static void TextureDump(LPDIRECTDRAWSURFACE s) MinTexY=GetPrivateProfileInt("Texture", "MinTexY", 0, sProfilePath); MaxTexY=GetPrivateProfileInt("Texture", "MaxTexY", 0, sProfilePath); OutTrace("TextureDump: size min=(%dx%d) max=(%dx%d)\n", MinTexX, MinTexY, MaxTexX, MaxTexY); + sprintf_s(pszFile, MAX_PATH, "%s\\texture.out", GetDxWndPath()); + CreateDirectory(pszFile, NULL); DoOnce = FALSE; } @@ -191,14 +238,10 @@ static void TextureDump(LPDIRECTDRAWSURFACE s) iSurfaceSize = ddsd.dwHeight * ddsd.lPitch; - //HANDLE hf; // file handle FILE *hf; BITMAPFILEHEADER hdr; // bitmap file-header BITMAPV4HEADER pbi; // bitmap info-header - //DWORD dwTmp; - char pszFile[MAX_PATH]; - //pbih = (PBITMAPINFOHEADER)&pbi; memset((void *)&pbi, 0, sizeof(BITMAPV4HEADER)); pbi.bV4Size = sizeof(BITMAPV4HEADER); pbi.bV4Width = ddsd.dwWidth; @@ -217,7 +260,6 @@ static void TextureDump(LPDIRECTDRAWSURFACE s) pbi.bV4BlueMask = ddsd.ddpfPixelFormat.dwBBitMask; pbi.bV4AlphaMask = ddsd.ddpfPixelFormat.dwRGBAlphaBitMask; pbi.bV4CSType = LCS_CALIBRATED_RGB; - //pbi.bV4CSType = 0xFFFFFFFF; iScanLineSize = ((pbi.bV4Width * pbi.bV4BitCount + 0x1F) & ~0x1F)/8; // calculate the bitmap hash @@ -229,7 +271,8 @@ static void TextureDump(LPDIRECTDRAWSURFACE s) } // Create the .BMP file. - sprintf_s(pszFile, 80, "%s\\texture.out\\texture.%03d.%03d.%08X.bmp", GetDxWndPath(), ddsd.dwWidth, ddsd.dwHeight, hash); + sprintf_s(pszFile, MAX_PATH, "%s\\texture.out\\texture.%03d.%03d.%s.%08X.bmp", + GetDxWndPath(), ddsd.dwWidth, ddsd.dwHeight, SurfaceType(ddsd.ddpfPixelFormat), hash); hf = fopen(pszFile, "wb"); if(!hf) break; @@ -302,7 +345,8 @@ static void TextureHack(LPDIRECTDRAWSURFACE s) if(!hash) break; // almost certainly, an empty black surface! // Look for the .BMP file. - sprintf_s(pszFile, 80, "%s\\texture.in\\texture.%03d.%03d.%08X.bmp", GetDxWndPath(), ddsd.dwWidth, ddsd.dwHeight, hash); + sprintf_s(pszFile, MAX_PATH, "%s\\texture.out\\texture.%03d.%03d.%s.%08X.bmp", + GetDxWndPath(), ddsd.dwWidth, ddsd.dwHeight, SurfaceType(ddsd.ddpfPixelFormat), hash); hf = fopen(pszFile, "rb"); if(!hf) break; // no updated texture to load @@ -350,8 +394,8 @@ static void TextureHack(LPDIRECTDRAWSURFACE s) void TextureHandling(LPDIRECTDRAWSURFACE s) { - OutTrace("TextureHandling: dxw.dwFlags5 = %x\n", dxw.dwFlags5 & (TEXTUREHIGHLIGHT|TEXTUREDUMP|TEXTUREHACK)); - switch(dxw.dwFlags5 & (TEXTUREHIGHLIGHT|TEXTUREDUMP|TEXTUREHACK)){ + //OutTrace("TextureHandling(1-7): dxw.dwFlags5 = %x\n", dxw.dwFlags5 & (TEXTUREHIGHLIGHT|TEXTUREDUMP|TEXTUREHACK)); + switch(dxw.dwFlags5 & TEXTUREMASK){ default: case TEXTUREHIGHLIGHT: TextureHighlight(s); @@ -362,5 +406,8 @@ void TextureHandling(LPDIRECTDRAWSURFACE s) case TEXTUREHACK: TextureHack(s); break; + case TEXTURETRANSP: + //TextureTransp(s); + break; } } diff --git a/dll/dxwnd.cpp b/dll/dxwnd.cpp index 23b4043..d9e42b1 100644 --- a/dll/dxwnd.cpp +++ b/dll/dxwnd.cpp @@ -24,7 +24,7 @@ along with this program. If not, see . #include "dxwnd.h" #include "dxwcore.hpp" -#define VERSION "2.03.04" +#define VERSION "2.03.05" #define DXWACTIVATESINGLETASK 1 // comment to allow multiple task activations #define DDTHREADLOCK 1 diff --git a/dll/dxwnd.vs2008.suo b/dll/dxwnd.vs2008.suo index 851da90..d6281e0 100644 Binary files a/dll/dxwnd.vs2008.suo and b/dll/dxwnd.vs2008.suo differ diff --git a/dll/dxwnd.vs2008.vcproj b/dll/dxwnd.vs2008.vcproj index a94f6ca..d862672 100644 --- a/dll/dxwnd.vs2008.vcproj +++ b/dll/dxwnd.vs2008.vcproj @@ -221,6 +221,10 @@ RelativePath=".\advapi.cpp" > + + @@ -245,6 +249,10 @@ /> + + @@ -365,6 +373,14 @@ RelativePath=".\hd3d7.cpp" > + + + + @@ -401,10 +417,6 @@ RelativePath=".\smack.cpp" > - - diff --git a/dll/hd3d.cpp b/dll/hd3d.cpp index 5fd8c73..8985c54 100644 --- a/dll/hd3d.cpp +++ b/dll/hd3d.cpp @@ -9,6 +9,7 @@ #include "dxhook.h" #include "dxhelper.h" #include "syslibs.h" +#include "stdio.h" #include "hd3d.doc.hpp" // fake include to hold documentation #define HOOKD3D10ANDLATER 1 @@ -32,6 +33,7 @@ HRESULT WINAPI voidDirect3DShaderValidatorCreate9(void); void WINAPI voidDebugSetLevel(void); void WINAPI voidDebugSetMute(void); BOOL WINAPI voidDisableD3DSpy(void); +BOOL WINAPI extDisableD3DSpy(void); // IDirect3D8/9 methods @@ -51,6 +53,7 @@ typedef HRESULT (WINAPI *D3DGetDeviceCaps_Type)(void *, UINT, D3DDEVTYPE, D3DCAP typedef HMONITOR (WINAPI *GetAdapterMonitor_Type)(void *, UINT); typedef HRESULT (WINAPI *CreateDevice_Type)(void *, UINT, D3DDEVTYPE, HWND, DWORD, void *, void **); typedef HRESULT (WINAPI *CreateDeviceEx_Type)(void *, UINT, D3DDEVTYPE, HWND, DWORD, void *, D3DDISPLAYMODEEX *, void **); +typedef BOOL (WINAPI *DisableD3DSpy_Type)(void); HRESULT WINAPI extRegisterSoftwareDevice(void *, void*); UINT WINAPI extGetAdapterCount8(void *); @@ -84,6 +87,7 @@ GetAdapterMonitor_Type pGetAdapterMonitor = 0; CreateDevice_Type pCreateDevice8 = 0; CreateDevice_Type pCreateDevice9 = 0; CreateDeviceEx_Type pCreateDeviceEx = 0; +DisableD3DSpy_Type pDisableD3DSpy = 0; // IDirect3DDevice8/9 methods @@ -102,6 +106,9 @@ typedef UINT (WINAPI *GetNumberOfSwapChains_Type)(void *); typedef HRESULT (WINAPI *BeginStateBlock_Type)(void *); typedef HRESULT (WINAPI *EndStateBlock8_Type)(void *, DWORD *); typedef HRESULT (WINAPI *EndStateBlock9_Type)(void *, IDirect3DStateBlock9**); +typedef HRESULT (WINAPI *CreateTexture8_Type)(void *, UINT, UINT, UINT, DWORD, D3DFORMAT, D3DPOOL, void **); +typedef HRESULT (WINAPI *CreateTexture9_Type)(void *, UINT, UINT, UINT, DWORD, D3DFORMAT, D3DPOOL, void **, HANDLE *); +typedef HRESULT (WINAPI *CopyRects_Type)(void *, void *, CONST RECT *, UINT, void *, CONST POINT *); HRESULT WINAPI extTestCooperativeLevel(void *); HRESULT WINAPI extGetDirect3D8(void *, void **); @@ -119,6 +126,9 @@ HRESULT WINAPI extBeginStateBlock8(void *); HRESULT WINAPI extBeginStateBlock9(void *); HRESULT WINAPI extEndStateBlock8(void *, DWORD *); HRESULT WINAPI extEndStateBlock9(void *, IDirect3DStateBlock9**); +HRESULT WINAPI extCreateTexture8(void *, UINT, UINT, UINT, DWORD, D3DFORMAT, D3DPOOL, void **); +HRESULT WINAPI extCreateTexture9(void *, UINT, UINT, UINT, DWORD, D3DFORMAT, D3DPOOL, void **, HANDLE *); +HRESULT WINAPI extCopyRects(void *, void *, CONST RECT *, UINT, void *, CONST POINT *); TestCooperativeLevel_Type pTestCooperativeLevel = 0; GetDirect3D8_Type pGetDirect3D8 = 0; @@ -136,6 +146,21 @@ BeginStateBlock_Type pBeginStateBlock8 = 0; BeginStateBlock_Type pBeginStateBlock9 = 0; EndStateBlock8_Type pEndStateBlock8 = 0; EndStateBlock9_Type pEndStateBlock9 = 0; +CreateTexture8_Type pCreateTexture8 = 0; +CreateTexture9_Type pCreateTexture9 = 0; +CopyRects_Type pCopyRects = 0; + +// IDirect3DTexture8/9 methods + +typedef HRESULT (WINAPI *LockRect_Type)(void *, UINT, D3DLOCKED_RECT *, CONST RECT *, DWORD); +typedef HRESULT (WINAPI *UnlockRect_Type)(void *, UINT); + +HRESULT WINAPI extLockRect(void *, UINT, D3DLOCKED_RECT *, CONST RECT *, DWORD); +HRESULT WINAPI extUnlockRect8(void *, UINT); +HRESULT WINAPI extUnlockRect9(void *, UINT); + +LockRect_Type pLockRect = NULL; +UnlockRect_Type pUnlockRect = NULL; // to sort ... @@ -160,7 +185,8 @@ typedef HRESULT (WINAPI *D3D10CreateDevice1_Type)(IDXGIAdapter *, D3D10_DRIVER_T typedef HRESULT (WINAPI *D3D10CreateDeviceAndSwapChain1_Type)(IDXGIAdapter *, D3D10_DRIVER_TYPE, HMODULE, UINT, UINT, DXGI_SWAP_CHAIN_DESC *, IDXGISwapChain **, ID3D10Device **); typedef HRESULT (WINAPI *D3D11CreateDevice_Type)(IDXGIAdapter *, D3D_DRIVER_TYPE, HMODULE, UINT, const D3D_FEATURE_LEVEL *, UINT, UINT, ID3D11Device **, D3D_FEATURE_LEVEL *, ID3D11DeviceContext **); typedef HRESULT (WINAPI *D3D11CreateDeviceAndSwapChain_Type)(IDXGIAdapter *, D3D_DRIVER_TYPE, HMODULE, UINT, const D3D_FEATURE_LEVEL *, UINT, UINT, const DXGI_SWAP_CHAIN_DESC *, IDXGISwapChain **, ID3D11Device **, D3D_FEATURE_LEVEL *, ID3D11DeviceContext **); -typedef void (WINAPI *RSSetViewports_Type)(void *, UINT, D3D11_VIEWPORT *); +typedef void (WINAPI *RSSetViewports10_Type)(void *, UINT, D3D10_VIEWPORT *); +typedef void (WINAPI *RSSetViewports11_Type)(void *, UINT, D3D11_VIEWPORT *); typedef ULONG (WINAPI *AddRef_Type)(void *); typedef ULONG (WINAPI *Release_Type)(void *); typedef HRESULT (WINAPI *Reset_Type)(void *, D3DPRESENT_PARAMETERS*); @@ -202,7 +228,8 @@ HRESULT WINAPI extD3D10CreateDevice1(IDXGIAdapter *, D3D10_DRIVER_TYPE, HMODULE, HRESULT WINAPI extD3D10CreateDeviceAndSwapChain1(IDXGIAdapter *, D3D10_DRIVER_TYPE, HMODULE, UINT, UINT, DXGI_SWAP_CHAIN_DESC *, IDXGISwapChain **, ID3D10Device **); HRESULT WINAPI extD3D11CreateDevice(IDXGIAdapter *, D3D_DRIVER_TYPE, HMODULE, UINT, const D3D_FEATURE_LEVEL *, UINT, UINT, ID3D11Device **, D3D_FEATURE_LEVEL *, ID3D11DeviceContext **); HRESULT WINAPI extD3D11CreateDeviceAndSwapChain(IDXGIAdapter *, D3D_DRIVER_TYPE, HMODULE, UINT, const D3D_FEATURE_LEVEL *, UINT, UINT, const DXGI_SWAP_CHAIN_DESC *, IDXGISwapChain **, ID3D11Device **, D3D_FEATURE_LEVEL *, ID3D11DeviceContext **); -void WINAPI extRSSetViewports(ID3D11DeviceContext *, UINT, D3D11_VIEWPORT *); +void WINAPI extRSSetViewports10(void *, UINT, D3D10_VIEWPORT *); +void WINAPI extRSSetViewports11(ID3D11DeviceContext *, UINT, D3D11_VIEWPORT *); extern char *ExplainDDError(DWORD); @@ -243,7 +270,8 @@ D3D10CreateDevice1_Type pD3D10CreateDevice1 = 0; D3D10CreateDeviceAndSwapChain1_Type pD3D10CreateDeviceAndSwapChain1 = 0; D3D11CreateDevice_Type pD3D11CreateDevice = 0; D3D11CreateDeviceAndSwapChain_Type pD3D11CreateDeviceAndSwapChain = 0; -RSSetViewports_Type pRSSetViewports = 0; +RSSetViewports10_Type pRSSetViewports10 = 0; +RSSetViewports11_Type pRSSetViewports11 = 0; AddRef_Type pAddRef9 = 0; Release_Type pRelease9 = 0; @@ -260,6 +288,7 @@ static HookEntry_Type d3d9Hooks[]={ {HOOK_HOT_CANDIDATE, "Direct3DCreate9", (FARPROC)NULL, (FARPROC *)&pDirect3DCreate9, (FARPROC)extDirect3DCreate9}, {HOOK_HOT_CANDIDATE, "Direct3DCreate9Ex", (FARPROC)NULL, (FARPROC *)&pDirect3DCreate9Ex, (FARPROC)extDirect3DCreate9Ex}, {HOOK_HOT_CANDIDATE, "CheckFullScreen", (FARPROC)NULL, (FARPROC *)&pCheckFullScreen, (FARPROC)extCheckFullScreen}, + {HOOK_HOT_CANDIDATE, "DisableD3DSpy", (FARPROC)NULL, (FARPROC *)&pDisableD3DSpy, (FARPROC)extDisableD3DSpy}, {HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator }; @@ -416,6 +445,10 @@ void HookD3DDevice8(void** ppD3Ddev8) SetHook((void *)(**(DWORD **)ppD3Ddev8 + 72), extSetGammaRamp, (void **)&pSetGammaRamp, "SetGammaRamp(D8)"); SetHook((void *)(**(DWORD **)ppD3Ddev8 + 76), extGetGammaRamp, (void **)&pGetGammaRamp, "GetGammaRamp(D8)"); } + if(dxw.dwFlags5 & TEXTUREMASK){ + SetHook((void *)(**(DWORD **)ppD3Ddev8 + 80), extCreateTexture8, (void **)&pCreateTexture8, "CreateTexture(D8)"); + //SetHook((void *)(**(DWORD **)ppD3Ddev8 + 112), extCopyRects, (void **)&pCopyRects, "CopyRects(D8)"); + } SetHook((void *)(**(DWORD **)ppD3Ddev8 + 100), extCreateRenderTarget8, (void **)&pCreateRenderTarget8, "CreateRenderTarget(D8)"); SetHook((void *)(**(DWORD **)ppD3Ddev8 + 136), extBeginScene8, (void **)&pBeginScene8, "BeginScene(D8)"); SetHook((void *)(**(DWORD **)ppD3Ddev8 + 140), extEndScene8, (void **)&pEndScene8, "EndScene(D8)"); @@ -452,6 +485,9 @@ void HookD3DDevice9(void** ppD3Ddev9) SetHook((void *)(**(DWORD **)ppD3Ddev9 + 84), extSetGammaRamp, (void **)&pSetGammaRamp, "SetGammaRamp(D9)"); SetHook((void *)(**(DWORD **)ppD3Ddev9 + 88), extGetGammaRamp, (void **)&pGetGammaRamp, "GetGammaRamp(D9)"); } + if(dxw.dwFlags5 & TEXTUREMASK){ + SetHook((void *)(**(DWORD **)ppD3Ddev9 + 92), extCreateTexture9, (void **)&pCreateTexture9, "CreateTexture(D9)"); + } SetHook((void *)(**(DWORD **)ppD3Ddev9 + 164), extBeginScene9, (void **)&pBeginScene9, "BeginScene(D9)"); SetHook((void *)(**(DWORD **)ppD3Ddev9 + 168), extEndScene9, (void **)&pEndScene9, "EndScene(D9)"); //SetHook((void *)(**(DWORD **)ppD3Ddev9 +188), extSetViewport, (void **)&pSetViewport, "SetViewport(D9)"); @@ -477,6 +513,21 @@ void HookD3DDevice9(void** ppD3Ddev9) } +// WIP +void HookD3DTexture8(void** ppD3Dtex8) +{ + OutTraceD3D("Device hook for IDirect3DTexture8 interface\n"); + SetHook((void *)(**(DWORD **)ppD3Dtex8 + 64), extLockRect, (void **)&pLockRect, "LockRect(D8)"); + SetHook((void *)(**(DWORD **)ppD3Dtex8 + 68), extUnlockRect8, (void **)&pUnlockRect, "UnlockRect(D8)"); +} + +void HookD3DTexture9(void** ppD3Dtex9) +{ + OutTraceD3D("Device hook for IDirect3DTexture9 interface\n"); + SetHook((void *)(**(DWORD **)ppD3Dtex9 + 76), extLockRect, (void **)&pLockRect, "LockRect(D9)"); + SetHook((void *)(**(DWORD **)ppD3Dtex9 + 80), extUnlockRect9, (void **)&pUnlockRect, "UnlockRect(D9)"); +} + void HookDirect3D8(void *lpd3d) { SetHook((void *)(*(DWORD *)lpd3d + 0), extQueryInterfaceD3D8, (void **)&pQueryInterfaceD3D8, "QueryInterface(D8)"); @@ -487,6 +538,12 @@ void HookDirect3D8(void *lpd3d) SetHook((void *)(*(DWORD *)lpd3d + 60), extCreateDevice, (void **)&pCreateDevice8, "CreateDevice(D8)"); } +BOOL WINAPI extDisableD3DSpy(void) +{ + if(TRUE) return FALSE; + return (*pDisableD3DSpy)(); +} + void* WINAPI extDirect3DCreate8(UINT sdkversion) { void *lpd3d; @@ -1217,7 +1274,7 @@ HRESULT WINAPI extD3D10CreateDevice( ID3D10Device **ppDevice) { HRESULT res; - D3D10_VIEWPORT ViewPort; + //D3D10_VIEWPORT ViewPort; OutTraceD3D("D3D10CreateDevice: DriverType=%x Flags=%x SDKVersion=%x\n", DriverType, Flags, SDKVersion); //return 0x887a0004; res=(*pD3D10CreateDevice)(pAdapter, DriverType, Software, Flags, SDKVersion, ppDevice); @@ -1225,17 +1282,20 @@ HRESULT WINAPI extD3D10CreateDevice( OutTraceE("D3D10CreateDevice: ret=%x(%s)\n", res, ExplainDDError(res)); return res; } - SetHook((void *)(*(DWORD *)*ppDevice + 100), extRSSetViewports, (void **)&pRSSetViewports, "RSSetViewports(D10)"); + // useless .... + //SetHook((void *)(*(DWORD *)*ppDevice + 120), extRSSetViewports10, (void **)&pRSSetViewports10, "RSSetViewports(D10)"); + + // useless .... + //if(dxw.Windowize){ + // ViewPort.TopLeftX=dxw.iPosX; + // ViewPort.TopLeftY=dxw.iPosY; + // ViewPort.Width=dxw.iSizX; + // ViewPort.Height=dxw.iSizY; + // ViewPort.MinDepth=1.0; + // ViewPort.MaxDepth=1.0; + // (*pRSSetViewports10)((void *)*ppDevice, 1, (D3D10_VIEWPORT *)&ViewPort); + //} - if(dxw.Windowize){ - ViewPort.TopLeftX=dxw.iPosX; - ViewPort.TopLeftY=dxw.iPosY; - ViewPort.Width=dxw.iSizX; - ViewPort.Height=dxw.iSizY; - ViewPort.MinDepth=1.0; - ViewPort.MaxDepth=1.0; - (*pRSSetViewports)((void *)*ppDevice, 1, (D3D11_VIEWPORT *)&ViewPort); - } OutTraceD3D("D3D10CreateDevice: ret=%x\n", res); return res; } @@ -1252,7 +1312,7 @@ HRESULT WINAPI extD3D10CreateDevice1( HRESULT res; OutTraceD3D("D3D10CreateDevice1: DriverType=%x Flags=%x HardwareLevel=%x SDKVersion=%x\n", DriverType, Flags, HardwareLevel, SDKVersion); res=(*pD3D10CreateDevice1)(pAdapter, DriverType, Software, Flags, HardwareLevel, SDKVersion, ppDevice); - SetHook((void *)(*(DWORD *)*ppDevice + 100), extRSSetViewports, (void **)&pRSSetViewports, "RSSetViewports(D10)"); + SetHook((void *)(*(DWORD *)*ppDevice + 100), extRSSetViewports10, (void **)&pRSSetViewports10, "RSSetViewports(D10)"); OutTraceD3D("D3D10CreateDevice1: ret=%x\n", res); return res; } @@ -1321,7 +1381,7 @@ HRESULT WINAPI extD3D11CreateDevice( OutTraceE("D3D11CreateDevice: ret=%x\n", res); return res; } - SetHook((void *)(*(DWORD *)ppImmediateContext + 148), extRSSetViewports, (void **)&pRSSetViewports, "RSSetViewports(D11)"); + SetHook((void *)(*(DWORD *)ppImmediateContext + 148), extRSSetViewports11, (void **)&pRSSetViewports11, "RSSetViewports(D11)"); //SetHook((void *)(*(DWORD *)ppImmediateContext + 152), extRSSetScissorRects, (void **)&pRSSetScissorRects, "RSSetScissorRects(D11)"); OutTraceD3D("D3D11CreateDevice ret=%x\n", res); return res; @@ -1348,7 +1408,7 @@ HRESULT WINAPI extD3D11CreateDeviceAndSwapChain( return res; } -void WINAPI extRSSetViewports(ID3D11DeviceContext *This, UINT NumViewports, D3D11_VIEWPORT *pViewports) +void WINAPI extRSSetViewports10(void *This, UINT NumViewports, D3D10_VIEWPORT *pViewports) { OutTraceD3D("RSSetViewports: NumViewports=%d\n", NumViewports); @@ -1359,7 +1419,21 @@ void WINAPI extRSSetViewports(ID3D11DeviceContext *This, UINT NumViewports, D3D1 pViewports->Height=dxw.iSizY; } - (*pRSSetViewports)(This, NumViewports, pViewports); + (*pRSSetViewports10)(This, NumViewports, pViewports); +} + +void WINAPI extRSSetViewports11(ID3D11DeviceContext *This, UINT NumViewports, D3D11_VIEWPORT *pViewports) +{ + OutTraceD3D("RSSetViewports: NumViewports=%d\n", NumViewports); + + if(dxw.Windowize && (NumViewports==1)){ + pViewports->TopLeftX=dxw.iPosX; + pViewports->TopLeftY=dxw.iPosY; + pViewports->Width=dxw.iSizX; + pViewports->Height=dxw.iSizY; + } + + (*pRSSetViewports11)(This, NumViewports, pViewports); } HRESULT WINAPI extQueryInterfaceD3D8(void *obj, REFIID riid, void** ppvObj) @@ -1746,3 +1820,91 @@ HRESULT WINAPI extEndStateBlock9(void *lpd3dd, IDirect3DStateBlock9** ppSB) res = (*pEndStateBlock9)(lpd3dd, ppSB); return res; } + +HRESULT WINAPI extCreateTexture8(void *lpd3dd, UINT Width, UINT Height, UINT Levels, + DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, + void **ppTexture) +{ + HRESULT res; + OutTraceD3D("CreateTexture(8): lpd3dd=%x size=(%dx%d) levels=%d usage=%x format=%d pool=%x\n", + lpd3dd, Width, Height, Levels, Usage, Format, Pool); + res=(*pCreateTexture8)(lpd3dd, Width, Height, Levels, Usage, Format, Pool, ppTexture); + if (res) + OutTraceE("CreateTexture(8) ERROR: err=%x\n", res); + else { + OutTraceD3D("CreateTexture(8): lpTexture=%x\n", *ppTexture); + HookD3DTexture8(ppTexture); + } + return res; +} + +HRESULT WINAPI extCreateTexture9(void *lpd3dd, UINT Width, UINT Height, UINT Levels, + DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, + void **ppTexture, HANDLE *pSharedHandle) +{ + HRESULT res; + OutTraceD3D("CreateTexture(9): lpd3dd=%x size=(%dx%d) levels=%d usage=%x format=%d pool=%x\n", + lpd3dd, Width, Height, Levels, Usage, Format, Pool, ppTexture, pSharedHandle); + res=(*pCreateTexture9)(lpd3dd, Width, Height, Levels, Usage, Format, Pool, ppTexture, pSharedHandle); + if (res) + OutTraceE("CreateTexture(9) ERROR: err=%x\n", res); + else { + OutTraceD3D("CreateTexture(9): lpTexture=%x\n", *ppTexture); + HookD3DTexture9(ppTexture); + } + return res; +} +BYTE *s; +int w, h, pitch; + +HRESULT WINAPI extLockRect(void *lpd3dtex, UINT Level, D3DLOCKED_RECT *pLockedRect, CONST RECT *pRect, DWORD Flags) +{ + HRESULT res; + if(IsTraceD3D){ + char sRect[81]; + if(pRect) + sprintf_s(sRect, 80, "(%d,%d)-(%d,%d)", pRect->left, pRect->top, pRect->right, pRect->bottom); + else + strcpy_s(sRect, 80, "NULL"); + OutTrace("Texture::LockRect: lpd3dtex=%x level=%d rect=%s flags=%x\n", lpd3dtex, Level, sRect, Flags); + } + res=(*pLockRect)(lpd3dtex, Level, pLockedRect, pRect, Flags); + if (res) OutTraceE("Device::LockRect ERROR: err=%x\n", res); + else { + OutTraceD3D("Device::LockRect: pBits=%x pitch=%d\n", pLockedRect->pBits, pLockedRect->Pitch); + } + return res; +} + +typedef void (*TextureHandling_Type)(void *, int); + +HRESULT WINAPI extUnlockRect(void *lpd3dtex, UINT Level, TextureHandling_Type TextureHandling) +{ + HRESULT res; + OutTraceD3D("Texture::UnlockRect: lpd3dtex=%x level=%d\n", lpd3dtex, Level); + res=(*pUnlockRect)(lpd3dtex, Level); + + if(TextureHandling) TextureHandling(lpd3dtex, Level); + return res; +} + +HRESULT WINAPI extUnlockRect8(void *lpd3dtex, UINT Level) +{ + extern void D3D8TextureHandling(void *, int); + return extUnlockRect(lpd3dtex, Level, D3D8TextureHandling); +} + +HRESULT WINAPI extUnlockRect9(void *lpd3dtex, UINT Level) +{ + extern void D3D9TextureHandling(void *, int); + return extUnlockRect(lpd3dtex, Level, D3D9TextureHandling); +} + +HRESULT WINAPI extCopyRects(void *lpd3dd, void *pSourceSurface, CONST RECT *pSourceRectsArray, UINT cRects, void *pDestinationSurface, CONST POINT* pDestPointsArray) +{ + HRESULT res; + OutTraceD3D("CopyRects: rects=%d\n", cRects); + res = (pCopyRects)(lpd3dd, pSourceSurface, pSourceRectsArray, cRects, pDestinationSurface, pDestPointsArray); + extern void D3D8TextureHandling(void *, int); + //D3D8TextureHandling(pDestinationSurface, 0); + return res;} diff --git a/dll/hd3d8.cpp b/dll/hd3d8.cpp new file mode 100644 index 0000000..9ec1a06 --- /dev/null +++ b/dll/hd3d8.cpp @@ -0,0 +1,68 @@ +#include +#include "dxwnd.h" +#include "dxwcore.hpp" +#include "dxhook.h" +#include "dxhelper.h" +#include "syslibs.h" +#include "stdio.h" + +extern void TextureHandling(LPDIRECTDRAWSURFACE); + +typedef HRESULT (WINAPI *LockRect_Type)(void *, UINT, D3DLOCKED_RECT *, CONST RECT *, DWORD); +typedef HRESULT (WINAPI *UnlockRect_Type)(void *, UINT); + +extern LockRect_Type pLockRect; +extern UnlockRect_Type pUnlockRect; + +extern void D3DTextureDump(D3DSURFACE_DESC, D3DLOCKED_RECT); +extern void D3DTextureHighlight(D3DSURFACE_DESC, D3DLOCKED_RECT); +extern void D3DTextureHack(D3DSURFACE_DESC, D3DLOCKED_RECT); +extern void D3DTextureTransp(D3DSURFACE_DESC, D3DLOCKED_RECT); +extern char *ExplainD3DSurfaceFormat(DWORD); + +void D3D8TextureHandling(void *arg, int Level) +{ + HRESULT res; + LPDIRECT3DTEXTURE8 lpd3dtex = (LPDIRECT3DTEXTURE8)arg; + IDirect3DSurface8 *pSurfaceLevel; + D3DSURFACE_DESC Desc; + D3DLOCKED_RECT LockedRect; + if(res=lpd3dtex->GetSurfaceLevel(Level, &pSurfaceLevel)){ + OutTraceE("Texture::GetSurfaceLevel ERROR: res=%d(%s)\n", res, ExplainDDError(res)); + return; + } + if(res=lpd3dtex->GetLevelDesc(Level, &Desc)){ + OutTraceE("Texture::GetLevelDesc ERROR: res=%d(%s)\n", res, ExplainDDError(res)); + return; + } + pSurfaceLevel->Release(); + switch(Desc.Type){ + case D3DRTYPE_SURFACE: + case D3DRTYPE_TEXTURE: + break; + default: + return; + break; + } + if(Desc.Usage == D3DUSAGE_RENDERTARGET)return; + //pSurfaceLevel->GetRenderTargetData(&pRenderTarget, &pDestSurface); + res=(*pLockRect)(lpd3dtex, Level, &LockedRect, NULL, 0); + OutTrace("D3D8TextureHandling: lpd3dtex=%x level=%d format=0x%x(%s) size=(%dx%d) bits=%x pitch=%d\n", + lpd3dtex, Level, Desc.Format, ExplainD3DSurfaceFormat(Desc.Format), + Desc.Width, Desc.Height, LockedRect.pBits, LockedRect.Pitch); + switch(dxw.dwFlags5 & TEXTUREMASK){ + case TEXTUREHIGHLIGHT: + D3DTextureHighlight(Desc, LockedRect); + break; + case TEXTUREDUMP: + D3DTextureDump(Desc, LockedRect); + break; + case TEXTUREHACK: + D3DTextureHack(Desc, LockedRect); + break; + case TEXTURETRANSP: + D3DTextureTransp(Desc, LockedRect); + break; + } + res=(*pUnlockRect)(lpd3dtex, Level); +} diff --git a/dll/hd3d9.cpp b/dll/hd3d9.cpp new file mode 100644 index 0000000..d239070 --- /dev/null +++ b/dll/hd3d9.cpp @@ -0,0 +1,68 @@ +#include +#include "dxwnd.h" +#include "dxwcore.hpp" +#include "dxhook.h" +#include "dxhelper.h" +#include "syslibs.h" +#include "stdio.h" + +extern void TextureHandling(LPDIRECTDRAWSURFACE); + +typedef HRESULT (WINAPI *LockRect_Type)(void *, UINT, D3DLOCKED_RECT *, CONST RECT *, DWORD); +typedef HRESULT (WINAPI *UnlockRect_Type)(void *, UINT); + +extern LockRect_Type pLockRect; +extern UnlockRect_Type pUnlockRect; + +extern void D3DTextureDump(D3DSURFACE_DESC, D3DLOCKED_RECT); +extern void D3DTextureHighlight(D3DSURFACE_DESC, D3DLOCKED_RECT); +extern void D3DTextureHack(D3DSURFACE_DESC, D3DLOCKED_RECT); +extern void D3DTextureTransp(D3DSURFACE_DESC, D3DLOCKED_RECT); +extern char *ExplainD3DSurfaceFormat(DWORD); + +void D3D9TextureHandling(void *arg, int Level) +{ + HRESULT res; + LPDIRECT3DTEXTURE9 lpd3dtex = (LPDIRECT3DTEXTURE9)arg; + IDirect3DSurface9 *pSurfaceLevel; + D3DSURFACE_DESC Desc; + D3DLOCKED_RECT LockedRect; + if(res=lpd3dtex->GetSurfaceLevel(Level, &pSurfaceLevel)){ + OutTraceE("Texture::GetSurfaceLevel ERROR: res=%d(%s)\n", res, ExplainDDError(res)); + return; + } + if(res=lpd3dtex->GetLevelDesc(Level, &Desc)){ + OutTraceE("Texture::GetLevelDesc ERROR: res=%d(%s)\n", res, ExplainDDError(res)); + return; + } + pSurfaceLevel->Release(); + switch(Desc.Type){ + case D3DRTYPE_SURFACE: + case D3DRTYPE_TEXTURE: + break; + default: + return; + break; + } + if(Desc.Usage == D3DUSAGE_RENDERTARGET)return; + //pSurfaceLevel->GetRenderTargetData(&pRenderTarget, &pDestSurface); + res=(*pLockRect)(lpd3dtex, Level, &LockedRect, NULL, D3DLOCK_READONLY); + OutTrace("D3D9TextureHandling: lpd3dtex=%x level=%d format=0x%x(%s) size=(%dx%d) bits=%x pitch=%d\n", + lpd3dtex, Level, Desc.Format, ExplainD3DSurfaceFormat(Desc.Format), + Desc.Width, Desc.Height, LockedRect.pBits, LockedRect.Pitch); + switch(dxw.dwFlags5 & TEXTUREMASK){ + case TEXTUREHIGHLIGHT: + D3DTextureHighlight(Desc, LockedRect); + break; + case TEXTUREDUMP: + D3DTextureDump(Desc, LockedRect); + break; + case TEXTUREHACK: + D3DTextureHack(Desc, LockedRect); + break; + case TEXTURETRANSP: + D3DTextureTransp(Desc, LockedRect); + break; + } + res=(*pUnlockRect)(lpd3dtex, Level); +} diff --git a/host/dxwndhost.vs2008.suo b/host/dxwndhost.vs2008.suo index 4b0c3ba..47b3c94 100644 Binary files a/host/dxwndhost.vs2008.suo and b/host/dxwndhost.vs2008.suo differ