diff options
Diffstat (limited to 'apps/plugins/mikmod/mmio.c')
-rw-r--r-- | apps/plugins/mikmod/mmio.c | 517 |
1 files changed, 517 insertions, 0 deletions
diff --git a/apps/plugins/mikmod/mmio.c b/apps/plugins/mikmod/mmio.c new file mode 100644 index 0000000000..344833e632 --- /dev/null +++ b/apps/plugins/mikmod/mmio.c | |||
@@ -0,0 +1,517 @@ | |||
1 | /* MikMod sound library | ||
2 | (c) 1998, 1999, 2000 Miodrag Vallat and others - see file AUTHORS for | ||
3 | complete list. | ||
4 | |||
5 | This library is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU Library General Public License as | ||
7 | published by the Free Software Foundation; either version 2 of | ||
8 | the License, or (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU Library General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||
18 | 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /*============================================================================== | ||
22 | |||
23 | $Id: mmio.c,v 1.3 2005/03/30 19:10:58 realtech Exp $ | ||
24 | |||
25 | Portable file I/O routines | ||
26 | |||
27 | ==============================================================================*/ | ||
28 | |||
29 | /* | ||
30 | |||
31 | The way this module works: | ||
32 | |||
33 | - _mm_fopen will call the errorhandler [see mmerror.c] in addition to | ||
34 | setting _mm_errno on exit. | ||
35 | - _mm_iobase is for internal use. It is used by Player_LoadFP to | ||
36 | ensure that it works properly with wad files. | ||
37 | - _mm_read_I_* and _mm_read_M_* differ : the first is for reading data | ||
38 | written by a little endian (intel) machine, and the second is for reading | ||
39 | big endian (Mac, RISC, Alpha) machine data. | ||
40 | - _mm_write functions work the same as the _mm_read functions. | ||
41 | - _mm_read_string is for reading binary strings. It is basically the same | ||
42 | as an fread of bytes. | ||
43 | |||
44 | */ | ||
45 | |||
46 | #ifdef HAVE_CONFIG_H | ||
47 | #include "config.h" | ||
48 | #endif | ||
49 | |||
50 | #ifdef HAVE_UNISTD_H | ||
51 | #include <unistd.h> | ||
52 | #endif | ||
53 | |||
54 | #include <stdio.h> | ||
55 | #include <string.h> | ||
56 | |||
57 | #include "mikmod.h" | ||
58 | #include "mikmod_internals.h" | ||
59 | |||
60 | #ifdef SUNOS | ||
61 | extern int fclose(FILE *); | ||
62 | extern int fgetc(FILE *); | ||
63 | extern int fputc(int, FILE *); | ||
64 | extern size_t fread(void *, size_t, size_t, FILE *); | ||
65 | extern int fseek(FILE *, long, int); | ||
66 | extern size_t fwrite(const void *, size_t, size_t, FILE *); | ||
67 | #endif | ||
68 | |||
69 | #define COPY_BUFSIZE 1024 | ||
70 | |||
71 | /* some prototypes */ | ||
72 | static int _mm_MemReader_Eof(MREADER* reader); | ||
73 | static int _mm_MemReader_Read(MREADER* reader,void* ptr,size_t size); | ||
74 | static int _mm_MemReader_Get(MREADER* reader); | ||
75 | static int _mm_MemReader_Seek(MREADER* reader,long offset,int whence); | ||
76 | static long _mm_MemReader_Tell(MREADER* reader); | ||
77 | |||
78 | //static long _mm_iobase=0,temp_iobase=0; | ||
79 | |||
80 | int _mm_fopen(CHAR* fname,CHAR* attrib) | ||
81 | { | ||
82 | int fp; | ||
83 | |||
84 | //if(!(fp=fopen(fname,attrib))) { | ||
85 | // _mm_errno = MMERR_OPENING_FILE; | ||
86 | // if(_mm_errorhandler) _mm_errorhandler(); | ||
87 | //} | ||
88 | fp = open(fname, O_RDONLY); | ||
89 | if( fp < 0 ) { | ||
90 | _mm_errno = MMERR_OPENING_FILE; | ||
91 | if(_mm_errorhandler) _mm_errorhandler(); | ||
92 | } | ||
93 | return fp; | ||
94 | } | ||
95 | |||
96 | int _mm_FileExists(CHAR* fname) | ||
97 | { | ||
98 | int fp; | ||
99 | |||
100 | //if(!(fp=fopen(fname,"r"))) return 0; | ||
101 | //fclose(fp); | ||
102 | fp = open(fname, O_RDONLY); | ||
103 | if ( fp < 0 ) return 0; | ||
104 | close(fp); | ||
105 | |||
106 | return 1; | ||
107 | } | ||
108 | |||
109 | int _mm_fclose(int fp) | ||
110 | { | ||
111 | //return fclose(fp); | ||
112 | return close(fp); | ||
113 | } | ||
114 | |||
115 | /* Sets the current file-position as the new iobase */ | ||
116 | void _mm_iobase_setcur(MREADER* reader) | ||
117 | { | ||
118 | reader->prev_iobase=reader->iobase; /* store old value in case of revert */ | ||
119 | reader->iobase=reader->Tell(reader); | ||
120 | } | ||
121 | |||
122 | /* Reverts to the last known iobase value. */ | ||
123 | void _mm_iobase_revert(MREADER* reader) | ||
124 | { | ||
125 | reader->iobase=reader->prev_iobase; | ||
126 | } | ||
127 | |||
128 | /*========== File Reader */ | ||
129 | |||
130 | typedef struct MFILEREADER { | ||
131 | MREADER core; | ||
132 | int file; | ||
133 | } MFILEREADER; | ||
134 | |||
135 | static int _mm_FileReader_Eof(MREADER* reader) | ||
136 | { | ||
137 | //return feof(((MFILEREADER*)reader)->file); | ||
138 | int size = filesize(((MFILEREADER*)reader)->file); | ||
139 | int offset = lseek(((MFILEREADER*)reader)->file, 0, SEEK_CUR); | ||
140 | return offset < 0; | ||
141 | return (size <= 0 || offset < 0 || offset >= size) ? 1 : 0; | ||
142 | } | ||
143 | |||
144 | static int _mm_FileReader_Read(MREADER* reader,void* ptr,size_t size) | ||
145 | { | ||
146 | //return !!fread(ptr,size,1,((MFILEREADER*)reader)->file); | ||
147 | return read(((MFILEREADER*)reader)->file, ptr, size); | ||
148 | } | ||
149 | |||
150 | static int _mm_FileReader_Get(MREADER* reader) | ||
151 | { | ||
152 | //return fgetc(((MFILEREADER*)reader)->file); | ||
153 | unsigned char c; | ||
154 | if ( read(((MFILEREADER*)reader)->file, &c, 1) ) | ||
155 | return c; | ||
156 | else | ||
157 | return EOF; | ||
158 | } | ||
159 | |||
160 | static int _mm_FileReader_Seek(MREADER* reader,long offset,int whence) | ||
161 | { | ||
162 | //return fseek(((MFILEREADER*)reader)->file, | ||
163 | // (whence==SEEK_SET)?offset+reader->iobase:offset,whence); | ||
164 | return lseek(((MFILEREADER*)reader)->file, | ||
165 | (whence==SEEK_SET)?offset+reader->iobase:offset,whence); | ||
166 | } | ||
167 | |||
168 | static long _mm_FileReader_Tell(MREADER* reader) | ||
169 | { | ||
170 | //return ftell(((MFILEREADER*)reader)->file)-reader->iobase; | ||
171 | return lseek( (((MFILEREADER*)reader)->file)-reader->iobase, 0, SEEK_CUR ); | ||
172 | } | ||
173 | |||
174 | MREADER *_mm_new_file_reader(int fp) | ||
175 | { | ||
176 | MFILEREADER* reader=(MFILEREADER*)MikMod_malloc(sizeof(MFILEREADER)); | ||
177 | if (reader) { | ||
178 | reader->core.Eof =&_mm_FileReader_Eof; | ||
179 | reader->core.Read=&_mm_FileReader_Read; | ||
180 | reader->core.Get =&_mm_FileReader_Get; | ||
181 | reader->core.Seek=&_mm_FileReader_Seek; | ||
182 | reader->core.Tell=&_mm_FileReader_Tell; | ||
183 | reader->file=fp; | ||
184 | } | ||
185 | return (MREADER*)reader; | ||
186 | } | ||
187 | |||
188 | void _mm_delete_file_reader (MREADER* reader) | ||
189 | { | ||
190 | if(reader) MikMod_free(reader); | ||
191 | } | ||
192 | |||
193 | /*========== File Writer */ | ||
194 | |||
195 | typedef struct MFILEWRITER { | ||
196 | MWRITER core; | ||
197 | int file; | ||
198 | } MFILEWRITER; | ||
199 | |||
200 | static int _mm_FileWriter_Seek(MWRITER* writer,long offset,int whence) | ||
201 | { | ||
202 | //return fseek(((MFILEWRITER*)writer)->file,offset,whence); | ||
203 | return lseek(((MFILEREADER*)writer)->file,offset,whence); | ||
204 | } | ||
205 | |||
206 | static long _mm_FileWriter_Tell(MWRITER* writer) | ||
207 | { | ||
208 | //return ftell(((MFILEWRITER*)writer)->file); | ||
209 | return lseek(((MFILEWRITER*)writer)->file, 0, SEEK_CUR); | ||
210 | } | ||
211 | |||
212 | static int _mm_FileWriter_Write(MWRITER* writer,void* ptr,size_t size) | ||
213 | { | ||
214 | //return (fwrite(ptr,size,1,((MFILEWRITER*)writer)->file)==size); | ||
215 | return (write(ptr,size,((MFILEWRITER*)writer)->file)==size); | ||
216 | } | ||
217 | |||
218 | static int _mm_FileWriter_Put(MWRITER* writer,int value) | ||
219 | { | ||
220 | //return fputc(value,((MFILEWRITER*)writer)->file); | ||
221 | return 1; // TODO | ||
222 | } | ||
223 | |||
224 | MWRITER *_mm_new_file_writer(int fp) | ||
225 | { | ||
226 | MFILEWRITER* writer=(MFILEWRITER*)MikMod_malloc(sizeof(MFILEWRITER)); | ||
227 | if (writer) { | ||
228 | writer->core.Seek =&_mm_FileWriter_Seek; | ||
229 | writer->core.Tell =&_mm_FileWriter_Tell; | ||
230 | writer->core.Write=&_mm_FileWriter_Write; | ||
231 | writer->core.Put =&_mm_FileWriter_Put; | ||
232 | writer->file=fp; | ||
233 | } | ||
234 | return (MWRITER*) writer; | ||
235 | } | ||
236 | |||
237 | void _mm_delete_file_writer (MWRITER* writer) | ||
238 | { | ||
239 | if(writer) MikMod_free (writer); | ||
240 | } | ||
241 | |||
242 | /*========== Memory Reader */ | ||
243 | |||
244 | |||
245 | typedef struct MMEMREADER { | ||
246 | MREADER core; | ||
247 | const void *buffer; | ||
248 | long len; | ||
249 | long pos; | ||
250 | } MMEMREADER; | ||
251 | |||
252 | void _mm_delete_mem_reader(MREADER* reader) | ||
253 | { | ||
254 | if (reader) { MikMod_free(reader); } | ||
255 | } | ||
256 | |||
257 | MREADER *_mm_new_mem_reader(const void *buffer, int len) | ||
258 | { | ||
259 | MMEMREADER* reader=(MMEMREADER*)MikMod_malloc(sizeof(MMEMREADER)); | ||
260 | if (reader) | ||
261 | { | ||
262 | reader->core.Eof =&_mm_MemReader_Eof; | ||
263 | reader->core.Read=&_mm_MemReader_Read; | ||
264 | reader->core.Get =&_mm_MemReader_Get; | ||
265 | reader->core.Seek=&_mm_MemReader_Seek; | ||
266 | reader->core.Tell=&_mm_MemReader_Tell; | ||
267 | reader->buffer = buffer; | ||
268 | reader->len = len; | ||
269 | reader->pos = 0; | ||
270 | } | ||
271 | return (MREADER*)reader; | ||
272 | } | ||
273 | |||
274 | static int _mm_MemReader_Eof(MREADER* reader) | ||
275 | { | ||
276 | if (!reader) { return 1; } | ||
277 | if ( ((MMEMREADER*)reader)->pos > ((MMEMREADER*)reader)->len ) { | ||
278 | return 1; | ||
279 | } | ||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | static int _mm_MemReader_Read(MREADER* reader,void* ptr,size_t size) | ||
284 | { | ||
285 | unsigned char *d=ptr; | ||
286 | const unsigned char *s; | ||
287 | |||
288 | if (!reader) { return 0; } | ||
289 | |||
290 | if (reader->Eof(reader)) { return 0; } | ||
291 | |||
292 | s = ((MMEMREADER*)reader)->buffer; | ||
293 | s += ((MMEMREADER*)reader)->pos; | ||
294 | |||
295 | if ( ((MMEMREADER*)reader)->pos + size > ((MMEMREADER*)reader)->len) | ||
296 | { | ||
297 | ((MMEMREADER*)reader)->pos = ((MMEMREADER*)reader)->len; | ||
298 | return 0; /* not enough remaining bytes */ | ||
299 | } | ||
300 | |||
301 | ((MMEMREADER*)reader)->pos += (long)size; | ||
302 | |||
303 | while (size--) | ||
304 | { | ||
305 | *d = *s; | ||
306 | s++; | ||
307 | d++; | ||
308 | } | ||
309 | |||
310 | return 1; | ||
311 | } | ||
312 | |||
313 | static int _mm_MemReader_Get(MREADER* reader) | ||
314 | { | ||
315 | int pos; | ||
316 | |||
317 | if (reader->Eof(reader)) { return 0; } | ||
318 | |||
319 | pos = ((MMEMREADER*)reader)->pos; | ||
320 | ((MMEMREADER*)reader)->pos++; | ||
321 | |||
322 | return ((unsigned char*)(((MMEMREADER*)reader)->buffer))[pos]; | ||
323 | } | ||
324 | |||
325 | static int _mm_MemReader_Seek(MREADER* reader,long offset,int whence) | ||
326 | { | ||
327 | if (!reader) { return -1; } | ||
328 | |||
329 | switch(whence) | ||
330 | { | ||
331 | case SEEK_CUR: | ||
332 | ((MMEMREADER*)reader)->pos += offset; | ||
333 | break; | ||
334 | case SEEK_SET: | ||
335 | ((MMEMREADER*)reader)->pos = offset; | ||
336 | break; | ||
337 | case SEEK_END: | ||
338 | ((MMEMREADER*)reader)->pos = ((MMEMREADER*)reader)->len - offset - 1; | ||
339 | break; | ||
340 | } | ||
341 | if ( ((MMEMREADER*)reader)->pos < 0) { ((MMEMREADER*)reader)->pos = 0; } | ||
342 | if ( ((MMEMREADER*)reader)->pos > ((MMEMREADER*)reader)->len ) { | ||
343 | ((MMEMREADER*)reader)->pos = ((MMEMREADER*)reader)->len; | ||
344 | } | ||
345 | return 0; | ||
346 | } | ||
347 | |||
348 | static long _mm_MemReader_Tell(MREADER* reader) | ||
349 | { | ||
350 | if (reader) { | ||
351 | return ((MMEMREADER*)reader)->pos; | ||
352 | } | ||
353 | return 0; | ||
354 | } | ||
355 | |||
356 | /*========== Write functions */ | ||
357 | |||
358 | void _mm_write_string(CHAR* data,MWRITER* writer) | ||
359 | { | ||
360 | if(data) | ||
361 | _mm_write_UBYTES(data,strlen(data),writer); | ||
362 | } | ||
363 | |||
364 | void _mm_write_M_UWORD(UWORD data,MWRITER* writer) | ||
365 | { | ||
366 | _mm_write_UBYTE(data>>8,writer); | ||
367 | _mm_write_UBYTE(data&0xff,writer); | ||
368 | } | ||
369 | |||
370 | void _mm_write_I_UWORD(UWORD data,MWRITER* writer) | ||
371 | { | ||
372 | _mm_write_UBYTE(data&0xff,writer); | ||
373 | _mm_write_UBYTE(data>>8,writer); | ||
374 | } | ||
375 | |||
376 | void _mm_write_M_ULONG(ULONG data,MWRITER* writer) | ||
377 | { | ||
378 | _mm_write_M_UWORD(data>>16,writer); | ||
379 | _mm_write_M_UWORD(data&0xffff,writer); | ||
380 | } | ||
381 | |||
382 | void _mm_write_I_ULONG(ULONG data,MWRITER* writer) | ||
383 | { | ||
384 | _mm_write_I_UWORD(data&0xffff,writer); | ||
385 | _mm_write_I_UWORD(data>>16,writer); | ||
386 | } | ||
387 | |||
388 | void _mm_write_M_SWORD(SWORD data,MWRITER* writer) | ||
389 | { | ||
390 | _mm_write_M_UWORD((UWORD)data,writer); | ||
391 | } | ||
392 | |||
393 | void _mm_write_I_SWORD(SWORD data,MWRITER* writer) | ||
394 | { | ||
395 | _mm_write_I_UWORD((UWORD)data,writer); | ||
396 | } | ||
397 | |||
398 | void _mm_write_M_SLONG(SLONG data,MWRITER* writer) | ||
399 | { | ||
400 | _mm_write_M_ULONG((ULONG)data,writer); | ||
401 | } | ||
402 | |||
403 | void _mm_write_I_SLONG(SLONG data,MWRITER* writer) | ||
404 | { | ||
405 | _mm_write_I_ULONG((ULONG)data,writer); | ||
406 | } | ||
407 | |||
408 | #if defined __STDC__ || defined _MSC_VER || defined MPW_C | ||
409 | #define DEFINE_MULTIPLE_WRITE_FUNCTION(type_name,type) \ | ||
410 | void _mm_write_##type_name##S (type *buffer,int number,MWRITER* writer) \ | ||
411 | { \ | ||
412 | while(number-->0) \ | ||
413 | _mm_write_##type_name(*(buffer++),writer); \ | ||
414 | } | ||
415 | #else | ||
416 | #define DEFINE_MULTIPLE_WRITE_FUNCTION(type_name,type) \ | ||
417 | void _mm_write_/**/type_name/**/S (type *buffer,int number,MWRITER* writer) \ | ||
418 | { \ | ||
419 | while(number-->0) \ | ||
420 | _mm_write_/**/type_name(*(buffer++),writer); \ | ||
421 | } | ||
422 | #endif | ||
423 | |||
424 | DEFINE_MULTIPLE_WRITE_FUNCTION(M_SWORD,SWORD) | ||
425 | DEFINE_MULTIPLE_WRITE_FUNCTION(M_UWORD,UWORD) | ||
426 | DEFINE_MULTIPLE_WRITE_FUNCTION(I_SWORD,SWORD) | ||
427 | DEFINE_MULTIPLE_WRITE_FUNCTION(I_UWORD,UWORD) | ||
428 | |||
429 | DEFINE_MULTIPLE_WRITE_FUNCTION(M_SLONG,SLONG) | ||
430 | DEFINE_MULTIPLE_WRITE_FUNCTION(M_ULONG,ULONG) | ||
431 | DEFINE_MULTIPLE_WRITE_FUNCTION(I_SLONG,SLONG) | ||
432 | DEFINE_MULTIPLE_WRITE_FUNCTION(I_ULONG,ULONG) | ||
433 | |||
434 | /*========== Read functions */ | ||
435 | |||
436 | int _mm_read_string(CHAR* buffer,int number,MREADER* reader) | ||
437 | { | ||
438 | return reader->Read(reader,buffer,number); | ||
439 | } | ||
440 | |||
441 | UWORD _mm_read_M_UWORD(MREADER* reader) | ||
442 | { | ||
443 | UWORD result=((UWORD)_mm_read_UBYTE(reader))<<8; | ||
444 | result|=_mm_read_UBYTE(reader); | ||
445 | return result; | ||
446 | } | ||
447 | |||
448 | UWORD _mm_read_I_UWORD(MREADER* reader) | ||
449 | { | ||
450 | UWORD result=_mm_read_UBYTE(reader); | ||
451 | result|=((UWORD)_mm_read_UBYTE(reader))<<8; | ||
452 | return result; | ||
453 | } | ||
454 | |||
455 | ULONG _mm_read_M_ULONG(MREADER* reader) | ||
456 | { | ||
457 | ULONG result=((ULONG)_mm_read_M_UWORD(reader))<<16; | ||
458 | result|=_mm_read_M_UWORD(reader); | ||
459 | return result; | ||
460 | } | ||
461 | |||
462 | ULONG _mm_read_I_ULONG(MREADER* reader) | ||
463 | { | ||
464 | ULONG result=_mm_read_I_UWORD(reader); | ||
465 | result|=((ULONG)_mm_read_I_UWORD(reader))<<16; | ||
466 | return result; | ||
467 | } | ||
468 | |||
469 | SWORD _mm_read_M_SWORD(MREADER* reader) | ||
470 | { | ||
471 | return((SWORD)_mm_read_M_UWORD(reader)); | ||
472 | } | ||
473 | |||
474 | SWORD _mm_read_I_SWORD(MREADER* reader) | ||
475 | { | ||
476 | return((SWORD)_mm_read_I_UWORD(reader)); | ||
477 | } | ||
478 | |||
479 | SLONG _mm_read_M_SLONG(MREADER* reader) | ||
480 | { | ||
481 | return((SLONG)_mm_read_M_ULONG(reader)); | ||
482 | } | ||
483 | |||
484 | SLONG _mm_read_I_SLONG(MREADER* reader) | ||
485 | { | ||
486 | return((SLONG)_mm_read_I_ULONG(reader)); | ||
487 | } | ||
488 | |||
489 | #if defined __STDC__ || defined _MSC_VER || defined MPW_C | ||
490 | #define DEFINE_MULTIPLE_READ_FUNCTION(type_name,type) \ | ||
491 | int _mm_read_##type_name##S (type *buffer,int number,MREADER* reader) \ | ||
492 | { \ | ||
493 | while(number-->0) \ | ||
494 | *(buffer++)=_mm_read_##type_name(reader); \ | ||
495 | return !reader->Eof(reader); \ | ||
496 | } | ||
497 | #else | ||
498 | #define DEFINE_MULTIPLE_READ_FUNCTION(type_name,type) \ | ||
499 | int _mm_read_/**/type_name/**/S (type *buffer,int number,MREADER* reader) \ | ||
500 | { \ | ||
501 | while(number-->0) \ | ||
502 | *(buffer++)=_mm_read_/**/type_name(reader); \ | ||
503 | return !reader->Eof(reader); \ | ||
504 | } | ||
505 | #endif | ||
506 | |||
507 | DEFINE_MULTIPLE_READ_FUNCTION(M_SWORD,SWORD) | ||
508 | DEFINE_MULTIPLE_READ_FUNCTION(M_UWORD,UWORD) | ||
509 | DEFINE_MULTIPLE_READ_FUNCTION(I_SWORD,SWORD) | ||
510 | DEFINE_MULTIPLE_READ_FUNCTION(I_UWORD,UWORD) | ||
511 | |||
512 | DEFINE_MULTIPLE_READ_FUNCTION(M_SLONG,SLONG) | ||
513 | DEFINE_MULTIPLE_READ_FUNCTION(M_ULONG,ULONG) | ||
514 | DEFINE_MULTIPLE_READ_FUNCTION(I_SLONG,SLONG) | ||
515 | DEFINE_MULTIPLE_READ_FUNCTION(I_ULONG,ULONG) | ||
516 | |||
517 | /* ex:set ts=4: */ | ||