/*
 * SkySOUND Portable Replay Library
 *
 * Main Header
 *
 * Copyright (c) 1997'2000, Jean-Michel HERVE
 * All Rights Reserved.
 *
 * This file is part of SkySOUND Portable Replay Library, and may only be
 * used, modified and distributed under the terms of the license provided in
 * your package, LICENSE.TXT. Please read it before going further.
 *
 * Code : TuO / StG
 * Date : 01/01/2000
 */

/*
 * SSND_OS : String to identify compiling OS
 *           In addition, define the __LINUX__ if under Linux & __LINUX__ isn't
 *           set. Btw, the detection is really insufficient.
 */
#ifdef _WIN32
#define SSND_OS "Win32"
#elif ((__MSDOS__) || (__WATCOMC__))
#define SSND_OS "DOS"
#elif __linux__
#define SSND_OS "Linux"
#ifndef __LINUX__
#define __LINUX__ 1
#endif
#else
#define SSND_OS "Unknown OS"
#endif

/*
 * SSND_DLL : Defines DLL export mode
 */
#ifdef _WIN32
#define SSND_DLL __declspec(dllexport)
#else
#define SSND_DLL
#endif

/*
 * Define __SSND_CDECL__ convention for compilator
 * Allow easy-portability between compilators.
 */
#ifdef  __GNUC__
/* GNUC assumes that all C function are exported with C convention */
#define __SSND_CDECL__
#else
/* Just define the real calling convention */
#define __SSND_CDECL__ __cdecl
#endif

/*
 * SSND_EXPORT : export definition of functions from SkySOUND (DO NOT MODIFY!)
 * The export mode is automatically created according to the OS
 *
 * This definition selects the export mode during compilation (WINDOWS DLL)
 * and the import mode during inclusion (for all compilators).
 */
#ifdef __cplusplus
#define SSND_EXPORT extern "C"  SSND_DLL
#else
#define SSND_EXPORT extern SSND_DLL
#endif

/*
 * SSND_EXPORT_VAR : export definition of variables from SkySOUND (DO NOT MODIFY!)
 * The export mode is automatically created according to the OS
 *
 * This definition selects the export mode during compilation (WINDOWS DLL)
 * and the import mode during inclusion (for all compilators).
 */
#ifdef __cplusplus
#define SSND_EXPORT_VAR extern "C" SSND_DLL
#else
#define SSND_EXPORT_VAR extern SSND_DLL
#endif

/*
 * SSND_ASM_IMPORT : import definition for the SkySOUND's ASM functions, to
 *                   avoid differences between C & C++ compilators. All ASM
 *                   functions are defined in agreement with the standard
 *                   __cdecl C calling & naming convention. This definition
 *                   allow easy compilation in C or C++.
 */
#ifdef __cplusplus
#define SSND_ASM_IMPORT extern "C"
#else
#define SSND_ASM_IMPORT extern
#endif

/* Include windows header if needed */
#ifdef _WIN32
#include <windows.h>
#endif

/*
 * __SSND_OWNDRIVER__ : Define this to use the SkySOUND own sound drivers. The
 *                      library will be compilated using built-in driver if
 *                      available. If you prefer to use extern sound systems
 *                      like MIDAS or SEAL, or add your own non-built-in
 *                      driver (ie something that uses another library),
 *                      undefine this and update the corresponding defines.
 *                      Note that it is not allowed to use more than ONE
 *                      external sound library at once, because one of those
 *                      library should be able to do everything. If not,
 *                      then choose another lib :)
 * NOTE : You can use the SSND_SetDriver to set your own external driver
 *        without recompiling the library. You can even compil library with
 *        minimal driver support, and use only your drivers if you want so.
 *        But btw the best thing you can do is adding your driver to the
 *        SkySOUND library to share it with the whole world.
 * Note that this configure the default settings of the library on systems
 * where you can't run the ./configure script (ie DOS and Win32 platforms).
 */
#ifndef HAVE_CONFIG_H
#    ifdef __MINGW32__
#        define __SSND_OWNDRIVER__
#    elif _WIN32
#        define __SSND_OWNDRIVER__
#    elif __linux__
#        define __SSND_OWNDRIVER__
#    else
#        undef  __SSND_OWNDRIVER__
#        define __SSND_MIDAS__
#        undef  __SSND_SEAL__
#    endif
#endif

/* Define Standard Portable Types */
#ifndef sky_typedef
#define sky_typedef

typedef	signed	 long  int SLONG;      /* 32 bit signed. */
#ifndef __MINGW32__
typedef	unsigned long  int ULONG;      /* 32 bit unsigned. */
#endif	/* defined already in winnt.h */
typedef	signed	 short int SWORD;      /* 16 bit signed. */
typedef	unsigned short int UWORD;      /* 16 bit unsigned. */
typedef	signed	 char      SBYTE;      /* 8 bit signed. */
typedef	unsigned char      UBYTE;      /* 8 bit unsigned. */
typedef	ULONG              LBOOL;      /* Yeah, should be a byte. */
typedef	UBYTE              BBOOL;      /* Most people define a bool as a long.  Bytes use less space and should be just as efficient. */

#define		TRUE				1
#define		FALSE				0

#endif

/* SkySOUND : main version number */
#define SSND_VERSION        "0.61.000"
/* SkySOUND : copyright date */
#define SSND_COPYRIGHTDATE  "1997'2000"
/* SkySOUND : introduction string */
#define SSND_COPYRIGHTTEXT  "SkySOUND Version " SSND_VERSION " (" SSND_OS " Version)\nCopyRight (c) " SSND_COPYRIGHTDATE ", TuO / StG\n"

/* Return defines */
#define SSND_RETURNOK            0x0000
#define SSND_RETURNNOMEMORY      0x0002
#define SSND_RETURNNEEDMORE      0x0003
#define SSND_RETURNFILENOTFOUND  0x0004
#define SSND_RETURNEOF           0x0005
#define SSND_RETURNERROR         -1
#define SSND_RETURNSTREAMEND     0x0006

/*
 * Initialization flags
 */
#define SSND_INTERNAL            0x0001
#define SSND_HUSHTEXT            0x0002

/*
 * Output capabilities defines
 * NOTE : These defines are provided to help user evaluate the system he is
 *        running (in fact the driver for that OS/SoundCard).
 * NOTE : SSNDCAPS_8BITS is set to 1 because this is the minimal support
 *        to be useable by SkySOUND. There's currently NO FM support (for
 *        adlib or those old-cards).
 * NOTE : SSNDCAPS_MONO is set to 1 for the same reason as SSNDCAPS_8BITS :
 *        this is the minimal support needed.
 */
#define SSNDCAPS_8BITS      0x0001
#define SSNDCAPS_16BITS     0x0002
#define SSNDCAPS_MONO       0x0001
#define SSNDCAPS_STEREO     0x0004

/*
 * Audio status
 * NOTE : These defines are provided to allow user know the stat of the audio
 *        device and act accordingly.
 */
#define SSNDSTATUS_READY    0x0000
#define SSNDSTATUS_BUSY     0x0001

/*
 * MPEG Initialization
 * Rate setting
 */
#define SSND_FULLRATE       0x0000
#define SSND_HALFRATE       0x0001
#define SSND_QUARTERRATE    0x0002
#define SSND_RATEMASK       0x0003

/*
 * MPEG Initialization
 * Output bit
 */
#define SSND_DEFAULTBIT     0x0000
#define SSND_FORCE16BIT     0x0010
#define SSND_FORCE8BIT      0x0020
#define SSND_FORCEULAW      0x0030
#define SSND_BITMASK        0x0030

/*
 * MPEG Initialization
 * Mono/Stereo handling
 */
#define SSND_DEFAULTPAN     0x0000
#define SSND_FORCEMONO      0x0100
#define SSND_FORCELEFT      0x0200
#define SSND_FORCERIGHT     0x0300
#define SSND_PANMASK        0x0300

/*
 * MPEG Initialization
 * Default setting
 */
#define SSND_MPEGDEFAULT    (SSND_FULLRATE|SSND_DEFAULTBIT|SSND_DEFAULTPAN)

/*
 * Defines maximum buffering before sending sounds
 */
#define SSND_MAXBUFFER      2

/*
 * Define maximum user variables in player buffers
 */
#define SSND_MAXUSERVARIABLES 16

/*
 * Stream Input Type
 */
enum SSND_INPUTTYPE { SSND_FROMFILE=0, SSND_FROMMEMORY };

/*
 * SkySOUND : Output Driver description structure
 */
typedef struct
{
    char   *Name;                         /* Printable driver short description */
    int   (*Check)(void);                 /* Check useability of driver */
    int   (*Init)(void);                  /* Initialize driver */
    int   (*Uninit)(void);                /* Uninitialize driver */
    ULONG (*GetCaps)(void);               /* Get driver capabilities */
    int   (*InitSamplePlay)(ULONG,ULONG,ULONG,ULONG); /* Init sample play */
    int   (*UninitSamplePlay)(void);      /* Uninit sample play mode */
    int   (*Write)(SLONG *,void *,SLONG); /* Write sample to audio */
    SLONG (*SendData)(void *,SLONG);      /* Send datas, partially grabbed */
    int   (*GetStatus)(void);             /* Get audio status */
    float (*GetVolume)(void);             /* Get output volume */
    int   (*SetVolume)(float);            /* Set output volume */
    SLONG (*GetPanning)(void);            /* Set stereo panning */
    int   (*SetPanning)(SLONG);           /* Set stereo panning */
    int   (*Poll)(void);                  /* Poll audio driver */
    int   (*StreamStat)(void);            /* Get stream stat (is it over or not?) */
    BBOOL   Available;                    /* Availability marker */
} TSSND_SOUNDDRIVER;
typedef TSSND_SOUNDDRIVER *PSSND_SOUNDDRIVER;

/*
 * SkySOUND : Audio Buffer Information structure
 */
typedef struct _SSND_ABI
{
  void *pBuffer;
  SLONG Length;
} SSND_ABI;

/* Pre define */
struct _TSSND_INPUT;

/*
 * SkySOUND : Player buffering description structure
 *            It applies mainly to streaming players (MPEG, WAVE, ...) but
 *            can be used for others (like MOD/IT/XM/... player).
 */
typedef struct
{
    int    Type;                          /* Type */
    int    FileHandle;                    /* Input file handle */
    SLONG  PosStreamSize;                 /* Input position in file or input size of stream */
    UBYTE *InputStream;                   /* Input pointer for memory input */
    UBYTE *CurrentInputStream;            /* Current position in memory input */
    SLONG  BufferSize;                    /* I/O Buffer size */
    UBYTE *InputBuffer;                   /* Input Buffer */
    UBYTE *CurrentInputBuffer;            /* Current position if input buffer */
    UBYTE *OutputBuffer;                  /* Output Buffer */
    SLONG  InputTrigger;                  /* Input trigger value */
    SLONG  OutputTrigger;                 /* Output trigger value */
    SLONG  InputBytes;                    /* Current number of bytes */
    SLONG  OutputBytes;                   /* Current number of bytes */
    int    Channels;                      /* Number of output channels (1/2) */
    int    Bits;                          /* Output bit number */
    int    SampleRate;                    /* Output sample rate */
    int    User[SSND_MAXUSERVARIABLES];   /* User variables */
    struct _TSSND_INPUT *In;              /* Input functions */
} TSSND_FORM;
typedef TSSND_FORM *PSSND_FORM;

/*
 * SkySOUND : Input Interface
 */
typedef struct _TSSND_INPUT
{
    char   *Name;                         /* Printable short description */
    int   (*Open)(PSSND_FORM,char*,long); /* Open input stream */
    int   (*Read)(PSSND_FORM,void*,long); /* Read datas from input stream */
    int   (*Seek)(PSSND_FORM,long,int);   /* Seek in stream */
    ULONG (*GetSize)(PSSND_FORM);         /* Get size of stream */
    int   (*Close)(PSSND_FORM);           /* Close input stream */
} TSSND_INPUT;
typedef TSSND_INPUT *PSSND_INPUT;

/*
 * SkySOUND : Call back typedef
 */
typedef SSND_ABI* (*SSND_CALLBACK)(void);

/*
 * SkySOUND : Error handler typedef
 */
typedef void (*SSND_ERRORHANDLER)(char *);

/*
 * SkySOUND : Buffers vars
 */
SSND_EXPORT_VAR SSND_ABI SSND_Buffering[];
SSND_EXPORT_VAR UBYTE    SSND_CurrentBuffer;
SSND_EXPORT_VAR BBOOL    SSND_AllBufferFilled;
SSND_EXPORT_VAR ULONG    SSND_Flags;

/*
 * SkySOUND : Output drivers exported for user
 */
SSND_EXPORT_VAR TSSND_SOUNDDRIVER SSND_Disk;

/*
 * SkySOUND : Main Handling Functions
 */
SSND_EXPORT int   __SSND_CDECL__ SSND_Init(ULONG Flags);
SSND_EXPORT int   __SSND_CDECL__ SSND_GetCaps(void);
SSND_EXPORT int   __SSND_CDECL__ SSND_Uninit(void);
SSND_EXPORT int   __SSND_CDECL__ SSND_InitSamplePlay(ULONG bits_per_sample,ULONG number_of_channels,ULONG samples_per_second,ULONG max_buffer_size);
SSND_EXPORT int   __SSND_CDECL__ SSND_SetCallBack(SSND_CALLBACK pCallBack);
SSND_EXPORT int   __SSND_CDECL__ SSND_FillBuffers(void *pBuffer, SLONG length);
SSND_EXPORT int   __SSND_CDECL__ SSND_StartSamplePlay(void);
SSND_EXPORT int   __SSND_CDECL__ SSND_UninitSamplePlay(void);
SSND_EXPORT int   __SSND_CDECL__ SSND_Write(SLONG *wrote, void *pBuffer,SLONG length);
SSND_EXPORT SLONG __SSND_CDECL__ SSND_SendData(void *pBuffer,SLONG length);
SSND_EXPORT int   __SSND_CDECL__ SSND_GetStatus(void);
SSND_EXPORT float __SSND_CDECL__ SSND_GetVolume(void);
SSND_EXPORT int   __SSND_CDECL__ SSND_SetVolume(float Vol);
SSND_EXPORT int   __SSND_CDECL__ SSND_GetPanning(void);
SSND_EXPORT int   __SSND_CDECL__ SSND_SetPanning(int Panning);
SSND_EXPORT int   __SSND_CDECL__ SSND_Poll(void);
SSND_EXPORT int   __SSND_CDECL__ SSND_StreamStat(void);

/*
 * SkySOUND : Driver Functions
 */
SSND_EXPORT int   __SSND_CDECL__ SSND_SetDriver(PSSND_SOUNDDRIVER Driver);

/*
 * SkySOUND : Buffer Functions (internal use)
 */
SSND_EXPORT int   __SSND_CDECL__ SSND_InitForm(PSSND_FORM Form, char *FileName, ULONG Size, ULONG BufferSize, int Type);
SSND_EXPORT int   __SSND_CDECL__ SSND_CheckForm(PSSND_FORM Form);
SSND_EXPORT int   __SSND_CDECL__ SSND_RefillForm(PSSND_FORM Form);
SSND_EXPORT ULONG __SSND_CDECL__ SSND_GetSizeForm(PSSND_FORM Form);
SSND_EXPORT int   __SSND_CDECL__ SSND_UninitForm(PSSND_FORM Form);

/*
 * SkySOUND : MPEG Functions
 */
SSND_EXPORT int   __SSND_CDECL__ SSND_PrepareMPG(char *FileName, long Size, int Flags, int BufferSize, int Type);
SSND_EXPORT int   __SSND_CDECL__ SSND_PlayMPG(void);
SSND_EXPORT int   __SSND_CDECL__ SSND_PollMPG(void);
SSND_EXPORT int   __SSND_CDECL__ SSND_StopMPG(void);
SSND_EXPORT int   __SSND_CDECL__ SSND_FreeMPG(void);
SSND_EXPORT ULONG __SSND_CDECL__ SSND_GetBytesDecoded(void);

/*
 * SkySOUND : Error Handling Functions
 */
SSND_EXPORT void * __SSND_CDECL__ SSND_malloc(size_t size);
SSND_EXPORT void   __SSND_CDECL__ SSND_SysError(char *error, ...);
SSND_EXPORT void   __SSND_CDECL__ SSND_SetErrorHandler(SSND_ERRORHANDLER ErrorHandler);

#ifdef _WIN32
SSND_EXPORT void __SSND_CDECL__  SSND_SetWindowHandle(HWND hWnd);
#endif
