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