bool CGUITextureManager::HasTexture(const CStdString &textureName, CStdString *path, int *bundle, int *size) { // default values if (bundle) *bundle = -1; if (size) *size = 0; if (path) *path = textureName; if (textureName == "-") return false; if (textureName.Find("://") >= 0) return false; // first check of texture exists... for (int i = 0; i < (int)m_vecTextures.size(); ++i) { CTextureMap *pMap = m_vecTextures[i]; if (pMap->GetName() == textureName) { for (int i = 0; i < 2; i++) { if (m_iNextPreload[i] != m_PreLoadNames[i].end() && (*m_iNextPreload[i] == textureName)) { ++m_iNextPreload[i]; // preload next file if (m_iNextPreload[i] != m_PreLoadNames[i].end()) m_TexBundle[i].PreloadFile(*m_iNextPreload[i]); } } if (size) *size = pMap->size(); return true; } } for (int i = 0; i < 2; i++) { if (m_iNextPreload[i] != m_PreLoadNames[i].end() && (*m_iNextPreload[i] == textureName)) { if (bundle) *bundle = i; ++m_iNextPreload[i]; // preload next file if (m_iNextPreload[i] != m_PreLoadNames[i].end()) m_TexBundle[i].PreloadFile(*m_iNextPreload[i]); return true; } else if (m_TexBundle[i].HasFile(textureName)) { if (bundle) *bundle = i; return true; } } CStdString fullPath = GetTexturePath(textureName); if (path) *path = fullPath; return !fullPath.IsEmpty(); }
int CGUITextureManager::Load(const CStdString& strTextureName, DWORD dwColorKey, bool checkBundleOnly /*= false */) { CStdString strPath; int bundle = -1; int size = 0; if (!HasTexture(strTextureName, &strPath, &bundle, &size)) return 0; if (size) // we found the texture return size; // See if texture is being overridden. CStdString strTextureFile = strTextureName; CStdString strTextureOverridePath1; CStdString strTextureOverridePath2; CStdString strExt = CUtil::GetExtension(strTextureFile); CUtil::RemoveExtension(strTextureFile); // Check original format and JPEG. strTextureOverridePath1.Format("%s/media/%s%s", _P("Q:"), strTextureFile.c_str(), strExt.c_str()); strTextureOverridePath2.Format("%s/media/%s.jpg", _P("Q:"), strTextureFile.c_str(), strExt.c_str()); if (checkBundleOnly && bundle == -1) return 0; if (XFILE::CFile::Exists(strTextureOverridePath1)) { strPath = strTextureOverridePath1; bundle = -1; } else if (XFILE::CFile::Exists(strTextureOverridePath2)) { strPath = strTextureOverridePath2; bundle = -1; } else if (bundle == -1) strPath = GetTexturePath(strTextureName); else strPath = strTextureName; //Lock here, we will do stuff that could break rendering CSingleLock lock(g_graphicsContext); #ifndef HAS_SDL LPDIRECT3DTEXTURE8 pTexture; LPDIRECT3DPALETTE8 pPal = 0; #else SDL_Surface* pTexture; SDL_Palette* pPal = NULL; #endif #ifdef _DEBUG LARGE_INTEGER start; QueryPerformanceCounter(&start); #endif D3DXIMAGE_INFO info; if (strPath.Right(4).ToLower() == ".gif") { CTextureMap* pMap; if (bundle >= 0) { #ifndef HAS_SDL LPDIRECT3DTEXTURE8* pTextures; #else SDL_Surface** pTextures; #endif int nLoops = 0; int* Delay; #ifndef HAS_SDL int nImages = m_TexBundle[bundle].LoadAnim(g_graphicsContext.Get3DDevice(), strTextureName, &info, &pTextures, &pPal, nLoops, &Delay); #else int nImages = m_TexBundle[bundle].LoadAnim(strTextureName, &info, &pTextures, &pPal, nLoops, &Delay); #endif if (!nImages) { CLog::Log(LOGERROR, "Texture manager unable to load bundled file: %s", strTextureName.c_str()); return 0; } pMap = new CTextureMap(strTextureName); for (int iImage = 0; iImage < nImages; ++iImage) { CTexture* pclsTexture = new CTexture(pTextures[iImage], info.Width, info.Height, true, 100, pPal); pclsTexture->SetDelay(Delay[iImage]); pclsTexture->SetLoops(nLoops); pMap->Add(pclsTexture); #ifndef HAS_SDL delete pTextures[iImage]; #else SDL_FreeSurface(pTextures[iImage]); #endif } delete [] pTextures; delete [] Delay; } else { CAnimatedGifSet AnimatedGifSet; int iImages = AnimatedGifSet.LoadGIF(strPath.c_str()); if (iImages == 0) { if (!strnicmp(strPath.c_str(), "q:\\skin", 7)) CLog::Log(LOGERROR, "Texture manager unable to load file: %s", strPath.c_str()); return 0; } int iWidth = AnimatedGifSet.FrameWidth; int iHeight = AnimatedGifSet.FrameHeight; int iPaletteSize = (1 << AnimatedGifSet.m_vecimg[0]->BPP); pMap = new CTextureMap(strTextureName); for (int iImage = 0; iImage < iImages; iImage++) { int w = iWidth; int h = iHeight; #if defined(HAS_SDL) pTexture = SDL_CreateRGBSurface(SDL_HWSURFACE, w, h, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000); if (pTexture) #else if (D3DXCreateTexture(g_graphicsContext.Get3DDevice(), w, h, 1, 0, D3DFMT_LIN_A8R8G8B8, D3DPOOL_MANAGED, &pTexture) == D3D_OK) #endif { CAnimatedGif* pImage = AnimatedGifSet.m_vecimg[iImage]; #ifndef HAS_SDL D3DLOCKED_RECT lr; RECT rc = { 0, 0, pImage->Width, pImage->Height }; if ( D3D_OK == pTexture->LockRect( 0, &lr, &rc, 0 )) #else if (SDL_LockSurface(pTexture) != -1) #endif { COLOR *palette = AnimatedGifSet.m_vecimg[0]->Palette; // set the alpha values to fully opaque for (int i = 0; i < iPaletteSize; i++) palette[i].x = 0xff; // and set the transparent colour if (AnimatedGifSet.m_vecimg[0]->Transparency && AnimatedGifSet.m_vecimg[0]->Transparent >= 0) palette[AnimatedGifSet.m_vecimg[0]->Transparent].x = 0; #ifdef HAS_SDL // Allocate memory for the actual pixels in the surface and set the surface BYTE* pixels = (BYTE*) malloc(w * h * 4); pTexture->pixels = pixels; #endif for (int y = 0; y < pImage->Height; y++) { #ifndef HAS_SDL BYTE *dest = (BYTE *)lr.pBits + y * lr.Pitch; #else BYTE *dest = (BYTE *)pixels + (y * w * 4); #endif BYTE *source = (BYTE *)pImage->Raster + y * pImage->BytesPerRow; for (int x = 0; x < pImage->Width; x++) { COLOR col = palette[*source++]; *dest++ = col.b; *dest++ = col.g; *dest++ = col.r; *dest++ = col.x; } } #ifndef HAS_SDL pTexture->UnlockRect( 0 ); #else SDL_UnlockSurface(pTexture); #endif CTexture* pclsTexture = new CTexture(pTexture, iWidth, iHeight, false, 100, pPal); pclsTexture->SetDelay(pImage->Delay); pclsTexture->SetLoops(AnimatedGifSet.nLoops); #ifdef HAS_SDL free(pixels); #endif #ifdef HAS_SDL_2D SDL_FreeSurface(pTexture); #endif pMap->Add(pclsTexture); } } } // of for (int iImage=0; iImage < iImages; iImage++) } #ifdef _DEBUG LARGE_INTEGER end, freq; QueryPerformanceCounter(&end); QueryPerformanceFrequency(&freq); char temp[200]; sprintf(temp, "Load %s: %.1fms%s\n", strPath.c_str(), 1000.f * (end.QuadPart - start.QuadPart) / freq.QuadPart, (bundle >= 0) ? " (bundled)" : ""); OutputDebugString(temp); #endif m_vecTextures.push_back(pMap); return pMap->size(); } // of if (strPath.Right(4).ToLower()==".gif") if (bundle >= 0) { #ifndef HAS_SDL if (FAILED(m_TexBundle[bundle].LoadTexture(g_graphicsContext.Get3DDevice(), strTextureName, &info, &pTexture, &pPal))) #else if (FAILED(m_TexBundle[bundle].LoadTexture(strTextureName, &info, &pTexture, &pPal))) #endif { CLog::Log(LOGERROR, "Texture manager unable to load bundled file: %s", strTextureName.c_str()); return 0; } } else { // normal picture // convert from utf8 CStdString texturePath; g_charsetConverter.utf8ToStringCharset(_P(strPath), texturePath); #ifndef HAS_SDL if ( D3DXCreateTextureFromFileEx(g_graphicsContext.Get3DDevice(), texturePath.c_str(), D3DX_DEFAULT, D3DX_DEFAULT, 1, 0, D3DFMT_LIN_A8R8G8B8, D3DPOOL_MANAGED, D3DX_FILTER_NONE , D3DX_FILTER_NONE, dwColorKey, &info, NULL, &pTexture) != D3D_OK) { if (!strnicmp(strPath.c_str(), "q:\\skin", 7)) CLog::Log(LOGERROR, "Texture manager unable to load file: %s", strPath.c_str()); return 0; } #else SDL_Surface *original = IMG_Load(texturePath.c_str()); CPicture pic; if (!original && !(original = pic.Load(texturePath, MAX_PICTURE_WIDTH, MAX_PICTURE_HEIGHT))) { CLog::Log(LOGERROR, "Texture manager unable to load file: %s", strPath.c_str()); return 0; } // make sure the texture format is correct SDL_PixelFormat format; format.palette = 0; format.colorkey = 0; format.alpha = 0; format.BitsPerPixel = 32; format.BytesPerPixel = 4; format.Amask = 0xff000000; format.Ashift = 24; format.Rmask = 0x00ff0000; format.Rshift = 16; format.Gmask = 0x0000ff00; format.Gshift = 8; format.Bmask = 0x000000ff; format.Bshift = 0; #ifdef HAS_SDL_OPENGL pTexture = SDL_ConvertSurface(original, &format, SDL_SWSURFACE); #else pTexture = SDL_ConvertSurface(original, &format, SDL_HWSURFACE); #endif SDL_FreeSurface(original); if (!pTexture) { CLog::Log(LOGERROR, "Texture manager unable to load file: %s", strPath.c_str()); return 0; } info.Width = pTexture->w; info.Height = pTexture->h; #endif } CTextureMap* pMap = new CTextureMap(strTextureName); CTexture* pclsTexture = new CTexture(pTexture, info.Width, info.Height, bundle >= 0, 100, pPal); pMap->Add(pclsTexture); m_vecTextures.push_back(pMap); #ifdef HAS_SDL_OPENGL SDL_FreeSurface(pTexture); #endif #ifdef _DEBUG LARGE_INTEGER end, freq; QueryPerformanceCounter(&end); QueryPerformanceFrequency(&freq); char temp[200]; sprintf(temp, "Load %s: %.1fms%s\n", strPath.c_str(), 1000.f * (end.QuadPart - start.QuadPart) / freq.QuadPart, (bundle >= 0) ? " (bundled)" : ""); OutputDebugString(temp); #endif return 1; }