Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
// -----------------------------------------------------------------------------
// Returns the sprite matching [name], loading it from resources if necessary.
// Sprite name also supports wildcards (?)
// -----------------------------------------------------------------------------
const MapTextureManager::Texture& MapTextureManager::sprite(
	std::string_view name,
	std::string_view translation,
	std::string_view palette)
{
	// Don't bother looking for nameless sprites
	if (name.empty())
		return tex_invalid;

	// Get sprite matching name
	/*auto hashname = StrUtil::upper(name);
	if (!translation.empty())
		hashname += StrUtil::lower(translation);
	if (!palette.empty())
		hashname += StrUtil::upper(palette);*/
	auto hashname = fmt::format("{}{}{}", name, translation, palette);
	StrUtil::upperIP(hashname);
	auto& mtex = sprites_[hashname];

	// Get desired filter type
	auto filter = OpenGL::TexFilter::Linear;
	if (map_tex_filter == 0)
		filter = OpenGL::TexFilter::NearestLinearMin;
	else if (map_tex_filter == 1)
		filter = OpenGL::TexFilter::Linear;
	else if (map_tex_filter == 2)
		filter = OpenGL::TexFilter::Linear;
	else if (map_tex_filter == 3)
		filter = OpenGL::TexFilter::NearestMipmap;

	// If the texture is loaded
	if (mtex.gl_id)
	{
		// If the texture filter matches the desired one, return it
		auto& tex_info = OpenGL::Texture::info(mtex.gl_id);
		if (tex_info.filter == filter)
			return mtex;
		else
		{
			// Otherwise, reload the texture
			OpenGL::Texture::clear(mtex.gl_id);
			mtex.gl_id = 0;
		}
	}

	// Sprite not found, look for it
	bool   found  = false;
	bool   mirror = false;
	SImage image;
	// Palette8bit* pal = getResourcePalette();
	auto entry = App::resources().getPatchEntry(name, "sprites", archive_);
	if (!entry)
		entry = App::resources().getPatchEntry(name, "", archive_);
	if (!entry && name.length() == 8)
	{
		std::string newname{ name };
		newname[4] = name[6];
		newname[5] = name[7];
		newname[6] = name[4];
		newname[7] = name[5];
		entry      = App::resources().getPatchEntry(newname, "sprites", archive_);
		if (entry)
			mirror = true;
	}
	if (entry)
	{
		found = true;
		Misc::loadImageFromEntry(&image, entry);
	}
	else // Try composite textures then
	{
		auto ctex = App::resources().getTexture(name, archive_);
		if (ctex && ctex->toImage(image, archive_, palette_.get(), true))
			found = true;
	}

	// We have a valid image either from an entry or a composite texture.
	if (found)
	{
		auto pal = palette_.get();

		// Apply translation
		if (!translation.empty())
			image.applyTranslation(translation, pal, true);

		// Apply palette override
		if (!palette.empty())
		{
			auto newpal = App::resources().getPaletteEntry(palette, archive_);
			if (newpal && newpal->size() == 768)
			{
				pal = image.palette();
				pal->loadMem(newpal->data());
			}
		}

		// Apply mirroring
		if (mirror)
			image.mirror(false);

		// Turn into GL texture
		mtex.gl_id = OpenGL::Texture::createFromImage(image, pal, filter, false);
		return mtex;
	}
	else if (name.back() == '?')
	{
		name.remove_suffix(1);
		auto stex = &sprite(fmt::format("{}0", name), translation, palette);
		if (!stex->gl_id)
			stex = &sprite(fmt::format("{}1", name), translation, palette);
		if (stex->gl_id)
			return *stex;
		if (!stex->gl_id && name.length() == 5)
		{
			for (char chr = 'A'; chr <= ']'; ++chr)
			{
				stex = &sprite(fmt::format("{}0{}0", name, chr), translation, palette);
				if (stex->gl_id)
					return *stex;
				stex = &sprite(fmt::format("{}1{}1", name, chr), translation, palette);
				if (stex->gl_id)
					return *stex;
			}
		}
	}

	return tex_invalid;
}