Mercurial > ~darius > hgwebdir.cgi > mikmod
comparison mmio/mmio.c @ 10:55420dceb8e0
Initial entry of mikmod into the CVS tree.
author | darius |
---|---|
date | Fri, 23 Jan 1998 16:05:11 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
9:990c9dadb348 | 10:55420dceb8e0 |
---|---|
1 /* | |
2 --> The MMIO Portable Input/Output functions | |
3 -> Divine Entertainment GameDev Libraries | |
4 | |
5 File: MMIO.C | |
6 | |
7 Description: | |
8 Miscellaneous I/O routines.. used to solve some portability issues | |
9 (like big/little endian machines and word alignment in structures ) | |
10 Also includes mikmod's ingenious error handling variable. | |
11 | |
12 Portability: | |
13 All systems - all compilers | |
14 | |
15 | |
16 ----------------------------------- | |
17 The way this module works - By Jake Stine [Air Richter] | |
18 | |
19 - _mm_fopen and _mm_copyfile will call the errorhandler [see mmerror.c] in | |
20 addition to setting _mm_errno on exit. | |
21 | |
22 - _mm_iobase is for internal use. It is used by ML_LoadFP() to ensure that it | |
23 works properly with wad files. | |
24 | |
25 - _mm_read_I_UWORD and _mm_read_M_UWORD have distinct differences: | |
26 the first is for reading data written by a little endian (intel) machine, | |
27 and the second is for reading big endian (Mac, RISC, Alpha) machine data. | |
28 | |
29 - _mm_write functions work the same as the _mm_read functions. | |
30 | |
31 - _mm_read_string is for reading binary strings. It is basically the same | |
32 as an fread of bytes. | |
33 */ | |
34 | |
35 #include "mmio.h" | |
36 #include <string.h> | |
37 | |
38 #define COPY_BUFSIZE 1024 | |
39 | |
40 static long _mm_iobase = 0, | |
41 temp_iobase = 0; | |
42 | |
43 UBYTE _mm_cpybuf[COPY_BUFSIZE]; | |
44 | |
45 | |
46 void StringWrite(CHAR *s, FILE *fp) | |
47 // Specialized file output procedure. Writes a UWORD length and then a | |
48 // string of the specified length (no NULL terminator) afterward. | |
49 { | |
50 int slen; | |
51 | |
52 if(s==NULL) | |
53 { _mm_write_I_UWORD(0,fp); | |
54 } else | |
55 { _mm_write_I_UWORD(slen = strlen(s),fp); | |
56 _mm_write_UBYTES(s,slen,fp); | |
57 } | |
58 } | |
59 | |
60 CHAR *StringRead(FILE *fp) | |
61 // Reads strings written out by StringWrite above: a UWORD length followed | |
62 // by length characters. A NULL is added to the string after loading. | |
63 { | |
64 CHAR *s; | |
65 UWORD len; | |
66 | |
67 len = _mm_read_I_UWORD(fp); | |
68 if(len==0) | |
69 { s = _mm_calloc(16, sizeof(CHAR)); | |
70 } else | |
71 { if((s = (CHAR *)_mm_malloc(len+1)) == NULL) return NULL; | |
72 _mm_read_UBYTES(s,len,fp); | |
73 s[len] = 0; | |
74 } | |
75 | |
76 return s; | |
77 } | |
78 | |
79 | |
80 FILE *_mm_fopen(CHAR *fname, CHAR *attrib) | |
81 { | |
82 FILE *fp; | |
83 | |
84 if((fp=fopen(fname,attrib)) == NULL) | |
85 { _mm_errno = _mm_errno = MMERR_OPENING_FILE; | |
86 if(_mm_errorhandler!=NULL) _mm_errorhandler(); | |
87 } | |
88 return fp; | |
89 } | |
90 | |
91 | |
92 int _mm_fseek(FILE *stream, long offset, int whence) | |
93 { | |
94 return fseek(stream,(whence==SEEK_SET) ? offset+_mm_iobase : offset, whence); | |
95 } | |
96 | |
97 | |
98 long _mm_ftell(FILE *stream) | |
99 { | |
100 return ftell(stream)-_mm_iobase; | |
101 } | |
102 | |
103 | |
104 BOOL _mm_FileExists(CHAR *fname) | |
105 { | |
106 FILE *fp; | |
107 | |
108 if((fp=fopen(fname,"r")) == NULL) return 0; | |
109 fclose(fp); | |
110 | |
111 return 1; | |
112 } | |
113 | |
114 | |
115 long _mm_flength(FILE *stream) | |
116 { | |
117 long tmp,tmp2; | |
118 | |
119 tmp = ftell(stream); | |
120 fseek(stream,0,SEEK_END); | |
121 tmp2 = ftell(stream); | |
122 fseek(stream,tmp,SEEK_SET); | |
123 return tmp2-tmp; | |
124 } | |
125 | |
126 | |
127 long _mm_iobase_get(void) | |
128 { | |
129 return _mm_iobase; | |
130 } | |
131 | |
132 | |
133 void _mm_iobase_set(long iobase) | |
134 { | |
135 temp_iobase = _mm_iobase; // store old value in case of revert | |
136 _mm_iobase = iobase; | |
137 } | |
138 | |
139 | |
140 // Sets the current file-position as the new _mm_iobase | |
141 void _mm_iobase_setcur(FILE *fp) | |
142 { | |
143 temp_iobase = _mm_iobase; // store old value in case of revert | |
144 _mm_iobase = ftell(fp); | |
145 } | |
146 | |
147 | |
148 // Reverts to the last known _mm_iobase value. | |
149 void _mm_iobase_revert(void) | |
150 { | |
151 _mm_iobase = temp_iobase; | |
152 } | |
153 | |
154 | |
155 // Procedure: _mm_copyfile | |
156 // Copies a given number of bytes from the source file to the destination | |
157 // file. Returns 1 on error, and calls the _mm_errnohandler, if registered. | |
158 BOOL _mm_copyfile(FILE *fpi, FILE *fpo, ULONG len) | |
159 { | |
160 ULONG todo; | |
161 | |
162 while(len) | |
163 { todo = (len > COPY_BUFSIZE) ? COPY_BUFSIZE : len; | |
164 if(!fread(_mm_cpybuf, todo, 1, fpi)) | |
165 { _mm_errno = _mm_errno = MMERR_END_OF_FILE; | |
166 if(_mm_errorhandler!=NULL) _mm_errorhandler(); | |
167 return 1; | |
168 } | |
169 if(!fwrite(_mm_cpybuf, todo, 1, fpo)) | |
170 { _mm_errno = _mm_errno = MMERR_DISK_FULL; | |
171 if(_mm_errorhandler!=NULL) _mm_errorhandler(); | |
172 return 1; | |
173 } | |
174 len -= todo; | |
175 } | |
176 | |
177 return 0; | |
178 } | |
179 | |
180 | |
181 void _mm_write_string(CHAR *data, FILE *fp) | |
182 { | |
183 if(data!=NULL) | |
184 _mm_write_UBYTES(data, strlen(data), fp); | |
185 } | |
186 | |
187 | |
188 void _mm_fputs(FILE *fp, CHAR *data) | |
189 { | |
190 if(data != NULL) | |
191 _mm_write_UBYTES(data, strlen(data), fp); | |
192 | |
193 #ifndef __UNIX__ | |
194 _mm_write_UBYTE(13,fp); | |
195 #endif | |
196 _mm_write_UBYTE(10,fp); | |
197 } | |
198 | |
199 | |
200 | |
201 /************* | |
202 // These have accompanying #define's in mmio.h | |
203 | |
204 void _mm_write_SBYTE(SBYTE data, FILE *fp) | |
205 { | |
206 fputc(data,fp); | |
207 } | |
208 | |
209 void _mm_write_UBYTE(UBYTE data,FILE *fp) | |
210 { | |
211 fputc(data,fp); | |
212 } | |
213 */ | |
214 | |
215 #ifdef MM_BIG_ENDIAN | |
216 | |
217 // --> Big Endian Write Functions | |
218 | |
219 void _mm_write_M_UWORD(UWORD data,FILE *fp) | |
220 { | |
221 _mm_write_UBYTE(data&0xff,fp); | |
222 _mm_write_UBYTE(data>>8,fp); | |
223 } | |
224 | |
225 | |
226 void _mm_write_I_UWORD(UWORD data,FILE *fp) | |
227 { | |
228 _mm_write_UBYTE(data>>8,fp); | |
229 _mm_write_UBYTE(data&0xff,fp); | |
230 } | |
231 | |
232 | |
233 void _mm_write_M_ULONG(ULONG data,FILE *fp) | |
234 { | |
235 _mm_write_M_UWORD(data&0xffff,fp); | |
236 _mm_write_M_UWORD(data>>16,fp); | |
237 } | |
238 | |
239 | |
240 void _mm_write_I_ULONG(ULONG data,FILE *fp) | |
241 { | |
242 _mm_write_I_UWORD(data>>16,fp); | |
243 _mm_write_I_UWORD(data&0xffff,fp); | |
244 } | |
245 | |
246 #else | |
247 | |
248 // --> Little Endian Write Functions | |
249 | |
250 void _mm_write_M_UWORD(UWORD data,FILE *fp) | |
251 { | |
252 _mm_write_UBYTE(data>>8,fp); | |
253 _mm_write_UBYTE(data&0xff,fp); | |
254 } | |
255 | |
256 | |
257 void _mm_write_I_UWORD(UWORD data,FILE *fp) | |
258 { | |
259 _mm_write_UBYTE(data&0xff,fp); | |
260 _mm_write_UBYTE(data>>8,fp); | |
261 } | |
262 | |
263 | |
264 void _mm_write_M_ULONG(ULONG data,FILE *fp) | |
265 { | |
266 _mm_write_M_UWORD(data>>16,fp); | |
267 _mm_write_M_UWORD(data&0xffff,fp); | |
268 } | |
269 | |
270 | |
271 void _mm_write_I_ULONG(ULONG data,FILE *fp) | |
272 { | |
273 _mm_write_I_UWORD(data&0xffff,fp); | |
274 _mm_write_I_UWORD(data>>16,fp); | |
275 } | |
276 | |
277 #endif | |
278 | |
279 | |
280 void _mm_write_M_SWORD(SWORD data,FILE *fp) | |
281 { | |
282 _mm_write_M_UWORD((UWORD)data,fp); | |
283 } | |
284 | |
285 | |
286 void _mm_write_I_SWORD(SWORD data,FILE *fp) | |
287 { | |
288 _mm_write_I_UWORD((UWORD)data,fp); | |
289 } | |
290 | |
291 | |
292 void _mm_write_M_SLONG(SLONG data,FILE *fp) | |
293 { | |
294 _mm_write_M_ULONG((ULONG)data,fp); | |
295 } | |
296 | |
297 | |
298 void _mm_write_I_SLONG(SLONG data,FILE *fp) | |
299 { | |
300 _mm_write_I_ULONG((ULONG)data,fp); | |
301 } | |
302 | |
303 | |
304 #define DEFINE_MULTIPLE_WRITE_FUNCTION(type_name, type) \ | |
305 void \ | |
306 _mm_write_##type_name##S (type *buffer, int number, FILE *fp) \ | |
307 { \ | |
308 while(number>0) \ | |
309 { _mm_write_##type_name(*(buffer++),fp); \ | |
310 number--; \ | |
311 } \ | |
312 } | |
313 | |
314 //DEFINE_MULTIPLE_WRITE_FUNCTION (SBYTE, SBYTE) | |
315 //DEFINE_MULTIPLE_WRITE_FUNCTION (UBYTE, UBYTE) | |
316 | |
317 DEFINE_MULTIPLE_WRITE_FUNCTION (M_SWORD, SWORD) | |
318 DEFINE_MULTIPLE_WRITE_FUNCTION (M_UWORD, UWORD) | |
319 DEFINE_MULTIPLE_WRITE_FUNCTION (I_SWORD, SWORD) | |
320 DEFINE_MULTIPLE_WRITE_FUNCTION (I_UWORD, UWORD) | |
321 | |
322 DEFINE_MULTIPLE_WRITE_FUNCTION (M_SLONG, SLONG) | |
323 DEFINE_MULTIPLE_WRITE_FUNCTION (M_ULONG, ULONG) | |
324 DEFINE_MULTIPLE_WRITE_FUNCTION (I_SLONG, SLONG) | |
325 DEFINE_MULTIPLE_WRITE_FUNCTION (I_ULONG, ULONG) | |
326 | |
327 | |
328 /********** | |
329 SBYTE _mm_read_SBYTE(FILE *fp) | |
330 { | |
331 return(fgetc(fp)); | |
332 } | |
333 | |
334 UBYTE _mm_read_UBYTE(FILE *fp) | |
335 { | |
336 return(fgetc(fp)); | |
337 } | |
338 **********/ | |
339 | |
340 | |
341 #ifdef MM_BIG_ENDIAN | |
342 | |
343 UWORD _mm_read_I_UWORD(FILE *fp) | |
344 { | |
345 UWORD result=((UWORD)_mm_read_UBYTE(fp))<<8; | |
346 result|=_mm_read_UBYTE(fp); | |
347 return result; | |
348 } | |
349 | |
350 UWORD _mm_read_M_UWORD(FILE *fp) | |
351 { | |
352 UWORD result=_mm_read_UBYTE(fp); | |
353 result|=((UWORD)_mm_read_UBYTE(fp))<<8; | |
354 return result; | |
355 } | |
356 | |
357 ULONG _mm_read_I_ULONG(FILE *fp) | |
358 { | |
359 ULONG result=((ULONG)_mm_read_M_UWORD(fp))<<16; | |
360 result|=_mm_read_M_UWORD(fp); | |
361 return result; | |
362 } | |
363 | |
364 ULONG _mm_read_M_ULONG(FILE *fp) | |
365 { | |
366 ULONG result=_mm_read_I_UWORD(fp); | |
367 result|=((ULONG)_mm_read_I_UWORD(fp))<<16; | |
368 return result; | |
369 } | |
370 | |
371 #else | |
372 | |
373 UWORD _mm_read_M_UWORD(FILE *fp) | |
374 { | |
375 UWORD result=((UWORD)_mm_read_UBYTE(fp))<<8; | |
376 result|=_mm_read_UBYTE(fp); | |
377 return result; | |
378 } | |
379 | |
380 UWORD _mm_read_I_UWORD(FILE *fp) | |
381 { | |
382 UWORD result=_mm_read_UBYTE(fp); | |
383 result|=((UWORD)_mm_read_UBYTE(fp))<<8; | |
384 return result; | |
385 } | |
386 | |
387 ULONG _mm_read_M_ULONG(FILE *fp) | |
388 { | |
389 ULONG result=((ULONG)_mm_read_M_UWORD(fp))<<16; | |
390 result|=_mm_read_M_UWORD(fp); | |
391 return result; | |
392 } | |
393 | |
394 ULONG _mm_read_I_ULONG(FILE *fp) | |
395 { | |
396 ULONG result=_mm_read_I_UWORD(fp); | |
397 result|=((ULONG)_mm_read_I_UWORD(fp))<<16; | |
398 return result; | |
399 } | |
400 | |
401 #endif | |
402 | |
403 SWORD _mm_read_M_SWORD(FILE *fp) | |
404 { | |
405 return((SWORD)_mm_read_M_UWORD(fp)); | |
406 } | |
407 | |
408 SWORD _mm_read_I_SWORD(FILE *fp) | |
409 { | |
410 return((SWORD)_mm_read_I_UWORD(fp)); | |
411 } | |
412 | |
413 SLONG _mm_read_M_SLONG(FILE *fp) | |
414 { | |
415 return((SLONG)_mm_read_M_ULONG(fp)); | |
416 } | |
417 | |
418 SLONG _mm_read_I_SLONG(FILE *fp) | |
419 { | |
420 return((SLONG)_mm_read_I_ULONG(fp)); | |
421 } | |
422 | |
423 | |
424 int _mm_read_string(CHAR *buffer, int number, FILE *fp) | |
425 { | |
426 fread(buffer,1,number,fp); | |
427 return !feof(fp); | |
428 } | |
429 | |
430 | |
431 | |
432 #define DEFINE_MULTIPLE_READ_FUNCTION(type_name, type) \ | |
433 int \ | |
434 _mm_read_##type_name##S (type *buffer, int number, FILE *fp) \ | |
435 { \ | |
436 while(number>0) \ | |
437 { *(buffer++)=_mm_read_##type_name(fp); \ | |
438 number--; \ | |
439 } \ | |
440 return !feof(fp); \ | |
441 } | |
442 | |
443 //DEFINE_MULTIPLE_READ_FUNCTION (SBYTE, SBYTE) | |
444 //DEFINE_MULTIPLE_READ_FUNCTION (UBYTE, UBYTE) | |
445 | |
446 DEFINE_MULTIPLE_READ_FUNCTION (M_SWORD, SWORD) | |
447 DEFINE_MULTIPLE_READ_FUNCTION (M_UWORD, UWORD) | |
448 DEFINE_MULTIPLE_READ_FUNCTION (I_SWORD, SWORD) | |
449 DEFINE_MULTIPLE_READ_FUNCTION (I_UWORD, UWORD) | |
450 | |
451 DEFINE_MULTIPLE_READ_FUNCTION (M_SLONG, SLONG) | |
452 DEFINE_MULTIPLE_READ_FUNCTION (M_ULONG, ULONG) | |
453 DEFINE_MULTIPLE_READ_FUNCTION (I_SLONG, SLONG) | |
454 DEFINE_MULTIPLE_READ_FUNCTION (I_ULONG, ULONG) | |
455 |