summaryrefslogtreecommitdiff
path: root/apps/plugins/mikmod/mmio.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/mikmod/mmio.c')
-rw-r--r--apps/plugins/mikmod/mmio.c517
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
61extern int fclose(FILE *);
62extern int fgetc(FILE *);
63extern int fputc(int, FILE *);
64extern size_t fread(void *, size_t, size_t, FILE *);
65extern int fseek(FILE *, long, int);
66extern size_t fwrite(const void *, size_t, size_t, FILE *);
67#endif
68
69#define COPY_BUFSIZE 1024
70
71/* some prototypes */
72static int _mm_MemReader_Eof(MREADER* reader);
73static int _mm_MemReader_Read(MREADER* reader,void* ptr,size_t size);
74static int _mm_MemReader_Get(MREADER* reader);
75static int _mm_MemReader_Seek(MREADER* reader,long offset,int whence);
76static long _mm_MemReader_Tell(MREADER* reader);
77
78//static long _mm_iobase=0,temp_iobase=0;
79
80int _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
96int _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
109int _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 */
116void _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. */
123void _mm_iobase_revert(MREADER* reader)
124{
125 reader->iobase=reader->prev_iobase;
126}
127
128/*========== File Reader */
129
130typedef struct MFILEREADER {
131 MREADER core;
132 int file;
133} MFILEREADER;
134
135static 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
144static 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
150static 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
160static 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
168static 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
174MREADER *_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
188void _mm_delete_file_reader (MREADER* reader)
189{
190 if(reader) MikMod_free(reader);
191}
192
193/*========== File Writer */
194
195typedef struct MFILEWRITER {
196 MWRITER core;
197 int file;
198} MFILEWRITER;
199
200static 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
206static long _mm_FileWriter_Tell(MWRITER* writer)
207{
208 //return ftell(((MFILEWRITER*)writer)->file);
209 return lseek(((MFILEWRITER*)writer)->file, 0, SEEK_CUR);
210}
211
212static 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
218static int _mm_FileWriter_Put(MWRITER* writer,int value)
219{
220 //return fputc(value,((MFILEWRITER*)writer)->file);
221 return 1; // TODO
222}
223
224MWRITER *_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
237void _mm_delete_file_writer (MWRITER* writer)
238{
239 if(writer) MikMod_free (writer);
240}
241
242/*========== Memory Reader */
243
244
245typedef struct MMEMREADER {
246 MREADER core;
247 const void *buffer;
248 long len;
249 long pos;
250} MMEMREADER;
251
252void _mm_delete_mem_reader(MREADER* reader)
253{
254 if (reader) { MikMod_free(reader); }
255}
256
257MREADER *_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
274static 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
283static 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
313static 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
325static 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
348static 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
358void _mm_write_string(CHAR* data,MWRITER* writer)
359{
360 if(data)
361 _mm_write_UBYTES(data,strlen(data),writer);
362}
363
364void _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
370void _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
376void _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
382void _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
388void _mm_write_M_SWORD(SWORD data,MWRITER* writer)
389{
390 _mm_write_M_UWORD((UWORD)data,writer);
391}
392
393void _mm_write_I_SWORD(SWORD data,MWRITER* writer)
394{
395 _mm_write_I_UWORD((UWORD)data,writer);
396}
397
398void _mm_write_M_SLONG(SLONG data,MWRITER* writer)
399{
400 _mm_write_M_ULONG((ULONG)data,writer);
401}
402
403void _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) \
410void _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) \
417void _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
424DEFINE_MULTIPLE_WRITE_FUNCTION(M_SWORD,SWORD)
425DEFINE_MULTIPLE_WRITE_FUNCTION(M_UWORD,UWORD)
426DEFINE_MULTIPLE_WRITE_FUNCTION(I_SWORD,SWORD)
427DEFINE_MULTIPLE_WRITE_FUNCTION(I_UWORD,UWORD)
428
429DEFINE_MULTIPLE_WRITE_FUNCTION(M_SLONG,SLONG)
430DEFINE_MULTIPLE_WRITE_FUNCTION(M_ULONG,ULONG)
431DEFINE_MULTIPLE_WRITE_FUNCTION(I_SLONG,SLONG)
432DEFINE_MULTIPLE_WRITE_FUNCTION(I_ULONG,ULONG)
433
434/*========== Read functions */
435
436int _mm_read_string(CHAR* buffer,int number,MREADER* reader)
437{
438 return reader->Read(reader,buffer,number);
439}
440
441UWORD _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
448UWORD _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
455ULONG _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
462ULONG _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
469SWORD _mm_read_M_SWORD(MREADER* reader)
470{
471 return((SWORD)_mm_read_M_UWORD(reader));
472}
473
474SWORD _mm_read_I_SWORD(MREADER* reader)
475{
476 return((SWORD)_mm_read_I_UWORD(reader));
477}
478
479SLONG _mm_read_M_SLONG(MREADER* reader)
480{
481 return((SLONG)_mm_read_M_ULONG(reader));
482}
483
484SLONG _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) \
491int _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) \
499int _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
507DEFINE_MULTIPLE_READ_FUNCTION(M_SWORD,SWORD)
508DEFINE_MULTIPLE_READ_FUNCTION(M_UWORD,UWORD)
509DEFINE_MULTIPLE_READ_FUNCTION(I_SWORD,SWORD)
510DEFINE_MULTIPLE_READ_FUNCTION(I_UWORD,UWORD)
511
512DEFINE_MULTIPLE_READ_FUNCTION(M_SLONG,SLONG)
513DEFINE_MULTIPLE_READ_FUNCTION(M_ULONG,ULONG)
514DEFINE_MULTIPLE_READ_FUNCTION(I_SLONG,SLONG)
515DEFINE_MULTIPLE_READ_FUNCTION(I_ULONG,ULONG)
516
517/* ex:set ts=4: */