#include #include "FIL_CPA.h" #define D_FIL_StructureDefine #include "ErmFil.h" #include "FIL_GF.h" #include "FIL_Pub.h" #include "FIL_Priv.h" #include "FIL_Conc.h" #include "MMG.h" /**************************************************************************/ FIL_tdxHandleToConcatFile FIL_fn_hCreateConcatFileHandle(unsigned long ulNumberOfPath,unsigned long ulNumberOfFiles) { FIL_tdstConcatFile *p_stConcatFile = NULL; MMG_fn_vAddMemoryInfo (MMG_C_lTypeFile , MMG_C_lSubTypeConcatFile , NULL); p_stConcatFile = (FIL_tdstConcatFile *)TMP_M_p_Malloc(sizeof(FIL_tdstConcatFile)); p_stConcatFile->ulNumberOfPath = ulNumberOfPath; p_stConcatFile->ulNumberOfFile = ulNumberOfFiles; if (ulNumberOfPath) { MMG_fn_vAddMemoryInfo (MMG_C_lTypeFile , MMG_C_lSubTypeConcatFile , NULL); p_stConcatFile->d_szPathList = (char **)TMP_M_p_Malloc(ulNumberOfPath*sizeof(char *)); } else p_stConcatFile->d_szPathList = NULL; MMG_fn_vAddMemoryInfo (MMG_C_lTypeFile , MMG_C_lSubTypeConcatFile , NULL); p_stConcatFile->d_stConcatFileElement = (FIL_tdstConcatFileElement *)TMP_M_p_Malloc(ulNumberOfFiles*sizeof(struct FIL_tdstConcatFileElement_)); return(p_stConcatFile); } /**************************************************************************/ void fn_vDestroyConcatFileHandle(FIL_tdxHandleToConcatFile hConcatFile) { unsigned long i; if (hConcatFile->d_szPathList!=NULL) { for (i=0;iulNumberOfPath;i++) TMP_M_Free(hConcatFile->d_szPathList[i]); TMP_M_Free(hConcatFile->d_szPathList); } if (hConcatFile->d_stConcatFileElement!=NULL) { for (i=0;iulNumberOfFile;i++) TMP_M_Free(hConcatFile->d_stConcatFileElement[i].p_szFileName); TMP_M_Free(hConcatFile->d_stConcatFileElement); } TMP_M_Free(hConcatFile); } /**************************************************************************/ unsigned char FIL_fn_bSetConcatPathElement(FIL_tdxHandleToConcatFile hConcatFile,unsigned long ulPathNumber,char *p_szPathName) { unsigned char bReturn = FALSE; if (ulPathNumberulNumberOfPath) { MMG_fn_vAddMemoryInfo (MMG_C_lTypeFile , MMG_C_lSubTypeConcatFile , NULL); hConcatFile->d_szPathList[ulPathNumber] = (char *)TMP_M_p_Malloc((strlen(p_szPathName)+1)*sizeof(char)); strcpy(hConcatFile->d_szPathList[ulPathNumber],p_szPathName); bReturn = TRUE; } return(bReturn); } /**************************************************************************/ unsigned char FIL_fn_bSetConcatFileElementWithoutPath(FIL_tdxHandleToConcatFile hConcatFile,unsigned long ulFileNumber,char *p_szFileName) { unsigned char bReturn = FALSE; if (ulFileNumberulNumberOfFile) { MMG_fn_vAddMemoryInfo (MMG_C_lTypeFile , MMG_C_lSubTypeConcatFile , NULL); hConcatFile->d_stConcatFileElement[ulFileNumber].p_szFileName = (char *)TMP_M_p_Malloc((strlen(p_szFileName)+1)*sizeof(char)); strcpy(hConcatFile->d_stConcatFileElement[ulFileNumber].p_szFileName,p_szFileName); bReturn = TRUE; } return(bReturn); } /**************************************************************************/ unsigned char FIL_fn_bSetConcatFileElement(FIL_tdxHandleToConcatFile hConcatFile,unsigned long ulFileNumber,char *p_szFileName) { char szTemp[_MAX_PATH]; unsigned char bReturn = FALSE; unsigned long i; if (ulFileNumberulNumberOfFile) { if (strrchr(p_szFileName,'\\')==NULL) { MMG_fn_vAddMemoryInfo (MMG_C_lTypeFile , MMG_C_lSubTypeConcatFile , NULL); hConcatFile->d_stConcatFileElement[ulFileNumber].p_szFileName = (char *)TMP_M_p_Malloc((strlen(p_szFileName)+1)*sizeof(char)); strcpy(hConcatFile->d_stConcatFileElement[ulFileNumber].p_szFileName,p_szFileName); hConcatFile->d_stConcatFileElement[ulFileNumber].lPathNumber = -1; bReturn = TRUE; } else { strcpy(szTemp,p_szFileName); *strrchr(szTemp,'\\')=0; for (i=0;iulNumberOfPath&&stricmp(szTemp,hConcatFile->d_szPathList[i]);i++); if (i!=hConcatFile->ulNumberOfPath) { strcpy(szTemp,strrchr(p_szFileName,'\\')+1); MMG_fn_vAddMemoryInfo (MMG_C_lTypeFile , MMG_C_lSubTypeConcatFile , NULL); hConcatFile->d_stConcatFileElement[ulFileNumber].p_szFileName = (char *)TMP_M_p_Malloc((strlen(szTemp)+1)*sizeof(char)); strcpy(hConcatFile->d_stConcatFileElement[ulFileNumber].p_szFileName,szTemp); hConcatFile->d_stConcatFileElement[ulFileNumber].lPathNumber = i; bReturn = TRUE; } } } return(bReturn); } /**************************************************************************/ void FIL_fn_vBuildConcatCompleteFileName(char *szCompleteFilename,FIL_tdxHandleToConcatFile hConcatFile,unsigned long ulIndex) { if (hConcatFile->d_stConcatFileElement[ulIndex].lPathNumber==-1) strcpy(szCompleteFilename,hConcatFile->d_stConcatFileElement[ulIndex].p_szFileName); else sprintf(szCompleteFilename,"%s\\%s",hConcatFile->d_szPathList[hConcatFile->d_stConcatFileElement[ulIndex].lPathNumber],hConcatFile->d_stConcatFileElement[ulIndex].p_szFileName); } /**************************************************************************/ /**************************************************************************/ /* O.C start*/ #define C_MARK_SIZE 4 #define C_RIFF_MARK "RIFF" #define C_AVI_MARK "AVI " #define C_AVI_HEADER_SIZE sizeof(tdstAviHeader) #define C_CHUNK_HEADER_SIZE sizeof(tdstChunkHeader) #define C_DEFAULT_CHUNK_NAME ".CNT" typedef struct tdstAviHeader_ { unsigned char ucRIFFMark[C_MARK_SIZE]; long lLength; unsigned char ucAVIMark[C_MARK_SIZE]; } tdstAviHeader; typedef struct tdstChunkHeader_ { unsigned char ucChunkMark[C_MARK_SIZE]; long lChunkLength; } tdstChunkHeader; tdstAviHeader stAviHeader; tdstChunkHeader stChunkHeader; long fn_lCheckForFileinAVI(FILE *p_stFile,char *szFileToFind,char *szChunkToFind) { long lOffset=-1L; if ( (fseek(p_stFile,0,SEEK_SET)==0) && (fread(&stAviHeader,1,C_AVI_HEADER_SIZE,p_stFile)==C_AVI_HEADER_SIZE) && (!strncmp((char*) &(stAviHeader.ucRIFFMark),C_RIFF_MARK,C_MARK_SIZE)) && (!strncmp((char*) &(stAviHeader.ucAVIMark),C_AVI_MARK,C_MARK_SIZE)) ) { long lTotalLen=stAviHeader.lLength+C_CHUNK_HEADER_SIZE; long lLen; unsigned char ucSize=0; char szBuffer[_MAX_PATH]; while ( ((lLen=ftell(p_stFile))!=-1L) && (lLenbUseXorCode,sizeof(unsigned char),1,p_stFile); fread(&hConcatFile->bUseCheckSum,sizeof(unsigned char),1,p_stFile); hConcatFile->p_stFile = p_stFile; /**** Load path table ****/ fread(&hConcatFile->ucPathXorCode,sizeof(unsigned char),1,p_stFile); ucInternalCheckSum = 0; for (i=0;iulNumberOfPath;i++) { fread(&ulInternalLength,sizeof(unsigned long),1,p_stFile); fread(szTemp,sizeof(char),ulInternalLength,p_stFile); szTemp[ulInternalLength] = 0; if (hConcatFile->bUseXorCode||hConcatFile->bUseCheckSum) { for (j=0;jbUseXorCode) szTemp[j]^=hConcatFile->ucPathXorCode; if (hConcatFile->bUseCheckSum) ucInternalCheckSum=(unsigned char)(ucInternalCheckSum+szTemp[j]); } } FIL_fn_bSetConcatPathElement(hConcatFile,i,szTemp); } fread(&hConcatFile->ucPathCheckSum,sizeof(unsigned char),1,p_stFile); if (hConcatFile->ucPathCheckSum!=ucInternalCheckSum) M_FILFatalErrorWithMessage(E_uwFILConcatCheckSumOpen,p_szFilename); /**** Load filenames table ****/ ucInternalCheckSum = 0; for (i=0;iulNumberOfFile;i++) { fread(&hConcatFile->d_stConcatFileElement[i].lPathNumber,sizeof(long),1,p_stFile); fread(&ulInternalLength,sizeof(unsigned long),1,p_stFile); fread(szTemp,sizeof(char),ulInternalLength,p_stFile); szTemp[ulInternalLength] = 0; if (hConcatFile->bUseXorCode) { for (j=0;jucPathXorCode; } FIL_fn_bSetConcatFileElementWithoutPath(hConcatFile,i,szTemp); fread(&hConcatFile->d_stConcatFileElement[i].ulXorCode,sizeof(unsigned long),1,p_stFile); fread(&hConcatFile->d_stConcatFileElement[i].ulCheckSum,sizeof(unsigned long),1,p_stFile); fread(&hConcatFile->d_stConcatFileElement[i].lOffset,sizeof(long),1,p_stFile); fread(&hConcatFile->d_stConcatFileElement[i].ulFileLength,sizeof(unsigned long),1,p_stFile); /* O.C.*/ hConcatFile->d_stConcatFileElement[i].lOffset+=lOffsetToAdd; } } return(hConcatFile); } /**************************************************************************/ void FIL_fn_vCloseConcatFile(FIL_tdxHandleToConcatFile *hConcatFile) { if (*hConcatFile!=NULL) { fclose((*hConcatFile)->p_stFile); fn_vDestroyConcatFileHandle(*hConcatFile); *hConcatFile = NULL; } } /**************************************************************************/ FIL_tdxHandleToFileInConcatFile FIL_fn_hOpenFileInConcatFile(FIL_tdxHandleToConcatFile hConcatFile,char *p_szPath,char *p_szFilename) { FIL_tdxHandleToFileInConcatFile hHandleToFile = NULL; unsigned char bFileFound = FALSE; char szTemp[_MAX_PATH]; FILE *p_stFile; unsigned long ulInternalLength; /* unsigned long ulInternalCheckSum;*/ unsigned long i/*,j*/; char *p_szPointer; /**** Convert / by \ in p_szFileName ****/ while((p_szPointer=strchr(p_szFilename,'/'))!=NULL) *p_szPointer = '\\'; if ((p_szPointer=strrchr(p_szFilename,'\\'))==NULL) p_szPointer = p_szFilename; else p_szPointer++; /**** Search file in concat file ****/ if (hConcatFile!=NULL) { for (i=0;iulNumberOfFile&&!bFileFound;i++) { if (!stricmp(p_szPointer,hConcatFile->d_stConcatFileElement[i].p_szFileName)) { FIL_fn_vBuildConcatCompleteFileName(szTemp,hConcatFile,i); if (!stricmp(p_szFilename,szTemp)) { bFileFound = TRUE; MMG_fn_vAddMemoryInfo (MMG_C_lTypeFile , MMG_C_lSubTypeConcatFile , NULL); hHandleToFile = (FIL_tdxHandleToFileInConcatFile)TMP_M_p_Malloc(sizeof(FIL_tdstFileInConcatFile)); hHandleToFile->bUseConcatFile = TRUE; hHandleToFile->p_stFile = hConcatFile->p_stFile; hHandleToFile->ulFileActualSeek = hConcatFile->d_stConcatFileElement[i].lOffset; hHandleToFile->ulFileEndSeek = hConcatFile->d_stConcatFileElement[i].lOffset + hConcatFile->d_stConcatFileElement[i].ulFileLength; if (!hConcatFile->bUseXorCode&&!hConcatFile->bUseCheckSum) { hHandleToFile->ulFileXorCode = 0; hHandleToFile->ulFileCheckSum = 0; } else { hHandleToFile->ulFileXorCode = hConcatFile->d_stConcatFileElement[i].ulXorCode; hHandleToFile->ulFileCheckSum = hConcatFile->d_stConcatFileElement[i].ulCheckSum; } hHandleToFile->ulCacheCheckSum = 0; if (hConcatFile->d_stConcatFileElement[i].ulFileLength>FIL_C_MaxConcatCacheSize) { MMG_fn_vAddMemoryInfo (MMG_C_lTypeFile , MMG_C_lSubTypeConcatFile , NULL); hHandleToFile->p_ucCache = (unsigned char *)TMP_M_p_Malloc(FIL_C_MaxConcatCacheSize*sizeof(unsigned char)); hHandleToFile->ulCacheSize = FIL_C_MaxConcatCacheSize; } else { MMG_fn_vAddMemoryInfo (MMG_C_lTypeFile , MMG_C_lSubTypeConcatFile , NULL); hHandleToFile->p_ucCache = (unsigned char *)TMP_M_p_Malloc(hConcatFile->d_stConcatFileElement[i].ulFileLength*sizeof(unsigned char)); hHandleToFile->ulCacheSize = hConcatFile->d_stConcatFileElement[i].ulFileLength; } hHandleToFile->ulCacheSeek = hHandleToFile->ulCacheSize; } } } } if (!bFileFound) { sprintf(szTemp,"%s\\%s",p_szPath,p_szFilename); ulInternalLength = FIL_fn_ulGetFileSize(szTemp); if ((p_stFile = fopen(szTemp,"rb"))!=NULL) { MMG_fn_vAddMemoryInfo (MMG_C_lTypeFile , MMG_C_lSubTypeConcatFile , NULL); hHandleToFile = (FIL_tdxHandleToFileInConcatFile)TMP_M_p_Malloc(sizeof(FIL_tdstFileInConcatFile)); hHandleToFile->bUseConcatFile = FALSE; hHandleToFile->p_stFile = p_stFile; hHandleToFile->ulFileActualSeek = 0; hHandleToFile->ulFileEndSeek = ulInternalLength; hHandleToFile->ulFileXorCode = 0; hHandleToFile->ulFileCheckSum = 0; hHandleToFile->ulCacheCheckSum = 0; if (ulInternalLength>FIL_C_MaxConcatCacheSize) { MMG_fn_vAddMemoryInfo (MMG_C_lTypeFile , MMG_C_lSubTypeConcatFile , NULL); hHandleToFile->p_ucCache = (unsigned char *)TMP_M_p_Malloc(FIL_C_MaxConcatCacheSize*sizeof(unsigned char)); hHandleToFile->ulCacheSize = FIL_C_MaxConcatCacheSize; } else { MMG_fn_vAddMemoryInfo (MMG_C_lTypeFile , MMG_C_lSubTypeConcatFile , NULL); hHandleToFile->p_ucCache = (unsigned char *)TMP_M_p_Malloc(ulInternalLength*sizeof(unsigned char)); hHandleToFile->ulCacheSize = ulInternalLength; } hHandleToFile->ulCacheSeek = hHandleToFile->ulCacheSize; } } return(hHandleToFile); } /**************************************************************************/ unsigned long FIL_fn_ulReadFromFileToCacheinConcatFile(FIL_tdxHandleToFileInConcatFile hHandleToFile) { unsigned long ulReadReturn; unsigned long i; fseek(hHandleToFile->p_stFile,hHandleToFile->ulFileActualSeek,SEEK_SET); if (hHandleToFile->ulFileActualSeek+hHandleToFile->ulCacheSize>hHandleToFile->ulFileEndSeek) ulReadReturn=fread(hHandleToFile->p_ucCache,sizeof(unsigned char),hHandleToFile->ulFileEndSeek-hHandleToFile->ulFileActualSeek,hHandleToFile->p_stFile); else ulReadReturn=fread(hHandleToFile->p_ucCache,sizeof(unsigned char),hHandleToFile->ulCacheSize,hHandleToFile->p_stFile); hHandleToFile->ulFileActualSeek += ulReadReturn*sizeof(unsigned char); hHandleToFile->ulCacheSeek = 0; hHandleToFile->ulCacheSize = ulReadReturn*sizeof(unsigned char); if (hHandleToFile->ulFileXorCode||hHandleToFile->ulFileCheckSum) { for (i=0;iulFileXorCode) ((unsigned long*)hHandleToFile->p_ucCache)[i]^=hHandleToFile->ulFileXorCode; if (hHandleToFile->ulFileCheckSum) hHandleToFile->ulCacheCheckSum+=((unsigned long*)hHandleToFile->p_ucCache)[i]; } } return(ulReadReturn); } /**************************************************************************/ void FIL_fn_vCloseFileInConcatFile(FIL_tdxHandleToFileInConcatFile *hHandleToFile) { if ((*hHandleToFile)->ulFileEndSeek==(*hHandleToFile)->ulFileActualSeek&&(*hHandleToFile)->ulFileCheckSum&&(*hHandleToFile)->ulCacheCheckSum!=(*hHandleToFile)->ulFileCheckSum) M_FILFatalError(E_uwFILConcatCheckSumRead); if (!(*hHandleToFile)->bUseConcatFile) fclose((*hHandleToFile)->p_stFile); if (hHandleToFile!=NULL) { if ((*hHandleToFile)->p_ucCache!=NULL) TMP_M_Free((*hHandleToFile)->p_ucCache); TMP_M_Free(*hHandleToFile); *hHandleToFile=NULL; } } /**************************************************************************/ long FIL_fn_lReadFileInConcatFile(void *p_vBuffer,long lSize,long lNumber,FIL_tdxHandleToFileInConcatFile hHandleToFile) { long lInternalLength = 0; long lReadLength = 0; void *p_vInternalPointer; if (hHandleToFile!=NULL&&lSize*lNumber>0) { /**** The asking size is above the file size ****/ if ((unsigned long)(lSize*lNumber)>(hHandleToFile->ulCacheSize-hHandleToFile->ulCacheSeek)+(hHandleToFile->ulFileEndSeek-hHandleToFile->ulFileActualSeek)) lInternalLength = (hHandleToFile->ulCacheSize-hHandleToFile->ulCacheSeek)+(hHandleToFile->ulFileEndSeek-hHandleToFile->ulFileActualSeek); else lInternalLength = lSize*lNumber; lReadLength = lInternalLength/lSize; for (p_vInternalPointer=p_vBuffer;lInternalLength!=0;) { if (hHandleToFile->ulCacheSeek+lInternalLength<=hHandleToFile->ulCacheSize) { memcpy(p_vInternalPointer,hHandleToFile->p_ucCache+hHandleToFile->ulCacheSeek,lInternalLength); hHandleToFile->ulCacheSeek+=lInternalLength; p_vInternalPointer=(void*)((unsigned long)p_vInternalPointer+lInternalLength); lInternalLength = 0; } else if (hHandleToFile->ulCacheSeekulCacheSize) { memcpy(p_vInternalPointer,hHandleToFile->p_ucCache+hHandleToFile->ulCacheSeek,hHandleToFile->ulCacheSize-hHandleToFile->ulCacheSeek); lInternalLength -= hHandleToFile->ulCacheSize-hHandleToFile->ulCacheSeek; p_vInternalPointer=(void*)((unsigned long)p_vInternalPointer+hHandleToFile->ulCacheSize-hHandleToFile->ulCacheSeek); hHandleToFile->ulCacheSeek = hHandleToFile->ulCacheSize; } else FIL_fn_ulReadFromFileToCacheinConcatFile(hHandleToFile); } } return(lReadLength); } /**************************************************************************/ /*------------------------------------------------------------------------*/ /**/ /* Author David Lassonde*/ /* Date 2 Sep 1998*/ /* */ /* Prototype FIL_fn_vOpenFileInConcatFile*/ /* Parameters hConcatFile : The concat file*/ /* p_szPath : */ /* p_szFilename : */ /* hHandleToFile : the global variable*/ /* Return Type int 0 : the handle is OK (the file was found and the global Handle is set)*/ /* -1 : the wanted file is not in the big file*/ /* */ /* Description */ /**/ /* same as FIL_fn_hOpenFileInConcatFile, except that it doesn't allocate a new handle for each texture loaded*/ /* */ /*------------------------------------------------------------------------*/ int FIL_fn_iOpenFileInConcatFile(FIL_tdxHandleToConcatFile hConcatFile,char *p_szPath,char *p_szFilename, FIL_tdxHandleToFileInConcatFile hHandleToFile) { /* FIL_tdxHandleToFileInConcatFile hHandleToFile = NULL;*/ unsigned char bFileFound = FALSE; char szTemp[_MAX_PATH]; /* unsigned long ulInternalCheckSum;*/ unsigned long i/*,j*/; char *p_szPointer; /**** Convert / by \ in p_szFileName ****/ while((p_szPointer=strchr(p_szFilename,'/'))!=NULL) *p_szPointer = '\\'; if ((p_szPointer=strrchr(p_szFilename,'\\'))==NULL) p_szPointer = p_szFilename; else p_szPointer++; /**** Search file in concat file ****/ if (hConcatFile!=NULL) { for (i=0;iulNumberOfFile&&!bFileFound;i++) { if (!stricmp(p_szPointer,hConcatFile->d_stConcatFileElement[i].p_szFileName)) { FIL_fn_vBuildConcatCompleteFileName(szTemp,hConcatFile,i); if (!stricmp(p_szFilename,szTemp)) { bFileFound = TRUE; hHandleToFile->ulFileActualSeek = hConcatFile->d_stConcatFileElement[i].lOffset; hHandleToFile->ulFileEndSeek = hConcatFile->d_stConcatFileElement[i].lOffset + hConcatFile->d_stConcatFileElement[i].ulFileLength; if (!hConcatFile->bUseXorCode&&!hConcatFile->bUseCheckSum) { hHandleToFile->ulFileXorCode = 0; hHandleToFile->ulFileCheckSum = 0; } else { hHandleToFile->ulFileXorCode = hConcatFile->d_stConcatFileElement[i].ulXorCode; hHandleToFile->ulFileCheckSum = hConcatFile->d_stConcatFileElement[i].ulCheckSum; } } } } } if (!bFileFound) { /* the file is not in the big file... We'll have to use the old function...*/ return -1; } return 0; }