CGmResMan::TLstCurve * CGmResMan::NewLstCurve( const char *pcFileName ) { TLstCurve * ptLstCurve = (TLstCurve *)FindFileEntry( pcFileName ); if( !ptLstCurve ) { LOG( "Loading LstCurve %s.\n", pcFileName ); ptLstCurve = new TLstCurve; if( !LoadCurves_( DATA_DIR + pcFileName, ptLstCurve ) ) { ERR( "LstCurve %s.\n", pcFileName ); DELETE_INSTANCE( ptLstCurve ); return 0; } NewFileEntry( pcFileName, ptLstCurve ); m_oArrLstCurve.Append( ptLstCurve ); } else { LOG( "LstCurve skipped: %s.\n", pcFileName ); } return ptLstCurve; }
TWav * CGmResMan::NewWav( const char *pcFileName ) { TWav * poWav = (TWav *)FindFileEntry( pcFileName ); if( !poWav ) { poWav = new TWav; if( !MakeWav_( poWav, pcFileName ) ) { ERR( "Wav %s.\n", pcFileName ); DELETE_INSTANCE( poWav ); return 0; } NewFileEntry( pcFileName, poWav ); m_oArrWav.Append( poWav ); } else { // deep copy //TWav *poWavNew = new TWav; //poWavNew->InitDeepCopy( *poWav ); //poWav = poWavNew; // copy with shared data poWav = NewWav( *poWav ); LOG( "(%s).\n", pcFileName ); } return poWav; }
CGmObjAnim3 * CGmResMan::NewAnim3( const char *pcFileName ) { CGmObjAnim3 * poAnim3 = (CGmObjAnim3 *)FindFileEntry( pcFileName ); if( !poAnim3 ) { LOG( "Loading Anim3 %s.\n", pcFileName ); poAnim3 = new CGmObjAnim3; if( !poAnim3->LoadFile( pcFileName ) ) { ERR( "Anim3 %s.\n", pcFileName ); DELETE_INSTANCE( poAnim3 ); return 0; } NewFileEntry( pcFileName, poAnim3 ); } else { // copy with shared data poAnim3 = new CGmObjAnim3( *poAnim3 ); LOG( "Anim3 copied: %s.\n", pcFileName ); } m_oArrAnim3.Append( poAnim3 ); return poAnim3; }
FatDirEntry1x* CmtFat::FindFile( cpchar pattern ) { uint32 subDir = 0; //Войти в поддиректорий pattern = GetSubDir( pattern, &subDir ); if( pattern ) { //Успешно вошли в поддиректорий return FindFileEntry( subDir, pattern, pattern + strlen(pattern) ); } return 0; //Нет файла }
Json::Value JPAK::FindFileEntry(vector<string> &path, Json::Value &root) { if(path.size() == 1) { return root["files"].get(path[0], JPAK_NOT_FOUND_DATA); }else{ string nextdir = path[0]; path.erase(path.begin()); if(root["directories"].get(nextdir, JPAK_NOT_FOUND_DATA) != "JPAK_NOT_FOUND_DATA") return FindFileEntry(path, root["directories"][nextdir]); else return Json::Value(JPAK_NOT_FOUND_DATA); } }
bool JPAK::GetFile(string &path, char **buffer, int *size) { vector<string> paths = split(path, '/'); // Here is relative to root, so the first will be blank if starts with "/" if(paths[0].size() == 0) paths.erase(paths.begin()); Json::Value fileentry = FindFileEntry(paths, root); if(fileentry != JPAK_NOT_FOUND_DATA) { jpakfile.seekg(fileentry["offset"].asInt(), ios_base::beg); *buffer = new char[fileentry["size"].asInt()]; jpakfile.read(*buffer, fileentry["size"].asInt()); *size = fileentry["size"].asInt(); return true; }else{ cout << "File not found: " << path << endl; return false; } }
//Получить начальный кластер для директория cpchar CmtFat::GetSubDir( cpchar pattern, uint32 *subDirStart ) { FatDirEntry1x *ptr; *subDirStart = 0; //Начнем с корневого директория while(1) { //Выделить очередной путь cpchar tail = pattern; //Инициализация хвоста while( *tail && *tail != '\\' && *tail != '/' ) tail++; //Получить позицию хвоста if( tail == pattern ) return 0; //Неудачная попытка - пустой директорий if( *tail == 0 ) { return pattern; //Остался один файл - поиск закончен } //Будем искать поддиректорий в текущем директории ptr = FindFileEntry( *subDirStart, pattern, tail ); if( ptr == 0 ) return 0; //Неудачная попытка - путь не найден *subDirStart = ptr->GetFirstCluster32(); //Сохранить начало текущего поддиректория pattern = tail + 1; } }
CGTex2 * CGmResMan::NewTexture( const char *pcFileName, bool bSmooth, bool bClamp ) { const CStr oFileEntry( CStr( pcFileName ) + ( bSmooth ? "s" : "" ) + ( bClamp ? "c" : "" ) ); CGTex2 *poTex = (CGTex2 *)FindFileEntry( oFileEntry ); if( !poTex ) { poTex = new CGTex2; if( !MakeTex_( poTex, ( CStr("tex/") + pcFileName ).GetData(), bSmooth, bClamp ) ) { ERR( "Texture %s.\n", pcFileName ); DELETE_INSTANCE( poTex ); return 0; } m_oArrTex.Append( poTex ); NewFileEntry( oFileEntry, poTex ); } else { LOG( "Texture skipped: %s.\n", pcFileName ); } return poTex; }
CGMeshMD5::CModel * CGmResMan::NewModelMD5( const char *pcFileNameMesh, const CArray<CStr> &roArrFileNameAnim, bool bTexSmooth ) { CGMeshMD5::CModel *poModel = 0; CStr oFileEntry( pcFileNameMesh ); for( unsigned int i=0; i<roArrFileNameAnim.GetSize(); ++i ) { oFileEntry += "&"; oFileEntry += roArrFileNameAnim[i]; } poModel = (CGMeshMD5::CModel *)FindFileEntry( oFileEntry.GetData() ); if( !poModel ) { poModel = new CGMeshMD5::CModel; //if( !MakeModelMD5_( poModel, pcFileNameMesh, roArrFileNameAnim, bTexSmooth ) ) //{ // ERR( "ModelMD5 %s.\n", pcFileNameMesh ); // DELETE_INSTANCE( poModel ); // return 0; //} { if( !poModel->InitModel( DATA_DIR + /*"model/" +*/ pcFileNameMesh ) ) { ERR( "ModelMD5 %s.\n", pcFileNameMesh ); DELETE_INSTANCE( poModel ); return 0; } CArray<CGTex2 *> oArrTex; const unsigned int uiMeshCount = poModel->GetMeshCount(); oArrTex.Resize( uiMeshCount ); oArrTex.Fill( 0 ); unsigned int i = uiMeshCount; while( i ) { --i; const char *pcMaterialName = poModel->GetMaterialName( i ); if( pcMaterialName ) { oArrTex[i] = NewTexture( pcMaterialName, bTexSmooth, false ); } } const unsigned int uiAnimCount = roArrFileNameAnim.GetSize(); for( unsigned int uiAnim=0; uiAnim<uiAnimCount; ++uiAnim ) { LOG( "Loading %s.\n", roArrFileNameAnim[uiAnim].GetData() ); if( poModel->InsertNewAnim( DATA_DIR + /*"model/" +*/ roArrFileNameAnim[uiAnim] ) ) { for( unsigned int i=0; i<uiMeshCount; ++i ) { if( oArrTex.GetSize() >= i && oArrTex[i] ) { poModel->SetTex( i, uiAnim, oArrTex[i] ); } } } } poModel->SetAnim( poModel->GetAnimCount() - 1 ); } m_oArrModelMD5.Append( poModel ); NewFileEntry( oFileEntry.GetData(), poModel ); } else { LOG( "ModelMD5 skipped: %s.\n", pcFileNameMesh ); } //else //{ // // copy with shared data // poModel = new CGMeshMD5::CModel( *poModel ); // // m_oArrModelMD5.Append( poModel ); // LOG( "ModelMD5 copied: %s.\n", pcFileNameMesh ); //} return poModel; }
CABuffer * CGmResMan::NewABuffer( const char *pcFileName ) { CABuffer * poABuffer = (CABuffer *)FindFileEntry( pcFileName ); if( !poABuffer ) { CStr oFileName( CGmResMan::DATA_DIR + "audio/" + pcFileName ); const int iDot = oFileName.FindRev( oFileName.GetSize() - 1, '.' ); if( iDot < 0 ) return false; CStr oExt( oFileName.GetData() + iDot + 1 ); oExt.ToLower(); bool bLoadOk = false; LOG( "Loading %s.\n", oFileName.GetData() ); poABuffer = new CABuffer; poABuffer->Init(); if( oExt == "wav" ) { CFileStreamWav oWav; if( oWav.Open( oFileName, CFile::FLAG_READ ) ) { unsigned char * pcBuffer = new unsigned char[oWav.m_uiDataBytes]; if( pcBuffer ) { oWav.Read( pcBuffer, oWav.m_uiDataBytes ); //ASSERT( oWav.m_uiChannels == 1 ); if( poABuffer->Load( pcBuffer, oWav.m_uiDataBytes, oWav.m_uiChannels, oWav.m_uiSampleFreq ) ) { bLoadOk = true; } else { ERR( "Audio Buffer %s.\n", pcFileName ); DELETE_INSTANCE( poABuffer ); } DELETE_ARRAY( pcBuffer ); } } else { bLoadOk = false; } } #ifdef GM_USE_OGG else if( oExt == "ogg" ) { unsigned char *pucData = 0; unsigned int uiBytes = 0; unsigned int uiChannelCount = 0; unsigned int uiSampleFreq = 0; if( bLoadOk = LoadOGG_( oFileName, &pucData, &uiBytes, &uiChannelCount, &uiSampleFreq ) ) { poABuffer->Load( pucData, uiBytes, uiChannelCount, uiSampleFreq ); DELETE_ARRAY( pucData ); } } #endif // GM_USE_OGG else { ERR( "Audio File %s.\n", oFileName.GetData() ); bLoadOk = false; } if( poABuffer && bLoadOk ) { m_oArrABuffer.Append( poABuffer ); NewFileEntry( pcFileName, poABuffer ); } else { DELETE_INSTANCE( poABuffer ); } } else { LOG( "Audio file skipped: %s.\n", pcFileName ); } return poABuffer; }