hge source explor 0x7 resource module
Resource Module |
首先是关于资源加载会用到的参数和类型。
struct CResourceList { char filename[_MAX_PATH]; char password[64]; CResourceList* next; }; // Resources char szTmpFilename[_MAX_PATH]; CResourceList* res; HANDLE hSearch; WIN32_FIND_DATA SearchData; |
从参数中可以看出来是用一个队列来维护一组资源。
其中的函数
Resource_MakePath(const char *filename) |
在这个函数中处理文件名,将文件名+工程路径:
- 如果文件名为空,则直接使用工程路径
- 如果文件名中包含'\'、'/'、':',则说明已经是绝对路径,直接使用作为路径
- 其他的情况下,则完成 工程路径+文件名
- 如果存在'/'则转化为'\'
![]() 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; } |
Resource_Load(const char *filename, DWORD *size) |
在这个函数中实现资源的加载,并且返回资源的大小,函数的实现为:
先判断文件名称是否为绝对路径
①是绝对路径的情况下
- 打开文件
- 在内存中申请空间
- 并将文件复制到内存中去
- 将文件大小保存
②不是绝对路径的情况下
- 遍历资源队列
- 查看每一个zip资源内文件
- 找到之后则打开并读取文件
- 保存文件大小
- 没找到资源则用绝对路径的方式在加载资源
![]() void* CALL HGE_Impl::Resource_Load(const char *filename, DWORD *size) { static 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, &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; } |
Resource_Free(void *res) |
函数中调用free来释放。
![]() void CALL HGE_Impl::Resource_Free(void *res) { if(res) free(res); } |
Resource_AttachPack(const char *filename, const char *password) |
将压缩包资源加载到资源队列
- 得到资源的绝对路径
- 判断资源队列中是否已经存在资源,存在则不需要在加入
- 加入资源队列
![]() 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; } |
Resource_RemovePack(const char *filename) |
查找资源队列中的资源并删除。
![]() 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; } } |
Resource_RemoveAllPacks() |
删除资源队列中的所有资源
![]() void CALL HGE_Impl::Resource_RemoveAllPacks() { CResourceList *resItem=res, *resNextItem; while(resItem) { resNextItem=resItem->next; delete resItem; resItem=resNextItem; } res=0; } |
Resource_EnumFiles(const char *wildcard) |
遍历文件
根据参数查找文件,找到文件时判断文件类型:目录则进目录继续查找;文件则返回。
![]() 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; } } } |
Resource_EnumFolders(const char *wildcard) |
遍历目录
根据参数查找目录,找到文件时判断文件类型:为目录时还需要判断是否为上层目录和当前目录;不为目录则继续寻找直到彻底找完没有。
![]() 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; } } } |
前面的部分
![]() |