aboutsummaryrefslogtreecommitdiff
path: root/archive/hge/resource.cpp
diff options
context:
space:
mode:
authorGravatar Chris Xiong <chirs241097@gmail.com> 2015-10-26 22:52:36 +0800
committerGravatar Chris Xiong <chirs241097@gmail.com> 2015-10-26 22:52:36 +0800
commit3bd383baf6a17e734329e1fc677c7e86283db772 (patch)
tree69a9148087577f797624ceb9c71323a2563d6bb4 /archive/hge/resource.cpp
parent543e4f570be9b279ba558ca61cc02cda251af384 (diff)
downloadbullet-lab-remix-3bd383baf6a17e734329e1fc677c7e86283db772.tar.xz
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.
Diffstat (limited to 'archive/hge/resource.cpp')
-rw-r--r--archive/hge/resource.cpp394
1 files changed, 394 insertions, 0 deletions
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 <zlib.h> // 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);
+}