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