/*=========================================================================== * * File: Dftexture.CPP * Author: Dave Humphrey (uesp@m0use.net) * Created On: Thursday, June 28, 2001 * * Implements the CDFTextureFileFile class for manipulating Daggerfall texture * files. * *=========================================================================*/ /* Include Files */ #include "dftexture.h" #include "dfpal.h" /*=========================================================================== * * Begin Local Variable Definitions * *=========================================================================*/ DEFINE_FILE(); /*=========================================================================== * End of Local Variable Definitions *=========================================================================*/ /*=========================================================================== * * Class CDFTextureFile Constructor * *=========================================================================*/ CDFTextureFile::CDFTextureFile() { m_NumImages = 0; m_Tag = 0; m_Name[0] = NULL_CHAR; /* Initialize the image and offset arrays */ m_pImages = NULL; m_pOffsets = NULL; } /*=========================================================================== * End of Class CDFTextureFile Constructor *=========================================================================*/ /*=========================================================================== * * Class CDFTextureFile Destructor * *=========================================================================*/ void CDFTextureFile::Destroy (void) { /* Unallocate the image and offset arrays */ DestroyArrayPointer(m_pImages); DestroyArrayPointer(m_pOffsets); m_Name[0] = NULL_CHAR; m_NumImages = 0; m_Tag = 0; } /*=========================================================================== * End of Class CDFTextureFile Destructor *=========================================================================*/ /*=========================================================================== * * Class CDFTextureFile Method - void AllocateArrays (NumImages); * * Protected class method to allocate the image and offset arrays. * *=========================================================================*/ void CDFTextureFile::AllocateArrays (const int NumImages) { DEFINE_FUNCTION("CDFTextureFile::AllocateArrays()"); /* Ensure valid object state and input */ ASSERT(m_pImages == NULL && m_pOffsets == NULL); ASSERT(NumImages > 0); /* Allocate the arrays */ CreateArrayPointer(m_pImages, CDFTextureImage, NumImages); CreateArrayPointer(m_pOffsets, dftextureoffset_t, NumImages); m_NumImages = NumImages; } /*=========================================================================== * End of Class Method CDFTextureFile::AllocateArrays() *=========================================================================*/ /*=========================================================================== * * Class CDFTextureFile Method - void ClearTags (void); * * Clears the tags for all the texture sub-images. * *=========================================================================*/ void CDFTextureFile::ClearTags (void) { int LoopCounter; for (LoopCounter = 0; LoopCounter < m_NumImages; LoopCounter++) { m_pImages[LoopCounter].SetTag(0); } } /*=========================================================================== * End of Class Method CDFTextureFile::ClearTags() *=========================================================================*/ /*=========================================================================== * * Class CDFTextureFile Method - boolean Load (pFilename); * * Attempt to load the entire texture file. Returns FALSE on any error. * *=========================================================================*/ boolean CDFTextureFile::Load (const char* pFilename) { DEFINE_FUNCTION("CDFTextureFile::Load(char*)"); boolean Result; /* Delete the current image information */ Destroy(); /* Attempt to open file for input */ Result = Open(pFilename, "rb"); if (!Result) return (FALSE); /* Read in the file */ Result = Read(); Close(); return (Result); } /*=========================================================================== * End of Class Method CDFTextureFile::Load() *=========================================================================*/ /*=========================================================================== * * Class CDFTextureFile Method - boolean Load (pFileHandle); * * Attempt to load the entire texture file based on an existing file handle. * Returns FALSE on any error. * *=========================================================================*/ boolean CDFTextureFile::Load (FILE* pFileHandle) { DEFINE_FUNCTION("CDFTextureFile::Load(FILE*)"); boolean Result; /* Ensure valid input */ if (pFileHandle == NULL) return (FALSE); /* Delete the current image information */ Destroy(); m_pFileHandle = pFileHandle; /* Read in the file */ Result = Read(); Close(); return (Result); } /*=========================================================================== * End of Class Method CDFTextureFile::Load() *=========================================================================*/ /*=========================================================================== * * Class CDFTextureFile Method - boolean Read (void); * * Helper function to read a texture file once it has been opened. * Returns FALSE on any error. Protected class method. * *=========================================================================*/ boolean CDFTextureFile::Read (void) { DEFINE_FUNCTION("CDFTextureFile::Read()"); boolean Result; /* Read in the header, offset and image data */ Result = ReadHeader(); if (Result) Result = ReadOffsets(); if (Result) Result = ReadImages(); return (Result); } /*=========================================================================== * End of Class Method CDFTextureFile::ReadOffsets() *=========================================================================*/ /*=========================================================================== * * Class CDFTextureFile Method - boolean ReadHeader (void); * * Attempt to read the texture header data from the current position in * thje file stream. Returns FALSE on any error. Protected class method. * *=========================================================================*/ boolean CDFTextureFile::ReadHeader (void) { DEFINE_FUNCTION("CDFTextureFile::ReadHeader()"); boolean Result; short NumImages; /* Move to the start of the header data and read data */ Result = Seek(DFTEXTURE_HEADER_OFFSET, SEEK_SET); if (Result) Result = ReadShort(NumImages); if (Result) Result = CGenFile::Read(m_Name, DFTEXTURE_NAME_SIZE); if (!Result) return (FALSE); /* Ensure a valid number of images */ if (NumImages < 0 || NumImages >= DFTEXTURE_MAX_IMAGES) { ErrorHandler.AddError(DFERR_TEXTURE_NUMIMAGES, "NumImages=%d", NumImages); return (FALSE); } /* Allocate the arrays */ AllocateArrays(NumImages); return (TRUE); } /*=========================================================================== * End of Class Method CDFTextureFile::ReadHeader() *=========================================================================*/ /*=========================================================================== * * Class CDFTextureFile Method - boolean ReadImages (void); * * Attempt to read the image data from the current position in the file * stream. Returns FALSE on any error. Protected class member. * *=========================================================================*/ boolean CDFTextureFile::ReadImages (void) { DEFINE_FUNCTION("CDFTextureFile::ReadImages()"); boolean Result; int ImageIndex; /* Ensure valid object state */ ASSERT(m_pOffsets != NULL && m_pImages != NULL); /* Input all image data */ for (ImageIndex = 0; ImageIndex < m_NumImages; ImageIndex++) { /* Ignore if image offset is zero (for textures 000 and 001) */ if (m_pOffsets[ImageIndex].HeaderOffset == 0) continue; /* Jump to image header position and read */ Result = Seek(m_pOffsets[ImageIndex].HeaderOffset, SEEK_SET); m_pImages[ImageIndex].Attach(GetHandle()); if (Result) Result = m_pImages[ImageIndex].Read(); m_pImages[ImageIndex].Detach(); if (!Result) return (FALSE); } return (TRUE); } /*=========================================================================== * End of Class Method CDFTextureFile::ReadImages() *=========================================================================*/ /*=========================================================================== * * Class CDFTextureFile Method - boolean ReadOffsets (void); * * Attempt to read the texture offset data from the current position in * the file stream. Returns FALSE on any error. Protected class method. * *=========================================================================*/ boolean CDFTextureFile::ReadOffsets (void) { DEFINE_FUNCTION("CDFTextureFile::ReadOffsets()"); boolean Result; /* Move to the start of the offset records and read */ Result = Seek(DFTEXTURE_OFFSETLIST_OFFSET, SEEK_SET); if (Result) Result = CGenFile::ReadEx((char *) m_pOffsets, DFTEXTURE_OFFSET_RECORDSIZE, m_NumImages); return (Result); } /*=========================================================================== * End of Class Method CDFTextureFile::ReadOffsets() *=========================================================================*/ /*=========================================================================== * * Function - rgbpalraw_t GetDFTextureSolidColor (TextureIndex, ImageIndex); * * Returns a DF palette entry for the given solid color texture. TextureIndex * must be 0 or 1 and ImageIndex from 0 to 127. Invalid indices will result * in black (0) being returned. * *=========================================================================*/ rgbpalraw_t GetDFTextureSolidColor (const int TextureIndex, const int ImageIndex) { rgbpalraw_t* pPalette = GetDefaultDFPal(); /* Ensure valid indices */ if (!IsValidDFTextureIndex(TextureIndex) || (ImageIndex < 0 || ImageIndex > 127)) { return (pPalette[0]); } return (pPalette[TextureIndex*128 + ImageIndex]); } /*=========================================================================== * End of Function GetDFTextureSolidColor() *=========================================================================*/ /*=========================================================================== * * Function - boolean IsDFTextureSolidColor (Index); * * Returns TRUE if the given texture index represents one of the special * solid color textures (0 and 1). * *=========================================================================*/ boolean IsDFTextureSolidColor (const int Index) { if (Index == 0 || Index == 1) return (TRUE); return (FALSE); } /*=========================================================================== * End of Function IsDFTextureSolidColor() *=========================================================================*/ /*=========================================================================== * * Function - boolean IsValidDFTextureIndex (Index); * * Returns TRUE if the given index is a valid Daggerfall texture index. * *=========================================================================*/ boolean IsValidDFTextureIndex (const int Index) { if (Index < 0 || Index >= DFTEXTURE_MAXFILES) { ErrorHandler.AddError(DFERR_TEXTURE_BADINDEX, "Invalid texture index %d received!", Index); return (FALSE); } return (TRUE); } /*=========================================================================== * End of Function IsValidDFTextureIndex() *=========================================================================*/