#define _CRT_SECURE_NO_WARNINGS #include #include #include #include "dxwnd.h" #include "dxwcore.hpp" #include "dxhook.h" #include "syslibs.h" #include "dxhelper.h" extern char *ExplainDDError(DWORD); typedef HRESULT (WINAPI *Lock_Type)(LPDIRECTDRAWSURFACE, LPRECT, LPDDSURFACEDESC, DWORD, HANDLE); typedef HRESULT (WINAPI *Unlock4_Type)(LPDIRECTDRAWSURFACE, LPRECT); typedef HRESULT (WINAPI *Unlock1_Type)(LPDIRECTDRAWSURFACE, LPVOID); extern Lock_Type pLock; extern Unlock4_Type pUnlockMethod(LPDIRECTDRAWSURFACE); extern int Set_dwSize_From_Surface(LPDIRECTDRAWSURFACE); #define GRIDSIZE 16 /* RS Hash Function */ static unsigned int Hash(BYTE *buf, int len) { unsigned int b = 378551; unsigned int a = 63689; DWORD hash = 0; for(int i = 0; i < len; i++){ hash = hash * a + buf[i]; a = a * b; } return hash; } void TextureHighlight(LPDIRECTDRAWSURFACE s) { DDSURFACEDESC2 ddsd; int x, y, w, h; HRESULT res; memset(&ddsd,0,sizeof(DDSURFACEDESC2)); ddsd.dwSize = Set_dwSize_From_Surface(s); ddsd.dwFlags = DDSD_LPSURFACE | DDSD_PITCH; if(res=(*pLock)(s, 0, (LPDDSURFACEDESC)&ddsd, DDLOCK_SURFACEMEMORYPTR|DDLOCK_WRITEONLY|DDLOCK_WAIT, 0)){ OutTraceE("TextureHigh: Lock ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); return; } extern LPDIRECTDRAWSURFACE lpDDSBack; if((ddsd.ddsCaps.dwCaps & DDSCAPS_TEXTURE) && (s != lpDDSBack)) { OutTrace("TextureHigh: lpdds=%x BitCount=%d size=(%dx%d)\n", s, ddsd.ddpfPixelFormat.dwRGBBitCount, ddsd.dwWidth, ddsd.dwHeight); w = ddsd.dwWidth; h = ddsd.dwHeight; switch (ddsd.ddpfPixelFormat.dwRGBBitCount){ case 8: { BYTE *p; BYTE color; color=(BYTE)(rand() & 0xFF); for(y=0; y> 1); for(x=0; x> 1); for(x=0; x> 2); for(x=0; x> 2); for(x=0; x (DWORD)iSurfaceSize) for (int i = pbi.bV4SizeImage - iSurfaceSize; i; i--) putc(0, hf); // Close the .BMP file. fclose(hf); break; } res=(*pUnlockMethod(s))(s, NULL); if (res) OutTraceE("TextureDump: Unlock ERROR lpdds=%x res=%x(%s) at %d\n", s, res, ExplainDDError(res), __LINE__); } static void TextureHack(LPDIRECTDRAWSURFACE s) { DDSURFACEDESC2 ddsd; int w, h, iSurfaceSize; HRESULT res; memset(&ddsd,0,sizeof(DDSURFACEDESC2)); ddsd.dwSize = Set_dwSize_From_Surface(s); ddsd.dwFlags = DDSD_LPSURFACE | DDSD_PITCH; if(res=(*pLock)(s, 0, (LPDDSURFACEDESC)&ddsd, DDLOCK_SURFACEMEMORYPTR|DDLOCK_WRITEONLY|DDLOCK_WAIT, 0)){ OutTraceE("TextureHack: Lock ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); return; } extern LPDIRECTDRAWSURFACE lpDDSBack; if((ddsd.ddsCaps.dwCaps & DDSCAPS_TEXTURE) && (s != lpDDSBack)) while (TRUE) { // fake loop to ensure final Unlock OutTrace("TextureHack: lpdds=%x BitCount=%d size=(%dx%d)\n", s, ddsd.ddpfPixelFormat.dwRGBBitCount, ddsd.dwWidth, ddsd.dwHeight); w = ddsd.dwWidth; h = ddsd.dwHeight; iSurfaceSize = ddsd.dwHeight * ddsd.lPitch; FILE *hf; BITMAPFILEHEADER hdr; // bitmap file-header BITMAPINFOHEADER pbi; // bitmap info-header char pszFile[81]; int iSizeImage; memset((void *)&pbi, 0, sizeof(BITMAPINFOHEADER)); pbi.biSize = sizeof(BITMAPINFOHEADER); pbi.biWidth = ddsd.dwWidth; pbi.biHeight = ddsd.dwHeight; pbi.biBitCount = (WORD)ddsd.ddpfPixelFormat.dwRGBBitCount; pbi.biSizeImage = ((pbi.biWidth * pbi.biBitCount + 0x1F) & ~0x1F)/8 * pbi.biHeight; iSizeImage = pbi.biSizeImage; // calculate the bitmap hash DWORD hash; hash = Hash((BYTE *)ddsd.lpSurface, iSurfaceSize); if(!hash) break; // almost certainly, an empty black surface! // Look for the .BMP file. sprintf_s(pszFile, 80, "texture.%x.bmp", hash); hf = fopen(pszFile, "rb"); if(!hf) break; // no updated texture to load OutTrace("HASH bmp file %x\n", hf); while(TRUE) { // fake loop to ensure final fclose // Read the BITMAPFILEHEADER from the .BMP file (and throw away ...). if(fread((LPVOID)&hdr, sizeof(BITMAPFILEHEADER), 1, hf) != 1)break; // Read the BITMAPINFOHEADER (and throw away ...). // If the file contains BITMAPV4HEADER or BITMAPV5HEADER, no problem: next fseek will settle things if(fread((LPVOID)&pbi, sizeof(BITMAPINFOHEADER), 1, hf) != 1) break; // skip the RGBQUAD array if the editor inserted one fseek(hf, hdr.bfOffBits, SEEK_SET); // Read the new texture from the .BMP file. if(pbi.biHeight < 0){ // height < 0 means scan lines in the up to down order, hence you can read them all if(fread((LPVOID)ddsd.lpSurface, iSurfaceSize, 1, hf) != 1) break; } else { for(int y=0; y<(int)ddsd.dwHeight; y++){ BYTE *p = (BYTE *)ddsd.lpSurface + (ddsd.lPitch * ((ddsd.dwHeight-1) - y)); if(fread((LPVOID)p, ddsd.lPitch, 1, hf) != 1) break; } } OutTrace("TextureHack: TEXTURE LOAD DONE\n"); break; } // Close the .BMP file. fclose(hf); break; } res=(*pUnlockMethod(s))(s, NULL); if (res) OutTraceE("TextureHack: Unlock ERROR lpdds=%x res=%x(%s) at %d\n", s, res, ExplainDDError(res), __LINE__); } void TextureHandling(LPDIRECTDRAWSURFACE s) { OutTrace("TextureHandling: dxw.dwFlags5 = %x\n", dxw.dwFlags5 & (TEXTUREHIGHLIGHT|TEXTUREDUMP|TEXTUREHACK)); switch(dxw.dwFlags5 & (TEXTUREHIGHLIGHT|TEXTUREDUMP|TEXTUREHACK)){ default: case TEXTUREHIGHLIGHT: TextureHighlight(s); break; case TEXTUREDUMP: TextureDump(s); break; case TEXTUREHACK: TextureHack(s); break; } }