diff --git a/Include/dxwnd.h b/Include/dxwnd.h index 1a2ea4d..477de08 100644 --- a/Include/dxwnd.h +++ b/Include/dxwnd.h @@ -258,6 +258,9 @@ #define NOHALDEVICE 0x00000040 // Simulates a situation of lack of 3D hardware support, like in presence of remote desktop #define CLIPLOCKED 0x00000080 // never destroy cursor clipper on window move events .... #define PRETENDVISIBLE 0x00000100 // Pretend the main window is visible (IsWindowVisible) and on Z-order top (GetTopWindow) +#define RAWFORMAT 0x00000200 // texture dump / hack are performed in raw format, compression / decompression to be made offline +#define WININSULATION 0x00000400 // EnumerateWin finds no windows! +#define FIXMOUSEHOOK 0x00000800 // fixes mouse coordinates retrieved through MouseProc routine associated to SetWindowsHook(WH_MOUSE,..) // logging Tflags DWORD: #define OUTTRACE 0x00000001 // enables tracing to dxwnd.log in general diff --git a/build/dxwnd.dll b/build/dxwnd.dll index 3b0b72e..ca8bd2d 100644 --- a/build/dxwnd.dll +++ b/build/dxwnd.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cf023536d20b33dd428096f18a29788e47eba0691547598d6de7ef7cc877956f -size 710144 +oid sha256:b3e4a919d94a65a136733126cb2ab2ea7ec6ea20d20d06acc7fc826fb8dd7bce +size 756736 diff --git a/build/dxwnd.exe b/build/dxwnd.exe index 743c81a..678ae18 100644 --- a/build/dxwnd.exe +++ b/build/dxwnd.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3840ce99c26e25e77df3d855fbd91c5533f0fcff4e4a876dc88b62a465d66b62 +oid sha256:f4781f62e3b9bbc3cb28f6ab03585167d87e0352520ba25ee7ad0102ad02a244 size 668160 diff --git a/build/dxwnd.ini b/build/dxwnd.ini deleted file mode 100644 index 0727a81..0000000 --- a/build/dxwnd.ini +++ /dev/null @@ -1,43 +0,0 @@ -[window] -exportpath=D:\DxWnd.develop\v2_03_99fx2_src\build\exports\ -exepath=F:\Games\The Sting!\TheSting!\ -posx=1154 -posy=553 -sizx=320 -sizy=200 -[target] -title0=The Sting! -path0=F:\Games\The Sting!\TheSting!\Sting.exe -startfolder0= -launchpath0= -module0= -opengllib0= -notes0= -registry0= -ver0=0 -monitorid0=0 -coord0=0 -flag0=136314914 -flagg0=1207959552 -flagh0=16 -flagi0=138412036 -flagj0=4224 -flagk0=65536 -flagl0=0 -flagm0=0 -tflag0=0 -dflag0=0 -posx0=50 -posy0=50 -sizx0=800 -sizy0=600 -maxfps0=0 -initts0=0 -winver0=0 -maxres0=-1 -swapeffect0=0 -maxddinterface0=7 -slowratio0=1 -scanline0=1 -initresw0=0 -initresh0=0 diff --git a/build/exports/Jagged Alliance 2 Gold.dxw b/build/exports/Jagged Alliance 2 Gold.dxw new file mode 100644 index 0000000..6c39636 --- /dev/null +++ b/build/exports/Jagged Alliance 2 Gold.dxw @@ -0,0 +1,36 @@ +[target] +title0=Jagged Alliance 2 Gold +path0=F:\Games\Jagged Alliance 2 Gold\ja2.exe +startfolder0= +launchpath0= +module0= +opengllib0= +notes0= +registry0= +ver0=0 +monitorid0=-1 +coord0=0 +flag0=-1474297694 +flagg0=1744832768 +flagh0=8212 +flagi0=138412036 +flagj0=5248 +flagk0=2162696 +flagl0=16 +flagm0=2305 +tflag0=0 +dflag0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 +swapeffect0=0 +maxddinterface0=7 +slowratio0=2 +scanline0=0 +initresw0=800 +initresh0=600 diff --git a/build/exports/Need for Speed 5 Porsche Unleashed.dxw b/build/exports/Need for Speed 5 Porsche Unleashed.dxw index a42a283..40c72ba 100644 --- a/build/exports/Need for Speed 5 Porsche Unleashed.dxw +++ b/build/exports/Need for Speed 5 Porsche Unleashed.dxw @@ -10,7 +10,7 @@ registry0= ver0=0 monitorid0=-1 coord0=0 -flag0=136314914 +flag0=136314922 flagg0=1207959552 flagh0=20 flagi0=138412036 @@ -33,3 +33,4 @@ maxddinterface0=7 slowratio0=2 initresw0=800 initresh0=600 +scanline0=1 diff --git a/build/exports/Rayman 2 (GOG).dxw b/build/exports/Rayman 2 (GOG).dxw index 660378c..6c6b9d4 100644 --- a/build/exports/Rayman 2 (GOG).dxw +++ b/build/exports/Rayman 2 (GOG).dxw @@ -5,7 +5,7 @@ module0= opengllib0= ver0=1 coord0=0 -flag0=402653219 +flag0=402653235 flagg0=1208025104 flagh0=20 flagi0=4194304 @@ -26,7 +26,17 @@ launchpath0= notes0= registry0= flagj0=128 -flagk0=65536 +flagk0=268500992 winver0=0 maxres0=0 swapeffect0=0 +startfolder0= +monitorid0=0 +flagl0=0 +flagm0=0 +dflag0=0 +maxddinterface0=7 +slowratio0=1 +scanline0=1 +initresw0=0 +initresh0=0 diff --git a/build/exports/Titanic.dxw b/build/exports/Titanic.dxw new file mode 100644 index 0000000..2843337 --- /dev/null +++ b/build/exports/Titanic.dxw @@ -0,0 +1,36 @@ +[target] +title0=Titanic +path0=F:\Games\Titanic\TI.noshim.EXE +startfolder0= +launchpath0= +module0= +opengllib0= +notes0= +registry0= +ver0=0 +monitorid0=-1 +coord0=0 +flag0=-1474293726 +flagg0=1745879072 +flagh0=540692 +flagi0=138412036 +flagj0=4224 +flagk0=67584 +flagl0=269484032 +flagm0=1024 +tflag0=0 +dflag0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 +swapeffect0=0 +maxddinterface0=7 +slowratio0=2 +scanline0=0 +initresw0=800 +initresh0=600 diff --git a/build/readme-relnotes.txt b/build/readme-relnotes.txt index f553d73..a0c6723 100644 --- a/build/readme-relnotes.txt +++ b/build/readme-relnotes.txt @@ -1372,15 +1372,22 @@ fix: recovered DEFAULTMESSAGES option fix: normalized output for ddraw GetScanLine() method fix: fixed the policy for redrecting the WindowProc routine. Fixes "Ultimate Spiderman" clipping problems, and possibly much more -v2.03.99/fx1-3 +v2.03.99 fix: unwanted hook to directsound when passing by CoCreateInstance() fix: transient mode, now checks for both the target and the launcher to be dead before terminating add: Direct3D TRIMTEXTUREFORMAT flag, to mimic MS "DirectXTrimTextureFormat" shim. Fixes problems in "Heavy Gear 2" and "Star Wars: Rogue Squardon 3D". add: D3DDevice GetCaps hooking and full dump of D3DDevice capabilities add: "No HAL Device" flag, making it unavailable the IID_Direct3DHALDevice device. Fixes "Grand Prix World" when the 3D car models are invisible. add: reorganization of mouse clipper fields, with the addition of LOCK mode (useful for Tribal Rage) -fix: handling of Lock/Unlock methods differentiated in ddraw 4 vs. 7. Fixes "Hoyle Casino Empire" -fix: texture hack now search for hacked textures in the texture.in folder, as stated in the documentation -fix: D3D7 EnumDevices hexdump fixed -add: flag "Pretend Win visible on top" (PRETENDVISIBLE) to let the program believe that the main window is always visible and on z-order top as a fullscreen window should be -fix: fixed some divide by 0 conditions when window is minimized \ No newline at end of file + +v2.04.00 +add: texture management for D3D textures: XCTn compressed textures, raw mode, texture highlight and hack +add: Input / "fix MOUSEHOOK callback" option, fixes "Jagged Alliance 2" mouse problems +add: GDI / "Pretend Win visible & on top" option: experimental, let the program believe that the main window is visible and on top of z-order as usually happens to full screen applications +add: GDI / "Win insulation" flag: avoid enumerating windows so that the program can't interfere with them. Fixes "Tribal Rage" damages to desktop. +add: hook to ddraw DuplicateSurface() method, so far for logging only. +fix: eliminated possible divide by 0 exception when minimizing windows +fix: mouse clipping now selected by radio buttons (default, off, on, locked) +fix: bug in D3D device enumeration log +fix: bug in Hybrid and GDI ddraw surface rendering +fix: missing "No HAL Device" flag default to disabled diff --git a/dll/d3dtexture.cpp b/dll/d3dtexture.cpp index 01c6f4b..e9bac6b 100644 --- a/dll/d3dtexture.cpp +++ b/dll/d3dtexture.cpp @@ -8,7 +8,23 @@ #include "syslibs.h" #include "stdio.h" +#define STB_DXT_IMPLEMENTATION +#include "stb_dxt.h" + extern unsigned int HashSurface(BYTE *, int, int, int); +extern char *GetDxWndPath(); + +static unsigned int HashBuffer(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++); + a = a * b; + } + return hash; +} static WORD Melt_123(WORD c1, WORD c2) { @@ -124,34 +140,191 @@ char *ExplainD3DSurfaceFormat(DWORD dwFormat) return s; } -#define GRIDSIZE 16 - -void D3DTextureHighlight(D3DSURFACE_DESC Desc, D3DLOCKED_RECT LockedRect) +static int FormatColorDepth(D3DFORMAT Format) { - switch (Desc.Format){ + int iColorDepth = 0; + switch (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: + case D3DFMT_DXT4: + case D3DFMT_DXT5: + case D3DFMT_A8: + case D3DFMT_L8: + iColorDepth = 32; + break; + case D3DFMT_DXT1: + case D3DFMT_A4R4G4B4: // AoE III + case D3DFMT_X4R4G4B4: + case D3DFMT_A1R5G5B5: // AoE III + case D3DFMT_X1R5G5B5: + case D3DFMT_R5G6B5: + iColorDepth = 16; break; } + return iColorDepth; +} + +// FormatColorBytes macro gives color depth in bytes by dividing by 8 (=> lshift 3) +#define FormatColorBytes(Format) (FormatColorDepth(Format) >> 3) + +static DWORD TextureSize(D3DSURFACE_DESC Desc, D3DLOCKED_RECT LockedRect) +{ + DWORD dwSize; + + // calculate the texture size + switch (Desc.Format){ + case D3DFMT_A4R4G4B4: + case D3DFMT_X4R4G4B4: + case D3DFMT_X1R5G5B5: + case D3DFMT_A1R5G5B5: + case D3DFMT_R5G6B5: + case D3DFMT_X8R8G8B8: + case D3DFMT_A8R8G8B8: + //case D3DFMT_A8: + //case D3DFMT_L8: + dwSize = Desc.Width * Desc.Height * FormatColorBytes(Desc.Format); + break; + case D3DFMT_DXT1: + case D3DFMT_DXT2: + case D3DFMT_DXT3: + case D3DFMT_DXT4: + case D3DFMT_DXT5: + dwSize = (Desc.Width * Desc.Height * FormatColorBytes(Desc.Format)) / 4; + break; + default: + dwSize = 0; // 0 = unknown or not interesting + break; + } + return dwSize; +} + +static DWORD D3DHash(D3DSURFACE_DESC Desc, D3DLOCKED_RECT LockedRect) +{ + DWORD hash; + static BOOL DoOnce = TRUE; + + // calculate the bitmap hash + hash = 0; + switch (Desc.Format){ + // hash for uncompressed bmp-like formats with possible empty area at end of pitch size + case D3DFMT_A4R4G4B4: + case D3DFMT_X4R4G4B4: + case D3DFMT_X8R8G8B8: + case D3DFMT_A8R8G8B8: + case D3DFMT_R5G6B5: + case D3DFMT_X1R5G5B5: + case D3DFMT_A1R5G5B5: + case D3DFMT_A8: + case D3DFMT_L8: + hash = HashSurface((BYTE *)LockedRect.pBits, LockedRect.Pitch, Desc.Width, Desc.Height); + break; + // hash for fixed ratio compressed formats + case D3DFMT_DXT1: + case D3DFMT_DXT2: + case D3DFMT_DXT3: + case D3DFMT_DXT4: + case D3DFMT_DXT5: + hash = HashBuffer((BYTE *)LockedRect.pBits, TextureSize(Desc, LockedRect)); + break; + case D3DFMT_V8U8: + case D3DFMT_Q8W8V8U8: // Tiger Woods PGA Tour 08 + case D3DFMT_V16U16: + case D3DFMT_Q16W16V16U16: + case D3DFMT_CxV8U8: + case D3DFMT_L6V5U5: + case D3DFMT_X8L8V8U8: + case D3DFMT_A2W10V10U10: + // Bumpmap surfaces, dump is meaningless ..... + break; + default: + char sMsg[80+1]; + 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; + } + return hash; +} + +BOOL SetBMPStruct(LPBITMAPV4HEADER lpBV4Hdr, LPBITMAPFILEHEADER lpBFHdr, D3DSURFACE_DESC Desc) +{ + // set bmp invariant parameters + memset((void *)lpBV4Hdr, 0, sizeof(BITMAPV4HEADER)); + lpBV4Hdr->bV4Size = sizeof(BITMAPV4HEADER); + lpBV4Hdr->bV4Width = Desc.Width; + lpBV4Hdr->bV4Height = Desc.Height; + lpBV4Hdr->bV4Planes = 1; + lpBV4Hdr->bV4V4Compression = BI_BITFIELDS; + lpBV4Hdr->bV4XPelsPerMeter = 1; + lpBV4Hdr->bV4YPelsPerMeter = 1; + lpBV4Hdr->bV4ClrUsed = 0; + lpBV4Hdr->bV4ClrImportant = 0; + lpBV4Hdr->bV4CSType = LCS_CALIBRATED_RGB; + lpBFHdr->bfType = 0x4d42; // 0x42 = "B" 0x4d = "M" + lpBFHdr->bfReserved1 = 0; + lpBFHdr->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: + case D3DFMT_L8: + lpBV4Hdr->bV4BitCount = 32; + lpBV4Hdr->bV4RedMask = 0x00FF0000; + lpBV4Hdr->bV4GreenMask = 0x0000FF00; + lpBV4Hdr->bV4BlueMask = 0x000000FF; + lpBV4Hdr->bV4AlphaMask = 0xFF000000; + break; + case D3DFMT_DXT1: + lpBV4Hdr->bV4BitCount = 16; + lpBV4Hdr->bV4RedMask = 0xF800; + lpBV4Hdr->bV4GreenMask = 0x07E0; + lpBV4Hdr->bV4BlueMask = 0x001F; + lpBV4Hdr->bV4AlphaMask = 0x0000; + break; + case D3DFMT_A4R4G4B4: // AoE III + case D3DFMT_X4R4G4B4: + lpBV4Hdr->bV4BitCount = 16; + lpBV4Hdr->bV4RedMask = 0x0F00; + lpBV4Hdr->bV4GreenMask = 0x00F0; + lpBV4Hdr->bV4BlueMask = 0x000F; + lpBV4Hdr->bV4AlphaMask = 0xF000; + break; + case D3DFMT_A1R5G5B5: // AoE III + case D3DFMT_X1R5G5B5: + lpBV4Hdr->bV4BitCount = 16; + lpBV4Hdr->bV4RedMask = 0x7C00; + lpBV4Hdr->bV4GreenMask = 0x03E0; + lpBV4Hdr->bV4BlueMask = 0x001F; + lpBV4Hdr->bV4AlphaMask = 0x8000; + break; + case D3DFMT_R5G6B5: + lpBV4Hdr->bV4BitCount = 16; + lpBV4Hdr->bV4RedMask = 0x7C00; + lpBV4Hdr->bV4GreenMask = 0x03E0; + lpBV4Hdr->bV4BlueMask = 0x001F; + lpBV4Hdr->bV4AlphaMask = 0x0000; + break; + } + + lpBV4Hdr->bV4SizeImage = ((lpBV4Hdr->bV4Width * lpBV4Hdr->bV4BitCount + 0x1F) & ~0x1F)/8 * lpBV4Hdr->bV4Height; + lpBV4Hdr->bV4Height = - lpBV4Hdr->bV4Height; + + // Compute the size of the entire file. + lpBFHdr->bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) + lpBV4Hdr->bV4Size + lpBV4Hdr->bV4ClrUsed * sizeof(RGBQUAD) + lpBV4Hdr->bV4SizeImage); + + // Compute the offset to the array of color indices. + lpBFHdr->bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + lpBV4Hdr->bV4Size + lpBV4Hdr->bV4ClrUsed * sizeof (RGBQUAD); + + return 0; } void D3DTextureDump(D3DSURFACE_DESC Desc, D3DLOCKED_RECT LockedRect) @@ -165,10 +338,10 @@ void D3DTextureDump(D3DSURFACE_DESC Desc, D3DLOCKED_RECT LockedRect) int iSurfaceSize, iScanLineSize; char pszFile[MAX_PATH]; DWORD hash; + BOOL IsRaw = (dxw.dwFlags8 & RAWFORMAT); 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); @@ -193,136 +366,35 @@ void D3DTextureDump(D3DSURFACE_DESC Desc, D3DLOCKED_RECT LockedRect) } 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: - case D3DFMT_L8: - 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; - case D3DFMT_V8U8: - case D3DFMT_Q8W8V8U8: // Tiger Woods PGA Tour 08 - case D3DFMT_V16U16: - case D3DFMT_Q16W16V16U16: - case D3DFMT_CxV8U8: - case D3DFMT_L6V5U5: - case D3DFMT_X8L8V8U8: - case D3DFMT_A2W10V10U10: - // Bumpmap surfaces, dump is meaningless ..... - 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; + // skip unsupported raw compressions + if(!TextureSize(Desc, LockedRect)){ + OutTrace("TextureDump: UNSUPPORTED\n"); + break; } + // calculate the bitmap hash + hash = D3DHash(Desc, LockedRect); if(!hash) { OutTrace("TextureDump: hash=NULL\n"); break; // almost certainly, an empty black surface! } // 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); + sprintf_s(pszFile, MAX_PATH, "%s\\texture.out\\texture.%03d.%03d.%s.%08X.%s", + GetDxWndPath(), Desc.Width, Desc.Height, ExplainD3DSurfaceFormat(Desc.Format), + hash, IsRaw ? "raw" : "bmp"); 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: - case D3DFMT_L8: - 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; + if(IsRaw){ + fwrite((BYTE *)LockedRect.pBits, TextureSize(Desc, LockedRect), 1, hf); + fclose(hf); + return; } - pbi.bV4SizeImage = ((pbi.bV4Width * pbi.bV4BitCount + 0x1F) & ~0x1F)/8 * pbi.bV4Height; + // set bmp invariant parameters + if (SetBMPStruct(&pbi, &hdr, Desc)) break; 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); @@ -531,6 +603,260 @@ void D3DTextureDump(D3DSURFACE_DESC Desc, D3DLOCKED_RECT LockedRect) void D3DTextureHack(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 iSurfaceSize, iScanLineSize; + char pszFile[MAX_PATH]; + DWORD hash; + int w, h; + BOOL IsRaw = (dxw.dwFlags8 & RAWFORMAT); + + OutTraceB("TextureHack(D3D)\n"); + + if(DoOnce){ + char sProfilePath[MAX_PATH]; + 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("TextureHack: size min=(%dx%d) max=(%dx%d)\n", MinTexX, MinTexY, MaxTexX, MaxTexY); + sprintf_s(pszFile, MAX_PATH, "%s\\texture.in", GetDxWndPath()); + DoOnce = FALSE; + } + + while(TRUE){ // fake loop + w = Desc.Width; + h = Desc.Height; + if((MinTexX && (wMaxTexX)) || (MaxTexY && (h>MaxTexY))) { + OutTrace("TextureHack: SKIP big texture\n"); + break; + } + iSurfaceSize = Desc.Height * LockedRect.Pitch; + + // calculate the bitmap hash + hash = D3DHash(Desc, LockedRect); + if(!hash) { + OutTrace("TextureHack: hash=NULL\n"); + break; // almost certainly, an empty black surface! + } + + // Look for the .BMP file. + sprintf_s(pszFile, MAX_PATH, "%s\\texture.in\\texture.%03d.%03d.%s.%08X.%s", + GetDxWndPath(), Desc.Width, Desc.Height, ExplainD3DSurfaceFormat(Desc.Format), + hash, IsRaw ? "raw" : "bmp"); + hf = fopen(pszFile, "rb"); + if(!hf) break; // no updated texture to load + + OutTrace("TextureHack: IMPORT path=%s\n", pszFile); + + if(IsRaw){ + fread((BYTE *)LockedRect.pBits, TextureSize(Desc, LockedRect), 1, hf); + fclose(hf); + return; + } + + int iBitCount = FormatColorDepth(Desc.Format); + if(iBitCount == 0){ + OutTrace("TextureHack: unsupported format=%x\n", Desc.Format); + break; + } + iScanLineSize = ((Desc.Width * iBitCount + 0x1F) & ~0x1F)/8; + + 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); + + switch (Desc.Format){ + case D3DFMT_X8R8G8B8: + case D3DFMT_A8R8G8B8: + // Read the new texture from the .BMP file. + if(pbi.bV4Height < 0){ + // biHeight < 0 -> scan lines from top to bottom, same as surface/texture convention + for(int y=0; y<(int)Desc.Height; y++){ + BYTE *p = (BYTE *)LockedRect.pBits + (LockedRect.Pitch * y); + fseek(hf, hdr.bfOffBits + (iScanLineSize * y), SEEK_SET); + if(fread((LPVOID)p, LockedRect.Pitch, 1, hf) != 1) break; + } + } + else { + // biHeight > 0 -> scan lines from bottom to top, inverse order as surface/texture convention + for(int y=0; y<(int)Desc.Height; y++){ + BYTE *p = (BYTE *)LockedRect.pBits + (LockedRect.Pitch * ((Desc.Height-1) - y)); + fseek(hf, hdr.bfOffBits + (iScanLineSize * y), SEEK_SET); + if(fread((LPVOID)p, LockedRect.Pitch, 1, hf) != 1) break; + } + } + break; + case D3DFMT_DXT1: + // Read the new texture from the .BMP file. + if(pbi.bV4Height < 0){ + BYTE *p = (BYTE *)LockedRect.pBits; + BYTE *fb; + fb = (BYTE *)malloc(Desc.Width * Desc.Height * sizeof(WORD)); + if(!fb) { + OutTrace("TextureHack: malloc error\n"); + break; + } + fseek(hf, hdr.bfOffBits, SEEK_SET); + if(fread((LPVOID)fb, Desc.Height * Desc.Width * (iBitCount / 8), 1, hf) != 1) { + OutTrace("TextureHack: fread error\n"); + free(fb); + break; + } + // biHeight < 0 -> scan lines from top to bottom, same as surface/texture convention + for(int y=0; y<(int)Desc.Height; y+=4){ + for(int x=0; x<(int)Desc.Width; x+=4){ + OutTrace("Compressing line=%d row=%d\n", y, x); + stb_compress_dxt_block(p, fb, FALSE, STB_DXT_NORMAL); + p += (16 * sizeof(DWORD) / 8); + OutTrace("Compression done\n"); + fb += 4 * 2; + } + } + free(fb); + } + break; + case D3DFMT_DXT5: + // Read the new texture from the .BMP file. + if(pbi.bV4Height < 0){ + BYTE *p = (BYTE *)LockedRect.pBits; + BYTE *fb; + fb = (BYTE *)malloc(Desc.Width * Desc.Height * sizeof(DWORD)); + if(!fb) { + OutTrace("TextureHack: malloc error\n"); + break; + } + fseek(hf, hdr.bfOffBits, SEEK_SET); + if(fread((LPVOID)fb, Desc.Height * Desc.Width * (iBitCount / 8), 1, hf) != 1) { + OutTrace("TextureHack: fread error\n"); + free(fb); + break; + } + // biHeight < 0 -> scan lines from top to bottom, same as surface/texture convention + for(int y=0; y<(int)Desc.Height; y+=4){ + for(int x=0; x<(int)Desc.Width; x+=4){ + OutTrace("Compressing line=%d row=%d\n", y, x); + stb_compress_dxt_block(p, fb, FALSE, STB_DXT_NORMAL); + p += (16 * sizeof(DWORD) / 4); + OutTrace("Compression done\n"); + fb += 4 * 4; + } + } + free(fb); + } + break; + } + + OutTrace("TextureHack: TEXTURE LOAD DONE\n"); + break; + } + + fclose(hf); + break; + } +} + +#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; xCreateClipper(0, &lpddC, NULL); - if (res) OutTraceE("CreateSurface: CreateClipper ERROR res=%x(%s)\n", res, ExplainDDError(res)); + if (res) OutTraceE("BuildRealSurfaces: CreateClipper ERROR res=%x(%s)\n", res, ExplainDDError(res)); res=lpddC->SetHWnd(0, dxw.GethWnd()); - if (res) OutTraceE("CreateSurface: SetHWnd ERROR res=%x(%s)\n", res, ExplainDDError(res)); + if (res) OutTraceE("BuildRealSurfaces: SetHWnd ERROR res=%x(%s)\n", res, ExplainDDError(res)); res=lpDDSEmu_Prim->SetClipper(lpddC); - if (res) OutTraceE("CreateSurface: SetClipper ERROR res=%x(%s)\n", res, ExplainDDError(res)); + if (res) OutTraceE("BuildRealSurfaces: SetClipper ERROR res=%x(%s)\n", res, ExplainDDError(res)); } // can't hook lpDDSEmu_Prim as generic, since the Flip method is unimplemented for a PRIMARY surface! // better avoid it or hook just useful methods. @@ -146,19 +146,19 @@ static void BuildRealSurfaces(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurfa ddsd.dwHeight = dxw.GetScreenHeight() << 1; } - OutTraceDW("CreateSurface: %s\n", LogSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[EmuBack]", __LINE__)); + OutTraceDW("BuildRealSurfaces: %s\n", LogSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[EmuBack]", __LINE__)); res=(*pCreateSurface)(lpdd, &ddsd, &lpDDSEmu_Back, 0); if(res) { ddsd.ddsCaps.dwCaps &= ~DDSCAPS_SYSTEMMEMORY; - OutTraceDW("CreateSurface: %s\n", LogSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[EmuBack]", __LINE__)); + OutTraceDW("BuildRealSurfaces: %s\n", LogSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[EmuBack]", __LINE__)); res=(*pCreateSurface)(lpdd, &ddsd, &lpDDSEmu_Back, 0); } if(res){ - OutTraceE("CreateSurface: CreateSurface ERROR on DDSEmuBack : res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + OutTraceE("BuildRealSurfaces: CreateSurface ERROR on DDSEmuBack : res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); if(res==DDERR_INVALIDPIXELFORMAT) DumpPixFmt(&ddsd); return; } - OutTraceDW("CreateSurface: created new DDSEmu_Back=%x\n", lpDDSEmu_Back); + OutTraceDW("BuildRealSurfaces: created new DDSEmu_Back=%x\n", lpDDSEmu_Back); if(IsDebug) DescribeSurface(lpDDSEmu_Back, dxversion, "DDSEmu_Back", __LINE__); dxwss.PopSurface(lpDDSEmu_Back); //if (dxw.dwTFlags & OUTPROXYTRACE) HookDDSurfaceGeneric(&lpDDSEmu_Back, dxversion); @@ -190,7 +190,7 @@ static HRESULT BuildPrimaryEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf DDSURFACEDESC2 ddsd; HRESULT res; - OutTraceDW("DEBUG: BuildPrimaryEmu: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); + OutTraceDW("BuildPrimaryEmu: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); // emulated primary surface memcpy((void *)&ddsd, lpddsd, lpddsd->dwSize); @@ -200,7 +200,7 @@ static HRESULT BuildPrimaryEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf // then save it dxw.VirtualPixelFormat = ddsd.ddpfPixelFormat; - OutTraceDW("DDSD_PIXELFORMAT: color=%d flags=%x\n", dxw.VirtualPixelFormat.dwRGBBitCount, dxw.VirtualPixelFormat.dwFlags); + OutTraceDW("BuildPrimaryEmu: DDSD_PIXELFORMAT color=%d flags=%x\n", dxw.VirtualPixelFormat.dwRGBBitCount, dxw.VirtualPixelFormat.dwFlags); ddsd.dwFlags &= ~(DDSD_BACKBUFFERCOUNT|DDSD_REFRESHRATE); ddsd.dwFlags |= (DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT); ddsd.ddsCaps.dwCaps &= ~(DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP|DDSCAPS_COMPLEX|DDSCAPS_VIDEOMEMORY|DDSCAPS_LOCALVIDMEM); @@ -213,16 +213,16 @@ static HRESULT BuildPrimaryEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf ddsd.dwHeight = dxw.GetScreenHeight(); // create Primary surface - OutTraceDW("CreateSurface: %s\n", LogSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Primary]" , __LINE__)); + OutTraceDW("BuildPrimaryEmu: %s\n", LogSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Primary]" , __LINE__)); res=(*pCreateSurface)(lpdd, &ddsd, lplpdds, 0); if(res){ - OutTraceE("CreateSurface: ERROR on DDSPrim res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + OutTraceE("BuildPrimaryEmu: CreateSurface ERROR on DDSPrim res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); if(res==DDERR_INVALIDPIXELFORMAT) DumpPixFmt(&ddsd); return res; } iBakBufferVersion=dxversion; // v2.03.01 - OutTraceDW("CreateSurface: created PRIMARY DDSPrim=%x\n", *lplpdds); + OutTraceDW("BuildPrimaryEmu: created PRIMARY DDSPrim=%x\n", *lplpdds); if(IsDebug) DescribeSurface(*lplpdds, dxversion, "DDSPrim", __LINE__); HookDDSurface(lplpdds, dxversion, TRUE); // "Hoyle Casino Empire" opens a primary surface and NOT a backbuffer .... @@ -232,12 +232,12 @@ static HRESULT BuildPrimaryEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf (dxw.dwFlags6 & SYNCPALETTE)){ if(lpDDP == NULL){ res=(*pCreatePaletteMethod(dxversion))(lpdd, DDPCAPS_8BIT|DDPCAPS_ALLOW256, DefaultSystemPalette, &lpDDP, NULL); - if(res) OutTrace("CreateSurface: CreatePalette ERROR err=%x at %d\n", res, __LINE__); + if(res) OutTrace("BuildPrimaryEmu: CreatePalette ERROR err=%x at %d\n", res, __LINE__); } // this must be done after hooking - who knows why? res=(*pSetPaletteMethod(dxversion))(*lplpdds, lpDDP); if(res) { - OutTraceE("CreateSurface: SetPalette ERROR err=%x at %d\n", res, __LINE__); + OutTraceE("BuildPrimaryEmu: SetPalette ERROR err=%x at %d\n", res, __LINE__); } else iDDPExtraRefCounter++; } @@ -263,7 +263,7 @@ static HRESULT BuildPrimaryFlippable(LPDIRECTDRAW lpdd, CreateSurface_Type pCrea DDSURFACEDESC2 ddsd; HRESULT res; - OutTraceDW("DEBUG: BuildPrimaryFlippable: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); + OutTraceDW("BuildPrimaryFlippable: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); // emulated primary surface memcpy((void *)&ddsd, lpddsd, lpddsd->dwSize); @@ -273,7 +273,7 @@ static HRESULT BuildPrimaryFlippable(LPDIRECTDRAW lpdd, CreateSurface_Type pCrea // then save it dxw.VirtualPixelFormat = ddsd.ddpfPixelFormat; - OutTraceDW("DDSD_PIXELFORMAT: color=%d flags=%x\n", dxw.VirtualPixelFormat.dwRGBBitCount, dxw.VirtualPixelFormat.dwFlags); + OutTraceDW("BuildPrimaryFlippable: DDSD_PIXELFORMAT color=%d flags=%x\n", dxw.VirtualPixelFormat.dwRGBBitCount, dxw.VirtualPixelFormat.dwFlags); // dwFlags ddsd.dwFlags &= ~(DDSD_REFRESHRATE); @@ -293,16 +293,16 @@ static HRESULT BuildPrimaryFlippable(LPDIRECTDRAW lpdd, CreateSurface_Type pCrea ddsd.dwHeight = dxw.GetScreenHeight(); // create Primary surface - OutTraceDW("CreateSurface: %s\n", LogSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Primary]" , __LINE__)); + OutTraceDW("BuildPrimaryFlippable: %s\n", LogSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Primary]" , __LINE__)); res=(*pCreateSurface)(lpdd, &ddsd, lplpdds, 0); if(res){ - OutTraceE("CreateSurface: ERROR on DDSPrim res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + OutTraceE("BuildPrimaryFlippable: CreateSurface ERROR on DDSPrim res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); if(res==DDERR_INVALIDPIXELFORMAT) DumpPixFmt(&ddsd); return res; } iBakBufferVersion=dxversion; // v2.03.01 - OutTraceDW("CreateSurface: created PRIMARY DDSPrim=%x\n", *lplpdds); + OutTraceDW("BuildPrimaryFlippable: created PRIMARY DDSPrim=%x\n", *lplpdds); if(IsDebug) DescribeSurface(*lplpdds, dxversion, "DDSPrim", __LINE__); HookDDSurface(lplpdds, dxversion, TRUE); // "Hoyle Casino Empire" opens a primary surface and NOT a backbuffer .... @@ -312,12 +312,12 @@ static HRESULT BuildPrimaryFlippable(LPDIRECTDRAW lpdd, CreateSurface_Type pCrea (dxw.dwFlags6 & SYNCPALETTE)){ if(lpDDP == NULL){ res=(*pCreatePaletteMethod(dxversion))(lpdd, DDPCAPS_8BIT|DDPCAPS_ALLOW256, DefaultSystemPalette, &lpDDP, NULL); - if(res) OutTrace("CreateSurface: CreatePalette ERROR err=%x at %d\n", res, __LINE__); + if(res) OutTrace("BuildPrimaryFlippable: CreatePalette ERROR err=%x at %d\n", res, __LINE__); } // this must be done after hooking - who knows why? res=(*pSetPaletteMethod(dxversion))(*lplpdds, lpDDP); if(res) { - OutTraceE("CreateSurface: SetPalette ERROR err=%x at %d\n", res, __LINE__); + OutTraceE("BuildPrimaryFlippable: SetPalette ERROR err=%x at %d\n", res, __LINE__); } else iDDPExtraRefCounter++; } @@ -341,12 +341,12 @@ static HRESULT BuildPrimaryFullscreen(LPDIRECTDRAW lpdd, CreateSurface_Type pCre DDSURFACEDESC2 ddsd; HRESULT res; - OutTraceDW("DEBUG: BuildPrimaryFullscreen: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); + OutTraceDW("BuildPrimaryFullscreen: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); // genuine primary surface memcpy((void *)&ddsd, lpddsd, lpddsd->dwSize); // create Primary surface - OutTraceDW("CreateSurface: %s\n", LogSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Primary]", __LINE__)); + OutTraceDW("BuildPrimaryFullscreen: %s\n", LogSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Primary]", __LINE__)); res=(*pCreateSurface)(lpdd, &ddsd, lplpdds, 0); if(res){ if (res==DDERR_PRIMARYSURFACEALREADYEXISTS){ @@ -360,20 +360,20 @@ static HRESULT BuildPrimaryFullscreen(LPDIRECTDRAW lpdd, CreateSurface_Type pCre case 4: pGetGDISurface = pGetGDISurface4; break; case 7: pGetGDISurface = pGetGDISurface7; break; } - OutTraceE("CreateSurface: CreateSurface DDERR_PRIMARYSURFACEALREADYEXISTS workaround\n"); + OutTraceE("BuildPrimaryFullscreen: CreateSurface DDERR_PRIMARYSURFACEALREADYEXISTS workaround\n"); (*pGetGDISurface)(lpPrimaryDD, &lpPrim); while ((*pReleaseSMethod(dxversion))(lpPrim)); res = (*pCreateSurface)(lpdd, &ddsd, lplpdds, 0); } /* fall through */ if(res){ - OutTraceE("CreateSurface: ERROR on DDSPrim res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + OutTraceE("BuildPrimaryFullscreen: CreateSurface ERROR on DDSPrim res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); if(res==DDERR_INVALIDPIXELFORMAT) DumpPixFmt(&ddsd); return res; } } - OutTraceDW("CreateSurface: created PRIMARY DDSPrim=%x\n", *lplpdds); + OutTraceDW("BuildPrimaryFullscreen: created PRIMARY DDSPrim=%x\n", *lplpdds); if(IsDebug) DescribeSurface(*lplpdds, dxversion, "DDSPrim", __LINE__); iBakBufferVersion=dxversion; @@ -388,7 +388,7 @@ static HRESULT BuildPrimaryDir(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf DDSURFACEDESC2 ddsd; HRESULT res; - OutTraceDW("DEBUG: BuildPrimaryDir: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); + OutTraceDW("BuildPrimaryDir: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); // genuine primary surface memcpy((void *)&ddsd, lpddsd, lpddsd->dwSize); // v2.03.98 - when going to fullscreen mode and no emulation do not alter the capability masks, or in other words ... @@ -400,7 +400,7 @@ static HRESULT BuildPrimaryDir(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf if ((lpddsd->dwFlags & DDSD_CAPS) && (lpddsd->ddsCaps.dwCaps & DDSCAPS_3DDEVICE)) ddsd.ddsCaps.dwCaps &= ~DDSCAPS_SYSTEMMEMORY; // create Primary surface - OutTraceDW("CreateSurface: %s\n", LogSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Primary]", __LINE__)); + OutTraceDW("BuildPrimaryDir: %s\n", LogSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Primary]", __LINE__)); res=(*pCreateSurface)(lpdd, &ddsd, lplpdds, 0); if(res){ if (res==DDERR_PRIMARYSURFACEALREADYEXISTS){ @@ -414,20 +414,20 @@ static HRESULT BuildPrimaryDir(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf case 4: pGetGDISurface = pGetGDISurface4; break; case 7: pGetGDISurface = pGetGDISurface7; break; } - OutTraceE("CreateSurface: CreateSurface DDERR_PRIMARYSURFACEALREADYEXISTS workaround\n"); + OutTraceE("BuildPrimaryDir: CreateSurface DDERR_PRIMARYSURFACEALREADYEXISTS workaround\n"); (*pGetGDISurface)(lpPrimaryDD, &lpPrim); while ((*pReleaseSMethod(dxversion))(lpPrim)); res = (*pCreateSurface)(lpdd, &ddsd, lplpdds, 0); } /* fall through */ if(res){ - OutTraceE("CreateSurface: ERROR on DDSPrim res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + OutTraceE("BuildPrimaryDir: CreateSurface ERROR on DDSPrim res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); if(res==DDERR_INVALIDPIXELFORMAT) DumpPixFmt(&ddsd); return res; } } - OutTraceDW("CreateSurface: created PRIMARY DDSPrim=%x\n", *lplpdds); + OutTraceDW("BuildPrimaryDir: created PRIMARY DDSPrim=%x\n", *lplpdds); if(IsDebug) DescribeSurface(*lplpdds, dxversion, "DDSPrim", __LINE__); if(dxw.dwFlags1 & EMULATEBUFFER){ @@ -440,13 +440,13 @@ static HRESULT BuildPrimaryDir(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf ddsd.dwHeight = dxw.GetScreenHeight(); ddsd.ddsCaps.dwCaps = 0; if (dxversion >= 4) ddsd.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN; - OutTraceDW("CreateSurface: %s\n", LogSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Dir FixBuf]", __LINE__)); + OutTraceDW("BuildPrimaryDir: %s\n", LogSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Dir FixBuf]", __LINE__)); res=(*pCreateSurface)(lpdd, &ddsd, lplpdds, 0); if(res){ - OutTraceE("CreateSurface: ERROR on DDSPrim res=%x(%s) at %d\n",res, ExplainDDError(res), __LINE__); + OutTraceE("BuildPrimaryDir: CreateSurface ERROR on DDSPrim res=%x(%s) at %d\n",res, ExplainDDError(res), __LINE__); return res; } - OutTraceDW("CreateSurface: created FIX DDSPrim=%x\n", *lplpdds); + OutTraceDW("BuildPrimaryDir: created FIX DDSPrim=%x\n", *lplpdds); if(IsDebug) DescribeSurface(*lplpdds, dxversion, "DDSPrim(2)", __LINE__); } @@ -462,7 +462,7 @@ static HRESULT BuildBackBufferEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateS DDSURFACEDESC2 ddsd; HRESULT res; - OutTraceDW("DEBUG: BuildBackBufferEmu: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); + OutTraceDW("BuildBackBufferEmu: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); // create BackBuffer surface memcpy(&ddsd, lpddsd, lpddsd->dwSize); ddsd.dwFlags &= ~(DDSD_BACKBUFFERCOUNT|DDSD_REFRESHRATE); @@ -481,15 +481,15 @@ static HRESULT BuildBackBufferEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateS ddsd.dwHeight = dxw.GetScreenHeight(); GetPixFmt(&ddsd); - OutTraceDW("CreateSurface: %s\n", LogSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Backbuf]", __LINE__)); + OutTraceDW("BuildBackBufferEmu: %s\n", LogSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Backbuf]", __LINE__)); res=(*pCreateSurface)(lpdd, &ddsd, lplpdds, 0); if(res) { - OutTraceE("CreateSurface ERROR: res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + OutTraceE("BuildBackBufferEmu: CreateSurface ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); if(res==DDERR_INVALIDPIXELFORMAT) DumpPixFmt(&ddsd); return res; } - OutTraceDW("CreateSurface: created BACK DDSBack=%x\n", *lplpdds); + OutTraceDW("BuildBackBufferEmu: created BACK DDSBack=%x\n", *lplpdds); if(IsDebug) DescribeSurface(*lplpdds, dxversion, "DDSBack", __LINE__); HookDDSurface(lplpdds, dxversion, FALSE); // added !!! iBakBufferVersion=dxversion; // v2.02.31 @@ -498,12 +498,12 @@ static HRESULT BuildBackBufferEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateS (dxw.dwFlags6 & SYNCPALETTE)){ if(lpDDP == NULL){ res=(*pCreatePaletteMethod(dxversion))(lpdd, DDPCAPS_8BIT|DDPCAPS_ALLOW256, DefaultSystemPalette, &lpDDP, NULL); - if(res) OutTrace("CreateSurface: CreatePalette ERROR err=%x at %d\n", res, __LINE__); + if(res) OutTrace("BuildBackBufferEmu: CreatePalette ERROR err=%x at %d\n", res, __LINE__); } // this must be done after hooking - who knows why? res=(*pSetPaletteMethod(dxversion))(*lplpdds, lpDDP); if(res) { - OutTraceE("CreateSurface: SetPalette ERROR err=%x at %d\n", res, __LINE__); + OutTraceE("BuildBackBufferEmu: SetPalette ERROR err=%x at %d\n", res, __LINE__); } else iDDPExtraRefCounter++; } @@ -524,7 +524,7 @@ static HRESULT BuildBackBufferFlippable(LPDIRECTDRAW lpdd, CreateSurface_Type pC DDSURFACEDESC2 ddsd; HRESULT res; - OutTraceDW("DEBUG: BuildBackBufferFlippable: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); + OutTraceDW("BuildBackBufferFlippable: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); //MessageBox(NULL, "BuildBackBufferFlippable", "DxWnd", MB_OK); // create BackBuffer surface @@ -540,15 +540,15 @@ static HRESULT BuildBackBufferFlippable(LPDIRECTDRAW lpdd, CreateSurface_Type pC ddsd.dwHeight = dxw.GetScreenHeight(); GetPixFmt(&ddsd); - OutTraceDW("CreateSurface: %s\n", LogSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Backbuf]", __LINE__)); + OutTraceDW("BuildBackBufferFlippable: %s\n", LogSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Backbuf]", __LINE__)); res=(*pCreateSurface)(lpdd, &ddsd, lplpdds, 0); if(res) { - OutTraceE("CreateSurface ERROR: res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + OutTraceE("BuildBackBufferFlippable: CreateSurface ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); if(res==DDERR_INVALIDPIXELFORMAT) DumpPixFmt(&ddsd); return res; } - OutTraceDW("CreateSurface: created BACK DDSBack=%x\n", *lplpdds); + OutTraceDW("BuildBackBufferFlippable: created BACK DDSBack=%x\n", *lplpdds); if(IsDebug) DescribeSurface(*lplpdds, dxversion, "DDSBack", __LINE__); HookDDSurface(lplpdds, dxversion, FALSE); // added !!! iBakBufferVersion=dxversion; // v2.02.31 @@ -557,12 +557,12 @@ static HRESULT BuildBackBufferFlippable(LPDIRECTDRAW lpdd, CreateSurface_Type pC (dxw.dwFlags6 & SYNCPALETTE)){ if(lpDDP == NULL){ res=(*pCreatePaletteMethod(dxversion))(lpdd, DDPCAPS_8BIT|DDPCAPS_ALLOW256, DefaultSystemPalette, &lpDDP, NULL); - if(res) OutTrace("CreateSurface: CreatePalette ERROR err=%x at %d\n", res, __LINE__); + if(res) OutTrace("BuildBackBufferFlippable: CreatePalette ERROR err=%x at %d\n", res, __LINE__); } // this must be done after hooking - who knows why? res=(*pSetPaletteMethod(dxversion))(*lplpdds, lpDDP); if(res) { - OutTraceE("CreateSurface: SetPalette ERROR err=%x at %d\n", res, __LINE__); + OutTraceE("BuildBackBufferFlippable: SetPalette ERROR err=%x at %d\n", res, __LINE__); } else iDDPExtraRefCounter++; } @@ -574,7 +574,7 @@ static HRESULT AttachBackBufferFlippable(LPDIRECTDRAW lpdd, CreateSurface_Type p { HRESULT res; LPDIRECTDRAWSURFACE lpDDSPrim; - OutTraceDW("DEBUG: AttachBackBufferFlippable: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); + OutTraceDW("AttachBackBufferFlippable: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); // retrieve the attached backbuffer surface and hook it @@ -594,11 +594,11 @@ static HRESULT AttachBackBufferFlippable(LPDIRECTDRAW lpdd, CreateSurface_Type p lpDDSPrim = dxwss.GetPrimarySurface(); res = (*pGetAttachedSurface)(lpDDSPrim, (LPDDSCAPS)&caps, lplpdds); if(res){ - OutTraceE("CreateSurface: GetAttachedSurface ERROR on DDSPrim res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + OutTraceE("AttachBackBufferFlippable: GetAttachedSurface ERROR on DDSPrim res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); return res; } - OutTraceDW("CreateSurface: retrieved BACK DDSBack=%x\n", *lplpdds); + OutTraceDW("AttachBackBufferFlippable: retrieved BACK DDSBack=%x\n", *lplpdds); if(IsDebug) DescribeSurface(*lplpdds, dxversion, "DDSBack", __LINE__); HookDDSurface(lplpdds, dxversion, FALSE); // added !!! iBakBufferVersion=dxversion; // v2.02.31 @@ -608,13 +608,13 @@ static HRESULT AttachBackBufferFlippable(LPDIRECTDRAW lpdd, CreateSurface_Type p static HRESULT BuildBackBufferFullscreen(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurface, LPDDSURFACEDESC2 lpddsd, int dxversion, LPDIRECTDRAWSURFACE *lplpdds, void *pu) { - OutTraceDW("DEBUG: BuildBackBufferFullscreen: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); + OutTraceDW("BuildBackBufferFullscreen: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); return DD_OK; } static HRESULT AttachBackBufferFullscreen(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurface, LPDDSURFACEDESC2 lpddsd, int dxversion, LPDIRECTDRAWSURFACE *lplpdds, void *pu) { - OutTraceDW("DEBUG: AttachBackBufferFullscreen: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); + OutTraceDW("AttachBackBufferFullscreen: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); return DD_OK; } @@ -623,7 +623,7 @@ static HRESULT BuildBackBufferDir(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateS DDSURFACEDESC2 ddsd; HRESULT res; - OutTraceDW("DEBUG: BuildBackBufferDir: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); + OutTraceDW("BuildBackBufferDir: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); // create BackBuffer surface // ClearSurfaceDesc((void *)&ddsd, dxversion); memcpy(&ddsd, lpddsd, lpddsd->dwSize); @@ -664,24 +664,24 @@ static HRESULT BuildBackBufferDir(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateS (*pReleaseSMethod(dxversion))(lpPrim); ddsd.dwWidth = prim.dwWidth; ddsd.dwHeight = prim.dwHeight; - OutTraceDW("BMX FIX: res=%x(%s) wxh=(%dx%d)\n", res, ExplainDDError(res),ddsd.dwWidth, ddsd.dwHeight); + OutTraceDW("BuildBackBufferDir: BMX FIX res=%x(%s) wxh=(%dx%d)\n", res, ExplainDDError(res),ddsd.dwWidth, ddsd.dwHeight); } - OutTraceDW("CreateSurface: %s\n", LogSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Backbuf]", __LINE__)); + OutTraceDW("BuildBackBufferDir: %s\n", LogSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Backbuf]", __LINE__)); res=(*pCreateSurface)(lpdd, &ddsd, lplpdds, 0); if(res) { if ((dxw.dwFlags1 & SWITCHVIDEOMEMORY) && (res==DDERR_OUTOFVIDEOMEMORY)){ - OutTraceDW("CreateSurface: CreateSurface DDERR_OUTOFVIDEOMEMORY ERROR at %d, retry in SYSTEMMEMORY\n", __LINE__); + OutTraceDW("BuildBackBufferDir: CreateSurface DDERR_OUTOFVIDEOMEMORY ERROR at %d, retry in SYSTEMMEMORY\n", __LINE__); ddsd.ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY; ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; res=(*pCreateSurface)(lpdd, &ddsd, lplpdds, 0); } if(res){ - OutTraceE("CreateSurface ERROR: res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + OutTraceE("BuildBackBufferDir: CreateSurface ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); return res; } } - OutTraceDW("CreateSurface: created BACK DDSBack=%x\n", *lplpdds); + OutTraceDW("BuildBackBufferDir: created BACK DDSBack=%x\n", *lplpdds); if(IsDebug) DescribeSurface(*lplpdds, dxversion, "DDSBack", __LINE__); HookDDSurface(lplpdds, dxversion, FALSE); // added !!! iBakBufferVersion=dxversion; // v2.02.31 @@ -694,7 +694,7 @@ static HRESULT BuildGenericEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf DDSURFACEDESC2 ddsd; HRESULT res; - OutTraceDW("DEBUG: BuildGenericEmu: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); + OutTraceDW("BuildGenericEmu: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); memcpy(&ddsd, lpddsd, lpddsd->dwSize); // Copy over .... FixSurfaceCaps(&ddsd, dxversion); // It looks that DDSCAPS_SYSTEMMEMORY surfaces can perfectly be DDSCAPS_3DDEVICE as well. @@ -708,24 +708,24 @@ static HRESULT BuildGenericEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf ){ DWORD dwWidth; dwWidth = ((ddsd.dwWidth + 3) >> 2) << 2; - if(dwWidth != ddsd.dwWidth) OutTraceDW("CreateSurface: fixed surface width %d->%d\n", ddsd.dwWidth, dwWidth); + if(dwWidth != ddsd.dwWidth) OutTraceDW("BuildGenericEmu: POWER2WIDTH fix surface width %d->%d\n", ddsd.dwWidth, dwWidth); ddsd.dwWidth = dwWidth; } } res=(*pCreateSurface)(lpdd, &ddsd, lplpdds, pu); if ((dxw.dwFlags1 & SWITCHVIDEOMEMORY) && (res!=DD_OK)){ - OutTraceDW("CreateSurface ERROR: res=%x(%s) at %d, retry\n", res, ExplainDDError(res), __LINE__); + OutTraceDW("BuildGenericEmu: CreateSurface ERROR res=%x(%s) at %d, retry\n", res, ExplainDDError(res), __LINE__); ddsd.ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY; ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; res=(*pCreateSurface)(lpdd, &ddsd, lplpdds, pu); } if (res) { - OutTraceE("CreateSurface: ERROR on Emu_Generic res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + OutTraceE("BuildGenericEmu: CreateSurface ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); return res; } - OutTraceDW("CreateSurface: CREATED lpddsd=%x version=%d %s\n", + OutTraceDW("BuildGenericEmu: CREATED lpddsd=%x version=%d %s\n", *lplpdds, dxversion, LogSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Emu Generic]", __LINE__)); // v2.02.66: if 8BPP paletized surface and a primary palette exixts, apply. @@ -733,9 +733,9 @@ static HRESULT BuildGenericEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf if(lpDDP && (ddsd.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8)){ res=(*pSetPaletteMethod(dxversion))(*lplpdds, lpDDP); if(res) - OutTraceE("SetPalette: ERROR on lpdds=%x(Emu_Generic) res=%x(%s) at %d\n", *lplpdds, res, ExplainDDError(res), __LINE__); + OutTraceE("BuildGenericEmu: SetPalette ERROR lpdds=%x res=%x(%s) at %d\n", *lplpdds, res, ExplainDDError(res), __LINE__); else { - OutTraceDW("CreateSurface: applied lpddp=%x to lpdds=%x\n", lpDDP, *lplpdds); + OutTraceDW("BuildGenericEmu: applied palette lpddp=%x to lpdds=%x\n", lpDDP, *lplpdds); iDDPExtraRefCounter++; } } @@ -751,7 +751,7 @@ static HRESULT BuildGenericFlippable(LPDIRECTDRAW lpdd, CreateSurface_Type pCrea DDSURFACEDESC2 ddsd; HRESULT res; - OutTraceDW("DEBUG: BuildGenericFlippable: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); + OutTraceDW("BuildGenericFlippable: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); memcpy(&ddsd, lpddsd, lpddsd->dwSize); // Copy over .... FixSurfaceCaps(&ddsd, dxversion); @@ -761,24 +761,24 @@ static HRESULT BuildGenericFlippable(LPDIRECTDRAW lpdd, CreateSurface_Type pCrea ){ DWORD dwWidth; dwWidth = ((ddsd.dwWidth + 3) >> 2) << 2; - if(dwWidth != ddsd.dwWidth) OutTraceDW("CreateSurface: fixed surface width %d->%d\n", ddsd.dwWidth, dwWidth); + if(dwWidth != ddsd.dwWidth) OutTraceDW("BuildGenericFlippable: POWER2WIDTH fix surface width %d->%d\n", ddsd.dwWidth, dwWidth); ddsd.dwWidth = dwWidth; } } res=(*pCreateSurface)(lpdd, &ddsd, lplpdds, pu); if ((dxw.dwFlags1 & SWITCHVIDEOMEMORY) && (res!=DD_OK)){ - OutTraceDW("CreateSurface ERROR: res=%x(%s) at %d, retry\n", res, ExplainDDError(res), __LINE__); + OutTraceDW("BuildGenericFlippable: CreateSurface ERROR res=%x(%s) at %d, retry\n", res, ExplainDDError(res), __LINE__); ddsd.ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY; ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; res=(*pCreateSurface)(lpdd, &ddsd, lplpdds, pu); } if (res) { - OutTraceE("CreateSurface: ERROR on Emu_Generic res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + OutTraceE("BuildGenericFlippable: CreateSurface ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); return res; } - OutTraceDW("CreateSurface: CREATED lpddsd=%x version=%d %s\n", + OutTraceDW("BuildGenericFlippable: CREATED lpddsd=%x version=%d %s\n", *lplpdds, dxversion, LogSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Emu Generic]", __LINE__)); // v2.02.66: if 8BPP paletized surface and a primary palette exixts, apply. @@ -786,9 +786,9 @@ static HRESULT BuildGenericFlippable(LPDIRECTDRAW lpdd, CreateSurface_Type pCrea if(lpDDP && (ddsd.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8)){ res=(*pSetPaletteMethod(dxversion))(*lplpdds, lpDDP); if(res) - OutTraceE("SetPalette: ERROR on lpdds=%x(Emu_Generic) res=%x(%s) at %d\n", *lplpdds, res, ExplainDDError(res), __LINE__); + OutTraceE("BuildGenericFlippable: SetPalette ERROR on lpdds=%x res=%x(%s) at %d\n", *lplpdds, res, ExplainDDError(res), __LINE__); else { - OutTraceDW("CreateSurface: applied lpddp=%x to lpdds=%x\n", lpDDP, *lplpdds); + OutTraceDW("BuildGenericFlippable: applied palette lpddp=%x to lpdds=%x\n", lpDDP, *lplpdds); iDDPExtraRefCounter++; } } @@ -803,25 +803,25 @@ static HRESULT BuildGenericDir(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf { HRESULT res; - OutTraceDW("DEBUG: BuildGenericDir: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); - OutTraceDW("CreateSurface: %s\n", LogSurfaceAttributes((LPDDSURFACEDESC)lpddsd, "[Dir Generic]", __LINE__)); + OutTraceDW("BuildGenericDir: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); + OutTraceDW("BuildGenericDir: %s\n", LogSurfaceAttributes((LPDDSURFACEDESC)lpddsd, "[Dir Generic]", __LINE__)); res = (*pCreateSurface)(lpdd, lpddsd, lplpdds, 0); if(res){ // v2.02.60: Ref. game Incoming GOG release, post by Marek, error DDERR_UNSUPPORTED while trying to create ZBUFFER surface if ((dxw.dwFlags1 & SWITCHVIDEOMEMORY) && ((res==DDERR_OUTOFVIDEOMEMORY)||(res==DDERR_UNSUPPORTED))){ - OutTraceDW("CreateSurface ERROR: res=%x(%s) at %d, retry\n", res, ExplainDDError(res), __LINE__); + OutTraceDW("BuildGenericDir: CreateSurface ERROR res=%x(%s) at %d, retry\n", res, ExplainDDError(res), __LINE__); lpddsd->ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY; lpddsd->ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; res = (*pCreateSurface)(lpdd, lpddsd, lplpdds, 0); } if(res){ - OutTraceE("CreateSurface: CreateSurface ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + OutTraceE("BuildGenericDir: CreateSurface ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); return res; } } - OutTraceDW("CreateSurface: CREATED lpddsd=%x version=%d %s\n", + OutTraceDW("BuildGenericDir: CREATED lpddsd=%x version=%d %s\n", *lplpdds, dxversion, LogSurfaceAttributes((LPDDSURFACEDESC)lpddsd, "[Dir Generic]", __LINE__)); // hooks .... @@ -1037,8 +1037,9 @@ HRESULT WINAPI extCreateSurface(int dxversion, CreateSurface_Type pCreateSurface dxwss.PopSurface(*lplpdds); if(lpddsd->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) { // v2.03.82: save ZBUFFER capabilities for later fix in D3D CreateDevice - if(lpddsd->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) dxwcdb.PushCaps(*lplpdds, lpddsd->ddsCaps.dwCaps); OutTraceDW("CreateSurface: lpDDZBuffer=%x save ZBUFFER caps=%x(%s)\n", *lplpdds, lpddsd->ddsCaps.dwCaps, ExplainDDSCaps(lpddsd->ddsCaps.dwCaps)); + lpDDZBuffer = *lplpdds; + dxwcdb.PushCaps(*lplpdds, lpddsd->ddsCaps.dwCaps); } } diff --git a/dll/ddraw.cpp b/dll/ddraw.cpp index 6439d92..ae63747 100644 --- a/dll/ddraw.cpp +++ b/dll/ddraw.cpp @@ -76,6 +76,11 @@ HRESULT WINAPI extCreateSurface2(LPDIRECTDRAW, DDSURFACEDESC *, LPDIRECTDRAWSURF HRESULT WINAPI extCreateSurface3(LPDIRECTDRAW, DDSURFACEDESC *, LPDIRECTDRAWSURFACE *, void *); HRESULT WINAPI extCreateSurface4(LPDIRECTDRAW, DDSURFACEDESC2 *, LPDIRECTDRAWSURFACE *, void *); HRESULT WINAPI extCreateSurface7(LPDIRECTDRAW, DDSURFACEDESC2 *, LPDIRECTDRAWSURFACE *, void *); +HRESULT WINAPI extDuplicateSurface1(LPDIRECTDRAW, LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE FAR *); +HRESULT WINAPI extDuplicateSurface2(LPDIRECTDRAW, LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE FAR *); +HRESULT WINAPI extDuplicateSurface3(LPDIRECTDRAW, LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE FAR *); +HRESULT WINAPI extDuplicateSurface4(LPDIRECTDRAW, LPDIRECTDRAWSURFACE4, LPDIRECTDRAWSURFACE4 FAR *); +HRESULT WINAPI extDuplicateSurface7(LPDIRECTDRAW, LPDIRECTDRAWSURFACE7, LPDIRECTDRAWSURFACE7 FAR *); HRESULT WINAPI extFlipToGDISurface1(LPDIRECTDRAW); HRESULT WINAPI extFlipToGDISurface2(LPDIRECTDRAW); HRESULT WINAPI extFlipToGDISurface3(LPDIRECTDRAW); @@ -314,6 +319,9 @@ Compact_Type pCompact; CreateClipper_Type pCreateClipper1, pCreateClipper2, pCreateClipper3, pCreateClipper4, pCreateClipper7; CreatePalette_Type pCreatePalette1, pCreatePalette2, pCreatePalette3, pCreatePalette4, pCreatePalette7; CreateSurface1_Type pCreateSurface1, pCreateSurface2, pCreateSurface3, pCreateSurface4, pCreateSurface7; +DuplicateSurface_Type pDuplicateSurface1, pDuplicateSurface2, pDuplicateSurface3; +DuplicateSurface4_Type pDuplicateSurface4; +DuplicateSurface7_Type pDuplicateSurface7; EnumDisplayModes1_Type pEnumDisplayModes1, pEnumDisplayModes2, pEnumDisplayModes3; EnumDisplayModes4_Type pEnumDisplayModes4, pEnumDisplayModes7; EnumSurfaces1_Type pEnumSurfaces1; @@ -416,7 +424,7 @@ GammaRamp_Type pDDSetGammaRamp; extern PALETTEENTRY DefaultSystemPalette[256]; LPDIRECTDRAWSURFACE lpDDSEmu_Prim=NULL; LPDIRECTDRAWSURFACE lpDDSEmu_Back=NULL; -LPDIRECTDRAWSURFACE lpDDZBuffer=NULL; +LPDIRECTDRAWSURFACE lpDDZBuffer=NULL; // BEWARE! Likely, this global is useless .... // v2.1.87: lpPrimaryDD is the DIRECTDRAW object to which the primary surface and all // the service objects (emulated backbuffer, emulater primary, ....) are attached. LPDIRECTDRAW lpPrimaryDD=NULL; @@ -1156,10 +1164,11 @@ void HookDDSession(LPDIRECTDRAW *lplpdd, int dxversion) switch(dxversion) { case 1: SetHook((void *)(**(DWORD **)lplpdd), extQueryInterfaceD1, (void **)&pQueryInterfaceD1, "QueryInterface(D1)"); - SetHook((void *)(**(DWORD **)lplpdd + 16), extCreateClipper1, (void **)&pCreateClipper1, "CreateClipper(D1)"); SetHook((void *)(**(DWORD **)lplpdd + 8), extReleaseD1, (void **)&pReleaseD1, "Release(D1)"); + SetHook((void *)(**(DWORD **)lplpdd + 16), extCreateClipper1, (void **)&pCreateClipper1, "CreateClipper(D1)"); SetHook((void *)(**(DWORD **)lplpdd + 20), extCreatePalette1, (void **)&pCreatePalette1, "CreatePalette(D1)"); SetHook((void *)(**(DWORD **)lplpdd + 24), extCreateSurface1, (void **)&pCreateSurface1, "CreateSurface(D1)"); + SetHook((void *)(**(DWORD **)lplpdd + 28), extDuplicateSurface1, (void **)&pDuplicateSurface1, "DuplicateSurface(D1)"); SetHook((void *)(**(DWORD **)lplpdd + 32), extEnumDisplayModes1, (void **)&pEnumDisplayModes1, "EnumDisplayModes(D1)"); SetHook((void *)(**(DWORD **)lplpdd + 40), extFlipToGDISurface1, (void **)&pFlipToGDISurface1, "FlipToGDISurface(D1)"); SetHook((void *)(**(DWORD **)lplpdd + 44), extGetCaps1D, (void **)&pGetCaps1D, "GetCaps(D1)"); @@ -1174,10 +1183,11 @@ void HookDDSession(LPDIRECTDRAW *lplpdd, int dxversion) break; case 2: SetHook((void *)(**(DWORD **)lplpdd), extQueryInterfaceD2, (void **)&pQueryInterfaceD2, "QueryInterface(D2)"); - SetHook((void *)(**(DWORD **)lplpdd + 16), extCreateClipper2, (void **)&pCreateClipper2, "CreateClipper(D2)"); SetHook((void *)(**(DWORD **)lplpdd + 8), extReleaseD2, (void **)&pReleaseD2, "Release(D2)"); + SetHook((void *)(**(DWORD **)lplpdd + 16), extCreateClipper2, (void **)&pCreateClipper2, "CreateClipper(D2)"); SetHook((void *)(**(DWORD **)lplpdd + 20), extCreatePalette2, (void **)&pCreatePalette2, "CreatePalette(D2)"); SetHook((void *)(**(DWORD **)lplpdd + 24), extCreateSurface2, (void **)&pCreateSurface2, "CreateSurface(D2)"); + SetHook((void *)(**(DWORD **)lplpdd + 28), extDuplicateSurface2, (void **)&pDuplicateSurface2, "DuplicateSurface(D2)"); SetHook((void *)(**(DWORD **)lplpdd + 32), extEnumDisplayModes2, (void **)&pEnumDisplayModes2, "EnumDisplayModes(D2)"); SetHook((void *)(**(DWORD **)lplpdd + 40), extFlipToGDISurface2, (void **)&pFlipToGDISurface2, "FlipToGDISurface(D2)"); SetHook((void *)(**(DWORD **)lplpdd + 44), extGetCaps2D, (void **)&pGetCaps2D, "GetCaps(D2)"); @@ -1194,10 +1204,11 @@ void HookDDSession(LPDIRECTDRAW *lplpdd, int dxversion) break; case 3: SetHook((void *)(**(DWORD **)lplpdd), extQueryInterfaceD3, (void **)&pQueryInterfaceD3, "QueryInterface(D3)"); - SetHook((void *)(**(DWORD **)lplpdd + 16), extCreateClipper3, (void **)&pCreateClipper3, "CreateClipper(D3)"); SetHook((void *)(**(DWORD **)lplpdd + 8), extReleaseD3, (void **)&pReleaseD3, "Release(D3)"); + SetHook((void *)(**(DWORD **)lplpdd + 16), extCreateClipper3, (void **)&pCreateClipper3, "CreateClipper(D3)"); SetHook((void *)(**(DWORD **)lplpdd + 20), extCreatePalette3, (void **)&pCreatePalette3, "CreatePalette(D3)"); SetHook((void *)(**(DWORD **)lplpdd + 24), extCreateSurface3, (void **)&pCreateSurface3, "CreateSurface(D3)"); + SetHook((void *)(**(DWORD **)lplpdd + 28), extDuplicateSurface3, (void **)&pDuplicateSurface3, "DuplicateSurface(D3)"); SetHook((void *)(**(DWORD **)lplpdd + 32), extEnumDisplayModes3, (void **)&pEnumDisplayModes3, "EnumDisplayModes(D3)"); SetHook((void *)(**(DWORD **)lplpdd + 40), extFlipToGDISurface3, (void **)&pFlipToGDISurface3, "FlipToGDISurface(D3)"); SetHook((void *)(**(DWORD **)lplpdd + 44), extGetCaps3D, (void **)&pGetCaps3D, "GetCaps(D3)"); @@ -1214,10 +1225,11 @@ void HookDDSession(LPDIRECTDRAW *lplpdd, int dxversion) break; case 4: SetHook((void *)(**(DWORD **)lplpdd), extQueryInterfaceD4, (void **)&pQueryInterfaceD4, "QueryInterface(D4)"); - SetHook((void *)(**(DWORD **)lplpdd + 16), extCreateClipper4, (void **)&pCreateClipper4, "CreateClipper(D4)"); SetHook((void *)(**(DWORD **)lplpdd + 8), extReleaseD4, (void **)&pReleaseD4, "Release(D4)"); + SetHook((void *)(**(DWORD **)lplpdd + 16), extCreateClipper4, (void **)&pCreateClipper4, "CreateClipper(D4)"); SetHook((void *)(**(DWORD **)lplpdd + 20), extCreatePalette4, (void **)&pCreatePalette4, "CreatePalette(D4)"); SetHook((void *)(**(DWORD **)lplpdd + 24), extCreateSurface4, (void **)&pCreateSurface4, "CreateSurface(D4)"); + SetHook((void *)(**(DWORD **)lplpdd + 28), extDuplicateSurface4, (void **)&pDuplicateSurface4, "DuplicateSurface(D4)"); SetHook((void *)(**(DWORD **)lplpdd + 32), extEnumDisplayModes4, (void **)&pEnumDisplayModes4, "EnumDisplayModes(D4)"); SetHook((void *)(**(DWORD **)lplpdd + 40), extFlipToGDISurface4, (void **)&pFlipToGDISurface4, "FlipToGDISurface(D4)"); SetHook((void *)(**(DWORD **)lplpdd + 44), extGetCaps4D, (void **)&pGetCaps4D, "GetCaps(D4)"); @@ -1236,10 +1248,11 @@ void HookDDSession(LPDIRECTDRAW *lplpdd, int dxversion) break; case 7: SetHook((void *)(**(DWORD **)lplpdd), extQueryInterfaceD7, (void **)&pQueryInterfaceD7, "QueryInterface(D7)"); - SetHook((void *)(**(DWORD **)lplpdd + 16), extCreateClipper7, (void **)&pCreateClipper7, "CreateClipper(D7)"); SetHook((void *)(**(DWORD **)lplpdd + 8), extReleaseD7, (void **)&pReleaseD7, "Release(D7)"); + SetHook((void *)(**(DWORD **)lplpdd + 16), extCreateClipper7, (void **)&pCreateClipper7, "CreateClipper(D7)"); SetHook((void *)(**(DWORD **)lplpdd + 20), extCreatePalette7, (void **)&pCreatePalette7, "CreatePalette(D7)"); SetHook((void *)(**(DWORD **)lplpdd + 24), extCreateSurface7, (void **)&pCreateSurface7, "CreateSurface(D7)"); + SetHook((void *)(**(DWORD **)lplpdd + 28), extDuplicateSurface7, (void **)&pDuplicateSurface7, "DuplicateSurface(D7)"); SetHook((void *)(**(DWORD **)lplpdd + 32), extEnumDisplayModes7, (void **)&pEnumDisplayModes7, "EnumDisplayModes(D4)"); SetHook((void *)(**(DWORD **)lplpdd + 40), extFlipToGDISurface7, (void **)&pFlipToGDISurface7, "FlipToGDISurface(D7)"); SetHook((void *)(**(DWORD **)lplpdd + 44), extGetCaps7D, (void **)&pGetCaps7D, "GetCaps(D7)"); @@ -1835,18 +1848,21 @@ HRESULT WINAPI extDirectDrawCreateEx(GUID FAR *lpguid, return DD_OK; } -static HRESULT WINAPI extInitialize(Initialize_Type pInitialize, LPDIRECTDRAW lpdd, GUID FAR *lpguid) +static HRESULT WINAPI extInitialize(int dxversion, Initialize_Type pInitialize, LPDIRECTDRAW lpdd, GUID FAR *lpguid) { HRESULT res; GUID FAR *lpPrivGuid = lpguid; - OutTraceDDRAW("Initialize: lpdd=%x guid=%x(%s)\n", lpdd, lpguid, ExplainGUID(lpguid)); + OutTraceDDRAW("Initialize(%d): lpdd=%x guid=%x(%s)\n", dxversion, lpdd, lpguid, ExplainGUID(lpguid)); if((dxw.dwFlags3 & FORCESHEL) && (lpguid==NULL)) lpPrivGuid=(GUID FAR *)DDCREATE_EMULATIONONLY; res=(*pInitialize)(lpdd, lpPrivGuid); - if(res == DDERR_ALREADYINITIALIZED) res=DD_OK; // v2.03.18: this error could be caused by the CoCreateInstance implementation + if(res == DDERR_ALREADYINITIALIZED) { + OutTrace("Initialize: SKIP DDERR_ALREADYINITIALIZED error\n"); + res=DD_OK; // v2.03.18: this error could be caused by the CoCreateInstance implementation + } if(dxw.dwFlags3 & COLORFIX) (((DDRAWI_DIRECTDRAW_INT *)lpdd))->lpLcl->dwAppHackFlags |= 0x800; if(res) OutTraceE("Initialize ERROR: res=%x(%s)\n", res, ExplainDDError(res)); @@ -1854,15 +1870,15 @@ static HRESULT WINAPI extInitialize(Initialize_Type pInitialize, LPDIRECTDRAW lp } HRESULT WINAPI extInitialize1(LPDIRECTDRAW lpdd, GUID FAR *lpguid) -{ return extInitialize(pInitialize1, lpdd, lpguid); } +{ return extInitialize(1, pInitialize1, lpdd, lpguid); } HRESULT WINAPI extInitialize2(LPDIRECTDRAW lpdd, GUID FAR *lpguid) -{ return extInitialize(pInitialize2, lpdd, lpguid); } +{ return extInitialize(2, pInitialize2, lpdd, lpguid); } HRESULT WINAPI extInitialize3(LPDIRECTDRAW lpdd, GUID FAR *lpguid) -{ return extInitialize(pInitialize3, lpdd, lpguid); } +{ return extInitialize(3, pInitialize3, lpdd, lpguid); } HRESULT WINAPI extInitialize4(LPDIRECTDRAW lpdd, GUID FAR *lpguid) -{ return extInitialize(pInitialize4, lpdd, lpguid); } +{ return extInitialize(4, pInitialize4, lpdd, lpguid); } HRESULT WINAPI extInitialize7(LPDIRECTDRAW lpdd, GUID FAR *lpguid) -{ return extInitialize(pInitialize7, lpdd, lpguid); } +{ return extInitialize(7, pInitialize7, lpdd, lpguid); } static HRESULT WINAPI extRestoreDisplayMode(int dxversion, RestoreDisplayMode_Type pRestoreDisplayMode, LPDIRECTDRAW lpdd) { @@ -2203,7 +2219,7 @@ HRESULT WINAPI extSetDisplayMode(int dxversion, LPDIRECTDRAW lpdd, char sInfo[81]; strcpy(sInfo, ""); if (dxversion>=4) sprintf(sInfo, " dwRefresh=%i dwFlags=%x", dwrefreshrate, dwflags); - OutTrace("SetDisplayMode: version=%d dwWidth=%i dwHeight=%i dwBPP=%i%s\n", + OutTrace("SetDisplayMode(%d): dwWidth=%i dwHeight=%i dwBPP=%i%s\n", dxversion, dwwidth, dwheight, dwbpp, sInfo); } @@ -2625,6 +2641,9 @@ HRESULT WINAPI extGetAttachedSurface(int dxversion, GetAttachedSurface_Type pGet OutTraceDW("GetAttachedSurface(%d): NOHALDEVICE no attached ZBUFFER\n", dxversion); return DDERR_NOTFOUND; } + + // attempt to fix S.C.A.R.S. black screen bug ... failed + //if(lpddsc->dwCaps == (DDSCAPS_TEXTURE|DDSCAPS_MIPMAP)) lpddsc->dwCaps = DDSCAPS_TEXTURE; } else { // Virtual primary surfaces are created with no DDSCAPS_3DDEVICE caps, so don't look for it .... @@ -3138,7 +3157,7 @@ HRESULT WINAPI extFlip(int dxversion, Flip_Type pFlip, LPDIRECTDRAWSURFACE lpdds bEmulatedFlip = dxw.Windowize || dxw.IsEmulated; IsPrim=dxwss.IsAPrimarySurface(lpdds); - OutTraceDDRAW("Flip(%d): %s lpdds=%x%s, src=%x, flags=%x(%s) version=%d\n", + OutTraceDDRAW("Flip(%d): %s lpdds=%x%s, src=%x, flags=%x(%s)\n", dxversion, bEmulatedFlip?"EMULATED":"GENUINE", lpdds, IsPrim?"(PRIM)":"", lpddssrc, dwflags, ExplainFlipFlags(dwflags)); @@ -3985,20 +4004,18 @@ static HRESULT WINAPI extUnlock(int dxversion, Unlock4_Type pUnlock, LPDIRECTDRA } res=(*pUnlock)(lpdds, lprect); + if(res==DDERR_NOTLOCKED) res=DD_OK; // ignore not locked error if (IsPrim && res==DD_OK) { if(dxversion < 4) lprect=NULL; // v2.03.60 res=sBlt(dxversion, pBlt, "Unlock", lpdds, lprect, lpdds, lprect, NULL, 0, FALSE); } - if(res==DDERR_NOTLOCKED) res=DD_OK; // ignore not locked error if (res) OutTraceE("Unlock ERROR res=%x(%s) at %d\n",res, ExplainDDError(res), __LINE__); - if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK; - if((dxw.dwFlags5 & TEXTUREMASK) && (!IsPrim)) { // Texture Handling on Unlock TextureHandling(lpdds, dxversion); } - + OutTraceB("Unlock OK\n"); return res; } @@ -4091,8 +4108,16 @@ static HRESULT WINAPI extUnlockDir(int dxversion, Unlock4_Type pUnlock, LPDIRECT res=(*pUnlock)(lpdds, lprect); if(res==DDERR_NOTLOCKED) res=DD_OK; // ignore not locked error if (res) OutTraceE("Unlock ERROR res=%x(%s) at %d\n",res, ExplainDDError(res), __LINE__); - if (IsPrim && res==DD_OK) sBlt(dxversion, pBlt, "Unlock", lpdds, NULL, lpdds, NULL, NULL, 0, FALSE); + if (IsPrim && res==DD_OK) { + if(dxversion < 4) lprect=NULL; // v2.03.60 + res=sBlt(dxversion, pBlt, "Unlock", lpdds, lprect, lpdds, lprect, NULL, 0, FALSE); + } if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK; + if((dxw.dwFlags5 & TEXTUREMASK) && (!IsPrim)) { + // Texture Handling on Unlock + TextureHandling(lpdds, dxversion); + } + OutTraceB("Unlock OK\n"); return res; } @@ -4603,6 +4628,7 @@ static HRESULT WINAPI extSetColorKey(SetColorKey_Type pSetColorKey, LPDIRECTDRAW res=(*pSetColorKey)(lpdds, flags, lpDDColorKey); if(res) OutTraceE("SetColorKey: ERROR flags=%x lpdds=%x res=%x(%s)\n", flags, lpdds, res, ExplainDDError(res)); + if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK; return res; } @@ -4617,32 +4643,33 @@ HRESULT WINAPI extSetColorKey4(LPDIRECTDRAWSURFACE lpdds, DWORD flags, LPDDCOLOR HRESULT WINAPI extSetColorKey7(LPDIRECTDRAWSURFACE lpdds, DWORD flags, LPDDCOLORKEY lpDDColorKey) { return extSetColorKey(pSetColorKey7, lpdds, flags, lpDDColorKey); } -static HRESULT WINAPI extGetColorKey(GetColorKey_Type pGetColorKey, LPDIRECTDRAWSURFACE lpdds, DWORD flags, LPDDCOLORKEY lpDDColorKey) +static HRESULT WINAPI extGetColorKey(int dxversion, GetColorKey_Type pGetColorKey, LPDIRECTDRAWSURFACE lpdds, DWORD flags, LPDDCOLORKEY lpDDColorKey) { HRESULT res; BOOL IsPrim; IsPrim=dxwss.IsAPrimarySurface(lpdds); - OutTraceDDRAW("GetColorKey(S): lpdds=%x%s flags=%x(%s)\n", - lpdds, (IsPrim ? "(PRIM)" : ""), flags, ExplainColorKeyFlag(flags)); + OutTraceDDRAW("GetColorKey(S%d): lpdds=%x%s flags=%x(%s)\n", + dxversion, lpdds, (IsPrim ? "(PRIM)" : ""), flags, ExplainColorKeyFlag(flags)); res=(*pGetColorKey)(lpdds, flags, lpDDColorKey); if(res) OutTraceE("GetColorKey: ERROR lpdds=%x flags=%x res=%x(%s)\n", lpdds, flags, res, ExplainDDError(res)); else OutTraceDDRAW("GetColorKey: colors=(L:%x,H:%x)\n", lpDDColorKey->dwColorSpaceLowValue, lpDDColorKey->dwColorSpaceHighValue); + if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK; return res; } HRESULT WINAPI extGetColorKey1(LPDIRECTDRAWSURFACE lpdds, DWORD flags, LPDDCOLORKEY lpDDColorKey) -{ return extGetColorKey(pGetColorKey1, lpdds, flags, lpDDColorKey); } +{ return extGetColorKey(1, pGetColorKey1, lpdds, flags, lpDDColorKey); } HRESULT WINAPI extGetColorKey2(LPDIRECTDRAWSURFACE lpdds, DWORD flags, LPDDCOLORKEY lpDDColorKey) -{ return extGetColorKey(pGetColorKey2, lpdds, flags, lpDDColorKey); } +{ return extGetColorKey(2, pGetColorKey2, lpdds, flags, lpDDColorKey); } HRESULT WINAPI extGetColorKey3(LPDIRECTDRAWSURFACE lpdds, DWORD flags, LPDDCOLORKEY lpDDColorKey) -{ return extGetColorKey(pGetColorKey3, lpdds, flags, lpDDColorKey); } +{ return extGetColorKey(3, pGetColorKey3, lpdds, flags, lpDDColorKey); } HRESULT WINAPI extGetColorKey4(LPDIRECTDRAWSURFACE lpdds, DWORD flags, LPDDCOLORKEY lpDDColorKey) -{ return extGetColorKey(pGetColorKey4, lpdds, flags, lpDDColorKey); } +{ return extGetColorKey(4, pGetColorKey4, lpdds, flags, lpDDColorKey); } HRESULT WINAPI extGetColorKey7(LPDIRECTDRAWSURFACE lpdds, DWORD flags, LPDDCOLORKEY lpDDColorKey) -{ return extGetColorKey(pGetColorKey7, lpdds, flags, lpDDColorKey); } +{ return extGetColorKey(7, pGetColorKey7, lpdds, flags, lpDDColorKey); } static HRESULT WINAPI extEnumAttachedSurfaces(EnumAttachedSurfaces_Type pEnumAttachedSurfaces, LPDIRECTDRAWSURFACE lpdds, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback) { @@ -4858,6 +4885,7 @@ static HRESULT WINAPI extGetCapsS(int dxInterface, GetCapsS_Type pGetCapsS, LPDI } if(IsFixed) OutTraceDW("GetCaps(S%d): lpdds=%x FIXED %s caps=%x(%s)\n", dxInterface, lpdds, sLabel, caps->dwCaps, ExplainDDSCaps(caps->dwCaps)); + //if(IsDebug) HexTrace((unsigned char *)caps, sizeof(DDSCAPS)); return res; } @@ -4947,6 +4975,7 @@ static HRESULT WINAPI extGetSurfaceDesc(int dxversion, GetSurfaceDesc_Type pGetS if(IsFixed){ OutTraceDW("GetSurfaceDesc: FIXED lpdds=%x %s\n", lpdds, LogSurfaceAttributes(lpddsd, sLabel, __LINE__)); + //if(IsDebug) HexTrace((unsigned char *)lpddsd, sizeof(DDSURFACEDESC)); } return DD_OK; @@ -5478,3 +5507,26 @@ HRESULT WINAPI extCompact(LPDIRECTDRAW lpdd) OutTraceDW("Compact: lpdd=%x\n", lpdd); return DD_OK; } + +HRESULT WINAPI extDuplicateSurface(int dxversion, DuplicateSurface_Type pDuplicateSurface, LPDIRECTDRAW lpdd, LPDIRECTDRAWSURFACE lpddssrc, LPDIRECTDRAWSURFACE FAR *lpddsdest) +{ + HRESULT res; + OutTrace("DuplicateSurface(%d): lpdd=%x lpddsrc=%x\n", dxversion, lpdd, lpddssrc); + res = (*pDuplicateSurface)(lpdd, lpddssrc, lpddsdest); + if(res) + OutTrace("DuplicateSurface: ERROR res=%x(%s)\n", res, ExplainDDError(res)); + else + OutTrace("DuplicateSurface: lpddsdest=%x\n", *lpddsdest); + return res; +} + +HRESULT WINAPI extDuplicateSurface1(LPDIRECTDRAW lpdd, LPDIRECTDRAWSURFACE lpddssrc, LPDIRECTDRAWSURFACE FAR *lpddsdest) +{ return extDuplicateSurface(1, pDuplicateSurface1, lpdd, lpddssrc, lpddsdest); } +HRESULT WINAPI extDuplicateSurface2(LPDIRECTDRAW lpdd, LPDIRECTDRAWSURFACE lpddssrc, LPDIRECTDRAWSURFACE FAR *lpddsdest) +{ return extDuplicateSurface(2, pDuplicateSurface2, lpdd, lpddssrc, lpddsdest); } +HRESULT WINAPI extDuplicateSurface3(LPDIRECTDRAW lpdd, LPDIRECTDRAWSURFACE lpddssrc, LPDIRECTDRAWSURFACE FAR *lpddsdest) +{ return extDuplicateSurface(3, pDuplicateSurface3, lpdd, lpddssrc, lpddsdest); } +HRESULT WINAPI extDuplicateSurface4(LPDIRECTDRAW lpdd, LPDIRECTDRAWSURFACE4 lpddssrc, LPDIRECTDRAWSURFACE4 FAR *lpddsdest) +{ return extDuplicateSurface(4, (DuplicateSurface_Type)pDuplicateSurface4, lpdd, (LPDIRECTDRAWSURFACE)lpddssrc, (LPDIRECTDRAWSURFACE *)lpddsdest); } +HRESULT WINAPI extDuplicateSurface7(LPDIRECTDRAW lpdd, LPDIRECTDRAWSURFACE7 lpddssrc, LPDIRECTDRAWSURFACE7 FAR *lpddsdest) +{ return extDuplicateSurface(7, (DuplicateSurface_Type)pDuplicateSurface7, lpdd, (LPDIRECTDRAWSURFACE)lpddssrc, (LPDIRECTDRAWSURFACE *)lpddsdest); } diff --git a/dll/ddtexture.cpp b/dll/ddtexture.cpp index 8cd171d..1d3e915 100644 --- a/dll/ddtexture.cpp +++ b/dll/ddtexture.cpp @@ -187,6 +187,7 @@ static void TextureDump(LPDIRECTDRAWSURFACE s, int dxversion) static int MinTexX, MinTexY, MaxTexX, MaxTexY; static BOOL DoOnce = TRUE; char pszFile[MAX_PATH]; + BOOL IsRaw = (dxw.dwFlags8 & RAWFORMAT); OutTraceB("TextureDump(%d): lpdds=%x\n", dxversion, s); @@ -228,6 +229,10 @@ static void TextureDump(LPDIRECTDRAWSURFACE s, int dxversion) OutTrace("TextureDump: SKIP 0BPP texture\n"); break; } + if((ddsd.lPitch == 0) || (ddsd.dwHeight == 0)) { + OutTrace("TextureDump: SKIP void texture\n"); + break; + } iSurfaceSize = ddsd.dwHeight * ddsd.lPitch; @@ -266,11 +271,18 @@ static void TextureDump(LPDIRECTDRAWSURFACE s, int dxversion) } // Create the .BMP file. - sprintf_s(pszFile, MAX_PATH, "%s\\texture.out\\texture.%03d.%03d.%s.%08X.bmp", - GetDxWndPath(), ddsd.dwWidth, ddsd.dwHeight, SurfaceType(ddsd.ddpfPixelFormat), hash); + sprintf_s(pszFile, MAX_PATH, "%s\\texture.out\\texture.%03d.%03d.%s.%08X.%s", + GetDxWndPath(), ddsd.dwWidth, ddsd.dwHeight, SurfaceType(ddsd.ddpfPixelFormat), + hash, IsRaw ? "raw" : "bmp"); hf = fopen(pszFile, "wb"); if(!hf) break; + if(IsRaw){ + fwrite((BYTE *)ddsd.lpSurface, ddsd.lPitch * ddsd.dwHeight, 1, hf); + fclose(hf); + return; + } + hdr.bfType = 0x4d42; // 0x42 = "B" 0x4d = "M" // Compute the size of the entire file. hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) + pbi.bV4Size + pbi.bV4ClrUsed * sizeof(RGBQUAD) + pbi.bV4SizeImage); @@ -309,6 +321,7 @@ static void TextureHack(LPDIRECTDRAWSURFACE s, int dxversion) DDSURFACEDESC2 ddsd; int w, h, iSurfaceSize, iScanLineSize; HRESULT res; + BOOL IsRaw = (dxw.dwFlags8 & RAWFORMAT); OutTraceB("TextureHack(%d): lpdds=%x\n", dxversion, s); @@ -332,6 +345,26 @@ static void TextureHack(LPDIRECTDRAWSURFACE s, int dxversion) char pszFile[81]; int iSizeImage; + // calculate the bitmap hash + DWORD hash; + hash = HashSurface((BYTE *)ddsd.lpSurface, ddsd.lPitch, ddsd.dwWidth, ddsd.dwHeight); + if(!hash) break; // almost certainly, an empty black surface! + + // Look for the .BMP file. + sprintf_s(pszFile, MAX_PATH, "%s\\texture.in\\texture.%03d.%03d.%s.%08X.%s", + GetDxWndPath(), ddsd.dwWidth, ddsd.dwHeight, SurfaceType(ddsd.ddpfPixelFormat), + hash, IsRaw ? "raw" : "bmp"); + hf = fopen(pszFile, "rb"); + if(!hf) break; // no updated texture to load + + OutTrace("TextureHack: IMPORT path=%s\n", pszFile); + + if(IsRaw){ + fread((BYTE *)ddsd.lpSurface, ddsd.lPitch * ddsd.dwHeight, 1, hf); + fclose(hf); + return; + } + memset((void *)&pbi, 0, sizeof(BITMAPINFOHEADER)); pbi.biSize = sizeof(BITMAPINFOHEADER); pbi.biWidth = ddsd.dwWidth; @@ -341,19 +374,6 @@ static void TextureHack(LPDIRECTDRAWSURFACE s, int dxversion) iSizeImage = pbi.biSizeImage; iScanLineSize = ((pbi.biWidth * pbi.biBitCount + 0x1F) & ~0x1F)/8; - // calculate the bitmap hash - DWORD hash; - hash = HashSurface((BYTE *)ddsd.lpSurface, ddsd.lPitch, ddsd.dwWidth, ddsd.dwHeight); - if(!hash) break; // almost certainly, an empty black surface! - - // Look for the .BMP file. - sprintf_s(pszFile, MAX_PATH, "%s\\texture.in\\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 - - 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; diff --git a/dll/dinput.cpp b/dll/dinput.cpp index b2d1482..b2c0108 100644 --- a/dll/dinput.cpp +++ b/dll/dinput.cpp @@ -222,7 +222,7 @@ HRESULT WINAPI extDirectInputCreateA(HINSTANCE hinst, DWORD dwversion, LPDIRECTI { HRESULT res; - OutTraceDW("DirectInputCreateA: version=%x\n", dwversion); + OutTraceDW("DirectInputCreateA(%x)\n", dwversion); res = (*pDirectInputCreateA)(hinst, dwversion, lplpdi, pu); if(res) { @@ -251,7 +251,7 @@ HRESULT WINAPI extDirectInputCreateW(HINSTANCE hinst, DWORD dwversion, LPDIRECTI { HRESULT res; - OutTraceDW("DirectInputCreateW: version=%x\n", dwversion); + OutTraceDW("DirectInputCreateW(%x)\n", dwversion); res = (*pDirectInputCreateW)(hinst, dwversion, lplpdi, pu); if(res) { diff --git a/dll/dxhook.cpp b/dll/dxhook.cpp index 4343855..60e910e 100644 --- a/dll/dxhook.cpp +++ b/dll/dxhook.cpp @@ -142,7 +142,7 @@ static char *Flag7Names[32]={ static char *Flag8Names[32]={ "FORCEWAIT", "FORCENOWAIT", "FORCEVSYNC", "FORCENOVSYNC", "VSYNCSCANLINES", "TRIMTEXTUREFORMATS", "NOHALDEVICE", "CLIPLOCK", - "", "", "", "", + "PRETENDVISIBLE", "RAWFORMAT", "WININSULATION", "FIXMOUSEHOOK", "", "", "", "", "", "", "", "", "", "", "", "", @@ -1380,14 +1380,6 @@ void HookInit(TARGETMAP *target, HWND hwnd) SetDllDirectory(sSourcePath); if(dxw.bHintActive) ShowHint(HINT_HINT); - if(dxw.dwFlags5 & HYBRIDMODE) { - // special mode settings .... - dxw.dwFlags1 |= EMULATESURFACE; - dxw.dwFlags2 |= SETCOMPATIBILITY; - dxw.dwFlags5 &= ~(BILINEARFILTER | AEROBOOST); - } - if(dxw.dwFlags5 & GDIMODE) dxw.dwFlags1 |= EMULATESURFACE; - if(dxw.dwFlags5 & STRESSRESOURCES) dxw.dwFlags5 |= LIMITRESOURCES; if(DoOnce){ DoOnce = FALSE; diff --git a/dll/dxwcore.cpp b/dll/dxwcore.cpp index 24f3577..5abda56 100644 --- a/dll/dxwcore.cpp +++ b/dll/dxwcore.cpp @@ -94,7 +94,6 @@ void dxwCore::InitTarget(TARGETMAP *target) dwFlags8 = target->flags8; dwTFlags = target->tflags; Windowize = (dwFlags2 & WINDOWIZE) ? TRUE : FALSE; - IsEmulated = (dwFlags1 & (EMULATESURFACE|EMULATEBUFFER)) ? TRUE : FALSE; IsVisible = TRUE; if(dwFlags3 & FULLSCREENONLY) FullScreen=TRUE; gsModules = target->module; @@ -151,6 +150,16 @@ void dxwCore::InitTarget(TARGETMAP *target) if (dwFlags3 & GDIEMULATEDC) GDIEmulationMode = GDIMODE_EMULATED; if (dwFlags6 & SHAREDDC) GDIEmulationMode = GDIMODE_SHAREDDC; + if(dwFlags5 & HYBRIDMODE) { + // special mode settings .... + dwFlags1 |= EMULATESURFACE; + dwFlags2 |= SETCOMPATIBILITY; + dwFlags5 &= ~(BILINEARFILTER | AEROBOOST); + } + if(dwFlags5 & GDIMODE) dwFlags1 |= EMULATESURFACE; + if(dwFlags5 & STRESSRESOURCES) dwFlags5 |= LIMITRESOURCES; + IsEmulated = (dwFlags1 & (EMULATESURFACE|EMULATEBUFFER)) ? TRUE : FALSE; // includes also the HYBRIDMODE and GDIMODE cases .... + extern GetWindowLong_Type pGetWindowLong; extern SetWindowLong_Type pSetWindowLong; // made before hooking !!! diff --git a/dll/dxwnd.aps b/dll/dxwnd.aps index 1a29971..f1007eb 100644 Binary files a/dll/dxwnd.aps and b/dll/dxwnd.aps differ diff --git a/dll/dxwnd.cpp b/dll/dxwnd.cpp index e06b253..3378b3f 100644 --- a/dll/dxwnd.cpp +++ b/dll/dxwnd.cpp @@ -27,10 +27,9 @@ along with this program. If not, see . #include "TlHelp32.h" -#define VERSION "2.03.99.fx3" +#define VERSION "2.03.40" #define DDTHREADLOCK 1 -//#define LOCKTHREADS LRESULT CALLBACK HookProc(int ncode, WPARAM wparam, LPARAM lparam); diff --git a/dll/dxwnd.vs2008.suo b/dll/dxwnd.vs2008.suo new file mode 100644 index 0000000..64774c1 Binary files /dev/null and b/dll/dxwnd.vs2008.suo differ diff --git a/dll/dxwnd.vs2008.vcproj b/dll/dxwnd.vs2008.vcproj index 2b33143..9a268e4 100644 --- a/dll/dxwnd.vs2008.vcproj +++ b/dll/dxwnd.vs2008.vcproj @@ -598,6 +598,10 @@ RelativePath=".\smack.h" > + + diff --git a/dll/hd3d7.cpp b/dll/hd3d7.cpp index 897ff5a..8549c61 100644 --- a/dll/hd3d7.cpp +++ b/dll/hd3d7.cpp @@ -698,7 +698,7 @@ HRESULT WINAPI extQueryInterfaceD3(int d3dversion, QueryInterfaceD3_Type pQueryI HRESULT res; OutTraceD3D("QueryInterfaceD3(%d): d3d=%x REFIID=%x obj=%x\n", d3dversion, lpd3d, riid.Data1, ppvObj); - d3dversion=0; + //d3dversion=0; res=(*pQueryInterfaceD3)(lpd3d, riid, ppvObj); //switch(riid.Data1){ // case 0x3BBA0080: d3dversion=1; break; diff --git a/dll/hddraw.h b/dll/hddraw.h index d7d76dc..0931285 100644 --- a/dll/hddraw.h +++ b/dll/hddraw.h @@ -26,6 +26,9 @@ typedef HRESULT (WINAPI *CreatePalette_Type)(LPDIRECTDRAW, DWORD, LPPALETTEENTRY typedef HRESULT (WINAPI *CreateSurface1_Type)(LPDIRECTDRAW, DDSURFACEDESC *, LPDIRECTDRAWSURFACE *, void *); typedef HRESULT (WINAPI *CreateSurface2_Type)(LPDIRECTDRAW, DDSURFACEDESC2 *, LPDIRECTDRAWSURFACE *, void *); typedef HRESULT (WINAPI *CreateSurface_Type)(LPDIRECTDRAW, DDSURFACEDESC2 *, LPDIRECTDRAWSURFACE *, void *); +typedef HRESULT (WINAPI *DuplicateSurface_Type)(LPDIRECTDRAW, LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE FAR *); +typedef HRESULT (WINAPI *DuplicateSurface4_Type)(LPDIRECTDRAW, LPDIRECTDRAWSURFACE4, LPDIRECTDRAWSURFACE4 FAR *); +typedef HRESULT (WINAPI *DuplicateSurface7_Type)(LPDIRECTDRAW, LPDIRECTDRAWSURFACE7, LPDIRECTDRAWSURFACE7 FAR *); typedef HRESULT (WINAPI *EnumDisplayModes1_Type)(LPDIRECTDRAW, DWORD, LPDDSURFACEDESC, LPVOID, LPDDENUMMODESCALLBACK); typedef HRESULT (WINAPI *EnumDisplayModes4_Type)(LPDIRECTDRAW, DWORD, LPDDSURFACEDESC2, LPVOID, LPDDENUMMODESCALLBACK2); typedef HRESULT (WINAPI *EnumSurfaces1_Type)(LPDIRECTDRAW, DWORD, LPDDSURFACEDESC, LPVOID, LPDDENUMSURFACESCALLBACK); diff --git a/dll/stb_dxt.h b/dll/stb_dxt.h new file mode 100644 index 0000000..318e306 --- /dev/null +++ b/dll/stb_dxt.h @@ -0,0 +1,1043 @@ +// stb_dxt.h - Real-Time DXT1/DXT5 compressor +// Based on original by fabian "ryg" giesen v1.04 +// Custom version, modified by Yann Collet +// +/* + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at : + - RygsDXTc source repository : http://code.google.com/p/rygsdxtc/ + +*/ +// use '#define STB_DXT_IMPLEMENTATION' before including to create the implementation +// +// USAGE: +// call stb_compress_dxt_block() for every block (you must pad) +// source should be a 4x4 block of RGBA data in row-major order; +// A is ignored if you specify alpha=0; you can turn on dithering +// and "high quality" using mode. +// +// version history: +// v1.06 - (cyan) implement Fabian Giesen's comments +// v1.05 - (cyan) speed optimizations +// v1.04 - (ryg) default to no rounding bias for lerped colors (as per S3TC/DX10 spec); +// single color match fix (allow for inexact color interpolation); +// optimal DXT5 index finder; "high quality" mode that runs multiple refinement steps. +// v1.03 - (stb) endianness support +// v1.02 - (stb) fix alpha encoding bug +// v1.01 - (stb) fix bug converting to RGB that messed up quality, thanks ryg & cbloom +// v1.00 - (stb) first release + +#ifndef STB_INCLUDE_STB_DXT_H +#define STB_INCLUDE_STB_DXT_H + + +//******************************************************************* +// Enable custom Optimisations +// Comment this define if you want to revert to ryg's original code +#define NEW_OPTIMISATIONS +//******************************************************************* + +// compression mode (bitflags) +#define STB_DXT_NORMAL 0 +#define STB_DXT_DITHER 1 // use dithering. dubious win. never use for normal maps and the like! +#define STB_DXT_HIGHQUAL 2 // high quality mode, does two refinement steps instead of 1. ~30-40% slower. + +void rygCompress( unsigned char *dst, unsigned char *src, int w, int h, int isDxt5 ); + +// TODO remove these, not working properly.. +void rygCompressYCoCg( unsigned char *dst, unsigned char *src, int w, int h ); +void linearize( unsigned char * dst, const unsigned char * src, int n ); + +void stb_compress_dxt_block(unsigned char *dest, const unsigned char *src, int alpha, int mode); +#define STB_COMPRESS_DXT_BLOCK + +#ifdef STB_DXT_IMPLEMENTATION + +// configuration options for DXT encoder. set them in the project/makefile or just define +// them at the top. + +// STB_DXT_USE_ROUNDING_BIAS +// use a rounding bias during color interpolation. this is closer to what "ideal" +// interpolation would do but doesn't match the S3TC/DX10 spec. old versions (pre-1.03) +// implicitly had this turned on. +// +// in case you're targeting a specific type of hardware (e.g. console programmers): +// NVidia and Intel GPUs (as of 2010) as well as DX9 ref use DXT decoders that are closer +// to STB_DXT_USE_ROUNDING_BIAS. AMD/ATI, S3 and DX10 ref are closer to rounding with no bias. +// you also see "(a*5 + b*3) / 8" on some old GPU designs. +// #define STB_DXT_USE_ROUNDING_BIAS + +#include +#include +#include +#include // memset +#include +#include +#include + + +static unsigned char stb__Expand5[32]; +static unsigned char stb__Expand6[64]; +static unsigned char stb__OMatch5[256][2]; +static unsigned char stb__OMatch6[256][2]; +static unsigned char stb__QuantRBTab[256+16]; +static unsigned char stb__QuantGTab[256+16]; + +static int stb__Mul8Bit(int a, int b) +{ + int t = a*b + 128; + return (t + (t >> 8)) >> 8; +} + +static void stb__From16Bit(unsigned char *out, unsigned short v) +{ + int rv = (v & 0xf800) >> 11; + int gv = (v & 0x07e0) >> 5; + int bv = (v & 0x001f) >> 0; + + out[0] = stb__Expand5[rv]; + out[1] = stb__Expand6[gv]; + out[2] = stb__Expand5[bv]; + out[3] = 0; +} + +static unsigned short stb__As16Bit(int r, int g, int b) +{ + return (stb__Mul8Bit(r,31) << 11) + (stb__Mul8Bit(g,63) << 5) + stb__Mul8Bit(b,31); +} + +// linear interpolation at 1/3 point between a and b, using desired rounding type +static int stb__Lerp13(int a, int b) +{ +#ifdef STB_DXT_USE_ROUNDING_BIAS + // with rounding bias + return a + stb__Mul8Bit(b-a, 0x55); +#else + // without rounding bias + // replace "/ 3" by "* 0xaaab) >> 17" if your compiler sucks or you really need every ounce of speed. + return (2*a + b) / 3; +#endif +} + +// lerp RGB color +static void stb__Lerp13RGB(unsigned char *out, unsigned char *p1, unsigned char *p2) +{ + out[0] = stb__Lerp13(p1[0], p2[0]); + out[1] = stb__Lerp13(p1[1], p2[1]); + out[2] = stb__Lerp13(p1[2], p2[2]); +} + +/****************************************************************************/ + +// compute table to reproduce constant colors as accurately as possible +static void stb__PrepareOptTable(unsigned char *Table,const unsigned char *expand,int size) +{ + int i,mn,mx; + for (i=0;i<256;i++) { + int bestErr = 256; + for (mn=0;mn> 4)]; + ep1[0] = bp[ 0] - dp[ 0]; + dp[ 4] = quant[bp[ 4] + ((7*ep1[0] + 3*ep2[2] + 5*ep2[1] + ep2[0]) >> 4)]; + ep1[1] = bp[ 4] - dp[ 4]; + dp[ 8] = quant[bp[ 8] + ((7*ep1[1] + 3*ep2[3] + 5*ep2[2] + ep2[1]) >> 4)]; + ep1[2] = bp[ 8] - dp[ 8]; + dp[12] = quant[bp[12] + ((7*ep1[2] + 5*ep2[3] + ep2[2]) >> 4)]; + ep1[3] = bp[12] - dp[12]; + bp += 16; + dp += 16; + et = ep1, ep1 = ep2, ep2 = et; // swap + } + } +} + +// The color matching function +static unsigned int stb__MatchColorsBlock(unsigned char *block, unsigned char *color,int dither) +{ + unsigned int mask = 0; + int dirr = color[0*4+0] - color[1*4+0]; + int dirg = color[0*4+1] - color[1*4+1]; + int dirb = color[0*4+2] - color[1*4+2]; + int dots[16]; + int stops[4]; + int i; + int c0Point, halfPoint, c3Point; + + for(i=0;i<16;i++) + dots[i] = block[i*4+0]*dirr + block[i*4+1]*dirg + block[i*4+2]*dirb; + + for(i=0;i<4;i++) + stops[i] = color[i*4+0]*dirr + color[i*4+1]*dirg + color[i*4+2]*dirb; + + // think of the colors as arranged on a line; project point onto that line, then choose + // next color out of available ones. we compute the crossover points for "best color in top + // half"/"best in bottom half" and then the same inside that subinterval. + // + // relying on this 1d approximation isn't always optimal in terms of euclidean distance, + // but it's very close and a lot faster. + // http://cbloomrants.blogspot.com/2008/12/12-08-08-dxtc-summary.html + + c0Point = (stops[1] + stops[3]) >> 1; + halfPoint = (stops[3] + stops[2]) >> 1; + c3Point = (stops[2] + stops[0]) >> 1; + + if(!dither) + { + // the version without dithering is straightforward + +#ifdef NEW_OPTIMISATIONS + const int indexMap[8] = { 0 << 30,2 << 30,0 << 30,2 << 30,3 << 30,3 << 30,1 << 30,1 << 30 }; + + for(int i=0;i<16;i++) + { + int dot = dots[i]; + mask >>= 2; + + int bits =( (dot < halfPoint) ? 4 : 0 ) + | ( (dot < c0Point) ? 2 : 0 ) + | ( (dot < c3Point) ? 1 : 0 ); + + mask |= indexMap[bits]; + } + +#else + for (i=15;i>=0;i--) { + int dot = dots[i]; + mask <<= 2; + + if(dot < halfPoint) + mask |= (dot < c0Point) ? 1 : 3; + else + mask |= (dot < c3Point) ? 2 : 0; + } +#endif + + } else { + // with floyd-steinberg dithering + int err[8],*ep1 = err,*ep2 = err+4; + int *dp = dots, y; + + c0Point <<= 4; + halfPoint <<= 4; + c3Point <<= 4; + for(i=0;i<8;i++) + err[i] = 0; + + for(y=0;y<4;y++) + { + int dot,lmask,step; + + dot = (dp[0] << 4) + (3*ep2[1] + 5*ep2[0]); + if(dot < halfPoint) + step = (dot < c0Point) ? 1 : 3; + else + step = (dot < c3Point) ? 2 : 0; + ep1[0] = dp[0] - stops[step]; + lmask = step; + + dot = (dp[1] << 4) + (7*ep1[0] + 3*ep2[2] + 5*ep2[1] + ep2[0]); + if(dot < halfPoint) + step = (dot < c0Point) ? 1 : 3; + else + step = (dot < c3Point) ? 2 : 0; + ep1[1] = dp[1] - stops[step]; + lmask |= step<<2; + + dot = (dp[2] << 4) + (7*ep1[1] + 3*ep2[3] + 5*ep2[2] + ep2[1]); + if(dot < halfPoint) + step = (dot < c0Point) ? 1 : 3; + else + step = (dot < c3Point) ? 2 : 0; + ep1[2] = dp[2] - stops[step]; + lmask |= step<<4; + + dot = (dp[3] << 4) + (7*ep1[2] + 5*ep2[3] + ep2[2]); + if(dot < halfPoint) + step = (dot < c0Point) ? 1 : 3; + else + step = (dot < c3Point) ? 2 : 0; + ep1[3] = dp[3] - stops[step]; + lmask |= step<<6; + + dp += 4; + mask |= lmask << (y*8); + { int *et = ep1; ep1 = ep2; ep2 = et; } // swap + } + } + + return mask; +} + +// The color optimization function. (Clever code, part 1) +static void stb__OptimizeColorsBlock(unsigned char *block, unsigned short *pmax16, unsigned short *pmin16) +{ + unsigned char *minp, *maxp; + double magn; + int v_r,v_g,v_b; + static const int nIterPower = 4; + float covf[6],vfr,vfg,vfb; + + // determine color distribution + int cov[6]; + int mu[3],min[3],max[3]; + int ch,i,iter; + + for(ch=0;ch<3;ch++) + { + const unsigned char *bp = ((const unsigned char *) block) + ch; + int muv,minv,maxv; + +#ifdef NEW_OPTIMISATIONS +# define MIN(a,b) (int)a + ( ((int)b-a) & ( ((int)b-a) >> 31 ) ) +# define MAX(a,b) (int)a + ( ((int)b-a) & ( ((int)a-b) >> 31 ) ) +# define RANGE(a,b,n) int min##n = MIN(a,b); int max##n = a+b - min##n; muv += a+b; +# define MINMAX(a,b,n) int min##n = MIN(min##a, min##b); int max##n = MAX(max##a, max##b); + + muv = 0; + RANGE(bp[0], bp[4], 1); + RANGE(bp[8], bp[12], 2); + RANGE(bp[16], bp[20], 3); + RANGE(bp[24], bp[28], 4); + RANGE(bp[32], bp[36], 5); + RANGE(bp[40], bp[44], 6); + RANGE(bp[48], bp[52], 7); + RANGE(bp[56], bp[60], 8); + + MINMAX(1,2,9); + MINMAX(3,4,10); + MINMAX(5,6,11); + MINMAX(7,8,12); + + MINMAX(9,10,13); + MINMAX(11,12,14); + + minv = MIN(min13,min14); + maxv = MAX(max13,max14); + +#else + muv = minv = maxv = bp[0]; + for(i=4;i<64;i+=4) + { + muv += bp[i]; + if (bp[i] < minv) minv = bp[i]; + else if (bp[i] > maxv) maxv = bp[i]; + } +#endif + + mu[ch] = (muv + 8) >> 4; + min[ch] = minv; + max[ch] = maxv; + } + + // determine covariance matrix + for (i=0;i<6;i++) + cov[i] = 0; + + for (i=0;i<16;i++) + { + int r = block[i*4+0] - mu[0]; + int g = block[i*4+1] - mu[1]; + int b = block[i*4+2] - mu[2]; + + cov[0] += r*r; + cov[1] += r*g; + cov[2] += r*b; + cov[3] += g*g; + cov[4] += g*b; + cov[5] += b*b; + } + + // convert covariance matrix to float, find principal axis via power iter + for(i=0;i<6;i++) + covf[i] = cov[i] / 255.0f; + + vfr = (float) (max[0] - min[0]); + vfg = (float) (max[1] - min[1]); + vfb = (float) (max[2] - min[2]); + + for(iter=0;iter magn) magn = fabs(vfg); + if (fabs(vfb) > magn) magn = fabs(vfb); + + if(magn < 4.0f) + { // too small, default to luminance + v_r = 299; // JPEG YCbCr luma coefs, scaled by 1000. + v_g = 587; + v_b = 114; + } else { + magn = 512.0 / magn; + v_r = (int) (vfr * magn); + v_g = (int) (vfg * magn); + v_b = (int) (vfb * magn); + } + + +#ifdef NEW_OPTIMISATIONS + // Pick colors at extreme points + int mind, maxd; + mind = maxd = block[0]*v_r + block[1]*v_g + block[2]*v_b; + minp = maxp = block; + for(i=1;i<16;i++) + { + int dot = block[i*4+0]*v_r + block[i*4+1]*v_g + block[i*4+2]*v_b; + + if (dot < mind) { + mind = dot; + minp = block+i*4; + continue; + } + + if (dot > maxd) { + maxd = dot; + maxp = block+i*4; + } + } +#else + int mind = 0x7fffffff,maxd = -0x7fffffff; + // Pick colors at extreme points + for(i=0;i<16;i++) + { + int dot = block[i*4+0]*v_r + block[i*4+1]*v_g + block[i*4+2]*v_b; + + if (dot < mind) { + mind = dot; + minp = block+i*4; + } + + if (dot > maxd) { + maxd = dot; + maxp = block+i*4; + } + } +#endif + + *pmax16 = stb__As16Bit(maxp[0],maxp[1],maxp[2]); + *pmin16 = stb__As16Bit(minp[0],minp[1],minp[2]); +} + +inline static int stb__sclamp(float y, int p0, int p1) +{ + int x = (int) y; + +#ifdef NEW_OPTIMISATIONS + x = x>p1 ? p1 : x; + return x p1) return p1; + return x; +#endif +} + +// The refinement function. (Clever code, part 2) +// Tries to optimize colors to suit block contents better. +// (By solving a least squares system via normal equations+Cramer's rule) +static int stb__RefineBlock(unsigned char *block, unsigned short *pmax16, unsigned short *pmin16, unsigned int mask) +{ + static const int w1Tab[4] = { 3,0,2,1 }; + static const int prods[4] = { 0x090000,0x000900,0x040102,0x010402 }; + // ^some magic to save a lot of multiplies in the accumulating loop... + // (precomputed products of weights for least squares system, accumulated inside one 32-bit register) + + float frb,fg; + unsigned short oldMin, oldMax, min16, max16; + int i, akku = 0, xx,xy,yy; + int At1_r,At1_g,At1_b; + int At2_r,At2_g,At2_b; + unsigned int cm = mask; + + oldMin = *pmin16; + oldMax = *pmax16; + + if((mask ^ (mask<<2)) < 4) // all pixels have the same index? + { + // yes, linear system would be singular; solve using optimal + // single-color match on average color + int r = 8, g = 8, b = 8; + for (i=0;i<16;++i) { + r += block[i*4+0]; + g += block[i*4+1]; + b += block[i*4+2]; + } + + r >>= 4; g >>= 4; b >>= 4; + + max16 = (stb__OMatch5[r][0]<<11) | (stb__OMatch6[g][0]<<5) | stb__OMatch5[b][0]; + min16 = (stb__OMatch5[r][1]<<11) | (stb__OMatch6[g][1]<<5) | stb__OMatch5[b][1]; + } else { + At1_r = At1_g = At1_b = 0; + At2_r = At2_g = At2_b = 0; + for (i=0;i<16;++i,cm>>=2) + { + int step = cm&3; + int w1 = w1Tab[step]; + int r = block[i*4+0]; + int g = block[i*4+1]; + int b = block[i*4+2]; + + akku += prods[step]; + At1_r += w1*r; + At1_g += w1*g; + At1_b += w1*b; + At2_r += r; + At2_g += g; + At2_b += b; + } + + At2_r = 3*At2_r - At1_r; + At2_g = 3*At2_g - At1_g; + At2_b = 3*At2_b - At1_b; + + // extract solutions and decide solvability + xx = akku >> 16; + yy = (akku >> 8) & 0xff; + xy = (akku >> 0) & 0xff; + + frb = 3.0f * 31.0f / 255.0f / (xx*yy - xy*xy); + fg = frb * 63.0f / 31.0f; + + // solve. + max16 = stb__sclamp((At1_r*yy - At2_r*xy)*frb+0.5f,0,31) << 11; + max16 |= stb__sclamp((At1_g*yy - At2_g*xy)*fg +0.5f,0,63) << 5; + max16 |= stb__sclamp((At1_b*yy - At2_b*xy)*frb+0.5f,0,31) << 0; + + min16 = stb__sclamp((At2_r*xx - At1_r*xy)*frb+0.5f,0,31) << 11; + min16 |= stb__sclamp((At2_g*xx - At1_g*xy)*fg +0.5f,0,63) << 5; + min16 |= stb__sclamp((At2_b*xx - At1_b*xy)*frb+0.5f,0,31) << 0; + } + + *pmin16 = min16; + *pmax16 = max16; + return oldMin != min16 || oldMax != max16; +} + +// Color block compression +static void stb__CompressColorBlock(unsigned char *dest, unsigned char *block, int mode) +{ + unsigned int mask; + int i; + int dither; + int refinecount; + unsigned short max16, min16; + unsigned char dblock[16*4],color[4*4]; + + dither = mode & STB_DXT_DITHER; + refinecount = (mode & STB_DXT_HIGHQUAL) ? 2 : 1; + + // check if block is constant + for (i=1;i<16;i++) + if (((unsigned int *) block)[i] != ((unsigned int *) block)[0]) + break; + + if(i == 16) + { // constant color + int r = block[0], g = block[1], b = block[2]; + mask = 0xaaaaaaaa; + max16 = (stb__OMatch5[r][0]<<11) | (stb__OMatch6[g][0]<<5) | stb__OMatch5[b][0]; + min16 = (stb__OMatch5[r][1]<<11) | (stb__OMatch6[g][1]<<5) | stb__OMatch5[b][1]; + } else + { + // first step: compute dithered version for PCA if desired + if(dither) + stb__DitherBlock(dblock,block); + + // second step: pca+map along principal axis + stb__OptimizeColorsBlock(dither ? dblock : block,&max16,&min16); + if (max16 != min16) + { + stb__EvalColors(color,max16,min16); + mask = stb__MatchColorsBlock(block,color,dither); + } else + mask = 0; + + // third step: refine (multiple times if requested) + for (i=0;i> 8); + dest[2] = (unsigned char) (min16); + dest[3] = (unsigned char) (min16 >> 8); + dest[4] = (unsigned char) (mask); + dest[5] = (unsigned char) (mask >> 8); + dest[6] = (unsigned char) (mask >> 16); + dest[7] = (unsigned char) (mask >> 24); +} + +// Alpha block compression (this is easy for a change) +static void stb__CompressAlphaBlock(unsigned char *dest,unsigned char *src,int mode) +{ + int i,dist,bias,dist4,dist2,bits,mask; + + // find min/max color + int mn,mx; + + mn = mx = src[3]; + for (i=1;i<16;i++) + { + if (src[i*4+3] < mn) mn = src[i*4+3]; + else if (src[i*4+3] > mx) mx = src[i*4+3]; + } + + // encode them + ((unsigned char *)dest)[0] = mx; + ((unsigned char *)dest)[1] = mn; + dest += 2; + +#ifdef NEW_OPTIMISATIONS + // mono-alpha shortcut + if (mn==mx) + { + *(unsigned short*)dest = 0; + dest += 2; + *(unsigned int*)dest = 0; + return; + } +#endif + + // determine bias and emit color indices + // given the choice of mx/mn, these indices are optimal: + // http://fgiesen.wordpress.com/2009/12/15/dxt5-alpha-block-index-determination/ + dist = mx-mn; + //printf("mn = %i; mx = %i; dist = %i\n", mn, mx, dist); + dist4 = dist*4; + dist2 = dist*2; + bias = (dist < 8) ? (dist - 1) : (dist/2 + 2); + bias -= mn * 7; + bits = 0, mask=0; + + for (i=0;i<16;i++) + { + int a = src[i*4+3]*7 + bias; + int ind,t; + + // select index. this is a "linear scale" lerp factor between 0 (val=min) and 7 (val=max). + t = (a >= dist4) ? -1 : 0; ind = t & 4; a -= dist4 & t; + t = (a >= dist2) ? -1 : 0; ind += t & 2; a -= dist2 & t; + ind += (a >= dist); + + // turn linear scale into DXT index (0/1 are extremal pts) + ind = -ind & 7; + ind ^= (2 > ind); + + // write index + mask |= ind << bits; + if((bits += 3) >= 8) + { + *dest++ = mask; + mask >>= 8; + bits -= 8; + } + } +} + + +static void stb__InitDXT() +{ + int i; + for(i=0;i<32;i++) + stb__Expand5[i] = (i<<3)|(i>>2); + + for(i=0;i<64;i++) + stb__Expand6[i] = (i<<2)|(i>>4); + + for(i=0;i<256+16;i++) + { + int v = i-8 < 0 ? 0 : i-8 > 255 ? 255 : i-8; + stb__QuantRBTab[i] = stb__Expand5[stb__Mul8Bit(v,31)]; + stb__QuantGTab[i] = stb__Expand6[stb__Mul8Bit(v,63)]; + } + + stb__PrepareOptTable(&stb__OMatch5[0][0],stb__Expand5,32); + stb__PrepareOptTable(&stb__OMatch6[0][0],stb__Expand6,64); +} + + +void stb_compress_dxt_block(unsigned char *dest, const unsigned char *src, int alpha, int mode) +{ + static int init=1; + if (init) + { + stb__InitDXT(); + init=0; + } + + if (alpha) + { + stb__CompressAlphaBlock(dest,(unsigned char*) src,mode); + dest += 8; + } + + stb__CompressColorBlock(dest,(unsigned char*) src,mode); +} + +int imin(int x, int y) { return (x < y) ? x : y; } + + + + + +static void extractBlock(const unsigned char *src, int x, int y, + int w, int h, unsigned char *block) +{ + int i, j; + +#ifdef NEW_OPTIMISATIONS + if ((w-x >=4) && (h-y >=4)) + { + // Full Square shortcut + src += x*4; + src += y*w*4; + for (i=0; i < 4; ++i) + { + *(unsigned int*)block = *(unsigned int*) src; block += 4; src += 4; + *(unsigned int*)block = *(unsigned int*) src; block += 4; src += 4; + *(unsigned int*)block = *(unsigned int*) src; block += 4; src += 4; + *(unsigned int*)block = *(unsigned int*) src; block += 4; + src += (w*4) - 12; + } + return; + } +#endif + + int bw = imin(w - x, 4); + int bh = imin(h - y, 4); + int bx, by; + + const int rem[] = + { + 0, 0, 0, 0, + 0, 1, 0, 1, + 0, 1, 2, 0, + 0, 1, 2, 3 + }; + + for(i = 0; i < 4; ++i) + { + by = rem[(bh - 1) * 4 + i] + y; + for(j = 0; j < 4; ++j) + { + bx = rem[(bw - 1) * 4 + j] + x; + block[(i * 4 * 4) + (j * 4) + 0] = + src[(by * (w * 4)) + (bx * 4) + 0]; + block[(i * 4 * 4) + (j * 4) + 1] = + src[(by * (w * 4)) + (bx * 4) + 1]; + block[(i * 4 * 4) + (j * 4) + 2] = + src[(by * (w * 4)) + (bx * 4) + 2]; + block[(i * 4 * 4) + (j * 4) + 3] = + src[(by * (w * 4)) + (bx * 4) + 3]; + } + } +} + + // should be a pretty optimized 0-255 clamper +inline static unsigned char clamp255( int n ) +{ + if( n > 255 ) n = 255; + if( n < 0 ) n = 0; + return n; +} + + +void rgbToYCoCgBlock( unsigned char * dst, const unsigned char * src ) +{ + // Calculate Co and Cg extents + int extents = 0; + int n = 0; + int iY, iCo, iCg; //, r, g, b; + int blockCo[16]; + int blockCg[16]; + int i; + + const unsigned char *px = src; + for(i=0;i extents) extents = -iCo; + if( iCo > extents) extents = iCo; + if(-iCg > extents) extents = -iCg; + if( iCg > extents) extents = iCg; + + blockCo[n] = iCo; + blockCg[n++] = iCg; + + px += 4; + } + + // Co = -510..510 + // Cg = -510..510 + float scaleFactor = 1.0f; + if(extents > 127) + scaleFactor = (float)extents * 4.0f / 510.0f; + + // Convert to quantized scalefactor + unsigned char scaleFactorQuantized = (unsigned char)(ceil((scaleFactor - 1.0f) * 31.0f / 3.0f)); + + // Unquantize + scaleFactor = 1.0f + (float)(scaleFactorQuantized / 31.0f) * 3.0f; + + unsigned char bVal = (unsigned char)((scaleFactorQuantized << 3) | (scaleFactorQuantized >> 2)); + + unsigned char *outPx = dst; + + n = 0; + px = src; + /* + for(i=0;i<16;i++) + { + // Calculate components + iY = ( px[0] + (px[1]<<1) + px[2] + 2 ) / 4; + iCo = ((blockCo[n] / scaleFactor) + 128); + iCg = ((blockCg[n] / scaleFactor) + 128); + + if(iCo < 0) iCo = 0; else if(iCo > 255) iCo = 255; + if(iCg < 0) iCg = 0; else if(iCg > 255) iCg = 255; + if(iY < 0) iY = 0; else if(iY > 255) iY = 255; + + px += 4; + + outPx[0] = (unsigned char)iCo; + outPx[1] = (unsigned char)iCg; + outPx[2] = bVal; + outPx[3] = (unsigned char)iY; + + outPx += 4; + }*/ + for(i=0;i<16;i++) + { + // Calculate components + int r = px[0]; + int g = (px[1] + 1) >> 1; + int b = px[2]; + int tmp = (2 + r + b) >> 2; + + // Co + iCo = clamp255( 128 + ((r - b + 1) >> 1) ); + // Y + iY = clamp255( g + tmp ); + // Cg + iCg = clamp255( 128 + g - tmp ); + + px += 4; + + outPx[0] = (unsigned char)iCo; + outPx[1] = (unsigned char)iCg; + outPx[2] = bVal; + outPx[3] = (unsigned char)iY; + + outPx += 4; + } + +} + + +void rygCompress( unsigned char *dst, unsigned char *src, int w, int h, int isDxt5 ) +{ + + unsigned char block[64]; + int x, y; + + for(y = 0; y < h; y += 4) + { + for(x = 0; x < w; x += 4) + { + extractBlock(src, x, y, w, h, block); + stb_compress_dxt_block(dst, block, isDxt5, 10); + dst += isDxt5 ? 16 : 8; + } + } +} + +void rygCompressYCoCg( unsigned char *dst, unsigned char *src, int w, int h ) +{ + unsigned char block[64]; + unsigned char ycocgblock[64]; + int x, y; + + for(y = 0; y < h; y += 4) + { + for(x = 0; x < w; x += 4) + { + extractBlock(src, x, y, w, h, block); + rgbToYCoCgBlock(ycocgblock,block); + stb_compress_dxt_block(dst, ycocgblock, 1, 10); + dst += 16; + } + } + +} + +static void stbgl__compress(unsigned char *p, unsigned char *rgba, int w, int h, int isDxt5) +{ + int i,j,y,y2; + int alpha = isDxt5; + + for (j=0; j < w; j += 4) { + int x=4; + for (i=0; i < h; i += 4) { + unsigned char block[16*4]; + if (i+3 >= w) x = w-i; + for (y=0; y < 4; ++y) { + if (j+y >= h) break; + memcpy(block+y*16, rgba + w*4*(j+y) + i*4, x*4); + } + if (x < 4) { + switch (x) { + case 0: assert(0); + case 1: + for (y2=0; y2 < y; ++y2) { + memcpy(block+y2*16+1*4, block+y2*16+0*4, 4); + memcpy(block+y2*16+2*4, block+y2*16+0*4, 8); + } + break; + case 2: + for (y2=0; y2 < y; ++y2) + memcpy(block+y2*16+2*4, block+y2*16+0*4, 8); + break; + case 3: + for (y2=0; y2 < y; ++y2) + memcpy(block+y2*16+3*4, block+y2*16+1*4, 4); + break; + } + } + y2 = 0; + for(; y<4; ++y,++y2) + memcpy(block+y*16, block+y2*16, 4*4); + stb_compress_dxt_block(p, block, alpha, 10); + p += alpha ? 16 : 8; + } + } + // assert(p <= end); +} + +static inline unsigned char linearize(unsigned char inByte) +{ + float srgbVal = ((float)inByte) / 255.0f; + float linearVal; + + if(srgbVal < 0.04045) + linearVal = srgbVal / 12.92f; + else + linearVal = pow( (srgbVal + 0.055f) / 1.055f, 2.4f); + + return (unsigned char)(floor(sqrt(linearVal)* 255.0 + 0.5)); +} + +void linearize( unsigned char * dst, const unsigned char * src, int n ) +{ + n*=4; + for( int i = 0; i < n; i++ ) + dst[i] = linearize(src[i]); +} + + + +#endif // STB_DXT_IMPLEMENTATION + +#endif // STB_INCLUDE_STB_DXT_H diff --git a/dll/user32.cpp b/dll/user32.cpp index 553d6f3..e165fc7 100644 --- a/dll/user32.cpp +++ b/dll/user32.cpp @@ -13,6 +13,7 @@ #include "dxhelper.h" #include "shareddc.hpp" #include +#include #define FIXCHILDSIZE FALSE @@ -139,6 +140,9 @@ HWND WINAPI extSetFocus(HWND); typedef HBITMAP (WINAPI *LoadBitmapA_Type)(HINSTANCE, LPCSTR); LoadBitmapA_Type pLoadBitmapA; HBITMAP WINAPI extLoadBitmapA(HINSTANCE, LPCSTR); +typedef BOOL (WINAPI *EnumWindows_Type)(WNDENUMPROC, LPARAM); +EnumWindows_Type pEnumWindows; +BOOL WINAPI extEnumWindows(WNDENUMPROC, LPARAM); @@ -248,7 +252,9 @@ static HookEntryEx_Type Hooks[]={ {HOOK_HOT_CANDIDATE, 0, "EnumDisplayDevicesW", (FARPROC)EnumDisplayDevicesW, (FARPROC *)&pEnumDisplayDevicesW, (FARPROC)extEnumDisplayDevicesW}, //{HOOK_IAT_CANDIDATE, 0, "LoadBitmapA", (FARPROC)NULL, (FARPROC *)&pLoadBitmapA, (FARPROC)extLoadBitmapA}, - + + {HOOK_IAT_CANDIDATE, 0, "EnumWindows", (FARPROC)NULL, (FARPROC *)&pEnumWindows, (FARPROC)extEnumWindows}, + {HOOK_IAT_CANDIDATE, 0, 0, NULL, 0, 0} // terminator }; @@ -3633,6 +3639,7 @@ LRESULT CALLBACK extMouseHookProc(int code, WPARAM wParam, LPARAM lParam) */ HOOKPROC glpMessageHookProcessFunction; +HOOKPROC glpMouseHookProcessFunction; LRESULT CALLBACK extMessageHookProc(int code, WPARAM wParam, LPARAM lParam) { @@ -3651,6 +3658,19 @@ LRESULT CALLBACK extMessageHookProc(int code, WPARAM wParam, LPARAM lParam) return ret; } +LRESULT CALLBACK extMouseHookProc(int code, WPARAM wParam, LPARAM lParam) +{ + LRESULT ret; + OutTraceC("MouseHookProc: code=%x wParam=%x lParam=%x\n", code, wParam, lParam); + MOUSEHOOKSTRUCT *pMouseStruct = (MOUSEHOOKSTRUCT *)lParam; + if (pMouseStruct != NULL){ + OutTraceC("MouseHookProc: event=%s pos=(%d,%d)\n", ExplainWinMessage(wParam), pMouseStruct->pt.x, pMouseStruct->pt.y); + extGetCursorPos(&(pMouseStruct->pt)); + } + ret = (*glpMouseHookProcessFunction)(code, wParam, lParam); + return ret; +} + static HHOOK WINAPI extSetWindowsHookEx(SetWindowsHookEx_Type pSetWindowsHookEx, int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId) { HHOOK ret; @@ -3677,6 +3697,12 @@ static HHOOK WINAPI extSetWindowsHookEx(SetWindowsHookEx_Type pSetWindowsHookEx, return NULL; } + if((dxw.dwFlags8 & FIXMOUSEHOOK) && (idHook == WH_MOUSE)){ + OutTraceDW("SetWindowsHookEx: FIXMOUSEHOOK filter active\n"); + glpMouseHookProcessFunction = lpfn; + lpfn=extMouseHookProc; + } + ret=(*pSetWindowsHookEx)(idHook, lpfn, hMod, dwThreadId); return ret; @@ -4083,6 +4109,16 @@ HBITMAP WINAPI extLoadBitmapA(HINSTANCE hInstance, LPCSTR lpBitmapName) return ret; } +BOOL WINAPI extEnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam) +{ + OutTrace("EnumerateWindows\n"); + if(dxw.dwFlags8 & WININSULATION){ + OutTrace("EnumerateWindows: BYPASS\n"); + return TRUE; + } + return (*pEnumWindows)(lpEnumFunc, lParam); +} + // To do: // GrayStringA // GrayStringW \ No newline at end of file diff --git a/host/TabDirect3D.cpp b/host/TabDirect3D.cpp index 8f3e2a1..663d255 100644 --- a/host/TabDirect3D.cpp +++ b/host/TabDirect3D.cpp @@ -42,6 +42,7 @@ void CTabDirect3D::DoDataExchange(CDataExchange* pDX) // Texture management DDX_Radio(pDX, IDC_TEXTURENONE, cTarget->m_TextureHandling); + DDX_Check(pDX, IDC_RAWFORMAT, cTarget->m_RawFormat); // 3D Effects DDX_Check(pDX, IDC_NOTEXTURES, cTarget->m_NoTextures); diff --git a/host/TabInput.cpp b/host/TabInput.cpp index 9bc5602..7134faa 100644 --- a/host/TabInput.cpp +++ b/host/TabInput.cpp @@ -36,7 +36,7 @@ void CTabInput::DoDataExchange(CDataExchange* pDX) DDX_Check(pDX, IDC_KEEPCURSORWITHIN, cTarget->m_KeepCursorWithin); DDX_Check(pDX, IDC_KEEPCURSORFIXED, cTarget->m_KeepCursorFixed); DDX_Check(pDX, IDC_MESSAGEPROC, cTarget->m_MessageProc); - //DDX_Check(pDX, IDC_NOMOUSEPROC, cTarget->m_NoMouseProc); + DDX_Check(pDX, IDC_FIXMOUSEHOOK, cTarget->m_FixMouseHook); DDX_Check(pDX, IDC_FIXNCHITTEST, cTarget->m_FixNCHITTEST); DDX_Check(pDX, IDC_SLOW, cTarget->m_SlowDown); DDX_Check(pDX, IDC_RELEASEMOUSE, cTarget->m_ReleaseMouse); diff --git a/host/TabSysLibs.cpp b/host/TabSysLibs.cpp index 113de62..26e7efd 100644 --- a/host/TabSysLibs.cpp +++ b/host/TabSysLibs.cpp @@ -36,6 +36,7 @@ void CTabSysLibs::DoDataExchange(CDataExchange* pDX) DDX_Check(pDX, IDC_SYNCPALETTE, cTarget->m_SyncPalette); DDX_Check(pDX, IDC_NOWINERRORS, cTarget->m_NoWinErrors); DDX_Check(pDX, IDC_PRETENDVISIBLE, cTarget->m_PretendVisible); + DDX_Check(pDX, IDC_WININSULATION, cTarget->m_WinInsulation); // OpenGL DDX_Check(pDX, IDC_HOOKOPENGL, cTarget->m_HookOpenGL); // duplicated diff --git a/host/TargetDlg.cpp b/host/TargetDlg.cpp index 8d19f83..7ae61d3 100644 --- a/host/TargetDlg.cpp +++ b/host/TargetDlg.cpp @@ -60,6 +60,8 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/) m_SuppressD3DExt = FALSE; m_Enum16bitModes = FALSE; m_TrimTextureFormats = FALSE; + m_NoHALDevice = FALSE; + m_RawFormat = FALSE; m_SetCompatibility = TRUE; // default true !! m_AEROBoost = TRUE; // default true !! m_DiabloTweak = FALSE; @@ -185,10 +187,9 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/) m_HideMultiMonitor = FALSE; m_FixD3DFrame = FALSE; m_NoWindowMove = FALSE; - //m_Force16BPP = FALSE; m_HookChildWin = FALSE; m_MessageProc = FALSE; - //m_NoMouseProc = FALSE; + m_FixMouseHook = FALSE; m_FixNCHITTEST = FALSE; m_RecoverScreenMode = FALSE; m_RefreshOnResize = FALSE; @@ -197,10 +198,6 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/) m_BackBufAttach = FALSE; m_ClearTextureFourCC = FALSE; m_NoDDExclusiveMode = FALSE; - //m_ForceVSync = FALSE; - //m_ForceNoVSync = FALSE; - //m_ForceWait = FALSE; - //m_ForceNoWait = FALSE; m_VSyncMode = 0; m_VSyncImpl = 0; m_WaitMode = 0; @@ -243,6 +240,7 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/) m_SyncPalette = FALSE; m_NoWinErrors = FALSE; m_PretendVisible = FALSE; + m_WinInsulation = FALSE; m_AnalyticMode = FALSE; m_NoPaletteUpdate = FALSE; m_WireFrame = FALSE; diff --git a/host/TargetDlg.h b/host/TargetDlg.h index 32c9e42..49e2651 100644 --- a/host/TargetDlg.h +++ b/host/TargetDlg.h @@ -148,7 +148,7 @@ public: BOOL m_NoWindowMove; BOOL m_HookChildWin; BOOL m_MessageProc; - //BOOL m_NoMouseProc; + BOOL m_FixMouseHook; BOOL m_FixNCHITTEST; BOOL m_RecoverScreenMode; BOOL m_RefreshOnResize; @@ -201,6 +201,7 @@ public: BOOL m_SyncPalette; BOOL m_NoWinErrors; BOOL m_PretendVisible; + BOOL m_WinInsulation; BOOL m_AnalyticMode; BOOL m_NoPaletteUpdate; BOOL m_LimitResources; @@ -263,6 +264,7 @@ public: BOOL m_SuppressD3DExt; BOOL m_Enum16bitModes; BOOL m_TrimTextureFormats; + BOOL m_RawFormat; BOOL m_LimitScreenRes; BOOL m_InitialRes; BOOL m_MaximumRes; diff --git a/host/dxelevate.cpp b/host/dxelevate.cpp index 9f42d24..150eae8 100644 --- a/host/dxelevate.cpp +++ b/host/dxelevate.cpp @@ -31,9 +31,12 @@ BOOL DxSelfElevate(CDxwndhostView *view) { // Launch itself as administrator. SHELLEXECUTEINFO sei = { sizeof(sei) }; + char CurrentDir[MAX_PATH+1]; CString args; sei.lpVerb = "runas"; sei.lpFile = szPath; + ::GetCurrentDirectory(MAX_PATH, CurrentDir); + sei.lpDirectory = CurrentDir; //sei.hwnd = (HWND)this->GetMainWnd(); sei.hwnd = (HWND)NULL; // set to NULL to force the confirmation dialog on top of everything... sei.nShow = SW_NORMAL; diff --git a/host/dxwndhost.aps b/host/dxwndhost.aps new file mode 100644 index 0000000..6380510 Binary files /dev/null and b/host/dxwndhost.aps differ diff --git a/host/dxwndhost.rc b/host/dxwndhost.rc index 9f5f8fc..5d44bb4 100644 Binary files a/host/dxwndhost.rc and b/host/dxwndhost.rc differ diff --git a/host/dxwndhost.vs2008.suo b/host/dxwndhost.vs2008.suo index d5d86e3..b4722a3 100644 Binary files a/host/dxwndhost.vs2008.suo and b/host/dxwndhost.vs2008.suo differ diff --git a/host/dxwndhostView.cpp b/host/dxwndhostView.cpp index b03b12c..6721961 100644 --- a/host/dxwndhostView.cpp +++ b/host/dxwndhostView.cpp @@ -222,7 +222,6 @@ void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg) if(dlg->m_HotPatch) t->flags4 |= HOTPATCH; if(dlg->m_FullScreenOnly) t->flags3 |= FULLSCREENONLY; if(dlg->m_ShowHints) t->flags7 |= SHOWHINTS; - //if(dlg->m_FilterMessages) t->flags3 |= FILTERMESSAGES; if(dlg->m_PeekAllMessages) t->flags3 |= PEEKALLMESSAGES; if(dlg->m_NoWinPosChanges) t->flags5 |= NOWINPOSCHANGES; if(dlg->m_MessagePump) t->flags5 |= MESSAGEPUMP; @@ -234,7 +233,6 @@ void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg) } switch(dlg->m_DxEmulationMode){ - //case 0: t->flags |= AUTOMATIC; break; case 0: break; case 1: t->flags |= EMULATEBUFFER; break; case 2: t->flags |= LOCKEDSURFACE; break; @@ -262,7 +260,6 @@ void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg) case 1: t->flags2 |= GDISTRETCHED; break; case 2: t->flags3 |= GDIEMULATEDC; break; case 3: t->flags6 |= SHAREDDC; break; - //case 3: t->flags |= MAPGDITOPRIMARY; break; } switch(dlg->m_ResTypes){ @@ -353,7 +350,6 @@ void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg) if(dlg->m_OutDebug) t->tflags |= OUTDEBUG; if(dlg->m_CursorTrace) t->tflags |= OUTCURSORTRACE; if(dlg->m_OutDebugString) t->tflags |= OUTDEBUGSTRING; - //if(dlg->m_EraseLogFile) t->tflags |= ERASELOGFILE; if(dlg->m_AddTimeStamp) t->tflags |= ADDTIMESTAMP; if(dlg->m_AddRelativeTime) t->tflags |= ADDRELATIVETIME; if(dlg->m_OutWinMessages) t->tflags |= OUTWINMESSAGES; @@ -388,6 +384,7 @@ void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg) if(dlg->m_SuppressD3DExt) t->flags3 |= SUPPRESSD3DEXT; if(dlg->m_Enum16bitModes) t->flags7 |= ENUM16BITMODES; if(dlg->m_TrimTextureFormats) t->flags8 |= TRIMTEXTUREFORMATS; + if(dlg->m_RawFormat) t->flags8 |= RAWFORMAT; if(dlg->m_SetCompatibility) t->flags2 |= SETCOMPATIBILITY; if(dlg->m_AEROBoost) t->flags5 |= AEROBOOST; if(dlg->m_DiabloTweak) t->flags5 |= DIABLOTWEAK; @@ -423,20 +420,15 @@ void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg) if(dlg->m_LimitScreenRes) t->flags4 |= LIMITSCREENRES; if(dlg->m_SingleProcAffinity) t->flags3 |= SINGLEPROCAFFINITY; if(dlg->m_UseLastCore) t->flags5 |= USELASTCORE; - //if(dlg->m_SaveLoad) t->flags |= SAVELOAD; if(dlg->m_SlowDown) t->flags |= SLOWDOWN; if(dlg->m_BlitFromBackBuffer) t->flags |= BLITFROMBACKBUFFER; if(dlg->m_NoFlipEmulation) t->flags4 |= NOFLIPEMULATION; if(dlg->m_LockColorDepth) t->flags7 |= LOCKCOLORDEPTH; - //if(dlg->m_SuppressClipping) t->flags |= SUPPRESSCLIPPING; - //if(dlg->m_ForceClipper) t->flags3 |= FORCECLIPPER; if(dlg->m_DisableGammaRamp) t->flags2 |= DISABLEGAMMARAMP; if(dlg->m_AutoRefresh) t->flags |= AUTOREFRESH; if(dlg->m_IndependentRefresh) t->flags2 |= INDEPENDENTREFRESH; if(dlg->m_TextureFormat) t->flags5 |= TEXTUREFORMAT; if(dlg->m_FixWinFrame) t->flags |= FIXWINFRAME; - //if(dlg->m_EnableClipping) t->flags |= DISABLECLIPPING; - //if(dlg->m_CursorClipping) t->flags |= CLIPCURSOR; if(dlg->m_VideoToSystemMem) t->flags |= SWITCHVIDEOMEMORY; if(dlg->m_FixTextOut) t->flags |= FIXTEXTOUT; if(dlg->m_HookGlide) t->flags4 |= HOOKGLIDE; @@ -468,15 +460,12 @@ void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg) if(dlg->m_HideMultiMonitor) t->flags2 |= HIDEMULTIMONITOR; if(dlg->m_FixD3DFrame) t->flags3 |= FIXD3DFRAME; if(dlg->m_NoWindowMove) t->flags3 |= NOWINDOWMOVE; - //if(dlg->m_Force16BPP) t->flags3 |= FORCE16BPP; if(dlg->m_HookChildWin) t->flags |= HOOKCHILDWIN; if(dlg->m_MessageProc) t->flags |= MESSAGEPROC; - //if(dlg->m_NoMouseProc) t->flags6 |= NOMOUSEPROC; + if(dlg->m_FixMouseHook) t->flags8 |= FIXMOUSEHOOK; if(dlg->m_FixNCHITTEST) t->flags2 |= FIXNCHITTEST; if(dlg->m_RecoverScreenMode) t->flags2 |= RECOVERSCREENMODE; if(dlg->m_RefreshOnResize) t->flags2 |= REFRESHONRESIZE; - //if(dlg->m_Init8BPP) t->flags2 |= INIT8BPP; - //if(dlg->m_Init16BPP) t->flags2 |= INIT16BPP; if(dlg->m_BackBufAttach) t->flags2 |= BACKBUFATTACH; if(dlg->m_ClearTextureFourCC) t->flags7 |= CLEARTEXTUREFOURCC; if(dlg->m_NoDDExclusiveMode) t->flags7 |= NODDEXCLUSIVEMODE; @@ -523,14 +512,11 @@ void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg) if(dlg->m_SyncPalette) t->flags6 |= SYNCPALETTE; if(dlg->m_NoWinErrors) t->flags7 |= NOWINERRORS; if(dlg->m_PretendVisible) t->flags8 |= PRETENDVISIBLE; + if(dlg->m_WinInsulation) t->flags8 |= WININSULATION; if(dlg->m_AnalyticMode) t->flags3 |= ANALYTICMODE; if(dlg->m_ReplacePrivOps) t->flags5 |= REPLACEPRIVOPS; if(dlg->m_InitialRes) t->flags7 |= INITIALRES; if(dlg->m_MaximumRes) t->flags7 |= MAXIMUMRES; - //if(dlg->m_ForceVSync) t->flags8 |= FORCEVSYNC; - //if(dlg->m_ForceNoVSync) t->flags8 |= FORCENOVSYNC; - //if(dlg->m_ForceWait) t->flags8 |= FORCEWAIT; - //if(dlg->m_ForceNoWait) t->flags8 |= FORCENOWAIT; t->posx = dlg->m_PosX; t->posy = dlg->m_PosY; t->sizx = dlg->m_SizX; @@ -577,7 +563,6 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg) dlg->m_NoBanner = t->flags2 & NOBANNER ? 1 : 0; dlg->m_FullScreenOnly = t->flags3 & FULLSCREENONLY ? 1 : 0; dlg->m_ShowHints = t->flags7 & SHOWHINTS ? 1 : 0; - //dlg->m_FilterMessages = t->flags3 & FILTERMESSAGES ? 1 : 0; dlg->m_PeekAllMessages = t->flags3 & PEEKALLMESSAGES ? 1 : 0; dlg->m_NoWinPosChanges = t->flags5 & NOWINPOSCHANGES ? 1 : 0; dlg->m_MessagePump = t->flags5 & MESSAGEPUMP ? 1 : 0; @@ -601,7 +586,6 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg) if(t->flags2 & GDISTRETCHED) dlg->m_DCEmulationMode = 1; if(t->flags3 & GDIEMULATEDC) dlg->m_DCEmulationMode = 2; if(t->flags6 & SHAREDDC ) dlg->m_DCEmulationMode = 3; - //if(t->flags & MAPGDITOPRIMARY) dlg->m_DCEmulationMode = 3; dlg->m_ResTypes = 0; if(t->flags4 & SUPPORTSVGA) dlg->m_ResTypes = 0; @@ -690,6 +674,7 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg) dlg->m_SuppressD3DExt = t->flags3 & SUPPRESSD3DEXT ? 1 : 0; dlg->m_Enum16bitModes = t->flags7 & ENUM16BITMODES ? 1 : 0; dlg->m_TrimTextureFormats = t->flags8 & TRIMTEXTUREFORMATS ? 1 : 0; + dlg->m_RawFormat = t->flags8 & RAWFORMAT ? 1 : 0; dlg->m_SetCompatibility = t->flags2 & SETCOMPATIBILITY ? 1 : 0; dlg->m_AEROBoost = t->flags5 & AEROBOOST ? 1 : 0; dlg->m_DiabloTweak = t->flags5 & DIABLOTWEAK ? 1 : 0; @@ -744,20 +729,15 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg) dlg->m_ClearTarget = t->flags5 & CLEARTARGET ? 1 : 0; dlg->m_FixPitch = t->flags6 & FIXPITCH ? 1 : 0; dlg->m_Power2Width = t->flags6 & POWER2WIDTH ? 1 : 0; - //dlg->m_SaveLoad = t->flags & SAVELOAD ? 1 : 0; dlg->m_SlowDown = t->flags & SLOWDOWN ? 1 : 0; dlg->m_BlitFromBackBuffer = t->flags & BLITFROMBACKBUFFER ? 1 : 0; dlg->m_NoFlipEmulation = t->flags4 & NOFLIPEMULATION ? 1 : 0; dlg->m_LockColorDepth = t->flags7 & LOCKCOLORDEPTH ? 1 : 0; -// dlg->m_SuppressClipping = t->flags & SUPPRESSCLIPPING ? 1 : 0; -// dlg->m_ForceClipper = t->flags3 & FORCECLIPPER ? 1 : 0; dlg->m_DisableGammaRamp = t->flags2 & DISABLEGAMMARAMP ? 1 : 0; dlg->m_AutoRefresh = t->flags & AUTOREFRESH ? 1 : 0; dlg->m_IndependentRefresh = t->flags2 & INDEPENDENTREFRESH ? 1 : 0; dlg->m_TextureFormat = t->flags5 & TEXTUREFORMAT ? 1 : 0; dlg->m_FixWinFrame = t->flags & FIXWINFRAME ? 1 : 0; - //dlg->m_EnableClipping = t->flags & DISABLECLIPPING ? 1 : 0; - //dlg->m_CursorClipping = t->flags & CLIPCURSOR ? 1 : 0; dlg->m_VideoToSystemMem = t->flags & SWITCHVIDEOMEMORY ? 1 : 0; dlg->m_FixTextOut = t->flags & FIXTEXTOUT ? 1 : 0; dlg->m_SharedDC = t->flags6 & SHAREDDC ? 1 : 0; @@ -790,9 +770,9 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg) dlg->m_HideMultiMonitor = t->flags2 & HIDEMULTIMONITOR ? 1 : 0; dlg->m_FixD3DFrame = t->flags3 & FIXD3DFRAME ? 1 : 0; dlg->m_NoWindowMove = t->flags3 & NOWINDOWMOVE ? 1 : 0; - //dlg->m_Force16BPP = t->flags3 & FORCE16BPP ? 1 : 0; dlg->m_HookChildWin = t->flags & HOOKCHILDWIN ? 1 : 0; dlg->m_MessageProc = t->flags & MESSAGEPROC ? 1 : 0; + dlg->m_FixMouseHook = t->flags8 & FIXMOUSEHOOK ? 1 : 0; dlg->m_FixNCHITTEST = t->flags2 & FIXNCHITTEST ? 1 : 0; dlg->m_RecoverScreenMode = t->flags2 & RECOVERSCREENMODE ? 1 : 0; dlg->m_RefreshOnResize = t->flags2 & REFRESHONRESIZE ? 1 : 0; @@ -842,14 +822,11 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg) dlg->m_SyncPalette = t->flags6 & SYNCPALETTE ? 1 : 0; dlg->m_NoWinErrors = t->flags7 & NOWINERRORS ? 1 : 0; dlg->m_PretendVisible = t->flags8 & PRETENDVISIBLE ? 1 : 0; + dlg->m_WinInsulation = t->flags8 & WININSULATION ? 1 : 0; dlg->m_AnalyticMode = t->flags3 & ANALYTICMODE ? 1 : 0; dlg->m_ReplacePrivOps = t->flags5 & REPLACEPRIVOPS ? 1 : 0; dlg->m_InitialRes = t->flags7 & INITIALRES ? 1 : 0; dlg->m_MaximumRes = t->flags7 & MAXIMUMRES ? 1 : 0; - //dlg->m_ForceVSync = t->flags8 & FORCEVSYNC ? 1 : 0; - //dlg->m_ForceNoVSync = t->flags8 & FORCENOVSYNC ? 1 : 0; - //dlg->m_ForceWait = t->flags8 & FORCEWAIT ? 1 : 0; - //dlg->m_ForceNoWait = t->flags8 & FORCENOWAIT ? 1 : 0; dlg->m_PosX = t->posx; dlg->m_PosY = t->posy; dlg->m_SizX = t->sizx; diff --git a/host/resource b/host/resource index 6babaaa..b14d3a8 100644 Binary files a/host/resource and b/host/resource differ