5 extern CD3DFramework* g_pFramework;
7 ////////////////////////////////////////////////////////////////////////////
9 BOOL CTexture::s_bLocked = FALSE;
10 DDSURFACEDESC2 CTexture::s_ddsd;
13 HRESULT CTexture::Initialize (BYTE *rgbSource, ULONG ulWidth, ULONG ulHeight, ULONG ulPitch)
15 m_rgbSource = rgbSource;
16 m_ulWidthSource = ulWidth;
17 m_ulHeightSource = ulHeight;
18 m_ulPitchSource = ulPitch;
23 HRESULT CTexture::Allocate (CPaletteInfo *ppi)
27 ASSERT (m_spddsMemory == NULL);
32 while (m_ulWidth < m_ulWidthSource)
36 while (m_ulHeight < m_ulHeightSource)
41 m_ulWidth = m_ulWidthSource;
42 m_ulHeight = m_ulHeightSource;
47 if (m_ulHeight > m_ulWidth)
49 m_ulWidth = m_ulHeight;
53 m_ulHeight = m_ulWidth;
57 m_flAdjX = (D3DVALUE) m_ulWidthSource / (D3DVALUE) m_ulWidth;
58 m_flAdjY = (D3DVALUE) m_ulHeightSource / (D3DVALUE) m_ulHeight;
61 ZeroMemory (&ddsd, sizeof (ddsd));
62 ddsd.dwSize = sizeof (ddsd);
63 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
64 ddsd.dwWidth = m_ulWidth;
65 ddsd.dwHeight = m_ulHeight;
66 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
67 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
68 ppi->GetPixelFormat (&ddsd.ddpfPixelFormat);
70 hr = g_pFramework->GetDirectDraw ()->CreateSurface(&ddsd, &m_spddsMemory, NULL);
71 ASSERT (SUCCEEDED (hr));
75 ASSERT (m_spddsMemory != NULL);
77 m_spddtMemory = m_spddsMemory;
82 if (ppi->IsIndexed ())
84 ddck.dwColorSpaceLowValue = 255;
85 ddck.dwColorSpaceHighValue = 255;
89 ddck.dwColorSpaceLowValue = 0;
90 ddck.dwColorSpaceHighValue = 0;
92 hr = m_spddsMemory->SetColorKey (DDCKEY_SRCBLT, &ddck);
93 ASSERT (SUCCEEDED (hr));
95 if (ppi->GetPalette () != NULL)
97 hr = m_spddsMemory->SetPalette (ppi->GetPalette ());
98 ASSERT (SUCCEEDED (hr));
104 HRESULT CTexture::Free (void)
108 m_spddtMemory = m_spddsMemory = NULL;
116 HRESULT CTexture::Lock (void)
123 s_ddsd.dwSize = sizeof (s_ddsd);
124 hr = m_spddsMemory->Lock (
132 ASSERT (SUCCEEDED (hr));
143 HRESULT CTexture::Unlock (void)
148 hr = m_spddsMemory->Unlock (NULL);
149 ASSERT (SUCCEEDED (hr));
162 void CTexture::PlotPixel (ULONG ulX, ULONG ulY, BYTE b)
164 ASSERT (ulX <= m_ulWidth);
165 ASSERT (ulY <= m_ulHeight);
168 ASSERT (s_ddsd.lpSurface != NULL);
170 switch (s_ddsd.ddpfPixelFormat.dwRGBBitCount)
174 * (((LPBYTE) s_ddsd.lpSurface) + ulX + ulY * s_ddsd.lPitch) = b;
181 if (!(m_bTransparent && b == 255))
183 w = m_ppi->Read16 (b);
189 * (WORD *) (((LPBYTE) s_ddsd.lpSurface) + ulX * 2 + ulY * s_ddsd.lPitch) = w;
201 void CTexture::SetBitmapData (BYTE *rgb, BOOL bRle)
208 void CTexture::CopyFromSource (void)
210 if (SUCCEEDED (Lock ()))
214 PBYTE pbLine = m_rgbSource + m_ulHeightSource + 4;;
215 for (ULONG y = 0; y < m_ulHeightSource; y ++)
218 PBYTE pbSrc = pbLine;
222 const BYTE RLE_CODE = 0xE0;
224 if ((b & RLE_CODE) != RLE_CODE)
226 PlotPixel (x++, y, b);
230 BYTE cb = b & (~RLE_CODE);
236 PlotPixel (x++, y, b);
239 ASSERT (x <= m_ulWidthSource);
241 pbLine += m_rgbSource [y + 4];
246 LPBYTE lpbDest = (LPBYTE) s_ddsd.lpSurface;
247 LPBYTE lpbSrc = m_rgbSource;
249 switch (s_ddsd.ddpfPixelFormat.dwRGBBitCount)
253 for (ULONG y = m_ulHeightSource; y != 0; y--)
255 memcpy (lpbDest, lpbSrc, m_ulPitchSource);
256 lpbDest += s_ddsd.lPitch;
257 lpbSrc += m_ulPitchSource;
263 for (ULONG y = m_ulHeightSource; y != 0; y--)
265 LPBYTE lpbLineSrc = lpbSrc;
266 LPWORD lpwLineDest = (LPWORD) lpbDest;
270 for (ULONG x = m_ulWidthSource; x != 0; x--)
272 BYTE b = *lpbLineSrc++;
273 *lpwLineDest++ = (b == 255) ? 0 : m_ppi->Read16 (b);
278 for (ULONG x = m_ulWidthSource; x != 0; x--)
280 *lpwLineDest++ = m_ppi->Read16 (*lpbLineSrc++);
283 lpbDest += s_ddsd.lPitch;
284 lpbSrc += m_ulPitchSource;
304 HRESULT CTexture::CleanMemory (void)
307 m_bDirtyMemory = FALSE;
311 IDirect3DTexture2 *CTexture::GetTexture ()
318 return m_spddtMemory;
321 ////////////////////////////////////////////////////////////////////////////
323 struct FindTextureData
325 DWORD bpp; // we want a texture format of this bpp
326 DDPIXELFORMAT ddpf; // place the format here
330 HRESULT CALLBACK FindTextureCallback(LPDDPIXELFORMAT pddpf, LPVOID lParam)
332 FindTextureData * FindData = (FindTextureData *)lParam;
335 // we use GetDC/BitBlt to init textures so we only
336 // want to use formats that GetDC will support.
338 if (pddpf->dwFlags & (DDPF_ALPHA|DDPF_ALPHAPIXELS))
342 if (pddpf->dwRGBBitCount == 16)
344 FindData->ddpf = ddpf;
351 // if (!(pddpf->dwFlags & DDPF_ALPHAPIXELS))
352 // return DDENUMRET_OK;
354 if (pddpf->dwRGBBitCount < 8)
357 if (pddpf->dwRGBBitCount == 8 && !(pddpf->dwFlags & DDPF_PALETTEINDEXED8))
360 if (pddpf->dwRGBBitCount > 8 && !(pddpf->dwFlags & DDPF_RGB))
364 // keep the texture format that is nearest to the bitmap we have
366 if (FindData->ddpf.dwRGBBitCount == 0 ||
367 (pddpf->dwRGBBitCount >= FindData->bpp && pddpf->dwRGBBitCount <= FindData->ddpf.dwRGBBitCount) //&&
368 //(pddpf->dwAlphaBitDepth != 0 && pddpf->dwAlphaBitDepth > FindData->ddpf.dwAlphaBitDepth) // ALPHA BIT DEPTHS ARE REVERSED!!!!
371 FindData->ddpf = *pddpf;
377 void ChooseTextureFormat(LPDIRECT3DDEVICE3 Device, DWORD bpp, DDPIXELFORMAT *pddpf)
380 FindTextureData FindData;
381 ZeroMemory(&FindData, sizeof(FindData));
383 hr = Device->EnumTextureFormats(FindTextureCallback, (LPVOID)&FindData);
385 *pddpf = FindData.ddpf;
388 HRESULT CPaletteInfo::Initialize ()
390 m_spddpPalette = NULL;
393 // find the best texture format to use.
395 ChooseTextureFormat (g_pFramework->GetD3DDevice (), 8, &m_ddpfPixelFormat);
397 m_cshftR = GetShift (m_mskR = m_ddpfPixelFormat.dwRBitMask);
398 m_cshftG = GetShift (m_mskG = m_ddpfPixelFormat.dwGBitMask);
399 m_cshftB = GetShift (m_mskB = m_ddpfPixelFormat.dwBBitMask);
403 D3DDEVICEDESC descHAL, descHEL;
404 descHAL.dwSize = descHEL.dwSize = sizeof (descHAL);
405 hr = g_pFramework->GetD3DDevice ()->GetCaps (&descHAL, &descHEL);
406 ASSERT (SUCCEEDED (hr));
408 if (!descHAL.dwFlags) {
409 m_bPow2 = (descHEL.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) != 0;
410 m_bSquare = (descHEL.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_SQUAREONLY) != 0;
412 m_bPow2 = (descHAL.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) != 0;
413 m_bSquare = (descHAL.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_SQUAREONLY) != 0;
418 hr = g_pFramework->GetDirectDraw ()->CreatePalette (DDPCAPS_8BIT | DDPCAPS_ALLOW256, m_rgpe, &m_spddpPalette, NULL);
419 ASSERT (SUCCEEDED (hr));
425 HRESULT CPaletteInfo::Uninitialize ()
427 m_spddpPalette = NULL; // smart pointer release
432 void CPaletteInfo::SetPaletteEntries (PALETTEENTRY rgpe [256])
434 // okay, we don't really need to cache the palette values
435 // we could implement ReadPalette by individual Getentries calls...
436 memcpy (m_rgpe, rgpe, sizeof (m_rgpe));
438 if (m_spddpPalette != NULL)
440 HRESULT hr = m_spddpPalette->SetEntries (0, 0, 256, m_rgpe);
441 ASSERT (SUCCEEDED (hr));
445 void CPaletteInfo::GetPaletteEntries (PALETTEENTRY rgpe [256])
447 if (m_spddpPalette != NULL)
449 HRESULT hr = m_spddpPalette->GetEntries (0, 0, 256, m_rgpe);
450 ASSERT (SUCCEEDED (hr));
454 ////////////////////////////////////////////////////////////////
455 CPaletteInfo *CTexture::m_ppi;
457 HRESULT CTextureSet::Initialize ()
461 hr = m_pi.Initialize ();
462 ASSERT (SUCCEEDED (hr));
464 CTexture::m_ppi = &m_pi;
466 for (TEXTURE_SET::iterator iter = m_setTextures.begin ();
467 iter != m_setTextures.end ();
470 (*iter)->Allocate (&m_pi);
476 HRESULT CTextureSet::Uninitialize ()
478 for (TEXTURE_SET::iterator iter = m_setTextures.begin ();
479 iter != m_setTextures.end ();
485 m_pi.Uninitialize ();
490 CTexture *CTextureSet::CreateTexture (BYTE *rgbSource, ULONG dx, ULONG dy, ULONG ulPitch)
492 CTexture *pTexture = new CTexture;
494 pTexture->Initialize (rgbSource, dx, dy, ulPitch);
495 pTexture->Allocate (&m_pi);
497 m_setTextures.insert (pTexture);
502 void CTextureSet::FreeTexture (CTexture *pTexture)
504 m_setTextures.erase (pTexture);
509 void CTextureSet::DirtyTextures (void)
511 for (TEXTURE_SET::iterator iter = m_setTextures.begin ();
512 iter != m_setTextures.end ();
515 (*iter)->DirtyMemory ();
520 void CTextureSet::SetPaletteEntries (PALETTEENTRY rgpe [256])
522 m_pi.SetPaletteEntries (rgpe);
524 if (!m_pi.IsIndexed ())
530 void CTextureSet::GetPaletteEntries (PALETTEENTRY rgpe [256])
532 m_pi.GetPaletteEntries (rgpe);