Exemplo n.º 1
0
/* Load a team colour mask texturepage into memory */
static bool dataTexPageTCMaskLoad(const char *fileName, void **ppData)
{
	char texpage[PATH_MAX] = {'\0'};

	// This hackery is needed, because fileName will include the directory name, whilst the LastResourceFilename will not, and we need a short name to identify the texpage
	sstrcpy(texpage, GetLastResourceFilename());

	// Check if a corresponding texpage exists, exit if no
	pie_MakeTexPageName(texpage);
	ASSERT_OR_RETURN(false, resPresent(DT_TEXPAGE, texpage), "Corresponding texpage %s doesn't exists!", texpage);

	pie_MakeTexPageTCMaskName(texpage);
		
	if (!dataImageLoad(fileName, ppData))
	{
		return false;
	}

	// see if this texture page has already been loaded
	if (resPresent(DT_TCMASK, texpage))
	{
		// replace the old texture page with the new one
		debug(LOG_TEXTURE, "replacing %s with new tcmask %s", texpage, fileName);
		pie_ReplaceTexPage((iV_Image *)*ppData, texpage, getTextureSize(), false);
	}
	else
	{
		debug(LOG_TEXTURE, "adding page %s with tcmask %s", texpage, fileName);
		SetLastResourceFilename(texpage);
		pie_AddTexPage((iV_Image *)*ppData, texpage, 0, getTextureSize(), false);
	}

	return true;
}
Exemplo n.º 2
0
/** Retrieve the texture number for a given texture resource.
 *
 *  @note We keep textures in a separate data structure _TEX_PAGE apart from the
 *        normal resource system.
 *
 *  @param filename The filename of the texture page to search for.
 *
 *  @return a non-negative index number for the texture, negative if no texture
 *          with the given filename could be found
 */
int iV_GetTexture(const char *filename)
{
    unsigned int i = 0;
    iV_Image sSprite;
    char path[PATH_MAX];

    /* Have we already loaded this one then? */
    sstrcpy(path, filename);
    pie_MakeTexPageName(path);
    for (i = 0; i < iV_TEX_MAX; i++)
    {
        if (strncmp(path, _TEX_PAGE[i].name, iV_TEXNAME_MAX) == 0)
        {
            return i;
        }
    }

    // Try to load it
    sstrcpy(path, "texpages/");
    sstrcat(path, filename);
    if (!iV_loadImage_PNG(path, &sSprite))
    {
        debug(LOG_ERROR, "Failed to load %s", path);
        return -1;
    }
    sstrcpy(path, filename);
    pie_MakeTexPageName(path);
    return pie_AddTexPage(&sSprite, path, 0, -1, true);	// FIXME, -1, use getTextureSize()
}
Exemplo n.º 3
0
/* Load a texturepage into memory */
static bool dataTexPageLoad(const char *fileName, void **ppData)
{
	char texpage[PATH_MAX] = {'\0'};

	// This hackery is needed, because fileName will include the directory name, whilst the LastResourceFilename will not, and we need a short name to identify the texpage
	sstrcpy(texpage, GetLastResourceFilename());

	pie_MakeTexPageName(texpage);
	if (!dataImageLoad(fileName, ppData))
	{
		return false;
	}

	// see if this texture page has already been loaded
	if (resPresent(DT_TEXPAGE, texpage))
	{
		// replace the old texture page with the new one
		debug(LOG_TEXTURE, "replacing %s with new texture %s", texpage, fileName);
		(void) pie_ReplaceTexPage(*ppData, texpage, getTextureSize(), true);
	}
	else
	{
		debug(LOG_TEXTURE, "adding page %s with texture %s", texpage, fileName);
		SetLastResourceFilename(texpage);
		(void) pie_AddTexPage(*ppData, texpage, 0, getTextureSize(), true);
	}

	return true;
}
Exemplo n.º 4
0
bool replaceTexture(const QString &oldfile, const QString &newfile)
{
	char tmpname[iV_TEXNAME_MAX];

	// Load new one to replace it
	iV_Image image;
	if (!iV_loadImage_PNG(QString("texpages/" + newfile).toUtf8().constData(), &image))
	{
		debug(LOG_ERROR, "Failed to load image: %s", newfile.toUtf8().constData());
		return false;
	}
	sstrcpy(tmpname, oldfile.toUtf8().constData());
	pie_MakeTexPageName(tmpname);
	// Have we already loaded this one?
	for (int i = 0; i < _TEX_PAGE.size(); i++)
	{
		if (strcmp(tmpname, _TEX_PAGE[i].name) == 0)
		{
			GL_DEBUG("Replacing texture");
			debug(LOG_TEXTURE, "Replacing texture %s with %s from index %d (tex id %u)", _TEX_PAGE[i].name, newfile.toUtf8().constData(), i, _TEX_PAGE[i].id);
			sstrcpy(tmpname, newfile.toUtf8().constData());
			pie_MakeTexPageName(tmpname);
			pie_AddTexPage(&image, tmpname, true, i);
			iV_unloadImage(&image);
			return true;
		}
	}
	iV_unloadImage(&image);
	debug(LOG_ERROR, "Nothing to replace!");
	return false;
}
Exemplo n.º 5
0
/** Retrieve the texture number for a given texture resource.
 *
 *  @note We keep textures in a separate data structure _TEX_PAGE apart from the
 *        normal resource system.
 *
 *  @param filename The filename of the texture page to search for.
 *  @param compression If we need to load it, should we use texture compression?
 *
 *  @return a non-negative index number for the texture, negative if no texture
 *          with the given filename could be found
 */
int iV_GetTexture(const char *filename, bool compression)
{
	iV_Image sSprite;
	char path[PATH_MAX];

	/* Have we already loaded this one then? */
	sstrcpy(path, filename);
	pie_MakeTexPageName(path);
	for (int i = 0; i < _TEX_PAGE.size(); i++)
	{
		if (strncmp(path, _TEX_PAGE[i].name, iV_TEXNAME_MAX) == 0)
		{
			return i;
		}
	}

	// Try to load it
	sstrcpy(path, "texpages/");
	sstrcat(path, filename);
	if (!iV_loadImage_PNG(path, &sSprite))
	{
		debug(LOG_ERROR, "Failed to load %s", path);
		return -1;
	}
	sstrcpy(path, filename);
	pie_MakeTexPageName(path);
	return pie_AddTexPage(&sSprite, path, compression);
}
Exemplo n.º 6
0
/**************************************************************************
	WRF files may specify overrides for the textures on a map. This
	is done through an ugly hack involving cutting the texture name
	down to just "page-NN", where NN is the page number, and
	replaceing the texture page with the same name if another file
	with this prefix is loaded.
**************************************************************************/
int pie_ReplaceTexPage(iV_Image *s, const char *texPage, int maxTextureSize, bool useMipmaping)
{
    int i = iV_GetTexture(texPage);

    ASSERT(i >= 0, "pie_ReplaceTexPage: Cannot find any %s to replace!", texPage);
    if (i < 0)
    {
        return -1;
    }

    glDeleteTextures(1, &_TEX_PAGE[i].id);
    debug(LOG_TEXTURE, "Reloading texture %s from index %d", texPage, i);
    _TEX_PAGE[i].name[0] = '\0';
    pie_AddTexPage(s, texPage, i, maxTextureSize, useMipmaping);

    return i;
}
Exemplo n.º 7
0
static unsigned short LoadTextureFile(const char *FileName)
{
	iV_Image *pSprite;
	unsigned int i;

	ASSERT_OR_RETURN( 0, resPresent("IMGPAGE", FileName), "Texture file \"%s\" not preloaded.", FileName);

	pSprite = (iV_Image*)resGetData("IMGPAGE", FileName);
	debug(LOG_TEXTURE, "Load texture from resource cache: %s (%d, %d)",
	      FileName, pSprite->width, pSprite->height);

	/* Have we already uploaded this one? */
	for (i = 0; i < _TEX_INDEX; ++i)
	{
		if (strcasecmp(FileName, _TEX_PAGE[i].name) == 0)
		{
			debug(LOG_TEXTURE, "LoadTextureFile: already uploaded");
			return _TEX_PAGE[i].id;
		}
	}

	debug(LOG_TEXTURE, "LoadTextureFile: had to upload texture!");
	return pie_AddTexPage(pSprite, FileName, 0, 0, true);
}
Exemplo n.º 8
0
IMAGEFILE *iV_LoadImageFile(const char *fileName)
{
	// Find the directory of images.
	std::string imageDir = fileName;
	if (imageDir.find_last_of('.') != std::string::npos)
	{
		imageDir.erase(imageDir.find_last_of('.'));
	}
	imageDir += '/';

	// Load the image list file.
	char *pFileData;
	unsigned pFileSize;
	if (!loadFile(fileName, &pFileData, &pFileSize))
	{
		debug(LOG_ERROR, "iV_LoadImageFile: failed to open %s", fileName);
		return NULL;
	}

	char *ptr = pFileData;
	// count lines, which is identical to number of images
	int numImages = 0;
	while (ptr < pFileData + pFileSize && *ptr != '\0')
	{
		numImages += *ptr == '\n';
		++ptr;
	}
	IMAGEFILE *imageFile = new IMAGEFILE;
	imageFile->imageDefs.resize(numImages);
	imageFile->imageNames.resize(numImages);
	ImageMerge pageLayout;
	pageLayout.images.resize(numImages);
	ptr = pFileData;
	numImages = 0;
	while (ptr < pFileData + pFileSize)
	{
		int temp, retval;
		ImageDef *ImageDef = &imageFile->imageDefs[numImages];

		char tmpName[256];
		retval = sscanf(ptr, "%d,%d,%255[^\r\n\",]%n", &ImageDef->XOffset, &ImageDef->YOffset, tmpName, &temp);
		if (retval != 3)
		{
			debug(LOG_ERROR, "Bad line in \"%s\".", fileName);
			return NULL;
		}
		imageFile->imageNames[numImages].first = tmpName;
		imageFile->imageNames[numImages].second = numImages;
		std::string spriteName = imageDir + tmpName;

		ImageMergeRectangle *imageRect = &pageLayout.images[numImages];
		imageRect->index = numImages;
		imageRect->data = new iV_Image;
		if (!iV_loadImage_PNG(spriteName.c_str(), imageRect->data))
		{
			debug(LOG_ERROR, "Failed to find image \"%s\" listed in \"%s\".", spriteName.c_str(), fileName);
			return NULL;
		}
		imageRect->siz = Vector2i(imageRect->data->width, imageRect->data->height);
		numImages++;
		ptr += temp;
		while (ptr < pFileData + pFileSize && *ptr++ != '\n') {} // skip rest of line

		images.insert(tmpName, ImageDef);
	}
	free(pFileData);

	std::sort(imageFile->imageNames.begin(), imageFile->imageNames.end());

	pageLayout.arrange();  // Arrange all the images onto texture pages (attempt to do so with as few pages as possible).
	imageFile->pages.resize(pageLayout.pages.size());

	std::vector<iV_Image> ivImages(pageLayout.pages.size());

	for (unsigned p = 0; p < pageLayout.pages.size(); ++p)
	{
		int size = pageLayout.pages[p];
		ivImages[p].depth = 4;
		ivImages[p].width = size;
		ivImages[p].height = size;
		ivImages[p].bmp = (unsigned char *)malloc(size*size*4);  // MUST be malloc, since this is free()d later by pie_AddTexPage().
		memset(ivImages[p].bmp, 0x00, size*size*4);
		imageFile->pages[p].size = size;
		// Must set imageFile->pages[p].id later, after filling out ivImages[p].bmp.
	}

	for (std::vector<ImageMergeRectangle>::const_iterator r = pageLayout.images.begin(); r != pageLayout.images.end(); ++r)
	{
		imageFile->imageDefs[r->index].TPageID = r->page;
		imageFile->imageDefs[r->index].Tu = r->loc.x;
		imageFile->imageDefs[r->index].Tv = r->loc.y;
		imageFile->imageDefs[r->index].Width = r->siz.x;
		imageFile->imageDefs[r->index].Height = r->siz.y;

		// Copy image data onto texture page.
		iV_Image *srcImage = r->data;
		int srcDepth = srcImage->depth;
		int srcStride = srcImage->width*srcDepth;  // Not sure whether to pad in the case that srcDepth ≠ 4, however this apparently cannot happen.
		unsigned char *srcBytes = srcImage->bmp + 0*srcDepth + 0*srcStride;
		iV_Image *dstImage = &ivImages[r->page];
		int dstDepth = dstImage->depth;
		int dstStride = dstImage->width*dstDepth;
		unsigned char *dstBytes = dstImage->bmp + r->loc.x*dstDepth + r->loc.y*dstStride;
		Vector2i size = r->siz;
		unsigned char rgba[4] = {0x00, 0x00, 0x00, 0xFF};
		for (int y = 0; y < size.y; ++y)
			for (int x = 0; x < size.x; ++x)
		{
			memcpy(rgba, srcBytes + x*srcDepth + y*srcStride, srcDepth);
			memcpy(dstBytes + x*dstDepth + y*dstStride, rgba, dstDepth);
		}

		// Finished reading the image data and copying it to the texture page, delete it.
		free(r->data->bmp);
		delete r->data;
	}

	// Debug usage only. Dump all images to disk (do mkdir images/, first). Doesn't dump the alpha channel, since the .ppm format doesn't support that.
	/*for (unsigned p = 0; p < pageLayout.pages.size(); ++p)
	{
		char fName[100];
		sprintf(fName, "%s-%d", fileName, p);
		printf("Dump %s\n", fName);
		FILE *f = fopen(fName, "wb");
		iV_Image *image = &ivImages[p];
		fprintf(f, "P6\n%d %d\n255\n", image->width, image->height);
		for (int x = 0; x < image->width*image->height; ++x)
			if (fwrite(image->bmp + x*4, 3, 1, f) == 0)
				abort();
		fclose(f);
	}*/

	// Upload texture pages and free image data.
	for (unsigned p = 0; p < pageLayout.pages.size(); ++p)
	{
		char arbitraryName[256];
		ssprintf(arbitraryName, "%s-%03u", fileName, p);
		// Now we can set imageFile->pages[p].id. This free()s the ivImages[p].bmp array!
		imageFile->pages[p].id = pie_AddTexPage(&ivImages[p], arbitraryName, 0, 0, true);
	}

	// duplicate some data, since we want another access point to these data structures now, FIXME
	for (unsigned i = 0; i < imageFile->imageDefs.size(); i++)
	{
		imageFile->imageDefs[i].textureId = imageFile->pages[imageFile->imageDefs[i].TPageID].id;
		imageFile->imageDefs[i].invTextureSize = 1.f / imageFile->pages[imageFile->imageDefs[i].TPageID].size;
	}

	files.append(imageFile);

	return imageFile;
}