diff --git a/Include/dxwnd.h b/Include/dxwnd.h
index f459b5b..0c33993 100644
--- a/Include/dxwnd.h
+++ b/Include/dxwnd.h
@@ -176,6 +176,8 @@
#define TEXTUREFORMAT 0x08000000 // Apply virtual pixel format to texture surfaces without DDSD_PIXELFORMAT attribute
#define GSKYHACK 0x10000000 // use VIDEOMEMORY+LOCALVIDMEM capability to turn hw acceleration on ...
#define LOCKRESERVEDPALETTE 0x20000000 // lock the reserved palette entries (usually 20: 0-9 and 246-255)
+#define UNLOCKZORDER 0x40000000 // Inhibit attempts to keep the main win on top of ZORDER by stripping BringWindowToTop and SetForegroundWindow calls
+#define EASPORTSHACK 0X80000000 // Hack to intercept and neutralize some of the hooks set internally by EA Sports games
// logging Tflags DWORD:
#define OUTTRACE 0x00000001 // enables tracing to dxwnd.log in general
diff --git a/build/dxwnd.dll b/build/dxwnd.dll
index 5192913..23dac4c 100644
--- a/build/dxwnd.dll
+++ b/build/dxwnd.dll
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:e6237930755cc2d17f723f7d6948732a5e75da7fd5dc9b2a8f0f6572774d38f7
-size 574464
+oid sha256:f437c5d0f51575ce6fd0d3ffcc160d7c5f84f86db47b3af6847427a28466cde4
+size 577024
diff --git a/build/dxwnd.exe b/build/dxwnd.exe
index 7201265..e67795d 100644
--- a/build/dxwnd.exe
+++ b/build/dxwnd.exe
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:6434855ecb64769aed7706cd7fef0bcab197a29b76710278cfe164933632ffaf
+oid sha256:4637fee61c70d8ffa927a88878191e4174bac16129dd30242892a5ad07dcbc6b
size 538624
diff --git a/build/exports/Darkened Skye.dxw b/build/exports/Darkened Skye.dxw
index ac9f547..a67b3be 100644
--- a/build/exports/Darkened Skye.dxw
+++ b/build/exports/Darkened Skye.dxw
@@ -5,7 +5,7 @@ module0=
opengllib0=
ver0=0
coord0=0
-flag0=679493664
+flag0=679493666
flagg0=1207959552
flagh0=65556
flagi0=69206020
@@ -25,3 +25,5 @@ initts0=0
winver0=0
maxres0=-1
launchpath0=
+notes0=
+flagj0=128
diff --git a/build/exports/dxwnd.ini b/build/exports/dxwnd.ini
new file mode 100644
index 0000000..1036463
--- /dev/null
+++ b/build/exports/dxwnd.ini
@@ -0,0 +1,5 @@
+[window]
+posx=1439
+posy=619
+sizx=320
+sizy=200
diff --git a/build/readme-relnotes.txt b/build/readme-relnotes.txt
index a7439c7..013e4df 100644
--- a/build/readme-relnotes.txt
+++ b/build/readme-relnotes.txt
@@ -771,3 +771,9 @@ fix: d3d Present method, to properly scale to window size (fixes "Silent Hunter
fix: GetMonitorInfo hooker: in windowed mode the call may fail, a virtual size and ok retcode should be returned
fix: Blt method recovering errors when D3D CreateAdditionalSwapChain method fails: allow to see the intro movies of "Silent Hunter III".
fix: added some missing D3D errorcode labels in log file
+
+v2.03.16
+fix: MapWindowPoints hook - added coordinate scaling (fixes "NBA Live 99" components size and position)
+fix: using "Suppress D3D8/9 reset" sets the backbuffer area as large as the whole desktop to avoid clipping
+add: added "Unlock Z-order" flag to avoid window to stay locked on top of z-order (useful for "NBA Live 99")
+add: added "EA Sprots hack" flag to suppress some interfering hooks set by EA games internally (useful for "NBA Live 99")
\ No newline at end of file
diff --git a/dll/ddblit.cpp b/dll/ddblit.cpp
index c81d9b2..dd776c8 100644
--- a/dll/ddblit.cpp
+++ b/dll/ddblit.cpp
@@ -187,10 +187,11 @@ static HRESULT sBltToPrimary(char *api, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdest
// to do: handle possible situations with surface 2 / 4 / 7 types
DDSURFACEDESC ddsd;
LPDIRECTDRAWSURFACE lpddsTmp;
+ extern GetSurfaceDesc_Type pGetSurfaceDesc1;
if (IsDebug) BlitTrace("KEYSRC", lpsrcrect, &destrect, __LINE__);
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
- lpddssrc->GetSurfaceDesc(&ddsd);
+ (*pGetSurfaceDesc1)(lpddssrc, &ddsd);
res=(*pCreateSurface1)(lpPrimaryDD, &ddsd, &lpddsTmp, NULL);
if(res) OutTraceE("CreateSurface: ERROR %x(%s) at %d", res, ExplainDDError(res), __LINE__);
// copy background
diff --git a/dll/ddraw.cpp b/dll/ddraw.cpp
index 45813c3..e9a04b9 100644
--- a/dll/ddraw.cpp
+++ b/dll/ddraw.cpp
@@ -3930,7 +3930,7 @@ typedef struct {
int h;
} SupportedRes_Type;
-static SupportedRes_Type SupportedSVGARes[10]= {
+static SupportedRes_Type SupportedSVGARes[11]= {
{320,200},
{320,240},
{512,384}, // needed by "Outcast" loading screen
@@ -3940,6 +3940,7 @@ static SupportedRes_Type SupportedSVGARes[10]= {
{800,600},
{1024,768}, // XGA
{1280,800}, // WXGA
+ {1600,1200}, // UXGA, needed by "LEGO Star Wars" in high res mode
{0,0}
};
diff --git a/dll/dxhook.cpp b/dll/dxhook.cpp
index 3a0c873..aa95c59 100644
--- a/dll/dxhook.cpp
+++ b/dll/dxhook.cpp
@@ -98,8 +98,8 @@ static char *Flag5Names[32]={
"REMAPMCI", "TEXTUREHIGHLIGHT", "TEXTUREDUMP", "TEXTUREHACK",
"TEXTURETRANSP", "NORMALIZEPERFCOUNT", "HYBRIDMODE", "GDICOLORCONV",
"INJECTSON", "ENABLESONHOOK", "FREEZEINJECTEDSON", "GDIMODE",
- "CENTERTOWIN", "MESSAGEPUMP", "TEXTUREFORMAT", "GSKYHACK",
- "LOCKRESERVEDPALETTE", "", "", "",
+ "CENTERTOWIN", "STRESSRESOURCES", "MESSAGEPUMP", "TEXTUREFORMAT",
+ "GSKYHACK", "LOCKRESERVEDPALETTE", "UNLOCKZORDER", "EASPORTSHACK",
};
static char *TFlagNames[32]={
@@ -1846,7 +1846,9 @@ void HookInit(TARGETMAP *target, HWND hwnd)
if (dxw.dwFlags1 & MESSAGEPROC){
extern HINSTANCE hInst;
- hMouseHook=SetWindowsHookEx(WH_GETMESSAGE, MessageHook, hInst, GetCurrentThreadId());
+ typedef HHOOK (WINAPI *SetWindowsHookEx_Type)(int, HOOKPROC, HINSTANCE, DWORD);
+ extern SetWindowsHookEx_Type pSetWindowsHookEx;
+ hMouseHook=(*pSetWindowsHookEx)(WH_GETMESSAGE, MessageHook, hInst, GetCurrentThreadId());
if(hMouseHook==NULL) OutTraceE("SetWindowsHookEx WH_GETMESSAGE failed: error=%d\n", GetLastError());
}
diff --git a/dll/dxwcore.cpp b/dll/dxwcore.cpp
index 9a66df4..29c7a1e 100644
--- a/dll/dxwcore.cpp
+++ b/dll/dxwcore.cpp
@@ -872,6 +872,17 @@ void dxwCore::UnmapWindow(LPRECT rect)
rect->bottom= ((rect->bottom - upleft.y) * (int)dwScreenHeight) / client.bottom;
}
+void dxwCore::UnmapWindow(LPPOINT point)
+{
+ RECT client;
+ POINT upleft = {0,0};
+ if(!(*pGetClientRect)(hWnd, &client)) return;
+ (*pClientToScreen)(hWnd, &upleft);
+ if((client.right == 0) || (client.bottom == 0)) return;
+ point->x= ((point->x - upleft.x) * (int)dwScreenWidth) / client.right;
+ point->y= ((point->y - upleft.y) * (int)dwScreenHeight) / client.bottom;
+}
+
POINT dxwCore::ClientOffset(HWND hwnd)
{
RECT desktop;
diff --git a/dll/dxwcore.hpp b/dll/dxwcore.hpp
index aa357a3..31ec851 100644
--- a/dll/dxwcore.hpp
+++ b/dll/dxwcore.hpp
@@ -64,6 +64,7 @@ public: // methods
void MapWindow(LPRECT);
void MapWindow(int *, int *, int *, int *);
void UnmapWindow(LPRECT);
+ void UnmapWindow(LPPOINT);
void FixWorkarea(LPRECT);
RECT GetScreenRect(void);
RECT GetUnmappedScreenRect();
diff --git a/dll/dxwnd.cpp b/dll/dxwnd.cpp
index fc3497e..de6e7ab 100644
--- a/dll/dxwnd.cpp
+++ b/dll/dxwnd.cpp
@@ -27,7 +27,7 @@ along with this program. If not, see .
#include "TlHelp32.h"
-#define VERSION "2.03.15"
+#define VERSION "2.03.16"
#define DDTHREADLOCK 1
//#define LOCKTHREADS
diff --git a/dll/dxwnd.vs2008.suo b/dll/dxwnd.vs2008.suo
index 01d1f72..cf841b6 100644
Binary files a/dll/dxwnd.vs2008.suo and b/dll/dxwnd.vs2008.suo differ
diff --git a/dll/hd3d.cpp b/dll/hd3d.cpp
index df658f2..24d2757 100644
--- a/dll/hd3d.cpp
+++ b/dll/hd3d.cpp
@@ -683,6 +683,20 @@ HRESULT WINAPI extGetAdapterIdentifier9(void *pd3dd, UINT Adapter, DWORD Flags,
return res;
}
+static char *ExplainSwapEffect(DWORD f)
+{
+ char *s;
+ switch(f){
+ case D3DSWAPEFFECT_DISCARD: s="DISCARD"; break;
+ case D3DSWAPEFFECT_FLIP: s="FLIP"; break;
+ case D3DSWAPEFFECT_COPY: s="COPY"; break;
+ case D3DSWAPEFFECT_OVERLAY: s="OVERLAY"; break;
+ case D3DSWAPEFFECT_FLIPEX: s="FLIPEX"; break;
+ default: s="unknown"; break;
+ }
+ return s;
+}
+
HRESULT WINAPI extReset(void *pd3dd, D3DPRESENT_PARAMETERS* pPresParam)
{
HRESULT res;
@@ -692,9 +706,11 @@ HRESULT WINAPI extReset(void *pd3dd, D3DPRESENT_PARAMETERS* pPresParam)
void *pD3D;
memcpy(param, pPresParam, (dwD3DVersion == 9)?56:52);
+ dxw.SetScreenSize(param[0], param[1]);
if(IsTraceD3D){
tmp = param;
+ DWORD SwapEffect;
OutTrace("D3D%d::Reset\n", dwD3DVersion);
OutTrace(" BackBufferWidth = %i\n", *(tmp ++));
OutTrace(" BackBufferHeight = %i\n", *(tmp ++));
@@ -702,7 +718,8 @@ HRESULT WINAPI extReset(void *pd3dd, D3DPRESENT_PARAMETERS* pPresParam)
OutTrace(" BackBufferCount = %i\n", *(tmp ++));
OutTrace(" MultiSampleType = %i\n", *(tmp ++));
if(dwD3DVersion == 9) OutTrace(" MultiSampleQuality = %i\n", *(tmp ++));
- OutTrace(" SwapEffect = 0x%x\n", *(tmp ++));
+ SwapEffect = *(tmp ++);
+ OutTrace(" SwapEffect = 0x%x(%s)\n", SwapEffect, ExplainSwapEffect(SwapEffect));
OutTrace(" hDeviceWindow = 0x%x\n", *(tmp ++));
OutTrace(" Windowed = %i\n", *(tmp ++));
OutTrace(" EnableAutoDepthStencil = %i\n", *(tmp ++));
@@ -804,7 +821,7 @@ HRESULT WINAPI extReset(void *pd3dd, D3DPRESENT_PARAMETERS* pPresParam)
HRESULT WINAPI extPresent(void *pd3dd, CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion)
{
HRESULT res;
- RECT RemappedRect;
+ RECT RemappedSrcRect, RemappedDstRect;
if(IsDebug){
char sSourceRect[81];
char sDestRect[81];
@@ -814,13 +831,27 @@ HRESULT WINAPI extPresent(void *pd3dd, CONST RECT *pSourceRect, CONST RECT *pDes
else strcpy(sDestRect, "(NULL)");
OutTraceB("Present: SourceRect=%s DestRect=%s hDestWndOverride=%x\n", sSourceRect, sDestRect, hDestWindowOverride);
}
+
// frame counter handling....
if (dxw.HandleFPS()) return D3D_OK;
if (dxw.dwFlags1 & SAVELOAD) dxw.VSyncWait();
- // v2.03.15 - fix target RECT region
+
if(dxw.dwFlags2 & FULLRECTBLT) pSourceRect = pDestRect = NULL;
- RemappedRect=dxw.MapClientRect((LPRECT)pDestRect);
- res=(*pPresent)(pd3dd, pSourceRect, &RemappedRect, hDestWindowOverride, pDirtyRegion);
+ if(dxw.Windowize){
+ // v2.03.15 - fix target RECT region
+ RemappedDstRect=dxw.MapClientRect((LPRECT)pDestRect);
+ pDestRect = &RemappedDstRect;
+ OutTraceB("Present: FIXED DestRect=(%d,%d)-(%d,%d)\n", RemappedDstRect.left, RemappedDstRect.top, RemappedDstRect.right, RemappedDstRect.bottom);
+ // in case of NOD3DRESET, remap source rect. Unfortunately, this doesn't work in fullscreen mode ....
+ if((dxw.dwFlags4 & NOD3DRESET) && (pSourceRect == NULL)){
+ RemappedSrcRect = dxw.GetScreenRect();
+ pSourceRect = &RemappedSrcRect;
+ OutTraceB("Present: NOD3DRESET FIXED SourceRect=(%d,%d)-(%d,%d)\n", RemappedSrcRect.left, RemappedSrcRect.top, RemappedSrcRect.right, RemappedSrcRect.bottom);
+ }
+ }
+
+ res=(*pPresent)(pd3dd, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
+ if(res) OutTraceE("Present: err=%x(%s)\n", res, ExplainDDError(res));
dxw.ShowOverlay();
return res;
}
@@ -972,6 +1003,7 @@ HRESULT WINAPI extCreateDevice(void *lpd3d, UINT adapter, D3DDEVTYPE devicetype,
if(IsTraceD3D){
tmp = param;
+ DWORD SwapEffect;
OutTrace("D3D%d::CreateDevice\n", dwD3DVersion);
OutTrace(" Adapter = %i\n", adapter);
OutTrace(" DeviceType = %i\n", devicetype);
@@ -983,7 +1015,8 @@ HRESULT WINAPI extCreateDevice(void *lpd3d, UINT adapter, D3DDEVTYPE devicetype,
OutTrace(" BackBufferCount = %i\n", *(tmp ++));
OutTrace(" MultiSampleType = %i\n", *(tmp ++));
if(dwD3DVersion == 9) OutTrace(" MultiSampleQuality = %i\n", *(tmp ++));
- OutTrace(" SwapEffect = 0x%x\n", *(tmp ++));
+ SwapEffect = *(tmp ++);
+ OutTrace(" SwapEffect = 0x%x(%s)\n", SwapEffect, ExplainSwapEffect(SwapEffect));
OutTrace(" hDeviceWindow = 0x%x\n", *(tmp ++));
OutTrace(" Windowed = %i\n", *(tmp ++));
OutTrace(" EnableAutoDepthStencil = %i\n", *(tmp ++));
@@ -1001,6 +1034,19 @@ HRESULT WINAPI extCreateDevice(void *lpd3d, UINT adapter, D3DDEVTYPE devicetype,
OutTraceD3D(" Current ScreenSize = (%dx%d)\n", mode.Width, mode.Height);
OutTraceD3D(" Current Refresh Rate = %d\n", mode.RefreshRate);
+ if((dxw.dwFlags4 & NOD3DRESET) && dxw.Windowize){
+ RECT desktop;
+ // Get a handle to the desktop window
+ const HWND hDesktop = (*pGetDesktopWindow)();
+ // Get the size of screen to the variable desktop
+ (*pGetWindowRect)(hDesktop, &desktop);
+ // The top left corner will have coordinates (0,0)
+ // and the bottom right corner will have coordinates
+ // (horizontal, vertical)
+ param[0] = desktop.right;
+ param[1] = desktop.bottom;
+ }
+
if(dwD3DVersion == 9){
if(dxw.Windowize){
param[7] = 0; //hDeviceWindow
@@ -1084,8 +1130,9 @@ HRESULT WINAPI extCreateDeviceEx(void *lpd3d, UINT adapter, D3DDEVTYPE devicetyp
if(dxw.Windowize) hfocuswindow=FixD3DWindowFrame(hfocuswindow);
- tmp = param;
if(IsTraceD3D){
+ tmp = param;
+ DWORD SwapEffect;
OutTrace("D3D%d::CreateDeviceEx\n", dwD3DVersion);
OutTrace(" Adapter = %i\n", adapter);
OutTrace(" DeviceType = %i\n", devicetype);
@@ -1097,7 +1144,8 @@ HRESULT WINAPI extCreateDeviceEx(void *lpd3d, UINT adapter, D3DDEVTYPE devicetyp
OutTrace(" BackBufferCount = %i\n", *(tmp ++));
OutTrace(" MultiSampleType = %i\n", *(tmp ++));
OutTrace(" MultiSampleQuality = %i\n", *(tmp ++));
- OutTrace(" SwapEffect = 0x%x\n", *(tmp ++));
+ SwapEffect = *(tmp ++);
+ OutTrace(" SwapEffect = 0x%x(%s)\n", SwapEffect, ExplainSwapEffect(SwapEffect));
OutTrace(" hDeviceWindow = 0x%x\n", *(tmp ++));
OutTrace(" Windowed = %i\n", *(tmp ++));
OutTrace(" EnableAutoDepthStencil = %i\n", *(tmp ++));
@@ -1113,6 +1161,19 @@ HRESULT WINAPI extCreateDeviceEx(void *lpd3d, UINT adapter, D3DDEVTYPE devicetyp
OutTraceD3D(" Current ScreenSize = (%dx%d)\n", mode.Width, mode.Height);
OutTraceD3D(" Current Refresh Rate = %d\n", mode.RefreshRate);
+ if((dxw.dwFlags4 & NOD3DRESET) && dxw.Windowize){
+ RECT desktop;
+ // Get a handle to the desktop window
+ const HWND hDesktop = (*pGetDesktopWindow)();
+ // Get the size of screen to the variable desktop
+ (*pGetWindowRect)(hDesktop, &desktop);
+ // The top left corner will have coordinates (0,0)
+ // and the bottom right corner will have coordinates
+ // (horizontal, vertical)
+ param[0] = desktop.right;
+ param[1] = desktop.bottom;
+ }
+
if(dxw.Windowize){
//param[7] = 0; //hDeviceWindow
param[7] = (DWORD)dxw.GethWnd(); //hDeviceWindow
@@ -1217,8 +1278,9 @@ HRESULT WINAPI extCreateAdditionalSwapChain(void *lpd3dd, D3DPRESENT_PARAMETERS
dxw.SetScreenSize(param[0], param[1]);
if(dxw.Windowize) FixD3DWindowFrame(dxw.GethWnd());
- tmp = param;
if(IsTraceD3D){
+ tmp = param;
+ DWORD SwapEffect;
OutTrace("D3D%d::CreateAdditionalSwapChain\n", dwD3DVersion);
OutTrace(" BackBufferWidth = %i\n", *(tmp ++));
OutTrace(" BackBufferHeight = %i\n", *(tmp ++));
@@ -1226,7 +1288,8 @@ HRESULT WINAPI extCreateAdditionalSwapChain(void *lpd3dd, D3DPRESENT_PARAMETERS
OutTrace(" BackBufferCount = %i\n", *(tmp ++));
OutTrace(" MultiSampleType = %i\n", *(tmp ++));
if(dwD3DVersion == 9) OutTrace(" MultiSampleQuality = %i\n", *(tmp ++));
- OutTrace(" SwapEffect = 0x%x\n", *(tmp ++));
+ SwapEffect = *(tmp ++);
+ OutTrace(" SwapEffect = 0x%x(%s)\n", SwapEffect, ExplainSwapEffect(SwapEffect));
OutTrace(" hDeviceWindow = 0x%x\n", *(tmp ++));
OutTrace(" Windowed = %i\n", *(tmp ++));
OutTrace(" EnableAutoDepthStencil = %i\n", *(tmp ++));
@@ -1984,6 +2047,7 @@ HRESULT WINAPI extGetSwapChain(void *lpd3dd, UINT iSwapChain, IDirect3DSwapChain
HRESULT res;
OutTraceD3D("GetSwapChain: d3dd=%x SwapChain=%d\n", lpd3dd, iSwapChain);
res = (*pGetSwapChain)(lpd3dd, iSwapChain, pSwapChain);
+ if(res) OutTraceE("GetSwapChain ERROR: res=%x(%s)\n", res, ExplainDDError(res));
return res;
}
diff --git a/dll/kernel32.cpp b/dll/kernel32.cpp
index 199bb79..c794fc1 100644
--- a/dll/kernel32.cpp
+++ b/dll/kernel32.cpp
@@ -18,7 +18,7 @@ typedef BOOL (WINAPI *CreateProcessA_Type)(LPCTSTR, LPTSTR, LPSECURITY_ATTRIBUTE
CreateProcessA_Type pCreateProcessA = NULL;
// v2.02.96: the GetSystemInfo API is NOT hot patchable on Win7. This can cause problems because it can't be hooked by simply
-// enabling hot patch. A solution is making all LiadLibrary* calls hot patchable, so that when loading the module, the call
+// enabling hot patch. A solution is making all LoadLibrary* calls hot patchable, so that when loading the module, the call
// can be hooked by the IAT lookup. This fixes a problem after movie playing in Wind Fantasy SP.
static HookEntry_Type Hooks[]={
@@ -761,9 +761,10 @@ HANDLE WINAPI extCreateFile(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwS
BOOL WINAPI extCloseHandle(HANDLE hObject)
{
+ BOOL ret;
OutTrace("CloseHandle: hFile=%x\n", hObject);
-
- return (*pCloseHandle)(hObject);
+ if (hObject && (hObject != (HANDLE)-1)) __try {ret=CloseHandle(hObject);} __except(EXCEPTION_EXECUTE_HANDLER){};
+ return ret;
}
DWORD WINAPI extSetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod)
diff --git a/dll/user32.cpp b/dll/user32.cpp
index e1b3d44..861f45e 100644
--- a/dll/user32.cpp
+++ b/dll/user32.cpp
@@ -12,7 +12,7 @@
#include "hddraw.h"
#include "dxhelper.h"
-#define FIXCHILDSIZE TRUE
+#define FIXCHILDSIZE FALSE
BOOL IsChangeDisplaySettingsHotPatched = FALSE;
@@ -24,6 +24,19 @@ BOOL IsChangeDisplaySettingsHotPatched = FALSE;
//EnumDisplayMonitors_Type pEnumDisplayMonitors = NULL;
//BOOL WINAPI extEnumDisplayMonitors(HDC, LPCRECT, MONITORENUMPROC, LPARAM);
+typedef BOOL (WINAPI *BringWindowToTop_Type)(HWND);
+BringWindowToTop_Type pBringWindowToTop = NULL;
+BOOL WINAPI extBringWindowToTop(HWND);
+typedef BOOL (WINAPI *SetForegroundWindow_Type)(HWND);
+SetForegroundWindow_Type pSetForegroundWindow = NULL;
+BOOL WINAPI extSetForegroundWindow(HWND);
+typedef HHOOK (WINAPI *SetWindowsHookEx_Type)(int, HOOKPROC, HINSTANCE, DWORD);
+SetWindowsHookEx_Type pSetWindowsHookEx = NULL;
+HHOOK WINAPI extSetWindowsHookEx(int, HOOKPROC, HINSTANCE, DWORD);
+typedef BOOL (WINAPI *PostMessageA_Type)(HWND, UINT, WPARAM, LPARAM);
+PostMessageA_Type pPostMessageA = NULL;
+BOOL WINAPI extPostMessageA(HWND, UINT, WPARAM, LPARAM);
+
#ifdef TRACEPALETTE
typedef UINT (WINAPI *GetDIBColorTable_Type)(HDC, UINT, UINT, RGBQUAD *);
GetDIBColorTable_Type pGetDIBColorTable = NULL;
@@ -78,6 +91,14 @@ static HookEntry_Type Hooks[]={
{HOOK_HOT_CANDIDATE, "GetDIBColorTable", (FARPROC)GetDIBColorTable, (FARPROC *)&pGetDIBColorTable, (FARPROC)extGetDIBColorTable},
{HOOK_HOT_CANDIDATE, "SetDIBColorTable", (FARPROC)SetDIBColorTable, (FARPROC *)&pSetDIBColorTable, (FARPROC)extSetDIBColorTable},
#endif
+
+ {HOOK_HOT_CANDIDATE, "BringWindowToTop", (FARPROC)BringWindowToTop, (FARPROC *)&pBringWindowToTop, (FARPROC)extBringWindowToTop},
+ {HOOK_HOT_CANDIDATE, "SetForegroundWindow", (FARPROC)SetForegroundWindow, (FARPROC *)&pSetForegroundWindow, (FARPROC)extSetForegroundWindow},
+ {HOOK_HOT_CANDIDATE, "ChildWindowFromPoint", (FARPROC)ChildWindowFromPoint, (FARPROC *)&pChildWindowFromPoint, (FARPROC)extChildWindowFromPoint},
+ {HOOK_HOT_CANDIDATE, "ChildWindowFromPointEx", (FARPROC)ChildWindowFromPointEx, (FARPROC *)&pChildWindowFromPointEx, (FARPROC)extChildWindowFromPointEx},
+ {HOOK_HOT_CANDIDATE, "WindowFromPoint", (FARPROC)WindowFromPoint, (FARPROC *)&pWindowFromPoint, (FARPROC)extWindowFromPoint},
+ {HOOK_HOT_CANDIDATE, "SetWindowsHookExA", (FARPROC)SetWindowsHookExA, (FARPROC *)&pSetWindowsHookEx, (FARPROC)extSetWindowsHookEx},
+
{HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator
};
@@ -386,7 +407,7 @@ void dxwFixWindowPos(char *ApiName, HWND hwnd, LPARAM lParam)
dwExStyle=(*pGetWindowLongA)(hwnd, GWL_EXSTYLE);
hMenu = (dwStyle & WS_CHILD) ? NULL : GetMenu(hwnd);
AdjustWindowRectEx(&full, dwStyle, (hMenu!=NULL), dwExStyle);
- if (hMenu) __try {CloseHandle(hMenu);} __except(EXCEPTION_EXECUTE_HANDLER){};
+ if (hMenu && (hMenu != (HMENU)-1)) __try {CloseHandle(hMenu);} __except(EXCEPTION_EXECUTE_HANDLER){};
BorderX= full.right - full.left - client.right;
BorderY= full.bottom - full.top - client.bottom;
OutTraceDW("%s: KEEPASPECTRATIO window borders=(%d,%d)\n", ApiName, BorderX, BorderY);
@@ -737,7 +758,7 @@ BOOL WINAPI extSetWindowPos(HWND hwnd, HWND hWndInsertAfter, int X, int Y, int c
// BEWARE: from MSDN - If the window is a child window, the return value is undefined.
hMenu = (dwCurStyle & WS_CHILD) ? NULL : GetMenu(hwnd);
AdjustWindowRectEx(&rect, dwCurStyle, (hMenu!=NULL), dwExStyle);
- if (hMenu) CloseHandle(hMenu);
+ if (hMenu && (hMenu != (HMENU)-1)) __try {CloseHandle(hMenu);} __except(EXCEPTION_EXECUTE_HANDLER){};
cx=rect.right; cy=rect.bottom;
OutTraceDW("SetWindowPos: main form hwnd=%x fixed size=(%d,%d)\n", hwnd, cx, cy);
@@ -1073,6 +1094,7 @@ int WINAPI extMapWindowPoints(HWND hWndFrom, HWND hWndTo, LPPOINT lpPoints, UINT
int ret;
// a rarely used API, but responsible for a painful headache: needs hooking for "Commandos 2", "Alien Nations".
// used also in "Full Pipe" activemovie
+ // used also in "NBA Live 99" menu screen
OutTraceDW("MapWindowPoints: hWndFrom=%x%s hWndTo=%x%s cPoints=%d FullScreen=%x\n",
hWndFrom, dxw.IsDesktop(hWndFrom)?"(DESKTOP)":"",
@@ -1089,14 +1111,25 @@ int WINAPI extMapWindowPoints(HWND hWndFrom, HWND hWndTo, LPPOINT lpPoints, UINT
if(dxw.IsRealDesktop(hWndFrom)) hWndFrom=dxw.GethWnd();
}
- // should scale the retcode and every point ???
ret=(*pMapWindowPoints)(hWndFrom, hWndTo, lpPoints, cPoints);
+ // v2.03.16: now must scale every point (fixes "NBA Live 99")
+ for(pi=0; pi>16, ret&0x0000FFFF);
return ret;
}
@@ -2136,8 +2169,8 @@ BOOL WINAPI extEndPaint(HWND hwnd, const PAINTSTRUCT *lpPaint)
{
BOOL ret;
- OutTraceDW("GDI.EndPaint: hwnd=%x lpPaint=%x lpPaint.hdc=%x\n", hwnd, lpPaint, lpPaint->hdc);
-
+ OutTraceDW("GDI.EndPaint: hwnd=%x lpPaint=%x lpPaint.rcpaint=(%d,%d)-(%d-%d) lpPaint.hdc=%x\n",
+ hwnd, lpPaint, lpPaint->rcPaint.left, lpPaint->rcPaint.top, lpPaint->rcPaint.right, lpPaint->rcPaint.bottom, lpPaint->hdc);
ret=(*pEndPaint)(hwnd, lpPaint);
OutTraceDW("GDI.EndPaint: hwnd=%x ret=%x\n", hwnd, ret);
if(!ret) OutTraceE("GDI.EndPaint ERROR: err=%d at %d\n", GetLastError(), __LINE__);
@@ -2738,7 +2771,7 @@ HWND WINAPI extWindowFromPoint(POINT Point)
HWND ret;
OutTraceDW("WindowFromPoint: point=(%d,%d)\n", Point.x, Point.y);
if(dxw.IsFullScreen()){
- dxw.UnmapClient(&Point);
+ dxw.UnmapWindow(&Point);
OutTraceDW("WindowFromPoint: FIXED point=(%d,%d)\n", Point.x, Point.y);
}
ret = (*pWindowFromPoint)(Point);
@@ -2750,7 +2783,7 @@ HWND WINAPI extChildWindowFromPoint(HWND hWndParent, POINT Point)
{
HWND ret;
OutTraceDW("ChildWindowFromPoint: hWndParent=%x point=(%d,%d)\n", hWndParent, Point.x, Point.y);
- if(dxw.IsDesktop(hWndParent) && dxw.IsFullScreen()){
+ if(dxw.IsDesktop(hWndParent) && dxw.IsFullScreen() && dxw.Windowize){
dxw.UnmapClient(&Point);
OutTraceDW("ChildWindowFromPoint: FIXED point=(%d,%d)\n", Point.x, Point.y);
}
@@ -2763,7 +2796,7 @@ HWND WINAPI extChildWindowFromPointEx(HWND hWndParent, POINT Point, UINT uFlags)
{
HWND ret;
OutTraceDW("ChildWindowFromPoint: hWndParent=%x point=(%d,%d) flags=%x\n", hWndParent, Point.x, Point.y, uFlags);
- if(dxw.IsDesktop(hWndParent) && dxw.IsFullScreen()){
+ if(dxw.IsDesktop(hWndParent) && dxw.IsFullScreen() && dxw.Windowize){
dxw.UnmapClient(&Point);
OutTraceDW("ChildWindowFromPointEx: FIXED point=(%d,%d)\n", Point.x, Point.y);
}
@@ -2941,3 +2974,66 @@ int WINAPI extGetWindowTextA(HWND hWnd, LPTSTR lpString, int nMaxCount)
return ret;
}
#endif
+
+BOOL WINAPI extBringWindowToTop(HWND hwnd)
+{
+ BOOL res;
+ OutTraceDW("BringWindowToTop: hwnd=%x\n", hwnd);
+ if(dxw.dwFlags5 & UNLOCKZORDER) return TRUE;
+ res=(*pBringWindowToTop)(hwnd);
+ return res;
+}
+
+BOOL WINAPI extSetForegroundWindow(HWND hwnd)
+{
+ BOOL res;
+ OutTraceDW("SetForegroundWindow: hwnd=%x\n", hwnd);
+ if(dxw.dwFlags5 & UNLOCKZORDER) return TRUE;
+ res=(*pSetForegroundWindow)(hwnd);
+ return res;
+}
+
+HOOKPROC glpMouseHookProcessFunction;
+HOOKPROC glpMessageHookProcessFunction;
+/*
+LRESULT CALLBACK extMouseHookProc(int code, WPARAM wParam, LPARAM lParam)
+{
+ LRESULT ret;
+ OutTrace("HookProc intercepted: code=%x wParam=%x lParam=%x\n", code, wParam, lParam);
+ MOUSEHOOKSTRUCT * pMouseStruct = (MOUSEHOOKSTRUCT *)lParam;
+ if (pMouseStruct != NULL){
+ dxw.UnmapWindow(&(pMouseStruct->pt));
+ }
+ ret= (*glpMouseHookProcessFunction)(code, wParam, lParam);
+ return ret;
+}
+*/
+
+LRESULT CALLBACK extMessageHookProc(int code, WPARAM wParam, LPARAM lParam)
+{
+ LRESULT ret;
+ OutTrace("MessageHookProc: code=%x wParam=%x lParam=%x\n", code, wParam, lParam);
+ MSG * pMessage = (MSG *)lParam;
+ ret = NULL;
+ if(pMessage){
+ UINT message = pMessage->message;
+ if ((message >= 0x600) || // custom messages
+ ((message >= WM_KEYFIRST) && (message <= WM_KEYLAST))) // keyboard messages
+ ret = (*glpMessageHookProcessFunction)(code, wParam, lParam);
+ }
+ return ret;
+}
+
+HHOOK WINAPI extSetWindowsHookEx(int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId)
+{
+ HHOOK ret;
+ if(dxw.dwFlags5 & EASPORTSHACK){
+ if(idHook == WH_MOUSE) return NULL;
+ if(idHook == WH_GETMESSAGE) {
+ glpMessageHookProcessFunction = lpfn;
+ lpfn=extMessageHookProc;
+ }
+ }
+ ret=(*pSetWindowsHookEx)(idHook, lpfn, hMod, dwThreadId);
+ return ret;
+}
diff --git a/host/TabCompat.cpp b/host/TabCompat.cpp
index 4c06250..ce3d98c 100644
--- a/host/TabCompat.cpp
+++ b/host/TabCompat.cpp
@@ -39,6 +39,7 @@ void CTabCompat::DoDataExchange(CDataExchange* pDX)
DDX_Check(pDX, IDC_NOPERFCOUNTER, cTarget->m_NoPerfCounter);
DDX_Check(pDX, IDC_HIDECDROMEMPTY, cTarget->m_HideCDROMEmpty);
DDX_Check(pDX, IDC_DIABLOTWEAK, cTarget->m_DiabloTweak);
+ DDX_Check(pDX, IDC_EASPORTSHACK, cTarget->m_EASportsHack);
DDX_Check(pDX, IDC_NOIMAGEHLP, cTarget->m_NoImagehlp);
DDX_Check(pDX, IDC_REPLACEPRIVOPS, cTarget->m_ReplacePrivOps);
diff --git a/host/TabWindow.cpp b/host/TabWindow.cpp
index a50610f..bf552f4 100644
--- a/host/TabWindow.cpp
+++ b/host/TabWindow.cpp
@@ -45,6 +45,7 @@ void CTabWindow::DoDataExchange(CDataExchange* pDX)
DDX_Check(pDX, IDC_NOWINDOWMOVE, cTarget->m_NoWindowMove);
//DDX_Check(pDX, IDC_SUPPRESSCHILD, cTarget->m_SuppressChild);
DDX_Check(pDX, IDC_HIDEDESKTOP, cTarget->m_HideDesktop);
+ DDX_Check(pDX, IDC_UNLOCKZORDER, cTarget->m_UnlockZOrder);
// color management
DDX_Check(pDX, IDC_INIT8BPP, cTarget->m_Init8BPP);
diff --git a/host/TargetDlg.cpp b/host/TargetDlg.cpp
index b7ca4d0..b56a783 100644
--- a/host/TargetDlg.cpp
+++ b/host/TargetDlg.cpp
@@ -45,6 +45,7 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/)
m_SetCompatibility = TRUE; // default true !!
m_AEROBoost = TRUE; // default true !!
m_DiabloTweak = FALSE;
+ m_EASportsHack = FALSE;
m_NoImagehlp = FALSE;
m_ReplacePrivOps = FALSE;
m_ForcesHEL = FALSE;
@@ -56,6 +57,7 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/)
m_NoD3DReset = FALSE;
//m_SuppressChild = FALSE;
m_HideDesktop = FALSE;
+ m_UnlockZOrder = FALSE;
m_LockSysColors = FALSE;
m_LockReservedPalette = FALSE;
m_ForceYUVtoRGB = FALSE;
diff --git a/host/TargetDlg.h b/host/TargetDlg.h
index 10e2315..3e15050 100644
--- a/host/TargetDlg.h
+++ b/host/TargetDlg.h
@@ -167,6 +167,7 @@ public:
BOOL m_SetCompatibility;
BOOL m_AEROBoost;
BOOL m_DiabloTweak;
+ BOOL m_EASportsHack;
BOOL m_NoImagehlp;
BOOL m_ForcesHEL;
BOOL m_ColorFix;
@@ -177,6 +178,7 @@ public:
BOOL m_NoD3DReset;
//BOOL m_SuppressChild;
BOOL m_HideDesktop;
+ BOOL m_UnlockZOrder;
BOOL m_LockSysColors;
BOOL m_LockReservedPalette;
BOOL m_SingleProcAffinity;
diff --git a/host/dxwndhost.aps b/host/dxwndhost.aps
index d8532fe..9a62459 100644
Binary files a/host/dxwndhost.aps and b/host/dxwndhost.aps differ
diff --git a/host/dxwndhost.rc b/host/dxwndhost.rc
index 9882855..9891e0c 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 115871e..eea5c8a 100644
Binary files a/host/dxwndhost.vs2008.suo and b/host/dxwndhost.vs2008.suo differ
diff --git a/host/dxwndhostView.cpp b/host/dxwndhostView.cpp
index b5c38fa..958fc4d 100644
--- a/host/dxwndhostView.cpp
+++ b/host/dxwndhostView.cpp
@@ -271,6 +271,7 @@ static void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg)
if(dlg->m_SetCompatibility) t->flags2 |= SETCOMPATIBILITY;
if(dlg->m_AEROBoost) t->flags5 |= AEROBOOST;
if(dlg->m_DiabloTweak) t->flags5 |= DIABLOTWEAK;
+ if(dlg->m_EASportsHack) t->flags5 |= EASPORTSHACK;
if(dlg->m_NoImagehlp) t->flags5 |= NOIMAGEHLP;
if(dlg->m_ForcesHEL) t->flags3 |= FORCESHEL;
if(dlg->m_ColorFix) t->flags3 |= COLORFIX;
@@ -281,6 +282,7 @@ static void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg)
if(dlg->m_NoD3DReset) t->flags4 |= NOD3DRESET;
//if(dlg->m_SuppressChild) t->flags4 |= SUPPRESSCHILD;
if(dlg->m_HideDesktop) t->flags4 |= HIDEDESKTOP;
+ if(dlg->m_UnlockZOrder) t->flags5 |= UNLOCKZORDER;
if(dlg->m_LockSysColors) t->flags3 |= LOCKSYSCOLORS;
if(dlg->m_LockReservedPalette) t->flags5 |= LOCKRESERVEDPALETTE;
if(dlg->m_ForceYUVtoRGB) t->flags3 |= YUV2RGB;
@@ -468,6 +470,7 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg)
dlg->m_SetCompatibility = t->flags2 & SETCOMPATIBILITY ? 1 : 0;
dlg->m_AEROBoost = t->flags5 & AEROBOOST ? 1 : 0;
dlg->m_DiabloTweak = t->flags5 & DIABLOTWEAK ? 1 : 0;
+ dlg->m_EASportsHack = t->flags5 & EASPORTSHACK ? 1 : 0;
dlg->m_NoImagehlp = t->flags5 & NOIMAGEHLP ? 1 : 0;
dlg->m_ForcesHEL = t->flags3 & FORCESHEL ? 1 : 0;
dlg->m_ColorFix = t->flags3 & COLORFIX ? 1 : 0;
@@ -478,6 +481,7 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg)
dlg->m_NoD3DReset = t->flags4 & NOD3DRESET ? 1 : 0;
//dlg->m_SuppressChild = t->flags4 & SUPPRESSCHILD ? 1 : 0;
dlg->m_HideDesktop = t->flags4 & HIDEDESKTOP ? 1 : 0;
+ dlg->m_UnlockZOrder = t->flags5 & UNLOCKZORDER ? 1 : 0;
dlg->m_LockSysColors = t->flags3 & LOCKSYSCOLORS ? 1 : 0;
dlg->m_LockReservedPalette = t->flags5 & LOCKRESERVEDPALETTE ? 1 : 0;
dlg->m_ForceRGBtoYUV = t->flags3 & RGB2YUV ? 1 : 0;
diff --git a/host/resource b/host/resource
index 7da5faa..162bf7c 100644
Binary files a/host/resource and b/host/resource differ