/*=========================================================================== * * DFCif.CPP - Dave Humphrey (uesp@m0use.net), 4 November 2000 * *=========================================================================*/ /* Includes */ #include "dfcif.h" #include "dfcommon.h" #undef __FUNC__ #define __FUNC__ "CDFCifFile::CDFCifFile()" /*=========================================================================== * * Class CDFCifFile Constructor * *=========================================================================*/ CDFCifFile::CDFCifFile() { NumImages = 0; } /*=========================================================================== * End of Class CDFCifFile Constructor *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CDFCifFile::Destroy()" /*=========================================================================== * * Class CDFCifFile Destructor * *=========================================================================*/ void CDFCifFile::Destroy (void) { int LoopCounter; for (LoopCounter = 0; LoopCounter < NumImages; LoopCounter++) { DestroyPointer(pImages[LoopCounter]); } NumImages = 0; } /*=========================================================================== * End of Class CDFCifFile Destructor *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CDFCifFile::Load()" /*=========================================================================== * * Class CDFCifFile Method - boolean Load (pFilename); * * Attempts to read in the given CIF file. Returns FALSE on any error. * *=========================================================================*/ boolean CDFCifFile::Load (const char* pFilename) { FILE* pFileHandle; boolean Result = TRUE; /* Attempt to open file for input */ pFileHandle = openfile(pFilename, "rb"); if (pFileHandle == NULL) { SET_EXT_ERROR3(ERR_FILE, "Failed to open file %s!", pFilename); return (FALSE); } /* Read a regular or weapon CIF file */ if (IsWeaponCIFFilename(pFilename)) Result = ReadWeaponCIF(pFileHandle); else Result = ReadCIF(pFileHandle); fclose (pFileHandle); return (Result); } /*=========================================================================== * End of Class Method CDFCifFile::Load() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CDFCifFile::ReadCIF()" /*=========================================================================== * * Class CDFCifFile Method - boolean ReadCIF (pFileHandle); * * Attempts to read in the regular CIF file. Returns FALSE on any error. * *=========================================================================*/ boolean CDFCifFile::ReadCIF (FILE* pFileHandle) { long FileSize; boolean Result = TRUE; /* Get the filesize */ FileSize = GetFilesize(pFileHandle); /* Check for errors and the special FACES.CIF file */ if (FileSize == INVALID_FILESIZE) { SET_EXT_ERROR2(ERR_READ, "Invalid filesize received!"); return (FALSE); } /* Destroy the current image information */ Destroy(); /* Read in image data until no more left */ while (FileSize - ftell(pFileHandle) >= DFCIF_MINBYTES_LEFT) { /* Ensure we don't load too many images to overflow array */ if (NumImages >= DFCIF_MAX_IMAGES) { SET_EXT_ERROR3(ERR_MAXINDEX, "Maximum number of images exceeded (%d)!", DFCIF_MAX_IMAGES); Result = FALSE; break; } /* Allocate the next image */ CreatePointer(pImages[NumImages], CDFCifImage); NumImages++; /* Special case for FACES.CIF */ if (FileSize == 249856l) { pImages[NumImages-1]->SetHasNoHeader(TRUE); pImages[NumImages-1]->SetWidth(64); pImages[NumImages-1]->SetHeight(64); pImages[NumImages-1]->SetImageSize(64*64); } /* Read in the next image file */ Result = pImages[NumImages-1]->Read(pFileHandle); if (!Result) break; } /* Output debug message */ return (Result); } /*=========================================================================== * End of Class Method CDFCifFile::ReadCIF() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CDFCifFile::ReadWeaponCIF()" /*=========================================================================== * * Class CDFCifFile Method - boolean ReadWeaponCIF (pFileHandle); * * Attempts to read in the given Weapon CIF file. Returns FALSE on any error. * *=========================================================================*/ boolean CDFCifFile::ReadWeaponCIF (FILE* pFileHandle) { long FileSize; boolean Result = TRUE; boolean HasNoFirstImage = FALSE; ushort OffsetList[DFCIF_NUM_OFFSETS]; int GroupCounter = 0; long GroupOffset; int LoopCounter; int NumSubImages; /* Get the filesize */ FileSize = GetFilesize(pFileHandle); /* Check for errors in filesize */ if (FileSize == INVALID_FILESIZE) { SET_EXT_ERROR2(ERR_READ, "Invalid filesize received!"); fclose (pFileHandle); return (FALSE); } /* Destroy the current image information */ Destroy(); /* Check to see if there is a first, regular, image */ fseek(pFileHandle, 8, SEEK_SET); if (fgetc(pFileHandle) == 0x15) HasNoFirstImage = TRUE; fseek (pFileHandle, 0, SEEK_SET); /* Read in the first, regular, image data */ if (!HasNoFirstImage) { CreatePointer(pImages[NumImages], CDFCifImage); pImages[NumImages]->SetCIFGroupIndex(GroupCounter); GroupCounter++; NumImages++; Result = pImages[NumImages-1]->Read(pFileHandle); if (!Result) return (FALSE); } /* Read in weapon CIF image data until no more left */ while (FileSize - ftell(pFileHandle) >= DFCIF_MINBYTES_LEFT) { /* Ensure we don't load too many images to overflow array */ if (NumImages >= DFCIF_MAX_IMAGES) { SET_EXT_ERROR3(ERR_MAXINDEX, "Maximum number of images exceeded (%d)!", DFCIF_MAX_IMAGES); Result = FALSE; break; } /* Save the group file offset */ GroupOffset = ftell(pFileHandle); /* Read in the first image in a group */ CreatePointer(pImages[NumImages], CDFCifImage); pImages[NumImages]->SetHasOffsetList(TRUE); pImages[NumImages]->SetHasCIFWeaponHeader(TRUE); pImages[NumImages]->SetCIFGroupIndex(GroupCounter); NumImages++; Result = pImages[NumImages-1]->Read(pFileHandle); if (!Result) break; /* Read in the group offset list */ fseek (pFileHandle, GroupOffset + 12, SEEK_SET); Result = fread (OffsetList, sizeof(short), DFCIF_NUM_OFFSETS, pFileHandle); if (Result != DFCIF_NUM_OFFSETS) { SET_EXT_ERROR4(ERR_READ, "Error reading offset list (%d of %d offsets)!", Result, DFCIF_NUM_OFFSETS); break; } /* Count the number of subimages */ for (NumSubImages = 0; NumSubImages < DFCIF_NUM_OFFSETS; NumSubImages++) { if (OffsetList[NumSubImages] == 0) break; } /* Read in each sub-image in group */ for (LoopCounter = 1; LoopCounter < NumSubImages; LoopCounter++) { /* Ensure we don't create too many images to overflow image array */ if (NumImages >= DFCIF_MAX_IMAGES) { SET_EXT_ERROR3(ERR_MAXINDEX, "Maximum number of images exceeded (%d)!", DFCIF_MAX_IMAGES); return (FALSE); } /* Allocate and setup the image */ CreatePointer(pImages[NumImages], CDFCifImage); pImages[NumImages]->SetHasNoHeader(TRUE); pImages[NumImages]->SetCIFGroupIndex(GroupCounter); pImages[NumImages]->SetWidth(pImages[NumImages-1]->GetWidth()); pImages[NumImages]->SetHeight(pImages[NumImages-1]->GetHeight()); NumImages++; /* Jump to the appropiate file offset and read image data */ fseek (pFileHandle, GroupOffset + OffsetList[LoopCounter], SEEK_SET); Result = pImages[NumImages-1]->Read(pFileHandle); if (!Result) return (FALSE); } /* Move to start of next image group */ fseek (pFileHandle, OffsetList[DFCIF_NUM_OFFSETS-1] + GroupOffset, SEEK_SET); /* Increment CIF group index counter */ GroupCounter++; } /* Output debug message */ return (Result); } /*=========================================================================== * End of Class Method CDFCifFile::ReadWeaponCIF() *=========================================================================*/