diff --git a/Include/dxwnd.h b/Include/dxwnd.h index 7ab2887..9672597 100644 --- a/Include/dxwnd.h +++ b/Include/dxwnd.h @@ -75,7 +75,7 @@ #define LIMITRESOURCES 0x10000000 // Limit resources to fit an old program's expectations #define STARTDEBUG 0x20000000 // Start in DEBUG mode #define SETCOMPATIBILITY 0x40000000 // invoke ddraw SetAppCompatData to set aero compatibility mode -#define WIREFRAME 0x80000000 // invoke ddraw SetAppCompatData to set aero compatibility mode +#define WIREFRAME 0x80000000 // forces wireframe display for D3D and Glide games // third flags DWORD dxw.dwFlags3: #define FORCEHOOKOPENGL 0x00000001 // loads OpenGL32.dll and hooks it @@ -86,12 +86,12 @@ #define FIXD3DFRAME 0x00000020 // Preserve windows frame in D3D9 programs #define FORCE16BPP 0x00000040 // Forces 16BPP desktop color depth #define BLACKWHITE 0x00000080 // Simulate a B&W screen monitor mapping colors to grayscales -#define SAVECAPS 0x00000100 // Saves and restores original surface flags & capabilities +//#define SAVECAPS 0x00000100 // Saves and restores original surface flags & capabilities (UNUSED) #define SINGLEPROCAFFINITY 0x00000200 // Set Process Affinity to a single core #define EMULATEREGISTRY 0x00000400 // Emulate registry api to read extra keys #define CDROMDRIVETYPE 0x00000800 // Pretends that GetDriveType() always returns DRIVE_CDROM #define NOWINDOWMOVE 0x00001000 // Do not try to update window position & size on D3D rendering -#define DISABLEHAL 0x00002000 // Disable HAL support (IID_IDirect3DHALDevice) - no longer used +//#define DISABLEHAL 0x00002000 // Disable HAL support (IID_IDirect3DHALDevice) - no longer used #define LOCKSYSCOLORS 0x00004000 // Lock Sys Colors changes by SetSysColors() call #define GDIEMULATEDC 0x00008000 // Map GDI/user32 calls to primary to a memory surface to be stretch-blitted to the primary #define FULLSCREENONLY 0x00010000 // assume that the program is always in fullscreen mode @@ -158,6 +158,11 @@ #define NOIMAGEHLP 0x00000200 // Interceptd Imagehlp.dll unsupported calls (used by "the 5th element") #define BILINEARFILTER 0x00000400 // experimental bilinear filtering #define REPLACEPRIVOPS 0x00000800 // replace privileged opcodes, such as IN (Ubik) +#define REMAPMCI 0x00001000 // remap MCI calls coordinates in mciSendString +#define TEXTUREHIGHLIGHT 0x00002000 // highlight textures with random color & grid +#define TEXTUREDUMP 0x00004000 // dump textures to file system as bmp files +#define TEXTUREHACK 0x00008000 // load (replace) hacked textures from file system (bmp files) +#define TEXTURETRANSP 0x00010000 // transparent textures (unimplemented) // logging Tflags DWORD: #define OUTTRACE 0x00000001 // enables tracing to dxwnd.log in general @@ -173,7 +178,6 @@ #define TRACEHOOKS 0x00000400 // log hook operations #define OUTD3DTRACE 0x00000800 // traces DxWnd direct3d screen handling #define OUTDXWINTRACE 0x00001000 // traces DxWnd internal operations -#define REMAPMCI 0x00002000 // remap MCI calls coordinates in mciSendString #define EMULATEFLAGS (EMULATEBUFFER | EMULATESURFACE | LOCKEDSURFACE) #define HANDLEFPS (SHOWFPS | SHOWFPSOVERLAY | LIMITFPS | SKIPFPS) diff --git a/build/Resources_CN.dll b/build/Resources_CN.dll deleted file mode 100644 index 20dcfab..0000000 --- a/build/Resources_CN.dll +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3c96c942826339906499d13f0a0b4bfe56365ca9bb956d61968865eea475e83d -size 132608 diff --git a/build/Resources_IT.dll b/build/Resources_IT.dll deleted file mode 100644 index 02dbf38..0000000 --- a/build/Resources_IT.dll +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4afa46ffdb77508826da9be40dfb13fbbe6fddfb268c477d8189fba258280b58 -size 139264 diff --git a/build/Resources_RU.dll b/build/Resources_RU.dll deleted file mode 100644 index 3834e92..0000000 --- a/build/Resources_RU.dll +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:15292e556b28f6c70341556e7e982256f6913f907f8cb970b9bbad6ea9e900fd -size 141824 diff --git a/build/dxwnd.dll b/build/dxwnd.dll index 70f6722..366d0fa 100644 --- a/build/dxwnd.dll +++ b/build/dxwnd.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:66fc7e3018d4d23c86d3c1c2bd2059713c55356b6c547891c0b05a3ec37bbbbf -size 532992 +oid sha256:9824b03ee7247489a9910c7407a1ac7ff990854e60fdfcb46311763dc75a5df8 +size 525312 diff --git a/build/dxwnd.exe b/build/dxwnd.exe index fc100b9..d4feaee 100644 --- a/build/dxwnd.exe +++ b/build/dxwnd.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:398e28489fc7d5eff0a809c8248039a3cd69ac3cee7e64f9931092bbec27416a -size 559616 +oid sha256:8512c89fbd6ea22a4efd33008c987208f2483763e568bc9ce0c8e9ce211b9b0a +size 532992 diff --git a/build/mp.dll b/build/mp.dll new file mode 100644 index 0000000..528e5f5 --- /dev/null +++ b/build/mp.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:df0d752747c863568c9965f6c437e91e3e21594695a9665dee285def0d20d6fe +size 16384 diff --git a/build/readme-relnotes.txt b/build/readme-relnotes.txt index 57b8235..c3a2fe2 100644 --- a/build/readme-relnotes.txt +++ b/build/readme-relnotes.txt @@ -643,3 +643,5 @@ fix: fixed RDTSC opcode search loop - fixed time stretching for "Ubik" add: added "Peplace privileged opcodes" flag - makes unpatched "Ubik" run fix: revised ddsurface capabilities policy to allow D3D1-7 games to run in emulated mode and bilinear filtering +v2.02.99 +fix: completed bilinear filtering for 16bpp desktop color depth diff --git a/build/vcomp90.dll b/build/vcomp90.dll new file mode 100644 index 0000000..71b9a14 --- /dev/null +++ b/build/vcomp90.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9140efe26252b6329da254201219fc2d17a3f651e1591e32ae04c86a27e35bb2 +size 51024 diff --git a/dll/ddraw.cpp b/dll/ddraw.cpp index 01ac518..c822a94 100644 --- a/dll/ddraw.cpp +++ b/dll/ddraw.cpp @@ -19,7 +19,8 @@ extern BOOL IsChangeDisplaySettingsHotPatched; BOOL bDontReleaseBackBuffer = FALSE; -BOOL bIs3DPrimarySurfaceDevice = FALSE; +DWORD dwBackBufferCaps; +extern void TextureHandling(LPDIRECTDRAWSURFACE); // DirectDraw API HRESULT WINAPI extDirectDrawCreate(GUID FAR *, LPDIRECTDRAW FAR *, IUnknown FAR *); @@ -674,7 +675,13 @@ static void ddSetCompatibility() int HookDirectDraw(HMODULE module, int version) { - if(dxw.dwFlags2 & SETCOMPATIBILITY) ddSetCompatibility(); + if(dxw.dwFlags2 & SETCOMPATIBILITY) { + static BOOL AlreadyDone = FALSE; + if(!AlreadyDone){ + ddSetCompatibility(); + AlreadyDone = TRUE; + } + } if(dxw.dwFlags4 & HOTPATCH) { // hot-patch all APIs and that's all folks! @@ -1379,6 +1386,14 @@ static void HookDDSurfaceGeneric(LPDIRECTDRAWSURFACE *lplpdds, int dxversion) SetHook((void *)(**(DWORD **)lplpdds + 140), extUpdateOverlayZOrderProxy, (void **)&pUpdateOverlayZOrder, "UpdateOverlayZOrder(S)"); } +static void HookGammaControl(LPVOID *obp) +{ + // IDirectDrawGammaControl::GetGammaRamp + SetHook((void *)(**(DWORD **)obp + 12), extDDGetGammaRamp, (void **)&pDDGetGammaRamp, "GetGammaRamp(G)"); + // IDirectDrawGammaControl::SetGammaRamp + SetHook((void *)(**(DWORD **)obp + 16), extDDSetGammaRamp, (void **)&pDDSetGammaRamp, "SetGammaRamp(G)"); +} + /* ------------------------------------------------------------------------------ */ // CleanRect: // takes care of a corrupted RECT struct where some elements are not valid pointers. @@ -1756,6 +1771,7 @@ HRESULT WINAPI extQueryInterfaceS(void *lpdds, REFIID riid, LPVOID *obp) BOOL IsBack; BOOL IsGammaRamp; unsigned int dwLocalDDVersion; + unsigned int dwLocalTexVersion; OutTraceDDRAW("QueryInterface(S): lpdds=%x REFIID=%x(%s) obp=%x\n", lpdds, riid.Data1, ExplainGUID((GUID *)&riid), *obp); @@ -1765,6 +1781,7 @@ HRESULT WINAPI extQueryInterfaceS(void *lpdds, REFIID riid, LPVOID *obp) IsGammaRamp=FALSE; dwLocalDDVersion=0; + dwLocalTexVersion=0; switch(riid.Data1){ case 0x6C14DB81: dwLocalDDVersion = 1; @@ -1800,6 +1817,15 @@ HRESULT WINAPI extQueryInterfaceS(void *lpdds, REFIID riid, LPVOID *obp) OutTraceDW("QueryInterface: IID_IDirectDrawGammaControl\n"); IsGammaRamp=TRUE; break; + // textures + case 0x2CDCD9E0: + OutTraceDW("QueryInterface: IID_IDirect3DTexture\n"); + dwLocalTexVersion = 1; + break; + case 0x93281502: + OutTraceDW("QueryInterface: IID_IDirect3DTexture2\n"); + dwLocalTexVersion = 2; + break; } if (dwLocalDDVersion > dxw.dwMaxDDVersion) { @@ -1820,50 +1846,51 @@ HRESULT WINAPI extQueryInterfaceS(void *lpdds, REFIID riid, LPVOID *obp) if (! *obp) { OutTraceDW("QueryInterface(S): Interface for DX version %d not found\n", dwLocalDDVersion); - return(0); + return 0; } // added trace - OutTraceDDRAW("QueryInterface(S): lpdds=%x%s REFIID=%x obp=%x DDVersion=%d ret=0\n", - lpdds, IsPrim?"(PRIM)":"", riid.Data1, *obp, dwLocalDDVersion); + OutTraceDW("QueryInterface(S): lpdds=%x%s REFIID=%x obp=%x DDVersion=%d TexVersion=%d GammaRamp=%d ret=0\n", + lpdds, IsPrim?"(PRIM)":"", riid.Data1, *obp, dwLocalDDVersion, dwLocalTexVersion, IsGammaRamp); - switch (dwLocalDDVersion){ - case 1: // added for The Sims - case 2: - case 3: - case 4: - case 7: - dxw.dwDDVersion=dwLocalDDVersion; - if(IsPrim){ - OutTraceDW("QueryInterface(S): primary=%x new=%x\n", lpdds, *obp); - dxw.MarkPrimarySurface((LPDIRECTDRAWSURFACE)*obp); - HookDDSurfacePrim((LPDIRECTDRAWSURFACE *)obp, dxw.dwDDVersion); + if (dwLocalDDVersion) { + switch (dwLocalDDVersion){ + case 1: // added for The Sims + case 2: + case 3: + case 4: + case 7: + dxw.dwDDVersion=dwLocalDDVersion; + if(IsPrim){ + OutTraceDW("QueryInterface(S): primary=%x new=%x\n", lpdds, *obp); + dxw.MarkPrimarySurface((LPDIRECTDRAWSURFACE)*obp); + HookDDSurfacePrim((LPDIRECTDRAWSURFACE *)obp, dxw.dwDDVersion); + } + else{ + if(IsBack) dxw.MarkBackBufferSurface((LPDIRECTDRAWSURFACE)*obp); + else dxw.MarkRegularSurface((LPDIRECTDRAWSURFACE)*obp); + // v2.02.13: seems that hooking inconditionally gives troubles. What is the proper safe hook condition? + HookDDSurfaceGeneric((LPDIRECTDRAWSURFACE *)obp, dxw.dwDDVersion); + } + break; } - else{ - if(IsBack) dxw.MarkBackBufferSurface((LPDIRECTDRAWSURFACE)*obp); - else dxw.MarkRegularSurface((LPDIRECTDRAWSURFACE)*obp); - // v2.02.13: seems that hooking inconditionally gives troubles. What is the proper safe hook condition? - HookDDSurfaceGeneric((LPDIRECTDRAWSURFACE *)obp, dxw.dwDDVersion); - } - break; - } - - if(IsGammaRamp){ - // IDirectDrawGammaControl::GetGammaRamp - SetHook((void *)(**(DWORD **)obp + 12), extDDGetGammaRamp, (void **)&pDDGetGammaRamp, "GetGammaRamp(G)"); - // IDirectDrawGammaControl::SetGammaRamp - SetHook((void *)(**(DWORD **)obp + 16), extDDSetGammaRamp, (void **)&pDDSetGammaRamp, "SetGammaRamp(G)"); - } - - if((lpdds == lpDDSBack) && dwLocalDDVersion) { - // assume that you always use the newer interface version, if available. - if(dwLocalDDVersion > (UINT)iBakBufferVersion){ - OutTraceDW("QueryInterface(S): switching backbuffer %x -> %x\n", lpDDSBack, *obp); - lpDDSBack = (LPDIRECTDRAWSURFACE)*obp; - iBakBufferVersion = dwLocalDDVersion; + if(lpdds == lpDDSBack) { + // assume that you always use the newer interface version, if available. + if(dwLocalDDVersion > (UINT)iBakBufferVersion){ + OutTraceDW("QueryInterface(S): switching backbuffer %x -> %x\n", lpDDSBack, *obp); + lpDDSBack = (LPDIRECTDRAWSURFACE)*obp; + iBakBufferVersion = dwLocalDDVersion; + } } } + if(dwLocalTexVersion) { + if(dxw.dwFlags5 & (TEXTUREHIGHLIGHT|TEXTUREDUMP|TEXTUREHACK)) TextureHandling((LPDIRECTDRAWSURFACE)lpdds); + HookTexture(obp, dwLocalTexVersion); + } + + if(IsGammaRamp) HookGammaControl(obp); + return 0; } @@ -2123,9 +2150,6 @@ static HRESULT BuildPrimaryEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf DDSURFACEDESC2 ddsd; HRESULT res; - // save primary surface type for later use - bIs3DPrimarySurfaceDevice = (lpddsd->dwFlags & DDSD_CAPS) && (lpddsd->ddsCaps.dwCaps & DDSCAPS_3DDEVICE); - // emulated primary surface memcpy((void *)&ddsd, lpddsd, lpddsd->dwSize); @@ -2139,18 +2163,8 @@ static HRESULT BuildPrimaryEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf 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); -#if 0 // DDSCAPS_OFFSCREENPLAIN seems required to support the palette in memory surfaces ddsd.ddsCaps.dwCaps |= (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY); -#else - // "problematic" situations: - // New Your Racer (intro movies & 3D part) Caps=DDSCAPS_COMPLEX+OVERLAY Pixel.Flags=DDPF_FOURCC - //ddsd.ddsCaps.dwCaps |= (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY); - //if(lpddsd->ddsCaps.dwCaps & DDSCAPS_OVERLAY) ddsd.ddsCaps.dwCaps &= ~(DDSCAPS_SYSTEMMEMORY); - //if(lpddsd->ddsCaps.dwCaps & DDSCAPS_OVERLAY) ddsd.ddsCaps.dwCaps &= ~(DDSCAPS_OFFSCREENPLAIN); - ddsd.ddsCaps.dwCaps |= (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY); - //ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; -#endif // on WinXP Fifa 99 doesn't like DDSCAPS_SYSTEMMEMORY cap, so better to leave a way to unset it.... if(dxw.dwFlags5 & NOSYSTEMEMULATED) ddsd.ddsCaps.dwCaps &= ~DDSCAPS_SYSTEMMEMORY; ddsd.dwWidth = dxw.GetScreenWidth(); @@ -2220,12 +2234,9 @@ static HRESULT BuildPrimaryEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf // DDSCAPS_OFFSCREENPLAIN seems required to support the palette in memory surfaces // DDSCAPS_SYSTEMMEMORY makes operations faster, but it is not always good... ddsd.ddsCaps.dwCaps = (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY); - // "problematic" situations that need no DDSCAPS_SYSTEMMEMORY: - // Flying Heroes (caps=DDSCAPS_3DDEVICE) - // Echelon (caps=DDSCAPS_COMPLEX+3DDEVICE) - if(bIs3DPrimarySurfaceDevice) ddsd.ddsCaps.dwCaps &= ~DDSCAPS_SYSTEMMEMORY; // on WinXP Fifa 99 doesn't like DDSCAPS_SYSTEMMEMORY cap, so better to leave a way to unset it.... if(dxw.dwFlags5 & NOSYSTEMEMULATED) ddsd.ddsCaps.dwCaps &= ~DDSCAPS_SYSTEMMEMORY; + dwBackBufferCaps = ddsd.ddsCaps.dwCaps; ddsd.dwWidth = dxw.GetScreenWidth(); ddsd.dwHeight = dxw.GetScreenHeight(); if(dxw.dwFlags4 & BILINEAR2XFILTER){ @@ -2255,15 +2266,13 @@ static HRESULT BuildPrimaryDir(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf DDSURFACEDESC2 ddsd; HRESULT res; - bIs3DPrimarySurfaceDevice = (lpddsd->dwFlags & DDSD_CAPS) && (lpddsd->ddsCaps.dwCaps & DDSCAPS_3DDEVICE); - // genuine primary surface memcpy((void *)&ddsd, lpddsd, lpddsd->dwSize); ddsd.dwFlags &= ~(DDSD_WIDTH|DDSD_HEIGHT|DDSD_BACKBUFFERCOUNT|DDSD_REFRESHRATE|DDSD_PIXELFORMAT); ddsd.ddsCaps.dwCaps &= ~(DDSCAPS_FLIP|DDSCAPS_COMPLEX); // v2.02.93: don't move primary / backbuf surfaces on systemmemory when 3DDEVICE is requested // this impact also on capabilities for temporary surfaces for AERO optimized handling - if(bIs3DPrimarySurfaceDevice) ddsd.ddsCaps.dwCaps &= ~DDSCAPS_SYSTEMMEMORY; + if ((lpddsd->dwFlags & DDSD_CAPS) && (lpddsd->ddsCaps.dwCaps & DDSCAPS_3DDEVICE)) ddsd.ddsCaps.dwCaps &= ~DDSCAPS_SYSTEMMEMORY; // create Primary surface DumpSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Primary]" , __LINE__); @@ -2325,7 +2334,7 @@ static HRESULT BuildBackBufferEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateS ddsd.ddsCaps.dwCaps &= ~(DDSCAPS_BACKBUFFER|DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP|DDSCAPS_COMPLEX|DDSCAPS_VIDEOMEMORY|DDSCAPS_LOCALVIDMEM); // DDSCAPS_OFFSCREENPLAIN seems required to support the palette in memory surfaces ddsd.ddsCaps.dwCaps |= (DDSCAPS_SYSTEMMEMORY|DDSCAPS_OFFSCREENPLAIN); - if(ddsd.ddsCaps.dwCaps & DDSCAPS_3DDEVICE) ddsd.ddsCaps.dwCaps &= ~DDSCAPS_SYSTEMMEMORY; + if(ddsd.ddsCaps.dwCaps & DDSCAPS_3DDEVICE) ddsd.ddsCaps.dwCaps &= ~DDSCAPS_SYSTEMMEMORY; // necessary: Martian Gotic crashes otherwise // on WinXP Fifa 99 doesn't like DDSCAPS_SYSTEMMEMORY cap, so better to leave a way to unset it.... if(dxw.dwFlags5 & NOSYSTEMMEMORY) ddsd.ddsCaps.dwCaps &= ~DDSCAPS_SYSTEMMEMORY; ddsd.dwWidth = dxw.GetScreenWidth(); @@ -2834,7 +2843,7 @@ HRESULT WINAPI PrimaryStretchBlt(LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, L if((TmpRect.bottom==0) || (TmpRect.right==0)) return DD_OK; // avoid blitting to null areas (Fifa 2000 D3D) ddsd.dwFlags = (DDSD_HEIGHT | DDSD_WIDTH | DDSD_CAPS); // capabilities must cope with primary / backbuffer surface capabilities to get speedy operations - ddsd.ddsCaps.dwCaps = bIs3DPrimarySurfaceDevice ? DDSCAPS_OFFSCREENPLAIN : (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY); + ddsd.ddsCaps.dwCaps = dwBackBufferCaps; res=(*pCreateSurface)(lpPrimaryDD, (LPDDSURFACEDESC)&ddsd, &lpddsTmp, NULL); if(res) { OutTraceE("CreateSurface: ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__); @@ -2852,11 +2861,38 @@ HRESULT WINAPI PrimaryStretchBlt(LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, L return res; } +void *LoadFilter(char *apiname) +{ + HMODULE filterlib; + #define MAX_FILE_PATH 512 + char sSourcePath[MAX_FILE_PATH+1]; + char *p; + DWORD dwAttrib; + + dwAttrib = GetFileAttributes("dxwnd.dll"); + if (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) return NULL; + GetModuleFileName(GetModuleHandle("dxwnd"), sSourcePath, MAX_FILE_PATH); + p=&sSourcePath[strlen(sSourcePath)-strlen("dxwnd.dll")]; + + *p=0; + SetDllDirectory(sSourcePath); + + strcpy(p, "mp.dll"); + filterlib=(*pLoadLibraryA)(sSourcePath); + if(!filterlib) { + OutTraceDW("DXWND: Load lib=\"%s\" failed err=%d\n", sSourcePath, GetLastError()); + return NULL; + } + return (*pGetProcAddress)(filterlib, apiname); +} + HRESULT WINAPI PrimaryBilinearBlt(LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect) { HRESULT res; - extern void Resize_HQ_4ch( unsigned char*, RECT *, int, unsigned char*, RECT *, int); + typedef void (WINAPI *Resize_HQ_Type)( unsigned char*, RECT *, int, unsigned char*, RECT *, int); + static Resize_HQ_Type pResize_HQ = NULL; /* to be implemented .... */ + DDSURFACEDESC2 ddsd; RECT TmpRect, SrcRect; LPDIRECTDRAWSURFACE lpddsTmp; @@ -2905,7 +2941,7 @@ HRESULT WINAPI PrimaryBilinearBlt(LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, TmpRect.right = ddsd.dwWidth = dwWidth; ddsd.dwFlags = (DDSD_HEIGHT | DDSD_WIDTH | DDSD_CAPS); // capabilities must cope with primary / backbuffer surface capabilities to get speedy operations - ddsd.ddsCaps.dwCaps = bIs3DPrimarySurfaceDevice ? DDSCAPS_OFFSCREENPLAIN : (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY); + ddsd.ddsCaps.dwCaps = dwBackBufferCaps; res=(*pCreateSurface)(lpPrimaryDD, (LPDDSURFACEDESC)&ddsd, &lpddsTmp, NULL); if(res) OutTraceE("CreateSurface: ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__); @@ -2926,9 +2962,41 @@ HRESULT WINAPI PrimaryBilinearBlt(LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, DestPitch = ddsd.lPitch; // do the filtering - Resize_HQ_4ch( - bSourceBuf, lpsrcrect, SrcPitch, - bDestBuf, lpdestrect, DestPitch); + if(!pResize_HQ) { + char *filter; + HMODULE filterlib; + switch(ddsd.ddpfPixelFormat.dwGBitMask) + { + default: + case 0x00FF00: + filter = "Resize_HQ_4ch"; + break; + case 0x0007E0: // RGB565 + filter = "Resize_HQ_2ch565"; + break; + case 0x0003E0: // RGB555 + filter = "Resize_HQ_2ch555"; + break; + } + + filterlib=(*pLoadLibraryA)("mp.dll"); + if(!filterlib) { + char sMsg[80+1]; + sprintf(sMsg, "DXWND: ERROR can't load lib=\"mp.dll\" err=%x\n", GetLastError()); + OutTraceE(sMsg); + MessageBox(0, sMsg, "ERROR", MB_OK | MB_ICONEXCLAMATION); + exit(0); + } + pResize_HQ = (Resize_HQ_Type)(*pGetProcAddress)(filterlib, filter); + if(!pResize_HQ){ + char sMsg[80+1]; + sprintf(sMsg, "DXWND: ERROR can't load name=\"%s\"\n", filter); + OutTraceE(sMsg); + MessageBox(0, sMsg, "ERROR", MB_OK | MB_ICONEXCLAMATION); + exit(0); + } + } + (*pResize_HQ)(bSourceBuf, lpsrcrect, SrcPitch, bDestBuf, lpdestrect, DestPitch); // fast-blit to primary (*pUnlockMethod(lpddssrc))(lpddssrc, NULL); @@ -3092,6 +3160,7 @@ HRESULT WINAPI sBlt(char *api, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, if (lpddssrc) DescribeSurface(lpddssrc, 0, "[SRC]" , __LINE__); // lpddssrc could be NULL!!! } if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=0; + if(dxw.dwFlags5 & (TEXTUREHIGHLIGHT|TEXTUREDUMP|TEXTUREHACK)) TextureHandling(lpdds); return res; } @@ -3246,6 +3315,7 @@ HRESULT WINAPI sBlt(char *api, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, res=(*pEmuBlt)(lpDDSEmu_Back, &emurect, lpdds, &emurect, DDBLT_WAIT, 0); } if(res) { + BlitError(res, &emurect, &emurect, __LINE__); if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=0; return res; } @@ -3777,6 +3847,8 @@ HRESULT WINAPI extUnlock(int dxversion, Unlock4_Type pUnlock, LPDIRECTDRAWSURFAC } if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK; + + if((dxw.dwFlags5 & (TEXTUREHIGHLIGHT|TEXTUREDUMP|TEXTUREHACK)) && (!IsPrim)) TextureHandling(lpdds); return res; } @@ -4673,7 +4745,6 @@ HRESULT WINAPI extGetSurfaceDesc7(LPDIRECTDRAWSURFACE2 lpdds, LPDDSURFACEDESC2 l OutTraceDW("GetSurfaceDesc: ASSERT - bad dwSize=%d lpdds=%x at %d\n", lpddsd->dwSize, lpdds, __LINE__); return DDERR_INVALIDOBJECT; } - OutTraceDW("GetSurfaceDesc: ASSERT - missing hook lpdds=%x dwSize=%d(%s) at %d\n", lpdds, lpddsd->dwSize, lpddsd->dwSize==sizeof(DDSURFACEDESC)?"DDSURFACEDESC":"DDSURFACEDESC2", __LINE__); return DDERR_INVALIDOBJECT; diff --git a/dll/dxemublt.cpp b/dll/dxemublt.cpp index 790ee32..c84393b 100644 --- a/dll/dxemublt.cpp +++ b/dll/dxemublt.cpp @@ -17,12 +17,10 @@ extern Unlock4_Type pUnlockMethod(LPDIRECTDRAWSURFACE); extern DWORD PaletteEntries[256]; extern DWORD *Palette16BPP; extern char *ExplainDDError(DWORD); -extern int Set_dwSize_From_Surface(LPDIRECTDRAWSURFACE); // just in case .... #define SwitchdwSize(s) s.dwSize=(s.dwSize==sizeof(DDSURFACEDESC))?sizeof(DDSURFACEDESC2):sizeof(DDSURFACEDESC) -#define DXWNDDIRECTBLITTING 1 #define MARKBLITCOLOR32 0x00FFFF00 #define MARKBLITCOLOR16 0x0FF0 EmuBlt_Type pEmuBlt; @@ -555,13 +553,12 @@ static HRESULT WINAPI EmuBlt_24_to_32(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdes return res; } +// note: better avoid direct blitting in case of identical color depth (e.g. EmuBlt_32_to_32, EmuBlt_16_to_16) +// because it does not work between complex surfaces when DDSDCAPS_SYSTEMMEMORY is not omogeneous! static HRESULT WINAPI EmuBlt_32_to_32(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdestrect, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPVOID lpsurface) { -#ifdef DXWNDDIRECTBLITTING - return (*pBlt)(lpddsdst, lpdestrect, lpddssrc, lpsrcrect, dwflags, NULL); -#else DWORD x, y, w, h; long srcpitch, destpitch; HRESULT res; @@ -628,7 +625,6 @@ static HRESULT WINAPI EmuBlt_32_to_32(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdes res=(*pUnlockMethod(lpddssrc))(lpddssrc, lpsrcrect); if (res) OutTraceE("EmuBlt32_32: Unlock ERROR dds=%x res=%x(%s) at %d\n", lpddssrc, res, ExplainDDError(res), __LINE__); return res; -#endif } static HRESULT WINAPI EmuBlt_8_to_16(LPDIRECTDRAWSURFACE lpddsdst, LPRECT lpdestrect, @@ -1210,11 +1206,11 @@ static HRESULT WINAPI BilinearBlt_32_to_32(LPDIRECTDRAWSURFACE lpddsdst, LPRECT ddsd_src.lPitch >>= 2; src32 = (DWORD *)(lpsurface ? lpsurface:ddsd_src.lpSurface); - src32 += (lpsrcrect->top >> 1)*ddsd_src.lPitch; - src32 += (lpsrcrect->left >> 1); + src32 += lpsrcrect->top*ddsd_src.lPitch; + src32 += lpsrcrect->left; srcpitch = ddsd_src.lPitch - w; - // OutTraceDW("DEBUG: h=%d w=%d src=%x dst=%x spitch=%d dpitch=%d\n",h,w,src8,dest,srcpitch,destpitch); + //OutTraceDW("DEBUG: h=%d w=%d src=%x dst=%x spitch=%d dpitch=%d\n",h,w,src32,dest,srcpitch,destpitch); for(y = 0; y < h-1; y ++){ register DWORD Q1, Q2, Q3, Q4, Q5; Q5 = Melt32(*(src32), *(src32+ddsd_src.lPitch)); @@ -1248,7 +1244,7 @@ static HRESULT WINAPI BilinearBlt_32_to_32(LPDIRECTDRAWSURFACE lpddsdst, LPRECT dest+=2; } - if(dxw.dwFlags3 & MARKBLIT) MarkRect16((SHORT *)dest0, 2*w, 2*h, destpitch); + if(dxw.dwFlags3 & MARKBLIT) MarkRect32(dest0, 2*w, 2*h, destpitch); res=(*pUnlockMethod(lpddsdst))(lpddsdst, lpdestrect); if (res) OutTraceE("BilBlt32_32: Unlock ERROR dds=%x res=%x(%s) at %d\n", lpddsdst, res, ExplainDDError(res), __LINE__); diff --git a/dll/dxhook.cpp b/dll/dxhook.cpp index 5e2b8d0..742dfaf 100644 --- a/dll/dxhook.cpp +++ b/dll/dxhook.cpp @@ -73,7 +73,7 @@ static char *Flag2Names[32]={ static char *Flag3Names[32]={ "FORCEHOOKOPENGL", "MARKBLIT", "HOOKDLLS", "SUPPRESSD3DEXT", "HOOKENABLED", "FIXD3DFRAME", "FORCE16BPP", "BLACKWHITE", - "SAVECAPS", "SINGLEPROCAFFINITY", "EMULATEREGISTRY", "CDROMDRIVETYPE", + "--SAVECAPS--", "SINGLEPROCAFFINITY", "EMULATEREGISTRY", "CDROMDRIVETYPE", "NOWINDOWMOVE", "--DISABLEHAL--", "LOCKSYSCOLORS", "GDIEMULATEDC", "FULLSCREENONLY", "FONTBYPASS", "YUV2RGB", "RGB2YUV", "BUFFEREDIOFIX", "FILTERMESSAGES", "PEEKALLMESSAGES", "SURFACEWARN", @@ -96,8 +96,8 @@ static char *Flag5Names[32]={ "DIABLOTWEAK", "CLEARTARGET", "NOWINPOSCHANGES", "NOSYSTEMMEMORY", "NOBLT", "NOSYSTEMEMULATED", "DOFASTBLT", "AEROBOOST", "QUARTERBLT", "NOIMAGEHLP", "BILINEARFILTER", "REPLACEPRIVOPS", - "", "", "", "", - "", "", "", "", + "REMAPMCI", "TEXTUREHIGHLIGHT", "TEXTUREDUMP", "TEXTUREHACK", + "TEXTURETRANSP", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", @@ -1163,19 +1163,10 @@ static void LockScreenMode(DWORD dmPelsWidth, DWORD dmPelsHeight, DWORD dmBitsPe static HMODULE LoadDisasm() { HMODULE disasmlib; - #define MAX_FILE_PATH 512 - char sSourcePath[MAX_FILE_PATH+1]; - char *p; - DWORD dwAttrib; - dwAttrib = GetFileAttributes("dxwnd.dll"); - if (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) return NULL; - GetModuleFileName(GetModuleHandle("dxwnd"), sSourcePath, MAX_FILE_PATH); - p=&sSourcePath[strlen(sSourcePath)-strlen("dxwnd.dll")]; - strcpy(p, "disasm.dll"); - disasmlib=(*pLoadLibraryA)(sSourcePath); + disasmlib=(*pLoadLibraryA)("disasm.dll"); if(!disasmlib) { - OutTraceDW("DXWND: Load lib=\"%s\" failed err=%d\n", sSourcePath, GetLastError()); + OutTraceDW("DXWND: Load lib=\"%s\" failed err=%d\n", "disasm.dll", GetLastError()); return NULL; } pGeterrwarnmessage=(Geterrwarnmessage_Type)(*pGetProcAddress)(disasmlib, "Geterrwarnmessage"); @@ -1590,6 +1581,7 @@ void HookInit(TARGETMAP *target, HWND hwnd) HMODULE base; char *sModule; char sModuleBuf[60+1]; + char sSourcePath[MAX_PATH+1]; static char *dxversions[14]={ "Automatic", "DirectX1~6", "", "", "", "", "", "DirectX7", "DirectX8", "DirectX9", "DirectX10", "DirectX11", "None", "" @@ -1600,6 +1592,17 @@ void HookInit(TARGETMAP *target, HWND hwnd) dxw.InitTarget(target); + // add the DxWnd install dir to the search path, to make all included dll linkable + DWORD dwAttrib; + dwAttrib = GetFileAttributes("dxwnd.dll"); + if (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) { + MessageBox(0, "DXWND: ERROR can't locate itself", "ERROR", MB_OK | MB_ICONEXCLAMATION); + exit(0); + } + GetModuleFileName(GetModuleHandle("dxwnd"), sSourcePath, MAX_PATH); + sSourcePath[strlen(sSourcePath)-strlen("dxwnd.dll")] = 0; // terminate the string just before "dxwnd.dll" + SetDllDirectory(sSourcePath); + if(dxw.dwFlags1 & AUTOMATIC) dxw.dwFlags1 |= EMULATESURFACE; // if AUTOMATIC, try this first! if(hwnd){ // v2.02.32: skip this when in code injection mode. diff --git a/dll/dxwnd.cpp b/dll/dxwnd.cpp index 08dda9e..91d1160 100644 --- a/dll/dxwnd.cpp +++ b/dll/dxwnd.cpp @@ -24,7 +24,7 @@ along with this program. If not, see . #include "dxwnd.h" #include "dxwcore.hpp" -#define VERSION "2.02.98" +#define VERSION "2.02.99" #define DXWACTIVATESINGLETASK 1 // comment to allow multiple task activations #define DDTHREADLOCK 1 diff --git a/dll/dxwnd.vs2008.suo b/dll/dxwnd.vs2008.suo index b4a8eab..8dcc06a 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 c2e0f4c..a94f6ca 100644 --- a/dll/dxwnd.vs2008.vcproj +++ b/dll/dxwnd.vs2008.vcproj @@ -154,6 +154,7 @@ ExceptionHandling="2" RuntimeLibrary="0" EnableFunctionLevelLinking="true" + OpenMP="true" PrecompiledHeaderFile=".\Release/dxwnd.pch" AssemblerListingLocation=".\Release/" ObjectFile=".\Release/" @@ -220,10 +221,6 @@ RelativePath=".\advapi.cpp" > - - @@ -404,6 +401,10 @@ RelativePath=".\smack.cpp" > + + diff --git a/dll/hd3d7.cpp b/dll/hd3d7.cpp index d5c45b0..5a94159 100644 --- a/dll/hd3d7.cpp +++ b/dll/hd3d7.cpp @@ -69,6 +69,8 @@ typedef HRESULT (WINAPI *GetCurrentViewport3_Type)(void *, LPDIRECT3DVIEWPORT3 * typedef HRESULT (WINAPI *SetCurrentViewport3_Type)(void *, LPDIRECT3DVIEWPORT3); typedef HRESULT (WINAPI *SetTexture3_Type)(void *, DWORD, LPDIRECT3DTEXTURE2); typedef HRESULT (WINAPI *SetTexture7_Type)(void *, DWORD, LPDIRECTDRAWSURFACE7); +typedef HRESULT (WINAPI *SwapTextureHandles_Type)(void *, LPDIRECT3DTEXTURE, LPDIRECT3DTEXTURE); +typedef HRESULT (WINAPI *SwapTextureHandles2_Type)(void *, LPDIRECT3DTEXTURE2, LPDIRECT3DTEXTURE2); D3DInitialize_Type pD3DInitialize = NULL; D3DGetCaps_Type pD3DGetCaps = NULL; @@ -96,6 +98,8 @@ GetCurrentViewport3_Type pGetCurrentViewport3 = NULL; SetCurrentViewport3_Type pSetCurrentViewport3 = NULL; SetTexture3_Type pSetTexture3 = NULL; SetTexture7_Type pSetTexture7 = NULL; +SwapTextureHandles_Type pSwapTextureHandles = NULL; +SwapTextureHandles2_Type pSwapTextureHandles2 = NULL; // IDirect3DViewport-n interfaces @@ -189,6 +193,28 @@ HRESULT WINAPI extSetViewport7(void *, LPD3DVIEWPORT7); HRESULT WINAPI extGetViewport7(void *, LPD3DVIEWPORT7); HRESULT WINAPI extSetTexture3(void *, DWORD, LPDIRECT3DTEXTURE2); HRESULT WINAPI extSetTexture7(void *, DWORD, LPDIRECTDRAWSURFACE7); +HRESULT WINAPI extSwapTextureHandles(void *, LPDIRECT3DTEXTURE, LPDIRECT3DTEXTURE); +HRESULT WINAPI extSwapTextureHandles2(void *, LPDIRECT3DTEXTURE2, LPDIRECT3DTEXTURE2); + +// Texture + +typedef HRESULT (WINAPI *TexInitialize_Type)(void *, LPDIRECT3DDEVICE, LPDIRECTDRAWSURFACE); +typedef HRESULT (WINAPI *TexGetHandle_Type)(void *, LPDIRECT3DDEVICE, LPD3DTEXTUREHANDLE); +typedef HRESULT (WINAPI *TexPaletteChanged_Type)(void *, DWORD, DWORD); +typedef HRESULT (WINAPI *TexLoad_Type)(void *, LPDIRECT3DTEXTURE); +typedef HRESULT (WINAPI *TexUnload_Type)(void *); + +TexInitialize_Type pTInitialize = NULL; +TexGetHandle_Type pTGetHandle = NULL; +TexPaletteChanged_Type pTPaletteChanged = NULL; +TexLoad_Type pTLoad = NULL; +TexUnload_Type pTUnload = NULL; + +HRESULT WINAPI extTexInitialize(void *, LPDIRECT3DDEVICE, LPDIRECTDRAWSURFACE); +HRESULT WINAPI extTexGetHandle(void *, LPDIRECT3DDEVICE, LPD3DTEXTUREHANDLE); +HRESULT WINAPI extTexPaletteChanged(void *, DWORD, DWORD); +HRESULT WINAPI extTexLoad(void *, LPDIRECT3DTEXTURE); +HRESULT WINAPI extTexUnload(void *); extern char *ExplainDDError(DWORD); int GD3DDeviceVersion; @@ -299,7 +325,9 @@ void HookDirect3DDevice(void **lpd3ddev, int d3dversion) switch(d3dversion){ case 1: + SetHook((void *)(**(DWORD **)lpd3ddev + 0), extQueryInterfaceD3, (void **)&pQueryInterfaceD3, "QueryInterface(D3D)"); //SetHook((void *)(**(DWORD **)lpd3ddev + 16), extGetCaps1, (void **)&pGetCaps1, "GetCaps(1)"); + SetHook((void *)(**(DWORD **)lpd3ddev + 20), extSwapTextureHandles, (void **)&pSwapTextureHandles, "SwapTextureHandles(1)"); SetHook((void *)(**(DWORD **)lpd3ddev + 36), extAddViewport1, (void **)&pAddViewport1, "AddViewport(1)"); SetHook((void *)(**(DWORD **)lpd3ddev + 40), extDeleteViewport1, (void **)&pDeleteViewport1, "DeleteViewport(1)"); SetHook((void *)(**(DWORD **)lpd3ddev + 44), extNextViewport1, (void **)&pNextViewport1, "NextViewport(1)"); @@ -307,7 +335,9 @@ void HookDirect3DDevice(void **lpd3ddev, int d3dversion) SetHook((void *)(**(DWORD **)lpd3ddev + 80), extEndScene1, (void **)&pEndScene1, "EndScene(1)"); break; case 2: + SetHook((void *)(**(DWORD **)lpd3ddev + 0), extQueryInterfaceD3, (void **)&pQueryInterfaceD3, "QueryInterface(D3D)"); //SetHook((void *)(**(DWORD **)lpd3ddev + 12), extGetCaps2, (void **)&pGetCaps2, "GetCaps(2)"); + SetHook((void *)(**(DWORD **)lpd3ddev + 16), extSwapTextureHandles, (void **)&pSwapTextureHandles, "SwapTextureHandles(1)"); SetHook((void *)(**(DWORD **)lpd3ddev + 24), extAddViewport2, (void **)&pAddViewport2, "AddViewport(2)"); SetHook((void *)(**(DWORD **)lpd3ddev + 28), extDeleteViewport2, (void **)&pDeleteViewport2, "DeleteViewport(2)"); SetHook((void *)(**(DWORD **)lpd3ddev + 32), extNextViewport2, (void **)&pNextViewport2, "NextViewport(2)"); @@ -323,6 +353,7 @@ void HookDirect3DDevice(void **lpd3ddev, int d3dversion) } break; case 3: + SetHook((void *)(**(DWORD **)lpd3ddev + 0), extQueryInterfaceD3, (void **)&pQueryInterfaceD3, "QueryInterface(D3D)"); SetHook((void *)(**(DWORD **)lpd3ddev + 12), extGetCaps3, (void **)&pGetCaps3, "GetCaps(3)"); SetHook((void *)(**(DWORD **)lpd3ddev + 20), extAddViewport3, (void **)&pAddViewport3, "AddViewport(3)"); SetHook((void *)(**(DWORD **)lpd3ddev + 36), extBeginScene3, (void **)&pBeginScene3, "BeginScene(3)"); @@ -339,6 +370,7 @@ void HookDirect3DDevice(void **lpd3ddev, int d3dversion) } break; case 7: + SetHook((void *)(**(DWORD **)lpd3ddev + 0), extQueryInterfaceD3, (void **)&pQueryInterfaceD3, "QueryInterface(D3D)"); SetHook((void *)(**(DWORD **)lpd3ddev + 20), extBeginScene7, (void **)&pBeginScene7, "BeginScene(7)"); SetHook((void *)(**(DWORD **)lpd3ddev + 24), extEndScene7, (void **)&pEndScene7, "EndScene(7)"); SetHook((void *)(**(DWORD **)lpd3ddev + 52), extSetViewport7, (void **)&pSetViewport7, "SetViewport(7)"); @@ -449,6 +481,25 @@ void HookMaterial(LPDIRECT3DMATERIAL *lpMaterial, int d3dversion) } } +void HookTexture(LPVOID *lpTexture, int version) +{ + OutTraceD3D("HookTexture: Texture=%x version=%d\n", *lpTexture, version); + switch(version){ + case 1: + SetHook((void *)(**(DWORD **)lpTexture + 12), extTexInitialize, (void **)&pTInitialize, "Initialize(T1)"); + SetHook((void *)(**(DWORD **)lpTexture + 16), extTexGetHandle, (void **)&pTGetHandle, "GetHandle(T1)"); + SetHook((void *)(**(DWORD **)lpTexture + 20), extTexPaletteChanged, (void **)&pTPaletteChanged, "PaletteChanged(T1)"); + SetHook((void *)(**(DWORD **)lpTexture + 24), extTexLoad, (void **)&pTLoad, "Load(T1)"); + SetHook((void *)(**(DWORD **)lpTexture + 28), extTexUnload, (void **)&pTUnload, "Unload(T1)"); + break; + case 2: + SetHook((void *)(**(DWORD **)lpTexture + 12), extTexGetHandle, (void **)&pTGetHandle, "GetHandle(T2)"); + SetHook((void *)(**(DWORD **)lpTexture + 16), extTexPaletteChanged, (void **)&pTPaletteChanged, "PaletteChanged(T2)"); + SetHook((void *)(**(DWORD **)lpTexture + 20), extTexLoad, (void **)&pTLoad, "Load(T2)"); + break; + } +} + HRESULT WINAPI extQueryInterfaceD3(void *lpd3d, REFIID riid, LPVOID *ppvObj) { HRESULT res; @@ -1249,20 +1300,22 @@ HRESULT WINAPI extNextViewport2(void *d3dd, LPDIRECT3DVIEWPORT2 lpd3dvp, LPDIREC HRESULT WINAPI extSetTexture3(void *d3dd, DWORD flags, LPDIRECT3DTEXTURE2 lptex) { HRESULT res; + OutTraceD3D("SetTexture(3): d3dd=%x flags=%x tex=%x\n", d3dd, flags, lptex); if (dxw.dwFlags4 & NOTEXTURES) return DD_OK; res=(*pSetTexture3)(d3dd, flags, lptex); - OutTraceD3D("SetTexture3: d3dd=%x, flags=%x, tex=%x res=%x\n", d3dd, flags, lptex, res); + if(res) OutTraceD3D("SetTexture(3): ERROR res=%x(%s)\n", res, ExplainDDError(res)); return res; } HRESULT WINAPI extSetTexture7(void *d3dd, DWORD flags, LPDIRECTDRAWSURFACE7 lptex) { HRESULT res; + OutTraceD3D("SetTexture(7): d3dd=%x, flags=%x, tex=%x\n", d3dd, flags, lptex); if (dxw.dwFlags4 & NOTEXTURES) return DD_OK; res=(*pSetTexture7)(d3dd, flags, lptex); - OutTraceD3D("SetTexture7: d3dd=%x, flags=%x, tex=%x res=%x\n", d3dd, flags, lptex, res); + if(res) OutTraceD3D("SetTexture(7): ERROR res=%x(%s)\n", res, ExplainDDError(res)); return res; } @@ -1270,7 +1323,7 @@ HRESULT WINAPI extSetMaterial(void *d3dd, LPD3DMATERIAL lpMaterial) { HRESULT res; - OutTraceD3D("SetMaterial: d3dd=%x, material=%x\n", d3dd, lpMaterial); + OutTraceD3D("SetMaterial: d3dd=%x material=%x\n", d3dd, lpMaterial); if(lpMaterial && IsDebug){ OutTraceD3D("Material: Size=%d Texture=%x diffuse=(%f,%f,%f,%f) ambient=(%f,%f,%f,%f) specular=(%f,%f,%f,%f) emissive=(%f,%f,%f,%f) power=%f\n", lpMaterial->dwSize, lpMaterial->hTexture, @@ -1291,7 +1344,7 @@ HRESULT WINAPI extGetMaterial(void *d3dd, LPD3DMATERIAL lpMaterial) HRESULT res; res=(*pGetMaterial)(d3dd, lpMaterial); - OutTraceD3D("GetMaterial: d3dd=%x, material=%x res=%x\n", d3dd, lpMaterial, res); + OutTraceD3D("GetMaterial: d3dd=%x material=%x res=%x\n", d3dd, lpMaterial, res); if(lpMaterial && IsDebug && (res==DD_OK)){ OutTraceD3D("Material: Size=%d diffuse=(%f,%f,%f,%f) ambient=(%f,%f,%f,%f) specular=(%f,%f,%f,%f) emissive=(%f,%f,%f,%f) power=%f\n", lpMaterial->dwSize, @@ -1304,3 +1357,69 @@ HRESULT WINAPI extGetMaterial(void *d3dd, LPD3DMATERIAL lpMaterial) } return res; } + +HRESULT WINAPI extSwapTextureHandles(void *d3dd, LPDIRECT3DTEXTURE t1, LPDIRECT3DTEXTURE t2) +{ + HRESULT res; + + OutTraceD3D("SwapTextureHandles(1): d3dd=%x t1=%x t2=%x\n", d3dd, t1, t2); + if (dxw.dwFlags4 & NOTEXTURES) return DD_OK; + + res=(*pSwapTextureHandles)(d3dd, t1, t2); + if(res) OutTraceD3D("SwapTextureHandles(1): ERROR res=%x\n", res); + return res; +} + +HRESULT WINAPI extSwapTextureHandles2(void *d3dd, LPDIRECT3DTEXTURE2 t1, LPDIRECT3DTEXTURE2 t2) +{ + HRESULT res; + + OutTraceD3D("SwapTextureHandles(2): d3dd=%x t1=%x t2=%x\n", d3dd, t1, t2); + if (dxw.dwFlags4 & NOTEXTURES) return DD_OK; + + res=(*pSwapTextureHandles2)(d3dd, t1, t2); + if(res) OutTraceD3D("SwapTextureHandles(2): ERROR res=%x\n", res); + return res; +} + +HRESULT WINAPI extTexInitialize(void *t, LPDIRECT3DDEVICE lpd3dd, LPDIRECTDRAWSURFACE lpdds) +{ + OutTrace("Texture::Initialize\n"); + return (*pTInitialize)(t, lpd3dd, lpdds); +} + +HRESULT WINAPI extTexGetHandle(void *t, LPDIRECT3DDEVICE lpd3dd, LPD3DTEXTUREHANDLE lpth) +{ + HRESULT ret; + OutTrace("Texture::GetHandle lpt=%x lpd3dd=%x lpth=%x\n", t, lpd3dd, lpth); + ret = (*pTGetHandle)(t, lpd3dd, lpth); + if(ret) OutTraceE("Texture::Load ERROR res=%x(%s)\n", ret, ExplainDDError(ret)); + return ret; +} + +HRESULT WINAPI extTexPaletteChanged(void *t, DWORD dw1, DWORD dw2) +{ + HRESULT ret; + OutTrace("Texture::PaletteChanged lpt=%x dw1=%x dw2=%x\n", t, dw1, dw2); + ret = (*pTPaletteChanged)(t, dw1, dw2); + if(ret) OutTraceE("Texture::PaletteChanged ERROR res=%x(%s)\n", ret, ExplainDDError(ret)); + return ret; +} + +HRESULT WINAPI extTexLoad(void *t, LPDIRECT3DTEXTURE lpt) +{ + HRESULT ret; + OutTrace("Texture::Load lpt=%x lpd3dt=%x\n", t, lpt); + ret = (*pTLoad)(t, lpt); + if(ret) OutTraceE("Texture::Load ERROR res=%x(%s)\n", ret, ExplainDDError(ret)); + return ret; +} + +HRESULT WINAPI extTexUnload(void *t) +{ + HRESULT ret; + OutTrace("Texture::Unload lpt=%x\n", t); + ret = (*pTUnload)(t); + if(ret) OutTraceE("Texture::Load ERROR res=%x(%s)\n", ret, ExplainDDError(ret)); + return ret; +} diff --git a/dll/hddraw.h b/dll/hddraw.h index 1317006..3cce6e6 100644 --- a/dll/hddraw.h +++ b/dll/hddraw.h @@ -126,3 +126,10 @@ typedef HRESULT (WINAPI *SetEntries_Type)(LPDIRECTDRAWPALETTE, DWORD, DWORD, DWO // // GammaRamp typedef HRESULT (WINAPI *GammaRamp_Type)(LPDIRECTDRAWSURFACE, DWORD, LPDDGAMMARAMP); + +// extern procedures + +extern void HookTexture(LPVOID *, int); +extern int Set_dwSize_From_Surface(LPDIRECTDRAWSURFACE); + + diff --git a/dll/texv4handle.cpp b/dll/texv4handle.cpp new file mode 100644 index 0000000..2e8284f --- /dev/null +++ b/dll/texv4handle.cpp @@ -0,0 +1,297 @@ +#define _CRT_SECURE_NO_WARNINGS + +#include +#include +#include +#include "dxwnd.h" +#include "dxwcore.hpp" +#include "dxhook.h" +#include "syslibs.h" +#include "dxhelper.h" + +extern char *ExplainDDError(DWORD); + +typedef HRESULT (WINAPI *Lock_Type)(LPDIRECTDRAWSURFACE, LPRECT, LPDDSURFACEDESC, DWORD, HANDLE); +typedef HRESULT (WINAPI *Unlock4_Type)(LPDIRECTDRAWSURFACE, LPRECT); +typedef HRESULT (WINAPI *Unlock1_Type)(LPDIRECTDRAWSURFACE, LPVOID); + +extern Lock_Type pLock; +extern Unlock4_Type pUnlockMethod(LPDIRECTDRAWSURFACE); +extern int Set_dwSize_From_Surface(LPDIRECTDRAWSURFACE); + +#define GRIDSIZE 16 + +/* RS Hash Function */ + +static unsigned int Hash(BYTE *buf, int len) +{ + unsigned int b = 378551; + unsigned int a = 63689; + DWORD hash = 0; + for(int i = 0; i < len; i++){ + hash = hash * a + buf[i]; + a = a * b; + } + return hash; +} + +void TextureHighlight(LPDIRECTDRAWSURFACE s) +{ + DDSURFACEDESC2 ddsd; + int x, y, w, h; + HRESULT res; + memset(&ddsd,0,sizeof(DDSURFACEDESC2)); + ddsd.dwSize = Set_dwSize_From_Surface(s); + ddsd.dwFlags = DDSD_LPSURFACE | DDSD_PITCH; + if(res=(*pLock)(s, 0, (LPDDSURFACEDESC)&ddsd, DDLOCK_SURFACEMEMORYPTR|DDLOCK_WRITEONLY|DDLOCK_WAIT, 0)){ + OutTraceE("TextureHigh: Lock ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + return; + } + extern LPDIRECTDRAWSURFACE lpDDSBack; + if((ddsd.ddsCaps.dwCaps & DDSCAPS_TEXTURE) && (s != lpDDSBack)) { + OutTrace("TextureHigh: lpdds=%x BitCount=%d size=(%dx%d)\n", + s, ddsd.ddpfPixelFormat.dwRGBBitCount, ddsd.dwWidth, ddsd.dwHeight); + w = ddsd.dwWidth; + h = ddsd.dwHeight; + switch (ddsd.ddpfPixelFormat.dwRGBBitCount){ + case 8: + { + BYTE *p; + BYTE color; + color=(BYTE)(rand() & 0xFF); + for(y=0; y> 1); + for(x=0; x> 1); + for(x=0; x> 2); + for(x=0; x> 2); + for(x=0; x (DWORD)iSurfaceSize) + for (int i = pbi.bV4SizeImage - iSurfaceSize; i; i--) putc(0, hf); + + // Close the .BMP file. + fclose(hf); + break; + } + res=(*pUnlockMethod(s))(s, NULL); + if (res) OutTraceE("TextureDump: Unlock ERROR lpdds=%x res=%x(%s) at %d\n", s, res, ExplainDDError(res), __LINE__); +} + +static void TextureHack(LPDIRECTDRAWSURFACE s) +{ + DDSURFACEDESC2 ddsd; + int w, h, iSurfaceSize; + HRESULT res; + + memset(&ddsd,0,sizeof(DDSURFACEDESC2)); + ddsd.dwSize = Set_dwSize_From_Surface(s); + ddsd.dwFlags = DDSD_LPSURFACE | DDSD_PITCH; + if(res=(*pLock)(s, 0, (LPDDSURFACEDESC)&ddsd, DDLOCK_SURFACEMEMORYPTR|DDLOCK_WRITEONLY|DDLOCK_WAIT, 0)){ + OutTraceE("TextureHack: Lock ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + return; + } + extern LPDIRECTDRAWSURFACE lpDDSBack; + if((ddsd.ddsCaps.dwCaps & DDSCAPS_TEXTURE) && (s != lpDDSBack)) while (TRUE) { // fake loop to ensure final Unlock + OutTrace("TextureHack: lpdds=%x BitCount=%d size=(%dx%d)\n", + s, ddsd.ddpfPixelFormat.dwRGBBitCount, ddsd.dwWidth, ddsd.dwHeight); + w = ddsd.dwWidth; + h = ddsd.dwHeight; + iSurfaceSize = ddsd.dwHeight * ddsd.lPitch; + + FILE *hf; + BITMAPFILEHEADER hdr; // bitmap file-header + BITMAPINFOHEADER pbi; // bitmap info-header + char pszFile[81]; + int iSizeImage; + + memset((void *)&pbi, 0, sizeof(BITMAPINFOHEADER)); + pbi.biSize = sizeof(BITMAPINFOHEADER); + pbi.biWidth = ddsd.dwWidth; + pbi.biHeight = ddsd.dwHeight; + pbi.biBitCount = (WORD)ddsd.ddpfPixelFormat.dwRGBBitCount; + pbi.biSizeImage = ((pbi.biWidth * pbi.biBitCount + 0x1F) & ~0x1F)/8 * pbi.biHeight; + iSizeImage = pbi.biSizeImage; + + // calculate the bitmap hash + DWORD hash; + hash = Hash((BYTE *)ddsd.lpSurface, iSurfaceSize); + if(!hash) break; // almost certainly, an empty black surface! + + // Look for the .BMP file. + sprintf_s(pszFile, 80, "texture.%x.bmp", hash); + hf = fopen(pszFile, "rb"); + if(!hf) break; // no updated texture to load + + OutTrace("HASH bmp file %x\n", hf); + + while(TRUE) { // fake loop to ensure final fclose + // Read the BITMAPFILEHEADER from the .BMP file (and throw away ...). + if(fread((LPVOID)&hdr, sizeof(BITMAPFILEHEADER), 1, hf) != 1)break; + + // Read the BITMAPINFOHEADER (and throw away ...). + // If the file contains BITMAPV4HEADER or BITMAPV5HEADER, no problem: next fseek will settle things + if(fread((LPVOID)&pbi, sizeof(BITMAPINFOHEADER), 1, hf) != 1) break; + + // skip the RGBQUAD array if the editor inserted one + fseek(hf, hdr.bfOffBits, SEEK_SET); + + // Read the new texture from the .BMP file. + if(pbi.biHeight < 0){ + // height < 0 means scan lines in the up to down order, hence you can read them all + if(fread((LPVOID)ddsd.lpSurface, iSurfaceSize, 1, hf) != 1) break; + } + else { + for(int y=0; y<(int)ddsd.dwHeight; y++){ + BYTE *p = (BYTE *)ddsd.lpSurface + (ddsd.lPitch * ((ddsd.dwHeight-1) - y)); + if(fread((LPVOID)p, ddsd.lPitch, 1, hf) != 1) break; + } + } + OutTrace("TextureHack: TEXTURE LOAD DONE\n"); + break; + } + + // Close the .BMP file. + fclose(hf); + break; + } + res=(*pUnlockMethod(s))(s, NULL); + if (res) OutTraceE("TextureHack: Unlock ERROR lpdds=%x res=%x(%s) at %d\n", s, res, ExplainDDError(res), __LINE__); +} + +void TextureHandling(LPDIRECTDRAWSURFACE s) +{ + OutTrace("TextureHandling: dxw.dwFlags5 = %x\n", dxw.dwFlags5 & (TEXTUREHIGHLIGHT|TEXTUREDUMP|TEXTUREHACK)); + switch(dxw.dwFlags5 & (TEXTUREHIGHLIGHT|TEXTUREDUMP|TEXTUREHACK)){ + default: + case TEXTUREHIGHLIGHT: + TextureHighlight(s); + break; + case TEXTUREDUMP: + TextureDump(s); + break; + case TEXTUREHACK: + TextureHack(s); + break; + } +} diff --git a/dll/user32.cpp b/dll/user32.cpp index 84dad77..46141d7 100644 --- a/dll/user32.cpp +++ b/dll/user32.cpp @@ -57,7 +57,7 @@ static HookEntry_Type Hooks[]={ {HOOK_IAT_CANDIDATE, "SystemParametersInfoA", (FARPROC)SystemParametersInfoA, (FARPROC *)&pSystemParametersInfoA, (FARPROC)extSystemParametersInfoA}, {HOOK_IAT_CANDIDATE, "SystemParametersInfoW", (FARPROC)SystemParametersInfoW, (FARPROC *)&pSystemParametersInfoW, (FARPROC)extSystemParametersInfoW}, //{HOOK_HOT_CANDIDATE, "GetActiveWindow", (FARPROC)NULL, (FARPROC *)&pGetActiveWindow, (FARPROC)extGetActiveWindow}, - //{HOOK_HOT_CANDIDATE, "GetForegroundWindow", (FARPROC)GetForegroundWindow, (FARPROC *)&pGetForegroundWindow, (FARPROC)extGetForegroundWindow}, + //{HOOK_HOT_CANDIDATE, "GetForegroundWindow", (FARPROC)NULL, (FARPROC *)&pGetForegroundWindow, (FARPROC)extGetForegroundWindow}, //{HOOK_IAT_CANDIDATE, "GetWindowTextA", (FARPROC)GetWindowTextA, (FARPROC *)&pGetWindowTextA, (FARPROC)extGetWindowTextA}, {HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator }; diff --git a/host/Resource.h b/host/Resource.h index b9405c4..42d887f 100644 Binary files a/host/Resource.h and b/host/Resource.h differ diff --git a/host/TabCompat.cpp b/host/TabCompat.cpp index 57ee6c4..4c06250 100644 --- a/host/TabCompat.cpp +++ b/host/TabCompat.cpp @@ -36,23 +36,12 @@ void CTabCompat::DoDataExchange(CDataExchange* pDX) DDX_Check(pDX, IDC_CDROMDRIVETYPE, cTarget->m_CDROMDriveType); DDX_Check(pDX, IDC_FONTBYPASS, cTarget->m_FontBypass); DDX_Check(pDX, IDC_BUFFEREDIOFIX, cTarget->m_BufferedIOFix); - DDX_Check(pDX, IDC_ZBUFFERCLEAN, cTarget->m_ZBufferClean); - DDX_Check(pDX, IDC_ZBUFFER0CLEAN, cTarget->m_ZBuffer0Clean); - DDX_Check(pDX, IDC_NOPOWER2FIX, cTarget->m_NoPower2Fix); DDX_Check(pDX, IDC_NOPERFCOUNTER, cTarget->m_NoPerfCounter); DDX_Check(pDX, IDC_HIDECDROMEMPTY, cTarget->m_HideCDROMEmpty); DDX_Check(pDX, IDC_DIABLOTWEAK, cTarget->m_DiabloTweak); DDX_Check(pDX, IDC_NOIMAGEHLP, cTarget->m_NoImagehlp); DDX_Check(pDX, IDC_REPLACEPRIVOPS, cTarget->m_ReplacePrivOps); - // 3D management - DDX_Check(pDX, IDC_NOTEXTURES, cTarget->m_NoTextures); - DDX_Check(pDX, IDC_WIREFRAME, cTarget->m_WireFrame); - DDX_Check(pDX, IDC_DISABLEFOGGING, cTarget->m_DisableFogging); - DDX_Check(pDX, IDC_CLEARTARGET, cTarget->m_ClearTarget); - DDX_Check(pDX, IDC_NOD3DRESET, cTarget->m_NoD3DReset); - DDX_Check(pDX, IDC_SUPPRESSD3DEXT, cTarget->m_SuppressD3DExt); - // Registry management DDX_Check(pDX, IDC_EMULATEREGISTRY, cTarget->m_EmulateRegistry); DDX_Check(pDX, IDC_OVERRIDEREGISTRY, cTarget->m_OverrideRegistry); diff --git a/host/TabDebug.cpp b/host/TabDebug.cpp index 5eee125..38579d7 100644 --- a/host/TabDebug.cpp +++ b/host/TabDebug.cpp @@ -33,7 +33,6 @@ void CTabDebug::DoDataExchange(CDataExchange* pDX) DDX_Check(pDX, IDC_ASSERT, cTarget->m_AssertDialog); DDX_Check(pDX, IDC_MARKBLIT, cTarget->m_MarkBlit); DDX_Check(pDX, IDC_NOBLT, cTarget->m_NoBlt); -// DDX_Check(pDX, IDC_BILINEARBLT, cTarget->m_BilinearBlt); DDX_Check(pDX, IDC_FASTBLT, cTarget->m_FastBlt); DDX_Check(pDX, IDC_ANALYTICMODE, cTarget->m_AnalyticMode); DDX_Check(pDX, IDC_SURFACEWARN, cTarget->m_SurfaceWarn); @@ -44,6 +43,8 @@ void CTabDebug::DoDataExchange(CDataExchange* pDX) DDX_Check(pDX, IDC_NOFILLRECT, cTarget->m_NoFillRect); DDX_Check(pDX, IDC_ZBUFFERALWAYS, cTarget->m_ZBufferAlways); DDX_Check(pDX, IDC_HOTPATCHALWAYS, cTarget->m_HotPatchAlways); + DDX_Check(pDX, IDC_NOSYSTEMMEMORY, cTarget->m_NoSystemMemory); + DDX_Check(pDX, IDC_NOSYSTEMEMULATED, cTarget->m_NoSystemEmulated); } BEGIN_MESSAGE_MAP(CTabDebug, CDialog) diff --git a/host/TabDirect3D.cpp b/host/TabDirect3D.cpp new file mode 100644 index 0000000..3c3c6b5 --- /dev/null +++ b/host/TabDirect3D.cpp @@ -0,0 +1,56 @@ +// TabDirect3D.cpp : implementation file +// + +#include "stdafx.h" +#include "TargetDlg.h" +#include "TabDirect3D.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CTabDirect3D dialog + +CTabDirect3D::CTabDirect3D(CWnd* pParent /*=NULL*/) + : CDialog(CTabDirect3D::IDD, pParent) +{ + //{{AFX_DATA_INIT(CTabDirect3D) + // NOTE: the ClassWizard will add member initialization here + //}}AFX_DATA_INIT +} + +void CTabDirect3D::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + CTargetDlg *cTarget = ((CTargetDlg *)(this->GetParent()->GetParent())); + + // Direct3D tweaks + DDX_Check(pDX, IDC_ZBUFFERCLEAN, cTarget->m_ZBufferClean); + DDX_Check(pDX, IDC_ZBUFFER0CLEAN, cTarget->m_ZBuffer0Clean); + DDX_Check(pDX, IDC_NOPOWER2FIX, cTarget->m_NoPower2Fix); + DDX_Check(pDX, IDC_NOD3DRESET, cTarget->m_NoD3DReset); + DDX_Check(pDX, IDC_SUPPRESSD3DEXT, cTarget->m_SuppressD3DExt); + DDX_Check(pDX, IDC_FORCESHEL, cTarget->m_ForcesHEL); + + // Texture management + DDX_Radio(pDX, IDC_TEXTURENONE, cTarget->m_TextureHandling); + + // 3D Effects + DDX_Check(pDX, IDC_NOTEXTURES, cTarget->m_NoTextures); + DDX_Check(pDX, IDC_WIREFRAME, cTarget->m_WireFrame); + DDX_Check(pDX, IDC_DISABLEFOGGING, cTarget->m_DisableFogging); + DDX_Check(pDX, IDC_CLEARTARGET, cTarget->m_ClearTarget); +} + +BEGIN_MESSAGE_MAP(CTabDirect3D, CDialog) + //{{AFX_MSG_MAP(CTabDirect3D) + // NOTE: the ClassWizard will add message map macros here + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CTabDirect3D message handlers + diff --git a/host/TabDirect3D.h b/host/TabDirect3D.h new file mode 100644 index 0000000..24205d8 --- /dev/null +++ b/host/TabDirect3D.h @@ -0,0 +1,48 @@ +#if !defined(AFX_TabDirect3D_H__798A9124_C906_446C_822D_322B5AB6C4C4__INCLUDED_) +#define AFX_TabDirect3D_H__798A9124_C906_446C_822D_322B5AB6C4C4__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// TabDirect3D.h : header file +// +#include "resource.h" + +///////////////////////////////////////////////////////////////////////////// +// CTabDirect3D dialog + +class CTabDirect3D : public CDialog +{ +// Construction +public: + CTabDirect3D(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CTabDirect3D) + enum { IDD = IDD_TAB_DIRECTX }; + // NOTE: the ClassWizard will add data members here + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CTabDirect3D) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CTabDirect3D) + // NOTE: the ClassWizard will add member functions here + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +public: +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif diff --git a/host/TabDirectX.cpp b/host/TabDirectX.cpp index f40e48b..51d47e4 100644 --- a/host/TabDirectX.cpp +++ b/host/TabDirectX.cpp @@ -27,9 +27,7 @@ void CTabDirectX::DoDataExchange(CDataExchange* pDX) CDialog::DoDataExchange(pDX); CTargetDlg *cTarget = ((CTargetDlg *)(this->GetParent()->GetParent())); DDX_Radio(pDX, IDC_AUTO, cTarget->m_DXVersion); - //DDX_Radio(pDX, IDC_NOEMULATESURFACE, cTarget->m_DxEmulationMode); DDX_Radio(pDX, IDC_AUTOMATIC, cTarget->m_DxEmulationMode); - //DDX_Check(pDX, IDC_HANDLEDC, cTarget->m_HandleDC); DDX_Radio(pDX, IDC_DDRAWFILTER, cTarget->m_DxFilterMode); DDX_Check(pDX, IDC_SUPPRESSCLIPPING, cTarget->m_SuppressClipping); DDX_Check(pDX, IDC_BLITFROMBACKBUFFER, cTarget->m_BlitFromBackBuffer); @@ -38,8 +36,6 @@ void CTabDirectX::DoDataExchange(CDataExchange* pDX) DDX_Check(pDX, IDC_SUPPRESSDXERRORS, cTarget->m_SuppressDXErrors); DDX_Check(pDX, IDC_BACKBUFATTACH, cTarget->m_BackBufAttach); DDX_Check(pDX, IDC_NOPALETTEUPDATE, cTarget->m_NoPaletteUpdate); - //DDX_Check(pDX, IDC_DISABLEHAL, cTarget->m_DisableHAL); - DDX_Check(pDX, IDC_FORCESHEL, cTarget->m_ForcesHEL); DDX_Check(pDX, IDC_NOPIXELFORMAT, cTarget->m_NoPixelFormat); DDX_Check(pDX, IDC_NOALPHACHANNEL, cTarget->m_NoAlphaChannel); DDX_Check(pDX, IDC_FIXREFCOUNTER, cTarget->m_FixRefCounter); @@ -48,8 +44,6 @@ void CTabDirectX::DoDataExchange(CDataExchange* pDX) DDX_Check(pDX, IDC_FULLRECTBLT, cTarget->m_FullRectBlt); DDX_Check(pDX, IDC_SETCOMPATIBILITY, cTarget->m_SetCompatibility); DDX_Check(pDX, IDC_AEROBOOST, cTarget->m_AEROBoost); - DDX_Check(pDX, IDC_NOSYSTEMMEMORY, cTarget->m_NoSystemMemory); - DDX_Check(pDX, IDC_NOSYSTEMEMULATED, cTarget->m_NoSystemEmulated); } BEGIN_MESSAGE_MAP(CTabDirectX, CDialog) diff --git a/host/TargetDlg.cpp b/host/TargetDlg.cpp index 806cae9..19cd0e4 100644 --- a/host/TargetDlg.cpp +++ b/host/TargetDlg.cpp @@ -45,7 +45,6 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/) m_DiabloTweak = FALSE; m_NoImagehlp = FALSE; m_ReplacePrivOps = FALSE; - m_DisableHAL = FALSE; m_ForcesHEL = FALSE; m_ColorFix = FALSE; m_NoPixelFormat = FALSE; @@ -59,7 +58,6 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/) m_ForceYUVtoRGB = FALSE; m_ForceRGBtoYUV = FALSE; m_LimitScreenRes = FALSE; - m_SaveCaps = FALSE; m_SingleProcAffinity = FALSE; m_LimitResources = FALSE; m_CDROMDriveType = FALSE; @@ -204,6 +202,8 @@ BOOL CTargetDlg::OnInitDialog() m_tabdxTabCtrl.InsertItem(i++, _T(sCaption)); LoadString(AfxGetResourceHandle(), DXW_TAB_DIRECTX, sCaption, sizeof(sCaption)); m_tabdxTabCtrl.InsertItem(i++, _T(sCaption)); + LoadString(AfxGetResourceHandle(), DXW_TAB_D3D, sCaption, sizeof(sCaption)); + m_tabdxTabCtrl.InsertItem(i++, _T(sCaption)); LoadString(AfxGetResourceHandle(), DXW_TAB_TIMING, sCaption, sizeof(sCaption)); m_tabdxTabCtrl.InsertItem(i++, _T(sCaption)); LoadString(AfxGetResourceHandle(), DXW_TAB_LOGS, sCaption, sizeof(sCaption)); diff --git a/host/TargetDlg.h b/host/TargetDlg.h index ed73873..11322b9 100644 --- a/host/TargetDlg.h +++ b/host/TargetDlg.h @@ -30,6 +30,7 @@ public: int m_DxFilterMode; int m_DCEmulationMode; int m_MouseVisibility; + int m_TextureHandling; BOOL m_HookDI; BOOL m_ModifyMouse; BOOL m_OutProxyTrace; @@ -154,7 +155,6 @@ public: BOOL m_AEROBoost; BOOL m_DiabloTweak; BOOL m_NoImagehlp; - BOOL m_DisableHAL; BOOL m_ForcesHEL; BOOL m_ColorFix; BOOL m_NoPixelFormat; @@ -165,7 +165,6 @@ public: BOOL m_SuppressChild; BOOL m_HideDesktop; BOOL m_LockSysColors; - BOOL m_SaveCaps; BOOL m_SingleProcAffinity; BOOL m_WireFrame; BOOL m_NoTextures; diff --git a/host/dxTabCtrl.cpp b/host/dxTabCtrl.cpp index a8fd6f4..9086e0b 100644 --- a/host/dxTabCtrl.cpp +++ b/host/dxTabCtrl.cpp @@ -24,6 +24,7 @@ #include "TabProgram.h" #include "TabLogs.h" #include "TabDirectX.h" +#include "TabDirect3D.h" #include "TabInput.h" #include "TabTiming.h" #include "TabWindow.h" @@ -51,6 +52,7 @@ CDXTabCtrl::CDXTabCtrl() m_tabPages[i++]=new CTabWindow; m_tabPages[i++]=new CTabInput; m_tabPages[i++]=new CTabDirectX; + m_tabPages[i++]=new CTabDirect3D; m_tabPages[i++]=new CTabTiming; m_tabPages[i++]=new CTabLogs; m_tabPages[i++]=new CTabSysLibs; @@ -76,6 +78,7 @@ void CDXTabCtrl::Init() m_tabPages[i++]->Create(IDD_TAB_OUTPUT, this); m_tabPages[i++]->Create(IDD_TAB_INPUT, this); m_tabPages[i++]->Create(IDD_TAB_DIRECTX, this); + m_tabPages[i++]->Create(IDD_TAB_D3D, this); m_tabPages[i++]->Create(IDD_TAB_TIMING, this); m_tabPages[i++]->Create(IDD_TAB_LOG, this); m_tabPages[i++]->Create(IDD_TAB_SYSLIBS, this); diff --git a/host/dxwndhost.aps b/host/dxwndhost.aps index a743b03..3628ef4 100644 Binary files a/host/dxwndhost.aps and b/host/dxwndhost.aps differ diff --git a/host/dxwndhost.rc b/host/dxwndhost.rc index a6b9a84..52ac7d8 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 70361bd..16410ff 100644 Binary files a/host/dxwndhost.vs2008.suo and b/host/dxwndhost.vs2008.suo differ diff --git a/host/dxwndhost.vs2008.vcproj b/host/dxwndhost.vs2008.vcproj index e6836c9..de9ad05 100644 --- a/host/dxwndhost.vs2008.vcproj +++ b/host/dxwndhost.vs2008.vcproj @@ -401,6 +401,14 @@ RelativePath=".\TabDebug.cpp" > + + + + @@ -628,6 +636,10 @@ > + + flags2 |= SHOWHWCURSOR; break; } + switch(dlg->m_TextureHandling){ + case 0: break; + case 1: t->flags5 |= TEXTUREHIGHLIGHT; break; + case 2: t->flags5 |= TEXTUREDUMP; break; + case 3: t->flags5 |= TEXTUREHACK; break; + } + if(dlg->m_HookDI) t->flags |= HOOKDI; if(dlg->m_ModifyMouse) t->flags |= MODIFYMOUSE; if(dlg->m_OutProxyTrace) t->tflags |= OUTPROXYTRACE; @@ -194,7 +201,6 @@ static void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg) if(dlg->m_AEROBoost) t->flags5 |= AEROBOOST; if(dlg->m_DiabloTweak) t->flags5 |= DIABLOTWEAK; if(dlg->m_NoImagehlp) t->flags5 |= NOIMAGEHLP; - if(dlg->m_DisableHAL) t->flags3 |= DISABLEHAL; if(dlg->m_ForcesHEL) t->flags3 |= FORCESHEL; if(dlg->m_ColorFix) t->flags3 |= COLORFIX; if(dlg->m_NoPixelFormat) t->flags3 |= NOPIXELFORMAT; @@ -208,7 +214,6 @@ static void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg) if(dlg->m_ForceYUVtoRGB) t->flags3 |= YUV2RGB; if(dlg->m_ForceRGBtoYUV) t->flags3 |= RGB2YUV; if(dlg->m_LimitScreenRes) t->flags4 |= LIMITSCREENRES; - if(dlg->m_SaveCaps) t->flags3 |= SAVECAPS; if(dlg->m_SingleProcAffinity) t->flags3 |= SINGLEPROCAFFINITY; if(dlg->m_SaveLoad) t->flags |= SAVELOAD; if(dlg->m_SlowDown) t->flags |= SLOWDOWN; @@ -348,6 +353,11 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg) if(t->flags & HIDEHWCURSOR) dlg->m_MouseVisibility = 1; if(t->flags2 & SHOWHWCURSOR) dlg->m_MouseVisibility = 2; + dlg->m_TextureHandling = 0; + if(t->flags5 & TEXTUREHIGHLIGHT) dlg->m_TextureHandling = 1; + if(t->flags5 & TEXTUREDUMP) dlg->m_TextureHandling = 2; + if(t->flags5 & TEXTUREHACK) dlg->m_TextureHandling = 3; + dlg->m_HookDI = t->flags & HOOKDI ? 1 : 0; dlg->m_ModifyMouse = t->flags & MODIFYMOUSE ? 1 : 0; dlg->m_OutProxyTrace = t->tflags & OUTPROXYTRACE ? 1 : 0; @@ -371,7 +381,6 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg) dlg->m_AEROBoost = t->flags5 & AEROBOOST ? 1 : 0; dlg->m_DiabloTweak = t->flags5 & DIABLOTWEAK ? 1 : 0; dlg->m_NoImagehlp = t->flags5 & NOIMAGEHLP ? 1 : 0; - dlg->m_DisableHAL = t->flags3 & DISABLEHAL ? 1 : 0; dlg->m_ForcesHEL = t->flags3 & FORCESHEL ? 1 : 0; dlg->m_ColorFix = t->flags3 & COLORFIX ? 1 : 0; dlg->m_NoPixelFormat = t->flags3 & NOPIXELFORMAT ? 1 : 0; @@ -385,7 +394,6 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg) dlg->m_ForceRGBtoYUV = t->flags3 & RGB2YUV ? 1 : 0; dlg->m_ForceYUVtoRGB = t->flags3 & YUV2RGB ? 1 : 0; dlg->m_LimitScreenRes = t->flags4 & LIMITSCREENRES ? 1 : 0; - dlg->m_SaveCaps = t->flags3 & SAVECAPS ? 1 : 0; dlg->m_SingleProcAffinity = t->flags3 & SINGLEPROCAFFINITY ? 1 : 0; dlg->m_LimitResources = t->flags2 & LIMITRESOURCES ? 1 : 0; dlg->m_CDROMDriveType = t->flags3 & CDROMDRIVETYPE ? 1 : 0; diff --git a/host/res/dxw5.ico b/host/res/dxw5.ico index ee03e26..8cd7287 100644 Binary files a/host/res/dxw5.ico and b/host/res/dxw5.ico differ diff --git a/host/res/run+33.ico b/host/res/run+33.ico index b6a8472..bf1fd99 100644 Binary files a/host/res/run+33.ico and b/host/res/run+33.ico differ diff --git a/host/res/run+66.ico b/host/res/run+66.ico index c52d247..87e2a4c 100644 Binary files a/host/res/run+66.ico and b/host/res/run+66.ico differ diff --git a/host/res/run-0.ico b/host/res/run-0.ico index d53cd9c..34b422d 100644 Binary files a/host/res/run-0.ico and b/host/res/run-0.ico differ diff --git a/host/res/run-180.ico b/host/res/run-180.ico index d53cd9c..34b422d 100644 Binary files a/host/res/run-180.ico and b/host/res/run-180.ico differ diff --git a/host/res/run-33.ico b/host/res/run-33.ico index f9a6f76..ab9c512 100644 Binary files a/host/res/run-33.ico and b/host/res/run-33.ico differ diff --git a/host/res/run-66.ico b/host/res/run-66.ico index f538b01..9be8b0d 100644 Binary files a/host/res/run-66.ico and b/host/res/run-66.ico differ diff --git a/host/resource b/host/resource new file mode 100644 index 0000000..ac83293 Binary files /dev/null and b/host/resource differ diff --git a/host/resource - Copia b/host/resource - Copia new file mode 100644 index 0000000..c9dff84 Binary files /dev/null and b/host/resource - Copia differ diff --git a/host/resource - Copia (2) b/host/resource - Copia (2) new file mode 100644 index 0000000..c1e94d6 Binary files /dev/null and b/host/resource - Copia (2) differ diff --git a/host/resource.xxx b/host/resource.xxx new file mode 100644 index 0000000..c9dff84 Binary files /dev/null and b/host/resource.xxx differ diff --git a/mp/Release/BuildLog.htm b/mp/Release/BuildLog.htm new file mode 100644 index 0000000..bf53ed7 Binary files /dev/null and b/mp/Release/BuildLog.htm differ diff --git a/mp/Release/bilinear16_555.obj b/mp/Release/bilinear16_555.obj new file mode 100644 index 0000000..f830298 Binary files /dev/null and b/mp/Release/bilinear16_555.obj differ diff --git a/mp/Release/bilinear16_565.obj b/mp/Release/bilinear16_565.obj new file mode 100644 index 0000000..2d23de8 Binary files /dev/null and b/mp/Release/bilinear16_565.obj differ diff --git a/mp/Release/bilinear32.obj b/mp/Release/bilinear32.obj new file mode 100644 index 0000000..f8cfb5f Binary files /dev/null and b/mp/Release/bilinear32.obj differ diff --git a/mp/Release/mp.dll.embed.manifest b/mp/Release/mp.dll.embed.manifest new file mode 100644 index 0000000..bfec505 --- /dev/null +++ b/mp/Release/mp.dll.embed.manifest @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/mp/Release/mp.dll.embed.manifest.res b/mp/Release/mp.dll.embed.manifest.res new file mode 100644 index 0000000..03f5c96 Binary files /dev/null and b/mp/Release/mp.dll.embed.manifest.res differ diff --git a/mp/Release/mp.dll.intermediate.manifest b/mp/Release/mp.dll.intermediate.manifest new file mode 100644 index 0000000..7256947 --- /dev/null +++ b/mp/Release/mp.dll.intermediate.manifest @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/mp/Release/mt.dep b/mp/Release/mt.dep new file mode 100644 index 0000000..a39d202 --- /dev/null +++ b/mp/Release/mt.dep @@ -0,0 +1 @@ +Manifest resource last updated at 12:28:44.86 on 23/11/2014 diff --git a/mp/Release/vc90.idb b/mp/Release/vc90.idb new file mode 100644 index 0000000..6b486a5 Binary files /dev/null and b/mp/Release/vc90.idb differ diff --git a/mp/Release/vc90.pdb b/mp/Release/vc90.pdb new file mode 100644 index 0000000..281774d Binary files /dev/null and b/mp/Release/vc90.pdb differ diff --git a/mp/bilinear16_555.cpp b/mp/bilinear16_555.cpp new file mode 100644 index 0000000..eb2682a --- /dev/null +++ b/mp/bilinear16_555.cpp @@ -0,0 +1,215 @@ +#include +#include +#include + +static int* g_px1a = NULL; +static int g_px1a_w = 0; +static int* g_px1ab = NULL; +static int g_px1ab_w = 0; + +void WINAPI Resize_HQ_2ch555( unsigned char* src, RECT *srcrect, int srcpitch, + unsigned char* dest, RECT *destrect, int destpitch) +{ + // Both buffers must be in RGB 565 format. + + int w1, w2, h1, h2; + w1 = srcrect->right - srcrect->left; + h1 = srcrect->bottom - srcrect->top; + w2 = destrect->right - destrect->left; + h2 = destrect->bottom - destrect->top; + + if(!srcpitch) srcpitch=w1<<1; + if(!destpitch) destpitch=w1<<1; + + // GHO addiction: new variables + // p1, p2: pitch offsets of source and dest surfaces in DWORD offset, that is pitch / sizeof(DWORD) + // beware: current version can operate on displaced source rect, but assumes the dest rect is always the full surface!! + USHORT p1 = srcpitch >> 1; + USHORT p2 = destpitch >> 1; + USHORT *dsrc = (USHORT *)src + (srcrect->top * p1) + srcrect->left; + USHORT *ddest = (USHORT *)dest; + + // arbitrary resize. + + bool bUpsampleX = (w1 < w2); + bool bUpsampleY = (h1 < h2); + + // If too many input pixels map to one output pixel, our 32-bit accumulation values + // could overflow - so, if we have huge mappings like that, cut down the weights: + // 256 max color value + // *256 weight_x + // *256 weight_y + // *256 (16*16) maximum # of input pixels (x,y) - unless we cut the weights down... + int weight_shift = 0; + + //gsky916: weight_shift calculation in bUpsampleX && bUpsampleY cases are not necessary. + //Move to else block to reduce floating point calculations. + + float fh = 256*h1/(float)h2; + float fw = 256*w1/(float)w2; + + if (bUpsampleX && bUpsampleY) + { + // faster to just do 2x2 bilinear interp here + + // cache x1a, x1b for all the columns: + // ...and your OS better have garbage collection on process exit :) + if (g_px1a_w < w2) + { + if (g_px1a) delete [] g_px1a; + g_px1a = new int[w2*2 * 1]; + g_px1a_w = w2*2; + } + for (int x2=0; x2> 8; + + USHORT *ddest = &((USHORT *)dest)[y2*p2 + 0]; + + for (int x2=0; x2> 8; + + USHORT *dsrc2 = &dsrc[y1c*p1 + x1c]; // GHO + + // PERFORM BILINEAR INTERPOLATION on 2x2 pixels + UINT r=0, g=0, b=0, a=0; + UINT weight_x = 256 - (x1a & 0xFF); + UINT weight_y = 256 - (y1a & 0xFF); + for (int y=0; y<2; y++) + { + for (int x=0; x<2; x++) + { + UINT c = (UINT)dsrc2[x + y*p1]; // GHO + UINT r_src = (c ) & 0x1F; + UINT g_src = (c>> 5) & 0x1F; + UINT b_src = (c>>10) & 0x1F; + UINT w = (weight_x * weight_y) >> weight_shift; + r += r_src * w; + g += g_src * w; + b += b_src * w; + weight_x = 256 - weight_x; + } + weight_y = 256 - weight_y; + } + + UINT c = ((r>>16) & 0x1F) | ((g>>(16-5)) & 0x3E0) | ((b>>(16-10)) & 0x7C00); + *ddest++ = (USHORT)c; + } + } + } + else // either downscale on vertical or horizontal direction ... + { + //gsky916: weight_shift calculation moved here. + float source_texels_per_out_pixel = ( (w1/(float)w2 + 1) + * (h1/(float)h2 + 1) + ); + float weight_per_pixel = source_texels_per_out_pixel * 256 * 256; //weight_x * weight_y + float accum_per_pixel = weight_per_pixel*256; //color value is 0-255 + float weight_div = accum_per_pixel / 4294967000.0f; + if (weight_div > 1) + weight_shift = (int)ceilf( logf((float)weight_div)/logf(2.0f) ); + weight_shift = min(15, weight_shift); // this could go to 15 and still be ok. + + // cache x1a, x1b for all the columns: + // ...and your OS better have garbage collection on process exit :) + if (g_px1ab_w < w2) + { + if (g_px1ab) delete [] g_px1ab; + g_px1ab = new int[w2*2 * 2]; + g_px1ab_w = w2*2; + } + for (int x2=0; x2 we want to interpolate between two pixels! + x1b = x1a + 256; + x1b = min(x1b, 256*w1 - 1); + g_px1ab[x2*2+0] = x1a; + g_px1ab[x2*2+1] = x1b; + } + + // FOR EVERY OUTPUT PIXEL + for (int y2=0; y2 we want to interpolate between two pixels! + y1b = y1a + 256; + y1b = min(y1b, 256*h1 - 1); + int y1c = y1a >> 8; + int y1d = y1b >> 8; + + ddest = &((USHORT *)dest)[y2*p2 + 0]; + + for (int x2=0; x2> 8; + int x1d = x1b >> 8; + + // ADD UP ALL INPUT PIXELS CONTRIBUTING TO THIS OUTPUT PIXEL: + UINT r=0, g=0, b=0, a=0; + for (int y=y1c; y<=y1d; y++) + { + UINT weight_y = 256; + if (y1c != y1d) + { + if (y==y1c) + weight_y = 256 - (y1a & 0xFF); + else if (y==y1d) + weight_y = (y1b & 0xFF); + } + + USHORT *dsrc2 = &dsrc[y*p1 + x1c]; // GHO + for (int x=x1c; x<=x1d; x++) + { + UINT weight_x = 256; + if (x1c != x1d) + { + if (x==x1c) + weight_x = 256 - (x1a & 0xFF); + else if (x==x1d) + weight_x = (x1b & 0xFF); + } + + UINT c = dsrc[y*p1 + x]; + UINT r_src = (c ) & 0x1F; + UINT g_src = (c>> 5) & 0x1F; + UINT b_src = (c>>10) & 0x1F; + UINT w = (weight_x * weight_y) >> weight_shift; + r += r_src * w; + g += g_src * w; + b += b_src * w; + a += w; + } + } + + // write results + UINT c = ((r/a) & 0x1F) | (((g/a) << 5) & 0x3E0) | (((b/a) << 10) & 0x7C00); + *ddest++ = c; + } + } + } +} \ No newline at end of file diff --git a/mp/bilinear16_565.cpp b/mp/bilinear16_565.cpp new file mode 100644 index 0000000..3b58652 --- /dev/null +++ b/mp/bilinear16_565.cpp @@ -0,0 +1,215 @@ +#include +#include +#include + +static int* g_px1a = NULL; +static int g_px1a_w = 0; +static int* g_px1ab = NULL; +static int g_px1ab_w = 0; + +void WINAPI Resize_HQ_2ch565( unsigned char* src, RECT *srcrect, int srcpitch, + unsigned char* dest, RECT *destrect, int destpitch) +{ + // Both buffers must be in RGB 565 format. + + int w1, w2, h1, h2; + w1 = srcrect->right - srcrect->left; + h1 = srcrect->bottom - srcrect->top; + w2 = destrect->right - destrect->left; + h2 = destrect->bottom - destrect->top; + + if(!srcpitch) srcpitch=w1<<1; + if(!destpitch) destpitch=w1<<1; + + // GHO addiction: new variables + // p1, p2: pitch offsets of source and dest surfaces in DWORD offset, that is pitch / sizeof(DWORD) + // beware: current version can operate on displaced source rect, but assumes the dest rect is always the full surface!! + USHORT p1 = srcpitch >> 1; + USHORT p2 = destpitch >> 1; + USHORT *dsrc = (USHORT *)src + (srcrect->top * p1) + srcrect->left; + USHORT *ddest = (USHORT *)dest; + + // arbitrary resize. + + bool bUpsampleX = (w1 < w2); + bool bUpsampleY = (h1 < h2); + + // If too many input pixels map to one output pixel, our 32-bit accumulation values + // could overflow - so, if we have huge mappings like that, cut down the weights: + // 256 max color value + // *256 weight_x + // *256 weight_y + // *256 (16*16) maximum # of input pixels (x,y) - unless we cut the weights down... + int weight_shift = 0; + + //gsky916: weight_shift calculation in bUpsampleX && bUpsampleY cases are not necessary. + //Move to else block to reduce floating point calculations. + + float fh = 256*h1/(float)h2; + float fw = 256*w1/(float)w2; + + if (bUpsampleX && bUpsampleY) + { + // faster to just do 2x2 bilinear interp here + + // cache x1a, x1b for all the columns: + // ...and your OS better have garbage collection on process exit :) + if (g_px1a_w < w2) + { + if (g_px1a) delete [] g_px1a; + g_px1a = new int[w2*2 * 1]; + g_px1a_w = w2*2; + } + for (int x2=0; x2> 8; + + USHORT *ddest = &((USHORT *)dest)[y2*p2 + 0]; + + for (int x2=0; x2> 8; + + USHORT *dsrc2 = &dsrc[y1c*p1 + x1c]; // GHO + + // PERFORM BILINEAR INTERPOLATION on 2x2 pixels + UINT r=0, g=0, b=0, a=0; + UINT weight_x = 256 - (x1a & 0xFF); + UINT weight_y = 256 - (y1a & 0xFF); + for (int y=0; y<2; y++) + { + for (int x=0; x<2; x++) + { + UINT c = (UINT)dsrc2[x + y*p1]; // GHO + UINT r_src = (c ) & 0x1F; + UINT g_src = (c>> 5) & 0x3F; + UINT b_src = (c>>11) & 0x1F; + UINT w = (weight_x * weight_y) >> weight_shift; + r += r_src * w; + g += g_src * w; + b += b_src * w; + weight_x = 256 - weight_x; + } + weight_y = 256 - weight_y; + } + + UINT c = ((r>>16) & 0x1F) | ((g>>(16-5)) & 0x7E0) | ((b>>(16-11)) & 0xF800); + *ddest++ = (USHORT)c; + } + } + } + else // either downscale on vertical or horizontal direction ... + { + //gsky916: weight_shift calculation moved here. + float source_texels_per_out_pixel = ( (w1/(float)w2 + 1) + * (h1/(float)h2 + 1) + ); + float weight_per_pixel = source_texels_per_out_pixel * 256 * 256; //weight_x * weight_y + float accum_per_pixel = weight_per_pixel*256; //color value is 0-255 + float weight_div = accum_per_pixel / 4294967000.0f; + if (weight_div > 1) + weight_shift = (int)ceilf( logf((float)weight_div)/logf(2.0f) ); + weight_shift = min(15, weight_shift); // this could go to 15 and still be ok. + + // cache x1a, x1b for all the columns: + // ...and your OS better have garbage collection on process exit :) + if (g_px1ab_w < w2) + { + if (g_px1ab) delete [] g_px1ab; + g_px1ab = new int[w2*2 * 2]; + g_px1ab_w = w2*2; + } + for (int x2=0; x2 we want to interpolate between two pixels! + x1b = x1a + 256; + x1b = min(x1b, 256*w1 - 1); + g_px1ab[x2*2+0] = x1a; + g_px1ab[x2*2+1] = x1b; + } + + // FOR EVERY OUTPUT PIXEL + for (int y2=0; y2 we want to interpolate between two pixels! + y1b = y1a + 256; + y1b = min(y1b, 256*h1 - 1); + int y1c = y1a >> 8; + int y1d = y1b >> 8; + + ddest = &((USHORT *)dest)[y2*p2 + 0]; + + for (int x2=0; x2> 8; + int x1d = x1b >> 8; + + // ADD UP ALL INPUT PIXELS CONTRIBUTING TO THIS OUTPUT PIXEL: + UINT r=0, g=0, b=0, a=0; + for (int y=y1c; y<=y1d; y++) + { + UINT weight_y = 256; + if (y1c != y1d) + { + if (y==y1c) + weight_y = 256 - (y1a & 0xFF); + else if (y==y1d) + weight_y = (y1b & 0xFF); + } + + USHORT *dsrc2 = &dsrc[y*p1 + x1c]; // GHO + for (int x=x1c; x<=x1d; x++) + { + UINT weight_x = 256; + if (x1c != x1d) + { + if (x==x1c) + weight_x = 256 - (x1a & 0xFF); + else if (x==x1d) + weight_x = (x1b & 0xFF); + } + + UINT c = dsrc[y*p1 + x]; + UINT r_src = (c ) & 0x1F; + UINT g_src = (c>> 5) & 0x3F; + UINT b_src = (c>>11) & 0x1F; + UINT w = (weight_x * weight_y) >> weight_shift; + r += r_src * w; + g += g_src * w; + b += b_src * w; + a += w; + } + } + + // write results + UINT c = ((r/a) & 0x1F) | (((g/a) << 5) & 0x7E0) | (((b/a) << 11) & 0xF800); + *ddest++ = c; + } + } + } +} \ No newline at end of file diff --git a/dll/bilinear.cpp b/mp/bilinear32.cpp similarity index 81% rename from dll/bilinear.cpp rename to mp/bilinear32.cpp index 7904458..c30c0d3 100644 --- a/dll/bilinear.cpp +++ b/mp/bilinear32.cpp @@ -54,10 +54,7 @@ static int g_px1a_w = 0; static int* g_px1ab = NULL; static int g_px1ab_w = 0; -static bool g_bMMX = false; -static bool g_bMMX_known = false; - -void Resize_HQ_4ch( unsigned char* src, RECT *srcrect, int srcpitch, +void WINAPI Resize_HQ_4ch( unsigned char* src, RECT *srcrect, int srcpitch, unsigned char* dest, RECT *destrect, int destpitch) { // Both buffers must be in ARGB format, and a scanline should be w*4 bytes. @@ -77,10 +74,10 @@ void Resize_HQ_4ch( unsigned char* src, RECT *srcrect, int srcpitch, // GHO addiction: new variables // p1, p2: pitch offsets of source and dest surfaces in DWORD offset, that is pitch / sizeof(DWORD) // beware: current version can operate on displaced source rect, but assumes the dest rect is always the full surface!! - unsigned int p1 = srcpitch >> 2; - unsigned int p2 = destpitch >> 2; - unsigned int *dsrc = (unsigned int *)src + (srcrect->top * p1) + srcrect->left; - unsigned int *ddest = (unsigned int *)dest; + UINT p1 = srcpitch >> 2; + UINT p2 = destpitch >> 2; + UINT *dsrc = (UINT *)src + (srcrect->top * p1) + srcrect->left; + UINT *ddest = (UINT *)dest; // arbitrary resize. @@ -131,8 +128,7 @@ void Resize_HQ_4ch( unsigned char* src, RECT *srcrect, int srcpitch, y1a = min(y1a, 256*(h1-1) - 1); int y1c = y1a >> 8; - // unsigned int *ddest = &((unsigned int *)dest)[y2*w2 + 0]; - unsigned int *ddest = &((unsigned int *)dest)[y2*p2 + 0]; + UINT *ddest = &((UINT *)dest)[y2*p2 + 0]; for (int x2=0; x2> 8; - //unsigned int *dsrc2 = &dsrc[y1c*w1 + x1c]; - unsigned int *dsrc2 = &dsrc[y1c*p1 + x1c]; // GHO + UINT *dsrc2 = &dsrc[y1c*p1 + x1c]; // GHO // PERFORM BILINEAR INTERPOLATION on 2x2 pixels - unsigned int r=0, g=0, b=0, a=0; - unsigned int weight_x = 256 - (x1a & 0xFF); - unsigned int weight_y = 256 - (y1a & 0xFF); + UINT r=0, g=0, b=0, a=0; + UINT weight_x = 256 - (x1a & 0xFF); + UINT weight_y = 256 - (y1a & 0xFF); for (int y=0; y<2; y++) { for (int x=0; x<2; x++) { - //unsigned int c = dsrc2[x + y*w1]; - unsigned int c = dsrc2[x + y*p1]; // GHO - unsigned int r_src = (c ) & 0xFF; - unsigned int g_src = (c>> 8) & 0xFF; - unsigned int b_src = (c>>16) & 0xFF; - unsigned int w = (weight_x * weight_y) >> weight_shift; + //UINT c = dsrc2[x + y*w1]; + UINT c = dsrc2[x + y*p1]; // GHO + UINT r_src = (c ) & 0xFF; + UINT g_src = (c>> 8) & 0xFF; + UINT b_src = (c>>16) & 0xFF; + UINT w = (weight_x * weight_y) >> weight_shift; r += r_src * w; g += g_src * w; b += b_src * w; @@ -165,10 +160,8 @@ void Resize_HQ_4ch( unsigned char* src, RECT *srcrect, int srcpitch, weight_y = 256 - weight_y; } - unsigned int c = ((r>>16)) | ((g>>8) & 0xFF00) | (b & 0xFF0000); - //*ddest++ = c;//ddest[y2*w2 + x2] = c; + UINT c = ((r>>16)) | ((g>>8) & 0xFF00) | (b & 0xFF0000); *ddest++ = c; - //ddest+=(w2-p2); } } } @@ -217,7 +210,7 @@ void Resize_HQ_4ch( unsigned char* src, RECT *srcrect, int srcpitch, int y1c = y1a >> 8; int y1d = y1b >> 8; - ddest = &((unsigned int *)dest)[y2*p2 + 0]; + ddest = &((UINT *)dest)[y2*p2 + 0]; for (int x2=0; x2> 8; // ADD UP ALL INPUT PIXELS CONTRIBUTING TO THIS OUTPUT PIXEL: - unsigned int r=0, g=0, b=0, a=0; + UINT r=0, g=0, b=0, a=0; for (int y=y1c; y<=y1d; y++) { - unsigned int weight_y = 256; + UINT weight_y = 256; if (y1c != y1d) { if (y==y1c) @@ -240,11 +233,11 @@ void Resize_HQ_4ch( unsigned char* src, RECT *srcrect, int srcpitch, weight_y = (y1b & 0xFF); } - //unsigned int *dsrc2 = &dsrc[y*w1 + x1c]; - unsigned int *dsrc2 = &dsrc[y*p1 + x1c]; // GHO + //UINT *dsrc2 = &dsrc[y*w1 + x1c]; + UINT *dsrc2 = &dsrc[y*p1 + x1c]; // GHO for (int x=x1c; x<=x1d; x++) { - unsigned int weight_x = 256; + UINT weight_x = 256; if (x1c != x1d) { if (x==x1c) @@ -253,12 +246,12 @@ void Resize_HQ_4ch( unsigned char* src, RECT *srcrect, int srcpitch, weight_x = (x1b & 0xFF); } - //unsigned int c = *dsrc2++;//dsrc[y*w1 + x]; - unsigned int c = dsrc[y*p1 + x]; - unsigned int r_src = (c ) & 0xFF; - unsigned int g_src = (c>> 8) & 0xFF; - unsigned int b_src = (c>>16) & 0xFF; - unsigned int w = (weight_x * weight_y) >> weight_shift; + //UINT c = *dsrc2++;//dsrc[y*w1 + x]; + UINT c = dsrc[y*p1 + x]; + UINT r_src = (c ) & 0xFF; + UINT g_src = (c>> 8) & 0xFF; + UINT b_src = (c>>16) & 0xFF; + UINT w = (weight_x * weight_y) >> weight_shift; r += r_src * w; g += g_src * w; b += b_src * w; @@ -267,11 +260,12 @@ void Resize_HQ_4ch( unsigned char* src, RECT *srcrect, int srcpitch, } // write results - unsigned int c = ((r/a)) | ((g/a)<<8) | ((b/a)<<16); + UINT c = ((r/a)) | ((g/a)<<8) | ((b/a)<<16); //*ddest++ = c;//ddest[y2*w2 + x2] = c; *ddest++ = c; //ddest+=(w2-p2); } } } -} \ No newline at end of file +} + diff --git a/mp/mp.def b/mp/mp.def new file mode 100644 index 0000000..f1cd989 --- /dev/null +++ b/mp/mp.def @@ -0,0 +1,5 @@ +LIBRARY mp +EXPORTS + Resize_HQ_4ch @1 + Resize_HQ_2ch565 @2 + Resize_HQ_2ch555 @3 diff --git a/mp/mp.sln b/mp/mp.sln new file mode 100644 index 0000000..3c2c4d2 --- /dev/null +++ b/mp/mp.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mp", "mp.vcproj", "{F3E96EF0-AF9C-43C2-8E3E-0DD10B66E0FC}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F3E96EF0-AF9C-43C2-8E3E-0DD10B66E0FC}.Debug|Win32.ActiveCfg = Debug|Win32 + {F3E96EF0-AF9C-43C2-8E3E-0DD10B66E0FC}.Debug|Win32.Build.0 = Debug|Win32 + {F3E96EF0-AF9C-43C2-8E3E-0DD10B66E0FC}.Release|Win32.ActiveCfg = Release|Win32 + {F3E96EF0-AF9C-43C2-8E3E-0DD10B66E0FC}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/mp/mp.suo b/mp/mp.suo new file mode 100644 index 0000000..b37c43d Binary files /dev/null and b/mp/mp.suo differ diff --git a/mp/mp.vcproj b/mp/mp.vcproj new file mode 100644 index 0000000..ef9aa5a --- /dev/null +++ b/mp/mp.vcproj @@ -0,0 +1,207 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mp/mp.vcproj.user b/mp/mp.vcproj.user new file mode 100644 index 0000000..0ce2ced --- /dev/null +++ b/mp/mp.vcproj.user @@ -0,0 +1 @@ + \ No newline at end of file