Пример #1
0
/* 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;
}
Пример #2
0
/* TextureXPanel::paste
 * Pastes any textures on the clipboard after the last selected
 * texture
 *******************************************************************/
void TextureXPanel::paste()
{
	// Check there is anything on the clipboard
	if (theClipboard->nItems() == 0)
		return;

	// Get last selected index
	int selected = list_textures->getLastSelected();
	if (selected == -1) selected = texturex.nTextures() - 1; // Add to end of the list if nothing selected

	// Begin recording undo level
	undo_manager->beginRecord("Paste Texture(s)");

	// Go through clipboard items
	for (unsigned a = 0; a < theClipboard->nItems(); a++)
	{
		// Skip if not a texture clipboard item
		if (theClipboard->getItem(a)->getType() != CLIPBOARD_COMPOSITE_TEXTURE)
			continue;

		// Get texture item
		TextureClipboardItem* item = (TextureClipboardItem*)(theClipboard->getItem(a));

		// Add new texture after last selected item
		CTexture* ntex = new CTexture((texturex.getFormat() == TXF_TEXTURES));
		ntex->copyTexture(item->getTexture(), true);
		ntex->setState(2);
		texturex.addTexture(ntex, ++selected);

		// Record undo step
		undo_manager->recordUndoStep(new TextureCreateDeleteUS(this, ntex, true));

		// Deal with patches
		for (unsigned p = 0; p < ntex->nPatches(); p++)
		{
			CTPatch* patch = ntex->getPatch(p);

			// Update patch table if necessary
			if (texturex.getFormat() != TXF_TEXTURES)
				tx_editor->patchTable().addPatch(patch->getName());

			// Get the entry for this patch
			ArchiveEntry* entry = patch->getPatchEntry(tx_editor->getArchive());

			// If the entry wasn't found in any open archive, try copying it from the clipboard
			// (the user may have closed the archive the original patch was in)
			if (!entry)
			{
				entry = item->getPatchEntry(patch->getName());

				// Copy the copied patch entry over to this archive
				if (entry)
					tx_editor->getArchive()->addEntry(entry, "patches", true);
			}

			// If the entry exists in the base resource archive or this archive, do nothing
			else if (entry->getParent() == theArchiveManager->baseResourceArchive() ||
			         entry->getParent() == tx_editor->getArchive())
				continue;

			// Otherwise, copy the entry over to this archive
			else
				tx_editor->getArchive()->addEntry(entry, "patches", true);
		}
	}

	// End recording undo level
	undo_manager->endRecord(true);

	// Refresh
	list_textures->updateList();

	// Update variables
	modified = true;
}
Пример #3
0
/* CTexture::toImage
 * Generates a SImage representation of this texture, using patches
 * from [parent] primarily, and the palette [pal]
 *******************************************************************/
bool CTexture::toImage(SImage& image, Archive* parent, Palette8bit* pal, bool force_rgba)
{
	// Init image
	image.clear();
	image.resize(width, height);

	// Add patches
	SImage p_img(PALMASK);
	si_drawprops_t dp;
	dp.src_alpha = false;
	if (defined)
	{
		CTPatchEx* patch = (CTPatchEx*)patches[0];
		if (!loadPatchImage(0, p_img, parent, pal))
			return false;
		width = p_img.getWidth();
		height = p_img.getHeight();
		image.resize(width, height);
		scale_x = (double)width / (double)def_width;
		scale_y = (double)height / (double)def_height;
		image.drawImage(p_img, 0, 0, dp, pal, pal);
	}
	else if (extended)
	{
		// Extended texture

		// Add each patch to image
		for (unsigned a = 0; a < patches.size(); a++)
		{
			CTPatchEx* patch = (CTPatchEx*)patches[a];

			// Load patch entry
			if (!loadPatchImage(a, p_img, parent, pal))
				continue;

			// Handle offsets
			int ofs_x = patch->xOffset();
			int ofs_y = patch->yOffset();
			if (patch->useOffsets())
			{
				ofs_x -= p_img.offset().x;
				ofs_y -= p_img.offset().y;
			}

			// Apply translation before anything in case we're forcing rgba (can't translate rgba images)
			if (patch->getBlendType() == 1)
				p_img.applyTranslation(&(patch->getTranslation()), pal);

			// Convert to RGBA if forced
			if (force_rgba)
				p_img.convertRGBA(pal);

			// Flip/rotate if needed
			if (patch->flipX())
				p_img.mirror(false);
			if (patch->flipY())
				p_img.mirror(true);
			if (patch->getRotation() != 0)
				p_img.rotate(patch->getRotation());

			// Setup transparency blending
			dp.blend = NORMAL;
			dp.alpha = 1.0f;
			dp.src_alpha = false;
			if (patch->getStyle() == "CopyAlpha" || patch->getStyle() == "Overlay")
				dp.src_alpha = true;
			else if (patch->getStyle() == "Translucent" || patch->getStyle() == "CopyNewAlpha")
				dp.alpha = patch->getAlpha();
			else if (patch->getStyle() == "Add")
			{
				dp.blend = ADD;
				dp.alpha = patch->getAlpha();
			}
			else if (patch->getStyle() == "Subtract")
			{
				dp.blend = SUBTRACT;
				dp.alpha = patch->getAlpha();
			}
			else if (patch->getStyle() == "ReverseSubtract")
			{
				dp.blend = REVERSE_SUBTRACT;
				dp.alpha = patch->getAlpha();
			}
			else if (patch->getStyle() == "Modulate")
			{
				dp.blend = MODULATE;
				dp.alpha = patch->getAlpha();
			}

			// Setup patch colour
			if (patch->getBlendType() == 2)
				p_img.colourise(patch->getColour(), pal);
			else if (patch->getBlendType() == 3)
				p_img.tint(patch->getColour(), patch->getColour().fa(), pal);


			// Add patch to texture image
			image.drawImage(p_img, ofs_x, ofs_y, dp, pal, pal);
		}
	}
	else
	{
		// Normal texture

		// Add each patch to image
		for (unsigned a = 0; a < patches.size(); a++)
		{
			CTPatch* patch = patches[a];
			if (Misc::loadImageFromEntry(&p_img, patch->getPatchEntry(parent)))
				image.drawImage(p_img, patch->xOffset(), patch->yOffset(), dp, pal, pal);
		}
	}

	return true;
}