diff --git a/Include/dds.h b/Include/dds.h new file mode 100644 index 0000000..4d74620 --- /dev/null +++ b/Include/dds.h @@ -0,0 +1,237 @@ +//-------------------------------------------------------------------------------------- +// dds.h +// +// This header defines constants and structures that are useful when parsing +// DDS files. DDS files were originally designed to use several structures +// and constants that are native to DirectDraw and are defined in ddraw.h, +// such as DDSURFACEDESC2 and DDSCAPS2. This file defines similar +// (compatible) constants and structures so that one can use DDS files +// without needing to include ddraw.h. +// +// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A +// PARTICULAR PURPOSE. +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// http://go.microsoft.com/fwlink/?LinkId=248926 +//-------------------------------------------------------------------------------------- + +#pragma once + +#if defined(_XBOX_ONE) && defined(_TITLE) +#include +#else +#include +#endif + +// VS 2010's stdint.h conflicts with intsafe.h +#pragma warning(push) +#pragma warning(disable : 4005) +#include +#pragma warning(pop) + +namespace DirectX +{ + +#pragma pack(push,1) + +const uint32_t DDS_MAGIC = 0x20534444; // "DDS " + +struct DDS_PIXELFORMAT +{ + uint32_t dwSize; + uint32_t dwFlags; + uint32_t dwFourCC; + uint32_t dwRGBBitCount; + uint32_t dwRBitMask; + uint32_t dwGBitMask; + uint32_t dwBBitMask; + uint32_t dwABitMask; +}; + +#define DDS_FOURCC 0x00000004 // DDPF_FOURCC +#define DDS_RGB 0x00000040 // DDPF_RGB +#define DDS_RGBA 0x00000041 // DDPF_RGB | DDPF_ALPHAPIXELS +#define DDS_LUMINANCE 0x00020000 // DDPF_LUMINANCE +#define DDS_LUMINANCEA 0x00020001 // DDPF_LUMINANCE | DDPF_ALPHAPIXELS +#define DDS_ALPHA 0x00000002 // DDPF_ALPHA +#define DDS_PAL8 0x00000020 // DDPF_PALETTEINDEXED8 + +#ifndef MAKEFOURCC + #define MAKEFOURCC(ch0, ch1, ch2, ch3) \ + ((uint32_t)(uint8_t)(ch0) | ((uint32_t)(uint8_t)(ch1) << 8) | \ + ((uint32_t)(uint8_t)(ch2) << 16) | ((uint32_t)(uint8_t)(ch3) << 24 )) +#endif /* defined(MAKEFOURCC) */ + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DXT1 = + { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','1'), 0, 0, 0, 0, 0 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DXT2 = + { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','2'), 0, 0, 0, 0, 0 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DXT3 = + { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','3'), 0, 0, 0, 0, 0 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DXT4 = + { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','4'), 0, 0, 0, 0, 0 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DXT5 = + { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','5'), 0, 0, 0, 0, 0 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_BC4_UNORM = + { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('B','C','4','U'), 0, 0, 0, 0, 0 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_BC4_SNORM = + { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('B','C','4','S'), 0, 0, 0, 0, 0 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_BC5_UNORM = + { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('B','C','5','U'), 0, 0, 0, 0, 0 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_BC5_SNORM = + { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('B','C','5','S'), 0, 0, 0, 0, 0 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_R8G8_B8G8 = + { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('R','G','B','G'), 0, 0, 0, 0, 0 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_G8R8_G8B8 = + { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('G','R','G','B'), 0, 0, 0, 0, 0 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_YUY2 = + { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('Y','U','Y','2'), 0, 0, 0, 0, 0 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A8R8G8B8 = + { sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_X8R8G8B8 = + { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A8B8G8R8 = + { sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_X8B8G8R8 = + { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_G16R16 = + { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 32, 0x0000ffff, 0xffff0000, 0x00000000, 0x00000000 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_R5G6B5 = + { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 16, 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A1R5G5B5 = + { sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x00007c00, 0x000003e0, 0x0000001f, 0x00008000 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A4R4G4B4 = + { sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x00000f00, 0x000000f0, 0x0000000f, 0x0000f000 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_R8G8B8 = + { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_L8 = + { sizeof(DDS_PIXELFORMAT), DDS_LUMINANCE, 0, 8, 0xff, 0x00, 0x00, 0x00 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_L16 = + { sizeof(DDS_PIXELFORMAT), DDS_LUMINANCE, 0, 16, 0xffff, 0x0000, 0x0000, 0x0000 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A8L8 = + { sizeof(DDS_PIXELFORMAT), DDS_LUMINANCEA, 0, 16, 0x00ff, 0x0000, 0x0000, 0xff00 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A8 = + { sizeof(DDS_PIXELFORMAT), DDS_ALPHA, 0, 8, 0x00, 0x00, 0x00, 0xff }; + +// D3DFMT_A2R10G10B10/D3DFMT_A2B10G10R10 should be written using DX10 extension to avoid D3DX 10:10:10:2 reversal issue + +// This indicates the DDS_HEADER_DXT10 extension is present (the format is in dxgiFormat) +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DX10 = + { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','1','0'), 0, 0, 0, 0, 0 }; + +#define DDS_HEADER_FLAGS_TEXTURE 0x00001007 // DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT +#define DDS_HEADER_FLAGS_MIPMAP 0x00020000 // DDSD_MIPMAPCOUNT +#define DDS_HEADER_FLAGS_VOLUME 0x00800000 // DDSD_DEPTH +#define DDS_HEADER_FLAGS_PITCH 0x00000008 // DDSD_PITCH +#define DDS_HEADER_FLAGS_LINEARSIZE 0x00080000 // DDSD_LINEARSIZE + +#define DDS_HEIGHT 0x00000002 // DDSD_HEIGHT +#define DDS_WIDTH 0x00000004 // DDSD_WIDTH + +#define DDS_SURFACE_FLAGS_TEXTURE 0x00001000 // DDSCAPS_TEXTURE +#define DDS_SURFACE_FLAGS_MIPMAP 0x00400008 // DDSCAPS_COMPLEX | DDSCAPS_MIPMAP +#define DDS_SURFACE_FLAGS_CUBEMAP 0x00000008 // DDSCAPS_COMPLEX + +#define DDS_CUBEMAP_POSITIVEX 0x00000600 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX +#define DDS_CUBEMAP_NEGATIVEX 0x00000a00 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX +#define DDS_CUBEMAP_POSITIVEY 0x00001200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY +#define DDS_CUBEMAP_NEGATIVEY 0x00002200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY +#define DDS_CUBEMAP_POSITIVEZ 0x00004200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ +#define DDS_CUBEMAP_NEGATIVEZ 0x00008200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ + +#define DDS_CUBEMAP_ALLFACES ( DDS_CUBEMAP_POSITIVEX | DDS_CUBEMAP_NEGATIVEX |\ + DDS_CUBEMAP_POSITIVEY | DDS_CUBEMAP_NEGATIVEY |\ + DDS_CUBEMAP_POSITIVEZ | DDS_CUBEMAP_NEGATIVEZ ) + +#define DDS_CUBEMAP 0x00000200 // DDSCAPS2_CUBEMAP + +#define DDS_FLAGS_VOLUME 0x00200000 // DDSCAPS2_VOLUME + +// Subset here matches D3D10_RESOURCE_DIMENSION and D3D11_RESOURCE_DIMENSION +enum DDS_RESOURCE_DIMENSION +{ + DDS_DIMENSION_TEXTURE1D = 2, + DDS_DIMENSION_TEXTURE2D = 3, + DDS_DIMENSION_TEXTURE3D = 4, +}; + +// Subset here matches D3D10_RESOURCE_MISC_FLAG and D3D11_RESOURCE_MISC_FLAG +enum DDS_RESOURCE_MISC_FLAG +{ + DDS_RESOURCE_MISC_TEXTURECUBE = 0x4L, +}; + +enum DDS_MISC_FLAGS2 +{ + DDS_MISC_FLAGS2_ALPHA_MODE_MASK = 0x7L, +}; + +enum DDS_ALPHA_MODE +{ + DDS_ALPHA_MODE_UNKNOWN = 0, + DDS_ALPHA_MODE_STRAIGHT = 1, + DDS_ALPHA_MODE_PREMULTIPLIED = 2, + DDS_ALPHA_MODE_OPAQUE = 3, + DDS_ALPHA_MODE_CUSTOM = 4, +}; + +struct DDS_HEADER +{ + uint32_t dwSize; + uint32_t dwFlags; + uint32_t dwHeight; + uint32_t dwWidth; + uint32_t dwPitchOrLinearSize; + uint32_t dwDepth; // only if DDS_HEADER_FLAGS_VOLUME is set in dwFlags + uint32_t dwMipMapCount; + uint32_t dwReserved1[11]; + DDS_PIXELFORMAT ddspf; + uint32_t dwCaps; + uint32_t dwCaps2; + uint32_t dwCaps3; + uint32_t dwCaps4; + uint32_t dwReserved2; +}; + +struct DDS_HEADER_DXT10 +{ + DXGI_FORMAT dxgiFormat; + uint32_t resourceDimension; + uint32_t miscFlag; // see DDS_RESOURCE_MISC_FLAG + uint32_t arraySize; + uint32_t miscFlags2; // see DDS_MISC_FLAGS2 +}; + +#pragma pack(pop) + +static_assert( sizeof(DDS_HEADER) == 124, "DDS Header size mismatch" ); +static_assert( sizeof(DDS_HEADER_DXT10) == 20, "DDS DX10 Extended Header size mismatch"); + +}; // namespace diff --git a/Include/dxwnd.h b/Include/dxwnd.h index 477de08..d318e1d 100644 --- a/Include/dxwnd.h +++ b/Include/dxwnd.h @@ -261,6 +261,7 @@ #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,..) +#define DDSFORMAT 0x00001000 // texture dump / hack are performed in MS DDS format // logging Tflags DWORD: #define OUTTRACE 0x00000001 // enables tracing to dxwnd.log in general diff --git a/build/dxwnd.dll b/build/dxwnd.dll index ca8bd2d..86a2c37 100644 --- a/build/dxwnd.dll +++ b/build/dxwnd.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b3e4a919d94a65a136733126cb2ab2ea7ec6ea20d20d06acc7fc826fb8dd7bce -size 756736 +oid sha256:b75df7287fd454e0b3591e2a03736287d786a51d15bfbdeb71958a1488e4db40 +size 758272 diff --git a/build/dxwnd.exe b/build/dxwnd.exe index 678ae18..3c9e984 100644 --- a/build/dxwnd.exe +++ b/build/dxwnd.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f4781f62e3b9bbc3cb28f6ab03585167d87e0352520ba25ee7ad0102ad02a244 -size 668160 +oid sha256:0f2265c91f849cbdc3a809b7ff592df41d95806ecd6d9cadb125ddb2e15b48b6 +size 669184 diff --git a/build/exports/LuXiaoFeng.dxw b/build/exports/LuXiaoFeng.dxw new file mode 100644 index 0000000..6e73979 --- /dev/null +++ b/build/exports/LuXiaoFeng.dxw @@ -0,0 +1,36 @@ +[target] +title0=LuXiaoFeng +path0=F:\Games\lxf\core.dat +startfolder0= +launchpath0=F:\Games\lxf\Lxf.exe +module0= +opengllib0= +notes0= +registry0= +ver0=0 +monitorid0=-1 +coord0=0 +flag0=673185826 +flagg0=1207959552 +flagh0=20 +flagi0=138412036 +flagj0=4224 +flagk0=65536 +flagl0=8704 +flagm0=0 +tflag0=0 +dflag0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=0 +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 a0c6723..36e81c8 100644 --- a/build/readme-relnotes.txt +++ b/build/readme-relnotes.txt @@ -1380,7 +1380,7 @@ 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) -v2.04.00 +v2.04.00/fx2 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 @@ -1391,3 +1391,5 @@ 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 +fix: improvements in texture handling, dds format support for DirectDraw textures +fix: fixed fast bilinear 2X on 32 bit color depth diff --git a/dll/d3dtexture.cpp b/dll/d3dtexture.cpp index e9bac6b..7c7d0d6 100644 --- a/dll/d3dtexture.cpp +++ b/dll/d3dtexture.cpp @@ -7,13 +7,22 @@ #include "dxhelper.h" #include "syslibs.h" #include "stdio.h" +#include "dxdds.h" #define STB_DXT_IMPLEMENTATION #include "stb_dxt.h" +//#define SOLIDCOLOR + extern unsigned int HashSurface(BYTE *, int, int, int); extern char *GetDxWndPath(); +typedef enum { + FORMAT_BMP = 0, + FORMAT_RAW, + FORMAT_DDS +}; + static unsigned int HashBuffer(BYTE *buf, int len) { unsigned int b = 378551; @@ -166,6 +175,35 @@ static int FormatColorDepth(D3DFORMAT Format) return iColorDepth; } +static DWORD DDSTextureType(D3DFORMAT Format) +{ + int dwFlag = 0; + switch (Format){ + case D3DFMT_X8R8G8B8: + case D3DFMT_X4R4G4B4: + case D3DFMT_X1R5G5B5: + case D3DFMT_R5G6B5: + dwFlag = DDPF_RGB; + break; + case D3DFMT_A8R8G8B8: + case D3DFMT_A4R4G4B4: // AoE III + case D3DFMT_A1R5G5B5: // AoE III + dwFlag = DDPF_RGB|DDPF_ALPHAPIXELS; + break; + case D3DFMT_DXT1: + case D3DFMT_DXT2: + case D3DFMT_DXT3: + case D3DFMT_DXT4: + case D3DFMT_DXT5: + dwFlag = DDPF_FOURCC; + break; + case D3DFMT_A8: + case D3DFMT_L8: + break; + } + return dwFlag; +} + // FormatColorBytes macro gives color depth in bytes by dividing by 8 (=> lshift 3) #define FormatColorBytes(Format) (FormatColorDepth(Format) >> 3) @@ -200,6 +238,56 @@ static DWORD TextureSize(D3DSURFACE_DESC Desc, D3DLOCKED_RECT LockedRect) return dwSize; } +static void SetDDSPixelFormat(D3DFORMAT Format, DDS_PIXELFORMAT *pf) +{ + switch (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: + pf->dwRGBBitCount = 32; + pf->dwRBitMask = 0x00FF0000; + pf->dwGBitMask = 0x0000FF00; + pf->dwBBitMask = 0x000000FF; + pf->dwABitMask = 0xFF000000; + break; + case D3DFMT_DXT1: + pf->dwRGBBitCount = 16; + pf->dwRBitMask = 0xF800; + pf->dwGBitMask = 0x07E0; + pf->dwBBitMask = 0x001F; + pf->dwABitMask = 0x0000; + break; + case D3DFMT_A4R4G4B4: // AoE III + case D3DFMT_X4R4G4B4: + pf->dwRGBBitCount = 16; + pf->dwRBitMask = 0x0F00; + pf->dwGBitMask = 0x00F0; + pf->dwBBitMask = 0x000F; + pf->dwABitMask = 0xF000; + break; + case D3DFMT_A1R5G5B5: // AoE III + case D3DFMT_X1R5G5B5: + pf->dwRGBBitCount = 16; + pf->dwRBitMask = 0x7C00; + pf->dwGBitMask = 0x03E0; + pf->dwBBitMask = 0x001F; + pf->dwABitMask = 0x8000; + break; + case D3DFMT_R5G6B5: + pf->dwRGBBitCount = 16; + pf->dwRBitMask = 0x7C00; + pf->dwGBitMask = 0x03E0; + pf->dwBBitMask = 0x001F; + pf->dwABitMask = 0x0000; + break; + } +} + static DWORD D3DHash(D3DSURFACE_DESC Desc, D3DLOCKED_RECT LockedRect) { DWORD hash; @@ -337,8 +425,9 @@ void D3DTextureDump(D3DSURFACE_DESC Desc, D3DLOCKED_RECT LockedRect) int w, h; int iSurfaceSize, iScanLineSize; char pszFile[MAX_PATH]; + char *sExt; DWORD hash; - BOOL IsRaw = (dxw.dwFlags8 & RAWFORMAT); + static int iTextureFileFormat; if(DoOnce){ char sProfilePath[MAX_PATH]; @@ -347,9 +436,12 @@ void D3DTextureDump(D3DSURFACE_DESC Desc, D3DLOCKED_RECT LockedRect) MaxTexX=GetPrivateProfileInt("Texture", "MaxTexX", 0, sProfilePath); MinTexY=GetPrivateProfileInt("Texture", "MinTexY", 0, sProfilePath); MaxTexY=GetPrivateProfileInt("Texture", "MaxTexY", 0, sProfilePath); - OutTrace("TextureDump: size min=(%dx%d) max=(%dx%d)\n", MinTexX, MinTexY, MaxTexX, MaxTexY); sprintf_s(pszFile, MAX_PATH, "%s\\texture.out", GetDxWndPath()); CreateDirectory(pszFile, NULL); + iTextureFileFormat = FORMAT_BMP; + if(dxw.dwFlags8 & RAWFORMAT) iTextureFileFormat = FORMAT_RAW; + if(dxw.dwFlags8 & DDSFORMAT) iTextureFileFormat = FORMAT_DDS; + OutTrace("TextureDump: size min=(%dx%d) max=(%dx%d) format=%d\n", MinTexX, MinTexY, MaxTexX, MaxTexY, iTextureFileFormat); DoOnce = FALSE; } @@ -379,224 +471,260 @@ void D3DTextureDump(D3DSURFACE_DESC Desc, D3DLOCKED_RECT LockedRect) break; // almost certainly, an empty black surface! } - // Create the .BMP file. + // Create the file. + switch (iTextureFileFormat){ + case FORMAT_BMP: sExt = "bmp"; break; + case FORMAT_RAW: sExt = "raw"; break; + case FORMAT_DDS: sExt = "dds"; break; + } 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"); + GetDxWndPath(), Desc.Width, Desc.Height, ExplainD3DSurfaceFormat(Desc.Format), hash, sExt); hf = fopen(pszFile, "wb"); if(!hf) break; - if(IsRaw){ - fwrite((BYTE *)LockedRect.pBits, TextureSize(Desc, LockedRect), 1, hf); - fclose(hf); - return; - } + switch(iTextureFileFormat){ - // set bmp invariant parameters - if (SetBMPStruct(&pbi, &hdr, Desc)) break; - iScanLineSize = ((pbi.bV4Width * pbi.bV4BitCount + 0x1F) & ~0x1F)/8; + case FORMAT_RAW: - // Copy the BITMAPFILEHEADER into the .BMP file. - fwrite((LPVOID)&hdr, sizeof(BITMAPFILEHEADER), 1, hf); + if(fwrite((BYTE *)LockedRect.pBits, TextureSize(Desc, LockedRect), 1, hf)!=1) + OutTraceE("TextureHack: fwrite ERROR err=%d\n", GetLastError()); + fclose(hf); + break; - // Copy the BITMAPINFOHEADER and RGBQUAD array into the file. - fwrite((LPVOID)&pbi, sizeof(BITMAPV4HEADER) + pbi.bV4ClrUsed * sizeof (RGBQUAD), 1, hf); + case FORMAT_DDS: { - switch (Desc.Format){ - case D3DFMT_X8R8G8B8: - case D3DFMT_A8R8G8B8: - case D3DFMT_A4R4G4B4: - case D3DFMT_X4R4G4B4: - case D3DFMT_A1R5G5B5: // AoE III - case D3DFMT_R5G6B5: // AoE III - case D3DFMT_X1R5G5B5: - { - // Copy the array of color indices into the .BMP file. - for(int y=0; y<(int)Desc.Height; y++) - fwrite((BYTE *)LockedRect.pBits + (y*LockedRect.Pitch), iScanLineSize, 1, hf); + DDS_HEADER ddsh; + if(fwrite("DDS ", 4, 1, hf)!=1) + OutTraceE("TextureHack: fwrite ERROR err=%d\n", GetLastError()); + memset(&ddsh, 0, sizeof(ddsh)); + ddsh.dwSize = sizeof(ddsh); + ddsh.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT; + ddsh.dwHeight = Desc.Height; + ddsh.dwWidth = Desc.Width; + ddsh.ddspf.dwSize = sizeof(DDS_PIXELFORMAT); + ddsh.ddspf.dwFlags = DDSTextureType(Desc.Format); + // compressed formats must have 0 pitch + if(ddsh.ddspf.dwFlags & DDPF_RGB) { + ddsh.dwPitchOrLinearSize = LockedRect.Pitch; + ddsh.dwFlags |= DDSD_PITCH; } - break; - case D3DFMT_A8: - case D3DFMT_L8: - { - // Copy the array of color indices into the .BMP file. - BYTE *p = (BYTE *)LockedRect.pBits; - for(int y=0; y<(int)Desc.Height; y++) - for(int x=0; x<(int)Desc.Width; x++){ - DWORD pixel; - pixel = 0xFF000000 | *p | (*p << 8) | (*p << 16); // gray color - fwrite((BYTE *)&pixel, sizeof(DWORD), 1, hf); - p++; - } - } - break; - case D3DFMT_DXT1: - { - // Copy the array of color indices into the .BMP file. - WORD *bm; - WORD *c; - int bmsize; - c = (WORD *)LockedRect.pBits; - bmsize = Desc.Width * Desc.Height * sizeof(WORD); - bm = (WORD *)malloc(bmsize); - for(int y=0; y<(int)Desc.Height; y+=4){ - for(int x=0; x<(int)Desc.Width; x+=4){ - WORD color_0, color_1, color_2, color_3; - color_0 = *c++; - color_1 = *c++; - color_2 = Melt_123(color_1, color_0); - color_3 = Melt_123(color_0, color_1); - for(int n=0; n<2; n++){ - int dy; - WORD color_indexes = *c++; - WORD color; - for (int m=0; m<8; m++){ - switch (color_indexes & 0x3){ - case 0x00: color = color_0; break; - case 0x01: color = color_1; break; - case 0x02: color = color_2; break; - case 0x03: color = color_3; break; + if(ddsh.ddspf.dwFlags & DDPF_FOURCC) ddsh.ddspf.dwFourCC = Desc.Format; + SetDDSPixelFormat(Desc.Format, &ddsh.ddspf); + if(fwrite((BYTE *)&ddsh, sizeof(ddsh), 1, hf)!=1) + OutTraceE("TextureHack: fwrite ERROR err=%d\n", GetLastError()); + if(fwrite((BYTE *)LockedRect.pBits, TextureSize(Desc, LockedRect), 1, hf)!=1) + OutTraceE("TextureHack: fwrite ERROR err=%d\n", GetLastError()); + } + break; + + case FORMAT_BMP: + + // set bmp invariant parameters + if (SetBMPStruct(&pbi, &hdr, Desc)) break; + iScanLineSize = ((pbi.bV4Width * pbi.bV4BitCount + 0x1F) & ~0x1F)/8; + + // Copy the BITMAPFILEHEADER into the .BMP file. + fwrite((LPVOID)&hdr, sizeof(BITMAPFILEHEADER), 1, hf); + + // Copy the BITMAPINFOHEADER and RGBQUAD array into the file. + fwrite((LPVOID)&pbi, sizeof(BITMAPV4HEADER) + pbi.bV4ClrUsed * sizeof (RGBQUAD), 1, hf); + + switch (Desc.Format){ + case D3DFMT_X8R8G8B8: + case D3DFMT_A8R8G8B8: + case D3DFMT_A4R4G4B4: + case D3DFMT_X4R4G4B4: + case D3DFMT_A1R5G5B5: // AoE III + case D3DFMT_R5G6B5: // AoE III + case D3DFMT_X1R5G5B5: + { + // Copy the array of color indices into the .BMP file. + for(int y=0; y<(int)Desc.Height; y++) + fwrite((BYTE *)LockedRect.pBits + (y*LockedRect.Pitch), iScanLineSize, 1, hf); + } + break; + case D3DFMT_A8: + case D3DFMT_L8: + { + // Copy the array of color indices into the .BMP file. + BYTE *p = (BYTE *)LockedRect.pBits; + for(int y=0; y<(int)Desc.Height; y++) + for(int x=0; x<(int)Desc.Width; x++){ + DWORD pixel; + pixel = 0xFF000000 | *p | (*p << 8) | (*p << 16); // gray color + fwrite((BYTE *)&pixel, sizeof(DWORD), 1, hf); + p++; + } + } + break; + case D3DFMT_DXT1: + { + // Copy the array of color indices into the .BMP file. + WORD *bm; + WORD *c; + int bmsize; + c = (WORD *)LockedRect.pBits; + bmsize = Desc.Width * Desc.Height * sizeof(WORD); + bm = (WORD *)malloc(bmsize); + for(int y=0; y<(int)Desc.Height; y+=4){ + for(int x=0; x<(int)Desc.Width; x+=4){ + WORD color_0, color_1, color_2, color_3; + color_0 = *c++; + color_1 = *c++; + color_2 = Melt_123(color_1, color_0); + color_3 = Melt_123(color_0, color_1); + for(int n=0; n<2; n++){ + int dy; + WORD color_indexes = *c++; + WORD color; + for (int m=0; m<8; m++){ + switch (color_indexes & 0x3){ + case 0x00: color = color_0; break; + case 0x01: color = color_1; break; + case 0x02: color = color_2; break; + case 0x03: color = color_3; break; + } + dy = (m<4) ? 0 : 1; + color_indexes >>= 2; + int index = ((y+(2*n)+dy)*Desc.Width) + (x+(m%4)); + if(index < bmsize/2) bm[index]=color; } - dy = (m<4) ? 0 : 1; - color_indexes >>= 2; - int index = ((y+(2*n)+dy)*Desc.Width) + (x+(m%4)); - if(index < bmsize/2) bm[index]=color; } } } + fwrite((BYTE *)bm, bmsize, 1, hf); + free(bm); } - fwrite((BYTE *)bm, bmsize, 1, hf); - free(bm); - } - break; - case D3DFMT_DXT2: - case D3DFMT_DXT3: - { - // Copy the array of color indices into the .BMP file. - DWORD *bm; - WORD *c; - int bmsize; - c = (WORD *)LockedRect.pBits; - bmsize = Desc.Width * Desc.Height * sizeof(DWORD); - bm = (DWORD *)malloc(bmsize); - memset(bm, 0, bmsize); - for(int y=0; y<(int)Desc.Height; y+=4){ - for(int x=0; x<(int)Desc.Width; x+=4){ - WORD color_0, color_1; - DWORD dwcolor[4]; - BYTE alpha[16]; - WORD *pAlpha; - pAlpha = (WORD *)c; - for(int row=0; row<4; row++){ - WORD a = *c++; - for(int col=0; col<4; col++){ - alpha[(row<<2)+col] = (a & 0xF); - a >>= 4; + break; + case D3DFMT_DXT2: + case D3DFMT_DXT3: + { + // Copy the array of color indices into the .BMP file. + DWORD *bm; + WORD *c; + int bmsize; + c = (WORD *)LockedRect.pBits; + bmsize = Desc.Width * Desc.Height * sizeof(DWORD); + bm = (DWORD *)malloc(bmsize); + memset(bm, 0, bmsize); + for(int y=0; y<(int)Desc.Height; y+=4){ + for(int x=0; x<(int)Desc.Width; x+=4){ + WORD color_0, color_1; + DWORD dwcolor[4]; + BYTE alpha[16]; + WORD *pAlpha; + pAlpha = (WORD *)c; + for(int row=0; row<4; row++){ + WORD a = *c++; + for(int col=0; col<4; col++){ + alpha[(row<<2)+col] = (a & 0xF); + a >>= 4; + } } + color_0 = *c++; + color_1 = *c++; + dwcolor[0] = Conv32(color_0); + dwcolor[1] = Conv32(color_1); + dwcolor[2] = Melt32_123(color_1, color_0); + dwcolor[3] = Melt32_123(color_0, color_1); + for(int n=0; n<2; n++){ + int dy; + WORD color_indexes = *c++; + DWORD color; + for (int m=0; m<8; m++){ + dy = (m<4) ? 0 : 1; + color = dwcolor[color_indexes & 0x3] & 0x00FFFFFF; + dy = (m<4) ? 0 : 1; + color_indexes >>= 2; + int index = ((y+(2*n)+dy)*Desc.Width) + (x+(m%4)); + int alpha_index = (((2*n) + dy)<<2) + (m % 4); + //if(index < bmsize/4) bm[index] = color | 0xFF000000; // uncomment to get rid of alpha channel + if(index < bmsize/4) bm[index] = color | (alpha[alpha_index]<<28); + } + } } - color_0 = *c++; - color_1 = *c++; - dwcolor[0] = Conv32(color_0); - dwcolor[1] = Conv32(color_1); - dwcolor[2] = Melt32_123(color_1, color_0); - dwcolor[3] = Melt32_123(color_0, color_1); - for(int n=0; n<2; n++){ - int dy; - WORD color_indexes = *c++; - DWORD color; - for (int m=0; m<8; m++){ - dy = (m<4) ? 0 : 1; - color = dwcolor[color_indexes & 0x3] & 0x00FFFFFF; - dy = (m<4) ? 0 : 1; - color_indexes >>= 2; - int index = ((y+(2*n)+dy)*Desc.Width) + (x+(m%4)); - int alpha_index = (((2*n) + dy)<<2) + (m % 4); - //if(index < bmsize/4) bm[index] = color | 0xFF000000; // uncomment to get rid of alpha channel - if(index < bmsize/4) bm[index] = color | (alpha[alpha_index]<<28); - } - } } + fwrite((BYTE *)bm, bmsize, 1, hf); + free(bm); } - fwrite((BYTE *)bm, bmsize, 1, hf); - free(bm); - } - break; - case D3DFMT_DXT4: - case D3DFMT_DXT5: - { - // Copy the array of color indices into the .BMP file. - DWORD *bm; - WORD *c; - int bmsize; - c = (WORD *)LockedRect.pBits; - bmsize = Desc.Width * Desc.Height * sizeof(DWORD); - bm = (DWORD *)malloc(bmsize); - memset(bm, 0, bmsize); - for(int y=0; y<(int)Desc.Height; y+=4){ - for(int x=0; x<(int)Desc.Width; x+=4){ - WORD color_0, color_1; - DWORD dwcolor[4]; - DWORD alpha[8]; - // alpha section (4 words) .... - alpha[1] = ((*c) >> 8) & 0xFF; - alpha[0] = (*c) & 0xFF; - c++; - if(alpha[0] > alpha[1]) - { - // 6 interpolated alpha values. - alpha[2] = ((6*alpha[0]) + (1*alpha[1])) / 7; // bit code 010 - alpha[3] = ((5*alpha[0]) + (2*alpha[1])) / 7; // bit code 011 - alpha[4] = ((4*alpha[0]) + (3*alpha[1])) / 7; // bit code 100 - alpha[5] = ((3*alpha[0]) + (4*alpha[1])) / 7; // bit code 101 - alpha[6] = ((2*alpha[0]) + (5*alpha[1])) / 7; // bit code 110 - alpha[7] = ((1*alpha[0]) + (6*alpha[1])) / 7; // bit code 111 - } - else - { - // 4 interpolated alpha values. - alpha[2] = ((4*alpha[0]) + (1*alpha[1])) / 5; // bit code 010 - alpha[3] = ((3*alpha[0]) + (2*alpha[1])) / 5; // bit code 011 - alpha[4] = ((2*alpha[0]) + (3*alpha[1])) / 5; // bit code 100 - alpha[5] = ((1*alpha[0]) + (4*alpha[1])) / 5; // bit code 101 - alpha[6] = 0x00; // bit code 110 (fully transparent) - alpha[7] = 0xFF; // bit code 111 (fully opaque) - } - BYTE *pAlpha = (BYTE *)c; - c += 3; - color_0 = *c++; - color_1 = *c++; - dwcolor[0] = Conv32(color_0); - dwcolor[1] = Conv32(color_1); - dwcolor[2] = Melt32_123(color_1, color_0); - dwcolor[3] = Melt32_123(color_0, color_1); - for(int n=0; n<2; n++){ - int dy; - DWORD dwAlpha_indexes = (*(pAlpha+0) & 0x0000FF) | ((*(pAlpha+1)<<8) & 0x00FF00) | ((*(pAlpha+2)<<16) & 0xFF0000); - pAlpha += 3; - DWORD alpha_color; - WORD color_indexes = *c++; - DWORD color; - for (int m=0; m<8; m++){ - alpha_color = (alpha[dwAlpha_indexes & 0x7] << 24) & 0xFF000000; - dy = (m<4) ? 0 : 1; - dwAlpha_indexes >>= 3; - color = dwcolor[color_indexes & 0x3] & 0x00FFFFFF; - dy = (m<4) ? 0 : 1; - color_indexes >>= 2; - int index = ((y+(2*n)+dy)*Desc.Width) + (x+(m%4)); - if(index < bmsize/4) bm[index] = color | alpha_color; + break; + case D3DFMT_DXT4: + case D3DFMT_DXT5: + { + // Copy the array of color indices into the .BMP file. + DWORD *bm; + WORD *c; + int bmsize; + c = (WORD *)LockedRect.pBits; + bmsize = Desc.Width * Desc.Height * sizeof(DWORD); + bm = (DWORD *)malloc(bmsize); + memset(bm, 0, bmsize); + for(int y=0; y<(int)Desc.Height; y+=4){ + for(int x=0; x<(int)Desc.Width; x+=4){ + WORD color_0, color_1; + DWORD dwcolor[4]; + DWORD alpha[8]; + // alpha section (4 words) .... + alpha[1] = ((*c) >> 8) & 0xFF; + alpha[0] = (*c) & 0xFF; + c++; + if(alpha[0] > alpha[1]) + { + // 6 interpolated alpha values. + alpha[2] = ((6*alpha[0]) + (1*alpha[1])) / 7; // bit code 010 + alpha[3] = ((5*alpha[0]) + (2*alpha[1])) / 7; // bit code 011 + alpha[4] = ((4*alpha[0]) + (3*alpha[1])) / 7; // bit code 100 + alpha[5] = ((3*alpha[0]) + (4*alpha[1])) / 7; // bit code 101 + alpha[6] = ((2*alpha[0]) + (5*alpha[1])) / 7; // bit code 110 + alpha[7] = ((1*alpha[0]) + (6*alpha[1])) / 7; // bit code 111 } - } + else + { + // 4 interpolated alpha values. + alpha[2] = ((4*alpha[0]) + (1*alpha[1])) / 5; // bit code 010 + alpha[3] = ((3*alpha[0]) + (2*alpha[1])) / 5; // bit code 011 + alpha[4] = ((2*alpha[0]) + (3*alpha[1])) / 5; // bit code 100 + alpha[5] = ((1*alpha[0]) + (4*alpha[1])) / 5; // bit code 101 + alpha[6] = 0x00; // bit code 110 (fully transparent) + alpha[7] = 0xFF; // bit code 111 (fully opaque) + } + BYTE *pAlpha = (BYTE *)c; + c += 3; + color_0 = *c++; + color_1 = *c++; + dwcolor[0] = Conv32(color_0); + dwcolor[1] = Conv32(color_1); + dwcolor[2] = Melt32_123(color_1, color_0); + dwcolor[3] = Melt32_123(color_0, color_1); + for(int n=0; n<2; n++){ + int dy; + DWORD dwAlpha_indexes = (*(pAlpha+0) & 0x0000FF) | ((*(pAlpha+1)<<8) & 0x00FF00) | ((*(pAlpha+2)<<16) & 0xFF0000); + pAlpha += 3; + DWORD alpha_color; + WORD color_indexes = *c++; + DWORD color; + for (int m=0; m<8; m++){ + alpha_color = (alpha[dwAlpha_indexes & 0x7] << 24) & 0xFF000000; + dy = (m<4) ? 0 : 1; + dwAlpha_indexes >>= 3; + color = dwcolor[color_indexes & 0x3] & 0x00FFFFFF; + dy = (m<4) ? 0 : 1; + color_indexes >>= 2; + int index = ((y+(2*n)+dy)*Desc.Width) + (x+(m%4)); + if(index < bmsize/4) bm[index] = color | alpha_color; + } + } + } } + fwrite((BYTE *)bm, bmsize, 1, hf); + free(bm); } - fwrite((BYTE *)bm, bmsize, 1, hf); - free(bm); - } - default: - break; + default: + break; + } + // Close the .BMP file. + fclose(hf); } - // Close the .BMP file. - if(hf) fclose(hf); break; } // end of fake loop 1 } @@ -610,9 +738,10 @@ void D3DTextureHack(D3DSURFACE_DESC Desc, D3DLOCKED_RECT LockedRect) BITMAPV4HEADER pbi; // bitmap info-header int iSurfaceSize, iScanLineSize; char pszFile[MAX_PATH]; + char *sExt; DWORD hash; int w, h; - BOOL IsRaw = (dxw.dwFlags8 & RAWFORMAT); + static int iTextureFileFormat; OutTraceB("TextureHack(D3D)\n"); @@ -623,8 +752,10 @@ void D3DTextureHack(D3DSURFACE_DESC Desc, D3DLOCKED_RECT LockedRect) 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()); + iTextureFileFormat = FORMAT_BMP; + if(dxw.dwFlags8 & RAWFORMAT) iTextureFileFormat = FORMAT_RAW; + if(dxw.dwFlags8 & DDSFORMAT) iTextureFileFormat = FORMAT_DDS; + OutTrace("TextureHack: size min=(%dx%d) max=(%dx%d) format=%d\n", MinTexX, MinTexY, MaxTexX, MaxTexY, iTextureFileFormat); DoOnce = FALSE; } @@ -649,117 +780,144 @@ void D3DTextureHack(D3DSURFACE_DESC Desc, D3DLOCKED_RECT LockedRect) } // Look for the .BMP file. + // Create the file. + switch (iTextureFileFormat){ + case FORMAT_BMP: sExt = "bmp"; break; + case FORMAT_RAW: sExt = "raw"; break; + case FORMAT_DDS: sExt = "dds"; break; + } 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"); + hash, sExt); 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; - } + switch(iTextureFileFormat){ - int iBitCount = FormatColorDepth(Desc.Format); - if(iBitCount == 0){ - OutTrace("TextureHack: unsupported format=%x\n", Desc.Format); + case FORMAT_RAW: + + if(fread((BYTE *)LockedRect.pBits, TextureSize(Desc, LockedRect), 1, hf)!=1) + OutTraceE("TextureHack: fread ERROR err=%d\n", GetLastError()); + break; + + case FORMAT_DDS: { + + BYTE magic[4]; + DDS_HEADER ddsh; + // assume the file is sane, read and throw away magic and dds header + if(fread(magic, 4, 1, hf)!=1) + OutTraceE("TextureHack: fread ERROR err=%d\n", GetLastError()); + if(fread((BYTE *)&ddsh, sizeof(ddsh), 1, hf)!=1) + OutTraceE("TextureHack: fread ERROR err=%d\n", GetLastError()); + memset(&ddsh, 0, sizeof(ddsh)); + if(fread((BYTE *)LockedRect.pBits, TextureSize(Desc, LockedRect), 1, hf)!=1) + OutTraceE("TextureHack: fread ERROR err=%d\n", GetLastError()); + } 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; + case FORMAT_BMP: - // 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; + int iBitCount = FormatColorDepth(Desc.Format); + if(iBitCount == 0){ + OutTrace("TextureHack: unsupported format=%x\n", Desc.Format); + break; + } + iScanLineSize = ((Desc.Width * iBitCount + 0x1F) & ~0x1F)/8; - // skip the RGBQUAD array if the editor inserted one - fseek(hf, hdr.bfOffBits, SEEK_SET); + 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; - 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; + // 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; } } - 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; + 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; } } - free(fb); - } - 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; + } + break; } OutTrace("TextureHack: TEXTURE LOAD DONE\n"); diff --git a/dll/ddtexture.cpp b/dll/ddtexture.cpp index 1d3e915..b128f1b 100644 --- a/dll/ddtexture.cpp +++ b/dll/ddtexture.cpp @@ -8,6 +8,7 @@ #include "dxhook.h" #include "syslibs.h" #include "dxhelper.h" +#include "dxdds.h" extern char *ExplainDDError(DWORD); @@ -21,6 +22,12 @@ extern int Set_dwSize_From_Surface(); #define GRIDSIZE 16 +typedef enum { + FORMAT_BMP = 0, + FORMAT_RAW, + FORMAT_DDS +}; + /* RS Hash Function */ static unsigned int Hash(BYTE *buf, int len) @@ -187,7 +194,8 @@ 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); + char *sExt; + static int iTextureFileFormat; OutTraceB("TextureDump(%d): lpdds=%x\n", dxversion, s); @@ -198,9 +206,12 @@ static void TextureDump(LPDIRECTDRAWSURFACE s, int dxversion) MaxTexX=GetPrivateProfileInt("Texture", "MaxTexX", 0, sProfilePath); MinTexY=GetPrivateProfileInt("Texture", "MinTexY", 0, sProfilePath); MaxTexY=GetPrivateProfileInt("Texture", "MaxTexY", 0, sProfilePath); - OutTrace("TextureDump: size min=(%dx%d) max=(%dx%d)\n", MinTexX, MinTexY, MaxTexX, MaxTexY); sprintf_s(pszFile, MAX_PATH, "%s\\texture.out", GetDxWndPath()); CreateDirectory(pszFile, NULL); + iTextureFileFormat = FORMAT_BMP; + if(dxw.dwFlags8 & RAWFORMAT) iTextureFileFormat = FORMAT_RAW; + if(dxw.dwFlags8 & DDSFORMAT) iTextureFileFormat = FORMAT_DDS; + OutTrace("TextureDump: size min=(%dx%d) max=(%dx%d) format=%d\n", MinTexX, MinTexY, MaxTexX, MaxTexY, iTextureFileFormat); DoOnce = FALSE; } @@ -271,43 +282,79 @@ static void TextureDump(LPDIRECTDRAWSURFACE s, int dxversion) } // Create the .BMP file. + switch (iTextureFileFormat){ + case FORMAT_BMP: sExt = "bmp"; break; + case FORMAT_RAW: sExt = "raw"; break; + case FORMAT_DDS: sExt = "dds"; break; + } 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"); + GetDxWndPath(), ddsd.dwWidth, ddsd.dwHeight, SurfaceType(ddsd.ddpfPixelFormat), hash, sExt); hf = fopen(pszFile, "wb"); if(!hf) break; - if(IsRaw){ - fwrite((BYTE *)ddsd.lpSurface, ddsd.lPitch * ddsd.dwHeight, 1, hf); - fclose(hf); - return; + switch(iTextureFileFormat){ + + case FORMAT_RAW: + + if(fwrite((BYTE *)ddsd.lpSurface, ddsd.lPitch * ddsd.dwHeight, 1, hf)!=1) + OutTraceE("TextureHack: fwrite ERROR err=%d\n", GetLastError()); + break; + + case FORMAT_DDS: { + + // no good for 8bpp textured bitmaps !!! + DDS_HEADER ddsh; + if(fwrite("DDS ", 4, 1, hf)!=1) + OutTraceE("TextureHack: fwrite ERROR err=%d\n", GetLastError()); + memset(&ddsh, 0, sizeof(ddsh)); + ddsh.dwSize = sizeof(ddsh); + ddsh.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_PITCH; + ddsh.dwHeight = ddsd.dwHeight; + ddsh.dwWidth = ddsd.dwWidth; + ddsh.ddspf.dwSize = sizeof(DDS_PIXELFORMAT); + ddsh.ddspf.dwFlags = DDPF_RGB; + ddsh.dwPitchOrLinearSize = (DWORD)ddsd.lPitch; + ddsh.ddspf.dwABitMask = ddsd.ddpfPixelFormat.dwRGBAlphaBitMask; + ddsh.ddspf.dwRBitMask = ddsd.ddpfPixelFormat.dwRBitMask; + ddsh.ddspf.dwGBitMask = ddsd.ddpfPixelFormat.dwGBitMask; + ddsh.ddspf.dwBBitMask = ddsd.ddpfPixelFormat.dwBBitMask; + ddsh.ddspf.dwRGBBitCount = ddsd.ddpfPixelFormat.dwRGBBitCount; + if(fwrite((BYTE *)&ddsh, sizeof(ddsh), 1, hf)!=1) + OutTraceE("TextureHack: fwrite ERROR err=%d\n", GetLastError()); + if(fwrite((BYTE *)ddsd.lpSurface, ddsd.lPitch * ddsd.dwHeight, 1, hf)!=1) + OutTraceE("TextureHack: fwrite ERROR err=%d\n", GetLastError()); + } + break; + + case FORMAT_BMP: + + 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); + hdr.bfReserved1 = 0; + hdr.bfReserved2 = 0; + + // Compute the offset to the array of color indices. + hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + pbi.bV4Size + pbi.bV4ClrUsed * sizeof (RGBQUAD); + + // Copy the BITMAPFILEHEADER into the .BMP file. + fwrite((LPVOID)&hdr, sizeof(BITMAPFILEHEADER), 1, hf); + + // Copy the BITMAPINFOHEADER array into the file. + fwrite((LPVOID)&pbi, sizeof(BITMAPV4HEADER), 1, hf); + + // Copy the RGBQUAD array into the file. + if(pbi.bV4ClrUsed){ + extern DWORD PaletteEntries[256]; + fwrite((LPVOID)PaletteEntries, pbi.bV4ClrUsed * sizeof (RGBQUAD), 1, hf); + } + + // Copy the array of color indices into the .BMP file. + for(int y=0; y<(int)ddsd.dwHeight; y++) + fwrite((BYTE *)ddsd.lpSurface + (y*ddsd.lPitch), iScanLineSize, 1, hf); + break; } - 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); - hdr.bfReserved1 = 0; - hdr.bfReserved2 = 0; - - // Compute the offset to the array of color indices. - hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + pbi.bV4Size + pbi.bV4ClrUsed * sizeof (RGBQUAD); - - // Copy the BITMAPFILEHEADER into the .BMP file. - fwrite((LPVOID)&hdr, sizeof(BITMAPFILEHEADER), 1, hf); - - // Copy the BITMAPINFOHEADER array into the file. - fwrite((LPVOID)&pbi, sizeof(BITMAPV4HEADER), 1, hf); - - // Copy the RGBQUAD array into the file. - if(pbi.bV4ClrUsed){ - extern DWORD PaletteEntries[256]; - fwrite((LPVOID)PaletteEntries, pbi.bV4ClrUsed * sizeof (RGBQUAD), 1, hf); - } - - // Copy the array of color indices into the .BMP file. - for(int y=0; y<(int)ddsd.dwHeight; y++) - fwrite((BYTE *)ddsd.lpSurface + (y*ddsd.lPitch), iScanLineSize, 1, hf); - // Close the .BMP file. fclose(hf); break; @@ -318,10 +365,27 @@ static void TextureDump(LPDIRECTDRAWSURFACE s, int dxversion) static void TextureHack(LPDIRECTDRAWSURFACE s, int dxversion) { + static BOOL DoOnce = TRUE; DDSURFACEDESC2 ddsd; int w, h, iSurfaceSize, iScanLineSize; HRESULT res; - BOOL IsRaw = (dxw.dwFlags8 & RAWFORMAT); + char *sExt; + static int iTextureFileFormat; + + 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); + //sprintf_s(pszFile, MAX_PATH, "%s\\texture.in", GetDxWndPath()); + iTextureFileFormat = FORMAT_BMP; + if(dxw.dwFlags8 & RAWFORMAT) iTextureFileFormat = FORMAT_RAW; + if(dxw.dwFlags8 & DDSFORMAT) iTextureFileFormat = FORMAT_DDS; + //OutTrace("TextureHack: size min=(%dx%d) max=(%dx%d) format=%d\n", MinTexX, MinTexY, MaxTexX, MaxTexY, iTextureFileFormat); + OutTrace("TextureHack: format=%d\n", iTextureFileFormat); + } OutTraceB("TextureHack(%d): lpdds=%x\n", dxversion, s); @@ -351,61 +415,86 @@ static void TextureHack(LPDIRECTDRAWSURFACE s, int dxversion) if(!hash) break; // almost certainly, an empty black surface! // Look for the .BMP file. + switch (iTextureFileFormat){ + case FORMAT_BMP: sExt = "bmp"; break; + case FORMAT_RAW: sExt = "raw"; break; + case FORMAT_DDS: sExt = "dds"; break; + } 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"); + GetDxWndPath(), ddsd.dwWidth, ddsd.dwHeight, SurfaceType(ddsd.ddpfPixelFormat), hash, sExt); 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; - } + switch(iTextureFileFormat){ - memset((void *)&pbi, 0, sizeof(BITMAPINFOHEADER)); - pbi.biSize = sizeof(BITMAPINFOHEADER); - pbi.biWidth = ddsd.dwWidth; - pbi.biHeight = ddsd.dwHeight; - pbi.biBitCount = (WORD)ddsd.ddpfPixelFormat.dwRGBBitCount; - pbi.biSizeImage = ((pbi.biWidth * pbi.biBitCount + 0x1F) & ~0x1F)/8 * pbi.biHeight; - iSizeImage = pbi.biSizeImage; - iScanLineSize = ((pbi.biWidth * pbi.biBitCount + 0x1F) & ~0x1F)/8; + case FORMAT_RAW: { - while(TRUE) { // fake loop to ensure final fclose - // Read the BITMAPFILEHEADER from the .BMP file (and throw away ...). - if(fread((LPVOID)&hdr, sizeof(BITMAPFILEHEADER), 1, hf) != 1)break; - - // Read the BITMAPINFOHEADER (and throw away ...). - // If the file contains BITMAPV4HEADER or BITMAPV5HEADER, no problem: next fseek will settle things - if(fread((LPVOID)&pbi, sizeof(BITMAPINFOHEADER), 1, hf) != 1) break; - - // skip the RGBQUAD array if the editor inserted one - fseek(hf, hdr.bfOffBits, SEEK_SET); - - // Read the new texture from the .BMP file. - if(pbi.biHeight < 0){ - // biHeight < 0 -> scan lines from top to bottom, same as surface/texture convention - for(int y=0; y<(int)ddsd.dwHeight; y++){ - BYTE *p = (BYTE *)ddsd.lpSurface + (ddsd.lPitch * y); - fseek(hf, hdr.bfOffBits + (iScanLineSize * y), SEEK_SET); - if(fread((LPVOID)p, ddsd.lPitch, 1, hf) != 1) break; + if(fread((BYTE *)ddsd.lpSurface, ddsd.lPitch * ddsd.dwHeight, 1, hf)!=1) + OutTraceE("TextureHack: fread ERROR err=%d\n", GetLastError()); } + break; + + case FORMAT_DDS: { + + BYTE magic[4]; + DDS_HEADER ddsh; + // assume the file is sane, read and throw away magic and dds header + if(fread(magic, 4, 1, hf)!=1) + OutTraceE("TextureHack: fread ERROR err=%d\n", GetLastError()); + if(fread((BYTE *)&ddsh, sizeof(ddsh), 1, hf)!=1) + OutTraceE("TextureHack: fread ERROR err=%d\n", GetLastError()); + memset(&ddsh, 0, sizeof(ddsh)); + if(fread((BYTE *)ddsd.lpSurface, ddsd.lPitch * ddsd.dwHeight, 1, hf)!=1) + OutTraceE("TextureHack: fread ERROR err=%d\n", GetLastError()); } - else { - // biHeight > 0 -> scan lines from bottom to top, inverse order as surface/texture convention - for(int y=0; y<(int)ddsd.dwHeight; y++){ - BYTE *p = (BYTE *)ddsd.lpSurface + (ddsd.lPitch * ((ddsd.dwHeight-1) - y)); - fseek(hf, hdr.bfOffBits + (iScanLineSize * y), SEEK_SET); - if(fread((LPVOID)p, ddsd.lPitch, 1, hf) != 1) break; + break; + + case FORMAT_BMP: + + memset((void *)&pbi, 0, sizeof(BITMAPINFOHEADER)); + pbi.biSize = sizeof(BITMAPINFOHEADER); + pbi.biWidth = ddsd.dwWidth; + pbi.biHeight = ddsd.dwHeight; + pbi.biBitCount = (WORD)ddsd.ddpfPixelFormat.dwRGBBitCount; + pbi.biSizeImage = ((pbi.biWidth * pbi.biBitCount + 0x1F) & ~0x1F)/8 * pbi.biHeight; + iSizeImage = pbi.biSizeImage; + iScanLineSize = ((pbi.biWidth * pbi.biBitCount + 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); + + // Read the new texture from the .BMP file. + if(pbi.biHeight < 0){ + // biHeight < 0 -> scan lines from top to bottom, same as surface/texture convention + for(int y=0; y<(int)ddsd.dwHeight; y++){ + BYTE *p = (BYTE *)ddsd.lpSurface + (ddsd.lPitch * y); + fseek(hf, hdr.bfOffBits + (iScanLineSize * y), SEEK_SET); + if(fread((LPVOID)p, ddsd.lPitch, 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)ddsd.dwHeight; y++){ + BYTE *p = (BYTE *)ddsd.lpSurface + (ddsd.lPitch * ((ddsd.dwHeight-1) - y)); + fseek(hf, hdr.bfOffBits + (iScanLineSize * y), SEEK_SET); + if(fread((LPVOID)p, ddsd.lPitch, 1, hf) != 1) break; + } + } + OutTrace("TextureHack: TEXTURE LOAD DONE\n"); + break; } - } - OutTrace("TextureHack: TEXTURE LOAD DONE\n"); break; } - // Close the .BMP file. fclose(hf); break; diff --git a/dll/dxdds.h b/dll/dxdds.h new file mode 100644 index 0000000..9549abd --- /dev/null +++ b/dll/dxdds.h @@ -0,0 +1,28 @@ +#ifndef DDS_HEADER +struct DDS_PIXELFORMAT { + DWORD dwSize; + DWORD dwFlags; + DWORD dwFourCC; + DWORD dwRGBBitCount; + DWORD dwRBitMask; + DWORD dwGBitMask; + DWORD dwBBitMask; + DWORD dwABitMask; +}; +typedef struct { + DWORD dwSize; + DWORD dwFlags; + DWORD dwHeight; + DWORD dwWidth; + DWORD dwPitchOrLinearSize; + DWORD dwDepth; + DWORD dwMipMapCount; + DWORD dwReserved1[11]; + DDS_PIXELFORMAT ddspf; + DWORD dwCaps; + DWORD dwCaps2; + DWORD dwCaps3; + DWORD dwCaps4; + DWORD dwReserved2; +} DDS_HEADER; +#endif \ No newline at end of file diff --git a/dll/dxemublt.cpp b/dll/dxemublt.cpp index 2e1584f..e7359fb 100644 --- a/dll/dxemublt.cpp +++ b/dll/dxemublt.cpp @@ -1336,10 +1336,10 @@ static HRESULT WINAPI BilinearBlt_32_to_32(int dxversion, Blt_Type pBlt, LPDIREC Q5 = Melt32(*(src32+1), *(src32+ddsd_src.lPitch+1)); // to be used in next for cycle Q4 = Melt32(Q3, Q5); - *(dest) = (WORD)Q1; - *(dest+1) = (WORD)Q2; - *(dest+ddsd_dst.lPitch) = (WORD)Q3; - *(dest+ddsd_dst.lPitch+1) = (WORD)Q4; + *(dest) = Q1; + *(dest+1) = Q2; + *(dest+ddsd_dst.lPitch) = Q3; + *(dest+ddsd_dst.lPitch+1) = Q4; src32++; dest+=2; } @@ -1351,10 +1351,10 @@ static HRESULT WINAPI BilinearBlt_32_to_32(int dxversion, Blt_Type pBlt, LPDIREC Q1 = *(src32); Q2 = Melt32(Q1, *(src32+1)); - *(dest) = (WORD)Q1; - *(dest+1) = (WORD)Q2; - *(dest+ddsd_dst.lPitch) = (WORD)Q1; - *(dest+ddsd_dst.lPitch+1) = (WORD)Q2; + *(dest) = Q1; + *(dest+1) = Q2; + *(dest+ddsd_dst.lPitch) = Q1; + *(dest+ddsd_dst.lPitch+1) = Q2; src32++; dest+=2; } diff --git a/dll/dxwnd.cpp b/dll/dxwnd.cpp index 3378b3f..ab7c3be 100644 --- a/dll/dxwnd.cpp +++ b/dll/dxwnd.cpp @@ -27,7 +27,7 @@ along with this program. If not, see . #include "TlHelp32.h" -#define VERSION "2.03.40" +#define VERSION "2.03.40.fx2" #define DDTHREADLOCK 1 diff --git a/dll/dxwnd.vs2008.suo b/dll/dxwnd.vs2008.suo index 64774c1..79b90e6 100644 Binary files a/dll/dxwnd.vs2008.suo and b/dll/dxwnd.vs2008.suo differ diff --git a/dll/dxwnd.vs2008.vcproj b/dll/dxwnd.vs2008.vcproj index 9a268e4..f487943 100644 --- a/dll/dxwnd.vs2008.vcproj +++ b/dll/dxwnd.vs2008.vcproj @@ -542,6 +542,10 @@ Name="Header Files" Filter="h;hpp;hxx;hm;inl" > + + diff --git a/host/TabDirect3D.cpp b/host/TabDirect3D.cpp index 663d255..016bf98 100644 --- a/host/TabDirect3D.cpp +++ b/host/TabDirect3D.cpp @@ -42,7 +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); + DDX_Radio(pDX, IDC_BMPFORMAT, cTarget->m_TextureFileFormat); // 3D Effects DDX_Check(pDX, IDC_NOTEXTURES, cTarget->m_NoTextures); diff --git a/host/TargetDlg.cpp b/host/TargetDlg.cpp index 7ae61d3..23baa78 100644 --- a/host/TargetDlg.cpp +++ b/host/TargetDlg.cpp @@ -61,7 +61,8 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/) m_Enum16bitModes = FALSE; m_TrimTextureFormats = FALSE; m_NoHALDevice = FALSE; - m_RawFormat = FALSE; + //m_RawFormat = FALSE; + m_TextureFileFormat = 0; m_SetCompatibility = TRUE; // default true !! m_AEROBoost = TRUE; // default true !! m_DiabloTweak = FALSE; diff --git a/host/TargetDlg.h b/host/TargetDlg.h index 49e2651..fb81bc9 100644 --- a/host/TargetDlg.h +++ b/host/TargetDlg.h @@ -264,7 +264,7 @@ public: BOOL m_SuppressD3DExt; BOOL m_Enum16bitModes; BOOL m_TrimTextureFormats; - BOOL m_RawFormat; + //BOOL m_RawFormat; BOOL m_LimitScreenRes; BOOL m_InitialRes; BOOL m_MaximumRes; @@ -285,6 +285,7 @@ public: int m_SwapEffect; int m_ClipperMode; int m_ScanLine; + int m_TextureFileFormat; //}}AFX_DATA diff --git a/host/dxwndhost.aps b/host/dxwndhost.aps index 6380510..f846f70 100644 Binary files a/host/dxwndhost.aps and b/host/dxwndhost.aps differ diff --git a/host/dxwndhost.rc b/host/dxwndhost.rc index 5d44bb4..7a2691f 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 b4722a3..993ff0f 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 6721961..6448de3 100644 --- a/host/dxwndhostView.cpp +++ b/host/dxwndhostView.cpp @@ -338,6 +338,12 @@ void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg) case 2: t->flags |= SUPPRESSCLIPPING; break; } + switch(dlg->m_TextureFileFormat){ + case 0: break; + case 1: t->flags8 |= RAWFORMAT; break; + case 2: t->flags8 |= DDSFORMAT; break; + } + if(dlg->m_HookDI) t->flags |= HOOKDI; if(dlg->m_HookDI8) t->flags |= HOOKDI8; if(dlg->m_EmulateRelMouse) t->flags6 |= EMULATERELMOUSE; @@ -384,7 +390,6 @@ 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; @@ -647,6 +652,10 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg) if (t->flags3 & FORCECLIPPER) dlg->m_ClipperMode = 1; if (t->flags & SUPPRESSCLIPPING) dlg->m_ClipperMode = 2; + dlg->m_TextureFileFormat = 0; + if( t->flags8 & RAWFORMAT) dlg->m_TextureFileFormat = 1; + if( t->flags8 & DDSFORMAT) dlg->m_TextureFileFormat = 2; + dlg->m_HookDI = t->flags & HOOKDI ? 1 : 0; dlg->m_HookDI8 = t->flags & HOOKDI8 ? 1 : 0; dlg->m_EmulateRelMouse = t->flags6 & EMULATERELMOUSE ? 1 : 0; @@ -674,7 +683,6 @@ 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; diff --git a/host/host.aps b/host/host.aps index 66fef52..fbddba3 100644 Binary files a/host/host.aps and b/host/host.aps differ diff --git a/host/resource b/host/resource index b14d3a8..9aed962 100644 Binary files a/host/resource and b/host/resource differ