#ifndef _MMIO_H_
#define _MMIO_H_

#include <stdio.h>
#include <stdlib.h>
#include "tdefs.h"


#ifdef __cplusplus
extern "C" {
#endif

// > LOG.C Prototypes

#define LOG_BRIEF   0
#define LOG_VERBOSE 1

int  log_init(CHAR *logfile, BOOL val);
void log_exit(void);
void log_verbose(void);
void log_silent(void);
void printlog(CHAR *fmt, ... );
void printlogv(CHAR *fmt, ... );

extern CHAR  *ERROR_OPENING_FILE;
extern CHAR  *ERROR_OUT_OF_MEMORY;
extern CHAR  *ERROR_END_OF_FILE;
extern CHAR  *ERROR_DISK_FULL;
extern CHAR  *_mm_error;        // returned techinical error message             

BOOL _mm_FileExists(CHAR *fname);
void StringWrite(CHAR *s, FILE *fp);
CHAR *StringRead(FILE *fp);

void *_mm_malloc(size_t size);
void *_mm_calloc(size_t nitems, size_t size);

#ifndef __WATCOMC__
#ifndef __BEOS__
CHAR *strdup(CHAR *str);
#endif // __BEOS__
#endif


//  MikMod/DivEnt style file input / output -
//    Solves several portability issues.
//    Notibly little vs. big endian machine complications.

#define _mm_write_SBYTE(x,y)    fputc((int)x,y)
#define _mm_write_UBYTE(x,y)    fputc((int)x,y)

#define _mm_read_SBYTE(x)    (SBYTE)fgetc(x)
#define _mm_read_UBYTE(x)    (UBYTE)fgetc(x)

#define _mm_write_SBYTES(x,y,z)  fwrite((void *)x,1,y,z)
#define _mm_write_UBYTES(x,y,z)  fwrite((void *)x,1,y,z)
#define _mm_read_SBYTES(x,y,z)   fread((void *)x,1,y,z)
#define _mm_read_UBYTES(x,y,z)   fread((void *)x,1,y,z)

#define _mm_rewind(x) _mm_fseek(x,0,SEEK_SET)


int  _mm_fseek(FILE *stream,long offset,int whence);
long _mm_iobase_get(void);
void _mm_iobase_set(long iobase);
void _mm_iobase_setcur(FILE *fp);
void _mm_iobase_revert(void);
long _mm_ftell(FILE *stream);
long _mm_flength(FILE *stream);
FILE *_mm_fopen(CHAR *fname, CHAR *attrib);
void _mm_fputs(FILE *fp, CHAR *data);
BOOL _mm_copyfile(FILE *fpi, FILE *fpo, ULONG len);

//extern SBYTE _mm_read_SBYTE (FILE *fp);
//extern UBYTE _mm_read_UBYTE (FILE *fp);

extern SWORD _mm_read_M_SWORD (FILE *fp);
extern SWORD _mm_read_I_SWORD (FILE *fp);

extern UWORD _mm_read_M_UWORD (FILE *fp);
extern UWORD _mm_read_I_UWORD (FILE *fp);

extern SLONG _mm_read_M_SLONG (FILE *fp);
extern SLONG _mm_read_I_SLONG (FILE *fp);

extern ULONG _mm_read_M_ULONG (FILE *fp);
extern ULONG _mm_read_I_ULONG (FILE *fp);

extern int _mm_read_string(CHAR *buffer, int number, FILE *fp);

//extern int _mm_read_SBYTES    (SBYTE *buffer, int number, FILE *fp);
//extern int _mm_read_UBYTES    (UBYTE *buffer, int number, FILE *fp);

extern int _mm_read_M_SWORDS  (SWORD *buffer, int number, FILE *fp);
extern int _mm_read_I_SWORDS  (SWORD *buffer, int number, FILE *fp);

extern int _mm_read_M_UWORDS  (UWORD *buffer, int number, FILE *fp);
extern int _mm_read_I_UWORDS  (UWORD *buffer, int number, FILE *fp);

extern int _mm_read_M_SLONGS  (SLONG *buffer, int number, FILE *fp);
extern int _mm_read_I_SLONGS  (SLONG *buffer, int number, FILE *fp);

extern int _mm_read_M_ULONGS  (ULONG *buffer, int number, FILE *fp);
extern int _mm_read_I_ULONGS  (ULONG *buffer, int number, FILE *fp);


//extern void _mm_write_SBYTE     (SBYTE data, FILE *fp);
//extern void _mm_write_UBYTE     (UBYTE data, FILE *fp);

extern void _mm_write_M_SWORD   (SWORD data, FILE *fp);
extern void _mm_write_I_SWORD   (SWORD data, FILE *fp);

extern void _mm_write_M_UWORD   (UWORD data, FILE *fp);
extern void _mm_write_I_UWORD   (UWORD data, FILE *fp);

extern void _mm_write_M_SLONG   (SLONG data, FILE *fp);
extern void _mm_write_I_SLONG   (SLONG data, FILE *fp);

extern void _mm_write_M_ULONG   (ULONG data, FILE *fp);
extern void _mm_write_I_ULONG   (ULONG data, FILE *fp);

//extern void _mm_write_SBYTES    (SBYTE *data, int number, FILE *fp);
//extern void _mm_write_UBYTES    (UBYTE *data, int number, FILE *fp);

extern void _mm_write_M_SWORDS  (SWORD *data, int number, FILE *fp);
extern void _mm_write_I_SWORDS  (SWORD *data, int number, FILE *fp);

extern void _mm_write_M_UWORDS  (UWORD *data, int number, FILE *fp);
extern void _mm_write_I_UWORDS  (UWORD *data, int number, FILE *fp);

extern void _mm_write_M_SLONGS  (SLONG *data, int number, FILE *fp);
extern void _mm_write_I_SLONGS  (SLONG *data, int number, FILE *fp);

extern void _mm_write_M_ULONGS  (ULONG *data, int number, FILE *fp);
extern void _mm_write_I_ULONGS  (ULONG *data, int number, FILE *fp);

extern void _mm_write_string    (UBYTE *data, FILE *fp);



#ifdef __cplusplus
}
#endif

#endif
