diff --git a/build/dxwnd.dll b/build/dxwnd.dll index 87b679e..272fccb 100644 --- a/build/dxwnd.dll +++ b/build/dxwnd.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9c8410eab8068ad4e1b67b255732d31c5638723a78b14f0ff2ace2da0b7cab6a -size 765952 +oid sha256:c1ff3a6f4bd35e8240757938f69a200d952634e134b6543dea433fc90ef1a35b +size 770560 diff --git a/build/dxwnd.exe b/build/dxwnd.exe index 415bf4f..d5d810c 100644 --- a/build/dxwnd.exe +++ b/build/dxwnd.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9e4a7cf529cd909fcf64fd97ea8e5422ca264152244cf9f401ade66517232eeb +oid sha256:490cb948680c5a66c5697716453ebc008d2a3614cda1924c369ccfd9d5f925a1 size 669184 diff --git a/build/dxwnd.log b/build/dxwnd.log deleted file mode 100644 index e0249d6..0000000 --- a/build/dxwnd.log +++ /dev/null @@ -1,20 +0,0 @@ -OnRun idx=6 prog="D:\Games\Tomb Raider III\tomb3.exe" -setwindowshook mode -OnRun idx=4 prog="D:\Games\Spearhead\Spearhead.exe" -injectsuspended mode -InjectSuspended: exe=D:\Games\Spearhead\Spearhead.exe dir=D:\Games\Spearhead -Target handle=7ac -NT Header offset=80 -AddressOfEntryPoint=1AA380 ImageBase=400000 -Thread start address=5aa380 -wait cycle 0 eip=5aa380 -OnRun idx=4 prog="D:\Games\Spearhead\Spearhead.exe" -injectsuspended mode -InjectSuspended: exe=D:\Games\Spearhead\Spearhead.exe dir=D:\Games\Spearhead -Target handle=768 -NT Header offset=80 -AddressOfEntryPoint=1AA380 ImageBase=400000 -Thread start address=5aa380 -wait cycle 0 eip=5aa380 -OnRun idx=3 prog="F:\Games\Nascar 2000\NASCAR 2000.exe" -setwindowshook mode diff --git a/build/exports/Tonic Trouble.dxw b/build/exports/Tonic Trouble.dxw new file mode 100644 index 0000000..ded73d2 --- /dev/null +++ b/build/exports/Tonic Trouble.dxw @@ -0,0 +1,36 @@ +[target] +title0=Tonic Trouble +path0=F:\Games\Tonic Trouble\TonicTrouble.exe +startfolder0= +launchpath0=F:\Games\Tonic Trouble\TonicTrouble.exe -cdrom:H +module0= +opengllib0= +notes0= +registry0= +ver0=0 +monitorid0=-1 +coord0=0 +flag0=673185830 +flagg0=1207959552 +flagh0=65556 +flagi0=138412036 +flagj0=4224 +flagk0=65536 +flagl0=536870912 +flagm0=36 +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 4739ca7..4a06b21 100644 --- a/build/readme-relnotes.txt +++ b/build/readme-relnotes.txt @@ -1393,7 +1393,7 @@ 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 -v2.04.01/fx6 +v2.04.01/fx5 add: preliminary WinG32 handling add: minimal WinG32 replacement, thank to Wine source code add: DirectX(2)/"Create a Desktop Win" option. Fixes "Man TT Super Bike" @@ -1409,4 +1409,11 @@ fix: added hooker for Smack32/SmackSetSystemRes call to prevent resolution chang fix: fixed virtual screen size initialization so that it doesn't override settings defined before first window creation: see "Spearhead" fix: fixed error condition when DirectDraw::GetCaps is invoked with wrong length - fix "Spearhead" bug fix?: ZBUFFER original capabilities passed to new surface created by QueryInterface - so far, useless -fix: bug causing crash when using fast bilinear filtering 2X + +v2.04.02 +fix: avoid crashing on View Shims command on WinXP +fix: bilinear 2X crash +fix: handling of 16 to 32 bpp color conversion in D3D8 IDirect3DDevice8 Copyrects and GetFrontBuffer methods. Fixes "Dirt track Racing 2" missing panels. +fix: more / better logging +fix: in USER32/CreateWindow* calls, handles the case where a to-be main window is moved/resized before being declared as main window. Fixes uncontrolled position changes in "Civil Wars 2 Generals". +add: preliminary hooks for message loop APIs USER32/PeekMessage, GetMessage, PostMessage. Now PeekMessage includes SLOWDOW flag processing, reduces CPU time in "Civil Wars 2 Generals". \ No newline at end of file diff --git a/dll/ddblit.cpp b/dll/ddblit.cpp index 063257e..ce40809 100644 --- a/dll/ddblit.cpp +++ b/dll/ddblit.cpp @@ -45,9 +45,7 @@ static HRESULT sBltNoPrimary(int dxversion, Blt_Type pBlt, char *api, LPDIRECTDR FromScreen=dxwss.IsAPrimarySurface(lpddssrc); // make a working copy of srcrect if not NULL - if (lpsrcrect){ - srcrect=*lpsrcrect; - } + if (lpsrcrect) srcrect=*lpsrcrect; // when blitting from a primary surface on screen (that is in non emulated mode), correct offsets // You should take account also for scaled primary surfaces, but that would be a hard task: // a reduced primary surface (in not-emulated mode) would bring quality loss!!! @@ -93,6 +91,7 @@ static HRESULT sBltNoPrimary(int dxversion, Blt_Type pBlt, char *api, LPDIRECTDR // } // break; case DDERR_SURFACEBUSY: + if (lpsrcrect) srcrect=*lpsrcrect; (*pUnlockMethod(dxversion))(lpdds, NULL); if (lpddssrc) (*pUnlockMethod(dxversion))(lpddssrc, NULL); if (IsDebug) BlitTrace("BUSY", lpsrcrect ? &srcrect : NULL, lpdestrect, __LINE__); diff --git a/dll/dxemublt.cpp b/dll/dxemublt.cpp index 96b6705..2d5cf85 100644 --- a/dll/dxemublt.cpp +++ b/dll/dxemublt.cpp @@ -96,7 +96,7 @@ static DWORD Melt16_565(DWORD c1, DWORD c2) return ret; } -static void SetPalette16BPP() +void SetPalette16BPP() { // OutTraceDW("DEBUG: h=%d w=%d src=%x dst=%x spitch=%d dpitch=%d\n",h,w,src16,dest,srcpitch,destpitch); unsigned int pi; diff --git a/dll/dxwnd.cpp b/dll/dxwnd.cpp index 40c91a0..3e36f93 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.04.01.fx6" +#define VERSION "2.04.02" #define DDTHREADLOCK 1 diff --git a/dll/dxwnd.vs2008.suo b/dll/dxwnd.vs2008.suo deleted file mode 100644 index a75a098..0000000 Binary files a/dll/dxwnd.vs2008.suo and /dev/null differ diff --git a/dll/dxwnd.vs2008.vcproj.DESKTOP-Q3RE27J.user.user b/dll/dxwnd.vs2008.vcproj.DESKTOP-Q3RE27J.user.user new file mode 100644 index 0000000..d055039 --- /dev/null +++ b/dll/dxwnd.vs2008.vcproj.DESKTOP-Q3RE27J.user.user @@ -0,0 +1,65 @@ + + + + + + + + + + + diff --git a/dll/hd3d.cpp b/dll/hd3d.cpp index 398644d..a885eca 100644 --- a/dll/hd3d.cpp +++ b/dll/hd3d.cpp @@ -109,12 +109,14 @@ typedef BOOL (WINAPI *ShowCursor8_Type)(void *, BOOL); typedef BOOL (WINAPI *ShowCursor9_Type)(void *, BOOL); typedef HRESULT (WINAPI *CreateAdditionalSwapChain_Type)(void *, D3DPRESENT_PARAMETERS *, IDirect3DSwapChain9 **); typedef HRESULT (WINAPI *GetSwapChain_Type)(void *, UINT, IDirect3DSwapChain9**); -typedef UINT (WINAPI *GetNumberOfSwapChains_Type)(void *); +typedef UINT (WINAPI *GetNumberOfSwapChains_Type)(void *); typedef HRESULT (WINAPI *BeginStateBlock_Type)(void *); typedef HRESULT (WINAPI *EndStateBlock8_Type)(void *, DWORD *); typedef HRESULT (WINAPI *EndStateBlock9_Type)(void *, IDirect3DStateBlock9**); typedef HRESULT (WINAPI *CreateTexture8_Type)(void *, UINT, UINT, UINT, DWORD, D3DFORMAT, D3DPOOL, void **); typedef HRESULT (WINAPI *CreateTexture9_Type)(void *, UINT, UINT, UINT, DWORD, D3DFORMAT, D3DPOOL, void **, HANDLE *); +typedef HRESULT (WINAPI *CopyRects_Type)(void *, LPDIRECTDRAWSURFACE, CONST RECT *, UINT, LPDIRECTDRAWSURFACE, CONST POINT *); +typedef HRESULT (WINAPI *GetFrontBuffer_Type)(void *, LPDIRECTDRAWSURFACE); UINT WINAPI extGetAvailableTextureMem8(void *); UINT WINAPI extGetAvailableTextureMem9(void *); @@ -138,6 +140,9 @@ HRESULT WINAPI extEndStateBlock8(void *, DWORD *); HRESULT WINAPI extEndStateBlock9(void *, IDirect3DStateBlock9**); HRESULT WINAPI extCreateTexture8(void *, UINT, UINT, UINT, DWORD, D3DFORMAT, D3DPOOL, void **); HRESULT WINAPI extCreateTexture9(void *, UINT, UINT, UINT, DWORD, D3DFORMAT, D3DPOOL, void **, HANDLE *); +// CopyRects prototype uses IDirect3DSurface8 *, but to avoid including d3d8.h better use a generic ptr as LPDIRECTDRAWSURFACE +HRESULT WINAPI extCopyRects(void *, LPDIRECTDRAWSURFACE, CONST RECT *, UINT, LPDIRECTDRAWSURFACE, CONST POINT *); +HRESULT WINAPI extGetFrontBuffer(void *, LPDIRECTDRAWSURFACE); GetAvailableTextureMem_Type pGetAvailableTextureMem8, pGetAvailableTextureMem9; TestCooperativeLevel_Type pTestCooperativeLevel8, pTestCooperativeLevel9; @@ -159,6 +164,8 @@ EndStateBlock8_Type pEndStateBlock8 = 0; EndStateBlock9_Type pEndStateBlock9 = 0; CreateTexture8_Type pCreateTexture8 = 0; CreateTexture9_Type pCreateTexture9 = 0; +CopyRects_Type pCopyRects = 0; +GetFrontBuffer_Type pGetFrontBuffer = 0; // IDirect3DTexture8/9 methods @@ -469,8 +476,9 @@ void HookD3DDevice8(void** ppD3Ddev8) if(dxw.dwFlags5 & TEXTUREMASK){ SetHook((void *)(**(DWORD **)ppD3Ddev8 + 80), extCreateTexture8, (void **)&pCreateTexture8, "CreateTexture(D8)"); } - //SetHook((void *)(**(DWORD **)ppD3Ddev8 + 112), extCopyRects, (void **)&pCopyRects, "CopyRects(D8)"); SetHook((void *)(**(DWORD **)ppD3Ddev8 + 100), extCreateRenderTarget8, (void **)&pCreateRenderTarget8, "CreateRenderTarget(D8)"); + SetHook((void *)(**(DWORD **)ppD3Ddev8 + 112), extCopyRects, (void **)&pCopyRects, "CopyRects(D8)"); + SetHook((void *)(**(DWORD **)ppD3Ddev8 + 120), extGetFrontBuffer, (void **)&pGetFrontBuffer, "GetFrontBuffer(D8)"); SetHook((void *)(**(DWORD **)ppD3Ddev8 + 136), extBeginScene8, (void **)&pBeginScene8, "BeginScene(D8)"); SetHook((void *)(**(DWORD **)ppD3Ddev8 + 140), extEndScene8, (void **)&pEndScene8, "EndScene(D8)"); if((dxw.dwFlags2 & WIREFRAME) || (dxw.dwFlags4 & DISABLEFOGGING) || (dxw.dwFlags4 & ZBUFFERALWAYS)){ @@ -2350,4 +2358,48 @@ UINT WINAPI extGetAdapterModeCount9(void *lpd3d, UINT Adapter, D3DFORMAT Format) } OutTraceD3D("GetAdapterModeCount(9): ret=%d\n", ret); return ret; -} \ No newline at end of file +} + +HRESULT WINAPI extGetFrontBuffer(void *lpd3dd, LPDIRECTDRAWSURFACE pDestSurface) +{ + HRESULT res; + OutTraceD3D("GetFrontBuffer(8): d3d=%x dest=%x\n", lpd3dd, pDestSurface); + res = (*pGetFrontBuffer)(lpd3dd, pDestSurface); + + // v2.04.02: Fix for "Dirt Track Racing 2": GetFrontBuffer in windowed mode through DxWnd intervention may yterminate in error + // since the Front Buffer size is the whole screen and the surface provided by the application only maps the virtual coordinates. + // So, the dxGetFrontBuffer() routine tries to match the surfaces, but in any case, also if an error happens, better return a + // fake D3D_OK condition. + + if(res == D3DERR_INVALIDCALL) { + extern HRESULT dxGetFrontBuffer(void *, LPDIRECTDRAWSURFACE); + res = dxGetFrontBuffer(lpd3dd, pDestSurface); + if(res) OutTraceDW("GetFrontBuffer(8): ret=%x return FAKE D3D_OK\n", res); + res = D3D_OK; + } + + OutTraceD3D("GetFrontBuffer(8): ret=%x\n", res); + return res; +} + +HRESULT WINAPI extCopyRects(void *lpd3dd, LPDIRECTDRAWSURFACE pSourceSurface, CONST RECT *pSourceRectsArray, UINT cRects, LPDIRECTDRAWSURFACE pDestinationSurface, CONST POINT *pDestPointsArray) +{ + HRESULT res; + OutTraceD3D("CopyRects(8): d3d=%x source=%x dest=%x rects=%d\n", lpd3dd, pSourceSurface, pDestinationSurface, cRects); + + // v2.04.02: Fix for "Dirt Track Racing 2": in early D3D8 implementation it seems that invoking this Copyrects method for 0 rects count didn't hurt, + // but now the method returns an error. + // added a patch for handling the "if(cRects==0)" case - it is not worth a flag, it seems good for all circumstances, isn't it? + // Beware: it seems (from some code snippet) that lpDevice->CopyRects(lpSrcSurface, NULL, 0, lpDestSurface, NULL) means copy the whole lpSrcSurface + // to lpDestSurface. In windowized mode the peration may fail because of the different sizing! + + res = (*pCopyRects)(lpd3dd, pSourceSurface, pSourceRectsArray, cRects, pDestinationSurface, pDestPointsArray); + if((res == D3DERR_INVALIDCALL) && (cRects==0)) { + extern HRESULT dxCopyRects(void *, LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE); + res = dxCopyRects(lpd3dd, pSourceSurface, pDestinationSurface); + if(res) OutTraceDW("CopyRects(8): res=%x FAKE D3D_OK on 0 rects\n", res); + res = D3D_OK; + } + OutTraceD3D("CopyRects(8): ret=%x\n", res); + return res; +} diff --git a/dll/hd3d7.cpp b/dll/hd3d7.cpp index 8549c61..c765aa0 100644 --- a/dll/hd3d7.cpp +++ b/dll/hd3d7.cpp @@ -119,6 +119,7 @@ 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); +typedef HRESULT (WINAPI *SetTransform_Type)(void *, D3DTRANSFORMSTATETYPE, LPD3DMATRIX); QueryInterfaceD3_Type pQueryInterfaceD3D = NULL; ReleaseD3D_Type pReleaseD3D1, pReleaseD3D2, pReleaseD3D3, pReleaseD3D7; @@ -150,6 +151,7 @@ SetTexture3_Type pSetTexture3 = NULL; SetTexture7_Type pSetTexture7 = NULL; SwapTextureHandles_Type pSwapTextureHandles = NULL; SwapTextureHandles2_Type pSwapTextureHandles2 = NULL; +SetTransform_Type pSetTransform2, pSetTransform3, pSetTransform7; // IDirect3DViewport-n interfaces @@ -275,6 +277,9 @@ HRESULT WINAPI extSetTexture3(void *, DWORD, LPDIRECT3DTEXTURE2); HRESULT WINAPI extSetTexture7(void *, DWORD, LPDIRECTDRAWSURFACE7); HRESULT WINAPI extSwapTextureHandles(void *, LPDIRECT3DTEXTURE, LPDIRECT3DTEXTURE); HRESULT WINAPI extSwapTextureHandles2(void *, LPDIRECT3DTEXTURE2, LPDIRECT3DTEXTURE2); +HRESULT WINAPI extSetTransform2(void *, D3DTRANSFORMSTATETYPE, LPD3DMATRIX); +HRESULT WINAPI extSetTransform3(void *, D3DTRANSFORMSTATETYPE, LPD3DMATRIX); +HRESULT WINAPI extSetTransform7(void *, D3DTRANSFORMSTATETYPE, LPD3DMATRIX); // Texture @@ -529,6 +534,7 @@ void HookDirect3DDevice(void **lpd3ddev, int d3dversion) SetHook((void *)(**(DWORD **)lpd3ddev + 52), extSetCurrentViewport2, (void **)&pSetCurrentViewport2, "SetCurrentViewport(2)"); SetHook((void *)(**(DWORD **)lpd3ddev + 56), extGetCurrentViewport2, (void **)&pGetCurrentViewport2, "GetCurrentViewport(2)"); SetHook((void *)(**(DWORD **)lpd3ddev + 92), extSetRenderState2, (void **)&pSetRenderState2, "SetRenderState(2)"); + //SetHook((void *)(**(DWORD **)lpd3ddev + 100), extSetTransform2, (void **)&pSetTransform2, "SetTransform(2)"); if(pSetRenderState2){ if(dxw.dwFlags2 & WIREFRAME)(*pSetRenderState2)(*lpd3ddev, D3DRENDERSTATE_FILLMODE, D3DFILL_WIREFRAME); if(dxw.dwFlags4 & DISABLEFOGGING) (*pSetRenderState2)(*lpd3ddev, D3DRENDERSTATE_FOGENABLE, FALSE); @@ -547,6 +553,7 @@ void HookDirect3DDevice(void **lpd3ddev, int d3dversion) SetHook((void *)(**(DWORD **)lpd3ddev + 52), extGetCurrentViewport3, (void **)&pGetCurrentViewport3, "GetCurrentViewport(3)"); SetHook((void *)(**(DWORD **)lpd3ddev + 88), extSetRenderState3, (void **)&pSetRenderState3, "SetRenderState(3)"); SetHook((void *)(**(DWORD **)lpd3ddev + 96), extSetLightState3, (void **)&pSetLightState3, "SetLightState(3)"); + //SetHook((void *)(**(DWORD **)lpd3ddev + 100), extSetTransform3, (void **)&pSetTransform3, "SetTransform(3)"); if (dxw.dwFlags4 & NOTEXTURES) SetHook((void *)(**(DWORD **)lpd3ddev + 152), extSetTexture3, (void **)&pSetTexture3, "SetTexture(D3)"); if(pSetRenderState3){ if(dxw.dwFlags2 & WIREFRAME)(*pSetRenderState3)(*lpd3ddev, D3DRENDERSTATE_FILLMODE, D3DFILL_WIREFRAME); @@ -561,6 +568,7 @@ void HookDirect3DDevice(void **lpd3ddev, int d3dversion) SetHook((void *)(**(DWORD **)lpd3ddev + 16), extEnumTextureFormats7, (void **)&pEnumTextureFormats7, "EnumTextureFormats(7)"); SetHook((void *)(**(DWORD **)lpd3ddev + 20), extBeginScene7, (void **)&pBeginScene7, "BeginScene(7)"); SetHook((void *)(**(DWORD **)lpd3ddev + 24), extEndScene7, (void **)&pEndScene7, "EndScene(7)"); + //SetHook((void *)(**(DWORD **)lpd3ddev + 44), extSetTransform7, (void **)&pSetTransform7, "SetTransform(7)"); //SetHook((void *)(**(DWORD **)lpd3ddev + 52), extSetViewport7, (void **)&pSetViewport7, "SetViewport(7)"); //SetHook((void *)(**(DWORD **)lpd3ddev + 60), extGetViewport7, (void **)&pGetViewport7, "GetViewport(7)"); SetHook((void *)(**(DWORD **)lpd3ddev + 80), extSetRenderState7, (void **)&pSetRenderState7, "SetRenderState(7)"); @@ -1234,19 +1242,11 @@ HRESULT WINAPI extSetRenderState(SetRenderState3_Type pSetRenderState, int versi } HRESULT WINAPI extSetRenderState2(void *d3dd, D3DRENDERSTATETYPE State, DWORD Value) -{ - return extSetRenderState(pSetRenderState2, 2, d3dd, State, Value); -} - +{ return extSetRenderState(pSetRenderState2, 2, d3dd, State, Value); } HRESULT WINAPI extSetRenderState3(void *d3dd, D3DRENDERSTATETYPE State, DWORD Value) -{ - return extSetRenderState(pSetRenderState3, 3, d3dd, State, Value); -} - +{ return extSetRenderState(pSetRenderState3, 3, d3dd, State, Value); } HRESULT WINAPI extSetRenderState7(void *d3dd, D3DRENDERSTATETYPE State, DWORD Value) -{ - return extSetRenderState(pSetRenderState7, 7, d3dd, State, Value); -} +{ return extSetRenderState(pSetRenderState7, 7, d3dd, State, Value); } static HRESULT WINAPI dxwRestoreCallback(LPDIRECTDRAWSURFACE lpDDSurface, LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext) { @@ -1578,11 +1578,11 @@ HRESULT WINAPI extSetViewport2_2(void *lpvp, LPD3DVIEWPORT2 vpd) { HRESULT res; - OutTraceD3D("SetViewport2(VP3): viewport=%x viewportd=%x size=%d pos=(%d,%d) dim=(%dx%d)\n", - lpvp, vpd, vpd->dwSize, vpd->dwX, vpd->dwY, vpd->dwWidth, vpd->dwHeight); + OutTraceD3D("SetViewport2(VP2): viewport=%x viewportd=%x size=%d pos=(%d,%d) dim=(%dx%d) Z=(%f-%f)\n", + lpvp, vpd, vpd->dwSize, vpd->dwX, vpd->dwY, vpd->dwWidth, vpd->dwHeight, vpd->dvMinZ, vpd->dvMaxZ); res=(*pSetViewport2_2)(lpvp, vpd); - if(res) OutTraceE("SetViewport2(VP3) ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); - else OutTraceD3D("SetViewport2(VP3): OK\n"); + if(res) OutTraceE("SetViewport2(VP2) ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + else OutTraceD3D("SetViewport2(VP2): OK\n"); return res; } @@ -1590,10 +1590,10 @@ HRESULT WINAPI extGetViewport2_2(void *lpvp, LPD3DVIEWPORT2 vpd) { HRESULT res; - OutTraceD3D("GetViewport2(VP3): viewport=%x viewportd=%x\n", lpvp, vpd); + OutTraceD3D("GetViewport2(VP2): viewport=%x viewportd=%x\n", lpvp, vpd); res=(*pGetViewport2_2)(lpvp, vpd); - if(res) OutTraceE("GetViewport2(VP3) ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); - else OutTraceD3D("GetViewport2(VP3): OK size=%d pos=(%d,%d) dim=(%dx%d)\n", + if(res) OutTraceE("GetViewport2(VP2) ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + else OutTraceD3D("GetViewport2(VP2): OK size=%d pos=(%d,%d) dim=(%dx%d)\n", vpd->dwSize, vpd->dwX, vpd->dwY, vpd->dwWidth, vpd->dwHeight); return res; } @@ -1602,8 +1602,8 @@ HRESULT WINAPI extSetViewport2_3(void *lpvp, LPD3DVIEWPORT2 vpd) { HRESULT res; - OutTraceD3D("SetViewport2(VP3): viewport=%x viewportd=%x size=%d pos=(%d,%d) dim=(%dx%d)\n", - lpvp, vpd, vpd->dwSize, vpd->dwX, vpd->dwY, vpd->dwWidth, vpd->dwHeight); + OutTraceD3D("SetViewport2(VP3): viewport=%x viewportd=%x size=%d pos=(%d,%d) dim=(%dx%d) Z=(%f-%f)\n", + lpvp, vpd, vpd->dwSize, vpd->dwX, vpd->dwY, vpd->dwWidth, vpd->dwHeight, vpd->dvMinZ, vpd->dvMaxZ); res=(*pSetViewport2_3)(lpvp, vpd); if(res) OutTraceE("SetViewport2(VP3) ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); else OutTraceD3D("SetViewport2(VP3): OK\n"); @@ -2016,7 +2016,7 @@ static HRESULT CALLBACK lpTextureDumper(LPDDPIXELFORMAT lpDDPixFmt, LPVOID lpCon HRESULT WINAPI extEnumTextureFormats(int d3dversion, EnumTextureFormats_Type pEnumTextureFormats, void *lpd3dd, LPD3DENUMPIXELFORMATSCALLBACK lptfcallback, LPVOID arg) { HRESULT res; - OutTrace("EnumTextureFormats(%d): lpd3dd=%x cb=%x arg=%x\n", d3dversion, lpd3dd, lptfcallback, arg); + OutTraceD3D("EnumTextureFormats(%d): lpd3dd=%x cb=%x arg=%x\n", d3dversion, lpd3dd, lptfcallback, arg); if(IsDebug) (*pEnumTextureFormats)(lpd3dd, lpTextureDumper, arg); if(dxw.dwFlags7 & CLEARTEXTUREFOURCC){ @@ -2028,7 +2028,7 @@ HRESULT WINAPI extEnumTextureFormats(int d3dversion, EnumTextureFormats_Type pEn else{ res = (*pEnumTextureFormats)(lpd3dd, lptfcallback, arg); } - if(res) OutTrace("EnumTextureFormats: res=%x(%s)\n", res, ExplainDDError(res)); + if(res) OutTraceD3D("EnumTextureFormats: res=%x(%s)\n", res, ExplainDDError(res)); return res; } @@ -2040,3 +2040,50 @@ HRESULT WINAPI extEnumTextureFormats3(void *lpd3dd, LPD3DENUMPIXELFORMATSCALLBAC { return extEnumTextureFormats(3, pEnumTextureFormats3, lpd3dd, lptfcallback, arg); } HRESULT WINAPI extEnumTextureFormats7(void *lpd3dd, LPD3DENUMPIXELFORMATSCALLBACK lptfcallback, LPVOID arg) { return extEnumTextureFormats(7, pEnumTextureFormats7, lpd3dd, lptfcallback, arg); } + +static char *sTransformType(D3DTRANSFORMSTATETYPE tstype) +{ + char *s; + switch(tstype){ + case D3DTRANSFORMSTATE_WORLD: s = "WORLD"; break; + case D3DTRANSFORMSTATE_VIEW: s = "VIEW"; break; + case D3DTRANSFORMSTATE_PROJECTION: s = "PROJECTION"; break; + case D3DTRANSFORMSTATE_WORLD1: s = "WORLD1"; break; + case D3DTRANSFORMSTATE_WORLD2: s = "WORLD2"; break; + case D3DTRANSFORMSTATE_WORLD3: s = "WORLD3"; break; + case D3DTRANSFORMSTATE_TEXTURE0: s = "TEXTURE0"; break; + case D3DTRANSFORMSTATE_TEXTURE1: s = "TEXTURE1"; break; + case D3DTRANSFORMSTATE_TEXTURE2: s = "TEXTURE2"; break; + case D3DTRANSFORMSTATE_TEXTURE3: s = "TEXTURE3"; break; + case D3DTRANSFORMSTATE_TEXTURE4: s = "TEXTURE4"; break; + case D3DTRANSFORMSTATE_TEXTURE5: s = "TEXTURE5"; break; + case D3DTRANSFORMSTATE_TEXTURE6: s = "TEXTURE6"; break; + case D3DTRANSFORMSTATE_TEXTURE7: s = "TEXTURE7"; break; + default: s = "unknown"; break; + } + return s; +} + +static HRESULT WINAPI SetTransform(int d3dversion, SetTransform_Type pSetTransform, void *lpd3dd, D3DTRANSFORMSTATETYPE tstype, LPD3DMATRIX matrix) +{ + HRESULT res; + + OutTrace("SetTransform(%d): lpd3dd=%x tstype=%x(%s) matrix={\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n}\n", + d3dversion, lpd3dd, tstype, sTransformType(tstype), + matrix->_11, matrix->_12, matrix->_13, matrix->_14, + matrix->_21, matrix->_22, matrix->_23, matrix->_24, + matrix->_31, matrix->_32, matrix->_33, matrix->_34, + matrix->_41, matrix->_42, matrix->_43, matrix->_44); + + res = (*pSetTransform)(lpd3dd, tstype, matrix); + if(res) OutTraceE("SetTransform ERROR: ret=%x\n", res); + return res; +} + +HRESULT WINAPI extSetTransform2(void *lpd3dd, D3DTRANSFORMSTATETYPE tstype, LPD3DMATRIX matrix) +{ return SetTransform(2, pSetTransform2, lpd3dd, tstype, matrix); } +HRESULT WINAPI extSetTransform3(void *lpd3dd, D3DTRANSFORMSTATETYPE tstype, LPD3DMATRIX matrix) +{ return SetTransform(3, pSetTransform3, lpd3dd, tstype, matrix); } +HRESULT WINAPI extSetTransform7(void *lpd3dd, D3DTRANSFORMSTATETYPE tstype, LPD3DMATRIX matrix) +{ return SetTransform(7, pSetTransform7, lpd3dd, tstype, matrix); } + diff --git a/dll/hd3d8.cpp b/dll/hd3d8.cpp index f3c8328..0c5696f 100644 --- a/dll/hd3d8.cpp +++ b/dll/hd3d8.cpp @@ -10,9 +10,17 @@ extern void TextureHandling(LPDIRECTDRAWSURFACE); typedef HRESULT (WINAPI *LockRect_Type)(void *, UINT, D3DLOCKED_RECT *, CONST RECT *, DWORD); typedef HRESULT (WINAPI *UnlockRect_Type)(void *, UINT); +typedef HRESULT (WINAPI *GetFrontBuffer_Type)(void *, LPDIRECTDRAWSURFACE); +typedef HRESULT (WINAPI *GetAdapterDisplayMode_Type)(void *, UINT, D3DDISPLAYMODE *); +typedef HRESULT (WINAPI *CopyRects_Type)(void *, LPDIRECTDRAWSURFACE, CONST RECT *, UINT, LPDIRECTDRAWSURFACE, CONST POINT *); +typedef HRESULT (WINAPI *GetDirect3D8_Type)(void *, void **); extern LockRect_Type pLockRect8; extern UnlockRect_Type pUnlockRect8; +extern GetAdapterDisplayMode_Type pGetAdapterDisplayMode8; +extern CopyRects_Type pCopyRects; +extern GetFrontBuffer_Type pGetFrontBuffer; +extern GetDirect3D8_Type pGetDirect3D8; extern void D3DTextureDump(D3DSURFACE_DESC, D3DLOCKED_RECT); extern void D3DTextureHighlight(D3DSURFACE_DESC, D3DLOCKED_RECT); @@ -69,3 +77,246 @@ void D3D8TextureHandling(void *arg, int Level) } res=(*pUnlockRect8)(lpd3dtex, Level); } + +/* +from http://realmike.org/blog/projects/taking-screenshots-with-direct3d-8/ + +Accessing the Front Buffer + +The IDirect3DDevice8 interface provides the GetFrontBuffer and GetBackBuffer methods to gain access to the swap chain of a Direct3D 8 application. These methods have the +following characteristics: + + GetBackBuffer – By using this method you can obtain an IDirect3DSurface8 interface pointer for each of the buffers in the swap chain. + However, unless you explicitily requested a lockable back buffer when creating the device (by using the D3DPRESENTFLAG_LOCKABLE_BACKBUFFER flag), + you are not allowed to lock the surface. The SDK docs mention a “performance cost” when using lockable back buffers, even if they’re not actually locked. + Our Screenshot function should not require you to rewrite your device creation code, let alone degrade performance, therefore we won’t use the GetBackBuffer method here. + GetFrontBuffer – This method copies the contents of the front buffer to a system-memory surface that is provided by the application. + What makes the GetFrontBuffer method especially useful for our purposes is that it converts the data into a 32-bit ARGB format so that we don’t have to handle + different formats manually. + +Note: When using the GetFrontBuffer method, we’ll always capture the entire screen, which might be undesired in a windowed application. However, the majority of +applications are full-screen. Therefore, we’ll ignore this issue. + +The GetFrontBuffer method requires us to provide a system-memory surface of the same dimensions as the screen. This surface will be filled with a copy of the front buffer’s +contents. So, how do we retrieve the screen dimensions when all we have is a pointer to the IDirect3DDevice8 interface? We can use the GetAdapterDisplayMode method of the +IDirect3D8 interface to query information about the current display mode of a given adapter. A pointer to the IDirect3D8 interface can be obtained by calling the GetDirect3D +method of the IDirect3DDevice8 interface. The adapter identifier that is expected by the GetAdapterDisplayMode method can be obtained by using the +IDirect3DDevice8::GetCreationParameters method. To summarize, these are the required steps to retrieve the screen dimensions: + + Call the IDirect3DDevice8::GetDirect3D method to retrieve a pointer to an IDirect3D8 interface. + Call the IDirect3DDevice8::GetCreationParameters method, which returns the identifier of the adapter that the Direct3D device uses. + Call the IDirect3D8::GetAdapterDisplayMode with the adapter identifier that we retrieved in Step 2. + +The following code snippet performs these three steps: + +D3DDEVICE_CREATION_PARAMETERS dcp; +dcp.AdapterOrdinal = D3DADAPTER_DEFAULT; +lpDevice->GetCreationParameters(&dcp); + +D3DDISPLAYMODE dm; +dm.Width = dm.Height = 0; + +// retrieve pointer to IDirect3D8 interface, +// which provides the GetAdapterDisplayMode method +LPDIRECT3D8 lpD3D = NULL; +lpDevice->GetDirect3D(&lpD3D); +if (lpD3D) +{ + // query the screen dimensions of the current adapter + lpD3D->GetAdapterDisplayMode(dcp.AdapterOrdinal, &dm); + SAFERELEASE(lpD3D); +} + +Now we can pass the values in dm.Width and dm.Height to the IDirect3DDevice8::CreateImageSurface method to create a system-memory surface that can be used by the GetFrontBuffer method. The expected format of the surface is D3DFMT_A8R8G8B8, which means that there are 8 bits each for the blue, green, red, and alpha components of the colors. The following code snippet creates the surface and calls the GetFrontBuffer method to fill the surface: + +LPDIRECT3DSURFACE8 lpSurface = NULL; +lpDevice->CreateImageSurface( + dm.Width, dm.Height, + D3DFMT_A8R8G8B8, + &lpSurface +); + +lpDevice->GetFrontBuffer(lpSurface); +*/ + +HRESULT dxGetFrontBuffer(void *lpd3dd, LPDIRECTDRAWSURFACE xdest) +{ + HRESULT res; + D3DDEVICE_CREATION_PARAMETERS dcp; + LPDIRECT3DSURFACE8 lpSurface = NULL; + IDirect3DDevice8 *lpDevice = (IDirect3DDevice8 *)lpd3dd; + IDirect3DSurface8 *dest = (IDirect3DSurface8 *)xdest; + + dcp.AdapterOrdinal = D3DADAPTER_DEFAULT; + lpDevice->GetCreationParameters(&dcp); + + D3DDISPLAYMODE dm; + dm.Width = dm.Height = 0; + + // retrieve pointer to IDirect3D8 interface, + // which provides the GetAdapterDisplayMode method + LPDIRECT3D8 lpD3D = NULL; + //res = lpDevice->GetDirect3D(&lpD3D); + res = (*pGetDirect3D8)(lpDevice, (void **)&lpD3D); + if(res) { + OutTraceE("GetFrontBuffer: GetDirect3D ERROR res=%x at %d\n", res, __LINE__); + return res; + } + + // query the screen dimensions of the current adapter + //res = lpD3D->GetAdapterDisplayMode(dcp.AdapterOrdinal, &dm); + res = (*pGetAdapterDisplayMode8)(lpD3D, dcp.AdapterOrdinal, &dm); + lpD3D->Release(); + if(res) { + OutTraceE("GetFrontBuffer: GetAdapterDisplayMode ERROR res=%x at %d\n", res, __LINE__); + return res; + } + else { + OutTraceB("GetFrontBuffer: screen size=(%dx%d)\n", dm.Width, dm.Height); + } + + res = lpDevice->CreateImageSurface(dm.Width, dm.Height, D3DFMT_A8R8G8B8, &lpSurface); + if(res) { + OutTraceE("GetFrontBuffer: CreateImageSurface ERROR res=%x at %d\n", res, __LINE__); + return res; + } + + //res = lpDevice->GetFrontBuffer(lpSurface); + res = (*pGetFrontBuffer)(lpDevice, (LPDIRECTDRAWSURFACE)lpSurface); + if(res) { + OutTraceE("GetFrontBuffer: GetFrontBuffer ERROR res=%x at %d\n", res, __LINE__); + lpSurface->Release(); + return res; + } + + RECT p0 = dxw.GetUnmappedScreenRect(); + RECT srcrect = dxw.GetScreenRect(); + OffsetRect(&srcrect, p0.left, p0.top); + OutTraceB("GetFrontBuffer: screen rect=(%d,%d)-(%d,%d)\n", srcrect.left, srcrect.top, srcrect.right, srcrect.bottom); + POINT destpoint = {0, 0}; + //res = lpDevice->CopyRects(lpSurface, (CONST RECT *)&srcrect, 1, dest, (CONST POINT *)&destpoint); + res = (*pCopyRects)(lpDevice, (LPDIRECTDRAWSURFACE)lpSurface, &srcrect, 1, (LPDIRECTDRAWSURFACE)dest, &destpoint); + lpSurface->Release(); + if(res) { + OutTraceE("GetFrontBuffer: CopyRects ERROR res=%x at %d\n", res, __LINE__); + return res; + } + + return DD_OK; +} + +HRESULT dxCopyRects(void *lpd3dd, LPDIRECTDRAWSURFACE psrc, LPDIRECTDRAWSURFACE pdst) +{ + HRESULT res; + IDirect3DSurface8 *lpsrc = (IDirect3DSurface8 *)psrc; + IDirect3DSurface8 *lpdst = (IDirect3DSurface8 *)pdst; + IDirect3DDevice8 *lpDevice = (IDirect3DDevice8 *)lpd3dd; + LPDIRECT3DSURFACE8 lpImageSrc = NULL; + LPDIRECT3DSURFACE8 lpImageDst = NULL; + D3DSURFACE_DESC SrcDesc, DstDesc; + D3DLOCKED_RECT SrcLockedRect, DstLockedRect; + + // first, build source image + if(res = lpsrc->GetDesc(&SrcDesc)){ + OutTraceE("dxCopyRects: GetDesc ERROR res=%x at %d\n", res, __LINE__); + return res; + } + else{ + OutTraceB("dxCopyRects: source size=(%dx%d) format=%d\n", SrcDesc.Width, SrcDesc.Height, SrcDesc.Format); + } + + if(res = lpDevice->CreateImageSurface(SrcDesc.Width, SrcDesc.Height, SrcDesc.Format, &lpImageSrc)){ + OutTraceE("dxCopyRects: CreateImageSurface ERROR res=%x at %d\n", res, __LINE__); + return res; + } + + // get source image + if(res = (*pCopyRects)(lpDevice, (LPDIRECTDRAWSURFACE)psrc, NULL, 0, (LPDIRECTDRAWSURFACE)lpImageSrc, NULL)){ + OutTraceE("dxCopyRects: CopyRects ERROR res=%x at %d\n", res, __LINE__); + return res; + } + + // build a target image similar to destination + if(res = lpdst->GetDesc(&DstDesc)){ + OutTraceE("dxCopyRects: GetDesc ERROR res=%x at %d\n", res, __LINE__); + return res; + } + else{ + OutTraceB("dxCopyRects: dest size=(%dx%d) format=%d\n", DstDesc.Width, DstDesc.Height, DstDesc.Format); + } + + if(res = lpDevice->CreateImageSurface(DstDesc.Width, DstDesc.Height, DstDesc.Format, &lpImageDst)){ + OutTraceE("dxCopyRects: GetDesc ERROR res=%x at %d\n", res, __LINE__); + return res; + } + + // make the conversion here .... + if (res=lpImageSrc->LockRect(&SrcLockedRect, NULL, D3DLOCK_READONLY)){ + OutTraceE("dxCopyRects: LockRect ERROR res=%x at %d\n", res, __LINE__); + return res; + } + if(res = lpImageDst->LockRect(&DstLockedRect, NULL, 0)){ + OutTraceE("dxCopyRects: LockRect ERROR res=%x at %d\n", res, __LINE__); + return res; + } + + // pixel conversion here + switch(SrcDesc.Format){ + case D3DFMT_A8R8G8B8: + case D3DFMT_X8R8G8B8: + switch(DstDesc.Format){ + case D3DFMT_R5G6B5: + { + OutTraceB("dxCopyRects: converting 32 to 16 BPP\n", res, __LINE__); + DWORD *srcpix; + WORD *dstpix; + for(unsigned int y=0; yUnlockRect(); + lpImageDst->UnlockRect(); + + // copy to target surface + if(res = (*pCopyRects)(lpDevice, (LPDIRECTDRAWSURFACE)lpImageDst, NULL, 0, (LPDIRECTDRAWSURFACE)lpdst, NULL)){ + OutTraceE("dxCopyRects: CopyRects ERROR res=%x at %d\n", res, __LINE__); + return res; + } + + // clean up + lpImageSrc->Release(); + lpImageDst->Release(); + return res; +} + + diff --git a/dll/user32.cpp b/dll/user32.cpp index b02f683..ec523f0 100644 --- a/dll/user32.cpp +++ b/dll/user32.cpp @@ -20,6 +20,8 @@ #define _Warn(s) MessageBox(0, s, "to do", MB_ICONEXCLAMATION) BOOL IsChangeDisplaySettingsHotPatched = FALSE; +BOOL InMainWinCreation = FALSE; + extern BOOL bFlippedDC; extern HDC hFlippedDC; @@ -38,9 +40,6 @@ SetWindowsHookEx_Type pSetWindowsHookExA = NULL; SetWindowsHookEx_Type pSetWindowsHookExW = NULL; HHOOK WINAPI extSetWindowsHookExA(int, HOOKPROC, HINSTANCE, DWORD); HHOOK WINAPI extSetWindowsHookExW(int, HOOKPROC, HINSTANCE, DWORD); -typedef BOOL (WINAPI *PostMessageA_Type)(HWND, UINT, WPARAM, LPARAM); -PostMessageA_Type pPostMessageA = NULL; -BOOL WINAPI extPostMessageA(HWND, UINT, WPARAM, LPARAM); typedef HRESULT (WINAPI *MessageBoxTimeoutA_Type)(HWND, LPCSTR, LPCSTR, UINT, WORD, DWORD); MessageBoxTimeoutA_Type pMessageBoxTimeoutA = NULL; HRESULT WINAPI extMessageBoxTimeoutA(HWND, LPCSTR, LPCSTR, UINT, WORD, DWORD); @@ -144,7 +143,14 @@ typedef BOOL (WINAPI *EnumWindows_Type)(WNDENUMPROC, LPARAM); EnumWindows_Type pEnumWindows; BOOL WINAPI extEnumWindows(WNDENUMPROC, LPARAM); - +typedef BOOL (WINAPI *GetMessage_Type)(LPMSG, HWND, UINT, UINT); +GetMessage_Type pGetMessageA, pGetMessageW; +BOOL WINAPI extGetMessageA(LPMSG, HWND, UINT, UINT); +BOOL WINAPI extGetMessageW(LPMSG, HWND, UINT, UINT); +typedef BOOL (WINAPI *PostMessage_Type)(HWND, UINT, WPARAM, LPARAM); +PostMessage_Type pPostMessageA, pPostMessageW; +BOOL WINAPI extPostMessageA(HWND, UINT, WPARAM, LPARAM); +BOOL WINAPI extPostMessageW(HWND, UINT, WPARAM, LPARAM); #ifdef TRACEPALETTE typedef UINT (WINAPI *GetDIBColorTable_Type)(HDC, UINT, UINT, RGBQUAD *); @@ -304,12 +310,6 @@ static HookEntryEx_Type ScaledHooks[]={ {HOOK_IAT_CANDIDATE, 0, 0, NULL, 0, 0} // terminator }; -static HookEntryEx_Type PeekAllHooks[]={ - {HOOK_IAT_CANDIDATE, 0, "PeekMessageA", (FARPROC)PeekMessageA, (FARPROC *)&pPeekMessageA, (FARPROC)extPeekMessageA}, - {HOOK_IAT_CANDIDATE, 0, "PeekMessageW", (FARPROC)PeekMessageW, (FARPROC *)&pPeekMessageW, (FARPROC)extPeekMessageW}, - {HOOK_IAT_CANDIDATE, 0, 0, NULL, 0, 0} // terminator -}; - static HookEntryEx_Type MouseHooks[]={ {HOOK_HOT_CANDIDATE, 0, "GetCursorPos", (FARPROC)GetCursorPos, (FARPROC *)&pGetCursorPos, (FARPROC)extGetCursorPos}, {HOOK_HOT_CANDIDATE, 0, "SetCursorPos", (FARPROC)SetCursorPos, (FARPROC *)&pSetCursorPos, (FARPROC)extSetCursorPos}, @@ -346,6 +346,16 @@ static HookEntryEx_Type DesktopHooks[]={ // currently unused, needed for X-Files {HOOK_IAT_CANDIDATE, 0, 0, NULL, 0, 0} // terminator }; +static HookEntryEx_Type MsgLoopHooks[]={ + {HOOK_IAT_CANDIDATE, 0, "PeekMessageA", (FARPROC)PeekMessageA, (FARPROC *)&pPeekMessageA, (FARPROC)extPeekMessageA}, + {HOOK_IAT_CANDIDATE, 0, "PeekMessageW", (FARPROC)PeekMessageW, (FARPROC *)&pPeekMessageW, (FARPROC)extPeekMessageW}, + {HOOK_IAT_CANDIDATE, 0, "GetMessageA", (FARPROC)GetMessageA, (FARPROC *)&pGetMessageA, (FARPROC)extGetMessageA}, + {HOOK_IAT_CANDIDATE, 0, "GetMessageW", (FARPROC)GetMessageW, (FARPROC *)&pGetMessageW, (FARPROC)extGetMessageW}, + {HOOK_IAT_CANDIDATE, 0, "PostMessageA", (FARPROC)PostMessageA, (FARPROC *)&pPostMessageA, (FARPROC)extPostMessageA}, + {HOOK_IAT_CANDIDATE, 0, "PostMessageW", (FARPROC)PostMessageW, (FARPROC *)&pPostMessageW, (FARPROC)extPostMessageW}, + {HOOK_IAT_CANDIDATE, 0, 0, NULL, 0, 0} // terminator +}; + static char *libname = "user32.dll"; void HookUser32(HMODULE hModule) @@ -353,12 +363,12 @@ void HookUser32(HMODULE hModule) HookLibraryEx(hModule, Hooks, libname); HookLibraryEx(hModule, WinHooks, libname); + HookLibraryEx(hModule, MsgLoopHooks, libname); if (dxw.GDIEmulationMode != GDIMODE_NONE) HookLibraryEx(hModule, SyscallHooks, libname); if (dxw.dwFlags2 & GDISTRETCHED) HookLibraryEx(hModule, ScaledHooks, libname); if (dxw.dwFlags1 & CLIENTREMAPPING) HookLibraryEx(hModule, RemapHooks, libname); if ((dxw.dwFlags1 & (MODIFYMOUSE|SLOWDOWN|KEEPCURSORWITHIN)) || (dxw.dwFlags2 & KEEPCURSORFIXED)) HookLibraryEx(hModule, MouseHooks, libname); - if (dxw.dwFlags3 & PEEKALLMESSAGES) HookLibraryEx(hModule, PeekAllHooks, libname); if (dxw.dwFlags2 & TIMESTRETCH) HookLibraryEx(hModule, TimeHooks, libname); IsChangeDisplaySettingsHotPatched = IsHotPatchedEx(Hooks, "ChangeDisplaySettingsExA") || IsHotPatchedEx(Hooks, "ChangeDisplaySettingsExW"); @@ -380,6 +390,7 @@ FARPROC Remap_user32_ProcAddress(LPCSTR proc, HMODULE hModule) FARPROC addr; if (addr=RemapLibraryEx(proc, hModule, Hooks)) return addr; if (addr=RemapLibraryEx(proc, hModule, WinHooks)) return addr; + if (addr=RemapLibraryEx(proc, hModule, MsgLoopHooks)) return addr; if (dxw.dwFlags1 & CLIENTREMAPPING) if (addr=RemapLibraryEx(proc, hModule, RemapHooks)) return addr; @@ -389,8 +400,6 @@ FARPROC Remap_user32_ProcAddress(LPCSTR proc, HMODULE hModule) if (addr=RemapLibraryEx(proc, hModule, ScaledHooks)) return addr; if ((dxw.dwFlags1 & (MODIFYMOUSE|SLOWDOWN|KEEPCURSORWITHIN)) || (dxw.dwFlags2 & KEEPCURSORFIXED)) if (addr=RemapLibraryEx(proc, hModule, MouseHooks)) return addr; - if (dxw.dwFlags3 & PEEKALLMESSAGES) - if (addr=RemapLibraryEx(proc, hModule, PeekAllHooks)) return addr; if((dxw.dwFlags2 & TIMESTRETCH) && (dxw.dwFlags4 & STRETCHTIMERS)) if (addr=RemapLibraryEx(proc, hModule, TimeHooks)) return addr; @@ -998,7 +1007,7 @@ BOOL WINAPI extSetWindowPos(HWND hwnd, HWND hWndInsertAfter, int X, int Y, int c } // in fullscreen, but a child window inside ..... - if (!dxw.IsDesktop(hwnd)){ + if (!dxw.IsDesktop(hwnd) && !InMainWinCreation){ RECT r; r.left = X; r.right = X + cx; @@ -1230,36 +1239,41 @@ static BOOL WINAPI extPeekMessage(PeekMessage_Type pPeekMessage, LPMSG lpMsg, HW BOOL res; if(dxw.dwFlags3 & PEEKALLMESSAGES){ - if((wMsgFilterMin==0) && (wMsgFilterMax == 0)){ - // no filtering, everything is good - res=(*pPeekMessage)(lpMsg, hwnd, wMsgFilterMin, wMsgFilterMax, (wRemoveMsg & 0x000F)); - } - else { - MSG Dummy; - // better eliminate all messages before and after the selected range !!!! - //if(wMsgFilterMin)(*pPeekMessage)(&Dummy, hwnd, 0, wMsgFilterMin-1, TRUE); - if(wMsgFilterMin>0x0F)(*pPeekMessage)(&Dummy, hwnd, 0x0F, wMsgFilterMin-1, TRUE); - res=(*pPeekMessage)(lpMsg, hwnd, wMsgFilterMin, wMsgFilterMax, (wRemoveMsg & 0x000F)); - if(wMsgFilterMax0x0F)(*pPeekMessage)(&Dummy, hwnd, 0x0F, wMsgFilterMin-1, TRUE); + res=(*pPeekMessage)(lpMsg, hwnd, wMsgFilterMin, wMsgFilterMax, (wRemoveMsg & 0x000F)); + if(wMsgFilterMaxhwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg, ExplainPeekRemoveMsg(wRemoveMsg), - lpMsg->message, ExplainWinMessage(lpMsg->message & 0xFFFF), - lpMsg->wParam, lpMsg->lParam, lpMsg->pt.x, lpMsg->pt.y, res); - else - OutTraceW("PeekMessage: ANY lpmsg=%x hwnd=%x filter=(%x-%x) remove=%x(%s) res=%x\n", - lpMsg, lpMsg->hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg, ExplainPeekRemoveMsg(wRemoveMsg), res); + if(res) + OutTraceW("PeekMessage: ANY lpmsg=%x hwnd=%x filter=(%x-%x) remove=%x(%s) msg=%x(%s) wparam=%x, lparam=%x pt=(%d,%d) res=%x\n", + lpMsg, lpMsg->hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg, ExplainPeekRemoveMsg(wRemoveMsg), + lpMsg->message, ExplainWinMessage(lpMsg->message & 0xFFFF), + lpMsg->wParam, lpMsg->lParam, lpMsg->pt.x, lpMsg->pt.y, res); + else + OutTraceW("PeekMessage: ANY lpmsg=%x hwnd=%x filter=(%x-%x) remove=%x(%s) res=%x\n", + lpMsg, lpMsg->hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg, ExplainPeekRemoveMsg(wRemoveMsg), res); } else { res=(*pPeekMessage)(lpMsg, hwnd, wMsgFilterMin, wMsgFilterMax, (wRemoveMsg & 0x000F)); - OutTrace("PeekMessage: lpmsg=%x hwnd=%x filter=(%x-%x) remove=%x(%s) msg=%x(%s) wparam=%x, lparam=%x pt=(%d,%d) res=%x\n", + OutTraceW("PeekMessage: lpmsg=%x hwnd=%x filter=(%x-%x) remove=%x(%s) msg=%x(%s) wparam=%x, lparam=%x pt=(%d,%d) res=%x\n", lpMsg, lpMsg->hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg, ExplainPeekRemoveMsg(wRemoveMsg), lpMsg->message, ExplainWinMessage(lpMsg->message & 0xFFFF), lpMsg->wParam, lpMsg->lParam, lpMsg->pt.x, lpMsg->pt.y, res); } + if(dxw.dwFlags1 & MODIFYMOUSE){ + extGetCursorPos(&(lpMsg->pt)); + } + + if(dxw.dwFlags1 & SLOWDOWN) (*pSleep)(1); return res; } @@ -1269,6 +1283,42 @@ BOOL WINAPI extPeekMessageA(LPMSG lpMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMs BOOL WINAPI extPeekMessageW(LPMSG lpMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg) { return extPeekMessage(pPeekMessageW, lpMsg, hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg); } +static BOOL WINAPI extGetMessage(GetMessage_Type pGetMessage, LPMSG lpMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax) +{ + BOOL res; + + res=(*pGetMessage)(lpMsg, hwnd, wMsgFilterMin, wMsgFilterMax); + OutTraceW("GetMessage: lpmsg=%x hwnd=%x filter=(%x-%x) msg=%x(%s) wparam=%x, lparam=%x pt=(%d,%d) res=%x\n", + lpMsg, lpMsg->hwnd, wMsgFilterMin, wMsgFilterMax, + lpMsg->message, ExplainWinMessage(lpMsg->message & 0xFFFF), + lpMsg->wParam, lpMsg->lParam, lpMsg->pt.x, lpMsg->pt.y, res); + + if(dxw.dwFlags1 & MODIFYMOUSE){ + extGetCursorPos(&(lpMsg->pt)); + } + + return res; +} + +BOOL WINAPI extGetMessageA(LPMSG lpMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax) +{ return extGetMessage(pGetMessageA, lpMsg, hwnd, wMsgFilterMin, wMsgFilterMax); } +BOOL WINAPI extGetMessageW(LPMSG lpMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax) +{ return extGetMessage(pGetMessageW, lpMsg, hwnd, wMsgFilterMin, wMsgFilterMax); } + +BOOL WINAPI extPostMessage(PostMessage_Type pPostMessage, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + BOOL res; + res = (*pPostMessage)(hWnd, Msg, wParam, lParam); + OutTraceW("PostMessage: hwnd=%x msg=%x(%s) wparam=%x, lparam=%x res=%x\n", + hWnd, Msg, ExplainWinMessage(Msg), wParam, lParam, res); + return res; +} + +BOOL WINAPI extPostMessageA(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ return extPostMessage(pPostMessageA, hwnd, Msg, wParam, lParam); } +BOOL WINAPI extPostMessageW(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ return extPostMessage(pPostMessageW, hwnd, Msg, wParam, lParam); } + BOOL WINAPI extClientToScreen(HWND hwnd, LPPOINT lppoint) { // v2.02.10: fully revised to handle scaled windows @@ -1716,8 +1766,8 @@ static HWND WINAPI CreateWindowCommon( x=dxw.iPosX; y=dxw.iPosY; } - nWidth=dxw.GetScreenWidth(); - nHeight=dxw.GetScreenHeight(); + nWidth=dxw.iSizX; + nHeight=dxw.iSizY; OutTraceDW("%s: fixed client pos=(%d,%d) size=(%d,%d) valid=%x\n", ApiName, x, y, nWidth, nHeight, isValidHandle); dxw.SetFullScreen(TRUE); @@ -1758,10 +1808,15 @@ static HWND WINAPI CreateWindowCommon( OutTraceB("%s: fixed pos=(%d,%d) size=(%d,%d) Style=%x(%s) ExStyle=%x(%s)\n", ApiName, x, y, nWidth, nHeight, dwStyle, ExplainStyle(dwStyle), dwExStyle, ExplainExStyle(dwExStyle)); + // v2.04.02: InMainWinCreation semaphore, signals to the CreateWin callback that the window to be created will be a main window, + // so rules about LOCKWINPOS etc. must be applied. Fixes "Civil War 2 Generals" main window displacement. + InMainWinCreation = TRUE; if(WideChar) hwnd= (*pCreateWindowExW)(dwExStyle, (LPCWSTR)lpClassName, (LPCWSTR)lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam); else hwnd= (*pCreateWindowExA)(dwExStyle, (LPCSTR)lpClassName, (LPCSTR)lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam); + InMainWinCreation = FALSE; + if (hwnd==(HWND)NULL){ OutTraceE("%s: ERROR err=%d Style=%x(%s) ExStyle=%x\n", ApiName, GetLastError(), dwStyle, ExplainStyle(dwStyle), dwExStyle); diff --git a/host/ShimsDialog.cpp b/host/ShimsDialog.cpp index bd65761..02219b1 100644 --- a/host/ShimsDialog.cpp +++ b/host/ShimsDialog.cpp @@ -381,6 +381,12 @@ char * MatchExe(char *FileName) pSdbGetMatchingExe = (PSdbGetMatchingExe) GetProcAddress(hAppHelp, "SdbGetMatchingExe"); pSdbReleaseMatchingExe = (PSdbReleaseMatchingExe) GetProcAddress(hAppHelp, "SdbReleaseMatchingExe"); + if(pSdbGetMatchingExe == NULL){ + // rough protection: we assume that if this is found, then all fpointers are there. + sprintf(sBuf, "Unsupported Shim DB\n", FileName); + return sBuf; + } + BOOL bRet = pSdbGetMatchingExe(NULL, (LPCWSTR)szFileName, NULL, NULL, 0, &result); if (bRet){ sprintf(sBuf, "Shim found for file: %s\n", FileName); diff --git a/host/dxwndhost.aps b/host/dxwndhost.aps deleted file mode 100644 index fbe0d1f..0000000 Binary files a/host/dxwndhost.aps and /dev/null differ diff --git a/host/dxwndhost.rc b/host/dxwndhost.rc index 429888a..d1fc472 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 0cd8462..65deb6e 100644 Binary files a/host/dxwndhost.vs2008.suo and b/host/dxwndhost.vs2008.suo differ diff --git a/host/dxwndhost.vs2008.vcproj.DESKTOP-Q3RE27J.user.user b/host/dxwndhost.vs2008.vcproj.DESKTOP-Q3RE27J.user.user new file mode 100644 index 0000000..723bba8 --- /dev/null +++ b/host/dxwndhost.vs2008.vcproj.DESKTOP-Q3RE27J.user.user @@ -0,0 +1,65 @@ + + + + + + + + + + + diff --git a/host/dxwndhostView.cpp b/host/dxwndhostView.cpp index cef0d35..76901bf 100644 --- a/host/dxwndhostView.cpp +++ b/host/dxwndhostView.cpp @@ -2925,7 +2925,7 @@ void InjectSuspended(char *exepath, char *dirpath) FILE *fExe = NULL; BOOL bKillProcess = FALSE; - OutTrace("InjectSuspended: exe=%s dir=%s\n",exepath, dirpath); + OutTrace("InjectSuspended: exe=\"%s\" dir=\"%s\"\n",exepath, dirpath); ZeroMemory(&sinfo, sizeof(sinfo)); sinfo.cb = sizeof(sinfo); // attempt to load the specified target diff --git a/host/resource b/host/resource index be9e9cb..94ed69c 100644 Binary files a/host/resource and b/host/resource differ