]> icculus.org git repositories - btb/d2x.git/blob - include/cfile.h
change cfopen to use buffers (speeding it up), and use cfopen instead of PHYSFS_openR...
[btb/d2x.git] / include / cfile.h
1 /* $Id: cfile.h,v 1.16 2005-01-23 14:38:04 schaffner Exp $ */
2 /*
3 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
4 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
5 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
6 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
7 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
8 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
9 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
10 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
11 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
12 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
13 */
14
15 /*
16  *
17  * Wrappers for physfs abstraction layer
18  *
19  */
20
21 #ifndef _CFILE_H
22 #define _CFILE_H
23
24 #include <stdio.h>
25 #include <string.h>
26 #include <physfs.h>
27
28 #include "pstypes.h"
29 #include "maths.h"
30 #include "vecmat.h"
31 #include "physfsx.h"
32 #include "strutil.h"
33
34 #define CFILE            PHYSFS_file
35 #define cfread(p,s,n,fp) PHYSFS_read(fp,p,s,n)
36 #define cfclose          PHYSFS_close
37 #define cftell           PHYSFS_tell
38 #define cfexist          PHYSFS_exists
39 #define cfilelength      PHYSFS_fileLength
40
41 //Open a file, set up a buffer
42 static inline PHYSFS_file *cfopen(char *filename, char *mode)
43 {
44         PHYSFS_file *fp;
45         PHYSFS_uint64 bufSize = 1024*1024;
46         
47         if (filename[0] == '\x01')
48         {
49                 //FIXME: don't look in dir, only in hogfile
50                 filename++;
51         }
52
53         if (!stricmp(mode, "rb"))
54         {
55                 fp = PHYSFS_openRead(filename);
56                 if (!fp)
57                         return NULL;
58                 bufSize = PHYSFS_fileLength(fp);
59         }
60         else if (!stricmp(mode, "wb"))
61         {
62                 fp = PHYSFS_openWrite(filename);
63                 if (!fp)
64                         return NULL;
65         }
66                 
67         while (!PHYSFS_setBuffer(fp, bufSize) && bufSize)
68                 bufSize /= 2;   // even if the error isn't memory full, for a 20MB file it'll only do this 8 times
69
70         return fp;
71 }
72
73 //Specify the name of the hogfile.  Returns 1 if hogfile found & had files
74 static inline int cfile_init(char *hogname)
75 {
76         char pathname[PATH_MAX];
77
78         if (!PHYSFSX_getRealPath(hogname, pathname))
79                 return 0;
80
81         return PHYSFS_addToSearchPath(pathname, 1);
82 }
83
84 static inline int cfile_close(char *hogname)
85 {
86         char pathname[PATH_MAX];
87
88         if (!PHYSFSX_getRealPath(hogname, pathname))
89                 return 0;
90
91         return PHYSFS_removeFromSearchPath(pathname);
92 }
93
94
95 static inline int cfile_size(char *hogname)
96 {
97         PHYSFS_file *fp;
98         int size;
99
100         fp = PHYSFS_openRead(hogname);
101         if (fp == NULL)
102                 return -1;
103         size = PHYSFS_fileLength(fp);
104         cfclose(fp);
105
106         return size;
107 }
108
109 static inline int cfgetc(PHYSFS_file *const fp)
110 {
111         unsigned char c;
112
113         if (PHYSFS_read(fp, &c, 1, 1) != 1)
114                 return EOF;
115
116         return c;
117 }
118
119 static inline int cfseek(PHYSFS_file *fp, long int offset, int where)
120 {
121         int c, goal_position;
122
123         switch(where)
124         {
125         case SEEK_SET:
126                 goal_position = offset;
127                 break;
128         case SEEK_CUR:
129                 goal_position = PHYSFS_tell(fp) + offset;
130                 break;
131         case SEEK_END:
132                 goal_position = PHYSFS_fileLength(fp) + offset;
133                 break;
134         default:
135                 return 1;
136         }
137         c = PHYSFS_seek(fp, goal_position);
138         return !c;
139 }
140
141 static inline char * cfgets(char *buf, size_t n, PHYSFS_file *const fp)
142 {
143         int i;
144         int c;
145
146         for (i = 0; i < n - 1; i++)
147         {
148                 do
149                 {
150                         c = cfgetc(fp);
151                         if (c == EOF)
152                         {
153                                 *buf = 0;
154
155                                 return NULL;
156                         }
157                         if (c == 0 || c == 10)  // Unix line ending
158                                 break;
159                         if (c == 13)            // Mac or DOS line ending
160                         {
161                                 int c1;
162
163                                 c1 = cfgetc(fp);
164                                 if (c1 != EOF)  // The file could end with a Mac line ending
165                                         cfseek(fp, -1, SEEK_CUR);
166                                 if (c1 == 10) // DOS line ending
167                                         continue;
168                                 else            // Mac line ending
169                                         break;
170                         }
171                 } while (c == 13);
172                 if (c == 13)    // because cr-lf is a bad thing on the mac
173                         c = '\n';   // and anyway -- 0xod is CR on mac, not 0x0a
174                 if (c == '\n')
175                         break;
176                 *buf++ = c;
177         }
178         *buf = 0;
179
180         return buf;
181 }
182
183
184 /*
185  * read some data types...
186  */
187
188 static inline int cfile_read_int(PHYSFS_file *file)
189 {
190         int i;
191
192         if (!PHYSFS_readSLE32(file, &i))
193         {
194                 fprintf(stderr, "Error reading int in cfile_read_int()");
195                 exit(1);
196         }
197
198         return i;
199 }
200
201 static inline short cfile_read_short(PHYSFS_file *file)
202 {
203         int16_t s;
204
205         if (!PHYSFS_readSLE16(file, &s))
206         {
207                 fprintf(stderr, "Error reading short in cfile_read_short()");
208                 exit(1);
209         }
210
211         return s;
212 }
213
214 static inline sbyte cfile_read_byte(PHYSFS_file *file)
215 {
216         sbyte b;
217
218         if (PHYSFS_read(file, &b, sizeof(b), 1) != 1)
219         {
220                 fprintf(stderr, "Error reading byte in cfile_read_byte()");
221                 exit(1);
222         }
223
224         return b;
225 }
226
227 static inline fix cfile_read_fix(PHYSFS_file *file)
228 {
229         int f;  // a fix is defined as a long for Mac OS 9, and MPW can't convert from (long *) to (int *)
230
231         if (!PHYSFS_readSLE32(file, &f))
232         {
233                 fprintf(stderr, "Error reading fix in cfile_read_fix()");
234                 exit(1);
235         }
236
237         return f;
238 }
239
240 static inline fixang cfile_read_fixang(PHYSFS_file *file)
241 {
242         fixang f;
243
244         if (!PHYSFS_readSLE16(file, &f))
245         {
246                 fprintf(stderr, "Error reading fixang in cfile_read_fixang()");
247                 exit(1);
248         }
249
250         return f;
251 }
252
253 static inline void cfile_read_vector(vms_vector *v, PHYSFS_file *file)
254 {
255         v->x = cfile_read_fix(file);
256         v->y = cfile_read_fix(file);
257         v->z = cfile_read_fix(file);
258 }
259
260 static inline void cfile_read_angvec(vms_angvec *v, PHYSFS_file *file)
261 {
262         v->p = cfile_read_fixang(file);
263         v->b = cfile_read_fixang(file);
264         v->h = cfile_read_fixang(file);
265 }
266
267 static inline void cfile_read_matrix(vms_matrix *m,PHYSFS_file *file)
268 {
269         cfile_read_vector(&m->rvec,file);
270         cfile_read_vector(&m->uvec,file);
271         cfile_read_vector(&m->fvec,file);
272 }
273
274 #endif