Esempio n. 1
0
/* PaletteManager::loadCustomPalettes
 * Loads any files in the '<userdir>/palettes' directory as palettes,
 * with names from the files (minus the file extension)
 *******************************************************************/
bool PaletteManager::loadCustomPalettes()
{
	// If the directory doesn't exist create it
	if (!wxDirExists(appPath("palettes", DIR_USER)))
		wxMkdir(appPath("palettes", DIR_USER));

	// Open the custom palettes directory
	wxDir res_dir;
	res_dir.Open(appPath("palettes", DIR_USER));

	// Go through each file in the directory
	string filename = wxEmptyString;
	bool files = res_dir.GetFirst(&filename, wxEmptyString, wxDIR_FILES);
	while (files)
	{
		// Load palette data
		Palette8bit* pal = new Palette8bit();
		MemChunk mc;
		mc.importFile(res_dir.GetName() + "/" + filename);
		pal->loadMem(mc);

		// Add the palette
		wxFileName fn(filename);
		addPalette(pal, fn.GetName());

		// Next file
		files = res_dir.GetNext(&filename);
	}

	return true;
}
Esempio n. 2
0
/* PaletteEntryPanel::loadEntry
 * Reads all palettes in the PLAYPAL entry and shows the first one
 *******************************************************************/
bool PaletteEntryPanel::loadEntry(ArchiveEntry* entry)
{
	// Clear any existing palettes
	for (size_t a = 0; a < palettes.size(); a++)
		delete palettes[a];
	palettes.clear();

	// Determine how many palettes are in the entry
	int n_palettes = entry->getSize() / 768;

	// Load each palette
	entry->seek(0, SEEK_SET);
	uint8_t pal_data[768];
	for (int a = 0; a < n_palettes; a++)
	{
		// Read palette data
		entry->read(&pal_data, 768);

		// Create palette
		Palette8bit* pal = new Palette8bit();
		pal->loadMem(pal_data, 768);

		// Add palette
		palettes.push_back(pal);
	}

	// Show first palette
	cur_palette = 0;
	showPalette(0);

	setModified(false);

	return true;
}
Esempio n. 3
0
	bool readImage(SImage& image, MemChunk& data, int index)
	{
		// Get image info
		SImage::info_t info;
		FIBITMAP* bm = getFIInfo(data, info);

		// Check it created/read ok
		if (!bm)
		{
			Global::error = "Unable to read image data (unsupported format?)";
			return false;
		}

		// Get image palette if it exists
		RGBQUAD* bm_pal = FreeImage_GetPalette(bm);
		Palette8bit palette;
		if (bm_pal)
		{
			int a = 0;
			int b = FreeImage_GetColorsUsed(bm);
			if (b > 256)
				b = 256;
			for (; a < b; a++)
				palette.setColour(a, rgba_t(bm_pal[a].rgbRed, bm_pal[a].rgbGreen, bm_pal[a].rgbBlue, 255));
		}

		// Create image
		if (info.has_palette)
			image.create(info, &palette);
		else
			image.create(info);
		uint8_t* img_data = imageData(image);

		// Convert to 32bpp & flip vertically
		FIBITMAP* rgba = FreeImage_ConvertTo32Bits(bm);
		FreeImage_FlipVertical(rgba);

		// Load raw RGBA data
		uint8_t* bits_rgba = FreeImage_GetBits(rgba);
		int c = 0;
		for (int a = 0; a < info.width * info.height; a++)
		{
			img_data[c++] = bits_rgba[a * 4 + 2];	// Red
			img_data[c++] = bits_rgba[a * 4 + 1];	// Green
			img_data[c++] = bits_rgba[a * 4];		// Blue
			img_data[c++] = bits_rgba[a * 4 + 3];	// Alpha
		}

		// Free memory
		FreeImage_Unload(rgba);
		FreeImage_Unload(bm);

		return true;
	}
Esempio n. 4
0
/* PaletteEntryPanel::duplicate
 * Make a copy of the current palette and add it to the list
 *******************************************************************/
bool PaletteEntryPanel::duplicate()
{
	Palette8bit* newpalette = new Palette8bit;
	if (!newpalette)
		return false;

	newpalette->copyPalette(palettes[cur_palette]);
	palettes.push_back(newpalette);

	// Refresh the display to show the updated amount of palettes
	showPalette(cur_palette);
	setModified();
	return true;
}
Esempio n. 5
0
/* PaletteEntryPanel::testPalette
 * A "lite" version of addCustomPalette, which does not add to the
 * palette folder so the palette is only available for the current
 * session.
 *******************************************************************/
bool PaletteEntryPanel::testPalette()
{
	// Get name to export as
	string name = "Test: " + wxGetTextFromUser("Enter name for Palette:", "Test Palettes");

	// Add to palette manager and main palette chooser
	Palette8bit* pal = new Palette8bit();
	pal->copyPalette(palettes[cur_palette]);
	thePaletteManager->addPalette(pal, name);
	thePaletteChooser->addPalette(name);
	thePaletteChooser->selectPalette(name);

	return true;
}
Esempio n. 6
0
/* PaletteEntryPanel::tweak
 * Tweaks the colours of the current palette
 *******************************************************************/
bool PaletteEntryPanel::tweak()
{
	Palette8bit* pal = new Palette8bit;
	if (pal == NULL) return false;
	pal->copyPalette(palettes[cur_palette]);
	PaletteColourTweakDialog pctd(theMainWindow, pal);
	if (pctd.ShowModal() == wxID_OK)
	{
		palettes[cur_palette]->copyPalette(pctd.getFinalPalette());
		showPalette(cur_palette);
		setModified();
	}
	delete pal;
	return true;
}
Esempio n. 7
0
/* PaletteEntryPanel::generatePalette
 * Just a helper for generatePalettes to make the code less redundant
 *******************************************************************/
void PaletteEntryPanel::generatePalette(int r, int g, int b, int shift, int steps)
{
	// Create a new palette
	Palette8bit* pal = new Palette8bit;
	if (pal == NULL) return;

	// Seed it with the basic palette
	pal->copyPalette(palettes[0]);

	// Tint palette with given values
	pal->idtint(r, g, b, shift, steps);

	// Add it to the palette list
	palettes.push_back(pal);
}
Esempio n. 8
0
/* SImage::shrinkPalette
 * Shifts all the used colours to the beginning of the palette
 *******************************************************************/
void SImage::shrinkPalette(Palette8bit* pal)
{
	// If the picture is not paletted, stop.
	if (type != PALMASK)
		return;

	// Get palette to use
	if (has_palette || !pal)
		pal = &palette;

	// Init variables
	Palette8bit newpal;
	bool* usedcolours = new bool[256];
	int* remap = new int[256];
	memset(usedcolours, 0, 256);
	size_t used = 0;

	// Count all color indices actually used on the picture
	for (int a = 0; a < width*height; ++a)
	{
		usedcolours[data[a]] = true;
	}

	// Create palette remapping information
	for (size_t b = 0; b < 256; ++b)
	{
		if (usedcolours[b])
		{
			newpal.setColour(used, pal->colour(b));
			remap[b] = used;
			++used;
		}
	}

	// Remap image to new palette indices
	for (int c = 0; c < width*height; ++c)
	{
		data[c] = remap[data[c]];
	}
	pal->copyPalette(&newpal);

	// Cleanup
	delete[] usedcolours;
	delete[] remap;
}
Esempio n. 9
0
/* PaletteEntryPanel::addCustomPalette
 * Adds the current palette to the custom user palettes folder, so
 * it can be selected via the palette selector
 *******************************************************************/
bool PaletteEntryPanel::addCustomPalette()
{
	// Get name to export as
	string name = wxGetTextFromUser("Enter name for Palette:", "Add to Palettes");
	if (name.IsEmpty())
		return false;

	// Write current palette to the user palettes directory
	string path = appPath(S_FMT("palettes/%s.pal", name), DIR_USER);
	palettes[cur_palette]->saveFile(path);

	// Add to palette manager and main palette chooser
	Palette8bit* pal = new Palette8bit();
	pal->copyPalette(palettes[cur_palette]);
	thePaletteManager->addPalette(pal, name);
	thePaletteChooser->addPalette(name);

	return true;
}
Esempio n. 10
0
/* PaletteManager::loadResourcePalettes
 * Loads any entries in the 'palettes' directory of SLADE.pk3 as
 * palettes, with names from the entries (minus the entry extension)
 *******************************************************************/
bool PaletteManager::loadResourcePalettes()
{
	// Get the 'palettes' directory of SLADE.pk3
	Archive* res_archive = theArchiveManager->programResourceArchive();
	ArchiveTreeNode* dir_palettes = res_archive->getDir("palettes/");

	// Check it exists
	if (!dir_palettes)
		return false;

	// Go through all entries in the directory
	for (size_t a = 0; a < dir_palettes->numEntries(); a++)
	{
		// Load palette data
		Palette8bit* pal = new Palette8bit();
		MemChunk mc(dir_palettes->getEntry(a)->getData(true), dir_palettes->getEntry(a)->getSize());
		pal->loadMem(mc);

		// Add the palette
		addPalette(pal, dir_palettes->getEntry(a)->getName(true));
	}

	return true;
}
Esempio n. 11
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;
}