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_MakePath

 

 

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_Load

 

 

Resource_Free(void *res)

  函数中调用free来释放。

void CALL HGE_Impl::Resource_Free(void *res)
{
    if(res) free(res);
}
Resource_Free

 

 

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_AttachPack

 

 

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_RemovePack 

 

 

Resource_RemoveAllPacks()

  删除资源队列中的所有资源

void CALL HGE_Impl::Resource_RemoveAllPacks()
{
    CResourceList *resItem=res, *resNextItem;

    while(resItem)
    {
        resNextItem=resItem->next;
        delete resItem;
        resItem=resNextItem;
    }

    res=0;
}
Resource_RemoveAllPacks 

 

 

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_EnumFiles 

 

 

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;
        }
    }
}
Resource_EnumFolders 

  

  前面的部分


posted @ 2016-05-24 22:14  YORU  阅读(290)  评论(0编辑  收藏  举报