Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

2778 lines
89 KiB

/*==========================================================================
*
* Copyright (C) 1997 Microsoft Corporation. All Rights Reserved.
*
* File: ddrawex.cpp
* Content: new DirectDraw object support
* History:
* Date By Reason
* ==== == ======
* 24-feb-97 ralphl initial implementation
* 25-feb-97 craige minor tweaks for dx checkin; integrated IBitmapSurface
* stuff
* 27-feb-97 craige use DIBSections for surface memory ddraw 3 surfaces
* (icky icky icky)
* 03-mar-97 craige IRGBColorTable support
* 06-mar-97 craige support for IDirectDrawSurface3::SetBits
* 14-mar-97 jeffort SetBits changed to reflect DX5 as SetSurfaceDesc
* 01-apr-97 jeffort Following changes checked in:
* D3DDevice and Texture interfaces supported in QueryInterface
* MakeDibInfo fills in a dummy pixel mask for Z Buffers
* Aligned freeing handled
* Does not init (MakeDibSection) of primary surfaces
* A palette is mapped in at GetDC calls
*
* 04-apr-97 jeffort LocalFree of bitmap info added
* Addref and release added for D3D interfaces
*
* 09-apr-97 jeffort Added call to SetDIBColorTable at GetDC time
* Support for WinNT4.0 Gold added by not creating a DIB section
* and not supporting SetSurfaceDesc calls
* Added support for halftone palette if no palette is
* selected in at init time
* Added support for proper handling of 1,2,and 4 bpp surface palettes
* IBitmapSurface creation needs to set OWNDC flag
*
* 10-apr-97 jeffort Correct number of entries used in palette creation at GetDC time
*
* 16-apr-97 jeffort Check for OWNDC when creating a DibSection. palette handling
* change in GetDC of setting flags
* 28-apr-97 jeffort Palette wrapping added/DX5 support
* 30-apr-97 jeffort Critical section shared from ddrawex object
* Attach list deleted at surface destruction time
* AddAttachedSurfaces now passes in real interfaces
* Palette functions pass in real interfaces to ddraw
* AddRef removed from D3D interface QI's
* 02-may-97 jeffort Deletion of implicit attached surface handled
* wrapping of GetDDInterface returns our ddrawex interface
* 06-may-97 jeffort Parameter checking, SetPalette handles null parameter
* wrapping of DeleteAttachedSurface
*
* 08-may-97 jeffort SetPalette fixes (release should have been addref)
* Better parameter checking
* 20-may-97 jeffort NT4.0 Gold handles OWNDC as SP3 does by creating a dib
* section and resets a few ddraw internal structures
* These are reset at surface release time
* 22-may-97 jeffort If a surface is being destroyed, detach any attached palette
* If a SetPalette is called with NULL, and a palette
* was previously attached, the member variable storing the
* palette is set to NULL
* 27-may-97 jeffort keep ref count on internal object eual to outer object
* 02-jun-97 jeffort Temporary fix for SP3 memory leak. Handle SP3 as NT Gold
* by storing off pointer values and restoring at free
* 17-jun-97 jeffort If releasing a surface that has explicitly attached surfaces
* we now addref the inner surface (which will be released when
* the inner surface we are releasing is released), and release
* our outer interface so ref counting models ddraw.
* 20-jun-97 jeffort added debug code to invaliudate objects when freed
* when creating the primary surface, this is now added to the primary
* surface list regardles if OWNDC is set or not
* 27-jun-97 jeffort IDirectDrawSurface3 interface support for DX3 was not
* added. We now use an IDirectDrawSurface2 to spoof it
* so we can support SetSurfaceDesc
* 02-jul-97 jeffort Use m_bSaveDC boolean if a DX5 surface with OWNDC set
* we need to not NULL out the DC when ReleaseDC is called
* so that a call to GetSurfaceFromDC will work
* 07-jul-97 jeffort Releasing DDrawEx object moved in destructor function to last step
* 07-jul-97 jeffort Wrapped GetSurfaceDesc so correct caps bits are set
* 10-jul-97 jeffort Added m_BMOld to reset the bitmap after releasing the one
* we create
* Do not add a surface to a palette list if it is already in this list
* 18-jul-97 jeffort Added D3D MMX Device support
* 22-jul-97 jeffort Removed IBitmapSurface and associated interfaces
* Fixed problem with attach lists, and releasing implicit created surfaces
* 02-aug-97 jeffort Added code to GetPalette to return a palette if the palette that
* was set was not created with the same ddrawex object that the surface was
* Added code to handle attaching surfaces that were created with different
* ddrawex objects
* 20-feb-98 stevela Added support for DX6 MMX rasterizers
***************************************************************************/
#include "ddfactry.h"
#include "d3d.h"
#define m_pDDSurface (m_DDSInt.m_pRealInterface)
#define m_pDDSurface2 (m_DDS2Int.m_pRealInterface)
#define m_pDDSurface3 (m_DDS3Int.m_pRealInterface)
#define m_pDDSurface4 (m_DDS4Int.m_pRealInterface)
#define DDSURFACETYPE_1 1
#define DDSURFACETYPE_2 2
#define DDSURFACETYPE_3 3
#define DDSURFACETYPE_4 4
typedef struct _ATTACHLIST
{
DWORD dwFlags;
struct _ATTACHLIST FAR *lpLink; // link to next attached surface
struct _DDRAWI_DDRAWSURFACE_LCL FAR *lpAttached; // attached surface local obj
struct _DDRAWI_DDRAWSURFACE_INT FAR *lpIAttached; // attached surface interface
} ATTACHLIST;
typedef ATTACHLIST FAR *LPATTACHLIST;
#define DDAL_IMPLICIT 0x00000001l
/*
* CDDSurface::CDDSurface
*
* Constructor for simple surface object
*/
CDDSurface::CDDSurface(
DDSURFACEDESC *pSurfaceDesc,
IDirectDrawSurface *pDDSurface,
IDirectDrawSurface2 *pDDSurface2,
IDirectDrawSurface3 *pDDSurface3,
IDirectDrawSurface4 *pDDSurface4,
IUnknown *pUnkOuter,
CDirectDrawEx *pDirectDrawEx) :
m_cRef(1),
m_pUnkOuter(pUnkOuter != 0 ? pUnkOuter : CAST_TO_IUNKNOWN(this)),
m_pDirectDrawEx(pDirectDrawEx),
m_bOwnDC((pSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_OWNDC) != 0),
m_HDC(NULL)
{
m_pDDSurface = pDDSurface;
m_pDDSurface2 = pDDSurface2;
m_pDDSurface3 = pDDSurface3;
m_pDDSurface4 = pDDSurface4;
m_DDSInt.m_pSimpleSurface = this;
m_DDS2Int.m_pSimpleSurface = this;
m_DDS3Int.m_pSimpleSurface = this;
m_DDS4Int.m_pSimpleSurface = this;
m_D3DDeviceRAMPInt = NULL;
m_D3DDeviceRGBInt = NULL;
m_D3DDeviceChrmInt = NULL;
m_D3DDeviceHALInt = NULL;
m_D3DDeviceMMXInt = NULL;
m_D3DTextureInt = NULL;
m_pCurrentPalette = NULL;
m_pPrevPalette = NULL;
m_pNextPalette = NULL;
m_pSaveBits = NULL;
m_bSaveDC = FALSE;
m_pAttach = NULL;
if (m_pDirectDrawEx->m_dwDDVer == WIN95_DX5 || m_pDirectDrawEx->m_dwDDVer == WINNT_DX5)
InitSurfaceInterfaces( pDDSurface, &m_DDSInt, pDDSurface2, &m_DDS2Int, pDDSurface3, &m_DDS3Int, pDDSurface4, &m_DDS4Int );
else
InitSurfaceInterfaces( pDDSurface, &m_DDSInt, pDDSurface2, &m_DDS2Int, NULL, &m_DDS3Int, pDDSurface4, &m_DDS4Int );
m_dwCaps = pSurfaceDesc->ddsCaps.dwCaps;
m_hDCDib = NULL;
m_hBMDib = NULL;
m_pBitsDib = NULL;
m_pDDPal = NULL;
m_pDDPalOurs = NULL;
m_bPrimaryPalette = FALSE;
pDirectDrawEx->AddRef();
pDirectDrawEx->AddSurfaceToList(this);
//we want to know if this is the primary surface or not
if (pSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
m_bIsPrimary = TRUE;
else
m_bIsPrimary = FALSE;
//if we created the DIBSection, and it is palettized, we need to add this to
//the list of surfaces using the primary surface's palette
if ( (m_bOwnDC && (pSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED1 ||
pSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED2 ||
pSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED4 ||
pSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8)) || m_bIsPrimary)
{
pDirectDrawEx->AddSurfaceToPrimaryList(this);
}
#ifdef DEBUG
m_DebugCheckDC = NULL;
#endif
DllAddRef();
} /* CDDSurface::CDDSurface */
/*
* CDDSurface::MakeDibInfo
*
* create a dib info structure based on the surface desc + palette
*/
HRESULT CDDSurface::MakeDibInfo( LPDDSURFACEDESC pddsd, LPBITMAPINFO pbmi )
{
DWORD bitcnt;
/*
* fill in basic values
*/
pbmi->bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
pbmi->bmiHeader.biPlanes = 1;
pbmi->bmiHeader.biSizeImage = 0;
pbmi->bmiHeader.biXPelsPerMeter = 0;
pbmi->bmiHeader.biYPelsPerMeter = 0;
pbmi->bmiHeader.biClrImportant = 0;
bitcnt = pddsd->ddpfPixelFormat.dwRGBBitCount;
pbmi->bmiHeader.biBitCount = (WORD) bitcnt;
/*
* fill out width, clrused, and compression fields based on bit depth
*/
switch( bitcnt )
{
case 1:
pbmi->bmiHeader.biWidth = pddsd->lPitch << 3;
pbmi->bmiHeader.biClrUsed = 2;
pbmi->bmiHeader.biCompression = BI_RGB;
break;
case 4:
pbmi->bmiHeader.biWidth = pddsd->lPitch << 1;
pbmi->bmiHeader.biClrUsed = 16;
pbmi->bmiHeader.biCompression = BI_RGB;
break;
case 8:
pbmi->bmiHeader.biWidth = pddsd->lPitch;
if(pddsd->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8)
{
pbmi->bmiHeader.biClrUsed = 256;
pbmi->bmiHeader.biCompression = BI_RGB;
}
else
{
pbmi->bmiHeader.biClrUsed = 0;
pbmi->bmiHeader.biCompression = BI_BITFIELDS;
}
break;
case 16:
pbmi->bmiHeader.biWidth = pddsd->lPitch >> 1;
pbmi->bmiHeader.biClrUsed = 0;
pbmi->bmiHeader.biCompression = BI_BITFIELDS;
break;
case 24:
// NOTE: we're assuming RGB format. This is okay since we
// don't do color conversion and neither does GDI at 24-bpp.
pbmi->bmiHeader.biWidth = pddsd->lPitch / 3;
pbmi->bmiHeader.biClrUsed = 0;
pbmi->bmiHeader.biCompression = BI_RGB;
break;
case 32:
pbmi->bmiHeader.biWidth = pddsd->lPitch >> 2;
pbmi->bmiHeader.biClrUsed = 0;
pbmi->bmiHeader.biCompression = BI_RGB;
break;
default:
{
char str[256];
wsprintf( str, "bitcnt = %ld", bitcnt );
MessageBox( NULL, str, "WHAT THE HECK, PIXEL DEPTH IS BAD BAD BAD", MB_OK );
}
}
/*
* set the color masks if we need to...
*/
if( pbmi->bmiHeader.biCompression == BI_BITFIELDS )
{
DWORD *p;
p = (DWORD *) &pbmi->bmiColors[0];
p[0] = pddsd->ddpfPixelFormat.dwRBitMask;
p[1] = pddsd->ddpfPixelFormat.dwGBitMask;
p[2] = pddsd->ddpfPixelFormat.dwBBitMask;
//check for no masks. Z-buffers don't have masks
//so set a dummy value for this function call
if (p[0] == 0 && p[1] == 0 && p[2] == 0){
p[0]=0xF800;
p[1]=0x07E0;
p[2]=0x001F;
}
/*
* set the image size too
*/
pbmi->bmiHeader.biSizeImage = pddsd->lPitch * (int) pddsd->dwHeight;
}
/*
* height is easy
*/
pbmi->bmiHeader.biHeight= -1*(int)pddsd->dwHeight;
/*
* fill in the color table...
*/
if( bitcnt <= 8 )
{
PALETTEENTRY pe[256];
int i;
LPDIRECTDRAWPALETTE pddpal;
HRESULT hr;
/*
* is there an attached palette?
*/
hr = m_pDDSurface->GetPalette( &pddpal );
if( SUCCEEDED( hr ) )
{
//need to figure out how many entries are in here
DWORD dwCaps;
hr = pddpal->GetCaps(&dwCaps);
if (SUCCEEDED(hr))
{
DWORD dwNumEntries;
if (dwCaps & DDPCAPS_1BIT)
dwNumEntries = 1;
else if (dwCaps & DDPCAPS_2BIT)
dwNumEntries = 4;
else if (dwCaps & DDPCAPS_4BIT)
dwNumEntries = 16;
else if (dwCaps & DDPCAPS_8BIT)
dwNumEntries = 256;
else
dwNumEntries = 0;
hr = pddpal->GetEntries( 0, 0, dwNumEntries, pe );
}
pddpal->Release();
}
//if we created the DIBSection, and we are in EXCLUSIVE mode
//then use the primary surface's palette if it exisits yet.
else if (m_pDirectDrawEx->m_bExclusive)
{
//try and find the primary surface palette
CDDPalette *pPal;
pPal = m_pDirectDrawEx->m_pFirstPalette;
while (pPal != NULL && pPal->m_bIsPrimary != TRUE)
pPal = pPal->m_pNext;
if (pPal != NULL)
{
DWORD dwCaps;
hr = pPal->m_DDPInt.m_pRealInterface->GetCaps(&dwCaps);
if (SUCCEEDED(hr))
{
DWORD dwNumEntries;
if (dwCaps & DDPCAPS_1BIT)
dwNumEntries = 1;
else if (dwCaps & DDPCAPS_2BIT)
dwNumEntries = 4;
else if (dwCaps & DDPCAPS_4BIT)
dwNumEntries = 16;
else if (dwCaps & DDPCAPS_8BIT)
dwNumEntries = 256;
else
dwNumEntries = 0;
hr = pPal->m_DDPInt.m_pRealInterface->GetEntries( 0, 0, dwNumEntries, pe );
}
}
}
/*
* nope, so use the system palette
*/
if( FAILED( hr ) )
{
HDC hdc;
hdc = ::GetDC( NULL );
GetSystemPaletteEntries(hdc, 0, 256, pe);
::ReleaseDC(NULL, hdc);
}
/*
* now copy the color table
*/
int iNumEntries;
switch (bitcnt)
{
case 1:
iNumEntries = 1;
break;
case 2:
iNumEntries = 4;
break;
case 4:
iNumEntries = 16;
break;
case 8:
iNumEntries = 256;
break;
default:
iNumEntries = 0;
break;
}
for(i=0;i < iNumEntries;i++)
{
pbmi->bmiColors[i].rgbRed = pe[i].peRed;
pbmi->bmiColors[i].rgbGreen = pe[i].peGreen;
pbmi->bmiColors[i].rgbBlue= pe[i].peBlue;
}
}
return DD_OK;
} /* CDDSurface::MakeDibInfo */
/*
* CDDSurface::MakeDIBSection()
*/
HRESULT CDDSurface::MakeDIBSection()
{
DDSURFACEDESC ddsd;
DWORD size;
DWORD bitcnt;
LPBITMAPINFO pbmi;
/*
* don't need to bother if the DirectDraw version isn't 3 or if it
* isn't a system memory surface
*/
#pragma message( REMIND( "Should we use a DIB unless the surface really is in video memory?" ))
if( m_pDirectDrawEx->m_dwDDVer == WIN95_DX5 || m_pDirectDrawEx->m_dwDDVer == WINNT_DX5 || !(m_dwCaps & DDSCAPS_SYSTEMMEMORY))
{
return 1;
}
/*
* so we need to make a dib section that is identical to this surface
* first, get the surface desc
*/
ddsd.dwSize = sizeof( ddsd );
m_pDDSurface->GetSurfaceDesc( &ddsd );
/*
* allocate a pixel format structure
*/
size = sizeof(BITMAPINFOHEADER);
bitcnt = ddsd.ddpfPixelFormat.dwRGBBitCount;
if( bitcnt <= 8)
{
size += (1<<bitcnt)*sizeof(RGBQUAD);
}
else
{
size += sizeof(DWORD)*3;
}
pbmi = (LPBITMAPINFO) LocalAlloc( LPTR, size );
if( pbmi == NULL )
{
return DDERR_OUTOFMEMORY;
}
/*
* flesh out the bitmap info header
*/
MakeDibInfo( &ddsd, pbmi );
/*
* make the DIB section
*/
m_hDCDib = CreateCompatibleDC(NULL);
if( m_hDCDib != NULL )
{
m_hBMDib = CreateDIBSection(
m_hDCDib, // the HDC
pbmi, // bitmap info
DIB_RGB_COLORS, // use color table in bitmap info
&m_pBitsDib, // dib bits
NULL, // no file handle
0 ); // offset into file (irrelevant)
//free up our bitmap info struct
LocalFree(pbmi);
if( m_hBMDib == NULL )
{
DeleteDC( m_hDCDib );
return DDERR_OUTOFMEMORY;
}
/*
* select our bitmap into our new DC
*/
m_hBMOld = (HBITMAP)SelectObject( m_hDCDib, (void *)m_hBMDib );
#ifdef DEBUG
ASSERT(m_hBMOld != NULL);
#endif
}
else
{
//free up our local bitmap structure
LocalFree(pbmi);
return DDERR_OUTOFMEMORY;
}
return DD_OK;
} /* CDDSurface::MakeDIBSection */
HRESULT CDDSurface::SupportOwnDC()
{
/*
* if we want our own DC, then create one
*/
HRESULT hr = DD_OK;
if( m_bOwnDC )
{
HRESULT hrGotSurface, hrGotDC;
IDirectDrawSurface *pTempSurface;
HDC hdcTemp = NULL;
/*
* Eat the cached HDC so owned DC surfaces won't use it.
*/
DDSURFACEDESC ddsd;
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY;
ddsd.dwHeight = ddsd.dwWidth = 1;
hrGotSurface = m_pDirectDrawEx->m_DDInt.m_pRealInterface->CreateSurface(&ddsd, &pTempSurface, NULL);
if( SUCCEEDED(hrGotSurface) )
{
hrGotDC = pTempSurface->GetDC(&hdcTemp);
}
/*
* get the DC and then unlock the surface
* we know that GetDC does a Lock, so the Unlock will allow the
* DC to be used and Lock/Unlock to be used together...
*/
hr = m_pDDSurface->GetDC(&m_HDC);
if( SUCCEEDED(hr) )
{
m_pDDSurface->Unlock(NULL);
}
else
{
m_bOwnDC = FALSE; // To prevent destructor from doing unlock trick
m_HDC = NULL; // Just to make sure...
}
/*
* clean up the extra surface/dc
*/
if( SUCCEEDED(hrGotSurface) )
{
if( SUCCEEDED(hrGotDC) )
{
pTempSurface->ReleaseDC(hdcTemp);
}
pTempSurface->Release();
}
}
return hr;
}//CDDSurface::SupportOwnDC
/*
* CDDSurface::Init
*
* Initialize the surface
*/
HRESULT CDDSurface::Init()
{
HRESULT hr = S_OK;
hr = MakeDIBSection();
if( FAILED( hr ) )
{
return hr;
}
/*
* if we made the DIB section, then we need to tweak the internal
* direct draw surface stucture (only allowed for direct draw 3)
*/
if( hr == DD_OK )
{
LPDDRAWI_DDRAWSURFACE_INT psurf_int;
psurf_int = (LPDDRAWI_DDRAWSURFACE_INT) m_pDDSurface;
/*
* mark the surface memory as freed, and replace the memory with
* our dib section memory
*/
psurf_int->lpLcl->lpGbl->dwGlobalFlags |= DDRAWISURFGBL_MEMFREE;
DWORD dwOffset;
LPVOID lpMem;
lpMem= (LPVOID) psurf_int->lpLcl->lpGbl->fpVidMem;
//probably don't need this check, but it can't hurt
if( NULL != lpMem )
{
if (m_pDirectDrawEx->m_dwDDVer != WINNT_DX2 && m_pDirectDrawEx->m_dwDDVer != WINNT_DX3)
{
//check to see if this surface has been aligned and reset the pointer if so
if(psurf_int->lpLcl->ddsCaps.dwCaps & DDSCAPS_ZBUFFER ||
psurf_int->lpLcl->ddsCaps.dwCaps & DDSCAPS_TEXTURE ||
psurf_int->lpLcl->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN)
{
dwOffset = *( (LPDWORD) ( ( (LPBYTE)lpMem ) - sizeof(DWORD) ) );
lpMem = (LPVOID) ( ( (LPBYTE) lpMem) - dwOffset );
}
//free the memory
LocalFree(lpMem);
}
else
{
//store this value off so we can use it when we destroy the surface
m_pSaveBits = (ULONG_PTR)lpMem;
m_pSaveHDC = psurf_int->lpLcl->hDC;
m_pSaveHBM = psurf_int->lpLcl->dwReserved1;
}
}
psurf_int->lpLcl->lpGbl->fpVidMem = (ULONG_PTR) m_pBitsDib;
return hr;
}
hr = SupportOwnDC();
return hr;
} /* CDDSurface::Init */
void CDDSurface::CleanUpSurface()
{
if( m_bOwnDC && m_HDC != NULL )
{
DDSURFACEDESC ddsd;
ddsd.dwSize = sizeof(ddsd);
m_pDDSurface->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL);
}
if( m_HDC != NULL )
{
m_pDDSurface->ReleaseDC(m_HDC);
}
if( m_hBMDib != NULL )
{
/* un-select our bitmap from the DC */
SelectObject(m_hDCDib, m_hBMOld);
DeleteObject( m_hBMDib );
}
if( m_hDCDib != NULL )
{
DeleteDC( m_hDCDib );
}
/*
* clean up...
*/
//if a palette is attached to this surface, detach it here
if (m_pCurrentPalette != NULL)
InternalSetPalette(NULL, 1);
m_pDirectDrawEx->RemoveSurfaceFromList(this);
if (m_pCurrentPalette)
m_pCurrentPalette->RemoveSurfaceFromList(this);
else if (m_bPrimaryPalette)
m_pDirectDrawEx->RemoveSurfaceFromPrimaryList(this);
//if we are running under NT4 Gold, we need to see if we modified the surface
if ((m_pDirectDrawEx->m_dwDDVer == WINNT_DX2 || m_pDirectDrawEx->m_dwDDVer == WINNT_DX3) && m_pSaveBits != NULL)
{
LPDDRAWI_DDRAWSURFACE_INT psurf_int;
psurf_int = (LPDDRAWI_DDRAWSURFACE_INT) m_pDDSurface;
psurf_int->lpLcl->lpGbl->dwGlobalFlags &= ~(DDRAWISURFGBL_MEMFREE);
psurf_int->lpLcl->lpGbl->fpVidMem = (FLATPTR) m_pSaveBits;
psurf_int->lpLcl->hDC = m_pSaveHDC;
psurf_int->lpLcl->dwReserved1 = m_pSaveHBM;
}
}
void CDDSurface::ReleaseRealInterfaces()
{
if( m_pDDSurface3 != NULL )
{
m_pDDSurface3->Release();
}
m_pDDSurface2->Release();
m_pDDSurface->Release();
m_pDirectDrawEx->Release();
#ifdef DEBUG
DWORD * ptr;
ptr = (DWORD *)this;
for (int i = 0; i < sizeof(CDDSurface) / sizeof(DWORD);i++)
*ptr++ = 0xDEADBEEF;
#endif
DllRelease();
}
void CDDSurface::AddSurfaceToDestroyList(CDDSurface * pSurface)
{
#ifdef DEBUG
ASSERT(pSurface != NULL);
#endif
ENTER_DDEX();
if( m_pDestroyList )
{
#ifdef DEBUG
ASSERT(m_pDestroyList->m_pPrev == NULL);
#endif
m_pDestroyList->m_pPrev = pSurface;
}
pSurface->m_pPrev = NULL;
pSurface->m_pNext = m_pDestroyList;
m_pDestroyList = pSurface;
LEAVE_DDEX();
}
void CDDSurface::DeleteAttachment(IDirectDrawSurface * pOrigSurf, CDDSurface * pFirst)
{
LPATTACHLIST lpAttach;
IDirectDrawSurface * pSurface;
CDDSurface * pSurfaceOuter;
CleanUpSurface();
//check for attached surface here
lpAttach = (LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(m_pDDSurface))->lpLcl->lpAttachList);
pSurface = m_pDDSurface;
while (lpAttach != NULL && pSurface != NULL)
{
if (lpAttach->dwFlags & DDAL_IMPLICIT)
{
lpAttach = lpAttach->lpLink;
if (((LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(pSurface))->lpLcl->lpAttachList)) != NULL)
pSurface = (IDirectDrawSurface *)((LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(pSurface))->lpLcl->lpAttachList))->lpIAttached;
else
pSurface = NULL;
//scan our list of surfaces for the outer surface here
pSurfaceOuter = m_pDirectDrawEx->m_pFirstSurface;
while (pSurfaceOuter != NULL && pSurfaceOuter->m_DDSInt.m_pRealInterface != pSurface)
pSurfaceOuter = pSurfaceOuter->m_pNext;
if (pSurface != pOrigSurf && pSurfaceOuter != NULL){
pSurfaceOuter->DeleteAttachment(pOrigSurf, pFirst);
//and add this to our list to be deleted at the end
pFirst->AddSurfaceToDestroyList(pSurfaceOuter);
}
else
lpAttach = NULL;
}
else
{
lpAttach = lpAttach->lpLink;
if (((LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(pSurface))->lpLcl->lpAttachList)) != NULL)
pSurface = (IDirectDrawSurface *)((LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(pSurface))->lpLcl->lpAttachList))->lpIAttached;
else
pSurface = NULL;
//scan our list of surfaces for the outer surface here
pSurfaceOuter = m_pDirectDrawEx->m_pFirstSurface;
while (pSurfaceOuter != NULL && pSurfaceOuter->m_DDSInt.m_pRealInterface != pSurface)
pSurfaceOuter = pSurfaceOuter->m_pNext;
if (pSurface != pOrigSurf && pSurfaceOuter != NULL){
//when the release of the surface is done, it will do a Release on the real interface
//of this surface, so we need to AddRef the real interface, but Release our interface here
pSurface->AddRef();
pSurfaceOuter->Release();
}
}
}
//we need to do the same thing for the m_pDDAttach list if it still remains
//all of these surface were not found in the code above. They are explicitly attached surfaces
//that were not create with the same ddrawex object that this surface was created with
while (m_pAttach != NULL)
{
DDAttachSurface * pDelete;
pDelete = m_pAttach;
m_pAttach = m_pAttach->pNext;
pDelete->pSurface->m_DDSInt.m_pRealInterface->AddRef();
pDelete->pSurface->Release();
delete pDelete;
}
if( m_pDDSurface3 != NULL )
{
m_pDDSurface3->Release();
}
HRESULT hr;
hr = m_pDDSurface2->Release();
#ifdef DEBUG
ASSERT(hr == 0);
#endif
hr = m_pDDSurface->Release();
m_pDirectDrawEx->Release();
DllRelease();
}
/*
* CDDSurface::~CDDSurface
*
* Destructor
*/
CDDSurface::~CDDSurface()
{
/*
* if we have an OwnDC, then Lock the surface so ReleaseDC will work right...
*/
LPATTACHLIST lpAttach;
IDirectDrawSurface * pSurface;
IDirectDrawSurface * pOrigSurf;
CDDSurface * pSurfaceOuter;
m_pDestroyList = NULL;
CleanUpSurface();
//check for attached surface here
lpAttach = (LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(m_pDDSurface))->lpLcl->lpAttachList);
pOrigSurf = pSurface = m_pDDSurface;
while (lpAttach != NULL && pSurface != NULL)
{
if (lpAttach->dwFlags & DDAL_IMPLICIT)
{
lpAttach = lpAttach->lpLink;
if (((LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(pSurface))->lpLcl->lpAttachList)) != NULL)
pSurface = (IDirectDrawSurface *)((LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(pSurface))->lpLcl->lpAttachList))->lpIAttached;
else
pSurface = NULL;
//scan our list of surfaces for the outer surface here
pSurfaceOuter = m_pDirectDrawEx->m_pFirstSurface;
while (pSurfaceOuter != NULL && pSurfaceOuter->m_DDSInt.m_pRealInterface != pSurface)
pSurfaceOuter = pSurfaceOuter->m_pNext;
if (pSurface != pOrigSurf && pSurfaceOuter != NULL)
{
pSurfaceOuter->DeleteAttachment(pOrigSurf, this);
AddSurfaceToDestroyList(pSurfaceOuter);
}
else
lpAttach = NULL;
}
else
{
lpAttach = lpAttach->lpLink;
if (((LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(pSurface))->lpLcl->lpAttachList)) != NULL)
pSurface = (IDirectDrawSurface *)((LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(pSurface))->lpLcl->lpAttachList))->lpIAttached;
else
pSurface = NULL;
//scan our list of surfaces for the outer surface here
pSurfaceOuter = m_pDirectDrawEx->m_pFirstSurface;
while (pSurfaceOuter != NULL && pSurfaceOuter->m_DDSInt.m_pRealInterface != pSurface)
pSurfaceOuter = pSurfaceOuter->m_pNext;
if (pSurface != pOrigSurf && pSurfaceOuter != NULL){
//when the release of the surface is done, it will do a Release on the real interface
//of this surface, so we need to AddRef the real interface, but Release our interface here
pSurface->AddRef();
pSurfaceOuter->Release();
}
}
}
//we need to do the same thing for the m_pDDAttach list if it still remains
//all of these surface were not found in the code above. They are explicitly attached surfaces
//that were not create with the same ddrawex object that this surface was created with
while (m_pAttach != NULL)
{
DDAttachSurface * pDelete;
pDelete = m_pAttach;
m_pAttach = m_pAttach->pNext;
pDelete->pSurface->m_DDSInt.m_pRealInterface->AddRef();
pDelete->pSurface->Release();
delete pDelete;
}
if (m_pDDSurface4)
{
m_pDDSurface4->Release();
}
if( m_pDDSurface3 != NULL )
{
m_pDDSurface3->Release();
}
HRESULT hr;
hr = m_pDDSurface2->Release();
#ifdef DEBUG
ASSERT(hr == 0);
#endif
hr = m_pDDSurface->Release();
//if we had implicit attached surface, we need to delete those here
if (m_pDestroyList != NULL)
{
CDDSurface * pDelete;
CDDSurface * pNext;
pDelete = m_pDestroyList;
while (pDelete != NULL)
{
pNext = pDelete->m_pNext;
#ifdef DEBUG
DWORD * ptr;
ptr = (DWORD *)pDelete;
for (int i = 0; i < sizeof(CDDSurface) / sizeof(DWORD);i++)
*ptr++ = 0xDEADBEEF;
#endif
delete (void *)pDelete;
pDelete = pNext;
}
m_pDestroyList = NULL;
}
m_pDirectDrawEx->Release();
#ifdef DEBUG
DWORD * ptr;
ptr = (DWORD *)this;
for (int i = 0; i < sizeof(CDDSurface) / sizeof(DWORD);i++)
*ptr++ = 0xDEADBEEF;
#endif
DllRelease();
} /* CDDSurface::~CDDSurface */
/*
* CDDSurface::CreateSimpleSurface
*
*/
HRESULT CDDSurface::CreateSimpleSurface(
LPDDSURFACEDESC pSurfaceDesc,
IDirectDrawSurface *pDDSurface,
IDirectDrawSurface2 *pDDSurface2,
IDirectDrawSurface3 *pDDSurface3,
IDirectDrawSurface4 *pDDSurface4,
IUnknown *pUnkOuter,
CDirectDrawEx *pDirectDrawEx,
IDirectDrawSurface **ppNewDDSurf,
DWORD dwFlags)
{
HRESULT hr;
CDDSurface *pSurface = new CDDSurface(pSurfaceDesc,
pDDSurface,
pDDSurface2,
pDDSurface3,
pDDSurface4,
pUnkOuter,
pDirectDrawEx);
if( !pSurface)
{
return E_OUTOFMEMORY;
}
else
{
//If we are running DX5, we can turn of the m_bOwnDC if it is on
if( pSurface->m_pDirectDrawEx->m_dwDDVer == WIN95_DX5 || pSurface->m_pDirectDrawEx->m_dwDDVer == WINNT_DX5)
{
pSurface->m_bOwnDC = FALSE;
//if OWNDC is set, we need to store the DC around after a ReleasDC, check that here
if (pSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_OWNDC || ((pSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_DATAEXCHANGE) == DDSCAPS_DATAEXCHANGE))
pSurface->m_bSaveDC = TRUE;
}
if ((pSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) &&
!(pSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
{
//we do not want to do this if we are running under WindowsNT4.0 gold
//but we have to because of palette problems, so call for anything. . .
if (pSurface->m_bOwnDC)
hr = pSurface->Init();
else
hr = DD_OK;
}
else
hr = DD_OK;
if( SUCCEEDED(hr) )
{
pSurface->NonDelegatingQueryInterface(pUnkOuter ? IID_IUnknown : IID_IDirectDrawSurface, (void **)ppNewDDSurf);
}
//if creating our own_dc/dib section failed, then this will release the surface
pSurface->NonDelegatingRelease();
}
return hr;
} /* CDDSurface::CreateSimpleSurface */
/*
* CDDSurface::InternalGetDC
*
* Simple surface GetDC implementation
*/
HRESULT CDDSurface::InternalGetDC(HDC *pHDC)
{
//palette handling was removed because we now wrap the palette functions and handle
//setting the DIB Color table when SetEntries or SetPallette is called.
//this will speed up the GetDc call signifigantly: JGO
HRESULT hr = DD_OK;
if (pHDC == NULL)
return DDERR_INVALIDPARAMS;
if( m_hDCDib )
{
*pHDC = m_hDCDib;
}
else if( m_bOwnDC )
{
*pHDC = m_HDC;
}
else
{
hr = m_pDDSurface->GetDC(pHDC);
if (SUCCEEDED(hr))
m_HDC = *pHDC;
}
#ifdef DEBUG
if ( m_DebugCheckDC)
{
//should we get the same DC? We should if OWNDC is set or DATAEXCHANGE is set
if (m_dwCaps & DDSCAPS_OWNDC || (m_dwCaps & DDSCAPS_DATAEXCHANGE) == DDSCAPS_DATAEXCHANGE)
ASSERT((DWORD)*pHDC == m_DebugCheckDC);
}
m_DebugCheckDC = (DWORD)*pHDC;
#endif
return hr;
} /* CDDSurface::InternalGetDC */
/*
* CDDSurface::InternalReleaseDC
*
* Simple surface ReleaseDC implementation
*/
HRESULT CDDSurface::InternalReleaseDC(HDC hdc)
{
HRESULT hr = DD_OK;
/*
* if we have a DIB section DC, do nothing
*/
if( m_hDCDib != NULL )
{
if( hdc != m_hDCDib )
{
hr = DDERR_INVALIDPARAMS;
}
}
/*
* if this is an OwnDC, do nothing
*/
else if( m_bOwnDC )
{
if( hdc != m_HDC )
{
hr = DDERR_INVALIDPARAMS;
}
}
/*
* allow ddraw to release the dc
*/
else
{
hr = m_pDDSurface->ReleaseDC(hdc);
if( SUCCEEDED(hr) )
{
if (!m_bSaveDC)
m_HDC = NULL;
}
}
return hr;
} /* CDDSurface::InternalReleaseDC */
/*
* CDDSurface::InternalAddAttachedSurface
*
* Simple surface AddAttachedSurface implementation
*/
HRESULT CDDSurface::InternalFlip (LPDIRECTDRAWSURFACE lpDDS, DWORD dw, DWORD dwSurfaceType)
{
HRESULT hr;
switch (dwSurfaceType)
{
case DDSURFACETYPE_1:
INTSTRUC_IDirectDrawSurface *lpIDDS;
lpIDDS = ((INTSTRUC_IDirectDrawSurface *)(lpDDS));
if (lpIDDS == NULL)
hr = m_pDDSurface->Flip(NULL, dw);
else
hr = m_pDDSurface->Flip(lpIDDS->m_pRealInterface, dw);
break;
case DDSURFACETYPE_2:
INTSTRUC_IDirectDrawSurface2 *lpIDDS2;
lpIDDS2 = ((INTSTRUC_IDirectDrawSurface2 *)(lpDDS));
if (lpIDDS2 == NULL)
hr = m_pDDSurface2->Flip(NULL, dw);
else
hr = m_pDDSurface2->Flip(lpIDDS2->m_pRealInterface, dw);
break;
case DDSURFACETYPE_3:
INTSTRUC_IDirectDrawSurface3 *lpIDDS3;
lpIDDS3 = ((INTSTRUC_IDirectDrawSurface3 *)(lpDDS));
if (lpIDDS3 == NULL)
hr = m_pDDSurface3->Flip(NULL, dw);
else
hr = m_pDDSurface3->Flip(lpIDDS3->m_pRealInterface, dw);
break;
case DDSURFACETYPE_4:
INTSTRUC_IDirectDrawSurface4 *lpIDDS4;
lpIDDS4 = ((INTSTRUC_IDirectDrawSurface4 *)(lpDDS));
if (lpIDDS4 == NULL)
hr = m_pDDSurface4->Flip(NULL, dw);
else
hr = m_pDDSurface4->Flip(lpIDDS4->m_pRealInterface, dw);
break;
}
return hr;
}
HRESULT CDDSurface::InternalBlt (LPRECT lpRect1,LPDIRECTDRAWSURFACE lpDDS, LPRECT lpRect2,DWORD dw, LPDDBLTFX lpfx, DWORD dwSurfaceType)
{
HRESULT hr;
switch (dwSurfaceType)
{
case DDSURFACETYPE_1:
INTSTRUC_IDirectDrawSurface *lpIDDS;
lpIDDS = ((INTSTRUC_IDirectDrawSurface *)(lpDDS));
if (lpDDS != NULL)
hr = m_pDDSurface->Blt(lpRect1, lpIDDS->m_pRealInterface, lpRect2,dw, lpfx);
else
hr = m_pDDSurface->Blt(lpRect1, NULL, lpRect2,dw, lpfx);
break;
case DDSURFACETYPE_2:
INTSTRUC_IDirectDrawSurface2 *lpIDDS2;
lpIDDS2 = ((INTSTRUC_IDirectDrawSurface2 *)(lpDDS));
if (lpDDS != NULL)
hr = m_pDDSurface2->Blt(lpRect1, lpIDDS2->m_pRealInterface, lpRect2,dw, lpfx);
else
hr = m_pDDSurface2->Blt(lpRect1, NULL, lpRect2,dw, lpfx);
break;
case DDSURFACETYPE_3:
INTSTRUC_IDirectDrawSurface3 *lpIDDS3;
lpIDDS3 = ((INTSTRUC_IDirectDrawSurface3 *)(lpDDS));
if (lpDDS != NULL)
hr = m_pDDSurface3->Blt(lpRect1, lpIDDS3->m_pRealInterface, lpRect2,dw, lpfx);
else
hr = m_pDDSurface3->Blt(lpRect1, NULL, lpRect2,dw, lpfx);
break;
case DDSURFACETYPE_4:
INTSTRUC_IDirectDrawSurface4 *lpIDDS4;
lpIDDS4 = ((INTSTRUC_IDirectDrawSurface4 *)(lpDDS));
if (lpDDS != NULL)
hr = m_pDDSurface4->Blt(lpRect1, lpIDDS4->m_pRealInterface, lpRect2,dw, lpfx);
else
hr = m_pDDSurface4->Blt(lpRect1, NULL, lpRect2,dw, lpfx);
break;
}
return hr;
}
HRESULT CDDSurface::InternalAddAttachedSurface (LPDIRECTDRAWSURFACE lpDDS, DWORD dwSurfaceType)
{
HRESULT hr;
INTSTRUC_IDirectDrawSurface *lpIDDS;
CDDSurface * pSurface;
if (lpDDS == NULL)
return DDERR_INVALIDPARAMS;
lpIDDS = ((INTSTRUC_IDirectDrawSurface *)(lpDDS));
pSurface = lpIDDS->m_pSimpleSurface;
switch (dwSurfaceType)
{
case DDSURFACETYPE_1:
//make the call to the actual DDraw function
hr = m_pDDSurface->AddAttachedSurface(pSurface->m_DDSInt.m_pRealInterface);
break;
case DDSURFACETYPE_2:
hr = m_pDDSurface2->AddAttachedSurface(pSurface->m_DDS2Int.m_pRealInterface);
break;
case DDSURFACETYPE_3:
hr = m_pDDSurface3->AddAttachedSurface(pSurface->m_DDS3Int.m_pRealInterface);
break;
case DDSURFACETYPE_4:
hr = m_pDDSurface4->AddAttachedSurface(pSurface->m_DDS4Int.m_pRealInterface);
break;
}
//if we succeeded we must do some fix up
if (!FAILED( hr ) && lpDDS != NULL){
//ddraw will addref the real interface
//release that here, and addref our fake interface
lpIDDS = ((INTSTRUC_IDirectDrawSurface *)(lpDDS));
lpIDDS->m_pRealInterface->Release();
((INTSTRUC_IDirectDrawSurface *)(lpDDS))->m_pSimpleSurface->AddRef();
//we need to make sure that this surface is in the ddrawex context of this surface,
//if it is not, then we need to add it to a list
if (m_pDirectDrawEx != lpIDDS->m_pSimpleSurface->m_pDirectDrawEx)
{
//this attached surface is not in the ddrawex object of this one, so add it to the attachlist
DDAttachSurface * pAttList = new DDAttachSurface;
if (pAttList == NULL)
return DDERR_OUTOFMEMORY;
//add this to the list of attached surfaces
pAttList->pNext = m_pAttach;
pAttList->pSurface = lpIDDS->m_pSimpleSurface;
m_pAttach = pAttList;
}
}
return hr;
}
void CDDSurface::DeleteAttachNode(CDDSurface * Surface)
{
DDAttachSurface *pDelete;
DDAttachSurface * pList = m_pAttach;
//special case first in the list
//ASSERT this!!
if (pList != NULL)
{
if (pList->pSurface == Surface)
{
m_pAttach = m_pAttach->pNext;
delete pList;
}
else
{
while (pList->pNext != NULL && (pList->pNext->pSurface != Surface))
{
pList = pList->pNext;
}
#ifdef DEBUG
ASSERT(pList->pNext != NULL);
#endif
if (pList->pNext != NULL)
{
pDelete = pList->pNext;
pList->pNext = pList->pNext->pNext;
delete pDelete;
}
}
}
}
HRESULT CDDSurface::InternalDeleteAttachedSurface (DWORD dwFlags, LPDIRECTDRAWSURFACE lpDDS, DWORD dwSurfaceType)
{
HRESULT hr;
INTSTRUC_IDirectDrawSurface *lpIDDS;
CDDSurface * pCallSurface;
ULONG_PTR * pSaveSurfaces;
DWORD dwCount;
pSaveSurfaces = NULL;
if (lpDDS)
{
//just one attachment, addref the surface before it is released if it is not an
//implicit attached surface
lpIDDS = ((INTSTRUC_IDirectDrawSurface *)(lpDDS));
lpIDDS->m_pRealInterface->AddRef();
}
else
{
LPATTACHLIST lpAttach;
IDirectDrawSurface * pOrigSurf;
CDDSurface * pSurfaceOuter;
//all attached surfaces are going to be released, addref them here
lpAttach = (LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(m_pDDSurface))->lpLcl->lpAttachList);
pOrigSurf = m_pDDSurface;
dwCount = 0;
while (lpAttach != NULL && (IDirectDrawSurface *)(lpAttach->lpIAttached) != pOrigSurf)
{
if (!(lpAttach->dwFlags & DDAL_IMPLICIT))
{
//we need to save these surfaces to be released later
//so count how many we need in here
dwCount++;
}
lpAttach = lpAttach->lpLink;
}
//we now need to save an array of surfaces to be Released if we succeed
pSaveSurfaces = (ULONG_PTR *)LocalAlloc(LPTR, dwCount*sizeof(ULONG_PTR));
if (pSaveSurfaces == NULL)
return DDERR_OUTOFMEMORY;
//now run the list again, call AddRef on the real interface, so that
//the release called by ddraw will not affect anything
//and save off the outer interfaces in our allocated array
lpAttach = (LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(m_pDDSurface))->lpLcl->lpAttachList);
pOrigSurf = m_pDDSurface;
dwCount = 0;
while (lpAttach != NULL && (IDirectDrawSurface *)(lpAttach->lpIAttached) != pOrigSurf)
{
if (!(lpAttach->dwFlags & DDAL_IMPLICIT))
{
//we must addref the surface pointed to here
((IDirectDrawSurface *)(lpAttach->lpIAttached))->AddRef();
pSurfaceOuter = m_pDirectDrawEx->m_pFirstSurface;
while (pSurfaceOuter != NULL && pSurfaceOuter->m_DDSInt.m_pRealInterface != (IDirectDrawSurface *)(lpAttach->lpIAttached))
pSurfaceOuter = pSurfaceOuter->m_pNext;
if (pSurfaceOuter != NULL)
pSaveSurfaces[dwCount++]= ((ULONG_PTR)(pSurfaceOuter));
}
lpAttach = lpAttach->lpLink;
}
//do the same addref for surfaces not in this ddrawex object
DDAttachSurface * pList = m_pAttach;
while (pList != NULL)
{
pList->pSurface->m_DDSInt.m_pRealInterface->AddRef();
pList = pList->pNext;
}
}
lpIDDS = ((INTSTRUC_IDirectDrawSurface *)(lpDDS));
if (lpIDDS != NULL)
pCallSurface = lpIDDS->m_pSimpleSurface;
else
pCallSurface = NULL;
switch (dwSurfaceType)
{
case DDSURFACETYPE_1:
//make the call to the actual DDraw function
if (pCallSurface != NULL)
hr = m_pDDSurface->DeleteAttachedSurface(dwFlags, pCallSurface->m_DDSInt.m_pRealInterface);
else
hr = m_pDDSurface->DeleteAttachedSurface(dwFlags, NULL);
break;
case DDSURFACETYPE_2:
if (pCallSurface != NULL)
hr = m_pDDSurface2->DeleteAttachedSurface(dwFlags, pCallSurface->m_DDS2Int.m_pRealInterface);
else
hr = m_pDDSurface2->DeleteAttachedSurface(dwFlags, NULL);
break;
case DDSURFACETYPE_3:
if (pCallSurface != NULL)
hr = m_pDDSurface3->DeleteAttachedSurface(dwFlags, pCallSurface->m_DDS3Int.m_pRealInterface);
else
hr = m_pDDSurface3->DeleteAttachedSurface(dwFlags, NULL);
break;
case DDSURFACETYPE_4:
if (pCallSurface != NULL)
hr = m_pDDSurface4->DeleteAttachedSurface(dwFlags, pCallSurface->m_DDS4Int.m_pRealInterface);
else
hr = m_pDDSurface4->DeleteAttachedSurface(dwFlags, NULL);
break;
}
//if we succeeded we must do some fix up
if (SUCCEEDED( hr ))
{
if (lpDDS)
{
//just one attachment, release the outer surface here
//if this is not in the same ddrawex object, then delete it from the list
if (m_pDirectDrawEx != lpIDDS->m_pSimpleSurface->m_pDirectDrawEx)
{
DeleteAttachNode(lpIDDS->m_pSimpleSurface);
}
lpIDDS = ((INTSTRUC_IDirectDrawSurface *)(lpDDS));
lpIDDS->m_pSimpleSurface->Release();
}
else
{
CDDSurface * pSurface;
for ( DWORD i = 0; i < dwCount; i++)
{
pSurface = (CDDSurface *)(pSaveSurfaces[i]);
pSurface->Release();
}
//do the same for any surfaces attached, not in this ddrawex object
DDAttachSurface * pList = m_pAttach;
while (m_pAttach != NULL)
{
pList = m_pAttach;
m_pAttach = m_pAttach->pNext;
pList->pSurface->Release();
delete pList;
}
}
}
else
{
if (lpDDS)
{
//just one attachment, addref the surface before it is released if it is not an
//implicit attached surface
lpIDDS = ((INTSTRUC_IDirectDrawSurface *)(lpDDS));
lpIDDS->m_pRealInterface->Release();
}
else
{
LPATTACHLIST lpAttach;
IDirectDrawSurface * pOrigSurf;
//all attached surfaces are going to be released, addref them here
lpAttach = (LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(m_pDDSurface))->lpLcl->lpAttachList);
pOrigSurf = m_pDDSurface;
while (lpAttach != NULL && (IDirectDrawSurface *)(lpAttach->lpIAttached) != pOrigSurf)
{
if (!(lpAttach->dwFlags & DDAL_IMPLICIT))
{
//we must release the surface pointed to here that we addref'ed above
((IDirectDrawSurface *)(lpAttach->lpIAttached))->Release();
}
lpAttach = lpAttach->lpLink;
}
//do the same for any surfaces attached, not in this ddrawex object
DDAttachSurface * pList = m_pAttach;
while (pList != NULL)
{
pList->pSurface->m_DDSInt.m_pRealInterface->Release();
pList = pList->pNext;
}
}
}
if (pSaveSurfaces != NULL)
LocalFree(pSaveSurfaces);
return hr;
}
/*
* CDDSurface::InternalGetAttachedSurface
*
* Simple surface GetAttachedSurface implementation
*/
HRESULT CDDSurface::InternalGetAttachedSurface(LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE FAR * lpDDS, DWORD dwSurfaceType)
{
HRESULT hr;
INTSTRUC_IDirectDrawSurface* lpIDDS;
DDSCAPS ddsCaps;
if (lpDDS == NULL)
return DDERR_INVALIDPARAMS;
ddsCaps = *lpDDSCaps;
//mask off owndc
ddsCaps.dwCaps &= ~DDSCAPS_OWNDC;
if ((ddsCaps.dwCaps & DDSCAPS_DATAEXCHANGE) == DDSCAPS_DATAEXCHANGE)
ddsCaps.dwCaps &= ~DDSCAPS_DATAEXCHANGE;
switch (dwSurfaceType)
{
case DDSURFACETYPE_1:
//make the call to the actual DDraw function
hr = m_pDDSurface->GetAttachedSurface(&ddsCaps, lpDDS);
break;
case DDSURFACETYPE_2:
hr = m_pDDSurface2->GetAttachedSurface(&ddsCaps, (LPDIRECTDRAWSURFACE2 *)lpDDS);
break;
case DDSURFACETYPE_3:
hr = m_pDDSurface3->GetAttachedSurface(&ddsCaps, (LPDIRECTDRAWSURFACE3 *)lpDDS);
break;
// Case 4 taken care of below...
} //make the call to the actual DDraw function
//if we succeeded we must do some fix up
CDDSurface * lpSurfaceList;
if (!FAILED( hr ) && lpDDS != NULL)
{
//we need to scan our list to pass back our interface
lpSurfaceList = m_pDirectDrawEx->m_pFirstSurface;
switch (dwSurfaceType)
{
case DDSURFACETYPE_1:
while (lpSurfaceList != NULL && lpSurfaceList->m_DDSInt.m_pRealInterface != *lpDDS)
lpSurfaceList = lpSurfaceList->m_pNext;
if (lpSurfaceList == NULL)
{
//check our AttachList
DDAttachSurface * pList = m_pAttach;
while (pList != NULL && pList->pSurface->m_DDSInt.m_pRealInterface != *lpDDS)
{
pList = pList->pNext;
}
if (pList != NULL)
lpSurfaceList = pList->pSurface;
}
if (lpSurfaceList != NULL)
*lpDDS = (IDirectDrawSurface *)(&lpSurfaceList->m_DDSInt);
break;
case DDSURFACETYPE_2:
while (lpSurfaceList != NULL && lpSurfaceList->m_DDS2Int.m_pRealInterface != (LPDIRECTDRAWSURFACE2)*lpDDS)
lpSurfaceList = lpSurfaceList->m_pNext;
if (lpSurfaceList == NULL)
{
//check our AttachList
DDAttachSurface * pList = m_pAttach;
while (pList != NULL && pList->pSurface->m_DDS2Int.m_pRealInterface != (LPDIRECTDRAWSURFACE2)*lpDDS)
{
pList = pList->pNext;
}
if (pList != NULL)
lpSurfaceList = pList->pSurface;
}
if (lpSurfaceList != NULL)
*lpDDS = (IDirectDrawSurface *)(&lpSurfaceList->m_DDS2Int);
break;
case DDSURFACETYPE_3:
while (lpSurfaceList != NULL && lpSurfaceList->m_DDS3Int.m_pRealInterface != (LPDIRECTDRAWSURFACE3)*lpDDS)
lpSurfaceList = lpSurfaceList->m_pNext;
if (lpSurfaceList == NULL)
{
//check our AttachList
DDAttachSurface * pList = m_pAttach;
while (pList != NULL && pList->pSurface->m_DDS3Int.m_pRealInterface != (LPDIRECTDRAWSURFACE3)*lpDDS)
{
pList = pList->pNext;
}
if (pList != NULL)
lpSurfaceList = pList->pSurface;
}
if (lpSurfaceList != NULL)
*lpDDS = (IDirectDrawSurface *)(&lpSurfaceList->m_DDS3Int);
break;
// Case 4 taken care of below...
}
//ddraw will addref the obtained surface's real interface
//release that here and addref our fake interface
if (lpSurfaceList != NULL)
{
lpIDDS = ((INTSTRUC_IDirectDrawSurface *)(*lpDDS));
lpIDDS->m_pRealInterface->Release();
((INTSTRUC_IDirectDrawSurface *)(*lpDDS))->m_pSimpleSurface->AddRef();
}
}
return hr;
}
HRESULT CDDSurface::InternalGetAttachedSurface4(LPDDSCAPS2 lpDDSCaps2, LPDIRECTDRAWSURFACE FAR * lpDDS)
{
HRESULT hr;
INTSTRUC_IDirectDrawSurface* lpIDDS;
DDSCAPS2 ddsCaps2;
if (lpDDS == NULL)
return DDERR_INVALIDPARAMS;
ddsCaps2 = *lpDDSCaps2;
//mask off owndc
ddsCaps2.dwCaps &= ~DDSCAPS_OWNDC;
if ((ddsCaps2.dwCaps & DDSCAPS_DATAEXCHANGE) == DDSCAPS_DATAEXCHANGE)
ddsCaps2.dwCaps &= ~DDSCAPS_DATAEXCHANGE;
hr = m_pDDSurface4->GetAttachedSurface(&ddsCaps2, (LPDIRECTDRAWSURFACE4 *)lpDDS);
//if we succeeded we must do some fix up
CDDSurface * lpSurfaceList;
if (!FAILED( hr ) && lpDDS != NULL)
{
//we need to scan our list to pass back our interface
lpSurfaceList = m_pDirectDrawEx->m_pFirstSurface;
while (lpSurfaceList != NULL && lpSurfaceList->m_DDS4Int.m_pRealInterface != (LPDIRECTDRAWSURFACE4)*lpDDS)
lpSurfaceList = lpSurfaceList->m_pNext;
if (lpSurfaceList == NULL)
{
//check our AttachList
DDAttachSurface * pList = m_pAttach;
while (pList != NULL && pList->pSurface->m_DDS4Int.m_pRealInterface != (LPDIRECTDRAWSURFACE4)*lpDDS)
{
pList = pList->pNext;
}
if (pList != NULL)
lpSurfaceList = pList->pSurface;
}
//ddraw will addref the obtained surface's real interface
//release that here and addref our fake interface
if (lpSurfaceList != NULL)
{
*lpDDS = (IDirectDrawSurface *)(&lpSurfaceList->m_DDS4Int);
lpIDDS = ((INTSTRUC_IDirectDrawSurface *)(*lpDDS));
lpIDDS->m_pRealInterface->Release();
((INTSTRUC_IDirectDrawSurface *)(*lpDDS))->m_pSimpleSurface->AddRef();
}
}
return hr;
}
HRESULT CDDSurface::InternalGetPalette(LPDIRECTDRAWPALETTE FAR * ppPal, DWORD dwSurfaceType)
{
HRESULT hr;
if (ppPal == NULL)
return DDERR_INVALIDPARAMS;
switch (dwSurfaceType)
{
case DDSURFACETYPE_1:
//make the call to the actual DDraw function
hr = m_pDDSurface->GetPalette(ppPal);
break;
case DDSURFACETYPE_2:
hr = m_pDDSurface2->GetPalette(ppPal);
break;
case DDSURFACETYPE_3:
hr = m_pDDSurface3->GetPalette(ppPal);
break;
case DDSURFACETYPE_4:
hr = m_pDDSurface4->GetPalette(ppPal);
break;
}
//if this succeeded, we need to return OUR interface to the palette, so scan our
//list and return the correct palette.
if (SUCCEEDED(hr))
{
INTSTRUC_IDirectDrawPalette* pIDDP;
//we need to scan our list to pass back our interface
CDDPalette * lpPaletteList;
lpPaletteList = m_pDirectDrawEx->m_pFirstPalette;
while (lpPaletteList != NULL && lpPaletteList->m_DDPInt.m_pRealInterface != *ppPal)
lpPaletteList = lpPaletteList->m_pNext;
if (lpPaletteList == NULL)
{
//this is a palette possibly, that is not in the same ddraw object as the surface
// handle that here
// TODO in the future, this code should be the default!
//the returned palette should equal the real interface of the m_pCurrentPalette
#ifdef DEBUG
ASSERT(m_pCurrentPalette != NULL);
ASSERT(m_pCurrentPalette->m_DDPInt.m_pRealInterface == *ppPal);
#endif
lpPaletteList = m_pCurrentPalette;
}
if (lpPaletteList != NULL)
{
*ppPal = (IDirectDrawPalette *)(&lpPaletteList->m_DDPInt);
pIDDP = ((INTSTRUC_IDirectDrawPalette *)(*ppPal));
pIDDP->m_pRealInterface->Release();
pIDDP->m_pSimplePalette->AddRef();
}
}
return hr;
}
HRESULT CDDSurface::InternalGetSurfaceDesc(LPDDSURFACEDESC pDesc, DWORD dwSurfaceType)
{
HRESULT hr;
switch (dwSurfaceType)
{
case DDSURFACETYPE_1:
hr = m_pDDSurface->GetSurfaceDesc(pDesc);
break;
case DDSURFACETYPE_2:
hr = m_pDDSurface2->GetSurfaceDesc(pDesc);
break;
case DDSURFACETYPE_3:
hr = m_pDDSurface3->GetSurfaceDesc(pDesc);
break;
// Case 4 handled below...
}
if (FAILED(hr))
return hr;
//if m_bOwnDC is set, we need to set this in the caps field
if (m_dwCaps & DDSCAPS_OWNDC)
//set the caps bit here
pDesc->ddsCaps.dwCaps |= DDSCAPS_OWNDC;
//see if data exchange was origianlly on
if ((m_dwCaps & DDSCAPS_DATAEXCHANGE) == DDSCAPS_DATAEXCHANGE )
{
pDesc->ddsCaps.dwCaps |= DDSCAPS_DATAEXCHANGE;
//see if OWNDC was really on
if (!(m_dwCaps & DDSCAPS_OWNDC))
//turn it off here
pDesc->ddsCaps.dwCaps &= ~DDSCAPS_OWNDC;
//see if offscreen plain was originally on
if (m_dwCaps & DDSCAPS_OFFSCREENPLAIN)
pDesc->ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
//we might have turned on texture, turn it off if so
if (!(m_dwCaps & DDSCAPS_TEXTURE))
pDesc->ddsCaps.dwCaps &= ~DDSCAPS_TEXTURE;
}
return hr;
}
HRESULT CDDSurface::InternalGetSurfaceDesc4(LPDDSURFACEDESC2 pDesc2)
{
HRESULT hr;
hr = m_pDDSurface4->GetSurfaceDesc(pDesc2);
if (FAILED(hr))
return hr;
//if m_bOwnDC is set, we need to set this in the caps field
if (m_dwCaps & DDSCAPS_OWNDC)
//set the caps bit here
pDesc2->ddsCaps.dwCaps |= DDSCAPS_OWNDC;
//see if data exchange was origianlly on
if ((m_dwCaps & DDSCAPS_DATAEXCHANGE) == DDSCAPS_DATAEXCHANGE )
{
pDesc2->ddsCaps.dwCaps |= DDSCAPS_DATAEXCHANGE;
//see if OWNDC was really on
if (!(m_dwCaps & DDSCAPS_OWNDC))
//turn it off here
pDesc2->ddsCaps.dwCaps &= ~DDSCAPS_OWNDC;
//see if offscreen plain was originally on
if (m_dwCaps & DDSCAPS_OFFSCREENPLAIN)
pDesc2->ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
//we might have turned on texture, turn it off if so
if (!(m_dwCaps & DDSCAPS_TEXTURE))
pDesc2->ddsCaps.dwCaps &= ~DDSCAPS_TEXTURE;
}
return hr;
}
HRESULT CDDSurface::InternalSetPalette(LPDIRECTDRAWPALETTE pPal, DWORD dwSurfaceType)
{
HRESULT hr;
INTSTRUC_IDirectDrawPalette* pIDDP;
pIDDP = ((INTSTRUC_IDirectDrawPalette *)(pPal));
//a bit of ugliness herein regards to reference counting. If this palette is
//different from the current palette, then it will release the current palette.
//we must protect for that before we call setpalette
if (m_pCurrentPalette && (pPal == NULL || m_pCurrentPalette != pIDDP->m_pSimplePalette))
{
m_pCurrentPalette->m_DDPInt.m_pRealInterface->AddRef();
}
switch (dwSurfaceType)
{
case DDSURFACETYPE_1:
//make the call to the actual DDraw function
if (pPal != NULL)
hr = m_pDDSurface->SetPalette(pIDDP->m_pRealInterface);
else
hr = m_pDDSurface->SetPalette(NULL);
break;
case DDSURFACETYPE_2:
if (pPal != NULL)
hr = m_pDDSurface2->SetPalette(pIDDP->m_pRealInterface);
else
hr = m_pDDSurface2->SetPalette(NULL);
break;
case DDSURFACETYPE_3:
if (pPal != NULL)
hr = m_pDDSurface3->SetPalette(pIDDP->m_pRealInterface);
else
hr = m_pDDSurface3->SetPalette(NULL);
break;
case DDSURFACETYPE_4:
if (pPal != NULL)
hr = m_pDDSurface4->SetPalette(pIDDP->m_pRealInterface);
else
hr = m_pDDSurface4->SetPalette(NULL);
break;
}
if (SUCCEEDED(hr))
{
//we must take care of reference counting here
//if there was an old palette not equal to the current, then do a release on the old palette
if (m_pCurrentPalette && (pPal == NULL || m_pCurrentPalette != pIDDP->m_pSimplePalette))
{
//release the old palette
m_pCurrentPalette->Release();
//if this release caused the palette to be destroyed, the palette destructor function
//will change m_pCurrentPalette to NULL. No worries below.
}
//if the new palette is NULL, we can return here
if (pPal == NULL)
{
if (m_pCurrentPalette)
{
m_pCurrentPalette->RemoveSurfaceFromList(this);
m_pCurrentPalette = NULL;
}
return hr;
}
//if the new palette is not equal to the old palette, then an addref was done on the
//real interface, as above
if (m_pCurrentPalette != pIDDP->m_pSimplePalette)
{
pIDDP->m_pRealInterface->Release();
pIDDP->m_pSimplePalette->AddRef();
}
DWORD dwNumEntries;
DWORD dwCaps;
PALETTEENTRY pe[256];
hr = pIDDP->m_pRealInterface->GetCaps(&dwCaps);
if (FAILED(hr))
return hr;
if (dwCaps & DDPCAPS_1BIT)
dwNumEntries = 1;
else if (dwCaps & DDPCAPS_2BIT)
dwNumEntries = 4;
else if (dwCaps & DDPCAPS_4BIT)
dwNumEntries = 16;
else if (dwCaps & DDPCAPS_8BIT)
dwNumEntries = 256;
else
dwNumEntries = 0;
hr = pIDDP->m_pRealInterface->GetEntries( 0, 0, dwNumEntries, pe);
if (FAILED(hr))
return hr;
if (m_bIsPrimary)
{
CDDSurface *pSurface = m_pDirectDrawEx->m_pPrimaryPaletteList;
while (pSurface != NULL)
{
//update the DIB COlor Table here
pIDDP->m_pSimplePalette->SetColorTable(pSurface, pe, dwNumEntries, 0);
pSurface = pSurface->m_pNextPalette;
}
//and mark this palette as being the primary
pIDDP->m_pSimplePalette->m_bIsPrimary = TRUE;
m_pCurrentPalette = pIDDP->m_pSimplePalette;
}
else
{
//if this surface already has a palette attached to it, then we need to remove it
if (m_pCurrentPalette && m_pCurrentPalette != pIDDP->m_pSimplePalette)
m_pCurrentPalette->RemoveSurfaceFromList(this);
else if (m_bPrimaryPalette)
//this surface will be in the list of surfaces which feed of the primary surface
//remove it from that list
m_pDirectDrawEx->RemoveSurfaceFromPrimaryList(this);
//now add this surface to the palette list if already is not in the list
if (m_pCurrentPalette != pIDDP->m_pSimplePalette)
pIDDP->m_pSimplePalette->AddSurfaceToList(this);
//and update this surface's DIB ColorTable
pIDDP->m_pSimplePalette->SetColorTable(this, pe, dwNumEntries, 0);
pIDDP->m_pSimplePalette->m_bIsPrimary = FALSE;
m_pCurrentPalette = pIDDP->m_pSimplePalette;
}
}
return hr;
}
#pragma message( REMIND( "What Lock of a rect bug in DirectDraw v3 is Ralph referring to?" ))
/*
* CDDSurface::InternalLock
*
* Simple surface Lock implementation
*/
HRESULT CDDSurface::InternalLock(LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent)
{
return m_pDDSurface->Lock(lpDestRect, lpDDSurfaceDesc, dwFlags, hEvent);
} /* CDDSurface::InternalLock */
/*
* CDDSurface::InternalUnlock
*
* Simple surface Unlock implementation
*/
HRESULT CDDSurface::InternalUnlock(LPVOID lpSurfaceData)
{
return m_pDDSurface->Unlock(lpSurfaceData);
} /* CDDSurface::InternalUnlock */
#define DEFINEPF(flags, fourcc, bpp, rMask, gMask, bMask, aMask) \
{ sizeof(DDPIXELFORMAT), (flags), (fourcc), (bpp), (rMask), (gMask), (bMask), (aMask) }
static DDPIXELFORMAT ddpfSupportedTexPFs[] =
{
/* Type FOURCC BPP Red Mask Green Mask Blue Mask Alpha Mask */
DEFINEPF(DDPF_RGB | DDPF_PALETTEINDEXED1, 0UL, 1UL, 0x00000000UL, 0x00000000Ul, 0x00000000UL, 0x00000000UL), /* Pal. */
DEFINEPF(DDPF_RGB | DDPF_PALETTEINDEXED1 |
DDPF_PALETTEINDEXEDTO8, 0UL, 1UL, 0x00000000UL, 0x00000000Ul, 0x00000000UL, 0x00000000UL), /* Pal. */
DEFINEPF(DDPF_RGB | DDPF_PALETTEINDEXED2, 0UL, 2UL, 0x00000000UL, 0x00000000Ul, 0x00000000UL, 0x00000000UL), /* Pal. */
DEFINEPF(DDPF_RGB | DDPF_PALETTEINDEXED2 |
DDPF_PALETTEINDEXEDTO8, 0UL, 2UL, 0x00000000UL, 0x00000000Ul, 0x00000000UL, 0x00000000UL), /* Pal. */
DEFINEPF(DDPF_RGB | DDPF_PALETTEINDEXED4, 0UL, 4UL, 0x00000000UL, 0x00000000Ul, 0x00000000UL, 0x00000000UL), /* Pal. */
DEFINEPF(DDPF_RGB | DDPF_PALETTEINDEXED4 |
DDPF_PALETTEINDEXEDTO8, 0UL, 4UL, 0x00000000UL, 0x00000000Ul, 0x00000000UL, 0x00000000UL), /* Pal. */
DEFINEPF(DDPF_RGB | DDPF_PALETTEINDEXED8, 0UL, 8UL, 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL), /* Pal. */
DEFINEPF(DDPF_RGB, 0UL, 8UL, 0x000000E0UL, 0x0000001CUL, 0x00000003UL, 0x00000000UL), /* 332 (RGB) */
DEFINEPF(DDPF_RGB | DDPF_ALPHAPIXELS, 0UL, 16UL, 0x00000F00UL, 0x000000F0UL, 0x0000000FUL, 0x0000F000UL), /* 4444 (RGB) */
DEFINEPF(DDPF_RGB, 0UL, 16UL, 0x0000F800UL, 0x000007E0UL, 0x0000001FUL, 0x00000000UL), /* 565 (RGB) */
DEFINEPF(DDPF_RGB, 0UL, 16UL, 0x0000001FUL, 0x000007E0UL, 0x0000F800UL, 0x00000000UL), /* 565 (BGR) */
DEFINEPF(DDPF_RGB, 0UL, 16UL, 0x00007C00UL, 0x000003E0UL, 0x0000001FUL, 0x00000000UL), /* 555 (RGB) */
DEFINEPF(DDPF_RGB | DDPF_ALPHAPIXELS, 0UL, 16UL, 0x00007C00UL, 0x000003E0UL, 0x0000001FUL, 0x00008000UL), /* 1555 (RGB) */
DEFINEPF(DDPF_RGB, 0UL, 24UL, 0x00FF0000UL, 0x0000FF00UL, 0x000000FFUL, 0x00000000UL), /* FFF (RGB) */
DEFINEPF(DDPF_RGB, 0UL, 24UL, 0x000000FFUL, 0x0000FF00UL, 0x00FF0000UL, 0x00000000UL), /* FFF (BGR) */
DEFINEPF(DDPF_RGB, 0UL, 32UL, 0x00FF0000UL, 0x0000FF00UL, 0x000000FFUL, 0x00000000UL), /* 0FFF (RGB) */
DEFINEPF(DDPF_RGB, 0UL, 32UL, 0x000000FFUL, 0x0000FF00UL, 0x00FF0000UL, 0x00000000UL), /* 0FFF (BGR) */
DEFINEPF(DDPF_RGB | DDPF_ALPHAPIXELS, 0UL, 32UL, 0x00FF0000UL, 0x0000FF00UL, 0x000000FFUL, 0xFF000000UL), /* FFFF (RGB) */
DEFINEPF(DDPF_RGB | DDPF_ALPHAPIXELS, 0UL, 32UL, 0x000000FFUL, 0x0000FF00UL, 0x00FF0000UL, 0xFF000000UL) /* FFFF (BGR) */
};
#define NUM_SUPPORTED_TEX_PFS (sizeof(ddpfSupportedTexPFs) / sizeof(ddpfSupportedTexPFs[0]))
static DDPIXELFORMAT ddpfSupportedOffScrnPFs[] =
{
/* Type FOURCC BPP Red Mask Green Mask Blue Mask Alpha Mask */
DEFINEPF(DDPF_RGB | DDPF_PALETTEINDEXED1, 0UL, 1UL, 0x00000000UL, 0x00000000Ul, 0x00000000UL, 0x00000000UL), /* Pal. */
DEFINEPF(DDPF_RGB | DDPF_PALETTEINDEXED2, 0UL, 2UL, 0x00000000UL, 0x00000000Ul, 0x00000000UL, 0x00000000UL), /* Pal. */
DEFINEPF(DDPF_RGB | DDPF_PALETTEINDEXED4, 0UL, 4UL, 0x00000000UL, 0x00000000Ul, 0x00000000UL, 0x00000000UL), /* Pal. */
DEFINEPF(DDPF_RGB | DDPF_PALETTEINDEXED8, 0UL, 8UL, 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL), /* Pal. */
DEFINEPF(DDPF_RGB, 0UL, 16UL, 0x0000F800UL, 0x000007E0UL, 0x0000001FUL, 0x00000000UL), /* 565 (RGB) */
DEFINEPF(DDPF_RGB, 0UL, 16UL, 0x00007C00UL, 0x000003E0UL, 0x0000001FUL, 0x00000000UL), /* 555 (RGB) */
DEFINEPF(DDPF_RGB, 0UL, 24UL, 0x00FF0000UL, 0x0000FF00UL, 0x000000FFUL, 0x00000000UL), /* FFF (RGB) */
DEFINEPF(DDPF_RGB, 0UL, 24UL, 0x000000FFUL, 0x0000FF00UL, 0x00FF0000UL, 0x00000000UL), /* FFF (BGR) */
DEFINEPF(DDPF_RGB, 0UL, 32UL, 0x00FF0000UL, 0x0000FF00UL, 0x000000FFUL, 0x00000000UL), /* 0FFF (RGB) */
DEFINEPF(DDPF_RGB, 0UL, 32UL, 0x000000FFUL, 0x0000FF00UL, 0x00FF0000UL, 0x00000000UL), /* 0FFF (BGR) */
};
#define NUM_SUPPORTED_OFFSCRN_PFS (sizeof(ddpfSupportedOffScrnPFs) / sizeof(ddpfSupportedOffScrnPFs[0]))
/*
* doPixelFormatsMatch
*/
BOOL doPixelFormatsMatch(LPDDPIXELFORMAT lpddpf1, LPDDPIXELFORMAT lpddpf2)
{
if( lpddpf1->dwFlags != lpddpf2->dwFlags )
{
return FALSE;
}
if( lpddpf1->dwFlags & DDPF_RGB )
{
if( lpddpf1->dwRGBBitCount != lpddpf2->dwRGBBitCount )
{
return FALSE;
}
if( lpddpf1->dwRBitMask != lpddpf2->dwRBitMask )
{
return FALSE;
}
if( lpddpf1->dwGBitMask != lpddpf2->dwGBitMask )
{
return FALSE;
}
if( lpddpf1->dwBBitMask != lpddpf2->dwBBitMask )
{
return FALSE;
}
if( lpddpf1->dwFlags & DDPF_ALPHAPIXELS )
{
if( lpddpf1->dwRGBAlphaBitMask != lpddpf2->dwRGBAlphaBitMask )
{
return FALSE;
}
}
}
else if( lpddpf1->dwFlags & DDPF_YUV )
{
/*
* (CMcC) Yes, I know that all these fields are in a
* union with the RGB ones so I could just use the same
* bit of checking code but just in case someone messes
* with DDPIXELFORMAT I'm going to do this explicitly.
*/
if( lpddpf1->dwFourCC != lpddpf2->dwFourCC )
{
return FALSE;
}
if( lpddpf1->dwYUVBitCount != lpddpf2->dwYUVBitCount )
{
return FALSE;
}
if( lpddpf1->dwYBitMask != lpddpf2->dwYBitMask )
{
return FALSE;
}
if( lpddpf1->dwUBitMask != lpddpf2->dwUBitMask )
{
return FALSE;
}
if( lpddpf1->dwVBitMask != lpddpf2->dwVBitMask )
{
return FALSE;
}
if( lpddpf1->dwFlags & DDPF_ALPHAPIXELS )
{
if( lpddpf1->dwYUVAlphaBitMask != lpddpf2->dwYUVAlphaBitMask )
{
return FALSE;
}
}
}
return TRUE;
} /* doPixelFormatsMatch */
/*
* isSupportedPixelFormat
*/
BOOL isSupportedPixelFormat(LPDDPIXELFORMAT lpddpf,
LPDDPIXELFORMAT lpddpfTable,
int cNumEntries)
{
int n;
LPDDPIXELFORMAT lpddCandidatePF;
n = cNumEntries;
lpddCandidatePF = lpddpfTable;
while( n > 0 )
{
if( doPixelFormatsMatch(lpddpf, lpddCandidatePF) )
{
return TRUE;
}
lpddCandidatePF++;
n--;
}
return FALSE;
} /* isSupportedPixelFormat */
/*
* checkPixelFormat
* bitdepth != screen bitdepth
*/
HRESULT checkPixelFormat( DWORD dwscaps, LPDDPIXELFORMAT lpDDPixelFormat )
{
if( dwscaps & DDSCAPS_TEXTURE )
{
if( !isSupportedPixelFormat(lpDDPixelFormat, ddpfSupportedTexPFs, NUM_SUPPORTED_TEX_PFS) )
{
return DDERR_INVALIDPIXELFORMAT;
}
}
else if( dwscaps & DDSCAPS_OFFSCREENPLAIN )
{
if( !isSupportedPixelFormat(lpDDPixelFormat, ddpfSupportedOffScrnPFs, NUM_SUPPORTED_OFFSCRN_PFS) )
{
return DDERR_INVALIDPIXELFORMAT;
}
}
return DD_OK;
} /* checkPixelFormat */
/*
* CDDSurface::InternalSetSurfaceDesc
*
* Simple surface change the bits
*/
HRESULT CDDSurface::InternalSetSurfaceDesc(
LPDDSURFACEDESC pddsd,
DWORD dwFlags)
{
LPDDRAWI_DDRAWSURFACE_INT psurf_int;
LPDDRAWI_DDRAWSURFACE_LCL psurf_lcl;
LPDDRAWI_DDRAWSURFACE_GBL psurf_gbl;
DWORD sdflags;
if( dwFlags )
{
return DDERR_INVALIDPARAMS;
}
//do not work on DDraw2 on WindowsNT4.0Gold
if (m_pDirectDrawEx->m_dwDDVer == WINNT_DX2)
{
return DDERR_UNSUPPORTED;
}
psurf_int = (LPDDRAWI_DDRAWSURFACE_INT) m_pDDSurface;
psurf_lcl = psurf_int->lpLcl;
psurf_gbl = psurf_lcl->lpGbl;
sdflags = pddsd->dwFlags;
/*
* don't allow anything but bits, height, width, pitch, and pixel format
* to change
*/
if( !(sdflags & (DDSD_LPSURFACE | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_PITCH )) )
{
return DDERR_INVALIDPARAMS;
}
/*
* don't work if it wasn't put in sysmem in the first place...
*/
if( !(psurf_gbl->dwGlobalFlags & DDRAWISURFGBL_SYSMEMREQUESTED ) )
{
return DDERR_UNSUPPORTED;
}
/*
* gotta have a pixel format to work...
*/
if( !(psurf_lcl->dwFlags & DDRAWISURF_HASPIXELFORMAT) &&
(sdflags & DDSD_PIXELFORMAT) )
{
return DDERR_INVALIDSURFACETYPE;
}
/*
* verify the new pixel format...
*/
if( sdflags & DDSD_PIXELFORMAT )
{
DWORD dwscaps;
HRESULT hr;
/*
* only allow changes for textures and offscreen plain...
*/
dwscaps = psurf_lcl->ddsCaps.dwCaps;
if( !(dwscaps & (DDSCAPS_TEXTURE|DDSCAPS_OFFSCREENPLAIN)) )
{
return DDERR_INVALIDSURFACETYPE;
}
hr = checkPixelFormat( dwscaps, &pddsd->ddpfPixelFormat );
if( FAILED( hr ) )
{
return hr;
}
}
/*
* replace bits ptr...
*/
if( sdflags & DDSD_LPSURFACE )
{
/*
* mark the surface memory as freed, and replace the memory with
* new user specified memory
*/
if( !(psurf_gbl->dwGlobalFlags & DDRAWISURFGBL_MEMFREE ) )
{
DWORD dwOffset;
LPVOID lpMem;
lpMem= (LPVOID) psurf_int->lpLcl->lpGbl->fpVidMem;
//probably don't need this check, but it can't hurt
if( NULL != lpMem )
{
if (m_pDirectDrawEx->m_dwDDVer != WINNT_DX3)
{
//check to see if this surface has been aligned and reset the pointer if so
if(psurf_int->lpLcl->ddsCaps.dwCaps & DDSCAPS_ZBUFFER ||
psurf_int->lpLcl->ddsCaps.dwCaps & DDSCAPS_TEXTURE ||
psurf_int->lpLcl->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN)
{
dwOffset = *( (LPDWORD) ( ( (LPBYTE)lpMem ) - sizeof(DWORD) ) );
lpMem = (LPVOID) ( ( (LPBYTE) lpMem) - dwOffset );
}
//free the memory
LocalFree(lpMem);
}
else
{
//store this value off so we can use it when we destroy the surface
m_pSaveBits = (ULONG_PTR)lpMem;
m_pSaveHDC = psurf_int->lpLcl->hDC;
m_pSaveHBM = psurf_int->lpLcl->dwReserved1;
}
}
psurf_gbl->dwGlobalFlags |= DDRAWISURFGBL_MEMFREE;
}
psurf_gbl->fpVidMem = (ULONG_PTR) pddsd->lpSurface;
}
/*
* replace other things
*/
if( sdflags & DDSD_PITCH )
{
psurf_gbl->lPitch = pddsd->lPitch;
}
if( sdflags & DDSD_WIDTH )
{
psurf_gbl->wWidth = (WORD) pddsd->dwWidth;
}
if( sdflags & DDSD_HEIGHT )
{
psurf_gbl->wHeight = (WORD) pddsd->dwHeight;
}
if( sdflags & DDSD_PIXELFORMAT )
{
psurf_gbl->ddpfSurface = pddsd->ddpfPixelFormat;
}
return DD_OK;
} /* CDDSurface::InternalSetBites */
HRESULT CDDSurface::InternalGetDDInterface(LPVOID FAR *ppInt)
{
//this is a simple function, simply addref on the m_pDirectDrawEx and return it's simple interface
return m_pDirectDrawEx->QueryInterface(IID_IDirectDraw, ppInt);
}
/*
* CDDSurface::QueryInterface
* AddRef
* Release
*
* The standard IUnknown that delegates...
*/
STDMETHODIMP CDDSurface::QueryInterface(REFIID riid, void ** ppv)
{
return m_pUnkOuter->QueryInterface(riid, ppv);
} /* CDirectDrawEx::QueryInterface */
STDMETHODIMP_(ULONG) CDDSurface::AddRef(void)
{
return m_pUnkOuter->AddRef();
} /* CDirectDrawEx::AddRef */
STDMETHODIMP_(ULONG) CDDSurface::Release(void)
{
return m_pUnkOuter->Release();
} /* CDirectDrawEx::Release */
/*
* NonDelegating IUnknown for simple surface follows...
*/
STDMETHODIMP CDDSurface::NonDelegatingQueryInterface(REFIID riid, void ** ppv)
{
HRESULT hr;
if (ppv == NULL)
return E_POINTER;
*ppv=NULL;
if( IID_IUnknown==riid )
{
*ppv=(INonDelegatingUnknown *)this;
}
else if( IID_IDirectDrawSurface==riid )
{
*ppv=&m_DDSInt;
}
else if( IID_IDirectDrawSurface2==riid )
{
*ppv=&m_DDS2Int;
}
else if( IID_IDirectDrawSurface3==riid )
{
*ppv=&m_DDS3Int;
}
else if (IID_IDirectDrawSurface4==riid )
{
if (m_DDS4Int.lpVtbl)
{
*ppv=&m_DDS4Int;
}
else
{
return (E_NOINTERFACE);
}
}
else if (IID_IDirect3DRampDevice == riid)
{
//#ifdef DBG
// hr = DDERR_LEGACYUSAGE;
//#else
HRESULT (__stdcall *lpFunc)(IDirectDrawVtbl **,REFIID, void **);
*(DWORD *)(&lpFunc) = *(DWORD *)*(DWORD **)m_pDDSurface;
hr = lpFunc(&(m_DDSInt.lpVtbl), riid, (void **)&m_D3DDeviceRAMPInt);
if( SUCCEEDED(hr) )
{
*ppv=m_D3DDeviceRAMPInt;
}
else
*ppv = NULL;
//#endif
return hr;
}
else if (IID_IDirect3DRGBDevice == riid)
{
//#ifdef DBG
// hr = DDERR_LEGACYUSAGE;
//#else
HRESULT (__stdcall *lpFunc)(IDirectDrawVtbl **,REFIID, void **);
*(DWORD *)(&lpFunc) = *(DWORD *)*(DWORD **)m_pDDSurface;
hr = lpFunc(&(m_DDSInt.lpVtbl), riid, (void **)&m_D3DDeviceRGBInt);
if( SUCCEEDED(hr) )
{
*ppv=m_D3DDeviceRGBInt;
}
else
*ppv = NULL;
//#endif
return hr;
}
else if (IID_IDirect3DChrmDevice == riid)
{
//#ifdef DBG
// hr = DDERR_LEGACYUSAGE;
//#else
HRESULT (__stdcall *lpFunc)(IDirectDrawVtbl **,REFIID, void **);
*(DWORD *)(&lpFunc) = *(DWORD *)*(DWORD **)m_pDDSurface;
hr = lpFunc(&(m_DDSInt.lpVtbl), riid, (void **)&m_D3DDeviceChrmInt);
if( SUCCEEDED(hr) )
{
*ppv=m_D3DDeviceChrmInt;
}
else
*ppv = NULL;
//#endif
return hr;
}
else if(IID_IDirect3DHALDevice == riid)
{
//#ifdef DBG
// hr = DDERR_LEGACYUSAGE;
//#else
HRESULT (__stdcall *lpFunc)(IDirectDrawVtbl **,REFIID, void **);
*(DWORD *)(&lpFunc) = *(DWORD *)*(DWORD **)m_pDDSurface;
hr = lpFunc(&(m_DDSInt.lpVtbl), riid, (void **)&m_D3DDeviceHALInt);
if( SUCCEEDED(hr) )
{
*ppv=m_D3DDeviceHALInt;
}
else
*ppv = NULL;
//#endif
return hr;
}
else if(IID_IDirect3DMMXDevice == riid)
{
//#ifdef DBG
// hr = DDERR_LEGACYUSAGE;
//#else
HRESULT (__stdcall *lpFunc)(IDirectDrawVtbl **,REFIID, void **);
*(DWORD *)(&lpFunc) = *(DWORD *)*(DWORD **)m_pDDSurface;
hr = lpFunc(&(m_DDSInt.lpVtbl), riid, (void **)&m_D3DDeviceMMXInt);
if( SUCCEEDED(hr) )
{
*ppv=m_D3DDeviceMMXInt;
}
else
*ppv = NULL;
//#endif
return hr;
}
else if (IID_IDirect3DTexture == riid)
{
HRESULT (__stdcall *lpFunc)(IDirectDrawVtbl **,REFIID, void **);
*(DWORD *)(&lpFunc) = *(DWORD *)*(DWORD **)m_pDDSurface;
hr = lpFunc(&(m_DDSInt.lpVtbl), riid, (void **)&m_D3DTextureInt);
if( SUCCEEDED(hr) )
{
*ppv=m_D3DTextureInt;
}
else
*ppv = NULL;
return hr;
}
else
{
return E_NOINTERFACE;
}
((LPUNKNOWN)*ppv)->AddRef();
return NOERROR;
}
STDMETHODIMP_(ULONG) CDDSurface::NonDelegatingAddRef()
{
m_pDDSurface->AddRef();
return InterlockedIncrement(&m_cRef);
}
STDMETHODIMP_(ULONG) CDDSurface::NonDelegatingRelease()
{
LONG lRefCount = InterlockedDecrement(&m_cRef);
if (lRefCount) {
m_pDDSurface->Release();
return lRefCount;
}
delete this;
return 0;
}
/*
* Quick inline fns to get at our internal data...
*/
_inline CDDSurface * SURFACEOF(IDirectDrawSurface * pDDS)
{
return ((INTSTRUC_IDirectDrawSurface *)pDDS)->m_pSimpleSurface;
}
_inline CDDSurface * SURFACEOF(IDirectDrawSurface2 * pDDS2)
{
return ((INTSTRUC_IDirectDrawSurface2 *)pDDS2)->m_pSimpleSurface;
}
_inline CDDSurface * SURFACEOF(IDirectDrawSurface3 * pDDS3)
{
return ((INTSTRUC_IDirectDrawSurface3 *)pDDS3)->m_pSimpleSurface;
}
_inline CDDSurface * SURFACEOF(IDirectDrawSurface4 * pDDS4)
{
return ((INTSTRUC_IDirectDrawSurface4 *)pDDS4)->m_pSimpleSurface;
}
/*
* the implementation of the functions in IDirectDrawSurface that we are
* overriding (IUnknown and GetDC, ReleaseDC, Lock, Unlock)
*/
STDMETHODIMP_(ULONG) IDirectDrawSurfaceAggAddRef(IDirectDrawSurface *pDDS)
{
return SURFACEOF(pDDS)->m_pUnkOuter->AddRef();
}
STDMETHODIMP_(ULONG) IDirectDrawSurfaceAggRelease(IDirectDrawSurface *pDDS)
{
return SURFACEOF(pDDS)->m_pUnkOuter->Release();
}
STDMETHODIMP IDirectDrawSurfaceAggGetDC(IDirectDrawSurface *pDDS, HDC * pHDC)
{
return SURFACEOF(pDDS)->InternalGetDC(pHDC);
}
STDMETHODIMP IDirectDrawSurfaceAggGetAttachedSurface(IDirectDrawSurface *pDDS, LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE FAR * lpDDS)
{
return SURFACEOF(pDDS)->InternalGetAttachedSurface(lpDDSCaps, lpDDS, DDSURFACETYPE_1);
}
STDMETHODIMP IDirectDrawSurfaceAggAddAttachedSurface(IDirectDrawSurface *pDDS, LPDIRECTDRAWSURFACE lpDDS)
{
return SURFACEOF(pDDS)->InternalAddAttachedSurface(lpDDS, DDSURFACETYPE_1);
}
STDMETHODIMP IDirectDrawSurfaceAggDeleteAttachedSurface(IDirectDrawSurface *pDDS, DWORD dwFlags, LPDIRECTDRAWSURFACE lpDDS)
{
return SURFACEOF(pDDS)->InternalDeleteAttachedSurface(dwFlags, lpDDS, DDSURFACETYPE_1);
}
STDMETHODIMP IDirectDrawSurfaceAggReleaseDC(IDirectDrawSurface *pDDS, HDC hdc)
{
return SURFACEOF(pDDS)->InternalReleaseDC(hdc);
}
STDMETHODIMP IDirectDrawSurfaceAggLock(IDirectDrawSurface *pDDS, LPRECT lpDestRect,
LPDDSURFACEDESC lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent)
{
return SURFACEOF(pDDS)->InternalLock(lpDestRect, lpDDSurfaceDesc, dwFlags, hEvent);
}
STDMETHODIMP IDirectDrawSurfaceAggUnlock(IDirectDrawSurface *pDDS, LPVOID lpSurfaceData)
{
return SURFACEOF(pDDS)->InternalUnlock(lpSurfaceData);
}
STDMETHODIMP IDirectDrawSurfaceAggFlip(IDirectDrawSurface *pDDS, LPDIRECTDRAWSURFACE lpSurf, DWORD dw)
{
return SURFACEOF(pDDS)->InternalFlip(lpSurf, dw, DDSURFACETYPE_1);
}
STDMETHODIMP IDirectDrawSurfaceAggBlt(IDirectDrawSurface *pDDS, LPRECT lpRect1,LPDIRECTDRAWSURFACE lpDDS, LPRECT lpRect2,DWORD dw, LPDDBLTFX lpfx)
{
return SURFACEOF(pDDS)->InternalBlt(lpRect1, lpDDS, lpRect2, dw, lpfx, DDSURFACETYPE_1);
}
STDMETHODIMP IDirectDrawSurfaceAggGetPalette(IDirectDrawSurface *pDDS, LPDIRECTDRAWPALETTE FAR * ppPal)
{
return SURFACEOF(pDDS)->InternalGetPalette(ppPal, DDSURFACETYPE_1);
}
STDMETHODIMP IDirectDrawSurfaceAggSetPalette(IDirectDrawSurface *pDDS, LPDIRECTDRAWPALETTE pPal)
{
return SURFACEOF(pDDS)->InternalSetPalette(pPal, DDSURFACETYPE_1);
}
STDMETHODIMP IDirectDrawSurfaceAggGetSurfaceDesc(IDirectDrawSurface *pDDS, LPDDSURFACEDESC lpDesc)
{
return SURFACEOF(pDDS)->InternalGetSurfaceDesc(lpDesc, DDSURFACETYPE_1);
}
/*
* the implementation of the functions in IDirectDrawSurface2 that we are
* overriding (IUnknown and GetDC, ReleaseDC, Lock, Unlock)
*/
STDMETHODIMP_(ULONG) IDirectDrawSurface2AggAddRef(IDirectDrawSurface2 *pDDS2)
{
return SURFACEOF(pDDS2)->m_pUnkOuter->AddRef();
}
STDMETHODIMP_(ULONG) IDirectDrawSurface2AggRelease(IDirectDrawSurface2 *pDDS2)
{
return SURFACEOF(pDDS2)->m_pUnkOuter->Release();
}
STDMETHODIMP IDirectDrawSurface2AggGetDC(IDirectDrawSurface2 *pDDS2, HDC * pHDC)
{
return SURFACEOF(pDDS2)->InternalGetDC(pHDC);
}
STDMETHODIMP IDirectDrawSurface2AggReleaseDC(IDirectDrawSurface2 *pDDS2, HDC hdc)
{
return SURFACEOF(pDDS2)->InternalReleaseDC(hdc);
}
STDMETHODIMP IDirectDrawSurface2AggLock(IDirectDrawSurface2 *pDDS2, LPRECT lpDestRect,
LPDDSURFACEDESC lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent)
{
return SURFACEOF(pDDS2)->InternalLock(lpDestRect, lpDDSurfaceDesc, dwFlags, hEvent);
}
STDMETHODIMP IDirectDrawSurface2AggUnlock(IDirectDrawSurface2 *pDDS2, LPVOID lpSurfaceData)
{
return SURFACEOF(pDDS2)->InternalUnlock(lpSurfaceData);
}
STDMETHODIMP IDirectDrawSurface2AggGetAttachedSurface(IDirectDrawSurface2 *pDDS, LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE2 FAR * lpDDS)
{
return SURFACEOF(pDDS)->InternalGetAttachedSurface(lpDDSCaps, (IDirectDrawSurface **)lpDDS, DDSURFACETYPE_2);
}
STDMETHODIMP IDirectDrawSurface2AggAddAttachedSurface(IDirectDrawSurface2 *pDDS, LPDIRECTDRAWSURFACE2 lpDDS)
{
return SURFACEOF(pDDS)->InternalAddAttachedSurface((IDirectDrawSurface *)lpDDS, DDSURFACETYPE_2);
}
STDMETHODIMP IDirectDrawSurface2AggDeleteAttachedSurface(IDirectDrawSurface2 *pDDS, DWORD dwFlags, LPDIRECTDRAWSURFACE2 lpDDS)
{
return SURFACEOF(pDDS)->InternalDeleteAttachedSurface(dwFlags, (IDirectDrawSurface *)lpDDS, DDSURFACETYPE_2);
}
STDMETHODIMP IDirectDrawSurface2AggFlip(IDirectDrawSurface2 *pDDS, LPDIRECTDRAWSURFACE2 lpSurf, DWORD dw)
{
return SURFACEOF(pDDS)->InternalFlip((LPDIRECTDRAWSURFACE)lpSurf, dw, DDSURFACETYPE_2);
}
STDMETHODIMP IDirectDrawSurface2AggBlt(IDirectDrawSurface2 *pDDS, LPRECT lpRect1,LPDIRECTDRAWSURFACE2 lpDDS, LPRECT lpRect2,DWORD dw, LPDDBLTFX lpfx)
{
return SURFACEOF(pDDS)->InternalBlt(lpRect1, (LPDIRECTDRAWSURFACE)lpDDS, lpRect2, dw, lpfx, DDSURFACETYPE_2);
}
STDMETHODIMP IDirectDrawSurface2AggGetPalette(IDirectDrawSurface2 *pDDS, LPDIRECTDRAWPALETTE FAR * ppPal)
{
return SURFACEOF(pDDS)->InternalGetPalette(ppPal, DDSURFACETYPE_2);
}
STDMETHODIMP IDirectDrawSurface2AggSetPalette(IDirectDrawSurface2 *pDDS, LPDIRECTDRAWPALETTE pPal)
{
return SURFACEOF(pDDS)->InternalSetPalette(pPal, DDSURFACETYPE_2);
}
STDMETHODIMP IDirectDrawSurface2AggGetDDInterface(IDirectDrawSurface2 *pDDS, LPVOID FAR * ppInt)
{
return SURFACEOF(pDDS)->InternalGetDDInterface(ppInt);
}
STDMETHODIMP IDirectDrawSurface2AggGetSurfaceDesc(IDirectDrawSurface2 *pDDS, LPDDSURFACEDESC lpDesc)
{
return SURFACEOF(pDDS)->InternalGetSurfaceDesc(lpDesc, DDSURFACETYPE_2);
}
/*
* the implementation of the functions in IDirectDrawSurface3 that we are
* overriding (IUnknown and GetDC, ReleaseDC, Lock, Unlock, SetSurfaceDesc)
*/
STDMETHODIMP_(ULONG) IDirectDrawSurface3AggAddRef(IDirectDrawSurface3 *pDDS3)
{
return SURFACEOF(pDDS3)->m_pUnkOuter->AddRef();
}
STDMETHODIMP_(ULONG) IDirectDrawSurface3AggRelease(IDirectDrawSurface3 *pDDS3)
{
return SURFACEOF(pDDS3)->m_pUnkOuter->Release();
}
STDMETHODIMP IDirectDrawSurface3AggGetDC(IDirectDrawSurface3 *pDDS3, HDC * pHDC)
{
return SURFACEOF(pDDS3)->InternalGetDC(pHDC);
}
STDMETHODIMP IDirectDrawSurface3AggReleaseDC(IDirectDrawSurface3 *pDDS3, HDC hdc)
{
return SURFACEOF(pDDS3)->InternalReleaseDC(hdc);
}
STDMETHODIMP IDirectDrawSurface3AggLock(IDirectDrawSurface3 *pDDS3, LPRECT lpDestRect,
LPDDSURFACEDESC lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent)
{
return SURFACEOF(pDDS3)->InternalLock(lpDestRect, lpDDSurfaceDesc, dwFlags, hEvent);
}
STDMETHODIMP IDirectDrawSurface3AggUnlock(IDirectDrawSurface3 *pDDS3, LPVOID lpSurfaceData)
{
return SURFACEOF(pDDS3)->InternalUnlock(lpSurfaceData);
}
STDMETHODIMP IDirectDrawSurface3AggSetSurfaceDesc(IDirectDrawSurface3 *pDDS3, LPDDSURFACEDESC pddsd, DWORD dwFlags)
{
return SURFACEOF(pDDS3)->InternalSetSurfaceDesc(pddsd, dwFlags);
}
STDMETHODIMP IDirectDrawSurface3AggGetAttachedSurface(IDirectDrawSurface3 *pDDS, LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE3 FAR * lpDDS)
{
return SURFACEOF(pDDS)->InternalGetAttachedSurface(lpDDSCaps, (IDirectDrawSurface**)lpDDS, DDSURFACETYPE_3);
}
STDMETHODIMP IDirectDrawSurface3AggAddAttachedSurface(IDirectDrawSurface3 *pDDS, LPDIRECTDRAWSURFACE3 lpDDS)
{
return SURFACEOF(pDDS)->InternalAddAttachedSurface((IDirectDrawSurface *)lpDDS, DDSURFACETYPE_3);
}
STDMETHODIMP IDirectDrawSurface3AggDeleteAttachedSurface(IDirectDrawSurface3 *pDDS, DWORD dwFlags, LPDIRECTDRAWSURFACE3 lpDDS)
{
return SURFACEOF(pDDS)->InternalDeleteAttachedSurface(dwFlags, (IDirectDrawSurface *)lpDDS, DDSURFACETYPE_3);
}
STDMETHODIMP IDirectDrawSurface3AggFlip(IDirectDrawSurface3 *pDDS, LPDIRECTDRAWSURFACE3 lpSurf, DWORD dw)
{
return SURFACEOF(pDDS)->InternalFlip((LPDIRECTDRAWSURFACE)lpSurf, dw, DDSURFACETYPE_3);
}
STDMETHODIMP IDirectDrawSurface3AggBlt(IDirectDrawSurface3 *pDDS, LPRECT lpRect1,LPDIRECTDRAWSURFACE3 lpDDS, LPRECT lpRect2,DWORD dw, LPDDBLTFX lpfx)
{
return SURFACEOF(pDDS)->InternalBlt(lpRect1, (LPDIRECTDRAWSURFACE)lpDDS, lpRect2, dw, lpfx, DDSURFACETYPE_3);
}
STDMETHODIMP IDirectDrawSurface3AggGetPalette(IDirectDrawSurface3 *pDDS, LPDIRECTDRAWPALETTE FAR * ppPal)
{
return SURFACEOF(pDDS)->InternalGetPalette(ppPal, DDSURFACETYPE_3);
}
STDMETHODIMP IDirectDrawSurface3AggSetPalette(IDirectDrawSurface3 *pDDS, LPDIRECTDRAWPALETTE pPal)
{
return SURFACEOF(pDDS)->InternalSetPalette(pPal, DDSURFACETYPE_3);
}
STDMETHODIMP IDirectDrawSurface3AggGetDDInterface(IDirectDrawSurface3 *pDDS, LPVOID FAR * ppInt)
{
return SURFACEOF(pDDS)->InternalGetDDInterface(ppInt);
}
STDMETHODIMP IDirectDrawSurface3AggGetSurfaceDesc(IDirectDrawSurface3 *pDDS, LPDDSURFACEDESC lpDesc)
{
return SURFACEOF(pDDS)->InternalGetSurfaceDesc(lpDesc, DDSURFACETYPE_3);
}
/*
* the implementation of the functions in IDirectDrawSurface4 that we are
* overriding (IUnknown and GetDC, ReleaseDC, Lock, Unlock, SetSurfaceDesc)
*/
STDMETHODIMP_(ULONG) IDirectDrawSurface4AggAddRef(IDirectDrawSurface4 *pDDS4)
{
return SURFACEOF(pDDS4)->m_pUnkOuter->AddRef();
}
STDMETHODIMP_(ULONG) IDirectDrawSurface4AggRelease(IDirectDrawSurface4 *pDDS4)
{
return SURFACEOF(pDDS4)->m_pUnkOuter->Release();
}
STDMETHODIMP IDirectDrawSurface4AggGetDC(IDirectDrawSurface4 *pDDS4, HDC * pHDC)
{
return SURFACEOF(pDDS4)->InternalGetDC(pHDC);
}
STDMETHODIMP IDirectDrawSurface4AggReleaseDC(IDirectDrawSurface4 *pDDS4, HDC hdc)
{
return SURFACEOF(pDDS4)->InternalReleaseDC(hdc);
}
STDMETHODIMP IDirectDrawSurface4AggLock(IDirectDrawSurface4 *pDDS4, LPRECT lpDestRect,
LPDDSURFACEDESC2 lpDDSurfaceDesc2, DWORD dwFlags, HANDLE hEvent)
{
INTSTRUC_IDirectDrawSurface4 * pdd4 = (INTSTRUC_IDirectDrawSurface4 *)pDDS4;
return pdd4->m_pRealInterface->Lock(lpDestRect, lpDDSurfaceDesc2, dwFlags, hEvent);
}
STDMETHODIMP IDirectDrawSurface4AggUnlock(IDirectDrawSurface4 *pDDS4, LPRECT lpRect)
{
INTSTRUC_IDirectDrawSurface4 * pdd4 = (INTSTRUC_IDirectDrawSurface4 *)pDDS4;
return pdd4->m_pRealInterface->Unlock(lpRect);
}
STDMETHODIMP IDirectDrawSurface4AggSetSurfaceDesc(IDirectDrawSurface4 *pDDS4, LPDDSURFACEDESC pddsd, DWORD dwFlags)
{
return SURFACEOF(pDDS4)->InternalSetSurfaceDesc(pddsd, dwFlags);
}
STDMETHODIMP IDirectDrawSurface4AggGetAttachedSurface(IDirectDrawSurface4 *pDDS, LPDDSCAPS2 lpDDSCaps, LPDIRECTDRAWSURFACE4 FAR * lpDDS)
{
return SURFACEOF(pDDS)->InternalGetAttachedSurface4(lpDDSCaps, (IDirectDrawSurface**)lpDDS);
}
STDMETHODIMP IDirectDrawSurface4AggAddAttachedSurface(IDirectDrawSurface4 *pDDS, LPDIRECTDRAWSURFACE4 lpDDS)
{
return SURFACEOF(pDDS)->InternalAddAttachedSurface((IDirectDrawSurface *)lpDDS, DDSURFACETYPE_4);
}
STDMETHODIMP IDirectDrawSurface4AggDeleteAttachedSurface(IDirectDrawSurface4 *pDDS, DWORD dwFlags, LPDIRECTDRAWSURFACE4 lpDDS)
{
return SURFACEOF(pDDS)->InternalDeleteAttachedSurface(dwFlags, (IDirectDrawSurface *)lpDDS, DDSURFACETYPE_4);
}
STDMETHODIMP IDirectDrawSurface4AggFlip(IDirectDrawSurface4 *pDDS, LPDIRECTDRAWSURFACE4 lpSurf, DWORD dw)
{
return SURFACEOF(pDDS)->InternalFlip((LPDIRECTDRAWSURFACE)lpSurf, dw, DDSURFACETYPE_4);
}
STDMETHODIMP IDirectDrawSurface4AggBlt(IDirectDrawSurface4 *pDDS, LPRECT lpRect1,LPDIRECTDRAWSURFACE4 lpDDS, LPRECT lpRect2,DWORD dw, LPDDBLTFX lpfx)
{
return SURFACEOF(pDDS)->InternalBlt(lpRect1, (LPDIRECTDRAWSURFACE)lpDDS, lpRect2, dw, lpfx, DDSURFACETYPE_4);
}
STDMETHODIMP IDirectDrawSurface4AggGetPalette(IDirectDrawSurface4 *pDDS, LPDIRECTDRAWPALETTE FAR * ppPal)
{
return SURFACEOF(pDDS)->InternalGetPalette(ppPal, DDSURFACETYPE_4);
}
STDMETHODIMP IDirectDrawSurface4AggSetPalette(IDirectDrawSurface4 *pDDS, LPDIRECTDRAWPALETTE pPal)
{
return SURFACEOF(pDDS)->InternalSetPalette(pPal, DDSURFACETYPE_4);
}
STDMETHODIMP IDirectDrawSurface4AggGetDDInterface(IDirectDrawSurface4 *pDDS, LPVOID FAR * ppInt)
{
return SURFACEOF(pDDS)->InternalGetDDInterface(ppInt);
}
STDMETHODIMP IDirectDrawSurface4AggGetSurfaceDesc(IDirectDrawSurface4 *pDDS, LPDDSURFACEDESC2 lpDesc2)
{
return SURFACEOF(pDDS)->InternalGetSurfaceDesc4(lpDesc2);
}