diff --git a/build/dxwnd.dll b/build/dxwnd.dll index 0e698fd..e23cee5 100644 --- a/build/dxwnd.dll +++ b/build/dxwnd.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e28f7cec6d5eae185c1bdf2c27ab49e1357051f487c243b60f5d25b11172c21f -size 694784 +oid sha256:aefbbf270e55f04618178767c563b732a273e29eac1e0a68a42bd15c1be21058 +size 697856 diff --git a/build/exports/Aztec Wars.dxw b/build/exports/Aztec Wars.dxw new file mode 100644 index 0000000..0cb2426 --- /dev/null +++ b/build/exports/Aztec Wars.dxw @@ -0,0 +1,35 @@ +[target] +title0=Aztec Wars +path0=F:\Games\Aztec Wars\The Aztec\Aztec.exe +startfolder0= +launchpath0= +module0= +opengllib0= +notes0= +registry0= +ver0=0 +monitorid0=-1 +coord0=0 +flag0=136314914 +flagg0=1207959552 +flagh0=20 +flagi0=138412036 +flagj0=67113088 +flagk0=65536 +flagl0=65536 +flagm0=0 +tflag0=0 +dflag0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 +swapeffect0=0 +maxddinterface0=7 +slowratio0=2 +initresw0=800 +initresh0=600 diff --git a/build/exports/FIFA 2000.dxw b/build/exports/FIFA 2000.dxw new file mode 100644 index 0000000..164eaa0 --- /dev/null +++ b/build/exports/FIFA 2000.dxw @@ -0,0 +1,35 @@ +[target] +title0=FIFA 2000 +path0=F:\Games\FIFA2000\fifa2000.exe +startfolder0= +launchpath0= +module0= +opengllib0= +notes0=Securdrive protected - needs crack +registry0= +ver0=0 +monitorid0=-1 +coord0=0 +flag0=752877602 +flagg0=1216348160 +flagh0=20 +flagi0=205520900 +flagj0=4224 +flagk0=65536 +flagl0=0 +flagm0=0 +tflag0=0 +dflag0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 +swapeffect0=0 +maxddinterface0=7 +slowratio0=2 +initresw0=800 +initresh0=600 diff --git a/build/exports/Gunbound (fullscreen).dxw b/build/exports/Gunbound (fullscreen).dxw new file mode 100644 index 0000000..428eb85 --- /dev/null +++ b/build/exports/Gunbound (fullscreen).dxw @@ -0,0 +1,35 @@ +[target] +title0=Gunbound (fullscreen) +path0=F:\Games\GunboundGitzWC\gitzgame.exe +startfolder0= +launchpath0= +module0= +opengllib0= +notes0= +registry0= +ver0=0 +monitorid0=0 +coord0=1 +flag0=681582626 +flagg0=1073741840 +flagh0=20 +flagi0=136314884 +flagj0=4224 +flagk0=67584 +flagl0=0 +flagm0=0 +tflag0=0 +dflag0=0 +posx0=50 +posy0=50 +sizx0=0 +sizy0=0 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 +swapeffect0=0 +maxddinterface0=7 +slowratio0=2 +initresw0=0 +initresh0=0 diff --git a/build/exports/Nascar Racing 3.dxw b/build/exports/Nascar Racing 3.dxw index 1c2409b..907127f 100644 --- a/build/exports/Nascar Racing 3.dxw +++ b/build/exports/Nascar Racing 3.dxw @@ -1,15 +1,15 @@ [target] -title0=Nascar Racing 3 -path0=D:\Games\Nascar Racing 3\NASCAR Racing 3.exe +title0=NASCAR Racing 3 +path0=G:\Games\Nascar Racing 3\NASCAR Racing 3.exe module0= opengllib0= ver0=0 coord0=0 -flag0=671105056 +flag0=136314914 flagg0=1207959552 flagh0=20 -flagi0=4 -tflag0=6163 +flagi0=134217732 +tflag0=0 initx0=0 inity0=0 minx0=0 @@ -22,3 +22,20 @@ sizx0=800 sizy0=600 maxfps0=0 initts0=0 +startfolder0= +launchpath0= +notes0= +registry0= +monitorid0=-1 +flagj0=4224 +flagk0=65536 +flagl0=0 +flagm0=0 +dflag0=0 +winver0=0 +maxres0=-1 +swapeffect0=0 +maxddinterface0=7 +slowratio0=2 +initresw0=800 +initresh0=600 diff --git a/build/readme-relnotes.txt b/build/readme-relnotes.txt index 87d28d4..5f91a71 100644 --- a/build/readme-relnotes.txt +++ b/build/readme-relnotes.txt @@ -1319,4 +1319,13 @@ fix: avoid issuing a GetPalette method against a deallocated object fix: automatic creation of Clipper object if needed for emulated ddraw blit to primary surface - fixes the well known black blitting problem fix: proper handling of dinput DirectInputDevice::GetDeviceData() DI_BUFFEROVERFLOW error condition fix: user32 GetCursorPos() wrapper -fix: user32 mouse_event() wrapper \ No newline at end of file +fix: user32 mouse_event() wrapper + +v2.03.94.fx1-2: +fix: aligned Lock cheats in Direct/Indirect mode ...... +fix: no window interventions in non windowed mode. Fix "Gunbound" in fullscreen mode +fix: avoid multiple injection for early-hooked programs. Fix "Gunbound" regression. +fix: Restore of all lost surfaces upon D3D BeginScene DDERR_LOSTSURFACE error. Fix "Gunbound" lost textures in fullscreen mode. +add: more logging in mciSendCommand - possibly some regression problem... +fix: corrected clipping bug introduced in v2.03.93. +fix: SetWindowLog hooker preventing to set DxWnd windowproc when not in fullscreen mode. Fixes "Nascar Racing 3" recursion and crash. \ No newline at end of file diff --git a/dll/ddblit.cpp b/dll/ddblit.cpp index ca0d914..647bca1 100644 --- a/dll/ddblit.cpp +++ b/dll/ddblit.cpp @@ -8,8 +8,6 @@ #include "hddraw.h" #include "dxhelper.h" -#define FIXBIGGERRECT 1 - extern LPDIRECTDRAWSURFACE lpDDSEmu_Prim; extern LPDIRECTDRAW lpPrimaryDD; extern Blt_Type pBlt; @@ -167,20 +165,20 @@ static HRESULT sBltToPrimary(int dxversion, Blt_Type pBlt, char *api, LPDIRECTDR } #endif -#if FIXBIGGERRECT // seems necessary to "cure" the "FIFA 2000" soccer game in hw accelerated graphics, when the Unlock() method // receives RECT coordinates with big positive or negative numbers! + // v2.03.94fx1: "FIFA2002" is ok with Unlock rect set to Lock previous value, but other games ("Aztec Wars", ...) + // require some software clipping when moving the cursor outside the window or similar cases if(lpdestrect){ if(lpdestrect->top < 0) lpdestrect->top = 0; - if(lpdestrect->top > (LONG)dxw.GetScreenWidth()) lpdestrect->top = 0; + if(lpdestrect->top > (LONG)dxw.GetScreenHeight()) lpdestrect->top = dxw.GetScreenHeight(); if(lpdestrect->left < 0) lpdestrect->left = 0; - if(lpdestrect->left > (LONG)dxw.GetScreenHeight()) lpdestrect->left = 0; + if(lpdestrect->left > (LONG)dxw.GetScreenWidth()) lpdestrect->left = (LONG)dxw.GetScreenWidth(); if(lpdestrect->bottom > (LONG)dxw.GetScreenHeight()) lpdestrect->bottom = dxw.GetScreenHeight(); if(lpdestrect->right > (LONG)dxw.GetScreenWidth()) lpdestrect->right = dxw.GetScreenWidth(); - if(lpdestrect->bottom < lpdestrect->top) lpdestrect->bottom = (LONG)dxw.GetScreenHeight(); - if(lpdestrect->right < lpdestrect->left) lpdestrect->right = (LONG)dxw.GetScreenWidth(); + if(lpdestrect->bottom < lpdestrect->top) lpdestrect->bottom = lpdestrect->top; + if(lpdestrect->right < lpdestrect->left) lpdestrect->right = lpdestrect->left; } -#endif if(dxw.dwFlags5 & QUARTERBLT){ BOOL QuarterUpdate; diff --git a/dll/ddraw.cpp b/dll/ddraw.cpp index d31d507..77de78c 100644 --- a/dll/ddraw.cpp +++ b/dll/ddraw.cpp @@ -4434,6 +4434,24 @@ DDSURFACEDESC SaveSurfaceDesc; LPDIRECTDRAWSURFACE SaveSurface = NULL; LPRECT SaveLockedlpRect = NULL; RECT SaveLockedRect; +LPDIRECTDRAWSURFACE SaveLockedSurface = NULL; + +static void PushLockedRect(LPDIRECTDRAWSURFACE lpdds, LPRECT lprect) +{ + SaveLockedSurface = lpdds; + SaveLockedlpRect = lprect; + if(SaveLockedlpRect) SaveLockedRect = *lprect; +} + +static LPRECT PopLockedRect(LPDIRECTDRAWSURFACE lpdds, LPRECT lprect) +{ + if(lpdds == SaveLockedSurface){ + SaveLockedSurface = NULL; + return SaveLockedlpRect; + } + else + return lprect; +} static HRESULT WINAPI extLock(int dxversion, Lock_Type pLock, LPDIRECTDRAWSURFACE lpdds, LPRECT lprect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD flags, HANDLE hEvent) { @@ -4450,19 +4468,18 @@ static HRESULT WINAPI extLock(int dxversion, Lock_Type pLock, LPDIRECTDRAWSURFAC dxversion, lpdds, (IsPrim ? "(PRIM)":""), flags, ExplainLockFlags(flags), lpDDSurfaceDesc, sRect); } - SaveLockedlpRect = lprect; - if(SaveLockedlpRect) SaveLockedRect = *lprect; + PushLockedRect(lpdds, lprect); res=(*pLock)(lpdds, lprect, lpDDSurfaceDesc, flags, hEvent); if(res==DDERR_SURFACEBUSY){ // v70: fix for "Ancient Evil" (*pUnlockMethod(dxversion))(lpdds, NULL); res = (*pLock)(lpdds, lprect, lpDDSurfaceDesc, flags, hEvent); - OutTraceDW("Lock RETRY: ret=%x(%s)\n", res, ExplainDDError(res)); + OutTraceDW("Lock SURFACEBUSY RETRY: ret=%x(%s)\n", res, ExplainDDError(res)); } if(res==DDERR_SURFACELOST){ lpdds->Restore(); res = (*pLock)(lpdds, lprect, lpDDSurfaceDesc, flags, hEvent); - OutTraceDW("Lock RETRY: ret=%x(%s)\n", res, ExplainDDError(res)); + OutTraceDW("Lock SURFACELOST RETRY: ret=%x(%s)\n", res, ExplainDDError(res)); } if(res) OutTraceE("Lock ERROR: ret=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); OutTraceB("Lock: lPitch=%d lpSurface=%x ZBufferBitDepth=%d %s\n", @@ -4517,8 +4534,7 @@ static HRESULT WINAPI extLockDir(int dxversion, Lock_Type pLock, LPDIRECTDRAWSUR dxversion, lpdds, (IsPrim ? "(PRIM)":""), flags, ExplainLockFlags(flags), lpDDSurfaceDesc, sRect); } - SaveLockedlpRect = lprect; - if(SaveLockedlpRect) SaveLockedRect = *lprect; + PushLockedRect(lpdds, lprect); switch(dxversion){ case 1: pBlt=pBlt1; pGetGDISurface=pGetGDISurface1; break; @@ -4578,6 +4594,16 @@ static HRESULT WINAPI extLockDir(int dxversion, Lock_Type pLock, LPDIRECTDRAWSUR } res=(*pLock)(lpdds, lprect, lpDDSurfaceDesc, flags, hEvent); + if(res==DDERR_SURFACEBUSY){ // v70: fix for "Ancient Evil" + (*pUnlockMethod(dxversion))(lpdds, NULL); + res = (*pLock)(lpdds, lprect, lpDDSurfaceDesc, flags, hEvent); + OutTraceDW("Lock SURFACEBUSY RETRY: ret=%x(%s)\n", res, ExplainDDError(res)); + } + if(res==DDERR_SURFACELOST){ + lpdds->Restore(); + res = (*pLock)(lpdds, lprect, lpDDSurfaceDesc, flags, hEvent); + OutTraceDW("Lock SURFACELOST RETRY: ret=%x(%s)\n", res, ExplainDDError(res)); + } if(res) OutTraceE("Lock ERROR: ret=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); OutTraceB("Lock: lPitch=%d lpSurface=%x ZBufferBitDepth=%d %s\n", @@ -4589,6 +4615,11 @@ static HRESULT WINAPI extLockDir(int dxversion, Lock_Type pLock, LPDIRECTDRAWSUR if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK; + if((dxw.dwFlags6 & FIXPITCH) || (dxw.dwFlags3 & MARKLOCK)){ + SaveSurfaceDesc = *lpDDSurfaceDesc; + SaveSurface = lpdds; + } + return res; } @@ -4647,7 +4678,7 @@ static HRESULT WINAPI extUnlock(int dxversion, Unlock4_Type pUnlock, LPDIRECTDRA // v2.02.92: found in Fifa 2000: lpRect is completely ignored, receiving bogus values like (-1, -1, -1, -1} // or {0, 0, 0, 0}, or {-109119151, -109119151, -109119151, -109119151}. // better use the Lock-ed rect - if(IsPrim) lprect = SaveLockedlpRect; + lprect = PopLockedRect(lpdds, lprect); } if((dxw.dwFlags6 & FIXPITCH) && !(IsPrim||IsBack) && (lpdds == SaveSurface)){ @@ -4739,7 +4770,7 @@ static HRESULT WINAPI extUnlockDir(int dxversion, Unlock4_Type pUnlock, LPDIRECT // v2.02.92: found in Fifa 2000: lpRect is completely ignored, receiving bogus values like (-1, -1, -1, -1} // or {0, 0, 0, 0}, or {-109119151, -109119151, -109119151, -109119151}. // better use the Lock-ed rect - if(IsPrim) lprect = SaveLockedlpRect; + lprect = PopLockedRect(lpdds, lprect); } if(IsTraceDDRAW){ diff --git a/dll/dxhook.cpp b/dll/dxhook.cpp index b402145..1b82994 100644 --- a/dll/dxhook.cpp +++ b/dll/dxhook.cpp @@ -689,7 +689,7 @@ void AdjustWindowFrame(HWND hwnd, DWORD width, DWORD height) (*pSetWindowLongA)(hwnd, GWL_EXSTYLE, exstyle); (*pShowWindow)(hwnd, SW_SHOWNORMAL); OutTraceDW("AdjustWindowFrame hwnd=%x, set style=%s extstyle=0\n", hwnd, (style == 0) ? "0" : "WS_OVERLAPPEDWINDOW"); - AdjustWindowPos(hwnd, width, height); + if (dxw.Windowize) AdjustWindowPos(hwnd, width, height); // fixing windows message handling procedure HookWindowProc(hwnd); diff --git a/dll/dxmapping.cpp b/dll/dxmapping.cpp index 116dc55..2b29b3f 100644 --- a/dll/dxmapping.cpp +++ b/dll/dxmapping.cpp @@ -485,6 +485,7 @@ void dxwCore::CalculateWindowPos(HWND hwnd, DWORD width, DWORD height, LPWINDOWP void dxwCore::AutoScale() { WINDOWPOS wp; + if(!dxw.Windowize) return; CalculateWindowPos(hWnd, dwScreenWidth, dwScreenHeight, &wp); OutTrace("AutoScale: new pos=(%d,%d) size=(%dx%d)\n", wp.x, wp.y, wp.cx, wp.cy); if(!(*pSetWindowPos)(hWnd, 0, wp.x, wp.y, wp.cx, wp.cy, 0)){ diff --git a/dll/dxwnd.cpp b/dll/dxwnd.cpp index 8e0f06b..a685fc6 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.93" +#define VERSION "2.03.94.fx2" #define DDTHREADLOCK 1 //#define LOCKTHREADS @@ -265,13 +265,15 @@ void InjectHook() int i; GetModuleFileName(0, name, MAX_PATH); name[MAX_PATH]=0; // terminator - for(i = 0; name[i]; i ++) name[i] = tolower(name[i]); + for(char *c = name; *c; c++) *c = tolower(*c); for(i = 0; pMapping[i].path[0]; i ++){ - if(pMapping[i].flags3 & HOOKENABLED){ - if(!strncmp(name, pMapping[i].path, strlen(name))){ - HookInit(&pMapping[i],NULL); - // beware: logging is possible only AFTER HookInit execution - OutTrace("InjectHook: task[%d]=\"%s\" hooked\n", i, pMapping[i].path); + if(pMapping[i].flags3 & HOOKENABLED){ + if(!strncmp(name, pMapping[i].path, strlen(name))){ + if ((pMapping[i].flags2 & STARTDEBUG) || (pMapping[i].flags7 & INJECTSUSPENDED)) { + HookInit(&pMapping[i],NULL); + // beware: logging is possible only AFTER HookInit execution + OutTrace("InjectHook: task[%d]=\"%s\" hooked\n", i, pMapping[i].path); + } break; } } diff --git a/dll/dxwnd.vs2008.suo b/dll/dxwnd.vs2008.suo index 3d2b464..04e5384 100644 Binary files a/dll/dxwnd.vs2008.suo and b/dll/dxwnd.vs2008.suo differ diff --git a/dll/hd3d7.cpp b/dll/hd3d7.cpp index 2bf5107..f529574 100644 --- a/dll/hd3d7.cpp +++ b/dll/hd3d7.cpp @@ -12,6 +12,8 @@ //#undef OutTraceD3D //#define OutTraceD3D OutTrace +extern LPDIRECTDRAW lpPrimaryDD; + // exported API typedef HRESULT (WINAPI *Direct3DCreateDevice_Type)(GUID FAR *, LPDIRECT3D, LPDIRECTDRAWSURFACE, LPDIRECT3D *, LPUNKNOWN); @@ -542,8 +544,8 @@ void HookDirect3DDevice(void **lpd3ddev, int d3dversion) case 7: //SetHook((void *)(**(DWORD **)lpd3ddev + 0), extQueryInterfaceD3D, (void **)&pQueryInterfaceD3D, "QueryInterface(D3D)"); SetHook((void *)(**(DWORD **)lpd3ddev + 8), extReleaseD3D7, (void **)&pReleaseD3D7, "ReleaseD3D(7)"); - //SetHook((void *)(**(DWORD **)lpd3ddev + 20), extBeginScene7, (void **)&pBeginScene7, "BeginScene(7)"); - //SetHook((void *)(**(DWORD **)lpd3ddev + 24), extEndScene7, (void **)&pEndScene7, "EndScene(7)"); + SetHook((void *)(**(DWORD **)lpd3ddev + 20), extBeginScene7, (void **)&pBeginScene7, "BeginScene(7)"); + SetHook((void *)(**(DWORD **)lpd3ddev + 24), extEndScene7, (void **)&pEndScene7, "EndScene(7)"); //SetHook((void *)(**(DWORD **)lpd3ddev + 52), extSetViewport7, (void **)&pSetViewport7, "SetViewport(7)"); //SetHook((void *)(**(DWORD **)lpd3ddev + 60), extGetViewport7, (void **)&pGetViewport7, "GetViewport(7)"); SetHook((void *)(**(DWORD **)lpd3ddev + 80), extSetRenderState7, (void **)&pSetRenderState7, "SetRenderState(7)"); @@ -1188,15 +1190,48 @@ HRESULT WINAPI extSetRenderState7(void *d3dd, D3DRENDERSTATETYPE State, DWORD Va return extSetRenderState(pSetRenderState7, 7, d3dd, State, Value); } +static HRESULT WINAPI dxwRestoreCallback(LPDIRECTDRAWSURFACE lpDDSurface, LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext) +{ + HRESULT res; + OutTrace("dxwRestoreCallback: ANALYZING lpdds=%x\n", lpDDSurface); + if(lpDDSurface->IsLost()){ + if(res=lpDDSurface->Restore()){ + OutTrace("dxwRestoreCallback: RESTORE FAILED lpdds=%x err=%x(%s)\n", lpDDSurface, res, ExplainDDError(res)); + return DDENUMRET_CANCEL; + } + OutTrace("dxwRestoreCallback: RESTORED lpdds=%x\n", lpDDSurface); + } + return DDENUMRET_OK; +} + HRESULT WINAPI extBeginScene1(void *d3dd) { HRESULT res; OutTraceD3D("BeginScene(1): d3dd=%x\n", d3dd); res=(*pBeginScene1)(d3dd); + if(res == DDERR_SURFACELOST){ + OutTraceDW("BeginScene: recovering from DDERR_SURFACELOST\n"); + lpPrimaryDD->EnumSurfaces(DDENUMSURFACES_DOESEXIST|DDENUMSURFACES_ALL, NULL, NULL, (LPDDENUMSURFACESCALLBACK)dxwRestoreCallback); + res=(*pBeginScene1)(d3dd); + } if(res) OutTraceE("BeginScene(1): res=%x(%s)\n", res, ExplainDDError(res)); return res; } +static HRESULT WINAPI dxwRestoreCallback2(LPDIRECTDRAWSURFACE4 lpDDSurface, LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID lpContext) +{ + HRESULT res; + OutTrace("dxwRestoreCallback2: ANALYZING lpdds=%x\n", lpDDSurface); + if(lpDDSurface->IsLost()){ + if(res=lpDDSurface->Restore()){ + OutTrace("dxwRestoreCallback2: RESTORE FAILED lpdds=%x err=%x(%s)\n", lpDDSurface, res, ExplainDDError(res)); + return DDENUMRET_CANCEL; + } + OutTrace("dxwRestoreCallback2: RESTORED lpdds=%x\n", lpDDSurface); + } + return DDENUMRET_OK; +} + HRESULT WINAPI extBeginScene2(void *d3dd) { HRESULT res; @@ -1220,6 +1255,11 @@ HRESULT WINAPI extBeginScene2(void *d3dd) } } res=(*pBeginScene2)(d3dd); + if(res == DDERR_SURFACELOST){ + OutTraceDW("BeginScene: recovering from DDERR_SURFACELOST\n"); + lpPrimaryDD->EnumSurfaces(DDENUMSURFACES_DOESEXIST|DDENUMSURFACES_ALL, NULL, NULL, (LPDDENUMSURFACESCALLBACK)dxwRestoreCallback2); + res=(*pBeginScene2)(d3dd); + } if(res) OutTraceE("BeginScene(2): res=%x(%s)\n", res, ExplainDDError(res)); return res; } @@ -1248,10 +1288,29 @@ HRESULT WINAPI extBeginScene3(void *d3dd) } } res=(*pBeginScene3)(d3dd); + if(res == DDERR_SURFACELOST){ + OutTraceDW("BeginScene: recovering from DDERR_SURFACELOST\n"); + lpPrimaryDD->EnumSurfaces(DDENUMSURFACES_DOESEXIST|DDENUMSURFACES_ALL, NULL, NULL, (LPDDENUMSURFACESCALLBACK)dxwRestoreCallback2); + res=(*pBeginScene3)(d3dd); + } if(res) OutTraceE("BeginScene(3): res=%x(%s)\n", res, ExplainDDError(res)); return res; } +static HRESULT WINAPI dxwRestoreCallback7(LPDIRECTDRAWSURFACE7 lpDDSurface, LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID lpContext) +{ + HRESULT res; + OutTrace("dxwRestoreCallback7: ANALYZING lpdds=%x\n", lpDDSurface); + if(lpDDSurface->IsLost()){ + if(res=lpDDSurface->Restore()){ + OutTrace("dxwRestoreCallback7: RESTORE FAILED lpdds=%x err=%x(%s)\n", lpDDSurface, res, ExplainDDError(res)); + return DDENUMRET_CANCEL; + } + OutTrace("dxwRestoreCallback7: RESTORED lpdds=%x\n", lpDDSurface); + } + return DDENUMRET_OK; +} + HRESULT WINAPI extBeginScene7(void *d3dd) { HRESULT res; @@ -1260,6 +1319,11 @@ HRESULT WINAPI extBeginScene7(void *d3dd) // there is no Clear method for Viewport object in D3D7 !!! res=(*pBeginScene7)(d3dd); + if(res == DDERR_SURFACELOST){ + OutTraceDW("BeginScene: recovering from DDERR_SURFACELOST\n"); + lpPrimaryDD->EnumSurfaces(DDENUMSURFACES_DOESEXIST|DDENUMSURFACES_ALL, NULL, NULL, (LPDDENUMSURFACESCALLBACK)dxwRestoreCallback7); + res=(*pBeginScene7)(d3dd); + } if(res) OutTraceE("BeginScene(7): res=%x(%s)\n", res, ExplainDDError(res)); return res; } diff --git a/dll/logall.h b/dll/logall.h index 1ea6b23..9e8d71e 100644 --- a/dll/logall.h +++ b/dll/logall.h @@ -30,3 +30,7 @@ #undef IsTraceE #define IsTraceE TRUE #endif +#ifdef IsDebug +#undef IsDebug +#define IsDebug TRUE +#endif diff --git a/dll/user32.cpp b/dll/user32.cpp index 71ee4ca..76d0974 100644 --- a/dll/user32.cpp +++ b/dll/user32.cpp @@ -843,8 +843,11 @@ LONG WINAPI extSetWindowLong(HWND hwnd, int nIndex, LONG dwNewLong, SetWindowLon } } + // v2.03.94.fx2: removed dxw.IsFullScreen() check here ... WinProc routine must be verified in all conditions + // fixes "Nascar Racing 3" that was setting the WinProc while still in non fullscreen mode! if (((nIndex==GWL_WNDPROC)||(nIndex==DWL_DLGPROC)) && - dxw.IsFullScreen() && // v2.02.51 - see A10 Cuba.... + dxw.Windowize && // v2.03.95 - replaced dxw.IsFullScreen() check + // dxw.IsFullScreen() && // v2.02.51 - see A10 Cuba.... !(dxw.dwFlags6 & NOWINDOWHOOKS)){ // v2.03.41 - debug flag WNDPROC lres; WNDPROC OldProc; @@ -856,7 +859,8 @@ LONG WINAPI extSetWindowLong(HWND hwnd, int nIndex, LONG dwNewLong, SetWindowLon } // GPL fix - if(dxw.IsRealDesktop(hwnd) && dxw.Windowize) { + // v2.03.94.fx2: moved dxw.IsFullScreen() check here ... + if(dxw.IsRealDesktop(hwnd) && dxw.Windowize && dxw.IsFullScreen()) { hwnd=dxw.GethWnd(); OutTraceDW("SetWindowLong: DESKTOP hwnd, FIXING hwnd=%x\n",hwnd); } diff --git a/dll/winmm.cpp b/dll/winmm.cpp index b6d0e41..f3575a6 100644 --- a/dll/winmm.cpp +++ b/dll/winmm.cpp @@ -15,7 +15,7 @@ #define EMULATEJOY TRUE #define INVERTJOYAXIS TRUE -// #include "logall.h" // comment when not debugging +#include "logall.h" // comment when not debugging BOOL IsWithinMCICall = FALSE; @@ -137,81 +137,222 @@ MMRESULT WINAPI exttimeKillEvent(UINT uTimerID) You can use the MCI_GETDEVCAPS_CAN_STRETCH flag with the MCI_GETDEVCAPS command to determine if a device scales the image. A device returns FALSE if it cannot scale the image. */ -MCIERROR WINAPI extmciSendCommand(mciSendCommand_Type pmciSendCommand, MCIDEVICEID IDDevice, UINT uMsg, DWORD_PTR fdwCommand, DWORD_PTR dwParam) +static char *sStatusItem(DWORD dwItem) +{ + char *s; + switch(dwItem){ + case MCI_STATUS_LENGTH: s = "LENGTH"; break; + case MCI_STATUS_POSITION: s = "POSITION"; break; + case MCI_STATUS_NUMBER_OF_TRACKS: s = "NUMBER_OF_TRACKS"; break; + case MCI_STATUS_MODE: s = "MODE"; break; + case MCI_STATUS_MEDIA_PRESENT: s = "MEDIA_PRESENT"; break; + case MCI_STATUS_TIME_FORMAT: s = "TIME_FORMAT"; break; + case MCI_STATUS_READY: s = "READY"; break; + case MCI_STATUS_CURRENT_TRACK: s = "CURRENT_TRACK"; break; + default: s = "???"; break; + } + return s; +} + +static char *sDeviceType(DWORD dt) +{ + char *s; + switch(dt){ + case MCI_ALL_DEVICE_ID: s="ALL_DEVICE_ID"; break; + case MCI_DEVTYPE_VCR: s="VCR"; break; + case MCI_DEVTYPE_VIDEODISC: s="VIDEODISC"; break; + case MCI_DEVTYPE_OVERLAY: s="OVERLAY"; break; + case MCI_DEVTYPE_CD_AUDIO: s="CD_AUDIO"; break; + case MCI_DEVTYPE_DAT: s="DAT"; break; + case MCI_DEVTYPE_SCANNER: s="SCANNER"; break; + case MCI_DEVTYPE_ANIMATION: s="ANIMATION"; break; + case MCI_DEVTYPE_DIGITAL_VIDEO: s="DIGITAL_VIDEO"; break; + case MCI_DEVTYPE_OTHER: s="OTHER"; break; + case MCI_DEVTYPE_WAVEFORM_AUDIO: s="WAVEFORM_AUDIO"; break; + case MCI_DEVTYPE_SEQUENCER: s="SEQUENCER"; break; + default: s="unknown"; break; + } + return s; +} + +static void DumpMciMessage(char *label, BOOL isAnsi, UINT uMsg, DWORD_PTR fdwCommand, DWORD_PTR dwParam) +{ + switch(uMsg){ + case MCI_BREAK: + { + LPMCI_BREAK_PARMS lpBreak = (LPMCI_BREAK_PARMS)dwParam; + OutTrace("mciSendCommand%s: MCI_BREAK cb=%x virtkey=%d hwndbreak=%x\n", + label, lpBreak->dwCallback, lpBreak->nVirtKey, lpBreak->hwndBreak); + } + break; + case MCI_INFO: + { + LPMCI_INFO_PARMS lpInfo = (LPMCI_INFO_PARMS)dwParam; + OutTrace("mciSendCommand%s: MCI_INFO cb=%x retsize=%x\n", + label, lpInfo->dwCallback, lpInfo->dwRetSize); + } + break; + case MCI_PLAY: + { + LPMCI_PLAY_PARMS lpPlay = (LPMCI_PLAY_PARMS)dwParam; + OutTrace("mciSendCommand%s: MCI_PLAY cb=%x from=%x to=%x\n", + label, lpPlay->dwCallback, lpPlay->dwFrom, lpPlay->dwTo); + } + break; + case MCI_GETDEVCAPS: + { + LPMCI_GETDEVCAPS_PARMS lpDevCaps = (LPMCI_GETDEVCAPS_PARMS)dwParam; + OutTrace("mciSendCommand%s: MCI_GETDEVCAPS cb=%x ret=%x item=%x\n", + label, lpDevCaps->dwCallback, lpDevCaps->dwReturn, lpDevCaps->dwItem); + } + break; + case MCI_OPEN: + { + DWORD dwFlags = (DWORD)fdwCommand; + // how to dump LPMCI_OPEN_PARMS strings without crash? + if(isAnsi){ + LPMCI_OPEN_PARMSA lpOpen = (LPMCI_OPEN_PARMSA)dwParam; + OutTrace("mciSendCommand%s: MCI_OPEN %scb=%x devid=%x devtype=%s elementname=%s alias=%s\n", + label, + (dwFlags & MCI_OPEN_SHAREABLE) ? "OPEN_SHAREABLE " : "", + lpOpen->dwCallback, lpOpen->wDeviceID, + "", //(dwFlags & MCI_OPEN_TYPE) ? lpOpen->lpstrDeviceType : "", + (dwFlags & MCI_OPEN_ELEMENT) ? lpOpen->lpstrElementName : "", + (dwFlags & MCI_OPEN_ALIAS) ? lpOpen->lpstrAlias : ""); + } + else{ + LPMCI_OPEN_PARMSW lpOpen = (LPMCI_OPEN_PARMSW)dwParam; + OutTrace("mciSendCommand%s: MCI_OPEN cb=%x devid=%x devtype=%ls elementname=%ls alias=%ls\n", + label, + (dwFlags & MCI_OPEN_SHAREABLE) ? "OPEN_SHAREABLE " : "", + lpOpen->dwCallback, lpOpen->wDeviceID, + L"", //(dwFlags & MCI_OPEN_TYPE) ? lpOpen->lpstrDeviceType : L"", + (dwFlags & MCI_OPEN_ELEMENT) ? lpOpen->lpstrElementName : L"", + (dwFlags & MCI_OPEN_ALIAS) ? lpOpen->lpstrAlias : L""); + } + } + break; + case MCI_STATUS: + { + LPMCI_STATUS_PARMS lpStatus = (LPMCI_STATUS_PARMS)dwParam; + OutTrace("mciSendCommand%s: MCI_STATUS cb=%x ret=%x item=%x(%s) track=%x\n", + label, lpStatus->dwCallback, lpStatus->dwReturn, lpStatus->dwItem, sStatusItem(lpStatus->dwItem), lpStatus->dwTrack); + } + break; + case MCI_SYSINFO: + { + LPMCI_SYSINFO_PARMS lpSysInfo = (LPMCI_SYSINFO_PARMS)dwParam; + OutTrace("mciSendCommand%s: MCI_SYSINFO cb=%x retsize=%x number=%x devtype=%x(%s)\n", + label, lpSysInfo->dwCallback, lpSysInfo->dwRetSize, lpSysInfo->dwNumber, lpSysInfo->wDeviceType, sDeviceType(lpSysInfo->wDeviceType)); + } + break; + default: + { + LPMCI_GENERIC_PARMS lpGeneric = (LPMCI_GENERIC_PARMS)dwParam; + OutTrace("mciSendCommand%s: %s cb=%x\n", + label, ExplainMCICommands(uMsg), lpGeneric->dwCallback); + } + break; + } +} + +MCIERROR WINAPI extmciSendCommand(BOOL isAnsi, mciSendCommand_Type pmciSendCommand, MCIDEVICEID IDDevice, UINT uMsg, DWORD_PTR fdwCommand, DWORD_PTR dwParam) { RECT saverect; MCIERROR ret; MCI_ANIM_RECT_PARMS *pr; MCI_OVLY_WINDOW_PARMSW *pw; - OutTraceDW("mciSendCommand: IDDevice=%x msg=%x(%s) Command=%x(%s)\n", - IDDevice, uMsg, ExplainMCICommands(uMsg), fdwCommand, ExplainMCIFlags(uMsg, fdwCommand)); + OutTraceDW("mciSendCommand%c: IDDevice=%x msg=%x(%s) Command=%x(%s)\n", + isAnsi ? 'A' : 'W', + IDDevice, + uMsg, ExplainMCICommands(uMsg), + fdwCommand, ExplainMCIFlags(uMsg, fdwCommand)); + + if(IsDebug) DumpMciMessage(">>", isAnsi, uMsg, fdwCommand, dwParam); if(dxw.dwFlags6 & BYPASSMCI){ - if((uMsg == MCI_STATUS) && (fdwCommand & MCI_STATUS_ITEM)){ - // fix for Tie Fighter 95: when bypassing, let the caller know you have no CD tracks - // otherwise you risk an almost endless loop going through the unassigned returned - // number of ghost tracks - // fix for "Emperor of the Fading Suns": the MCI_STATUS_ITEM is set in .or. with - // MCI_TRACK - MCI_STATUS_PARMS *p = (MCI_STATUS_PARMS *)dwParam; - OutTraceDW("mciSendCommand: MCI_STATUS item=%d track=%d ret=%d\n", p->dwItem, p->dwReturn, p->dwTrack); - if(fdwCommand & MCI_TRACK){ - p->dwReturn = 1; - } - else{ - p->dwItem = 0; - p->dwTrack = 0; - p->dwReturn = 0; - } - OutTraceDW("mciSendCommand: BYPASS fixing MCI_STATUS\n"); + //MCI_OPEN_PARMS *op; + MCI_STATUS_PARMS *sp; + switch(uMsg){ + case MCI_STATUS: + if(fdwCommand & MCI_STATUS_ITEM){ + // fix for Tie Fighter 95: when bypassing, let the caller know you have no CD tracks + // otherwise you risk an almost endless loop going through the unassigned returned + // number of ghost tracks + // fix for "Emperor of the Fading Suns": the MCI_STATUS_ITEM is set in .or. with + // MCI_TRACK + sp = (MCI_STATUS_PARMS *)dwParam; + switch(fdwCommand){ + case MCI_TRACK: + sp->dwReturn = 1; + break; + default: + sp->dwTrack = 0; + if(sp->dwItem == MCI_STATUS_CURRENT_TRACK) sp->dwTrack = 1; + if(sp->dwItem == MCI_STATUS_NUMBER_OF_TRACKS) sp->dwTrack = 1; + if(sp->dwItem == MCI_STATUS_LENGTH) sp->dwTrack = 200; + sp->dwReturn = 0; + break; + } + } + ret = 0; + break; + default: + ret = 0; + break; } - else{ - OutTraceDW("mciSendCommand: BYPASS\n"); - } - return 0; + if(IsDebug) DumpMciMessage("<<", isAnsi, uMsg, fdwCommand, dwParam); + return ret; } if(dxw.IsFullScreen()){ switch(uMsg){ - case MCI_WINDOW: - pw = (MCI_OVLY_WINDOW_PARMSW *)dwParam; - OutTraceB("mciSendCommand: hwnd=%x CmdShow=%x\n", - pw->hWnd, pw->nCmdShow); - //fdwCommand |= MCI_ANIM_WINDOW_ENABLE_STRETCH; - //fdwCommand &= ~MCI_ANIM_WINDOW_DISABLE_STRETCH; - //fdwCommand &= ~MCI_ANIM_WINDOW_HWND; - if(dxw.IsRealDesktop(pw->hWnd)) { - pw->hWnd = dxw.GethWnd(); - OutTraceB("mciSendCommand: REDIRECT hwnd=%x\n", pw->hWnd); - } - break; - case MCI_PUT: - RECT client; - pr = (MCI_ANIM_RECT_PARMS *)dwParam; - OutTraceB("mciSendCommand: rect=(%d,%d),(%d,%d)\n", - pr->rc.left, pr->rc.top, pr->rc.right, pr->rc.bottom); - (*pGetClientRect)(dxw.GethWnd(), &client); - //fdwCommand |= MCI_ANIM_PUT_DESTINATION; - fdwCommand |= MCI_ANIM_RECT; - saverect=pr->rc; - pr->rc.top = (pr->rc.top * client.bottom) / dxw.GetScreenHeight(); - pr->rc.bottom = (pr->rc.bottom * client.bottom) / dxw.GetScreenHeight(); - pr->rc.left = (pr->rc.left * client.right) / dxw.GetScreenWidth(); - pr->rc.right = (pr->rc.right * client.right) / dxw.GetScreenWidth(); - OutTraceB("mciSendCommand: fixed rect=(%d,%d),(%d,%d)\n", - pr->rc.left, pr->rc.top, pr->rc.right, pr->rc.bottom); - break; - case MCI_PLAY: - if(dxw.dwFlags6 & NOMOVIES) return 0; // ??? - break; - case MCI_OPEN: - if(dxw.dwFlags6 & NOMOVIES) return 275; // quite brutal, but working .... - break; + case MCI_WINDOW: + pw = (MCI_OVLY_WINDOW_PARMSW *)dwParam; + OutTraceB("mciSendCommand: hwnd=%x CmdShow=%x\n", + pw->hWnd, pw->nCmdShow); + if(dxw.IsRealDesktop(pw->hWnd)) { + pw->hWnd = dxw.GethWnd(); + OutTraceB("mciSendCommand: REDIRECT hwnd=%x\n", pw->hWnd); + } + break; + case MCI_PUT: + RECT client; + pr = (MCI_ANIM_RECT_PARMS *)dwParam; + OutTraceB("mciSendCommand: rect=(%d,%d),(%d,%d)\n", + pr->rc.left, pr->rc.top, pr->rc.right, pr->rc.bottom); + (*pGetClientRect)(dxw.GethWnd(), &client); + //fdwCommand |= MCI_ANIM_PUT_DESTINATION; + fdwCommand |= MCI_ANIM_RECT; + saverect=pr->rc; + pr->rc.top = (pr->rc.top * client.bottom) / dxw.GetScreenHeight(); + pr->rc.bottom = (pr->rc.bottom * client.bottom) / dxw.GetScreenHeight(); + pr->rc.left = (pr->rc.left * client.right) / dxw.GetScreenWidth(); + pr->rc.right = (pr->rc.right * client.right) / dxw.GetScreenWidth(); + OutTraceB("mciSendCommand: fixed rect=(%d,%d),(%d,%d)\n", + pr->rc.left, pr->rc.top, pr->rc.right, pr->rc.bottom); + break; + case MCI_PLAY: + if(dxw.dwFlags6 & NOMOVIES) return 0; // ??? + break; + case MCI_OPEN: + if(dxw.dwFlags6 & NOMOVIES) return 275; // quite brutal, but working .... + break; + case MCI_STOP: + if(dxw.dwFlags6 & NOMOVIES) return 0; // ??? + break; } } + LPMCI_GENERIC_PARMS lpGeneric = (LPMCI_GENERIC_PARMS)dwParam; + if(HIWORD(lpGeneric->dwCallback) == NULL) { + lpGeneric->dwCallback = MAKELONG(dxw.GethWnd(),0); + OutTraceB("mciSendCommand: REDIRECT dwCallback=%x\n", dxw.GethWnd()); + } + ret=(*pmciSendCommand)(IDDevice, uMsg, fdwCommand, dwParam); + if(IsDebug) DumpMciMessage("<<", isAnsi, uMsg, fdwCommand, dwParam); if(ret == 0){ switch(uMsg){ @@ -229,12 +370,12 @@ MCIERROR WINAPI extmciSendCommand(mciSendCommand_Type pmciSendCommand, MCIDEVICE MCIERROR WINAPI extmciSendCommandA(MCIDEVICEID IDDevice, UINT uMsg, DWORD_PTR fdwCommand, DWORD_PTR dwParam) { - return extmciSendCommand(pmciSendCommandA, IDDevice, uMsg, fdwCommand, dwParam); + return extmciSendCommand(TRUE, pmciSendCommandA, IDDevice, uMsg, fdwCommand, dwParam); } MCIERROR WINAPI extmciSendCommandW(MCIDEVICEID IDDevice, UINT uMsg, DWORD_PTR fdwCommand, DWORD_PTR dwParam) { - return extmciSendCommand(pmciSendCommandW, IDDevice, uMsg, fdwCommand, dwParam); + return extmciSendCommand(FALSE, pmciSendCommandW, IDDevice, uMsg, fdwCommand, dwParam); } MCIERROR WINAPI extmciSendStringA(LPCTSTR lpszCommand, LPTSTR lpszReturnString, UINT cchReturn, HANDLE hwndCallback)