4 * Some simple physfs extensions
11 #if !defined(macintosh) && !defined(_MSC_VER)
12 #include <sys/param.h>
14 #if defined(__linux__)
16 #elif defined(__MACH__) && defined(__APPLE__)
17 #include <sys/mount.h>
29 // Initialise PhysicsFS, set up basic search paths and add arguments from .ini file(s).
30 // The arguments are used to determine the search paths, so the first .ini file must be
31 // in the same directory as D2X. A second one can be in the user directory.
32 static inline void PHYSFSX_init(int argc, char *argv[])
37 PHYSFS_permitSymbolicLinks(1);
39 PHYSFS_addToSearchPath(PHYSFS_getBaseDir(), 1);
40 InitArgs( argc,argv );
42 if ((t = FindArg("-userdir"))
44 || 1 // or if it's a unix platform
48 // This stuff below seems overly complicated - brad
50 char *path = Args[t+1];
51 char fullPath[PATH_MAX + 5];
57 PHYSFS_removeFromSearchPath(PHYSFS_getBaseDir());
59 if (path[0] == '~') // yes, this tilde can be put before non-unix paths.
61 const char *home = PHYSFS_getUserDir();
63 strcpy(fullPath, home); // prepend home to the path
65 if (*path == *PHYSFS_getDirSeparator())
67 strncat(fullPath, path, PATH_MAX + 5 - strlen(home));
70 strncpy(fullPath, path, PATH_MAX + 5);
72 PHYSFS_setWriteDir(fullPath);
73 if (!PHYSFS_getWriteDir())
76 char ancestor[PATH_MAX + 5]; // the directory which actually exists
77 char child[PATH_MAX + 5]; // the directory relative to the above we're trying to make
79 strcpy(ancestor, fullPath);
80 while (!PHYSFS_getWriteDir() && ((p = strrchr(ancestor, *PHYSFS_getDirSeparator()))))
83 { // separator at the end (intended here, for safety)
84 *p = 0; // kill this separator
85 if (!((p = strrchr(ancestor, *PHYSFS_getDirSeparator()))))
86 break; // give up, this is (usually) the root directory
89 p[1] = 0; // go to parent
90 PHYSFS_setWriteDir(ancestor);
93 strcpy(child, fullPath + strlen(ancestor));
94 for (p = child; (p = strchr(p, *PHYSFS_getDirSeparator())); p++)
97 PHYSFS_setWriteDir(fullPath);
100 PHYSFS_addToSearchPath(PHYSFS_getWriteDir(), 1);
104 if (!PHYSFS_getWriteDir())
106 PHYSFS_setWriteDir(PHYSFS_getBaseDir());
107 if (!PHYSFS_getWriteDir())
108 Error("can't set write dir\n");
110 PHYSFS_addToSearchPath(PHYSFS_getWriteDir(), 0);
113 //tell cfile where hogdir is
114 if ((t=FindArg("-hogdir")))
115 PHYSFS_addToSearchPath(Args[t + 1], 1);
117 else if (!FindArg("-nohogdir"))
118 PHYSFS_addToSearchPath(SHAREPATH, 1);
121 PHYSFS_addToSearchPath(":Data:", 1); // untested
125 static inline PHYSFS_sint64 PHYSFSX_readString(PHYSFS_file *file, char *s)
129 if (PHYSFS_eof(file))
133 PHYSFS_read(file, ptr, 1, 1);
134 while (!PHYSFS_eof(file) && *ptr++ != 0);
139 static inline PHYSFS_sint64 PHYSFSX_gets(PHYSFS_file *file, char *s)
143 if (PHYSFS_eof(file))
147 PHYSFS_read(file, ptr, 1, 1);
148 while (!PHYSFS_eof(file) && *ptr++ != '\n');
154 static inline PHYSFS_sint64 PHYSFSX_writeU8(PHYSFS_file *file, PHYSFS_uint8 val)
156 return PHYSFS_write(file, &val, 1, 1);
159 static inline PHYSFS_sint64 PHYSFSX_writeString(PHYSFS_file *file, const char *s)
161 return PHYSFS_write(file, s, 1, (PHYSFS_uint32)strlen(s) + 1);
164 static inline PHYSFS_sint64 PHYSFSX_puts(PHYSFS_file *file, const char *s)
166 return PHYSFS_write(file, s, 1, (PHYSFS_uint32)strlen(s));
169 static inline int PHYSFSX_putc(PHYSFS_file *file, int c)
171 unsigned char ch = (unsigned char)c;
173 if (PHYSFS_write(file, &ch, 1, 1) < 1)
179 static inline PHYSFS_sint64 PHYSFSX_printf(PHYSFS_file *file, const char *format, ...)
184 va_start(args, format);
185 vsprintf(buffer, format, args);
187 return PHYSFSX_puts(file, buffer);
190 #define PHYSFSX_writeFix PHYSFS_writeSLE32
191 #define PHYSFSX_writeFixAng PHYSFS_writeSLE16
193 static inline int PHYSFSX_writeVector(PHYSFS_file *file, vms_vector *v)
195 if (PHYSFSX_writeFix(file, v->x) < 1 ||
196 PHYSFSX_writeFix(file, v->y) < 1 ||
197 PHYSFSX_writeFix(file, v->z) < 1)
203 static inline int PHYSFSX_writeAngleVec(PHYSFS_file *file, vms_angvec *v)
205 if (PHYSFSX_writeFixAng(file, v->p) < 1 ||
206 PHYSFSX_writeFixAng(file, v->b) < 1 ||
207 PHYSFSX_writeFixAng(file, v->h) < 1)
213 static inline int PHYSFSX_writeMatrix(PHYSFS_file *file, vms_matrix *m)
215 if (PHYSFSX_writeVector(file, &m->rvec) < 1 ||
216 PHYSFSX_writeVector(file, &m->uvec) < 1 ||
217 PHYSFSX_writeVector(file, &m->fvec) < 1)
223 static inline int PHYSFSX_getRealPath(const char *stdPath, char *realPath)
225 const char *realDir = PHYSFS_getRealDir(stdPath);
226 const char *sep = PHYSFS_getDirSeparator();
231 realDir = PHYSFS_getWriteDir();
236 strncpy(realPath, realDir, PATH_MAX - 1);
237 if (strlen(realPath) >= strlen(sep))
239 p = realPath + strlen(realPath) - strlen(sep);
240 if (strcmp(p, sep)) // no sep at end of realPath
241 strncat(realPath, sep, PATH_MAX - 1 - strlen(realPath));
244 if (strlen(stdPath) >= 1)
251 strncat(realPath, sep, PATH_MAX - 1 - strlen(realPath));
254 if (strlen(realPath) < PATH_MAX - 2)
256 p = realPath + strlen(realPath);
267 static inline int PHYSFSX_rename(const char *oldpath, const char *newpath)
269 char old[PATH_MAX], new[PATH_MAX];
271 PHYSFSX_getRealPath(oldpath, old);
272 PHYSFSX_getRealPath(newpath, new);
273 return (rename(old, new) == 0);
277 // returns -1 if error
278 // Gets bytes free in current write dir
279 static inline PHYSFS_sint64 PHYSFSX_getFreeDiskSpace()
281 #if defined(__linux__) || (defined(__MACH__) && defined(__APPLE__))
284 if (!statfs(PHYSFS_getWriteDir(), &sfs))
285 return (PHYSFS_sint64)(sfs.f_bavail * sfs.f_bsize);
293 //Open a file for reading, set up a buffer
294 static inline PHYSFS_file *PHYSFSX_openReadBuffered(const char *filename)
297 PHYSFS_uint64 bufSize;
299 if (filename[0] == '\x01')
301 //FIXME: don't look in dir, only in hogfile
305 fp = PHYSFS_openRead(filename);
309 bufSize = PHYSFS_fileLength(fp);
310 while (!PHYSFS_setBuffer(fp, bufSize) && bufSize)
311 bufSize /= 2; // even if the error isn't memory full, for a 20MB file it'll only do this 8 times
316 //Open a file for writing, set up a buffer
317 static inline PHYSFS_file *PHYSFSX_openWriteBuffered(const char *filename)
320 PHYSFS_uint64 bufSize = 1024*1024; // hmm, seems like an OK size.
322 fp = PHYSFS_openWrite(filename);
326 while (!PHYSFS_setBuffer(fp, bufSize) && bufSize)
332 #endif /* PHYSFSX_H */