/*========================================================================== * * 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<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); }