Index: ddraw/glDirectDraw.cpp |
— | — | @@ -835,13 +835,14 @@ |
836 | 836 | if(!lpDDSurfaceDesc2) TRACE_RET(HRESULT,23,DDERR_INVALIDPARAMS);
|
837 | 837 | if(pUnkOuter) TRACE_RET(HRESULT,23,DDERR_INVALIDPARAMS);
|
838 | 838 | if(lpDDSurfaceDesc2->dwSize < sizeof(DDSURFACEDESC2)) TRACE_RET(HRESULT,23,DDERR_INVALIDPARAMS);
|
839 | | - TRACE_RET(HRESULT,23,CreateSurface2(lpDDSurfaceDesc2,lplpDDSurface,pUnkOuter));
|
| 839 | + TRACE_RET(HRESULT,23,CreateSurface2(lpDDSurfaceDesc2,lplpDDSurface,pUnkOuter,TRUE));
|
840 | 840 | }
|
841 | 841 |
|
842 | 842 |
|
843 | | -HRESULT glDirectDraw7::CreateSurface2(LPDDSURFACEDESC2 lpDDSurfaceDesc2, LPDIRECTDRAWSURFACE7 FAR *lplpDDSurface, IUnknown FAR *pUnkOuter)
|
| 843 | +HRESULT glDirectDraw7::CreateSurface2(LPDDSURFACEDESC2 lpDDSurfaceDesc2, LPDIRECTDRAWSURFACE7 FAR *lplpDDSurface, IUnknown FAR *pUnkOuter, BOOL RecordSurface)
|
844 | 844 | {
|
845 | | - TRACE_ENTER(4,14,this,14,lpDDSurfaceDesc2,14,lplpDDSurface,14,pUnkOuter);
|
| 845 | + HRESULT error;
|
| 846 | + TRACE_ENTER(5, 14, this, 14, lpDDSurfaceDesc2, 14, lplpDDSurface, 14, pUnkOuter, 22, RecordSurface);
|
846 | 847 | if(!this) TRACE_RET(HRESULT,23,DDERR_INVALIDOBJECT);
|
847 | 848 | if(!lpDDSurfaceDesc2) TRACE_RET(HRESULT,23,DDERR_INVALIDPARAMS);
|
848 | 849 | if(pUnkOuter) TRACE_RET(HRESULT,23,DDERR_INVALIDPARAMS);
|
— | — | @@ -857,24 +858,31 @@ |
858 | 859 | }
|
859 | 860 | else TRACE_RET(HRESULT,23,DDERR_PRIMARYSURFACEALREADYEXISTS);
|
860 | 861 | }
|
861 | | - surfacecount++;
|
862 | | - if(surfacecount > surfacecountmax)
|
| 862 | + if (RecordSurface)
|
863 | 863 | {
|
864 | | - glDirectDrawSurface7 **surfaces2;
|
865 | | - surfaces2 = (glDirectDrawSurface7 **)realloc(surfaces,(surfacecountmax+1024)*sizeof(glDirectDrawSurface7 *));
|
866 | | - if(!surfaces2) TRACE_RET(HRESULT,23,DDERR_OUTOFMEMORY);
|
867 | | - surfaces = surfaces2;
|
868 | | - ZeroMemory(&surfaces[surfacecountmax],1024*sizeof(glDirectDrawSurface7 *));
|
869 | | - surfacecountmax += 1024;
|
| 864 | + surfacecount++;
|
| 865 | + if (surfacecount > surfacecountmax)
|
| 866 | + {
|
| 867 | + glDirectDrawSurface7 **surfaces2;
|
| 868 | + surfaces2 = (glDirectDrawSurface7 **)realloc(surfaces, (surfacecountmax + 1024)*sizeof(glDirectDrawSurface7 *));
|
| 869 | + if (!surfaces2) TRACE_RET(HRESULT, 23, DDERR_OUTOFMEMORY);
|
| 870 | + surfaces = surfaces2;
|
| 871 | + ZeroMemory(&surfaces[surfacecountmax], 1024 * sizeof(glDirectDrawSurface7 *));
|
| 872 | + surfacecountmax += 1024;
|
| 873 | + }
|
| 874 | + surfaces[surfacecount - 1] = new glDirectDrawSurface7(this, lpDDSurfaceDesc2, &error, false, NULL);
|
| 875 | + if (lpDDSurfaceDesc2->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
|
| 876 | + {
|
| 877 | + primary = surfaces[surfacecount - 1];
|
| 878 | + primarylost = false;
|
| 879 | + }
|
| 880 | + *lplpDDSurface = surfaces[surfacecount - 1];
|
870 | 881 | }
|
871 | | - HRESULT error;
|
872 | | - surfaces[surfacecount-1] = new glDirectDrawSurface7(this,lpDDSurfaceDesc2,&error,false,NULL);
|
873 | | - if(lpDDSurfaceDesc2->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
|
| 882 | + else
|
874 | 883 | {
|
875 | | - primary = surfaces[surfacecount-1];
|
876 | | - primarylost = false;
|
| 884 | + if (lpDDSurfaceDesc2->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) TRACE_RET(23, HRESULT, DDERR_INVALIDPARAMS);
|
| 885 | + *lplpDDSurface = new glDirectDrawSurface7(this, lpDDSurfaceDesc2, &error, false, NULL);
|
877 | 886 | }
|
878 | | - *lplpDDSurface = surfaces[surfacecount-1];
|
879 | 887 | TRACE_VAR("*lplpDDSurface",14,*lplpDDSurface);
|
880 | 888 | TRACE_EXIT(23,error);
|
881 | 889 | return error;
|
— | — | @@ -1152,6 +1160,7 @@ |
1153 | 1161 | ZeroMemory(surfaces,1024*sizeof(glDirectDrawSurface7 *));
|
1154 | 1162 | surfacecount = 0;
|
1155 | 1163 | surfacecountmax = 1024;
|
| 1164 | + tmpsurface = NULL;
|
1156 | 1165 | clippers = (glDirectDrawClipper **)malloc(1024*sizeof(glDirectDrawClipper *));
|
1157 | 1166 | if(!clippers) TRACE_RET(HRESULT,23,DDERR_OUTOFMEMORY);
|
1158 | 1167 | ZeroMemory(clippers,1024*sizeof(glDirectDrawClipper *));
|
— | — | @@ -1679,7 +1688,11 @@ |
1680 | 1689 | TRACE_ENTER(2,14,this,14,surface);
|
1681 | 1690 | for(int i = 0; i < surfacecount; i++)
|
1682 | 1691 | if(surfaces[i] == surface) surfaces[i] = NULL;
|
1683 | | - if(surface == primary) primary = NULL;
|
| 1692 | + if (surface == primary)
|
| 1693 | + {
|
| 1694 | + primary = NULL;
|
| 1695 | + DeleteTempSurface();
|
| 1696 | + }
|
1684 | 1697 | TRACE_EXIT(0,0);
|
1685 | 1698 | }
|
1686 | 1699 |
|
— | — | @@ -1691,6 +1704,60 @@ |
1692 | 1705 | TRACE_EXIT(0,0);
|
1693 | 1706 | }
|
1694 | 1707 |
|
| 1708 | +HRESULT glDirectDraw7::SetupTempSurface(DWORD width, DWORD height)
|
| 1709 | +{
|
| 1710 | + DDSURFACEDESC2 ddsd;
|
| 1711 | + HRESULT error;
|
| 1712 | + if (!width || !height) return DDERR_INVALIDPARAMS;
|
| 1713 | + if (!tmpsurface)
|
| 1714 | + {
|
| 1715 | + ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2));
|
| 1716 | + ddsd.dwSize = sizeof(DDSURFACEDESC2);
|
| 1717 | + ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
|
| 1718 | + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
|
| 1719 | + ddsd.dwWidth = width;
|
| 1720 | + ddsd.dwHeight = height;
|
| 1721 | + error = CreateSurface2(&ddsd, (LPDIRECTDRAWSURFACE7*)&tmpsurface, NULL, FALSE);
|
| 1722 | + if (error == DDERR_OUTOFVIDEOMEMORY)
|
| 1723 | + {
|
| 1724 | + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
|
| 1725 | + error = CreateSurface2(&ddsd, (LPDIRECTDRAWSURFACE7*)&tmpsurface, NULL, FALSE);
|
| 1726 | + }
|
| 1727 | + if (error != DD_OK) return error;
|
| 1728 | + }
|
| 1729 | + else
|
| 1730 | + {
|
| 1731 | + if ((tmpsurface->ddsd.dwWidth >= width) && (tmpsurface->ddsd.dwHeight >= height)) return DD_OK;
|
| 1732 | + else
|
| 1733 | + {
|
| 1734 | + ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2));
|
| 1735 | + ddsd.dwSize = sizeof(DDSURFACEDESC2);
|
| 1736 | + ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
|
| 1737 | + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
|
| 1738 | + ddsd.dwWidth = width > tmpsurface->ddsd.dwWidth ? width : tmpsurface->ddsd.dwWidth;
|
| 1739 | + ddsd.dwHeight = height > tmpsurface->ddsd.dwHeight ? height : tmpsurface->ddsd.dwHeight;
|
| 1740 | + tmpsurface->Release();
|
| 1741 | + tmpsurface = NULL;
|
| 1742 | + error = CreateSurface(&ddsd, (LPDIRECTDRAWSURFACE7*)&tmpsurface, NULL);
|
| 1743 | + if (error == DDERR_OUTOFVIDEOMEMORY)
|
| 1744 | + {
|
| 1745 | + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
|
| 1746 | + error = CreateSurface(&ddsd, (LPDIRECTDRAWSURFACE7*)&tmpsurface, NULL);
|
| 1747 | + }
|
| 1748 | + if (error != DD_OK) return error;
|
| 1749 | + }
|
| 1750 | + }
|
| 1751 | + return DD_OK;
|
| 1752 | +}
|
| 1753 | +
|
| 1754 | +void glDirectDraw7::DeleteTempSurface()
|
| 1755 | +{
|
| 1756 | + if (tmpsurface)
|
| 1757 | + {
|
| 1758 | + tmpsurface->Release();
|
| 1759 | + tmpsurface = 0;
|
| 1760 | + }
|
| 1761 | +}
|
1695 | 1762 | // DDRAW1 wrapper
|
1696 | 1763 | glDirectDraw1::glDirectDraw1(glDirectDraw7 *gl_DD7)
|
1697 | 1764 | {
|
— | — | @@ -1766,7 +1833,7 @@ |
1767 | 1834 | if(!lpDDSurfaceDesc) TRACE_RET(HRESULT,23,DDERR_INVALIDPARAMS);
|
1768 | 1835 | if(lpDDSurfaceDesc->dwSize < sizeof(DDSURFACEDESC)) TRACE_RET(HRESULT,23,DDERR_INVALIDPARAMS);
|
1769 | 1836 | LPDIRECTDRAWSURFACE7 lpDDS7;
|
1770 | | - HRESULT err = glDD7->CreateSurface2((LPDDSURFACEDESC2)lpDDSurfaceDesc,&lpDDS7,pUnkOuter);
|
| 1837 | + HRESULT err = glDD7->CreateSurface2((LPDDSURFACEDESC2)lpDDSurfaceDesc,&lpDDS7,pUnkOuter,TRUE);
|
1771 | 1838 | if(err == DD_OK)
|
1772 | 1839 | {
|
1773 | 1840 | lpDDS7->QueryInterface(IID_IDirectDrawSurface,(LPVOID*) lplpDDSurface);
|
— | — | @@ -1954,7 +2021,7 @@ |
1955 | 2022 | if(!lpDDSurfaceDesc) TRACE_RET(HRESULT,23,DDERR_INVALIDPARAMS);
|
1956 | 2023 | if(lpDDSurfaceDesc->dwSize < sizeof(DDSURFACEDESC)) TRACE_RET(HRESULT,23,DDERR_INVALIDPARAMS);
|
1957 | 2024 | LPDIRECTDRAWSURFACE7 lpDDS7;
|
1958 | | - HRESULT err = glDD7->CreateSurface2((LPDDSURFACEDESC2)lpDDSurfaceDesc,&lpDDS7,pUnkOuter);
|
| 2025 | + HRESULT err = glDD7->CreateSurface2((LPDDSURFACEDESC2)lpDDSurfaceDesc,&lpDDS7,pUnkOuter,TRUE);
|
1959 | 2026 | if(err == DD_OK)
|
1960 | 2027 | {
|
1961 | 2028 | lpDDS7->QueryInterface(IID_IDirectDrawSurface,(LPVOID*) lplpDDSurface);
|
— | — | @@ -2165,7 +2232,7 @@ |
2166 | 2233 | if(!lpDDSurfaceDesc) TRACE_RET(HRESULT,23,DDERR_INVALIDPARAMS);
|
2167 | 2234 | if(lpDDSurfaceDesc->dwSize < sizeof(DDSURFACEDESC2)) TRACE_RET(HRESULT,23,DDERR_INVALIDPARAMS);
|
2168 | 2235 | LPDIRECTDRAWSURFACE7 lpDDS7;
|
2169 | | - HRESULT err = glDD7->CreateSurface2((LPDDSURFACEDESC2)lpDDSurfaceDesc,&lpDDS7,pUnkOuter);
|
| 2236 | + HRESULT err = glDD7->CreateSurface2((LPDDSURFACEDESC2)lpDDSurfaceDesc,&lpDDS7,pUnkOuter,TRUE);
|
2170 | 2237 | if(err == DD_OK)
|
2171 | 2238 | {
|
2172 | 2239 | lpDDS7->QueryInterface(IID_IDirectDrawSurface4,(LPVOID*) lplpDDSurface);
|
Index: ddraw/glDirectDraw.h |
— | — | @@ -19,6 +19,8 @@ |
20 | 20 | #ifndef _GLDIRECTDRAW_H
|
21 | 21 | #define _GLDIRECTDRAW_H
|
22 | 22 |
|
| 23 | +#define DXGLBLT_NOPALSHADER 0x80000000
|
| 24 | +
|
23 | 25 | class glDirectDrawSurface7;
|
24 | 26 | class glDirectDrawClipper;
|
25 | 27 | class glDirect3D7;
|
— | — | @@ -70,7 +72,7 @@ |
71 | 73 | HRESULT WINAPI EvaluateMode(DWORD dwFlags, DWORD *pSecondsUntilTimeout);
|
72 | 74 |
|
73 | 75 | // internal functions
|
74 | | - HRESULT CreateSurface2(LPDDSURFACEDESC2 lpDDSurfaceDesc2, LPDIRECTDRAWSURFACE7 FAR *lplpDDSurface, IUnknown FAR *pUnkOuter);
|
| 76 | + HRESULT CreateSurface2(LPDDSURFACEDESC2 lpDDSurfaceDesc2, LPDIRECTDRAWSURFACE7 FAR *lplpDDSurface, IUnknown FAR *pUnkOuter, BOOL RecordSurface);
|
75 | 77 | HRESULT err() {return error;}
|
76 | 78 | void RemoveSurface(glDirectDrawSurface7 *surface);
|
77 | 79 | void GetSizes(LONG *sizes);
|
— | — | @@ -82,6 +84,8 @@ |
83 | 85 | bool GetFullscreen(){return fullscreen;};
|
84 | 86 | void DeleteSurface(glDirectDrawSurface7 *surface);
|
85 | 87 | void DeleteClipper(glDirectDrawClipper *clipper);
|
| 88 | + HRESULT SetupTempSurface(DWORD width, DWORD height);
|
| 89 | + void DeleteTempSurface();
|
86 | 90 | glDirectDrawSurface7 *primary;
|
87 | 91 | bool primarylost;
|
88 | 92 | bool lastsync;
|
— | — | @@ -90,6 +94,7 @@ |
91 | 95 | glDirectDraw4 *glDD4;
|
92 | 96 | DDDEVICEIDENTIFIER2 devid;
|
93 | 97 | glRenderer *renderer;
|
| 98 | + glDirectDrawSurface7 *tmpsurface;
|
94 | 99 | private:
|
95 | 100 | HRESULT error;
|
96 | 101 | ULONG refcount;
|
Index: ddraw/glDirectDrawSurface.cpp |
— | — | @@ -607,6 +607,8 @@ |
608 | 608 | }
|
609 | 609 | HRESULT WINAPI glDirectDrawSurface7::Blt(LPRECT lpDestRect, LPDIRECTDRAWSURFACE7 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx)
|
610 | 610 | {
|
| 611 | + HRESULT error;
|
| 612 | + RECT tmprect;
|
611 | 613 | TRACE_ENTER(6,14,this,26,lpDestRect,14,lpDDSrcSurface,26,lpSrcRect,9,dwFlags,14,lpDDBltFx);
|
612 | 614 | if(!this) TRACE_RET(HRESULT,23,DDERR_INVALIDOBJECT);
|
613 | 615 | if((dwFlags & DDBLT_COLORFILL) && !lpDDBltFx) TRACE_RET(HRESULT,23,DDERR_INVALIDPARAMS);
|
— | — | @@ -626,7 +628,18 @@ |
627 | 629 | src->ddsd.ddpfPixelFormat.dwRGBBitCount);
|
628 | 630 | src->dirty &= ~1;
|
629 | 631 | }
|
630 | | - TRACE_RET(HRESULT,23,ddInterface->renderer->Blt(lpDestRect,src,this,lpSrcRect,dwFlags,lpDDBltFx));
|
| 632 | + if (this == src)
|
| 633 | + {
|
| 634 | + tmprect.left = tmprect.top = 0;
|
| 635 | + tmprect.right = lpSrcRect->right - lpSrcRect->left;
|
| 636 | + tmprect.bottom = lpSrcRect->bottom - lpSrcRect->top;
|
| 637 | + error = ddInterface->SetupTempSurface(tmprect.right, tmprect.bottom);
|
| 638 | + if (error) TRACE_RET(HRESULT, 23, error);
|
| 639 | + error = ddInterface->tmpsurface->Blt(&tmprect, lpDDSrcSurface, lpSrcRect, 0, NULL);
|
| 640 | + if (error) TRACE_RET(HRESULT, 23, error);
|
| 641 | + TRACE_RET(HRESULT,23,this->Blt(lpDestRect, ddInterface->tmpsurface, &tmprect, dwFlags, lpDDBltFx));
|
| 642 | + }
|
| 643 | + else TRACE_RET(HRESULT,23,ddInterface->renderer->Blt(lpDestRect,src,this,lpSrcRect,dwFlags,lpDDBltFx));
|
631 | 644 | }
|
632 | 645 | HRESULT WINAPI glDirectDrawSurface7::BltBatch(LPDDBLTBATCH lpDDBltBatch, DWORD dwCount, DWORD dwFlags)
|
633 | 646 | {
|