Add "MikMod for Rockbox 0.1" from 2007-06-29
[mikmod-rockbox.git] / apps / plugins / mikmod / mmio / mmio.c
diff --git a/apps/plugins/mikmod/mmio/mmio.c b/apps/plugins/mikmod/mmio/mmio.c
new file mode 100644 (file)
index 0000000..50269fb
--- /dev/null
@@ -0,0 +1,427 @@
+/*     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