]> icculus.org git repositories - btb/d2x.git/blob - include/cfile.h
build dumpmine.c for editor
[btb/d2x.git] / include / cfile.h
1 /* $Id: cfile.h,v 1.15 2004-12-04 04:07:16 btb 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
33 #define CFILE            PHYSFS_file
34 #define cfread(p,s,n,fp) PHYSFS_read(fp,p,s,n)
35 #define cfclose          PHYSFS_close
36 #define cftell           PHYSFS_tell
37 #define cfexist          PHYSFS_exists
38 #define cfilelength      PHYSFS_fileLength
39
40 //Open a file, set up a read buffer
41 static inline PHYSFS_file *cfopen(char *filename, char *mode)
42 {
43         PHYSFS_file *fp;
44         PHYSFS_uint64 bufSize;
45         
46         mode = mode;    // no warning
47
48         if (filename[0] == '\x01')
49         {
50                 //FIXME: don't look in dir, only in hogfile
51                 filename++;
52         }
53         fp = PHYSFS_openRead(filename);
54         if (!fp)
55                 return NULL;
56
57         bufSize = PHYSFS_fileLength(fp);
58         while (!PHYSFS_setBuffer(fp, bufSize) && bufSize)
59                 bufSize /= 2;   // even if the error isn't memory full, for a 20MB file it'll only do this 8 times
60
61         return fp;
62 }
63
64 //Specify the name of the hogfile.  Returns 1 if hogfile found & had files
65 static inline int cfile_init(char *hogname)
66 {
67         char pathname[PATH_MAX];
68
69         if (!PHYSFSX_getRealPath(hogname, pathname))
70                 return 0;
71
72         return PHYSFS_addToSearchPath(pathname, 1);
73 }
74
75 static inline int cfile_close(char *hogname)
76 {
77         char pathname[PATH_MAX];
78
79         if (!PHYSFSX_getRealPath(hogname, pathname))
80                 return 0;
81
82         return PHYSFS_removeFromSearchPath(pathname);
83 }
84
85
86 static inline int cfile_size(char *hogname)
87 {
88         PHYSFS_file *fp;
89         int size;
90
91         fp = PHYSFS_openRead(hogname);
92         if (fp == NULL)
93                 return -1;
94         size = PHYSFS_fileLength(fp);
95         cfclose(fp);
96
97         return size;
98 }
99
100 static inline int cfgetc(PHYSFS_file *const fp)
101 {
102         unsigned char c;
103
104         if (PHYSFS_read(fp, &c, 1, 1) != 1)
105                 return EOF;
106
107         return c;
108 }
109
110 static inline int cfseek(PHYSFS_file *fp, long int offset, int where)
111 {
112         int c, goal_position;
113
114         switch(where)
115         {
116         case SEEK_SET:
117                 goal_position = offset;
118                 break;
119         case SEEK_CUR:
120                 goal_position = PHYSFS_tell(fp) + offset;
121                 break;
122         case SEEK_END:
123                 goal_position = PHYSFS_fileLength(fp) + offset;
124                 break;
125         default:
126                 return 1;
127         }
128         c = PHYSFS_seek(fp, goal_position);
129         return !c;
130 }
131
132 static inline char * cfgets(char *buf, size_t n, PHYSFS_file *const fp)
133 {
134         int i;
135         int c;
136
137         for (i = 0; i < n - 1; i++)
138         {
139                 do
140                 {
141                         c = cfgetc(fp);
142                         if (c == EOF)
143                         {
144                                 *buf = 0;
145
146                                 return NULL;
147                         }
148                         if (c == 0 || c == 10)  // Unix line ending
149                                 break;
150                         if (c == 13)            // Mac or DOS line ending
151                         {
152                                 int c1;
153
154                                 c1 = cfgetc(fp);
155                                 if (c1 != EOF)  // The file could end with a Mac line ending
156                                         cfseek(fp, -1, SEEK_CUR);
157                                 if (c1 == 10) // DOS line ending
158                                         continue;
159                                 else            // Mac line ending
160                                         break;
161                         }
162                 } while (c == 13);
163                 if (c == 13)    // because cr-lf is a bad thing on the mac
164                         c = '\n';   // and anyway -- 0xod is CR on mac, not 0x0a
165                 if (c == '\n')
166                         break;
167                 *buf++ = c;
168         }
169         *buf = 0;
170
171         return buf;
172 }
173
174
175 /*
176  * read some data types...
177  */
178
179 static inline int cfile_read_int(PHYSFS_file *file)
180 {
181         int i;
182
183         if (!PHYSFS_readSLE32(file, &i))
184         {
185                 fprintf(stderr, "Error reading int in cfile_read_int()");
186                 exit(1);
187         }
188
189         return i;
190 }
191
192 static inline short cfile_read_short(PHYSFS_file *file)
193 {
194         int16_t s;
195
196         if (!PHYSFS_readSLE16(file, &s))
197         {
198                 fprintf(stderr, "Error reading short in cfile_read_short()");
199                 exit(1);
200         }
201
202         return s;
203 }
204
205 static inline sbyte cfile_read_byte(PHYSFS_file *file)
206 {
207         sbyte b;
208
209         if (PHYSFS_read(file, &b, sizeof(b), 1) != 1)
210         {
211                 fprintf(stderr, "Error reading byte in cfile_read_byte()");
212                 exit(1);
213         }
214
215         return b;
216 }
217
218 static inline fix cfile_read_fix(PHYSFS_file *file)
219 {
220         int f;  // a fix is defined as a long for Mac OS 9, and MPW can't convert from (long *) to (int *)
221
222         if (!PHYSFS_readSLE32(file, &f))
223         {
224                 fprintf(stderr, "Error reading fix in cfile_read_fix()");
225                 exit(1);
226         }
227
228         return f;
229 }
230
231 static inline fixang cfile_read_fixang(PHYSFS_file *file)
232 {
233         fixang f;
234
235         if (!PHYSFS_readSLE16(file, &f))
236         {
237                 fprintf(stderr, "Error reading fixang in cfile_read_fixang()");
238                 exit(1);
239         }
240
241         return f;
242 }
243
244 static inline void cfile_read_vector(vms_vector *v, PHYSFS_file *file)
245 {
246         v->x = cfile_read_fix(file);
247         v->y = cfile_read_fix(file);
248         v->z = cfile_read_fix(file);
249 }
250
251 static inline void cfile_read_angvec(vms_angvec *v, PHYSFS_file *file)
252 {
253         v->p = cfile_read_fixang(file);
254         v->b = cfile_read_fixang(file);
255         v->h = cfile_read_fixang(file);
256 }
257
258 static inline void cfile_read_matrix(vms_matrix *m,PHYSFS_file *file)
259 {
260         cfile_read_vector(&m->rvec,file);
261         cfile_read_vector(&m->uvec,file);
262         cfile_read_vector(&m->fvec,file);
263 }
264
265 #endif