diff --git a/Include/dxwnd.h b/Include/dxwnd.h index 0c33993..c39728d 100644 --- a/Include/dxwnd.h +++ b/Include/dxwnd.h @@ -8,9 +8,11 @@ #define MAXTARGETS 256 #define ONEPIXELFIX 1 +#define HOOKDDRAWNONE 12 +#define HANDLEFLIPTOGDI 1 // first flags DWORD dwFlags1: -#define UNNOTIFY 0x00000001 +#define UNNOTIFY 0x00000001 #define EMULATESURFACE 0x00000002 #define CLIPCURSOR 0x00000004 // Force cursor clipping within window #define RESETPRIMARY 0x00000008 // reset emulated primary surface when reopening DDRaw object @@ -179,6 +181,9 @@ #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 +// sixth flags DWORD dxw.dwFlags6: +#define FORCESWAPEFFECT 0x00000001 // in D3D8/9, forces the SwapEffect value in CreateDevice/Reset operations + // logging Tflags DWORD: #define OUTTRACE 0x00000001 // enables tracing to dxwnd.log in general #define OUTDDRAWTRACE 0x00000002 // traces DxWnd directdraw screen handling @@ -214,6 +219,7 @@ typedef struct TARGETMAP int flags3; int flags4; int flags5; + int flags6; int tflags; short initx; short inity; @@ -229,6 +235,7 @@ typedef struct TARGETMAP short InitTS; short FakeVersionId; short MaxScreenRes; + short SwapEffect; }TARGETMAP; typedef struct diff --git a/build/dxwnd.dll b/build/dxwnd.dll index 5c3db29..4761121 100644 --- a/build/dxwnd.dll +++ b/build/dxwnd.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2e7c1adfbd594089e1c8eb7040b06037ae1f239498a09399e82ef4e52023c080 -size 576512 +oid sha256:30f6a78ea3b87ee01aff8159e37ade8c64528ce94e51299d3f5e5b3f7c7e8276 +size 575488 diff --git a/build/dxwnd.exe b/build/dxwnd.exe index 74d412c..3002862 100644 --- a/build/dxwnd.exe +++ b/build/dxwnd.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a512e18dc9a004e3cb5f8f08eca94a0b06c8e5d935689eac885ba75f5636cde1 -size 538624 +oid sha256:292da547aea629cb8b159cd7ac8c768bdc915cdd4ecd294dbc0ec14097ec869c +size 539648 diff --git a/build/readme-relnotes.txt b/build/readme-relnotes.txt index 7f73f80..6443c63 100644 --- a/build/readme-relnotes.txt +++ b/build/readme-relnotes.txt @@ -785,3 +785,12 @@ fix: eliminated InvalidateRect calls in ddrow Unlock hooker: this is not the rig fix: DirectDrawEnumerateEx log fix: cursor is hidden in fullscreen mode only fix: CoCreateInstance & CoCreateInstanceEx wrappers. Now "Crusaders of Might & Magic" is playable in window + +v2.03.19: +fix: scaling of movie coordinates rendered through MciSendString +fix: doubled rendering to screen with fast 2x bilinear filtering +fix: crash when setting "showFPS overlay" with DirectX "hybrid mode" +fix: "keep aspect ratio" with DirectX "GDI mode" +fix: when ddraw hook is set to "none", no hook operations are performed on ddraw +add: possibility to control the D3D8/9 SwapEffect field with the "force swap effect" flag +fix: revised handling of GDI device context shared with DirectDraw primary surface, improved behaviour of "Star trek Armada" \ No newline at end of file diff --git a/dll/ddblit.cpp b/dll/ddblit.cpp index ec66120..15f61e5 100644 --- a/dll/ddblit.cpp +++ b/dll/ddblit.cpp @@ -10,7 +10,6 @@ extern LPDIRECTDRAWSURFACE lpDDSBack; extern LPDIRECTDRAWSURFACE lpDDSEmu_Prim; -extern LPDIRECTDRAWSURFACE lpDDSEmu_Back; extern LPDIRECTDRAW lpPrimaryDD; extern Blt_Type pBlt; extern ReleaseS_Type pReleaseS; @@ -290,6 +289,10 @@ static HRESULT sBltToPrimary(char *api, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdest if(lpDDSEmu_Prim->IsLost()) lpDDSEmu_Prim->Restore(); dxw.ShowOverlay(lpDDSSource); + if(dxw.dwFlags4 & BILINEAR2XFILTER){ + emurect.right <<= 1; + emurect.bottom <<= 1; + } if (IsDebug) BlitTrace("BACK2PRIM", &emurect, &destrect, __LINE__); res=(*pPrimaryBlt)(lpDDSEmu_Prim, &destrect, lpDDSSource, &emurect); @@ -364,7 +367,7 @@ HRESULT WINAPI sBlt(char *api, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, OutTrace(sLog); } - if(ToPrim) + if(ToPrim) res = sBltToPrimary(api, lpdds, lpdestrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx, isFlipping); else res = sBltNoPrimary(api, lpdds, lpdestrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx); diff --git a/dll/ddraw.cpp b/dll/ddraw.cpp index 927cec0..b0b511f 100644 --- a/dll/ddraw.cpp +++ b/dll/ddraw.cpp @@ -23,6 +23,11 @@ DWORD dwBackBufferCaps; extern void TextureHandling(LPDIRECTDRAWSURFACE); ColorConversion_Type pColorConversion = NULL; +#ifdef HANDLEFLIPTOGDI +HDC hFlippedDC = NULL; +BOOL bFlippedDC = FALSE; +#endif + // DirectDraw API HRESULT WINAPI extDirectDrawCreate(GUID FAR *, LPDIRECTDRAW FAR *, IUnknown FAR *); HRESULT WINAPI extDirectDrawCreateEx(GUID FAR *, LPDIRECTDRAW FAR *, REFIID, IUnknown FAR *); @@ -283,6 +288,7 @@ static HookEntry_Type ddHooks[]={ FARPROC Remap_ddraw_ProcAddress(LPCSTR proc, HMODULE hModule) { FARPROC addr; + if (dxw.dwTargetDDVersion == HOOKDDRAWNONE) return NULL; if (addr=RemapLibrary(proc, hModule, ddHooks)) return addr; return NULL; } @@ -2367,6 +2373,8 @@ static HRESULT BuildPrimaryEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf if (dxw.dwTFlags & OUTPROXYTRACE) HookDDSurfaceGeneric(&lpDDSEmu_Back, dxversion); } + bFlippedDC = TRUE; + return DD_OK; } @@ -3696,7 +3704,6 @@ HRESULT WINAPI extLockDir(LPDIRECTDRAWSURFACE lpdds, LPRECT lprect, LPDDSURFACED HRESULT WINAPI extUnlock(int dxversion, Unlock4_Type pUnlock, LPDIRECTDRAWSURFACE lpdds, LPRECT lprect) { HRESULT res; - //RECT screen, rect; BOOL IsPrim; BOOL IsBack; @@ -3858,13 +3865,17 @@ HRESULT WINAPI extReleaseDC(LPDIRECTDRAWSURFACE lpdds, HDC FAR hdc) HRESULT WINAPI extFlipToGDISurface(LPDIRECTDRAW lpdd) { - //HRESULT res; + // HRESULT res; OutTraceDDRAW("FlipToGDISurface: lpdd=%x\n", lpdd); // to revise: so far, it seems the best thing to do is NOTHING, just return 0. - //res=(*pFlipToGDISurface)(lpdd); - //if (res) OutTraceE("FlipToGDISurface: ERROR res=%x(%s), skipping\n", res, ExplainDDError(res)); + // res=(*pFlipToGDISurface)(lpdd); + // if (res) OutTraceE("FlipToGDISurface: ERROR res=%x(%s), skipping\n", res, ExplainDDError(res)); // pretend you flipped anyway.... +#ifdef HANDLEFLIPTOGDI + bFlippedDC = TRUE; +#endif + return 0; } @@ -3876,6 +3887,7 @@ HRESULT WINAPI extGetGDISurface(LPDIRECTDRAW lpdd, LPDIRECTDRAWSURFACE *w) // in EMULATED mode, should not return the actual ddraw primary surface, but the virtual one. if(dxw.dwFlags1 & EMULATESURFACE){ *w=dxw.GetPrimarySurface(); + OutTraceDW("GetGDISurface: EMULATED lpdd=%x w=%x\n", lpdd, *w); return DD_OK; } diff --git a/dll/dxhelper.cpp b/dll/dxhelper.cpp index c97a6f0..2dfb051 100644 --- a/dll/dxhelper.cpp +++ b/dll/dxhelper.cpp @@ -968,7 +968,7 @@ char *ExplainGUID(GUID FAR *lpguid) case DDCREATE_HARDWAREONLY: return "DDCREATE_HARDWAREONLY"; break; case DDCREATE_EMULATIONONLY: return "DDCREATE_EMULATIONONLY"; break; } - switch ((*(DWORD *)lpguid)){ + switch (lpguid->Data1){ case 0x00000000: sguid="IID_IUnknown"; break; case 0x6C14DB80: sguid="IID_IDirectDraw"; break; case 0xB3A6F3E0: sguid="IID_IDirectDraw2"; break; diff --git a/dll/dxhook.cpp b/dll/dxhook.cpp index 06afaf3..9d41a14 100644 --- a/dll/dxhook.cpp +++ b/dll/dxhook.cpp @@ -102,6 +102,17 @@ static char *Flag5Names[32]={ "GSKYHACK", "LOCKRESERVEDPALETTE", "UNLOCKZORDER", "EASPORTSHACK", }; +static char *Flag6Names[32]={ + "FORCESWAPEFFECT", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", +}; + static char *TFlagNames[32]={ "OUTTRACE", "OUTDDRAWTRACE", "OUTWINMESSAGES", "OUTCURSORTRACE", "OUTPROXYTRACE", "DXPROXED", "ASSERTDIALOG", "OUTIMPORTTABLE", @@ -149,6 +160,7 @@ static void OutTraceHeader(FILE *fp) for(i=0, dword=dxw.dwFlags3; i<32; i++, dword>>=1) if(dword & 0x1) fprintf(fp, "%s ", Flag3Names[i]); for(i=0, dword=dxw.dwFlags4; i<32; i++, dword>>=1) if(dword & 0x1) fprintf(fp, "%s ", Flag4Names[i]); for(i=0, dword=dxw.dwFlags5; i<32; i++, dword>>=1) if(dword & 0x1) fprintf(fp, "%s ", Flag5Names[i]); + for(i=0, dword=dxw.dwFlags6; i<32; i++, dword>>=1) if(dword & 0x1) fprintf(fp, "%s ", Flag6Names[i]); for(i=0, dword=dxw.dwTFlags; i<32; i++, dword>>=1) if(dword & 0x1) fprintf(fp, "%s ", TFlagNames[i]); fprintf(fp, "***\n"); } @@ -1344,7 +1356,7 @@ void HookModule(HMODULE base, int dxversion) //if(dxw.dwFlags2 & SUPPRESSIME) HookImeLib(module); HookGDI32(base); if(dxw.dwFlags1 & HOOKDI) HookDirectInput(base, dxversion); - HookDirectDraw(base, dxversion); + if(dxw.dwTargetDDVersion != HOOKDDRAWNONE) HookDirectDraw(base, dxversion); HookDirect3D(base, dxversion); HookDirect3D7(base, dxversion); if(dxw.dwFlags2 & HOOKOPENGL) HookOpenGLLibs(base, dxw.CustomOpenGLLib); diff --git a/dll/dxwcore.cpp b/dll/dxwcore.cpp index 7958352..0869d6e 100644 --- a/dll/dxwcore.cpp +++ b/dll/dxwcore.cpp @@ -6,6 +6,7 @@ #include "syslibs.h" #include "dxhelper.h" #include "resource.h" +#include "d3d9.h" /* ------------------------------------------------------------------ */ // Internal function pointers @@ -81,6 +82,7 @@ void dxwCore::InitTarget(TARGETMAP *target) dwFlags3 = target->flags3; dwFlags4 = target->flags4; dwFlags5 = target->flags5; + dwFlags6 = target->flags6; dwTFlags = target->tflags; Windowize = (dwFlags2 & WINDOWIZE) ? TRUE : FALSE; if(dwFlags3 & FULLSCREENONLY) FullScreen=TRUE; @@ -98,6 +100,13 @@ void dxwCore::InitTarget(TARGETMAP *target) FakeVersionId = target->FakeVersionId; MaxScreenRes = target->MaxScreenRes; Coordinates = target->coordinates; + switch(target->SwapEffect){ + case 0: SwapEffect = D3DSWAPEFFECT_DISCARD; break; + case 1: SwapEffect = D3DSWAPEFFECT_FLIP; break; + case 2: SwapEffect = D3DSWAPEFFECT_COPY; break; + case 3: SwapEffect = D3DSWAPEFFECT_OVERLAY; break; + case 4: SwapEffect = D3DSWAPEFFECT_FLIPEX; break; + } MustShowOverlay=((dwFlags2 & SHOWFPSOVERLAY) || (dwFlags4 & SHOWTIMESTRETCH)); if(dwFlags4 & FINETIMING){ pTimeShifter = TimeShifterFine; @@ -722,11 +731,11 @@ RECT dxwCore::MapClientRect(LPRECT lpRect) LONG Width, Height; Width = ClientRect.right - (2*bx); Height = ClientRect.bottom - (2*by); - // v2.03.15 - fixed right & bottom values + // v2.03.18 - fixed right & bottom values RetRect.left = bx + (lpRect->left * Width / dwScreenWidth); - RetRect.right = RetRect.left + Width; + RetRect.right = bx + (lpRect->right * Width / dwScreenWidth); RetRect.top = by + (lpRect->top * Height / dwScreenHeight); - RetRect.bottom = RetRect.top + Height; + RetRect.bottom = by + (lpRect->bottom * Height / dwScreenHeight); } else{ RetRect.left = ClientRect.left + bx; @@ -1327,11 +1336,15 @@ void dxwCore::ShowOverlay() void dxwCore::ShowOverlay(LPDIRECTDRAWSURFACE lpdds) { + typedef HRESULT (WINAPI *GetDC_Type) (LPDIRECTDRAWSURFACE, HDC FAR *); + typedef HRESULT (WINAPI *ReleaseDC_Type)(LPDIRECTDRAWSURFACE, HDC); + extern GetDC_Type pGetDC; + extern ReleaseDC_Type pReleaseDC; if (MustShowOverlay) { HDC hdc; // the working dc int h, w; if(!lpdds) return; - if (FAILED(lpdds->GetDC(&hdc))) return; + if (FAILED((*pGetDC)(lpdds, &hdc))) return; w = this->GetScreenWidth(); h = this->GetScreenHeight(); if(this->dwFlags4 & BILINEAR2XFILTER) { @@ -1339,7 +1352,7 @@ void dxwCore::ShowOverlay(LPDIRECTDRAWSURFACE lpdds) h <<=1; } this->ShowOverlay(hdc, w, h); - lpdds->ReleaseDC(hdc); + (*pReleaseDC)(lpdds, hdc); } } diff --git a/dll/dxwcore.hpp b/dll/dxwcore.hpp index 31ec851..4d84035 100644 --- a/dll/dxwcore.hpp +++ b/dll/dxwcore.hpp @@ -139,12 +139,14 @@ public: // simple data variables DWORD dwFlags3; DWORD dwFlags4; DWORD dwFlags5; + DWORD dwFlags6; DWORD dwTFlags; HWND hParentWnd; HWND hChildWnd; BOOL bActive; BOOL bDInputAbs; DWORD MaxFPS; + DWORD SwapEffect; char *gsModules; int TimeShift; LPDIRECTDRAWSURFACE lpDDSPrimHDC; diff --git a/dll/dxwnd.cpp b/dll/dxwnd.cpp index 7b88850..cf8a001 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.18" +#define VERSION "2.03.19" #define DDTHREADLOCK 1 //#define LOCKTHREADS diff --git a/dll/dxwnd.vs2008.suo b/dll/dxwnd.vs2008.suo index 65f237b..6f7ec42 100644 Binary files a/dll/dxwnd.vs2008.suo and b/dll/dxwnd.vs2008.suo differ diff --git a/dll/gdiblt.cpp b/dll/gdiblt.cpp index e3f7816..4775915 100644 --- a/dll/gdiblt.cpp +++ b/dll/gdiblt.cpp @@ -18,52 +18,6 @@ extern GetDC_Type pGetDC; extern ReleaseDC_Type pReleaseDC; extern Unlock1_Type pUnlock1; -//#define HDC_CACHE_OPTIMIZED - -#ifdef HDC_CACHE_OPTIMIZED -void BlitToWindow(HWND w, LPDIRECTDRAWSURFACE s) -{ - static HDC thdc = NULL; - HDC shdc; - static HWND LastWindow = NULL; - RECT client; - HRESULT res; - BOOL ret; - - if(!s) return; // for surface color fill - ret=(*pGetClientRect)(w, &client); - if(!ret) OutTrace("GetClientRect error=%d\n", GetLastError()); - res=(*pGetDC)(s, &shdc); - if(res) OutTrace("ddraw GetDC error lpdds=%x res=%x(%s)\n", s, res, ExplainDDError(res)); - if(w != LastWindow){ - if(LastWindow){ - ret=(*pGDIReleaseDC)(LastWindow, thdc); - if(!ret) OutTrace("GDI ReleaseDC error=%d\n", GetLastError()); - } - LastWindow = w; - thdc=(*pGDIGetDC)(w); - if(!thdc) OutTrace("GDI GetDC error=%d\n", GetLastError()); - } - if(dxw.dwFlags5 & CENTERTOWIN){ - int x, y; - x = (client.right - dxw.GetScreenWidth()) >> 1; // right-shift 1 bit means divide by 2! - y = (client.bottom - dxw.GetScreenHeight()) >> 1; - ret=(*pGDIBitBlt)(thdc, x, y, dxw.GetScreenWidth(), dxw.GetScreenHeight(), shdc, 0, 0, SRCCOPY); - if(!ret) OutTrace("BitBlt error=%d\n", GetLastError()); - } - else{ - if(dxw.dwFlags5 & BILINEARFILTER) { - ret=SetStretchBltMode(thdc, HALFTONE); - if((!ret) || (ret==ERROR_INVALID_PARAMETER)) OutTrace("GDI SetStretchBltMode error=%d\n", GetLastError()); - } - ret=(*pGDIStretchBlt)(thdc, 0, 0, client.right, client.bottom, shdc, 0, 0, dxw.GetScreenWidth(), dxw.GetScreenHeight(), SRCCOPY); - if(!ret) OutTrace("GDI StretchBlt error=%d\n", GetLastError()); - } - dxw.ShowOverlay(thdc); - res=(*pReleaseDC)(s, shdc); - if(res) OutTrace("ddraw ReleaseDC error lpdds=%x res=%x(%s)\n", s, res, ExplainDDError(res)); -} -#else void BlitToWindow(HWND w, LPDIRECTDRAWSURFACE s) { HDC shdc, thdc; @@ -72,16 +26,15 @@ void BlitToWindow(HWND w, LPDIRECTDRAWSURFACE s) BOOL ret; if(!s) return; // for surface color fill - ret=(*pGetClientRect)(w, &client); - if(!ret) OutTrace("GetClientRect error=%d\n", GetLastError()); res=(*pGetDC)(s, &shdc); if(res) OutTrace("ddraw GetDC error lpdds=%x res=%x(%s)\n", s, res, ExplainDDError(res)); thdc=(*pGDIGetDC)(w); if(!thdc) OutTrace("GDI GetDC error=%d\n", GetLastError()); + client = dxw.MapClientRect(NULL); if(dxw.dwFlags5 & CENTERTOWIN){ int x, y; - x = (client.right - dxw.GetScreenWidth()) >> 1; // right-shift 1 bit means divide by 2! - y = (client.bottom - dxw.GetScreenHeight()) >> 1; + x = (client.left + client.right - dxw.GetScreenWidth()) >> 1; // right-shift 1 bit means divide by 2! + y = (client.top + client.bottom - dxw.GetScreenHeight()) >> 1; ret=(*pGDIBitBlt)(thdc, x, y, dxw.GetScreenWidth(), dxw.GetScreenHeight(), shdc, 0, 0, SRCCOPY); if(!ret) OutTrace("BitBlt error=%d\n", GetLastError()); } @@ -90,7 +43,9 @@ void BlitToWindow(HWND w, LPDIRECTDRAWSURFACE s) ret=SetStretchBltMode(thdc, HALFTONE); if((!ret) || (ret==ERROR_INVALID_PARAMETER)) OutTrace("GDI SetStretchBltMode error=%d\n", GetLastError()); } - ret=(*pGDIStretchBlt)(thdc, 0, 0, client.right, client.bottom, shdc, 0, 0, dxw.GetScreenWidth(), dxw.GetScreenHeight(), SRCCOPY); + ret=(*pGDIStretchBlt)(thdc, + client.left, client.top, client.right-client.left, client.bottom-client.top, + shdc, 0, 0, dxw.GetScreenWidth(), dxw.GetScreenHeight(), SRCCOPY); if(!ret) OutTrace("GDI StretchBlt error=%d\n", GetLastError()); } dxw.ShowOverlay(thdc); @@ -99,4 +54,4 @@ void BlitToWindow(HWND w, LPDIRECTDRAWSURFACE s) ret=(*pGDIReleaseDC)(w, thdc); if(!ret) OutTrace("GDI ReleaseDC error=%d\n", GetLastError()); } -#endif + diff --git a/dll/hd3d.cpp b/dll/hd3d.cpp index 24d2757..7beab3c 100644 --- a/dll/hd3d.cpp +++ b/dll/hd3d.cpp @@ -282,6 +282,7 @@ AddRef_Type pAddRef9 = 0; Release_Type pRelease9 = 0; DWORD dwD3DVersion; +DWORD dwD3DSwapEffect; static HookEntry_Type d3d8Hooks[]={ {HOOK_HOT_CANDIDATE, "Direct3DCreate8", (FARPROC)NULL, (FARPROC *)&pDirect3DCreate8, (FARPROC)extDirect3DCreate8}, @@ -327,6 +328,7 @@ static HookEntry_Type d3d11Hooks[]={ FARPROC Remap_d3d8_ProcAddress(LPCSTR proc, HMODULE hModule) { FARPROC addr; + //if (dxw.dwTargetDDVersion == HOOKDDRAWNONE) return NULL; if (addr=RemapLibrary(proc, hModule, d3d8Hooks)) return addr; return NULL; } @@ -334,6 +336,7 @@ FARPROC Remap_d3d8_ProcAddress(LPCSTR proc, HMODULE hModule) FARPROC Remap_d3d9_ProcAddress(LPCSTR proc, HMODULE hModule) { FARPROC addr; + //if (dxw.dwTargetDDVersion == HOOKDDRAWNONE) return NULL; if (addr=RemapLibrary(proc, hModule, d3d9Hooks)) return addr; if (dxw.dwFlags3 & SUPPRESSD3DEXT) if (addr=RemapLibrary(proc, hModule, d3d9Extra)) return addr; return NULL; @@ -342,6 +345,7 @@ FARPROC Remap_d3d9_ProcAddress(LPCSTR proc, HMODULE hModule) FARPROC Remap_d3d10_ProcAddress(LPCSTR proc, HMODULE hModule) { FARPROC addr; + //if (dxw.dwTargetDDVersion == HOOKDDRAWNONE) return NULL; if (addr=RemapLibrary(proc, hModule, d3d10Hooks)) return addr; return NULL; } @@ -349,6 +353,7 @@ FARPROC Remap_d3d10_ProcAddress(LPCSTR proc, HMODULE hModule) FARPROC Remap_d3d10_1_ProcAddress(LPCSTR proc, HMODULE hModule) { FARPROC addr; + //if (dxw.dwTargetDDVersion == HOOKDDRAWNONE) return NULL; if (addr=RemapLibrary(proc, hModule, d3d10_1Hooks)) return addr; return NULL; } @@ -356,6 +361,7 @@ FARPROC Remap_d3d10_1_ProcAddress(LPCSTR proc, HMODULE hModule) FARPROC Remap_d3d11_ProcAddress(LPCSTR proc, HMODULE hModule) { FARPROC addr; + //if (dxw.dwTargetDDVersion == HOOKDDRAWNONE) return NULL; if (addr=RemapLibrary(proc, hModule, d3d11Hooks)) return addr; return NULL; } @@ -750,6 +756,8 @@ HRESULT WINAPI extReset(void *pd3dd, D3DPRESENT_PARAMETERS* pPresParam) OutTraceD3D("GetAdapterDisplayMode FAILED! %x\n", res); return(DD_OK); } + if(dxw.dwFlags6 & FORCESWAPEFFECT) param[6] = dxw.SwapEffect; //Swap effect; + dwD3DSwapEffect = param[6]; param[7] = 0; //hDeviceWindow dxw.SetFullScreen(~param[8]?TRUE:FALSE); param[8] = 1; //Windowed @@ -769,6 +777,8 @@ HRESULT WINAPI extReset(void *pd3dd, D3DPRESENT_PARAMETERS* pPresParam) OutTraceD3D("GetAdapterDisplayMode FAILED! %x\n", res); return(DD_OK); } + if(dxw.dwFlags6 & FORCESWAPEFFECT) param[5] = dxw.SwapEffect; //Swap effect; + dwD3DSwapEffect = param[5]; param[6] = 0; //hDeviceWindow dxw.SetFullScreen(~param[7]?TRUE:FALSE); param[7] = 1; //Windowed @@ -839,8 +849,10 @@ HRESULT WINAPI extPresent(void *pd3dd, CONST RECT *pSourceRect, CONST RECT *pDes if(dxw.dwFlags2 & FULLRECTBLT) pSourceRect = pDestRect = NULL; if(dxw.Windowize){ // v2.03.15 - fix target RECT region + if ((dwD3DSwapEffect == D3DSWAPEFFECT_COPY) && (dxw.dwFlags2 & KEEPASPECTRATIO)) { 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)){ @@ -1049,6 +1061,8 @@ HRESULT WINAPI extCreateDevice(void *lpd3d, UINT adapter, D3DDEVTYPE devicetype, if(dwD3DVersion == 9){ if(dxw.Windowize){ + if(dxw.dwFlags6 & FORCESWAPEFFECT) param[6] = dxw.SwapEffect; //Swap effect; + dwD3DSwapEffect = param[6]; param[7] = 0; //hDeviceWindow dxw.SetFullScreen(~param[8]?TRUE:FALSE); param[8] = 1; //Windowed @@ -1070,6 +1084,8 @@ HRESULT WINAPI extCreateDevice(void *lpd3d, UINT adapter, D3DDEVTYPE devicetype, } else{ if(dxw.Windowize){ + if(dxw.dwFlags6 & FORCESWAPEFFECT) param[5] = dxw.SwapEffect; //Swap effect; + dwD3DSwapEffect = param[5]; param[6] = 0; //hDeviceWindow dxw.SetFullScreen(~param[7]?TRUE:FALSE); param[7] = 1; //Windowed @@ -1175,6 +1191,8 @@ HRESULT WINAPI extCreateDeviceEx(void *lpd3d, UINT adapter, D3DDEVTYPE devicetyp } if(dxw.Windowize){ + if(dxw.dwFlags6 & FORCESWAPEFFECT) param[6] = dxw.SwapEffect; //Swap effect; + dwD3DSwapEffect = param[6]; //param[7] = 0; //hDeviceWindow param[7] = (DWORD)dxw.GethWnd(); //hDeviceWindow dxw.SetFullScreen(~param[8]?TRUE:FALSE); @@ -1313,6 +1331,8 @@ HRESULT WINAPI extCreateAdditionalSwapChain(void *lpd3dd, D3DPRESENT_PARAMETERS if(dxw.Windowize){ if(dwD3DVersion == 9){ + if(dxw.dwFlags6 & FORCESWAPEFFECT) param[6] = dxw.SwapEffect; //Swap effect; + dwD3DSwapEffect = param[6]; param[7] = 0; //hDeviceWindow dxw.SetFullScreen(~param[8]?TRUE:FALSE); param[8] = 1; //Windowed @@ -1320,6 +1340,8 @@ HRESULT WINAPI extCreateAdditionalSwapChain(void *lpd3dd, D3DPRESENT_PARAMETERS param[13] = D3DPRESENT_INTERVAL_DEFAULT; //PresentationInterval } else{ + if(dxw.dwFlags6 & FORCESWAPEFFECT) param[5] = dxw.SwapEffect; //Swap effect; + dwD3DSwapEffect = param[5]; param[6] = 0; //hDeviceWindow dxw.SetFullScreen(~param[7]?TRUE:FALSE); param[7] = 1; //Windowed diff --git a/dll/syslibs.h b/dll/syslibs.h index 8b35f8e..75ec488 100644 --- a/dll/syslibs.h +++ b/dll/syslibs.h @@ -571,7 +571,6 @@ extern void STDAPICALLTYPE extCoUninitialize(void); // user32.dll: extern HDC WINAPI extBeginPaint(HWND, LPPAINTSTRUCT); -extern HDC WINAPI extEMUBeginPaint(HWND, LPPAINTSTRUCT); extern HDC WINAPI extDDBeginPaint(HWND, LPPAINTSTRUCT); extern LRESULT WINAPI extCallWindowProc(WNDPROC, HWND, UINT, WPARAM, LPARAM); extern LONG WINAPI extChangeDisplaySettingsA(DEVMODEA *, DWORD); @@ -589,7 +588,6 @@ extern LRESULT WINAPI extDefWindowProcW(HWND, UINT, WPARAM, LPARAM); extern int WINAPI extDrawTextA(HDC, LPCTSTR, int, LPRECT, UINT); extern int WINAPI extDrawTextExA(HDC, LPTSTR, int, LPRECT, UINT, LPDRAWTEXTPARAMS); extern BOOL WINAPI extEndPaint(HWND, const PAINTSTRUCT *); -extern BOOL WINAPI extEMUEndPaint(HWND, const PAINTSTRUCT *); extern BOOL WINAPI extDDEndPaint(HWND, const PAINTSTRUCT *); extern LONG WINAPI extEnumDisplaySettings(LPCTSTR, DWORD, DEVMODE *); extern int WINAPI extFillRect(HDC, const RECT *, HBRUSH); @@ -607,7 +605,6 @@ extern int WINAPI extGetSystemMetrics(int); extern HWND WINAPI extGetTopWindow(HWND); extern int WINAPI extGetUpdateRgn(HWND, HRGN, BOOL); extern HDC WINAPI extGDIGetWindowDC(HWND); -extern HDC WINAPI extEMUGetWindowDC(HWND); extern HDC WINAPI extDDGetWindowDC(HWND); extern LONG WINAPI extGetWindowLongA(HWND, int); extern LONG WINAPI extGetWindowLongW(HWND, int); @@ -621,7 +618,6 @@ extern BOOL WINAPI extRedrawWindow(HWND, const RECT *, HRGN, UINT); extern ATOM WINAPI extRegisterClassExA(WNDCLASSEXA *); extern ATOM WINAPI extRegisterClassA(WNDCLASSA *); extern int WINAPI extGDIReleaseDC(HWND, HDC); -extern int WINAPI extEMUReleaseDC(HWND, HDC); extern int WINAPI extDDReleaseDC(HWND, HDC); extern BOOL WINAPI extScreenToClient(HWND, LPPOINT); extern LRESULT WINAPI extSendMessageA(HWND, UINT, WPARAM, LPARAM); @@ -639,7 +635,6 @@ extern BOOL WINAPI extDestroyWindow(HWND); extern BOOL WINAPI extCloseWindow(HWND); extern BOOL WINAPI extSetSysColors(int, const INT *, const COLORREF *); extern HDC WINAPI extGDIGetDCEx(HWND, HRGN, DWORD); -extern HDC WINAPI extEMUGetDCEx(HWND, HRGN, DWORD); extern HDC WINAPI extDDGetDCEx(HWND, HRGN, DWORD); extern BOOL WINAPI extUpdateWindow(HWND); extern BOOL WINAPI extGetWindowPlacement(HWND, WINDOWPLACEMENT *); diff --git a/dll/user32.cpp b/dll/user32.cpp index bc35be4..e9c5e42 100644 --- a/dll/user32.cpp +++ b/dll/user32.cpp @@ -15,6 +15,10 @@ #define FIXCHILDSIZE FALSE BOOL IsChangeDisplaySettingsHotPatched = FALSE; +#define GDIMODE_STRETCHED 0 +#define GDIMODE_EMULATED 1 +#define GDIMODE_DIRECTDRAW 2 +int GDIEmulationMode = 0; //typedef BOOL (WINAPI *ValidateRect_Type)(HWND, const RECT *); //BOOL WINAPI extValidateRect(HWND, const RECT *); @@ -42,6 +46,9 @@ HRESULT WINAPI extMessageBoxTimeoutA(HWND, LPCSTR, LPCSTR, UINT, WORD, DWORD); typedef HRESULT (WINAPI *MessageBoxTimeoutW_Type)(HWND, LPCWSTR, LPCWSTR, UINT, WORD, DWORD); MessageBoxTimeoutW_Type pMessageBoxTimeoutW = NULL; HRESULT WINAPI extMessageBoxTimeoutW(HWND, LPCWSTR, LPCWSTR, UINT, WORD, DWORD); +typedef BOOL (WINAPI *IsIconic_Type)(HWND); +IsIconic_Type pIsIconic = NULL; +BOOL WINAPI extIsIconic(HWND); #ifdef TRACEPALETTE typedef UINT (WINAPI *GetDIBColorTable_Type)(HDC, UINT, UINT, RGBQUAD *); @@ -108,6 +115,8 @@ static HookEntry_Type Hooks[]={ //{HOOK_HOT_CANDIDATE, "MessageBoxTimeoutA", (FARPROC)NULL, (FARPROC *)&pMessageBoxTimeoutA, (FARPROC)extMessageBoxTimeoutA}, //{HOOK_HOT_CANDIDATE, "MessageBoxTimeoutW", (FARPROC)NULL, (FARPROC *)&pMessageBoxTimeoutW, (FARPROC)extMessageBoxTimeoutW}, + //{HOOK_HOT_CANDIDATE, "IsIconic", (FARPROC)IsIconic, (FARPROC *)&pIsIconic, (FARPROC)extIsIconic}, + {HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator }; @@ -118,18 +127,19 @@ static HookEntry_Type NoGDIHooks[]={ }; static HookEntry_Type EmulateHooks[]={ - {HOOK_IAT_CANDIDATE, "BeginPaint", (FARPROC)BeginPaint, (FARPROC *)&pBeginPaint, (FARPROC)extEMUBeginPaint}, - {HOOK_IAT_CANDIDATE, "EndPaint", (FARPROC)EndPaint, (FARPROC *)&pEndPaint, (FARPROC)extEMUEndPaint}, - {HOOK_IAT_CANDIDATE, "GetDC", (FARPROC)GetDC, (FARPROC *)&pGDIGetDC, (FARPROC)extEMUGetDC}, - {HOOK_IAT_CANDIDATE, "GetDCEx", (FARPROC)GetDCEx, (FARPROC *)&pGDIGetDCEx, (FARPROC)extEMUGetDCEx}, - {HOOK_IAT_CANDIDATE, "GetWindowDC", (FARPROC)GetWindowDC, (FARPROC *)&pGDIGetWindowDC, (FARPROC)extEMUGetWindowDC}, - {HOOK_IAT_CANDIDATE, "ReleaseDC", (FARPROC)ReleaseDC, (FARPROC *)&pGDIReleaseDC, (FARPROC)extEMUReleaseDC}, + {HOOK_IAT_CANDIDATE, "BeginPaint", (FARPROC)BeginPaint, (FARPROC *)&pBeginPaint, (FARPROC)extBeginPaint}, + {HOOK_IAT_CANDIDATE, "EndPaint", (FARPROC)EndPaint, (FARPROC *)&pEndPaint, (FARPROC)extEndPaint}, + {HOOK_IAT_CANDIDATE, "GetDC", (FARPROC)GetDC, (FARPROC *)&pGDIGetDC, (FARPROC)extGDIGetDC}, + {HOOK_IAT_CANDIDATE, "GetDCEx", (FARPROC)GetDCEx, (FARPROC *)&pGDIGetDCEx, (FARPROC)extGDIGetDCEx}, + {HOOK_IAT_CANDIDATE, "GetWindowDC", (FARPROC)GetWindowDC, (FARPROC *)&pGDIGetWindowDC, (FARPROC)extGDIGetWindowDC}, + {HOOK_IAT_CANDIDATE, "ReleaseDC", (FARPROC)ReleaseDC, (FARPROC *)&pGDIReleaseDC, (FARPROC)extGDIReleaseDC}, //{HOOK_IAT_CANDIDATE, "InvalidateRect", (FARPROC)InvalidateRect, (FARPROC *)&pInvalidateRect, (FARPROC)extInvalidateRect}, {HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator }; static HookEntry_Type DDHooks[]={ {HOOK_IAT_CANDIDATE, "BeginPaint", (FARPROC)BeginPaint, (FARPROC *)&pBeginPaint, (FARPROC)extDDBeginPaint}, + //{HOOK_IAT_CANDIDATE, "BeginPaint", (FARPROC)BeginPaint, (FARPROC *)&pBeginPaint, (FARPROC)extBeginPaint}, {HOOK_IAT_CANDIDATE, "EndPaint", (FARPROC)EndPaint, (FARPROC *)&pEndPaint, (FARPROC)extDDEndPaint}, {HOOK_IAT_CANDIDATE, "GetDC", (FARPROC)GetDC, (FARPROC *)&pGDIGetDC, (FARPROC)extDDGetDC}, {HOOK_IAT_CANDIDATE, "GetDCEx", (FARPROC)GetDCEx, (FARPROC *)&pGDIGetDCEx, (FARPROC)extDDGetDCEx}, @@ -232,6 +242,11 @@ static char *libname = "user32.dll"; void HookUser32(HMODULE hModule) { + GDIEmulationMode = GDIMODE_STRETCHED; // default + if (dxw.dwFlags2 & GDISTRETCHED) GDIEmulationMode = GDIMODE_STRETCHED; + if (dxw.dwFlags3 & GDIEMULATEDC) GDIEmulationMode = GDIMODE_EMULATED; + if (dxw.dwFlags1 & MAPGDITOPRIMARY) GDIEmulationMode = GDIMODE_DIRECTDRAW; + HookLibrary(hModule, Hooks, libname); if (!(dxw.dwFlags2 & GDISTRETCHED) && !(dxw.dwFlags3 & GDIEMULATEDC) && !(dxw.dwFlags1 & MAPGDITOPRIMARY)) HookLibrary(hModule, NoGDIHooks, libname); @@ -1847,216 +1862,92 @@ LONG WINAPI extChangeDisplaySettingsExW(LPCTSTR lpszDeviceName, DEVMODEW *lpDevM return (*pChangeDisplaySettingsExW)(lpszDeviceName, lpDevMode, hwnd, dwflags, lParam); } -HDC WINAPI extGDIGetDC(HWND hwnd) +static HDC WINAPI sGetDC(HWND hwnd, char *ApiName) { + // to do: add parameter and reference to pGDIGetDCEx to merge properly GetDC and GetDCEx HDC ret; HWND lochwnd; - OutTraceDW("GDI.GetDC: hwnd=%x\n", hwnd); lochwnd=hwnd; + if (dxw.IsRealDesktop(hwnd)) { - OutTraceDW("GDI.GetDC: desktop remapping hwnd=%x->%x\n", hwnd, dxw.GethWnd()); + OutTraceDW("%s: desktop remapping hwnd=%x->%x\n", ApiName, hwnd, dxw.GethWnd()); lochwnd=dxw.GethWnd(); } - ret=(*pGDIGetDC)(lochwnd); - +#ifdef HANDLEFLIPTOGDI + extern BOOL bFlippedDC; + //if(bFlippedDC && (OBJ_DC == GetObjectType(ret))) { + if(bFlippedDC) { + extern HDC hFlippedDC; + LPDIRECTDRAWSURFACE lpDDSPrim; + //extern Unlock4_Type pUnlockMethod(LPDIRECTDRAWSURFACE); + lpDDSPrim = dxw.GetPrimarySurface(); + //(*pUnlockMethod(lpDDSPrim))(lpDDSPrim, NULL); + (*pGetDC)(lpDDSPrim, &hFlippedDC); + OutTraceDW("%s: remapping flipped GDI hdc=%x\n", ApiName, hFlippedDC); + return hFlippedDC; + } +#endif + + switch(GDIEmulationMode){ + case GDIMODE_STRETCHED: + ret=(*pGDIGetDC)(lochwnd); + break; + case GDIMODE_EMULATED: + ret=dxw.AcquireEmulatedDC(lochwnd); + dxw.VirtualHDC=ret; + break; + case GDIMODE_DIRECTDRAW: + break; + } + if(ret){ - OutTraceDW("GDI.GetDC: hwnd=%x ret=%x\n", lochwnd, ret); + OutTraceDW("%s: hwnd=%x ret=%x\n", ApiName, lochwnd, ret); } else{ int err; err=GetLastError(); - OutTraceE("GDI.GetDC ERROR: hwnd=%x err=%d at %d\n", lochwnd, err, __LINE__); + OutTraceE("%s ERROR: hwnd=%x err=%d at %d\n", ApiName, lochwnd, err, __LINE__); if((err==ERROR_INVALID_WINDOW_HANDLE) && (lochwnd!=hwnd)){ ret=(*pGDIGetDC)(hwnd); if(ret) - OutTraceDW("GDI.GetDC: hwnd=%x ret=%x\n", hwnd, ret); + OutTraceDW("%s: hwnd=%x ret=%x\n", ApiName, hwnd, ret); else - OutTraceE("GDI.GetDC ERROR: hwnd=%x err=%d at %d\n", hwnd, GetLastError(), __LINE__); + OutTraceE("%s ERROR: hwnd=%x err=%d at %d\n", ApiName, hwnd, GetLastError(), __LINE__); } } return ret; } -HDC WINAPI extEMUGetDC(HWND hwnd) +HDC WINAPI extGDIGetDC(HWND hwnd) { - HDC ret; - HWND lochwnd; - OutTraceDW("GDI.GetDC: hwnd=%x\n", hwnd); - - lochwnd=hwnd; - if (dxw.IsRealDesktop(hwnd)) { - OutTraceDW("GDI.GetDC: desktop remapping hwnd=%x->%x\n", hwnd, dxw.GethWnd()); - lochwnd=dxw.GethWnd(); - } - - ret=dxw.AcquireEmulatedDC(lochwnd); - OutTraceDW("GDI.GetDC: remapping hdc=%x->%x\n", (*pGDIGetDC)(hwnd), ret); - dxw.VirtualHDC=ret; - - if(ret){ - OutTraceDW("GDI.GetDC: hwnd=%x ret=%x\n", lochwnd, ret); - } - else{ - int err; - err=GetLastError(); - OutTraceE("GDI.GetDC ERROR: hwnd=%x err=%d at %d\n", lochwnd, err, __LINE__); - if((err==ERROR_INVALID_WINDOW_HANDLE) && (lochwnd!=hwnd)){ - ret=(*pGDIGetDC)(hwnd); - if(ret) - OutTraceDW("GDI.GetDC: hwnd=%x ret=%x\n", hwnd, ret); - else - OutTraceE("GDI.GetDC ERROR: hwnd=%x err=%d at %d\n", hwnd, GetLastError(), __LINE__); - } - } - - return ret; + return sGetDC(hwnd, "GDI.GetDC"); } HDC WINAPI extGDIGetDCEx(HWND hwnd, HRGN hrgnClip, DWORD flags) { // used by Star Wars Shadow of the Empire - HDC ret; - HWND lochwnd; - OutTraceDW("GDI.GetDCEx: hwnd=%x hrgnClip=%x flags=%x(%s)\n", hwnd, hrgnClip, flags, ExplainGetDCExFlags(flags)); - lochwnd=hwnd; - if (dxw.IsRealDesktop(hwnd)) { - OutTraceDW("GDI.GetDCEx: desktop remapping hwnd=%x->%x\n", hwnd, dxw.GethWnd()); - lochwnd=dxw.GethWnd(); - } - - ret=(*pGDIGetDC)(lochwnd); - - if(ret){ - OutTraceDW("GDI.GetDCEx: hwnd=%x ret=%x\n", lochwnd, ret); - } - else{ - int err; - err=GetLastError(); - OutTraceE("GDI.GetDCEx ERROR: hwnd=%x err=%d at %d\n", lochwnd, err, __LINE__); - if((err==ERROR_INVALID_WINDOW_HANDLE) && (lochwnd!=hwnd)){ - ret=(*pGDIGetDCEx)(hwnd, hrgnClip, flags); - if(ret) - OutTraceDW("GDI.GetDCEx: hwnd=%x ret=%x\n", hwnd, ret); - else - OutTraceE("GDI.GetDCEx ERROR: hwnd=%x err=%d at %d\n", hwnd, GetLastError(), __LINE__); - } - } - - return ret; -} - -HDC WINAPI extEMUGetDCEx(HWND hwnd, HRGN hrgnClip, DWORD flags) -{ - // used by Star Wars Shadow of the Empire - HDC ret; - HWND lochwnd; - - OutTraceDW("GDI.GetDCEx: hwnd=%x hrgnClip=%x flags=%x(%s)\n", hwnd, hrgnClip, flags, ExplainGetDCExFlags(flags)); - lochwnd=hwnd; - if (dxw.IsRealDesktop(hwnd)) { - OutTraceDW("GDI.GetDCEx: desktop remapping hwnd=%x->%x\n", hwnd, dxw.GethWnd()); - lochwnd=dxw.GethWnd(); - } - - ret=dxw.AcquireEmulatedDC(lochwnd); - OutTraceDW("GDI.GetDCEx: remapping hdc=%x->%x\n", (*pGDIGetDC)(hwnd), ret); - dxw.VirtualHDC=ret; - - if(ret){ - OutTraceDW("GDI.GetDCEx: hwnd=%x ret=%x\n", lochwnd, ret); - } - else{ - int err; - err=GetLastError(); - OutTraceE("GDI.GetDCEx ERROR: hwnd=%x err=%d at %d\n", lochwnd, err, __LINE__); - if((err==ERROR_INVALID_WINDOW_HANDLE) && (lochwnd!=hwnd)){ - ret=(*pGDIGetDCEx)(hwnd, hrgnClip, flags); - if(ret) - OutTraceDW("GDI.GetDCEx: hwnd=%x ret=%x\n", hwnd, ret); - else - OutTraceE("GDI.GetDCEx ERROR: hwnd=%x err=%d at %d\n", hwnd, GetLastError(), __LINE__); - } - } - - return ret; + return sGetDC(hwnd, "GDI.GetDCEx"); } HDC WINAPI extGDIGetWindowDC(HWND hwnd) { - HDC ret; - HWND lochwnd; OutTraceDW("GDI.GetWindowDC: hwnd=%x\n", hwnd); - lochwnd=hwnd; - if (dxw.IsRealDesktop(hwnd)) { - OutTraceDW("GDI.GetWindowDC: desktop remapping hwnd=%x->%x\n", hwnd, dxw.GethWnd()); - lochwnd=dxw.GethWnd(); + + // if not fullscreen or not desktop win, just proxy the call + if(!dxw.IsFullScreen() || !dxw.IsDesktop(hwnd)){ + HDC ret; + ret=(*pGDIGetWindowDC)(hwnd); + OutTraceDW("GDI.GetWindowDC: hwnd=%x hdc=%x\n", hwnd, ret); + return ret; } - if(dxw.IsFullScreen()){ - ret=dxw.AcquireEmulatedDC(lochwnd); - OutTraceDW("GDI.GetWindowDC: remapping hdc=%x->%x\n", (*pGDIGetDC)(hwnd), ret); - dxw.VirtualHDC=ret; - } - else - ret=(*pGDIGetWindowDC)(lochwnd); - - if(ret){ - OutTraceDW("GDI.GetWindowDC: hwnd=%x ret=%x\n", lochwnd, ret); - } - else{ - int err; - err=GetLastError(); - OutTraceE("GDI.GetWindowDC ERROR: hwnd=%x err=%d at %d\n", lochwnd, err, __LINE__); - if((err==ERROR_INVALID_WINDOW_HANDLE) && (lochwnd!=hwnd)){ - ret=(*pGDIGetWindowDC)(hwnd); - if(ret) - OutTraceDW("GDI.GetWindowDC: hwnd=%x ret=%x\n", hwnd, ret); - else - OutTraceE("GDI.GetWindowDC ERROR: hwnd=%x err=%d at %d\n", hwnd, GetLastError(), __LINE__); - } - } - return ret; + return sGetDC(hwnd, "GDI.GetWindowDC"); } - -HDC WINAPI extEMUGetWindowDC(HWND hwnd) -{ - HDC ret; - HWND lochwnd; - OutTraceDW("GDI.GetWindowDC: hwnd=%x\n", hwnd); - lochwnd=hwnd; - if (dxw.IsRealDesktop(hwnd)) { - OutTraceDW("GDI.GetWindowDC: desktop remapping hwnd=%x->%x\n", hwnd, dxw.GethWnd()); - lochwnd=dxw.GethWnd(); - } - - if(dxw.IsDesktop(hwnd) && dxw.IsFullScreen()) - ret=(*pGDIGetDC)(lochwnd); - else - ret=(*pGDIGetWindowDC)(lochwnd); - - if(ret){ - OutTraceDW("GDI.GetWindowDC: hwnd=%x ret=%x\n", lochwnd, ret); - } - else{ - int err; - err=GetLastError(); - OutTraceE("GDI.GetWindowDC ERROR: hwnd=%x err=%d at %d\n", lochwnd, err, __LINE__); - if((err==ERROR_INVALID_WINDOW_HANDLE) && (lochwnd!=hwnd)){ - ret=(*pGDIGetWindowDC)(hwnd); - if(ret) - OutTraceDW("GDI.GetWindowDC: hwnd=%x ret=%x\n", hwnd, ret); - else - OutTraceE("GDI.GetWindowDC ERROR: hwnd=%x err=%d at %d\n", hwnd, GetLastError(), __LINE__); - } - } - return ret; -} - int WINAPI extGDIReleaseDC(HWND hwnd, HDC hDC) { int res; @@ -2064,22 +1955,34 @@ int WINAPI extGDIReleaseDC(HWND hwnd, HDC hDC) OutTraceDW("GDI.ReleaseDC: hwnd=%x hdc=%x\n", hwnd, hDC); if (dxw.IsRealDesktop(hwnd)) hwnd=dxw.GethWnd(); - res=(*pGDIReleaseDC)(hwnd, hDC); - if (!res) OutTraceE("GDI.ReleaseDC ERROR: err=%d at %d\n", GetLastError(), __LINE__); - return(res); -} -int WINAPI extEMUReleaseDC(HWND hwnd, HDC hDC) -{ - int res; - HDC windc; +#ifdef HANDLEFLIPTOGDI + extern BOOL bFlippedDC; + extern HDC hFlippedDC; + if(bFlippedDC && (hDC == hFlippedDC)) { + HRESULT ret; + OutTraceDW("GDI.ReleaseDC: releasing flipped GDI hdc=%x\n", hDC); + ret=(*pReleaseDC)(dxw.GetPrimarySurface(), hDC); + if (ret) OutTraceE("GDI.ReleaseDC ERROR: err=%x(%s) at %d\n", ret, ExplainDDError(ret), __LINE__); + dxw.ScreenRefresh(); + return (ret == DD_OK); + } +#endif - OutTraceDW("GDI.ReleaseDC: hwnd=%x hdc=%x\n", hwnd, hDC); + switch(GDIEmulationMode){ + case GDIMODE_STRETCHED: + res=(*pGDIReleaseDC)(hwnd, hDC); + break; + case GDIMODE_EMULATED: + HDC windc; + windc=(*pGDIGetDC)(hwnd); + res=dxw.ReleaseEmulatedDC(hwnd); + res=(*pGDIReleaseDC)(hwnd, windc); + break; + case GDIMODE_DIRECTDRAW: + break; + } - if (dxw.IsRealDesktop(hwnd)) hwnd=dxw.GethWnd(); - windc=(*pGDIGetDC)(hwnd); - res=dxw.ReleaseEmulatedDC(hwnd); - res=(*pGDIReleaseDC)(hwnd, windc); if (!res) OutTraceE("GDI.ReleaseDC ERROR: err=%d at %d\n", GetLastError(), __LINE__); return(res); } @@ -2089,45 +1992,43 @@ HDC WINAPI extBeginPaint(HWND hwnd, LPPAINTSTRUCT lpPaint) HDC hdc; OutTraceDW("GDI.BeginPaint: hwnd=%x lpPaint=%x FullScreen=%x\n", hwnd, lpPaint, dxw.IsFullScreen()); - hdc=(*pBeginPaint)(hwnd, lpPaint); // avoid access to real desktop if(dxw.IsRealDesktop(hwnd)) hwnd=dxw.GethWnd(); + hdc=(*pBeginPaint)(hwnd, lpPaint); + // if not in fullscreen mode, that's all! if(!dxw.IsFullScreen()) return hdc; // on CLIENTREMAPPING, resize the paint area to virtual screen size if(dxw.dwFlags1 & CLIENTREMAPPING) lpPaint->rcPaint=dxw.GetScreenRect(); + switch(GDIEmulationMode){ + case GDIMODE_STRETCHED: + break; + case GDIMODE_EMULATED: + HDC EmuHDC; + EmuHDC = dxw.AcquireEmulatedDC(hwnd); + lpPaint->hdc=EmuHDC; + hdc = EmuHDC; + break; + case GDIMODE_DIRECTDRAW: + (*pGDIReleaseDC)(hwnd, lpPaint->hdc); + (*pGetDC)(dxw.lpDDSPrimHDC,&PrimHDC); + lpPaint->hdc=PrimHDC; + // resize the paint area to virtual screen size (see CivIII clipped panels...) + lpPaint->rcPaint=dxw.GetScreenRect(); + OutTraceDW("GDI.BeginPaint(MAPGDITOPRIMARY): hdc=%x -> %x\n", hdc, PrimHDC); + hdc = PrimHDC; + break; + } + OutTraceDW("GDI.BeginPaint: hdc=%x rcPaint=(%d,%d)-(%d,%d)\n", hdc, lpPaint->rcPaint.left, lpPaint->rcPaint.top, lpPaint->rcPaint.right, lpPaint->rcPaint.bottom); return hdc; } -HDC WINAPI extEMUBeginPaint(HWND hwnd, LPPAINTSTRUCT lpPaint) -{ - HDC hdc; - HDC EmuHDC; - - OutTraceDW("GDI.BeginPaint(GDIEMULATEDC): hwnd=%x lpPaint=%x FullScreen=%x\n", hwnd, lpPaint, dxw.IsFullScreen()); - hdc=(*pBeginPaint)(hwnd, lpPaint); - - // avoid access to real desktop - if(dxw.IsRealDesktop(hwnd)) hwnd=dxw.GethWnd(); - - // if not in fullscreen mode, that's all! - if(!dxw.IsFullScreen()) return hdc; - - // on CLIENTREMAPPING, resize the paint area to virtual screen size - if(dxw.dwFlags1 & CLIENTREMAPPING) lpPaint->rcPaint=dxw.GetScreenRect(); - - EmuHDC = dxw.AcquireEmulatedDC(hwnd); - lpPaint->hdc=EmuHDC; - OutTraceDW("GDI.BeginPaint(GDIEMULATEDC): hdc=%x -> %x\n", hdc, EmuHDC); - return EmuHDC; -} - HDC WINAPI extDDBeginPaint(HWND hwnd, LPPAINTSTRUCT lpPaint) { HDC hdc; @@ -2179,32 +2080,34 @@ BOOL WINAPI extEndPaint(HWND hwnd, const PAINTSTRUCT *lpPaint) { BOOL ret; - 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__); - return ret; -} + OutTraceDW("GDI.EndPaint: hwnd=%x lpPaint=%x lpPaint.hdc=%x lpPaint.rcpaint=(%d,%d)-(%d-%d)\n", + hwnd, lpPaint, lpPaint->hdc, lpPaint->rcPaint.left, lpPaint->rcPaint.top, lpPaint->rcPaint.right, lpPaint->rcPaint.bottom); -BOOL WINAPI extEMUEndPaint(HWND hwnd, const PAINTSTRUCT *lpPaint) -{ - BOOL ret; - - OutTraceDW("GDI.EndPaint: hwnd=%x lpPaint=%x lpPaint.hdc=%x\n", hwnd, lpPaint, lpPaint->hdc); - - if(dxw.IsFullScreen()){ - // avoid access to real desktop - if(dxw.IsRealDesktop(hwnd)) hwnd=dxw.GethWnd(); - OutTraceDW("GDI.EndPaint(GDIEMULATEDC): hwnd=%x\n", hwnd); - ret=dxw.ReleaseEmulatedDC(hwnd); + // if not fullscreen or not desktop win, just proxy the call + if(!dxw.IsFullScreen() || !dxw.Windowize){ + ret=(*pEndPaint)(hwnd, lpPaint); + return ret; } - else{ - // proxy part ... - ret=(*pEndPaint)(hwnd, lpPaint); + + // avoid access to real desktop + if(dxw.IsRealDesktop(hwnd)) hwnd=dxw.GethWnd(); + + switch(GDIEmulationMode){ + case GDIMODE_STRETCHED: + ret=(*pEndPaint)(hwnd, lpPaint); + break; + case GDIMODE_EMULATED: + ret=dxw.ReleaseEmulatedDC(hwnd); + break; + case GDIMODE_DIRECTDRAW: + break; } - OutTraceDW("GDI.EndPaint: hwnd=%x ret=%x\n", hwnd, ret); - if(!ret) OutTraceE("GDI.EndPaint ERROR: err=%d at %d\n", GetLastError(), __LINE__); + + if(ret) + OutTraceDW("GDI.EndPaint: hwnd=%x ret=%x\n", hwnd, ret); + else + OutTraceE("GDI.EndPaint ERROR: err=%d at %d\n", GetLastError(), __LINE__); + return ret; } @@ -3065,3 +2968,11 @@ HRESULT WINAPI extMessageBoxTimeoutW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaptio return res; } +BOOL WINAPI extIsIconic(HWND hWnd) +{ + BOOL ret; + ret = (*pIsIconic)(hWnd); + OutTrace("IsIconic: hwnd=%x ret=%x\n", hWnd, ret); + //return FALSE; + return ret; +} \ No newline at end of file diff --git a/dll/winmm.cpp b/dll/winmm.cpp index d7923b4..1028bdc 100644 --- a/dll/winmm.cpp +++ b/dll/winmm.cpp @@ -162,7 +162,12 @@ MCIERROR WINAPI extmciSendStringA(LPCTSTR lpszCommand, LPTSTR lpszReturnString, if (sscanf(lpszCommand, "put %s destination at %ld %ld %ld %ld", sMovieNickName, &(rect.left), &(rect.top), &(rect.right), &(rect.bottom))==5){ char NewCommand[256]; + // v2.03.19 height / width fix + rect.right += rect.left; // convert width to position + rect.bottom += rect.top; // convert height to position rect=dxw.MapClientRect(&rect); + rect.right -= rect.left; // convert position to width + rect.bottom -= rect.top; // convert position to height sprintf(NewCommand, "put %s destination at %d %d %d %d", sMovieNickName, rect.left, rect.top, rect.right, rect.bottom); lpszCommand=NewCommand; OutTraceDW("mciSendStringA: replaced Command=\"%s\"\n", lpszCommand); @@ -186,7 +191,12 @@ MCIERROR WINAPI extmciSendStringW(LPCWSTR lpszCommand, LPWSTR lpszReturnString, if (swscanf(lpszCommand, L"put %ls destination at %ld %ld %ld %ld", sMovieNickName, &(rect.left), &(rect.top), &(rect.right), &(rect.bottom))==5){ WCHAR NewCommand[256]; + // v2.03.19 height / width fix + rect.right += rect.left; // convert width to position + rect.bottom += rect.top; // convert height to position rect=dxw.MapClientRect(&rect); + rect.right -= rect.left; // convert position to width + rect.bottom -= rect.top; // convert position to height swprintf(NewCommand, L"put %ls destination at %d %d %d %d", sMovieNickName, rect.left, rect.top, rect.right, rect.bottom); lpszCommand=NewCommand; OutTraceDW("mciSendStringW: replaced Command=\"%ls\"\n", lpszCommand); diff --git a/host/TabDirect3D.cpp b/host/TabDirect3D.cpp index 3c3c6b5..5b9999c 100644 --- a/host/TabDirect3D.cpp +++ b/host/TabDirect3D.cpp @@ -43,6 +43,10 @@ void CTabDirect3D::DoDataExchange(CDataExchange* pDX) DDX_Check(pDX, IDC_WIREFRAME, cTarget->m_WireFrame); DDX_Check(pDX, IDC_DISABLEFOGGING, cTarget->m_DisableFogging); DDX_Check(pDX, IDC_CLEARTARGET, cTarget->m_ClearTarget); + + // Swap Effect + DDX_Check(pDX, IDC_FORCESWAPEFFECT, cTarget->m_ForcesSwapEffect); + DDX_Radio(pDX, IDC_SWAP_DISCARD, cTarget->m_SwapEffect); } BEGIN_MESSAGE_MAP(CTabDirect3D, CDialog) diff --git a/host/TargetDlg.cpp b/host/TargetDlg.cpp index b56a783..c136853 100644 --- a/host/TargetDlg.cpp +++ b/host/TargetDlg.cpp @@ -49,6 +49,7 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/) m_NoImagehlp = FALSE; m_ReplacePrivOps = FALSE; m_ForcesHEL = FALSE; + m_ForcesSwapEffect = FALSE; m_ColorFix = FALSE; m_NoPixelFormat = FALSE; m_NoAlphaChannel = FALSE; @@ -186,6 +187,7 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/) m_SizY = 600; m_MaxFPS = 0; m_InitTS = 8; + m_SwapEffect = 0; //}}AFX_DATA_INIT } diff --git a/host/TargetDlg.h b/host/TargetDlg.h index 3e15050..6b17882 100644 --- a/host/TargetDlg.h +++ b/host/TargetDlg.h @@ -170,6 +170,7 @@ public: BOOL m_EASportsHack; BOOL m_NoImagehlp; BOOL m_ForcesHEL; + BOOL m_ForcesSwapEffect; BOOL m_ColorFix; BOOL m_NoPixelFormat; BOOL m_NoAlphaChannel; @@ -205,6 +206,7 @@ public: int m_FakeVersionId; int m_MaxScreenRes; int m_ResTypes; + int m_SwapEffect; //}}AFX_DATA diff --git a/host/dxwndhost.aps b/host/dxwndhost.aps index e8a5659..34f53ba 100644 Binary files a/host/dxwndhost.aps and b/host/dxwndhost.aps differ diff --git a/host/dxwndhost.rc b/host/dxwndhost.rc index 9891e0c..d3e3113 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 1a31ec4..d2f4513 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 958fc4d..a02dd19 100644 --- a/host/dxwndhostView.cpp +++ b/host/dxwndhostView.cpp @@ -166,6 +166,7 @@ static void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg) t->flags3 = 0; t->flags4 = 0; t->flags5 = 0; + t->flags6 = 0; t->tflags = 0; if(dlg->m_UnNotify) t->flags |= UNNOTIFY; if(dlg->m_Windowize) t->flags2 |= WINDOWIZE; @@ -274,6 +275,7 @@ static void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg) if(dlg->m_EASportsHack) t->flags5 |= EASPORTSHACK; if(dlg->m_NoImagehlp) t->flags5 |= NOIMAGEHLP; if(dlg->m_ForcesHEL) t->flags3 |= FORCESHEL; + if(dlg->m_ForcesSwapEffect) t->flags6 |= FORCESWAPEFFECT; if(dlg->m_ColorFix) t->flags3 |= COLORFIX; if(dlg->m_NoPixelFormat) t->flags3 |= NOPIXELFORMAT; if(dlg->m_NoAlphaChannel) t->flags4 |= NOALPHACHANNEL; @@ -382,6 +384,7 @@ static void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg) t->InitTS = dlg->m_InitTS-8; t->FakeVersionId = dlg->m_FakeVersionId; t->MaxScreenRes = dlg->m_MaxScreenRes; + t->SwapEffect = dlg->m_SwapEffect; strcpy_s(t->module, sizeof(t->module), dlg->m_Module); strcpy_s(t->OpenGLLib, sizeof(t->OpenGLLib), dlg->m_OpenGLLib); } @@ -473,6 +476,7 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg) 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_ForcesSwapEffect = t->flags6 & FORCESWAPEFFECT ? 1 : 0; dlg->m_ColorFix = t->flags3 & COLORFIX ? 1 : 0; dlg->m_NoPixelFormat = t->flags3 & NOPIXELFORMAT ? 1 : 0; dlg->m_NoAlphaChannel = t->flags4 & NOALPHACHANNEL ? 1 : 0; @@ -596,6 +600,7 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg) dlg->m_InitTS = t->InitTS+8; dlg->m_FakeVersionId = t->FakeVersionId; dlg->m_MaxScreenRes = t->MaxScreenRes; + dlg->m_SwapEffect = t->SwapEffect; } static void SaveConfigItem(TARGETMAP *TargetMap, PRIVATEMAP *PrivateMap, int i, char *InitPath) @@ -634,6 +639,9 @@ static void SaveConfigItem(TARGETMAP *TargetMap, PRIVATEMAP *PrivateMap, int i, sprintf_s(key, sizeof(key), "flagj%i", i); sprintf_s(val, sizeof(val), "%i", TargetMap->flags5); WritePrivateProfileString("target", key, val, InitPath); + sprintf_s(key, sizeof(key), "flagk%i", i); + sprintf_s(val, sizeof(val), "%i", TargetMap->flags6); + WritePrivateProfileString("target", key, val, InitPath); sprintf_s(key, sizeof(key), "tflag%i", i); sprintf_s(val, sizeof(val), "%i", TargetMap->tflags); WritePrivateProfileString("target", key, val, InitPath); @@ -680,6 +688,9 @@ static void SaveConfigItem(TARGETMAP *TargetMap, PRIVATEMAP *PrivateMap, int i, sprintf_s(key, sizeof(key), "maxres%i", i); sprintf_s(val, sizeof(val), "%i", TargetMap->MaxScreenRes); WritePrivateProfileString("target", key, val, InitPath); + sprintf_s(key, sizeof(key), "swapeffect%i", i); + sprintf_s(val, sizeof(val), "%i", TargetMap->SwapEffect); + WritePrivateProfileString("target", key, val, InitPath); } static void ClearTarget(int i, char *InitPath) @@ -703,6 +714,8 @@ static void ClearTarget(int i, char *InitPath) WritePrivateProfileString("target", key, 0, InitPath); sprintf_s(key, sizeof(key), "flagj%i", i); WritePrivateProfileString("target", key, 0, InitPath); + sprintf_s(key, sizeof(key), "flagk%i", i); + WritePrivateProfileString("target", key, 0, InitPath); sprintf_s(key, sizeof(key), "tflag%i", i); WritePrivateProfileString("target", key, 0, InitPath); sprintf_s(key, sizeof(key), "initx%i", i); @@ -727,6 +740,8 @@ static void ClearTarget(int i, char *InitPath) WritePrivateProfileString("target", key, 0, InitPath); sprintf_s(key, sizeof(key), "maxfps%i", i); WritePrivateProfileString("target", key, 0, InitPath); + sprintf_s(key, sizeof(key), "swapeffect%i", i); + WritePrivateProfileString("target", key, 0, InitPath); sprintf_s(key, sizeof(key), "initts%i", i); WritePrivateProfileString("target", key, 0, InitPath); @@ -770,6 +785,8 @@ static int LoadConfigItem(TARGETMAP *TargetMap, PRIVATEMAP *PrivateMap, int i, c TargetMap->flags4 = GetPrivateProfileInt("target", key, 0, InitPath); sprintf_s(key, sizeof(key), "flagj%i", i); TargetMap->flags5 = GetPrivateProfileInt("target", key, 0, InitPath); + sprintf_s(key, sizeof(key), "flagk%i", i); + TargetMap->flags6 = GetPrivateProfileInt("target", key, 0, InitPath); sprintf_s(key, sizeof(key), "tflag%i", i); TargetMap->tflags = GetPrivateProfileInt("target", key, 0, InitPath); sprintf_s(key, sizeof(key), "initx%i", i); @@ -796,7 +813,8 @@ static int LoadConfigItem(TARGETMAP *TargetMap, PRIVATEMAP *PrivateMap, int i, c TargetMap->MaxFPS = GetPrivateProfileInt("target", key, 0, InitPath); sprintf_s(key, sizeof(key), "initts%i", i); TargetMap->InitTS = GetPrivateProfileInt("target", key, 0, InitPath); - + sprintf_s(key, sizeof(key), "swapeffect%i", i); + TargetMap->SwapEffect = GetPrivateProfileInt("target", key, 0, InitPath); sprintf_s(key, sizeof(key), "winver%i", i); TargetMap->FakeVersionId = GetPrivateProfileInt("target", key, 0, InitPath); sprintf_s(key, sizeof(key), "maxres%i", i); diff --git a/host/resource b/host/resource index 162bf7c..80e061a 100644 Binary files a/host/resource and b/host/resource differ