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
92 KiB
2778 lines
92 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);
|
|
}
|
|
|
|
|