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

2778 lines
89 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1997 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: ddrawex.cpp
  6. * Content: new DirectDraw object support
  7. * History:
  8. * Date By Reason
  9. * ==== == ======
  10. * 24-feb-97 ralphl initial implementation
  11. * 25-feb-97 craige minor tweaks for dx checkin; integrated IBitmapSurface
  12. * stuff
  13. * 27-feb-97 craige use DIBSections for surface memory ddraw 3 surfaces
  14. * (icky icky icky)
  15. * 03-mar-97 craige IRGBColorTable support
  16. * 06-mar-97 craige support for IDirectDrawSurface3::SetBits
  17. * 14-mar-97 jeffort SetBits changed to reflect DX5 as SetSurfaceDesc
  18. * 01-apr-97 jeffort Following changes checked in:
  19. * D3DDevice and Texture interfaces supported in QueryInterface
  20. * MakeDibInfo fills in a dummy pixel mask for Z Buffers
  21. * Aligned freeing handled
  22. * Does not init (MakeDibSection) of primary surfaces
  23. * A palette is mapped in at GetDC calls
  24. *
  25. * 04-apr-97 jeffort LocalFree of bitmap info added
  26. * Addref and release added for D3D interfaces
  27. *
  28. * 09-apr-97 jeffort Added call to SetDIBColorTable at GetDC time
  29. * Support for WinNT4.0 Gold added by not creating a DIB section
  30. * and not supporting SetSurfaceDesc calls
  31. * Added support for halftone palette if no palette is
  32. * selected in at init time
  33. * Added support for proper handling of 1,2,and 4 bpp surface palettes
  34. * IBitmapSurface creation needs to set OWNDC flag
  35. *
  36. * 10-apr-97 jeffort Correct number of entries used in palette creation at GetDC time
  37. *
  38. * 16-apr-97 jeffort Check for OWNDC when creating a DibSection. palette handling
  39. * change in GetDC of setting flags
  40. * 28-apr-97 jeffort Palette wrapping added/DX5 support
  41. * 30-apr-97 jeffort Critical section shared from ddrawex object
  42. * Attach list deleted at surface destruction time
  43. * AddAttachedSurfaces now passes in real interfaces
  44. * Palette functions pass in real interfaces to ddraw
  45. * AddRef removed from D3D interface QI's
  46. * 02-may-97 jeffort Deletion of implicit attached surface handled
  47. * wrapping of GetDDInterface returns our ddrawex interface
  48. * 06-may-97 jeffort Parameter checking, SetPalette handles null parameter
  49. * wrapping of DeleteAttachedSurface
  50. *
  51. * 08-may-97 jeffort SetPalette fixes (release should have been addref)
  52. * Better parameter checking
  53. * 20-may-97 jeffort NT4.0 Gold handles OWNDC as SP3 does by creating a dib
  54. * section and resets a few ddraw internal structures
  55. * These are reset at surface release time
  56. * 22-may-97 jeffort If a surface is being destroyed, detach any attached palette
  57. * If a SetPalette is called with NULL, and a palette
  58. * was previously attached, the member variable storing the
  59. * palette is set to NULL
  60. * 27-may-97 jeffort keep ref count on internal object eual to outer object
  61. * 02-jun-97 jeffort Temporary fix for SP3 memory leak. Handle SP3 as NT Gold
  62. * by storing off pointer values and restoring at free
  63. * 17-jun-97 jeffort If releasing a surface that has explicitly attached surfaces
  64. * we now addref the inner surface (which will be released when
  65. * the inner surface we are releasing is released), and release
  66. * our outer interface so ref counting models ddraw.
  67. * 20-jun-97 jeffort added debug code to invaliudate objects when freed
  68. * when creating the primary surface, this is now added to the primary
  69. * surface list regardles if OWNDC is set or not
  70. * 27-jun-97 jeffort IDirectDrawSurface3 interface support for DX3 was not
  71. * added. We now use an IDirectDrawSurface2 to spoof it
  72. * so we can support SetSurfaceDesc
  73. * 02-jul-97 jeffort Use m_bSaveDC boolean if a DX5 surface with OWNDC set
  74. * we need to not NULL out the DC when ReleaseDC is called
  75. * so that a call to GetSurfaceFromDC will work
  76. * 07-jul-97 jeffort Releasing DDrawEx object moved in destructor function to last step
  77. * 07-jul-97 jeffort Wrapped GetSurfaceDesc so correct caps bits are set
  78. * 10-jul-97 jeffort Added m_BMOld to reset the bitmap after releasing the one
  79. * we create
  80. * Do not add a surface to a palette list if it is already in this list
  81. * 18-jul-97 jeffort Added D3D MMX Device support
  82. * 22-jul-97 jeffort Removed IBitmapSurface and associated interfaces
  83. * Fixed problem with attach lists, and releasing implicit created surfaces
  84. * 02-aug-97 jeffort Added code to GetPalette to return a palette if the palette that
  85. * was set was not created with the same ddrawex object that the surface was
  86. * Added code to handle attaching surfaces that were created with different
  87. * ddrawex objects
  88. * 20-feb-98 stevela Added support for DX6 MMX rasterizers
  89. ***************************************************************************/
  90. #include "ddfactry.h"
  91. #include "d3d.h"
  92. #define m_pDDSurface (m_DDSInt.m_pRealInterface)
  93. #define m_pDDSurface2 (m_DDS2Int.m_pRealInterface)
  94. #define m_pDDSurface3 (m_DDS3Int.m_pRealInterface)
  95. #define m_pDDSurface4 (m_DDS4Int.m_pRealInterface)
  96. #define DDSURFACETYPE_1 1
  97. #define DDSURFACETYPE_2 2
  98. #define DDSURFACETYPE_3 3
  99. #define DDSURFACETYPE_4 4
  100. typedef struct _ATTACHLIST
  101. {
  102. DWORD dwFlags;
  103. struct _ATTACHLIST FAR *lpLink; // link to next attached surface
  104. struct _DDRAWI_DDRAWSURFACE_LCL FAR *lpAttached; // attached surface local obj
  105. struct _DDRAWI_DDRAWSURFACE_INT FAR *lpIAttached; // attached surface interface
  106. } ATTACHLIST;
  107. typedef ATTACHLIST FAR *LPATTACHLIST;
  108. #define DDAL_IMPLICIT 0x00000001l
  109. /*
  110. * CDDSurface::CDDSurface
  111. *
  112. * Constructor for simple surface object
  113. */
  114. CDDSurface::CDDSurface(
  115. DDSURFACEDESC *pSurfaceDesc,
  116. IDirectDrawSurface *pDDSurface,
  117. IDirectDrawSurface2 *pDDSurface2,
  118. IDirectDrawSurface3 *pDDSurface3,
  119. IDirectDrawSurface4 *pDDSurface4,
  120. IUnknown *pUnkOuter,
  121. CDirectDrawEx *pDirectDrawEx) :
  122. m_cRef(1),
  123. m_pUnkOuter(pUnkOuter != 0 ? pUnkOuter : CAST_TO_IUNKNOWN(this)),
  124. m_pDirectDrawEx(pDirectDrawEx),
  125. m_bOwnDC((pSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_OWNDC) != 0),
  126. m_HDC(NULL)
  127. {
  128. m_pDDSurface = pDDSurface;
  129. m_pDDSurface2 = pDDSurface2;
  130. m_pDDSurface3 = pDDSurface3;
  131. m_pDDSurface4 = pDDSurface4;
  132. m_DDSInt.m_pSimpleSurface = this;
  133. m_DDS2Int.m_pSimpleSurface = this;
  134. m_DDS3Int.m_pSimpleSurface = this;
  135. m_DDS4Int.m_pSimpleSurface = this;
  136. m_D3DDeviceRAMPInt = NULL;
  137. m_D3DDeviceRGBInt = NULL;
  138. m_D3DDeviceChrmInt = NULL;
  139. m_D3DDeviceHALInt = NULL;
  140. m_D3DDeviceMMXInt = NULL;
  141. m_D3DTextureInt = NULL;
  142. m_pCurrentPalette = NULL;
  143. m_pPrevPalette = NULL;
  144. m_pNextPalette = NULL;
  145. m_pSaveBits = NULL;
  146. m_bSaveDC = FALSE;
  147. m_pAttach = NULL;
  148. if (m_pDirectDrawEx->m_dwDDVer == WIN95_DX5 || m_pDirectDrawEx->m_dwDDVer == WINNT_DX5)
  149. InitSurfaceInterfaces( pDDSurface, &m_DDSInt, pDDSurface2, &m_DDS2Int, pDDSurface3, &m_DDS3Int, pDDSurface4, &m_DDS4Int );
  150. else
  151. InitSurfaceInterfaces( pDDSurface, &m_DDSInt, pDDSurface2, &m_DDS2Int, NULL, &m_DDS3Int, pDDSurface4, &m_DDS4Int );
  152. m_dwCaps = pSurfaceDesc->ddsCaps.dwCaps;
  153. m_hDCDib = NULL;
  154. m_hBMDib = NULL;
  155. m_pBitsDib = NULL;
  156. m_pDDPal = NULL;
  157. m_pDDPalOurs = NULL;
  158. m_bPrimaryPalette = FALSE;
  159. pDirectDrawEx->AddRef();
  160. pDirectDrawEx->AddSurfaceToList(this);
  161. //we want to know if this is the primary surface or not
  162. if (pSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
  163. m_bIsPrimary = TRUE;
  164. else
  165. m_bIsPrimary = FALSE;
  166. //if we created the DIBSection, and it is palettized, we need to add this to
  167. //the list of surfaces using the primary surface's palette
  168. if ( (m_bOwnDC && (pSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED1 ||
  169. pSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED2 ||
  170. pSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED4 ||
  171. pSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8)) || m_bIsPrimary)
  172. {
  173. pDirectDrawEx->AddSurfaceToPrimaryList(this);
  174. }
  175. #ifdef DEBUG
  176. m_DebugCheckDC = NULL;
  177. #endif
  178. DllAddRef();
  179. } /* CDDSurface::CDDSurface */
  180. /*
  181. * CDDSurface::MakeDibInfo
  182. *
  183. * create a dib info structure based on the surface desc + palette
  184. */
  185. HRESULT CDDSurface::MakeDibInfo( LPDDSURFACEDESC pddsd, LPBITMAPINFO pbmi )
  186. {
  187. DWORD bitcnt;
  188. /*
  189. * fill in basic values
  190. */
  191. pbmi->bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
  192. pbmi->bmiHeader.biPlanes = 1;
  193. pbmi->bmiHeader.biSizeImage = 0;
  194. pbmi->bmiHeader.biXPelsPerMeter = 0;
  195. pbmi->bmiHeader.biYPelsPerMeter = 0;
  196. pbmi->bmiHeader.biClrImportant = 0;
  197. bitcnt = pddsd->ddpfPixelFormat.dwRGBBitCount;
  198. pbmi->bmiHeader.biBitCount = (WORD) bitcnt;
  199. /*
  200. * fill out width, clrused, and compression fields based on bit depth
  201. */
  202. switch( bitcnt )
  203. {
  204. case 1:
  205. pbmi->bmiHeader.biWidth = pddsd->lPitch << 3;
  206. pbmi->bmiHeader.biClrUsed = 2;
  207. pbmi->bmiHeader.biCompression = BI_RGB;
  208. break;
  209. case 4:
  210. pbmi->bmiHeader.biWidth = pddsd->lPitch << 1;
  211. pbmi->bmiHeader.biClrUsed = 16;
  212. pbmi->bmiHeader.biCompression = BI_RGB;
  213. break;
  214. case 8:
  215. pbmi->bmiHeader.biWidth = pddsd->lPitch;
  216. if(pddsd->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8)
  217. {
  218. pbmi->bmiHeader.biClrUsed = 256;
  219. pbmi->bmiHeader.biCompression = BI_RGB;
  220. }
  221. else
  222. {
  223. pbmi->bmiHeader.biClrUsed = 0;
  224. pbmi->bmiHeader.biCompression = BI_BITFIELDS;
  225. }
  226. break;
  227. case 16:
  228. pbmi->bmiHeader.biWidth = pddsd->lPitch >> 1;
  229. pbmi->bmiHeader.biClrUsed = 0;
  230. pbmi->bmiHeader.biCompression = BI_BITFIELDS;
  231. break;
  232. case 24:
  233. // NOTE: we're assuming RGB format. This is okay since we
  234. // don't do color conversion and neither does GDI at 24-bpp.
  235. pbmi->bmiHeader.biWidth = pddsd->lPitch / 3;
  236. pbmi->bmiHeader.biClrUsed = 0;
  237. pbmi->bmiHeader.biCompression = BI_RGB;
  238. break;
  239. case 32:
  240. pbmi->bmiHeader.biWidth = pddsd->lPitch >> 2;
  241. pbmi->bmiHeader.biClrUsed = 0;
  242. pbmi->bmiHeader.biCompression = BI_RGB;
  243. break;
  244. default:
  245. {
  246. char str[256];
  247. wsprintf( str, "bitcnt = %ld", bitcnt );
  248. MessageBox( NULL, str, "WHAT THE HECK, PIXEL DEPTH IS BAD BAD BAD", MB_OK );
  249. }
  250. }
  251. /*
  252. * set the color masks if we need to...
  253. */
  254. if( pbmi->bmiHeader.biCompression == BI_BITFIELDS )
  255. {
  256. DWORD *p;
  257. p = (DWORD *) &pbmi->bmiColors[0];
  258. p[0] = pddsd->ddpfPixelFormat.dwRBitMask;
  259. p[1] = pddsd->ddpfPixelFormat.dwGBitMask;
  260. p[2] = pddsd->ddpfPixelFormat.dwBBitMask;
  261. //check for no masks. Z-buffers don't have masks
  262. //so set a dummy value for this function call
  263. if (p[0] == 0 && p[1] == 0 && p[2] == 0){
  264. p[0]=0xF800;
  265. p[1]=0x07E0;
  266. p[2]=0x001F;
  267. }
  268. /*
  269. * set the image size too
  270. */
  271. pbmi->bmiHeader.biSizeImage = pddsd->lPitch * (int) pddsd->dwHeight;
  272. }
  273. /*
  274. * height is easy
  275. */
  276. pbmi->bmiHeader.biHeight= -1*(int)pddsd->dwHeight;
  277. /*
  278. * fill in the color table...
  279. */
  280. if( bitcnt <= 8 )
  281. {
  282. PALETTEENTRY pe[256];
  283. int i;
  284. LPDIRECTDRAWPALETTE pddpal;
  285. HRESULT hr;
  286. /*
  287. * is there an attached palette?
  288. */
  289. hr = m_pDDSurface->GetPalette( &pddpal );
  290. if( SUCCEEDED( hr ) )
  291. {
  292. //need to figure out how many entries are in here
  293. DWORD dwCaps;
  294. hr = pddpal->GetCaps(&dwCaps);
  295. if (SUCCEEDED(hr))
  296. {
  297. DWORD dwNumEntries;
  298. if (dwCaps & DDPCAPS_1BIT)
  299. dwNumEntries = 1;
  300. else if (dwCaps & DDPCAPS_2BIT)
  301. dwNumEntries = 4;
  302. else if (dwCaps & DDPCAPS_4BIT)
  303. dwNumEntries = 16;
  304. else if (dwCaps & DDPCAPS_8BIT)
  305. dwNumEntries = 256;
  306. else
  307. dwNumEntries = 0;
  308. hr = pddpal->GetEntries( 0, 0, dwNumEntries, pe );
  309. }
  310. pddpal->Release();
  311. }
  312. //if we created the DIBSection, and we are in EXCLUSIVE mode
  313. //then use the primary surface's palette if it exisits yet.
  314. else if (m_pDirectDrawEx->m_bExclusive)
  315. {
  316. //try and find the primary surface palette
  317. CDDPalette *pPal;
  318. pPal = m_pDirectDrawEx->m_pFirstPalette;
  319. while (pPal != NULL && pPal->m_bIsPrimary != TRUE)
  320. pPal = pPal->m_pNext;
  321. if (pPal != NULL)
  322. {
  323. DWORD dwCaps;
  324. hr = pPal->m_DDPInt.m_pRealInterface->GetCaps(&dwCaps);
  325. if (SUCCEEDED(hr))
  326. {
  327. DWORD dwNumEntries;
  328. if (dwCaps & DDPCAPS_1BIT)
  329. dwNumEntries = 1;
  330. else if (dwCaps & DDPCAPS_2BIT)
  331. dwNumEntries = 4;
  332. else if (dwCaps & DDPCAPS_4BIT)
  333. dwNumEntries = 16;
  334. else if (dwCaps & DDPCAPS_8BIT)
  335. dwNumEntries = 256;
  336. else
  337. dwNumEntries = 0;
  338. hr = pPal->m_DDPInt.m_pRealInterface->GetEntries( 0, 0, dwNumEntries, pe );
  339. }
  340. }
  341. }
  342. /*
  343. * nope, so use the system palette
  344. */
  345. if( FAILED( hr ) )
  346. {
  347. HDC hdc;
  348. hdc = ::GetDC( NULL );
  349. GetSystemPaletteEntries(hdc, 0, 256, pe);
  350. ::ReleaseDC(NULL, hdc);
  351. }
  352. /*
  353. * now copy the color table
  354. */
  355. int iNumEntries;
  356. switch (bitcnt)
  357. {
  358. case 1:
  359. iNumEntries = 1;
  360. break;
  361. case 2:
  362. iNumEntries = 4;
  363. break;
  364. case 4:
  365. iNumEntries = 16;
  366. break;
  367. case 8:
  368. iNumEntries = 256;
  369. break;
  370. default:
  371. iNumEntries = 0;
  372. break;
  373. }
  374. for(i=0;i < iNumEntries;i++)
  375. {
  376. pbmi->bmiColors[i].rgbRed = pe[i].peRed;
  377. pbmi->bmiColors[i].rgbGreen = pe[i].peGreen;
  378. pbmi->bmiColors[i].rgbBlue= pe[i].peBlue;
  379. }
  380. }
  381. return DD_OK;
  382. } /* CDDSurface::MakeDibInfo */
  383. /*
  384. * CDDSurface::MakeDIBSection()
  385. */
  386. HRESULT CDDSurface::MakeDIBSection()
  387. {
  388. DDSURFACEDESC ddsd;
  389. DWORD size;
  390. DWORD bitcnt;
  391. LPBITMAPINFO pbmi;
  392. /*
  393. * don't need to bother if the DirectDraw version isn't 3 or if it
  394. * isn't a system memory surface
  395. */
  396. #pragma message( REMIND( "Should we use a DIB unless the surface really is in video memory?" ))
  397. if( m_pDirectDrawEx->m_dwDDVer == WIN95_DX5 || m_pDirectDrawEx->m_dwDDVer == WINNT_DX5 || !(m_dwCaps & DDSCAPS_SYSTEMMEMORY))
  398. {
  399. return 1;
  400. }
  401. /*
  402. * so we need to make a dib section that is identical to this surface
  403. * first, get the surface desc
  404. */
  405. ddsd.dwSize = sizeof( ddsd );
  406. m_pDDSurface->GetSurfaceDesc( &ddsd );
  407. /*
  408. * allocate a pixel format structure
  409. */
  410. size = sizeof(BITMAPINFOHEADER);
  411. bitcnt = ddsd.ddpfPixelFormat.dwRGBBitCount;
  412. if( bitcnt <= 8)
  413. {
  414. size += (1<<bitcnt)*sizeof(RGBQUAD);
  415. }
  416. else
  417. {
  418. size += sizeof(DWORD)*3;
  419. }
  420. pbmi = (LPBITMAPINFO) LocalAlloc( LPTR, size );
  421. if( pbmi == NULL )
  422. {
  423. return DDERR_OUTOFMEMORY;
  424. }
  425. /*
  426. * flesh out the bitmap info header
  427. */
  428. MakeDibInfo( &ddsd, pbmi );
  429. /*
  430. * make the DIB section
  431. */
  432. m_hDCDib = CreateCompatibleDC(NULL);
  433. if( m_hDCDib != NULL )
  434. {
  435. m_hBMDib = CreateDIBSection(
  436. m_hDCDib, // the HDC
  437. pbmi, // bitmap info
  438. DIB_RGB_COLORS, // use color table in bitmap info
  439. &m_pBitsDib, // dib bits
  440. NULL, // no file handle
  441. 0 ); // offset into file (irrelevant)
  442. //free up our bitmap info struct
  443. LocalFree(pbmi);
  444. if( m_hBMDib == NULL )
  445. {
  446. DeleteDC( m_hDCDib );
  447. return DDERR_OUTOFMEMORY;
  448. }
  449. /*
  450. * select our bitmap into our new DC
  451. */
  452. m_hBMOld = (HBITMAP)SelectObject( m_hDCDib, (void *)m_hBMDib );
  453. #ifdef DEBUG
  454. ASSERT(m_hBMOld != NULL);
  455. #endif
  456. }
  457. else
  458. {
  459. //free up our local bitmap structure
  460. LocalFree(pbmi);
  461. return DDERR_OUTOFMEMORY;
  462. }
  463. return DD_OK;
  464. } /* CDDSurface::MakeDIBSection */
  465. HRESULT CDDSurface::SupportOwnDC()
  466. {
  467. /*
  468. * if we want our own DC, then create one
  469. */
  470. HRESULT hr = DD_OK;
  471. if( m_bOwnDC )
  472. {
  473. HRESULT hrGotSurface, hrGotDC;
  474. IDirectDrawSurface *pTempSurface;
  475. HDC hdcTemp = NULL;
  476. /*
  477. * Eat the cached HDC so owned DC surfaces won't use it.
  478. */
  479. DDSURFACEDESC ddsd;
  480. ddsd.dwSize = sizeof(ddsd);
  481. ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
  482. ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY;
  483. ddsd.dwHeight = ddsd.dwWidth = 1;
  484. hrGotSurface = m_pDirectDrawEx->m_DDInt.m_pRealInterface->CreateSurface(&ddsd, &pTempSurface, NULL);
  485. if( SUCCEEDED(hrGotSurface) )
  486. {
  487. hrGotDC = pTempSurface->GetDC(&hdcTemp);
  488. }
  489. /*
  490. * get the DC and then unlock the surface
  491. * we know that GetDC does a Lock, so the Unlock will allow the
  492. * DC to be used and Lock/Unlock to be used together...
  493. */
  494. hr = m_pDDSurface->GetDC(&m_HDC);
  495. if( SUCCEEDED(hr) )
  496. {
  497. m_pDDSurface->Unlock(NULL);
  498. }
  499. else
  500. {
  501. m_bOwnDC = FALSE; // To prevent destructor from doing unlock trick
  502. m_HDC = NULL; // Just to make sure...
  503. }
  504. /*
  505. * clean up the extra surface/dc
  506. */
  507. if( SUCCEEDED(hrGotSurface) )
  508. {
  509. if( SUCCEEDED(hrGotDC) )
  510. {
  511. pTempSurface->ReleaseDC(hdcTemp);
  512. }
  513. pTempSurface->Release();
  514. }
  515. }
  516. return hr;
  517. }//CDDSurface::SupportOwnDC
  518. /*
  519. * CDDSurface::Init
  520. *
  521. * Initialize the surface
  522. */
  523. HRESULT CDDSurface::Init()
  524. {
  525. HRESULT hr = S_OK;
  526. hr = MakeDIBSection();
  527. if( FAILED( hr ) )
  528. {
  529. return hr;
  530. }
  531. /*
  532. * if we made the DIB section, then we need to tweak the internal
  533. * direct draw surface stucture (only allowed for direct draw 3)
  534. */
  535. if( hr == DD_OK )
  536. {
  537. LPDDRAWI_DDRAWSURFACE_INT psurf_int;
  538. psurf_int = (LPDDRAWI_DDRAWSURFACE_INT) m_pDDSurface;
  539. /*
  540. * mark the surface memory as freed, and replace the memory with
  541. * our dib section memory
  542. */
  543. psurf_int->lpLcl->lpGbl->dwGlobalFlags |= DDRAWISURFGBL_MEMFREE;
  544. DWORD dwOffset;
  545. LPVOID lpMem;
  546. lpMem= (LPVOID) psurf_int->lpLcl->lpGbl->fpVidMem;
  547. //probably don't need this check, but it can't hurt
  548. if( NULL != lpMem )
  549. {
  550. if (m_pDirectDrawEx->m_dwDDVer != WINNT_DX2 && m_pDirectDrawEx->m_dwDDVer != WINNT_DX3)
  551. {
  552. //check to see if this surface has been aligned and reset the pointer if so
  553. if(psurf_int->lpLcl->ddsCaps.dwCaps & DDSCAPS_ZBUFFER ||
  554. psurf_int->lpLcl->ddsCaps.dwCaps & DDSCAPS_TEXTURE ||
  555. psurf_int->lpLcl->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN)
  556. {
  557. dwOffset = *( (LPDWORD) ( ( (LPBYTE)lpMem ) - sizeof(DWORD) ) );
  558. lpMem = (LPVOID) ( ( (LPBYTE) lpMem) - dwOffset );
  559. }
  560. //free the memory
  561. LocalFree(lpMem);
  562. }
  563. else
  564. {
  565. //store this value off so we can use it when we destroy the surface
  566. m_pSaveBits = (ULONG_PTR)lpMem;
  567. m_pSaveHDC = psurf_int->lpLcl->hDC;
  568. m_pSaveHBM = psurf_int->lpLcl->dwReserved1;
  569. }
  570. }
  571. psurf_int->lpLcl->lpGbl->fpVidMem = (ULONG_PTR) m_pBitsDib;
  572. return hr;
  573. }
  574. hr = SupportOwnDC();
  575. return hr;
  576. } /* CDDSurface::Init */
  577. void CDDSurface::CleanUpSurface()
  578. {
  579. if( m_bOwnDC && m_HDC != NULL )
  580. {
  581. DDSURFACEDESC ddsd;
  582. ddsd.dwSize = sizeof(ddsd);
  583. m_pDDSurface->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL);
  584. }
  585. if( m_HDC != NULL )
  586. {
  587. m_pDDSurface->ReleaseDC(m_HDC);
  588. }
  589. if( m_hBMDib != NULL )
  590. {
  591. /* un-select our bitmap from the DC */
  592. SelectObject(m_hDCDib, m_hBMOld);
  593. DeleteObject( m_hBMDib );
  594. }
  595. if( m_hDCDib != NULL )
  596. {
  597. DeleteDC( m_hDCDib );
  598. }
  599. /*
  600. * clean up...
  601. */
  602. //if a palette is attached to this surface, detach it here
  603. if (m_pCurrentPalette != NULL)
  604. InternalSetPalette(NULL, 1);
  605. m_pDirectDrawEx->RemoveSurfaceFromList(this);
  606. if (m_pCurrentPalette)
  607. m_pCurrentPalette->RemoveSurfaceFromList(this);
  608. else if (m_bPrimaryPalette)
  609. m_pDirectDrawEx->RemoveSurfaceFromPrimaryList(this);
  610. //if we are running under NT4 Gold, we need to see if we modified the surface
  611. if ((m_pDirectDrawEx->m_dwDDVer == WINNT_DX2 || m_pDirectDrawEx->m_dwDDVer == WINNT_DX3) && m_pSaveBits != NULL)
  612. {
  613. LPDDRAWI_DDRAWSURFACE_INT psurf_int;
  614. psurf_int = (LPDDRAWI_DDRAWSURFACE_INT) m_pDDSurface;
  615. psurf_int->lpLcl->lpGbl->dwGlobalFlags &= ~(DDRAWISURFGBL_MEMFREE);
  616. psurf_int->lpLcl->lpGbl->fpVidMem = (FLATPTR) m_pSaveBits;
  617. psurf_int->lpLcl->hDC = m_pSaveHDC;
  618. psurf_int->lpLcl->dwReserved1 = m_pSaveHBM;
  619. }
  620. }
  621. void CDDSurface::ReleaseRealInterfaces()
  622. {
  623. if( m_pDDSurface3 != NULL )
  624. {
  625. m_pDDSurface3->Release();
  626. }
  627. m_pDDSurface2->Release();
  628. m_pDDSurface->Release();
  629. m_pDirectDrawEx->Release();
  630. #ifdef DEBUG
  631. DWORD * ptr;
  632. ptr = (DWORD *)this;
  633. for (int i = 0; i < sizeof(CDDSurface) / sizeof(DWORD);i++)
  634. *ptr++ = 0xDEADBEEF;
  635. #endif
  636. DllRelease();
  637. }
  638. void CDDSurface::AddSurfaceToDestroyList(CDDSurface * pSurface)
  639. {
  640. #ifdef DEBUG
  641. ASSERT(pSurface != NULL);
  642. #endif
  643. ENTER_DDEX();
  644. if( m_pDestroyList )
  645. {
  646. #ifdef DEBUG
  647. ASSERT(m_pDestroyList->m_pPrev == NULL);
  648. #endif
  649. m_pDestroyList->m_pPrev = pSurface;
  650. }
  651. pSurface->m_pPrev = NULL;
  652. pSurface->m_pNext = m_pDestroyList;
  653. m_pDestroyList = pSurface;
  654. LEAVE_DDEX();
  655. }
  656. void CDDSurface::DeleteAttachment(IDirectDrawSurface * pOrigSurf, CDDSurface * pFirst)
  657. {
  658. LPATTACHLIST lpAttach;
  659. IDirectDrawSurface * pSurface;
  660. CDDSurface * pSurfaceOuter;
  661. CleanUpSurface();
  662. //check for attached surface here
  663. lpAttach = (LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(m_pDDSurface))->lpLcl->lpAttachList);
  664. pSurface = m_pDDSurface;
  665. while (lpAttach != NULL && pSurface != NULL)
  666. {
  667. if (lpAttach->dwFlags & DDAL_IMPLICIT)
  668. {
  669. lpAttach = lpAttach->lpLink;
  670. if (((LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(pSurface))->lpLcl->lpAttachList)) != NULL)
  671. pSurface = (IDirectDrawSurface *)((LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(pSurface))->lpLcl->lpAttachList))->lpIAttached;
  672. else
  673. pSurface = NULL;
  674. //scan our list of surfaces for the outer surface here
  675. pSurfaceOuter = m_pDirectDrawEx->m_pFirstSurface;
  676. while (pSurfaceOuter != NULL && pSurfaceOuter->m_DDSInt.m_pRealInterface != pSurface)
  677. pSurfaceOuter = pSurfaceOuter->m_pNext;
  678. if (pSurface != pOrigSurf && pSurfaceOuter != NULL){
  679. pSurfaceOuter->DeleteAttachment(pOrigSurf, pFirst);
  680. //and add this to our list to be deleted at the end
  681. pFirst->AddSurfaceToDestroyList(pSurfaceOuter);
  682. }
  683. else
  684. lpAttach = NULL;
  685. }
  686. else
  687. {
  688. lpAttach = lpAttach->lpLink;
  689. if (((LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(pSurface))->lpLcl->lpAttachList)) != NULL)
  690. pSurface = (IDirectDrawSurface *)((LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(pSurface))->lpLcl->lpAttachList))->lpIAttached;
  691. else
  692. pSurface = NULL;
  693. //scan our list of surfaces for the outer surface here
  694. pSurfaceOuter = m_pDirectDrawEx->m_pFirstSurface;
  695. while (pSurfaceOuter != NULL && pSurfaceOuter->m_DDSInt.m_pRealInterface != pSurface)
  696. pSurfaceOuter = pSurfaceOuter->m_pNext;
  697. if (pSurface != pOrigSurf && pSurfaceOuter != NULL){
  698. //when the release of the surface is done, it will do a Release on the real interface
  699. //of this surface, so we need to AddRef the real interface, but Release our interface here
  700. pSurface->AddRef();
  701. pSurfaceOuter->Release();
  702. }
  703. }
  704. }
  705. //we need to do the same thing for the m_pDDAttach list if it still remains
  706. //all of these surface were not found in the code above. They are explicitly attached surfaces
  707. //that were not create with the same ddrawex object that this surface was created with
  708. while (m_pAttach != NULL)
  709. {
  710. DDAttachSurface * pDelete;
  711. pDelete = m_pAttach;
  712. m_pAttach = m_pAttach->pNext;
  713. pDelete->pSurface->m_DDSInt.m_pRealInterface->AddRef();
  714. pDelete->pSurface->Release();
  715. delete pDelete;
  716. }
  717. if( m_pDDSurface3 != NULL )
  718. {
  719. m_pDDSurface3->Release();
  720. }
  721. HRESULT hr;
  722. hr = m_pDDSurface2->Release();
  723. #ifdef DEBUG
  724. ASSERT(hr == 0);
  725. #endif
  726. hr = m_pDDSurface->Release();
  727. m_pDirectDrawEx->Release();
  728. DllRelease();
  729. }
  730. /*
  731. * CDDSurface::~CDDSurface
  732. *
  733. * Destructor
  734. */
  735. CDDSurface::~CDDSurface()
  736. {
  737. /*
  738. * if we have an OwnDC, then Lock the surface so ReleaseDC will work right...
  739. */
  740. LPATTACHLIST lpAttach;
  741. IDirectDrawSurface * pSurface;
  742. IDirectDrawSurface * pOrigSurf;
  743. CDDSurface * pSurfaceOuter;
  744. m_pDestroyList = NULL;
  745. CleanUpSurface();
  746. //check for attached surface here
  747. lpAttach = (LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(m_pDDSurface))->lpLcl->lpAttachList);
  748. pOrigSurf = pSurface = m_pDDSurface;
  749. while (lpAttach != NULL && pSurface != NULL)
  750. {
  751. if (lpAttach->dwFlags & DDAL_IMPLICIT)
  752. {
  753. lpAttach = lpAttach->lpLink;
  754. if (((LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(pSurface))->lpLcl->lpAttachList)) != NULL)
  755. pSurface = (IDirectDrawSurface *)((LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(pSurface))->lpLcl->lpAttachList))->lpIAttached;
  756. else
  757. pSurface = NULL;
  758. //scan our list of surfaces for the outer surface here
  759. pSurfaceOuter = m_pDirectDrawEx->m_pFirstSurface;
  760. while (pSurfaceOuter != NULL && pSurfaceOuter->m_DDSInt.m_pRealInterface != pSurface)
  761. pSurfaceOuter = pSurfaceOuter->m_pNext;
  762. if (pSurface != pOrigSurf && pSurfaceOuter != NULL)
  763. {
  764. pSurfaceOuter->DeleteAttachment(pOrigSurf, this);
  765. AddSurfaceToDestroyList(pSurfaceOuter);
  766. }
  767. else
  768. lpAttach = NULL;
  769. }
  770. else
  771. {
  772. lpAttach = lpAttach->lpLink;
  773. if (((LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(pSurface))->lpLcl->lpAttachList)) != NULL)
  774. pSurface = (IDirectDrawSurface *)((LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(pSurface))->lpLcl->lpAttachList))->lpIAttached;
  775. else
  776. pSurface = NULL;
  777. //scan our list of surfaces for the outer surface here
  778. pSurfaceOuter = m_pDirectDrawEx->m_pFirstSurface;
  779. while (pSurfaceOuter != NULL && pSurfaceOuter->m_DDSInt.m_pRealInterface != pSurface)
  780. pSurfaceOuter = pSurfaceOuter->m_pNext;
  781. if (pSurface != pOrigSurf && pSurfaceOuter != NULL){
  782. //when the release of the surface is done, it will do a Release on the real interface
  783. //of this surface, so we need to AddRef the real interface, but Release our interface here
  784. pSurface->AddRef();
  785. pSurfaceOuter->Release();
  786. }
  787. }
  788. }
  789. //we need to do the same thing for the m_pDDAttach list if it still remains
  790. //all of these surface were not found in the code above. They are explicitly attached surfaces
  791. //that were not create with the same ddrawex object that this surface was created with
  792. while (m_pAttach != NULL)
  793. {
  794. DDAttachSurface * pDelete;
  795. pDelete = m_pAttach;
  796. m_pAttach = m_pAttach->pNext;
  797. pDelete->pSurface->m_DDSInt.m_pRealInterface->AddRef();
  798. pDelete->pSurface->Release();
  799. delete pDelete;
  800. }
  801. if (m_pDDSurface4)
  802. {
  803. m_pDDSurface4->Release();
  804. }
  805. if( m_pDDSurface3 != NULL )
  806. {
  807. m_pDDSurface3->Release();
  808. }
  809. HRESULT hr;
  810. hr = m_pDDSurface2->Release();
  811. #ifdef DEBUG
  812. ASSERT(hr == 0);
  813. #endif
  814. hr = m_pDDSurface->Release();
  815. //if we had implicit attached surface, we need to delete those here
  816. if (m_pDestroyList != NULL)
  817. {
  818. CDDSurface * pDelete;
  819. CDDSurface * pNext;
  820. pDelete = m_pDestroyList;
  821. while (pDelete != NULL)
  822. {
  823. pNext = pDelete->m_pNext;
  824. #ifdef DEBUG
  825. DWORD * ptr;
  826. ptr = (DWORD *)pDelete;
  827. for (int i = 0; i < sizeof(CDDSurface) / sizeof(DWORD);i++)
  828. *ptr++ = 0xDEADBEEF;
  829. #endif
  830. delete (void *)pDelete;
  831. pDelete = pNext;
  832. }
  833. m_pDestroyList = NULL;
  834. }
  835. m_pDirectDrawEx->Release();
  836. #ifdef DEBUG
  837. DWORD * ptr;
  838. ptr = (DWORD *)this;
  839. for (int i = 0; i < sizeof(CDDSurface) / sizeof(DWORD);i++)
  840. *ptr++ = 0xDEADBEEF;
  841. #endif
  842. DllRelease();
  843. } /* CDDSurface::~CDDSurface */
  844. /*
  845. * CDDSurface::CreateSimpleSurface
  846. *
  847. */
  848. HRESULT CDDSurface::CreateSimpleSurface(
  849. LPDDSURFACEDESC pSurfaceDesc,
  850. IDirectDrawSurface *pDDSurface,
  851. IDirectDrawSurface2 *pDDSurface2,
  852. IDirectDrawSurface3 *pDDSurface3,
  853. IDirectDrawSurface4 *pDDSurface4,
  854. IUnknown *pUnkOuter,
  855. CDirectDrawEx *pDirectDrawEx,
  856. IDirectDrawSurface **ppNewDDSurf,
  857. DWORD dwFlags)
  858. {
  859. HRESULT hr;
  860. CDDSurface *pSurface = new CDDSurface(pSurfaceDesc,
  861. pDDSurface,
  862. pDDSurface2,
  863. pDDSurface3,
  864. pDDSurface4,
  865. pUnkOuter,
  866. pDirectDrawEx);
  867. if( !pSurface)
  868. {
  869. return E_OUTOFMEMORY;
  870. }
  871. else
  872. {
  873. //If we are running DX5, we can turn of the m_bOwnDC if it is on
  874. if( pSurface->m_pDirectDrawEx->m_dwDDVer == WIN95_DX5 || pSurface->m_pDirectDrawEx->m_dwDDVer == WINNT_DX5)
  875. {
  876. pSurface->m_bOwnDC = FALSE;
  877. //if OWNDC is set, we need to store the DC around after a ReleasDC, check that here
  878. if (pSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_OWNDC || ((pSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_DATAEXCHANGE) == DDSCAPS_DATAEXCHANGE))
  879. pSurface->m_bSaveDC = TRUE;
  880. }
  881. if ((pSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) &&
  882. !(pSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
  883. {
  884. //we do not want to do this if we are running under WindowsNT4.0 gold
  885. //but we have to because of palette problems, so call for anything. . .
  886. if (pSurface->m_bOwnDC)
  887. hr = pSurface->Init();
  888. else
  889. hr = DD_OK;
  890. }
  891. else
  892. hr = DD_OK;
  893. if( SUCCEEDED(hr) )
  894. {
  895. pSurface->NonDelegatingQueryInterface(pUnkOuter ? IID_IUnknown : IID_IDirectDrawSurface, (void **)ppNewDDSurf);
  896. }
  897. //if creating our own_dc/dib section failed, then this will release the surface
  898. pSurface->NonDelegatingRelease();
  899. }
  900. return hr;
  901. } /* CDDSurface::CreateSimpleSurface */
  902. /*
  903. * CDDSurface::InternalGetDC
  904. *
  905. * Simple surface GetDC implementation
  906. */
  907. HRESULT CDDSurface::InternalGetDC(HDC *pHDC)
  908. {
  909. //palette handling was removed because we now wrap the palette functions and handle
  910. //setting the DIB Color table when SetEntries or SetPallette is called.
  911. //this will speed up the GetDc call signifigantly: JGO
  912. HRESULT hr = DD_OK;
  913. if (pHDC == NULL)
  914. return DDERR_INVALIDPARAMS;
  915. if( m_hDCDib )
  916. {
  917. *pHDC = m_hDCDib;
  918. }
  919. else if( m_bOwnDC )
  920. {
  921. *pHDC = m_HDC;
  922. }
  923. else
  924. {
  925. hr = m_pDDSurface->GetDC(pHDC);
  926. if (SUCCEEDED(hr))
  927. m_HDC = *pHDC;
  928. }
  929. #ifdef DEBUG
  930. if ( m_DebugCheckDC)
  931. {
  932. //should we get the same DC? We should if OWNDC is set or DATAEXCHANGE is set
  933. if (m_dwCaps & DDSCAPS_OWNDC || (m_dwCaps & DDSCAPS_DATAEXCHANGE) == DDSCAPS_DATAEXCHANGE)
  934. ASSERT((DWORD)*pHDC == m_DebugCheckDC);
  935. }
  936. m_DebugCheckDC = (DWORD)*pHDC;
  937. #endif
  938. return hr;
  939. } /* CDDSurface::InternalGetDC */
  940. /*
  941. * CDDSurface::InternalReleaseDC
  942. *
  943. * Simple surface ReleaseDC implementation
  944. */
  945. HRESULT CDDSurface::InternalReleaseDC(HDC hdc)
  946. {
  947. HRESULT hr = DD_OK;
  948. /*
  949. * if we have a DIB section DC, do nothing
  950. */
  951. if( m_hDCDib != NULL )
  952. {
  953. if( hdc != m_hDCDib )
  954. {
  955. hr = DDERR_INVALIDPARAMS;
  956. }
  957. }
  958. /*
  959. * if this is an OwnDC, do nothing
  960. */
  961. else if( m_bOwnDC )
  962. {
  963. if( hdc != m_HDC )
  964. {
  965. hr = DDERR_INVALIDPARAMS;
  966. }
  967. }
  968. /*
  969. * allow ddraw to release the dc
  970. */
  971. else
  972. {
  973. hr = m_pDDSurface->ReleaseDC(hdc);
  974. if( SUCCEEDED(hr) )
  975. {
  976. if (!m_bSaveDC)
  977. m_HDC = NULL;
  978. }
  979. }
  980. return hr;
  981. } /* CDDSurface::InternalReleaseDC */
  982. /*
  983. * CDDSurface::InternalAddAttachedSurface
  984. *
  985. * Simple surface AddAttachedSurface implementation
  986. */
  987. HRESULT CDDSurface::InternalFlip (LPDIRECTDRAWSURFACE lpDDS, DWORD dw, DWORD dwSurfaceType)
  988. {
  989. HRESULT hr;
  990. switch (dwSurfaceType)
  991. {
  992. case DDSURFACETYPE_1:
  993. INTSTRUC_IDirectDrawSurface *lpIDDS;
  994. lpIDDS = ((INTSTRUC_IDirectDrawSurface *)(lpDDS));
  995. if (lpIDDS == NULL)
  996. hr = m_pDDSurface->Flip(NULL, dw);
  997. else
  998. hr = m_pDDSurface->Flip(lpIDDS->m_pRealInterface, dw);
  999. break;
  1000. case DDSURFACETYPE_2:
  1001. INTSTRUC_IDirectDrawSurface2 *lpIDDS2;
  1002. lpIDDS2 = ((INTSTRUC_IDirectDrawSurface2 *)(lpDDS));
  1003. if (lpIDDS2 == NULL)
  1004. hr = m_pDDSurface2->Flip(NULL, dw);
  1005. else
  1006. hr = m_pDDSurface2->Flip(lpIDDS2->m_pRealInterface, dw);
  1007. break;
  1008. case DDSURFACETYPE_3:
  1009. INTSTRUC_IDirectDrawSurface3 *lpIDDS3;
  1010. lpIDDS3 = ((INTSTRUC_IDirectDrawSurface3 *)(lpDDS));
  1011. if (lpIDDS3 == NULL)
  1012. hr = m_pDDSurface3->Flip(NULL, dw);
  1013. else
  1014. hr = m_pDDSurface3->Flip(lpIDDS3->m_pRealInterface, dw);
  1015. break;
  1016. case DDSURFACETYPE_4:
  1017. INTSTRUC_IDirectDrawSurface4 *lpIDDS4;
  1018. lpIDDS4 = ((INTSTRUC_IDirectDrawSurface4 *)(lpDDS));
  1019. if (lpIDDS4 == NULL)
  1020. hr = m_pDDSurface4->Flip(NULL, dw);
  1021. else
  1022. hr = m_pDDSurface4->Flip(lpIDDS4->m_pRealInterface, dw);
  1023. break;
  1024. }
  1025. return hr;
  1026. }
  1027. HRESULT CDDSurface::InternalBlt (LPRECT lpRect1,LPDIRECTDRAWSURFACE lpDDS, LPRECT lpRect2,DWORD dw, LPDDBLTFX lpfx, DWORD dwSurfaceType)
  1028. {
  1029. HRESULT hr;
  1030. switch (dwSurfaceType)
  1031. {
  1032. case DDSURFACETYPE_1:
  1033. INTSTRUC_IDirectDrawSurface *lpIDDS;
  1034. lpIDDS = ((INTSTRUC_IDirectDrawSurface *)(lpDDS));
  1035. if (lpDDS != NULL)
  1036. hr = m_pDDSurface->Blt(lpRect1, lpIDDS->m_pRealInterface, lpRect2,dw, lpfx);
  1037. else
  1038. hr = m_pDDSurface->Blt(lpRect1, NULL, lpRect2,dw, lpfx);
  1039. break;
  1040. case DDSURFACETYPE_2:
  1041. INTSTRUC_IDirectDrawSurface2 *lpIDDS2;
  1042. lpIDDS2 = ((INTSTRUC_IDirectDrawSurface2 *)(lpDDS));
  1043. if (lpDDS != NULL)
  1044. hr = m_pDDSurface2->Blt(lpRect1, lpIDDS2->m_pRealInterface, lpRect2,dw, lpfx);
  1045. else
  1046. hr = m_pDDSurface2->Blt(lpRect1, NULL, lpRect2,dw, lpfx);
  1047. break;
  1048. case DDSURFACETYPE_3:
  1049. INTSTRUC_IDirectDrawSurface3 *lpIDDS3;
  1050. lpIDDS3 = ((INTSTRUC_IDirectDrawSurface3 *)(lpDDS));
  1051. if (lpDDS != NULL)
  1052. hr = m_pDDSurface3->Blt(lpRect1, lpIDDS3->m_pRealInterface, lpRect2,dw, lpfx);
  1053. else
  1054. hr = m_pDDSurface3->Blt(lpRect1, NULL, lpRect2,dw, lpfx);
  1055. break;
  1056. case DDSURFACETYPE_4:
  1057. INTSTRUC_IDirectDrawSurface4 *lpIDDS4;
  1058. lpIDDS4 = ((INTSTRUC_IDirectDrawSurface4 *)(lpDDS));
  1059. if (lpDDS != NULL)
  1060. hr = m_pDDSurface4->Blt(lpRect1, lpIDDS4->m_pRealInterface, lpRect2,dw, lpfx);
  1061. else
  1062. hr = m_pDDSurface4->Blt(lpRect1, NULL, lpRect2,dw, lpfx);
  1063. break;
  1064. }
  1065. return hr;
  1066. }
  1067. HRESULT CDDSurface::InternalAddAttachedSurface (LPDIRECTDRAWSURFACE lpDDS, DWORD dwSurfaceType)
  1068. {
  1069. HRESULT hr;
  1070. INTSTRUC_IDirectDrawSurface *lpIDDS;
  1071. CDDSurface * pSurface;
  1072. if (lpDDS == NULL)
  1073. return DDERR_INVALIDPARAMS;
  1074. lpIDDS = ((INTSTRUC_IDirectDrawSurface *)(lpDDS));
  1075. pSurface = lpIDDS->m_pSimpleSurface;
  1076. switch (dwSurfaceType)
  1077. {
  1078. case DDSURFACETYPE_1:
  1079. //make the call to the actual DDraw function
  1080. hr = m_pDDSurface->AddAttachedSurface(pSurface->m_DDSInt.m_pRealInterface);
  1081. break;
  1082. case DDSURFACETYPE_2:
  1083. hr = m_pDDSurface2->AddAttachedSurface(pSurface->m_DDS2Int.m_pRealInterface);
  1084. break;
  1085. case DDSURFACETYPE_3:
  1086. hr = m_pDDSurface3->AddAttachedSurface(pSurface->m_DDS3Int.m_pRealInterface);
  1087. break;
  1088. case DDSURFACETYPE_4:
  1089. hr = m_pDDSurface4->AddAttachedSurface(pSurface->m_DDS4Int.m_pRealInterface);
  1090. break;
  1091. }
  1092. //if we succeeded we must do some fix up
  1093. if (!FAILED( hr ) && lpDDS != NULL){
  1094. //ddraw will addref the real interface
  1095. //release that here, and addref our fake interface
  1096. lpIDDS = ((INTSTRUC_IDirectDrawSurface *)(lpDDS));
  1097. lpIDDS->m_pRealInterface->Release();
  1098. ((INTSTRUC_IDirectDrawSurface *)(lpDDS))->m_pSimpleSurface->AddRef();
  1099. //we need to make sure that this surface is in the ddrawex context of this surface,
  1100. //if it is not, then we need to add it to a list
  1101. if (m_pDirectDrawEx != lpIDDS->m_pSimpleSurface->m_pDirectDrawEx)
  1102. {
  1103. //this attached surface is not in the ddrawex object of this one, so add it to the attachlist
  1104. DDAttachSurface * pAttList = new DDAttachSurface;
  1105. if (pAttList == NULL)
  1106. return DDERR_OUTOFMEMORY;
  1107. //add this to the list of attached surfaces
  1108. pAttList->pNext = m_pAttach;
  1109. pAttList->pSurface = lpIDDS->m_pSimpleSurface;
  1110. m_pAttach = pAttList;
  1111. }
  1112. }
  1113. return hr;
  1114. }
  1115. void CDDSurface::DeleteAttachNode(CDDSurface * Surface)
  1116. {
  1117. DDAttachSurface *pDelete;
  1118. DDAttachSurface * pList = m_pAttach;
  1119. //special case first in the list
  1120. //ASSERT this!!
  1121. if (pList != NULL)
  1122. {
  1123. if (pList->pSurface == Surface)
  1124. {
  1125. m_pAttach = m_pAttach->pNext;
  1126. delete pList;
  1127. }
  1128. else
  1129. {
  1130. while (pList->pNext != NULL && (pList->pNext->pSurface != Surface))
  1131. {
  1132. pList = pList->pNext;
  1133. }
  1134. #ifdef DEBUG
  1135. ASSERT(pList->pNext != NULL);
  1136. #endif
  1137. if (pList->pNext != NULL)
  1138. {
  1139. pDelete = pList->pNext;
  1140. pList->pNext = pList->pNext->pNext;
  1141. delete pDelete;
  1142. }
  1143. }
  1144. }
  1145. }
  1146. HRESULT CDDSurface::InternalDeleteAttachedSurface (DWORD dwFlags, LPDIRECTDRAWSURFACE lpDDS, DWORD dwSurfaceType)
  1147. {
  1148. HRESULT hr;
  1149. INTSTRUC_IDirectDrawSurface *lpIDDS;
  1150. CDDSurface * pCallSurface;
  1151. ULONG_PTR * pSaveSurfaces;
  1152. DWORD dwCount;
  1153. pSaveSurfaces = NULL;
  1154. if (lpDDS)
  1155. {
  1156. //just one attachment, addref the surface before it is released if it is not an
  1157. //implicit attached surface
  1158. lpIDDS = ((INTSTRUC_IDirectDrawSurface *)(lpDDS));
  1159. lpIDDS->m_pRealInterface->AddRef();
  1160. }
  1161. else
  1162. {
  1163. LPATTACHLIST lpAttach;
  1164. IDirectDrawSurface * pOrigSurf;
  1165. CDDSurface * pSurfaceOuter;
  1166. //all attached surfaces are going to be released, addref them here
  1167. lpAttach = (LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(m_pDDSurface))->lpLcl->lpAttachList);
  1168. pOrigSurf = m_pDDSurface;
  1169. dwCount = 0;
  1170. while (lpAttach != NULL && (IDirectDrawSurface *)(lpAttach->lpIAttached) != pOrigSurf)
  1171. {
  1172. if (!(lpAttach->dwFlags & DDAL_IMPLICIT))
  1173. {
  1174. //we need to save these surfaces to be released later
  1175. //so count how many we need in here
  1176. dwCount++;
  1177. }
  1178. lpAttach = lpAttach->lpLink;
  1179. }
  1180. //we now need to save an array of surfaces to be Released if we succeed
  1181. pSaveSurfaces = (ULONG_PTR *)LocalAlloc(LPTR, dwCount*sizeof(ULONG_PTR));
  1182. if (pSaveSurfaces == NULL)
  1183. return DDERR_OUTOFMEMORY;
  1184. //now run the list again, call AddRef on the real interface, so that
  1185. //the release called by ddraw will not affect anything
  1186. //and save off the outer interfaces in our allocated array
  1187. lpAttach = (LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(m_pDDSurface))->lpLcl->lpAttachList);
  1188. pOrigSurf = m_pDDSurface;
  1189. dwCount = 0;
  1190. while (lpAttach != NULL && (IDirectDrawSurface *)(lpAttach->lpIAttached) != pOrigSurf)
  1191. {
  1192. if (!(lpAttach->dwFlags & DDAL_IMPLICIT))
  1193. {
  1194. //we must addref the surface pointed to here
  1195. ((IDirectDrawSurface *)(lpAttach->lpIAttached))->AddRef();
  1196. pSurfaceOuter = m_pDirectDrawEx->m_pFirstSurface;
  1197. while (pSurfaceOuter != NULL && pSurfaceOuter->m_DDSInt.m_pRealInterface != (IDirectDrawSurface *)(lpAttach->lpIAttached))
  1198. pSurfaceOuter = pSurfaceOuter->m_pNext;
  1199. if (pSurfaceOuter != NULL)
  1200. pSaveSurfaces[dwCount++]= ((ULONG_PTR)(pSurfaceOuter));
  1201. }
  1202. lpAttach = lpAttach->lpLink;
  1203. }
  1204. //do the same addref for surfaces not in this ddrawex object
  1205. DDAttachSurface * pList = m_pAttach;
  1206. while (pList != NULL)
  1207. {
  1208. pList->pSurface->m_DDSInt.m_pRealInterface->AddRef();
  1209. pList = pList->pNext;
  1210. }
  1211. }
  1212. lpIDDS = ((INTSTRUC_IDirectDrawSurface *)(lpDDS));
  1213. if (lpIDDS != NULL)
  1214. pCallSurface = lpIDDS->m_pSimpleSurface;
  1215. else
  1216. pCallSurface = NULL;
  1217. switch (dwSurfaceType)
  1218. {
  1219. case DDSURFACETYPE_1:
  1220. //make the call to the actual DDraw function
  1221. if (pCallSurface != NULL)
  1222. hr = m_pDDSurface->DeleteAttachedSurface(dwFlags, pCallSurface->m_DDSInt.m_pRealInterface);
  1223. else
  1224. hr = m_pDDSurface->DeleteAttachedSurface(dwFlags, NULL);
  1225. break;
  1226. case DDSURFACETYPE_2:
  1227. if (pCallSurface != NULL)
  1228. hr = m_pDDSurface2->DeleteAttachedSurface(dwFlags, pCallSurface->m_DDS2Int.m_pRealInterface);
  1229. else
  1230. hr = m_pDDSurface2->DeleteAttachedSurface(dwFlags, NULL);
  1231. break;
  1232. case DDSURFACETYPE_3:
  1233. if (pCallSurface != NULL)
  1234. hr = m_pDDSurface3->DeleteAttachedSurface(dwFlags, pCallSurface->m_DDS3Int.m_pRealInterface);
  1235. else
  1236. hr = m_pDDSurface3->DeleteAttachedSurface(dwFlags, NULL);
  1237. break;
  1238. case DDSURFACETYPE_4:
  1239. if (pCallSurface != NULL)
  1240. hr = m_pDDSurface4->DeleteAttachedSurface(dwFlags, pCallSurface->m_DDS4Int.m_pRealInterface);
  1241. else
  1242. hr = m_pDDSurface4->DeleteAttachedSurface(dwFlags, NULL);
  1243. break;
  1244. }
  1245. //if we succeeded we must do some fix up
  1246. if (SUCCEEDED( hr ))
  1247. {
  1248. if (lpDDS)
  1249. {
  1250. //just one attachment, release the outer surface here
  1251. //if this is not in the same ddrawex object, then delete it from the list
  1252. if (m_pDirectDrawEx != lpIDDS->m_pSimpleSurface->m_pDirectDrawEx)
  1253. {
  1254. DeleteAttachNode(lpIDDS->m_pSimpleSurface);
  1255. }
  1256. lpIDDS = ((INTSTRUC_IDirectDrawSurface *)(lpDDS));
  1257. lpIDDS->m_pSimpleSurface->Release();
  1258. }
  1259. else
  1260. {
  1261. CDDSurface * pSurface;
  1262. for ( DWORD i = 0; i < dwCount; i++)
  1263. {
  1264. pSurface = (CDDSurface *)(pSaveSurfaces[i]);
  1265. pSurface->Release();
  1266. }
  1267. //do the same for any surfaces attached, not in this ddrawex object
  1268. DDAttachSurface * pList = m_pAttach;
  1269. while (m_pAttach != NULL)
  1270. {
  1271. pList = m_pAttach;
  1272. m_pAttach = m_pAttach->pNext;
  1273. pList->pSurface->Release();
  1274. delete pList;
  1275. }
  1276. }
  1277. }
  1278. else
  1279. {
  1280. if (lpDDS)
  1281. {
  1282. //just one attachment, addref the surface before it is released if it is not an
  1283. //implicit attached surface
  1284. lpIDDS = ((INTSTRUC_IDirectDrawSurface *)(lpDDS));
  1285. lpIDDS->m_pRealInterface->Release();
  1286. }
  1287. else
  1288. {
  1289. LPATTACHLIST lpAttach;
  1290. IDirectDrawSurface * pOrigSurf;
  1291. //all attached surfaces are going to be released, addref them here
  1292. lpAttach = (LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(m_pDDSurface))->lpLcl->lpAttachList);
  1293. pOrigSurf = m_pDDSurface;
  1294. while (lpAttach != NULL && (IDirectDrawSurface *)(lpAttach->lpIAttached) != pOrigSurf)
  1295. {
  1296. if (!(lpAttach->dwFlags & DDAL_IMPLICIT))
  1297. {
  1298. //we must release the surface pointed to here that we addref'ed above
  1299. ((IDirectDrawSurface *)(lpAttach->lpIAttached))->Release();
  1300. }
  1301. lpAttach = lpAttach->lpLink;
  1302. }
  1303. //do the same for any surfaces attached, not in this ddrawex object
  1304. DDAttachSurface * pList = m_pAttach;
  1305. while (pList != NULL)
  1306. {
  1307. pList->pSurface->m_DDSInt.m_pRealInterface->Release();
  1308. pList = pList->pNext;
  1309. }
  1310. }
  1311. }
  1312. if (pSaveSurfaces != NULL)
  1313. LocalFree(pSaveSurfaces);
  1314. return hr;
  1315. }
  1316. /*
  1317. * CDDSurface::InternalGetAttachedSurface
  1318. *
  1319. * Simple surface GetAttachedSurface implementation
  1320. */
  1321. HRESULT CDDSurface::InternalGetAttachedSurface(LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE FAR * lpDDS, DWORD dwSurfaceType)
  1322. {
  1323. HRESULT hr;
  1324. INTSTRUC_IDirectDrawSurface* lpIDDS;
  1325. DDSCAPS ddsCaps;
  1326. if (lpDDS == NULL)
  1327. return DDERR_INVALIDPARAMS;
  1328. ddsCaps = *lpDDSCaps;
  1329. //mask off owndc
  1330. ddsCaps.dwCaps &= ~DDSCAPS_OWNDC;
  1331. if ((ddsCaps.dwCaps & DDSCAPS_DATAEXCHANGE) == DDSCAPS_DATAEXCHANGE)
  1332. ddsCaps.dwCaps &= ~DDSCAPS_DATAEXCHANGE;
  1333. switch (dwSurfaceType)
  1334. {
  1335. case DDSURFACETYPE_1:
  1336. //make the call to the actual DDraw function
  1337. hr = m_pDDSurface->GetAttachedSurface(&ddsCaps, lpDDS);
  1338. break;
  1339. case DDSURFACETYPE_2:
  1340. hr = m_pDDSurface2->GetAttachedSurface(&ddsCaps, (LPDIRECTDRAWSURFACE2 *)lpDDS);
  1341. break;
  1342. case DDSURFACETYPE_3:
  1343. hr = m_pDDSurface3->GetAttachedSurface(&ddsCaps, (LPDIRECTDRAWSURFACE3 *)lpDDS);
  1344. break;
  1345. // Case 4 taken care of below...
  1346. } //make the call to the actual DDraw function
  1347. //if we succeeded we must do some fix up
  1348. CDDSurface * lpSurfaceList;
  1349. if (!FAILED( hr ) && lpDDS != NULL)
  1350. {
  1351. //we need to scan our list to pass back our interface
  1352. lpSurfaceList = m_pDirectDrawEx->m_pFirstSurface;
  1353. switch (dwSurfaceType)
  1354. {
  1355. case DDSURFACETYPE_1:
  1356. while (lpSurfaceList != NULL && lpSurfaceList->m_DDSInt.m_pRealInterface != *lpDDS)
  1357. lpSurfaceList = lpSurfaceList->m_pNext;
  1358. if (lpSurfaceList == NULL)
  1359. {
  1360. //check our AttachList
  1361. DDAttachSurface * pList = m_pAttach;
  1362. while (pList != NULL && pList->pSurface->m_DDSInt.m_pRealInterface != *lpDDS)
  1363. {
  1364. pList = pList->pNext;
  1365. }
  1366. if (pList != NULL)
  1367. lpSurfaceList = pList->pSurface;
  1368. }
  1369. if (lpSurfaceList != NULL)
  1370. *lpDDS = (IDirectDrawSurface *)(&lpSurfaceList->m_DDSInt);
  1371. break;
  1372. case DDSURFACETYPE_2:
  1373. while (lpSurfaceList != NULL && lpSurfaceList->m_DDS2Int.m_pRealInterface != (LPDIRECTDRAWSURFACE2)*lpDDS)
  1374. lpSurfaceList = lpSurfaceList->m_pNext;
  1375. if (lpSurfaceList == NULL)
  1376. {
  1377. //check our AttachList
  1378. DDAttachSurface * pList = m_pAttach;
  1379. while (pList != NULL && pList->pSurface->m_DDS2Int.m_pRealInterface != (LPDIRECTDRAWSURFACE2)*lpDDS)
  1380. {
  1381. pList = pList->pNext;
  1382. }
  1383. if (pList != NULL)
  1384. lpSurfaceList = pList->pSurface;
  1385. }
  1386. if (lpSurfaceList != NULL)
  1387. *lpDDS = (IDirectDrawSurface *)(&lpSurfaceList->m_DDS2Int);
  1388. break;
  1389. case DDSURFACETYPE_3:
  1390. while (lpSurfaceList != NULL && lpSurfaceList->m_DDS3Int.m_pRealInterface != (LPDIRECTDRAWSURFACE3)*lpDDS)
  1391. lpSurfaceList = lpSurfaceList->m_pNext;
  1392. if (lpSurfaceList == NULL)
  1393. {
  1394. //check our AttachList
  1395. DDAttachSurface * pList = m_pAttach;
  1396. while (pList != NULL && pList->pSurface->m_DDS3Int.m_pRealInterface != (LPDIRECTDRAWSURFACE3)*lpDDS)
  1397. {
  1398. pList = pList->pNext;
  1399. }
  1400. if (pList != NULL)
  1401. lpSurfaceList = pList->pSurface;
  1402. }
  1403. if (lpSurfaceList != NULL)
  1404. *lpDDS = (IDirectDrawSurface *)(&lpSurfaceList->m_DDS3Int);
  1405. break;
  1406. // Case 4 taken care of below...
  1407. }
  1408. //ddraw will addref the obtained surface's real interface
  1409. //release that here and addref our fake interface
  1410. if (lpSurfaceList != NULL)
  1411. {
  1412. lpIDDS = ((INTSTRUC_IDirectDrawSurface *)(*lpDDS));
  1413. lpIDDS->m_pRealInterface->Release();
  1414. ((INTSTRUC_IDirectDrawSurface *)(*lpDDS))->m_pSimpleSurface->AddRef();
  1415. }
  1416. }
  1417. return hr;
  1418. }
  1419. HRESULT CDDSurface::InternalGetAttachedSurface4(LPDDSCAPS2 lpDDSCaps2, LPDIRECTDRAWSURFACE FAR * lpDDS)
  1420. {
  1421. HRESULT hr;
  1422. INTSTRUC_IDirectDrawSurface* lpIDDS;
  1423. DDSCAPS2 ddsCaps2;
  1424. if (lpDDS == NULL)
  1425. return DDERR_INVALIDPARAMS;
  1426. ddsCaps2 = *lpDDSCaps2;
  1427. //mask off owndc
  1428. ddsCaps2.dwCaps &= ~DDSCAPS_OWNDC;
  1429. if ((ddsCaps2.dwCaps & DDSCAPS_DATAEXCHANGE) == DDSCAPS_DATAEXCHANGE)
  1430. ddsCaps2.dwCaps &= ~DDSCAPS_DATAEXCHANGE;
  1431. hr = m_pDDSurface4->GetAttachedSurface(&ddsCaps2, (LPDIRECTDRAWSURFACE4 *)lpDDS);
  1432. //if we succeeded we must do some fix up
  1433. CDDSurface * lpSurfaceList;
  1434. if (!FAILED( hr ) && lpDDS != NULL)
  1435. {
  1436. //we need to scan our list to pass back our interface
  1437. lpSurfaceList = m_pDirectDrawEx->m_pFirstSurface;
  1438. while (lpSurfaceList != NULL && lpSurfaceList->m_DDS4Int.m_pRealInterface != (LPDIRECTDRAWSURFACE4)*lpDDS)
  1439. lpSurfaceList = lpSurfaceList->m_pNext;
  1440. if (lpSurfaceList == NULL)
  1441. {
  1442. //check our AttachList
  1443. DDAttachSurface * pList = m_pAttach;
  1444. while (pList != NULL && pList->pSurface->m_DDS4Int.m_pRealInterface != (LPDIRECTDRAWSURFACE4)*lpDDS)
  1445. {
  1446. pList = pList->pNext;
  1447. }
  1448. if (pList != NULL)
  1449. lpSurfaceList = pList->pSurface;
  1450. }
  1451. //ddraw will addref the obtained surface's real interface
  1452. //release that here and addref our fake interface
  1453. if (lpSurfaceList != NULL)
  1454. {
  1455. *lpDDS = (IDirectDrawSurface *)(&lpSurfaceList->m_DDS4Int);
  1456. lpIDDS = ((INTSTRUC_IDirectDrawSurface *)(*lpDDS));
  1457. lpIDDS->m_pRealInterface->Release();
  1458. ((INTSTRUC_IDirectDrawSurface *)(*lpDDS))->m_pSimpleSurface->AddRef();
  1459. }
  1460. }
  1461. return hr;
  1462. }
  1463. HRESULT CDDSurface::InternalGetPalette(LPDIRECTDRAWPALETTE FAR * ppPal, DWORD dwSurfaceType)
  1464. {
  1465. HRESULT hr;
  1466. if (ppPal == NULL)
  1467. return DDERR_INVALIDPARAMS;
  1468. switch (dwSurfaceType)
  1469. {
  1470. case DDSURFACETYPE_1:
  1471. //make the call to the actual DDraw function
  1472. hr = m_pDDSurface->GetPalette(ppPal);
  1473. break;
  1474. case DDSURFACETYPE_2:
  1475. hr = m_pDDSurface2->GetPalette(ppPal);
  1476. break;
  1477. case DDSURFACETYPE_3:
  1478. hr = m_pDDSurface3->GetPalette(ppPal);
  1479. break;
  1480. case DDSURFACETYPE_4:
  1481. hr = m_pDDSurface4->GetPalette(ppPal);
  1482. break;
  1483. }
  1484. //if this succeeded, we need to return OUR interface to the palette, so scan our
  1485. //list and return the correct palette.
  1486. if (SUCCEEDED(hr))
  1487. {
  1488. INTSTRUC_IDirectDrawPalette* pIDDP;
  1489. //we need to scan our list to pass back our interface
  1490. CDDPalette * lpPaletteList;
  1491. lpPaletteList = m_pDirectDrawEx->m_pFirstPalette;
  1492. while (lpPaletteList != NULL && lpPaletteList->m_DDPInt.m_pRealInterface != *ppPal)
  1493. lpPaletteList = lpPaletteList->m_pNext;
  1494. if (lpPaletteList == NULL)
  1495. {
  1496. //this is a palette possibly, that is not in the same ddraw object as the surface
  1497. // handle that here
  1498. // TODO in the future, this code should be the default!
  1499. //the returned palette should equal the real interface of the m_pCurrentPalette
  1500. #ifdef DEBUG
  1501. ASSERT(m_pCurrentPalette != NULL);
  1502. ASSERT(m_pCurrentPalette->m_DDPInt.m_pRealInterface == *ppPal);
  1503. #endif
  1504. lpPaletteList = m_pCurrentPalette;
  1505. }
  1506. if (lpPaletteList != NULL)
  1507. {
  1508. *ppPal = (IDirectDrawPalette *)(&lpPaletteList->m_DDPInt);
  1509. pIDDP = ((INTSTRUC_IDirectDrawPalette *)(*ppPal));
  1510. pIDDP->m_pRealInterface->Release();
  1511. pIDDP->m_pSimplePalette->AddRef();
  1512. }
  1513. }
  1514. return hr;
  1515. }
  1516. HRESULT CDDSurface::InternalGetSurfaceDesc(LPDDSURFACEDESC pDesc, DWORD dwSurfaceType)
  1517. {
  1518. HRESULT hr;
  1519. switch (dwSurfaceType)
  1520. {
  1521. case DDSURFACETYPE_1:
  1522. hr = m_pDDSurface->GetSurfaceDesc(pDesc);
  1523. break;
  1524. case DDSURFACETYPE_2:
  1525. hr = m_pDDSurface2->GetSurfaceDesc(pDesc);
  1526. break;
  1527. case DDSURFACETYPE_3:
  1528. hr = m_pDDSurface3->GetSurfaceDesc(pDesc);
  1529. break;
  1530. // Case 4 handled below...
  1531. }
  1532. if (FAILED(hr))
  1533. return hr;
  1534. //if m_bOwnDC is set, we need to set this in the caps field
  1535. if (m_dwCaps & DDSCAPS_OWNDC)
  1536. //set the caps bit here
  1537. pDesc->ddsCaps.dwCaps |= DDSCAPS_OWNDC;
  1538. //see if data exchange was origianlly on
  1539. if ((m_dwCaps & DDSCAPS_DATAEXCHANGE) == DDSCAPS_DATAEXCHANGE )
  1540. {
  1541. pDesc->ddsCaps.dwCaps |= DDSCAPS_DATAEXCHANGE;
  1542. //see if OWNDC was really on
  1543. if (!(m_dwCaps & DDSCAPS_OWNDC))
  1544. //turn it off here
  1545. pDesc->ddsCaps.dwCaps &= ~DDSCAPS_OWNDC;
  1546. //see if offscreen plain was originally on
  1547. if (m_dwCaps & DDSCAPS_OFFSCREENPLAIN)
  1548. pDesc->ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
  1549. //we might have turned on texture, turn it off if so
  1550. if (!(m_dwCaps & DDSCAPS_TEXTURE))
  1551. pDesc->ddsCaps.dwCaps &= ~DDSCAPS_TEXTURE;
  1552. }
  1553. return hr;
  1554. }
  1555. HRESULT CDDSurface::InternalGetSurfaceDesc4(LPDDSURFACEDESC2 pDesc2)
  1556. {
  1557. HRESULT hr;
  1558. hr = m_pDDSurface4->GetSurfaceDesc(pDesc2);
  1559. if (FAILED(hr))
  1560. return hr;
  1561. //if m_bOwnDC is set, we need to set this in the caps field
  1562. if (m_dwCaps & DDSCAPS_OWNDC)
  1563. //set the caps bit here
  1564. pDesc2->ddsCaps.dwCaps |= DDSCAPS_OWNDC;
  1565. //see if data exchange was origianlly on
  1566. if ((m_dwCaps & DDSCAPS_DATAEXCHANGE) == DDSCAPS_DATAEXCHANGE )
  1567. {
  1568. pDesc2->ddsCaps.dwCaps |= DDSCAPS_DATAEXCHANGE;
  1569. //see if OWNDC was really on
  1570. if (!(m_dwCaps & DDSCAPS_OWNDC))
  1571. //turn it off here
  1572. pDesc2->ddsCaps.dwCaps &= ~DDSCAPS_OWNDC;
  1573. //see if offscreen plain was originally on
  1574. if (m_dwCaps & DDSCAPS_OFFSCREENPLAIN)
  1575. pDesc2->ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
  1576. //we might have turned on texture, turn it off if so
  1577. if (!(m_dwCaps & DDSCAPS_TEXTURE))
  1578. pDesc2->ddsCaps.dwCaps &= ~DDSCAPS_TEXTURE;
  1579. }
  1580. return hr;
  1581. }
  1582. HRESULT CDDSurface::InternalSetPalette(LPDIRECTDRAWPALETTE pPal, DWORD dwSurfaceType)
  1583. {
  1584. HRESULT hr;
  1585. INTSTRUC_IDirectDrawPalette* pIDDP;
  1586. pIDDP = ((INTSTRUC_IDirectDrawPalette *)(pPal));
  1587. //a bit of ugliness herein regards to reference counting. If this palette is
  1588. //different from the current palette, then it will release the current palette.
  1589. //we must protect for that before we call setpalette
  1590. if (m_pCurrentPalette && (pPal == NULL || m_pCurrentPalette != pIDDP->m_pSimplePalette))
  1591. {
  1592. m_pCurrentPalette->m_DDPInt.m_pRealInterface->AddRef();
  1593. }
  1594. switch (dwSurfaceType)
  1595. {
  1596. case DDSURFACETYPE_1:
  1597. //make the call to the actual DDraw function
  1598. if (pPal != NULL)
  1599. hr = m_pDDSurface->SetPalette(pIDDP->m_pRealInterface);
  1600. else
  1601. hr = m_pDDSurface->SetPalette(NULL);
  1602. break;
  1603. case DDSURFACETYPE_2:
  1604. if (pPal != NULL)
  1605. hr = m_pDDSurface2->SetPalette(pIDDP->m_pRealInterface);
  1606. else
  1607. hr = m_pDDSurface2->SetPalette(NULL);
  1608. break;
  1609. case DDSURFACETYPE_3:
  1610. if (pPal != NULL)
  1611. hr = m_pDDSurface3->SetPalette(pIDDP->m_pRealInterface);
  1612. else
  1613. hr = m_pDDSurface3->SetPalette(NULL);
  1614. break;
  1615. case DDSURFACETYPE_4:
  1616. if (pPal != NULL)
  1617. hr = m_pDDSurface4->SetPalette(pIDDP->m_pRealInterface);
  1618. else
  1619. hr = m_pDDSurface4->SetPalette(NULL);
  1620. break;
  1621. }
  1622. if (SUCCEEDED(hr))
  1623. {
  1624. //we must take care of reference counting here
  1625. //if there was an old palette not equal to the current, then do a release on the old palette
  1626. if (m_pCurrentPalette && (pPal == NULL || m_pCurrentPalette != pIDDP->m_pSimplePalette))
  1627. {
  1628. //release the old palette
  1629. m_pCurrentPalette->Release();
  1630. //if this release caused the palette to be destroyed, the palette destructor function
  1631. //will change m_pCurrentPalette to NULL. No worries below.
  1632. }
  1633. //if the new palette is NULL, we can return here
  1634. if (pPal == NULL)
  1635. {
  1636. if (m_pCurrentPalette)
  1637. {
  1638. m_pCurrentPalette->RemoveSurfaceFromList(this);
  1639. m_pCurrentPalette = NULL;
  1640. }
  1641. return hr;
  1642. }
  1643. //if the new palette is not equal to the old palette, then an addref was done on the
  1644. //real interface, as above
  1645. if (m_pCurrentPalette != pIDDP->m_pSimplePalette)
  1646. {
  1647. pIDDP->m_pRealInterface->Release();
  1648. pIDDP->m_pSimplePalette->AddRef();
  1649. }
  1650. DWORD dwNumEntries;
  1651. DWORD dwCaps;
  1652. PALETTEENTRY pe[256];
  1653. hr = pIDDP->m_pRealInterface->GetCaps(&dwCaps);
  1654. if (FAILED(hr))
  1655. return hr;
  1656. if (dwCaps & DDPCAPS_1BIT)
  1657. dwNumEntries = 1;
  1658. else if (dwCaps & DDPCAPS_2BIT)
  1659. dwNumEntries = 4;
  1660. else if (dwCaps & DDPCAPS_4BIT)
  1661. dwNumEntries = 16;
  1662. else if (dwCaps & DDPCAPS_8BIT)
  1663. dwNumEntries = 256;
  1664. else
  1665. dwNumEntries = 0;
  1666. hr = pIDDP->m_pRealInterface->GetEntries( 0, 0, dwNumEntries, pe);
  1667. if (FAILED(hr))
  1668. return hr;
  1669. if (m_bIsPrimary)
  1670. {
  1671. CDDSurface *pSurface = m_pDirectDrawEx->m_pPrimaryPaletteList;
  1672. while (pSurface != NULL)
  1673. {
  1674. //update the DIB COlor Table here
  1675. pIDDP->m_pSimplePalette->SetColorTable(pSurface, pe, dwNumEntries, 0);
  1676. pSurface = pSurface->m_pNextPalette;
  1677. }
  1678. //and mark this palette as being the primary
  1679. pIDDP->m_pSimplePalette->m_bIsPrimary = TRUE;
  1680. m_pCurrentPalette = pIDDP->m_pSimplePalette;
  1681. }
  1682. else
  1683. {
  1684. //if this surface already has a palette attached to it, then we need to remove it
  1685. if (m_pCurrentPalette && m_pCurrentPalette != pIDDP->m_pSimplePalette)
  1686. m_pCurrentPalette->RemoveSurfaceFromList(this);
  1687. else if (m_bPrimaryPalette)
  1688. //this surface will be in the list of surfaces which feed of the primary surface
  1689. //remove it from that list
  1690. m_pDirectDrawEx->RemoveSurfaceFromPrimaryList(this);
  1691. //now add this surface to the palette list if already is not in the list
  1692. if (m_pCurrentPalette != pIDDP->m_pSimplePalette)
  1693. pIDDP->m_pSimplePalette->AddSurfaceToList(this);
  1694. //and update this surface's DIB ColorTable
  1695. pIDDP->m_pSimplePalette->SetColorTable(this, pe, dwNumEntries, 0);
  1696. pIDDP->m_pSimplePalette->m_bIsPrimary = FALSE;
  1697. m_pCurrentPalette = pIDDP->m_pSimplePalette;
  1698. }
  1699. }
  1700. return hr;
  1701. }
  1702. #pragma message( REMIND( "What Lock of a rect bug in DirectDraw v3 is Ralph referring to?" ))
  1703. /*
  1704. * CDDSurface::InternalLock
  1705. *
  1706. * Simple surface Lock implementation
  1707. */
  1708. HRESULT CDDSurface::InternalLock(LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent)
  1709. {
  1710. return m_pDDSurface->Lock(lpDestRect, lpDDSurfaceDesc, dwFlags, hEvent);
  1711. } /* CDDSurface::InternalLock */
  1712. /*
  1713. * CDDSurface::InternalUnlock
  1714. *
  1715. * Simple surface Unlock implementation
  1716. */
  1717. HRESULT CDDSurface::InternalUnlock(LPVOID lpSurfaceData)
  1718. {
  1719. return m_pDDSurface->Unlock(lpSurfaceData);
  1720. } /* CDDSurface::InternalUnlock */
  1721. #define DEFINEPF(flags, fourcc, bpp, rMask, gMask, bMask, aMask) \
  1722. { sizeof(DDPIXELFORMAT), (flags), (fourcc), (bpp), (rMask), (gMask), (bMask), (aMask) }
  1723. static DDPIXELFORMAT ddpfSupportedTexPFs[] =
  1724. {
  1725. /* Type FOURCC BPP Red Mask Green Mask Blue Mask Alpha Mask */
  1726. DEFINEPF(DDPF_RGB | DDPF_PALETTEINDEXED1, 0UL, 1UL, 0x00000000UL, 0x00000000Ul, 0x00000000UL, 0x00000000UL), /* Pal. */
  1727. DEFINEPF(DDPF_RGB | DDPF_PALETTEINDEXED1 |
  1728. DDPF_PALETTEINDEXEDTO8, 0UL, 1UL, 0x00000000UL, 0x00000000Ul, 0x00000000UL, 0x00000000UL), /* Pal. */
  1729. DEFINEPF(DDPF_RGB | DDPF_PALETTEINDEXED2, 0UL, 2UL, 0x00000000UL, 0x00000000Ul, 0x00000000UL, 0x00000000UL), /* Pal. */
  1730. DEFINEPF(DDPF_RGB | DDPF_PALETTEINDEXED2 |
  1731. DDPF_PALETTEINDEXEDTO8, 0UL, 2UL, 0x00000000UL, 0x00000000Ul, 0x00000000UL, 0x00000000UL), /* Pal. */
  1732. DEFINEPF(DDPF_RGB | DDPF_PALETTEINDEXED4, 0UL, 4UL, 0x00000000UL, 0x00000000Ul, 0x00000000UL, 0x00000000UL), /* Pal. */
  1733. DEFINEPF(DDPF_RGB | DDPF_PALETTEINDEXED4 |
  1734. DDPF_PALETTEINDEXEDTO8, 0UL, 4UL, 0x00000000UL, 0x00000000Ul, 0x00000000UL, 0x00000000UL), /* Pal. */
  1735. DEFINEPF(DDPF_RGB | DDPF_PALETTEINDEXED8, 0UL, 8UL, 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL), /* Pal. */
  1736. DEFINEPF(DDPF_RGB, 0UL, 8UL, 0x000000E0UL, 0x0000001CUL, 0x00000003UL, 0x00000000UL), /* 332 (RGB) */
  1737. DEFINEPF(DDPF_RGB | DDPF_ALPHAPIXELS, 0UL, 16UL, 0x00000F00UL, 0x000000F0UL, 0x0000000FUL, 0x0000F000UL), /* 4444 (RGB) */
  1738. DEFINEPF(DDPF_RGB, 0UL, 16UL, 0x0000F800UL, 0x000007E0UL, 0x0000001FUL, 0x00000000UL), /* 565 (RGB) */
  1739. DEFINEPF(DDPF_RGB, 0UL, 16UL, 0x0000001FUL, 0x000007E0UL, 0x0000F800UL, 0x00000000UL), /* 565 (BGR) */
  1740. DEFINEPF(DDPF_RGB, 0UL, 16UL, 0x00007C00UL, 0x000003E0UL, 0x0000001FUL, 0x00000000UL), /* 555 (RGB) */
  1741. DEFINEPF(DDPF_RGB | DDPF_ALPHAPIXELS, 0UL, 16UL, 0x00007C00UL, 0x000003E0UL, 0x0000001FUL, 0x00008000UL), /* 1555 (RGB) */
  1742. DEFINEPF(DDPF_RGB, 0UL, 24UL, 0x00FF0000UL, 0x0000FF00UL, 0x000000FFUL, 0x00000000UL), /* FFF (RGB) */
  1743. DEFINEPF(DDPF_RGB, 0UL, 24UL, 0x000000FFUL, 0x0000FF00UL, 0x00FF0000UL, 0x00000000UL), /* FFF (BGR) */
  1744. DEFINEPF(DDPF_RGB, 0UL, 32UL, 0x00FF0000UL, 0x0000FF00UL, 0x000000FFUL, 0x00000000UL), /* 0FFF (RGB) */
  1745. DEFINEPF(DDPF_RGB, 0UL, 32UL, 0x000000FFUL, 0x0000FF00UL, 0x00FF0000UL, 0x00000000UL), /* 0FFF (BGR) */
  1746. DEFINEPF(DDPF_RGB | DDPF_ALPHAPIXELS, 0UL, 32UL, 0x00FF0000UL, 0x0000FF00UL, 0x000000FFUL, 0xFF000000UL), /* FFFF (RGB) */
  1747. DEFINEPF(DDPF_RGB | DDPF_ALPHAPIXELS, 0UL, 32UL, 0x000000FFUL, 0x0000FF00UL, 0x00FF0000UL, 0xFF000000UL) /* FFFF (BGR) */
  1748. };
  1749. #define NUM_SUPPORTED_TEX_PFS (sizeof(ddpfSupportedTexPFs) / sizeof(ddpfSupportedTexPFs[0]))
  1750. static DDPIXELFORMAT ddpfSupportedOffScrnPFs[] =
  1751. {
  1752. /* Type FOURCC BPP Red Mask Green Mask Blue Mask Alpha Mask */
  1753. DEFINEPF(DDPF_RGB | DDPF_PALETTEINDEXED1, 0UL, 1UL, 0x00000000UL, 0x00000000Ul, 0x00000000UL, 0x00000000UL), /* Pal. */
  1754. DEFINEPF(DDPF_RGB | DDPF_PALETTEINDEXED2, 0UL, 2UL, 0x00000000UL, 0x00000000Ul, 0x00000000UL, 0x00000000UL), /* Pal. */
  1755. DEFINEPF(DDPF_RGB | DDPF_PALETTEINDEXED4, 0UL, 4UL, 0x00000000UL, 0x00000000Ul, 0x00000000UL, 0x00000000UL), /* Pal. */
  1756. DEFINEPF(DDPF_RGB | DDPF_PALETTEINDEXED8, 0UL, 8UL, 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL), /* Pal. */
  1757. DEFINEPF(DDPF_RGB, 0UL, 16UL, 0x0000F800UL, 0x000007E0UL, 0x0000001FUL, 0x00000000UL), /* 565 (RGB) */
  1758. DEFINEPF(DDPF_RGB, 0UL, 16UL, 0x00007C00UL, 0x000003E0UL, 0x0000001FUL, 0x00000000UL), /* 555 (RGB) */
  1759. DEFINEPF(DDPF_RGB, 0UL, 24UL, 0x00FF0000UL, 0x0000FF00UL, 0x000000FFUL, 0x00000000UL), /* FFF (RGB) */
  1760. DEFINEPF(DDPF_RGB, 0UL, 24UL, 0x000000FFUL, 0x0000FF00UL, 0x00FF0000UL, 0x00000000UL), /* FFF (BGR) */
  1761. DEFINEPF(DDPF_RGB, 0UL, 32UL, 0x00FF0000UL, 0x0000FF00UL, 0x000000FFUL, 0x00000000UL), /* 0FFF (RGB) */
  1762. DEFINEPF(DDPF_RGB, 0UL, 32UL, 0x000000FFUL, 0x0000FF00UL, 0x00FF0000UL, 0x00000000UL), /* 0FFF (BGR) */
  1763. };
  1764. #define NUM_SUPPORTED_OFFSCRN_PFS (sizeof(ddpfSupportedOffScrnPFs) / sizeof(ddpfSupportedOffScrnPFs[0]))
  1765. /*
  1766. * doPixelFormatsMatch
  1767. */
  1768. BOOL doPixelFormatsMatch(LPDDPIXELFORMAT lpddpf1, LPDDPIXELFORMAT lpddpf2)
  1769. {
  1770. if( lpddpf1->dwFlags != lpddpf2->dwFlags )
  1771. {
  1772. return FALSE;
  1773. }
  1774. if( lpddpf1->dwFlags & DDPF_RGB )
  1775. {
  1776. if( lpddpf1->dwRGBBitCount != lpddpf2->dwRGBBitCount )
  1777. {
  1778. return FALSE;
  1779. }
  1780. if( lpddpf1->dwRBitMask != lpddpf2->dwRBitMask )
  1781. {
  1782. return FALSE;
  1783. }
  1784. if( lpddpf1->dwGBitMask != lpddpf2->dwGBitMask )
  1785. {
  1786. return FALSE;
  1787. }
  1788. if( lpddpf1->dwBBitMask != lpddpf2->dwBBitMask )
  1789. {
  1790. return FALSE;
  1791. }
  1792. if( lpddpf1->dwFlags & DDPF_ALPHAPIXELS )
  1793. {
  1794. if( lpddpf1->dwRGBAlphaBitMask != lpddpf2->dwRGBAlphaBitMask )
  1795. {
  1796. return FALSE;
  1797. }
  1798. }
  1799. }
  1800. else if( lpddpf1->dwFlags & DDPF_YUV )
  1801. {
  1802. /*
  1803. * (CMcC) Yes, I know that all these fields are in a
  1804. * union with the RGB ones so I could just use the same
  1805. * bit of checking code but just in case someone messes
  1806. * with DDPIXELFORMAT I'm going to do this explicitly.
  1807. */
  1808. if( lpddpf1->dwFourCC != lpddpf2->dwFourCC )
  1809. {
  1810. return FALSE;
  1811. }
  1812. if( lpddpf1->dwYUVBitCount != lpddpf2->dwYUVBitCount )
  1813. {
  1814. return FALSE;
  1815. }
  1816. if( lpddpf1->dwYBitMask != lpddpf2->dwYBitMask )
  1817. {
  1818. return FALSE;
  1819. }
  1820. if( lpddpf1->dwUBitMask != lpddpf2->dwUBitMask )
  1821. {
  1822. return FALSE;
  1823. }
  1824. if( lpddpf1->dwVBitMask != lpddpf2->dwVBitMask )
  1825. {
  1826. return FALSE;
  1827. }
  1828. if( lpddpf1->dwFlags & DDPF_ALPHAPIXELS )
  1829. {
  1830. if( lpddpf1->dwYUVAlphaBitMask != lpddpf2->dwYUVAlphaBitMask )
  1831. {
  1832. return FALSE;
  1833. }
  1834. }
  1835. }
  1836. return TRUE;
  1837. } /* doPixelFormatsMatch */
  1838. /*
  1839. * isSupportedPixelFormat
  1840. */
  1841. BOOL isSupportedPixelFormat(LPDDPIXELFORMAT lpddpf,
  1842. LPDDPIXELFORMAT lpddpfTable,
  1843. int cNumEntries)
  1844. {
  1845. int n;
  1846. LPDDPIXELFORMAT lpddCandidatePF;
  1847. n = cNumEntries;
  1848. lpddCandidatePF = lpddpfTable;
  1849. while( n > 0 )
  1850. {
  1851. if( doPixelFormatsMatch(lpddpf, lpddCandidatePF) )
  1852. {
  1853. return TRUE;
  1854. }
  1855. lpddCandidatePF++;
  1856. n--;
  1857. }
  1858. return FALSE;
  1859. } /* isSupportedPixelFormat */
  1860. /*
  1861. * checkPixelFormat
  1862. * bitdepth != screen bitdepth
  1863. */
  1864. HRESULT checkPixelFormat( DWORD dwscaps, LPDDPIXELFORMAT lpDDPixelFormat )
  1865. {
  1866. if( dwscaps & DDSCAPS_TEXTURE )
  1867. {
  1868. if( !isSupportedPixelFormat(lpDDPixelFormat, ddpfSupportedTexPFs, NUM_SUPPORTED_TEX_PFS) )
  1869. {
  1870. return DDERR_INVALIDPIXELFORMAT;
  1871. }
  1872. }
  1873. else if( dwscaps & DDSCAPS_OFFSCREENPLAIN )
  1874. {
  1875. if( !isSupportedPixelFormat(lpDDPixelFormat, ddpfSupportedOffScrnPFs, NUM_SUPPORTED_OFFSCRN_PFS) )
  1876. {
  1877. return DDERR_INVALIDPIXELFORMAT;
  1878. }
  1879. }
  1880. return DD_OK;
  1881. } /* checkPixelFormat */
  1882. /*
  1883. * CDDSurface::InternalSetSurfaceDesc
  1884. *
  1885. * Simple surface change the bits
  1886. */
  1887. HRESULT CDDSurface::InternalSetSurfaceDesc(
  1888. LPDDSURFACEDESC pddsd,
  1889. DWORD dwFlags)
  1890. {
  1891. LPDDRAWI_DDRAWSURFACE_INT psurf_int;
  1892. LPDDRAWI_DDRAWSURFACE_LCL psurf_lcl;
  1893. LPDDRAWI_DDRAWSURFACE_GBL psurf_gbl;
  1894. DWORD sdflags;
  1895. if( dwFlags )
  1896. {
  1897. return DDERR_INVALIDPARAMS;
  1898. }
  1899. //do not work on DDraw2 on WindowsNT4.0Gold
  1900. if (m_pDirectDrawEx->m_dwDDVer == WINNT_DX2)
  1901. {
  1902. return DDERR_UNSUPPORTED;
  1903. }
  1904. psurf_int = (LPDDRAWI_DDRAWSURFACE_INT) m_pDDSurface;
  1905. psurf_lcl = psurf_int->lpLcl;
  1906. psurf_gbl = psurf_lcl->lpGbl;
  1907. sdflags = pddsd->dwFlags;
  1908. /*
  1909. * don't allow anything but bits, height, width, pitch, and pixel format
  1910. * to change
  1911. */
  1912. if( !(sdflags & (DDSD_LPSURFACE | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_PITCH )) )
  1913. {
  1914. return DDERR_INVALIDPARAMS;
  1915. }
  1916. /*
  1917. * don't work if it wasn't put in sysmem in the first place...
  1918. */
  1919. if( !(psurf_gbl->dwGlobalFlags & DDRAWISURFGBL_SYSMEMREQUESTED ) )
  1920. {
  1921. return DDERR_UNSUPPORTED;
  1922. }
  1923. /*
  1924. * gotta have a pixel format to work...
  1925. */
  1926. if( !(psurf_lcl->dwFlags & DDRAWISURF_HASPIXELFORMAT) &&
  1927. (sdflags & DDSD_PIXELFORMAT) )
  1928. {
  1929. return DDERR_INVALIDSURFACETYPE;
  1930. }
  1931. /*
  1932. * verify the new pixel format...
  1933. */
  1934. if( sdflags & DDSD_PIXELFORMAT )
  1935. {
  1936. DWORD dwscaps;
  1937. HRESULT hr;
  1938. /*
  1939. * only allow changes for textures and offscreen plain...
  1940. */
  1941. dwscaps = psurf_lcl->ddsCaps.dwCaps;
  1942. if( !(dwscaps & (DDSCAPS_TEXTURE|DDSCAPS_OFFSCREENPLAIN)) )
  1943. {
  1944. return DDERR_INVALIDSURFACETYPE;
  1945. }
  1946. hr = checkPixelFormat( dwscaps, &pddsd->ddpfPixelFormat );
  1947. if( FAILED( hr ) )
  1948. {
  1949. return hr;
  1950. }
  1951. }
  1952. /*
  1953. * replace bits ptr...
  1954. */
  1955. if( sdflags & DDSD_LPSURFACE )
  1956. {
  1957. /*
  1958. * mark the surface memory as freed, and replace the memory with
  1959. * new user specified memory
  1960. */
  1961. if( !(psurf_gbl->dwGlobalFlags & DDRAWISURFGBL_MEMFREE ) )
  1962. {
  1963. DWORD dwOffset;
  1964. LPVOID lpMem;
  1965. lpMem= (LPVOID) psurf_int->lpLcl->lpGbl->fpVidMem;
  1966. //probably don't need this check, but it can't hurt
  1967. if( NULL != lpMem )
  1968. {
  1969. if (m_pDirectDrawEx->m_dwDDVer != WINNT_DX3)
  1970. {
  1971. //check to see if this surface has been aligned and reset the pointer if so
  1972. if(psurf_int->lpLcl->ddsCaps.dwCaps & DDSCAPS_ZBUFFER ||
  1973. psurf_int->lpLcl->ddsCaps.dwCaps & DDSCAPS_TEXTURE ||
  1974. psurf_int->lpLcl->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN)
  1975. {
  1976. dwOffset = *( (LPDWORD) ( ( (LPBYTE)lpMem ) - sizeof(DWORD) ) );
  1977. lpMem = (LPVOID) ( ( (LPBYTE) lpMem) - dwOffset );
  1978. }
  1979. //free the memory
  1980. LocalFree(lpMem);
  1981. }
  1982. else
  1983. {
  1984. //store this value off so we can use it when we destroy the surface
  1985. m_pSaveBits = (ULONG_PTR)lpMem;
  1986. m_pSaveHDC = psurf_int->lpLcl->hDC;
  1987. m_pSaveHBM = psurf_int->lpLcl->dwReserved1;
  1988. }
  1989. }
  1990. psurf_gbl->dwGlobalFlags |= DDRAWISURFGBL_MEMFREE;
  1991. }
  1992. psurf_gbl->fpVidMem = (ULONG_PTR) pddsd->lpSurface;
  1993. }
  1994. /*
  1995. * replace other things
  1996. */
  1997. if( sdflags & DDSD_PITCH )
  1998. {
  1999. psurf_gbl->lPitch = pddsd->lPitch;
  2000. }
  2001. if( sdflags & DDSD_WIDTH )
  2002. {
  2003. psurf_gbl->wWidth = (WORD) pddsd->dwWidth;
  2004. }
  2005. if( sdflags & DDSD_HEIGHT )
  2006. {
  2007. psurf_gbl->wHeight = (WORD) pddsd->dwHeight;
  2008. }
  2009. if( sdflags & DDSD_PIXELFORMAT )
  2010. {
  2011. psurf_gbl->ddpfSurface = pddsd->ddpfPixelFormat;
  2012. }
  2013. return DD_OK;
  2014. } /* CDDSurface::InternalSetBites */
  2015. HRESULT CDDSurface::InternalGetDDInterface(LPVOID FAR *ppInt)
  2016. {
  2017. //this is a simple function, simply addref on the m_pDirectDrawEx and return it's simple interface
  2018. return m_pDirectDrawEx->QueryInterface(IID_IDirectDraw, ppInt);
  2019. }
  2020. /*
  2021. * CDDSurface::QueryInterface
  2022. * AddRef
  2023. * Release
  2024. *
  2025. * The standard IUnknown that delegates...
  2026. */
  2027. STDMETHODIMP CDDSurface::QueryInterface(REFIID riid, void ** ppv)
  2028. {
  2029. return m_pUnkOuter->QueryInterface(riid, ppv);
  2030. } /* CDirectDrawEx::QueryInterface */
  2031. STDMETHODIMP_(ULONG) CDDSurface::AddRef(void)
  2032. {
  2033. return m_pUnkOuter->AddRef();
  2034. } /* CDirectDrawEx::AddRef */
  2035. STDMETHODIMP_(ULONG) CDDSurface::Release(void)
  2036. {
  2037. return m_pUnkOuter->Release();
  2038. } /* CDirectDrawEx::Release */
  2039. /*
  2040. * NonDelegating IUnknown for simple surface follows...
  2041. */
  2042. STDMETHODIMP CDDSurface::NonDelegatingQueryInterface(REFIID riid, void ** ppv)
  2043. {
  2044. HRESULT hr;
  2045. if (ppv == NULL)
  2046. return E_POINTER;
  2047. *ppv=NULL;
  2048. if( IID_IUnknown==riid )
  2049. {
  2050. *ppv=(INonDelegatingUnknown *)this;
  2051. }
  2052. else if( IID_IDirectDrawSurface==riid )
  2053. {
  2054. *ppv=&m_DDSInt;
  2055. }
  2056. else if( IID_IDirectDrawSurface2==riid )
  2057. {
  2058. *ppv=&m_DDS2Int;
  2059. }
  2060. else if( IID_IDirectDrawSurface3==riid )
  2061. {
  2062. *ppv=&m_DDS3Int;
  2063. }
  2064. else if (IID_IDirectDrawSurface4==riid )
  2065. {
  2066. if (m_DDS4Int.lpVtbl)
  2067. {
  2068. *ppv=&m_DDS4Int;
  2069. }
  2070. else
  2071. {
  2072. return (E_NOINTERFACE);
  2073. }
  2074. }
  2075. else if (IID_IDirect3DRampDevice == riid)
  2076. {
  2077. //#ifdef DBG
  2078. // hr = DDERR_LEGACYUSAGE;
  2079. //#else
  2080. HRESULT (__stdcall *lpFunc)(IDirectDrawVtbl **,REFIID, void **);
  2081. *(DWORD *)(&lpFunc) = *(DWORD *)*(DWORD **)m_pDDSurface;
  2082. hr = lpFunc(&(m_DDSInt.lpVtbl), riid, (void **)&m_D3DDeviceRAMPInt);
  2083. if( SUCCEEDED(hr) )
  2084. {
  2085. *ppv=m_D3DDeviceRAMPInt;
  2086. }
  2087. else
  2088. *ppv = NULL;
  2089. //#endif
  2090. return hr;
  2091. }
  2092. else if (IID_IDirect3DRGBDevice == riid)
  2093. {
  2094. //#ifdef DBG
  2095. // hr = DDERR_LEGACYUSAGE;
  2096. //#else
  2097. HRESULT (__stdcall *lpFunc)(IDirectDrawVtbl **,REFIID, void **);
  2098. *(DWORD *)(&lpFunc) = *(DWORD *)*(DWORD **)m_pDDSurface;
  2099. hr = lpFunc(&(m_DDSInt.lpVtbl), riid, (void **)&m_D3DDeviceRGBInt);
  2100. if( SUCCEEDED(hr) )
  2101. {
  2102. *ppv=m_D3DDeviceRGBInt;
  2103. }
  2104. else
  2105. *ppv = NULL;
  2106. //#endif
  2107. return hr;
  2108. }
  2109. else if (IID_IDirect3DChrmDevice == riid)
  2110. {
  2111. //#ifdef DBG
  2112. // hr = DDERR_LEGACYUSAGE;
  2113. //#else
  2114. HRESULT (__stdcall *lpFunc)(IDirectDrawVtbl **,REFIID, void **);
  2115. *(DWORD *)(&lpFunc) = *(DWORD *)*(DWORD **)m_pDDSurface;
  2116. hr = lpFunc(&(m_DDSInt.lpVtbl), riid, (void **)&m_D3DDeviceChrmInt);
  2117. if( SUCCEEDED(hr) )
  2118. {
  2119. *ppv=m_D3DDeviceChrmInt;
  2120. }
  2121. else
  2122. *ppv = NULL;
  2123. //#endif
  2124. return hr;
  2125. }
  2126. else if(IID_IDirect3DHALDevice == riid)
  2127. {
  2128. //#ifdef DBG
  2129. // hr = DDERR_LEGACYUSAGE;
  2130. //#else
  2131. HRESULT (__stdcall *lpFunc)(IDirectDrawVtbl **,REFIID, void **);
  2132. *(DWORD *)(&lpFunc) = *(DWORD *)*(DWORD **)m_pDDSurface;
  2133. hr = lpFunc(&(m_DDSInt.lpVtbl), riid, (void **)&m_D3DDeviceHALInt);
  2134. if( SUCCEEDED(hr) )
  2135. {
  2136. *ppv=m_D3DDeviceHALInt;
  2137. }
  2138. else
  2139. *ppv = NULL;
  2140. //#endif
  2141. return hr;
  2142. }
  2143. else if(IID_IDirect3DMMXDevice == riid)
  2144. {
  2145. //#ifdef DBG
  2146. // hr = DDERR_LEGACYUSAGE;
  2147. //#else
  2148. HRESULT (__stdcall *lpFunc)(IDirectDrawVtbl **,REFIID, void **);
  2149. *(DWORD *)(&lpFunc) = *(DWORD *)*(DWORD **)m_pDDSurface;
  2150. hr = lpFunc(&(m_DDSInt.lpVtbl), riid, (void **)&m_D3DDeviceMMXInt);
  2151. if( SUCCEEDED(hr) )
  2152. {
  2153. *ppv=m_D3DDeviceMMXInt;
  2154. }
  2155. else
  2156. *ppv = NULL;
  2157. //#endif
  2158. return hr;
  2159. }
  2160. else if (IID_IDirect3DTexture == riid)
  2161. {
  2162. HRESULT (__stdcall *lpFunc)(IDirectDrawVtbl **,REFIID, void **);
  2163. *(DWORD *)(&lpFunc) = *(DWORD *)*(DWORD **)m_pDDSurface;
  2164. hr = lpFunc(&(m_DDSInt.lpVtbl), riid, (void **)&m_D3DTextureInt);
  2165. if( SUCCEEDED(hr) )
  2166. {
  2167. *ppv=m_D3DTextureInt;
  2168. }
  2169. else
  2170. *ppv = NULL;
  2171. return hr;
  2172. }
  2173. else
  2174. {
  2175. return E_NOINTERFACE;
  2176. }
  2177. ((LPUNKNOWN)*ppv)->AddRef();
  2178. return NOERROR;
  2179. }
  2180. STDMETHODIMP_(ULONG) CDDSurface::NonDelegatingAddRef()
  2181. {
  2182. m_pDDSurface->AddRef();
  2183. return InterlockedIncrement(&m_cRef);
  2184. }
  2185. STDMETHODIMP_(ULONG) CDDSurface::NonDelegatingRelease()
  2186. {
  2187. LONG lRefCount = InterlockedDecrement(&m_cRef);
  2188. if (lRefCount) {
  2189. m_pDDSurface->Release();
  2190. return lRefCount;
  2191. }
  2192. delete this;
  2193. return 0;
  2194. }
  2195. /*
  2196. * Quick inline fns to get at our internal data...
  2197. */
  2198. _inline CDDSurface * SURFACEOF(IDirectDrawSurface * pDDS)
  2199. {
  2200. return ((INTSTRUC_IDirectDrawSurface *)pDDS)->m_pSimpleSurface;
  2201. }
  2202. _inline CDDSurface * SURFACEOF(IDirectDrawSurface2 * pDDS2)
  2203. {
  2204. return ((INTSTRUC_IDirectDrawSurface2 *)pDDS2)->m_pSimpleSurface;
  2205. }
  2206. _inline CDDSurface * SURFACEOF(IDirectDrawSurface3 * pDDS3)
  2207. {
  2208. return ((INTSTRUC_IDirectDrawSurface3 *)pDDS3)->m_pSimpleSurface;
  2209. }
  2210. _inline CDDSurface * SURFACEOF(IDirectDrawSurface4 * pDDS4)
  2211. {
  2212. return ((INTSTRUC_IDirectDrawSurface4 *)pDDS4)->m_pSimpleSurface;
  2213. }
  2214. /*
  2215. * the implementation of the functions in IDirectDrawSurface that we are
  2216. * overriding (IUnknown and GetDC, ReleaseDC, Lock, Unlock)
  2217. */
  2218. STDMETHODIMP_(ULONG) IDirectDrawSurfaceAggAddRef(IDirectDrawSurface *pDDS)
  2219. {
  2220. return SURFACEOF(pDDS)->m_pUnkOuter->AddRef();
  2221. }
  2222. STDMETHODIMP_(ULONG) IDirectDrawSurfaceAggRelease(IDirectDrawSurface *pDDS)
  2223. {
  2224. return SURFACEOF(pDDS)->m_pUnkOuter->Release();
  2225. }
  2226. STDMETHODIMP IDirectDrawSurfaceAggGetDC(IDirectDrawSurface *pDDS, HDC * pHDC)
  2227. {
  2228. return SURFACEOF(pDDS)->InternalGetDC(pHDC);
  2229. }
  2230. STDMETHODIMP IDirectDrawSurfaceAggGetAttachedSurface(IDirectDrawSurface *pDDS, LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE FAR * lpDDS)
  2231. {
  2232. return SURFACEOF(pDDS)->InternalGetAttachedSurface(lpDDSCaps, lpDDS, DDSURFACETYPE_1);
  2233. }
  2234. STDMETHODIMP IDirectDrawSurfaceAggAddAttachedSurface(IDirectDrawSurface *pDDS, LPDIRECTDRAWSURFACE lpDDS)
  2235. {
  2236. return SURFACEOF(pDDS)->InternalAddAttachedSurface(lpDDS, DDSURFACETYPE_1);
  2237. }
  2238. STDMETHODIMP IDirectDrawSurfaceAggDeleteAttachedSurface(IDirectDrawSurface *pDDS, DWORD dwFlags, LPDIRECTDRAWSURFACE lpDDS)
  2239. {
  2240. return SURFACEOF(pDDS)->InternalDeleteAttachedSurface(dwFlags, lpDDS, DDSURFACETYPE_1);
  2241. }
  2242. STDMETHODIMP IDirectDrawSurfaceAggReleaseDC(IDirectDrawSurface *pDDS, HDC hdc)
  2243. {
  2244. return SURFACEOF(pDDS)->InternalReleaseDC(hdc);
  2245. }
  2246. STDMETHODIMP IDirectDrawSurfaceAggLock(IDirectDrawSurface *pDDS, LPRECT lpDestRect,
  2247. LPDDSURFACEDESC lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent)
  2248. {
  2249. return SURFACEOF(pDDS)->InternalLock(lpDestRect, lpDDSurfaceDesc, dwFlags, hEvent);
  2250. }
  2251. STDMETHODIMP IDirectDrawSurfaceAggUnlock(IDirectDrawSurface *pDDS, LPVOID lpSurfaceData)
  2252. {
  2253. return SURFACEOF(pDDS)->InternalUnlock(lpSurfaceData);
  2254. }
  2255. STDMETHODIMP IDirectDrawSurfaceAggFlip(IDirectDrawSurface *pDDS, LPDIRECTDRAWSURFACE lpSurf, DWORD dw)
  2256. {
  2257. return SURFACEOF(pDDS)->InternalFlip(lpSurf, dw, DDSURFACETYPE_1);
  2258. }
  2259. STDMETHODIMP IDirectDrawSurfaceAggBlt(IDirectDrawSurface *pDDS, LPRECT lpRect1,LPDIRECTDRAWSURFACE lpDDS, LPRECT lpRect2,DWORD dw, LPDDBLTFX lpfx)
  2260. {
  2261. return SURFACEOF(pDDS)->InternalBlt(lpRect1, lpDDS, lpRect2, dw, lpfx, DDSURFACETYPE_1);
  2262. }
  2263. STDMETHODIMP IDirectDrawSurfaceAggGetPalette(IDirectDrawSurface *pDDS, LPDIRECTDRAWPALETTE FAR * ppPal)
  2264. {
  2265. return SURFACEOF(pDDS)->InternalGetPalette(ppPal, DDSURFACETYPE_1);
  2266. }
  2267. STDMETHODIMP IDirectDrawSurfaceAggSetPalette(IDirectDrawSurface *pDDS, LPDIRECTDRAWPALETTE pPal)
  2268. {
  2269. return SURFACEOF(pDDS)->InternalSetPalette(pPal, DDSURFACETYPE_1);
  2270. }
  2271. STDMETHODIMP IDirectDrawSurfaceAggGetSurfaceDesc(IDirectDrawSurface *pDDS, LPDDSURFACEDESC lpDesc)
  2272. {
  2273. return SURFACEOF(pDDS)->InternalGetSurfaceDesc(lpDesc, DDSURFACETYPE_1);
  2274. }
  2275. /*
  2276. * the implementation of the functions in IDirectDrawSurface2 that we are
  2277. * overriding (IUnknown and GetDC, ReleaseDC, Lock, Unlock)
  2278. */
  2279. STDMETHODIMP_(ULONG) IDirectDrawSurface2AggAddRef(IDirectDrawSurface2 *pDDS2)
  2280. {
  2281. return SURFACEOF(pDDS2)->m_pUnkOuter->AddRef();
  2282. }
  2283. STDMETHODIMP_(ULONG) IDirectDrawSurface2AggRelease(IDirectDrawSurface2 *pDDS2)
  2284. {
  2285. return SURFACEOF(pDDS2)->m_pUnkOuter->Release();
  2286. }
  2287. STDMETHODIMP IDirectDrawSurface2AggGetDC(IDirectDrawSurface2 *pDDS2, HDC * pHDC)
  2288. {
  2289. return SURFACEOF(pDDS2)->InternalGetDC(pHDC);
  2290. }
  2291. STDMETHODIMP IDirectDrawSurface2AggReleaseDC(IDirectDrawSurface2 *pDDS2, HDC hdc)
  2292. {
  2293. return SURFACEOF(pDDS2)->InternalReleaseDC(hdc);
  2294. }
  2295. STDMETHODIMP IDirectDrawSurface2AggLock(IDirectDrawSurface2 *pDDS2, LPRECT lpDestRect,
  2296. LPDDSURFACEDESC lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent)
  2297. {
  2298. return SURFACEOF(pDDS2)->InternalLock(lpDestRect, lpDDSurfaceDesc, dwFlags, hEvent);
  2299. }
  2300. STDMETHODIMP IDirectDrawSurface2AggUnlock(IDirectDrawSurface2 *pDDS2, LPVOID lpSurfaceData)
  2301. {
  2302. return SURFACEOF(pDDS2)->InternalUnlock(lpSurfaceData);
  2303. }
  2304. STDMETHODIMP IDirectDrawSurface2AggGetAttachedSurface(IDirectDrawSurface2 *pDDS, LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE2 FAR * lpDDS)
  2305. {
  2306. return SURFACEOF(pDDS)->InternalGetAttachedSurface(lpDDSCaps, (IDirectDrawSurface **)lpDDS, DDSURFACETYPE_2);
  2307. }
  2308. STDMETHODIMP IDirectDrawSurface2AggAddAttachedSurface(IDirectDrawSurface2 *pDDS, LPDIRECTDRAWSURFACE2 lpDDS)
  2309. {
  2310. return SURFACEOF(pDDS)->InternalAddAttachedSurface((IDirectDrawSurface *)lpDDS, DDSURFACETYPE_2);
  2311. }
  2312. STDMETHODIMP IDirectDrawSurface2AggDeleteAttachedSurface(IDirectDrawSurface2 *pDDS, DWORD dwFlags, LPDIRECTDRAWSURFACE2 lpDDS)
  2313. {
  2314. return SURFACEOF(pDDS)->InternalDeleteAttachedSurface(dwFlags, (IDirectDrawSurface *)lpDDS, DDSURFACETYPE_2);
  2315. }
  2316. STDMETHODIMP IDirectDrawSurface2AggFlip(IDirectDrawSurface2 *pDDS, LPDIRECTDRAWSURFACE2 lpSurf, DWORD dw)
  2317. {
  2318. return SURFACEOF(pDDS)->InternalFlip((LPDIRECTDRAWSURFACE)lpSurf, dw, DDSURFACETYPE_2);
  2319. }
  2320. STDMETHODIMP IDirectDrawSurface2AggBlt(IDirectDrawSurface2 *pDDS, LPRECT lpRect1,LPDIRECTDRAWSURFACE2 lpDDS, LPRECT lpRect2,DWORD dw, LPDDBLTFX lpfx)
  2321. {
  2322. return SURFACEOF(pDDS)->InternalBlt(lpRect1, (LPDIRECTDRAWSURFACE)lpDDS, lpRect2, dw, lpfx, DDSURFACETYPE_2);
  2323. }
  2324. STDMETHODIMP IDirectDrawSurface2AggGetPalette(IDirectDrawSurface2 *pDDS, LPDIRECTDRAWPALETTE FAR * ppPal)
  2325. {
  2326. return SURFACEOF(pDDS)->InternalGetPalette(ppPal, DDSURFACETYPE_2);
  2327. }
  2328. STDMETHODIMP IDirectDrawSurface2AggSetPalette(IDirectDrawSurface2 *pDDS, LPDIRECTDRAWPALETTE pPal)
  2329. {
  2330. return SURFACEOF(pDDS)->InternalSetPalette(pPal, DDSURFACETYPE_2);
  2331. }
  2332. STDMETHODIMP IDirectDrawSurface2AggGetDDInterface(IDirectDrawSurface2 *pDDS, LPVOID FAR * ppInt)
  2333. {
  2334. return SURFACEOF(pDDS)->InternalGetDDInterface(ppInt);
  2335. }
  2336. STDMETHODIMP IDirectDrawSurface2AggGetSurfaceDesc(IDirectDrawSurface2 *pDDS, LPDDSURFACEDESC lpDesc)
  2337. {
  2338. return SURFACEOF(pDDS)->InternalGetSurfaceDesc(lpDesc, DDSURFACETYPE_2);
  2339. }
  2340. /*
  2341. * the implementation of the functions in IDirectDrawSurface3 that we are
  2342. * overriding (IUnknown and GetDC, ReleaseDC, Lock, Unlock, SetSurfaceDesc)
  2343. */
  2344. STDMETHODIMP_(ULONG) IDirectDrawSurface3AggAddRef(IDirectDrawSurface3 *pDDS3)
  2345. {
  2346. return SURFACEOF(pDDS3)->m_pUnkOuter->AddRef();
  2347. }
  2348. STDMETHODIMP_(ULONG) IDirectDrawSurface3AggRelease(IDirectDrawSurface3 *pDDS3)
  2349. {
  2350. return SURFACEOF(pDDS3)->m_pUnkOuter->Release();
  2351. }
  2352. STDMETHODIMP IDirectDrawSurface3AggGetDC(IDirectDrawSurface3 *pDDS3, HDC * pHDC)
  2353. {
  2354. return SURFACEOF(pDDS3)->InternalGetDC(pHDC);
  2355. }
  2356. STDMETHODIMP IDirectDrawSurface3AggReleaseDC(IDirectDrawSurface3 *pDDS3, HDC hdc)
  2357. {
  2358. return SURFACEOF(pDDS3)->InternalReleaseDC(hdc);
  2359. }
  2360. STDMETHODIMP IDirectDrawSurface3AggLock(IDirectDrawSurface3 *pDDS3, LPRECT lpDestRect,
  2361. LPDDSURFACEDESC lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent)
  2362. {
  2363. return SURFACEOF(pDDS3)->InternalLock(lpDestRect, lpDDSurfaceDesc, dwFlags, hEvent);
  2364. }
  2365. STDMETHODIMP IDirectDrawSurface3AggUnlock(IDirectDrawSurface3 *pDDS3, LPVOID lpSurfaceData)
  2366. {
  2367. return SURFACEOF(pDDS3)->InternalUnlock(lpSurfaceData);
  2368. }
  2369. STDMETHODIMP IDirectDrawSurface3AggSetSurfaceDesc(IDirectDrawSurface3 *pDDS3, LPDDSURFACEDESC pddsd, DWORD dwFlags)
  2370. {
  2371. return SURFACEOF(pDDS3)->InternalSetSurfaceDesc(pddsd, dwFlags);
  2372. }
  2373. STDMETHODIMP IDirectDrawSurface3AggGetAttachedSurface(IDirectDrawSurface3 *pDDS, LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE3 FAR * lpDDS)
  2374. {
  2375. return SURFACEOF(pDDS)->InternalGetAttachedSurface(lpDDSCaps, (IDirectDrawSurface**)lpDDS, DDSURFACETYPE_3);
  2376. }
  2377. STDMETHODIMP IDirectDrawSurface3AggAddAttachedSurface(IDirectDrawSurface3 *pDDS, LPDIRECTDRAWSURFACE3 lpDDS)
  2378. {
  2379. return SURFACEOF(pDDS)->InternalAddAttachedSurface((IDirectDrawSurface *)lpDDS, DDSURFACETYPE_3);
  2380. }
  2381. STDMETHODIMP IDirectDrawSurface3AggDeleteAttachedSurface(IDirectDrawSurface3 *pDDS, DWORD dwFlags, LPDIRECTDRAWSURFACE3 lpDDS)
  2382. {
  2383. return SURFACEOF(pDDS)->InternalDeleteAttachedSurface(dwFlags, (IDirectDrawSurface *)lpDDS, DDSURFACETYPE_3);
  2384. }
  2385. STDMETHODIMP IDirectDrawSurface3AggFlip(IDirectDrawSurface3 *pDDS, LPDIRECTDRAWSURFACE3 lpSurf, DWORD dw)
  2386. {
  2387. return SURFACEOF(pDDS)->InternalFlip((LPDIRECTDRAWSURFACE)lpSurf, dw, DDSURFACETYPE_3);
  2388. }
  2389. STDMETHODIMP IDirectDrawSurface3AggBlt(IDirectDrawSurface3 *pDDS, LPRECT lpRect1,LPDIRECTDRAWSURFACE3 lpDDS, LPRECT lpRect2,DWORD dw, LPDDBLTFX lpfx)
  2390. {
  2391. return SURFACEOF(pDDS)->InternalBlt(lpRect1, (LPDIRECTDRAWSURFACE)lpDDS, lpRect2, dw, lpfx, DDSURFACETYPE_3);
  2392. }
  2393. STDMETHODIMP IDirectDrawSurface3AggGetPalette(IDirectDrawSurface3 *pDDS, LPDIRECTDRAWPALETTE FAR * ppPal)
  2394. {
  2395. return SURFACEOF(pDDS)->InternalGetPalette(ppPal, DDSURFACETYPE_3);
  2396. }
  2397. STDMETHODIMP IDirectDrawSurface3AggSetPalette(IDirectDrawSurface3 *pDDS, LPDIRECTDRAWPALETTE pPal)
  2398. {
  2399. return SURFACEOF(pDDS)->InternalSetPalette(pPal, DDSURFACETYPE_3);
  2400. }
  2401. STDMETHODIMP IDirectDrawSurface3AggGetDDInterface(IDirectDrawSurface3 *pDDS, LPVOID FAR * ppInt)
  2402. {
  2403. return SURFACEOF(pDDS)->InternalGetDDInterface(ppInt);
  2404. }
  2405. STDMETHODIMP IDirectDrawSurface3AggGetSurfaceDesc(IDirectDrawSurface3 *pDDS, LPDDSURFACEDESC lpDesc)
  2406. {
  2407. return SURFACEOF(pDDS)->InternalGetSurfaceDesc(lpDesc, DDSURFACETYPE_3);
  2408. }
  2409. /*
  2410. * the implementation of the functions in IDirectDrawSurface4 that we are
  2411. * overriding (IUnknown and GetDC, ReleaseDC, Lock, Unlock, SetSurfaceDesc)
  2412. */
  2413. STDMETHODIMP_(ULONG) IDirectDrawSurface4AggAddRef(IDirectDrawSurface4 *pDDS4)
  2414. {
  2415. return SURFACEOF(pDDS4)->m_pUnkOuter->AddRef();
  2416. }
  2417. STDMETHODIMP_(ULONG) IDirectDrawSurface4AggRelease(IDirectDrawSurface4 *pDDS4)
  2418. {
  2419. return SURFACEOF(pDDS4)->m_pUnkOuter->Release();
  2420. }
  2421. STDMETHODIMP IDirectDrawSurface4AggGetDC(IDirectDrawSurface4 *pDDS4, HDC * pHDC)
  2422. {
  2423. return SURFACEOF(pDDS4)->InternalGetDC(pHDC);
  2424. }
  2425. STDMETHODIMP IDirectDrawSurface4AggReleaseDC(IDirectDrawSurface4 *pDDS4, HDC hdc)
  2426. {
  2427. return SURFACEOF(pDDS4)->InternalReleaseDC(hdc);
  2428. }
  2429. STDMETHODIMP IDirectDrawSurface4AggLock(IDirectDrawSurface4 *pDDS4, LPRECT lpDestRect,
  2430. LPDDSURFACEDESC2 lpDDSurfaceDesc2, DWORD dwFlags, HANDLE hEvent)
  2431. {
  2432. INTSTRUC_IDirectDrawSurface4 * pdd4 = (INTSTRUC_IDirectDrawSurface4 *)pDDS4;
  2433. return pdd4->m_pRealInterface->Lock(lpDestRect, lpDDSurfaceDesc2, dwFlags, hEvent);
  2434. }
  2435. STDMETHODIMP IDirectDrawSurface4AggUnlock(IDirectDrawSurface4 *pDDS4, LPRECT lpRect)
  2436. {
  2437. INTSTRUC_IDirectDrawSurface4 * pdd4 = (INTSTRUC_IDirectDrawSurface4 *)pDDS4;
  2438. return pdd4->m_pRealInterface->Unlock(lpRect);
  2439. }
  2440. STDMETHODIMP IDirectDrawSurface4AggSetSurfaceDesc(IDirectDrawSurface4 *pDDS4, LPDDSURFACEDESC pddsd, DWORD dwFlags)
  2441. {
  2442. return SURFACEOF(pDDS4)->InternalSetSurfaceDesc(pddsd, dwFlags);
  2443. }
  2444. STDMETHODIMP IDirectDrawSurface4AggGetAttachedSurface(IDirectDrawSurface4 *pDDS, LPDDSCAPS2 lpDDSCaps, LPDIRECTDRAWSURFACE4 FAR * lpDDS)
  2445. {
  2446. return SURFACEOF(pDDS)->InternalGetAttachedSurface4(lpDDSCaps, (IDirectDrawSurface**)lpDDS);
  2447. }
  2448. STDMETHODIMP IDirectDrawSurface4AggAddAttachedSurface(IDirectDrawSurface4 *pDDS, LPDIRECTDRAWSURFACE4 lpDDS)
  2449. {
  2450. return SURFACEOF(pDDS)->InternalAddAttachedSurface((IDirectDrawSurface *)lpDDS, DDSURFACETYPE_4);
  2451. }
  2452. STDMETHODIMP IDirectDrawSurface4AggDeleteAttachedSurface(IDirectDrawSurface4 *pDDS, DWORD dwFlags, LPDIRECTDRAWSURFACE4 lpDDS)
  2453. {
  2454. return SURFACEOF(pDDS)->InternalDeleteAttachedSurface(dwFlags, (IDirectDrawSurface *)lpDDS, DDSURFACETYPE_4);
  2455. }
  2456. STDMETHODIMP IDirectDrawSurface4AggFlip(IDirectDrawSurface4 *pDDS, LPDIRECTDRAWSURFACE4 lpSurf, DWORD dw)
  2457. {
  2458. return SURFACEOF(pDDS)->InternalFlip((LPDIRECTDRAWSURFACE)lpSurf, dw, DDSURFACETYPE_4);
  2459. }
  2460. STDMETHODIMP IDirectDrawSurface4AggBlt(IDirectDrawSurface4 *pDDS, LPRECT lpRect1,LPDIRECTDRAWSURFACE4 lpDDS, LPRECT lpRect2,DWORD dw, LPDDBLTFX lpfx)
  2461. {
  2462. return SURFACEOF(pDDS)->InternalBlt(lpRect1, (LPDIRECTDRAWSURFACE)lpDDS, lpRect2, dw, lpfx, DDSURFACETYPE_4);
  2463. }
  2464. STDMETHODIMP IDirectDrawSurface4AggGetPalette(IDirectDrawSurface4 *pDDS, LPDIRECTDRAWPALETTE FAR * ppPal)
  2465. {
  2466. return SURFACEOF(pDDS)->InternalGetPalette(ppPal, DDSURFACETYPE_4);
  2467. }
  2468. STDMETHODIMP IDirectDrawSurface4AggSetPalette(IDirectDrawSurface4 *pDDS, LPDIRECTDRAWPALETTE pPal)
  2469. {
  2470. return SURFACEOF(pDDS)->InternalSetPalette(pPal, DDSURFACETYPE_4);
  2471. }
  2472. STDMETHODIMP IDirectDrawSurface4AggGetDDInterface(IDirectDrawSurface4 *pDDS, LPVOID FAR * ppInt)
  2473. {
  2474. return SURFACEOF(pDDS)->InternalGetDDInterface(ppInt);
  2475. }
  2476. STDMETHODIMP IDirectDrawSurface4AggGetSurfaceDesc(IDirectDrawSurface4 *pDDS, LPDDSURFACEDESC2 lpDesc2)
  2477. {
  2478. return SURFACEOF(pDDS)->InternalGetSurfaceDesc4(lpDesc2);
  2479. }