diff --git a/Include/dxwnd.h b/Include/dxwnd.h index d079f95..9e44332 100644 --- a/Include/dxwnd.h +++ b/Include/dxwnd.h @@ -197,6 +197,7 @@ #define NOSYSMEMBACKBUF 0x00002000 // forces suppression of DDSCAPS_SYSTEMMEMORY capability on emulated backbuffer surface #define CONFIRMONCLOSE 0x00004000 // on close button, ask the user before closing the window / terminating the program #define TERMINATEONCLOSE 0x00008000 // on WM_CLOSE message, also terminates the program +#define FLIPEMULATION 0x00010000 // create virtual primary and backbuffer as un-attached surfaces and replace Flip with Blt // logging Tflags DWORD: #define OUTTRACE 0x00000001 // enables tracing to dxwnd.log in general diff --git a/build/dxwnd.dll b/build/dxwnd.dll index 9a39756..7dbb1fa 100644 --- a/build/dxwnd.dll +++ b/build/dxwnd.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:801f4eac2532d06296db4f257f4b14b6d58d6e6729a7df14a5c73407cbfbb3a5 -size 578560 +oid sha256:fb897fb45eee04399f47f1872c1f63f8a3aaccd0c6d936ca3eabc0e41ecdef7e +size 580608 diff --git a/build/dxwnd.exe b/build/dxwnd.exe index 620b79a..46ba3e7 100644 --- a/build/dxwnd.exe +++ b/build/dxwnd.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:298792319c4f1da616431a5ac3e9cbd4ae54c82335a70f27affa029e8f0b3183 +oid sha256:36da51e4bf39269c8ad561b1573553024b8de8be9072da196c89e32955a2ffb8 size 541696 diff --git a/build/dxwnd.ini b/build/dxwnd.ini new file mode 100644 index 0000000..f1dc130 --- /dev/null +++ b/build/dxwnd.ini @@ -0,0 +1,5 @@ +[window] +posx=1220 +posy=260 +sizx=320 +sizy=200 diff --git a/build/exports/Blair Witch Volume Three - Elly Kedward.dxw b/build/exports/Blair Witch Volume Three - Elly Kedward.dxw new file mode 100644 index 0000000..3e3bc18 --- /dev/null +++ b/build/exports/Blair Witch Volume Three - Elly Kedward.dxw @@ -0,0 +1,31 @@ +[target] +title0=Blair Witch Volume Three - Elly Kedward +path0=D:\Games\Blair Witch Volume Three - Elly Kedward\bw3.exe +launchpath0= +module0= +opengllib0= +notes0="Limit available resources" to bypass the resource cheks, though not fully necessary: \ntyping the enter key the game starts anyway.\n +ver0=0 +coord0=0 +flag0=136314914 +flagg0=1476395008 +flagh0=20 +flagi0=138412036 +flagj0=4224 +flagk0=0 +tflag0=0 +initx0=0 +inity0=0 +minx0=0 +miny0=0 +maxx0=0 +maxy0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 +swapeffect0=0 diff --git a/build/exports/Blair Witch Volume Two.dxw b/build/exports/Blair Witch Volume Two.dxw new file mode 100644 index 0000000..2a01b7e --- /dev/null +++ b/build/exports/Blair Witch Volume Two.dxw @@ -0,0 +1,31 @@ +[target] +title0=Blair Witch Volume Two +path0=D:\Games\Blair Witch II\blairwitch2.exe +launchpath0= +module0= +opengllib0= +notes0="Limit available resources" to bypass the resource cheks, though not fully necessary: \ntyping the enter key the game starts anyway.\n +ver0=0 +coord0=0 +flag0=136314914 +flagg0=1476395008 +flagh0=20 +flagi0=138412036 +flagj0=4224 +flagk0=0 +tflag0=0 +initx0=0 +inity0=0 +minx0=0 +miny0=0 +maxx0=0 +maxy0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 +swapeffect0=0 diff --git a/build/exports/Evil Islands.dxw b/build/exports/Evil Islands.dxw new file mode 100644 index 0000000..91ac389 --- /dev/null +++ b/build/exports/Evil Islands.dxw @@ -0,0 +1,31 @@ +[target] +title0=Evil Islands +path0=D:\Games\Evil Islands\Game.exe +launchpath0= +module0= +opengllib0= +notes0= +ver0=0 +coord0=0 +flag0=136314914 +flagg0=1207959552 +flagh0=20 +flagi0=134217732 +flagj0=4224 +flagk0=0 +tflag0=0 +initx0=0 +inity0=0 +minx0=0 +miny0=0 +maxx0=0 +maxy0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 +swapeffect0=0 diff --git a/build/exports/Sheep Dog'n Wolf.dxw b/build/exports/Sheep Dog'n Wolf.dxw new file mode 100644 index 0000000..951f33b --- /dev/null +++ b/build/exports/Sheep Dog'n Wolf.dxw @@ -0,0 +1,31 @@ +[target] +title0=Sheep Dog'n Wolf +path0=D:\Games\Sheep & Wolf\SheepD3D.exe +launchpath0= +module0= +opengllib0= +notes0= +ver0=0 +coord0=0 +flag0=136314914 +flagg0=1207959552 +flagh0=20 +flagi0=138412036 +flagj0=4224 +flagk0=0 +tflag0=0 +initx0=0 +inity0=0 +minx0=0 +miny0=0 +maxx0=0 +maxy0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 +swapeffect0=0 diff --git a/build/exports/The Watchmaker.dxw b/build/exports/The Watchmaker.dxw new file mode 100644 index 0000000..2a67922 --- /dev/null +++ b/build/exports/The Watchmaker.dxw @@ -0,0 +1,31 @@ +[target] +title0=The Watchmaker +path0=D:\Games\The Watchmaker\Wm.exe +launchpath0= +module0= +opengllib0= +notes0= +ver0=0 +coord0=0 +flag0=136314914 +flagg0=1207959552 +flagh0=20 +flagi0=134217732 +flagj0=4224 +flagk0=0 +tflag0=0 +initx0=0 +inity0=0 +minx0=0 +miny0=0 +maxx0=0 +maxy0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 +swapeffect0=0 diff --git a/build/exports/Theme Park World.dxw b/build/exports/Theme Park World.dxw new file mode 100644 index 0000000..1122df8 --- /dev/null +++ b/build/exports/Theme Park World.dxw @@ -0,0 +1,31 @@ +[target] +title0=Theme Park World +path0=D:\Games\Theme Park World\tp.exe +launchpath0= +module0= +opengllib0= +notes0= +ver0=0 +coord0=0 +flag0=681590839 +flagg0=1207959552 +flagh0=20 +flagi0=138412036 +flagj0=4224 +flagk0=0 +tflag0=0 +initx0=0 +inity0=0 +minx0=0 +miny0=0 +maxx0=0 +maxy0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 +swapeffect0=0 diff --git a/build/exports/TrickStyle (D3D).dxw b/build/exports/TrickStyle (D3D).dxw new file mode 100644 index 0000000..82d1ee9 --- /dev/null +++ b/build/exports/TrickStyle (D3D).dxw @@ -0,0 +1,31 @@ +[target] +title0=TrickStyle (D3D) +path0=D:\Games\TrickStyle\TS_D3D.exe +launchpath0= +module0= +opengllib0= +notes0= +ver0=0 +coord0=0 +flag0=136331298 +flagg0=1207959552 +flagh0=20 +flagi0=138412036 +flagj0=67113088 +flagk0=0 +tflag0=0 +initx0=0 +inity0=0 +minx0=0 +miny0=0 +maxx0=0 +maxy0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 +swapeffect0=0 diff --git a/build/exports/Urban Chaos.dxw b/build/exports/Urban Chaos.dxw new file mode 100644 index 0000000..20658e6 --- /dev/null +++ b/build/exports/Urban Chaos.dxw @@ -0,0 +1,31 @@ +[target] +title0=Urban Chaos +path0=D:\Games\Urban Chaos\fallen.exe +launchpath0= +module0= +opengllib0= +notes0= +ver0=0 +coord0=0 +flag0=136314914 +flagg0=1207959552 +flagh0=20 +flagi0=138412036 +flagj0=4224 +flagk0=0 +tflag0=0 +initx0=0 +inity0=0 +minx0=0 +miny0=0 +maxx0=0 +maxy0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 +swapeffect0=0 diff --git a/build/exports/Wargasm.dxw b/build/exports/Wargasm.dxw new file mode 100644 index 0000000..61e04c5 --- /dev/null +++ b/build/exports/Wargasm.dxw @@ -0,0 +1,31 @@ +[target] +title0=Wargasm +path0=D:\Games\Wargasm\tank.exe +launchpath0= +module0= +opengllib0= +notes0=Must set HOVAPPDATA=. environment variable +ver0=0 +coord0=0 +flag0=681574434 +flagg0=1207959552 +flagh0=20 +flagi0=138412036 +flagj0=4224 +flagk0=0 +tflag0=0 +initx0=0 +inity0=0 +minx0=0 +miny0=0 +maxx0=0 +maxy0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 +swapeffect0=0 diff --git a/build/readme-relnotes.txt b/build/readme-relnotes.txt index 510bec6..f696c27 100644 --- a/build/readme-relnotes.txt +++ b/build/readme-relnotes.txt @@ -867,3 +867,8 @@ add: flags "Ask confirmation on window close" and "Terminate on window close" fix: implemented surface stack cleanup on overflow: this should allow "European Air War" to run through several seasons. debug: added a few diagnostic messages to trap possible errors in DLL injection functions fix: recovered the menu Edit->Add command that went disabled + +v2.03.33: +add: new surface handling, more similar to D3DWindower. The previous mode can be activated by setting the "Flip emulation" flag. The new mode can successfully manage "Microsoft Motocross Madness 2". +fix: Reelease operation for primary surface when used for GDI GetDC operation +fix: protections for GDI ReleaseDC operations against null window or DC diff --git a/dll/ddblit.cpp b/dll/ddblit.cpp index 68c2f26..693df6c 100644 --- a/dll/ddblit.cpp +++ b/dll/ddblit.cpp @@ -19,6 +19,8 @@ extern CreateSurface1_Type pCreateSurface3; extern CreateSurface2_Type pCreateSurface4; extern CreateSurface2_Type pCreateSurface7; extern Unlock4_Type pUnlockMethod(LPDIRECTDRAWSURFACE); +extern HDC hFlippedDC; +extern ReleaseDC_Type pReleaseDC; extern void BlitError(HRESULT, LPRECT, LPRECT, int); extern void BlitTrace(char *, LPRECT, LPRECT, int); @@ -239,12 +241,12 @@ static HRESULT sBltToPrimary(char *api, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdest emurect.bottom = dxw.GetScreenHeight(); } - res=0; + res=DD_OK; // blit only when source and dest surface are different. Should make ScreenRefresh faster. if (lpdds != lpddssrc){ if (IsDebug) BlitTrace("SRC2EMU", &emurect, &destrect, __LINE__); if(destrect.top == -32000) return DD_OK; // happens when window is minimized & do not notify on task switch ... - if(lpdds->IsLost()) lpdds->Restore(); // lpDDSEmu_Back could get lost ..... + if(lpdds->IsLost()) lpdds->Restore(); // lpDDSEmu_Back could get lost ..... res=(*pBlt)(lpdds, &emurect, lpddssrc, lpsrcrect, dwflags, lpddbltfx); } @@ -272,10 +274,13 @@ static HRESULT sBltToPrimary(char *api, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdest // Try to handle HDC lock concurrency.... if(res==DDERR_SURFACEBUSY){ + (*pReleaseDC)(lpdds, hFlippedDC); +#if 0 res=(*pUnlockMethod(lpddssrc))(lpddssrc, NULL); if(res && (res!=DDERR_NOTLOCKED)) OutTraceE("Unlock ERROR: lpdds=%x err=%x(%s)\n", lpddssrc, res, ExplainDDError(res)); res=(*pUnlockMethod(lpdds))(lpdds, NULL); // v2.03.24 reintroduced because of "Virtua Cop" if(res && (res!=DDERR_NOTLOCKED)) OutTraceE("Unlock ERROR: lpdds=%x err=%x(%s)\n", lpdds, res, ExplainDDError(res)); +#endif if (IsDebug) BlitTrace("BUSY", &emurect, &destrect, __LINE__); res=(*pBlt)(lpdds, &emurect, lpddssrc, lpsrcrect, dwflags, lpddbltfx); if (res) BlitError(res, lpsrcrect, &destrect, __LINE__); @@ -287,7 +292,7 @@ static HRESULT sBltToPrimary(char *api, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdest LPDIRECTDRAWSURFACE lpDDSSource; if (res=(*pColorConversion)(lpdds, emurect, &lpDDSSource)) { - OutTraceE("sBlt ERROR: Color conversion failed res=%d(%s)\n", res, ExplainDDError(res)); + OutTraceE("sBlt ERROR: Color conversion failed res=%x(%s)\n", res, ExplainDDError(res)); if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK; return res; } diff --git a/dll/ddraw.cpp b/dll/ddraw.cpp index 16daaf0..9ebec0c 100644 --- a/dll/ddraw.cpp +++ b/dll/ddraw.cpp @@ -2182,81 +2182,17 @@ static void ClearSurfaceDesc(void *ddsd, int dxversion) ((LPDDSURFACEDESC)ddsd)->dwSize = size; } -static HRESULT BuildPrimaryEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurface, LPDDSURFACEDESC2 lpddsd, int dxversion, LPDIRECTDRAWSURFACE *lplpdds, void *pu) +static void BuildRealSurfaces(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurface, LPDDSURFACEDESC2 lpddsd, int dxversion) { - DDSURFACEDESC2 ddsd; HRESULT res; + DDSURFACEDESC2 ddsd; - // emulated primary surface - memcpy((void *)&ddsd, lpddsd, lpddsd->dwSize); - - // handle the surface attributes before the ddsd.dwFlags gets updated: - // if a surface desc is NOT specified, build one - if(!(ddsd.dwFlags & DDSD_PIXELFORMAT)) SetPixFmt((LPDDSURFACEDESC2)&ddsd); - // then save it - dxw.VirtualPixelFormat = ddsd.ddpfPixelFormat; - - OutTraceDW("DDSD_PIXELFORMAT: color=%d flags=%x\n", dxw.VirtualPixelFormat.dwRGBBitCount, dxw.VirtualPixelFormat.dwFlags); - ddsd.dwFlags &= ~(DDSD_BACKBUFFERCOUNT|DDSD_REFRESHRATE); - ddsd.dwFlags |= (DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT); - ddsd.ddsCaps.dwCaps &= ~(DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP|DDSCAPS_COMPLEX|DDSCAPS_VIDEOMEMORY|DDSCAPS_LOCALVIDMEM); - // DDSCAPS_OFFSCREENPLAIN seems required to support the palette in memory surfaces - ddsd.ddsCaps.dwCaps |= (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY); - // on WinXP Fifa 99 doesn't like DDSCAPS_SYSTEMMEMORY cap, so better to leave a way to unset it.... - if(dxw.dwFlags6 & NOSYSMEMPRIMARY) ddsd.ddsCaps.dwCaps &= ~DDSCAPS_SYSTEMMEMORY; - - extern BOOL bInCreateDevice; - //if (bInCreateDevice) ddsd.ddsCaps.dwCaps &= ~DDSCAPS_SYSTEMMEMORY; - //if (bInCreateDevice) ddsd.ddsCaps.dwCaps &= ~DDSCAPS_3DDEVICE; - - // this would make STCC work in emulated mode, but SLOW!!!! - //if(ddsd.ddsCaps.dwCaps & DDSCAPS_3DDEVICE) { - // ddsd.ddsCaps.dwCaps &= ~DDSCAPS_SYSTEMMEMORY; - // //ddsd.ddsCaps.dwCaps |= (DDSCAPS_VIDEOMEMORY|DDSCAPS_LOCALVIDMEM); - //} - - ddsd.dwWidth = dxw.GetScreenWidth(); - ddsd.dwHeight = dxw.GetScreenHeight(); - - // create Primary surface - OutTraceDW("CreateSurface: %s\n", LogSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Primary]" , __LINE__)); - res=(*pCreateSurface)(lpdd, &ddsd, lplpdds, 0); - if(res){ - if (res==DDERR_PRIMARYSURFACEALREADYEXISTS){ - LPDIRECTDRAWSURFACE lpPrim; - OutTraceE("CreateSurface: CreateSurface DDERR_PRIMARYSURFACEALREADYEXISTS workaround\n"); - (*pGetGDISurface)(lpPrimaryDD, &lpPrim); - while ((*pReleaseS)(lpPrim)); - res = (*pCreateSurface)(lpdd, &ddsd, lplpdds, 0); - } - /* fall through */ - if(res){ - OutTraceE("CreateSurface: ERROR on DDSPrim res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); - if(res==DDERR_INVALIDPIXELFORMAT) DumpPixFmt(&ddsd); - return res; - } - } - - OutTraceDW("CreateSurface: created PRIMARY DDSPrim=%x\n", *lplpdds); - if(IsDebug) DescribeSurface(*lplpdds, dxversion, "DDSPrim", __LINE__); - HookDDSurfacePrim(lplpdds, dxversion); - // "Hoyle Casino Empire" opens a primary surface and NOT a backbuffer .... - iBakBufferVersion=dxversion; // v2.03.01 - - // set a global capability value for surfaces that have to blit to primary - // DDSCAPS_OFFSCREENPLAIN seems required to support the palette in memory surfaces - // DDSCAPS_SYSTEMMEMORY makes operations faster, but it is not always good... - dwBackBufferCaps = (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY); - // on WinXP Fifa 99 doesn't like DDSCAPS_SYSTEMMEMORY cap, so better to leave a way to unset it.... - // this is important to avoid that certain D3D operations will abort - see "Forsaken" problem - if(dxw.dwFlags6 & NOSYSMEMBACKBUF) dwBackBufferCaps = DDSCAPS_OFFSCREENPLAIN; - - if(dxw.dwFlags5 & GDIMODE) return DD_OK; - + OutTraceDW("DEBUG: BuildRealSurfaces: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); if(lpDDSEmu_Prim==NULL){ ClearSurfaceDesc((void *)&ddsd, dxversion); ddsd.dwFlags = DDSD_CAPS; - ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + //ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE|DDSCAPS_SYSTEMMEMORY; OutTraceDW("CreateSurface: %s\n", LogSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[EmuPrim]", __LINE__)); res=(*pCreateSurface)(lpdd, &ddsd, &lpDDSEmu_Prim, 0); if(res==DDERR_PRIMARYSURFACEALREADYEXISTS){ @@ -2276,7 +2212,7 @@ static HRESULT BuildPrimaryEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf if(res){ OutTraceE("CreateSurface: ERROR on DDSEmu_Prim res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); if(res==DDERR_INVALIDPIXELFORMAT) DumpPixFmt(&ddsd); - return res; + return; } OutTraceDW("CreateSurface: created new DDSEmu_Prim=%x\n",lpDDSEmu_Prim); if(IsDebug) DescribeSurface(lpDDSEmu_Prim, dxversion, "DDSEmu_Prim", __LINE__); @@ -2290,7 +2226,8 @@ static HRESULT BuildPrimaryEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf if(lpDDSEmu_Back==NULL){ ClearSurfaceDesc((void *)&ddsd, dxversion); ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.ddsCaps.dwCaps = dwBackBufferCaps; + //ddsd.ddsCaps.dwCaps = dwBackBufferCaps; + ddsd.ddsCaps.dwCaps = dwBackBufferCaps|DDSCAPS_SYSTEMMEMORY; ddsd.dwWidth = dxw.GetScreenWidth(); ddsd.dwHeight = dxw.GetScreenHeight(); if(dxw.dwFlags4 & BILINEAR2XFILTER){ @@ -2305,16 +2242,128 @@ static HRESULT BuildPrimaryEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf if(res){ OutTraceE("CreateSurface: CreateSurface ERROR on DDSEmuBack : res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); if(res==DDERR_INVALIDPIXELFORMAT) DumpPixFmt(&ddsd); - return res; + return; } OutTraceDW("CreateSurface: created new DDSEmu_Back=%x\n", lpDDSEmu_Back); if(IsDebug) DescribeSurface(lpDDSEmu_Back, dxversion, "DDSEmu_Back", __LINE__); dxwss.PopSurface(lpDDSEmu_Back); if (dxw.dwTFlags & OUTPROXYTRACE) HookDDSurfaceGeneric(&lpDDSEmu_Back, dxversion); } +} + +static HRESULT BuildPrimaryEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurface, LPDDSURFACEDESC2 lpddsd, int dxversion, LPDIRECTDRAWSURFACE *lplpdds, void *pu) +{ + DDSURFACEDESC2 ddsd; + HRESULT res; + + OutTraceDW("DEBUG: BuildPrimaryEmu: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); + // emulated primary surface + memcpy((void *)&ddsd, lpddsd, lpddsd->dwSize); + + // handle the surface attributes before the ddsd.dwFlags gets updated: + // if a surface desc is NOT specified, build one + if(!(ddsd.dwFlags & DDSD_PIXELFORMAT)) SetPixFmt((LPDDSURFACEDESC2)&ddsd); + // then save it + dxw.VirtualPixelFormat = ddsd.ddpfPixelFormat; + + OutTraceDW("DDSD_PIXELFORMAT: color=%d flags=%x\n", dxw.VirtualPixelFormat.dwRGBBitCount, dxw.VirtualPixelFormat.dwFlags); + ddsd.dwFlags &= ~(DDSD_BACKBUFFERCOUNT|DDSD_REFRESHRATE); + ddsd.dwFlags |= (DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT); + ddsd.ddsCaps.dwCaps &= ~(DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP|DDSCAPS_COMPLEX|DDSCAPS_VIDEOMEMORY|DDSCAPS_LOCALVIDMEM); + // DDSCAPS_OFFSCREENPLAIN seems required to support the palette in memory surfaces + ddsd.ddsCaps.dwCaps |= (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY); + // on WinXP Fifa 99 doesn't like DDSCAPS_SYSTEMMEMORY cap, so better to leave a way to unset it.... + if(dxw.dwFlags6 & NOSYSMEMPRIMARY) ddsd.ddsCaps.dwCaps &= ~DDSCAPS_SYSTEMMEMORY; + + ddsd.dwWidth = dxw.GetScreenWidth(); + ddsd.dwHeight = dxw.GetScreenHeight(); + + // create Primary surface + OutTraceDW("CreateSurface: %s\n", LogSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Primary]" , __LINE__)); + res=(*pCreateSurface)(lpdd, &ddsd, lplpdds, 0); + if(res){ + OutTraceE("CreateSurface: ERROR on DDSPrim res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + if(res==DDERR_INVALIDPIXELFORMAT) DumpPixFmt(&ddsd); + return res; + } + + OutTraceDW("CreateSurface: created PRIMARY DDSPrim=%x\n", *lplpdds); + if(IsDebug) DescribeSurface(*lplpdds, dxversion, "DDSPrim", __LINE__); + HookDDSurfacePrim(lplpdds, dxversion); + // "Hoyle Casino Empire" opens a primary surface and NOT a backbuffer .... + iBakBufferVersion=dxversion; // v2.03.01 + + // set a global capability value for surfaces that have to blit to primary + // DDSCAPS_OFFSCREENPLAIN seems required to support the palette in memory surfaces + // DDSCAPS_SYSTEMMEMORY makes operations faster, but it is not always good... + dwBackBufferCaps = (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY); + // on WinXP Fifa 99 doesn't like DDSCAPS_SYSTEMMEMORY cap, so better to leave a way to unset it.... + // this is important to avoid that certain D3D operations will abort - see "Forsaken" problem + if(dxw.dwFlags6 & NOSYSMEMBACKBUF) dwBackBufferCaps = DDSCAPS_OFFSCREENPLAIN; bFlippedDC = TRUE; - + + if(dxw.dwFlags5 & GDIMODE) return DD_OK; + + BuildRealSurfaces(lpdd, pCreateSurface, lpddsd, dxversion); + return DD_OK; +} + +static HRESULT BuildPrimaryFlippable(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurface, LPDDSURFACEDESC2 lpddsd, int dxversion, LPDIRECTDRAWSURFACE *lplpdds, void *pu) +{ + DDSURFACEDESC2 ddsd; + HRESULT res; + + OutTraceDW("DEBUG: BuildPrimaryFlippable: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); + // emulated primary surface + memcpy((void *)&ddsd, lpddsd, lpddsd->dwSize); + + // handle the surface attributes before the ddsd.dwFlags gets updated: + // if a surface desc is NOT specified, build one + if(!(ddsd.dwFlags & DDSD_PIXELFORMAT)) SetPixFmt((LPDDSURFACEDESC2)&ddsd); + // then save it + dxw.VirtualPixelFormat = ddsd.ddpfPixelFormat; + + OutTraceDW("DDSD_PIXELFORMAT: color=%d flags=%x\n", dxw.VirtualPixelFormat.dwRGBBitCount, dxw.VirtualPixelFormat.dwFlags); + + // dwFlags + ddsd.dwFlags &= ~(DDSD_REFRESHRATE); + ddsd.dwFlags |= (DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT|DDSD_BACKBUFFERCOUNT); + + // dwBackBufferCount: set to at least 1 + if(!(lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) || (lpddsd->dwBackBufferCount == 0)) ddsd.dwBackBufferCount = 1; + + // dwCaps + ddsd.ddsCaps.dwCaps &= ~(DDSCAPS_PRIMARYSURFACE|DDSCAPS_VIDEOMEMORY|DDSCAPS_LOCALVIDMEM); + ddsd.ddsCaps.dwCaps |= (DDSCAPS_COMPLEX|DDSCAPS_FLIP|DDSCAPS_OFFSCREENPLAIN); + + // dwWidth & dwHeight + ddsd.dwWidth = dxw.GetScreenWidth(); + ddsd.dwHeight = dxw.GetScreenHeight(); + + // create Primary surface + OutTraceDW("CreateSurface: %s\n", LogSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Primary]" , __LINE__)); + res=(*pCreateSurface)(lpdd, &ddsd, lplpdds, 0); + if(res){ + OutTraceE("CreateSurface: ERROR on DDSPrim res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + if(res==DDERR_INVALIDPIXELFORMAT) DumpPixFmt(&ddsd); + return res; + } + + OutTraceDW("CreateSurface: created PRIMARY DDSPrim=%x\n", *lplpdds); + if(IsDebug) DescribeSurface(*lplpdds, dxversion, "DDSPrim", __LINE__); + HookDDSurfacePrim(lplpdds, dxversion); + // "Hoyle Casino Empire" opens a primary surface and NOT a backbuffer .... + iBakBufferVersion=dxversion; // v2.03.01 + + // set a global capability value for surfaces that have to blit to primary + dwBackBufferCaps = (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY); + + bFlippedDC = TRUE; + + if(dxw.dwFlags5 & GDIMODE) return DD_OK; + + BuildRealSurfaces(lpdd, pCreateSurface, lpddsd, dxversion); return DD_OK; } @@ -2323,6 +2372,7 @@ static HRESULT BuildPrimaryDir(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf DDSURFACEDESC2 ddsd; HRESULT res; + OutTraceDW("DEBUG: BuildPrimaryDir: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); // genuine primary surface memcpy((void *)&ddsd, lpddsd, lpddsd->dwSize); ddsd.dwFlags &= ~(DDSD_WIDTH|DDSD_HEIGHT|DDSD_BACKBUFFERCOUNT|DDSD_REFRESHRATE|DDSD_PIXELFORMAT); @@ -2384,6 +2434,7 @@ static HRESULT BuildBackBufferEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateS DDSURFACEDESC2 ddsd; HRESULT res; + OutTraceDW("DEBUG: BuildBackBufferEmu: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); // create BackBuffer surface memcpy(&ddsd, lpddsd, lpddsd->dwSize); ddsd.dwFlags &= ~(DDSD_BACKBUFFERCOUNT|DDSD_REFRESHRATE); @@ -2411,6 +2462,91 @@ static HRESULT BuildBackBufferEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateS HookDDSurfaceGeneric(lplpdds, dxversion); // added !!! iBakBufferVersion=dxversion; // v2.02.31 + // V2.1.85/V2.2.34: tricky !!!! + // When a real backbuffer is created, it has a reference to its frontbuffer. + // some games (Monopoly 3D) may depend on this setting - i.e. they could close + // the exceeding references - so this is better be replicated adding an initial + // reference to the zero count. But you don't have to do this if the backbuffer + // is created independently by the primary surface. + (*lplpdds)->AddRef(); // should it be repeated BBCount times???? + + return DD_OK; +} + +static HRESULT BuildBackBufferFlippable(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurface, LPDDSURFACEDESC2 lpddsd, int dxversion, LPDIRECTDRAWSURFACE *lplpdds, void *pu) +{ + DDSURFACEDESC2 ddsd; + HRESULT res; + + OutTraceDW("DEBUG: BuildBackBufferFlippable: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); + + // create BackBuffer surface + memcpy(&ddsd, lpddsd, lpddsd->dwSize); + + ddsd.dwFlags &= ~(DDSD_BACKBUFFERCOUNT|DDSD_REFRESHRATE); + ddsd.dwFlags |= (DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT); + + ddsd.ddsCaps.dwCaps &= ~(DDSCAPS_BACKBUFFER|DDSCAPS_PRIMARYSURFACE); + ddsd.ddsCaps.dwCaps |= (DDSCAPS_FLIP|DDSCAPS_COMPLEX|DDSCAPS_VIDEOMEMORY|DDSCAPS_LOCALVIDMEM); + + ddsd.dwWidth = dxw.GetScreenWidth(); + ddsd.dwHeight = dxw.GetScreenHeight(); + GetPixFmt(&ddsd); + + OutTraceDW("CreateSurface: %s\n", LogSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Backbuf]", __LINE__)); + res=(*pCreateSurface)(lpdd, &ddsd, lplpdds, 0); + if(res) { + OutTraceE("CreateSurface ERROR: res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + if(res==DDERR_INVALIDPIXELFORMAT) DumpPixFmt(&ddsd); + return res; + } + + OutTraceDW("CreateSurface: created BACK DDSBack=%x\n", *lplpdds); + if(IsDebug) DescribeSurface(*lplpdds, dxversion, "DDSBack", __LINE__); + HookDDSurfaceGeneric(lplpdds, dxversion); // added !!! + iBakBufferVersion=dxversion; // v2.02.31 + + return DD_OK; +} + +static HRESULT AttachBackBufferFlippable(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurface, LPDDSURFACEDESC2 lpddsd, int dxversion, LPDIRECTDRAWSURFACE *lplpdds, void *pu) +{ + HRESULT res; + LPDIRECTDRAWSURFACE lpDDSPrim; + OutTraceDW("DEBUG: AttachBackBufferFlippable: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); + + // retrieve the attached backbuffer surface and hook it + + if(lpddsd->dwBackBufferCount == 0) return DD_OK; // nothing to retrieve + + GetAttachedSurface_Type pGetAttachedSurface; + DDSCAPS2 caps; + switch(dxversion){ + default: + case 1: + case 2: + pGetAttachedSurface = pGetAttachedSurface1; break; + case 3: + pGetAttachedSurface = pGetAttachedSurface3; break; + case 4: + pGetAttachedSurface = pGetAttachedSurface4; break; + case 7: + pGetAttachedSurface = pGetAttachedSurface7; break; + } + memset(&caps, 0, sizeof(caps)); + caps.dwCaps = DDSCAPS_BACKBUFFER; + lpDDSPrim = dxwss.GetPrimarySurface(); + res = (*pGetAttachedSurface)(lpDDSPrim, (LPDDSCAPS)&caps, lplpdds); + if(res){ + OutTraceE("CreateSurface: GetAttachedSurface ERROR on DDSPrim res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + return res; + } + + OutTraceDW("CreateSurface: retrieved BACK DDSBack=%x\n", *lplpdds); + if(IsDebug) DescribeSurface(*lplpdds, dxversion, "DDSBack", __LINE__); + HookDDSurfaceGeneric(lplpdds, dxversion); // added !!! + iBakBufferVersion=dxversion; // v2.02.31 + return DD_OK; } @@ -2419,6 +2555,7 @@ static HRESULT BuildBackBufferDir(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateS DDSURFACEDESC2 ddsd; HRESULT res; + OutTraceDW("DEBUG: BuildBackBufferDir: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); // create BackBuffer surface // ClearSurfaceDesc((void *)&ddsd, dxversion); memcpy(&ddsd, lpddsd, lpddsd->dwSize); @@ -2474,6 +2611,7 @@ static HRESULT BuildGenericEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf DDSURFACEDESC2 ddsd; HRESULT res; + OutTraceDW("DEBUG: BuildGenericEmu: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); memcpy(&ddsd, lpddsd, lpddsd->dwSize); // Copy over .... FixSurfaceCaps(&ddsd, dxversion); // It looks that DDSCAPS_SYSTEMMEMORY surfaces can perfectly be DDSCAPS_3DDEVICE as well. @@ -2506,7 +2644,7 @@ static HRESULT BuildGenericEmu(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf } OutTraceDW("CreateSurface: CREATED lpddsd=%x version=%d %s\n", - *lplpdds, dxversion, LogSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Dir Generic]", __LINE__)); + *lplpdds, dxversion, LogSurfaceAttributes((LPDDSURFACEDESC)&ddsd, "[Emu Generic]", __LINE__)); // v2.02.66: if 8BPP paletized surface and a primary palette exixts, apply. // fixes "Virtua Fighter PC" palette bug @@ -2528,6 +2666,7 @@ static HRESULT BuildGenericDir(LPDIRECTDRAW lpdd, CreateSurface_Type pCreateSurf { HRESULT res; + OutTraceDW("DEBUG: BuildGenericDir: lpdd=%x pCreateSurface=%x lpddsd=%x version=%d\n", lpdd, pCreateSurface, lpddsd, dxversion); OutTraceDW("CreateSurface: %s\n", LogSurfaceAttributes((LPDDSURFACEDESC)lpddsd, "[Dir Generic]", __LINE__)); res = (*pCreateSurface)(lpdd, lpddsd, lplpdds, 0); @@ -2567,21 +2706,39 @@ static HRESULT WINAPI extCreateSurface(int dxversion, CreateSurface_Type pCreate typedef HRESULT (*BuildSurface_Type)(LPDIRECTDRAW, CreateSurface_Type, LPDDSURFACEDESC2, int, LPDIRECTDRAWSURFACE *, void *); BuildSurface_Type BuildPrimary; BuildSurface_Type BuildBackBuffer; + BuildSurface_Type AttachBackBuffer; BuildSurface_Type BuildGeneric; - - if (dxw.dwFlags1 & EMULATESURFACE){ - BuildPrimary = BuildPrimaryEmu; - BuildBackBuffer = BuildBackBufferEmu; - BuildGeneric = BuildGenericEmu; - } - else { - BuildPrimary = BuildPrimaryDir; - BuildBackBuffer = BuildBackBufferDir; - BuildGeneric = BuildGenericDir; - } + enum { + PRIMARY_DIRECT = 0, + PRIMARY_FLIPPABLE, + PRIMARY_EMULATED + } SurfaceMode; OutTraceDDRAW("CreateSurface: Version=%d lpdd=%x %s\n", dxversion, lpdd, LogSurfaceAttributes((LPDDSURFACEDESC)lpddsd, "[CreateSurface]", __LINE__)); + + SurfaceMode = (dxw.dwFlags1 & EMULATESURFACE) ? ((dxw.dwFlags6 & FLIPEMULATION) ? PRIMARY_EMULATED : PRIMARY_FLIPPABLE) : PRIMARY_DIRECT; + + switch(SurfaceMode) { + case PRIMARY_DIRECT: + BuildPrimary = BuildPrimaryDir; + BuildBackBuffer = BuildBackBufferDir; + AttachBackBuffer = BuildBackBufferDir; + BuildGeneric = BuildGenericDir; + break; + case PRIMARY_FLIPPABLE: + BuildPrimary = BuildPrimaryFlippable; + BuildBackBuffer = BuildBackBufferFlippable; + AttachBackBuffer = AttachBackBufferFlippable; + BuildGeneric = BuildGenericEmu; + break; + case PRIMARY_EMULATED: + BuildPrimary = BuildPrimaryEmu; + BuildBackBuffer = BuildBackBufferEmu; + AttachBackBuffer = BuildBackBufferEmu; + BuildGeneric = BuildGenericEmu; + break; + } // check for lpddsd->dwSize value TargetSize=(dxversion<4)?sizeof(DDSURFACEDESC):sizeof(DDSURFACEDESC2); @@ -2628,7 +2785,7 @@ static HRESULT WINAPI extCreateSurface(int dxversion, CreateSurface_Type pCreate if (ddsd.dwFlags & DDSD_BACKBUFFERCOUNT) { // Praetorians !!!! lpDDSBack = dxwss.GetBackBufferSurface(); if (lpDDSBack) { - while(lpDDSBack->Release()); + if(dxw.dwFlags6 & FLIPEMULATION) while(lpDDSBack->Release()); dxwss.PopSurface(lpDDSBack); lpDDSBack = NULL; } @@ -2663,17 +2820,9 @@ static HRESULT WINAPI extCreateSurface(int dxversion, CreateSurface_Type pCreate if (BBCount){ // build emulated backbuffer surface - res=BuildBackBuffer(lpdd, pCreateSurface, lpddsd, dxversion, &lpDDSBack, NULL); + res=AttachBackBuffer(lpdd, pCreateSurface, lpddsd, dxversion, &lpDDSBack, NULL); if(res) return res; dxwss.PushBackBufferSurface(lpDDSBack, dxversion); - - // V2.1.85/V2.2.34: tricky !!!! - // When a real backbuffer is created, it has a reference to its frontbuffer. - // some games (Monopoly 3D) may depend on this setting - i.e. they could close - // the exceeding references - so this is better be replicated adding an initial - // reference to the zero count. But you don't have to do this if the backbuffer - // is created independently by the primary surface. - lpDDSBack->AddRef(); // should it be repeated BBCount times???? } if(IsTraceDDRAW){ @@ -2722,7 +2871,6 @@ static HRESULT WINAPI extCreateSurface(int dxversion, CreateSurface_Type pCreate } } - return res; } @@ -2760,40 +2908,48 @@ HRESULT WINAPI extGetAttachedSurface(int dxversion, GetAttachedSurface_Type pGet OutTraceDDRAW("GetAttachedSurface(%d): lpdds=%x%s caps=%x(%s)\n", dxversion, lpdds, (IsPrim?"(PRIM)":(IsBack ? "(BACK)":"")), lpddsc->dwCaps, ExplainDDSCaps(lpddsc->dwCaps)); - // v2.1.81: fix to make "Silver" working: if the primary surface was created with - // backbuffercount == 2, the game expects some more surface to be attached to - // the attached backbuffer. Since there would be no use for it, just return - // the attached backbuffer itself. Makes Silver working, anyway.... - // beware: "Snowboard Racer" fails if you return an attached surface anyhow! There, - // the primary surface was created with back buffer count == 1. - // v2.2.62 fix: a check to implement doublebuffer emulation only in case of DDSCAPS_BACKBUFFER - // requests. A call to GetAttachedSurface can be made to retrieve DDSCAPS_ZBUFFER surfaces, and in - // this case the BackBuffer surface can't be returned. + if(dxw.dwFlags6 & FLIPEMULATION){ - if (IsBack && (DDSD_Prim.dwBackBufferCount > 1) && (lpddsc->dwCaps & DDSCAPS_BACKBUFFER)){ - *lplpddas = lpdds; - OutTraceDW("GetAttachedSurface(%d): DOUBLEBUFFER attached to BACK=%x\n", dxversion, lpdds); - return DD_OK; - } + // v2.1.81: fix to make "Silver" working: if the primary surface was created with + // backbuffercount == 2, the game expects some more surface to be attached to + // the attached backbuffer. Since there would be no use for it, just return + // the attached backbuffer itself. Makes Silver working, anyway.... + // beware: "Snowboard Racer" fails if you return an attached surface anyhow! There, + // the primary surface was created with back buffer count == 1. + // v2.2.62 fix: a check to implement doublebuffer emulation only in case of DDSCAPS_BACKBUFFER + // requests. A call to GetAttachedSurface can be made to retrieve DDSCAPS_ZBUFFER surfaces, and in + // this case the BackBuffer surface can't be returned. - // on primary surface return the backbuffer surface coming from either an explicit - // AddAttachedSurface, or a primary complex surface creation otherwise.... - - if(IsPrim && (lpddsc->dwCaps & (DDSCAPS_BACKBUFFER|DDSCAPS_FLIP))) { // v2.02.42 added DDSCAPS_FLIP for Empire Earth - // in "Tomb Raider III" GOG release, the primary surface is queryed and has no attached - // backbuffer, but a backbuffer does exist and has to be retrieved by GetBackBufferSurface. - LPDIRECTDRAWSURFACE lpddsback = dxwss.GetBackBufferSurface(); - if (lpddsback) { - *lplpddas = lpddsback; - OutTraceDW("GetAttachedSurface(%d): BACKBUFFER attached=%x\n", dxversion, *lplpddas); + if (IsBack && (DDSD_Prim.dwBackBufferCount > 1) && (lpddsc->dwCaps & DDSCAPS_BACKBUFFER)){ + *lplpddas = lpdds; + OutTraceDW("GetAttachedSurface(%d): DOUBLEBUFFER attached to BACK=%x\n", dxversion, lpdds); return DD_OK; } - else { - *lplpddas = NULL; - OutTraceDW("GetAttachedSurface(%d): no attached BACKBUFFER\n", dxversion); - return DDERR_NOTFOUND; + + // on primary surface return the backbuffer surface coming from either an explicit + // AddAttachedSurface, or a primary complex surface creation otherwise.... + + if(IsPrim && (lpddsc->dwCaps & (DDSCAPS_BACKBUFFER|DDSCAPS_FLIP))) { // v2.02.42 added DDSCAPS_FLIP for Empire Earth + // in "Tomb Raider III" GOG release, the primary surface is queryed and has no attached + // backbuffer, but a backbuffer does exist and has to be retrieved by GetBackBufferSurface. + LPDIRECTDRAWSURFACE lpddsback = dxwss.GetBackBufferSurface(); + if (lpddsback) { + *lplpddas = lpddsback; + OutTraceDW("GetAttachedSurface(%d): BACKBUFFER attached=%x\n", dxversion, *lplpddas); + return DD_OK; + } + else { + *lplpddas = NULL; + OutTraceDW("GetAttachedSurface(%d): no attached BACKBUFFER\n", dxversion); + return DDERR_NOTFOUND; + } } } + else { + // Virtual primary surfaces are created with no DDSCAPS_3DDEVICE caps, so don't look for it .... + if(IsPrim && (lpddsc->dwCaps & (DDSCAPS_BACKBUFFER|DDSCAPS_FLIP))) + lpddsc->dwCaps &= ~DDSCAPS_3DDEVICE; + } // proxy the call... @@ -3169,6 +3325,18 @@ HRESULT WINAPI extFlip(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWSURFACE lpddssrc, OutTraceDDRAW("Flip: lpdds=%x%s, src=%x, flags=%x(%s)\n", lpdds, IsPrim?"(PRIM)":"", lpddssrc, dwflags, ExplainFlipFlags(dwflags)); + if (!(dxw.dwFlags6 & FLIPEMULATION) && 0) { + OutTrace("DEBUG: attempting actual Flip\n"); + //res=(*pFlip)(lpdds, lpddssrc, dwflags); + res=(*pFlip)(lpdds, lpddssrc, 0); + if(res){ + OutTraceE("Flip: ERROR res=%x(%s)\n", res, ExplainDDError(res)); + return res; + } + if(dxw.dwFlags1 & EMULATESURFACE) dxw.ScreenRefresh(); + return DD_OK; + } + if (!IsPrim){ if(lpddssrc){ res=(*pFlip)(lpdds, lpddssrc, dwflags); @@ -4616,9 +4784,19 @@ HRESULT WINAPI extGetSurfaceDesc(GetSurfaceDesc_Type pGetSurfaceDesc, LPDIRECTDR if (IsBack) { OutTraceDW("GetSurfaceDesc: fixing BACKBUFFER surface\n"); IsFixed=TRUE; - lpddsd->ddsCaps.dwCaps |= (DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY|DDSCAPS_LOCALVIDMEM); // you never know.... - lpddsd->ddsCaps.dwCaps &= ~(DDSCAPS_SYSTEMMEMORY|DDSCAPS_OFFSCREENPLAIN); // primary surfaces can't be this way - if(lpddsd->ddsCaps.dwCaps & DDSCAPS_3DDEVICE) lpddsd->ddsCaps.dwCaps |= DDSCAPS_LOCALVIDMEM; + //lpddsd->ddsCaps.dwCaps |= (DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY|DDSCAPS_LOCALVIDMEM); // you never know.... + //lpddsd->ddsCaps.dwCaps &= ~(DDSCAPS_SYSTEMMEMORY|DDSCAPS_OFFSCREENPLAIN); // backbuffer surfaces can't be this way + //if(lpddsd->ddsCaps.dwCaps & DDSCAPS_3DDEVICE) lpddsd->ddsCaps.dwCaps |= DDSCAPS_LOCALVIDMEM; + + //if(!(dxw.dwFlags6 & FLIPEMULATION)){ + // lpddsd->ddsCaps.dwCaps |= (DDSCAPS_3DDEVICE); // you never know.... + // lpddsd->ddsCaps.dwCaps &= ~(DDSCAPS_COMPLEX|DDSCAPS_FLIP); // backbuffer surfaces can't be this way + //} + // try ... + lpddsd->ddsCaps.dwCaps |= (DDSCAPS_3DDEVICE|DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY|DDSCAPS_LOCALVIDMEM); + lpddsd->ddsCaps.dwCaps &= ~(DDSCAPS_SYSTEMMEMORY|DDSCAPS_OFFSCREENPLAIN|DDSCAPS_COMPLEX|DDSCAPS_FLIP); // backbuffer surfaces can't be this way + + } if (lpddsd->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) { diff --git a/dll/dxwnd.cpp b/dll/dxwnd.cpp index 9e50140..8ee69a2 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.32" +#define VERSION "2.03.33" #define DDTHREADLOCK 1 //#define LOCKTHREADS diff --git a/dll/dxwnd.vs2008.suo b/dll/dxwnd.vs2008.suo index bea27dc..96403ea 100644 Binary files a/dll/dxwnd.vs2008.suo and b/dll/dxwnd.vs2008.suo differ diff --git a/dll/user32.cpp b/dll/user32.cpp index af8ed17..455b467 100644 --- a/dll/user32.cpp +++ b/dll/user32.cpp @@ -2019,9 +2019,13 @@ int WINAPI extGDIReleaseDC(HWND hwnd, HDC hDC) OutTraceDW("GDI.ReleaseDC: hwnd=%x hdc=%x\n", hwnd, hDC); if (dxw.IsRealDesktop(hwnd)) hwnd=dxw.GethWnd(); + if(hwnd == 0) return(TRUE); if(bFlippedDC && (hDC == hFlippedDC)) { HRESULT ret; + LPDIRECTDRAWSURFACE lpDDSPrim; + lpDDSPrim = dxwss.GetPrimarySurface(); + if(!lpDDSPrim) return(TRUE); OutTraceDW("GDI.ReleaseDC: releasing flipped GDI hdc=%x\n", hDC); ret=(*pReleaseDC)(dxwss.GetPrimarySurface(), hDC); if (ret) OutTraceE("GDI.ReleaseDC ERROR: err=%x(%s) at %d\n", ret, ExplainDDError(ret), __LINE__); diff --git a/host/TabDirect3D.cpp b/host/TabDirect3D.cpp index 04ea1d5..2d5876e 100644 --- a/host/TabDirect3D.cpp +++ b/host/TabDirect3D.cpp @@ -34,6 +34,8 @@ void CTabDirect3D::DoDataExchange(CDataExchange* pDX) DDX_Check(pDX, IDC_NOD3DRESET, cTarget->m_NoD3DReset); DDX_Check(pDX, IDC_SUPPRESSD3DEXT, cTarget->m_SuppressD3DExt); DDX_Check(pDX, IDC_FORCESHEL, cTarget->m_ForcesHEL); + DDX_Check(pDX, IDC_FIXREFCOUNTER, cTarget->m_FixRefCounter); + DDX_Check(pDX, IDC_RETURNNULLREF, cTarget->m_ReturnNullRef); // Ddraw tweaks DDX_Check(pDX, IDC_NOSYSMEMPRIMARY, cTarget->m_NoSysMemPrimary); diff --git a/host/TabDirectX.cpp b/host/TabDirectX.cpp index b4e7da7..6158799 100644 --- a/host/TabDirectX.cpp +++ b/host/TabDirectX.cpp @@ -40,9 +40,8 @@ void CTabDirectX::DoDataExchange(CDataExchange* pDX) DDX_Check(pDX, IDC_NOPALETTEUPDATE, cTarget->m_NoPaletteUpdate); DDX_Check(pDX, IDC_NOPIXELFORMAT, cTarget->m_NoPixelFormat); DDX_Check(pDX, IDC_NOALPHACHANNEL, cTarget->m_NoAlphaChannel); - DDX_Check(pDX, IDC_FIXREFCOUNTER, cTarget->m_FixRefCounter); - DDX_Check(pDX, IDC_RETURNNULLREF, cTarget->m_ReturnNullRef); DDX_Check(pDX, IDC_NOFLIPEMULATION, cTarget->m_NoFlipEmulation); + DDX_Check(pDX, IDC_FLIPEMULATION, cTarget->m_FlipEmulation); DDX_Check(pDX, IDC_FULLRECTBLT, cTarget->m_FullRectBlt); DDX_Check(pDX, IDC_CENTERTOWIN, cTarget->m_CenterToWin); DDX_Check(pDX, IDC_SETCOMPATIBILITY, cTarget->m_SetCompatibility); diff --git a/host/TargetDlg.cpp b/host/TargetDlg.cpp index 00ce1d7..c2dca3f 100644 --- a/host/TargetDlg.cpp +++ b/host/TargetDlg.cpp @@ -28,6 +28,7 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/) m_MouseVisibility = 0; m_HookDI = FALSE; m_ModifyMouse = TRUE; // default true !! + m_LogEnabled = FALSE; m_OutProxyTrace = FALSE; m_OutDebug = FALSE; m_RegistryOp = FALSE; @@ -37,6 +38,10 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/) m_OutD3DTrace = FALSE; m_OutDDRAWTrace = FALSE; m_OutDebugString = FALSE; + m_EraseLogFile = FALSE; + m_AddTimeStamp = FALSE; + m_ImportTable = FALSE; + m_TraceHooks = FALSE; m_DXProxed = FALSE; //m_HandleDC = FALSE; m_HandleExceptions = FALSE; @@ -124,6 +129,7 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/) m_KeepCursorFixed = FALSE; m_UseRGB565 = TRUE; // seems the default for 16bit video mode m_SuppressDXErrors = FALSE; + m_FlipEmulation = FALSE; m_MarkBlit = FALSE; m_MarkLock = FALSE; m_NoSysMemPrimary = FALSE; diff --git a/host/TargetDlg.h b/host/TargetDlg.h index 43d4058..c0e3bd6 100644 --- a/host/TargetDlg.h +++ b/host/TargetDlg.h @@ -97,6 +97,7 @@ public: BOOL m_KeepCursorFixed; BOOL m_UseRGB565; BOOL m_SuppressDXErrors; + BOOL m_FlipEmulation; BOOL m_MarkBlit; BOOL m_MarkLock; BOOL m_NoSysMemPrimary; diff --git a/host/dxwndhost.aps b/host/dxwndhost.aps index 7790ac0..9d095d4 100644 Binary files a/host/dxwndhost.aps and b/host/dxwndhost.aps differ diff --git a/host/dxwndhost.rc b/host/dxwndhost.rc index 6355d10..6df0913 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 e911037..16f5ebc 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 e41c5e5..8b70dd8 100644 --- a/host/dxwndhostView.cpp +++ b/host/dxwndhostView.cpp @@ -326,6 +326,7 @@ static void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg) if(dlg->m_KeepCursorFixed) t->flags2 |= KEEPCURSORFIXED; if(dlg->m_UseRGB565) t->flags |= USERGB565; if(dlg->m_SuppressDXErrors) t->flags |= SUPPRESSDXERRORS; + if(dlg->m_FlipEmulation) t->flags6 |= FLIPEMULATION; if(dlg->m_MarkBlit) t->flags3 |= MARKBLIT; if(dlg->m_MarkLock) t->flags3 |= MARKLOCK; if(dlg->m_NoSysMemPrimary) t->flags6 |= NOSYSMEMPRIMARY; @@ -554,6 +555,7 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg) dlg->m_KeepCursorFixed = t->flags2 & KEEPCURSORFIXED ? 1 : 0; dlg->m_UseRGB565 = t->flags & USERGB565 ? 1 : 0; dlg->m_SuppressDXErrors = t->flags & SUPPRESSDXERRORS ? 1 : 0; + dlg->m_FlipEmulation = t->flags6 & FLIPEMULATION ? 1 : 0; dlg->m_MarkBlit = t->flags3 & MARKBLIT ? 1 : 0; dlg->m_MarkLock = t->flags3 & MARKLOCK ? 1 : 0; dlg->m_NoSysMemPrimary = t->flags6 & NOSYSMEMPRIMARY ? 1 : 0; diff --git a/host/resource b/host/resource index 7dd19c1..2a40ede 100644 Binary files a/host/resource and b/host/resource differ