/* CTexture::loadPatchImage * Loads the image for the patch at [pindex] into [image]. Can deal * with textures-as-patches *******************************************************************/ bool CTexture::loadPatchImage(unsigned pindex, SImage& image, Archive* parent, Palette8bit* pal) { // Check patch index if (pindex >= patches.size()) return false; CTPatch* patch = patches[pindex]; // If the texture is extended, search for textures-as-patches first // (as long as the patch name is different from this texture's name) if (extended && !(S_CMPNOCASE(patch->getName(), name))) { // Search the texture list we're in first if (in_list) { for (unsigned a = 0; a < in_list->nTextures(); a++) { CTexture* tex = in_list->getTexture(a); // Don't look past this texture in the list if (tex->getName() == name) break; // Check for name match if (S_CMPNOCASE(tex->getName(), patch->getName())) { // Load texture to image return tex->toImage(image, parent, pal); } } } // Otherwise, try the resource manager // TODO: Something has to be ignored here. The entire archive or just the current list? CTexture* tex = theResourceManager->getTexture(patch->getName(), parent); if (tex) return tex->toImage(image, parent, pal); } // Get patch entry ArchiveEntry* entry = patch->getPatchEntry(parent); // Load entry to image if valid if (entry) return Misc::loadImageFromEntry(&image, entry); else return false; }
GLTexture* MapTextureManager::getTexture(string name, bool mixed) { // Get texture matching name map_tex_t& mtex = textures[name.Upper()]; // Get desired filter type int filter = 1; if (map_tex_filter == 0) filter = GLTexture::NEAREST_LINEAR_MIN; else if (map_tex_filter == 1) filter = GLTexture::LINEAR; else if (map_tex_filter == 2) filter = GLTexture::LINEAR_MIPMAP; else if (map_tex_filter == 3) filter = GLTexture::NEAREST_MIPMAP; // If the texture is loaded if (mtex.texture) { // If the texture filter matches the desired one, return it if (mtex.texture->getFilter() == filter) return mtex.texture; else { // Otherwise, reload the texture if (mtex.texture != &(GLTexture::missingTex())) delete mtex.texture; mtex.texture = NULL; } } // Texture not found or unloaded, look for it Palette8bit* pal = getResourcePalette(); // Look for stand-alone textures first ArchiveEntry* etex = theResourceManager->getTextureEntry(name, "hires", archive); int textypefound = TEXTYPE_HIRES; if (etex == NULL) { etex = theResourceManager->getTextureEntry(name, "textures", archive); textypefound = TEXTYPE_TEXTURE; } /* if (etex == NULL) { etex = theResourceManager->getTextureEntry(name, "flats", archive); textypefound = TEXTYPE_FLAT; } */ if (etex) { SImage image; // Get image format hint from type, if any if (Misc::loadImageFromEntry(&image, etex)) { mtex.texture = new GLTexture(false); mtex.texture->setFilter(filter); mtex.texture->loadImage(&image, pal); } } // Try composite textures then CTexture* ctex = theResourceManager->getTexture(name, archive); if (ctex && (!mtex.texture || textypefound == TEXTYPE_FLAT)) { textypefound = TEXTYPE_WALLTEXTURE; SImage image; if (ctex->toImage(image, archive, pal)) { mtex.texture = new GLTexture(false); mtex.texture->setFilter(filter); mtex.texture->loadImage(&image, pal); } } // Not found if (!mtex.texture) { // Try flats if mixed if (mixed) return getFlat(name, false); // Otherwise use missing texture else mtex.texture = &(GLTexture::missingTex()); } return mtex.texture; }
GLTexture* MapTextureManager::getSprite(string name, string translation, string palette) { // Don't bother looking for nameless sprites if (name.IsEmpty()) return NULL; // Get sprite matching name string hashname = name.Upper(); if (!translation.IsEmpty()) hashname += translation.Lower(); if (!palette.IsEmpty()) hashname += palette.Upper(); map_tex_t& mtex = sprites[hashname]; // Get desired filter type int filter = 1; if (map_tex_filter == 0) filter = GLTexture::NEAREST_LINEAR_MIN; else if (map_tex_filter == 1) filter = GLTexture::LINEAR; else if (map_tex_filter == 2) filter = GLTexture::LINEAR; else if (map_tex_filter == 3) filter = GLTexture::NEAREST_MIPMAP; // If the texture is loaded if (mtex.texture) { // If the texture filter matches the desired one, return it if (mtex.texture->getFilter() == filter) return mtex.texture; else { // Otherwise, reload the texture delete mtex.texture; mtex.texture = NULL; } } // Sprite not found, look for it bool found = false; bool mirror = false; SImage image; Palette8bit* pal = getResourcePalette(); ArchiveEntry* entry = theResourceManager->getPatchEntry(name, "sprites", archive); if (!entry) entry = theResourceManager->getPatchEntry(name, "", archive); if (!entry && name.length() == 8) { string newname = name; newname[4] = name[6]; newname[5] = name[7]; newname[6] = name[4]; newname[7] = name[5]; entry = theResourceManager->getPatchEntry(newname, "sprites", archive); if (entry) mirror = true; } if (entry) { found = true; Misc::loadImageFromEntry(&image, entry); } else // Try composite textures then { CTexture* ctex = theResourceManager->getTexture(name, archive); if (ctex && ctex->toImage(image, archive, pal)) found = true; } // We have a valid image either from an entry or a composite texture. if (found) { // Apply translation if (!translation.IsEmpty()) image.applyTranslation(translation, pal); // Apply palette override if (!palette.IsEmpty()) { ArchiveEntry* newpal = theResourceManager->getPaletteEntry(palette, archive); if (newpal && newpal->getSize() == 768) { // Why is this needed? // Copying data in pal->loadMem shouldn't // change it in the original entry... // We shouldn't need to copy the data in a temporary place first. pal = image.getPalette(); MemChunk mc; mc.importMem(newpal->getData(), newpal->getSize()); pal->loadMem(mc); } } // Apply mirroring if (mirror) image.mirror(false); // Turn into GL texture mtex.texture = new GLTexture(false); mtex.texture->setFilter(filter); mtex.texture->setTiling(false); mtex.texture->loadImage(&image, pal); return mtex.texture; } else if (name.EndsWith("?")) { name.RemoveLast(1); GLTexture* sprite = getSprite(name + '0', translation, palette); if (!sprite) sprite = getSprite(name + '1', translation, palette); if (sprite) return sprite; if (!sprite && name.length() == 5) { for (char chr = 'A'; chr <= ']'; ++chr) { sprite = getSprite(name + '0' + chr + '0', translation, palette); if (sprite) return sprite; sprite = getSprite(name + '1' + chr + '1', translation, palette); if (sprite) return sprite; } } } return NULL; }
/* MapTextureManager::getTexture * Returns the texture matching [name]. Loads it from resources if * necessary. If [mixed] is true, flats are also searched if no * matching texture is found *******************************************************************/ GLTexture* MapTextureManager::getTexture(string name, bool mixed) { // Get texture matching name map_tex_t& mtex = textures[name.Upper()]; // Get desired filter type int filter = 1; if (map_tex_filter == 0) filter = GLTexture::NEAREST_LINEAR_MIN; else if (map_tex_filter == 1) filter = GLTexture::LINEAR; else if (map_tex_filter == 2) filter = GLTexture::LINEAR_MIPMAP; else if (map_tex_filter == 3) filter = GLTexture::NEAREST_MIPMAP; // If the texture is loaded if (mtex.texture) { // If the texture filter matches the desired one, return it if (mtex.texture->getFilter() == filter) return mtex.texture; else { // Otherwise, reload the texture if (mtex.texture != &(GLTexture::missingTex())) delete mtex.texture; mtex.texture = NULL; } } // Texture not found or unloaded, look for it //Palette8bit* pal = getResourcePalette(); // Look for stand-alone textures first ArchiveEntry* etex = theResourceManager->getTextureEntry(name, "hires", archive); int textypefound = TEXTYPE_HIRES; if (etex == NULL) { etex = theResourceManager->getTextureEntry(name, "textures", archive); textypefound = TEXTYPE_TEXTURE; } if (etex) { SImage image; // Get image format hint from type, if any if (Misc::loadImageFromEntry(&image, etex)) { mtex.texture = new GLTexture(false); mtex.texture->setFilter(filter); mtex.texture->loadImage(&image, palette); // Handle hires texture scale if (textypefound == TEXTYPE_HIRES) { ArchiveEntry* ref = theResourceManager->getTextureEntry(name, "textures", archive); if (ref) { SImage imgref; if (Misc::loadImageFromEntry(&imgref, ref)) { int w, h, sw, sh; w = image.getWidth(); h = image.getHeight(); sw = imgref.getWidth(); sh = imgref.getHeight(); mtex.texture->setScale((double)sw/(double)w, (double)sh/(double)h); } } } } } // Try composite textures then CTexture* ctex = theResourceManager->getTexture(name, archive); if (ctex && (!mtex.texture || textypefound == TEXTYPE_FLAT)) { textypefound = TEXTYPE_WALLTEXTURE; SImage image; if (ctex->toImage(image, archive, palette)) { mtex.texture = new GLTexture(false); mtex.texture->setFilter(filter); mtex.texture->loadImage(&image, palette); double sx = ctex->getScaleX(); if (sx == 0) sx = 1.0; double sy = ctex->getScaleY(); if (sy == 0) sy = 1.0; mtex.texture->setScale(1.0/sx, 1.0/sy); } } // Not found if (!mtex.texture) { // Try flats if mixed if (mixed) return getFlat(name, false); // Otherwise use missing texture else mtex.texture = &(GLTexture::missingTex()); } return mtex.texture; }