示例#1
0
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();
}
示例#2
0
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;
}