--- /dev/null
+/* MikMod sound library\r
+ (c) 1998, 1999, 2000 Miodrag Vallat and others - see file AUTHORS for\r
+ complete list.\r
+\r
+ This library is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU Library General Public License as\r
+ published by the Free Software Foundation; either version 2 of\r
+ the License, or (at your option) any later version.\r
+ \r
+ This program is distributed in the hope that it will be useful,\r
+ but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU Library General Public License for more details.\r
+ \r
+ You should have received a copy of the GNU Library General Public\r
+ License along with this library; if not, write to the Free Software\r
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA\r
+ 02111-1307, USA.\r
+*/\r
+\r
+/*==============================================================================\r
+\r
+ $Id: mmio.c,v 1.2 2004/02/06 19:29:05 raph Exp $\r
+\r
+ Portable file I/O routines\r
+\r
+==============================================================================*/\r
+\r
+/*\r
+\r
+ The way this module works:\r
+\r
+ - _mm_fopen will call the errorhandler [see mmerror.c] in addition to\r
+ setting _mm_errno on exit.\r
+ - _mm_iobase is for internal use. It is used by Player_LoadFP to\r
+ ensure that it works properly with wad files.\r
+ - _mm_read_I_* and _mm_read_M_* differ : the first is for reading data\r
+ written by a little endian (intel) machine, and the second is for reading\r
+ big endian (Mac, RISC, Alpha) machine data.\r
+ - _mm_write functions work the same as the _mm_read functions.\r
+ - _mm_read_string is for reading binary strings. It is basically the same\r
+ as an fread of bytes.\r
+\r
+*/\r
+\r
+/* FIXME\r
+ the _mm_iobase variable ought to be MREADER-specific. It will eventually\r
+ become a private field of the MREADER structure, but this will require a\r
+ soname version bump.\r
+\r
+ In the meantime, the drawback is that if you use the xxx_LoadFP functions,\r
+ you can't have several MREADER objects with different iobase values.\r
+*/\r
+\r
+#ifdef HAVE_CONFIG_H\r
+#include "config.h"\r
+#endif\r
+\r
+#ifdef HAVE_UNISTD_H\r
+#include <unistd.h>\r
+#endif\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+\r
+#include "mikmod_internals.h"\r
+\r
+#define COPY_BUFSIZE 1024\r
+\r
+static long _mm_iobase=0,temp_iobase=0;\r
+\r
+\r
+int _mm_fopen(CHAR* fname,int attrib)\r
+{\r
+ int fp;\r
+\r
+ fp=rb->open(fname,attrib);\r
+ if(fp == -1) {\r
+ fp = 0;\r
+ _mm_errno = MMERR_OPENING_FILE;\r
+ if(_mm_errorhandler) _mm_errorhandler();\r
+ }\r
+ return fp;\r
+}\r
+\r
+BOOL _mm_FileExists(CHAR* fname)\r
+{\r
+ int fp;\r
+\r
+ if(!(fp=rb->open(fname, O_RDONLY))) return 0;\r
+ rb->close(fp);\r
+\r
+ return 1;\r
+}\r
+\r
+int _mm_fclose(int fp)\r
+{\r
+ return rb->close(fp);\r
+}\r
+\r
+/* Sets the current file-position as the new _mm_iobase */\r
+void _mm_iobase_setcur(MREADER* reader)\r
+{\r
+ temp_iobase=_mm_iobase; /* store old value in case of revert */\r
+ _mm_iobase=reader->Tell(reader);\r
+}\r
+\r
+/* Reverts to the last known _mm_iobase value. */\r
+void _mm_iobase_revert(void)\r
+{\r
+ _mm_iobase=temp_iobase;\r
+}\r
+\r
+/*========== File Reader */\r
+\r
+typedef struct MFILEREADER {\r
+ MREADER core;\r
+ int file;\r
+ int waseof;\r
+} MFILEREADER;\r
+\r
+static BOOL _mm_FileReader_Eof(MREADER* reader)\r
+{\r
+ /*\r
+ if ((lseek(((MFILEREADER*)reader)->file, 0, SEEK_CUR)-_mm_iobase) < filesize(((MFILEREADER*)reader)->file))\r
+ return 0;\r
+ else\r
+ return 1;\r
+ */\r
+ return ((MFILEREADER*)reader)->waseof;\r
+}\r
+\r
+static BOOL _mm_FileReader_Read(MREADER* reader,void* ptr,size_t size)\r
+{\r
+ int tempb;\r
+ tempb = rb->read(((MFILEREADER*)reader)->file, ptr, size);\r
+ //printf("(**) READ: %i\n", tempb);\r
+ /*\r
+ if (tempb != size)\r
+ {\r
+ printf("Read: count: %i newpos: %i return: %i\n", size, lseek(((MFILEREADER*)reader)->file-_mm_iobase, 0, SEEK_CUR), tempb);\r
+ }\r
+ */\r
+ if ((tempb < 1) && size > 0)\r
+ {\r
+ tempb = 0;\r
+ ((MFILEREADER*)reader)->waseof = 1;\r
+ }\r
+ else\r
+ {\r
+ ((MFILEREADER*)reader)->waseof = 0;\r
+ }\r
+ return tempb;\r
+}\r
+\r
+static int _mm_FileReader_Get(MREADER* reader)\r
+{\r
+ char buf;\r
+ if ((rb->read(((MFILEREADER*)reader)->file, &buf, 1) > 0) == 1)\r
+ {\r
+ ((MFILEREADER*)reader)->waseof = 0;\r
+ //printf("Get: newpos: %i _mm_iobase: %i\n", lseek(((MFILEREADER*)reader)->file-_mm_iobase, 0, SEEK_CUR), _mm_iobase);\r
+ return buf;\r
+ }\r
+ else\r
+ {\r
+ ((MFILEREADER*)reader)->waseof = 1;\r
+ //printf("Get: newpos: %i _mm_iobase: %i\n", lseek(((MFILEREADER*)reader)->file-_mm_iobase, 0, SEEK_CUR), _mm_iobase);\r
+ return EOF;\r
+ }\r
+}\r
+\r
+static BOOL _mm_FileReader_Seek(MREADER* reader,long offset,int whence)\r
+{\r
+ long tempb;\r
+\r
+ tempb = rb->lseek(((MFILEREADER*)reader)->file,\r
+ (whence==SEEK_SET)?offset+_mm_iobase:offset,whence);\r
+ ((MFILEREADER*)reader)->waseof = 0;\r
+ //printf("(**) SEEK: %i\n", tempb);\r
+ if (tempb < 0)\r
+ {\r
+ //printf("Seek: count: %i newpos: %i return: %i\n", offset, lseek(((MFILEREADER*)reader)->file-_mm_iobase, 0, SEEK_CUR), tempb);\r
+ return 1;\r
+ }\r
+ else\r
+ {\r
+ return 0;\r
+ }\r
+}\r
+\r
+static long _mm_FileReader_Tell(MREADER* reader)\r
+{\r
+ return rb->lseek(((MFILEREADER*)reader)->file, 0, SEEK_CUR)-_mm_iobase;\r
+}\r
+\r
+MREADER *_mm_new_file_reader(int fp)\r
+{\r
+ MFILEREADER* reader=(MFILEREADER*)_mm_malloc(sizeof(MFILEREADER));\r
+ if (reader) {\r
+ reader->core.Eof =&_mm_FileReader_Eof;\r
+ reader->core.Read=&_mm_FileReader_Read;\r
+ reader->core.Get =&_mm_FileReader_Get;\r
+ reader->core.Seek=&_mm_FileReader_Seek;\r
+ reader->core.Tell=&_mm_FileReader_Tell;\r
+ reader->file=fp;\r
+ reader->waseof = 0;\r
+ }\r
+ return (MREADER*)reader;\r
+}\r
+\r
+void _mm_delete_file_reader (MREADER* reader)\r
+{\r
+ if(reader) free(reader);\r
+}\r
+\r
+/*========== File Writer */\r
+\r
+typedef struct MFILEWRITER {\r
+ MWRITER core;\r
+ int file;\r
+} MFILEWRITER;\r
+\r
+static BOOL _mm_FileWriter_Seek(MWRITER* writer,long offset,int whence)\r
+{\r
+ return rb->lseek(((MFILEWRITER*)writer)->file,offset,whence);\r
+}\r
+\r
+static long _mm_FileWriter_Tell(MWRITER* writer)\r
+{\r
+ return rb->lseek(((MFILEREADER*)writer)->file, 0, SEEK_CUR);\r
+}\r
+\r
+static BOOL _mm_FileWriter_Write(MWRITER* writer,void* ptr,size_t size)\r
+{\r
+ return (rb->write(((MFILEWRITER*)writer)->file, ptr, size)==size);\r
+}\r
+\r
+static BOOL _mm_FileWriter_Put(MWRITER* writer,int value)\r
+{\r
+ char buf = value;\r
+ if (rb->write(((MFILEWRITER*)writer)->file, &buf, 1))\r
+ return 0;\r
+ else\r
+ return -1;\r
+}\r
+\r
+MWRITER *_mm_new_file_writer(int fp)\r
+{\r
+ MFILEWRITER* writer=(MFILEWRITER*)_mm_malloc(sizeof(MFILEWRITER));\r
+ if (writer) {\r
+ writer->core.Seek =&_mm_FileWriter_Seek;\r
+ writer->core.Tell =&_mm_FileWriter_Tell;\r
+ writer->core.Write=&_mm_FileWriter_Write;\r
+ writer->core.Put =&_mm_FileWriter_Put;\r
+ writer->file=fp;\r
+ }\r
+ return (MWRITER*) writer;\r
+}\r
+\r
+void _mm_delete_file_writer (MWRITER* writer)\r
+{\r
+ if(writer) free (writer);\r
+}\r
+\r
+/*========== Write functions */\r
+\r
+void _mm_write_string(CHAR* data,MWRITER* writer)\r
+{\r
+ if(data)\r
+ _mm_write_UBYTES(data,strlen(data),writer);\r
+}\r
+\r
+void _mm_write_M_UWORD(UWORD data,MWRITER* writer)\r
+{\r
+ _mm_write_UBYTE(data>>8,writer);\r
+ _mm_write_UBYTE(data&0xff,writer);\r
+}\r
+\r
+void _mm_write_I_UWORD(UWORD data,MWRITER* writer)\r
+{\r
+ _mm_write_UBYTE(data&0xff,writer);\r
+ _mm_write_UBYTE(data>>8,writer);\r
+}\r
+\r
+void _mm_write_M_ULONG(ULONG data,MWRITER* writer)\r
+{\r
+ _mm_write_M_UWORD((UWORD)(data>>16),writer);\r
+ _mm_write_M_UWORD((UWORD)(data&0xffff),writer);\r
+}\r
+\r
+void _mm_write_I_ULONG(ULONG data,MWRITER* writer)\r
+{\r
+ _mm_write_I_UWORD((UWORD)(data&0xffff),writer);\r
+ _mm_write_I_UWORD((UWORD)(data>>16),writer);\r
+}\r
+\r
+void _mm_write_M_SWORD(SWORD data,MWRITER* writer)\r
+{\r
+ _mm_write_M_UWORD((UWORD)data,writer);\r
+}\r
+\r
+void _mm_write_I_SWORD(SWORD data,MWRITER* writer)\r
+{\r
+ _mm_write_I_UWORD((UWORD)data,writer);\r
+}\r
+\r
+void _mm_write_M_SLONG(SLONG data,MWRITER* writer)\r
+{\r
+ _mm_write_M_ULONG((ULONG)data,writer);\r
+}\r
+\r
+void _mm_write_I_SLONG(SLONG data,MWRITER* writer)\r
+{\r
+ _mm_write_I_ULONG((ULONG)data,writer);\r
+}\r
+\r
+#if defined __STDC__ || defined _MSC_VER || defined MPW_C\r
+#define DEFINE_MULTIPLE_WRITE_FUNCTION(type_name,type) \\r
+void _mm_write_##type_name##S (type *buffer,int number,MWRITER* writer) \\r
+{ \\r
+ while(number-->0) \\r
+ _mm_write_##type_name(*(buffer++),writer); \\r
+}\r
+#else\r
+#define DEFINE_MULTIPLE_WRITE_FUNCTION(type_name,type) \\r
+void _mm_write_/**/type_name/**/S (type *buffer,int number,MWRITER* writer) \\r
+{ \\r
+ while(number-->0) \\r
+ _mm_write_/**/type_name(*(buffer++),writer); \\r
+}\r
+#endif\r
+\r
+DEFINE_MULTIPLE_WRITE_FUNCTION(M_SWORD,SWORD)\r
+DEFINE_MULTIPLE_WRITE_FUNCTION(M_UWORD,UWORD)\r
+DEFINE_MULTIPLE_WRITE_FUNCTION(I_SWORD,SWORD)\r
+DEFINE_MULTIPLE_WRITE_FUNCTION(I_UWORD,UWORD)\r
+\r
+DEFINE_MULTIPLE_WRITE_FUNCTION(M_SLONG,SLONG)\r
+DEFINE_MULTIPLE_WRITE_FUNCTION(M_ULONG,ULONG)\r
+DEFINE_MULTIPLE_WRITE_FUNCTION(I_SLONG,SLONG)\r
+DEFINE_MULTIPLE_WRITE_FUNCTION(I_ULONG,ULONG)\r
+\r
+/*========== Read functions */\r
+\r
+int _mm_read_string(CHAR* buffer,int number,MREADER* reader)\r
+{\r
+ return reader->Read(reader,buffer,number);\r
+}\r
+\r
+UWORD _mm_read_M_UWORD(MREADER* reader)\r
+{\r
+ UWORD result=((UWORD)_mm_read_UBYTE(reader))<<8;\r
+ result|=_mm_read_UBYTE(reader);\r
+ return result;\r
+}\r
+\r
+UWORD _mm_read_I_UWORD(MREADER* reader)\r
+{\r
+ UWORD result=_mm_read_UBYTE(reader);\r
+ result|=((UWORD)_mm_read_UBYTE(reader))<<8;\r
+ return result;\r
+}\r
+\r
+ULONG _mm_read_M_ULONG(MREADER* reader)\r
+{\r
+ ULONG result=((ULONG)_mm_read_M_UWORD(reader))<<16;\r
+ result|=_mm_read_M_UWORD(reader);\r
+ return result;\r
+}\r
+\r
+ULONG _mm_read_I_ULONG(MREADER* reader)\r
+{\r
+ ULONG result=_mm_read_I_UWORD(reader);\r
+ result|=((ULONG)_mm_read_I_UWORD(reader))<<16;\r
+ return result;\r
+}\r
+\r
+SWORD _mm_read_M_SWORD(MREADER* reader)\r
+{\r
+ return((SWORD)_mm_read_M_UWORD(reader));\r
+}\r
+\r
+SWORD _mm_read_I_SWORD(MREADER* reader)\r
+{\r
+ return((SWORD)_mm_read_I_UWORD(reader));\r
+}\r
+\r
+SLONG _mm_read_M_SLONG(MREADER* reader)\r
+{\r
+ return((SLONG)_mm_read_M_ULONG(reader));\r
+}\r
+\r
+SLONG _mm_read_I_SLONG(MREADER* reader)\r
+{\r
+ return((SLONG)_mm_read_I_ULONG(reader));\r
+}\r
+\r
+#if defined __STDC__ || defined _MSC_VER || defined MPW_C\r
+#define DEFINE_MULTIPLE_READ_FUNCTION(type_name,type) \\r
+int _mm_read_##type_name##S (type *buffer,int number,MREADER* reader) \\r
+{ \\r
+ while(number-->0) \\r
+ *(buffer++)=_mm_read_##type_name(reader); \\r
+ return !reader->Eof(reader); \\r
+}\r
+#else\r
+#define DEFINE_MULTIPLE_READ_FUNCTION(type_name,type) \\r
+int _mm_read_/**/type_name/**/S (type *buffer,int number,MREADER* reader) \\r
+{ \\r
+ while(number-->0) \\r
+ *(buffer++)=_mm_read_/**/type_name(reader); \\r
+ return !reader->Eof(reader); \\r
+}\r
+#endif\r
+\r
+DEFINE_MULTIPLE_READ_FUNCTION(M_SWORD,SWORD)\r
+DEFINE_MULTIPLE_READ_FUNCTION(M_UWORD,UWORD)\r
+DEFINE_MULTIPLE_READ_FUNCTION(I_SWORD,SWORD)\r
+DEFINE_MULTIPLE_READ_FUNCTION(I_UWORD,UWORD)\r
+\r
+DEFINE_MULTIPLE_READ_FUNCTION(M_SLONG,SLONG)\r
+DEFINE_MULTIPLE_READ_FUNCTION(M_ULONG,ULONG)\r
+DEFINE_MULTIPLE_READ_FUNCTION(I_SLONG,SLONG)\r
+DEFINE_MULTIPLE_READ_FUNCTION(I_ULONG,ULONG)\r
+\r
+/* ex:set ts=4: */\r