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