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