From 3bd383baf6a17e734329e1fc677c7e86283db772 Mon Sep 17 00:00:00 2001 From: Chris Xiong Date: Mon, 26 Oct 2015 22:52:36 +0800 Subject: Added support for relative line numbers. Added instructions for, brk and cont. (They are still untested...) Parser code cleanup. Removed garbage output to stderr. Reorganize the repository structure. Updated BLR2 code move it into archive. Added BLR1 files. --- archive/hge/resource.cpp | 394 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 394 insertions(+) create mode 100644 archive/hge/resource.cpp (limited to 'archive/hge/resource.cpp') diff --git a/archive/hge/resource.cpp b/archive/hge/resource.cpp new file mode 100644 index 0000000..4937ee1 --- /dev/null +++ b/archive/hge/resource.cpp @@ -0,0 +1,394 @@ +/* +** Haaf's Game Engine 1.8 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** Core functions implementation: resources management +*/ + +#include "hge_impl.h" + +#include // the system version is better here. HGE's is out of date. + +#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); + + while(resItem) + { + if(!strcmp(szName,resItem->filename)) return false; + resItem=resItem->next; + } + + zip=unzOpen(szName); + if(!zip) { + System_Log("Unable to unzip: %s", szName); + 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); + + 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; +} + +void* CALL HGE_Impl::Resource_Load(const char *filename, DWORD *size) +{ + 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; + FILE *hF; + + if(filename[0]=='\\' || filename[0]=='/' || filename[1]==':') goto _fromfile; // skip absolute paths + + // Load from pack + + strcpy(szName,filename); + 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); + 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 = fopen(Resource_MakePath(filename), "rb"); + if(hF == NULL) + { + sprintf(szName, res_err, filename); + _PostError(szName); + return 0; + } + + struct stat statbuf; + if (fstat(fileno(hF), &statbuf) == -1) + { + fclose(hF); + sprintf(szName, res_err, filename); + _PostError(szName); + return 0; + } + + file_info.uncompressed_size = statbuf.st_size; + ptr = malloc(file_info.uncompressed_size); + if(!ptr) + { + fclose(hF); + sprintf(szName, res_err, filename); + _PostError(szName); + return 0; + } + if(fread(ptr, file_info.uncompressed_size, 1, hF) != 1) + { + fclose(hF); + free(ptr); + sprintf(szName, res_err, filename); + _PostError(szName); + return 0; + } + + fclose(hF); + + if(size) *size=file_info.uncompressed_size; + return ptr; +} + + +void CALL HGE_Impl::Resource_Free(void *res) +{ + if(res) free(res); +} + +// this is from PhysicsFS originally ( http://icculus.org/physfs/ ) +// (also zlib-licensed.) +static int locateOneElement(char *buf) +{ + char *ptr = NULL; + DIR *dirp = NULL; + struct dirent *dent = NULL; + + if (access(buf, F_OK) == 0) + return 1; /* quick rejection: exists in current case. */ + + ptr = strrchr(buf, '/'); /* find entry at end of path. */ + if (ptr == NULL) + { + dirp = opendir("."); + ptr = buf; + } + else + { + *ptr = '\0'; + dirp = opendir(buf); + *ptr = '/'; + ptr++; /* point past dirsep to entry itself. */ + } + + while ((dent = readdir(dirp)) != NULL) + { + if (strcasecmp(dent->d_name, ptr) == 0) + { + strcpy(ptr, dent->d_name); /* found a match. Overwrite with this case. */ + closedir(dirp); + return 1; + } + } + + /* no match at all... */ + closedir(dirp); + return 0; +} + +static int locateCorrectCase(char *buf) +{ + char *ptr = buf; + + while ((ptr = strchr(ptr + 1, '/'))) + { + *ptr = '\0'; /* block this path section off */ + if (!locateOneElement(buf)) + { + *ptr = '/'; /* restore path separator */ + return -2; /* missing element in path. */ + } + *ptr = '/'; /* restore path separator */ + } + + /* check final element... */ + return locateOneElement(buf) ? 0 : -1; +} + +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]='/'; } + + locateCorrectCase(szTmpFilename); + + return szTmpFilename; +} + +// !!! FIXME: kinda messy, and probably doesn't get all the corner cases right. +bool HGE_Impl::_WildcardMatch(const char *str, const char *wildcard) +{ + if ((str == NULL) || (wildcard == NULL)) + return false; + + while ((*str) && (*wildcard)) + { + const char wildch = *wildcard; + const char strch = *str; + if (wildch == '?') + ; // okay. + else if (wildch == '*') + { + do { + wildcard++; + } while (((*wildcard == '*') || (*wildcard == '?')) && (*wildcard != '\0')); + const char newwild = *wildcard; + if (newwild == '\0') return true; + const char *ptr = str; + while (*ptr) // find the greediest match possible... + { + if (*ptr == newwild) + str = ptr; + ptr++; + } + } + else if ( (toupper(strch)) != (toupper(wildch)) ) + { + return false; + } + + str++; + wildcard++; + } + + while (*wildcard == '*') + wildcard++; + + return ((*str == '\0') && (*wildcard == '\0')); +} + +bool HGE_Impl::_PrepareFileEnum(const char *wildcard) +{ + if(hSearch) { closedir(hSearch); hSearch=0; } + char *madepath = Resource_MakePath(wildcard); + const char *fname = strrchr(madepath, '/'); + const char *dir = NULL; + if (fname == NULL) { + dir = "."; + fname = madepath; + } else { + dir = madepath; + char *ptr = (char *) fname; + *ptr = '\0'; // split dir and filename. + fname++; + } + + strcpy(szSearchDir, dir); + strcpy(szSearchWildcard, fname); + + hSearch=opendir(dir); + return (hSearch!=0); +} + +char *HGE_Impl::_DoEnumIteration(const bool wantdir) +{ + if(!hSearch) return 0; + while (true) + { + struct dirent *dent = readdir(hSearch); + if(dent == NULL) { closedir(hSearch); hSearch=0; return 0; } + if ((strcmp(dent->d_name, ".") == 0) || (strcmp(dent->d_name, "..") == 0)) + continue; + if (!_WildcardMatch(dent->d_name, szSearchWildcard)) + continue; + char fullpath[_MAX_PATH]; + snprintf(fullpath, sizeof (fullpath), "%s/%s", szSearchDir, dent->d_name); + struct stat statbuf; + if (stat(fullpath, &statbuf) == -1) // this follows symlinks. + continue; + const bool isdir = ((S_ISDIR(statbuf.st_mode)) != 0); + if (isdir == wantdir) // this treats pipes, devs, etc, as "files" ... + { + strcpy(szSearchResult, dent->d_name); + return szSearchResult; + } + } + return 0; +} + +char* CALL HGE_Impl::Resource_EnumFiles(const char *wildcard) +{ + if(wildcard) + { + if (!_PrepareFileEnum(wildcard)) + return 0; + } + return _DoEnumIteration(false); +} + +char* CALL HGE_Impl::Resource_EnumFolders(const char *wildcard) +{ + if(wildcard) + { + if (!_PrepareFileEnum(wildcard)) + return 0; + } + return _DoEnumIteration(true); +} -- cgit v1.2.3