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