/* ** Haaf's Game Engine 1.8 ** Copyright (C) 2003-2007, Relish Games ** hge.relishgames.com ** ** Core functions implementation: resources management */ #include "hge_impl.h" #define NOCRYPT //#define NOUNCRYPT #include "ZLIB/unzip.h" bool CALL HGE_Impl::Resource_AttachPack(const char *filename, const char *password) { char *szName; CResourceList *resItem=res; unzFile zip; szName=Resource_MakePath(filename); strupr(szName); while(resItem) { if(!strcmp(szName,resItem->filename)) return false; resItem=resItem->next; } zip=unzOpen(szName); if(!zip) return false; unzClose(zip); resItem=new CResourceList; strcpy(resItem->filename, szName); if(password) strcpy(resItem->password, password); else resItem->password[0]=0; resItem->next=res; res=resItem; return true; } void CALL HGE_Impl::Resource_RemovePack(const char *filename) { char *szName; CResourceList *resItem=res, *resPrev=0; szName=Resource_MakePath(filename); strupr(szName); while(resItem) { if(!strcmp(szName,resItem->filename)) { if(resPrev) resPrev->next=resItem->next; else res=resItem->next; delete resItem; break; } resPrev=resItem; resItem=resItem->next; } } void CALL HGE_Impl::Resource_RemoveAllPacks() { CResourceList *resItem=res, *resNextItem; while(resItem) { resNextItem=resItem->next; delete resItem; resItem=resNextItem; } res=0; } #undef DWORD void* CALL HGE_Impl::Resource_Load(const char *filename, DWORD *size) { static const char *res_err="Can't load resource: %s"; CResourceList *resItem=res; char szName[_MAX_PATH]; char szZipName[_MAX_PATH]; unzFile zip; unz_file_info file_info; int done, i; void *ptr; HANDLE hF; if(filename[0]=='\\' || filename[0]=='/' || filename[1]==':') goto _fromfile; // skip absolute paths // Load from pack strcpy(szName,filename); strupr(szName); for(i=0; szName[i]; i++) { if(szName[i]=='/') szName[i]='\\'; } while(resItem) { zip=unzOpen(resItem->filename); done=unzGoToFirstFile(zip); while(done==UNZ_OK) { unzGetCurrentFileInfo(zip, &file_info, szZipName, sizeof(szZipName), NULL, 0, NULL, 0); strupr(szZipName); for(i=0; szZipName[i]; i++) { if(szZipName[i]=='/') szZipName[i]='\\'; } if(!strcmp(szName,szZipName)) { if(unzOpenCurrentFilePassword(zip, resItem->password[0] ? resItem->password : 0) != UNZ_OK) { unzClose(zip); sprintf(szName, res_err, filename); _PostError(szName); return 0; } ptr = malloc(file_info.uncompressed_size); if(!ptr) { unzCloseCurrentFile(zip); unzClose(zip); sprintf(szName, res_err, filename); _PostError(szName); return 0; } if(unzReadCurrentFile(zip, ptr, file_info.uncompressed_size) < 0) { unzCloseCurrentFile(zip); unzClose(zip); free(ptr); sprintf(szName, res_err, filename); _PostError(szName); return 0; } unzCloseCurrentFile(zip); unzClose(zip); if(size) *size=file_info.uncompressed_size; return ptr; } done=unzGoToNextFile(zip); } unzClose(zip); resItem=resItem->next; } // Load from file _fromfile: hF = CreateFile(Resource_MakePath(filename), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL); if(hF == INVALID_HANDLE_VALUE) { sprintf(szName, res_err, filename); _PostError(szName); return 0; } file_info.uncompressed_size = GetFileSize(hF, NULL); ptr = malloc(file_info.uncompressed_size); if(!ptr) { CloseHandle(hF); sprintf(szName, res_err, filename); _PostError(szName); return 0; } if(ReadFile(hF, ptr, file_info.uncompressed_size, (LPDWORD)&file_info.uncompressed_size, NULL ) == 0) { CloseHandle(hF); free(ptr); sprintf(szName, res_err, filename); _PostError(szName); return 0; } CloseHandle(hF); if(size) *size=file_info.uncompressed_size; return ptr; } void CALL HGE_Impl::Resource_Free(void *res) { if(res) free(res); } char* CALL HGE_Impl::Resource_MakePath(const char *filename) { int i; if(!filename) strcpy(szTmpFilename, szAppPath); else if(filename[0]=='\\' || filename[0]=='/' || filename[1]==':') strcpy(szTmpFilename, filename); else { strcpy(szTmpFilename, szAppPath); if(filename) strcat(szTmpFilename, filename); } for(i=0; szTmpFilename[i]; i++) { if(szTmpFilename[i]=='/') szTmpFilename[i]='\\'; } return szTmpFilename; } char* CALL HGE_Impl::Resource_EnumFiles(const char *wildcard) { if(wildcard) { if(hSearch) { FindClose(hSearch); hSearch=0; } hSearch=FindFirstFile(Resource_MakePath(wildcard), &SearchData); if(hSearch==INVALID_HANDLE_VALUE) { hSearch=0; return 0; } if(!(SearchData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) return SearchData.cFileName; else return Resource_EnumFiles(); } else { if(!hSearch) return 0; for(;;) { if(!FindNextFile(hSearch, &SearchData)) { FindClose(hSearch); hSearch=0; return 0; } if(!(SearchData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) return SearchData.cFileName; } } } char* CALL HGE_Impl::Resource_EnumFolders(const char *wildcard) { if(wildcard) { if(hSearch) { FindClose(hSearch); hSearch=0; } hSearch=FindFirstFile(Resource_MakePath(wildcard), &SearchData); if(hSearch==INVALID_HANDLE_VALUE) { hSearch=0; return 0; } if((SearchData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && strcmp(SearchData.cFileName,".") && strcmp(SearchData.cFileName,"..")) return SearchData.cFileName; else return Resource_EnumFolders(); } else { if(!hSearch) return 0; for(;;) { if(!FindNextFile(hSearch, &SearchData)) { FindClose(hSearch); hSearch=0; return 0; } if((SearchData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && strcmp(SearchData.cFileName,".") && strcmp(SearchData.cFileName,"..")) return SearchData.cFileName; } } }