/*========================================================================= * * DFARCH3D.CPP - Dave Humphrey (uesp@m0use.net), 29 October 2000 * *=======================================================================*/ /* Include Files */ #include "dfarch3d.h" #undef __FUNC__ #define __FUNC__ "CDFArch3D::CDFArch3D()" /*=========================================================================== * * Class CDFArch3D Constructor * *=========================================================================*/ CDFArch3D::CDFArch3D() { int LoopCounter; CreatePointerArray(p3DObjects, CDF3DObject*, DFARCH_MAX_3DOBJECTS); for (LoopCounter = 0; LoopCounter < DFARCH_MAX_3DOBJECTS; LoopCounter++) { p3DObjects[LoopCounter] = NULL; } SetFilename("arena2\\arch3d.bsa"); } /*=========================================================================== * End of Class CDFArch3D Constructor *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CDFArch3D::~CDFArch3D()" /*=========================================================================== * * Class CDFArch3D Destructor * *=========================================================================*/ CDFArch3D::~CDFArch3D() { Destroy(); DestroyPointerArray(p3DObjects); } /*=========================================================================== * End of Class CDFArch3D Destructor *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CDFArch3D::Destroy()" /*=========================================================================== * * Class CDFArch3D Destructor * *=========================================================================*/ void CDFArch3D::Destroy (void) { int LoopCounter; for (LoopCounter = 0; LoopCounter < DFARCH_MAX_3DOBJECTS; LoopCounter++) { DestroyPointer(p3DObjects[LoopCounter]); } /* Call base class method */ CDFBSAFile::Destroy(); } /*=========================================================================== * End of Class CDFArch3D Destructor *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CDFArch3D::Create3DObject()" /*=========================================================================== * * Class CDFArch3D Method - void Create3DObject (RecordIndex); * * Creates the given object array. Protected class method. * *=========================================================================*/ void CDFArch3D::Create3DObject (const int RecordIndex) { /* Delete the object if it exists */ DestroyPointer(p3DObjects[RecordIndex]); /* Alloate the new object */ CreatePointer(p3DObjects[RecordIndex], CDF3DObject); } /*=========================================================================== * End of Class Method CDFArch3D::Create3DObject() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CDFArch3D::DebugCompare()" /*=========================================================================== * * Class CDFArch3D Method - int DebugCompare (ValueID, p3DObject); * * Compares the given 3D Object record with the 3D object with the given ValueID * in the opened ARCH3D.BSA file. Does a simple compare on a byte-by-byte * basis. Returns DFBSA_ERROR on any error, a positive value if the records * do not match, and 0 if they match. Assumes that the BSA header and * directory have already been loaded. * *=========================================================================*/ int CDFArch3D::DebugCompare (const long ValueID, CDF3DObject* p3DObject) { int RecordIndex; /* Find the record in the current directory and ensure it exists */ RecordIndex = FindRecordIndex(ValueID); if (RecordIndex == DFBSA_ERROR) return (DFBSA_ERROR); /* Call the indexed version */ return (DebugCompareIndex(ValueID, p3DObject)); } /*=========================================================================== * End of Class Method CDFArch3D::DebugCompare() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CDFArch3D::DebugCompareIndex()" /*=========================================================================== * * Class CDFArch3D Method - int DebugCompareIndex (RecordIndex, p3DObject); * * Compares the given 3D Object record with the 3D object with the given ValueID * in the opened ARCH3D.BSA file. Does a simple compare on a byte-by-byte * basis. Returns DFBSA_ERROR on any error, a positive value if the records * do not match, and 0 if they match. Assumes that the BSA header and * directory have already been loaded. * *=========================================================================*/ int CDFArch3D::DebugCompareIndex (const int RecordIndex, CDF3DObject* p3DObject) { int Result; int Result1; int Result2; long RecordSize; char* pDataBuffer1; char* pDataBuffer2; FILE* pTempHandle; /* Ensure valid input */ if (!IsOpen() || p3DObject == NULL) { SET_EXT_ERROR2(ERR_NULL, "Invalid object or BSA file not open!"); return (DFBSA_ERROR); } /* Ensure a valid record index */ if (!IsValidRecordIndex(RecordIndex)) { SET_EXT_ERROR3(ERR_INDEX, "Invalid BSA record index %d!", RecordIndex); return (DFBSA_ERROR); } /* Check the record sizes first for equality */ RecordSize = pDirectory[RecordIndex]->RecordSize; if (p3DObject->GetRecordSize() != RecordSize) { SET_EXT_ERROR2(ERR_CUSTOM, "Record sizes are different!"); return (DFBSA_ERROR); } /* Create temp file for input/output */ pTempHandle = openfile("temp.3d", "w+b"); if (pTempHandle == NULL) { SET_EXT_ERROR2(ERR_FILE, "Failed to open temporary file 'temp.3d'!"); return (DFBSA_ERROR); } /* Output 3D Object data to temp file */ Result = p3DObject->Write(pTempHandle); if (!Result) return (DFBSA_ERROR); fflush (pTempHandle); /* Allocate a temp buffers for the data */ CreatePointerArray(pDataBuffer1, char, RecordSize); CreatePointerArray(pDataBuffer2, char, RecordSize); /* Jump to record position in BSA file */ fseek (pFileHandle, pDirectory[RecordIndex]->RecordOffset, SEEK_SET); /* Read in data from BSA and ensure success */ Result1 = fread(pDataBuffer1, 1, RecordSize, pFileHandle); /* Read in data from temp file */ fseek (pTempHandle, 0, SEEK_SET); Result2 = fread (pDataBuffer2, 1, RecordSize, pTempHandle); fclose (pTempHandle); if (Result1 != RecordSize || Result2 != RecordSize) { DestroyPointer(pDataBuffer1); DestroyPointer(pDataBuffer2); SET_EXT_ERROR2(ERR_READ, "Failed to read from temp or BSA files!"); return (DFBSA_ERROR); } /* Compare data */ Result = memcmp(pDataBuffer1, pDataBuffer2, RecordSize); /* Unallocate temp data buffers */ DestroyPointer(pDataBuffer1); DestroyPointer(pDataBuffer2); /* Return result */ if (Result == 0) return (0); return (1); } /*=========================================================================== * End of Class Method CDFArch3D::DebugCompareIndex() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CDFArch3D::Get3DObject()" /*=========================================================================== * * Class CDFArch3D Method - CDF3DObject* Get3DObject (ValueID); * * Attempts to retrieve a 3d object given its value ID, loading the data if * required. Returns NULL on any error. * *=========================================================================*/ CDF3DObject* CDFArch3D::Get3DObject (const long ValueID) { int RecordIndex; /* Try and find the record index */ RecordIndex = FindRecordIndex(ValueID); if (RecordIndex == DFBSA_ERROR) return (NULL); /* Load the object with the given record index */ return (Get3DObject(RecordIndex)); } /*=========================================================================== * End of Class Method CDFArch3D::Get3DObject() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CDFArch3D::Get3DObject()" /*=========================================================================== * * Class CDFArch3D Method - CDF3DObject* Get3DObject (RecordIndex); * * Attempts to retrieve a 3d object given its index, loading the data if * required. Returns NULL on any error. * *=========================================================================*/ CDF3DObject* CDFArch3D::Get3DObject (const int RecordIndex) { boolean HadToOpenFile = FALSE; boolean Result; /* Open file if required to compare directory */ if (!DirectoryRead && !IsOpen()) { if (!Open()) return (FALSE); HadToOpenFile = TRUE; } /* Ensure a valid record index */ if (!IsValidRecordIndex(RecordIndex)) { SET_EXT_ERROR3(ERR_INDEX, "Invalid 3DObject record index %d received!", RecordIndex); if (HadToOpenFile) Close(); return (NULL); } /* Return the object if it is already loaded */ if (p3DObjects[RecordIndex] != NULL) { if (HadToOpenFile) Close(); //SystemLog.Printf ("\t\tNum Faces = %d", p3DObjects[RecordIndex]->GetNumPlanes()); return (p3DObjects[RecordIndex]); } /* Open file if required to read object */ if (!IsOpen()) { if (!Open()) return (FALSE); HadToOpenFile = TRUE; } /* Attempt to load the object */ Result = Load3DObjectIndex (RecordIndex); if (HadToOpenFile) Close(); //SystemLog.Printf ("\t\tNum Faces = %d", p3DObjects[RecordIndex]->GetNumPlanes()); /* Return appropiate value */ if (!Result) return (NULL); return (p3DObjects[RecordIndex]); } /*=========================================================================== * End of Class Method CDFArch3D::Get3DObject() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CDFArch3D::Load3DObject()" /*=========================================================================== * * Class CDFArch3D Method - boolean Load3DObject (ValueID); * * Attempts to load a 3d object given its value ID. Returns FALSE * on any error. * *=========================================================================*/ boolean CDFArch3D::Load3DObject (const long ValueID) { int RecordIndex; /* Try and find the record index */ RecordIndex = FindRecordIndex(ValueID); if (RecordIndex == DFBSA_ERROR) return (FALSE); /* Load the object with the given record index */ return (Load3DObjectIndex(RecordIndex)); } /*=========================================================================== * End of Class Method CDFArch3D::Load3DObject() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CDFArch3D::Load3DObjectIndex()" /*=========================================================================== * * Class CDFArch3D Method - boolean Load3DObjectIndex (ValueID); * * Attempts to load a 3d object given its record index. Returns FALSE on any * error. * *=========================================================================*/ boolean CDFArch3D::Load3DObjectIndex (const int RecordIndex) { boolean Result; /* Is the given record index valid? */ if (!IsValidRecordIndex(RecordIndex)) { SET_EXT_ERROR3(ERR_INDEX, "Invalid BSA record index %d!", RecordIndex); return (FALSE); } /* Create the required object */ Create3DObject(RecordIndex); /* Set the BSA object data */ p3DObjects[RecordIndex]->SetBSARecordID(pDirectory[RecordIndex]->Value); p3DObjects[RecordIndex]->SetBSARecordOffset(pDirectory[RecordIndex]->RecordOffset); p3DObjects[RecordIndex]->SetBSARecordSize(pDirectory[RecordIndex]->RecordSize); p3DObjects[RecordIndex]->SetBSARecordIndex(RecordIndex); /* Move file pointer to appropiate spot */ fseek (pFileHandle, pDirectory[RecordIndex]->RecordOffset, SEEK_SET); /* Attempt to load item */ Result = p3DObjects[RecordIndex]->Read(pFileHandle); if (!Result) { DestroyPointer(p3DObjects[RecordIndex]); return (FALSE); } return (TRUE); } /*=========================================================================== * End of Class Method CDFArch3D::Load3DObjectIndex() *=========================================================================*/